请参见下面的代码段。
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 Object
和num.hasOwnProperty('prop')
返回false
的原因,但是我们仍然可以在Object.prototype
上访问num
的属性
答案 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]]内部方法时,将执行以下步骤:
- 如果V不是对象,则返回false。
数字甚至不是instanceof Number
:
console.log(1 instanceof Number);
但是,如果您使用了new Number
(不应使用)并创建了一个实际的数字对象,它将按您的预期工作:
console.log(new Number(1) instanceof Number);
答案 2 :(得分:0)
hasOwnProperty()
方法返回一个布尔值,指示对象是否具有指定的属性作为其自身的属性( 而不是继承它的 )。
强调地雷
该数字继承了该属性,因此您可以访问它,但是并未将其定义为数字本身的属性,这就是hasOwnProperty("prop")
返回false的原因。
instanceof
失败的原因是,它只能用于显式对象(构造的或文字的)。