Understanding JavaScript Scoping & Hoisting (ii) _javascript tips

Source: Internet
Author: User

Scoping & Hoisting

var a = 1;

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

Foo ();

What happens when the above code is run?

Although this is a piece of cake for experienced programmers, I still follow the usual ideas of beginners:

1. Create a global variable A, define its value to 1
2. Create a function foo
3. In the function body of Foo, the IF statement will not execute because!A converts the variable A to a Boolean false value, which is false
4. Skip conditional branch, alert variable A, the final result should be output 1

Well, it looks like an airtight inference, but it's amazing: the answer is 2! Why?

Don't worry, I'll explain it to you. First of all I want to tell you that this is not a mistake, but an (unofficial) feature of the JavaScript language interpreter, which someone (Ben Cherry) calls this feature:hoisting(there is no standard translation at this time, and it is more common to promote ).

Declaration and definition

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

var a = 1;

Have you ever wondered what happened to the above code when it was running?
Do you know which of the two statements "declaring variable a" and "defining variable a" are correct in terms of this code?
• The following example is called "declaring a variable":

var A;

• The following example is called "Defining variables":

var a = 1;

• Disclaimer: Refers to the existence of something you claim to be, such as a variable or a function, but you do not say what it is, just tell the interpreter that something exists;
• Definition: Refers to the specific realization of something, such as the value of a variable, what the function of a function is, and exactly how it is expressed.

To sum up:

var A; It's a statement.
A = 1; This is the definition (Assignment)
var a = 1; Unite: Declare the existence of a variable and assign it to it

Here's the point: when you think you've only done one thing (var a = 1), the interpreter actually breaks it down into two steps, one is the declaration (Var a) and the other is the definition (a = 1).

What does this have to do with hoisting?

Back to the first confusing example, I'll 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 point A is not the global variable outside the function body
}

As the code shows, the interpreter declares a new variable a when it enters the function body, and assigns a value of 2 to the new variable a regardless of the condition of the IF statement. If you don't believe in the function body, alert (a), and then execute foo (), compare the results to see.

Scoping (Scope)

One might ask: "Why not declare variable A in an if statement?" ”

Because JavaScript does not have block-level scopes (blocks scoping), only functional scopes (function scoping), not seeing a pair of curly braces {} represents a new scope, unlike C!

When the parser reads the IF statement, it finds that there is a variable declaration and assignment, so the parser promotes its declaration to the top of the current scope (which is the default behavior and cannot be changed), which is called hoisting.

OK, everybody knows, do you understand?

Understand does not represent will use, take the first example, if I just want to alert (a) out that 1 can do it?

Create a new scope

Alert (a), when executed, looks for the position of the variable a, starting from the current scope up (or outward) to find the top scope, and if not, report undefined.

Because in the sibling scope of alert (a) We declare the local variable a again, so it is 2, so we can move the declaration of the local variable a down (or inward) so that alert (a) cannot find it.

Remember: JavaScript has only function scopes!

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 inside of Foo (), so alert is not reachable
    } ());        But this scope can access the upper scope oh, this is called: "Closure"
  };
  alert (a);
};

Foo ();

You may have read in countless JavaScript books and articles: "Always keep the declaration of all variables within the scope at the top of the scope," and now you know why you have said that? Because this avoids the obsession with the hoisting feature (which I'm not so happy to say, because hoisting itself is nothing wrong), it's also clear to tell all the people who read the code (including yourself) What variables are available in the current scope. However, the promotion of variable declarations is not all hoisting. In JavaScript, there are four ways to get names into scope (by priority):

1. Name of the language definition: for example, this or arguments, which is valid in all scopes and has the highest precedence, so you can't name the variable "this" anywhere, so it doesn't make sense.
2. Formal parameters: The formal arguments declared when the function is defined are hoisting to the scope of the function as a variable. So the formal parameter is local, not external or global. Of course, you can pass the external variables in when the function is executed, but it's local when it's passed in.
3. Function declaration: Functions can also be declared within the body, but they are also local
4. Variable declaration: This priority is actually the lowest, but they are also the most common

Also, remember that we discussed the differences between declarations and definitions before? I didn't say why to understand the difference at the time, but now it's time to remember:

Hosting only elevated naming, no elevation definition

This is closely related to what we are going to talk about, please see:

difference between a function declaration and a 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 ();

Classmate, after understanding the scoping & hoisting, you know how to explain all this?

In the first example, the function foo is a declaration, since the Declaration will be promoted (I specifically wrapped an outer scope, because the global scope requires your imagination, not so intuitive, but the truth is the same), so before the execution of Foo (), the scope knows the existence of the function foo. This is called a function declaration, and the function declaration is connected to the name and function body to be promoted to the top of the scope.

In the second example, however, only the variable name Foo is promoted, and its definition remains where it belongs. Therefore, before executing foo (), the scope only knows the name of Foo and does not know what it is, so execution complains (usually: undefined is not a function). This is called a function Expression, and the function expression only has a name that is promoted, and the defined function body does not.

Tail: Ben Cherry's original explanation is more detailed, just English. I this is jiehuaxianfo, mainly more obvious explanation for beginners to listen, to see more examples, please go 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.