简体   繁体   中英

Javascript inheritance with access to *all* methods in 'superclass'?

Trying to understand how inheritance can be done in Javascript, I stumbled across many differerent implementations, including Crockfords, Resigs, Prototype , klass , and others.

What I missed (I brace myself for the uproar) was the Smalltalkish self/super pair: self playing a similar role than this , namely representing the current "object", and super referring to a superclass-only version of this .

[Skip to "]" if you know what super does in Smalltalk: Assuming Subclass has overriden method1 defined in Superclass , I can still access the superclass implementation using super.method1() in Subclass.method2() . This will not execute the Subclass.method1() code.

function Superclass () {
}
Superclass.prototype.method1 = function () {
  return "super";
}

function Subclass () {
}
Subclass.prototype.method1 = function () {
  return "sub";
}
Subclass.prototype.method2 = function () {
  alert (super.method1 ());
}

var o = new Subclass;
o.method2 (); // prints "super"

]

Is there any "Javatalk" package out there? So far, I have seen only OO emulations in Javascript which give access to the superclass implementation of the currently defined method ( method2 ), not any other (such as method1 ).

Thanks, nobi

You don't have a super feature in JavaScript.

When you know the superclass, you can call the super method directly using call :

Superclass.method1.call(this);

If you want to emulate a generic super (which I don't advocate), you could use this :

function sup(obj, name) {
     var superclass = Object.getPrototypeOf(Object.getPrototypeOf(obj));
     return superclass[name].apply(obj, [].slice.call(arguments,2));
}

that you would use as

sup(this, 'method1');

instead of your

super.method1();

And if you have arguments to pass :

sup(this, 'method1', 'some', 'args');

instead of

super.method1('some', 'args');

Note that this supposes proper prototype inheritance that you set using

Subclass.prototype = new Superclass();

Okey, long story short: this is the best JavaScript tutorial I've ever read. So I can recomment it to you. Good luck!

There are so many ways to implement a super feature in JavaScript. For instance:

function SuperClass(someValue) {
    this.someValue = someValue;
}

SuperClass.prototype.method1 = function () {
    return this.someValue;
};

function SubClass(someValue) {
    //call the SuperClass constructor
    this.super.constructor.call(this, someValue);
}

//inherit from SuperClass
SubClass.prototype = Object.create(SuperClass.prototype);

//create the super member that points to the SuperClass prototype
SubClass.prototype.super = SuperClass.prototype;

SubClass.prototype.method2 = function () {
    alert(this.super.method1.call(this));
};

var sub = new SubClass('some value');

sub.method2();

EDIT:

Here's an example of an extremely generic super method that relies on non-standard features. I really do not recommend this and it's just there as learning purposes.

Object.prototype.super = function () {
    var superProto = Object.getPrototypeOf(Object.getPrototypeOf(this)),
        fnName = arguments.callee.caller.name,
        constructorName = this.constructor.name;

    if (superProto == null) throw constructorName + " doesn't have a superclass";
    if (typeof superProto[fnName] !== 'function') {
        throw constructorName + "'s superclass (" 
            + superProto.constructor.name + ") doesn't have a " + fnName + ' function';
    }

    return superProto[arguments.callee.caller.name].apply(
        this, 
        [].slice.call(arguments, 1)
    );
};   


function A() {
}

A.prototype.toString = function toString() {
    //call super method Object.prototype.toString
    return this.super();
};

var a = new A();

console.log(a.toString());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM