JS scope and scope chain concept understanding and use _ basic knowledge

Source: Internet
Author: User
Tags anonymous closure function definition

(1) Scope

The scope of a variable is the region of the variable that is defined in the program's source code.

1. The lexical scope is used in JS (lexical scope)

A variable that is not declared within any function (which is also considered global for omitting var within a function) is called a global variable (scope)
A variable declared within a function has a functional scope (function scope) and belongs to a local variable

Local variable priority is higher than global variable

var name= "one";
function test () {
 var name= "two";
 Console.log (name); Two
}
test ();

If you omit Var within a function, it affects the global variable, because it is actually rewritten 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 scopes like C + +, such as if for

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 the Name=

Of course, JS also used in the higher-order function, in fact, can be understood as nested functions

function Test1 () {
 var name = ' One ';
 return function () {
  console.log (name);
 }
}
Test1 () ();

Test1 () then calls the outer function, returns an inner function, continues (), executes the inner function on the corresponding call, and outputs "one"
Nested functions involve closures, which are discussed later. Here the inner function can access the variable name declared in the outer function, which involves the scope chain mechanism

2. JS declaration in advance

The function scope in JS refers to all variables declared within a function that are always visible in the function body. Also, the variable can be used before the declaration, which is called the Declaration of Advance (hoisting)
Tip: The declaration was made in advance of the JS engine precompiled, and before the code was executed there was a statement that the earlier phenomenon produced

Like what

var name= "one";
function test () {
 console.log (name);//undefined
 var name= "two";
 Console.log (name); Two
}

test ();

The top has the following effect

var name= "one";
function test () {
 var name;
 Console.log (name); Undefined
 name= "two";
 Console.log (name); Two
}

test ();

Try to get rid of Var again? This is the name within the function that has become 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 should be noted that none of the above mentioned parameters, and if the test has parameters, then what?

function test (name) {
 console.log (name);//one
 name= "two";
 Console.log (name); Two
}

var name = "One";
Test (name);
Console.log (name); One

As I said before, the base type is passed by value, so the name passed in test is actually just a copy, and the copy is cleared after the function returns.
Do not think that the name= "two" in the function modifies the global name because they are two separate name

(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 an associated scope chain (scope chain).

The scope chain is a list of objects or lists of objects that define the variables in the scope in this code.

When JS needs to find the value of the variable x (this process is called variable resolution (variable resolution)), it starts looking from the first object in the chain, and if the object has a property named X, it will use the value of the property directly, if there is no property named X in the first object, JS will continue to find the next object on the chain. If the second object still does not have a property named X, it continues to find the next one, and so on. If no object on the scope chain contains an attribute x, it is assumed that there is no X on the scope chain of the code and eventually throws a reference error (REFERENCEERROR) exception.

2. Scope Chain Example:

In the top-most code of JS (that is, not including code within any function definition), the scope chain consists of a global object.

In the body that contains no nested functions, there are two objects on the scope chain, the first is the object that defines the function arguments and local variables, and the second is the global object.

In a nested function body, there are at least three objects on the scope.

3. Scope Chain Creation rules:

When a function is defined (note, 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 arguments or local variables, and adds the object to that scope chain, while creating a new, longer "chain" that represents the scope of the function invocation.

For nested functions, the situation has changed: the internal function is redefined each time an external function is invoked. Because each time the external function is invoked, the scope chain is different. Internal functions are subtly different each time they are defined---each time an external function is invoked, the code for the intrinsic function is the same, and the scope chain of the associated code is different.

(Tip: The above three points to understand well, remember, it is best to be able to use their own words out, or on the back, because the interviewer directly asked you: Please describe the scope chain ...)

A practical example of a scope chain:

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 top is a nested function, corresponding to three objects on the scope chain
So, when you call, you need to look up the value of name, and you'll find it on the scope chain.

When the Test1 () is successfully invoked, the order is test1 ()->test ()-> the Global Object window because the name value test1 is found on three (), so the search returns
When the Test1 () is successfully invoked, the order is test2 ()->test ()-> the Global Object window because the name value is not found on test2 (), so find the value two of name in Test () and complete the search return

Another example is that sometimes we make mistakes and often get cheated in the interview.

<! DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 transitional//en" "Http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
 
 

Why?
According to the search rules for variables in the scope chain:

B.addeventlistener ("click", Function () { 
      Alert ("button" +i);
    },false);

Here's a function, which is an anonymous function, and since it's a function, it has an object on the scope chain, which uses the variable I, which naturally looks for it on the scope.
The lookup order is the function--> external to this anonymous function buttoninit ()--> Global Object window

I was not found in the anonymous function, naturally ran to the Buttoninit (), OK, found in the for,

At this point the registration event is over, do not think it will be one to put I down, because variables within the scope of the function is always visible within the scope, that is, will remain in the final state

When the anonymous function to use I, the registration event is over, I has become 4, so it is Button4

So how do we solve it?

Give it a value to go in, each loop, and then use an anonymous function, the for inside of the I pass in, anonymous function rules such as code

<! DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 transitional//en" "Http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">
 
 

So you can Button1. 2..3.

4. The above is the basic description of the scope chain, in addition, the WITH statement can be used to temporarily extend the scope chain (not recommended with)

Grammatical form:

With (object)

Statement

This with statement, adds object to the head of the scope chain, executes statement, and finally restores the scope chain to its original state

Simple usage:

For example, assign values to the values of each item in a form

Normally, we can do this directly.

var f = document.forms[0];
F.name.value = "";
F.age.value = "";
F.email.value = "";

With the introduction of the with (because using with has a series of problems, so use the form above)

With (Document.forms[0]) {
f.name.value = "";
F.age.value = "";
F.email.value = "";
}

In addition, if an object o has an x attribute, o.x = 1;
Then use

With (o) {
 x = 2;
}

can be converted into o.x = 2;
If o does not define attribute X, its function is just equal to x = 2; A global variable.

Because with provides a shortcut to read the properties of O, he does not create an attribute that is not in the O itself.

To understand the scope of a variable, you have to understand the chain of scopes first.
when you declare a variable with the var keyword, you add a property to the object that contains the variable.
Scope chain: Because the variables of JS are the properties of the object, and the object may be the property of other objects, and all objects are properties of the Window object, the relationship of these objects can be considered as a chain
The chain is the object where the variable is, and the end of the chain is the Window object

Look at the following code:

Copy Code code as follows:

function T () {
var A;
Function T2 () {
var b;
}
}

JS in the function is also an object, so the object of variable A is t,t and in the Window object, so a scope chain is as follows
T--window
So B so in the object that is t2,t2 and included in T, T again in the Window object, so B's scope chain is as follows
T2--t--window
It's clear. The scope analysis of the starting variable under the scoping chain
1 JavaScript variables with no var are global variables and are properties of the Window object
Copy Code code as follows:

function Test1 () {
When executing this sentence, it will find the scope object, which is the first object in the scope chain, but there are no related var statements in this object
Uri the second object in the scope chain, the global object, and there is no associated VAR statement in the Global object
Because there is no related VAR statement, JS implicitly declares the variable var all in function.
all = 30;
alert (all);
}
Test1 ();
alert (all);
alert (Window.all);

2 variables defined within a function (except functions within a function) are valid within the entire function
Copy Code code as follows:

function Test2 () {
var t = 0;
To define a variable in the condition of for, the scope chain object of this change is this function
So it works in the whole function.
for (var i = 0; i < 5; i++) {
T + = i;
}
alert (i);
}
Test2 ();

3 variables inside the function replace the global variable of the same name
Copy Code code as follows:

var t = "BB";
function Test () {
When executing T, it will first find the scope chain object, because it is defined inside the function, so this function is the first object of its scope chain
And in this object there is the definition of T, so t is a local variable, it replaces the global variable T
T is only defined at this time, but is not assigned a value, the assignment is on the next line, so here is the output of the undefined
Alert (t);
var t = "AA";
Alert (t);
}
Test ();

4 Scope of No blocks
Copy Code code as follows:

if (true) {
A variable is defined in the block, and the first object in its scope chain is the Global object window
var tmp = 0;
}
The first object in the scope chain of TMP is the Global Object window, which has the associated VAR statement in the global object, so output 0
Alert (TMP);


The following content from Reading online blog summary, when the use of notes, only remember the key, but also very grateful to share the bloggers, you let me stand on the shoulders of giants!
1,
Copy Code code as follows:

var temp = (function () {
var name = "Test";
return function () {
alert (name);
}
})();

The above code fragment is our jser often see the writing, is the legendary closure. As we all know: Calling Temp () pops up "test", which can be explained by the following three theories:

1 JS scope is only related to the definition of function, function and function nesting form the scope chain;
2 The rule of the scope chain is to copy the scope chain of the upper layer of environment, and put the pointer to the object of the environment variable to the top of the chain;
3 in JavaScript, if an object is no longer referenced, the object is collected by GC. If two objects are referenced to each other and are no longer referenced by the 3rd, then the two referenced objects are also reclaimed.

If you look at the above 3 are not clear, you can see the following combination of the theory of the detailed code explanation:
The outer function is first executed and destroyed, but the scope chain of the outer function is copied into the scope chain of the inner function. Part of the scope chain that makes up the inner function, remember to copy, not reference (according to 2nd), so the inner function can still access to name, because the returned inner function is referenced by temp. So when the outer function is destroyed, the inner function, though as part of the outer function, still exists, as the 3rd basis, it is referenced by a third party; the legendary closure is the reason.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.