mirror of
https://github.com/ruanyf/es6tutorial.git
synced 2025-05-24 10:22:23 +00:00
edit decorator/mixin
This commit is contained in:
parent
1fe658fd8b
commit
1248f27af2
@ -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类似,但是提供更多功能,比如防止同名方法的冲突、排除混入某些方法、为混入的方法起别名等等。
|
||||
|
@ -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的用法介绍
|
||||
|
Loading…
x
Reference in New Issue
Block a user