我有一个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…)并获取它们的键和值?
当前回答
在ES6中,我们有众所周知的符号来公开一些以前的内部方法,您可以使用它来定义迭代器如何为这个对象工作:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3",
*[Symbol.iterator]() {
yield *Object.keys(this);
}
};
[...p] //["p1", "p2", "p3"]
这将给出与用于…相同的结果。。。在es6循环中。
for(var key in p) {
console.log(key);
}
但了解您现在使用es6的能力很重要!
其他回答
for(key in p) {
alert( p[key] );
}
注意:可以对数组执行此操作,但也要对长度和其他财产进行迭代。
我会这样做,而不是在每个for…中检查obj.hasOwnerProperty。。。在循环中。
var obj = {a : 1};
for(var key in obj){
//obj.hasOwnProperty(key) is not needed.
console.log(key);
}
//then check if anybody has messed the native object. Put this code at the end of the page.
for(var key in Object){
throw new Error("Please don't extend the native object");
}
有趣的是,这些答案中的人都提到了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))
这没有理由不起作用。
欢迎来到未来。
通过带有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
在最新的ES脚本中,您可以执行以下操作:
让p={foo:“bar”};for(let[key,value]of Object.entries(p)){console.log(键,值);}