DEV Community

Cover image for JavaScript - Prototypal Inheritance
Joseph Lynn
Joseph Lynn

Posted on

JavaScript - Prototypal Inheritance

JavaScript is a prototype-based language that has prototypal inheritance. Which is not the same as classical inheritance. Prototypal inheritance is more flexible than classical inheritance. With classical inheritance, you inherit all of the parent's methods. With prototypal inheritance, you can inherit specific functions by adding them to the .prototype.

I'll give some code examples below and here is the code sandbox to view the code as well.

Reference: class vs prototypal
Reference: inheritance and the prototype chain
Reference: Object prototypes
Reference: Constructor Pattern

Classes are functions

Creating a class in JavaScript is syntax sugar (makes your code more readable). When creating classes, you are creating a function that serves as a constructor (a function called with the new operator). Here is what that looks like:

Reference: new operator

// constructor function
function Person(firstName, lastName, age) {
  this.firstName = firstName;
  this.lastName = lastName;
  this.age = age;
}

// creating an instance method on Person
// this method can be called on any new instance of Person
Person.prototype.getFullName = function () {
  return `${this.firstName} ${this.lastName}`;
};

// creating an instance method on Person
// this method can be called on any new instance of Person
Person.prototype.getAge = function () {
  return this.age;
};

console.log(typeof Person); // => function

// creating an instance of Person
const user = new Person("Joe", "Lynn", 27);
console.log(user.getFullName()); // => 'Joe Lynn'
console.log(user.getAge()); // => 27
Enter fullscreen mode Exit fullscreen mode

Class implementation of above example

// create User class 
class User {
  constructor(firstName, lastName, age) {
    this.firstName = firstName
    this.lastName = lastName
    this.age = age
  }

  // creating a method getFullName()
  getFullName() {
    return `${this.firstName} ${this.lastName}`
  }

  // creating a method getAge()
  getAge() {
    return this.age
  }
}

console.log(typeof User) // => function 

const user2 = new User('Sierra', 'Lynn', 26)
console.log(user2.getFullName()) // => 'Sierra Lynn'
console.log(user2.getAge()) // => 26
Enter fullscreen mode Exit fullscreen mode

What is a prototype?

All JavaScript objects inherit properties and methods from a prototype. A prototype is an object that lets you store properties and methods that we want to be inherited further down the prototype chain.

// Object prototype
{
  constructor: ƒ Object()
  hasOwnProperty: ƒ hasOwnProperty()
  isPrototypeOf: ƒ isPrototypeOf()
  propertyIsEnumerable: ƒ propertyIsEnumerable()
  toLocaleString: ƒ toLocaleString()
  toString: ƒ toString()
  valueOf: ƒ valueOf()
  __defineGetter__: ƒ __defineGetter__()
  __defineSetter__: ƒ __defineSetter__()
  __lookupGetter__: ƒ __lookupGetter__()
  __lookupSetter__: ƒ __lookupSetter__()
  get __proto__: ƒ __proto__()
  set __proto__: ƒ __proto__()
}
Enter fullscreen mode Exit fullscreen mode

What is the prototype chain?

The prototype chain is what makes inheritance possible. Every object in JavaScript inherits the prototype Object. You can walk up the prototype chain until you hit null.

console.log(Object.getPrototypeOf(user)); /* => 
{
  getAge: ƒ ()
  getFullName: ƒ ()
  constructor: ƒ Person(firstName, lastName, age)
  __proto__: Object
}
*/
console.log(Object.getPrototypeOf(Object.getPrototypeOf(user))); /* =>
{
  constructor: ƒ Object()
  hasOwnProperty: ƒ hasOwnProperty()
  isPrototypeOf: ƒ isPrototypeOf()
  propertyIsEnumerable: ƒ propertyIsEnumerable()
  toLocaleString: ƒ toLocaleString()
  toString: ƒ toString()
  valueOf: ƒ valueOf()
  __defineGetter__: ƒ __defineGetter__()
  __defineSetter__: ƒ __defineSetter__()
  __lookupGetter__: ƒ __lookupGetter__()
  __lookupSetter__: ƒ __lookupSetter__()
  get __proto__: ƒ __proto__()
  set __proto__: ƒ __proto__()
}
*/
console.log(
  Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(user)))
); // => null
Enter fullscreen mode Exit fullscreen mode

Thanks for checking out this post. Please leave feedback on what can be improved/corrected. I always want to learn more.

Top comments (0)