[英]ES6 constructor returns instance of base 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
...以及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
為了解決這個問題,你可能需要使用每個實例的hack,比如將所有TestB.prototype
的方法復制到實例上。 理想情況下,嘗試使用Vector
通過聚合(也就是“組合”,例如,通過將Vector
實例作為類的實例的屬性)而不是繼承,而不是黑客,因為它不是為繼承而設置的。
我不知道這個問題的確切原因,但黑客原型解決了這個問題。 :)
class TestB extends Vector {
constructor() {
super();
this.__proto__ = TestB.prototype;
}
Log() {
console.log("" + this);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.