Javascript scope and variable upgrade

Source: Internet
Author: User

What is the result of the following program?

Var foo = 1;
Function bar (){
If (! Foo ){
Var foo = 10;
}
Alert (foo );
}
Bar ();

The result is 10;

 

What about the following?

Var a = 1;
Function B (){
A = 10;
Return;
Function (){}
}
B ();
Alert ();

The result is 1.

 

Are you shocked? What happened? This may be unfamiliar, dangerous, and confusing. In fact, it is also a very useful and impressive javascript language feature. I don't know whether there is a standard title for this kind of behavior, but I like this term: "Hoisting (variable escalation )". This article will introduce this mechanism, but first let us have some necessary understanding of the javascript scope.

Javascript Scope
For beginners of Javascript, the most confusing thing is the scope. In fact, it is not just for beginners. I have seen some experienced javascript programmers, but they have little understanding of scope. The javascript scope is confusing because its program syntax is long like a C family language, like the following C program:

 
# Include <stdio. h>
Int main (){
Int x = 1;
Printf ("% d,", x); // 1
If (1 ){
Int x = 2;
Printf ("% d,", x); // 2
}
Printf ("% d \ n", x); // 1
}

The output result is 1 2 1. This is because the C family language has a block scope. When the program is controlled into a block, for example, if blocks, variables that only act on the block can be declared, it does not affect the scope of the block. But in Javascript, this does not work. Take a look at the following code:

 
Var x = 1;
Console. log (x); // 1
If (true ){
Var x = 2;
Console. log (x); // 2
}
Console. log (x); // 2

The result is 1 2 2. Because javascript is a function scope. This is the biggest difference from the c family. If in the program does not create a new scope.

 

For many C, c ++, and java programmers, this is not what they expect and welcome. Fortunately, the flexibility of javascript-based functions is flexible. If you must create a temporary scope, you can do the following:

 
Function foo (){
Var x = 1;
If (x ){
(Function (){
Var x = 2;
// Some other code
}());
}
// X is still 1.
}

This method is flexible and can be used wherever you want to create a temporary scope. It is not just a block. However, I strongly recommend that you take some time to understand the javascript scope. It is useful and is one of my favorite javascript features. If you understand the scope, the variable upgrade will be more meaningful to you.

 

Variable declaration, naming, and elevation
In javascript, there are four basic methods for variables to enter the scope:

1 Language built-in: this and arguments are available in all scopes; (Note: the global scope of arguments is invisible after testing)
2. Form parameters: the form parameters of a function are part of the function scope;
3 function declaration: function foo (){};
4 variable Declaration: Like this: var foo;
The function declaration and variable declaration will always be quietly "promoted" to the top of the method body by the interpreter. This means, like the following code:

 
Function foo (){
Bar ();
Var x = 1;
}

It will be interpreted:

 
Function foo (){
Var x;
Bar ();
X = 1;
}

Whether or not the block that defines the variable can be executed. The following two functions are actually one thing:

 
Function foo (){
If (false ){
Var x = 1;
}
Return;
Var y = 1;
}
Function foo (){
Var x, y;
If (false ){
X = 1;
}
Return;
Y = 1;
}

Note that the variable assignment is not promoted, but the Declaration is promoted. However, the declaration of the function is a little different, and the function body will be upgraded together. However, note that there are two methods to declare a function:

 
Function test (){
Foo (); // TypeError "foo is not a function"
Bar (); // "this will run! "
Var foo = function () {// variable pointing to function expression
Alert ("this won't run! ");
}
Function bar () {// function declaration function Name bar
Alert ("this will run! ");
}
}
Test ();

In this example, only functional declarations are promoted together with the function body. The declaration of foo will be promoted, but the function body to which it points will only be assigned a value during execution.

 

The above things cover some basic knowledge of improvement, and they do not seem so confused. However, in some special scenarios, there is still a certain degree of complexity.

Variable parsing Sequence
The most important thing to remember is the variable parsing sequence. Do you remember the four methods I mentioned earlier to enter the scope? The order in which variables are parsed is the order listed by me. Generally, if a name has been defined, it will not be overwritten by other attributes with the same name. The declaration of a function has a higher priority than that of a variable declaration. This does not mean that the variable value is useless, but the Declaration will not be ignored. (Note: the declaration of a function has a higher priority than the declaration of a variable. The following program can help you understand)

 
<Script>
Function (){
}
Var;
Alert (a); // print the function body of.
</Script>
 
<Script>
 
Var;
Function (){
}
Alert (a); // print the function body of.
</Script>
// Note the difference between the two statements below:
<Script>
Var a = 1;
Function (){
}
Alert (a); // print out 1
</Script>
 
<Script>
Function (){
}
 
Var a = 1;
 
Alert (a); // print out 1
</Script>


There are three exceptions:
1 The built-in name arguments is very strange. It looks like it should be declared after the function form parameter, but before the function declaration. This means that if the parameter contains arguments, it has a higher priority than the built-in parameter. This is a bad feature, so it is necessary to prevent the use of arguments in the form parameter;
2. syntax errors occur when this variable is defined anywhere. this is a good feature;
3 if multiple form parameters have the same name, the last one has a priority, even if its value is undefined during actual operation;

 

Naming Functions
You can give a function a name. In this case, it is not a function declaration. At the same time, the specified function name in the function body definition (if any, the following spam, Translator's note) will not be upgraded, but is ignored. Here are some code to help you understand:

 
Foo (); // TypeError "foo is not a function"
Bar (); // valid
Baz (); // TypeError "baz is not a function"
Spam (); // ReferenceError "spam is not defined"
 
Var foo = function () {}; // foo points to an anonymous function
Function bar () {}; // function declaration
Var baz = function spam () {}; // name function. Only baz is promoted and spam is not promoted.
 
Foo (); // valid
Bar (); // valid
Baz (); // valid
Spam (); // ReferenceError "spam is not defined"

 

How to write code
Now that you understand the scope and variable upgrade, what does this mean for javascript encoding? The most important thing is that you always use var to define your variables. I strongly recommend that for a name, there will always be only one var declaration in one scope. If you do this, you will not encounter problems with scope and variable upgrade.

What are language specifications?
I found that the ECMAScript reference document is always useful. The following section describes how to improve the scope and variables:
If the variable is declared in the function body class, it is the function scope. Otherwise, it is a global scope (as a global attribute ). The variable will be created when the execution enters the scope. The block does not define a new scope. Only the function Declaration and Program (the translator thinks that it is a global code execution) will create a new scope. The variable is initialized to undefined when it is created. If the variable declaration statement contains a value assignment operation, the value assignment operation only occurs when it is executed, rather than when it is created.

I hope this article will bring a glimmer of light to programmers who are confused with javascript. I also try my best to avoid more confusion. If I say something wrong or ignore it, please let me know.

 

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.