粥里有勺糖

vuePress-theme-reco 粥里有勺糖    2018 - 2023
粥里有勺糖 粥里有勺糖

Choose mode

  • dark
  • auto
  • light
关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
author-avatar

粥里有勺糖

285

文章

40

标签

关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
  • note

    • 学习笔记
    • Chrome 调试技巧-基础
    • Chrome 调试技巧-Console
    • Chrome 调试技巧-Network
    • Chrome 调试技巧-Elements
    • Chrome 调试技巧-Drawer
    • Chrome 调试技巧-workspace
    • 设计模式-设计原则
    • 设计模式-创建型模式
    • 设计模式-结构型模式
    • 学习笔记:TypeScript装饰器

设计模式-结构型模式

vuePress-theme-reco 粥里有勺糖    2018 - 2023

设计模式-结构型模式

粥里有勺糖 2021-06-24 技术笔记学习笔记

# 设计模式-结构型模式

# 装饰器模式

使用装饰器可以装饰一个类或类中的属性

在不修改装饰对象上的代码情况下改变目标对象的行为

下面的实践均采用ts编写,使用ts-node直接运行,需在全局安装typescipt与ts-node

全局安装依赖

npm i typescript ts-node -g
1

运行ts文件

ts-node xx.ts
1

# 类装饰器

装饰器对象是一个类

function classDecorator(target){
    return target
}

@classDecorator
class C{
    hello(){
        console.log('hello world')
    }
}
1
2
3
4
5
6
7
8
9
10
  • target表示装饰的目标类

示例:在目标类上拓展 sayHello 方法

function helloWorld(target){
    // target === 目标类
    target.prototype.sayHello = function(){
        console.log('hello world');
    }
    return target
}

@helloWorld
class Router {
    sayHello() {
        throw new Error("Method not implemented.");
    }

}


const r = new Router()

r.sayHello() // hello world
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 函数装饰器

装饰对象的值是一个函数

function funDecorator(target, name, descriptor){
    return descriptor.value
}
class C{
    @funDecorator
    hello(){
        console.log('hello world')
    }
}
1
2
3
4
5
6
7
8
9
  • target: 目标类的原型
  • name: 属性名
  • descriptor:属性描述符号
    • value:属性值
    • writable:是否可以被重写
    • enumerable:是否可枚举
    • configurable:是否可配置

示例:提示某个方法已经失效

function expired(target, name, descriptor): any {
    console.log('fun:',name, 'is expired');
    return descriptor.value
}

@helloWorld
class Router {
    @expired
    hello() {
        // ...code
    }
    @expired
    hello2(){
        // ...code
    }
}
// fun: hello is expired
// fun: hello2 is expired
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# get/set装饰器

装饰存/取器的装饰器

  • target: 静态方法指向类的构造函数,实例方法指向类的原型
  • name: 属性名
  • descriptor:属性描述符号
    • value:属性值
    • writable:是否可以被重写
    • enumerable:是否可枚举
    • configurable:是否可配置
function getDecorator(target,name,descriptor){

}

function getDecorator(target,name,descriptor){
    
}

class C{
    private _x: number
    private _y: number
    constructor(x, y) {
        this._x = x
        this._y = y
    }

    @getDecorator
    get x() {
        return this._x
    }

    @getDecorator
    get y() {
        return this._y
    }
        
    @setDecorator
    set x(v) {
        this._x = v
    }

    @getDecorator
    set y(v) {
        this._y = v
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

emmmm,暂没想到用武之地

# 属性装饰器

简而言之就是装饰对象是一个普通的属性,参数和上述函数装饰器一致

函数也可以看做是类的一个属性,只不过其属性值是function

function propertyDecorator(target,name){

}

class C{
    @propertyDecorator
    private property:string|undefined
}
1
2
3
4
5
6
7
8

示例:设置默认值

function defaultValue(v: any) {
    return function (target, name) {
        target[name] = v
    }
}

class Router {
    @defaultValue('666')
    public name: string | undefined
}


const r = new Router()

console.log(r.name);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

其中装饰器传参实现,可以看做是一个闭包调用

在设置装饰器的时候传递参数,然后返回一个函数去真正装饰目标对象

这个被装饰的对象可以使用传递的参数

# 函数参数装饰器

顾名思义,装饰对象是函数中的一个参数

function paramDecorator(target,name,idx){

}

class C{
    fun1(@paramDecorator a){

    }
    static func2(@paramDecorator a){

    }
}
1
2
3
4
5
6
7
8
9
10
11
12
  • target: 静态方法指向类的构造函数,实例方法指向类的原型
  • name:属性名
  • idx:参数在函数中所处位置

示例:获取参数在函数中的相对位置

function printParamPos(target, name, idx) {
    console.log('paramCount:', target[name].length, 'paramPos:', idx);
}

class Router {
    hello3(@printParamPos name: string) {
        console.log('hello3', name);
    }
    static hello4(@printParamPos name: string) {
        console.log('hello4', name);
    }
}

const r = new Router()
Router.hello4('123')
r.hello3('456')
// paramCount: 1 paramPos: 0
// paramCount: 1 paramPos: 0
// hello4 123
// hello3 456
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 参考

  • TypeScript-decorators (opens new window)
Edit this page (opens new window)
Last Updated: 2022/5/15 12:46:34