I know that one should not use __proto__
directly in the code, but just out of curiosity I was playing around with this in node. I was under the impression that if x.__proto__ == X.prototype
then it means x instanceof X
will yield true
until I hit this code with primitive values.
> (2).__proto__ == Number.prototype
true
> 2 instanceof Number
false
> (2) instanceof Number
false
> "abc".__proto__ == String.prototype
true
> "abc" instanceof String
false
> ("abc") instanceof String
false
Why is this?
instanceof
will always yieldfalse
if the left-hand side is not an object (see Step 3 here).The reason
(2).__proto__ == Number.prototype
is true is that when you apply a property accessor to a primitive (in this case,.__proto__
), a temporary object with the same underlying primitive value is created and used.So the thing you're getting the
__proto__
property from isn't the same thing you're using in yourinstanceof
cases, because it isn't a primitive. Your test cases would more accurately be:That's true as far as it goes (or would be if you used
===
, for a fairly obscure reason1), but note that the converse is not true: Ifx instanceof X
is true, that doesn't necessarily meanx.__proto__ == X.prototype
will be true, for a couple of reasons:It could be that you need to use
x.__proto__.__proto__
, orx.__proto__.__proto__.__proto__
, or... :-)x.__proto__
may well beundefined
. For instance, it is if you createx
like this:x = Object.create(null)
. The reason is that the__proto__
property accessor is provided byObject.prototype
, but if you create an object that doesn't inherit fromObject.prototype
, it doesn't have the__proto__
property accessor (on a compliant implementation). This is one reason to useObject.getPrototypeOf(x)
instead.1 Fairly obscure reason: If
x
was created viaObject.create(null)
(or using any prototype that doesn't trace back toObject.prototype
) and thus doesn't have the__proto__
property accessor, andX.prototype
isnull
,x.__proto__ == X.prototype
would betrue
even though they could well be completely and utterly unrelated, sincex.__proto__
would beundefined
andundefined == null
is true. ;-)