liveBook · Manning

Mixin

As explained in The Joy of JavaScript

A composition approach that combines reusable behavior into objects by mixing in properties or methods from multiple sources.

A mixin is a small, reusable piece of object behavior or data. Instead of relying on one prototype chain to supply an object’s API, you can copy properties from several independent objects into a target. Keep each mixin narrowly focused and self-sustaining, even if it looks incomplete on its own. section 3.4 section 3.0

Use `Object.assign(target, ...mixins)` to assemble an object, or spread mixin properties into an object literal. This is concatenative extension: the resulting object has its own assigned properties rather than inheriting those properties through links. A mixin can also extend a class prototype or one particular instance. section 3.4 section 3.5

const Sandwich = (size = '6', unit = 'in') => 
  Object.assign({
   size, unit
 }, 
 HasBread,
 HasToppings,
 HasTomatoes, 
 HasMeat
);

const footLong = Sandwich(1, 'ft');
footLong.tomatoe; // 'Cherry'

The sandwich factory joins small property sets with Object.assign, then reads a property from the assembled object. section 3.4

Copying trades the memory efficiency of shared prototype properties for independently assembled objects and less exposure to downstream changes through prototype links. When sources define the same property, Object.assign favors the last source. Assignment is not identical to definition, however: assigning an existing key can invoke a target setter. section 1.2 section 3.4.2 section 3.3.2

const TerrestrialAnimal = {   
  walk() {
     ...
  },
  breathe() {
    return 'Using my lungs to breathe';
  }
};

const AquaticAnimal = {
  swim() {
     ...
  },
  breathe() {
    return 'Using my gills to breathe';
  }
};

const Amphibian = name => Object.assign(
  { 
    name 
  }, 
  AquaticAnimal, 
  TerrestrialAnimal
);

const frog = Amphibian('Frog');

frog.walk();

frog.swim();

Two behavior objects both define `breathe`; their order in Object.assign determines which method the assembled amphibian uses. section 3.4.2

A configurable mixin can be a function returning methods: `HasHash(['sender', 'recipient', 'funds'])` supplies `calculateHash()` for a suitable target. The same hashing and validation behaviors can be attached to different domain objects. Mixins can also supply interfaces such as a functor’s `map` or a monad’s `flatMap`. Watch for methods that silently depend on the target’s `this` and property names; extracting functions with explicit inputs makes those dependencies easier to see. section 3.4.1 section 3.5 section 5.4.1 section 5.4.2

How The Joy of JavaScript covers it

How deep it goes
Works through assignment, reuse, and collision order, but leaves mixins broadly treated and cryptographic method internals aside.
Examples
Uses sandwich parts, conflicting amphibian behaviors, blockchain domain objects, and functor and monad interfaces.
What it assumes
Assumes familiarity with JavaScript objects and prototype or class models while demonstrating mixin assembly through concrete object literals.
What you can do after
Apply it via Object.assign to combine focused behaviors on objects, class prototypes, or individual instances.
How it connects
Connects object composition to prototype chains, multiple inheritance, behavior delegation, and pure functions.

Also explained in

Compare how 4 books explain mixin →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Joy of JavaScript. The section links point to the parts of the book it draws on.