Lexical Scope
Lexical Scope is the Scope model adopted by JavaScript. Lexical scope is also called static scope.
Corresponding definitions:
1.”functions are executed using the variable scope that was in effect when they were defined, not the variable scope that is in effect when they are invoked” – according to JavaScript Definition Guide.
The execution of a function depends on the scope of the variable generated when the function is defined, not when the function is called.
2.Lexical Scoping defines how variable names are resolved in nested functions: inner functions contain the scope of parent functions even if the parent function has returned(closure). – according to stackoverflow answer
Lexical scope defines how variable names are resolved in nested functions: the inner function contains the scope of the parent function even if the parent function has returned.
3.programming (“static scope”) In a lexically scoped language, the {scope} of an {identifier} is fixed at {compile time} to some region in the {source code} containing the identifier’s declaration. This means that an identifier is only accessible within that region (including procedures declared within it).
Programs (” static scope “) In lexical scoped languages, the {scope} of {identifier} in {compile time} is fixed to {source code}, containing some area of identifier declaration. This means that identifiers can only be accessed in this area (including procedures declared in it).
4.In lexical scoping (and if you’re the interpreter), you search in the local function (the function which is running now), then you search in the function (or scope) in which that function was defined, then you search in the function (scope) in which that function was defined, and so forth.
“Lexical” here refers to text, in that you can find out what variable is being referred to by looking at the nesting of scopes in the program text.
In the lexical scope (if you are the interpreter), you search in the current function (the function that is now running), then in the function (or scope) that defines it, then in the function (scope) that defines it, and so on.
“Lexical” here refers to context, because you can find referenced variables by looking at the nesting of scopes in the program context.
Static scope:
var a = 2;
function foo() {
console.log(a); // Output 2 static scope
}
function bar() {
var a = 3;
foo();
}
bar();
Copy the code
Function foo looks inside foo to see if there is a local variable, a. If not, it looks for the global variable, a equals 2, so it prints 2.
Dynamic scope:
/ / pseudo code
var a = 2;
function foo() {
print a; // Output 3 instead of 2! Dynamic scope concerns where functions are called from, and its scope chain is based on the call stack at run time.
}
function bar() {
var a = 3;
foo();
}
bar();
Copy the code
If I execute foo, I still look inside foo to see if there’s a local variable a. If not, the a variable is looked up from within the calling function’s scope chain, that is, the bar function, so the result prints 3.
Scope query:
Lexical scope means that in a nested group of functions, the inner functions have access to the variables and other resources of their parent scope. This means that the child’s functions are lexically bound to the execution context of their parents.
Lexical scope means that within a nested set of functions, an inner function can access variables and other resources in its parent scope. This means that the child function is lexically bound to the execution context of its parent function.
var name = "outer";
function one() {
var name = "middle";
var other = "findme";
function two() {
var name = "inner";
// Here `name` is "inner" and `other` is "findme"
console.dir({name: name, other: other});
}
two();
// Here `name` is "middle" and `other` is "findme"
console.dir({name: name, other: other});
}
one();
// Here `name` is "outer" and `other` is not defined.
console.dir({name: name});
console.dir({other: other});
Copy the code
Once the first match is found, the scoped query is stopped. The same identifier name can be specified in multiple layers of nested scopes, called “shadowing” (the inner identifier “shadowing” the outer identifier). Regardless of masking, scope queries always start at the innermost scope currently being executed and work outward/upward until the first match. But from the outside, the internal variables are undefined.
Variables with the same name in different execution contexts are prioritized from the top to the bottom of the execution stack. The same name in the innermost function (the topmost context of the execution stack) will have higher precedence.
Another:
function grandfather() {
var name = 'Hammad';
// 'likes' is not accessible here
function parent() {
// 'name' is accessible here
// 'likes' is not accessible here
function child() {
// Innermost level of the scope chain
// 'name' is also accessible here
var likes = 'Coding'; }}}Copy the code
Lexical scope works forward, which means that name can be accessed through the execution context of its children.
But it doesn’t go back to its parent, which means its parent can’t access the variable likes.
AST Intuitive understanding
back to the example of static scope
var a = 2;
function foo() {
console.log(a);
}
function bar() {
var a = 3;
foo();
}
bar(); / / 2
Copy the code
As can be seen from the figure, the program consists of four parts. The global scope contains VariableDeclaration, function foo(), function bar(), and ExpreesionStatement(bar()).
The variable declaration section declares the variable identifier(a) in the global scope and assigns 2 to a.
Function foo() section. Log console.log(a)
Function bar() section.
Notice that in the function scope of bar, there is a new variable declaration identifier(a) that assigns 3 to a.
Executing foo ()
ExpreesionStatement(bar ())
Since foo is not a nested function of bar, variable A cannot be found in foo’s scope. It then looks directly from the global variable and finds 2.
Nested function
var value = 1;
function bar() {
var value = 2;
function foo() {
console.log(value);
}
foo()
}
bar() / / 2
Copy the code
If it is nested, it looks from the current child scope to the parent scope until the first value (2) is found.
The AST for function bar() is as follows:
Variable pollution
var a = 2;
function foo() {
console.log(a);
}
function bar() {
a = 3;
foo()
}
bar() / / 3
console.log(a) / / 3
Copy the code
Again, focus on the AST in the function bar() section:
It is no longer a VariableDeclaration, but an ExpressionStatement. So when we execute bar, we first assign 3 to the global variable a according to the context order, and find the global variable A = 3 through foo, and print 3. Local variables modify global variables, resulting in variable contamination. This code can also be thought of as declaring a again in the function bar() scope and assigning 3 to a. The var declaration has no concept of block scope, resulting in the creation of a variable in the global scope. As shown in the figure:
This a = 3 is mysterious! Let me verify for an hour what it is, still can’t come to a conclusion..
REF: Lexical Scope:
Stackoverflow.com/questions/1…
Howtonode.org/what-is-thi…
www.gnu.org/software/gu…
Wiki.c2.com/?LexicalSco…
Wiki.c2.com/?DynamicSco…