Programing

JavaScript 개체의 속성을 어떻게 열거합니까?

crosscheck 2020. 10. 2. 21:34
반응형

JavaScript 개체의 속성을 어떻게 열거합니까? [복제]


이 질문에 이미 답변이 있습니다.

JavaScript 개체의 속성을 어떻게 열거합니까?

실제로 정의 된 모든 변수와 해당 값을 나열하고 싶지만 변수를 정의하면 실제로 창 개체의 속성이 생성된다는 것을 배웠습니다.


충분히 간단합니다.

for(var propertyName in myObject) {
   // propertyName is what you want
   // you can get the value like this: myObject[propertyName]
}

이제는 사용할 수 없기 때문에 이러한 방식으로 개인 변수를 얻을 수 없습니다.


편집 : @bitwiseplatypushasOwnProperty()방법 을 사용하지 않으면 상속되는 속성을 얻을 수 있다는 것이 맞습니다. 그러나 객체 지향 프로그래밍에 익숙한 사람이 왜 그다지 기대하지 않는지 모르겠습니다! 일반적으로이 문제를 제기하는 사람은 이에 대해 Douglas Crockford의 경고를 받았지만 여전히 약간 혼란 스럽습니다. 다시 말하지만 상속은 OO 언어의 일반적인 부분이므로 프로토 타입 임에도 불구하고 JavaScript의 일부입니다.

이제 말했다, hasOwnProperty() 이다 필터링하는 데 유용하지만, 우리는 상속 된 속성을 가져 오는 위험한 무언가가있는 것처럼 경고를 소리를 할 필요가 없습니다.

편집 2 : @bitwiseplatypus 는 원래 객체를 작성한 시점보다 나중에 (프로토 타입을 통해) 누군가가 객체에 속성 / 메소드를 추가하면 발생할 수있는 상황을 나타냅니다.하지만 이것이 예기치 않은 동작을 일으킬 수 있다는 것은 사실입니다. , 나는 개인적으로 그것을 완전히 내 문제로 보지 않습니다. 단지 의견의 문제입니다. 게다가 객체를 구성하는 동안 프로토 타입을 사용하면서 객체의 속성을 반복하는 코드가 있고 상속 된 모든 속성을 원하는 방식으로 디자인하면 어떻게 될까요? 나는 사용하지 않을 것 hasOwnProperty()입니다. 그런 다음 누군가 나중에 새 속성을 추가한다고 가정 해 보겠습니다. 그 시점에서 상황이 나빠지면 그게 내 잘못입니까? 나는 그렇게 생각하지 않는다. 예를 들어 jQuery가 작동 방식을 확장하는 방법을 지정한 이유라고 생각합니다.jQuery.extendjQuery.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의 진술에 동의하지 않습니다. 이다 는 코드의 동작을 변경할 수 있기 때문에, 당신은 기대하지 않는 이상 상속 된 속성을 열거의 위험.

It doesn't matter whether this problem exists in other languages; the fact is it exists, and JavaScript is particularly vulnerable since modifications to an object's prototype affects child objects even if the modification takes place after instantiation.

This is why JavaScript provides hasOwnProperty(), and this is why you should use it in order to ensure that third party code (or any other code that might modify a prototype) doesn't break yours. Apart from adding a few extra bytes of code, there is no downside to using hasOwnProperty().


The standard way, which has already been proposed several times is:

for (var name in myObject) {
  alert(name);
}

However Internet Explorer 6, 7 and 8 have a bug in the JavaScript interpreter, which has the effect that some keys are not enumerated. If you run this code:

var obj = { toString: 12};
for (var name in obj) {
  alert(name);
}

If will alert "12" in all browsers except IE. IE will simply ignore this key. The affected key values are:

  • isPrototypeOf
  • hasOwnProperty
  • toLocaleString
  • toString
  • valueOf

To be really safe in IE you have to use something like:

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]);
  }
}

The good news is that EcmaScript 5 defines the Object.keys(myObject) function, which returns the keys of an object as array and some browsers (e.g. Safari 4) already implement it.


In modern browsers (ECMAScript 5) to get all enumerable properties you can do:

Object.keys(obj) (Check the link to get a snippet for backward compatibility on older browsers)

Or to get also non-enumerable properties:

Object.getOwnPropertyNames(obj)

Check ECMAScript 5 compatibility table

Additional info: What is a enumerable attribute?


I think an example of the case that has caught me by surprise is relevant:

var myObject = { name: "Cody", status: "Surprised" };
for (var propertyName in myObject) {
  document.writeln( propertyName + " : " + myObject[propertyName] );
}

But to my surprise, the output is

name : Cody
status : Surprised
forEach : function (obj, callback) {
    for (prop in obj) {
        if (obj.hasOwnProperty(prop) && typeof obj[prop] !== "function") {
            callback(prop);
        }
    }
}

Why? Another script on the page has extended the Object prototype:

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]);
}

Simple JavaScript code:

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
});

I found it... for (property in object) { // do stuff } will list all the properties, and therefore all the globally declared variables on the window object..


Here's how to enumerate an object's properties:

var params = { name: 'myname', age: 'myage' }

for (var key in params) {
  alert(key + "=" + params[key]);
}

If you are using the Underscore.js library, you can use function keys:

_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]

You can use the for of loop.

If you want an array use:

Object.keys(object1)

Ref. Object.keys()


Python's dict has 'keys' method, and that is really useful. I think in JavaScript we can have something this:

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 });

EDIT: But the answer of @carlos-ruana works very well. I tested Object.keys(window), and the result is what I expected.

EDIT after 5 years: it is not good idea to extend Object, because it can conflict with other libraries that may want to use keys on their objects and it will lead unpredictable behavior on your project. @carlos-ruana answer is the correct way to get keys of an object.


If you're trying to enumerate the properties in order to write new code against the object, I would recommend using a debugger like Firebug to see them visually.

Another handy technique is to use Prototype's Object.toJSON() to serialize the object to JSON, which will show you both property names and values.

var data = {name: 'Violet', occupation: 'character', age: 25, pets: ['frog', 'rabbit']};
Object.toJSON(data);
//-> '{"name": "Violet", "occupation": "character", "age": 25, "pets": ["frog","rabbit"]}'

http://www.prototypejs.org/api/object/tojson


I'm still a beginner in JavaScript, but I wrote a small function to recursively print all the properties of an object and its children:

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;
}

참고URL : https://stackoverflow.com/questions/85992/how-do-i-enumerate-the-properties-of-a-javascript-object

반응형