JavaScript function (3) - closure and scope

closure

concept

Only sub functions within a function can read local variables, so closures can be understood as "functions defined within a function.". In essence, a closure is a bridge connecting the interior and exterior of a function

Example

function outer(){
    var localVal = 30;
    return localVal;
}

outer();//30

function outer(){
    var localVal = 30;
    return function() {
        return localVal;
    }
}

var func = outer();
func();//30

Function: for example, to nest a function in a function, you can let the nested function access the local variables of the function wrapping it through the closure.

encapsulation

(function(){
    var _userId = 123;
    var _typeId = 'item';
    var export = {};
    
    function converter(userId){
        return + userId;
    }
    
    export.getUserId = function(){
        return converter(_userId);
    }
    
    export.getTypeId = function(){
        return _typeId;
    }
    window.export = export;
})();

export.getUserId();//123
export.getTypeId();//item

export._uerId;//undefined
export._typeId;//undefined
export.converter;//undefined

Closure trap

var tasks = [];

for (var i=0; i<3; i++) {
    tasks.push(function() {
        console.log('>>> ' + i);
    });
}

console.log('end for.');

for (var j=0; j<tasks.length; j++) {
    tasks[j]();
}

The output is all 3. The reason for this problem is that when the function is created, it is not executed, so end for., is printed first, and then the function is executed. Because the function references the loop variable i, and the scope of i is the whole function, not the loop, when the function is executed, the value of i has become 3.

Solution
Create another function and pass in the loop variable as a function parameter:

var tasks = [];

for (var i=0; i<3; i++) {
    var fn = function(n) {
        tasks.push(function() {
            console.log('>>> ' + n);
        });
    };
    fn(i);
}

//Simplify the syntax by using the immediate execution mode of anonymous functions (function() {...}) ()

var tasks = [];

for (var i=0; i<3; i++) {
    (function(n) {
       tasks.push(function() {
           console.log('>>> ' + n);
        });
    })(i);
}

summary

Advantages: flexible and convenient, encapsulation
Disadvantages: space waste, memory leak, performance consumption

Keywords: Javascript

Added by Buglish on Mon, 27 Jan 2020 17:37:50 +0200