Answers:
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]);
}
}
for in
与传统的非常相似foreach
。
在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]);
});
for ... in ... hasOwnProperty
据我所知,该模式可以在任何对象上调用(对象,数组,null,未定义,true,false,数字基元,对象)。
Object.keys()
让它变慢,而是forEach()
反复访问.length
!如果使用的是经典for
-loop相反,它几乎快两倍,for..in
+ hasOwnProperty()
在Firefox 33
这个问题
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]);
}
}
}
}
在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.
});
在ES7 / 2016中,您可以使用和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.
});
上面会也作为一个一行代码:
Object.entries(myObj).forEach(([key, val]) => console.log(key, val));
如果还想遍历嵌套对象,则可以使用递归函数(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.
});
};
与上述功能相同,但使用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.
});
};
在这里我们遍历嵌套对象的更改值并Object.entries()
结合使用Object.fromEntries()
(ES10 / 2019)一次性返回一个新对象:
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.
})
);
_.each(validation_messages, function(value, key){
_.each(value, function(value, key){
console.log(value);
});
});
如果您使用递归,则可以返回任何深度的对象属性-
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
}
*/
该答案是本文中提供的解决方案的汇总,并提供了一些性能反馈。我认为有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在内部初始化了很多变量以构建此过程(请参见反馈以获取证明)。除非您没有开发一个值得优化的大型应用程序,否则就可以,但是如果您将优化放在首位,则应该考虑一下。
✔ 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
,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
我知道这已经很晚了,但是我花了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]);
}
}
}
}
obj
可能已经hasOwnProperty
在其自身上定义了功能,所以它将不使用中的功能Object.prototype
。您可以for
像这样在循环之前进行尝试,并且该循环obj.hasOwnProperty = function(){return false;}
不会遍历任何属性。
在ES7中,您可以执行以下操作:
for (const [key, value] of Object.entries(obj)) {
//
}
for(var key in validation_messages){
for(var subkey in validation_messages[key]){
//code here
//subkey being value, key being 'yourname' / 'yourmsg'
}
}
很少有这样做的方法...
1) 2层...在循环中...
for (let key in validation_messages) {
const vmKeys = validation_messages[key];
for (let vmKey in vmKeys) {
console.log(vmKey + vmKeys[vmKey]);
}
}
2)使用Object.key
Object.keys(validation_messages).forEach(key => {
const vmKeys = validation_messages[key];
Object.keys(vmKeys).forEach(key => {
console.log(vmKeys + vmKeys[key]);
});
});
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]);
}
}
}
并这样称呼:
recursiveObj(validation_messages);
这是AgileJon解决方案的改进和递归版本(demo):
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);
该解决方案适用于各种不同深度。
另外一个选项:
var testObj = {test: true, test1: false};
for(let x of Object.keys(testObj)){
console.log(x);
}
我认为值得指出的是jQuery很好地解决了这一问题$.each()
。
请参阅:https://api.jquery.com/each/
例如:
$('.foo').each(function() {
console.log($(this));
});
$(this)
是对象中的单个项目。$('.foo')
如果您不想使用jQuery的选择器引擎,请切换到变量。
var obj={
name:"SanD",
age:"27"
}
Object.keys(obj).forEach((key)=>console.log(key,obj[key]));
要遍历JavaScript对象,我们可以使用forEach并使用箭头函数来优化代码
我无法获得以上职位来做我想做的事情。
在与其他答复一起玩耍之后,我做到了。这很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);
}
...在控制台中产生:
myObj.pageURL = BLAH
myObj.emailBox.model = emailAddress
myObj.emailBox.selector = #emailAddress
myObj.passwordBox.model = password
myObj.passwordBox.selector = #password
适用于我的解决方案如下
_private.convertParams=function(params){
var params= [];
Object.keys(values).forEach(function(key) {
params.push({"id":key,"option":"Igual","value":params[key].id})
});
return params;
}
就我而言(在前面的基础上)可以是任意数量的级别。
var myObj = {
rrr: undefined,
pageURL : "BLAH",
emailBox : {model:"emailAddress", selector:"#emailAddress"},
passwordBox: {model:"password" , selector:"#password"},
proba: {odin:{dva:"rr",trr:"tyuuu"}, od:{ff:5,ppa:{ooo:{lll:'lll'}},tyt:'12345'}}
};
function lookdeep(obj,p_Name,gg){
var A=[], tem, wrem=[], dd=gg?wrem:A;
for(var p in obj){
var y1=gg?'':p_Name, y1=y1 + '.' + p;
if(obj.hasOwnProperty(p)){
var tem=obj[p];
if(tem && typeof tem=='object'){
a1=arguments.callee(tem,p_Name,true);
if(a1 && typeof a1=='object'){for(i in a1){dd.push(y1 + a1[i])};}
}
else{
dd.push(y1 + ':' + String(tem));
}
}
};
return dd
};
var s=lookdeep(myObj,'myObj',false);
for (var x=0; x < s.length; ++x) {
console.log(s[x]+'\n');}
结果:
["myObj.rrr:undefined",
"myObj.pageURL:BLAH",
"myObj.emailBox.model:emailAddress",
"myObj.emailBox.selector:#emailAddress",
"myObj.passwordBox.model:password",
"myObj.passwordBox.selector:#password",
"myObj.proba.odin.dva:rr",
"myObj.proba.odin.trr:tyuuu",
"myObj.proba.od.ff:5",
"myObj.proba.od.ppa.ooo.lll:lll",
"myObj.proba.od.tyt:12345"]