2

This is something that seems to have started with the latest Chrome update, and I'm trying to find information on it but have been unsuccessful. Consider the following code:

var lines = ['asdf','qwer',''];
for (var i in lines) console.log(i, lines[i]);

If I run that in the Firefox "Firebug" console, my output, as expected, is this:

0 asdf
1 qwer
2 (an empty string)

However, when I run it in the Chrome console, I get this:

0 asdf
1 qwer
2 
remove function ( from, to )
{
    var rest = this.slice((to || from) + 1 || this.length);
    this.length = from < 0 ? this.length + from : from;

    return this.push.apply(this, rest);
}

I've noticed that extra "remove" item coming up regularly. The problem is that it breaks several of the jQuery plugins I've downloaded for use, which have code like this:

for (var i in lines) {
    line = lines[i].split("=");
    ...

Since the extra element is a function, rather than a string, it doesn't have the split() function, and so my code stops dead in its tracks with an error. I don't want to have to go through all my code manually removing elements from arrays, so is there some kind of flag I can set or command I can run before execution to prevent the extra element from being added?

DiMono
  • 3,308
  • 2
  • 19
  • 40
  • 4
    Please *do not* use `for ... in` with arrays – Yuriy Galanter Oct 25 '13 at 19:56
  • what version of chrome exactly? It seems much more likely that this is coming from a plugin adding a `remove` to array's prototype. – numbers1311407 Oct 25 '13 at 19:57
  • 4
    `for (var in array)` includes inherited properties. You should either use a numeric iteration or check `lines.hasOwnProperty(i)`. See http://stackoverflow.com/questions/3010840/loop-through-array-in-javascript/3010848#3010848 – Barmar Oct 25 '13 at 20:00
  • I've edited my question to make it more clear that I did not write these plugins, they're things I've downloaded for use. – DiMono Oct 25 '13 at 20:09

1 Answers1

2

This looks like a classic reason why you should never use the construct for (var i in lines) to enumerate the entries in the array.

The for (var i in lines) construct enumerates properties of the array object, including things beyond numeric array indexes such as added properties and methods that are enumerable.

If you use for (var i = 0, len = lines.length; i < len; i++), you will only enumerate actual items in the array.


Our guess here is that some 3rd party library you are using is adding a .remove() method to the array object and thus when you iterate the enumerable properties of any array instance, you are also getting the remove property.

If you switch to the for (var i = 0, len = lines.length; i < len; i++) method of array enumeration, you will not have this problem.

for (var i = 0, len = lines.length; i < len; i++) {
    line = lines[i].split("=");
    ...
}

FYI, lines.hasOwnProperty(i) can also be used to work-around this issue, but if you just wnat to enumerate array items, you should really just use the proper way of enumerating arrays.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • Which is all well and good, but at this point I have a very large website that until recently worked, and now does not. I don't want to have to go through 40,000 lines of code looking for instances of `for ... in` and replacing them. And again, this only happens in Chrome, not Firefox. Is there a way to stop this from happening? – DiMono Oct 25 '13 at 20:12
  • @DiMono - your code is wrong and you have combined it with a 3rd party library that makes your wrong code break. You can fix it by either removing the 3rd party library that adds the `.remove` property or fix your code. Seriously, using `for (i in lines)` with lots of third party code around is a ticking time bomb and it just exploded on you. You really should just fix your code. If you don't fix your code now and find some work-around, your wrong code will probably just explode again some time in the future. Good software engineers take the time to fix wrong code. – jfriend00 Oct 25 '13 at 20:14
  • It's not code I wrote, it's mostly third-party jQuery plugins. However, I have confirmed that in a naked Chrome window it does not happen. So it is indeed to do with another plugin adding that .remove property. Thank you for your answer that suggested it might be the problem, it's time to go hunting. – DiMono Oct 25 '13 at 20:15
  • `for (i in lines)` is incompatible with plugins that add enumerable methods to the array object. You have to fix the code or remove the plugin. – jfriend00 Oct 25 '13 at 20:16