【问题标题】:Check if the constructor call is coming from extended class检查构造函数调用是否来自扩展类
【发布时间】:2016-04-06 18:09:40
【问题描述】:

假设我们有两个库:

  1. 某人编写的库,使用functionprototype语法在JS中构建类类类型。

  2. 我们使用 ES6 编写的库,扩展了第一个库。

使用class OurLibrary extends TheOtherLibrary {...} 可以正常工作(即使TheOtherLibrary 是使用function TheOtherLibrary (...) {...} 声明的,并且它的方法是使用prototype 方式附加的)。

问题是在不使用类的时候,可以return 取值。一种常见的方法是在没有new 的情况下处理呼叫。这就是我现在遇到的问题。

我们有这样的东西:

function TheOtherLibrary (foo) {
  if (this.constructor !== TheOtherLibrary) {
     return new TheOtherLibrary(foo);
  }
  //...
}
TheOtherLibrary.someMethod = function () {/*...*/};

class MyLibrary extends TheOtherLibrary {
   constructor (foo) {
       super(foo);
   }
   anotherMethod () {/*...*/}
}

var bar = new MyLibrary(42);
console.log(bar.constructor.name);
// => TheOtherLibrary
console.log(bar.anotherMethod);
// => undefined

那么,如何改进第二行中的 if 表达式以检查调用是否来自扩展类?

var notCalledFromExtendedClass = ???
if (this.constructor !== TheOtherLibrary && !notCalledFromExtendedClass) {
   return new TheOtherLibrary(foo);
}

或者是否有希望以另一种更好的方式实现这一点?

【问题讨论】:

标签: javascript class prototype


【解决方案1】:

像这样使用instanceof 来检测TheOtherLibrary 是否在原型链中的任何位置:

function TheOtherLibrary (foo) {
  if (!(this instanceof TheOtherLibrary)) {
     return new TheOtherLibrary(foo);
  }
  ...
}

这将适用于TheOtherLibrary 的直接实例或任何派生类的实例。如果您也想支持在没有new 的情况下对派生类进行调用,那么您也必须将此结构放入派生类的构造函数中,这样您就可以捕获在没有foo 的情况下调用的任何构造函数,然后可以创建正确的对象的类型。

【讨论】:

  • 哦,太棒了!非常感谢!不知道这么简单。 :-) 新年快乐!
  • @jfriend00,有没有办法专门获取.constructor的.constructor?
  • @Pacerier - 什么是构造函数的构造函数?您通常可以(尽管并非总是)使用obj.constructor 获取对象实例的构造函数,但这不是构造函数的构造函数,所以我不确定您的意思。
  • @jfriend00,从实例bar,我们如何获得实例MyLibrary 的引用? (bar.constructorbar.__proto__.constructor 不起作用。)
  • 如果整个对象定义正确完成,它将起作用。您必须准确显示您正在使用的代码。我建议您发布一个新问题,因为这与此问题不同。例如:jsfiddle.net/jfriend00/x5k8kgqs.
猜你喜欢
  • 1970-01-01
  • 2014-05-29
  • 2014-04-18
  • 2013-11-15
  • 2018-09-26
  • 1970-01-01
  • 2021-02-13
  • 2019-01-07
  • 1970-01-01
相关资源
最近更新 更多