Reputation: 85
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?
Upvotes: 4
Views: 67
Reputation: 1204
@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.
Upvotes: 0
Reputation: 4506
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.
Upvotes: 1
Reputation: 281485
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.
Upvotes: 8
Reputation: 339816
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.
Upvotes: 2