Scope and Scope Chain

Usually, the names used in a section of program code are not always valid or available, and the code scope that limits the availability of a name is called the scope scope. When a method or member is declared, it has the current execution context context environment, and within a specific value context, expressions are visible and can be referenced. If a variable or other expression is not in the current scope, it cannot be used. Scopes can also be hierarchically layered based on the code level, so that a child scope can access a parent scope. It usually refers to searching along the chain of scope and not being able to reference variables and references from a child scope in the parent scope.

Scope

JavaScript scope is static scope static scope, also known as lexical scope lexical scope. Its main feature is that, when encountered in a function scope, if it is neither a parameter nor a locally defined variable in the function, it looks up in the context when the function is defined. In contrast, dynamic scope dynamic scope is different. When encountered in a function scope, if it is neither a parameter nor a locally defined variable in the function, it looks up in the context when the function is called.

var a = 1;
var s = function(){
    console.log(a);
};

(function(){
    var a = 2;
    s(); // 1
})();

Calling s() prints a as 1, which is static scope, meaning that the scope is determined at declaration time. In the case of dynamic scope, 2 would be printed here. Nowadays, most languages use static scope, such as C, C++, Java, PHP, Python, etc., while languages with dynamic scope include Emacs Lisp, Common Lisp, Perl, etc.

Global Scope

Variables or methods declared directly at the top level run in the global scope. The scope can be viewed by using the function's [[Scopes]] property, which holds the function's scope chain and is an internal property of the function that cannot be directly accessed but can be printed to view.

function s(){}
console.dir(s);
/*
  ...
  [[Scopes]]: Scopes[1]
    0: Global ...
*/
// We can see that the declared s function runs in the global scope context

Function Scope

After declaring a function, the running environment for methods or members declared within the function is the function's function scope.

(function localContext(){
    var a = 1;
    function s(){ return a; }
    console.dir(s);
})();
/*
  ...
  [[Scopes]]: Scopes[2]
    0: Closure (localContext) {a: 1}
    1: Global ...
*/
// We can see that the declared s function runs in the context of the localContext function's scope, also known as the local scope

Block Scope

If there is let or const within a code block, the block will form a closed scope for the variables declared with these commands from the beginning of the block.

{
    let a = 1;
    function s(){return a;}
    console.dir(s);
    /*
      ...
      [[Scopes]]: Scopes[2]
        0: Block {a: 1}
        1: Global ...
    */
}
// We can see that the declared s function runs in the context of the Block block scope, which is also a local scope

Scope Chain

var a = 1;
(function s(){
    var a = 2;
    console.log(a); // 2
})();
console.log(a); // 1
var a = 1;
function localContext() {
    var b = 2;
    function localContext2() {
        var c = 3;
        {
            let d = 4;
            function s() { return a + b + c + d; }
            console.dir(s);
            /*
              ...
              [[Scopes]]: Scopes[4]
                0: Block (localContext2) {d: 4}
                1: Closure (localContext2) {c: 3}
                2: Closure (localContext) {b: 2}
                3: Global ...
            */
        }
    }
    localContext2();
}
localContext();

You can see the scope chain of s through [[Scopes]]. When we use d in s, if the parameter or local variable d does not exist in s, it will look up in the [[Scopes]]. It finds the value when it reaches the Block scope, and it gets the value of d. The same principle applies when using c, b, and a, where it looks up the scope chain to localContext2, localContext, and Global scope, respectively. In summary, when a function or variable needs to be used and the value is not found in the current scope, it will look up in the parent scope until it reaches the global scope. This chain formed by the lookup process is called a scope chain.

Closures: https://github.com/WindrunnerMax/EveryDay/blob/master/JavaScript/JavaScript%E9%97%AD%E5%8C%85.md let and const: https://github.com/WindrunnerMax/EveryDay/blob/master/JavaScript/let%E4%B8%8Econst.md

Daily Question

https://github.com/WindrunnerMax/EveryDay

References

https://www.jianshu.com/p/a198dce5d523 https://www.cnblogs.com/gaosirs/p/10579059.html