JS Scoping and hoisting

Source: Internet
Author: User

Refer to this article

Http://www.jb51.net/article/30719.htm

var v='HelloWorld';(function () {    console.log (v);}) () Output: Hello World

But

var v='HelloWorld';(function () {    console.log (v);     var ' Hi ' ;}) () Output: undefined

This hides a trap-----variable elevation (hoisting) in JavaScript. In JS, it is the definition in the back of the east (variable or function) to the previous definition.

First look at the variable scope (scoping), not the same as C + + :

var 1  //  1if (true) {    var2;     // 2 }console.log (x); //

This is because:

block, just like the IF statement, does not create a new scope. Only the function creates a new scope.

If you have to create a temporary scope in the function, do this as follows:

var 1  if} ());  //

Variable elevation is simply the place where the variable is raised to the top of the function. What I need to make clear is that the variable promotion is just the declaration of the promoted variable and does not raise the assignment.

For example, we define three variables:

var a='one'var b='    var c='three'

In fact, it's like this:

var a,b,c; a='one'; b='one '; c= ' three '

This is the time to raise the variable.

function Promotion:

is to refer the whole function to the front.

When we write JS code, we have 2, one is the function expression, and the other is the function declaration method. It is important to note that only the function declaration form can be promoted.

The function declaration promotes the "success" code as follows: function MyTest () {foo (); function foo () {console.log (" I am from foo") ); }} myTest (); Result: I am from foo

Another type of function expression, you can't:

function expression promoted "failed" var foo =function foo () {console.log (" I come from foo");}} MyTest (); Result: foo ();     ^ is not a function

In addition, there are several examples in the following article

Http://www.jb51.net/article/30718.htm

Example one:

var 1 ; function bar () {    if (!  Foo) {        var;    }    Console.log (foo);} Bar (); Results:

But

var 1 ; function B () {    ten;     return ;    function A () {}}b (); Console.log (a); results:1

Also note that function A is commented out:

/**/var1; function B (    ) {ten;     return ;     // function A () {} }b (); Console.log (a);

Output:
10

It turns out that the A in function B does not have Var, which means that the global variable is used. If you add Var, the result will be different:

var 1 ; function B () {    var;     return ;     // function A () {} }b (); Console.log (a); results:1

And then go back to the 2nd code above, actually because of the function promotion, the functions a referred to the front

var 1 ; function B () {    ten;     return ;    function A () {}}b (); Console.log (a); results:1

In JavaScript, the name in one scope (scope) has the following four types:
1. Language itself definition (language-defined): All scopes default to include this and arguments.
2. function parameter (formal parameters): The function has the name of the form to enter into the scope of the function body.
3. Function Decalrations: In the form of functions Foo () {}.
4. Variable declaration (Variable declarations): In the form of Var foo;


function declarations and variable declarations are always implicitly lifted by the JavaScript interpreter (hoist) to the top of the scope that contains them. It is clear that the language itself and the function parameters are already at the top of the scope. This is like the following code:

var 1

is actually interpreted as such:

var1

Notice that the assignment portion of the declaration is not promoted (hoist). Only the name of the declaration has been promoted.

This is different from the function declaration, where the entire function body is also promoted.

But keep in mind that declaring a function generally has two ways .

 function Test () {foo ();  //  TypeError "Foo is not a function"  bar (); //  "This would run!"  var  foo = function () {//  function expression is assigned to Variable ' foo '  alert ("  this Won ' t run!   "  //  Alert ( " this would run!   " 

Here, only the way the function is declared is promoted together with the function body, and only the name is promoted in the function expression , and the function body is assigned only when it executes to an assignment statement.

Name Resolution Order
One of the most important exceptions to remember is the name resolution order (named resolution Order).

The sequence of parsing is listed above:

1. Language itself definition (language-defined): All scopes default to include this and arguments.
2. function parameter (formal parameters): The function has the name of the form to enter into the scope of the function body.
3. Function Decalrations: In the form of functions Foo () {}.
4. Variable declaration (Variable declarations): In the form of Var foo;

In general, if a name is already defined, he will never be overwritten by another name that has no attributes.

This means that the function declaration has a higher precedence than the variable declaration . But this does not mean that the assignment of the name is invalid, just that the part of the declaration is ignored.

The built-in name arguments behaves somewhat strangely. He appears to be declared after the formal parameter, before the function declaration. This means that a shape named arguments has a higher priority than the built-in arguments, even if the parameter is undefined. This is a bad feature, do not use arguments as a formal parameter.

Any attempt to use this as an identity will cause a syntax error, which is a good feature.
If there is more than one parameter with the same name, the parameter at the end of the list has the highest priority, even if it is undefined.

Name Function Expressions
You can define a name for a function in a function expression, just like a statement in a function declaration. But this does not make it a function declaration, and the name is not introduced into the scope, and the function body is not promoted (hoist). Here are some code to show what I mean:

Foo ();//TypeError "Foo is not a function"Bar ();//validBaz ();//TypeError "Baz is not a function"Spam ();//referenceerror "spam is not defined"varfoo = function () {};//anonymous function expression (' foo ' is promoted)function bar () {};//function declarations (' bar ' and function body are promoted)varBaz = function spam () {};//named function expression (only ' Baz ' is promoted)Foo ();//validBar ();//validBaz ();//validSpam ();//referenceerror "spam is not defined"

How to Code with this knowledge
Now that you understand scope and elevation, what does this mean for writing JavaScript code? The most important one is to always use the Var statement when declaring a variable. I strongly recommend that you use only one var at the top of each scope. If you force yourself to do this, you will never be bothered by the problem of Ascension. Although doing so makes it more difficult to keep track of which variables are actually declared in the current scope. I recommend using the Onevar option in JSLint. If you do all of the previous suggestions, your code will look like this:

/**/var1"something"

I find it always useful to have a direct reference to ECMAScript standard (PDF) to understand how these things work. Here is an excerpt of the variable Declaration and scope (Section 12.2.2):
IF The variable statement occurs inside a functiondeclaration, the variables is defined with function-local scope on that function, as described in section 10.1.3. Otherwise, they was defined with global scope (so is, they was created as members of the global object, as described in Section 10.1.3) using the property attributes {Dontdelete}. Variables was created when the execution scope was entered. A Block does not define a new execution scope. Program and Functiondeclaration produce a new scope. Variables is initialised to undefined when created. A variable with an initialiser was assigned the value of its assignmentexpression when the variablestatement is executed, n OT when the variable is created.

JS Scoping and hoisting

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.