Можно ли вызвать базовый метод из метода-прототипа в JavaScript, если он был переопределен?
MyClass = function(name){
this.name = name;
this.do = function() {
//do somthing
}
};
MyClass.prototype.do = function() {
if (this.name === 'something') {
//do something new
} else {
//CALL BASE METHOD
}
};
javascript
prototype
overriding
markvpc
источник
источник
Ответы:
Я не понял, что именно вы пытаетесь сделать, но обычно реализация объектно-ориентированного поведения выполняется в следующих направлениях:
источник
Ну, один из способов сделать это - сохранить базовый метод, а затем вызвать его из замещающего метода, например
источник
_do_base
сохраняет ссылку на любую функцию, которая была определена ранее. Если бы его не было, то было быundefined
. JavaScript не работает -make
выражения никогда не оцениваются лениво, как вы предполагаете. Теперь, если прототип, унаследованный от, также использовал _do_base для хранения того, что, по его мнению, является реализацией его базового типаdo
, тогда у вас действительно есть проблема. Итак, да, замыкание было бы лучшим безопасным для наследования способом сохранить ссылку на исходную реализацию функции при использовании этого метода, хотя для этого потребуется использоватьFunction.prototype.call(this)
.Боюсь, ваш пример не работает так, как вы думаете. Эта часть:
перезаписывает определение
Поскольку вновь созданный объект уже имеет свойство «do», он не ищет цепочку прототипов.
Классическая форма наследования в Javascript неудобна, и ее трудно понять. Я бы предложил вместо этого использовать простой шаблон наследования Дугласа Крокфорда. Как это:
На мой взгляд, это гораздо более понятный способ обработки объектов, конструкторов и наследования в javascript. Вы можете прочитать больше в Crockfords Javascript: Хорошие части .
источник
base_do
как функцию, потому что таким образом вы теряете любуюthis
привязку в исходномdo
методе. Итак, настройка базового метода немного сложнее, особенно если вы хотите вызвать его, используя базовый объектthis
вместо дочернего объекта. Я бы предложил что-нибудь похожееbase_do.apply(me, arguments)
.var
дляbase_do
? Это сделано специально, и если да, то почему? И, как сказал @GiulioPiancastelli, нарушает ли этоthis
привязку внутриbase_do()
или этот вызов наследуетthis
от вызывающего?var
Должен быть там. Использованиеcall
(илиapply
) позволяет намthis
правильно выполнять привязку .Я знаю, что это сообщение написано 4 года назад, но из-за моего опыта работы с C # я искал способ вызвать базовый класс без необходимости указывать имя класса, а получить его с помощью свойства в подклассе. Поэтому мое единственное изменение в ответе Кристофа будет
Из этого:
К этому:
источник
this.constructor
может не всегда указывать наMyClass
.если вы определяете такую функцию (используя ООП)
есть два способа вызвать функцию-прототип: 1) создать экземпляр и вызвать функцию объекта:
а другой способ ... 2) вызывает функцию прямо из прототипа:
источник
Это решение использует
Object.getPrototypeOf
TestA
супер, что естьgetName
TestB
является дочерним элементом, который переопределяет,getName
но также имеет,getBothNames
что вызываетsuper
версию,getName
а такжеchild
версиюисточник
источник
Альтернатива :
источник
__proto__
следует избегать использования (которое изменяет [[Prototype]] `объекта).Object.create(...)
Вместо этого используйте маршрут.Если я правильно понимаю, вы хотите, чтобы базовая функциональность выполнялась всегда, а часть ее следует оставить для реализации.
Вам может помочь шаблон проектирования « шаблонный метод ».
источник
Если вы знаете свой суперкласс по имени, вы можете сделать что-то вроде этого:
Это напечатает
как и ожидалось.
источник
Другой способ с ES5 - явное прохождение цепочки прототипов, используя
Object.getPrototypeOf(this)
источник
Нет, вам нужно будет дать функции do в конструкторе и функции do в прототипе разные имена.
источник
Кроме того, если вы хотите переопределить все экземпляры, а не только один особый, этот может помочь.
результат:
источник
источник