ES6构造函数返回基类的实例? [英] ES6 constructor returns instance of base class?

查看:111
本文介绍了ES6构造函数返回基类的实例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆