Iterate through object properties
1 2 3 4 5 6 7 8 9 10 11 12 | var obj = { name:"Simon", age:"20", clothing: { style:"simple", hipster: false } } for(var propt in obj){ console.log(propt + ': ' + obj[propt]); } |
变量
迭代属性需要额外的
1 2 3 4 5 | for (var property in object) { if (object.hasOwnProperty(property)) { // do stuff } } |
这是必要的,因为对象的原型包含对象的附加属性,这些属性在技术上是对象的一部分。这些附加属性继承自基本对象类,但仍然是
从javascript 1.8.5开始,可以使用
1 2 3 4 | Object.keys(obj).forEach(function(key,index) { // key: the name of the object key // index: the ordinal position of the key within the object }); |
这比使用for-in循环更好(也更可读)。
这些浏览器支持它:
- 火狐(Gecko):4(2.0)
- 铬:5
- Internet Explorer:9
有关更多信息,请参阅mozilla developer network object.keys()的参考。
我们是2017年的女孩和男孩,我们没有那么多时间打字……所以让我们来做这个酷的新花式ecmascript 2016:
1 | Object.keys(obj).forEach(e => console.log(`key=${e} value=${obj[e]}`)); |
它是
您可以将其理解为"对于
在即将推出的ES版本中,您可以使用
1 | for (const [key, value] of Object.entries(obj)) { } |
或
1 | Object.entries(obj).forEach(([key, value]) => ...) |
如果只想迭代这些值,那么使用object.values:
1 | for (const value of Object.values(obj)) { } |
或
1 | Object.values(obj).forEach(value => ...) |
这只是一个
jquery允许您现在这样做:
1 2 3 | $.each( obj, function( key, value ) { alert( key +":" + value ); }); |
多米尼克的回答是完美的,我只是更喜欢这样做,因为阅读起来更干净:
1 2 3 4 5 | for (var property in object) { if (!object.hasOwnProperty(property)) continue; // Do stuff... } |
上面的答案有点烦人,因为在确保它是一个对象之后,它们无法解释您在for循环中所做的操作:您不能直接访问它!实际上,您只收到了应用于obj所需的密钥:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | var obj = { a:"foo", b:"bar", c:"foobar" }; // We need to iterate the string keys (not the objects) for(var someKey in obj) { // We check if this key exists in the obj if (obj.hasOwnProperty(someKey)) { // someKey is only the KEY (string)! Use it to get the obj: var myActualPropFromObj = obj[someKey]; // Since dynamic, use [] since the key isn't literally named"someKey" // NOW you can treat it like an obj var shouldBeBar = myActualPropFromObj.b; } } |
这都是ECMA5安全的。甚至可以在Rame JS版本中工作,比如Rhino;)
如果您的环境支持ES2017,那么我推荐object.entries:
1 2 3 | Object.entries(obj).forEach(([key, value]) => { console.log(`${key} ${value}`); }); |
如mozilla object.entries()文档所示:
The Object.entries() method returns an array of a given object's own
enumerable property [key, value] pairs, in the same order as that
provided by a for...in loop (the difference being that a for-in loop
enumerates properties in the prototype chain as well).
基本上,对于object.entries,我们可以放弃旧的for…in循环所需的以下额外步骤:
1 2 3 4 | // This step is not necessary with Object.entries if (object.hasOwnProperty(property)) { // do stuff } |
添加ES2015对
例如:
1 | let obj = { a: 'Carrot', b: 'Potato', Car: { doors: 4 } }; |
可以迭代
1 2 | // logs each key Reflect.ownKeys(obj).forEach(key => console.log(key)); |
如果要直接迭代对象键的值,可以定义一个
JS将尝试通过默认迭代器属性进行迭代,该属性必须定义为
如果希望能够迭代所有对象,可以将其添加为对象原型:
1 2 3 | Object.prototype[Symbol.iterator] = function*() { for(p of Reflect.ownKeys(this)){ yield this[p]; } } |
这将使您能够使用for…of循环迭代对象的值,例如:
1 | for(val of obj) { console.log('Value is:' + val ) } |
注意:在编写此答案(2018年6月)时,除了支持Generator和
for…in循环表示对象中的每个属性,因为它就像for循环。您在for…in循环中通过执行以下操作定义了propt:
1 2 3 | for(var propt in obj){ alert(propt + ': ' + obj[propt]); } |
for…in循环迭代对象的可枚举属性。无论您定义或放入for…in循环中的哪个变量,在每次进入它迭代的下一个属性时都会发生更改。for…in循环中的变量迭代键,但它的值是键的值。例如:
1 2 3 4 | for(var propt in obj) { console.log(propt);//logs name console.log(obj[propt]);//logs"Simon" } |
您可以看到变量与变量值的区别。相反,for…of循环则相反。
我希望这有帮助。
1 2 3 4 5 6 7 | let obj = {"a": 3,"b": 2,"6":"a"} Object.keys(obj).map((item) => {console.log("item", obj[item])}) // a // 3 // 2 |
你可以用木屑。文件
1 2 3 4 | var obj = {a: 1, b: 2, c: 3}; _.keys(obj).forEach(function (key) { ... }); |
1 2 3 | Object.keys(obj).forEach(key => console.log(`key=${key} value=${obj[key]}`) ); |
javascript中的对象是属性集合,因此可以在for each语句中循环。
您应该将
您的
现在,只需添加symbol.iterator方法,就可以将标准JS对象转换为可ITerable对象。然后,您可以使用
1 2 3 4 5 6 7 8 9 10 11 | var o = {a:1,b:2,c:3}, a = []; o[Symbol.iterator] = function*(){ var ok = Object.keys(this); i = 0; while (i < ok.length) yield this[ok[i++]]; }; for (var value of o) console.log(value); // or you can even do like a = [...o]; console.log(a); |
同时添加递归方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | function iterate(obj) { // watch for objects we've already iterated so we won't end in endless cycle // for cases like var foo = {}; foo.bar = foo; iterate(foo); var walked = []; var stack = [{obj: obj, stack: ''}]; while(stack.length > 0) { var item = stack.pop(); var obj = item.obj; for (var property in obj) { if (obj.hasOwnProperty(property)) { if (typeof obj[property] =="object") { // check if we haven't iterated through the reference yet var alreadyFound = false; for(var i = 0; i < walked.length; i++) { if (walked[i] === obj[property]) { alreadyFound = true; break; } } // new object reference if (!alreadyFound) { walked.push(obj[property]); stack.push({obj: obj[property], stack: item.stack + '.' + property}); } } else { console.log(item.stack + '.' + property +"=" + obj[property]); } } } } } |
用途:
1 | iterate({ foo:"foo", bar: { foo:"foo"} }); |
如果运行节点,我建议:
1 2 3 | Object.keys(obj).forEach((key, index) => { console.log(key); }); |
您基本上希望遍历对象中的每个属性。
杰西德
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | var Dictionary = { If: { you: { can: '', make: '' }, sense: '' }, of: { the: { sentence: { it: '', worked: '' } } } }; function Iterate(obj) { for (prop in obj) { if (obj.hasOwnProperty(prop) && isNaN(prop)) { console.log(prop + ': ' + obj[prop]); Iterate(obj[prop]); } } } Iterate(Dictionary); |
我想添加到上面的答案中,因为您可能与JavaScript有不同的意图。JSON对象和JavaScript对象是不同的,您可能希望使用上面提出的解决方案迭代JSON对象的属性,然后感到惊讶。
假设您有一个JSON对象,比如:
1 2 3 4 5 6 7 | var example = { "prop1":"value1", "prop2": ["value2_0", value2_1"], "prop3": { "prop3_1":"value3_1" } } |
迭代其"属性"的方法错误:
1 2 3 4 5 6 | function recursivelyIterateProperties(jsonObject) { for (var prop in Object.keys(example)) { console.log(prop); recursivelyIterateProperties(jsonObject[prop]); } } |
当遍历
递归迭代JSON对象属性的更好方法是首先检查该对象是否是序列:
1 2 3 4 5 6 7 8 9 10 11 | function recursivelyIterateProperties(jsonObject) { for (var prop in Object.keys(example)) { console.log(prop); if (!(typeof(jsonObject[prop]) === 'string') && !(jsonObject[prop] instanceof Array)) { recursivelyIterateProperties(jsonObject[prop]); } } } |
在循环中..的作用是创建一个新变量(var somevariable),然后将给定对象的每个属性逐个存储在这个新变量(somevariable)中。因此,如果使用块,则可以迭代。考虑下面的例子。
1 2 3 4 5 6 7 8 9 10 11 | var obj = { name:'raman', hobby:'coding', planet:'earth' }; for(var someVariable in obj) { //do nothing.. } console.log(someVariable); // outputs planet |
在这里,我将迭代每个节点并创建有意义的节点名。如果您注意到,instanceof array和instanceof object基本上做了相同的事情(在我的应用程序中,我给出了不同的逻辑)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function iterate(obj,parent_node) { parent_node = parent_node || ''; for (var property in obj) { if (obj.hasOwnProperty(property)) { var node = parent_node +"/" + property; if(obj[property] instanceof Array) { //console.log('array: ' + node +":" + obj[property]); iterate(obj[property],node) } else if(obj[property] instanceof Object){ //console.log('Object: ' + node +":" + obj[property]); iterate(obj[property],node) } else { console.log(node +":" + obj[property]); } } } } |
注意-我受到了恩德雷克·斯韦杰达尔的回答的启发。但是这个解决方案有更好的性能和更少的模糊性
为了进一步完善已接受的答案,值得注意的是,如果用
1 2 3 4 5 | for (var property in object) { if (Object.prototype.hasOwnProperty.call(object, property)) { // do stuff } } |