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

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

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


当前回答

考虑到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。

其他回答

Object.keys(obj):数组检索所有可枚举自身(非继承)财产的所有字符串值键。

因此,通过使用hasOwnProperty测试每个对象键,它提供了与您想要的相同的键列表。您不需要额外的测试操作,因为Object.keys(obj).forEach(function(key){})应该更快。让我们来证明一下:

var uniqid=函数(){var text=“”,i=0,可能=“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvxyz”;对于(;i<32;i++){text+=可能的charAt(数学地板(数学随机()*可能的长度));}返回文本;}, 周期=100000,obj={},p1,p2,p3,钥匙//使用随机财产填充对象Array.apply(null,Array(CYCLES)).forEach(function(){obj[uniqid()]=新日期()});//方法#1p1=performance.now();Object.keys(obj).forEach(函数(键){var waste=obj[key];});p2=performance.now();console.log(“Object.keys方法耗时”+(p2-p1)+“毫秒”);//方法#2for(在obj中键入){if(obj.hasOwnProperty(键)){var waste=obj[key];}}p3=performance.now();console.log(“for…in/hasOwnProperty方法花费了”+(p3-p2)+“毫秒”);

在我的Firefox中,我有以下结果

Object.keys方法耗时40.21101451665163毫秒。对于in/hasOwnProperty方法耗时98.26163508463651毫秒。

在Chrome上,差异更大http://codepen.io/dsheiko/pen/JdrqXa

PS2:在ES6(EcmaScript 2015)中,您可以更好地迭代可迭代对象:

let map=new map().set('a',1).set('b',2);for(let对映射){console.log(对);}//或let map=新地图([[错误,'否'],[真,'是'],]);map.forEach((value,key)=>{console.log(键,值);});

因为提问者的[第二个目标是循环一些键值对],最后不要寻找循环。

var p ={"p1":"value1","p2":"value2","p3":"value3"};
if('p1' in p){
  var val=p['p1'];
  ...
}

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

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

有两个选项:

您可以使用。。在那里

变量p={“p1”:“值1”,“p2”:“值2”,“p3”:“值3”};for(p中的常量项){console.log(`key=${item},value=${p[item]}`);}

您还可以调用Object.entries()来创建一个包含所有可枚举财产的数组。之后,您可以使用map、foreach或for循环浏览它。。属于

变量p={“p1”:“值1”,“p2”:“值2”,“p3”:“值3”};Object.entries(p).map(item=>{console.log(项)})

变量p={“p1”:“值1”,“p2”:“值2”,“p3”:“值3”};Object.entries(p).forEach(item=>{console.log(项)})

变量p={“p1”:“值1”,“p2”:“值2”,“p3”:“值3”};for(Object.entries(p)的常量项){console.log(项)}

有关Object.entries()的更多信息,请参见此处

您必须使用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
}