Understanding scope

The three elements:

  1. Engine: in charge from start to finishThe compilation and execution process of the whole JS program.
  2. Compiler: one of the engine’s best friends, responsible for languageMethod analysis and code generation, etcDirty work.
  3. Scope: Another friend of the engine that collects and maintains a series of queries made up of all declared identifiers (variables) and enforces a very strict set of rules,Determines the access rights of the currently executing code to these identifiers.

How the three of them work together:

var a = 2;Copy the code

When encountering the above code:

  1. When var a is encountered, the compiler asks the scope if a variable with the name (a) already exists. If so, the compiler ignores the declaration; Otherwise it will require the scope to declare a new variable in the collection of the current scope and name it a.
  2. The compiler then generates the code the engine needs at runtime, executing a = 2. The engine first asks the scope if there is a variable called a. If yes, the engine uses this variable, otherwiseContinue looking outward for the variableI’ll talk about that later.
  3. When the engine finds a, it assigns 2 to it. If it is never found, an error is thrown.

The compiler says something

The engine has two types of variable lookups:

  1. LHS: Finds the variable’s container itself. Example: a = 2, the purpose is to copy a, do not need to know the value of a before.
  2. RHS: The value of the variable to be found. Example: console.log(a), the purpose is to find the value of a for console.log, find 2.

Code analysis:

function foo(a) {
    console.log(a); / / 2
}
foo(2)
Copy the code
  1. Foo (2), performs an RHS lookup on foo, retrieves a value of a function type, and executes it.
  2. Hide code a = 2, do an LHS lookup on A, find the container, and copy 2 to it.
  3. Console. log(a), RHS search a, obtain a numeric value for console.log.

From an engine and scope perspective, execute this code:

Scope nesting

function foo(a) {
    console.log(a); / / 2
}
foo(2)
Copy the code

There are two scopes: the global scope and the local scope formed by Foo (function scope). When console.log(a) is executed, it searches for the nearest local scope first and then searches outward.

Deepen the understanding

If Xiao Ming wants to go to the barber shop, he will go to Village C first, go to County B if he can’t find it, and then go to a city if he can’t find it. If you find it halfway, go for a haircut and never look outside. But js doesn’t allow him to go to County A.

Both LHS and RHS references follow the lookup rules above.

abnormal

  1. If a is undeclared, the container will be named a in the global scope and 1 will be assigned to a.
  2. B does not declare direct console.log(b), raising ReferenceError.
a = 1
console.log(a)
console.log(b)
Copy the code

Why does a not throw an error?

LHS reference wants to create a container, so no error will be reported. The RHS reference wants a value and cannot find a value, so an error is reported

Important: LHS references in strict mode also report errors