为什么JavaScript原语不是Objectof?

Gar*_*ang 8 javascript instanceof

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

> 1 instanceof Object
false
> (1).__proto__
{}
> (1).__proto__ instanceof Object
true
> (1).__proto__.__proto__ === Object.prototype
true
Run Code Online (Sandbox Code Playgroud)

现在,根据MDN,这instanceof是什么:

instanceof运算符测试对象在其原型链中是否具有构造函数的prototype属性.

但显然Object.prototype是IS 1的原型链.那么为什么是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'
Run Code Online (Sandbox Code Playgroud)

显然,所有数字基元都从一个对象继承,并且所有字符串基元都从另一个对象继承.这两个对象都继承自Object.prototype.

现在的问题是,如果数字和字符串被认为是原语,为什么要从其他对象继承它们?或者相反,当它们从其他对象继承时,为什么不考虑它们呢?对我来说,对象的孩子不是对象似乎是荒谬的.

顺便说一句,我也在Firefox 22中测试了这些并得到了相同的结果.

Zir*_*rak 29

你被一种通常被称为"拳击"(c#相关文章,java相关文章)的机制所欺骗,这种机制会使所有遇到它的人陷入困境.你在开始时得到了正确的答案:

也许是因为1是一个原始而不是一个开始的对象?

正是如此.但是,原语如何能够包含方法?它们如何包含属性?毕竟,在js中,它们代表最低级别(见#4.3.2).为了使这些值真正有用,无论何时,都会primitive.property发生以下情况(#11.2.1):

Object(primitive).property;
Run Code Online (Sandbox Code Playgroud)

换句话说,js有自动装箱.这可以使用我最喜欢的技巧证明:

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

primitive.isPizza 因为这个拳击而消失了:

var primitive = 'food';
Object(primitive).isPizza = true;
console.log(Object(primitive).isPizza);
Run Code Online (Sandbox Code Playgroud)

盒装primitive是它自己独特的雪花 - 当你第二次装盒时,它并不是指相同的东西.盒装值很快就会被GCd所遗忘,并在时间的迷雾中被遗忘.

如果你的原语不是原始的,那就不会发生这种情况:

var obj = new String('food');
obj.isPizza = true;
console.log(obj.isPizza); //true
Run Code Online (Sandbox Code Playgroud)

这是否意味着你应该只使用对象,而不是原始对象?不,原因很简单,你的时间需要存储元数据的原语是很远的也很少,和对象复杂的事情:

obj === primitive; //false, obj is an object, primitive is a primitive
Run Code Online (Sandbox Code Playgroud)