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.    }());

以上。

原文地址:https://www.cnblogs.com/yangyangxxb/p/10105379.html

时间: 2024-09-30 22:09:09

Typescript中的装饰器原理的相关文章

自己编写一个装饰器中的装饰器函数

看了"大道曙光"的<探究functools模块wraps装饰器的用途>的文章.基本上弄清了wraps的工作原理,为了检验一下自己理解的程度,于是动手写一个类似的 wraps函数,请大家指教. #!/usr/bin/env python # -*- coding: utf-8 -*- #filename : mywrapper.py #date: 2017-06-02 ''' wrapper function by my code.''' import functools i

@修饰符--python中的装饰器

http://blog.csdn.net/shangzhihaohao/article/details/6928808 装饰器模式可以在不影响其他对象的情况下,以动态.透明的方式给单个对象添加职责,也能够处理那些可以撤销的职责.经常用于日志记录.性能测试等场合. 想象一下这个很常见的场景,你写了一个方法只提供给以登陆的用户访问(事实上我也是通过django的@login_required才了解到@修饰符的),你可以写以下代码: 这当然没什么问题,但是你又写了一个方法B,也要求只有登录用户可以访问

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

Python 中使用装饰器对在运行期对函数进行一些外部功能的扩展.但是在使用过程中,由于装饰器的加入导致解释器认为函数本身发生了改变,在某些情况下--比如测试时--会导致一些问题.Python 通过 functool.wraps 为我们解决了这个问题:在编写装饰器时,在实现前加入 @functools.wraps(func) 可以保证装饰器不会对被装饰函数造成影响.比如,在 Flask 中,我们要自己重写 login_required 装饰器,但不想影响被装饰器装饰的方法,则 login_req

【react】---react中使用装饰器(高阶组件的升级用法)

一.creact-react-app中使用装饰器 运行 npm run eject 可以让由create-react-app创建的项目的配置项暴露出来 此时,项目中多了一个config文件,并且各个配置文件已经暴露出来了.(运行npm run eject之前,保证本地没有待提交到git的文件) 安装babel插件npm install --save-dev @babel/plugin-proposal-decorators 修改package.json文件的babel配置项 "babel&quo

二十五:视图之类视图中使用装饰器

对于url的保护,一般是通过装饰器实现,如:某个页面需要登录后才能访问 函数视图实现 from flask import Flask, render_template, requestfrom functools import wrapsapp = Flask(__name__)def login_required(func): @wraps(func) def wrapper(*args, **kwargs): username = request.args.get('username') r

Angular中的装饰器

Angualr中的装饰器是一个函数,它将元数据添加到类.类成员(属性.方法)和函数参数 用法:要想用装饰器,把它放到被装饰对象的上面或做左面 1.类装饰器: 类装饰器应用于类构造函数,可以用来监控.修改或替换类定义 类装饰器表达式会在运行时当作函数被调用,类的构造函数作为唯一的参数 @Component 标记类作为组件并收集组件配置元数据(继承Directive) @Directive 标记类作为指令并收集组件配置元数据 声明当前类时一个指令,并提供关于该指令的元数据 @Pipc 声明当前类是一

如何理解python中的装饰器, 这篇文章就够了!

1. python中的函数 理解裝飾器之前先要理解閉包, python中閉包的出現是因爲函數在python中也是一個對象, 也可以被引用, 然後調用, 比如 def log(): print('我是一些log信息') if __name__ == '__main__': print(type(log)) log_func = log log_func() 執行結果如下 <class 'function'> 我是一些log信息 可以看到log函數是一個對象, 可以被賦值給log_func, lo

python cookbook 学习系列(一) python中的装饰器

简介 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓存.权限校验等场景.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用.概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能,我们也称之为AOP(面向切面编程) 原理 实现装饰器的最主要的原因是python中一切皆为对象,我们会把方法看做一个对

浅显易懂的谈一谈python中的装饰器!!

hello大家好~~我是稀里糊涂林老冷,一天天稀里糊涂的. 前一段时间学习了装饰器,觉着这东西好高大上哇靠!!哈哈,一定要总结一下,方便以后自己查阅,也希望帮助其他伙伴们共同进步! 装饰器: 大家可以这样理解,装饰器是运用闭包的基本原理,对一个目标函数进行装饰.即是在执行一个目标函数之前.之后执行一些特定的事情. 学习装饰器一定要有闭包的基础知识,如果对闭包不是特别理解的话,可以参考我之前的博文http://www.cnblogs.com/Lin-Yi/p/7305364.html,也可以学习其