前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TypeScript系列教程十一《装饰器》 -- 类装饰器

TypeScript系列教程十一《装饰器》 -- 类装饰器

作者头像
星宇大前端
发布2022-05-06 17:19:13
7570
发布2022-05-06 17:19:13
举报
文章被收录于专栏:大宇笔记

类装饰器顾名思义是对类的内容进行修饰,在Typescript 类其实就是对象,这样配合原型对象操作可以达到操作类的目的。

类装饰器定义

首先看下类装饰器在TS中的定义:

  • 是一个函数
  • 函数的参数是一个继承函数类型的泛型函数
  • 返回可以是一个装饰器函数或者不返回(工厂模式返回函数后面介绍)
代码语言:javascript
复制
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;

类装饰器

案例思路描述:

  1. 创建一个学生类
  2. 让学生类具拥有谈钢琴的技能
  3. 同时艺术家也想拥有弹钢琴的技能

我们用组合的思想,可以将弹钢琴的技能部分单独实现出来,谁想拥有引入即可。

装饰器相同的道理,只需要实现这个装饰器即可,下面用代码实现。

代码语言:javascript
复制
const musicDecorator : ClassDecorator = (target:Function)=>{  
  target.prototype.playPiano = () => {
    console.log('弹钢琴');
  }
}

@musicDecorator
class Student {
}

@musicDecorator
class Artist{
}

var xiaoming = new Student();
(<any>xiaoming).playPiano()

var jay = new Artist();
(<any>jay).playPiano()

控制台输出:

在这里插入图片描述
在这里插入图片描述

类装饰器原理

类装饰器其实就是一个语法糖,类装饰器相当于一个函数,函数的参数是类构造函数。

那么上面的例子我们完全可以这么写,输出结果一致:

代码语言:javascript
复制
const musicDecorator : ClassDecorator = (target:Function)=>{  
  target.prototype.playPiano = () => {
    console.log('弹钢琴');
  }
}

class Student {
}

class Artist{
}

//函数调用
musicDecorator(Student)
musicDecorator(Artist)


var xiaoming = new Student();
(<any>xiaoming).playPiano()

var jay = new Artist();
(<any>jay).playPiano()

工厂类装饰器

有些装饰器需要参数判断情况,比如学生和艺术家都能弹钢琴,但是弹的曲目不一样,那么需要带参数判断,工厂根据参数创造出装饰器返回。

代码思路:

  • 学生类
  • 艺术家类
  • 工厂装饰器根据参数让学生弹 小星星,艺术家弹奏夜曲

下面看代码例子:

代码语言:javascript
复制
const musicDecorator:(song:string)=> ClassDecorator = (song)=>{
  return (target:Function)=>{
     target.prototype.playPiano = () => {
        console.log(song);
     }
  }
}

@musicDecorator('小星星')
class Student {
}

@musicDecorator('小夜曲')
class Artist{
}

var xiaoming = new Student();
(<any>xiaoming).playPiano()

var jay = new Artist();
(<any>jay).playPiano()

控制台输出:

在这里插入图片描述
在这里插入图片描述

类装饰器组合

类装饰器和函数一样是可以叠加的,一般是可以这么想象的。

如下面的例子:(学生既可以弹钢琴,又有班级属性)

代码语言:javascript
复制
const musicDecorator:(song:string)=> ClassDecorator = (song)=>{
  return (target:Function)=>{
     target.prototype.playPiano = () => {
        console.log(song);
     }
  }
}

const classNameDecorator:ClassDecorator = (target:Function)=>{
  target.prototype.className  = '三年二班'
}

@musicDecorator('小星星')
@classNameDecorator
class Student {
}


var xiaoming = new Student();
(<any>xiaoming).playPiano()
console.log((<any>xiaoming).className);

思考装饰叠加的执行顺序

验证案例思路:

  • 两个装饰器
  • 两个装饰器都往原型对象上加属性
  • 查看调用顺序

示例代码:

代码语言:javascript
复制
const musicDecorator:ClassDecorator = (target:Function)=>{
  console.log('执行musicDecorator');
  console.log(target.prototype.className);
  
  target.prototype.song  = '小星星'
}

const classNameDecorator:ClassDecorator = (target:Function)=>{
  console.log('执行classNameDecorator');
  console.log(target.prototype.song);
  target.prototype.className  = '三年二班'
}


@classNameDecorator
@musicDecorator
class Student {
}

打印结果:

在这里插入图片描述
在这里插入图片描述

结论:

装饰器嵌套相当于 函数嵌套,先执行后面的装饰器,当后面的装饰器执行完,才执行前面的。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-03-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 类装饰器定义
  • 类装饰器
  • 类装饰器原理
  • 工厂类装饰器
  • 类装饰器组合
    • 思考装饰叠加的执行顺序
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档