简体   繁体   中英

Why does adding a method to the Array prototype in javascript break iteration on a for loop?

I'm working in a large legacy codebase and just realized that someone did this:

Array.prototype.insertAt = function (i,el){ return this.splice(i,0,el); }
Array.prototype.deleteAt = function (i){return this.splice(i, 1); }

and that this is the reason i can't to this:

var derp = new Array();
derp.push('duh');
derp.push('what?');

for (var i in derp) {
    console.log(derp[i]);
}

Well, it's not that i can't do it, but if i do, i get unexpected results. That being instead of getting two lines of output (for 'duh' and 'what?') i get four. the last two being the two functions listed above.

I don't want to remove the original prototype functions (because god knows what depends on them), but i am wondering if there is a way to prevent the for loop from looping over the functions that were added.

Use .forEach to iterate over an array or a regular for loop. for in is meant for object iteration and will include all properties on the prototype (which is why Object.keys(obj).forEach is preferred for object iteration as it does a hasOwnProperty check internally)

Method 1: Use a regular for (best supported)

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

Method 2: Use hasOwnProperty

for(var i in arr){
 if(arr.hasOwnProperty(i)){
     console.log(i)
  }
}

Method 3: Use Object.defineProperty:

Object.defineProperty(Array.prototype, 'insertAt', {
    writeable: true,
    enumerable: false,
    value: Array.prototype.insertAt
})
Object.defineProperty(Array.prototype, 'deleteAt', {
    writeable: true,
    enumerable: false,
    value: Array.prototype.deleteAt
})

for(var i in derp){
    console.log(derp[i])
}

Which one you use depends on your browser support, last one prevents changing all for code written though

for (var i in derp) {
    if(derp.hasOwnProperty(i)) 
        console.log(derp[i]);
}

But then, normal for loop is far better for Array than using for-in (which is actually for Object)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM