Подтвердить что ты не робот

Наследование 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, но должен быть способ сделать это.

4b9b3361

Ответ 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.