JavaScript Object Composition

Inheritance, Mixins, traits, AOP and all that jazz

Mikael Karon <mikael.karon@ef.com>
EF Labs (Shanghai)

JavaScript Object Composition

Inheritance, Mixins, traits, AOP and all that jazz

Mikael Karon

mikaelkaron

Basics

  • Inheritence (classical / multiple / prototypal)
  • Mixins and traits
  • AOP

Basics: inheritance

Inheritance is the fundamental concept of inheriting functionality from other classes. Inheritance systems provide a means for overriding existing functionality.

Multiple inheritance is an extension of inheritance to compose functionality from multiple classes. The original design has largely been superseded by mixins and traits due to the fragility of only being able to compose with hard references to super classes.

Prototypal inheritance uses the prototype chain and instances of objects rather than classes to achieve inheritance.

Basics: mixins and traits

Mixins are an improvement over multiple inheritance, allowing for more flexible composition of components, without relying on shared inheritance chains.

Traits address the issues of composition of mixins when different parts of mixins need to be individually selected, providing a much more robust solution in the face of conflicting methods.

Basics: AOP

Aspects provide fine-grained composition of functionality for individual methods.

Traditional inheritance in JavaScript

JavaScript is a bit confusing for developers experienced in class-based languages (like Java or C++), as it is dynamic and does not provide a class implementation (although the keyword class is a reserved keyword and cannot be used as a variable name).

Traditional inheritance in JavaScript

When it comes to inheritance, JavaScript only has one construct: objects. Each object has an internal link to another object called its prototype. That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype. null, by definition, has no prototype, and acts as the final link in this prototype chain.

Traditional inheritance in JavaScript

While this is often considered to be one of JavaScript's weaknesses, the prototypal inheritance model is in fact more powerful than the classic model. It is, for example, fairly trivial to build a classic model on top of a prototypal model, while the other way around is a far more difficult task.

var Shape = {
  "name": "Shape"
};

Shape.prototype.toString = function () {
  return this.name;
};
var Rectangle = function (width, height) {
  this.width = width;
  this.height = height;
  this.shape = "Rectangle";
};

Rectangle.prototype = new Shape;
Rectangle.prototype.area = function () {
  return this.width * this.height;
};
var Square = function (width) {
  this.width = width;
  this.shape = "Square";
};

Square.prototype = new Rectangle();
Square.prototype.area = function () {
  return this.width * this.width;
};
var myShape = new Square(6);

Mixins and traits

Traits were originally defined as composable units of behavior: reusable groups of methods that can be composed together to form a class. Their purpose is to enable reuse of methods across class hierarchies.

Mixins and traits

Single-inheritance class hierarchies often suffer from methods being duplicated across the hierarchy, because a class cannot inherit methods from two separate sources.

Mixins and traits

The main difference between traits and alternative composition techniques such as multiple inheritance and mixins is that upon trait composition, name conflicts (a.k.a. name clashes) should be explicitly resolved by the composer. This is in contrast to mixins and multiple inheritance, which define various kinds of linearization schemes that impose an implicit precedence on the composed entities, with one entity overriding all of the methods of another entity.

AOP

Aspect Oriented Programming (AOP) is a technique for augmenting the behavior of objects, methods, and functions non-invasively. AOP allows you to add new behaviors and to combine and modify existing behaviors "from the outside".

AOP

AOP is actually a subset of Object Oriented programming. It helps in code re-use where there are cross-cutting concerns that don't fit well in to the single inheritance model. These can be things like logging which you may want to apply to objects throughout your program that don't share a common ancestor that would make sense to add the functionality to.

AOP

The functional part of an aspect is called an advice such as before, after, and around.

The mechanism to add an advice to a method is called a pointcut.

If you've ever done the following, you've done AOP in JavaScrip

var origDoSomething = thing.doSomething;

// Method replacement is a simple form of AOP
thing.doSomething = function () {
  doSomethingElseFirst();

  return origDoSomething.apply(this, arguments);
}

In AOP parlance, We can say that doSomethingElseFirst is a behavior aspect that has been applied to thing.doSomething.

Specifically, doSomethingElseFirst is called "before advice" ... that is, we have advised thing.doSomething that it should doSomethingElseFirst before doing it's original job.

Questions?

JS Object tricks of the trade

By Mikael Karon

JS Object tricks of the trade

  • 806