4

var a = function(){
    alert("2");
}

function a(){
    alert("1");
}

a();

As above, I declared two functions in different ways. When I run a(), I got 2. Why?

1
  • 6
    keyword "hoisting" Commented Jul 11, 2015 at 14:30

4 Answers 4

8

When you declare a function or variable in JavaScript it gets "hoisted", meaning that the JavaScript interpreter pretends that the variable (a in your case) was declared at the top of the file scope.

When that declaration takes the form function a() ..., the definition of the function is hoisted along with the declaration.

Assignments like a = function ()... don't get hoisted, and so that assignment happens after the function a() ... piece and overrides it.

Sign up to request clarification or add additional context in comments.

5 Comments

So, the order is var a;, function a(){…} and then a = function(){…}, right?
The var version is also hoisted, but the function is hoisted on top.developer.mozilla.org/en-US/docs/Glossary/Hoisting
"...at the top of the file" At the top of the scope to be precise since these can be declared in other functions.
@DOCASAREL only the var a of the var version is hoisted - the assignment to a is left where it is.
@Alnitak Oh, thanks. Better document: adequatelygood.com/JavaScript-Scoping-and-Hoisting.html (slighty more confusing%)P.
2

Since function and variable declarations get "hoisted" to the top of the enclosing scope your code is equivalent to this:

// hoisted function declaration (but written as an
// assignment of a function expression to a variable)
var a = function a(){
    alert("1");
}

a = function(){
    alert("2");
}

a();

Hence it's the latter value of a that gets invoked, displaying 2 as you have observed.

Comments

1

One word: hoisting.

That's because variable and function declarations are hoisted to the top of the block, and assigning values to variables (which you're doing in the alert(2) case) only takes effect after these.

As such, a is given a value as a function alerting 2 after it has been declared as a function alerting 1.

Look at the output of this code:

// this logs the "second" version, even though it might look like `a` was not even declared yet.
console.log('a curently:',a.toString()); 
var a = function(){
    console.log('first');
    alert("2");
}

function a(){
    console.log('second');
    alert("1");
}

a(); //calling a here logs "first" and alerts 2, as you describe.

Comments

0

@RichieHindle is correct on the concept of what's happening, which is hoisting. Both variable declarations (not their assignments) and functions declared using the function keyword get hoisted to the top of the scope; and in the order they are parsed by the javascript runtime.

In effect, your code is parsed and interpreted by the browser as the following:

var a;
function a(){ 
    alert("1");
}
a = function(){
    alert("2");
}

a();  // alerts "2"

The other effect at play here is shadowing, meaning that the second assignment to a overrides the previous assignment of a declared as a function. Variables of the same name in the same scope can override each other, as Javascript doesn't have strict variable types. Something to be cognizant of when writing Javascript and relying on hoisting.

This is also why many Javascript devs and style guides suggest declaring your variables at the top of the scope and not relying on the side-effects of hoisting, as you (or someone else working on your code) may end up shadowing and re-assigning a variable declared previously in the same scope.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.