Emulate super in javascript

后端 未结 11 1130
生来不讨喜
生来不讨喜 2020-12-08 10:18

Basically is there a good elegant mechanism to emulate super with syntax that is as simple as one of the following

  • this.$super.prop()
11条回答
  •  北海茫月
    2020-12-08 10:55

    JsFiddle:

    What is wrong with this?

    'use strict';
    
    function Class() {}
    Class.extend = function (constructor, definition) {
        var key, hasOwn = {}.hasOwnProperty, proto = this.prototype, temp, Extended;
    
        if (typeof constructor !== 'function') {
            temp = constructor;
            constructor = definition || function () {};
            definition = temp;
        }
        definition = definition || {};
    
        Extended = constructor;
        Extended.prototype = new this();
    
        for (key in definition) {
            if (hasOwn.call(definition, key)) {
                Extended.prototype[key] = definition[key];
            }
        }
    
        Extended.prototype.constructor = Extended;
    
        for (key in this) {
            if (hasOwn.call(this, key)) {
                Extended[key] = this[key];
            }
        }
    
        Extended.$super = proto;
        return Extended;
    };
    

    Usage:

    var A = Class.extend(function A () {}, {
        foo: function (n) { return n;}
    });
    var B = A.extend(function B () {}, {
        foo: function (n) {
            if (n > 100) return -1;
            return B.$super.foo.call(this, n+1);
        }
    });
    var C = B.extend(function C () {}, {
        foo: function (n) {
            return C.$super.foo.call(this, n+2);
        }
    });
    
    var c = new C();
    document.write(c.foo(0) + '
    '); //3 A.prototype.foo = function(n) { return -n; }; document.write(c.foo(0)); //-3

    Example usage with privileged methods instead of public methods.

    var A2 = Class.extend(function A2 () {
        this.foo = function (n) {
            return n;
        };
    });
    var B2 = A2.extend(function B2 () {
        B2.$super.constructor();
        this.foo = function (n) {
            if (n > 100) return -1;
            return B2.$super.foo.call(this, n+1);
        };
    });
    var C2 = B2.extend(function C2 () {
        C2.$super.constructor();
        this.foo = function (n) {
            return C2.$super.foo.call(this, n+2);
        };
    });
    
    //you must remember to constructor chain
    //if you don't then C2.$super.foo === A2.prototype.foo
    
    var c = new C2();
    document.write(c.foo(0) + '
    '); //3

提交回复
热议问题