JavaScript 개체의 속성을 어떻게 열거합니까?[복제하다]
-
01-07-2019 - |
문제
이 질문에는 이미 답변이 있습니다.
JavaScript 개체의 속성을 어떻게 열거합니까?
실제로 정의된 모든 변수와 해당 값을 나열하고 싶지만 변수를 정의하면 실제로는 창 개체의 속성이 생성된다는 것을 배웠습니다.
해결책
충분히 간단합니다.
for(var propertyName in myObject) {
// propertyName is what you want
// you can get the value like this: myObject[propertyName]
}
이제 개인 변수는 사용할 수 없기 때문에 이 방법으로 얻을 수 없습니다.
편집하다: @bitwiseplatypus 당신이 hasOwnProperty()
메소드를 사용하면 상속된 속성을 얻을 수 있습니다. 그러나 객체 지향 프로그래밍에 익숙한 사람이 왜 그 이하를 기대하는지 모르겠습니다!일반적으로 이 문제를 제기하는 사람은 이에 대해 Douglas Crockford의 경고를 받았는데, 이는 여전히 나를 약간 혼란스럽게 합니다.다시 말하지만, 상속은 OO 언어의 일반적인 부분이므로 프로토타입임에도 불구하고 JavaScript의 일부입니다.
자, 그 말은, hasOwnProperty()
~이다 필터링에는 유용하지만 상속된 속성을 얻는 데 위험한 것이 있는 것처럼 경고를 울릴 필요는 없습니다.
편집 2: @bitwiseplatypus 처음에 객체를 작성한 시점(프로토타입을 통해)보다 늦은 시점에 누군가가 객체에 속성/메서드를 추가하면 발생할 수 있는 상황이 발생합니다. 이로 인해 예상치 못한 동작이 발생할 수 있다는 것은 사실이지만 저는 개인적으로 그렇게 생각하지 않습니다. 그것이 전적으로 내 문제라고는 볼 수 없습니다.단지 의견의 문제입니다.게다가, 객체를 구성하는 동안 프로토타입을 사용하는 방식으로 사물을 디자인하지만 객체의 속성을 반복하는 코드가 있고 모든 상속된 속성을 원하면 어떻게 될까요?나는 사용하지 않을 것이다 hasOwnProperty()
.그런 다음 나중에 누군가가 새 속성을 추가한다고 가정해 보겠습니다.그 시점에서 상황이 나쁘게 행동하면 그게 내 잘못인가요?나는 그렇게 생각하지 않습니다.나는 이것이 jQuery가 예를 들어 작동 방식을 확장하는 방법을 지정한 이유라고 생각합니다. jQuery.extend
그리고 jQuery.fn.extend
).
다른 팁
사용 for..in
루프를 사용하여 객체의 속성을 열거하지만 주의하세요.열거는 열거되는 개체의 속성뿐만 아니라 상위 개체의 프로토타입에서도 속성을 반환합니다.
var myObject = {foo: 'bar'};
for (var name in myObject) {
alert(name);
}
// results in a single alert of 'foo'
Object.prototype.baz = 'quux';
for (var name in myObject) {
alert(name);
}
// results in two alerts, one for 'foo' and one for 'baz'
열거형에 상속된 속성을 포함하지 않으려면 다음을 확인하세요. hasOwnProperty()
:
for (var name in myObject) {
if (myObject.hasOwnProperty(name)) {
alert(name);
}
}
편집하다: 나는 상속된 속성을 열거하는 것에 대해 걱정할 필요가 없다는 JasonBunting의 진술에 동의하지 않습니다.거기 ~이다 예상하지 못한 상속된 속성을 열거하는 것은 코드의 동작을 변경할 수 있기 때문에 위험합니다.
이 문제가 다른 언어에도 존재하는지 여부는 중요하지 않습니다.사실은 존재하며, 객체의 프로토타입에 대한 수정은 수정이 인스턴스화 후에 발생하더라도 하위 객체에 영향을 주기 때문에 JavaScript는 특히 취약합니다.
이것이 JavaScript가 제공하는 이유입니다. hasOwnProperty()
, 그리고 이것이 제3자 코드(또는 프로토타입을 수정할 수 있는 다른 코드)가 귀하의 코드를 손상시키지 않도록 하기 위해 이를 사용해야 하는 이유입니다.몇 바이트의 추가 코드를 추가하는 것 외에는 사용에 따른 단점이 없습니다. hasOwnProperty()
.
이미 여러 번 제안된 표준 방법은 다음과 같습니다.
for (var name in myObject) {
alert(name);
}
그러나 Internet Explorer 6, 7 및 8에는 JavaScript 인터프리터에 버그가 있어 일부 키가 열거되지 않는 효과가 있습니다.이 코드를 실행하면:
var obj = { toString: 12};
for (var name in obj) {
alert(name);
}
If는 IE를 제외한 모든 브라우저에서 "12"를 경고합니다.IE는 이 키를 무시합니다.영향을 받는 키 값은 다음과 같습니다.
isPrototypeOf
hasOwnProperty
toLocaleString
toString
valueOf
IE에서 정말로 안전하려면 다음과 같은 것을 사용해야 합니다:
for (var key in myObject) {
alert(key);
}
var shadowedKeys = [
"isPrototypeOf",
"hasOwnProperty",
"toLocaleString",
"toString",
"valueOf"
];
for (var i=0, a=shadowedKeys, l=a.length; i<l; i++) {
if map.hasOwnProperty(a[i])) {
alert(a[i]);
}
}
좋은 소식은 EcmaScript 5가 Object.keys(myObject)
객체의 키를 배열과 일부 브라우저(예:Safari 4)는 이미 구현했습니다.
최신 브라우저(ECMAScript 5)에서는 열거 가능한 모든 속성을 얻으려면 다음을 수행할 수 있습니다.
Object.keys(obj)(이전 브라우저에서 이전 버전과의 호환성을 위한 스니펫을 얻으려면 링크를 확인하세요.)
또는 열거할 수 없는 속성도 얻으려면:
Object.getOwnPropertyNames(obj)
추가 정보:열거 가능한 속성이란 무엇입니까?
나는 나를 놀라게 한 사례의 예가 적절하다고 생각합니다.
var myObject = { name: "Cody", status: "Surprised" };
for (var propertyName in myObject) {
document.writeln( propertyName + " : " + myObject[propertyName] );
}
하지만 놀랍게도 출력은 다음과 같습니다.
name : Cody
status : Surprised
forEach : function (obj, callback) {
for (prop in obj) {
if (obj.hasOwnProperty(prop) && typeof obj[prop] !== "function") {
callback(prop);
}
}
}
왜?페이지의 또 다른 스크립트는 객체 프로토타입을 확장했습니다.
Object.prototype.forEach = function (obj, callback) {
for ( prop in obj ) {
if ( obj.hasOwnProperty( prop ) && typeof obj[prop] !== "function" ) {
callback( prop );
}
}
};
for (prop in obj) {
alert(prop + ' = ' + obj[prop]);
}
간단한 JavaScript 코드:
for(var propertyName in myObject) {
// propertyName is what you want.
// You can get the value like this: myObject[propertyName]
}
jQuery:
jQuery.each(obj, function(key, value) {
// key is what you want.
// The value is in: value
});
찾았어요... for (property in object) { // do stuff }
모든 속성을 나열하므로 창 개체에 전역적으로 선언된 모든 변수가 나열됩니다.
객체의 속성을 열거하는 방법은 다음과 같습니다.
var params = { name: 'myname', age: 'myage' }
for (var key in params) {
alert(key + "=" + params[key]);
}
당신이 사용하는 경우 Underscore.js 라이브러리, 기능을 사용할 수 있습니다 열쇠:
_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]
Python의 dict에는 'keys' 메소드가 있는데, 이는 정말 유용합니다.JavaScript에서는 다음과 같은 것을 가질 수 있다고 생각합니다.
function keys(){
var k = [];
for(var p in this) {
if(this.hasOwnProperty(p))
k.push(p);
}
return k;
}
Object.defineProperty(Object.prototype, "keys", { value : keys, enumerable:false });
편집하다:그러나 @carlos-ruana의 답변은 매우 잘 작동합니다.Object.keys(window)를 테스트했는데 결과는 예상한 대로였습니다.
5년 후 편집:연장하는 것은 좋지 않다 Object
, 사용하려는 다른 라이브러리와 충돌할 수 있기 때문입니다. keys
해당 개체에 영향을 미치면 프로젝트에서 예측할 수 없는 동작이 발생하게 됩니다.@carlos-ruana 답변은 객체의 키를 얻는 올바른 방법입니다.
개체에 대해 새 코드를 작성하기 위해 속성을 열거하려는 경우 Firebug와 같은 디버거를 사용하여 시각적으로 확인하는 것이 좋습니다.
또 다른 편리한 기술은 Prototype의 Object.toJSON()을 사용하여 객체를 JSON으로 직렬화하는 것입니다. 그러면 속성 이름과 값이 모두 표시됩니다.
var data = {name: 'Violet', occupation: 'character', age: 25, pets: ['frog', 'rabbit']};
Object.toJSON(data);
//-> '{"name": "Violet", "occupation": "character", "age": 25, "pets": ["frog","rabbit"]}'
저는 아직 JavaScript 초보자이지만 객체와 그 자식의 모든 속성을 재귀적으로 인쇄하는 작은 함수를 작성했습니다.
getDescription(object, tabs) {
var str = "{\n";
for (var x in object) {
str += Array(tabs + 2).join("\t") + x + ": ";
if (typeof object[x] === 'object' && object[x]) {
str += this.getDescription(object[x], tabs + 1);
} else {
str += object[x];
}
str += "\n";
}
str += Array(tabs + 1).join("\t") + "}";
return str;
}