Object.create (null)로 JS 객체를 생성합니까?


150

JS 객체를 만드는 많은 방법을 알고 있지만의 것을 알지 못했습니다 Object.create(null).

질문:

정확히 다음과 동일합니까?

var p = {}

vs

var p2 = Object.create(null);

?

답변:


199

그것들은 동등하지 않습니다. {}.constructor.prototype == Object.prototype반면에 Object.create(null)아무것도 상속받지 않으므로 속성이 전혀 없습니다.

즉, 자바 스크립트 객체는 다음과 같이 프로토 타입으로 null로 명시 적으로 생성하지 않는 한 기본적으로 Object에서 상속됩니다 Object.create(null).

{}대신에 동일합니다 Object.create(Object.prototype).


Chrome Devtool에서는 속성 Object.create(null)이없는 것을 알 수 있습니다 .__proto__{}

여기에 이미지 설명을 입력하십시오


99

그것들은 분명히 동등하지 않습니다. 왜 차이가 나는지 더 자세히 설명하기 위해이 답변을 작성하고 있습니다.

  1. var p = {};

    의 속성과 메서드를 상속하는 개체를 만듭니다 Object.

  2. var p2 = Object.create(null);

    상속받지 않는 객체를 만듭니다.

객체를지도로 사용하고 위의 방법 1을 사용하여 객체를 만드는 경우지도에서 조회를 수행 할 때 특히주의해야합니다. 의 속성과 메소드 Object가 상속되므로지도에 삽입하지 않은 키가있는 경우 코드가 실행될 수 있습니다. 예를 들어,에서 조회를 수행 한 경우 toString해당 값을 입력하지 않아도 함수를 찾을 수 있습니다. 다음과 같이 해결할 수 있습니다.

if (Object.prototype.hasOwnProperty.call(p, 'toString')) {
    // we actually inserted a 'toString' key into p
}

에 무언가를 할당하는 것이 좋으며 p.toString, 상속 된 toString함수를 단순히 무시할 것 입니다 p.

p.hasOwnProperty('toString')"hasOwnProperty"키를 삽입했을 수 있기 때문에 수행 할 수 없으므로 p에 구현을 사용하도록 강요합니다 Object.

반면, 위의 방법 2를 사용 Object하면지도에 표시되는 것에 대해 걱정할 필요가 없습니다 .

다음과 같이 간단한 속성의 존재를 확인할 수 없습니다 if.

// Unreliable:
if (p[someKey]) {
    // ...
}

값은 빈 문자열 false이거나 null, 또는 undefined, 또는 0, 또는 NaN등일 수 있습니다 Object.prototype.hasOwnProperty.call(p, someKey). 속성이 존재하는지 여부를 확인하려면 여전히을 사용해야 합니다.


6
재산의 존재를 확인하는 간단한 대안은 다음과 같습니다.if (someKey in p) {
mrcrowl

2
@mrcrowl 그들이 사용한 경우에만 Object.create(null). 나는 당신이 그것을 사용한다고 절대적으로 옳았더라도 Object.create(null)코드가 변경 될 수 있다고 가정하고 객체 Object를 어느 시점에서 상속하는 것으로 바꿀 수 있습니다 . hasOwnProperty항상 작동합니다.
doug65536

1
이와 같은 것에 대해 조심해야한다고 생각합니다. 귀하의 답변에 감사하지만 문서는 작업중 인 코드로 작업하는 데 필요한 API를 제공해야합니다. github에서 임의의 코드를 가져 오는 경우 포크를 사용하여 문서화 된 업데이트가 적어도 안전합니다. 언급하지 않는 것이 코드 {}보다 Object.create(null)우연히 상속 된 속성을 잡는 경우 걱정할 더 큰 버그가있을 가능성이 있습니다. Object.create (null)을 사소한 최적화로 사용하는 사람들 만 볼 수 있습니다.
aaaaaa

이중 부정 !!p[key]은 잘 작동합니다 Object.create(null). 그러나 hasKey = (key, input) => Object.prototype.hasOwnProperty.call(input, key)나쁘지 않습니다
그리고

> p에 "hasOwnProperty"키를 삽입 했으므로 p.hasOwnProperty ( 'toString')을 수행 할 수 없으므로 Object에서 구현을 사용하도록 강요합니다. 불필요합니다. 이 경우 p모든 메소드를 삽입 할 수있어 안전하지 않기 때문에 메소드를 사용할 수 없습니다 .
xianshenglu

1

를 사용하여 객체를 만들면 {}프로토 타입 Object.prototype에서 기본 기능을 상속 하는 프로토 타입이 있는 Object객체 Object.create(null)가 생성되고 프로토 타입이 null 인 빈 객체가 생성됩니다.


0

누군가 구현을 찾고 있다면 Object.create(null)어떻게 작동하는지 알고 싶습니다. __proto__비표준 인을 사용하여 작성 되었으므로 권장하지 않습니다 .

function objectCreateMimic()
{
  /*optional parameters: prototype_object, own_properties*/
  var P = arguments.length>0?arguments[0]:-1;
  var Q = arguments.length>1?arguments[1]:null;
  var o = {};
  if(P!==null && typeof P === "object")
  {
    o.__proto__ = P;
  }
  else if(P===null)
  {
    o.__proto__ = null;
  }
  if(Q!==null && typeof Q === "object")
  {
   for(var key in Q)
   {
     o[key] = Q[key];
   }
  }
  return o;
}

참고 : 호기심으로 이것을 작성했으며 간단한 용어로 작성되었습니다. 예를 들어 속성 ​​설명자를 두 번째 객체에서 반환 객체로 전송하지 않습니다.


1
여름에 ECMAScript가 출시 될 때 공식적 으로는 언어의 일부가 될 __proto__것 입니다.
Chiru

1
-1arguments.length>0?arguments[0]:-1;?
happy_marmoset

@happy_marmoset 늦은 응답이지만 Object첫 번째 인수가 주어지지 않은 경우 프로토 타입이 유지 되도록 null이 아닌 자리 표시 자 인 것처럼 보입니다 . 여기서 변수 이름이 훨씬 나을 수 있습니다.
Mike Hill

또한 두 번째 매개 변수는 실제 속성 자체가 아닌 속성 설명자를 설명 해야 합니다. 참조 : developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Mike Hill

0

Object.create (null)로 Object를 만들면 프로토 타입없이 Object를 만듭니다. 여기서 null 은 프로토 타입 체인의 끝을 의미합니다. 그럼에도 불구하고 {}와 같은 객체를 만들면 객체 프로토 타입이 추가됩니다. 따라서 이들은 프로토 타입이없는 다른 하나의 프로토 타입을 가진 두 개의 서로 다른 객체입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.