S. A. Malik
S. A. Malik

Reputation: 3665

Function in Scope Before Declaration

I read in a book about function declaration. The code goes like this.

function outer(){
    assert(typeof inner === "function", "inner() in scope before declaration");
    function inner(){}
    assert(typeof inner === "function", "inner() in scope after declaration");
    assert(typeof window.inner === "undefined", "inner() undefined in global space")
}

When the tests are run all the three statements are asserted true, showing that the inner() function existed in scope before its declaration. My concept about javascript is that the script is executed line by line and the functions should be declared before there call.

The question is how can the inner function exist in the scope before its declaration?

Upvotes: 0

Views: 178

Answers (2)

Shruti Singh
Shruti Singh

Reputation: 181

Javascript executes a function in two Pass, consider this :

There are two ways that you can use a function

1st: function quack(num){
      for(var i=0; i<num ; i++)
       {
        console.log("quacking")
       }
      } - this is a function declaration.   

2nd:   var fly = function(num){
        for(var i=0; i<num ; i++)
        {
         console.log("Flying!!!")
        }
       } - This is a function expression.

Now in the first pass the javascript looks for function declaration
which is

 function quack(num){
          for(var i=0; i<num ; i++)
           {
            console.log("quacking")
           }
          } 

So it assigns quack's reference to a variable which has the same name as that of the method ie.. quack . So if you call quack() before you declare it, it works fine.

However in the 2nd pass it looks for function expression which
means you cannot call fly before evaluating it. I hope this gives a better explanation.

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074979

My concept about javascript is that the script is executed line by line and the functions should be declared before there call.

That's incorrect. In JavaScript, all function declarations in an execution context are processed upon entry into that execution context, before any step-by-step code is executed. So function declarations within functions are processed upon entry into the function when it gets called, and function declarations at global scope are processed before any global step-by-step code is executed. This is sometimes called "hoisting" (because the function declarations are effectively "hoisted" [lifted] up to the top of the scope they're declared in). (Side note: var is also hoisted, more on my blog: Poor misunderstood var.)

This is distinct from function expressions, which like all expressions, are evaluated in the step-by-step execution of the code.

Here's a function declaration:

function foo() { }

Here are three function expressions, note that in each case, they're used as right-hand values (e.g., they're assigned to a var or property, passed into a function, used in a containing expression, etc.), which is what makes them expressions rather than declarations:

var x = function foo() { };
obj = {
   b: function bar() { }
};
doSomethingWith(function() { });

There I've shown two named function expressions and one anonymous function expression. If you're going to be writing code for IE8 and earlier, you may want to steer clear of named function expressions as IE's "JScript" interpreter gets them wrong; more (also my blog): Double take.

Upvotes: 1

Related Questions