Object.getOwnPropertyNames 대 Object.keys


214

자바 스크립트 Object.getOwnPropertyNamesObject.keys자바 스크립트 의 차이점은 무엇입니까 ? 또한 일부 예가 이해 될 것이다.


3
둘 다 MDN 기사에서 판단하면 반환 목록에 열거 할 수없는 속성이 포함되는지 여부는 다릅니다. Object.keys() 그들을 반환하지 않습니다, 동안 Object.getOwnPropertyNames()않습니다.
Sirko

답변:


289

약간의 차이가 있습니다. Object.getOwnPropertyNames(a)객체의 모든 속성을 반환 합니다 a. 열거 가능한 모든 자체 속성을 Object.keys(a)반환 합니다 . 즉, 객체 속성을 만들지 않고 객체 속성을 정의하면 enumerable: false이 두 가지 방법으로 동일한 결과를 얻을 수 있습니다.

테스트하기 쉽습니다.

var a = {};
Object.defineProperties(a, {
    one: {enumerable: true, value: 'one'},
    two: {enumerable: false, value: 'two'},
});
Object.keys(a); // ["one"]
Object.getOwnPropertyNames(a); // ["one", "two"]

속성 속성 설명자를 제공하지 않고 속성을 정의하는 경우 (사용하지 않음을 의미 Object.defineProperties) 예를 들면 다음과 같습니다.

a.test = 21;

그런 속성은 자동으로 열거 가능하고 두 방법 모두 동일한 배열을 생성합니다.


26
특히 length배열 객체 의 속성은 열거 할 수 없으므로에 표시되지 않습니다 Object.keys.
Barmar

6
@Barmar length객체 의 속성은 객체 자체가 아니라 프로토 타입에 있으므로 나열 하지도 Object.keys않습니다 Object.getOwnPropertyNames.
Qodesmith

9
@TheQodesmith Object.getOwnPropertyNames(anyArray)포함 결과length
thorn̈

6
나는 정정되었다! Object.getOwnPropertyNames(anyArray)실제로 length반환 된 배열에 포함 됩니다!
Qodesmith

예. 그러나 Array.prototype도 있습니다. Array.prototype을 일반 배열처럼 수정할 수 있다는 것은 이상합니다. 그러나 새로 생성 된 Array 인스턴스에는 영향을 미치지 않는 것 같습니다. stackoverflow.com/questions/48020958/…
trollkotze

21

또 다른 차이점은 배열 Object.getOwnPropertyNames메서드가 추가 속성 인을 반환한다는 것입니다 length.

var x = ["a", "b", "c", "d"];
Object.keys(x);  //[ '0', '1', '2', '3' ]
Object.getOwnPropertyNames(x);  //[ '0', '1', '2', '3', 'length' ]

1

객체 생성시 리터럴 표기법 vs 생성자 여기에 나를 얻는 것이 있습니다.

const cat1 = {
    eat() {},
    sleep() {},
    talk() {}
};

// here the methods will be part of the Cat Prototype
class Cat {
    eat() {}
    sleep() {}
    talk() {}
}

const cat2 = new Cat()

Object.keys(cat1) // ["eat", "sleep", "talk"]
Object.keys(Object.getPrototypeOf(cat2)) // []

Object.getOwnPropertyNames(cat1) // ["eat", "sleep", "talk"]
Object.getOwnPropertyNames(Object.getPrototypeOf(cat2)) // ["eat", "sleep", "talk"]

cat1 // {eat: function, sleep: function, talk: function}
cat2 // Cat {}

// a partial of a function that is used to do some magic redeclaration of props
function foo(Obj) {
    var propNames = Object.keys(Obj);

    // I was missing this if
    // if (propNames.length === 0) {
    //     propNames = Object.getOwnPropertyNames(Obj);
    // }

    for (var prop in propNames) {
        var propName = propNames[prop];

        APIObject[propName] = "reasign/redefine or sth";
    }
}

따라서 필자의 경우 foocat2 유형의 객체를 제공하면 함수가 작동하지 않았습니다.

객체를 만드는 다른 방법이 있으므로 거기에 다른 꼬임이있을 수 있습니다.


Object.getOwnPropertyNames에 대한 속성 이름을 반환 cat1하지 cat2. 객체를 생성하는 두 가지 방법 사이의 차이를 생성하지 않는 Object.getOwnPropertyNamesObject.keys.
Boric

1
@Boric 네 맞습니다. cat2 대신 Object.getPrototypeOf (cat2)를 두 가지 방법으로 모두 사용할 수있었습니다. 코드가 기억 나지 않아서 확실하지 않습니다. 답을 고칠 것입니다.
h3dkandi

0

이미 설명했듯이 .keys열거 가능한 속성을 반환하지 않습니다.

예제와 관련하여 함정 사례 중 하나는 Error객체입니다. 일부 속성은 열거 할 수 있습니다.
그래서 잠시 console.log(Object.keys(new Error('some msg')))생산량 [], console.log(Object.getOwnPropertyNames(new Error('some msg')))수율["stack", "message"]

console.log(Object.keys(new Error('some msg')));
console.log(Object.getOwnPropertyNames(new Error('some msg')));


-5

또 다른 차이점은 (적어도 nodejs와 함께) "getOwnPropertyNames"함수는 키 순서를 보장하지 않으므로 일반적으로 "키"함수를 사용합니다.

    Object.keys(o).forEach(function(k) {
      if (!o.propertyIsEnumerable(k)) return;
      // do something...
    });

1
현재 버전의 Node.js에서도 여전히 그렇 getOwnPropertyNames습니까? 그렇다면 순서 가 맞지 않은 예를 알고 있습니까? ES2015를 지정하기 때문에 를 주문Obect.getOwnPropertyNames 그동안, 대한 순서Obect.keys 까지 구현에 아직도있다.
szupie 2016 년

7
나는 항상 JS 객체 키의 순서가 없다고 생각했으며 구현이 순서를 유지하더라도 그것에 의존해서는 안됩니까?
Juan Mendes

1
음, 나는 그것이 다른 방향이라고 생각합니다. getOwnPropertyNames의 순서는 사양에 정의되어 있습니다. Object.keys는 구현에 달려 있습니다.
tjvr

1
: 다음의 모든 지정되지 않은 순서를 가지고 for-in loop, Object.keys하고 Object.getOwnPropertyNames. 즉, 세 가지 모두 서로에 대해 일관된 순서로 열거됩니다.
Thomas Eding
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.