Deep understanding of JavaScript advanced lexical scope and scope chain _ basics

Source: Internet
Author: User
Tags variable scope subdomain

Main content:
1, analyze the meaning of JavaScript lexical scope

2. The scope chain of analytic variables

3. What is the name of the variable?

In a recent lecture on JavaScript on the podcast, many friends feel that JavaScript is so simple, but I don't know how to use it, so I have some content for you to share.
This series focuses on the content of the advanced part of JavaScript, including scope chains, closures, function call patterns, prototypes, and object-oriented things. Here does not contain the basic JavaScript syntax, if you need to understand the basics of the students can go to http://net.itcast.cn inside to download free video to learn. Well, the nonsense is not much to say, directly into our business.

First, about block-level scopes
When it comes to JavaScript, the variable scope is different from the class C we normally use.
For example, the following code in C #:

Copy Code code as follows:

static void Main (string[] args)
{
if (true)
{
int num = 10;
}
System.Console.WriteLine (num);
}

This code cannot be passed if compiled, because name Num does not exist in the current context. Because here
The scope of a variable is defined by curly braces, called block-level scopes.

Under block-level scopes, all variables are within the curly braces defined, starting at the beginning of the definition and closing the curly braces.
Can be used in the range. Out of this range will not be accessible. Which means the code

Copy Code code as follows:

if (true)
{
int num = 10;
System.Console.WriteLine (num);
}

This can be accessed because the definition of the variable is in the same curly bracket as the one used.

In JavaScript, however, there is no block-level scoping concept in JavaScript.

Ii. scope in JavaScript
In JavaScript, the following code:

Copy Code code as follows:

if (true) {
var num = 10;
}
alert (num);

The result of the operation is the window 10. So how does the scope of variables in JavaScript qualify?

2.1 Function Qualifying Variable scope
In JavaScript, only functions can limit the scope of a variable. What does that mean?
That is, in JavaScript, variables defined within a function can be accessed within a function, but outside the function
cannot be accessed. Look at the following code:

Copy Code code as follows:

var func = function () {
var num = 10;
};
try {
alert (num);
catch (e) {
Alert (e);
}

When this code is run, an exception is thrown, and the variable num is undefined. In other words, variables defined in a function cannot
Used outside of a function, of course, can be used freely within a function, even before assigning a value. Look at the following code:

Copy Code code as follows:

var func = function () {
alert (num);
var num = 10;
alert (num);
};
try {
Func ();
catch (e) {
Alert (e);
}

After this code runs, it will not throw errors, the window two times, respectively, are undefined and 10 (as for why, explained below).

It can be seen from here that variables can be accessed only in functions. Similarly, a function in this function can also be accessed.


2.2 Subdomain Access Parent domain
As mentioned earlier, a function can qualify the scope of a variable, then a function in a function becomes a subdomain of that scope. In a child domain
The code in can access variables in the parent domain. Look at the following code:

Copy Code code as follows:

var func = function () {
var num = 10;
var sub_func = function () {
alert (num);
};
Sub_func ();
};
Func ();

The result of this code execution is 10. You can see the variable access described above. However, access to the parent domain in the subdomain
The code is also conditional. Like the following code:

Copy Code code as follows:

var func = function () {
var num = 10;
var sub_func = function () {
var num = 20;
alert (num);
};
Sub_func ();
};
Func ();

This code is more than the previous one "var num = 20;", the code in the subdomain, then the child domain access to the parent domains are
Has changed, the result of this code printing is 20. That is, the NUM that the subdomain accesses is the variable in the child domain, not the parent domain.

This shows that the visit has certain rules to say. Using variables in JavaScript, the JavaScript interpreter starts at the current
Search the domain for the definition of the variable, and if so, use the variable; if not, look for the variable in the parent domain.
And so on, until the top-most scope, still not found, throws an exception "variable undefined". Look at the following code:

Copy Code code as follows:

(function () {
var num = 10;
(function () {
var num = 20;
(function () {
alert (num);
})()
})();
})();

This code prints out 20 after execution. If the "var num = 20;" Remove, then the print is 10. Again, if you remove
' var num = 10 ', an undefined error occurs.

Iii. Scope Chain
With the scoping of JavaScript, you can connect JavaScript's access scope to a chain-like tree structure.
Once the scope chain of JavaScript is clearly understood, the variables and closures for JavaScript are very clear.
The following drawing method is used to draw the scope chain.

3.1 Drawing rules:
1 Scope chain is an array of objects
2 script is a 0-level chain, each object occupies a position
3 General See function Extension of a chain out, first level expansion
4 Access first look at the current function, if not defined go to the top level chain check
5 so reciprocating until the level 0 chain

3.2 Examples
Look at the following code:

Copy Code code as follows:

var num = 10;
var func1 = function () {
var num = 20;
var func2 = function () {
var num = 30;
alert (num);
};
Func2 ();
};
var func2 = function () {
var num = 20;
var func3 = function () {
alert (num);
};
Func3 ();
};
Func1 ();
Func2 ();

The following is an analysis of this code:
-> first the whole piece of code is a global scope that can be labeled as a 0-magnitude scope chain, so there's an array
var link_0 = [num, func1, Func2];//here in pseudo code description
-> here func1 and Func2 are functions, so they lead to two 1-level scope chains, respectively
var link_1 = {func1: [num, Func2]};//here in pseudo code description
var link_1 = {func2: [num, func3]};//here in pseudo code description
-> the first 1-level chain derived 2-level chain
var link_2 = {func2: [num]};//here in pseudo code description
-> The second 1 chain does not define a variable, is an empty chain, which is represented as
var link_2 = {func3: []};
-> The above code, you can represent the scope chain as:

Copy Code code as follows:

This is described in pseudo code
var link = [//0 level chain
Num
{func1: [//The first 1-level chain
Num
{FUNC2: [//2-level chain
Num
] }
]},
{FUNC2: [//second Level 1 chain]
Num
{func3: []}
]}
];

-> is represented by an image as

Figure: 01_01 scope chain. bmp

Note: The chain of the graph with the JS code to show, and then highlighted the time is very clear.

With the graph of the scope chain, it's very clear how the access variable works:
When you need to use a variable, first look for the variable on the current chain, and if you find it, use it directly, not
Look up and, if not found, go up the first-level scope chain until the level 0 scope chain.


If you can very clearly determine the level of the scope chain to which the variable belongs, then in the analysis JavaScript
Code is very easy (at least I am) when it comes to advanced JavaScript features such as closures.

Third, variable name promotion and function name promotion

With access rules for scope chains and variables, there is a very tricky problem. First look down.
The JavaScript code:

Copy Code code as follows:

var num = 10;
var func = function () {
alert (num);
var num = 20;
alert (num);
};
Func ();

What will be the result of the execution? You can think about it, I will not reveal the answer first.

Let's take a look at this piece of code first.
This code contains a 0-level scope chain with member Num and func. It's a 1-level action under Func.
Domain chain, with member Num inside. Therefore, when the function is called, the Func is detected in the current scope
The variable num is defined, so the variable is used. However, NUM is not assigned a value at this time because the generation
The code is run from the top down. So the first print is undefined, and the second one is 20.
You got the right answer?

The code is defined like this in the back, and the previous use is common in JavaScript
Problem. As if the variable had been defined at the outset, the result would be like the following code:

Copy Code code as follows:

var num = 10;
var func = function () {
var num; It feels like it's already defined here, but it's not assigned the same value.
alert (num);
var num = 20;
alert (num);
};
Func ();

This phenomenon is often referred to as variable name elevation. There is also a function name elevation that said. Like the following code:

Copy Code code as follows:

var func = function () {
Alert ("Call outside function");
};
var foo = function () {
Func ();

var func = function () {
Alert ("Call internal function");
};

Func ();
};

Okay, what's the result of this code? Or what should be different, I do not say that I do not keep the reader to think about it!
The next one will be answered.

Because of these differences, it is recommended that the variables be written at the beginning, when they are actually developed,
That is, the variable is defined at the beginning of the function, similar to the C language rule. This is also in the JS Library
That's how it's done, such as jquery.

Iv. Summary

All right, this article is mainly about how the lexical scope of JavaScript is going on, and explaining
How to analyze the scope chain, and variable access, and finally leave another practice to finish it!!!

Look at the following code execution results:

Copy Code code as follows:

if (! "A" in window) {
var a = "define variable";
}
alert (a);

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.