A quick digression about the constructor property in Javascript

When i think about the constructor, i think about the function called when a class is instantiated. Well, that is true about Java but i would like to write about the constructor in Javascript.

For me is a challenge write about the constructor; after years of Javascript i still see it as something confusing; anyway recently i had the opportunity to go through it and i would like to write here some considerations.

Well, as introduction i think is good to give some definitions, distinguishing between two kinds of constructor:

  • constructor functions: functions designed to be instantiated.
  • constructor property: a property of the prototype pointing back to the constructor function
    (keep in mind that every function in js, when defined, gets its own prototype object).

Well, quite confusing introduction, here an example of what i am saying:

var MyType = function(){};
MyType.prototype.constructor === MyType; // true
var test = new MyType();
test.constructor === MyType; // true : got from prototype
test instanceof MyType; // true

Sometimes i have seen “classes” (i should say objects) defined in this way:

var MyType = function(){};
MyType.prototype = {
    method1: function(){},
    method2: function(){}
}

The prototype is an object so all seems right and of course the methods will work but the constructor property will be “broken”. Let’s check it:

(new MyType()).constructor === MyType // false
(new MyType()).constructor === Object // true

I think the constructor property was intended to be “MyType”; what happens there is the same to write this:

var MyType = function(){},
    methods = {};
MyType.prototype.constructor === MyType; // true
MyType.prototype.constructor === Object; // false
methods.constructor === Object; // true
methods.method1 = function(){};
methods.method2 = function(){};
MyType.prototype = methods; // here happens the change...
MyType.prototype.constructor === MyType; // false
MyType.prototype.constructor === Object; // true

Is the constructor property always the function instantiated with the new operator?

A quick example to check it:

var MyType = function(){alert("MyType")},
    OneMoreType = function(){alert("OneMoreType")};
MyType.prototype.constructor = OneMoreType;
var test = new MyType(); // alerts "MyType"
test.constructor === OneMoreType; // true
test instanceof MyType; // true
test instanceof OneMoreType; // false

The function instantiated (and executed) is MyType but the constructor property refers to OneMoreType.
That means: you can reassign the constructor property to a different function. That doesn’t change the code executed calling that function or the function’s prototype!

In other words: the constructor property of a constructor function could not be the constructor function itself (but it is by default and it is intended to be).

Manually assign the constructor property

We have just seen that is possible to manually assign the constructor property, sometimes it can be useful. Think about a situation like this:

var MyType = function(){},
    methods = {};
methods.constructor === Object; // true
methods.method1 = function(){};
methods.method2 = function(){};
methods.constructor = MyType;
MyType.prototype = methods;

The object methods will be the prototype of the function MyType and we want to keep the original constructor property of the function (it is MyType of course). Let’s check the result:

(new MyType()).constructor === MyType // true
(new MyType()).constructor === Object // false

It works: so we can say that it is something good, to manually set the constructor and make it as intended? I don’t think so: this approach changes the constructor’s “enum flag value”. It is easier to explain that with an example:

var methods = {};
methods.constructor === Object; // true

// you are going to get 0 alert from here
for(var property in methods){
    alert(property);
}

methods.constructor = function(){};

// you get one alert here: it says "constructor"
for(var property in methods){
 alert(property);
}

What that means? It means that, as default, constructor is not an enumerable property but, changing it manually, makes of it an enumerable property.
How much bad is that? Up to you answer it. Always keep in mind you will be able to make your code handles this situation but what about code is not from you?

Conclusions

The role of a constructor function is obvious but what about the rule of the constructor property? The constructor property of an object is a writeable property intended to refer to the constructor function.

Foot notes

There is a relationship between the instanceof operator and the constructor property?
Let’s check it with a quick example:

var MyType = function(){alert("MyType")},
    OneMoreType = function(){alert("OneMoreType")};
MyType.prototype.constructor = OneMoreType;
var test = new MyType(); // alerts "MyType"
test.constructor === OneMoreType; // true
test instanceof MyType; // true
test instanceof OneMoreType; // false

I have already used that example inside the post but i think it is a good example for this situation; as you can see, instanceof doesn’t dipend from the constructor.

Some links

Thanks for reading!

Advertisements
This entry was posted in Javascript, Programming and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s