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

IT技术 javascript class inheritance
2021-03-15 05:44:08

例如:

function A(){}
function B(){}
B.prototype = new A();

如何检查B类是否继承了A类?

5个回答

请尝试以下操作:

ChildClass.prototype instanceof ParentClass
@Omid ES6 类语法主要是:一些特殊语法在幕后,“类”的实际处理没有改变,因此您仍然可以使用A.prototype... developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/ ...
2021-04-28 05:44:08
什么ES6 classclass A extends B{}那么我如何检查类的继承A
2021-05-11 05:44:08

您可以测试直接继承

B.prototype.constructor === A

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

B.prototype instanceof A

(这第二个解决方案首先由 Nirvana Tikku 给出)

刚刚恢复了。感谢dystroy(也更新了这个答案)
2021-04-22 05:44:08
不,只会检查父类,而不是所有的继承链。
2021-05-17 05:44:08

回到 2017 年:
检查它是否适合你

ParentClass.isPrototypeOf(ChildClass)

如果您想要防止阴影的替代方法:

const isPrototypeOf = Function.call.bind(Object.prototype.isPrototypeOf);

// Usage:
isPrototypeOf(ParentClass, ChildClass); // true or false
工作完美,但 lint 抱怨。看来如果程序不能完全控制ParentClass,那么ParentClass就有伪造答案的风险。它扩展到所有原型函数。如果程序确实可以完全控制 ParentClass,那么应该没问题。
2021-04-17 05:44:08
它如何伪造答案?通过使用符号?他们为什么要这样做,如果发生了,那可能是有意为之
2021-04-26 05:44:08
我不同意它必须始终更换。只有在这种情况下,程序员不控制可能的 ParentClass 值的范围时才需要。
2021-05-09 05:44:08
“此外,对象可能具有隐藏 Object.prototype 上的内置函数的属性,这可能会导致意外行为或拒绝服务安全漏洞。”
2021-05-11 05:44:08
“例如,网络服务器解析来自客户端的 JSON 输入并直接在结果对象上调用 hasOwnProperty 是不安全的,因为恶意客户端可能会发送类似 {"hasOwnProperty": 1} 的 JSON 值并导致服务器崩溃. 为了避免这样的细微错误,最好总是从 Object.prototype 调用这些方法。例如, foo.hasOwnProperty("bar") 应该替换为 Object.prototype.hasOwnProperty.call(foo, "bar")。 ” -- eslint.org/docs/rules/no-prototype-builtins
2021-05-14 05:44:08

问题:请注意,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 of proto of 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”,但您是否已将“C”参数替换为“ParentClass”
2021-04-19 05:44:08

我不认为 SimonB.prototype = new A()在他的问题中的意思,因为这肯定不是在 JavaScript 中链接原型的方式。

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

我认为您今天有最好的答案,但B.prototype = new A()至少class在 ES6 中引入之前,它确实是链接原型的有效方法(对于那些想要经典风格继承的人)
2021-04-28 05:44:08