关于如何“正确”迭代 Javascript 中的数组存在很多困惑。至少有两个帖子有数百个赞,但答案非常矛盾。我很困惑。
ES5 添加了Array.prototype.forEach
功能。这是最终的答案,还是还有避免介入的陷阱?
如果有,请发布真正的一次迭代。我可以使用 ES5 如果您不知道自己在说什么,请不要发帖。
关于如何“正确”迭代 Javascript 中的数组存在很多困惑。至少有两个帖子有数百个赞,但答案非常矛盾。我很困惑。
ES5 添加了Array.prototype.forEach
功能。这是最终的答案,还是还有避免介入的陷阱?
如果有,请发布真正的一次迭代。我可以使用 ES5 如果您不知道自己在说什么,请不要发帖。
简单的回答:如果你想避免不愉快的意外,没有办法理解 Javascript 的对象模型,包括原型继承。Javascript 数组基本上是具有一些附加属性的对象,它们与任何其他流行语言中的数组都非常不同。
Array.prototype.forEach
并且还有jquery.each
一个比干净更大的陷阱for (var k in a)
通常建议不要的清洁更大的陷阱。我还没有看到任何其他帖子中提到的这个陷阱。
看:
Array.prototype[2] = 'hi';
var a = [];
a.forEach(alert); // nothing
alert(a); // ''
a[3] = 3;
a.forEach(alert); // 'hi', then '3'
alert(a); // ',,hi,1'
这里发生了什么事?请参阅MDN (在“兼容性”下)实现的规范兼容算法Array.prototype.forEach
。
a.forEach(myCallback)
或多或少等同于常见的
for (var p = 0, len = a.length; p < len; p++) {
if (p in a)
myCallback(a[p], p, a);
}
这意味着它也循环遍历原型链中的属性!但只是以一种不太可靠的方式,因为它只循环遍历满足的属性p < len
。
以下版本仅迭代可枚举属性。该Object.getOwnPropertyNames
函数可以用来代替Object.keys
包含不可枚举的属性。
数字的,自己的,顺序的
a.forEach(function(v, k, a) {
if (a.hasOwnProperty[k])
myCallback(v, k, a);
});
自己的,顺序的
Object.keys(a).sort(mySortFunc).forEach(function(k) {
myCallback(a[k], k, a);
});
数字的,顺序的
alert("Don't do it");
自己的
Object.keys(a).forEach(function(k) {
myCallback(a[k], k, a);
});
(没有限制)
for (var k in a) {
myCallback(a[k], k, a);
}
我不认为最后一个是一个糟糕的选择。这是一种非常诚实和简洁的迭代方式。作为旁注,顺序数值迭代已被证明在大多数实现中具有性能优势,至少对于非稀疏数组而言。但也许这不是规范的错。