装饰器会调用
Foo = __decorate([
Cls(),
__param(0, Param()),
__metadata("design:paramtypes", [String])
], Foo);
之类的代码
我们来研究一下decorate的作用
总体代码如下
var __decorate =
(this && this.__decorate) ||
function (decorators, target, key, desc) {
var c = arguments.length,
r =
c < 3
? target
: desc === null
? (desc = Object.getOwnPropertyDescriptor(target, key))
: desc,
d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
r = Reflect.decorate(decorators, target, key, desc);
else
for (var i = decorators.length - 1; i >= 0; i--)
if ((d = decorators[i]))
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
先来看开头
(this && this.__decorate)
判断this以及this下是否存在,如果存在则直接继承,不存在则赋值函数
函数传参四个
function (decorators, target, key, desc)
装饰器,目标对象,key值,描述符
然后再看一句
var c = arguments.length,
r =
c < 3
? target
: desc === null
? (desc = Object.getOwnPropertyDescriptor(target, key))
: desc,
d;
c为参数长度,r来根据c来判断
如果c小于3
则为target
如果描述符不为空,则为自身,否则则为取描述符
这里大概可以看出来选项有三种,对象,描述符,自身
应该是要设置的位置
声明了一个d,没有赋值
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
r = Reflect.decorate(decorators, target, key, desc);
else
for (var i = decorators.length - 1; i >= 0; i--)
if ((d = decorators[i]))
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
判断是否有Reflect.decorate函数,如果没有则我们自己执行循环,有则直接传入
for (var i = decorators.length - 1; i >= 0; i--)
if ((d = decorators[i]))
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
遍历装饰器数组
从后向前遍历
判断每个装饰器赋值给d并是否不为空
如果不为空则调用
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key))
这里可以看到是根据传入的参数来传入不同的内容
如果小于3则只传入对象r,大于三传入目标对象,key,r,否则传入目标对象,key
我们对比官方文档以及林不渡的TypeScript 全面进阶指南
可以知道
类装饰器是一个对象,传入一个类
方法装饰器三个对象,原型,方法名,属性描述符
访问符装饰器三个对象,原型,方法名,属性描述符
属性装饰器两个对象,原型,属性名
参数装饰器三个对象,原型,参数名,索引值
因为我们还需要传入装饰器
也就是说
类2个
方法4个
访问符4个
装饰器3个
参数4个
对比这里
【小于3则只传入对象r】(指代类装饰器,传入类)
【大于三传入目标对象,key,r】(指代原型,名字,描述符/索引值)
【否则传入目标对象,key 】指代属性装饰器的原型和属性名
那我们就可以知道r分为类、描述符、index
最后调用
return c > 3 && r && Object.defineProperty(target, key, r), r;
判断是否是四个参数,如果是则定义一下,然后返回r
结束
撒花~