Как изменить конструктор класса ES6 - PullRequest
2 голосов
/ 19 марта 2019

Я пытаюсь выполнить горячую перезагрузку кода с помощью классов ES6. Мне нужно иметь возможность модифицировать конструктор классов, не заменяя класс новым (потому что другие люди могут иметь ссылку на него).

Однако я обнаружил, что выглядит так, как будто объект класса имеет некоторую внутреннюю ссылку на конструктор, с которым он был первоначально определен; создание экземпляра класса с помощью new не ищет ни constructor, ни prototype.constructor класса.

Пример:

class OldC { constructor() { console.log("old"); } }
class NewC { constructor() { console.log("new"); } }

OldC.prototype.constructor = NewC.prototype.constructor;
OldC.constructor = NewC.constructor;
new OldC();

---> "старый"

(Обновление всех других методов работает нормально; у меня просто проблемы с конструктором.)

Думая, что конструктор может быть найден через [[prototype]], я также добавил это:

Object.setPrototypeOf(OldC, Object.getPrototypeOf(NewC));
Object.setPrototypeOf(OldC.prototype, Object.getPrototypeOf(NewC.prototype));

Это тоже не поможет (и я бы не ожидал, что это не даст никакого подкласса).

После всего этого проверка OldC показывает, что свойства прототипа точно такие, как я ожидал, с OldC.prototype.constructor, являющимся новым. Но все же, создание экземпляра OldC вызывает оригинальный конструктор.

Что происходит и как я могу это исправить?

1 Ответ

1 голос
/ 19 марта 2019

Тем не менее, создание экземпляра OldC вызывает оригинальный конструктор.

Да, потому что OldC сама является функцией конструктора.Вам нужно перезаписать переменную OldC, чтобы изменить то, что делает new OldC.

Изменить конструктор классов, не заменяя класс новым (потому что другие люди могут иметь ссылку на него).

Как отметил @trincot в комментариях, вы не можете изменить код функции .Вы должны заменить конструктор новым, без него обойтись невозможно.

Вы можете сохранить объект-прототип (хотя и изменяемый), поскольку это то, на что ссылаются большинство других вещей (особенно старые экземпляры).

NewC.prototype = OldC.prototype;
NewC.prototype.constructor = NewC;
OldC = NewC;

С людьми, которые взяли ссылку на старый конструктор, который нельзя изменить сейчас, помочь нельзя.Лучше всего вообще не раздавать сам класс, а только фабрику, поведение которой ваш код обновления знает, как изменить.

...