Skip to content

Instantly share code, notes, and snippets.

@m3g4p0p
Created December 24, 2016 10:12
Show Gist options
  • Save m3g4p0p/701f524997cacb7c89f0b4c12aa3a5aa to your computer and use it in GitHub Desktop.
Save m3g4p0p/701f524997cacb7c89f0b4c12aa3a5aa to your computer and use it in GitHub Desktop.
A universal factory function
const make = function make ({
proto = {},
self = {},
init = function init (obj) {
Object.assign(this, obj)
return this
},
mixins = []
}) {
const mixProto = {}
const mixSelf = {}
mixins.forEach(mixin => {
const current = mixin()
Object.assign(mixProto, Object.getPrototypeOf(current))
Object.assign(mixSelf, current)
})
Object.assign(mixProto, proto)
Object.assign(mixSelf, self)
return function makeInstance (...args) {
const instance = Object.create(mixProto)
Object.assign(instance, mixSelf)
return init.apply(instance, args)
}
}
@m3g4p0p
Copy link
Author

m3g4p0p commented Dec 24, 2016

This is basically a universal factory function for creating and mixing objects with a given prototype. The idea is heavily inspired by Eric Elliott's stampit, but it's much more minimalist in its API and implementation.

Sample usage:

const person = make({
  proto: {
    setName (name) {
      this.name = name
      return this
    }
  }
})

const raptorIncidents = make({
  proto: {
    increment () {
      this.count++
      return this
    }
  },
  init (count = 0) {
    this.count = count
    return this
  }
})

const superhero = make({
  self: {
    powers: []
  },
  proto: {
    addPower (power) {
      this.powers.push(power)
      return this
    },
    log () {
      console.log(`
        ${this.name} has the powers ${this.powers.join(', ')}.
        There have been ${this.count} raptor incidents so far.
      `)
    }
  },
  mixins: [person, raptorIncidents]
})

superhero()
  .setName('Superman')
  .addPower('X-ray vision')
  .addPower('flying')
  .log()

MIT @ m3g4p0p

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment