深入理解 Angular 中的装饰器(一)

在 Angular 开发中,会使用到很多装饰器,比如在定义 Angular的模块时,需要使用 NgModule 装饰器修饰 AppModule 类;在定义组件时使用 Component 装饰器修饰组件类。但什么是装饰器?它的工作原理是什么样的呢? 本系列带大家深入理解 Angular 中的装饰器

什么是装饰器(Decorator)?

装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。 如果读者有其它高级语言(比如Java, C#等)的一些经验,就会发现这和其它语言中的注解(annation)很相似。

装饰器使用 @expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。装饰器本身其实就是一个函数,理论上忽略参数的话,任何函数都可以当做装饰器使用。

一个最简单的装饰器(Decorator)

新建一个 hello.ts 文件,在文件中定义函数 Hello 如下:

1
2
3
4
5
function Simple() {
return function(target: any) {
console.log('This is a simple');
}
}

这样就得到了一个装饰器: Hello, 采用的是闭包的定义方式,参数 who 是装饰器能能接收的参数。下面让我们在类中使用这个装饰器, 简单的定义一个类,给它加上 Hello 装饰器,

1
2
3
4
@Simple()
class SimpleClass {

}

编译 typescript, 将生成对应的 hello.js 文件,如果编译时遇到 ts1219 的错误,可以参考 处理 error TS1219 (Experimental support for decorators is a feature that is subject to change in a future release) 错误 然后在 node 中运行

1
2
tsc -p ./
node hello.js

系统将输出:

1
This is a simple

从运行结果可以看到,Simple中返回的函数被执行了。但我们在 hello.ts 中并没有写任何调用函数的代码,也没有写任何使用 SimpleClass 的代码(包括 new 一个类的实例)。那这段代码时怎么执行的呢?

其实魔术就在 javascript 代码编译的时候完成的,我们知道 typescript 需要编译为 javascript 在运行,但其实 javascript 在运行之前也需要编译,装饰器就是一个在 javascript 编译阶段执行的函数。所以我们看到的结果就是并没有写调用函数和使用类的代码,但装饰器还是被执行了。也就是说,通过装饰器这样的语法,我们获得了在编译阶段执行指定操作的能力。

下一步

下一篇文章 ,我们将开始向大家展示不同类型的装饰器(Decorator)

附 - 执行案例所必要的设置

在TypeScript中装饰器还属于实验性语法,所以要想使用必须在配置文件中 tsconfig.json 编译选项中开启,在 Angular 项目中,这个开关在项目目录下的 tsconfig.json 文件中,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"module": "esnext",
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es2015",
"typeRoots": [
"node_modules/@types"
],
"lib": [
"es2018",
"dom"
]
}
}

选项 experimentalDecorators 指明在当前的项目中是否启用装饰器,默认为 true。 如果不是在 Angular 环境,可以参考 处理 error TS1219 (Experimental support for decorators is a feature that is subject to change in a future release) 错误 进行设置

本文标题:深入理解 Angular 中的装饰器(一)

文章作者:梅老师

发布时间:2019年07月06日 - 21:07

最后更新:2020年05月28日 - 16:05

原始链接:https://www.mls-tech.info/web/angular/angular-typescript-decorator/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。