JavaScript Extending Class

前端 未结 10 1371

I have a base class:

function Monster() {
  this.health = 100;
}

Monster.prototype.growl = function() {
  console.log(\"Grr!\");
}

That

10条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-11-30 18:35

    This is an extension (excuse the pun) of elclanrs' solution to include detail on instance methods, as well as taking an extensible approach to that aspect of the question; I fully acknowledge that this is put together thanks to David Flanagan's "JavaScript: The Definitive Guide" (partially adjusted for this context). Note that this is clearly more verbose than other solutions, but would probably benefit in the long-term.

    First we use David's simple "extend" function, which copies properties to a specified object:

    function extend(o,p) {
        for (var prop in p) {
            o[prop] = p[prop];
        }
        return o;
    }
    

    Then we implement his Subclass definition utility:

    function defineSubclass(superclass,     // Constructor of our superclass
                              constructor,  // Constructor of our new subclass
                              methods,      // Instance methods
                              statics) {    // Class properties
            // Set up the prototype object of the subclass
        constructor.prototype = Object.create(superclass.prototype);
        constructor.prototype.constructor = constructor;
        if (methods) extend(constructor.prototype, methods);
        if (statics) extend(constructor, statics);
        return constructor;
    }
    

    For the last bit of preparation we enhance our Function prototype with David's new jiggery-pokery:

    Function.prototype.extend = function(constructor, methods, statics) {
        return defineSubclass(this, constructor, methods, statics);
    };
    

    After defining our Monster class, we do the following (which is re-usable for any new Classes we want to extend/inherit):

    var Monkey = Monster.extend(
            // constructor
        function Monkey() {
            this.bananaCount = 5;
            Monster.apply(this, arguments);    // Superclass()
        },
            // methods added to prototype
        {
            eatBanana: function () {
                this.bananaCount--;
                this.health++;
                this.growl();
            }
        }
    );
    

提交回复
热议问题