질문자 :edt
객체인 값을 포함하여 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" } }
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]); } }
AgileJonObject.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]); });
Axel Rauschmayer이것의 문제
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]); } } } }
ChangoES6/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. });
JS 빈
ES7/2016 에서는 Object.keys
대신 Object.entries
를 사용하고 다음과 같이 객체를 반복할 수 있습니다.
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));
jsbin
중첩된 객체도 반복하려는 경우 재귀 함수(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. }); };
JS 빈
위의 함수와 동일하지만 Object.keys()
대신 ES7 Object.entries()
사용:
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.fromEntries()
( ES10/2019 )와 결합된 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. }) );
객체를 반복하는 또 다른 방법은 for ... in 및 for ... of 를 사용하는 것입니다 . vdogenne의 멋지게 작성된 답변을 참조하십시오.
RotaretiUnderscore.js의 _.each
:
_.each(validation_messages, function(value, key){ _.each(value, function(value, key){ console.log(value); }); });
Tim Santeford재귀를 사용하면 모든 깊이의 객체 속성을 반환할 수 있습니다.
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 } */
kennebec이 답변은 일부 성능 피드백 과 함께 이 게시물에서 제공된 솔루션의 집합체입니다. 나는 두 가지 사용 사례가 있다고 생각하며 OP는 루프 프로세스 중에 키를 사용하기 위해 키에 액세스해야 하는지에 대해 언급하지 않았습니다.
I. 키에 액세스해야 합니다.
✔ 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)) { }
그러나 편집 당시에는 JavaScript가 이 절차를 빌드하기 위해 내부적으로 많은 변수를 초기화하기 때문에 ES7 방법을 권장하지 않습니다(증명에 대한 피드백 참조). 최적화할 가치가 있는 거대한 응용 프로그램을 개발하지 않는 한 괜찮지만 최적화가 최우선이라면 생각해 봐야 합니다.
Ⅱ. 각 값에 액세스하기만 하면 됩니다.
✔ 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
for...of
루프를 사용하는 것보다 조금 더 빠른 것 같습니다. 그러나 차이점은 그다지 중요하지 않으며 Chrome은 for...of
for
루프보다 빠르게 실행되므로 어떤 경우에도(4차 및 6차 테스트) Object.values
를 처리할 때 for...of
를 사용하는 것이 좋습니다.
Firefox에서 for...in
루프는 정말 느리므로 반복 중에 키를 캐시하려면 Object.keys
를 사용하는 것이 좋습니다. 또한 Chrome은 동일한 속도로 두 구조를 모두 실행합니다(첫 번째 및 마지막 테스트).
https://jsperf.com/es7-and-misc-loops 에서 테스트를 확인할 수 있습니다.
vdegennefor(var k in validation_messages) { var o = validation_messages[k]; do_something_with(o.your_name); do_something_else_with(o.your_msg); }
chaosAgileJon 답변의 최적화되고 개선된 버전:
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]); } } } }
Azderp는 값
for (var key in p) { alert(key + ' => ' + p[key]); }
또는
Object.keys(p).forEach(key => { console.log(key, p[key]) })
WesamES7에서는 다음을 수행할 수 있습니다.
for (const [key, value] of Object.entries(obj)) { // }
Kévin Berthommierfor(var key in validation_messages){ for(var subkey in validation_messages[key]){ //code here //subkey being value, key being 'yourname' / 'yourmsg' } }
Dmitri Farkov그 방법 몇가지...
1) 2계층 for...in 루프...
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);
Alireza다른 옵션:
var testObj = {test: true, test1: false}; for(let x of Object.keys(testObj)){ console.log(x); }
dude다음은 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);
이 솔루션은 모든 종류의 다양한 깊이에서 작동합니다.
JepZ한 달 전에 완성된 ECMAScript 2017 에는 Object.values()가 도입되었습니다. 이제 다음과 같이 할 수 있습니다.
let v; for (v of Object.values(validation_messages)) console.log(v.your_name); // jimmy billy
Chong Lip Phang$.each()
이것을 잘 정렬한다는 점을 지적할 가치가 있다고 생각합니다.
참조: .each()
예시:
$('.foo').each(function() { console.log($(this)); });
$(this)
는 객체 내부의 단일 항목입니다. jQuery의 선택기 엔진을 사용하지 않으려면 $('.foo')
Daniel Dewhurst나는 내가 추구했던 것을 꽤하기 위해 이전 답변을 얻을 수 없었습니다.
여기에서 다른 답변을 가지고 놀다가 이것을 만들었습니다. 해킹이지만 작동합니다!
이 개체의 경우:
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
user1833875 var obj = { name: "SanD", age: "27" } Object.keys(obj).forEach((key) => console.log(key,obj[key]));
JavaScript 객체 를 반복하기 위해 forEach를 사용할 수 있고 코드를 최적화하기 위해 화살표 기능을 사용할 수 있습니다.
Sandip BailkarES8 Object.entries()를 사용하는 것이 이를 달성하는 보다 간결한 방법이어야 합니다.
Object.entries(validation_messages).map(([key,object]) => { alert(`Looping through key : ${key}`); Object.entries(object).map(([token, value]) => { alert(`${token} : ${value}`); }); });
simmmplyAmit나를 위해 작동하는 솔루션은 다음과 같습니다.
_private.convertParams = function(params){ var params = []; Object.keys(values).forEach(function(key) { params.push({"id":key, "option":"Igual", "value":params[key].id}) }); return params; }
Jorge Santos Neill이국적인 것 - 깊은 횡단
JSON.stringify(validation_messages,(field,value)=>{ if(!field) return value; // ... your code return value; })
이 솔루션에서는 전체 개체와 중첩 개체를 심층 탐색할 수 있는 교체기 를 사용합니다. 각 수준에서 모든 필드와 값을 얻을 수 있습니다. 각 필드에 대한 전체 경로 를 가져와야 하는 경우 여기를 참조하십시오 .
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; })
Kamil Kiełczewski 2020년에 당신은 불변하고 보편적인 기능을 원합니다
이것은 하위 개체, 배열 및 문자열로 구성된 다차원 개체를 살펴보고 사용자 정의 함수를 적용합니다.
export const iterate = (object, func) => { const entries = Object.entries(object).map(([key, value]) => Array.isArray(value) ? [key, value.map(e => iterate(e, func))] : typeof value === 'object' ? [key, iterate(value, func)] : [key, func(value)] ); return Object.fromEntries(entries); };
용법:
const r = iterate(data, e=>'converted_'+e); console.log(r);
Sebastien HorinforEach2
(여기 에서 찾음):
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); } } } }); }
T.Toduavar validation_messages = { "key_1": { "your_name": "jimmy", "your_msg": "hello world" }, "key_2": { "your_name": "billy", "your_msg": "foo equals bar" } } for (var i in validation_messages) { console.log("i = \"" + i + "\""); console.log("validation_messages[\"" + i + "\"] = "); console.log(validation_messages[i]); console.log("\n"); for (var j in validation_messages[i]) { console.log("j = \"" + j + "\""); console.log("validation_messages[\"" + i + "\"][\"" + j + "\"] = \"" + validation_messages[i][j] + "\""); console.log("\n"); } console.log('\n'); }
출력:
i = "key_1" validation_messages["key_1"] = { your_name:"jimmy", your_msg:"hello world" } j = "your_name" validation_messages["key_1"]["your_name"] = "jimmy" j = "your_msg" validation_messages["key_1"]["your_msg"] = "hello world" i = "key_2" validation_messages["key_2"] = { your_name:"billy", your_msg:"foo equals bar" } j = "your_name" validation_messages["key_2"]["your_name"] = "billy" j = "your_msg" validation_messages["key_2"]["your_msg"] = "foo equals bar"
Steve Williams제 경우에는(위의 내용을 기반으로) 여러 수준에서 가능합니다.
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"]
user2515312출처 : http:www.stackoverflow.com/questions/921789/how-to-loop-through-a-plain-javascript-object-with-the-objects-as-members