Reputation: 35301
For most values of x
that I have tested, the following evaluates to true
:
Object.getPrototypeOf(x) === x.constructor.prototype
...but there are a few exceptions: if x
is a string, the LHS of the expression above fails with an error like
TypeError: "abc" is not an object
...although, e.g., "abc".constructor.prototype
evaluates to String.prototype
. One gets analogous results if x
is a number or a boolean.
What's going on? Are there more exceptions to the identity shown earlier?
More to the point, the above suggests that x.constructor.prototype
is more robust than Object.getPrototypeOf(x)
.
Is there any good reason not to use x.constructor.prototype
exclusively and forget entirely about the Object.getPrototypeOf(x)
?
Upvotes: 4
Views: 146
Reputation: 9884
Object.getPrototypeOf is not supported by older browsers where as x.constructor.prototype is more cross-browser solution.
However, if available it is more reliable to use Object.getPrototypeOf because x.constructor can be changed like so: x.constructor = 'my new value';
I suggest you to create this polyfill function:
if (!Object.getPrototypeOf) {
Object.getPrototypeOf = function(o) { return o.__proto__ || o.constructor.prototype; };
}
Upvotes: 0
Reputation: 324620
Strings (and other primitives) can behave a little weirdly.
Basically, when you try to access a property of a primitive, it is boxed in a Just-In-Time fashion using its Object equivalent, and then the property of that object is returned.
So in this case, when you try to access "abc".constructor
, what's actually happening is the same as new String("abc").constructor
(which of course returns the String
object).
On the other hand, Object.getPrototypeOf
does no such boxing, instead returning an error if you pass it anything that isn't an object.
As you suggest, x.constructor.prototype
does seem to be a more reliable method of determining the constructor of something, since it does handle this "boxing" case. That said, personally I can't think of any real situation where something like this might be needed, since... well, typically, you already know what type something is. It's the same reason I don't see any real point in using ===
most of the time.
Upvotes: 1