1

在萤火虫控制台中:

>>> a=12 
12
>>> a.__proto__
Number {}
>>> (12).__proto__
Number {}
>>> a.constructor.prototype === (12).__proto__
true
>>> a.constructor.prototype.isPrototypeOf(a)
false

与其他行相比,最后一行让我很困惑。还看到Constructor.prototype 不在原型链中?

4

3 回答 3

2

当您将.运算符与原语一起使用时,语言会使用适当的对象类型(在本例中为数字)自动将其装箱。那是因为 JavaScript 中的简单原始类型实际上不是 Object 实例。

因此,实际的左侧

a.__proto__

不是数量12而是本质上new Number(12)。但是,变量“a”仍然是简单的数值12

编辑——规范的第 8.7 节用典型的 ECMA 262 月球语言“解释”了这一点。我找不到清晰的段落来描述原始baseValue被视为数字、布尔值或字符串实例的方式,但该部分直接暗示了这一点。我认为因为那些非原始的合成值是短暂的(它们只是在评估.or[]表达式时才是“真实的”),所以规范只是谈论行为而没有明确要求构造一个实际的 Number。不过我猜。

于 2013-03-29T14:27:25.740 回答
1

@Pointy 已经很好地解释了它。基本上,如果你希望你的最后一个陈述是真实的,你必须这样写:

a.constructor.prototype.isPrototypeOf(new Number(a));
于 2013-03-29T14:37:14.870 回答
0

在 JavaScript 中,原语没有原型链。只有对象可以。原始值包括:

  1. 布尔值
  2. 数字
  3. 字符串
  4. 空值
  5. 不明确的

因此,如果您isPrototypeOf使用原始值调用,那么它将始终返回false

如果您尝试使用布尔值、数字或字符串作为对象,那么 JavaScript 会自动将其强制转换为您的对象。因此a.constructor评估到new Number(a).constructor幕后。这就是您可以将原始值用作对象的原因。

如果您希望经常使用将原始值存储为对象的变量,那么最好明确地将其设为对象。例如,在您的情况下,最好将其定义anew Number(12). 优点是:

  1. JavaScript doesn't need to coerce the primitive to an object every time you try to use it as an object. You only create the object once. Hence it's performance efficient.
  2. The 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.
于 2013-03-29T14:40:37.503 回答