实验性的特性,需要在tslint里面把这项设置为true

作用域类的声明方法、访问符、属性和参数上
使用@符号加一个名字来定义,名字必须是一个函数,或者求值后是一个函数

装饰器工厂,setPro当做一个装饰器工厂,里面返回一个函数的结果。
调用的时候直接@setProp() 后面加上括号去调用

装饰器组合使用,装饰器工厂是从上往下调用,普通的装饰器是从下往上一次执行

如果都是装饰器工厂,就是从上向下执行,依次就出来装饰器工厂内的值

定义两个装饰器工厂

  在类的上面加上装饰器的工厂,从上到下执行装饰器工厂,求完值之后,再从后往前执行这个装饰器逻辑

类装饰器在类声明之前声明


判断sign是不是等于类ClassDec

sign是否等于原型对象上的构造函数,也是true

判断相等说明他们是同一个对象,通过装饰器,我们可以修改类的远行对象或构造函数


所以我们要定义文件接口通过声明合并来解决这个问题
在ClassD后面定义一个接口叫做ClassD和类ClassD的名字相同。这样classD就有了name属性了。

这样就打印出了类的属性,通过装饰器把name属性修改成了name

使用了。同名的 接口和同名的类,进行声明合并以后,name添加到了类的原型对象上,所以我们也可以拿到它的值
如果类装饰器返回一个值,那么会使用这个返回的值替代被装饰的类的声明,所以我们使用这个特性去修改类的实现。但是要注意的是我们要自己处理我们的原型链
可以通过装饰器来覆盖类里面的一些操作,可以看一下官方的一个例子

14分53秒
首先定义一个装饰器,给它使用一个泛型,并且进行约束,它是一个类, 构造函数,接收任意多的参数,返回值是一个对象


接收一个target参数

返回一个class定义,继承target构造函数 这个类,在这个实例上添加两个属性,一个是NewProperty 一个是hello

定义好装饰器工厂,接下来来定义一个类,也在类上添加两个属性

在类Greeter前面使用装饰器,这里是装饰器而不是装饰器工厂

装饰器返回了一个类,并且是继承了被修饰的这个类,target就是指的被修饰的类

给这个类传一个world字符串

装饰器返回的是一个类,这个类又继承了被修饰的类,装饰器返回的这个类会替换被装饰的类的声明,所有新创建的这个类既包含原来类的属性,又包含了新定义的属性,使用新的类替换了这个类之后,Greeter就是这两个雷结合之后的类

修改装饰器,返回的类不再继承被修饰的类

方法装饰器

用来处理类中的方法,可以处理方法的属性描述符,方法的定义,在运行的时候也是被当做函数调用的
,包含三个参数,分两种情况,第一个如果装饰的是静态成员的情况,参数代表的就是类的构造函数,如果装饰的是实例成员的时候,参数1就是累的原型对象
参数2是成员的名字
参数3是成员的属性描述符
先来补充一个js的知识,属性装饰符。对象可以设置属性,如果属性值是函数,那么这个函数成为方法,每一个属性和方法在定义的时候都伴随三个示例描述符
分别代表可配置、可写、可枚举

要修改属性描述符他要用es5有的Object.defineProperty 方法,参数1是我们创建的UI对象,参数2你要处理的属性名或方法名,参数3就是对象用来设置属性描述符,
它有四个值,第一个值是Value:也就是我们要给这个属性设置的名字,可以是实际的字符串或者number类型的值,也开始是一个函数,如果你设置为一个函数呢,这个属性就称之为方法
现在先设置为一个字符串的值,

第二设置可写性,设置为false那么就是不可写的

可配置的,可枚举的

输出,上面就有个name属性

访问下它的name值,提示不存在


所以先给他指定类型,定义一个接口

因为设置了可写性是false,所以这里修改了name的值再去打印出来还是原来的值


可枚举关闭后,for循环这个对象,里面什么也输出不了

定义的时候默认加一个age属性,就可以输出了,因为我们通过defineProperty设置的是name属性

可枚举属性打开,就可以输出name的值

可配置型

在上面先设置了name属性,可写性为false,看配置型为false
下面又定义了一遍name属性,设置可写行为true,但是就报错了 不能重复定义。
可配置性是不可逆的操作,如果期初设置了可配置性为false,后续就不能再通过deineProperty去修改属性修饰符了

方法装饰器对于属性描述符的相关操作,所有不支持es5的浏览器无法支持属性描述符
定义一个装饰器
description.enumerable=bool表示设置属性描述符
propertyName是方法的名字

第三个参数是一个对象,包含了三个属性描述符


getAge方法上用装饰器

当方法装饰器装饰的是静态成员时,是构造函数,装饰的是实例成员时是类的原型对象,还有类的原型对象上定义的方法它的target也是类的原型对象
打印出的target就是被修饰的类的构造函数

propertyName是方法的名字

第三个参数:PropertyDescruotionMap

定义了他的接口,有三个可选值,还有属性值value

这里直接修改它的属性值,是否可枚举就可以了

遍历它的值,只遍历到了age属性

可枚举设置为true,不光是有age,继承过来的getAge也打印出来了

就是这个方法装饰器,就可以控制方法或者属性的可枚举性
如果方法装饰器返回一个值,那么就会用这个值作为方法的属性描述符对象,也就是相当于下面这个

修改这个装饰器:

再加一个返回值类型为any

创建实例后调用getAge方法

这是因为方法装饰器返回的值,他会用这个值作为这个属性描述符对象,做一个替换

通过方法装饰器,即可以修改方法或者属性的属性的属性描述符的值,还可以直接替换他的实现,这里还是要提醒一下,当构建目标小于es5的时候,方法装饰器的返回值会被忽略

访问器装饰器

也就是之前讲的get和set存取值函数,一个在设置属性值的时候触发,一个在获取属性值的时候触发
ts不允许同时装饰成员的get和set访问器

访问器装饰器也有三个参数,这个三个参数和方法装饰器是一模一样的




定义name 的存取器

在get上面加装饰器

不能同时给get和set同时加装饰器

创建实例,打印实例的属性,打印出来的只有下划线name

如果去掉装饰器,既有下划线name也有name

如果设置了装饰器为true同样也是两个值

属性装饰器

声明在属性的声明之前,有两个参数,和方法装饰器的前两个参数是一样的,就是没有属性描述符对象。
属性装饰器没法操作属性的属性描述符,只能判断某个类中是否声明了某个名字的属性

参数1被修饰的目标,参数2属性名。这里直接打印了属性名

给的属性name使用了装饰器

参数装饰器

也有三个参数,前两个和方法装饰器是一样的。
参数1:装饰静态成员的时候是类的构造函数,装饰实例成员或者类的原型对象的时候是类的原型对象
参数2:成员的名字,修饰的成员的名字
参数3:参数在函数的参数列表中的索引
参数装饰器的返回值会被忽略



定义方法getInfo,输出前缀和要传入的属性名的值

再定义一个接口可以有任意多的属性,属性类型可以是string 可以是number也可以是个function(函数)

实例类ClassI,调用继承过来的getInfo方法,传入参数1:hihi 参数2:age属性

在infoType这个属性前面使用装饰器,

就会输出console内容

装饰器是一个实验性的功能,在生产环境上尽量不使用,以后可能会有颠覆性的修改

TypeScript完全解读(26课时)_17.装饰器的更多相关文章

  1. TypeScript完全解读(26课时)_汇总贴

    ECMAScript 6 入门:http://es6.ruanyifeng.com/ 官网:http://www.typescriptlang.org/ 中文网:https://www.tslang. ...

  2. TypeScript完全解读(26课时)_9.TypeScript完全解读-TS中的类

    9.TypeScript完全解读-TS中的类 创建class.ts文件,并在index.ts内引用 创建一个类,这个类在创建好后有好几个地方都标红了 这是tslint的一些验证规则 一保存就会自动修复 ...

  3. TypeScript完全解读(26课时)_12.TypeScript完全解读-高级类型(1)

    12.TypeScript完全解读-高级类型(1) 高级类型中文网的地址:https://typescript.bootcss.com/advanced-types.html 创建新的测试文件 ind ...

  4. TypeScript完全解读(26课时)_1.TypeScript完全解读-开发环境搭建

    1.TypeScript完全解读-开发环境搭建 初始化项目 手动创建文件夹 D:\MyDemos\tsDemo\client-demo 用VSCode打开 npm init:初始化项目 然后我们的项目 ...

  5. TypeScript完全解读(26课时)_2.TypeScript完全解读-基础类型

    2.TypeScript完全解读-基础类型 src下新建example文件夹并新建文件.basic-type.ts.截图中单词拼错了.后需注意一下是basic-type.ts 可以装tslint的插件 ...

  6. TypeScript完全解读(26课时)_4.TypeScript完全解读-接口

    4.TypeScript完全解读-接口 初始化tslint tslint --init:初始化完成后会生成tslint.json的文件 如果我们涉及到一些规则都会在这个rules里面进行配置 安装ts ...

  7. TypeScript完全解读(26课时)_5.TypeScript完全解读-函数

    5.TypeScript完全解读-函数 新建function.ts.然后在index.ts内引用 给函数定义参数类型:上面是es5的写法 下面是ts6的写法 一个完整的函数类型.括号 箭头 numbe ...

  8. TypeScript完全解读(26课时)_6.TypeScript完全解读-泛型

    6.TypeScript完全解读-泛型 创建实例ts文件generics.ts 在index.ts内引入 fill是填充数组,创建的数组的元素数是times,填充的值就是接收的value的值 这里传入 ...

  9. TypeScript完全解读(26课时)_8.ES6精讲-ES6中的类(进阶)

    8.TypeScript完全解读-ES6精讲-类(进阶) 在index.ts内引入 Food创建的实例赋值给Vegetabled这个原型对象,这样使用Vegetables创建实例的时候,就能继承到Fo ...

随机推荐

  1. struct platform_device中的id成员

    include/linux/platform_device.h #define PLATFORM_DEVID_NONE (-1) #define PLATFORM_DEVID_AUTO (-2) dr ...

  2. 使用 Kingfisher 处理网络图片的读取与缓存

    Kingfisher 是一个读取网络图片和处理本地缓存的开源库,由 onevcat 开发.提到图片缓存库,那么熟悉 Objective-C 开发的同学,可能会想起 SDWebImage. 没错,Kin ...

  3. 《好好说话》zz

    最近,<奇葩说>闹出来了一些不愉快. 在半决赛中,姜思达惜败,愤怒的粉丝把矛头指向那场比赛的其他人.最终,马薇薇.黄执中和网友们吵起来了. 这件事本不算大事,毕竟娱乐业就是这个样子.刚刚好 ...

  4. 【Spark Core】TaskScheduler源代码与任务提交原理浅析2

    引言 上一节<TaskScheduler源代码与任务提交原理浅析1>介绍了TaskScheduler的创建过程,在这一节中,我将承接<Stage生成和Stage源代码浅析>中的 ...

  5. kubernetes集群管理常用命令一

    系列目录 我们把集群管理命令分为两个部分,第一部分介绍一些简单的,但是可能是非常常用的命令以及一些平时可能没有碰到的技巧.第二部分将综合前面介绍的工具通过示例来讲解一些更为复杂的命令. 列出集群中所有 ...

  6. g++ 6.4编译opencv-2.4.10报错记录

      fetch公司的项目进行编译,此项目依赖opencv库.由于本人一直比较偏爱fedora,但也因此给我带来了许多"乐趣"(麻烦).fedora一直走得比较前沿,g++ 6.3了 ...

  7. Centos7-安装Apache2.4+PHP5.6

    linux系统CentOS7先下载Apache需要依赖的软件1.APR下载地址http://apr.apache.org/download.cgiwget下载路径http://mirror.bit.e ...

  8. RS485总线典型电路介绍

    一.RS485总线介绍: RS485总线是一种常见的串行总线标准,采用平衡发送与差分接收的方式,因此具有抑制共模干扰的能力.在一些要求通信距离为几十米到上千米的时候,RS485总线是一种应用最为广泛的 ...

  9. iOS不用上架就能下载安装ipa应用内测:使用FIR.im发布自己的移动端APP

    本文转自:http://www.cnblogs.com/imzzk/p/firim.html 一次很偶然的机会知道fir.im,这家公司主要的产品就是帮助开发者方便便捷地发布iOS或者Android应 ...

  10. PAT天梯赛 L2-026. 小字辈 【BFS】

    题目链接 https://www.patest.cn/contests/gplt/L2-026 思路 用一个二维vector 来保存 每个人的子女 然后用BFS 广搜下去,当目前的状态 是搜完的时候 ...