Наследование Javascript и метод переопределения
Предположим, что у меня есть класс:
function Widget() {
this.id = new Date().getTime();
// other fields
}
Widget.prototype = {
load: function(args) {
// do something
}
}
Из этого класса я создал несколько других классов, которые наследуют один и тот же прототип, но имеют некоторые добавленные методы. То, что я хочу сделать, - это определить способ load() в подклассах, который сначала вызывает родительский метод, а затем выполняет некоторый код. Что-то вроде:
SpecialWidget.prototype = {
load: function(args) {
super.load(args);
// specific code here
}
}
Я знаю, что в Javascript нет ключевого слова super, но должен быть способ сделать это.
Ответы
Ответ 1
Вы можете имитировать это следующим образом:
SpecialWidget.prototype = {
load: function(args) {
Widget.prototype.load.call(this, args);
// specific code here
}
}
Или вы можете создать свой собственный супер-свойство следующим образом:
SpecialWidget.prototype.parent = Widget.prototype;
SpecialWidget.prototype = {
load: function(args) {
this.parent.load.call(this,args);
// specific code here
}
}
Ответ 2
Итак, сначала вы настроили свой "подкласс" таким образом
function SubClass(name) {
Super.call(this);
// stuff here
}
SubClass.prototype = new SuperClass(null);
SubClass.prototype.constructor = SubClass;
а затем вы можете сделать
SuperClass.prototype.theMethod.apply(this);
изнутри реализации подкласса, чтобы специально вызвать супер-реализацию.
Ответ 3
Я не знаю, является ли это лучшим решением, но вы можете сделать что-то вроде этого:
function Widget() {
this.id = new Date().getTime();
}
Widget.prototype.load = function(args) {
alert( 'parent load' );
};
SpecialWidget = function(){};
// Make the prototype of SpecialWidget an instance of Widget
var proto = SpecialWidget.prototype = new Widget;
// Give the prototype a function that references the "load" from Widget
proto.parent_load = proto.load;
// Give SpecialWidget its own "load" that first calls the parent_load
proto.load = function( args ) {
this.parent_load( args );
alert( 'special load' );
};
var inst = new SpecialWidget;
inst.load();
Это делает прототип SpecialWidget
экземпляра Widget
так, чтобы он наследовал все, что Widget
имеет.
Затем он ссылается на load()
of Widget
, называемый parent_load()
, и создает свой собственный load()
, который вызывает parent_load()
при вызове.
Ответ 4
Можно было бы сохранить старое значение метода load
в закрытии, если вы выполнили свое переопределение следующим образом:
function Widget() {
this.id = new Date().getTime();
// other fields
}
Widget.prototype = {
load: function(args) {
// do something
alert("Widget Prototype Load");
}
};
function SpecialWidget(){
};
SpecialWidget.prototype = new Widget();
(function(){
var oldLoad = SpecialWidget.prototype.load;
SpecialWidget.prototype.load = function(){
oldLoad();
alert("new Load");
};
}());
var x = new SpecialWidget();
x.load();
Это работает, но я не уверен, что это лучший метод.
Ответ 5
Использование Простой класс Javascript:
Class.extend('Widget', {
load: function () {
alert('foo');
}
});
Widget.extend('SpecialWidget', {
load: function () {
this.super();
alert('bar');
}
});
new Widget().load(); // Alert: 'foo'
new SpecialWidget().load(); // Alert: 'foo' and 'bar'
Взгляните на Простой проект класса Javascript, Простой JavaScript Наследование и Наследование шаблонов в JavaScript.