W3cubDocs

/JavaScript

object.constructor

The constructor property returns a reference to the Object constructor function that created the instance object. Note that the value of this property is a reference to the function itself, not a string containing the function's name. The value is only read-only for primitive values such as 1, true and "test".

Description

All objects (with the exception of objects created with Object.create(null)) will have a constructor property. Objects created without the explicit use of a constructor function (i.e. the object and array literals) will have a constructor property that points to the Fundamental Object constructor type for that object.

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

var o = new Object;
o.constructor === Object; // true

var a = [];
a.constructor === Array; // true

var a = new Array;
a.constructor === Array; // true

var n = new Number(3);
n.constructor === Number; // true

Examples

Displaying the constructor of an object

The following example creates a prototype, Tree, and an object of that type, theTree. The example then displays the constructor property for the object theTree.

function Tree(name) {
  this.name = name;
}

var theTree = new Tree('Redwood');
console.log('theTree.constructor is ' + theTree.constructor);

This example displays the following output:

theTree.constructor is function Tree(name) {
  this.name = name;
}

Changing the constructor of an object

The following example shows how to modify constructor value of generic objects. Only true, 1 and "test" will not be affected as they have read-only native constructors. This example shows that it is not always safe to rely on the constructor property of an object.

function Type () {}

var types = [
  new Array(),
  [],
  new Boolean(),
  true,             // remains unchanged
  new Date(),
  new Error(),
  new Function(),
  function () {},
  Math,
  new Number(),
  1,                // remains unchanged
  new Object(),
  {},
  new RegExp(),
  /(?:)/,
  new String(),
  'test'            // remains unchanged
];

for (var i = 0; i < types.length; i++) {
  types[i].constructor = Type;
  types[i] = [types[i].constructor, types[i] instanceof Type, types[i].toString()];
}

console.log(types.join('\n'));

This example displays the following output (comments added for reference):

function Type() {},false,                                     // new Array()
function Type() {},false,                                     // []
function Type() {},false,false                                // new Boolean()
function Boolean() {
    [native code]
},false,true                                                  // true
function Type() {},false,Mon Sep 01 2014 16:03:49 GMT+0600    // new Date()
function Type() {},false,Error                                // new Error()
function Type() {},false,function anonymous() {

}                                                             // new Function()
function Type() {},false,function () {}                       // function () {}
function Type() {},false,[object Math]                        // Math
function Type() {},false,0                                    // new Number()
function Number() {
    [native code]
},false,1                                                     // 1
function Type() {},false,[object Object]                      // new Object()
function Type() {},false,[object Object]                      // {} 
function Type() {},false,/(?:)/                               // new Regexp()
function Type() {},false,/(?:)/                               // /(?:)/ 
function Type() {},false,                                     // new String()
function String() {
    [native code]
},false,test                                                  // 'test'

Changing the constructor of a function

Mostly this property is used for defining a function as a function-constructor with further calling it with new and prototype-inherits chain.

function Parent() {}
Parent.prototype.parentMethod = function parentMethod() {};

function Child() {}
Child.prototype = Object.create(Parent.prototype); // re-define child prototype to Parent prototype

Child.prototype.constructor = Child; // return original constructor to Child

But when do we need to perform last line here? Unfortunately the answer is - it depends.

Let's try to define the cases in which re-assignment of the original constructor will play a major role and when it will be one extra unused line of code.

Take the following case: the object has create method to create itself.

function Parent() {};
function CreatedConstructor() {}

CreatedConstructor.prototype = Object.create(Parent.prototype);

CreatedConstructor.prototype.create = function create() {
  return new this.constructor();
}

new CreatedConstructor().create().create(); // TypeError undefined is not a function since constructor === Parent

In the example above the exception will be shown since constructor links to Parent.

To avoid this just assign necessary constructor which you are going to use.

function Parent() {}; 
function CreatedConstructor() {} 

CreatedConstructor.prototype = Object.create(Parent.prototype); 
CreatedConstructor.prototype.constructor = CreatedConstructor; // set right constructor for further using

CreatedConstructor.prototype.create = function create() { 
  return new this.constructor();
} 

new CreatedConstructor().create().create(); // it's pretty fine

Ok, now it's pretty clear why changing of the constructor can be useful.

Let's consider one more case.

function ParentWithStatic() {}

ParentWithStatic.startPosition = { x: 0, y:0 };
ParentWithStatic.getStartPosition = function getStartPosition() {
  return this.startPosition;
} 

function Child(x, y) {
  this.position = {
    x: x,
    y: y
  };
}

Child.prototype = Object.create(ParentWithStatic.prototype); 
Child.prototype.constructor = Child;

Child.prototype.getOffsetByInitialPosition = function getOffsetByInitialPosition() {
  var position = this.position;
  var startPosition = this.constructor.getStartPosition(); // error undefined is not a function, since the constructor is Child

  return {
    offsetX: startPosition.x - position.x,
    offsetY: startPosition.y - position.y
  }
};

For this example we need to stay parent constructor to continue to work properly.

Summary: manually updating or setting the constructor can lead to differrent and sometimes confusing consequences. To prevent this just define the role of constructor in each specific case. In most cases constructor is not used and reassignment of it is not necessary.

Specifications

Browser compatibilityUpdate compatibility data on GitHub

Desktop
Chrome Edge Firefox Internet Explorer Opera Safari
Basic support Yes Yes 1 Yes Yes Yes
Mobile
Android webview Chrome for Android Edge Mobile Firefox for Android Opera for Android iOS Safari Samsung Internet
Basic support Yes Yes Yes 4 Yes Yes Yes
Server
Node.js
Basic support Yes

© 2005–2018 Mozilla Developer Network and individual contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor