The scope chain is because js variables are all attributes of objects, and this object may be attributes of other objects, and all objects are properties of window objects, therefore, the relationship between these objects can be considered as a chain.
(1) Scope
The scope of a variable is the region of the variable defined in the program source code.
1. lexical scope is used in JS)
Variables not declared in any function (if var is omitted in the function, it is also regarded as global)
A variable declared in a function has a function scope and is a local variable.
The priority of local variables is higher than that of global variables.
var name="one";function test(){ var name="two"; console.log(name); //two}test();
If var is omitted in the function, the global variable is affected because it has actually been overwritten as a global variable.
var name="one";function test(){ name="two"; }test();console.log(name); //two
Function scope, that is, a function is the basic unit of a scope. js does not have block-level scope like c/c ++, such as if.
Function test () {for (var I = 0; I <10; I ++) {if (I = 5) {var name = "one" ;}} console. log (name); // one} test (); // because it is a function-level scope, you can access name = "one"
Of course, higher-order functions are also used in js, which can be understood as nested functions.
function test1(){ var name = "one"; return function (){ console.log(name); }}test1()();
After test1 (), the outer function is called, an inner function is returned, and then () is continued, the inner function is called and executed accordingly, so "one" is output"
Nested functions involve closures, which will be discussed later. Here, the inner function can access the variable name declared in the outer function, which involves the scope chain mechanism.
2. Advance the Declaration in JS
The function scope in js indicates that all variables declared in the function are always visible in the function body. In addition, variables can be used before they are declared. This situation is called hoisting)
Tip: the Declaration is carried out in advance during the js engine pre-compilation, and the declaration has been made before the code is executed.
For example
var name="one";function test(){ console.log(name); //undefined var name="two"; console.log(name); //two}test();
The above shows the following results.
var name="one";function test(){ var name; console.log(name); //undefined name="two"; console.log(name); //two}test();
Try again to remove var? This is because the name in the function has been changed to a global variable, so it is no longer undefined.
var name="one";function test(){ console.log(name); //one name="two"; console.log(name); //two}test();
3. It is worth noting that none of the above mentioned parameters are passed. What if test has parameters?
function test(name){ console.log(name); //one name="two"; console.log(name); //two}var name = "one";test(name);console.log(name); // one
As mentioned before, the basic type is passed by value, so the name passed into test is actually a copy, and the copy is cleared after the function returns.
Do not change the global name for name = "two" in the function, because they are two independent names.
(2) Scope chain
The advanced functions mentioned above involve the scope chain.
function test1(){ var name = "one"; return function (){ console.log(name); }}test1()();
1. Introduce a large paragraph to explain:
Each js Code (Global Code or function) has a scope chain associated with it ).
This scope chain is a list of objects or a linked list. This group of objects defines the variables in the "scope" in this Code.
When js needs to find the value of variable x (this process is called variable resolution), it will start searching from the first object of the chain, if this object has an attribute named x, the value of this attribute is directly used. If the first object does not have an attribute named x, js will continue to search for the next object in the chain. If the second object still does not have the property named x, the next object will be searched, and so on. If no object in the scope chain contains attribute x, the Code does not have x in the scope chain, and a reference error (ReferenceError) is thrown.
2. Example of scope chain:
In the top-level JavaScript code (that is, the Code does not include any function definition), the scope chain is composed of a global object.
In a function that does not contain nesting, there are two objects in the scope chain. The first is the object that defines function parameters and local variables, and the second is the global object.
In a nested function, there are at least three objects in the scope.
3. Create a scope chain rule:
When defining a function (note that it starts when it is defined), it actually saves a scope chain.
When this function is called, it creates a new object to store its parameters or local variables, and adds the object to the scope chain, at the same time, create a new longer "chain" that represents the function call scope ".
For nested functions, the situation has changed: each time an external function is called, the internal function is redefined. Because each time an external function is called, The scope chain is different. Each time an internal function is defined, it requires a subtle difference-the code of the internal function is the same each time an external function is called, And the scope chain associated with this code is also different.
(Tip: I understand the above three points. Remember, I 'd better say it in my own words, or I will stick it back, because the interviewer will ask you directly: Please describe the scope chain ...)
A practical example of the scope chain is as follows:
var name="one";function test(){ var name="two"; function test1(){ var name="three"; console.log(name); //three } function test2(){ console.log(name); // two } test1(); test2();}test();
The above is a nested function, which corresponds to three objects in the scope chain.
In this case, you need to find the value of name in the scope chain.
When test1 () is successfully called, the sequence is test1 ()-> test ()-> Global Object window because the value of name three is found on test1, so return after completing the search
When test1 () is successfully called, the sequence is test2 ()-> test ()-> Global Object window because the name value is not found on test2, so find the two value of name in test (), and then complete the search and return.
Another example is that sometimes we make mistakes and often get cheated during interviews.