JSFiddle - React, Tailwind, and code Playground
JavaScript 1.7
function extend(Class) {
const name = Class.name;
const symbol = Symbol(name);
// callable `this` in Implementation.doSomething
// `this` is an alias for Implementation.for
Class.for = function _for(value) {
return value[symbol];
}
Class.instance = function(constructor, methods) {
constructor.prototype[symbol] = methods;
}
Class.symbol = symbol;
const properties = Object.getOwnPropertyDescriptors(Class.prototype);
Object.keys(properties)
.filter(key => key !== 'constructor')
.forEach(key => {
// bind for so `this()` calls `Class.for`
Class.prototype[key] = Class.prototype[key].bind(Class.for)
});
return Class
}
const Adder = extend(
class Adder {
add(left, right) {
const {
add
} = this(left);
return add(left, right);
}
}
)
const {
add
} = Adder.prototype;
Adder.instance(Number, {
add(left, right) {
return left + right;
}
});
console.log(add(1, 2)); // 3
Adder.instance(String, {
add(left, right) {
return left.concat(right);
}
});
console.log(add("1", "2")); // "12"