Green Green - 7 months ago 8
Javascript Question

Why is it impossible to change constructor function from prototype?

I have such example.

function Rabbit() {
var jumps = "yes";
};
var rabbit = new Rabbit();
alert(rabbit.jumps); // undefined
alert(Rabbit.prototype.constructor); // outputs exactly the code of the function Rabbit();


I want to change the code in
Rabbit()
so that the
var jumps
becomes public. I do it this way:

Rabbit.prototype.constructor = function Rabbit() {
this.jumps = "no";
};
alert(Rabbit.prototype.constructor); // again outputs the code of function Rabbit() and with new this.jumps = "no";
var rabbit2 = new Rabbit(); // create new object with new constructor
alert(rabbit2.jumps); // but still outputs undefined


Why is it not possible to change the code in constructor function this way?

Answer

What is happening is that Rabbit.prototype.constructor is just a pointer to the original constructor (function Rabit(){...}), so that users of the 'class' can detect the constructor from an instance. Therefore, when you try to do

Rabbit.prototype.constructor = function Rabbit() {
    this.jumps = "no";
};

You're just breaking the link between the original constructor and the reference to it on the prototype. So the answer is, no, you cannot change a constructor by reassigning to prototype.constructor

Inheritance in JS

Many libraries implement inheritance with something like the following:

function extend(base, sub) {

  function surrogateCtor() {}
  // Copy the prototype from the base to setup inheritance
  surrogateCtor.prototype = base.prototype;
  // Tricky huh?
  sub.prototype = new surrogateCtor();
  // The constructor property is set wrong (to the base constructor)
  // with the above trick, let's fix it
  sub.prototype.constructor = sub;
}

You can see that in the above code, we have to fix the constructor property, but it doesn't affect the actual constructor. See my post about JS inheritance http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html

How to redefine a constructor If you really want to redefine a constructor, just do

var oldProto = Rabbit.prototype;
Rabbit = function() {...};
Rabbit.prototype = oldProto;