Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of prototype constructor in JS

Tags:

javascript

oop

Can someone explain to me use of Me.prototype.constructor = Me; and why is needed, when this code is working and without it?

In code prototype object is created on Me object and it is instantiated and replaced old prototype object. Why do I need to point to Me constructor in a given up code?

function Me(){
    this.name = 'Dejan';

}

function You(){
    this.name = 'Ivan';
}

Me.prototype = new You();

somebody = new Me();

Me.prototype.constructor = Me; // Why?

Me.prototype.foo = function(){
    alert('Proto Me!'); // It always fire up this alert, ether constructor is pointing to Me or not... !
}

You.prototype.foo = function(){
    alert('Proto You!');
}

somebody.foo();
alert(somebody.name); // Alert 'Dejan'
like image 907
Dexy_Wolf Avatar asked Jul 30 '11 17:07

Dexy_Wolf


1 Answers

It's not needed, and it's not even needed for instanceof contrary to popular belief (instanceof internally checks the prototype chain and does not need a constructor property). Normally, constructor is inherently a non-enumerable property on a constructor's prototype. Thus giving any objects instantiated by that constructor, a non-enumerable constructor property, pointing to that constructor.

It's good to put it there if you need to, ideally non-enumerable. Some code will assume the existence of .constructor on objects.

In the code you posted, yes, when doing inheritance that way, it's necessary to reset constructor (if you want it there), because the object you instantiated to act as the child prototype has a constructor property pointing to the wrong constructor (its constructor).

In ES5, you would do:

Child.prototype = Object.create(Parent.prototype, {
  constructor: { value: Child, enumerable: false }
});

edit: Also, might be worth mentioning, when doing inheritance using the non-standard __proto__, it's not necessary to reset constructor because __proto__ merely specifies and object's prototype, which it to say, the object on which lookups will be performed when an own property doesn't exist. A new prototype will always have a property called constructor.

So in doing:

var child = function() {};
child.prototype.__proto__ = parent.prototype;

You do not have to set constructor because child.prototype's base constructor property is still there. If accessed, no prototype chain lookups need to be performed.

like image 110
chjj Avatar answered Oct 01 '22 20:10

chjj