我有一个JavaScript对象,如下所示:

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

我如何循环遍历p的所有元素(p1、p2、p3…)并获取它们的键和值?


当前回答

使用纯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、Undercore等)决定重新实现之外,没有一种真正可靠的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和谐

在这成为新标准之前,旧方法仍然可以使用,但在流行的库中也有替代方法,甚至对于那些不使用这些库的人来说,也有轻量级的替代方法。

其他回答

您可以像这样迭代:

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

注意,键不会接受属性的值,它只是一个索引值。

您必须使用for in循环

但在使用这种循环时要非常小心,因为这将沿着原型链循环所有财产。

因此,在循环中使用for时,请始终使用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
}

考虑到ES6,我想添加自己的一勺糖,并提供另一种方法来迭代对象的财产。

由于纯JS对象不能立即迭代,因此我们无法使用。。用于迭代其内容的循环。但没有人能阻止我们使其可迭代。

让我们有书的对象。

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];
  }

}

当然,通过在原型级别上使Object可迭代,您可以对所有对象应用这样的行为。

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。

只有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
}

您还可以使用Object.keys(),并按如下方式迭代对象键以获取值:

变量p={“p1”:“值1”,“p2”:“值2”,“p3”:“值3”};Object.keys(p).forEach((key)=>{console.log(键+'->'+p[key]);});