为什么JavaScript原语不是对象的实例?

为什么JavaScript原语不是对象的实例?,javascript,instanceof,Javascript,Instanceof,今天我碰巧有太多的时间来消磨,我玩了一下Node(v0.10.13)命令行: > 1 instanceof Object false > (1).__proto__ {} > (1).__proto__ instanceof Object true > (1).__proto__.__proto__ === Object.prototype true 现在,根据,instanceof所做的是: instanceof操作符测试对象在其原型中是否有 链接构造函数的原型属性

今天我碰巧有太多的时间来消磨,我玩了一下Node(v0.10.13)命令行:

> 1 instanceof Object
false
> (1).__proto__
{}
> (1).__proto__ instanceof Object
true
> (1).__proto__.__proto__ === Object.prototype
true
现在,根据,
instanceof
所做的是:

instanceof操作符测试对象在其原型中是否有 链接构造函数的原型属性

但是很明显,
Object.prototype
1
的原型链中。那么为什么对象的
1 instanceof
为false?也许是因为
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中测试了这些功能,得到了相同的结果。

你被一种被称为“拳击”(boxing)的机制所欺骗,这种机制让所有遇到它的人都着迷。一开始你的答案是正确的:

也许是因为1是一个原语而不是一个对象

确实如此。然而,原语如何能够包含方法呢?它们如何包含属性?毕竟,在js中,它们是以尽可能低的级别表示的(请参阅)。为了使这些值真正有用,每当执行
primitive.property
,都会发生以下情况():

换句话说,js具有自动装箱功能。这可以用我最喜欢的一个技巧来证明:

var primitive = 'food';
primitive.isPizza = true; //yummy
console.log(primitive.isPizza); //undefined. where did my pizza go!?
primitive.isPizza
因此装箱而消失:

var primitive = 'food';
Object(primitive).isPizza = true;
console.log(Object(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
obj === primitive; //false, obj is an object, primitive is a primitive