简体   繁体   中英

javascript inheritance and unique instances

function Shape() {
    this.name = "none"; 
}

function Rect () {        
    this.x = 0;
    this.y = 0;
    this.width = 0;
    this.height = 0;
};

If all the property of Shape should be available to Rect is it correct to write

Rect.prototype = Shape;

In this case will each instance of Rect(ie Object.create(Rect)) gets a seperate name from Shape object.

Rect.prototype = Shape; is definitely incorrect. Every instance of Rect would have the same properties as the function Shape . That includes methods that every function has, like .call and .apply .

But even Rect.prototype = new Shape; as suggested in the other answer is not a good solution. While this would add name to every instance of Rect , every instance would share the same name property. But name is an instance specific property, it does not belong on the prototype. The prototype chain should only hold properties (values) that are supposed to be shared by every instance.

So, how to do it?

Add Shape.prototype to the prototype chain of Rect instances:

Rect.prototype = Object.create(Shape.prototype, {constructor: {value: Rect}});

You don't have any custom properties on Shape.prototype yet, however, setting this up makes the following work:

var r = new Rect();
r instanceof Shape; // true

You also have to call the super constructor ( Shape ) inside the Rect constructor, setting this to the new instance:

function Rect () {
    Shape.call(this);

    this.x = 0;
    this.y = 0;
    this.width = 0;
    this.height = 0;
}

Shape.call(this); is the moment where name is assigned to our new Rect instance .

If you come from Java or another class-oriented OO language, this is basically the same as calling super(); in the child constructor.


All of the above is exactly what the new ES6 class syntax does internally.

class Rect extends Shape {
  constructor() {
      super();
      // ...
  }
}

You would have to write the following.

Rect.prototype = new Shape();

That would create a new object for Shape and then assign it as the prototype for Rect . You can't assign a function as a prototype.

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