企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 装饰器模式 https://cloud.tencent.com/developer/article/1690642 https://cloud.tencent.com/developer/article/1690642 https://juejin.cn/post/6844904100144889864#heading-6 ## 类装饰器 给目标类增加静态属性 test ```js const decoratorClass=(targetClass)=>{ targetClass.test='123' } @decoratorClass class Test {} Test.test; // '123' ``` ## 类属性装饰器 类属性装饰器可以用在类的属性、方法、get/set 函数中,一般会接收三个参数: target:被修饰的类;name:类成员的名字;descriptor:属性描述符,对象会将这个参数传给 Object.defineProperty ```js function readonly(target, name, descriptor) { descriptor.writable = false; return descriptor; } class Person { @readonly name = 'person' } const person = new Person(); person.name = 'tom'; ``` ## why装饰器不能用于函数? 装饰器只能用于类和类的方法,不能用于函数,因为存在函数提升。 ```js var counter = 0; var add = function () { counter++; }; @add function foo() {} //意图是执行后counter等于1,但是实际上结果是counter等于0-----提升之后 var counter; var add; @add function foo() {} counter = 0; add = function () { counter++; }; ``` ## Mixin Mixin模式,就是对象继承的一种替代方案,在一个对象之中混入另外一个对象的方法 通用脚本mixins.js,将 Mixin 写成一个装饰器 ```js export function mixins(...list) { return function(target){ Object.assign(target.prototype, ...list) }; } // 在MyClass类上面“混入”Foo对象的foo方法 import { mixins } from './mixins'; const Foo = { foo() { console.log('foo') } }; @mixins(Foo) class MyClass {} let obj = new MyClass(); obj.foo() // "foo" ``` # 装饰器案例-ES7 https://blog.csdn.net/beLaity/article/details/108463843 装饰器模式:在不修改类原来接口的情况下,动态的为对象添加功能 ## 案例一高阶函数 高阶函数就是一个函数就可以接收另一个函数作为参数。 ```javascript const add = (x, y, f) => { return f(x) + f(y); } const num = add(2, -2, Math.abs); console.log(num); // 4 ``` 函数 add 就是一个简单的高阶函数,而 add 相对于 Math.abs 来说相当于一个装饰器 ## 案例二高阶组件(HOC) 在 react 中,高阶组件(HOC)也是装饰器模式的一种体现,通常用来不改变原来组件的情况下添加一些属性,达到组件复用的功能。 ```javascript import React from 'react'; const BgHOC = WrappedComponent => class extends React.Component { render () { return ( <div style={{ background: 'blue' }}> <WrappedComponent /> </div> ); } } ``` 装饰器模式将现有对象和装饰器进行分离,两者独立存在,符合开放封闭原则和单一职责模式 使用场景: es7 装饰器、vue mixins、core-decorators 等 ## 案例三防抖装饰器 定义一个防抖装饰器 装饰器本质上依然是一个函数,不过这个函数的参数是固定的,如下是防抖装饰器的代码 ```javascript function debounce(wait) { returnfunction(target, name, descriptor) { descriptor.value = debounce(descriptor.value, wait) } } // 使用方式 class MyClass { @debounce(100) follow() { console.log('我是子君,我的公众号是 【前端有的玩】,关注有惊喜哦') } } ``` target: 这个类属性函数是在谁上面挂载的,如上例对应的是MyClass类 name: 这个类属性函数的名称,对应上面的follow descriptor: 这个就是我们前面说的属性描述符,通过直接descriptor上面的属性,即可实现属性只读,数据重写等功能 ## core-decorators.js `core-decorators` 是一个封装了常用装饰器的 JS 库,它归纳了下面这些装饰器(只列举了部分)。 1. ***autobind***:自动绑定 `this`,告别箭头函数和 `bind` 2. ***readonly***:将类属性设置为只读 3. ***override***:检查子类的方法是否正确覆盖了父类的同名方法 4. ***debounce***:防抖函数 5. ***throttle***:节流函数 6. ***enumerable***:让一个类方法变得可枚举 7. ***nonenumerable***:让一个类属性变得不可枚举 8. ***time***:打印函数执行耗时 9. ***mixin***:将多个对象混入类(和我们上面的 mixin 不太一样)