Decorator装饰器
来源:互联网 发布:日式衬衫知乎 编辑:程序博客网 时间:2024/06/03 20:31
Decorator 修饰器
说明
由 ES2017 引入了这个功能,他是一个函数用来修改类的行为,解决了不同类之间共享方法的问题
修饰器对类的行为的改变是在代码编译时发生的,而不是在运行时,本质就是编译时执行的函数
由于存在变量提升,使得修饰器不能用于函数(包括构造函数),类不会提升所以不会有这个问题
基本使用
@decorator class Test { constructor(name) { this.name = name; } } function decorator (target) { // target 就是需要被修饰的类 target.prototype.getName = function () { console.log(this.name); } } const test = new Test('xiaobai'); test.getName(); // xiaobai
修饰器通过封装后接受其他参数
function addMethod(methods) { return function (target) { Object.assign(target.prototype, methods); } } const methods = { change: function () {console.log('change')}, add: function () {}, delete: function () {}, get: function () {} } @addMethod(methods) class Test {} const test = new Test(); test.change(); // change
修饰器可以修饰类中的方法
作用在方法上的 decorator 接受的第一个参数是类的 prototype;作用到类上的 decorator 第一个参数表示类本身
Decorators 的本质是利用了 ES5 的 Object.defineProperty 属性,所以它的三个参数:target name descriptor 跟 Object.defineProperty 的参数是一致的
Object.defineProperty 的参数详解看这里
- target:需要修饰的类的原型 prototype
- name: 需要修饰的类的属性名或者方法名
- descriptor:被修改的属性的描述符
- configurable:true | false 表示对象的属性是否可以被删除,以及除 writable 特性外的其他特性是否可以被修改
- enumerable:true | false 定义被修改的属性是否可以是可以枚举的
- value:此属性对应的值(数值、对象、函数等)
- writable:true | false 是否可以重写此属性
- initializer:如果修饰器修饰的是一个属性不是方法,则会有这个属性出现代替 value
function log (target, name, descriptor) { // 保留旧的方法 const tempFn = descriptor.value; // 重新定义方法 descriptor.value = function () { console.log(`this is ${name} arguments: `, arguments); // 借用旧的方法 return tempFn.apply(this, arguments); } return descriptor; } class Test { constructor() { this.list = [] } @log add (...items) { this.list.push(...items); } } var test = new Test(); test.add(12, 33, 222); // 修饰器打印的日志 // this is add arguments: (3) [12, 33, 222, callee: (...), Symbol(Symbol.iterator): function] console.log(test); // {list: [12, 33, 222]}
修饰器修饰属性
function change(target, name, descriptor) { const tempVal = descriptor.initializer(); console.log(descriptor.initializer); /* initializer 函数类型 function initializer() { return 'def value'; } */ descriptor.initializer = function () { return 'change ' + tempVal; } return descriptor; } class Test { @change def = 'def value' } const test = new Test(); console.log(test.def) // change def value
修饰器可以叠加使用
function log (order) { return function (target, name, descriptor) { const tempFn = descriptor.value; descriptor.value = function () { console.log('decorator ' + order); return tempFn.apply(this, arguments); } return descriptor; } } class Test { constructor() { this.list = [] } @log('top') @log('bottom') add (...items) { this.list.push(...items); } } var test = new Test(); test.add(12, 33, 222); // decorator top | decorator bottom console.log(test); // {list: [12, 33, 222]}
更多文章
- ECMAScript 6 常用特性整理
- Promise-使用整理
- Decorator装饰器
- Iterator、Generator、async、await 异步编程
阅读全文
0 0
- Decorator Pattern(装饰器)
- 装饰器(Decorator)模式
- Decorator装饰器
- 装饰器(Decorator)模式
- 装饰器(Decorator)模式
- 装饰器(Decorator)模式
- 装饰器模式(Decorator)
- 装饰器(Decorator)模式
- Decorator装饰器
- 装饰器-decorator
- Python Decorator(装饰器)
- 装饰器(Decorator)模式
- python decorator(装饰器)
- Python 装饰器/Decorator
- Python decorator(装饰器)
- 装饰器 decorator (python)
- 装饰器模式 decorator
- Python装饰器 Decorator
- 格列佛游记思维导图
- docker容器中springboot 差八小时解决办法
- 单例模式应用场景
- Docker 自修笔记(五)—— 示例学习
- 最大间距
- Decorator装饰器
- Ubuntu14.04系统c++调用sqlite3失败
- 系统之间数据相互交互如何使用Feign构造参数请求
- C++动态内存分配
- C3P0 连接池 —— 基础使用 与 SpringMVC 中使用
- 将mybatis源码导入eclipse项目中
- react 组件库封装(一)
- VS2015调用Matlab2017a环境配置
- ASCII码的一些理解