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 |
那么,这到底是怎么回事?
isPrototypeOf和getPrototypeOf直接查看原型链,而instanceof则查看给定构造函数的.prototype属性。您需要使用:
1 2 3
| function isError(x) {
return Error.prototype.isPrototypeOf(x)
} |
您的函数测试x是否从Error构造函数对象继承。
-
但是使用instanceof更容易吗?
-
这很有意义,谢谢。这导致我尝试其他操作:Object.getPrototypeOf(Error).isPrototypeOf(new RangeError)返回false,而Error.prototype.isPrototypeOf(new RangeError)返回true –这是怎么回事?
-
Object.getPrototypeOf(new Error()).isPrototypeOf(new RangeError)返回true,您必须了解构造函数的prototype属性和实例原型之间的区别,通常__proto__
-
也就是说,Object.getPrototypeOf(Error)是Function.prototype,因为您要查询函数(构造函数)的原型
-
当然,这是有道理的。我认为今天的咖啡不足(或太多!)非常感谢您的见解!
-
@ al-Zami:首先,没有通过Parent.apply(this)建立关系;您需要实际设置原型链。其次,没有构造函数设置为任何东西,.constructor只是从原型对象继承的属性。最后,对您的困惑感到抱歉。我的意思并不是说instanceof查看给定实例的.constructor属性(它没有),但是instanceof被赋予了构造函数以供查看。
-
@ al-Zami参见stackoverflow.com/questions/4152931/
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的原型链上。
-
RangeError.prototype是Error的实例吗?
-
@KubaWyrostek是的,我相信是的。如果您了解得更多,请告诉我。
-
我不知道更好。我只是问。 :-)是不是它的RangeError.prototype = Object.create(Error.prototype)而不是RangeError.prototype = new Error()?
-
好的,我没有考虑过这种微妙的区别。甚至有可能找出答案吗?您要强调的是与实现相关的区别。
-
我想不可能。这实际上取决于我们如何定义"实例"。没关系我的问题,我只是想让我脑海中有些事情。 :-)