我有一个JavaScript对象,如下所示:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
我如何循环遍历p的所有元素(p1、p2、p3…)并获取它们的键和值?
我有一个JavaScript对象,如下所示:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
我如何循环遍历p的所有元素(p1、p2、p3…)并获取它们的键和值?
当前回答
在ECMAScript 5下,可以组合Object.keys()和Array.protocol.forEach():
var obj = { first: "John", last: "Doe" };
Object.keys(obj).forEach(function(key) {
console.log(key, obj[key]);
});
ECMAScript 6添加了。。。第页,共页:
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)
);
你可以组合。。。of、destructuring和Object.entries:
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
Object.keys()和Object.entries()以与for相同的顺序迭代财产。。。但忽略原型链。只迭代对象自己的可枚举财产。
其他回答
表演
今天2020.03.06我在MacOs High Sierra v10.13.6上对Chrome v80.0、Safari v13.0.5和Firefox 73.0.1上选择的解决方案进行了测试
结论
基于(A,B)中for的解决方案对于大小对象的所有浏览器都是快速的(或最快的)令人惊讶的是,对于小型和大型物体,of(H)解决方案在铬上的速度很快基于显式索引i(J,K)的解决方案在所有浏览器上对于小对象都非常快(对于firefox,对于大对象也很快,但在其他浏览器上则很快)基于迭代器(D,E)的解决方案是最慢的,不推荐解决方案C对于大对象是慢的,对于小对象是中等慢的
细节
进行了性能测试
小对象-有3个字段-您可以在这里对机器进行测试“大”对象-有1000个字段-您可以在这里的机器上执行测试
以下片段介绍了使用过的解决方案
函数A(obj,s=“”){for(let key in obj)if(obj.hasOwnProperty(key))s+=key+'->'+obj[key]+'';返回s;}函数B(obj,s=“”){for(let key in obj)s+=key+“->”+obj[key]+“”;返回s;}函数C(obj,s=“”){const map=新映射(Object.entries(obj));for(let[key,value]of map)s+=key+'->'+value+'';返回s;}函数D(obj,s=“”){设o={…对象,*[符号迭代器](){for(Object.keys(this)的常量i)yield[i,this[i]];}}for(设o的[key,value])s+=key+'->'+value+'';返回s;}函数E(obj,s=“”){设o={…对象,*[Symbol.iiterator](){yield*Object.keys(this)}}for(let key of o)s+=key+'->'+o[key]+'';返回s;}函数F(obj,s=“”){for(let key of Object.keys(obj))s+=键+“->”+obj[key]+“”;返回s;}函数G(obj,s=“”){for(let[key,value]of Object.entries(obj))s+=键+“->”+值+“”;返回s;}函数H(obj,s=“”){for(let key of Object.getOwnPropertyNames(obj))s+=key+'->'+obj[key]+'';返回s;}函数I(obj,s=“”){for(Reflect.ownKeys(obj)的常量键)s+=key+'->'+obj[key]+'';返回s;}函数J(obj,s=“”){let keys=Object.keys(obj);for(设i=0;i<keys.length;i++){let key=键[i];s+=键+“->”+obj[key]+“”;}返回s;}函数K(obj,s=“”){var keys=对象密钥(obj),len=密钥长度,i=0;而(i<len){let key=键[i];s+=键+“->”+obj[key]+“”;i+=1;}返回s;}函数L(obj,s=“”){Object.keys(obj).forEach(key=>s+=key+'->'+obj[key]+'');返回s;}函数M(obj,s=“”){Object.entries(obj).forEach(([key,value])=>s+=key+'->'+value+'');返回s;}函数N(obj,s=“”){Object.getOwnPropertyNames(obj).forEach(key=>s+=key+'->'+obj[key]+'');返回s;}函数O(obj,s=“”){Reflect.ownKeys(obj).forEach(key=>s+=key+'->'+obj[key]+'');返回s;}//测试变量p={“p1”:“值1”,“p2”:“值2”,“p3”:“值3”};let log=(name,f)=>console.log(`${name}${f(p)}`)日志('A',A);日志('B',B);日志('C',C);日志('D',D);对数('E',E);日志('F',F);日志('G',G);对数('H',H);日志('I',I);日志('J',J);log('K',K);对数('L',L);日志(M’,M);对数('N',N);日志('O',O);此代码段仅显示选定的解决方案
下面是铬上小物体的结果
在ECMAScript 5中,在literal-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的兼容表上看到浏览器支持
对于旧浏览器,您有简单而完整的polyfill
UPD:
perfjs.info上此问题中所有最常见情况的性能比较:
对象文字迭代
您必须使用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.defineProperty(Object.prototype, 'forEach', {
value: function (func) {
for (var key in this) {
if (!this.hasOwnProperty(key)) {
// skip loop if the property is from prototype
continue;
}
var value = this[key];
func(key, value);
}
},
enumerable: false
});
对于那些不喜欢“For…in”方法的人:
Object.defineProperty(Object.prototype, 'forEach', {
value: function (func) {
var arr = Object.keys(this);
for (var i = 0; i < arr.length; i++) {
var key = arr[i];
func(key, this[key]);
}
},
enumerable: false
});
现在,您可以简单地调用:
p.forEach (function(key, value){
console.log ("Key: " + key);
console.log ("Value: " + value);
});
如果您不想与其他forEach方法发生冲突,可以使用您的唯一名称命名它。
因为提问者的[第二个目标是循环一些键值对],最后不要寻找循环。
var p ={"p1":"value1","p2":"value2","p3":"value3"};
if('p1' in p){
var val=p['p1'];
...
}