got*_*itz 10 javascript traits composition mixins ecmascript-6
根据各种来源(2ality,esdiscuss),应该能够将mixins添加到类中:
编辑发现类方法不可枚举,因此无法工作.编辑了下面的代码,但仍然没有快乐
class CartoonCharacter {
constructor(author) {
this.author = author;
}
drawnBy() {
console.log("drawn by", this.author);
}
}
// THIS CANNOT WORK
// class methods are not enumerable
// class Human {
// haveFun() {
// console.log("drinking beer");
// }
// }
let Human = Object.create({}, {
haveFun: {
enumerable: true,
value: function () {
console.log("drinking beer");
}
}
});
class Simpson extends Object.assign(CartoonCharacter, Human) {
constructor(author) {
super(author);
}
}
let homer = new Simpson("Matt Groening");
homer.drawnBy(); // expected: drawn by Matt Groening
homer.haveFun(); // expected: drinking beer
Run Code Online (Sandbox Code Playgroud)
我得到了"由Matt Groening绘制"但不是"喝啤酒"我得到了一个错误
-> Uncaught TypeError: E.haveFun is not a function
Run Code Online (Sandbox Code Playgroud)
小智 16
还有另一种在Javascript中实现mixins的方法:使用子类工厂.
子类工厂是一个除了基类并返回此基类的扩展子类的函数:
const mixin = base => class extends base {
/* properties to mix in */
}
Run Code Online (Sandbox Code Playgroud)
子类工厂可能有两个原因:
classes可以定义为表达式,是Javascript中的第一类*extends 子句可以包含任意表达式让我们应用这种模式:
// superclass
class CartoonCharacter {
constructor(author) { this.author = author }
drawnBy() { return "drawn by " + this.author }
}
// mixin 1
const Human = base => class extends base {
haveFun() { return "drinking beer" }
}
// mixin 2
const Simpson = base => class extends base {}
// composed subclass
const Homer = Simpson(Human(CartoonCharacter));
// create an instance
const homer = new Homer("Matt Groening")
console.log(homer.drawnBy());
console.log(homer.haveFun());Run Code Online (Sandbox Code Playgroud)
sublcass工厂的mixins有什么优势?
Human/ Simpson)和subclasses(Homer)都可以super照常使用国家让事情变得艰难.你应该尽可能避免国家.但是,有时你的mixin需要它自己的状态,它通过构造函数传递:
class CartoonCharacter {
constructor(author) { this.author = author }
drawnBy() { return "drawn by " + this.author }
}
const Human = base => class extends base {
haveFun() { return "drinking beer" }
}
const Simpson = base => class extends base {
constructor(arg, ...superArgs) {
super(...superArgs);
this.name = arg;
}
sayHey() { return "Hey, I am " + this.name }
}
const Homer = Simpson(Human(CartoonCharacter));
const homer = new Homer("Homer Simpson", "Matt Groening")
console.log(homer.drawnBy());
console.log(homer.haveFun());
console.log(homer.sayHey());Run Code Online (Sandbox Code Playgroud)
*术语第一类函数意味着函数可以作为参数传递或返回值,如普通数据
Aad*_*hah 14
你的mixins有两个问题:
Object.assign仅复制对象的可枚举属性.但是,类的方法和属性是不可枚举的.这是使用mixins扩展类的方法:
class CartoonCharacter {
constructor(author) {
this.author = author;
}
drawnBy() {
console.log("drawn by", this.author);
}
}
class Human {
haveFun() {
console.log("drinking beer");
}
}
mixin(CartoonCharacter, Human);
class Simpson extends CartoonCharacter {
constructor(author) {
super(author);
}
}
let homer = new Simpson("Matt Groening");
homer.drawnBy(); // expected: drawn by Matt Groening
homer.haveFun(); // expected: drinking beer
function mixin(target, source) {
target = target.prototype; source = source.prototype;
Object.getOwnPropertyNames(source).forEach(function (name) {
if (name !== "constructor") Object.defineProperty(target, name,
Object.getOwnPropertyDescriptor(source, name));
});
}
Run Code Online (Sandbox Code Playgroud)
它在Babel:demo中按预期工作.
| 归档时间: |
|
| 查看次数: |
6405 次 |
| 最近记录: |