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中的装饰器原理的更多相关文章

  1. C#中的 Attribute 与 Python/TypeScript 中的装饰器是同个东西吗

    前言 最近成功把「前端带师」带入C#的坑(实际是前端带师开始从cocos转unity游戏开发了) 某天,「前端带师」看到这段代码后问了个问题:[这个是装饰器]? [HttpGet] public Re ...

  2. 【Python】python中的装饰器——@

    对装饰器本来就一知半解的,今天终于弄清楚了,Python中的装饰器是对装饰者模式的很好运用,简化到骨子里了. python中为什么需要装饰器,看这里:http://www.cnblogs.com/hu ...

  3. python学习之【第十四篇】:Python中的装饰器

    1.什么是装饰器? 器即函数 装饰即修饰,意指为其他函数添加新功能 装饰器定义:本质就是函数,功能是为其他函数添加新功能 2.遵循的原则 装饰器必须遵循以下两个原则: 不修改被装饰函数的源代码(开放封 ...

  4. Python函数装饰器原理与用法详解《摘》

    本文实例讲述了Python函数装饰器原理与用法.分享给大家供大家参考,具体如下: 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值 ...

  5. 简单说明Python中的装饰器的用法

    简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下   装饰器对与 ...

  6. django ----CBV中加装饰器

    CBV中加装饰器 from django import views from django.utils.decorators import method_decorator def login_aut ...

  7. Python 标准库中的装饰器

    题目描述 1.简单举例 Python 标准库中的装饰器 2.说说你用过的 Python 标准库中的装饰器 1. 首先,我们比较熟悉,也是比较常用的 Python 标准库提供的装饰器有:property ...

  8. Python 中实现装饰器时使用 @functools.wraps 的理由

    Python 中使用装饰器对在运行期对函数进行一些外部功能的扩展.但是在使用过程中,由于装饰器的加入导致解释器认为函数本身发生了改变,在某些情况下——比如测试时——会导致一些问题.Python 通过  ...

  9. 写python中的装饰器

    python中的装饰器主要用于在已有函数实现功能前附加需要输出的信息,下面将用实例展示我如何写装饰器. 首先分别尝试写装饰器装饰一个无参函数和一个有参函数(被装饰函数仅输出,无返回值情况下) def ...

随机推荐

  1. [py]js前端求和与flask后端求和

    index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  2. python2精确除法

    python2和python3除法的最大区别: python2: print 500/1000 python2结果:取整数部分,小数并没有保留 0 Process finished with exit ...

  3. appium环境搭建-运行

    appium是测试移动端的测试工具 首先要下载手机模拟器,或者连接真机.我用的夜神模拟器.安装打开它.安装这个有很高的兼容性要求,我也是小白,摸索了三天才弄出来 一.原理如图: 二.需要安装的软件: ...

  4. sql server 按年月日分组

    sql server  按年月日分组 ----------------------------------------------- --author:yangjinwang --date:2017- ...

  5. z-tree学习笔记

    做项目时,需要用到带复选框的tree.经比较后优选了ztree,功能强大,文档清晰. http://www.treejs.cn/v3/api.php 直接上代码吧. 1.下载ztree后.将里面需要用 ...

  6. 第七篇——Struts2的接收参数

    Struts2的接收参数 1.使用Action的属性接收参数 2.使用Domain Model接收参数 3.使用ModelDriven接收参数 项目实例 1.项目结构 2.pom.xml <pr ...

  7. 星型数据仓库olap工具kylin介绍和简单使用示例

    本文转载自:https://www.cnblogs.com/hsydj/p/4515057.html 星型数据仓库olap工具kylin介绍 星型数据仓库olap工具kylin介绍 数据仓库是目前企业 ...

  8. JVM内存结构分析

    对于Java程序员来说,内存是由JVM自动管理的,所以一旦出现内存泄漏或溢出的问题,不了解JVM的内存结构和各个内存区域的工作职责,将对解决问题带来很大的麻烦,本文参照周志明的<深入理解Java ...

  9. eclipse自定义快捷键(模板)

    window->Preferences->Java->Editor->Templates https://blog.csdn.net/changqing5818/article ...

  10. Oarcle 入门之from关键字

    作用:检索“表” 注意:检索的表后可以添加别名(别名不需要被双引号引起) *每一句都不可缺少