I found this technique to create a mixin:
let fooMixin = {
foo() {console.log('foo')},
};
class A {
bar() {console.log('bar')}
}
Object.assign(A.prototype, fooMixin);
however I would prefer to use class syntax also for the mixin.
I tried this:
class FooMixinClass {
foo() {console.log('foo')}
}
class B {
bar() {console.log('bar')}
}
Object.assign(B.prototype, FooMixinClass.prototype);
let b = new B();
b.bar();
b.foo();
but get this error:
"bar"
TypeError: b.foo is not a function. (In 'b.foo()', 'b.foo' is undefined)"
I would like to understand why it doesn't work, since inspecting FooMixinClass.prototype at runtime reveals an object almost identical to fooMixin.
Fiddle: https://jsfiddle.net/a5ufjchz/
I would like to understand why it doesn't work, since inspecting
FooMixinClass.prototypeat runtime reveals an object almost identical tofooMixin.
The keyword is almost. Methods on a class are not enumerable and Object.assign() only copies properties that are enumerable and not inherited
A utility-function:
class FooMixinClass {
static foo() {
console.log("foo, but static");
}
foo() {
console.log('foo')
}
}
class B {
bar() {
console.log('bar')
}
}
function mixin(target, source) {
// ignore the Function-properties
const {name,length,prototype,...statics} = Object.getOwnPropertyDescriptors(source);
Object.defineProperties(target, statics);
// console.log("static", statics);
// ignore the constructor
const {constructor,...proto} = Object.getOwnPropertyDescriptors(source.prototype);
Object.defineProperties(target.prototype, proto);
// console.log("proto", proto);
return target;
}
mixin(B, FooMixinClass);
let b = new B();
b.bar();
b.foo();
B.foo();
.as-console-wrapper{top:0;max-height:100%!important}