Вызов переопределенных методов в JavaScript - PullRequest
2 голосов
/ 04 сентября 2011

Я попытался найти способ вызвать переопределенный метод суперкласса в JS и получил это.

function A() {
    this.superclass = new Array(A.prototype);
}
A.prototype.call_method = function(method, args, pos) {
    if (!(pos >= 0)) pos = this.superclass.length - 1;
    while (!this.superclass[pos].hasOwnProperty(method)) if ((--pos) < 0) return;
    if (this.superclass[pos][method]) this.superclass[pos][method].apply(this, args);
    if (pos) this.call_method(method, args, pos - 1);
}
A.prototype.add = function() {
    this.superclass.push(arguments.callee.caller.prototype);
}
A.prototype.test = function(a, b, c) {
    alert("test of A ");
}

function B() {
    A.call(this);
    this.add();
}
B.prototype = new A();
B.prototype.constructor = B;
B.prototype.test1 = function(a, b, c) {
    alert("test of B ");
}

function C() {
    B.call(this);
    this.add();
}
C.prototype = new B();
C.prototype.constructor = C;
C.prototype.test = function(a, b, c) {
    alert("test of C");
}

var aa = new C();
aa.call_method("test", [1, 2, 3]);

Что вы думаете, это нормально?Или, может быть, он может вызвать «утечки памяти» (ссылка на собственный прототип)?Большое спасибо


Спасибо за ваш ответ, я опробовал ваш код.Но если я создаю подкласс SubClass, например, var a = SubClass1 (), (SubClass1 имеет свой собственный foo ())

и вызывает a.foo (), то будут вызываться только SubClass1 и BaseClass foo,

не подкласс foo () Код:

function BaseClass() { } BaseClass.prototype.foo = function() {     
  alert('called BaseClass.foo'); 
};  
SubClass = function() { }; 
SubClass.prototype = new BaseClass; 
SubClass.prototype.foo = function() {     
    alert('called SubClass.foo');      
    // calling super.foo();   
    this.constructor.prototype.foo.call(this); 
}; 
SubClass1 = function() { }; 
SubClass1.prototype = new SubClass; 
SubClass1.prototype.foo = function() {     
    alert('called SubClass1.foo');      
    // calling super.foo();   
    this.constructor.prototype.foo.call(this); 
}; 
var a=new SubClass1();
a.foo();

Спасибо

1 Ответ

6 голосов
/ 04 сентября 2011

Вы можете использовать свойство для хранения родительского класса и вызова методов непосредственно в родительском классе:

function BaseClass() {
}
BaseClass.prototype.foo = function() {
    console.log('called BaseClass.foo');
};

SubClass = function() {
};
SubClass.prototype = new BaseClass;
SubClass.prototype.__super__ = BaseClass;
SubClass.prototype.foo = function() {
    console.log('called SubClass.foo');

    // calling super.foo();
    this.__super__.prototype.foo.call(this);
};

Вы можете добавить небольшую абстракцию:

// The `clazz` parameter allows super-classes to use super() too.
// It should be the calling class
BaseClass.prototype.super = function(clazz, functionName) {
    // take all the arguments after functionName
    var args = Array.prototype.slice.call(arguments, 2);
    // call the function on super's prototype
    clazz.prototype.__super__.prototype[functionName].apply(this, args);
};

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

SubClass.prototype.foo = function() {
    console.log('called SubClass.foo');

    // calling super.foo();
    // Pass the calling class as first parameter
    this.super(SubClass, 'foo');
};    

Попробуйте здесь: http://jsfiddle.net/ZWZP6/2/

В CoffeeScript

В сценарии кофе вы можете использовать конструкцию super() [документы] :

class BaseClass
    foo: -> console.log('called BaseClass.foo')

class SubClass extends BaseClass
    foo: ->
        console.log('called SubClass.foo')
        super()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...