注:Decorator提案经过大幅修改,目前还没有定案
什么是装饰器
- 装饰器在很多语言中都有,是一种和类(class)相关语法,用来
注释或修改类和类方法。ES7引入,目前还没有定案 - 装饰器是一种
函数,写成@ + 函数名 - 大部分时候当作高阶函数使用
作用范围
- 类
- 类的方法
类的装饰
@testable
class MyTestableClass {
// ...
}
function testable(target) {
target.isTestable = true;
}
MyTestableClass.isTestable // true
从上面例子可以看出
testable函数就是一个装饰器函数,该函数接受一个参数target,就是所要装饰的目标类- 装饰器执行的写法:
@testable
修改装饰器行为
装饰器自身只能接收一个参数target,如果觉得这样不够。可以在装饰器外面再封装一层函数。利用闭包
funtion testable(isTestable) {
return function(target) {
target.isTestable = isTestable;
}
}
@testable(true)
class A {}
A.isTestable // true
@testable(false)
class B {}
B.isTestable // false
修改状态时机
装饰器对类的行为修改,是在代码编译时发生的,而不是运行时
使用场景
React和Redux库结合使用时,常常需要以下方法
class Com extends React.Component {}
connect(mapStateToPros, mapDispatchToProps)(Com)
可以利用装饰器写成
@connect(mapStateToProps, mapDispatchToProps)
class Com extends React.Component {}
方法的装饰器
class Person {
@readonly
name() { return this.first }
}
/**
装饰器函数
target: 类的原型对象,这个例子就是Person.prototype
name: 要装饰的属性名
descriptor:该属性的描述对象
*/
function readonly(target, name, descriptor) {
// descriptor对象原来的值如下
// {
// value: specifiedFunction,
// enumerable: false,
// configurable: true,
// writable: true
// };
descriptor.writable = false;
return descriptor;
}
readonly(Person.prototype, 'name', descriptor);
// 类似于
Object.defineProperty(Person.prototype, 'name', descriptor);
为什么不能用于函数
因为存在函数提升
core-decorators.js
core-decorators:一个第三方库,提供了一些装饰器