为什么JavaScript原语不是Objectof? [英] Why are JavaScript primitives not instanceof Object?

查看:90
本文介绍了为什么JavaScript原语不是Objectof?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Today I happened to have too much time to kill and I played a bit with the Node (v0.10.13) command line:

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

现在,根据 MDN instanceof 确实是:


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

The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.

但显然 Object.prototype IS在 1 的原型链。那么为什么 1 instanceof Object false?也许是因为 1 是一个基元而不是一个开头的对象?

But clearly Object.prototype IS in 1's prototype chain. So why is 1 instanceof Object false? Perhaps because 1 is a primitive not an object to begin with?

好的,我接受了,我做了更多测试:

Okay, I accept that, and I did more tests:

> (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

So apparently all number primitives inherit from one object, and all string primitives inherit from another object. Both these 2 objects inherit from Object.prototype.

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

Now the question is, if numbers and strings are considered primitives, why inherit them from other objects? Or inversely, as they inherit from other objects, why not consider them objects too? It seems nonsensical to me that the child of an object isn't an object..

顺便说一句,我也在Firefox 22中对它们进行了测试并获得了相同的结果。

By the way, I have also tested these in Firefox 22 and got the same result.

推荐答案

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

You have been tricked by a mechanism commonly known as "boxing" (c# related article, java related article) which mesmerises all who come across it. You had the correct answer in the beginning:


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

Perhaps because 1 is a primitive not an object to begin with?

完全正确。但是,原语如何能够包含方法?它们如何包含属性?毕竟,在js中,它们以尽可能低的水平表示(参见#4.3.2 ) )。为了使这些值真正有用,无论何时执行 primitive.property ,都会发生以下情况(#11.2.1 ):

Exactly so. However, how can primitives ever be able to contain methods? How can they contain properties? After all, in js, they are represented at the lowest level possible (see #4.3.2). To make these values actually useful, whenever you do primitive.property, the following happens (#11.2.1):

Object(primitive).property;

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

In other words, js has automatic boxing. This can be proven using one of my favourite tricks:

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并且在时间的迷雾中被遗忘。

The boxed primitive is its own unique snowflake - when you box it a second time, it does not refer to the same thing. The boxed values are quickly GCd and forgotten in the mists of time.

如果您的原语不是原始的,那么这不会发生:

This does not happen if your primitive isn't, well, a primitive:

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

这是否意味着你应该只使用对象,而不是原语?不,原因很简单,你的时间需要在基元上存储元数据是非常少而且对象复杂化了:

Does this mean you should only use objects, never primitives? Nope, for the simple reason that the times you do need to store meta-data on primitives are very far and few, and objects complicate things:

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

这篇关于为什么JavaScript原语不是Objectof?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆