问题
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:
- Booleans
- Numbers
- Strings
- Null
- 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:
- 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.
- The
isPrototypeOf
method in your case will returntrue
asa
will be an instance ofNumber
. Hence it will haveNumber.prototype
in its prototype chain.
来源:https://stackoverflow.com/questions/15705232/confusion-about-prototype-chain-primitives-and-objects