Typescript中的装饰器原理
Typescript中的装饰器原理
1、小原理
因为react中的高阶组件本质上是个高阶函数的调用,
所以高阶组件的使用,我们既可以使用函数式方法调用,也可以使用装饰器。
也就是说,装饰器的本质就是一个高阶函数,
就是利用TypeScript的弱类型特性和装饰器特性,实现了一个加强版。
2、以一个例子来讲
//定义一个装饰器函数decTest
function decTest(constructor: Function) {
console.log(constructor("hello!"));
}
//在类Greeter上安装decTest装饰器
@decTest
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
console.log("in constructor:",message);
}
greet() {
return "Hello, " + this.greeting;
}
}
编译后:
//第一行定义了一个_decarate函数,这个函数会处理类装饰器的功能 //第18行可以看出,调用_decorate函数时只给了两个参数,
//一个是数组,其中包含多个类装饰器,这里只使用了一个装饰器
//另一个是Greeter类的构造函数Greeter()
//调用__decorate函数时decorators为一个装饰器数组;
//target为构造函数Greeter(),
//key和desc均未使用,值为undefined。
//这里的__decorate函数为各种装饰器的通用代码,
//在方法装饰器中key和desc均有使用。 1. var __decorate = (this && this._decorate) || function (decorators, target, key, desc) { //第2行参数数量在类装饰器中为2,显然小于3。 2. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; //第3行指出如果系统支持反射,
//则直接使用Reflect.decorate(decorators,target, key, desc)方法。
//否则自行定义实现装饰器机制的代码。 3. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4. 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;
5. return c > 3 && r && Object.defineProperty(target, key, r), r;
6. };
7. function decTest(constructor) {
8. console.log(constructor("hello!"));
9. } //定义了一个函数,从第22行可以看出,这个函数是自调用的 10. var Greeter = (function () {
11. function Greeter(message) {
12. this.greeting = message;
13. console.log("in constructor:", message);
14. }
15. Greeter.prototype.greet = function () {
16. return "Hello, " + this.greeting;
17. }; //18行的时候函数调用了_decorate函数 18. Greeter = __decorate([
19. decTest
20. ], Greeter);
21. return Greeter;
22. }());
简化:
1. var __decorate = function (decorators, target, key, desc) {
2. r = target;
//可以看出第三行实现了装饰器的堆叠
//堆叠的规则是先处理后面的,
//再处理前面的
3. for (var i = decorators.length - 1; i >= 0; i--)
4. if (d = decorators[i]) r = d(r);
5. return r;
6. };
7.
8. function decTest(constructor) {
9. console.log(constructor("hello!"));
10. }
//这个方法最后返回一个Greeter,改造后的Greeter
11. var Greeter = (function () {
12. function Greeter(message) {
13. this.greeting = message;
14. console.log("in constructor:", message);
15. }
16. Greeter.prototype.greet = function () {
17. return "Hello, " + this.greeting;
18. };
//第19行实际上就是通过类装饰器函数修改了Greeter类的构造函数Greeter(message)的行为,
//从而修改了对象的特性,
//比如增加接口,注入类成员……等等。
19. Greeter = __decorate([
20. decTest
21. ], Greeter);
22. return Greeter;
23. }());
以上。
Typescript中的装饰器原理的更多相关文章
- C#中的 Attribute 与 Python/TypeScript 中的装饰器是同个东西吗
前言 最近成功把「前端带师」带入C#的坑(实际是前端带师开始从cocos转unity游戏开发了) 某天,「前端带师」看到这段代码后问了个问题:[这个是装饰器]? [HttpGet] public Re ...
- 【Python】python中的装饰器——@
对装饰器本来就一知半解的,今天终于弄清楚了,Python中的装饰器是对装饰者模式的很好运用,简化到骨子里了. python中为什么需要装饰器,看这里:http://www.cnblogs.com/hu ...
- python学习之【第十四篇】:Python中的装饰器
1.什么是装饰器? 器即函数 装饰即修饰,意指为其他函数添加新功能 装饰器定义:本质就是函数,功能是为其他函数添加新功能 2.遵循的原则 装饰器必须遵循以下两个原则: 不修改被装饰函数的源代码(开放封 ...
- Python函数装饰器原理与用法详解《摘》
本文实例讲述了Python函数装饰器原理与用法.分享给大家供大家参考,具体如下: 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值 ...
- 简单说明Python中的装饰器的用法
简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下 装饰器对与 ...
- django ----CBV中加装饰器
CBV中加装饰器 from django import views from django.utils.decorators import method_decorator def login_aut ...
- Python 标准库中的装饰器
题目描述 1.简单举例 Python 标准库中的装饰器 2.说说你用过的 Python 标准库中的装饰器 1. 首先,我们比较熟悉,也是比较常用的 Python 标准库提供的装饰器有:property ...
- Python 中实现装饰器时使用 @functools.wraps 的理由
Python 中使用装饰器对在运行期对函数进行一些外部功能的扩展.但是在使用过程中,由于装饰器的加入导致解释器认为函数本身发生了改变,在某些情况下——比如测试时——会导致一些问题.Python 通过 ...
- 写python中的装饰器
python中的装饰器主要用于在已有函数实现功能前附加需要输出的信息,下面将用实例展示我如何写装饰器. 首先分别尝试写装饰器装饰一个无参函数和一个有参函数(被装饰函数仅输出,无返回值情况下) def ...
随机推荐
- php判断是否为命令行模式
function is_cli(){ : ; }
- Mybatis入门及于hibernate的区别
pojo:不按mvc分层,只是java bean有一些属性,还有get set方法domain:不按mvc分层,只是java bean有一些属性,还有get set方法po:用在持久层,还可以再增加或 ...
- Eclipse安装fatjar(不用自己下载fatjar包)
.安装Eclipse-jee-luna-SR2-win32-x86_64版本的插件支持 方法如下: Help -> Install New Software... -> Work with ...
- tensorboard窥视
运行神经网络时,跟踪网络参数,以及输入输出是很重要的,可据此判断模型是否在学习,损失函数的值是否在不断减小.Tensorboard通过可视化方法,用于分析和调试网络模型. 使用tensorboard的 ...
- 2017.11.10 重读C++ Primer
第二章 变量和变量类型 1. C++ 算数类型 bool 布尔 最小尺寸未定义 char 字符 8位 wchar_t ...
- winform中的dateTimePicker控件设置默认值为空
winform中的dateTimePicker控件设置默认值为空 第一步:设置Format的属性值为“Custom” 第二步:设置CustomFormat的属性值为空,需要按一个空格键
- P4027 [NOI2007]货币兑换(斜率优化dp+cdq分治)
P4027 [NOI2007]货币兑换 显然,如果某一天要买券,一定是把钱全部花掉.否则不是最优(攒着干啥) 我们设$f[j]$为第$j$天时用户手上最多有多少钱 设$w$为花完钱买到的$B$券数 $ ...
- Docker Swarm nginx 集群搭建
环境1: 系统:Linux Centos 7.4 x64 内核:Linux docker 3.10.0-693.2.2.el7.x86_64 Docker 版本:18.09.1 redis 版本:ng ...
- Linux TCP并发请求溺出 调优
TCP并发请求溺出 调优:系统开启某个监听端口后,当多个TCP请求连接监听端后,会把多个请求交给backlog的默认监听队列由socket server一并处理,backlog有自己的队列长度默认12 ...
- 单元测试系列之一:如何使用JUnit、JaCoCo和EclEmma提高单元测试覆盖率
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6726664.html -----如 ...