温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Decorator修饰器的作用

发布时间:2021-08-30 21:51:29 来源:亿速云 阅读:163 作者:chen 栏目:大数据

本篇内容主要讲解“Decorator修饰器的作用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Decorator修饰器的作用”吧!

修饰器(Decorator)是ES7的一个提案,熟悉javascript设计模式的读者,肯定知道用es5语法来实现修饰器模式是多么的麻烦,而用ES7的修饰器本身实现了修饰者模式,修饰器主要的作用有两个:

  1. 不同类间共享方法

  2. 编译期对类和方法的行为进行改变

首先来了解一下decorator的语法:

decorator就是一个函数,这个函数既可以修饰类,也可以修饰类的属性和方法,decorator在修饰类的时候只能传递一个参数,这个参数指的就是被修饰的类,decorator在修饰类里面的属性的时候可以传递三个参数,target指的是类本身,key被修饰的属性,descriptor属性描述符。

下面演示deractor的使用方法,首先演示第一种,用deractor修饰类,代码如下:

@setProp
class User {}

function setProp(target) {
   console.log(target)
   target.age = 30
}

console.log(User.age);

打印结果如图:

Decorator修饰器的作用

我们使用修饰器给User这个类增加了一个属性,并且可以看到target就是类本身。

上面的案例为User这个类设置的age属性是写死的,能不能再调用修饰类的时候,通过传递参数设置不同的age呢?看如下代码:

@setProp(20)
class User {}

function setProp(value) {
   return function (target) {
       target.age = value
   }
}

console.log(User.age)

仔细观察代码,我们发现修饰器就是一个函数,我们将这个修饰器包裹在另外一个函数中,将变量提取为参数,在使用的地方调用这个函数,传入参数,函数内部返回修饰器,这也是开发中经常用到的修饰器的方式。

deractor修饰类的时候除了直接为类增加属性,也可以修饰类的prototype,看如下代码:

Decorator修饰器的作用

我们通过deractor为类的原型设置属性。

说完了deractor修饰类,下面数一下,deractor修饰类的属性和方法代码如下:

class User {
   @readonly
   getName() {
       return 'Hello World'
   }
}

// readonly修饰函数,对方法进行只读操作
function readonly(target, name, descriptor) {
   console.log(target, name, descriptor)
   descriptor.writable = false
   return descriptor
}

let u = new User()
// 尝试修改函数,在控制台会报错
u.getName = () => {
   return 'I will override'
}

观察以上代码,首先定义了一个类,这个类的原型上有一个getName的方法,此方法返回hello world,然后定义了一个deractor,这个修饰器里面传了三个参数,并打印,打印结果如下:

Decorator修饰器的作用

可以看出来,分别是对应着类本身,属性key值,属性描述符。在修饰器函数里面我们将属性描述符的writable改成了false,这个属性就是只读的了,不能被修改了。代码最后两行,我们定义了一个实例,然后修改实例的getName方法,程序就会报错。

那这个修饰器用在实际应用中,有哪些场景呢?

实际应用1:日志管理在用webpack打包时,我们经常需要好多步骤,比如第一步读取package.json文件,第二步处理该文件,第三步加载webpack.base.js文件,第四步进行打包...为了直观,我们经常在每一步打印一些日志文件,比如这步都干了些什么事,很明显打印日志的操作和业务代码根本就一点关系没有,我们不应该把日志和业务掺和在一起,这样使用修饰器就是避免这个问题,以下为代码:

Decorator修饰器的作用

实际应用2:检查登录这个例子在实际的开发中常用得到,我们一些操作前,必须得判断用户是否登录,比较点赞、结算、发送弹幕...按照之前的写法,我们必须在每一个方法中判断用户的登录情况,然后再进行业务的操作,很显然前置条件和业务又混到了一起,用修饰器,就可以完美的解决这一问题,代码如下:

class User {
   // 获取已登录用户的用户信息
   @checkLogin
   getUserInfo() {
       /**
        * 之前,我们都会这么写:
        *      if(checkLogin()) {
        *          // 业务代码
        *      }
        *  这段代码会在每一个需要登录的方法中执行
        *  还是上面的问题,执行的前提和业务又混到了一起
        */
       console.log('获取已登录用户的用户信息')
   }
   // 发送消息
   @checkLogin
   sendMsg() {
       console.log('发送消息')
   }
}

// 检查用户是否登录,如果没有登录,就跳转到登录页面
function checkLogin(target, name, descriptor) {
   let method = descriptor.value

   // 模拟判断条件
   let isLogin = true

   descriptor.value = function (...args) {
       if (isLogin) {
           method.apply(this, args)
       } else {
           console.log('没有登录,即将跳转到登录页面...')
       }
   }
}
let u = new User()
u.getUserInfo()
u.sendMsg()

实际应用3:前端埋点,在工作中有得时候我们需要埋点,从而统计一下交互数据,代码如下:

Decorator修饰器的作用

在上面的函数中我们定义了一个类,这个类里面包含一些方法,这些方法是需要被被埋点监控的,然后我们将埋点函数抽离到了装饰器中,并为其设置参数,不同的用户操作行为,传递不同的参数,然后,在定义类的时候,修饰具体的方法,这样的代码易于维护,逻辑表达更加清晰。

到此,相信大家对“Decorator修饰器的作用”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI