Javascript inheritance: calling Object.create when setting up a prototype

I am studying some aspects of object oriented Javascript. I came across this fragment

var Person = function(firstName, lastName) { this.lastName = lastName; this.firstName = firstName; }; Object.defineProperties(Person.prototype, { sayHi: { value: function() { return "Hi my name is " + this.firstName; } }, fullName: { get: function() { return this.firstName + " " + this.lastName; } } }); var Employee = function(firstName, lastName, position) { Person.call(this, firstName, lastName); this.position = position; }; Employee.prototype = Object.create(Person.prototype); var john = new Employee("John", "Doe", "Dev"); 

And my question is: why does this snippet use Object.create (Person.prototype)? Shouldn't we just reset the prototype with:

 Employee.prototype = Person.prototype; 
+7
source share
2 answers

Doing Employee.prototype = Person.prototype is like saying "Employee is Person" and not "Employee is Person". Any changes in any prototype will be reflected in both classes.

Here is a demo . Obviously, we do not want our Persons to work, because they have no position.

So the correct way to set up a prototype chain without Object.create is:

 Employee.prototype = new Person; 

But this requires creating an instance of the object that is a bit funky, especially if you do not want the Person constructor to call. All instances of Employee are going to inherit the undefined properties "firstName" and "lastName", regardless of whether you want this.

In this case, it does not matter much - the Employee constructor is going to set these properties on its own, which will replace the properties inherited from Person. But consider this example . You might think that freeTime is an instance level property for Person that will not be copied because it is not on a prototype. In addition, we never called the Person constructor from Employee. Not so - freeTime was installed on the Employee prototype because we needed to instantiate the object.

So the best and purest inheritance you can do is through Object.create. If you want to call the constructor of the parent class, you can do this explicitly from the constructor of the subclass. Another nice thing: Object.create has a second (optional) argument to defineProperties. So you can also do this:

 Employee.prototype = Object.create(Person.prototype, { work: { value: function() { return this.fullName+" is doing some "+this.position+" stuff"); } } }); 

Of course, if you need to support legacy browsers, you cannot use Object.create. An alternative is to use a clone / extension from libraries like underscore or lodash. Or there is this little dance:

 var subclass = function() { }; subclass.prototype = Person.prototype; Employee.prototype = new subclass; 
+8
source

I assume the goal is to create a new object, not just a link from Person.

 //create a new object with its prototype assigned to Person.prototype Employee.prototype = Object.create(Person.prototype); 
+1
source

All Articles