在萤火虫控制台中:
>>> a=12
12
>>> a.__proto__
Number {}
>>> (12).__proto__
Number {}
>>> a.constructor.prototype === (12).__proto__
true
>>> a.constructor.prototype.isPrototypeOf(a)
false
与其他行相比,最后一行让我很困惑。还看到Constructor.prototype 不在原型链中?
在萤火虫控制台中:
>>> a=12
12
>>> a.__proto__
Number {}
>>> (12).__proto__
Number {}
>>> a.constructor.prototype === (12).__proto__
true
>>> a.constructor.prototype.isPrototypeOf(a)
false
与其他行相比,最后一行让我很困惑。还看到Constructor.prototype 不在原型链中?
当您将.
运算符与原语一起使用时,语言会使用适当的对象类型(在本例中为数字)自动将其装箱。那是因为 JavaScript 中的简单原始类型实际上不是 Object 实例。
因此,实际的左侧
a.__proto__
不是数量12
而是本质上new Number(12)
。但是,变量“a”仍然是简单的数值12
。
编辑——规范的第 8.7 节用典型的 ECMA 262 月球语言“解释”了这一点。我找不到清晰的段落来描述原始baseValue被视为数字、布尔值或字符串实例的方式,但该部分直接暗示了这一点。我认为因为那些非原始的合成值是短暂的(它们只是在评估.
or[]
表达式时才是“真实的”),所以规范只是谈论行为而没有明确要求构造一个实际的 Number。不过我猜。
@Pointy 已经很好地解释了它。基本上,如果你希望你的最后一个陈述是真实的,你必须这样写:
a.constructor.prototype.isPrototypeOf(new Number(a));
在 JavaScript 中,原语没有原型链。只有对象可以。原始值包括:
因此,如果您isPrototypeOf
使用原始值调用,那么它将始终返回false
。
如果您尝试使用布尔值、数字或字符串作为对象,那么 JavaScript 会自动将其强制转换为您的对象。因此a.constructor
评估到new Number(a).constructor
幕后。这就是您可以将原始值用作对象的原因。
如果您希望经常使用将原始值存储为对象的变量,那么最好明确地将其设为对象。例如,在您的情况下,最好将其定义a
为new Number(12)
. 优点是:
isPrototypeOf
method in your case will return true
as a
will be an instance of Number
. Hence it will have Number.prototype
in its prototype chain.