JavaScript 的 Mixin 问题
JavaScript 从 ES6 开始支持 class 了, 如何在现在的 class 上实现 mixin 呢? 很多人推荐这种搞法
Object.assign(MyClass.prototype, MyMixin);
这个做法很丑, 不能令人满意。
我找到了一个更有趣的做法,和 dart 比较接近:
"Real" Mixins with JavaScript Classes
他最终的做法是这样的:
class MyClass extends mix(MyBaseClass).with(Mixin1, Mixin2) {
/* ... */
}
Mixin1 Mixin2 的定义是
let Mixin1 = (superclass) => class extends superclass {
foo() {
console.log('foo from Mixin1');
if (super.foo) super.foo();
}
};
let Mixin2 = (superclass) => class extends superclass {
foo() {
console.log('foo from Mixin2');
if (super.foo) super.foo();
}
};
class S {
foo() {
console.log('foo from S');
}
}
class C extends Mixin1(Mixin2(S)) {
foo() {
console.log('foo from C');
super.foo();
}
}
new C().foo();
要点是 class 在 js 里性质和 function 相似, 都具有闭包性, 因此可以通过函数构造出来.
说到这个前两天根据我们需要什么样的 ORM 框架 - Inshua - 博客园的思考, 正好试验了这个特征:
function nvarchar(n){
return class{
constructor(){
this.size = n;
}
}
}
var t = nvarchar(200);
var c = new t();
看起来效果还可以, 但是 JavaScript 变量不支持类型, 所以目前还无法发挥它的实力.
Flow 和 TypeScript 能给 JavaScript 添加类型, 但都没有很好的往这个方向走. Dart 就不用考虑了, class 不能定义在 function 里, 也不能作为值使用. 可能裁剪的 TypeScript 是比较适当的选择, 但是我不想使用这种生成 js 的套盒语言.