为什么在 javascript 中向数组原型添加方法会破坏 for 循环上的迭代

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

本文关键字:for 循环 迭代 方法 javascript 数组 添加 原型 为什么      更新时间:2023-09-26

我正在一个大型遗留代码库中工作,刚刚意识到有人这样做了:

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

我不能这样做的原因:

var derp = new Array();
derp.push('duh');
derp.push('what?');
for (var i in derp) {
    console.log(derp[i]);
}

好吧,不是我做不到,而是如果我这样做,我会得到意想不到的结果。 也就是说,我得到的不是两行输出(对于"duh"和"什么?"),而是得到四行。 最后两个是上面列出的两个函数。

我不想删除原始原型函数(因为上帝知道什么依赖于它们),但我想知道是否有办法防止 for 循环遍历添加的函数。

方法 1:使用常规 for(最好支持)

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

方法 2: 使用 hasOwnProperty

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

方法 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])
}

您使用哪一个取决于您的浏览器支持,最后一个可以防止更改所有编写的代码

使用 .forEach

遍历数组或常规 for 循环。 for in 用于对象迭代,并将包含原型上的所有属性(这就是为什么 Object.keys(obj).forEach 是对象迭代的首选,因为它在内部执行 hasOwnProperty 检查)

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

但是,正常的for循环对Array来说比使用for-in(实际上是针对Object的)要好得多。

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