From: rainy.im
Links: http://blog.rainy.im/2015/07/04/scope-chain-and-prototype-chain-in-js/
This article attempts to illustrate the mechanisms behind context and scope in JavaScript, mainly related to the concepts of execution context (execution context), scope chain (scope chain), closure (closure), this, and so on.
Execution context
The execution context (referred to as context) determines which variables, functions, and data can be obtained during JS execution, a program may be split into many different contexts, each of which binds a variable object (variable object), which is like a container, Used to store all defined or available variables, functions, and so on in the current context. The context at the top or outermost is called the global context, and the global context depends on the execution environment, such as window in global and browser in node:
It is important to note that the context and scope (scope) are different concepts. JS itself is a single process, whenever a function is executed, it will produce a new context, the context will be pressed into the context stack of JS, the function executes after the completion of the popup, so the JS interpreter is always executed in the top of the stack. When a new context is generated, the variable object for that context is first bound, including arguments and the variables defined in the function, followed by a scope chain (scope chain) that belongs to the context, and finally this is given the object to which this function belongs. This process can be represented by:
This
As mentioned above, this is given to the object that the function belongs to, specifically, when function is defined in the global pair, this points to global; When function is the method of object, this points to the object:
var x = 1;
var f = function () {
Console.log (this.x);
}
f (); 1
var ff = function () {
This.x = 2;
Console.log (this.x);
}
FF (); 2
X///2
var o = {x: "O ' s X", f:f};
O.F (); "O ' s X"
Scope Chain
As mentioned earlier, when a function is executed, a new context is generated that binds the variable object of the current context before creating a scope chain. We know that the definition of a function can be nested within the context created by other function or in the same context (such as global) in a side-by-side context. A scope chain is essentially a bottom-up string of variable objects bound by the context of all nested definitions, so that nested functions can "inherit" variables from the upper context, while the parallel function does not interfere with each other:
var x = ' Global ';
function A () {
var x = "A ' s X";
Function B () {
var y = "B ' s Y";
Console.log (x);
};
b ();
}
Function C () {
var x = "C ' s X";
Function d () {
Console.log (y);
};
D ();
}
A (); "A ' s X"
C (); -Referenceerror:y is not defined
X//-"global"
Y//-referenceerror:y is not defined
Closure
If you understand the context and scope chain mechanisms mentioned above, then it is clear that the concept of closures. Each function creates a new context and scope chain at invocation, and the scope chain is the concatenation of variable objects bound by the outer (upper-layer) context, so that the current function can acquire variables, data, and so on in the outer context. If we define a new function in function and return the inner function as a value, the scope chain contained within the inner function will be returned together, even if the inner function is executed in another context. Its internal scope chain still maintains the original data, and the current context may not be able to get the data in the original outer function, so that the scope chain inside the function is protected to form a "closure." Look at the following example:
var x = 100;
var inc = function () {
var x = 0;
return function () {
Console.log (x + +);
};
};
var inc1 = Inc ();
var inc2 = Inc ();
Inc1 (); 0
Inc1 (); 1
INC2 (); 0
Inc1 (); 2
INC2 (); 1
X 100
The execution process, as shown, shows that the scope chain generated at the time of creation of the anonymous function returned by Inc includes The X in the Inc, even if it is subsequently assigned to INC1 and INC2, and the scope chain is still determined by the context in which the definition is located. , and because x is defined in function Inc, it cannot be changed by the outer global context to achieve closure effects:
This in closure
We have repeatedly mentioned that the execution context and scope are actually created and segmented by function, and this in function is different from the scope chain, which is determined by the object environment currently in place when the function is executed. This is also the one that is most easily confused with the wrong point. The general examples are as follows:
var name = "Global";
var o = {
Name: "O",
Getname:function () {
Return this.name
}
};
O.getname (); "O"
Since O.getname () is executed, this is the O that getName binds, so this = = O; more easily confused is under closure conditions:
var name = "Global";
var oo = {
Name: "Oo",
Getnamefunc:function () {
return function () {
return this.name;
};
}
}
Oo.getnamefunc () (); "Global"
At this point the closure function is called after the return call is equivalent to:
GetName = Oo.getnamefunc ();
GetName (); "Global"
For a more obvious example:
var ooo = {
Name: "Ooo",
GetName:oo.getNameFunc ()//This time the closure function's this is bound to the new object
};
Ooo.getname (); "Ooo"
Of course, sometimes in order to avoid being replaced by this in the closure, you can take the following approach:
var name = "Global";
var oooo = {
Name: "Ox4",
Getnamefunc:function () {
var = this;
return function () {
return self.name;
};
}
};
Oooo.getnamefunc () (); "Ox4"
Or, when invoked, enforces the definition of an object that executes:
var name = "Global";
var oo = {
Name: "Oo",
Getnamefunc:function () {
return function () {
return this.name;
};
}
}
Oo.getnamefunc () (); "Global"
Oo.getnamefunc (). bind (OO) (); "Oo"
Summarize
JS is a very interesting language, because it is a lot of features of the DOM in the HTML operation, so it seems arbitrary and slightly less rigorous, but with the development of the front-end and the rise of node, JS is no longer "toy language" or the "CSS extension" of the jquery era, The concepts mentioned in this article are easy to confuse or misunderstand, both for beginners and for JS developers who are over-developed from traditional web development, and hope this article will help.
The reason for this summary is that learn JavaScript in one I shared on GitHub was initially questioned as a grammar table (syntax cheat sheet) and would not involve deeper closures, scopes, etc. But unexpectedly, this project has won more than 3,000 star, so can not be a half-baked, above.
References
1.Understanding Scope and Context in JavaScript
2.this-javascript | MDN
3. Closures-JavaScript | MDN
Graphical JavaScript context and scope