var validation_messages = {
"key_1": {
"your_name": "jimmy",
"your_msg": "hello world"
},
"key_2": {
"your_name": "billy",
"your_msg": "foo equals bar"
}
}
#1 楼
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]);
}
}
评论
当您做obj [prop]时,Internet Explorer不同意(叹息),说“对象不支持此属性或方法”。我还没有找到解决方案。
–user999717
2011-12-21 12:02
如果您认为JS对象不必要具有数字键,则@MildFuzz实际上是有意义的。您不能只遍历一个对象。 JS中的for与传统的foreach非常相似。
–杰克·威尔逊(Jake Wilson)
13年2月28日在5:16
for ... in是一个很好的解决方案,但是如果在for()循环中使用promise,请小心,因为如果在循环中创建var,则不能在promise'then函数中使用它。您的var在循环中仅存在一次,因此它在每个then函数中都具有相同的值,甚至是最后一个值。如果您有此问题,请尝试“ Object.keys(obj).forEach”或我的下面解答。
–纤维
16-11-22在21:15
hasOwnProperty对于现代浏览器(IE9 +)几乎总是多余的。
– Filyus
6月5日10:14
#2 楼
在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]);
});
评论
+1可以简化代码,但显然效果不如令人惊讶。 JSPerf-for vs.Object.keys
–techiev2
2012年9月4日12:33
使用这种方法要当心此错误:“ TypeError:在非对象上调用Object.keys”。就我所知,可以在任何对象上调用for ... in ... hasOwnProperty模式(对象,数组,空,未定义,真,假,数字基元,对象)。
– theazureshadow
2012年10月12日,下午2:17
请注意,IE7不支持此功能。
– Paul D. Waite
13年11月8日在11:02
@ techiev2这些测试永远无效。有关当前的性能状态,请参阅我的更新版本:jsperf.com/objdir/20
–OrganicPanda
14-10-16在10:39
@ techiev2:不是让Object.keys()变慢的原因,而是forEach()和对.length的重复访问!如果使用经典的for循环,则其速度几乎是Firefox 33中..in + hasOwnProperty()的两倍。
– CodeManX
2014年11月5日23:50
#3 楼
for (var key in validation_messages) {
var obj = validation_messages[key];
for (var prop in obj) {
alert(prop + " = " + obj[prop]);
}
}
的问题在于,您还将循环遍历原始对象的原型。
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]);
}
}
}
}
评论
简而言之:在for-in循环中检查hasOwnProperty。
–罗里·奥凯恩(Rory O'Kane)
2012年11月21日5:11
请注意,仅当您的对象具有原型方法时才需要这样做。例如,如果要循环访问的对象只是JSON对象,则不需要进行此检查。
–gitaarik
2013年12月29日19:46
@rednaw为安全起见,我使用该检查,因为可以修改Object.prototype。没有理智的脚本会这样做,但是您无法控制由疯狂的浏览器扩展在页面中运行的脚本。浏览器扩展程序在您的页面上运行(在大多数浏览器上),它们可能会引起奇怪的问题(例如,将window.setTimeout设置为null!)。
–robocat
2014年12月5日在2:42
#4 楼
在ES6 / 2015中,您可以遍历这样的对象:(使用箭头功能)Object.keys(myObj).forEach(key => {
console.log(key); // the name of the current key.
console.log(myObj[key]); // the value of the current key.
});
jsbin
在ES7 / 2016中,您可以使用
Object.entries
而不是Object.keys
并循环遍历这样的对象: jsbin
如果还想遍历嵌套对象,则可以使用递归函数(ES6):
Object.entries(myObj).forEach(([key, val]) => {
console.log(key); // the name of the current key.
console.log(val); // the value of the current key.
});
jsbin
与上述功能相同,但使用ES7
Object.entries()
而不是Object.keys()
:对象更改值并结合使用Object.entries()
和Object.fromEntries()
(ES10 / 2019)一次性返回新对象:Object.entries(myObj).forEach(([key, val]) => console.log(key, val));
评论
对于使用Object.entries示例的ES7,您需要将箭头函数参数[key,val]包装在括号中,例如:`Object.entries(myObj).forEach(([[key,val])=> {/ *语句* /}
– Puiu
17 Mar 2 '17 at 17:10
我认为添加Object.entries和Object.keys不会在原型上进行迭代这一事实很有用,这是它与for in构造之间的最大区别。
–steviejay
17年3月28日在19:06
#5 楼
使用Underscore.js的_.each
:_.each(validation_messages, function(value, key){
_.each(value, function(value, key){
console.log(value);
});
});
评论
谢谢蒂姆,使用下划线绝对非常有用,可以提供一个快速而干净的选项。
–编码器
2012年10月21日在22:18
#6 楼
如果使用递归,则可以返回任何深度的对象属性-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
}
*/
评论
当心循环,就像在DOM节点上调用它一样。
– theazureshadow
2012-10-12 2:35
#7 楼
此答案是本帖子中提供的解决方案的汇总,并提供了一些性能反馈。我认为有2个用例,OP没有提及他是否需要在循环过程中访问这些键以使用它们。
我。需要访问密钥的
✔
of
和Object.keys
方法let k;
for (k of Object.keys(obj)) {
/* k : key
* obj[k] : value
*/
}
✔
in
方法let k;
for (k in obj) {
/* k : key
* obj[k] : value
*/
}
谨慎使用它,因为它可以打印
obj
的原型属性✔ES7方法
for (const [key, value] of Object.entries(obj)) {
}
但是,在编辑时,我不建议使用ES7方法,因为JavaScript在内部初始化了许多变量以构建此过程(请参见反馈以获取证明)。除非您没有开发一个值得优化的大型应用程序,否则就可以,但是如果优化是您的优先事项,那么您应该考虑一下。
II。我们只需要访问每个值,
✔
of
和Object.values
方法let v;
for (v of Object.values(obj)) {
}
有关测试的更多反馈:
缓存
Object.keys
或Object.values
的性能可以忽略不计例如,
const keys = Object.keys(obj);
let i;
for (i of keys) {
//
}
// same as
for (i of Object.keys(obj)) {
//
}
对于
Object.values
情况,在Firefox中使用带有缓存变量的本机for
循环似乎比使用for...of
循环快一点。但是区别并不那么重要,Chrome运行for...of
的速度比原生for
循环快,因此在任何情况下(第4和第6测试),我建议在处理for...of
时都使用Object.values
。确实很慢,所以当我们要在迭代过程中缓存密钥时,最好使用for...in
。此外,Chrome还在两种速度下同时运行两种结构(首次测试和最后一次测试)。 您可以在此处检查测试:
https://jsperf.com/es7-and-misc-loops
评论
ES7示例与React Native一样具有魅力!
– Ty Bailey
17-10-26在20:58
很好解释。谢谢
– Alok Ranjan
19年5月31日在12:05
#8 楼
for(var k in validation_messages) {
var o = validation_messages[k];
do_something_with(o.your_name);
do_something_else_with(o.your_msg);
}
#9 楼
我知道这已经很晚了,但是我花了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]);
}
}
}
}
评论
为什么您要在自己的所有者中存储hasOwnProperty,然后调用owns.call(obj,prop)而不是像这个答案那样仅调用obj.hasOwnProperty(prop)?
–罗里·奥凯恩(Rory O'Kane)
2012年11月21日5:25
因为obj可能在其自身上定义了hasOwnProperty函数,所以它不会使用Object.prototype中的那个。您可以像这样obj.hasOwnProperty = function(){return false;}那样在for循环之前尝试,它不会对任何属性进行迭代。
–阿兹德
2012年11月21日下午5:38
@Azder为答案+1,如果我对Object.prototype.hasOwnProperty感兴趣,可以+1。我之前在下划线库的源代码中看到了这一点,但不知道为什么。
–塞缪尔
2014年1月3日在15:28
#10 楼
p是值for (var key in p) {
alert(key + ' => ' + p[key]);
}
OR
Object.keys(p).forEach(key => { console.log(key, p[key]) })
#11 楼
在ES7中,您可以执行以下操作:for (const [key, value] of Object.entries(obj)) {
//
}
评论
我做了一些测试,这种方法在处理大量数据时确实很慢。
–vdegenne
17年9月24日在3:34
#12 楼
for(var key in validation_messages){
for(var subkey in validation_messages[key]){
//code here
//subkey being value, key being 'yourname' / 'yourmsg'
}
}
#13 楼
几种方法...1)2层...在循环中...
for (let key in validation_messages) {
const vmKeys = validation_messages[key];
for (let vmKey in vmKeys) {
console.log(vmKey + vmKeys[vmKey]);
}
}
3)递归函数
Object.keys(validation_messages).forEach(key => {
const vmKeys = validation_messages[key];
Object.keys(vmKeys).forEach(key => {
console.log(vmKeys + vmKeys[key]);
});
});
并像这样称呼:
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]);
}
}
}
#14 楼
另一种选择:var testObj = {test: true, test1: false};
for(let x of Object.keys(testObj)){
console.log(x);
}
评论
我在Chrome 55.0中尝试了您的解决方案,但出现类型错误。您的答案看起来不错,也很简洁,如果可以解决,那可能是更好的选择之一。我试图弄清楚它,但不了解您的解决方案。
– TolMera
16/12/23在13:38
@TolMera固定。
–花花公子
16/12/23在14:05
#15 楼
这是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);
该解决方案适用于各种不同深度。
#16 楼
ECMAScript-2017(一个月前刚刚完成)引入了Object.values()。现在,您可以执行以下操作:let v;
for (v of Object.values(validation_messages))
console.log(v.your_name); // jimmy billy
#17 楼
我认为值得指出的是,jQuery使用$.each()
很好地解决了这个问题。如果不想使用jQuery的选择器引擎,请将$(this)
交换为变量。#18 楼
var obj={
name:"SanD",
age:"27"
}
Object.keys(obj).forEach((key)=>console.log(key,obj[key]));
要遍历JavaScript对象,我们可以使用forEach并优化代码,我们可以使用箭头功能
#19 楼
我无法获得以上职位来做我想做的事。它很hacky,但是可以用!var myObj = {
pageURL : "BLAH",
emailBox : {model:"emailAddress", selector:"#emailAddress"},
passwordBox: {model:"password" , selector:"#password"}
};
...在控制台中生成此代码:
// Get every value in the object into a separate array item ...
function buildArray(p_MainObj, p_Name) {
var variableList = [];
var thisVar = "";
var thisYes = false;
for (var key in p_MainObj) {
thisVar = p_Name + "." + key;
thisYes = false;
if (p_MainObj.hasOwnProperty(key)) {
var obj = p_MainObj[key];
for (var prop in obj) {
var myregex = /^[0-9]*$/;
if (myregex.exec(prop) != prop) {
thisYes = true;
variableList.push({item:thisVar + "." + prop,value:obj[prop]});
}
}
if ( ! thisYes )
variableList.push({item:thisVar,value:obj});
}
}
return variableList;
}
// Get the object items into a simple array ...
var objectItems = buildArray(myObj, "myObj");
// Now use them / test them etc... as you need to!
for (var x=0; x < objectItems.length; ++x) {
console.log(objectItems[x].item + " = " + objectItems[x].value);
}
#20 楼
适用于我的解决方案如下_private.convertParams=function(params){
var params= [];
Object.keys(values).forEach(function(key) {
params.push({"id":key,"option":"Igual","value":params[key].id})
});
return params;
}
#21 楼
异国情调的一个-深度遍历JSON.stringify(validation_messages,(field,value)=>{
if(!field) return value;
// ... your code
return value;
})
在此解决方案中,我们使用replacer来深度遍历整个对象和嵌套对象-在每个级别上,您将获得所有字段和值。如果您需要获取每个字段的完整路径,请点击此处
var validation_messages = {
"key_1": {
"your_name": "jimmy",
"your_msg": "hello world"
},
"key_2": {
"your_name": "billy",
"your_msg": "foo equals bar",
"deep": {
"color": "red",
"size": "10px"
}
}
}
JSON.stringify(validation_messages,(field,value)=>{
if(!field) return value;
console.log(`key: ${field.padEnd(11)} - value: ${value}`);
return value;
})
#22 楼
使用ES8 Object.entries()应该是实现此目的的更紧凑的方法。Object.entries(validation_messages).map(([key,object]) => {
alert(`Looping through key : ${key}`);
Object.entries(object).map(([token, value]) => {
alert(`${token} : ${value}`);
});
});
评论
此解决方案已在另一个答案中提出。
–谢尔盖·舒宾
6月19日8:10
#23 楼
forEach2(在这里找到):
var lunch = {
sandwich: 'ham',
age: 48,
};
lunch.forEach2(function (item, key) {
console.log(key);
console.log(item);
});
代码:
if (!Object.prototype.forEach2) {
Object.defineProperty(Object.prototype, 'forEach2', {
value: function (callback, thisArg) {
if (this == null) {
throw new TypeError('Not an object');
}
thisArg = thisArg || window;
for (var key in this) {
if (this.hasOwnProperty(key)) {
callback.call(thisArg, this[key], key, this);
}
}
}
});
}
#24 楼
在2020年,您需要不变的通用函数遍历由子对象,数组和字符串组成的多维对象,并应用自定义函数
/>
#25 楼
在我的情况下(在前述基础上)可以是任意数量的级别。结果:
评论
通过JavaScript对象循环的可能重复对象