关联数组对象的Javascript foreach循环

Szy*_*oda 167 javascript arrays foreach

为什么我的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]);
}
Run Code Online (Sandbox Code Playgroud)

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

Poi*_*nty 296

.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]);
}
Run Code Online (Sandbox Code Playgroud)

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

for (var key in arr_jq_TabContents) {
  if (arr_jq_TabContents.hasOwnProperty(key))
    console.log(arr_jq_TabContents[key]);
}
Run Code Online (Sandbox Code Playgroud)

编辑 - 现在可能是一个好主意,要注意该Object.keys()功能在现代浏览器和Node等中可用.该函数返回一个对象的"自己"键,作为一个数组:

Object.keys(arr_jq_TabContents).forEach(function(key, index) {
  console.log(this[key]);
}, arr_jq_TabContents);
Run Code Online (Sandbox Code Playgroud)

.forEach()使用每个键和返回的数组中的键索引调用传递给的回调函数Object.keys().它也传递了函数迭代的数组,但是这个数组对我们并没有用; 我们需要原始的对象.这可以通过名称直接访问,但是(在我看来)显式传递它会更好一点,这是通过传递第二个参数来实现的.forEach()- 原始对象 - 它将被绑定this在回调内部.(只是看到这在下面的评论中被注明.)

  • 所有现代Web浏览器都应该可以使用:Object.keys(arr_jq_TabContents).forEach(function(key){...});而不是使用hasOwnProperty,它可以在所有现代Web浏览器中迭代对象的键. (7认同)

tik*_*ika 73

这是一种非常简单的方法.优点是你也可以获得钥匙:

for (var key in array) {
    var value = array[key];
    console.log(key, value);
}
Run Code Online (Sandbox Code Playgroud)

对于ES6:

array.forEach(value => {
  console.log(value)
})  
Run Code Online (Sandbox Code Playgroud)

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

array.forEach((value, index, self) => {
  console.log(value, index, self)
})  
Run Code Online (Sandbox Code Playgroud)

  • 不要在循环中使用`var`来建议不存在的范围.在循环前面使用`var`或在循环中使用`let`. (12认同)
  • @Dennis在大多数语言中,`for`循环中的变量声明生成一个仅限于`for`循环体的范围.但是在JavaScript中,`var`声明的变量总是函数全局,即使你在`for`循环中写它.见这里:https://davidwalsh.name/for-and-against-let (6认同)
  • @ceving,你能解释一下为什么不在循环中使用var吗?我来自C++/PHP背景,我不明白这一点.范围确实存在于循环中,但是暂时的,所以我不确定你的意思. (2认同)

ban*_*yan 8

如果 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
Run Code Online (Sandbox Code Playgroud)

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


Jos*_*bou 5

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

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

在JavaScript中,所有内容都是一个对象(基本类型除外:字符串,数字,布尔值),数组是一种特定的实现,可让您拥有数字索引。任何事情推到一个数组会影响它length,并且可以重复使用以上Array方法(mapforEachreducefilterfind,等),但因为一切是一个对象,你总是可以简单地分配属性,因为这是你做的东西任何物体。方括号表示法只是访问属性的另一种方法,因此在您的情况下:

array['Main'] = 'Main Page';
Run Code Online (Sandbox Code Playgroud)

实际上等效于:

array.Main = 'Main Page';
Run Code Online (Sandbox Code Playgroud)

根据您的描述,我的猜测是您需要一个“关联数组”,但是对于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));
Run Code Online (Sandbox Code Playgroud)