JavaScript Extending Class

前端 未结 10 1368

I have a base class:

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

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

That

相关标签:
10条回答
  • 2020-11-30 18:26

    Try this:

    Function.prototype.extends = function(parent) {
      this.prototype = Object.create(parent.prototype);
    };
    
    Monkey.extends(Monster);
    function Monkey() {
      Monster.apply(this, arguments); // call super
    }
    

    Edit: I put a quick demo here http://jsbin.com/anekew/1/edit. Note that extends is a reserved word in JS and you may get warnings when linting your code, you can simply name it inherits, that's what I usually do.

    With this helper in place and using an object props as only parameter, inheritance in JS becomes a bit simpler:

    Function.prototype.inherits = function(parent) {
      this.prototype = Object.create(parent.prototype);
    };
    
    function Monster(props) {
      this.health = props.health || 100;
    }
    
    Monster.prototype = {
      growl: function() {
        return 'Grrrrr';
      }
    };
    
    Monkey.inherits(Monster);
    function Monkey() {
      Monster.apply(this, arguments);
    }
    
    var monkey = new Monkey({ health: 200 });
    
    console.log(monkey.health); //=> 200
    console.log(monkey.growl()); //=> "Grrrr"
    
    0 讨论(0)
  • 2020-11-30 18:28

    For Autodidacts:

    function BaseClass(toBePrivate){
        var morePrivates;
        this.isNotPrivate = 'I know';
        // add your stuff
    }
    var o = BaseClass.prototype;
    // add your prototype stuff
    o.stuff_is_never_private = 'whatever_except_getter_and_setter';
    
    
    // MiddleClass extends BaseClass
    function MiddleClass(toBePrivate){
        BaseClass.call(this);
        // add your stuff
        var morePrivates;
        this.isNotPrivate = 'I know';
    }
    var o = MiddleClass.prototype = Object.create(BaseClass.prototype);
    MiddleClass.prototype.constructor = MiddleClass;
    // add your prototype stuff
    o.stuff_is_never_private = 'whatever_except_getter_and_setter';
    
    
    
    // TopClass extends MiddleClass
    function TopClass(toBePrivate){
        MiddleClass.call(this);
        // add your stuff
        var morePrivates;
        this.isNotPrivate = 'I know';
    }
    var o = TopClass.prototype = Object.create(MiddleClass.prototype);
    TopClass.prototype.constructor = TopClass;
    // add your prototype stuff
    o.stuff_is_never_private = 'whatever_except_getter_and_setter';
    
    
    // to be continued...
    

    Create "instance" with getter and setter:

    function doNotExtendMe(toBePrivate){
        var morePrivates;
        return {
            // add getters, setters and any stuff you want
        }
    }
    
    0 讨论(0)
  • 2020-11-30 18:31

    the absolutely minimal (and correct, unlike many of the answers above) version is:

    function Monkey(param){
      this.someProperty = param;
    }
    Monkey.prototype = Object.create(Monster.prototype);
    Monkey.prototype.eatBanana = function(banana){ banana.eat() }
    

    That's all. You can read here the longer explanation

    0 讨论(0)
  • 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();
            }
        }
    );
    
    0 讨论(0)
  • 2020-11-30 18:36

    If you don't like the prototype approach, because it doesn't really behave in a nice OOP-way, you could try this:

    var BaseClass = function() 
    {
        this.some_var = "foobar";
    
        /**
         * @return string
         */
        this.someMethod = function() {
            return this.some_var;
        }
    };
    
    var MyClass = new Class({ extends: BaseClass }, function()
    {
        /**
         * @param string value
         */
        this.__construct = function(value)
        {
            this.some_var = value;
        }
    })
    

    Using lightweight library (2k minified): https://github.com/haroldiedema/joii

    0 讨论(0)
  • 2020-11-30 18:37

    ES6 gives you now the opportunity to use class & extends keywords :

    Then , your code will be :

    You have a base class:

    class Monster{
           constructor(){
                 this.health = 100;
            }
           growl() {
               console.log("Grr!");
           }
    
    }
    

    That You want to extend and create another class with:

    class Monkey extends Monster {
            constructor(){
                super(); //don't forget "super"
                this.bananaCount = 5;
            }
    
    
            eatBanana() {
               this.bananaCount--;
               this.health++; //Accessing variable from parent class monster
               this.growl(); //Accessing function from parent class monster
            }
    
    }
    
    0 讨论(0)
提交回复
热议问题