Last active
December 4, 2019 22:46
-
-
Save WesleyDRobinson/816924d7c29f2d0acabb5ce2ed8fe93f to your computer and use it in GitHub Desktop.
composing instances > mixed-in classes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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