Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IE8 for...in enumerator

So I am using this in IE8:

var hi=["hi", "lo", "foo", "bar"];
for(i in hi){console.log(i)};
//WTF is that indexOf i value?
LOG: 0
LOG: 1
LOG: 2
LOG: 3
LOG: indexOf
undefined

In chrome and others, I'll just get 0-3, no mysterious "indexOf" thing. Why and what's the fix?

like image 534
randomor Avatar asked Jan 31 '12 18:01

randomor


3 Answers

Don't use for...in for arrays. It's best to use the traditional for loop in that case.

The reason is because for...in looks at the array as an object, and therefore properties like indexOf or length may be included in the loop. The normal for loop only deals with numeric keys, so this problem is avoided.

On a side note, unwanted properties could show up when iterating over plain objects as well (as others have noted, properties you add to the object's prototype will show up). You can get around this by writing your for...in loops this way:

var obj = { ... };
for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    var item = obj[prop];
    ...
  }
}

To be clear though: you still shouldn't use this method on arrays.

like image 168
benekastah Avatar answered Oct 31 '22 02:10

benekastah


You're using the wrong type of loop for an array - for ... in ... will also include any enumerable properties of the object, which in your case includes the .indexOf() method.

Use this instead:

var i, n = hi.length;
for (i = 0; i < n; ++i) {
    console.log(i, hi[i]);
}

Chrome and other up to date browsers implement ECMAScript 5, and correctly mark all built-in methods as non-enumerable properties.

like image 27
Alnitak Avatar answered Oct 31 '22 02:10

Alnitak


This is happening because a script you are including on your page is adding the indexOf method to Array.prototype. This means all arrays inherit an indexOf method, which is good, since it means you can use that method even in IE8.

But, since there is no way to mark a property as non-enumerable in IE8, you will end up seeing it every time you enumerate over all the properties of the array, which is what you do in a for-in loop. You probably wanted a for loop instead.

like image 4
Domenic Avatar answered Oct 31 '22 04:10

Domenic