我最近写了几个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中。
答案 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);
}
}