JS Basics: Closures and Scope Chains

Introduction

  A function defined inside a function forms a closure with the outer function that contains it. The inner function can access the variables of the outer function, and these variables will remain in memory until the inner function can no longer be referenced.

E.g:

var a = 0 ;
function outerFun (i) {
     var b = i;
    function innerFun (j) {
         var c = j;
        console.log( "Global variable: "+ a);
        console.log( "External variable: "+ b);
        console.log( "Internal variable: "+ c);
        a++;
        b++;
        c++;
    }
    return innerFun;
}
var testFun1 = outerFun (10 );
testFun1(10); // Global variable: 0 External variable: 10 Internal variable: 10 
testFun1(10); // Global variable: 1 External variable: 11 Internal variable: 10

var testFun2 = outerFun (20 );
testFun2(20); // Global variable: 2 External variable: 20 Internal variable: 20 
testFun2(20); // Global variable: 3 External variable: 21 Internal variable: 20

in conclusion:

c is the local variable of innerFun(), it will be reassigned every time innerFun() is executed;
b is the upper-level variable of innerFun(), the result of each execution of innerFun() will be saved in memory, which is the local of outerFun() Variable, it will be reassigned every time outerFun() is executed;
a is the upper-level variable of innerFun(), the result of each execution of innerFun() will be saved in memory, and it is the upper-level variable of outerFun(), each time The result of executing outerFun() is also stored in memory;

  In JavaScript, there are only two scopes: the global scope and the function-level scope. In the lower-level scope, you can access and modify the variables of the upper-level scope. When a function is defined, JS will automatically maintain a scope chain. The current local scope is at the top of the scope chain and can be traced back in sequence. The essence of closures is to extend the scope chain.

variable lifetime

  As mentioned above, there are only two types of global variables and function-level local variables in js. Of course, the life cycle of global variables is permanent unless we actively destroy the global variables. For local variables declared with the var keyword in a function, when the function is exited, these local variables lose their value, and they will be destroyed with the end of the function call.

E.g:

// The page has 5 divs, expect to click on each div to output its serial number 
for ( var i=0; i<5; i++ ) {
    $('div').eq(i).on('click',function() {
        console.log(i);
    })
}

However, in fact, clicking on each div outputs 5. This is because i is a global variable and is at the top of the scope chain. When the value of i is changed, all functions that reference it will be affected. When the loop After the run, the final value of i is 5, so of course the output of each div is 5. At this time, we can extend the scope chain through the closure, and save a copy of the value of i so that they do not affect each other.

E.g:

for(var i=0; i<5; i++) {
    function outerFun() {
        var j = i;
        function innerFun() {
            $('div').eq(j).on('click',function() {
                console.log(j);
            })
        }
        innerFun ();
    }
    outerFun();
}

Both outerFun() and innerFun() can be replaced by anonymous self-executing functions, for example:

for(var i=0; i<5; i++) {
    ( function () {
         var j = i;
        (function() {
            $('div').eq(j).on('click',function() {
                console.log(j);
            })
        })();
    })();
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325501352&siteId=291194637