preface

There are a lot of discussions about scope and scope chain on the nuggets, but few people are clear about the relevant mechanism in JS. Here I will pick up some of the big guys to see the rest of the knowledge, to talk about the preparation before understanding scope. Read the article with these questions in mind:

  • JavaScriptHow is it compiled and executed?
  • How do you work your way up a scope?
  • JavaScriptWhat is the nature of scope chains?

2. How does JavaScript execute?

And shorthand tips:Scoped chain tips

1. Popularity before Understanding: How compilation works

1.1 Word segmentation/lexical analysis

These code blocks are called lexical units (tokens), and these lexical units make up an array of lexical unit streams

var sum = 30; / / the lexical analysis result [" var ":" keyword ", "sum" : "identifier", "=" : "the assignment", "30" : "integer", "; ": "eos" (end of statement) ]Copy the code

1.2 Grammar Analysis

An array of lexical unit streams is converted into a hierarchical nested Tree of elements that represents the Syntax structure of the program. This Tree is called Abstract Syntax Tree (AST).

1.3 Code Generation

The abstract syntax tree (AST) is converted into a set of machine instructions, known as executable code, which is simply used to create a variable a and store the value 3 in a.

1.4 Differences in JavaScript compilation process

  • JavaScriptMost of the time compilation happens a few microseconds (or less!) before the code executes. Period of time
  • JavaScriptThe engine ran out of options (e.gJIT, you can delay or even recompile) for optimal performance

2. How is JavaScript executed?

  • Key point: All declarations, including variables and functions, are processed first before any code is executed.

  • The moment the function runs, create an AO (Active Object) running carrier.

Example 2.1 a


function a(age) {
    console.log(age);
    var age = 20
    console.log(age);
    function age() {
    }
    console.log(age);
}
a(18);
Copy the code

2.1.1 Analysis phase

The moment the function runs, create an AO (Active Object).

Active Object (AO) is equivalent to a carrier

AO = {}
Copy the code
The first step is to analyze function parameters:
Age = undefined Parameter: Ao. age = 18Copy the code
Step 2, analyze variable declarations:
Ao.age = 18; ao.age = 18Copy the code
Step 3, analyze function declaration:
Function age(){} ao.age = function age(){}Copy the code
Function declaration features: If the AO has an attribute with the same name as the function, the AO will be overwritten by the function.

Because in the JS world, functions are also a type of variable

The final results of the analysis phase are as follows:
AO.age = function age() {}
Copy the code

2.1.2 Execution Phase

2.2 example 2

    function a(age) {
        console.log(age);
        var age = function () {
            console.log('25');
        }
    }
    a(18);
Copy the code

2.2.1 Analysis phase

The first step is to analyze function parameters:
Age = undefined Parameter: Ao. age = 18Copy the code
Step 2, analyze variable declarations:
Var age = function () {console.log('25'); }} age = 18; ao.age = 18; ao.age = 18Copy the code
Step 3, analysis function declaration (none)
The final results of the analysis phase are as follows:
AO.age = 18
Copy the code

2.2.2 Execution Phase

2.3 example 3

 function a(age) {
        console.log(age);
        var age = function () {
            console.log(age);
        }
        age();
    }
a(18);
Copy the code

2.3.1 Analysis phase

The first step is to analyze function parameters:AO.age = 18
Second, analyze the variable declaration: it has a property of the same name and does nothingAO.age = 18
Step 3, analysis function declaration (none)
The final results of the analysis phase are as follows:
AO.age = 18
Copy the code

2.3.2 Execution Phase

Here, a lot of people get confused: age(); Shouldn’t it print 18?

Code executes to age(); In fact, it will be analyzed & executed again.

2.3.3 age()Analysis & execution of

// Create the AO object in the analysis stage, AO = {} in the first step, analyze the function parameters (none) in the second step, analyze the variable declaration (none) in the third step, analyze the function declaration (none) in the analysis stage, the final result is: AO = {} in the analysis stage.Copy the code
  • whenage()Their ownAO object, i.e.,age.AOIs an empty object, it will call up.
  • The higher level ofAO objectisa, i.e.,a.AO.a.AOAnd then we have the next one that we get after we execute ita.AO.age = function(){console.log(age); }
  • The outputƒ () {the console. The log (age); } `

2.4 Summary of implementation: What is a scope chain

Every function on JavaScript executes in its own creationAOFind the corresponding attribute value. If you can’t find it, look for the AO of the parent function. If you can’t find it again, go up to the AO of the parent functionAOUntil you find the big boss:windowGlobal scope. And this one forms the”AOChain “isJavaScriptScope chain in.

3.LHSandRHSQueries: Two powerful tools of the scope chain

The terms LHS and RHS are used when the engine queries variables. It’s also clearly described in Javascript you Don’t Know (Part 1). Here, I’d like to quote the above answer from Fred Codecamp to explain:

LHS = Variable assignment or write to memory. Imagine saving a text file to your hard disk. RHS = Variable lookup or read from memory. Imagine opening a text file from your hard drive. Learning Javascript, LHS RHS

3.1 Characteristics of both

  • Is queried in all scopes
  • In strict mode, the engine throws when the desired variable is not foundReferenceErrorThe exception.
  • In the non-strict mode,LHRSlightly special: a global variable is automatically created
  • When the query is successful, the engine will throw a value that is not of a function type, for example, a function call to a value that is not of a function typeTypeErrorabnormal

3.2 Take the example in the book

function foo(a) {
    var b = a;
    return a + b;
}
var c = foo( 2 );
Copy the code

Look directly at performing the lookup:

LHS(write to memory) :

C =, a=2(implicit variable assignment), b=Copy the code

RHS(Read memory) :

Read foo(2), = a, a, bCopy the code

Is it easier to understand by write/read memory than in the book?

3.3 aboutLHSandRHSThrow the wrong

Take the two simplest examples:

3.3.1 Unreasonable operation

LHSDuring the query execution, the original query succeeded, but theaFunction calla();, so the engine throws TypeError.

3.3.2 rainfall distribution on 10-12LHSThrow the wrong

The rare thing about LHS is that there are a lot of times when we don’t turn on strict mode, which is: “Use strict”. You can now open the Chrome debugger and try the following output in strict/non-strict mode:

Function init(a){b=a+3; } init(2); console.log(b);Copy the code

3.3.3 RHSThrow the wrong

4. Scope chain tips

Here’s an illustration from Javascript You Don’t Know (part 1) :

I’ve also summarized a scope chain formula to help you quickly find the output:

  • Analysis stage creation AO, parameters look for variables, variables are not the top function, after the top of the universe.

  • During the execution phase, I looked at LR. The inner layer was not good, and I could not find the outer layer. I threw an exception and looked again and again.

Comprehension:

These days to find a lot of information, found a lot of language is unclear. Or it’s very complicated, very esoteric. Or it’s a rough summary without a systematic introduction. This is also the reason why there are so many scopes and scope chains, but none of them are completely understood.

A collection of author’s articles

  • The answer to the Vue question “Learn from source” that no interviewer knows
  • “Learn from the source” Vue source JS operations
  • “Learn from source” thoroughly understand the Vue option Props
  • The “Vue Practice” project upgrades vuE-CLI3 to correct posture
  • Why do you never understand JavaScript scope chains?

The public,