The previous words
Most of the time, the main reason why we are confused about scope is that we cannot distinguish whether variable searches should be performed in the nested order of function positions or in the order of function calls. Coupled with the interference of this mechanism, variable search is very prone to errors. This is actually caused by two scope working models. The scope is divided into lexical scope and dynamic scope. By distinguishing these two scope models, you can have a clear understanding of the variable search process. This article is the second chapter of the JavaScript scope series - Lexical scope and dynamic scope
Lexical scope
As mentioned in the first article, the first working stage of the compiler is called word participle, which decomposes a string composed of characters into lexical units. This concept is the basis for understanding the lexical scope
Simply put, the lexical scope defines the scope at the lexical stage, which is determined by where the variables and block scope are written when writing the code. Therefore, the scope remains unchanged when the lexical analyzer processes the code.
relation
No matter where the function is called, and no matter how it is called, its lexical scope is determined only by the position where the function is declared.
function foo(a) {var b = a * 2;function bar(c) {console.log( a, b, c );}bar(b * 3);}foo( 2 ); // 2 4 12In this example, there are three nested scopes. To help understand, think of them as several bubbles that are included step by step
Scope bubbles are determined by where their corresponding scope block code is written, and they are included step by step.
Bubble 1 contains the entire global scope, with only one identifier: foo
Bubble 2 contains the scope created by foo, which has three identifiers: a, bar, and b
Bubble 3 contains the scope created by bar, with only one identifier: c
Find
The structure of scoped bubbles and their positional relationships provide the engine with sufficient position information, which the engine uses to find the location of the identifier.
In the code snippet, the engine executes the console.log(...) declaration and looks for references to the three variables a, b and c. It first starts with the innermost scope, that is, the scope of the bar(...) function. The engine cannot find a here, so it will go to the previous level to continue searching in the scope of the nested foo(...). A is found here, so the engine uses this reference. The same goes for b. And for c, the engine found it in bar(...)
[Note] Lexical scope search will only look for first-level identifiers. If the code references foo.bar.baz, lexical scope search will only try to find foo identifiers. After finding this variable, the object attribute access rules take over access to bar and baz attributes respectively
foo = {bar:{baz: 1}};console.log(foo.bar.baz);//1Cover
Scope search starts from the innermost scope at which the runtime is located, and proceeds step by step outward or upward until the first matching identifier is met.
Identifiers with the same name can be defined in multi-layer nested scopes, which is called the "occlusion effect". The internal identifiers "occlude" external identifiers
var a = 0;function test(){var a = 1;console.log(a);//1}test();Global variables are automatically attributes of global objects, so they can be accessed directly by reference to global objects' attributes instead of directly passing through the lexical name of the global object.
var a = 0;function test(){var a = 1;console.log(window.a);//0}test();This technique allows access to global variables that are obscured by variables of the same name. But if non-global variables are blocked, they cannot be accessed no matter what.
Dynamic scope
JavaScript uses lexical scope, and its most important feature is that its definition process takes place during the writing stage of the code.
Then why introduce dynamic scope? In fact, dynamic scope is another important mechanism of javascript to cousin this. Most of the confusion of scope is because the lexical scope and this mechanism are confused, so I can't tell the difference between stupidly
Dynamic scopes do not care about how functions and scopes are declared and declared anywhere, only where they are called from. In other words, scope chains are based on the call stack, not scope nesting in the code
var a = 2;function foo() {console.log( a );}function bar() {var a = 3;foo();}bar();[1] If it is in the lexical scope, it is the current JavaScript environment. The variable a is first searched in the foo() function, but it is not found. So follow the scope chain to search in the global scope, find and assign a value of 2. So the console outputs 2
【2】If it is in dynamic scope, similarly, the variable a is first searched in foo() and not found. Here, you will follow the call stack to search in the place where the foo() function is called, that is, the bar() function, find and assign the value to 3. So the console outputs 3
Summary: The difference between the two scopes. In short, the lexical scope is determined at definition time, while the dynamic scope is determined at runtime.
The above is the second part of the lexical scope and dynamic scope introduced by the editor to you. I hope it will be helpful to you. If you want to know more, please pay attention to Wulin.com!