Reputation: 443
From http://dmitry.baranovskiy.com/post/91403200
if (!("a" in window)) {
var a = 1;
}
alert(a);
Here are the results I got:
What's going on??! I expected undefined, since the "if" should return a false (since "a" in window should be false, and !false should be true, therefore the variable a never gets a value). What am I missing?
EDIT: Ok, I realized var statements are executed first, and "a" in window just returns whether such a variable exists or not. But then why are Firebug and jsfiddle giving different answers?
Upvotes: 0
Views: 82
Reputation: 707158
This code gets seen by the javascript interpreter as this:
var a;
if (!("a" in window)) {
a = 1;
}
alert(a);
You have four permutations for this code based on whether a
already exists in the global scope and whether the code is run in the global scope or in a local scope.
If the code is run in a local function scope, then it essentially looks like this:
function whatever() {
var a;
if (!("a" in window)) {
a = 1;
}
alert(a);
}
So, here are the permutations:
global a exists already scope code runs in value of alert(a)
-----------------------------------------------------------------------
yes, has value of 2 global 2
yes exists, value undefined global undefined
no global 1
yes, has value of 2 local undefined
yes exists, value undefined local undefined
no local 1
So, the variation in answers you are getting is because the scope this code is running in is different in each case.
In a jsFiddle, you have to be careful with the settings in the upper left corner. If set to onload
, then the jsFiddle runs in a local function scope (an onload handler function).
What's going on here is that if this code is running the global scope, then ("a" in window)
will always be true because the var a
part of the code is hoisted above the executing code thus var a
in global scope has always been executed so there is always ("a" in window)
. Thus a = 1
is never executed when run in the global scope and the alert(a)
simply outputs whatever the value of global a
is. If it previously had a defined value that's what you will see. If it didn't previously have a defined value, then it will just alert undefined
because (thought it exists), it hasn't been assigned a value.
If this code is run in the local scope, then the alert(a)
will always see the locally defined a
in the alert(a)
. So, you will see 1
as the value if there is no global a
because then a = 1
will execute on the local a
. Or, if there is a global a
, then the a = 1
will never execute, thus the locally defined a
will always be undefined
and that's what the alert will show.
Upvotes: 2