7

Perhaps I'm not aware of how for loop index variables get scoped, but I was very surprised when one of my loops didn't complete, seemingly because a function called from within a loop contained an i for its for loop index as well.

Here's a little script I put together to demonstrate this behavior:

var loopOne = function(test) {
    for(i = 0; i < test.length; i++)
        console.log(getMask(test));
};

var getMask = function(pass) {      
    var s = "";
    for (i = 0; i < pass.length; i++) {
        s = s + "*";
    }
    return s;      
};

loopOne('hello');

If I run this in Chrome and look at the console log, I should see ***** five times. However, I only see it once. Upon further inspection, if I type i in the Chrome javascript console, it will output 6 ( = 'hello'.length + 1). This makes me think that i has become a part of the global scope and is not limited to the scope of the for loop for which it was needed.

Is this correct? If so, what's a better practice for defining the index variable of a for loop in javascript?

ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
Ben McCormack
  • 32,086
  • 48
  • 148
  • 223

3 Answers3

12

In Javascript, variables are scoped with the var keyword. When declaring variables with var, the variable is scoped to the current function. When assigning to a variable without using the var keyword, it is assumed you're talking about an already defined variable in the same or a higher scope. If none is found, the variable is created in the highest scope.

Bottom line: declare all your variables using var.

deceze
  • 510,633
  • 85
  • 743
  • 889
  • 1
    "If none is found, the variable is created in the highest scope." That's just evil. Thanks for the explanation about scoping using `var`. Now that you mention it, I should have remembered that. – Ben McCormack May 18 '11 at 01:39
  • @Ben Indeed, it's one of the many pitfalls of Javascript. AFAIK this is being/was rectified in the latest ECMAScript spec. – deceze May 18 '11 at 01:40
  • I think only if you add `"use strict"`. – alex May 18 '11 at 01:55
  • 1
    Rember that javascript was intended as a simple, easy to use language. It also needs to support closures so assigning to undeclared idnetifiers is reasonabley common. So undeclared variables are added to the global object **when they are first assigned a value**, not before. – RobG May 18 '11 at 02:01
  • @Rob Added that as clarification. – deceze May 18 '11 at 02:03
10

You should declare your loop index variable with let:

for (let i = 0; i < test.length; i++) ...

That will declare and set the proper scope for the variable.

Jordão
  • 55,340
  • 13
  • 112
  • 144
4

When you declare your variables with var, you scope them to the current execution context.

When you don't, they become properties of the global object (window in a browser).

alex
  • 479,566
  • 201
  • 878
  • 984