为什么数字从Object.prototype继承时不是对象的实例?

时间:2019-05-18 08:59:05

标签: javascript object ecmascript-6

请参见下面的代码段。

let num = 3;
Object.prototype.prop = "something";
console.log(num instanceof Object); //false;
console.log(num.hasOwnProperty('prop')) //false

console.log(num.prop) //'something'

有人可以解释为什么num instanceof Objectnum.hasOwnProperty('prop')返回false的原因,但是我们仍然可以在Object.prototype上访问num的属性

3 个答案:

答案 0 :(得分:5)

数字是primitives,所以它们不是从Object继承的,也不是instanceof的任何东西。

但是,当您尝试访问属性(例如方法)时,JavaScript会在Number对象上加一个数字,以使该属性访问实际上位于在以下情况下创建的Number对象上:飞行中。就像你做的一样:

console.log((new Number(num)).constructor.name);
console.log((new Number(num)).hasOwnProperty('prop'));
console.log((new Number(num)).prop): 

prop将在Number对象的原型链中找到,但是hasOwnProperty(顾名思义,是 not 不会看到)原型链,因此不会考虑您放在Object.prototype上的内容。

请注意,当您不尝试访问属性时,不会发生这种无声拳击操作,因此在num instanceof中考虑的是原语,而不是其Number的变体。

您实际上可以通过调用toSource方法来查看该拳击的痕迹:

let num = 5;
console.log(num.toSource());

有趣的事实:您还可以使用数字 literal 来获得此拳击拳-要从小数点消除歧义还需要第二点:

console.log(1..toSource());

“拳击”规范

EcmaScript规范在Property Accessors部分中定义了此过程。评估依靠

GetValue(propertyNameReference).

依次definition正在执行此操作:

If IsPropertyReference(V) is true, then

   If HasPrimitiveBase(V) is true, then
       Assert: In this case, base will never be undefined or null.
       Set base to ! ToObject(base).

最后ToObject执行实际的换行。

答案 1 :(得分:0)

只有实际对象的instanceof才能解析为true。请参见instanceof上的specification,它指向HasInstance

  

使用值V调用F的[[HasInstance]]内部方法时,将执行以下步骤:

     
      
  1. 如果V不是对象,则返回false。
  2.   

数字甚至不是instanceof Number

console.log(1 instanceof Number);

但是,如果您使用了new Number(不应使用)并创建了一个实际的数字对象,它将按您的预期工作:

console.log(new Number(1) instanceof Number);

答案 2 :(得分:0)

hasOwnProperty on MDN

  

hasOwnProperty()方法返回一个布尔值,指示对象是否具有指定的属性作为其自身的属性( 而不是继承它的 )。

强调地雷

该数字继承了该属性,因此您可以访问它,但是并未将其定义为数字本身的属性,这就是hasOwnProperty("prop")返回false的原因。

instanceof失败的原因是,它只能用于显式对象(构造的或文字的)。