意外的JS原型行为

时间:2013-09-06 12:43:22

标签: 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 (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;

道具的原因也可能是差异 udiff 。所以,问题解决了,但这种行为确实让我失控,不得不做额外的类型测试听起来笨拙。也许这里有人对原型扩展会发生什么有更深入的了解?

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

2 个答案:

答案 0 :(得分:2)

有关详细说明,请参阅this answer


  

问题解决但这种行为确实让我措手不及,不得不做额外的类型测试听起来很笨拙。

正确的方法是not to use for in loops on arrays但是迭代它们直到它们的长度:

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

答案 1 :(得分:0)

对于javascript中的每个循环,迭代对象中的所有符号(包括原型中的那些符号)。这就是你获得结果的原因。这也是为什么你应该总是将函数hasOwnProperty()与for循环结合使用。

var arr = [];
for (prop in arr) {
    if(arr.hasOwnProperty(prop)) {
        arr[prop].attrib = arr[prop].attrib.replaceAll('_', ' ', true);
    }
}