Книга: Functional Programming in JavaScript
Назад: JavaScript's prototype chain
Дальше: Mixing functional and object-oriented programming in JavaScript

Inheritance in JavaScript and the Object.create() method

Just as there are many ways to create objects in JavaScript, there are also many ways to replicate class-based, classical inheritance. But the one preferred way to do it is with the method.

var Polygon = function(n) {   this.numSides = n; }  var Rectangle = function(w, l) {   this.width = w;   this.length = l; }  // the Rectangle's prototype is redefined with Object.create Rectangle.prototype = Object.create(Polygon.prototype);  // it's important to now restore the constructor attribute // otherwise it stays linked to the Polygon Rectangle.prototype.constructor = Rectangle;  // now we can continue to define the Rectangle class Rectangle.prototype.numSides = 4; Rectangle.prototype.getArea = function() {   return this.width * this.length; }  var Square = function(w) {   this.width = w;   this.length = w; } Square.prototype = Object.create(Rectangle.prototype); Square.prototype.constructor = Square;  var s = new Square(5); console.log( s.getArea() ); // 25

This syntax may seem unusual to many but, with a little practice, it will become familiar. The keyword must be used to gain access to the internal property, , which all objects have. The method declares a new object with a specified object for its prototype to inherit from. In this way, classical inheritance can be achieved in JavaScript.

Note

The method was introduced in ECMAScript 5.1 in 2011, and it was billed as the new and preferred way to create objects. This was just one of many attempts to integrate inheritance into JavaScript. Thankfully, this method works pretty well.

We saw this structure of inheritance when building the classes in , Category Theory. Here are the , , and classes, which inherit from each other just like the preceding example.

var Maybe = function(){};   var None = function(){};  None.prototype = Object.create(Maybe.prototype); None.prototype.constructor = None; None.prototype.toString = function(){return 'None';};  var Just = function(x){this.x = x;}; Just.prototype = Object.create(Maybe.prototype); Just.prototype.constructor = Just; Just.prototype.toString = function(){return "Just "+this.x;};

This shows that class inheritance in JavaScript can be an enabler of functional programming.

A common mistake is to pass a constructor into instead of a object. This problem is compounded by the fact that an error will not be thrown until the subclass tries to use an inherited member function.

Foo.prototype = Object.create(Parent.prototype); // correct Bar.prototype = Object.create(Parent); // incorrect Bar.inheritedMethod(); // Error: function is undefined

The function won't be found if the method has been attached to the class. If the method is attached directly to the instance with in the constructor, then this use of as an argument of could be correct.

Назад: JavaScript's prototype chain
Дальше: Mixing functional and object-oriented programming in JavaScript

bsn
thank
Vesa Karvonen
I hope you don't mind, but I’d like to point you and your readers to my high-performance optics library for JavaScript that is in production use in multiple projects, has comprehensive support for partial optics and interactive documentation: https://calmm-js.github.io/partial.lenses/ (this takes a moment to load — be patient!)