В Javascript, как клонировать класс - PullRequest
1 голос
/ 10 июля 2020

Как можно клонировать существующий класс (не экземпляр класса)?

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"

Я мог бы использовать экземпляр класса, но это обходит конструктор в последующем коде и не может использоваться с new Clone(whatever)

Ответы [ 2 ]

1 голос
/ 10 июля 2020

Вы не можете клонировать класс из javascript. Давайте посмотрим на этот пример:

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 используют проверки в конструкторе и функциях-членах, поэтому вы не можете напрямую вызывать класс без нов. Он проверяет, this instanceOf constructor
  2. Если вы клонируете класс, вам нужно клонировать все свойства. Многие свойства являются функциями и работают только с одним типом, поэтому создание нескольких типов может вызвать странные ошибки.

Тем не менее есть способ клонировать класс ECMA6 с помощью eval.

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

Это клонирует все свойства класса и клонирует все функции. Когда oldClz изменяется после того, как он был создан (например, oldClz.foo = () => 'bar'), это изменение не будет применяться к клонированному классу.

Это работает только для классов ecmascript6, а не для простых js классов. Создание нескольких типов с одинаковыми функциями может вызвать большие проблемы.

0 голосов
/ 10 июля 2020

Object.assign

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

Для получения дополнительной информации посетите эту ссылку .

...