Understanding JavaScript prototypes

JavaScript is a prototype-based language. What it means is that JavaScript objects have a prototype and inherit properties and methods from their prototype. It can be confusing to anyone who is more familiar with a class-based language such as Java. The way of inheritance in JavaScript is different. This post will be helpful for you to have a basic understanding of JavaScript prototypes.

JavaScript Prototype

// ExampleOne.js
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
};
var me = new Person('Jace', 'Park');
me.prototype.introduce = function() {
  console.log('I am ' + this.firstName + ' ' + this.lastName + '.');
};
me.introduce();

Can you determine the result of this code? The above code is, of course, wrong. There is a syntax error saying that Uncaught TypeError: Cannot set property ‘introduce’ of undefined.

JavaScript prototype mentioned in references can be either a prototype object or prototype link based on context. JavaScript beginners get confused between the two types of prototype. While a prototype property of JavaScript objects is a prototype object, a __proto__ property is a prototype link. When people study JavaScript prototypes, they think a prototype property is a JavaScript prototype. But, It is not. If you did not know the answer to the first example, you could not differentiate two types of prototypes.

Before moving forward, we need to see what “console.log(me)” looks like.
me
The above code throws an error because a “me” variable does have a __proto__ property instead of a prototype property.

What is __proto__?

__proto__: It is a link to the prototype of an object. Even though it was never included in the ECMAScript language spec, it is supported by modern web browsers. The use of __proto__ is deprecated in favor of Object.getPrototypeOf().

To resolve the syntax error of the first example, we can call either “Person.prototype” or “Object.getPrototypeOf(me)” to add the “introduce” method in the following code.

// ExampleTwo.js
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
};
var me = new Person('Jace', 'Park');
Person.prototype.introduce = function() {
  console.log('I am ' + this.firstName + ' ' + this.lastName + '.');
};
/* either this way
Object.getPrototypeOf(me).introduce = function() {
    console.log('I am ' + this.firstName + ' ' + this.lastName + '.');
};*/

Then, we can see the“introduce” method in the prototype of Person.
me.introduce.png

What exactly are constructor and prototype?

constructor: It is one of the members in a prototype object creating the instance object. For example, a function String(), function Object(), and function Function() are constructors for creating each String object, Object object and function() object.

prototype: It means a prototype property, not a prototype link. Only the constructor can have this. A group of properties passes to an object created through prototype itself.

How to extend JavaScript objects?

ES6 introduces a class-based inheritance, but an ES5 standard would be used in this article because the ES5 style shows how prototype and constructor explicitly make use of extending a class.

// ExampleThree.js
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
};
Person.prototype.introduce = function() {
  console.log('I am ' + this.firstName + ' ' + this.lastName + '.');
};

function Employee(firstName, lastName, companyName) {
    Person.call(this, firstName, lastName);
    this.companyName = companyName;
};
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.introduce = function() {
  Person.prototype.introduce.call(this);
  console.log('I am working for ' + this.companyName + '.');
}

Employee.prototype.constructor == Person;
// true
var me = new Employee('Jace', 'Park', 'Company A');
me.introduce();
// I am Jace Park.
// I am working for Company A.

prototype

This shows what an Employee instance looks like. Employee.prototype is Person. And, Person.prototype is Object whose prototype is Object, too. What does it mean? JavaScript has a prototype chain and the below image shows it.

JavaScript prototypes.jpg

At the end of a prototype chain, there is an Object whose prototype points to null. The second to last item is Object type but its prototype is Object, too. Extending JavaScript objects is different from Java because of this prototype chain.

In Conclusion

This post has clarified two types of prototypes with the definition of __proto__, constructor, and prototype. Then, it illustrates the way of extending JavaScript objects from code examples and prototype chain images. If it is still confusing to you, check the following references:

Leave a comment