Наследование Javascript и переопределение метода - PullRequest
31 голосов
/ 24 января 2011

Предположим, у меня есть такой класс:

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 нет супер-ключевого слова, но должен быть способ сделать это.

Ответы [ 5 ]

40 голосов
/ 24 января 2011

Вы можете смоделировать это так:

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 голосов
/ 24 января 2011

Итак, сначала вы устанавливаете свой «подкласс» следующим образом:

function SubClass(name) {
    Super.call(this);

    // stuff here
}

SubClass.prototype = new SuperClass(null);
SubClass.prototype.constructor = SubClass;

, а затем вы можете сделать

SuperClass.prototype.theMethod.apply(this);

из реализации подкласса, чтобы специально вызвать реализацию супер.

1 голос
/ 24 января 2011

Я не знаю, является ли это лучшим решением, но вы могли бы сделать что-то вроде этого:

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() из Widget, называемому parent_load(), и создает собственный load(), который вызывает parent_load() при вызове.

0 голосов
/ 05 декабря 2013

Использование Простой класс 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 .

0 голосов
/ 24 января 2011

Можно было бы сохранить старое значение метода 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();

Это работает, но я не уверен, если этолучший метод

...