2013-07-30 2 views
8

오늘은 죽일 너무 많은 시간이 우연히 내가 노드 (v0.10.13) 명령 줄 조금을했다 : 어떤 instanceof가하는 것은, MDN에 따라, 이제JavaScript primitives가 objectof 객체가 아닌 이유는 무엇입니까?

> 1 instanceof Object 
false 
> (1).__proto__ 
{} 
> (1).__proto__ instanceof Object 
true 
> (1).__proto__.__proto__ === Object.prototype 
true 

:

instanceof 연산자는 객체의 프로토 타입이 인지 여부를 테스트하여 생성자의 프로토 타입 속성을 연결합니다.

분명히 Object.prototype1의 프로토 타입 체인입니다. 그렇다면 1 instanceof Object은 왜 거짓입니까? 아마도 1은 원시 객체가 아니기 때문에 시작하는 것일까?

좋아, 내가 받아 들일, 나는 더 많은 테스트를했다 :

> (1).__proto__ === (2).__proto__ 
true 
> 'a'.__proto__ === 'b'.__proto__ 
true 
> (1).__proto__ === 'a'.__proto__ 
false 
> (1).__proto__.__proto__ === 'a'.__proto__.__proto__ 
true 
> (1).__proto__.type = 'number' 
'number' 
> 'a'.__proto__.type = 'string' 
'string' 
> (2).type 
'number' 
> (1.5).type 
'number' 
> 'b'.type 
'string' 

그래서 분명히 모든 수의 기본 요소는 하나의 객체에서 상속, 모든 문자열 프리미티브는 다른 객체로부터 상속합니다. 이 두 객체는 ​​모두 Object.prototype에서 상속받습니다.

이제 숫자와 문자열을 프리미티브로 간주하면 왜 다른 개체에서 상속합니까? 반대로, 다른 객체를 상속받을 때 왜 객체를 고려해야합니까? 객체의 자식이 객체가 아니라는 것은 나에게 무의미한 것처럼 보인다.

한편, 나는 Firefox 22에서 이것들을 테스트했으며 같은 결과를 얻었다.

답변

25

"복싱"(c# related article, java related article)으로 알려진 속임수에 빠져 들어 와서 모든 사람을 혼란스럽게합니다. 처음에 올바른 답을 얻었습니다 :

아마도 1은 원시 객체가 아니기 때문에 시작했을까요?

정확합니다. 그러나, 어떻게 프리미티브가 메소드를 포함 할 수 있습니까? 속성을 어떻게 포함 할 수 있습니까? 결국 js에서는 가능한 가장 낮은 수준으로 표현됩니다 (#4.3.2 참조). 당신이 primitive.property을 할 때마다이 값이 실제로 유용하게하려면, 다음 (#11.2.1)을 발생합니다

Object(primitive).property; 

즉, JS 자동 복싱이있다. 이것은 내가 좋아하는 트릭 중 하나를 사용하여 검증 할 수 있습니다

var primitive = 'food'; 
Object(primitive).isPizza = true; 
console.log(Object(primitive).isPizza); 

박스형 primitive은 고유 눈송이 - 당신은 그것을 두 번째 상자 때, 그것은 :

var primitive = 'food'; 
primitive.isPizza = true; //yummy 
console.log(primitive.isPizza); //undefined. where did my pizza go!? 

primitive.isPizza 때문에이 복싱의 사라 같은 것을 말하는 것이 아닙니다. 박스형 값은 빠르게 GCd되며 시간이 지나면 잊어 버릴 수 있습니다.당신의 원시가 아니라,없는 경우

이것은 원시적 발생하지 않습니다

var obj = new String('food'); 
obj.isPizza = true; 
console.log(obj.isPizza); //true 

이 당신은 객체를 사용한다는 의미 하는가, 프리미티브하지? 아니, 시간은 당신이 기본 요소에 대한 메타 데이터를 저장하는 필요성을 있다는 단순한 이유 아주 멀리 몇 가지, 그리고 객체는 일을 복잡하게 :

obj === primitive; //false, obj is an object, primitive is a primitive 
+0

멋진 대답, 감사합니다. –

+0

내 모든 +1이 당신에게 간다! – Greg

+0

Myne 2 .... :-). –

관련 문제