On JS variable declaration and function declaration promotion

Source: Internet
Author: User

Let's start with two questions.

Most of the time, intuitively, we think that the JS code executes at the top-down line, but in fact, there is a situation that causes the hypothesis to be wrong.

=2;var a;console.log(a);

Traditionally, the Console.log (a) output should be undefined, since Var A is after a = 2. However, the output is 2.

Look at the second piece of code:

console.log(a);var=2;

Someone would think of the first piece of code and then answer undefined. Others would argue that a was not declared before it was used, and therefore throws a Referenceerror exception. Unfortunately, the result is undefined.

Why is it?

Look at the problem from the compiler's point of view

JS in the compile phase, part of the compiler's job is to find all the declarations and correlate them with the appropriate scopes. For the average person, var a = 2 is just a declaration, but the JS compiler splits the code into two segments, namely: var A and a = 2. var a defines the declaration to be executed during the compilation phase, while A = 2 assignment declaration waits in place for the traditional execution from top to bottom.

So, from the compiler's point of view, the first piece of code actually looks like this:

var a;  // 编译阶段执行=2;console.log(a);

So, the output is 2.

Similarly, the second code fragment is actually executed like this:

var a;console.log(a);=2;

In this case, it is clear that the output should be undefined, because only a is defined and no assignment is made to a declaration.

As you can see from the two examples above, variable declarations are moved to the top of the current scope from where they appear in the code, a process called Ascension .

function promotion

Next, let's look at a piece of code

foo();functionfoo{    console.log(a);    var=2;}

In this example, the output undefined without error, because the function variable can also be improved. That is, it actually runs like the following scenario.

functionfoo{    var a;    console.log(a);    =2;}foo();

Speaking of which, do you think that the promotion is very simple, as long as the variables are placed at the top of the current scope to execute it?

Below, I have an unexpected situation: the elevation of the function expression.

Promotion of function expressions
foo();var=functionbar{    console.log(a);    var=2;}

Do you want to say that this example is not the same as the previous one? The output of course is undefined ah. However, the result is, do not output, because JS reported typeerror error!

Because, the function expression is not promoted!

The actual operation of this example is as follows:

var foo;foo();=functionbar{    var a;    console.log(a);    =2;}

The Referenceerror error is not reported because Foo is found in the scope at the top of execution, but Foo is not assigned at this time (if Foo is a function declaration and not a function expression, then the value is assigned), that is, the actual foo ( ) is a function call to a variable with a value of undefined, so it is rightfully to throw the TypeError exception.

It is worth mentioning that even a named function expression, the name identifier can not be used in the scope before the assignment, that is:

foo();  // TypeErrorbar();  // ReferenceErrorvar=functionbar{}
function first

Both the function declaration and the variable declaration are promoted, but there is a noticeable detail that the function is first promoted and then the variable!

Look at the following code:

foo();var foo;functionfoo{    console.log(1);}=function{    console.log(2);}

This section of code will output 1, because the function takes precedence.

This section of code can be converted to the following form:

functionfoo{    console.log(1);}var foo;    // 重复声明,被忽略foo();      // 输出1=function{    console.log(2);}

If, at the end of the code, the Foo function is executed again, at this point, the output is 1.

functionfoo{    console.log(1);}var foo;    // 重复声明,被忽略foo();      // 输出1=function{    console.log(2);}foo();      // 输出2

Because, although duplicate declarations are ignored, the following function can overwrite the previous function.

Knowing this, you can understand the following question:

foo();var=true;if{    functionfoo{        console.log("a");    }}else{    functionfoo{        console.log("b");    }}

What do you think the result of this problem output is? It's b!. Why? Because Foo makes two declarations, the last function overrides the previous one. So when you call Foo, the Console.log ("B") is always called.

Summarize

1. All declarations (variables and functions) are moved to the top of their respective scopes, a process known as ascending

2. Various assignment operations, such as function expressions, are not promoted

3. Function Precedence principle

4. Avoid raising problems as much as possible

Reference: You Dont ' t Know Js:scope & Closures

On JS variable declaration and function declaration promotion

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.