我有一个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…)并获取它们的键和值?
当前回答
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(键,值);});
其他回答
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(键,值);});
有趣的是,这些答案中的人都提到了Object.keys()和for。。。但从未组合:
var map = {well:'hello', there:'!'};
for (let key of Object.keys(map))
console.log(key + ':' + map[key]);
你不能只是为了。。。因为它不是迭代器,并且。。。index或.forEach()调用Object.keys()是丑陋/低效的。我很高兴大多数人都没有。。。in(有或没有检查.hasOwnProperty()),因为这也有点混乱,所以除了我上面的答案之外,我想说。。。
您可以使普通对象关联迭代!行为就像地图一样,直接使用了。。。属于DEMO在Chrome和FF中工作(我假设只有ES6)
var ordinaryObject = {well:'hello', there:'!'};
for (let pair of ordinaryObject)
//key:value
console.log(pair[0] + ':' + pair[1]);
//or
for (let [key, value] of ordinaryObject)
console.log(key + ':' + value);
只要你在下面加上我的垫片:
//makes all objects iterable just like Maps!!! YAY
//iterates over Object.keys() (which already ignores prototype chain for us)
Object.prototype[Symbol.iterator] = function() {
var keys = Object.keys(this)[Symbol.iterator]();
var obj = this;
var output;
return {next:function() {
if (!(output = keys.next()).done)
output.value = [output.value, obj[output.value]];
return output;
}};
};
无需创建一个真正的Map对象,该对象不具备良好的语法功能。
var trueMap = new Map([['well', 'hello'], ['there', '!']]);
for (let pair of trueMap)
console.log(pair[0] + ':' + pair[1]);
事实上,有了这个填充程序,如果您仍然想利用Map的其他功能(不填充它们),但仍然想使用整洁的对象表示法,因为对象现在是可迭代的,那么您现在只需从中创建一个Map即可!
//shown in demo
var realMap = new Map({well:'hello', there:'!'});
对于那些不喜欢填充,或者不喜欢处理原型的人,可以在窗口上创建函数,然后调用类似于getObjIterator()的函数;
//no prototype manipulation
function getObjIterator(obj) {
//create a dummy object instead of adding functionality to all objects
var iterator = new Object();
//give it what the shim does but as its own local property
iterator[Symbol.iterator] = function() {
var keys = Object.keys(obj)[Symbol.iterator]();
var output;
return {next:function() {
if (!(output = keys.next()).done)
output.value = [output.value, obj[output.value]];
return output;
}};
};
return iterator;
}
现在,您可以将其作为普通函数调用,其他任何内容都不受影响
var realMap = new Map(getObjIterator({well:'hello', there:'!'}))
or
for (let pair of getObjIterator(ordinaryObject))
这没有理由不起作用。
欢迎来到未来。
考虑到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()上使用for
喜欢:
let对象={“key1”:“value1”,“key2”:“value2”,“key3”:“value3”};for(let key of Object.keys(对象)){console.log(key+“:”+对象[key])}
下面是另一种迭代对象的方法。
变量p={“p1”:“值1”,“p2”:“值2”,“p3”:“值3”};Object.keys(p).forEach(key=>{console.log(key,p[key])})