1

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

Liam
  • 27,717
  • 28
  • 128
  • 190
Andrew Schools
  • 321
  • 3
  • 10
  • I take it you've seen [How does JavaScript .prototype work?](http://stackoverflow.com/questions/572897/how-does-javascript-prototype-work) – Liam Jun 05 '15 at 15:09
  • @Liam - Thanks for the link. I will read this over. I have done a bunch of reading about inheritance just don't understand why I'm seeing different things in the console when omitting this piece of code. – Andrew Schools Jun 05 '15 at 15:51

3 Answers3

4

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.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
  • @Feliz - So in my code above, there is really no need to set the constructor since technically there is no change to the prototype chain. I see that Mozilla has an example that does NOT omit this line. Is it for clarify? I ask because I want to find the most intuitive way and then stick with it. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create – Andrew Schools Jun 05 '15 at 15:57
  • 2
    You probably want to read [What it the significance of the Javascript constructor property?](http://stackoverflow.com/q/4012998/218196) – Felix Kling Jun 05 '15 at 16:00
2

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

Kiril
  • 2,935
  • 1
  • 33
  • 41
2

...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
apsillers
  • 112,806
  • 17
  • 235
  • 239