/** * Supporting JS module to define and use plain * JavaScript mixins. */ /** * The mix function can be used to extend a class with mixin * objects that provide common behavior. * * In case that the class define a function that exists in the * mixin, the class implementation will take precedence over * the function in the mixin. * * Typical usage: * * const canFlyMixin = { * fly() { * ... * } * } * * const canSwimMixin = { * swim() { * ... * } * } * * class Animal { * constructor(name) { * this.name = name; * } * } * * class Duck extends mix(canFlyMixin, canSwimMixin, Animal) {} */ export function mix(...chain) { const [baseClass, ...mixins] = chain.reverse() class Mixed extends baseClass {} for (const mixin of mixins) { for (const [key, value] of Object.entries(mixin)) { /* eslint no-prototype-builtins: "off" */ if (!Mixed.prototype.hasOwnProperty(key)) { Mixed.prototype[key] = value } } } return Mixed }