Difference between Javascript function declaration and function expression

Javascript Functions are everywhere and powerful! Through Javascript functions, JS can have some object-oriented features, realize encapsulation, inheritance, etc., and also allow code to be reused. But things have two sides. Javascript functions are sometimes "willful". If you don't understand its "temperament", it is likely to create some unexpected troubles (bugs) for you.  

There are two types of Javascript Functions:

1) Function Declaration;

 // 函数声明
    function funDeclaration(type){
        return type==="Declaration";
    }

2) Function Expression (Function Expression).

// 函数表达式
    var funExpression = function(type){
        return type==="Expression";
    }

The code above looks similar and doesn't feel much different. But in fact, a "gotcha" in Javascript functions is reflected in the definition of two types of functions in Javascript. Let's look at the two pieces of code (marked as Code 1 and Code 2 respectively):

funDeclaration("Declaration");//=> true
    function funDeclaration(type){
      return type==="Declaration";
  }
funExpression("Expression");//=>error
      var funExpression = function(type){
        return type==="Expression";
   }
A function funDeclaration created with a function declaration can be called before funDeclaration is defined; 
a function funExpression created with a function expression cannot be called before funExpression is assigned a value.
Why is this so? ! This is to understand the difference between the two types of Javascript Function: 
functions created with function declarations can be called after function parsing (and other logical processing during parsing); 
while functions created with function expressions are assigned at runtime and require It cannot be called until the expression assignment is complete.
This difference may seem small, but in some cases it is a hard-to-find trap. 
The essential reason for this pitfall is the difference between the two types in Javascript function hoisting (function hoisting) 
and runtime (parse-time/run-time) . 
Regarding variable promotion , you can see my other blog post < JavaScript Variable Promotion > The function promotion of the above two pieces of code can be shown as the following figure:

Code 1 The JS function is equivalent to:

function funDeclaration(type){
        return type==="Declaration";
    }
    funDeclaration("Declaration");//=> true

Code 2 The JS function is equivalent to:

var funExpression;
    funExpression("Expression");//==>error
    funExpression = function(type){
        return type==="Expression";
    }

When the above code is running, only the funExpression variable is defined, but the value is undefined. So function calls cannot be made on undefined. At this point, the funExpression assignment statement has not been executed yet. To further deepen the distinction between the two types of JS functions, here is a more confusing example, look at the code below (code snippet 4):

var sayHello;
    console.log(typeof (sayHey));//=>function    
    console.log(typeof (sayHo));//=>undefined
    if (true) {
        function sayHey() {
            console.log("sayHey");
        }
        sayHello = function sayHo() {
            console.log("sayHello");
    }
    } else {
        function sayHey() {
            console.log("sayHey2");
        }
        sayHello = function sayHo() {
            console.log("sayHello2");
        }
    }    
    sayHey();// => sayHey2    
    sayHello();// => sayHello

Analysis : sayHey is created with a function declaration. When JS is parsed, the JS compiler upgrades the function definition. That is to say, when parsing JS code, the JS compiler (conditional judgment does not form a new scope, two Each sayHey function definition is hoisted out of the conditional judgment) It is detected that there are two sayHey definitions with the same name in the scope, the first definition is hoisted first, and the second definition is hoisted next (the second definition is in the first definition. below), the second definition overrides the first sayHey definition, so sayHey() outputs sayHey2; while sayHello is created with a function expression, the content of which is determined at JS runtime (not parsing time) (Conditional judgment comes into play here), so the sayHello expression executes the first function definition and assigns a value, then sayHello() outputs sayHello.

  The code of Snippet 4 is actually equivalent to the following code (Snippet 5):

var sayHello;
    function sayHey() {
            console.log("sayHey");
        }
    function sayHey() {
            console.log("sayHey2");
    }
    console.log(typeof (sayHey));//=>function    
    console.log(typeof (sayHo));//=>undefined
    if (true) {
        //hoisting...
        sayHello = function sayHo() {
            console.log("sayHello");
    }
    } else {
        //hoisting...
        sayHello = function sayHo() {
            console.log("sayHello2");
        }
    }    
    sayHey();// => sayHey2    
    sayHello();// => sayHello

Some people may suspect that the definition of the function sayHey is the second overriding the first one? We can output the source code of sayHey, there are pictures and truths, as shown in the following figure:

Summarize

  There is a difference between function declarations and function expressions in Javascript. Function declarations perform function promotion during JS parsing . Therefore, within the same scope, no matter where the function declaration is defined, the function can be called. The value of a function expression is determined at JS runtime, and the function can only be called after the expression is assigned. This slight difference may lead to unexpected bugs in the JS code and let you fall into inexplicable traps.

  Finally, the core steps of the two functions sayHello and sayHey in code segment 4 are attached ( personal understanding, if you have any objections, please leave a message for discussion ):

  The above figure is a schematic diagram of the main steps executed by the sayHello function.

The above figure is a schematic diagram of the main steps performed by the sayHey function. If you are interested in closures , you can read another blog post < JavaScript Advanced Features Closures >

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324411948&siteId=291194637