Why don't I use Child.prototype = Parent.Prototype, and not Child.prototype = new Parent (); for Javascript inheritance?

I do not understand this behavior in javascript for inheritance. I always saw it like this:

function GameObject(oImg, x, y) { this.x = x; this.y = y; this.img = oImg; this.hit = new Object(); this.hitBox.x = x; this.hitBox.y = y; this.hitBox.width = oImg.width; this.hitBox.height = oImg.height; } Spaceship.prototype = new GameObject(); Spaceship.prototype.constructor = Spaceship; function Spaceship(){ console.log("instantiate ship"); GameObject.apply(this, arguments); this.vx = 0; this.vy = 0; this.speed = 3; this.friction = 0.94; } 

But in my case, these lines:

  this.hitBox.width = oImg.width; this.hitBox.height = oImg.height; 

When I create console.log (this) in my Spaceship constructor, I see that the proto property is set to Spaceship instead of GameObject, if I delete them, it will be set to GameObject.

And if I use:

  Spaceship.prototype = GameObject.prototype; 

I have no more problems with this. The reason this blocks me is because I have another object with the add () method and it checks that the inerhits GameObject with this code is:

  if(object instanceof GameObject) 

I do not understand that these two lines can probably change so that inheritance is broken when they are present, and I'm not sure if inheritance is the second way. Can someone enlighten me about this, please? :)

+7
source share
3 answers

If you do

Spaceship.prototype = GameObject.prototype;

Then they both refer to the same object, so you can have everything in GameObject , if you add something to Spaceship.prototype , it will be added to GameObject.prototype . You can easily test it by adding something to Spaceship.prototype after the assignment. For example, in your case, you can see that GameObject.prototype.constructor is actually a Spaceship .

Concerning

 Spaceship.prototype = new GameObject(); 

This causes a constructor that may have unwanted side effects, you'd rather use:

 Spaceship.prototype = Object.create(GameObject.prototype); 

If the used functionality of Object.create here comes down to the following:

 Object.create = function( proto ) { function f(){} f.prototype = proto; return new f; }; 

Modern browsers already have a feature.

+13
source

It never explained why you became weird behavior with this.hitBox (I think you were trying to say).

If you inherit by calling the parent constructor to create the prototype, this parent constructor runs once to create an instance of the parent type, and then all instances of the child type will use this instance as their prototype.

The problem is that if this constructor has any lines that assign mutable objects to this , then these objects will be the properties of this prototype, and any changes to these objects will be displayed in all instances of the child type:

 Spaceship.prototype = new GameObject(); Spaceship.prototype.constructor = Spaceship; var sps1 = new Spaceship(); var sps2 = new Spaceship(); sps1.hitBox.x = 9; sps2.hitBox.x = 12; console.log(sps1.hitBox.x); // 12 (oh noes! what happened) console.log(sps2.hitBox.x); // 12 

(there are other similar problems with “calling the constructor to make a prototype”, but I just leave it here at this point)

@ The idea of ​​using Object.create(baseObject) is the first step to solving this problem. It creates a new object, the prototype of which is baseObject , but without the content created in the constructor (this is good, but it must be taken into account. Read on ...).

As I said, this will create an object in which the initialization logic of the parent constructor never starts, but in most cases this logic is related to the functionality of the object. So, there’s something else you need to do to make the child constructor invoke the parent constructor:

 function Spaceship(oImg, x, y) { // call parent constructor on this object and pass in arguments. // you could also use default values for the arguments when applicable GameObject.call(this, oImg, x, y); // remainder of Spaceship constructor... } 

This ensures that the parent constructor logic runs separately for each new Spaceship and performs the necessary initialization tasks.

+2
source
 function GameObject(oImg, x, y) { this.x = x; this.y = y; this.img = oImg || {width:null, height: null}; this.hitBox = new Object(); this.hitBox.x = x; this.hitBox.y = y; this.hitBox.width = this.img.width; this.hitBox.height = this.img.height; } function Spaceship(){ GameObject.apply(this, arguments); this.vx = 0; this.vy = 0; this.speed = 3; this.friction = 0.94; } Spaceship.prototype = new GameObject(); var sps1 = new Spaceship(); var sps2 = new Spaceship(); sps1.hitBox.x = 9; sps2.hitBox.x = 12; console.log(sps1.hitBox.x); // 9 console.log(sps2.hitBox.x); // 12 
0
source

All Articles