Javascript Prototypal Inheritance?

后端 未结 5 2004
日久生厌
日久生厌 2021-02-04 05:43

I\'been doing some inheritance in js in order to understand it better, and I found something that confuses me.

I know that when you call an \'constructor function\' with

5条回答
  •  一生所求
    2021-02-04 05:55

    I know it's already been answered but, there's a better way to do inheritance. Calling a constructor just for the purpose of inheritance is not desirable. One of the undesired effects is.

    function Base() {this.a = "A"}
    function Child() {this.b = "B"};
    
    Child.prototype = new Base();
    

    Now You've added property "a" to the prototype of Child that you didn't intend to.

    Here's the right way (I didn't invent this, Ext-JS and other libs use this)

    // This is used to avoid calling a base class's constructor just to setup inheritance.
    function SurrogateCtor() {}
    
    /**
     * Sets a contructor to inherit from another constructor
     */
    function extend(BaseCtor, DerivedCtor) {
      // Copy the prototype to the surrogate constructor
      SurrogateCtor.prototype = BaseCtor.prototype;
      // this sets up the inheritance chain
      DerivedCtor.prototype = new SurrogateCtor();
      // Fix the constructor property, otherwise it would point to the BaseCtor
      DerivedCtor.prototype.constructor = DerivedCtor;
      // Might as well add a property to the constructor to 
      // allow for simpler calling of base class's method
      DerivedCtor.superclass = BaseCtor;
    }
    
    function Base() {
      this.a = "A";
    }
    
    Base.prototype.getA = function() {return this.a}
    
    function Derived() {
      Derived.superclass.call(this);  // No need to reference the base class by name
      this.b = "B";
    }
    
    extend(Base, Derived);
    // Have to set methods on the prototype after the call to extend
    // otherwise the prototype is overridden;
    Derived.prototype.getB = function(){return this.b};
    var obj = new Derived();
    

    An even easier way is to add a third parameter to extend where you specify the method of the derived class so that you don't have to call extend and then add methods to the prototype

    extend(BaseCtor, DerivedCtor, {
      getB: function() {return this.b}
    });
    

    Then there are many other things you could do for syntactic sugar.

    Blogged about it: http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

提交回复
热议问题