简体   繁体   中英

isPrototypeOf says no, but instanceof says yes – what's going on?

I tried doing some simple type checking for errors, and had the following code:

function isError(x) {
  return Error.isPrototypeOf(x)
}

However, if I call the function with an instance of an error, I get false , like so:

isError(new RangeError) // false

So I fired up node (well, io.js anyway), and did the following:

> Object.getPrototypeOf(Object.getPrototypeOf(new RangeError))
[Error]

In the end, if I do a check with instanceof , it works, like so:

> (new RangeError) instanceof Error
true

So, what exactly is going on here?

isPrototypeOf and getPrototypeOf look at the prototype chain directly, while instanceof looks at the .prototype property of the given constructor function. You need to use:

function isError(x) {
  return Error.prototype.isPrototypeOf(x)
}

Your function tests whether x inherits from the Error constructor function object .

instanceof looks at the .prototype property (ie not [[Prototype]] / __proto__ ) of the specified constructor function for you (ie it does some additional work).

isPrototypeOf doesn't work as hard and requires you to specify the exact object instance you want to check for on the prototype chain.

Error.isPrototypeOf(r = new RangeError); // false.

false because the function Error does not sit on the prototype chain of r . The prototype chain of r is:

r => RangeError.prototype (an instance of Error ) => Error.prototype (an instance of Object ))

Nowhere on this chain is the Error constructor function, hence false.

If we modify your example like so:

Error.prototype.isPrototypeOf(r = new RangeError); // true.

This returns true because the .prototype property of the Error function is on the prototype chain of r .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM