43

在 JavaScript 中,我可以有一个带孔的数组:

a = [];
a[0] = 100;
a[5] = 200;
a[3] = 300;

a.forEach(function(x) {alert(x);});

我找不到有关元素是否会按升序处理的信息,或者这不是可靠的事实。

我检查了“for .. in”循环以升序遍历数组索引,而对象的属性名称以它们添加到对象的相同顺序遍历(至少看起来如此)。

(即看起来数组是某种内部树,而对象是哈希表。)

我刚刚发现 Rhino JavaScript 也遍历了不存在的元素:http: //ideone.com/7Z3AFh(不像 for..in)。

4

3 回答 3

71

ECMA-262 第 5 版规范和MDN 的Array.forEach()页面都显示了 的算法.forEach(),并且它肯定会按索引升序迭代数组元素(跳过从未分配过值的索引)。

当然,某些浏览器可能无法正确实现该算法,但我不知道有哪些没有。

于 2012-11-28T08:46:16.173 回答
15

规范说 forEach将按数字顺序访问数组元素。它不会访问不存在的元素。有关详细信息,请参阅链接。因此,对于您的示例数组,它将访问 element 0、 then 3、 then 5。将它们添加到数组中的顺序对访问它们的顺序没有影响。

我检查了“for .. in”循环以升序遍历数组索引,而对象的属性名称以它们添加到对象的相同顺序遍历(至少看起来如此)。

规范没有for-in定义访问对象属性的顺序,即使在 ES2015(又名 ES6)中也没有定义,尽管 ES2015定义了对象属性的顺序 ——该顺序不适用于or 。(有关此答案的更多信息。)如果您想按 ES2015 中定义的顺序访问属性,您可以使用(对于未使用名称定义的属性)或(对于两者和字符串属性名称[记住数字属性名称是真的是字符串])。两者尊重财产秩序。for-inObject.keysObject.getOwnPropertyNamesSymbolReflect.ownKeysSymbol

于 2012-11-28T08:45:47.053 回答
4

直接脱离ECMAScript 标准

forEach为数组中存在的每个元素按升序调用一次 callbackfn。callbackfn 仅对实际存在的数组元素调用;它不需要数组的缺失元素。

所以 Array.forEach 将跳过数组中的某些元素。你的例子

a.forEach( function( value ) { console.log( value ) }); // prints 100, 300, 200

如果您确实想按升序遍历数组并且所有元素都是数字,那么您可以像这样预先对数组进行排序

a.sort( function( a, b ) { return a - b });
// this now prints 100, 200, 300
a.forEach( function( value ) { console.log( value ) }); 
于 2012-11-28T08:42:39.587 回答