ES6学习:装饰器学习笔记
装饰器
安装
npm i babel-plugin-transform-decorators-legacy babel-register --D
transform-decorators-legacy 用于支持装饰器的写法 babel-register 用于接入 node api 能以命令行方式运行
运行方法
- 命令行操作
babel --plugins transform-decorators-legacy input.js>input.es5.js
- require hook
js
require('babel-register')({
plugins: ['transform-decorators-legacy']
})
require('./input.js') // 这个文件下有装饰器语法装饰器用法
js
class Boy {
@sayName
say(){}
}
const monkey = new Monkey();
monkey.say();
function sayName(target, key, descriptor){
descriptor.value = () => {
console.log("我是XXX");
}
console.log("报上名来")
return descriptor;
}
//报上名来
//我是XXX
// 装饰器函数yourName 参数固定为这个三个 参照object原型函数
// Object.defineProperty其实可以想简单点,我是这样理解的。我们通过 const monkey = new Monkey() monkey实例上有了 类上的sayName方法,现在我们执行sayName方法,在这之前会先执行装饰器函数 sayYourName。
monkey.sayName() 应该什么都没对吧,但实际上,sayYourName方法被调用了。同时 装饰器函数可以传递三个参数,分别是 target, key, descriptor。
- target 就是修饰器所在的类, 上面是 Monkey {}
- key 为修饰器方法的名称 sayYourName
- descriptor 是一个对象,可与 Object.defineProperty 相比较,我们来打印一下
js
function sayYourName(target, key, descriptor) {
for (k of Object.keys(descriptor)) {
console.log(k)
}
}- value 也就是其自身的返回值,这也就是我们能通过装饰器扩展对象属性方法的秘密了
- writable 设置可写性
- enumerable 设置可枚举
- configurable 设置可配置
扩展类
js
class Boy {
@language('中文')
say() {
console.log('hello')
console.log('I can speak ' + this.language)
}
}
const fri = new Boy()
fri.say()
function language(lang) {
return function(target, key, descriptor) {
target.language = lang
return descriptor
}
}Boy构造函数中并没有 language 属性,但最终我们还是能得到该值,这就是装饰器的功劳了。 通过上述,我们知道了,在执行 fri.say() 时先执行了装饰函数 language,'中文'作为参数传递,target 指向 Boy 构造函数,所以target.language = lang 就是在给 Boy 增加属性
