1
0
mirror of https://github.com/ruanyf/es6tutorial.git synced 2025-05-24 18:32:22 +00:00

edit decorator/mixin

This commit is contained in:
ruanyf 2016-01-19 18:37:18 +08:00
parent 1fe658fd8b
commit 1248f27af2
2 changed files with 82 additions and 1 deletions

View File

@ -423,7 +423,7 @@ let obj = new MyClass();
obj.foo() // 'foo'
```
上面代码之中对象Foo有一个foo方法通过`Object.assign`方法可以将foo方法“混入”MyClass类导致MyClass的实例obj对象都具有foo方法。这就是“混入”模式的一个简单实现。
上面代码之中,对象`Foo`有一个`foo`方法,通过`Object.assign`方法,可以将`foo`方法“混入”`MyClass`类,导致`MyClass`的实例`obj`对象都具有`foo`方法。这就是“混入”模式的一个简单实现。
下面,我们部署一个通用脚本`mixins.js`将mixin写成一个修饰器。
@ -453,6 +453,86 @@ obj.foo() // "foo"
通过mixins这个修饰器实现了在MyClass类上面“混入”Foo对象的`foo`方法。
不过,上面的方法会改写`MyClass`类的`prototype`对象如果不喜欢这一点也可以通过类的继承实现mixin。
```javascript
class MyClass extends MyBaseClass {
/* ... */
}
```
上面代码中,`MyClass`继承了`MyBaseClass`。如果我们想在`MyClass`里面“混入”一个`foo`方法,一个办法是在`MyClass``MyBaseClass`之间插入一个混入类,这个类具有`foo`方法,并且继承了`MyBaseClass`的所有方法,然后`MyClass`再继承这个类。
```javascript
let MyMixin = (superclass) => class extends superclass {
foo() {
console.log('foo from MyMixin');
}
};
```
上面代码中,`MyMixin`是一个混入类生成器,接受`superclass`作为参数,然后返回一个继承`superclass`的子类,该子类包含一个`foo`方法。
接着,目标类再去继承这个混入类,就达到了“混入”`foo`方法的目的。
```javascript
class MyClass extends MyMixin(MyBaseClass) {
/* ... */
}
let c = new MyClass();
c.foo(); // "foo from MyMixin"
```
如果需要“混入”多个方法,就生成多个混入类。
```javascript
class MyClass extends Mixin1(Mixin2(MyBaseClass)) {
/* ... */
}
```
这种写法的一个好处,是可以调用`super`,因此可以避免在“混入”过程中覆盖父类的同名方法。
```javascript
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();
}
}
```
上面代码中,每一次`混入`发生时,都调用了父类的`super.foo`方法,导致父类的同名方法没有被覆盖,行为被保留了下来。
```javascript
new C().foo()
// foo from C
// foo from Mixin1
// foo from Mixin2
// foo from S
```
## Trait
Trait也是一种修饰器效果与Mixin类似但是提供更多功能比如防止同名方法的冲突、排除混入某些方法、为混入的方法起别名等等。

View File

@ -173,6 +173,7 @@
## Decorator
- Maximiliano Fierro, [Declarative vs Imperative](http://elmasse.github.io/js/decorators-bindings-es7.html): Decorators和Mixin介绍
- Justin Fagnani, ["Real" Mixins with JavaScript Classes](http://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/): 使用类的继承实现Mixin
- Addy Osmani, [Exploring ES2016 Decorators](https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841): Decorator的深入介绍
- Sebastian McKenzie, [Allow decorators for functions as well](https://github.com/wycats/javascript-decorators/issues/4): 为什么修饰器不能用于函数
- Maximiliano Fierro, [Traits with ES7 Decorators](http://cocktailjs.github.io/blog/traits-with-es7-decorators.html): Trait的用法介绍