On scope and closure in JavaScript

  • 2020-07-21 06:52:51
  • OfStack

The scope of JavaScript is bounded by functions, and different functions have relatively independent scopes. Inside a function, global variables can be declared and accessed, or local variables can be declared (using the var keyword, the parameters of the function are also local variables), but internal local variables cannot be accessed outside the function:


function test() {
var a = 0; //  A local variable 
b = 1; //  The global variable 
}
a = ?, b = ? // a for undefined . b for 1

Local variables with the same name will overwrite global variables, but they are essentially two independent variables, the change of one square will not affect the other square:


a = 5; //  Outside the function a The value of 5
function test() {
var a = 4; //  Within the function a The value of 4
}();
a = ? //  Outside the function a The value of the still 5 It's not affected by the function 

In general, when a function is finished, all references to variables inside the function are finished, local variables inside the function are recovered, and the execution environment of the function is cleared. However, if the internal function is the return result of the function, the situation will change:


function test(i) {
var b = i * i;
return function() {
return b--;
};
}
var a = test(8);
a(); //  The return value is 64 .   Internal variables b for 63
a(); //  The return value is 63 .   Internal variables b for 62

When an inner function is returned, the local variable of the function cannot be recovered because the reference to the inner variable does not end after the function ends, and the execution environment of the function is preserved, thus creating a closure effect, through which the inner variable that should have been recovered can be accessed.
Closures also make the local variables of a function "private", accessible only by the inner function that is returned and not changed by any other means.
Therefore, closures can be used to maintain local variables and protect variables.
When closures are not used:


var a = []; //  Assuming that a Contained in the 5 An element 
for (var i = 0, m = a.length; i < m; i++) {
a[i].onclick = function(e) {
return 'No. ' + i;
};
}
//  Click on any 1 The return value of each element is" No. 5 "Because i The final value is zero 5
 When closures are used: 
function test(i) {
return function(e) {
return 'No. ' + i;
};
}
var a = []; //  Assuming that a Contained in the 5 An element 
for (var i = 0, m = a.length; i < m; i++) {
a[i].onclick = test(i);
}
//  Using closures to maintain local variables, click element Return No. 0 ~ No. 4

Along with the convenience of closures, there are a couple of drawbacks:
1, the program complexity increased, more difficult to understand
2, interfere with normal garbage collection, complex closures can also cause memory to fail to collect and crash
Large closures are often associated with performance issues
Therefore, closures should be compact rather than large and complex, and closures should be avoided on a large scale. Closures, as such, are an bug of the language, but they survive because of their unique functionality. It is an adjunct, not a primary function.


Related articles: