在 Javascript 中,如何克隆一个 class

In Javascript, how does one clone a class

如何克隆现有的 class(而不是 class 的实例)?

class Base {
  constructor(input='base') {
    this.base = input
  }
}

class CloneBase {
  constructor(input='CloneBase') {
    this.base = input
  }
}

class A extends Base {
  get a() {
    return "a"
  }
}

const Clone = A // how does one clone A?

Object.setPrototypeOf( Clone, CloneBase )

const a = new A()
console.log(a.base) // should be "Base"

const clone = new Clone()
console.log(Clone.base) // should be "CloneBase"

我可以使用 class 的一个实例,但它绕过了后续代码中的构造函数,不能与 new Clone(whatever)

一起使用

Object.assign

let clone = Object.assign( Object.create( Object.getPrototypeOf(orig)), orig)

请访问此 以获取更多信息。

您不能在 javascript 中克隆 class。让我们看看这个例子:

function classCloner(x) {
  var constructor = function() {
    if(!(this instanceof constructor)) throw new TypeError("Not a constructor");
    x.apply(this, Array.prototype.slice.call(arguments));
  }
  for(var attr in x) {console.log(attr);
    if(Object.hasOwnProperty(attr)) constructor[attr] = x[attr];
  }
  constructor.prototype = Object.create(Object.getPrototypeOf(x.prototype));
  for(var attr in x.prototype) {
    if(Object.hasOwnProperty(attr)) constructor.prototype[attr] = x.prototype[attr];
  }
  return constructor;
}

此功能无效:

  1. ECMA6 classes在构造函数和成员函数中使用了检查,所以你不能在没有new的情况下直接调用class。它检查是否 this instanceOf constructor
  2. 如果克隆 class,则需要克隆所有属性。许多属性都是函数,它们只适用于一种类型,创建多种类型可能会导致奇怪的错误。

还有一种方法可以使用 eval 克隆 ECMA6 class。

var clonedClz = eval(oldClz.toString());

这将克隆 class 的所有属性,并将克隆所有函数。当 oldClz 在创建后被修改时(例如 oldClz.foo = () => 'bar'),则该更改将不适用于克隆的 class.

这只适用于 ecmascript6 classes,不适用于普通 js classes。创建具有相同功能的多个类型可能会导致大问题。