Andrew Schools
Andrew Schools

Reputation: 321

Omitting prototype.constructor changes prototype chain

I'm trying to understand inheritance in JavaScript and I've seen that in JavaScript there are different ways to accomplish inheritance. One such way is based off of an example from the Mozilla site which does something similar to the code below:

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

Person.prototype.getName = function() {
  return this.name;
}

Person.prototype.setName = function(name) {
  this.name = name;
}

function Employee(name, Id) {
  Person.call(this, name);
  this.Id = Id;
}

Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;

Employee.prototype.getId = function() {
  return this.Id;
}

Employee.prototype.setId = function(Id) {
  this.Id = Id;
}

var andrew = new Employee("Andrew", "123");

I understand that this code is pretty basic and that I don't really need to define getters and setters. I only added them to show that I can add to each of the prototype objects. For the most part I understand what this code does.

Where I start to get confused is when I see the following line:

Employee.prototype.constructor = Employee;

I understand that we are setting the constructor property of the Employee.prototype object to point to the Employee constructor function. I have read other posts from this site that say I can omit this line and indeed if I do, everything works as expected. But... When I do omit this line I see some changes to the prototype chain. The __proto__ property of the Employee object now points to a generic Object with the following methods: getId and setId. The __proto__ property of this object then points to the Person.prototype object.

So my question is:

why is it that when I omit Employee.prototype.constructor = Employee that the __proto__ property points to an generic object with the methods I set in the Employee.prototype object and not the Employee.prototype object itself? Further more, how are the getId and setId methods attached to this mysterious prototype and is there any performance hit because of this?

I have attached the console.logs from the Chrome console to show the __proto__ property when manually setting the constructor property and then when omitting it.

With Employee.prototype.constructor

Without Employee.prototype.constructor

Upvotes: 1

Views: 94

Answers (3)

Felix Kling
Felix Kling

Reputation: 816780

Objects don't have names. So what you see next to __proto__ is a name that the console infers somehow. Apparently that way involves constructor somehow.

The prototype chain doesn't change, only the information that is presented to you. __proto__ refers to Employee.prototype regardless of the value of constructor.


Have a look at this example:

var foo = {};
console.log(foo); // Object {}

foo.constructor = function Foo() {};
console.log(foo); // Foo {}

foo doesn't change here, it's a normal object. However, once constructor is set, it's presented as if it was an instance of Foo.

Upvotes: 4

apsillers
apsillers

Reputation: 115970

...the __proto__ property points to an generic object with the methods I set in the Employee.prototype object and not the Employee.prototype object itself?

The "generic object" you're talking about is Employee.prototype. You can test this very easily yourself in Chrome by:

  • right-clicking on the __proto__: Object line
  • selecting "Store as global variable" from the menu to create a temp1 varaible
  • testing that temp1 == Employee.prototype is true

Upvotes: 2

Kiril
Kiril

Reputation: 2963

Seems that Chrome simply takes constructor property to display the Class name of the object in console.
So may create any object and simply assign any function to it's constructor property. As a result - you'll see this name in console:

var obj = { prop: 1 };
obj.constructor = function MyName() {};

will show:

enter image description here

Upvotes: 2

Related Questions