The "constructor" property

  1. Example
  2. The origins of constructor
  3. Keeping constructor up to date
  4. Summary

An object has a build-in property named constructor. It is meant to reference the function which made the object, but it fails to do it sometimes.

Example

Let’s create a simple constructor and see how new objects have the right constructor value:

function Rabbit() { }

var rabbit = new Rabbit()

alert( rabbit.constructor == Rabbit ) // true

The origins of constructor

When you declare a function:

function Rabbit() { /* ..code.. */ }

The interpreter creates the new function object from your declaration. Together with the function, it’s prototype property is created and populated.

This default value the prototype is an object with property constructor, which is set to the function itself. In our case, to Rabbit:

Rabbit.prototype = { constructor: Rabbit }

So, when new Rabbit is called, the Rabbit.prototype becomes __proto__ and the constructor becomes accessible from the object:

rabbit.__proto__ == { constructor: Rabbit )

Let’s make a direct check:

function Rabbit() { }

var rabbit = new Rabbit()

alert( rabbit.hasOwnProperty('constructor') ) // false
alert( Rabbit.prototype.hasOwnProperty('constructor') ) // true

Keeping constructor up to date

Calling rabbit.constructor actually returns rabbit.__proto__.constructor.

There is a side effect. For example, let’s see what happens when we replace the prototype:

function Rabbit() { } // (1)

Rabbit.prototype = {}  // (2)

var rabbit = new Rabbit()

alert( rabbit.constructor == Object ) // true

Whops! The rabbit lost it’s constructor.

It happened, because Rabbit.prototype is replaced with a new Object.

See the picture for better understanding:

In other words, when the interpreter creates a prototype of a function, it makes an object and puts constructor in there.

But the custom prototype {} is an object without constructor.
So, the interpreter falls back to it’s __proto__, ultimately using the native Object.prototype.constructor.

The constructor property is assigned to function prototype. Then the interpreter forgets about it.

Additional code is usually required to prevent it from being overwritten.

If you intent to keep it correct, then put it into the new prototype, like this:

function Rabbit() { } 

Rabbit.prototype = { constructor: Rabbit }  

var rabbit = new Rabbit()

alert( rabbit.constructor == Rabbit ) // now fine

There’s the code:

var obj = new Foo();  // Foo is an arbitrary function

We need to create an object using the same constructor function.

Will the following code work right?
If yes, will it work correctly for any Foo, or only for particular cases?

var obj2 = new obj.constructor;

Open solution
Solution

From the first glance - yes, it will work.
For example:

function Foo() { 
  this.toString = function() { return 'Foo!'; };
}

var obj = new Foo();
var obj2 = new obj.constructor;

alert(obj2); // Foo!

But it only works, because Foo.prototype.constructor == Foo. So, if someone overwrites Foo.prototype (or spoils constructor in another way), the code would fail:

function Foo() { 
  this.toString = function() { return 'Foo!'; };
}
*!*
Foo.prototype = {};
*/!*

var obj = new Foo();
var obj2 = new obj.constructor;

alert(obj2); // [object Object]

The result is an empty literal object, because {} is actually new Object, with constructor == Object.

So, obj2 gets created using the default Object constructor instead of Foo.

Summary

  • The constructor property is created together with the function as a single property of func.prototype.
  • When the prototype is replaced, the constructor is lost. The interpreter doesn’t keep it.
  • If we want to have the right constructor after inheritance - we need to set it by our own.

Tutorial

Donate

Donate to this project