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. 15.IEnumerable和IEnumerator

    先说IEnumerable,我们每天用的foreach你真的懂它吗? 阅读目录 自己实现迭代器 yield的使用 怎样高性能的随机取IEnumerable中的值 我们先思考几个问题: 为什么在fore ...

  2. Mysql InnoDB 数据更新/删除导致锁表

    一. 如下对账表数据结构 create table t_cgw_ckjnl ( CNL_CODE ) default ' ' not null comment '通道编码', CNL_PLT_CD ) ...

  3. 竖倾斜ScrollView

    using UnityEngine; using UnityEngine.EventSystems; public class ObliqueScroll : MonoBehaviour,IDragH ...

  4. jquery对复选框(checkbox)的操作(精华)

    @{ Layout = null;} <!DOCTYPE html> <html><head> <meta name="viewport" ...

  5. 解决mysql中文乱码问题?

    mysql是我们项目中非常常用的数据型数据库.但是因为我们需要在数据库保存中文字符,所以经常遇到数据库乱码情况.下面就来介绍一下如何彻底解决数据库中文乱码情况. 1.中文乱码 1.1.中文乱码 cre ...

  6. Android 性能优化之内存泄漏检测以及内存优化(中)

    https://blog.csdn.net/self_study/article/details/66969064 上篇博客我们写到了 Java/Android 内存的分配以及相关 GC 的详细分析, ...

  7. Linux 进程管理、系统状态查询

    1.内存给进程一段空间让他启动,让内核通过cpu来管理它. 2.ps命令查看命令信息. 用户.pid号.使用cpu.使用内存.虚拟内存.真实内存.控制台.状态.启动时间.运行时间.名 USER PID ...

  8. 剑指offer(55)链表中环的入口节点

    题目描述 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 题目分析 1.一快一慢指针,先找到碰撞点. 2.然后碰撞点到入口节点的距离就是头结点到入口节点的距离. 具体原理可 ...

  9. 51Nod - 1384

    全排列函数解法 #include <iostream> #include <cstdio> #include <cstring> #include <cmat ...

  10. 放大镜jQuery效果

    今天我们来写一下jQuery的效果来上代码 1,html代码 <div id='small'><img src="./icon/images/sj1.jpg" a ...