ES6构造函数返回基类的实例? [英] ES6 constructor returns instance of base class?
问题描述
派生类的构造函数返回基类的实例。
The constructor of a derived class returns an instance of the base class.
以下代码解释了我的问题:
The following code explains my problem:
// 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
可以做到的一个例子:
Here's an example of one way Vector
could do that:
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
。
The key here is that since Vector
returns a different object than the one new
created, it's of the wrong type. A relatively little-known thing about constructor functions is that if they return a non-null
object reference, the result of new Constructor
is the object the constructor returned, rather than the object new
created.
这是一个片段,用于那些浏览器支持 class
:
Here's a snippet for those whose browsers support 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 的实时副本t。
...and a live copy on Babel's REPL for those whose browsers don't.
令我惊讶的是,Babel和Chrome都允许我使用类Vector
执行此操作并返回来自构造函数的值
;我还没有从规范中想出它是否真的有效:
To my surprise, both Babel and Chrome let me do this using class Vector
as well and returning a value from constructor
; I haven't figured out (yet) from the specification whether it's actually valid:
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
实例作为类的实例的属性而不是继承,因为它没有设置为继承。
To get around it, you'll likely need to use a per-instance hack, like copying all of TestB.prototype
's methods onto the instance. Ideally, rather than hacking, try to use Vector
via aggregation (aka "composition", e.g., by having a Vector
instance as a property of your class's instances) rather than inheritance, since it's not set up for inheritance.
这篇关于ES6构造函数返回基类的实例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!