В комментариях @Bergi сделал предположение, что вы можете создавать экземпляры новых объектов MyClass во время выполнения и ссылаться на них. Поскольку вы пытаетесь изменить метод экземпляра объекта MyClass, а не его прототипа, все новые экземпляры MyClass (создаваемые с ключевым словом "new") по-прежнему будут наследовать свойства исходного MyClass.
Например, рассмотрим класс Fruit
class Fruit {
constructor() {
this.pieces = 1;
}
cutIntoPieces(pieces) {
this.pieces = pieces;
return this;
}
}
и функция f
, которая принимает любой объект и изменяет его свойство cutIntoPieces
, устанавливая для него функцию, которая безусловно возвращает ноль и больше ничего не делает:
const f = object => {
object.cutIntoPieces = () => null;
};
Давайте немного поэкспериментируем с этим в узле REPL:
> banana = new Fruit();
Fruit { pieces: 1 }
> orange = new Fruit();
Fruit { pieces: 1 }
> papaya = new Fruit();
Fruit { pieces: 1 }
> f(banana);
undefined
> banana.cutIntoPieces(2);
null
> banana
Fruit { pieces: 1, cutIntoPieces: [Function] }
> orange.cutIntoPieces(3);
Fruit { pieces: 3 }
> papaya.cutIntoPieces(4);
Fruit { pieces: 4 }
Вы можете видеть, что вызов f
для банана изменил его поведение, когда вы хотите разрезать его на части. Это произошло потому, что теперь бананы имеют свое собственное свойство cutIntoPieces
, которое является функцией, которая безусловно возвращает ноль и не влияет на объект.
Чтобы переопределить метод cutIntoPieces
во всех экземплярах объекта, нам нужно изменить его в их прототипе, который является Fruit:
> Object.getPrototypeOf(banana);
Fruit {}
Чтобы создать такую функцию, которая берет прототип объекта и изменяет его свойство, так что все экземпляры этого объекта наследуют измененное свойство, нам нужно немного переделать нашу функцию f
. Давайте объявим другую функцию и назовем ее g
:
const g = object => {
object.cutIntoPieces = function (cuts) {
this.pieces = 2 ** cuts;
return this;
};
};
Здесь g
переопределил метод cutIntoPieces
любого объекта, чтобы сделать резку более эффективной. Теперь, если мы вызовем g
с Fruit.prototype, он изменит метод cutIntoPieces
апельсина и папайи:
> g(Fruit.prototype);
undefined
> orange.cutIntoPieces(4);
Fruit { pieces: 16 }
> papaya.cutIntoPieces(10);
Fruit { pieces: 1024 }
Что тогда с бананом?
> banana.cutIntoPieces(2);
null
> banana
Fruit { pieces: 1, cutIntoPieces: [Function] }
Поскольку мы назвали f
на банане, banana.cutIntoPieces
теперь не имеет отношения к Fruit.prototype.cutIntoPieces
. В то время как у апельсина и папайи этот метод унаследован от прототипа, у банана есть свой собственный:
> orange.cutIntoPieces === Fruit.prototype.cutIntoPieces
true
> papaya.cutIntoPieces === Fruit.prototype.cutIntoPieces
true
> banana.cutIntoPieces === Fruit.prototype.cutIntoPieces
false
Что хорошо, я думаю. Если вы хотите изменить только поведение одного экземпляра, вы можете определить его собственное свойство, его собственный метод; с другой стороны, когда вам нужно изменить поведение всех экземпляров, у которых есть методы, унаследованные от прототипа, вы можете изменить их прототип.
Но как заставить банан вести себя идентично другим фруктам при разрезании на кусочки? Давайте удалим его cutIntoPieces
!
> delete banana.cutIntoPieces
true
> banana
Fruit { pieces: 1 }
> banana.cutIntoPieces(2)
Fruit { pieces: 4 }
Смотрите, после удаления собственного свойства объекта другое, с тем же именем, наследуется от прототипа, когда оно есть:
> banana.cutIntoPieces === Fruit.prototype.cutIntoPieces
true
Теперь банан, апельсин и папайя ведут себя одинаково.
Надеюсь, это поможет и удачи!