ES6构造函数返回基类的实例?

art*_*.sw 8 javascript inheritance constructor derived-class ecmascript-6

派生类的构造函数返回基类的实例.

以下代码解释了我的问题:

// Vector is defined by an external module (Unreal.js)
class TestB extends Vector {
    constructor() {
        super();
    }
    Log() {
        console.log("" + this);
    }
}
console.log(new TestB() instanceof TestB) // returns false !!! why ??? 
console.log(new TestB() instanceof Vector) // returns true...

class TestA extends Array {
    constructor() {
        super();
    }
    Log() {
        console.log("" + this);
    }
}
console.log(new TestA() instanceof TestA); // returns true, all is good
Run Code Online (Sandbox Code Playgroud)

这怎么可能?

T.J*_*der 10

它似乎Vector以一种使其不兼容的方式实现class.

以下是一种Vector可以做到这一点的方法的示例:

function Vector() {
  var v = Object.create(Vector.prototype);
  return v;
}

class TestB extends Vector {
  constructor() {
    super();
  }
}

console.log(new TestB() instanceof TestB);  // false
console.log(new TestB() instanceof Vector); // true
Run Code Online (Sandbox Code Playgroud)

这里的关键是,由于Vector返回的对象与new创建的对象不同,因此类型错误.关于构造函数的一个相对鲜为人知的事情是,如果它们返回非null对象引用,则结果new Constructor是构造函数返回的对象,而不是new创建的对象.

以下是浏览器支持的代码段class:

function Vector() {
  var v = Object.create(Vector.prototype);
  return v;
}

class TestB extends Vector {
  constructor() {
    super();
  }
}

console.log(new TestB() instanceof TestB); // false
console.log(new TestB() instanceof Vector); // true
Run Code Online (Sandbox Code Playgroud)

...以及Babel的REPL实时副本,适用于那些浏览器没有的人.

令我惊讶的是,Babel和Chrome让我也可以使用class Vector它并返回一个值constructor; 我还没有从规范中弄清楚它是否真的有效:

class Vector {
  constructor() {
    var v = Object.create(Vector.prototype);
    return v;
  }
}

class TestB extends Vector {
  constructor() {
    super();
  }
}

console.log(new TestB() instanceof TestB); // false
console.log(new TestB() instanceof Vector); // true
Run Code Online (Sandbox Code Playgroud)

为了解决这个问题,你可能需要使用每个实例的hack,比如将所有TestB.prototype方法复制到实例上.理想情况下,尝试使用Vectorvia聚合(也就是"组合",例如,通过将Vector实例作为类的实例的属性)而不是继承,因为它不是为了继承而设置.

  • 啊哈,所以使用"has-a"关系,而不是"is-a"关系. (2认同)