1

I am learning javascript hoisting and came across a scenario for which I need a bit more explanation. Below is the program that I have

test();
console.log("The value of data is "+data);
function test(){
  console.log("Hello");
}
var data = 15;

If I run the above program in JsFiddle, I am getting the below output:

Hello
The value of data is undefined
  1. Is the data hoisted? I am seeing the console as undefined so I presume that the data variable is hoisted.

  2. Is variable hoisting only inside the function? In the above program, if the data is hoisted does that imply that the data variable hoisted even at global level?

  3. The above program prints the text Hello when I define the function without a variable. So is this referred to as function hoisting or is it global function?

  4. If the var data = 15 is changed to data = 15, then I get the error: Uncaught ReferenceError: data is not defined. Why is it behaving differently than in case of function?

Please help me understand what I am missing here.

zilcuanu
  • 3,451
  • 8
  • 52
  • 105
  • What's with the downvotes? This seems a perfectly asked question. +1. – Mitya Jan 28 '16 at 16:39
  • 4
    Variable and function _declarations_ are hoisted in their scope, not assignments. – Teemu Jan 28 '16 at 16:39
  • 1
    the variable `data` has been declared, but has no value since JavaScript Hoisting only pushes variable declarations(`var data`) and not initializations( `= 15`) – james Jan 28 '16 at 16:41
  • If someone could answer my question point wise, it would be very useful to me. – zilcuanu Jan 28 '16 at 16:41
  • The downvote could be due to "lack of research", since this is extensively documented and covered in many questions on SO. –  Jan 28 '16 at 17:17
  • Frankly, I'm mystified by the level of interest in hoisting. Sure, maybe it's useful to know this. But it doesn't really matter. Just declare your variables at the top of the function and you won't have to worry about it. Don't you have more important things to learn? –  Jan 28 '16 at 17:19

2 Answers2

1

Your program :

test();
console.log("The value of data is "+data);
function test(){
  console.log("Hello");
}
var data = 15;

is actually executed as though you had written :

var data;                           // declaration of data hoisted
function test(){                    // Also function definition
  console.log("Hello");
}
test();                                     // Show 'Hello' 
console.log("The value of data is "+data);  // Data still has no value!!
data = 15;                                  // Now data has the value 15.

In short the declaration of variables and functions are hoisted, the assignment of values remains where you write them.

Now as an exercise, what does this produce :

test();    
var test = function test(){definition
  console.log("Hello");
}
console.log("The value of data is "+data);value!!
data = 15;

and why?

HBP
  • 15,685
  • 6
  • 28
  • 34
1

Is the data hoisted? I am seeing the console as undefined so I presume that the data variable is hoisted.

The binding is hoisted and it's always initialized to undefined, this means data exists but there hasn't been an assignment yet.

Is variable hoisting only inside the function? In the above program, if the data is hoisted does that imply that the data variable hoisted even at global level?

Hoisting happens either way, but variables defined inside inner functions aren't hoisted to the script/function that contains them. So var a inside a function fn won't be available on the outer scope.

The above program prints the text Hello when I define the function without a variable. So is this referred to as function hoisting or is it global function?

Javascript understands function differently depending on the context. When you define a function like this:

function fn(){

}

It's considered a function declaration, when you write something like this:

var fn = function(){ };

The function part is considered a function expression. The expression is evaluated when it reaches that point in the script. While the declaration is hoisted to the top. They both produce a fn in their relevant scope, it's just that one is hoisted the other one isn't.

If the var data = 15 is changed to data = 15, then I get the error: Uncaught ReferenceError: data is not defined. Why is it behaving differently than in case of function?

When you removed the var portion, the binding is no longer hoisted. In non-strict mode, the binding will be available after the assignment. In strict mode not only does reading data will fail, but also the assignment will fail.

MinusFour
  • 13,913
  • 3
  • 30
  • 39