Javascript 意外的JS原型行为

Javascript 意外的JS原型行为,javascript,arrays,Javascript,Arrays,我最近为JS阵列原型编写了几个扩展 Array.prototype.diff = function (a) { return this.filter(function (i) { return !(a.indexOf(i) > -1); }); }; Array.prototype.udiff = function (a, b) { var rslt = this.concat(b); return rslt.filter(function

我最近为JS阵列原型编写了几个扩展

Array.prototype.diff = function (a) {
    return this.filter(function (i) {
        return !(a.indexOf(i) > -1);
    });
};

Array.prototype.udiff = function (a, b) {
    var rslt = this.concat(b);
    return rslt.filter(function (i) {
        return !(a.indexOf(i) > -1);
    });
};
那里没有什么特别令人兴奋的事。但后来我遇到了一些非常不寻常的事情。这里有一个例子

var arr = [];
for (prop in arr) {
    arr[prop].attrib = arr[prop].attrib.replaceAll('_', ' ', true);
}
这是一段看起来很无辜的代码,但我看到一个错误,大意是“undefined没有方法replaceAll-其中replaceAll是我自己的String.prototype扩展名

解决方案很简单-在操作arr[prop]之前,只需解决这个问题

if ('string' == typeof(prop)) continue;
原因是,道具也可以是diffudiff。所以,问题解决了,但这种行为确实让我失去了警惕,不得不做额外类型的测试听起来确实很笨拙。也许这里有人对原型扩展有更深入的了解


我应该提到的是,所有这些问题都发生在Windows上的Chrome中。

javascript中的for-each循环会迭代对象中的所有符号(包括原型中的符号)。这就是为什么您会得到这样的结果。这也是为什么您应该始终将函数与for-each循环结合使用的原因

var arr = [];
for (prop in arr) {
    if(arr.hasOwnProperty(prop)) {
        arr[prop].attrib = arr[prop].attrib.replaceAll('_', ' ', true);
    }
}
有关详细说明,请参阅


问题解决了,但这种行为确实让我放松了警惕,不得不做额外类型的测试听起来确实很笨拙

正确的方法是迭代它们,直到它们的长度:

for (var i=0; i<arr.length; i++) {
    arr[i].attrib = arr[i].attrib.replaceAll('_', ' ', true);
}

for(var i=0;i可能的重复项或defineProperty允许使属性不可枚举(即,这不是向对象类型添加方法的正确方法).不。您可以合理地期望值得枚举的对象没有非预期继承的可枚举属性,因此不需要
hasOwnProperty
。对于数组,您应该只使用适当的
for(var i=0;iGood point,@Bergi。如果回答这个问题,我将接受它。-1,
for(a中的var p)
是迭代数组中的值的错误方法,无论您如何“强化”它。