如何检查Javascript类是否继承另一个(不创建obj)?


Answers:



31

您可以使用以下方法测试直接继承

B.prototype.constructor === A

要测试间接继承,可以使用:

B.prototype instanceof A

(第二个解决方案是由Nirvana Tikku首次提出的)


6
否,那只会检查父类,而不是所有遗产链。
西蒙(Simon)

刚刚恢复。谢谢dystroy(也更新了这个答案)
Nirvana Tikku 2013年

22

回到2017年:
检查是否适合您

ParentClass.isPrototypeOf(ChildClass)

正常工作,但皮棉抱怨。看来,如果该程序不能完全控制ParentClass,则存在ParentClass伪造答案的风险。它扩展到所有原型功能。如果程序确实可以完全控制ParentClass,则应该没有问题。
Craig Hicks

如何伪造答案?通过使用符号?以及为什么要这样做(如果发生的话,可能是设计
使然)

“此外,对象还可以具有遮盖Object.prototype上内置内容的属性,从而可能导致意外行为或拒绝服务安全漏洞。”
Craig Hicks

“例如,对于网络服务器来说,解析来自客户端的JSON输入并直接在生成的对象上调用hasOwnProperty是不安全的,因为恶意客户端可能会发送{{“ hasOwnProperty”:1}这样的JSON值,并导致服务器崩溃为了避免此类细微的错误,最好始终从Object.prototype调用这些方法,例如foo.hasOwnProperty(“ bar”)应该替换为Object.prototype.hasOwnProperty.call(foo,“ bar”)。 ” - eslint.org/docs/rules/no-prototype-builtins
克雷格·希克斯

我不同意必须始终更换它。在这种情况下,仅当程序员不控制可能的ParentClass值的范围时才需要。
Craig Hicks

1

陷阱:请注意,instanceof如果您使用多个执行上下文/窗口,则无法按预期工作。参见§§


另外,根据https://johnresig.com/blog/objectgetprototypeof/,这是一个替代实现,与以下示例相同instanceof

function f(_, C) { // instanceof Polyfill
  while (_ != null) {
    if (_ == C.prototype)
      return true;
    _ = _.__proto__;
  }
  return false;
}

对其进行修改以直接检查类可为我们提供:

function f(ChildClass, ParentClass) {
  _ = ChildClass.prototype;
  while (_ != null) {
    if (_ == C.prototype)
      return true;
    _ = _.__proto__;
  }
  return false;
}


边注

instanceof本身检查是否obj.protof.prototype,因此:

function A(){};
A.prototype = Array.prototype;
[]instanceof Array // true

和:

function A(){}
_ = new A();
// then change prototype:
A.prototype = [];
/*false:*/ _ instanceof A
// then change back:
A.prototype = _.__proto__
_ instanceof A //true

和:

function A(){}; function B(){};
B.prototype=Object.prototype;
/*true:*/ new A()instanceof B 

如果不相等,则在检查中将proto与proto的proto交换,然后将proto的proto的proto交换,依此类推。从而:

function A(){}; _ = new A()
_.__proto__.__proto__ = Array.prototype
g instanceof Array //true

和:

function A(){}
A.prototype.__proto__ = Array.prototype
g instanceof Array //true

和:

f=()=>{};
f.prototype=Element.prototype
document.documentElement instanceof f //true
document.documentElement.__proto__.__proto__=[];
document.documentElement instanceof f //false


在修改后的代码段中,您具有“ C.prototype”,尽管您已用“ ParentClass”替换了“ C”参数
user251242

1

我认为Simon并不是B.prototype = new A()在说他的问题,因为这肯定不是在JavaScript中链接原型的方法。

假设B扩展了A,使用 Object.prototype.isPrototypeOf.call(A.prototype, B.prototype)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.