< deep understanding javascript> Learning Notes (2) _ Secret named function expressions

Source: Internet
Author: User

Write it in front.

Note: This article is read in-depth understanding of JavaScript after the deep feeling, so make notes convenient after the review.

I feel this chapter is a bit esoteric .... Slightly difficult to understand AH.

Just sit down and take notes to deepen your impressions.

I mainly remember what I feel useful ... Ha ha

function expressions and Function declarations

In ECMAScript, the two most common methods of creating a function are function expressions and function declarations, and the difference between the two is a bit faint, because the ECMA specification is only one point: the function declaration must be marked with an identifier (Identifier) (the name of the function that is often called). The function expression can omit this identifier:

function declaration:

function function name ( parameter: Optional ) { body }

function expression:

function name (optional)( parameter: Optional ) { function body }

So, it can be seen that if the function name is not declared, it must be an expression, but if the function name is declared, how to determine whether it is a function declaration or function expression? ECMAScript is distinguished by context, if function foo () {} is part of an assignment expression, it is a function expression, if function foo () {} is contained within a function body, or at the top of the program, Then it is a function declaration.

function // declaration, because it is part  of the program var function // expression, because it is part  of an assignment expression New function // expression, because it is a new expression   (function() {    function//  declaration, as it is part of the body of the function   })();

There are very subtle differences between expressions and declarations, and first, function declarations are parsed and evaluated before any expression is parsed and evaluated, even if you declare it in the last line of code, and it is parsed/evaluated before the first expression in the same scope, as in the following example. The function FN is declared after alert, but when alert executes, FN is already defined:

alert (FN ());   function fn () {    return ' Hello world! ' ;  }

Also, it is important to note that function declarations are useful in conditional statements, but are not standardized, meaning that different environments may have different execution results , so it is best to use function expressions:

//don't do this!   //because some browsers return the function of first, and some browsers return the second  if(true) {    functionfoo () {return' First '; }  }  Else {    functionfoo () {return' Second ';  }} foo (); //instead, in this case, we're going to use a function expression  varfoo; if(true) {foo=function() {      return' First ';  }; }  Else{foo=function() {      return' Second ';  }; } foo ();

The actual rules for function declarations are as follows:

A function declaration can only appear within the body of a program or function . In the syntax, they cannot appear in blocks (block) ({...} ), for example, cannot appear in an if, while, or for statement. Because block (block) can contain only statement statements, it cannot contain source elements such as function declarations . On the other hand, a closer look at the rules will also reveal that the only thing that can make an expression appear in block is to make it part of an expression statement . However, the specification explicitly specifies that an expression statement cannot begin with a keyword function. This, in effect, means that the function expression also cannot appear in the statement statement or block (because block is made up of statement statements).

Bugs in JScript

Worse, IE's ECMAScript implementation of JScript seriously confused the name function expression, many people are out against the name function expression, and even the latest version (version 5.8 used in IE8) still has the following problems.

Let's take a look at the IE in the implementation of the mistakes made, as the saying goes, we know that can baizhanbudai. Let's take a look at a few examples below:

Example 1: identifier of a function expression leaked to an external scope

  var function g () {};     typeof // "function"

As we said above, the identifier of the named function expression is invalid outside scope, but JScript is obviously a violation of this specification, the above example of the identifier G is parsed into a function object, this is a mess, a lot of difficult to find bugs are caused by this reason.

Note: IE9 seems to have fixed this problem.

Example 2: Use a named function expression as both a function declaration and a function expression

typeof // "function"    var function g () {};

In an attribute environment, a function declaration takes precedence over any expression being parsed, and the example above shows that JScript actually treats a named function expression as a function declaration because it parses G before actually declaring it.

This example leads to the next example.
Example 3: A named function expression creates two distinct function objects!

var function g () {};     // false = ' foo ';          // undefined

See here, people will feel the problem is serious, because to modify any one object, the other has nothing to change, this is too bad. In this example, it is possible to create 2 different objects, that is to say, if you want to modify the properties of F to save a certain information and then take it for granted by referencing the same property with the same name as g of the same object, the problem is large, because it is not possible at all.

Let's look at a slightly more complicated example:

Example 4: Conditional statement blocks are ignored in order to parse function declarations only

  var function g () {      return 1;    };     if (false) {      function  g () {        return 2;      };    }     // 2

This bug is much more difficult to find, but the cause of the bug is very simple. First, G is parsed as a function declaration, because function declarations in JScript are not constrained by conditional code blocks, so in this very bad if branch, G is treated as another function g () {return 2}, which is also declared once. Then, all the "regular" expressions are evaluated, and F is given a reference to another newly created object. Since the expression is evaluated, it never goes into "This hateful if branch, so F will continue to refer to the first function g () {return 1}. Analysis here, the problem is clear: if you are not careful enough to call G in F, then will call a irrelevant G function object.

What is the difference between a different object and a arguments.callee when you compare it? Let's take a look at:

var function g () {    return  [      = = F      ,= = g    ];  };   // [True, false]  // [False, True]

As you can see, the Arguments.callee reference has always been called function, which is actually a good thing to explain later.

Another interesting example is the use of a named function expression in an assignment statement that does not include a declaration:

(function() {    function  f () {};  }) ();

According to the analysis of the code, we originally wanted to create a global attribute F (Note that it is not confused with the General anonymous function, which is used with the name of life), JScript is here to make a mess, first of all, he interpreted the expression as a function declaration, So the left F is declared as a local variable (as in the General anonymous function), and then when the function executes, f is already defined, and the Right function f () {} is directly assigned to the local variable F, so f is not a global attribute at all.

Knowing that JScript is such a pervert, we have to prevent these problems in time, first of all to prevent the identifier leak with the external scope , and secondly, should never refer to the identifier used as the function name ; Remember that annoying identifier g in the previous example? If we can avoid any unnecessary trouble when G does not exist. Therefore, the key is to always refer to the function through F or arguments.callee. If you use a named function expression, you should only use that name when debugging. Finally, keep in mind that it is important to clean up functions that are incorrectly created during the declaration of a named function expression .

For the last point above, we have to explain it again.

This chapter is really a bit biased, we can only simply understand the next. Other individuals feel less useful and do not take notes.

< deep understanding javascript> Learning Notes (2) _ Secret named function expressions

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.