Understanding JavaScriptScoping & Hoisting (2) _ javascript skills

Source: Internet
Author: User
This article mainly introduces understanding JavaScriptScoping & amp; Hoisting. Although it is only a piece of cake for experienced programmers, I still follow the common ideas of beginners to describe Scoping & Hoisting

var a = 1;function foo() {  if (!a) {    var a = 2;  }  alert(a);};foo();

What are the results of the above Code?

Although this is just a piece of cake for experienced programmers, I would like to describe it as follows the common ideas of beginners:

1. Create global variable a and define its value as 1
2. Created the function foo.
3. In the foo function, the if statement will not be executed, because! A converts variable a to a Boolean false value, that is, false.
4. Skip the condition branch. The final result of alert variable a is output 1.

Well, it looks like an impeccable reasoning, but surprisingly, the answer is actually 2! Why?

Don't worry, I will explain it to you. First, I want to tell you that this is not a mistake, but a (unofficial) feature of the JavaScript interpreter. Someone (Ben Cherry) calls this feature:Hoisting(There is no standard translation yet. The most common one isUpgrade).

Declaration and definition

To understand Hoisting, let's look at a simple situation:

Var a = 1;

Have you ever wondered what happened when the above Code was running?
Do you know which of the following statements about "declare variable a" and "define variable a" are true for this code?
• The following example is called "declare variable ":

Var;

• The following example is called "definition variable ":

Var a = 1;

• Declaration: you claim the existence of something, such as a variable or a function. But you have not explained what such a thing actually exists, just to tell the interpreter that it exists;
• Definition: you specify the specific implementation of something, such as the value of a variable, the body of a function, and the meaning of such a thing.

Summary:

Var a; // This is the Declaration
A = 1; // This is the definition (Value assignment)
Var a = 1; // combine them into one: declare the existence of a variable and assign it

The point is: When you think you only do one thing (var a = 1), in fact, the interpreter splits this thing into two steps, one is Declaration (var ), the other is definition (a = 1 ).

What is the relationship between this and Hoisting?

Back to the confusing example at the beginning, I will tell you how the interpreter analyzes your code:

Var a; a = 1; function foo () {var a; // The key here is if (! A) {a = 2;} alert (a); // at this time, a is not the global variable of the function in vitro}

As shown in the Code, after entering the function body, the interpreter declares the new variable a. Regardless of the conditions of the if statement, the new variable a is assigned a value of 2. If you don't believe it, you can use alert (a) outside the function body, and then execute foo () to compare the results.

Scoping (Scope)

Someone may ask: "Why isn't variable a declared in the if statement ?"

Because JavaScript does not have Block-level scope (Block Scoping) and only has Function scope (Function Scoping), not seeing a pair of curly braces {} represents a new scope, which is different from C!

When the parser reads the if statement, it finds that there is a variable declaration and a value assignment here, so the parser will promote its declaration to the top of the current scope (this is the default action, and cannot be changed). This behavior is called Hoisting.

Okay, everyone understands. Do you understand ......

If I understand it, it doesn't mean I will use it. In the first example, what if I want alert (a) to get out of that 1?

Create a new scope

During execution, alert (a) searches for the position of variable a, which starts from the current scope and goes up (or out) until the top-level scope is found, undefined is returned if no value is found.

Because in the same-level scope of alert (a), we declared the local variable a again, so it reported 2; so we can move the declaration of the local variable a down (or inward, in this way, alert (a) cannot find it.

Remember: JavaScript only has function scope!

Var a = 1; function foo () {if (! A) {(function () {// This is the IIFE mentioned in the previous article. It creates a new function scope var a = 2; // and the scope is in foo () so alert cannot access} (); // However, this scope can access the upper-level scope, which is called: "closure"}; alert ();}; foo ();

You may have read in countless JavaScript books and articles: "Please always keep the declaration of all variables in the scope at the top of the scope ", now you should understand why? This can avoid the troubles caused by the Hoisting feature (I am not willing to say so, because Hoisting itself has nothing to do with it ), you can also clearly tell all the code readers (including yourself) which variables are accessible in the current scope. However, the promotion of variable declaration is not all about Hoisting. In JavaScript, there are four ways to put a name into the scope (by priority ):

1. language-defined naming: for example, this or arguments, they are valid in all scopes and have the highest priority. Therefore, you cannot name variables like this anywhere. this is meaningless.
2. Formal parameters: the formal parameters declared during function definition will be hoisting to the scope of the function as variables. Therefore, the formal parameters are local, not external or global. Of course, you can pass in the external variables when executing the function, but after passing in, it is local.
3. function declaration: You can declare functions in the function body, but they are both local.
4. Variable Declaration: the priority is actually the lowest, but they are also the most commonly used

In addition, do you remember the differences between declarations and definitions we discussed before? At that time, I didn't say why I understood the difference, but now is the time to remember:

Hosting only promotes the name but does not enhance the definition.

This is closely related to what we will talk about next. Please refer:

Differences between function declaration and function expression

Let's take a look at two examples:

Function test () {foo (); function foo () {alert ("I will appear ...... ") ;}} Test ();

Function test () {foo (); var foo = function () {alert ("I won't appear ...... ") ;}} Test ();

After learning about Scoping & Hoisting, do you know how to explain it all?

In the first example, the function foo is a declaration. Since it is a declaration, it will be promoted (I specially wrapped an outer scope because the global scope requires your imagination and is not so intuitive, but the principle is the same), so before executing foo (), the scope knows that the function foo exists. This is called Function Declaration. Function declarations are promoted to the top of the scope together with the name and Function body.

However, in the second example, the variable name foo is promoted, and its definition remains at the original place. Therefore, before executing foo (), the scope only knows the name of foo and does not know what it is. Therefore, an error is reported during execution (usually: undefined is not a function ). This is called a Function Expression. A Function Expression is promoted only after its name is defined.

Note: Ben Cherry's original explanation is more detailed, but only in English. I am here to show the Buddha with flowers, mainly for beginners to learn more. If you want to see more examples, please move to the original. Thank you.

Related Article

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.