如何遍历或枚举JavaScript对象?

我有一个如下的JavaScript对象:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

现在我想通过所有回路p元素(p1p2p3...),并得到他们的键和值。我怎样才能做到这一点?

我可以根据需要修改JavaScript对象。我的最终目标是遍历一些键值对,如果可能的话,我想避免使用eval

卡卡西米亚2020/03/09 13:28:16

在最新的ES脚本中,您可以执行以下操作:

Object.entries(p);
阿飞小卤蛋2020/03/09 13:28:16

从ES06开始,您可以使用

let arrValues = Object.values( yourObject) ;

它返回对象值的数组,并且不从原型中提取值!

MDN DOCS Object.values()

和钥匙(在这里我已经回答了)

let arrKeys   = Object.keys(yourObject);
Near神奇2020/03/09 13:28:16

考虑到ES6,我想添加自己的糖勺,并提供另一种方法来遍历对象的属性。

由于普通的JS对象不是开箱即用的,所以不能迭代,因此我们无法使用for..of循环来迭代其内容。但是没有人能阻止我们使其变得可迭代

让我们有book对象。

let book = {
  title: "Amazing book",
  author: "Me",
  pages: 3
}

book[Symbol.iterator] = function(){

  let properties = Object.keys(this); // returns an array with property names
  let counter = 0;
  let isDone = false;

  let next = () => {
    if(counter >= properties.length){
      isDone = true;
    }
    return { done: isDone, value: this[properties[counter++]] }
  }

  return { next };
}

既然我们做到了,我们可以这样使用它:

for(let pValue of book){
  console.log(pValue);
}
------------------------
Amazing book
Me
3

或者,如果您知道ES6 生成器的功能,那么您当然可以使上面的代码更短。

book[Symbol.iterator] = function *(){

  let properties = Object.keys(this);
  for (let p of properties){
    yield this[p];
  }

}

当然,您可以Objectprototype级别可迭代的情况下将此类行为应用于所有对象

Object.prototype[Symbol.iterator] = function() {...}

而且,符合迭代协议的对象可以与新的ES2015功能扩展运算符一起使用,因此我们可以将对象属性值读取为数组。

let pValues = [...book];
console.log(pValues);
-------------------------
["Amazing book", "Me", 3]

或者您可以使用解构分配:

let [title, , pages] = book; // notice that we can just skip unnecessary values
console.log(title);
console.log(pages);
------------------
Amazing book
3

您可以使用上面提供的所有代码签出JSFiddle

飞云Eva2020/03/09 13:28:16

如果有人需要遍历带有条件的arrayObjects

var arrayObjects = [{"building":"A", "status":"good"},{"building":"B","status":"horrible"}];

for (var i=0; i< arrayObjects.length; i++) {
  console.log(arrayObjects[i]);
  
  for(key in arrayObjects[i]) {      
    
      if (key == "status" && arrayObjects[i][key] == "good") {
        
          console.log(key + "->" + arrayObjects[i][key]);
      }else{
          console.log("nothing found");
      }
   }
}

飞云Tom小宇宙2020/03/09 13:28:16

使用for-ofObject.keys()

喜欢:

let object = {
   "key1": "value1"
   "key2": "value2"
   "key3": "value3"
};

for (var key of Object.keys(p)) {
   console.log(key + " : " + object[key])
}
Tony西门古一2020/03/09 13:28:16

在ES6中,我们有众所周知的符号来公开一些以前的内部方法,您可以使用它定义该对象的迭代器如何工作:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3",
    *[Symbol.iterator]() {
        yield *Object.keys(this);
    }
};

[...p] //["p1", "p2", "p3"]

这将产生与在es6循环中使用for ...相同的结果。

for(var key in p) {
    console.log(key);
}

但是了解使用es6现在所具有的功能很重要!

小胖梅2020/03/09 13:28:16

使用纯JavaScript时,循环可能非常有趣。似乎只有ECMA6(新的2015 JavaScript规范)可以控制循环。不幸的是,在我撰写本文时,浏览器和流行的集成开发环境(IDE)仍在努力完全支持新功能。

乍一看,这是ECMA6之前的JavaScript对象循环:

for (var key in object) {
  if (p.hasOwnProperty(key)) {
    var value = object[key];
    console.log(key); // This is the key;
    console.log(value); // This is the value;
  }
}

另外,我知道这个问题超出了范围,但在2011年,ECMAScript 5.1 forEach添加了用于数组方法,方法基本上创建了一种新的改进方法来遍历数组,同时仍然使旧的冗长而混乱的for循环成为不可迭代的对象但是奇怪的是,这种新forEach方法不被支持break,这导致了各种各样的其他问题。

基本上在2011年,除了许多流行的库(jQuery,Underscore等)决定重新实现之外,没有真正可靠的方法可以在JavaScript中循环。

截至2015年,我们现在有了更好的开箱即用的方式来循环(和中断)任何对象类型(包括数组和字符串)。当推荐成为主流时,JavaScript中的循环最终将是这样:

for (let [key, value] of Object.entries(object)) {
    console.log(key); // This is the key;
    console.log(value); // This is the value;
}

请注意,自2016年6月18日起,大多数浏览器将不支持上述代码。即使在Chrome中,您也需要启用此特殊标志才能使其正常工作: chrome://flags/#enable-javascript-harmony

在成为新标准之前,仍然可以使用旧方法,但是流行的库中还有其他选择,甚至对于那些不使用这些库的人来说,甚至还有轻量级的选择

番长神无2020/03/09 13:28:16

    var p =[{"username":"ordermanageadmin","user_id":"2","resource_id":"Magento_Sales::actions"},
{"username":"ordermanageadmin_1","user_id":"3","resource_id":"Magento_Sales::actions"}]
for(var value in p) {
    for (var key in value) {
        if (p.hasOwnProperty(key)) {
            console.log(key + " -> " + p[key]);
        }
    }
}

Harry小宇宙2020/03/09 13:28:16

仅JavaScript代码没有依赖项:

var p = {"p1": "value1", "p2": "value2", "p3": "value3"};
keys = Object.keys(p);   // ["p1", "p2", "p3"]

for(i = 0; i < keys.length; i++){
  console.log(keys[i] + "=" + p[keys[i]]);   // p1=value1, p2=value2, p3=value3
}
SamEva2020/03/09 13:28:16

Object.keys()方法返回给定对象自己的可枚举属性的数组。在这里了解更多

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Object.keys(p).map((key)=> console.log(key + "->" + p[key]))

理查德阳光2020/03/09 13:28:16

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " = " + p[key]);
    }
}
<p>
  Output:<br>
  p1 = values1<br>
  p2 = values2<br>
  p3 = values3
</p>

神乐路易2020/03/09 13:28:16

这是另一种遍历对象的方法。

   var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};


Object.keys(p).forEach(key => { console.log(key, p[key]) })

番长猴子古一2020/03/09 13:28:16

通过原型的forEach() 其应该跳过原型链属性:

Object.prototype.each = function(f) {
    var obj = this
    Object.keys(obj).forEach( function(key) { 
        f( key , obj[key] ) 
    });
}


//print all keys and values
var obj = {a:1,b:2,c:3}
obj.each(function(key,value) { console.log(key + " " + value) });
// a 1
// b 2
// c 3
卡卡西卡卡西2020/03/09 13:28:16
for(key in p) {
  alert( p[key] );
}

注意:您可以在数组上执行此操作,但是也将在length和其他属性上进行迭代

小卤蛋前端2020/03/09 13:28:16

您可以像这样遍历它:

for (var key in p) {
  alert(p[key]);
}

请注意,它key不会采用该属性的值,而只是一个索引值。

满天星2020/03/09 13:28:16

您可以使用for-in其他人所示循环。但是,您还必须确保获得的键是对象的实际属性,而不是来自原型。

这是代码段:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}

用Object.keys()替代:

var p = {
    0: "value1",
    "b": "value2",
    key: "value3"
};

for (var key of Object.keys(p)) {
    console.log(key + " -> " + p[key])
}

请注意,使用of for-of代替for-in,如果不使用它将在命名属性上返回未定义,并Object.keys()确保仅使用对象自身的属性,而不使用整个原型链属性

使用新Object.entries()方法:

Note: This method is not supported natively by Internet Explorer. You may consider using a Polyfill for older browsers.

const p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (let [key, value] of Object.entries(p)) {
  console.log(`${key}: ${value}`);
}
宝儿猿2020/03/09 13:28:16

在ECMAScript 5下,您可以将Object.keys()结合使用Array.prototype.forEach()

var obj = { first: "John", last: "Doe" };

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

ECMAScript 6添加了for...of

for (const key of Object.keys(obj)) {
    console.log(key, obj[key]);
}

ECMAScript 8进行了添加Object.entries(),从而避免了在原始对象中查找每个值的麻烦:

Object.entries(obj).forEach(
    ([key, value]) => console.log(key, value)
);

您可以合并for...of,销毁和Object.entries

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

二者Object.keys()Object.entries()以相同的顺序作为迭代性质for...in但忽略原型链仅迭代对象自身的可枚举属性。

猪猪小小小哥2020/03/09 13:28:16

在ECMAScript 5中,您可以在文字的迭代字段中采用新方法- Object.keys

您可以在MDN上看到更多信息

下面是我的选择,它是当前版本浏览器(Chrome30,IE10,FF25)中的一种更快的解决方案

var keys = Object.keys(p),
    len = keys.length,
    i = 0,
    prop,
    value;
while (i < len) {
    prop = keys[i];
    value = p[prop];
    i += 1;
}

您可以将这种方法的性能与jsperf.com上的不同实现进行比较

您可以在Kangax的compat表上看到的浏览器支持

对于旧的浏览器,您可以使用简单完整的 polyfill

UPD:

此问题上所有最受欢迎案例的性能比较perfjs.info

对象文字迭代

猴子古一蛋蛋2020/03/09 13:28:16

您必须使用for-in循环

但是在使用这种循环时要非常小心,因为这会沿原型链循环所有属性

因此,在使用for-in循环时,请始终使用该hasOwnProperty方法来确定迭代中的当前属性是否确实是您要检查的对象的属性:

for (var prop in p) {
    if (!p.hasOwnProperty(prop)) {
        //The current property is not a direct property of p
        continue;
    }
    //Do your logic with the property here
}