一、简介
装饰器依赖于
ES5
的Object.defineProperty
方法
1.1 Object.defineProperty
Object.defineProperty()
方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象- 该方法允许精确添加或修改对象的属性。通过赋值来添加的普通属性会创建在属性枚举期间显示的属性(
for...in
或Object.keys
方法), 这些值可以被改变,也可以被删除。这种方法允许这些额外的细节从默认值改变。默认情况下,使用Object.defineProperty()
添加的属性值是不可变的
Object.defineProperty(obj, prop, descriptor) |
obj
:要在其上定义属性的对象。prop
:要定义或修改的属性的名称。descriptor
:将被定义或修改的属性描述符。- 返回值:被传递给函数的对象。
在
ES6
中,由于Symbol
类型 的特殊性,用Symbol
类型 的值来做对象的key
与常规的定义或修改不同,而Object.defineProperty
是定义key
为Symbol
的属性的方法之一
descriptor属性描述符
对象里目前存在的属性描述符有两种主要形式:数据描述符和存取描述符
- 数据描述符是一个具有值的属性,该值可能是可写的,也可能不是可写的。
- 存取描述符是由
getter-setter
函数对描述的属性。
configurable
当且仅当该属性的
configurable
为true
时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为false
enumerable
enumerable
定义了对象的属性是否可以在for...in
循环和Object.keys()
中被枚举。- 当且仅当该属性的
enumerable
为true
时,该属性才能够出现在对象的枚举属性中。默认为false
。
二、Babel
安装编译
npm install --save-dev @babel/core @babel/cli npm install --save-dev @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties |
新建
.babelrc
文件
{ "plugins": [ ["@babel/plugin-proposal-decorators", { "legacy": true }], ["@babel/plugin-proposal-class-properties", {"loose": true}] ] } |
再编译指定的文件
babel decorator.js --out-file decorator-compiled.js |
三、用法
装饰器主要用于
- 装饰类
- 装饰方法或属性
3.1 类的装饰
@testable class MyTestableClass { // ... } function testable(target) { target.isTestable = true; } MyTestableClass.isTestable // true |
上面代码中,
@testable
就是一个装饰器。它修改了MyTestableClass
这 个类的行为,为它加上了静态属性isTestable