ES7装饰器decorators解析

ES7装饰器decorators解析

1,首先思考一个问题,在哪种情况下需要用到装饰器,装饰器的作用是什么?
我自己的答案:装饰器可以修改类里面的属性,或是新增类的属性。在需要就类原本的功能扩展新功能时会用到装饰器。我当时理解到这里时不禁产生了一个疑问,如果只是这样,要加新功能直接在类上面加就是了,为什么还要弄个装饰器出来呢?解释是,自己定义的类,想怎么改属性当然就能怎么改了,但是继承的类呢,比如说有一个你自己写的react组件,它继承于component,你现在想修改它的componentUpdate生命周期方法,给它加上一些功能,并且不会影响到其他继承了这个类的实例,那么答案就很明显了,这就是装饰器的用处。

2,装饰器用法

2.1 装饰类

第一步:全局定义一个方法

function test(target) {
	target.xx = '艾欧尼亚'
}

这里的target就是接收要修饰的对象的一个形参,也就是下面的类Lei
第二步: 装饰一个类

@test
class Lei { 
	xx = '芜湖'
}
console.log(Lei.xx) // '艾欧尼亚'

这样,就修改了类的属性xx了。这种修饰写法等同于 test(Lei),函数调用完后会返回一个根据test(target)函数加工过的类Lei,这种有点类似于高阶组件的写法,高阶组件就是一个构造函数定义的组件,这个函数接收一个组件B作为参数,对这个组件做过某些处理后再返回一个包含组件B的类方式定义的组件出来。
修饰的时候也可以传参,写法如下,后面提到的装饰类的属性要是要传参也可以这样写

function test(xx) {
	return function(target) {
	  target.name = xx;
	}
}
@test('幸运儿')
class Lei { 
	name = '倒霉蛋'
}
console.log(Lei.name ) // '幸运儿'
2.2 装饰类的属性

这里也分为两步,就一起写了

function test(target, say, descriptor) {
	// target参数代表类的原型对象,也就是Lei.prototype
	// say参数代表要装饰的属性名
	// descriptor参数是一个对象,如下
	// {
	// value: say函数的函数地址,也就是要装饰的属性的值
	// enumerable: false 该属性是否允许枚举(就是被遍历到)
	// configurable: true 该属性是控制descriptor能否被修改
	// writable: true 该属性控制此属性的值是否可修改
	//}
	//在这里可以通过descriptor参数对say方法进行一些功能上的扩展,比如先将
	//descriptor.value的值赋值给变量a,a此时就相当于函数say(),然后再将一个实现扩展功能的函数赋值
	//给变量b,且在这个方法中调用a(), ps: 如果这个方法中需要修改this指向,可以用call或apply
	// 这样做就可以保留原方法,且扩展新功能了
	//最后再返回这个方法结合enumerable等属性的一个对象
	return descriptor
}

class Lei { 
	state = { xx: 'Hi' }
	@test
	say(this.state.xx) { }
}

3,装饰器原理
基于es5的object.defineProperty方法,这个方法本来就是修改某个对象的某个属性的值,所以结合装饰器的功能,很好理解,但具体是基于这个方法做了怎样的处理实现了装饰器这种写法,就有待深究了。。。。
ps: 注意es版本,低版本使用babel转义

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值