Detecting if a Javascript variable is really undefined
How can we differentiate between var foo;
and var foo=undefined;
?
typeof foo
will return for both "undefined" and foo in window
will return for both true;
var foo
implies var foo=undefined
, unless of course undefined
is set to something other than undefined
.
This can be seen in the Browser Console, if you initialise a variable but don't give it a value, it will have the value undefined
(and the type "undefined"
)
How can we difference between var foo;
and var foo=undefined;
?
There is no difference between them, if this line precedes all uses of foo
. (It doesn't have to.) The JavaScript engine sees the line var foo=undefined;
like this:
// At top of scope
var foo; // `foo` will have the value `undefined`
// Where the var foo=undefined; line was
foo = undefined;
Note that they are completely different things that happen at different times. The declaration and the "initialization" (it's really an assignment) happen separately. The declaration happens upon entry to the execution unit; the initialization/assignment happens later, as part of the step-by-step code execution. (More: Poor misunderstood var
)
This means that if you have this:
foo = 5;
alert(typeof foo); // "number"
var foo = undefined;
alert(typeof foo); // "undefined"
...it is not an error, because the way the engine handles that is:
var foo;
foo = 5;
alert(typeof foo); // "number"
foo = undefined;
alert(typeof foo); // "undefined"
A correct example works wonders:
function winFoo() {
console.log('foo' in window);
}
function startFoo() {
window.foo = 'bar';
}
function ovrFoo() {
window.foo = undefined;
}
function removeFoo() {
delete window.foo;
}
//window.foo === undefined
//window.foo hasn't been defined yet
winFoo(); //false
//so it makes sense that 'foo' is not in window
startFoo(); //window.foo === 'bar'
//window.foo has now been set to 'bar'
winFoo(); //true
//so it makes sense that 'foo' is in window
ovrFoo(); //window.foo === undefined
//window.foo has been overridden with a value of undefined
winFoo(); //true
//but the key 'foo' still exists in window, it just has a value of undefined
removeFoo(); //window.foo === undefined
//the key 'foo' has been removed from window and its value is therefor forgotten
winFoo(); //false
//so it makes sense that 'foo' is not in window
Here's a fiddle
Additionally, declaring var foo
outside of any function context instantiates window.foo
with a value of undefined
if !('foo' in window)
(meaning that if you call var foo
multiple times in the same code block it doesn't override the existing value if there is one). More importantly, var
and function
statements are actually hoisted to the top of their scope, which means that:
console.log('foo' in window);
var foo;
console.log('foo' in window);
will print true
twice instead of false
followed by true
.
上一篇: 性能测试独立于迭代次数