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?
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With