JavaScript proper prototypical inheritance

前端 未结 2 1702
走了就别回头了
走了就别回头了 2021-01-07 00:42

I\'ve been spending my past couple hours researching prototypical inheritance, but I\'m left with conflicting/unclear answers on how it should be done. It seems to be wo

相关标签:
2条回答
  • 2021-01-07 01:24

    A good reference is the MDN - Inheritance revisited page

    What you are looking for (I think) is something like this:

    Paper.Component = function(x,y,w,h){
        this.setPosition( x, y );
        this.setSize( w, h );
    }; 
    Paper.Component.prototype.isInBounds  = function(x, y){};
    Paper.Component.prototype.setPosition = function(x, y){};
    Paper.Component.prototype.setSize     = function(w, h){};
    
    Paper.Button = function(x, y, w, h, text){
        Paper.Component.apply( this, arguments );
    }
    Paper.Button.prototype = Object.create(Paper.Component.prototype);
    Paper.Button.prototype.constructor = Paper.Button;
    

    Things to note:

    • Do not do Paper.Component.prototype = { ... } as it will overwrite the current prototype (e.g. the existing .prototype.constructor and anything else anyone has already created).
    • Remember to set the constructor (the last line).
    0 讨论(0)
  • 2021-01-07 01:34

    What you have so far is fine. The missing bit in Button looks like this:

    Paper.Button = function(x, y, w, h, text){
        Paper.Component.call(this, /*...any args required by it...*/);
    
        // Button stuff here...
    };
    

    Function#call calls a function with a specific this value and any arguments you pass it. So the above calls Paper.Component from within Paper.Button with this referencing the current object, and passing along any appropriate arguments.

    You also want to set the constructor property on any prototype you replace rather than just adding to. It's largely optional (JavaScript itself doesn't use constructor for anything), but since the JavaScript engine sets it on the default prototype objects, we should set it when replacing them, just so we're consistent with the default prototypes.

    Slightly simpler, concrete example:

    function Shape(sides, color) {
        this.sides = sides;
        this.color = color;
    }
    // Shape.prototype.method = ...
    
    function Rectangle(color) {
        Shape.call(this, 4, color);
    
        // Rectangle stuff here...
    }
    
    Rectangle.prototype = Object.create(Shape.prototype);
    Rectangle.prototype.constructor = Rectangle;          // <== The constructor bit
    // Rectangle.prototype.method = ...
    

    If you're interested in setting up hierarchies of "classes" of objects using prototypical inheritance in JavaScript, you might want to look at my Lineage helper script, which automates the above with a simpler syntax and provides other useful features.

    0 讨论(0)
提交回复
热议问题