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

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

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


当前回答

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

其他回答

通过带有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

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(键,值);});

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

使用纯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和谐

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

你可以使用我的库monadic对象来实现这一点。它的设计目的是简化对象修改并使其行为类似于数组:

p.forEach((key, value) => console.log(key, value))

安装:npm i一元对象

该库还包括以下方法:

地图滤器每一个一些

有关更多信息,请参阅README!