If you are in the global scope already, the difference is so small that you don't have to worry about it
imagine that you had two for
loops, and you wanted to do something with them.
.
for (i = 0; i < elements.length; i++) {
element = elements[i];
for (i = 0; i < items.length) {
item = items[i];
element.add(item);
}
}
This piece of pseudo-code would work fine in many different languages.
The program would see an inner-loop and an outer-loop, and could tell that i
wasn't referring to the same thing.
In JavaScript, they're the same i
.
That's because other languages have block-scope -- any time you enter new curly braces, the program treats variables like they're new.
In JavaScript there is only function scope, meaning that inside of functions variables are treated as new, but inside of control statements (if
, for
, switch
), they're the same variable with the same value.
So the outer loop sets i
to 0, and then goes into the inner loop.
The inner loop goes through all of its list of items, and builds i
up as it goes...
Then it goes back to the outer loop, and i
still equals items.length - 1
...
If that's less than elements.length
then it adds one to i
, which is now higher than items
length, so nothing happens in the inner loop, anymore...
...if items.length
is greater than elements.length
instead, then the outer loop just ends after one time through.
Now, I'm sure that you can start to think about times where you might want to use x
or name
or value
or el
or sum
or i
or default
or src
or url
or img
or script
, etc several times in your whole program (tens of thousands of lines, even), and you can start to think about situations like that loop up above, where things could go wrong if you tried calling two different things by the same name.
This is the same problem as var-fallthrough
If you have one function which uses a variable called x
and another function which uses another variable called x
, that's great...
...unless you forget to declare the variable.
// no problems!
function func1 () { var x = 0; }
function func2 () { var x = "Bob"; }
// big problems!
function func1 () { x = 0; }
function func2 () { x = "Bob"; }
func1
set window.x = 0;
func2
set window.x = "Bob";
...if window.x
was supposed to equal 42, for some other program to work right, now you have the potential to have 3 broken apps, just because of a few missing var
s.
It doesn't instantly set the global variable, though. What it actually does is goes through the function chain. If you create a function inside of another function, then an undeclared var will look to its parent's vars, and then its grandparent's vars and then its great-grandparent's vars...
If it gets all the way to window
and nobody has a var of that name, then it creates one with that name on window
.
function func1 () {
var x = 0;
function func2 () {
var y = 1;
x = 2;
z = 3;
}
func2();
}
When you call func1, it sets its own x
to 0, and calls func2.
func2 sets its own y
to 1.
Then it sets func1's x
to 2.
Then, because func2 doesn't have z
and func1 doesn't have z
and window
doesn't have z
, it sets window.z
to 3.
That's only the start of the confusion, and why its a very, very good idea to make sure that you're defining vars which need to be available inside of that function (and in any functions created inside of that function)...
...and when you reference pre-existing vars, you reference them carefully, and know where that var is supposed to be, in your code (which function defined it... ...so where on the chain the program is going to stop looking, before it gets to window
), and why you're changing it from inside of another function.