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?
instanceofwill always yieldfalseif the left-hand side is not an object (see Step 3 here).The reason
(2).__proto__ == Number.prototypeis 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 yourinstanceofcases, 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 Xis true, that doesn't necessarily meanx.__proto__ == X.prototypewill 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 createxlike 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
xwas 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.prototypeisnull,x.__proto__ == X.prototypewould betrueeven though they could well be completely and utterly unrelated, sincex.__proto__would beundefinedandundefined == nullis true. ;-)