Reputation: 55729
If I understand correctly mixins can have state, whereas traits, as a subset of mixins, cannot.
How can we implement stateful mixins in JavaScript.
I can think of two ways - partial application and via closure. Are there any others?
For example:
var foo, bar, bam, closedOver = 'c';
foo = { a: function() { console.log('a'); } };
bar = { b: (function(x) { console.log('b: ' + x); }.bind(this, '1')) };
bam = { c: function() { console.log(closedOver); } };
function mix(original, ...objs) {
objs.forEach(o => {
Object.keys(o).forEach(k => {
original[k] = o[k];
});
});
}
mix(foo, bar, bam);
console.log(foo.a); // a
console.log(foo.b); // b: 1
console.log(foo.c); // c
Edit: I just realised that of course functions are objects in JavaScript and can have arbitrary state associated with them. I would like to know the answer to an ancillary question - do mixins have to be functions?
Upvotes: 0
Views: 235
Reputation: 13376
How can we implement stateful mixins in JavaScript.
.
Edit: I just realised that of course functions are objects in JavaScript and can have arbitrary state associated with them. I would like to know the answer to an ancillary question - do mixins have to be functions?
Not necessarily - mixin approaches based on plain objects and [libraryName].extends
are much more widespread in production than function based ones.
But especially with state, my strong opinion is that a function based approach is most natural for this languages design since it does provide delegation for free and at the same time also enables injecting of and passing around state.
I do recommend reading 2 papers, both are covering a library agnostic pure function based approach for Mixins / Traits / Talents.
Note: the 2nd link does promote an article of mine.
Upvotes: 0
Reputation: 664538
Per-instance state must be created in the constructor. Therefore, mixins that need state have some kind of init
method that can be called from a class constructor.
Upvotes: 2