Skip to content

Instantly share code, notes, and snippets.

@WesleyDRobinson
Last active December 4, 2019 22:46
Show Gist options
  • Save WesleyDRobinson/816924d7c29f2d0acabb5ce2ed8fe93f to your computer and use it in GitHub Desktop.
Save WesleyDRobinson/816924d7c29f2d0acabb5ce2ed8fe93f to your computer and use it in GitHub Desktop.
composing instances > mixed-in classes
// Base Class
class ComicBookCharacter {
constructor(first, last) {
this.firstName = first
this.lastName = last
}
realName() {
return this.firstName + ' ' + this.lastName
}
}
// "mixin" utility object
const UtilityBelt = {
// optionally semantic `init` method, bootstraps UNIQUE target instances with SHARED methods
giveBeltTo(target) {
// using [] ensures a new array for each instance
Object.defineProperty(target, '_utilityBelt', { value: [] })
// Optional instance.method() ergonomics, if we must.
// "partial invocation" binds Class methods to the target
Object.defineProperty(target, 'getUtilities', {
value: function() {
return UtilityBelt.getUtilities(target)
}
})
Object.defineProperty(target, 'addToBelt', {
value: function(tool) {
return UtilityBelt.addToBelt(target, tool)
}
})
},
// Class defined methods, can be used freely as a library,
// May optionally be bound to initialized instances
addToBelt(target, tool) {
target._utilityBelt.push(tool)
return {
target,
tool
}
},
getUtilities(target) {
return target._utilityBelt.slice(0)
}
}
// examples, as instance methods... implicit interface, loathesome, confusing:
const batman = new ComicBookCharacter('Bruce', 'Wayne')
UtilityBelt.giveBeltTo(batman)
batman.addToBelt('batarang')
batman.addToBelt('batmobile-key')
// example, as methods library... exposed interface, charming, standard JS:
const catwoman = new ComicBookCharacter('Selina', 'Kyle')
UtilityBelt.giveBeltTo(catwoman)
UtilityBelt.addToBelt(catwoman, 'extra-claws')
UtilityBelt.addToBelt(catwoman, 'Cat-illac-key')
// but we can use this same pattern either way for the same result:
console.log(batman.realName(), batman.getUtilities())
console.log(catwoman.realName(), UtilityBelt.getUtilities(catwoman))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment