我有一个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…)并获取它们的键和值?
当前回答
表演
今天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);此代码段仅显示选定的解决方案
下面是铬上小物体的结果
其他回答
使用纯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和谐
在这成为新标准之前,旧方法仍然可以使用,但在流行的库中也有替代方法,甚至对于那些不使用这些库的人来说,也有轻量级的替代方法。
如果还想迭代非可枚举财产,可以使用Object.getOwnPropertyNames(obj)返回直接在给定对象上找到的所有财产(可枚举或不可枚举)的数组。
var obj=对象.创建({}{//不可枚举属性获取食物:{value:函数(){return this.foo;},可枚举:false}});obj.foo=1;//可枚举属性Object.getOwnPropertyNames(obj).forEach(函数(名称){document.write(name+':'+obj[name]+'<br/>');});
只有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
}
下面是另一种迭代对象的方法。
变量p={“p1”:“值1”,“p2”:“值2”,“p3”:“值3”};Object.keys(p).forEach(key=>{console.log(key,p[key])})
在最新的ES脚本中,您可以执行以下操作:
让p={foo:“bar”};for(let[key,value]of Object.entries(p)){console.log(键,值);}