0
b();
console.log(a);

var a = 'Hello World';

function b(){
    console.log('Called b!');
}

I have read about the term "hoisting", but it isn't pretty clear to me. Why does the function gets executed while the variable is set to undefined?

The interesting part is, the variable didn't show any error. But it showed undefined. But when I remove the variable totally, then it shows an error. That means, the variable is present somewhere though. right?

But if it is present, then why can't the compiler compile it and can compile the function here?

I know that var a is getting hoisted. I want to know why the engine is treating the variable and the function in a different way that is what's happening behind the scenes during the execution context.

Any detailed explanation would be helpful about how the engine is creating the execution context.

In this question I'm asking about how javascript engine is behaving differently with the function and the variable. And what is exactly happening in the creating state and execution state of the execution phase. So, it's not a duplicate question.

marukobotto
  • 759
  • 3
  • 12
  • 26

4 Answers4

2

But if it is present, then why can't the compiler compile it and can compile the function here?

Basically it boils down to whether the value of the binding can be determined without executing the code or not.

The function declaration itself doesn't depend on runtime information. Keep in mind that the body is not evaluated until the function is called. So even without really executing the code, its clear that the value of b is a function.

However, the initialization value of a variable declaration may depend on runtime information. Consider this:

var a = 10 + bar();

There is no way for the engine to "hoist" the initialization value without evaluating the expression (and executing bar in the process).

Of course in your example, the initialization value ('Hello World') is static as well, so it could be hoisted. But then the behavior would be inconsistent and probably more confusing.


What exactly happens when control enters a new function is defined in the spec. There you can see how variable declarations and function declarations are treated.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • That made some sense. The body is not evaluated until the function is called and the variable declaration may depend on runtime info. – marukobotto Dec 04 '15 at 16:49
  • @nickB: Not the declaration, the *initialisation*. – Bergi Dec 05 '15 at 19:40
  • @Bergi you are right. initialisation. The variable was declared and initialized as `undefined` in the beginning when it can't find the value. The actual initialization takes place during the runtime. – marukobotto Dec 05 '15 at 19:44
1

With hoisting, this is what your code looks like

function b(){
    console.log('Called b!');
}
var a;

b();
console.log(a);

a = 'Hello World';

As you can see, a is declared at the the top, but has not been set to a value yet. That is why you get undefined when you log that variable.

If you remove the a variable altogether, you get the Uncaught ReferenceError because a has not been declared.

AmmarCSE
  • 30,079
  • 5
  • 45
  • 53
  • I know. I want to know the reason for the engine to treat function and variable in a different way at the time of execution – marukobotto Dec 04 '15 at 16:46
0

The above code is same as below

var a;
function b(){
    console.log('Called b!');
}
b();
console.log(a);

a = 'Hello World';

Explanation - Function along with its definition are hoisted to the top. Variable declaration is hoisted not its definition

Nikhil Aggarwal
  • 28,197
  • 4
  • 43
  • 59
0

var a; is hoisted. a = 'Hello World!'; is not hoisted. It's that simple.

djechlin
  • 59,258
  • 35
  • 162
  • 290