1

我最近为 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);
}

一段看起来很无辜的代码,但它返回给我的错误是“未定义没有方法 replaceAll - 其中 replaceAll 是我自己的 String.prototype 扩展。

解决方案很简单 - 在操作 arr[prop] 之前只需发出

if ('string' == typeof(prop)) continue;

原因是 prop 也可以是diffudiff。所以,问题解决了,但这种行为确实让我失去了警惕,不得不做额外的 typeof 测试听起来很笨拙。也许这里有人对原型扩展会发生什么有更深入的了解?

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

4

2 回答 2

2

有关详细说明,请参阅此答案


问题解决了,但这种行为确实让我失去了警惕,不得不做额外的 typeof 测试听起来很笨拙。

正确的方法是不要for in在数组上使用循环,而是迭代它们直到它们的长度:

for (var i=0; i<arr.length; i++) {
    arr[i].attrib = arr[i].attrib.replaceAll('_', ' ', true);
}
于 2013-09-06T13:33:30.560 回答
0

好吧,javascript 中的 for each 循环遍历对象中的所有符号(包括原型中的符号)。这就是为什么你得到你所做的结果。这也是为什么您应该始终将该函数hasOwnProperty()与 for each 循环结合使用。

var arr = [];
for (prop in arr) {
    if(arr.hasOwnProperty(prop)) {
        arr[prop].attrib = arr[prop].attrib.replaceAll('_', ' ', true);
    }
}
于 2013-09-06T12:52:30.973 回答