JavaScript中的For..In循环-键值对


414

我想知道是否有办法foreach在JavaScript中执行类似PHP 循环的操作。我正在寻找的功能类似于以下PHP代码片段:

foreach($data as $key => $value) { }

我当时在看JS for..in循环,但是似乎没有办法指定as。如果我使用“普通”的for循环(for(var i = 0; i < data.length; i++)执行此操作,是否有办法获取键=>值对?

Answers:


215

如果您可以在本地使用ES6或与Babel(js编译器)一起使用,则可以执行以下操作:

const test = {a: 1, b: 2, c: 3};

for (const [key, value] of Object.entries(test)) {
  console.log(key, value);
}

将输出以下输出:

a 1
b 2
c 3

Object.entries()方法返回给定对象自己的可枚举属性[key, value]对的数组,其顺序与for...in循环提供的顺序相同(不同之处在于,for-in循环也枚举原型链中的属性)

希望能帮助到你!=)


1
这样做很完美,只是在想-与“在对象中输入键,然后通过对象[键]获取值”相比,哪个提供了更好的性能?
lsheng

1
在这种情况下,我会因为Object.entries通话而变慢。我没有进行任何测试。
Francesco Casula

6
这是对当前问题的最佳答案,该问题询问要在for循环中同时获取键和值。
cipak

4
可以接受接受的答案,因为它实际上回答了问题,尽管在提出问题时尚不可用。
Marc Qualie '18

1
您可能需要检查以下问题:stackoverflow.com/questions/47213651/…似乎表明建议使用这种类型的语法:Object.keys(myObject).forEach(key => {...
Will59

519
for (var k in target){
    if (target.hasOwnProperty(k)) {
         alert("Key is " + k + ", value is " + target[k]);
    }
}

hasOwnProperty用于检查您是否target确实具有该属性,而不是从其原型继承而来。会更简单一些:

for (var k in target){
    if (typeof target[k] !== 'function') {
         alert("Key is " + k + ", value is" + target[k]);
    }
}

它仅仅检查k是不是方法(好像targetarray,你会得到很多的方法提醒,如indexOfpushpop,等。)


87
仅在“自己的”属性上进行迭代的另一种方法是Object.keysObject.keys(target).forEach(function (key) { target[key]; });
katspaugh

3
如果target使用创建的Object.create(null),将无法正常工作,则应更改代码target.hasOwnProperty(k)->Object.prototype.hasOwnProperty.call(target,k)
Azder 2015年

为什么不使用问题示例中给出的变量?这里是什么ktargetproperty?对我来说,非javascripter这个未定义的区域是:)
Gediminas

2
Object.keys(target).forEach((key)=> {target [key];}); for Angular
askilondz

315

没有人提到过,Object.keys所以我会提及。

Object.keys(obj).forEach(function (key) {
   // do something with obj[key]
});

3
注意:IE8和更低版本不支持。
Edwin Stoteler

1
此时,您应该使用ES5垫片。如果您现在生活在不错的ES6中,请使用for of tc39wiki.calculist.org/es6/for-of
godslacker 2014年

17
值得注意的是,“除了抛出异常外,没有其他方法可以停止或中断forEach()循环”
rluks 2016年

Object.keys(obj).forEach((key)=> {}); for Angular
askilondz

它在ES6上不起作用,或者我听不懂。Felix在下面有一个更好,更易读的答案:data.forEach(function(value,index){console.log(index); // 0,1,2 ...});
gtamborero

115

因为...将为您工作。

for( var key in obj ) {
  var value = obj[key];
}

在现代JavaScript中,您还可以执行以下操作:

for ( const [key,value] of Object.entries( obj ) ) {

}

64
var obj = {...};
for (var key in obj) {
    var value = obj[key];

}

php语法只是糖。


这还将迭代所有继承的属性。为避免这种情况,请使用.hasOwnProperty()。
LSerni

24

我假设您知道这i是关键,并且可以通过data[i](只需一个快捷方式)获取值。

ECMAScript5 为数组引入了forEach [MDN](似乎您有一个数组):

data.forEach(function(value, index) {

});

MDN文档为不支持该功能的浏览器提供了填充程序。

当然,这不适用于对象,但是您可以为它们创建类似的功能:

function forEach(object, callback) {
    for(var prop in object) {
        if(object.hasOwnProperty(prop)) {
            callback(prop, object[prop]);
        }
    }
}

由于您将问题标记为 ,jQuery提供了$.each [docs],它可以遍历数组和对象结构。


那是Array forEach,而不是object forEach

2
所以?显然,OP在数组上循环。
菲利克斯·克林

Mozilla(Firefox,SpiderMonkey-C,Rhino&c)也具有允许for each语法的非标准扩展名。for each (let val in myObj) console.log(val);
katspaugh

2
@katspaugh:是的,但是因为它仅是Mozilla,所以它似乎不是很有用。
Felix Kling

非常感谢您的回答。我将仔细阅读您提供的信息。您知道答案之初的假设是正确的,我知道,除了我对这个项目的投入如此之高,以至于我无法专注并忘记它。。谢谢。
歌舞表演


9
for (var key in myMap) {
    if (myMap.hasOwnProperty(key)) {
        console.log("key =" + key);
        console.log("value =" + myMap[key]);
    }
}

在javascript中,每个对象都有一堆内置的具有元信息的键值对。当您遍历对象的所有键值对时,您也在遍历它们。使用hasOwnProperty()可以将其过滤掉。


2

ES6将提供Map.prototype.forEach(callback),可以像这样使用

myMap.forEach(function(value, key, myMap) {
                        // Do something
                    });

2
参数myMap是什么?
phil294

地图不是对象。它们是完全独立的东西。
Dakusan '17

2
forEach函数不包含数组的“键”,而是包含您当前正在迭代的元素的索引。
弗朗西斯·马洛赫

2
let test = {a: 1, b: 2, c: 3};
Object.entries(test).forEach(([key, value]) => console.log(key, value))

// a 1
// b 2
// c 3

5
您可以在发布的代码中添加一些解释,而不是发布可能难以理解的纯代码。
AaoIi

Object.entries根据原始对象的键/值对拉出一个数组数组[['a', 1],['b',2],['c',3]]。在forEach解构每个键/值阵列,并设置两个变量keyvalue,只要你想的在功能上使用-在这里输出console.log
Mark Swardstrom



1

如果您正在使用Lodash,则可以使用_.forEach

_.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
  console.log(key + ": " + value);
});
// => Logs 'a: 1' then 'b: 2' (iteration order is not guaranteed).

1

提出此问题以来的最近几年,Javascript添加了一些新功能。其中之一是Object.Entries方法。

直接从MDN复制的是以下代码段


const object1 = {
  a: 'somestring',
  b: 42
};

for (let [key, value] of Object.entries(object1)) {
  console.log(`${key}: ${value}`);
}

-2

是的,您也可以在javascript中使用关联数组:

var obj = 
{
    name:'some name',
    otherProperty:'prop value',
    date: new Date()
};
for(i in obj)
{
    var propVal = obj[i]; // i is the key, and obj[i] is the value ...
}

@PaulPRO ... javascript中的所有内容都是键值对(因此,对象实际上是键值对的关联数组...)
Alex Pacurar 2011年

@AlexPacurar和关联数组具有顺序。对象无序。多数民众赞成在很大的不同
雷诺斯2011年

@Raynos,您可能是正确的。它将很好地帮助您确切地解释对象是如何无序的……给出了上面的示例,可以期望for循环中的“ i”为[name,otherProperty,最后是日期] ...那么,在哪种情况下,对象的属性顺序会混合吗?
Alex Pacurar 2011年

@AlexPacurar它将循环遍历对象的特定顺序是特定于浏览器的。有些按字母顺序进行,有些按定义顺序进行,等等
Raynos

3
@Raynos:关联数组是否必须排序?我经常看到更广泛使用的术语。例如,在关联数组Wikipedia上
杰里米·班克斯

-8
var global = (function() {
   return this;
})();

// Pair object, similar to Python

function Pair(key, value) {
    this.key = key;
    this.value = value;

    this.toString = function() {
       return "(" + key + ", " + value + ")";
    };
}

/**
 * as function
 * @param {String} dataName A String holding the name of your pairs list.
 * @return {Array:Pair} The data list filled
 *    with all pair objects.
 */
Object.prototype.as = function(dataName) {
    var value, key, data;
    global[dataName] = data = [];

    for (key in this) {
       if (this.hasOwnProperty(key)) {
          value = this[key];

          (function() {
             var k = key,
                 v = value;

            data.push(new Pair(k, v));
          })();
       }
    }

    return data;
};

var d = {
   'one': 1,
   'two': 2
};

// Loop on your (key, list) pairs in this way
for (var i = 0, max = d.as("data").length; i < max; i += 1) {
   key = data[i].key;
   value = data[i].value;

   console.log("key: " + key + ", value: " + value);
}

// delete data when u've finished with it.
delete data;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.