My last blog title is wrong, causing some misunderstanding. I think the purpose of blogging is not to recite textbooks, but to share research and development experience. My last title was changed to "one of the topics of JavaScript closures: its impact on outer scope" because I did not strictly analyze the definition of closures, but rather analyzed one of the semantic aspects of implementing closures.
It's a hassle to make clear about closures, and I don't see any authoritative work on javascript (like C + + programming language with Bjarne Stroustrup in C + + language). So in addition to studying the JavaScript language international standard "Standard ECMA-262 specification", I cannot recommend a "closure" of the best textbook.
Netizen "Mu Yi" of "scope chaining" indeed is relatively close to the essence, but also not comprehensive. I had no choice but to make a further attempt.
The implications of closures include the following three key concepts:
Lexical scope and scope Chain
The concept of lexical scope is not a javacript invention, but as part of a JavaScript function, it is an added value in the concept of "traditional" functions.
The lexical scope and runtime scope of traditional functions (c, C + +, Java, C #, etc.) are the same. The lexical scope of JavaScript refers to the "environment" when the function is defined, not the environment at which the function is run.
For a particular function, its "free variable" is the main content to be captured in this function closure. The lexical capture (capture) Order of the free variable (a variable not defined in this function) is (that is, the order of scope chaining):
A, the local variable of the parent function
B. Input argument of the parent function
C Repeat a,b in the parent function of the parent function until the topmost level (GLOBAL scope)
In the definition of the following myobj:
var x = 1000; Line 0
function myobj (x, y) {//Line1
THIS.FUNC1 = function () {//Line2
x + +;
Y--;
}
This.get1 = function ()
{
return x;
}
This.get2 = function ()
{
return y;
}
var x = 0; Line 3
}
MyObj.prototype.AddTwo = function (z)
{
return This.get1 () + this.get2 () + Z;
}
var m1 = new MyObj (10, 20); Line 4
var m2 = new MyObj (30, 70); Line 5
Console.log (' m1.x: ' + m1.get1 ()); Line 6
Console.log (' m1.y: ' + M1.get2 ()); Line 7
Console.log (' m2.x: ' + m2.get1 ()); Line 8
Console.log (' m2.y: ' + M2.get2 ()); Line 9
For the above example, if it is not lexical scope, line 6-line 9 should print 10, 20, 30, 70.
But because of the lexical scope capture sequence, X is 0 (see Line 3), so the print is: 0, 20, 0, 70.
Note out the line3, according to the capture sequence, printed on the 10, 20, 30, 70.
The MyObj (x, y) is changed to MyObj (Z, y), and the printed form is 1000, 20, 1000, 70. 1000 of them are captured from global (line 0).
Lexical capture was carried out in parsing stage.
The capture sequence above must be performed at the parsing stage of the function. The function's data structure contains all the "reference" of the capture variable after parsing, and the runtime does not change. This is why line 3 above defines the reason that can take precedence over input parameter x. If capture is executed, line 3 is after the definition of the function, the capture is said to be input parameter x.
compiler languages such as c,c++ are directly translated into native functions, and all function information is dynamically obtained by stack frame. The only concept that is close to the closure is the "whole variable (global variable)". These global variables are also converted to memory addresses at compile time, and the runtime can be "resolved in place" without a separate closure. These functions are not object and do not need to be dynamically generated, so there is no need for a "static" closure.
JavaScript needs a separate closure, I think because all JavaScript is object, can be "dynamically generated", but the definition (the first parsing) is static, the "static" part of the need for closure, the dynamic part of the same as the traditional functions, Rely on runtime context support.
This "complexity of implementation" is the cost of the convenience of dealing with asynchronous events, as a result of closures.
Lexical capture is reference, not value.
This is where my last blog wanted to emphasize. If the above myobj executes, if the capture is the value of x, then these three functions Func1,get1,get2 will not have any connection.
Because the capture is the reference of X, the above three functions see X is the same variable.
This is important because local variables in JavaScript are not all heap. At least GOOGLE V2 is not. But the X on line 3 must be "Born and live" in heap, otherwise Func1,get1,get2 would be working on the destroyed stack variable x, making the above program meaningless.
In other words, the runtime cost of closures is to transfer the closed-package variables from stack to heap.
Summarize
I think that only understand the closure of the appeal three concepts, can be in the closure of the application of an invincible.