Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Hoisting in JavaScript

DZone's Guide to

Hoisting in JavaScript

Just like the ‘this’ keyword, another area that may be confusing in JavaScript are scope and hoisting

· Web Dev Zone
Free Resource

Add user login and MFA to your next project in minutes. Create a free Okta developer account, drop in one of our SDKs to your application and get back to building.

Just like the ‘this’ keyword, another area that may be confusing in JavaScript are scope and hoisting . So in the next few minutes we will try to understand the hoisting in JavaScript.

Hoisting is the process of raising or lifting up of ‘something’ from one ‘position’ to another. In JavaScript the ‘something’ is variables and functions and the new position is the top of function or global context. Ok let’s look into some examples and understand it in detail.

Can you predict the output of the following?

console.log(myVariable);

Note:You can check this in firebug console or any other developer tools in browsers.

As you can see the output is ReferenceError: myVariable is not defined. You know why this happens. Because the variable myVariable is not defined when it is printed to console.

Ok. Now check the following code.

var myVariable;
console.log(myVariable); //undefined


You all know there will not be a ReferenceError: and since myVariabledoesn’t have any value assigned to it, myVariable remains undefined.

So what will be result for the following code?

console.log(myVariable); //undefined
var myVariable ='javascript';


You would have surprised if you expected ReferenceError: myVariable is not defined. But how come it is undefined?. What happened here is the result of variable hoisting. The variables in JavaScript are hoisted to the top of the scope. So the variable myVariable is hoisted to the top before executing console.log(myVariable);. Note that only declaration is hoisted and not the actual definition. So the example shown above is equivalent to the following code at the time of execution.

var myVariable;
console.log(myVariable); //undefined
myVariable ='javascript';


So in JavaScript it is always advised to declare the variables at the top of the scope (in global context or in function).

Hoisting for multiple variables
suppose we have two variable with same value. We would probably declare them as

var myVar1 = "javascript";
var myVar2 = myVar1;

and we already know the above code can be written as follows.

var myVar1, myVar2 =  myVar1 = "javascript";


But you should be careful about the order of assigning. If you write the code as follows:

var myVar1 = myVar2,  myVar2 = "javascript";
console.log(myVar1 + myVar2); //undefinedjavascript

The output will be undefinedJavaScript as you saw in the console. This is because the variable myVar2 is assigned to myVar1 when myVar2 isundefined and then only the variable myVar2 is assigned to JavaScript. In other words the example shown above is equivalent to the following code.

var myVar1, myVar2;
myVar1 = myVar2;
myVar2 = "javascript";
console.log(myVar1 + myVar2); //undefinedjavascript

Remember I said the declarations will only be hoisted and not the definitions; and that is why var myVar1, myVar2; is hoisted and the myVar1 = myVar2; are kept as it is for later executions.


Function hoisting in JavaScript
We have seen the declarations of the variables will be hoisted in JavaScript. Now what happens to functions? Well it depends on how we declare and define a function. There are two ways for declaring a function

1st way is function foo () {//do something}; and 2nd way is var foo = function () {//do something}; 

The entire function definition will be hoisted in the first case and only declaration will be hoisted in the second case. Well we can clearly understand this from the following scenario.

function test () {
foo();//this will work
bar();//this will not work- TypeError: undefined is not a function
function  foo() {
console.log('in function foo');
};
var bar = function () {
console.log('in function bar');
}
}
test();

The error in executing bar(); is due to the hoisting of variable bar and leaving function definition. But in the case of foo the entire function definition will be hoisted and will execute correctly. Effectively the above code will be equivalent to the following.

function test () {
var bar; //bar is undefined now
function  foo() {
console.log('in function foo');
};

foo();
bar();

bar = function () {
console.log('in function bar');
}
}
test();

But remember if we call these functions after their definitions; they will work in the normal way;

function test () {
function  foo() {
console.log('in function foo');
};
var bar = function () {
console.log('in function bar');
};
foo();//in function foo
bar();//in function bar
}
test();


But if we define a function with named function expression like  var zoo = function boo() {//do something}  the code  boo();  will not get executed even after function definition. Let's check.

function test () {
zoo(); //TypeError: undefined is not a function
boo(); //ReferenceError: boo is not defined
var zoo = function boo() {
console.log(' function executed');
};
zoo();// function executed
boo();//ReferenceError: boo is not defined
}
test();


Scope in JavaScript
As the hoisting is related to scope, we can take a look into scope in JavaScript also. The JavaScript does not have any block level scope. Which means the scope of a variable/function is entitled to function or global context and does not to a if(){..} or else(){..} block.
Let us check with an example;

function test() {
var x = 5;
console.log(x);
if(true) {
var x=6;
console.log(x);
}
console.log(x);
}
test();


The output will be 5,6,6 as the var x=6; inside the if block is hoisted to the top of the function. So that piece of code will not create a brand newx with value 6 instead it just assigns the new value to already existingx.The output will be 5,6,6 as the var x=6; inside the if block is hoisted to the top of the function. So that piece of code will not create a brand new x with value 6 instead it just assigns the new value to already existing x.

Launch your application faster with Okta’s user management API. Register today for the free forever developer edition!

Topics:
javascript ,web dev

Published at DZone with permission of Saju Edayan. See the original article here.

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}