简体   繁体   English

为什么在javascript中向Array原型添加方法会中断for循环上的迭代?

[英]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. 那不是得到两行输出(“ duh”和“ what?”),而是四行。 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. 我不想删除原始的原型函数(因为上帝知道什么取决于它们),但是我想知道是否有一种方法可以防止for循环遍历添加的函数。

Use .forEach to iterate over an array or a regular for loop. 使用.forEach遍历数组或常规for循环。 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) for in是用于对象迭代的,并且将包括原型上的所有属性(这就是为什么Object.keys(obj).forEach是对象迭代首选的原因,因为它在内部进行hasOwnProperty检查)

Method 1: Use a regular for (best supported) 方法1:使用常规(最佳支持)

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

Method 2: Use hasOwnProperty 方法2:使用hasOwnProperty

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

Method 3: Use Object.defineProperty: 方法3:使用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循环对于Array要比使用for-in (实际上是针对Object)要好得多

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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