9

我有一个稀疏数组,其内容不能保证按索引顺序插入,但需要按索引顺序迭代。要遍历稀疏数组,我知道您需要使用 for..in 语句。

但是,根据这篇文章

不能保证 for...in 会以任何特定顺序返回索引

但是像这样的stackoverflow问题表明,虽然不能保证对象属性顺序,但数组顺序是:

JavaScript 不保证对象中的属性顺序,您需要使用数组。

我在最新版本的 Chrome、Firefox 和 IE 中对此进行了测试。

<ol id="items"></ol>
var list = [];

function addItem(index) {
    list[index] = { idx : index };
}

var insertOrder = [ 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 ];

for ( var i = 0; i < 15; i++ ) {
    addItem(insertOrder[i]);
}

for(var item in list) {
    $("#items").append("<li>" + list[item].idx + "</li>");
}

所有人似乎都尊重索引顺序,所以我可以相信这总是如此吗?否则,我如何最好地按索引顺序获取它们?

4

2 回答 2

12

MDN有你原来问题的答案:

注意:for..in 不应用于迭代索引顺序很重要的数组。

数组索引只是具有整数名称的可枚举属性,在其他方面与一般 Object 属性相同。不能保证 for...in 会以任何特定顺序返回索引,并且它将返回所有可枚举的属性,包括具有非整数名称的属性和继承的属性。

您不必使用for..in遍历稀疏数组,如果可以的话,您绝对应该避免这样做。

您可以使用.forEach

list.forEach(function (el) {  // add a second parameter if you need the indices
    $("#items").append($("<li>").text(el.idx));
});

forEach 被定义为按索引顺序迭代,并且只包含数组中存在的元素:

forEach对数组中存在的每个元素按升序执行一次提供的回调。它不会为已删除或删除的索引调用。但是,它会针对存在且值为 undefined 的元素执行。


如果您的目标环境不支持forEach,则可以使用以下内容或该 MDN 页面上提供的 shim:

for (var i = 0; i < list.length; i += 1) {
    if (i in list) {
        $("#items").append($("<li>").text(list[i].idx));
    }
}
于 2014-12-22T07:36:37.087 回答
1

ECMAScript 2015 中的 for...of 结构仅迭代数组数据(不是原型方法)并保证顺序。请参阅 MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/fBlockquoteor...of和这个答案:“for...of”循环迭代是否遵循数组顺序JavaScript?

请参阅在 for-of 循​​环中访问 ES6 数组元素索引以检索索引。请注意, for..of 迭代数组中未定义的孔/空值,因此您需要检查是否key in array不想要这些。

此处进一步讨论:https ://groups.google.com/forum/#!topic/strengthen-js/jj7UX -fU-_A - 表明 javascript 缺少有序的地图数据结构。

于 2018-04-11T04:11:42.940 回答