首页 > 解决方案 > ES6 从现有实例实例化派生类

问题描述

考虑以下场景:

class A {
  constructor() {
    this.A = 'A';
  }

  createB() {
    //Create a B instance from this current instance
  }
}

class B extends A {
  constructor() {
    super();
    this.B = 'B';
  }
}

var base = new A();
var derived = new B();

base.A = 'C';

// Create a B instance from A so that
// a new A isn't instantiated and 
// fromInstance.A === 'C'
var fromInstance = base.createB();

我希望能够创建一个实例B而不必创建一个新的实例A,而是使用现有的A实例。

我的目标是能够B通过调用内部的函数来生成实例A,但也允许B直接创建实例并处理构造默认值A

B当扩展A并需要super()调用时,我怎样才能实现这样的目标?

标签: javascriptecmascript-6

解决方案


不确定这正是您想要的,但它适用于您的示例:

class A {
  constructor() {
    this.A = 'A';
  }
}

class B extends A {
  constructor() {
    super();
    this.B = 'B';
  }
}

var base = new A();
var derived = new B();

base.A = 'C';

// Create a B instance from A so that
// a new A isn't instantiated and 
// fromInstance.A === 'C'
var fromInstance = new B();
Object.assign(fromInstance, base);

console.log(fromInstance);

这是一个替代解决方案。它实际上在 C# 和 Java 中很常见,但是由于 JS 没有方法重载,因此与上述解决方案相比,这有点麻烦并且不太好:

class A {
  constructor(source) {
    if(source){
      //use properties/stuff from source
      this.A=source.A;
    }
    else{
      //only perform initialization if source is not provided
      this.A = 'A';
    }
  }
}

class B extends A {
  constructor(source) {
    super(source);
    this.B = 'B';
  }
}

var base = new A();
var derived = new B();

base.A = 'C';

// Create a B instance from A so that
// a new A isn't instantiated and 
// fromInstance.A === 'C'
var fromInstance = new B(base);

console.log(fromInstance);

基本上,构造函数有两个版本,一个创建一个全新的对象,一个几乎复制一个旧对象。

我认为有一点误解,B根据定义,每个实例都是 的实例A,无论您做什么。如果您想super被调用,您正在调用 的构造函数A,从而“实例化” A


推荐阅读