Understanding Javascript scopes and variables in depth _ javascript tips-js tutorial

Source: Internet
Author: User
This article mainly analyzes and introduces the Javascript scope and variable promotion in detail. If you need a friend, please refer to it and hope to help you. What is the result of the following program?

The Code is as follows:


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


The result is 10;

What about the following?

The Code is as follows:


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:

The Code is as follows:


# Include
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:

The Code is as follows:


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:

The Code is as follows:


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)

• 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:

The Code is as follows:


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


It will be interpreted:

The Code is as follows:


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:

The Code is as follows:


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:

The Code is as follows:


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.

The Code is as follows:


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:

The Code is as follows:


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.

Supplemented by translators

A friend reminded me that I found the problem of improving the name function in the global scope of IE:

I tested this when translating articles:

The Code is as follows:


Script
Functiont (){
Spam ();
Var baz = function spam () {alert ('this is spam ')};
}
T ();
Script


This method is used to improve the naming function in non-global scope. It is consistent in ie and ff. I changed it:

The Code is as follows:


Script
Spam ();
Var baz = function spam () {alert ('this is spam ')};
Script


In ie, spam can be executed, but not in ff. It indicates that different browsers have different processing details.

This problem also leads me to think about the other two problems. 1: For variables that apply globally to the range, var differs from non-var variables. without var writing, its variables will not be promoted. For example, in the following two programs, the second will report an error:

The Code is as follows:


Script
Alert ();
Var a = 1;
Script


The Code is as follows:


Script
Alert ();
A = 1;
Script


2: The local variables created in eval will not be upgraded (it cannot do it ).

The Code is as follows:


Script
Var a = 1;
Function t (){
Alert ();
Eval ('var a = 2 ');
Alert ();
}
T ();
Alert ();
Script

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.