I’m writing this to remind myself about what happens when new object is constructed in JavaScript. This is based on the knowledge I have so far. Please let me know if you find something which is not correct.
Every object in JavaScript has a property called [[Prototype]] which is hidden and not accessible. The exceptions are functions which are also objects in JavaScript. Each function has an additional public property called prototype.
This property is used when setting up a prototypal inheritance. It’s important to mention that public prototype property is not equal to the private hidden [[Prototype]] property.
In order to create a new object of the specific type the constructor has to be defined first. In JavaScript constructors are just regular functions. For example:
// function which will be used to construct new object (constructor)
function Foo() {}
A new object can be created with the operator ‘new’:
// new object is created
var foo = new Foo;
The operator ‘new’ in the line above does a few things:
1) it creates a new object with the [[Prototype]] property
2) the [[Prototype]] property of the newly created object is set to the prototype of the function used as a constructor to create the object. This sounds complicated but it’s actually pretty simple. Let’s take a look at this code:
// __proto__ is a visible
// in some browsers (Chrome, Safari, FF)
// and it's deprecated now: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/proto
// the [[Prototype]] property is set to the prototype of the constructor (function)
console.log(foo.__proto__ === Foo.prototype) // true
3) The newly created object is passed to Foo() as the implicit parameter ‘this’
4) The object ‘this’ is returned and assigned to the variable foo
Foo’s public prototype property is an object itself and has access to it’s own [[Prototype]] property. On top of that it also has an extra property called constructor which points back to function Foo.
We can test it with:
console.log(Foo.prototype.constructor === Foo) // true
Thanks to the prototypal nature of JavaScript we can access the properties of the Foo’s prototype directly from foo. Since we alredy know that:
console.log(foo.__proto__ === Foo.prototype) // true
and:
console.log(Foo.prototype.constructor) // Foo
based on the above we know that:
console.log(foo.constructor === Foo.prototype.constructor) // true
What actually happens when we try to access constructor property from foo is that first the runtime looks up the property on the object foo level and it doesn’t find it:
console.log(foo.hasOwnProperty('constructor')) // false
then it looks up the property in the object referenced by [[Prototype]] property.
Since in this case we know that the [[Prototype]] of foo points to the public prototype property on Foo, the constructor is present and visible.
Here are the tests together:
function Foo() {}
var foo = new Foo;
console.log(Foo.prototype.constructor === Foo) // true
console.log(foo.__proto__ === Foo.prototype) // true
console.log(Foo.prototype.constructor) // Foo
console.log(foo.constructor === Foo.prototype.constructor) // true
console.log(foo.hasOwnProperty('constructor')) // false