简体   繁体   中英

Assigning prototype inside constructor

I have this code:

var MyClass = function(b) {
    this.a = b;
    this.getA = function() {
        return that.a;
    }
}

var SecondClass = function(b) {
    this.prototype = new MyClass(b);
    this.getB = function() {
        return 6;
    }
}

var a = new SecondClass(2);
console.log(a.getA());

The output tells me that a has no method called getA()

I assumed that doing this.prototype = new MyClass() inside the constructor for SecondClass would cause it to inhert methods from MyClass?

I'm sure there are better ways to do this, but I am trying to understand the behaviour of the prototype keyword.

prototype is a special property of the constructor function , not of the instance .

When you call the constructor function with new Func() , the engine will create a new object which inherits from Func.prototype and then sets this inside the constructor function to refer to the new object.

So, aside from this.prototype just being an ordinary property, the inheritance already took place when the assignment takes place.

Since you are not assigning any methods to MyClass.prototype , you don't have to do anything with prototype inheritance here. All you have to do is apply MyClass to the newly created instance using .call [MDN] :

var SecondClass = function(b) {
    MyClass.call(this, b);
    this.getB = function() {
        return 6;
    }
};

However, you should add all methods that are shared by instances to the prototype and then let each instance of SecondClass inherit from it. This is how a complete setup could look like:

var MyClass = function(b) {
    this.a = b;
}
MyClass.prototype.getA = function() {
    return this.a;
};

var SecondClass = function(b) {
    // call parent constructor (like 'super()' in other languages)
    MyClass.call(this, b);
}
// Setup inheritance - add 'MyClass.prototype' to the prototype chain
SecondClass.prototype = Object.create(MyClass.prototype);
SecondClass.prototype.getB = function() {
    return 6;
};

var a = new SecondClass(2);
console.log(a.getA());

All of this will become easier in ES6 .

A property called "prototype" is only interesting on objects that are functions. Assigning a value to the "prototype" property in your constructor has no effect (in this case); what matters would be the "prototype" property of the constructor function itself.

SecondClass.prototype = new MyClass();

or something. The prototype object of a constructor is shared among all the instances constructed, so having the prototype vary by a constructor parameter also doesn't make a lot of sense.

Another thing you could do would be to call the "MyClass" constructor from inside "SecondClass":

function SecondClass(b) {
  MyClass.call(this, b);
  this.getB = function() {
    return 6;
  };
}

That would have the effect of making the this that's constructed in the new SecondClass() call be decorated by the "MyClass" constructor. It wouldn't really be inheritance, but you'd get a "getA" function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM