Skip to content

Instantly share code, notes, and snippets.

@a-x-
Forked from march213/mixin.js
Last active October 25, 2017 08:11
Show Gist options
  • Save a-x-/ef04f11e508aa5357901cb8aee3f9354 to your computer and use it in GitHub Desktop.
Save a-x-/ef04f11e508aa5357901cb8aee3f9354 to your computer and use it in GitHub Desktop.
(() => {
// todo: mixins collection
class Foo {
foo() {
console.log(this.bar());
}
bar() { console.log('bar'); return 42 }
}
const SomeMixin = {
foo: function () { console.log('mixin'); this.__super(); }
}
// @param {Class} Target - класс, методы которого заменяются на соответствующие из миксина
// @param {Object} mixin - хеш с миксуемыми методами
// Методы миксина могут вызывать через this.__super() прежние методы класса
function mix(Target, mixin) {
// Обёртка над Target, чтобы не модифицировать переданных класс
class Target_ extends Target {}
Object.keys(mixin).forEach((prop) => {
if (typeof Target.prototype[prop] === 'function') {
// Метод класса сохраняется для __super
const oldMethod = Target.prototype[prop];
// Новый метод оборачивает вызов одноимённого метода миксина
// и заменяет соответствующий метод Target
Target_.prototype[prop] = function (...args) {
// __super на время вызова метода устанавливается в соответствие прежнему методу класс
const prevSuper = this.__super;
this.__super = oldMethod;
const res = mixin[prop].apply(this, args);
// А затем восстанавливается
this.__super = prevSuper;
return res;
};
} else {
Target_.prototype[prop] = mixin[prop];
}
});
// copy statics
return Target_;
}
const Foo_ = mix(Foo, SomeMixin);
return new Foo_().foo();
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment