如何克隆ES6类对象构造函数?

Pie*_*rre 1 javascript ecmascript-6 es6-class

使用ES6类创建一个简单的ORM,我运行了一个阻塞问题 - 我无法正确复制一个类(就像我util.extend在ES5中一样).

具体来说,这是我尝试过的:

class BaseModel {

  echo() {
    console.log(this.props);
  }

  static _setProperties(props) {
    this.props = props;
  }

}

function makeModel(props) {

  // Try to copy the Class object
  const Model = 
      Object.assign(Object.create(Object.getPrototypeOf(BaseModel)), BaseModel);

  // Copy my static methods – is there a better way to do this?
  Object.getOwnPropertyNames(BaseModel).forEach((key) => {
    if (!key.startsWith('_')) return;
    Model[key] = BaseModel[key];
  });

  // Configure the new model
  Model._setProperties(props);
  return Model;
}

const GreeterModel = makeModel('hello');
const greeter = new GreeterModel();
greeter.echo(); // Should log hello
Run Code Online (Sandbox Code Playgroud)

我得到的错误是:

TypeError: GreeterModel is not a constructor
Run Code Online (Sandbox Code Playgroud)

有没有办法用ES6课程实现这一目标,还是我必须坚持ES5风格?

可选问题:有没有更好的方法来复制静态方法?解决方案getOwnPropertyNames并不理想,因为它还返回只读属性,例如length.

谢谢!

Fel*_*ing 5

基类中存在逻辑错误.this总是取决于函数的调用方式.通常在构造函数上调用静态函数,即BaseModel._setProperties(...)在这种情况下this引用BaseModel.然而,实例方法在实例本身上调用,因此this引用实例而不是构造函数.

为了完成BaseModel工作,你必须使用

echo() {
  console.lof(this.constructor.props);
}
Run Code Online (Sandbox Code Playgroud)

但要回答你的实际问题,你可以简单地扩展课程:

function makeModel(props) {
  class Model extends BaseModel {}
  Model._setProperties(props);
  return Model;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这不是"克隆"基类,而是扩展它.没有合理的方法可以在JavaScript中克隆一个函数(迄今为止最少).