Hello, and welcome to the second part of “Javascript: The Scope Pitfall”. Let’s get started, shall we?
What does the following code print?
var n = 0;
function add() {
var m = n + 1;
print(m);
}
add();
That was easy, right? The answer, of course is 1, because 0 + 1 == 1. Alright, a slight variation on the same example:
var n = 0;
function add2() {
var n = n + 1;
print(n);
}
add2();
What does this print? If your answer is NaN (not a number), you can stop reading. If you think the answer is 1 (as I did), read on. What is happening here? In my previous post I explained that Javascript lifts variable declarations to the top of the function. So, this code is equivalent to:
var n = 0;
function add2() {
var n;
n = n + 1;
print(n);
}
add2();
It also turns out that when a previously undeclared variable (in this scope) is declared it is initialized to undefined. So we get:
var n = 0;
function add2() {
var n = undefined;
n = n + 1;
print(n);
}
add2();
Any calculation involving undefined will return NaN, so naturally it will indeed print NaN. You can rewrite the code a little bit to make it print 1 again:
var n = 0;
var oldN = n;
function add3() {
var n = oldN + 1;
print(n);
}
add3();
It took me a while to figure this one out, though, when I ran into it. Just thought I would share.
Tags: javascript
I was watching http://channel9.msdn.com/posts/Charles/Introduc... and it seems there's a scope bug in IE:
function test() {
var x = 3;
try { throw 5; }
catch (x) {}
alert(x);
}
The output should be 3, but in IE it's 5. Apparently the scope rules are giving the IE team a hard time. :p
That's disappointing. Any version of IE in particular?
Nice clean example! I figured I’d add a variation of your example that highlights the case of javascript lifting variable declarations to the top of a function:
var x=0;
function add() {
x = x + 1;
if (false) { var x; }
return x;
}
add();
That will return NaN (not 1), because even though the
if (false)block doesn’t get executed and appears to do nothing, thevar xfloats up to the top of the function, which makesxundefined in the scope of the add function.Sorry for the late reply, but at least in IE8 (so most likely also in all previous versions).
Indeed. Here's a more direct example of hoisting.
if ( asdfghjkl in window ) {
alert(“Ohai”);
}
var asdfghjkl;