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

标签 javascript inheritance constructor ecmascript-6 derived-class

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

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

// 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

这怎么可能?

最佳答案

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

这里的关键在于,由于 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

...和一个live copy on Babel's 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

要绕过它,您可能需要使用针对每个实例的 hack,例如将所有 TestB.prototype 的方法复制到实例中。理想情况下,而不是黑客攻击,尝试通过聚合(也称为“组合”,例如,通过将 Vector 实例作为类实例的属性)而不是继承来使用 Vector ,因为它不是为继承而设置的。

关于javascript - ES6 构造函数返回基类的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37329977/

相关文章:

javascript - iFrame 属性不会通过 JS DOM 更新

javascript - 返回包含在属性中共享公共(public)值的对象的数组数组

c++选择函数的继承优先级

python - 从子类继承的属性打印子对象而不是来自父类的字符串

java - Java ArrayList实现中的类型删除

c++ - 插入 >> 运算符重载 : exception handling when retrieving object's ctor parameters from cin

java - 如果构造函数的签名包含泛型类型的定义,那么该构造函数的用户需要承担哪些额外责任?

javascript - 多页 Javascript 样式表更改器仅更改一个子页面中的样式表,而不是所有子页面中的样式表

c# - 使用 Wrapped<B> 类填充 Wrapped<A> 的集合,其中 B 实现 A

javascript - 如何使用货币掩码自动格式化输入数字( ionic )