202

为什么我的 for-each 循环没有遍历我的 JavaScript 关联数组对象?

// Defining an array
var array = [];

// Assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";

// Expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
    console.log(array[i]);
}

jQueryeach()可能会有所帮助:https ://api.jquery.com/jQuery.each/

4

9 回答 9

349

.length属性仅跟踪具有数字索引(键)的属性。您正在使用字符串作为键。

你可以这样做:

var arr_jq_TabContents = {}; // no need for an array

arr_jq_TabContents["Main"] = jq_TabContents_Main;
arr_jq_TabContents["Guide"] = jq_TabContents_Guide;
arr_jq_TabContents["Articles"] = jq_TabContents_Articles;
arr_jq_TabContents["Forum"] = jq_TabContents_Forum;

for (var key in arr_jq_TabContents) {
    console.log(arr_jq_TabContents[key]);
}

为了安全起见,最好在这样的循环中确保没有任何属性是继承的意外结果:

for (var key in arr_jq_TabContents) {
  if (arr_jq_TabContents.hasOwnProperty(key))
    console.log(arr_jq_TabContents[key]);
}

编辑——现在注意该Object.keys()函数在现代浏览器和 Node 等中可用可能是个好主意。该函数以数组的形式返回对象的“自己的”键:

Object.keys(arr_jq_TabContents).forEach(function(key, index) {
  console.log(this[key]);
}, arr_jq_TabContents);

传递给的回调函数.forEach()被调用,每个键和键在数组中的索引由Object.keys(). 它还传递了函数正在迭代的数组,但该数组对我们并没有真正的用处;我们需要原始对象。这可以通过名称直接访问,但是(在我看来)显式传递它会更好一些,这是通过将第二个参数传递给.forEach()原始对象来完成的,该对象将this在回调内部绑定。(刚刚看到下面的评论中提到了这一点。)

于 2013-09-14T17:42:52.860 回答
91

这是非常简单的方法。优点是您也可以获得密钥:

for (var key in array) {
    var value = array[key];
    console.log(key, value);
}

对于 ES6:

array.forEach(value => {
  console.log(value)
})

对于 ES6(如果你想要值、索引和数组本身):

array.forEach((value, index, self) => {
  console.log(value, index, self)
})
于 2015-03-14T02:35:33.850 回答
9

如果 Node.js 或浏览器支持Object.entries(),它可以用作替代使用Object.keys()Pointy 的回答)。

const h = {
  a: 1,
  b: 2
};

Object.entries(h).forEach(([key, value]) => console.log(value));
// logs 1, 2

在此示例中,forEach使用数组的解构赋值。

于 2019-02-11T08:48:22.320 回答
7

已经有一些简单的示例,但我从您对问题的措辞中注意到您可能来自 PHP 背景,并且您期望 JavaScript 以相同的方式工作 - 但事实并非如此。PHParray与 JavaScript 非常不同Array

在 PHP 中,关联数组可以完成数字索引数组可以完成的大部分工作(array_*函数可以工作,您可以count(),等等)。您只需创建一个数组并开始分配给字符串索引而不是数字。

在 JavaScript 中,一切都是对象(除了原语:字符串、数字、布尔值),而数组是一种允许您拥有数字索引的特定实现。任何推送到数组的东西都会影响它,并且可以使用数组方法( , , , ,等)length进行迭代。但是,因为一切都是对象,所以您总是可以自由地简单地分配属性,因为这是您要做的事情任何物体。方括号表示法只是访问属性的另一种方式,因此在您的情况下:mapforEachreducefilterfind

array['Main'] = 'Main Page';

实际上相当于:

array.Main = 'Main Page';

根据您的描述,我的猜测是您想要一个“关联数组”,但对于 JavaScript,这是使用对象作为哈希图的简单案例。另外,我知道这是一个示例,但要避免仅描述变量类型的无意义名称(例如array),以及基于它应该包含的内容的名称(例如pages)。简单的对象没有很多好的直接迭代方法,所以我们通常会先使用可以循环的Object方法(Object.keys在这种情况下——现在也有entries并被values添加到某些浏览器中)将其转换为数组。

// Assigning values to corresponding keys
const pages = {
  Main: 'Main page',
  Guide: 'Guide page',
  Articles: 'Articles page',
  Forum: 'Forum board',
};

Object.keys(pages).forEach((page) => console.log(page));
于 2017-02-12T13:26:18.773 回答
4

arr_jq_TabContents[key]将数组视为 0 索引形式。

于 2016-08-05T11:45:38.437 回答
4

这是使用关联数组作为泛型 Object 类型的简单方法:

Object.prototype.forEach = function(cb){
   if(this instanceof Array) return this.forEach(cb);
   let self = this;
   Object.getOwnPropertyNames(this).forEach(
      (k)=>{ cb.call(self, self[k], k); }
   );
};

Object({a:1,b:2,c:3}).forEach((value, key)=>{ 
    console.log(`key/value pair: ${key}/${value}`);
});

于 2018-06-08T09:29:06.253 回答
1

在大多数情况下,这(基本上)是不正确的:

var array = [];
array["Main"] = "Main page";

这会在数组上创建一个名为 name 的非元素属性Main。尽管数组是对象,但通常您不想在它们上创建非元素属性。

如果您想array通过这些名称进行索引,通常您会使用一个Map或一个普通对象,而不是一个数组。

使用Map(ES2015+),map因为我很有创意,所以我会调用它:

let map = new Map();
map.set("Main", "Main page");

values然后,您使用其、keys或方法中的迭代器对其进行迭代entries,例如:

for (const value of map.values()) {
    // Here, `value` will be `"Main page"`, etc.
}

使用一个普通的对象,我将创造性地称之为obj

let obj = Object.create(null); // Creates an object with no prototype
obj.Main = "Main page"; // Or: `obj["Main"] = "Main page";`

然后,您将使用 、 或 迭代其内容Object.keysObject.values例如Object.entries

for (const value of Object.values(proches_X)) {
    // Here, `value` will be `"Main page"`, etc.
}
于 2019-09-02T17:37:26.817 回答
0

var obj = {
  no: ["no", 32],
  nt: ["no", 32],
  nf: ["no", 32, 90]
};

count = -1; // Which must be a static value
for (i in obj) {
  count++;
  if (obj.hasOwnProperty(i)) {
    console.log(obj[i][count])
  };
};

在这段代码中,我使用括号方法来调用数组中的值,因为它包含一个数组。但是,简要地介绍一下变量i具有属性键和循环调用关联数组的两个值的想法。

这是完美的方法。

于 2017-09-27T20:46:11.810 回答
0

你可以这样做:

var array = [];

// Assigning values to corresponding keys
array[0] = "Main page";
array[1] = "Guide page";
array[2] = "Articles page";
array[3] = "Forum board";


array.forEach(value => {
    console.log(value)
})

 

于 2020-03-14T13:31:09.093 回答