“This is the first day of my participation in the First Challenge 2022. For details: First Challenge 2022”
What is scope
One of the most basic features of almost any programming language is the ability to store a value in a variable and access or modify that value later. In fact, it is this ability to store and access the value of a variable that brings state to the program. Without the concept of state, a program could perform some simple tasks, but it would be highly limited and not very interesting. These problems illustrate the need for a well-designed set of rules to store variables and make them easy to find later. This set of rules is called scope. That is, the scope is responsible for collecting and maintaining a series of queries made up of all declared identifiers (variables), with a set of rules that determine whether the currently executing code has access to those identifiers.
Lexical scope
Lexical scope is simply the scope of a definition at the lexical stage. What is the lexical stage? It is a step in code compilation where the compiler breaks the string into lexical units. A lexical unit is a block of code that makes sense to a programming language. Such as:
var name = "snail"
Copy the code
It is decomposed into var, name and snail.
Next comes the parsing phase, where these lexical units are converted into a hierarchical nested tree of elements representing the program’s syntactic structure. This Tree is called the Abstract Syntax Tree (AST). Finally, there is the code generation phase, where the AST is transformed into executable code.
So the lexical scope is determined by where you write the variable and block scope when you write the code.
Function scope
All variables belonging to this function can be used and reused within the scope of the whole function, or within nested child functions, if any. The rules for storing and accessing variables belonging to functions are called function scopes.
We imagine the scope of each function as a bubble, then the bubble corresponding to the scope of the inner sub-function is a small bubble within the current bubble, and the bubble of the current function scope is also contained in a larger bubble.
Block-level scope
Block-level scopes, as the name suggests, belong to the scope of a code block, but unfortunately, prior to ES6, there were no block-level scopes in JavaScript.
console.log('1',i) // undefined for(var i = 0; i<3; i++){} console.log('2',i) // 3Copy the code
Here we define the variable I in the for loop, but we only want to use I in the context of the inside of the for loop, but in JavaScript, the variable declared by var is bound to the outside scope, which is called variable promotion, and sometimes this can cause some trouble. For example, loop traps:
var result = []; for(var i = 0; i<10; i++){ result[i] = function(){ console.log(i) } } result[0](); // 10 result[1](); / / 10Copy the code
For example, variable override:
var name = 'snail'
if(true){
var name = 'running snail'
}
console.log(name) // running snail
Copy the code
Before ES6, the basic unit of variable scope was function scope, so when we needed to create a block scope, the most common method was to call function expressions (IIFE) immediately, in addition to plain function declarations. Such as:
var name = 'snail' ; (function(){ var name = 'running snail' console.log(name) // running snail })() console.log(name) // snailCopy the code
As a result of this problem, ES6 introduced let and const declarations. Variables declared by let and const are valid only within the current code block. So they actually add block-level scope to JavaScript.
console.log('1',i) // ReferenceError: i is not defined for(let i = 0; i<3; i++){}Copy the code
Dynamic scope
JavaScript doesn’t actually have dynamic scope; it only has lexical scope. Here’s why:
The difference between lexical scope and dynamic scope is that lexical scope is determined when code or variable definitions are written; Dynamic scopes are determined at run time;
Lexical scopes focus on where functions are declared, while dynamic scopes focus on where functions are invoked. And because JavaScript needs to be compiled and executed, it is lexical, not dynamic.
But this mechanism is a lot like dynamic scope. Because this is bound at run time, not at write time, its context depends on various conditions at the time the function is called. The binding of this has nothing to do with the position of the function declaration, except how the function is called.
The scope chain
Nesting of scopes occurs when a code block or function is nested within another code block or function. Therefore, when a variable cannot be found in the current scope, the engine will continue searching in the outer nested scope until it finds the variable or reaches the outermost scope (that is, the global scope). We regard each scope as a ring, and layer upon layer between scopes forms a chain, which is the scope chain.
Ok, this is the summary of scope related knowledge, you learn to waste? <( ̄)  ̄)>
If you have any questions or suggestions, please leave a comment! 👏 🏻 👏 🏻 👏 🏻