关于javascript:isPrototypeOf表示不,但instanceof表示是–这是怎么回事?

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

我尝试执行一些简单的类型检查错误,并具有以下代码:

1
2
3
function isError(x) {
  return Error.isPrototypeOf(x)
}

但是,如果我使用错误实例调用该函数,则会得到false,如下所示:

1
isError(new RangeError) // false

因此,我启动了节点(无论如何,还是io.js),并执行了以下操作:

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

最后,如果我用instanceof进行检查,它的工作原理如下:

1
2
> (new RangeError) instanceof Error
true

那么,这到底是怎么回事?


isPrototypeOfgetPrototypeOf直接查看原型链,而instanceof则查看给定构造函数的.prototype属性。您需要使用:

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

您的函数测试x是否从Error构造函数对象继承。


instanceof为您查看指定构造函数的.prototype属性(即不是[[Prototype]] / __proto__)(即,它执行一些其他工作)。

isPrototypeOf并不那么努力,它要求您指定要在原型链上检查的确切对象实例。

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

false,因为函数Error不位于r的原型链上。 r的原型链为:

r => RangeError.prototype(Error的实例)=> Error.prototype(Object的实例))

该链上的任何地方都不是Error构造函数,因此为false。

如果我们像这样修改您的示例:

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

这返回true,因为Error函数的.prototype属性在r的原型链上。