Mixins in Javascript

Inheritance

Classical

Object-Oriented

Programming

Real world entity

Variable holding object

Class of the object

Santa

santaClaus

Man

Human

Superclass of class Man

Levels of abstraction

class Human {
    // ...
}

class Man extends Human {
    // ...
}

Man santaClaus = new Man();

Implementation

Prototypal

Object-Oriented

Programming

Real world entity

Variable holding object

Prototype of object santaClaus

Santa

santaClaus

man

human

Prototype of object Man

Levels of abstraction

const human = {};
human.sayHello = function() {
  console.log('hello');
};
const man = Object.create(humanA);
const santaClaus = Object.create(manA);
santaClaus.sayHello();

Implementation

const Human = function() {};
Human.prototype.sayHello = function() {
  console.log('hello');
};
const Man = function() {
  Human.call(this);
};
Man.prototype = Object.create(Human.prototype);
Man.prototype.constructor = Man;
const santaClaus = new Man();
santaClaus.sayHello();
class Human {
  sayHello() {
    console.log('hello');
  }
}
class Man extends Human {}
const santaClaus = new Man();
santaClaus.sayHello();

Implementation in ES6

What about the mixins ?

Example in theory

function mixin(source, target) {  
  for (var prop in source) {
    if (source.hasOwnProperty(prop)) {
      target[prop] = source[prop];
    }
  }
}

mixin(MixinSuperpower, Man.prototype);

Simple implementation

In the real world ?

Sharelock - FileUpload

BDR

beneficial-owners

upload (file storage + verification)

create/update

create/update

Sharelock - Encryption


module.exports = (Model, options) ->

  getCtxInstance = (ctx) ->
    return ctx.data if ctx.data
    return ctx.instance if ctx.instance

  Model.observe 'persist', (ctx, next) ->
    Model.app.models.CipherKey.isDefined (err , isDefined) ->
      return next 'Invalid encryption key' unless isDefined
      if ctx.data
        for key, value of options
          try
            ctx.data[key] = crypto.AES.encrypt(ctx.data[key], Model.app.models.CipherKey.value).toString()
          catch err
            next err
      next()

  Model.observe 'loaded', (ctx, next) ->
    Model.app.models.CipherKey.isDefined (err , isDefined) ->
      return next 'Invalid encryption key' unless isDefined
      instance = getCtxInstance ctx
      if instance
        for key, value of options
          try
            bytes = crypto.AES.decrypt instance[key], Model.app.models.CipherKey.value
            instance[key] = bytes.toString crypto.enc.Utf8
          catch err
            next err
      next()

Questions

deck

By Jérémie Drouet

deck

  • 915