Bhojendra Rauniyar
Bhojendra Rauniyar

Reputation: 85575

different behaviour of hoisting of functions

function myFunction() {
   function myInternalFunction() {
      return 10;
   }
   return myInternalFunction();
   function myInternalFunction() {
      return 20;
   }
}
alert(myFunction()); // What will this alert?

The answer is 20.

function myFunction() {
   var myInternalFunction = function() {
      return "Hello World.";
   }
   return myInternalFunction();
   var myInternalFunction = function() {
      return "Second Definition.";
   }
}
alert(myFunction()); // What will this alert?

The answer is "Hello Wold".

Why???? why not "Second Definition" ????

Upvotes: 1

Views: 41

Answers (3)

Andrew Marshall
Andrew Marshall

Reputation: 96964

A variable’s declaration is hoisted, but not its definition. So your second example is equivalent to:

function myFunction() {
   var myInternalFunction
   myInternalFunction = function() {
     return "Hello World."
   }
   return myInternalFunction()

   myInternalFunction = function() {
     return "Second Definition."
   }
}

Here it becomes obvious that the myInternalFunction is unreachable, so the first definition is used as it is the value of myInternalFunction at the time it’s called. JSLint correctly complains (using your original code):

Unreachable var after return.


Compare with your first example, where the function declarations are hoisted, so your code is equivalent to:

function myFunction() {
   function myInternalFunction() {
     return 10
   }
   function myInternalFunction() {
     return 20
   }
   return myInternalFunction()
}

As we can see here, myInternalFunction is immediately redeclared, and so the last one wins. Both declarations happen before calling the function itself.


So, why this expressions alert lastly called variable:

var a = "one";
var a = "two";
alert(a); // alerts two ???? shouldn't be "one" if expressions?

This isn’t equivalent to your function example; an equivalent example would be:

var a = "one"
alert(a)
var a = "two"

And expected it to alert “two”. I think it’s obvious it won’t. The value of the variable, be it function, string, or anything else, is not relevant.

Upvotes: 3

xdazz
xdazz

Reputation: 160863

Function declarations and variable declarations are always moved (“hoisted”) invisibly to the top of their containing scope by the JavaScript interpreter.

Note it has to be Function declarations, which means only the syntax of function foo() {} will be hoisted.

First code is equal to:

function myFunction() {
   function myInternalFunction() {
      return 10;
   }
   function myInternalFunction() {
      return 20;
   }
   return myInternalFunction();
}

Second code is equal to:

function myFunction() {
   var myInternalFunction;

   myInternalFunction = function() {
      return "Hello World.";
   }

   return myInternalFunction();

   myInternalFunction = function() {
      return "Second Definition.";
   }
}

Upvotes: 0

thefourtheye
thefourtheye

Reputation: 239513

Because, in the first case, during the compile time itself, second myInternalFunction replaces the first myInternalFunction in the current scope. It means that, only the second myInternalFunction function exists in the myFunction's scope.

But in the second case, the functions are created during the execution only. By the time alert was executed, only the first myInternalFunction function was created, the second myInternalFunction is not created at all. That is why Hello World is alerted.

Upvotes: 3

Related Questions