JavaScript: Global By Default
September 1, 2008
Here's a very simple JavaScript function that prints the sum of its arguments:
function sum() {
s = 0;
for(i=0; i < arguments.length; i++) {
s += arguments[i];
}
return s;
}
document.write('sum = '+sum(1, 2, 3));
Looks simple enough. Translated directly into non-idiomatic Ruby, that would be:
def sum(*args)
s = 0
i = 0
while i < args.length
s += args[i]
i += 1
end
s
end
So let's say you now want your sum function to return the sum of the factorial of each number. No problem:
function sum() {
s = 0;
for(i=0; i < arguments.length; i++) {
s += factorial(arguments[i]);
}
return s;
}
function factorial(n) {
f = 1;
for(i=1; i <= n; i++) {
f *= i;
}
return f;
}
document.write('sum = '+sum(1, 2, 3));
Oops. That prints 1, but the answer we were looking for was 9. Hmmm, let's translate it to ruby and see what we get:
def sum(*args)
s = 0
i = 0
while i < args.length
s += factorial(args[i])
i += 1
end
s
end
def factorial(n)
s = 1
i = 1
while i <= n
s = s * i
i += 1
end
s
end
puts sum(1, 2, 3)
Ok, so Ruby gives us 9. So what's up? The truth is that is not a direct translation. Here's the correct translation:
def sum(*args)
$s = 0
$i = 0
while $i < args.length
$s += factorial(args[$i])
$i += 1
end
$s
end
def factorial(n)
$s = 1
$i = 1
while $i <= n
$s = $s * $i
$i += 1
end
$s
end
puts sum(1, 2, 3)
This gives us the same result as the flawed JavaScript, which is 1. As you can see, in both functions, the variables s and i are declared as global variables, which you can tell by the $ sigil. But in JavaScript, variables are global by default. That's right, the simple little innocuous-looking i=0 in our JavaScript for loop defines a global variable. Here is the corrected JavaScript version:
function sum() {
var s = 0;
for(var i=0; i < arguments.length; i++) {
s += factorial(arguments[i]);
}
return s;
}
function factorial(n) {
var f = 1;
for(var i=1; i <= n; i++) {
f *= i;
}
return f;
}
document.write('sum = '+sum(1, 2, 3));
The moral of the story is always prefix your variable declarations with var. If you are a web developer who writes JavaScript and this is news to you, stop what you are doing an read Douglas Crockford's JavaScript: The Good Parts.