在Javascript中如何“正确地”迭代数组有太多的困惑。至少有两个帖子有几百个赞成票,但答案非常矛盾。我很困惑。
ES5添加了Array.prototype.forEach函数。这是最终的答案吗?还是还有陷阱需要避免?
如果有的话,请发布真实的迭代。我可以使用ES5,如果你不知道你在说什么,不要发帖。
发布于 2013-11-08 02:07:32
答案很简单:如果你想避免令人不快的意外,就没有办法理解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'这是怎么回事?请参阅实现Array.prototype.forEach的spec-compliant algorithm on MDN (在“兼容性”下)。
a.forEach(myCallback)或多或少等同于我们经常看到的
for (var p = 0, len = a.length; p < len; p++) {
if (p in a)
myCallback(a[p], p, a);
}这意味着它也会遍历原型链中的属性!但只是以一种不太可靠的方式,因为它只在满足p < len的属性上循环。
100%可靠的方法:
下面的版本只迭代可枚举的属性。可以使用Object.getOwnPropertyNames函数代替Object.keys来包含不可枚举的属性。
数字、own、顺序
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);
}我不认为最后一个是一个糟糕的选择。这是一种非常诚实和简洁的迭代方式。作为附注,顺序数值迭代已被证明在大多数实现上具有性能优势,至少对于非稀疏数组是如此;但这可能不是规范的错误。
https://stackoverflow.com/questions/19843420
复制相似问题