42

The JavaScript Prototypal Inheritance Pattern

 5 years ago
source link: https://www.tuicool.com/articles/hit/NvA3iq6
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

JavaScript does not contain classes and but it’s an still strongly object oriented language. The object-to-object relation in JavaScript is implemented with the prototype and the resulting prototypal pattern is very unique to JavaScript.

Before the ES6 class syntax , the topic of inheritance has been mostly confusing for developers who came from other languages. This is because JS, in my humble opinion, is a truly object-driven language.

This makes it quite difficult to grasp the idea of inheritance in JavaScript objects, like: how do you create new objects with same properties without classes? . This article is an attempt to explain it and how this property applies to a specific object oriented pattern in JavaScript.

As we’ve previously seen, objects in JavaScript have the ability to inherit directly from other objects through a shared property called prototype and how the prototype is used for implementing inheritance in JavaScript objects.

Now, this inheritance is not the traditional inheritance that we’re used to in class-based languages but instead it’s something comparable to object delegation . Roughly meaning, if a particular property is not found in an object, then I’d check its prototype for the definition of the property in question.

Here is a quick snippet to show what I’m talking about:

let Alligator = function(color) {
  this.color = color;
}

Alligator.prototype.introduce = function() {
 console.log('I am ' + this.color);
}

let Croc = function(color) {
  Alligator.call(this, color);
}

Croc.prototype = Object.create(Alligator.prototype)

let alligatorObj = new Alligator('green');
let crocObj = new Croc('yellow');

alligatorObj.introduce(); // I am green
crocObj.introduce(); // I am yellow

So what happened above is this - the instance of croc has a copy of a prototype that links to the prototype of Croc which in turn links to the prototype of Alligator . The Alligator prototype is able to provide us with the definition for introduce() .

This is what I mean by delegation , searching for the target behavior inside objects (i.e the prototype ). Also, JavaScript prototypes can link to multiple prototypes, so in that way we can have multiple inheritance as well, but that’s often a bad idea in practice.

The snippet is an example of how object-to-object code looks like. It’s very primitive but facilitates direct transfer of properties and methods between objects. This is built into the design of JavaScript; the class syntactic sugar or the constructor are simply wrappers on top this to make it feel like classical OOP.

Most of the time, prototypal pattern is very simple and easy to implement. Why? Because of our classical understanding of objects and classes, we expect a constructor function to create an instance for us. In JavaScript any function can be a constructor, like this :

function Alligator(color) {
 This.color = color;
}

Let alligator = new Alligator('purple');

All we have to do is prefix the new keyword to the function invocation and we have an object. All that the new keyword does is that it invokes the Alligator() function as a constructor by binding this (which is the new context) to the function call. It feels like we are simply going out of our way to make classical object pattern work in JavaScript. Compared to this, the prototypal pattern feels intuitive. Note also that by convention functions that are meant to be used as a constructor for new objects should start with a capital letter, otherwise it could get quite confusing to know where the new keyword should be used.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK