Confusion about prototype chain , primitives and objects

被刻印的时光 ゝ 提交于 2019-12-13 02:37:45

问题


in firebug console :

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

the final line causes me a great confusion as compared to the other lines. also see Constructor.prototype not in the prototype chain?


回答1:


When you use the . operator with a primitive, the language auto-boxes it with the appropriate Object type (in this case, Number). That's because simple primitive types in JavaScript really are not Object instances.

Thus, the actual left-hand side of

a.__proto__

is not the number 12 but essentially new Number(12). However, the variable "a" continues to be the simple number value 12.

edit — Section 8.7 of the spec "explains" this with typical ECMA 262 moon language. I can't find a clear paragraph that describes the way that a primitive baseValue is treated as a Number, Boolean, or String instance, but that section directly implies it. I think that because those non-primitive synthetic values are ephemeral (they're only "real" while the . or [] expression is being evaluated) that the spec just talks about the behavior without explicitly requiring that an actual Number is constructed. I'm guessing on that however.




回答2:


@Pointy has explained it very well. Basically, if you want your last statement to be true, you would have to write it like:

a.constructor.prototype.isPrototypeOf(new Number(a));



回答3:


In JavaScript primitives do not have a prototype chain. Only objects do. A primitive value includes:

  1. Booleans
  2. Numbers
  3. Strings
  4. Null
  5. Undefined

Hence if you call isPrototypeOf with a primitive value then it'll always return false.

If you try to use a boolean, number or string as an object then JavaScript automatically coerces it into an object for you. Hence a.constructor evaluates to new Number(a).constructor behind the scenes. This is the reason you can use a primitive value as an object.

If you wish to use a variable storing a primitive value as an object often then it's better to explicitly make it an object. For example in your case it would have been better to define a as new Number(12). The advantages are:

  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.


来源:https://stackoverflow.com/questions/15705232/confusion-about-prototype-chain-primitives-and-objects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!