edt*_*edt 1521 javascript
如何遍历JavaScript对象中的所有成员,包括作为对象的值.
例如,我怎么能循环这个(访问每个的"your_name"和"your_message")?
var validation_messages = {
"key_1": {
"your_name": "jimmy",
"your_msg": "hello world"
},
"key_2": {
"your_name": "billy",
"your_msg": "foo equals bar"
}
}
Run Code Online (Sandbox Code Playgroud)
Agi*_*Jon 2056
for (var key in validation_messages) {
// skip loop if the property is from prototype
if (!validation_messages.hasOwnProperty(key)) continue;
var obj = validation_messages[key];
for (var prop in obj) {
// skip loop if the property is from prototype
if (!obj.hasOwnProperty(prop)) continue;
// your code
alert(prop + " = " + obj[prop]);
}
}
Run Code Online (Sandbox Code Playgroud)
Axe*_*yer 726
在ECMAScript中5,你可以结合Object.keys()
和Array.prototype.forEach()
:
var obj = {
first: "John",
last: "Doe"
};
//
// Visit non-inherited enumerable keys
//
Object.keys(obj).forEach(function(key) {
console.log(key, obj[key]);
});
Run Code Online (Sandbox Code Playgroud)
Cha*_*ngo 381
这个问题
for (var key in validation_messages) {
var obj = validation_messages[key];
for (var prop in obj) {
alert(prop + " = " + obj[prop]);
}
}
Run Code Online (Sandbox Code Playgroud)
是你还将循环原始对象的原型.
有了这个,你会避免它:
for (var key in validation_messages) {
if (validation_messages.hasOwnProperty(key)) {
var obj = validation_messages[key];
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
alert(prop + " = " + obj[prop]);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
Rot*_*eti 274
在ES6中,您可以循环遍历这样的对象:(使用箭头功能)
Object.keys(myObj).forEach(key => {
console.log(key); // the name of the current key.
console.log(myObj[key]); // the value of the current key.
});
Run Code Online (Sandbox Code Playgroud)
在ES7中,你可以使用Object.entries
代替Object.keys
和循环遍历这样的对象:
Object.entries(myObj).forEach(([key, val]) => {
console.log(key); // the name of the current key.
console.log(val); // the value of the current key.
});
Run Code Online (Sandbox Code Playgroud)
以上也可以作为一个单行:
Object.entries(myObj).forEach(([key, val]) => console.log(key, val));
Run Code Online (Sandbox Code Playgroud)
如果您想循环遍历嵌套对象,可以使用递归函数(ES6):
const loopNestedObj = obj => {
Object.keys(obj).forEach(key => {
if (obj[key] && typeof obj[key] === "object") loopNestedObj(obj[key]); // recurse.
else console.log(key, obj[key]); // or do something with key and val.
});
};
Run Code Online (Sandbox Code Playgroud)
与上面的功能相同,但使用ES7 Object.entries()
代替Object.keys()
:
const loopNestedObj = obj => {
Object.entries(obj).forEach(([key, val]) => {
if (val && typeof val === "object") loopNestedObj(val); // recurse.
else console.log(key, val); // or do something with key and val.
});
};
Run Code Online (Sandbox Code Playgroud)
如果您正在使用函数式编程,则可以使用Object.entries()
/ Object.fromEntries()
枚举对象,然后处理这些值,然后使用Object.entries
它们转换回新对象.
const loopNestedObj = obj =>
Object.fromEntries(
Object.entries(obj).map(([key, val]) => {
if (val && typeof val === "object") [key, loopNestedObj(val)]; // recurse
else [key, updateMyVal(val)]; // or do something with key and val.
})
);
Run Code Online (Sandbox Code Playgroud)
Tim*_*ord 94
_.each(validation_messages, function(value, key){
_.each(value, function(value, key){
console.log(value);
});
});
Run Code Online (Sandbox Code Playgroud)
ken*_*bec 55
如果使用递归,则可以返回任何深度的对象属性 -
function lookdeep(object){
var collection= [], index= 0, next, item;
for(item in object){
if(object.hasOwnProperty(item)){
next= object[item];
if(typeof next== 'object' && next!= null){
collection[index++]= item +
':{ '+ lookdeep(next).join(', ')+'}';
}
else collection[index++]= [item+':'+String(next)];
}
}
return collection;
}
//example
var O={
a:1, b:2, c:{
c1:3, c2:4, c3:{
t:true, f:false
}
},
d:11
};
var lookdeepSample= 'O={'+ lookdeep(O).join(',\n')+'}';
/* returned value: (String)
O={
a:1,
b:2,
c:{
c1:3, c2:4, c3:{
t:true, f:false
}
},
d:11
}
*/
Run Code Online (Sandbox Code Playgroud)
vde*_*nne 39
这个答案是本文中提供的一些性能反馈解决方案的汇总.我认为有2个用例,OP没有提到他是否需要访问密钥以便在循环过程中使用它们.
✔ of
和Object.keys
方法
let k;
for (k of Object.keys(obj)) {
/* k : key
* obj[k] : value
*/
}
Run Code Online (Sandbox Code Playgroud)
✔ in
方法
let k;
for (k in obj) {
/* k : key
* obj[k] : value
*/
}
Run Code Online (Sandbox Code Playgroud)
谨慎使用这个,因为它可以打印原型的属性 obj
✔ES7方法
for (const [key, value] of Object.entries(obj)) {
}
Run Code Online (Sandbox Code Playgroud)
但是,在编辑时我不建议使用ES7方法,因为JavaScript在内部初始化了很多变量来构建此过程(请参阅反馈以获取证明).除非你没有开发一个值得优化的巨大应用程序,否则它是可以的,但如果优化是你的首要任务,你应该考虑一下.
✔ of
和Object.values
方法
let v;
for (v of Object.values(obj)) {
}
Run Code Online (Sandbox Code Playgroud)
Object.keys
或Object.values
性能可以忽略不计例如,
const keys = Object.keys(obj);
let i;
for (i of keys) {
//
}
// same as
for (i of Object.keys(obj)) {
//
}
Run Code Online (Sandbox Code Playgroud)
例如Object.values
,for
在Firefox中使用带有缓存变量的本机循环似乎比使用for...of
循环要快一些.然而,差异并不重要,Chrome运行for...of
速度比原生for
循环快,所以我建议在任何情况下for...of
处理时使用Object.values
(第4和第6次测试).
在Firefox中,for...in
循环非常慢,因此当我们想要在迭代期间缓存密钥时,最好使用Object.keys
.此外,Chrome以相同的速度运行两种结构(第一次和最后一次测试).
您可以在此处查看测试:https: //jsperf.com/es7-and-misc-loops
Azd*_*der 29
我知道这已经很晚了,但是我花了2分钟来编写这个AgileJon的优化和改进版本的答案:
var key, obj, prop, owns = Object.prototype.hasOwnProperty;
for (key in validation_messages ) {
if (owns.call(validation_messages, key)) {
obj = validation_messages[key];
for (prop in obj ) {
// using obj.hasOwnProperty might cause you headache if there is
// obj.hasOwnProperty = function(){return false;}
// but owns will always work
if (owns.call(obj, prop)) {
console.log(prop, "=", obj[prop]);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
cha*_*aos 28
for(var k in validation_messages) {
var o = validation_messages[k];
do_something_with(o.your_name);
do_something_else_with(o.your_msg);
}
Run Code Online (Sandbox Code Playgroud)
Wes*_*sam 12
p是值
for (var key in p) {
alert(key + ' => ' + p[key]);
}
Run Code Online (Sandbox Code Playgroud)
要么
Object.keys(p).forEach(key => { console.log(key, p[key]) })
Run Code Online (Sandbox Code Playgroud)
在ES7中,您可以:
for (const [key, value] of Object.entries(obj)) {
//
}
Run Code Online (Sandbox Code Playgroud)
for(var key in validation_messages){
for(var subkey in validation_messages[key]){
//code here
//subkey being value, key being 'yourname' / 'yourmsg'
}
}
Run Code Online (Sandbox Code Playgroud)
遍历对象的方法有很多种。请看下面的例子。
var obj = {'name':'John Doe','email':'johndoe@example.com'}
Run Code Online (Sandbox Code Playgroud)
方法一
var keys = Object.keys(obj)
for(var i= 0; i < keys.length;i++){
console.log(keys[i]+ ': ' + obj[keys[i]])
}
Run Code Online (Sandbox Code Playgroud)
方法2
for(var key in obj){
console.log(key+': '+ obj[key])
}
Run Code Online (Sandbox Code Playgroud)
方法3
Object.keys(obj).forEach(function (key) {
console.log(key+ ': ' + obj[key])
})
Run Code Online (Sandbox Code Playgroud)
另外一个选项:
var testObj = {test: true, test1: false};
for(let x of Object.keys(testObj)){
console.log(x);
}
Run Code Online (Sandbox Code Playgroud)
很少有这样做的方法...
1) 2层...在循环中...
for (let key in validation_messages) {
const vmKeys = validation_messages[key];
for (let vmKey in vmKeys) {
console.log(vmKey + vmKeys[vmKey]);
}
}
Run Code Online (Sandbox Code Playgroud)
2)使用Object.key
Object.keys(validation_messages).forEach(key => {
const vmKeys = validation_messages[key];
Object.keys(vmKeys).forEach(key => {
console.log(vmKeys + vmKeys[key]);
});
});
Run Code Online (Sandbox Code Playgroud)
3)递归函数
const recursiveObj = obj => {
for(let key in obj){
if(!obj.hasOwnProperty(key)) continue;
if(typeof obj[key] !== 'object'){
console.log(key + obj[key]);
} else {
recursiveObj(obj[key]);
}
}
}
Run Code Online (Sandbox Code Playgroud)
并这样称呼:
recursiveObj(validation_messages);
Run Code Online (Sandbox Code Playgroud)
这是AgileJon解决方案(演示)的改进和递归版本:
function loopThrough(obj){
for(var key in obj){
// skip loop if the property is from prototype
if(!obj.hasOwnProperty(key)) continue;
if(typeof obj[key] !== 'object'){
//your code
console.log(key+" = "+obj[key]);
} else {
loopThrough(obj[key]);
}
}
}
loopThrough(validation_messages);
Run Code Online (Sandbox Code Playgroud)
该解决方案适用于各种不同的深度.
一个月前刚刚完成的ECMAScript 2017引入了 Object.values()。所以现在你可以这样做:
let v;
for (v of Object.values(validation_messages))
console.log(v.your_name); // jimmy billy
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1581897 次 |
最近记录: |