Search code examples
javascripthoistingecma

Confusing EcmaScript Specification - Declaration Binding Instantiation



When I read specification for learn "hoisting" in there FunctionDeclaration happens on step 5 but VariableDeclaration happened step 8 and I think this mean function declaration are given higher priority than variable declaration.
What do you think why Function Declaration declare fist and is this have any reason?
Note: You can read this part from this link http://www.ecma-international.org/ecma-262/5.1/#sec-10.5

I have hypothesis for my question. This is not answer this is hypothesis because I don't really know this question answer apparently people also don't know answer.
My hypothesis this
Function can override another function but variable can't I think because that first functionDeclaration happens.


Solution

  • There are two choices, either this code is invalid (e.g., syntax error):

    function foo() {
        console.log("foo1");
    }
    var foo = function() {
        console.log("foo2");
    };
    foo();

    ...or there is an order to things. In the JavaScript spec, in this case, there's an order to things:

    1. The function declaration creates a binding in the scope for foo which logs foo1.
    2. The var in var foo = ... has no effect because varAlreadyDeclared is true.
    3. foo is overwritten with the value resulting from the function expression foo = function() { /*...*/ };

    Why? Because that's how it's specified. More specifically, because a function declaration and a var statement both create a mutable binding in the execution context, so whichever one gets there first creates the binding. "First" again needs definition, and so the definition chosen was that the declaration creates the binding first. But both create mutable bindings, and remember that the var foo part and the foo = ... part are handled completely separately. Since function declarations are processed before the step-by-step execution of the code, the following does exactly the same thing as the above:

    var foo = function() {
        console.log("foo2");
    };
    function foo() {
        console.log("foo1");
    }
    foo();

    Although the function declaration creates the binding first and sets it to the function that does console.log("foo1"), the foo = ... part happens afterward and updates the binding so that it refers to the new function that does console.log("foo2").

    Other choices were available to Brendan Eich, but this was the choice he made during those fateful 10 days in May, 1995. :-) And it does follow logically from these decisions:

    1. Function declarations create mutable bindings
    2. Function declarations and var declarations create the same kind of bindings
    3. Function declarations are hoisted (e.g., the function is created and assigned to the binding before step-by-step execution begins)
    4. The declaration part of a var is hoisted, using the initialization value undefined, but the initializer part of var x = y is not set until the step-by-step execution of the code.