检查构造函数调用是否来自扩展类

时间:2016-01-02 18:01:01

标签: javascript class prototype

假设我们有两个库:

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

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

  3. 使用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);
    }
    

    或者是否有希望以另一种更好的方式使用它?

1 个答案:

答案 0 :(得分:1)

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

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

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