1.类的修饰:

修饰器(Decorator)函数,用来修改类的行为。
修饰器是一个对类进行处理的函数。修饰器函数的第一个参数,就是所要修饰的目标类。

  1. @testable
  2. class MyTestableClass {
  3. // ...
  4. }
  5.  
  6. function testable(target) {
  7. target.isTestable = true;
  8. }
  9.  
  10. MyTestableClass.isTestable

上面代码中,@testable就是一个修饰器。它修改了MyTestableClass这个类的行为,为它加上了静态属性isTestabletestable函数的参数targetMyTestableClass类本身。参数target,就是会被修饰的类。

如果觉得一个参数不够用,可以在修饰器外面再封装一层函数。

  1. function testable(isTestable) {
  2. return function(target) {
  3. target.isTestable = isTestable;
  4. }
  5. }
  6.  
  7. @testable(true)
  8. class MyTestableClass {}
  9. MyTestableClass.isTestable // true
  10.  
  11. @testable(false)
  12. class MyClass {}
  13. MyClass.isTestable // false

注意,修饰器对类的行为的改变,是代码编译时发生的,而不是在运行时。这意味着,修饰器能在编译阶段运行代码。也就是说,修饰器本质就是编译时执行的函数。

前面的例子是为类添加一个静态属性,如果想添加实例属性,可以通过目标类的prototype对象操作。

  1. function testable(target) {
  2. target.prototype.isTestable = true;
  3. }
  4.  
  5. @testable
  6. class MyTestableClass {}
  7.  
  8. let obj = new MyTestableClass();
  9. obj.isTestable // true

上面代码中,修饰器函数testable是在目标类的prototype对象上添加属性,因此就可以在实例上调用。

实际开发中,React 与 Redux 库结合使用时,常常需要写成下面这样。

  1. class MyReactComponent extends React.Component {}
  2. export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);

有了装饰器,就可以改写上面的代码。

  1. @connect(mapStateToProps, mapDispatchToProps)
  2. export default class MyReactComponent extends React.Component {}

2.方法的修饰:

修饰器不仅可以修饰类,还可以修饰类的属性。

  1. function readonly(target, name, descriptor) {
  2. // descriptor对象原来的值如下
  3. // {
  4. // value: specifiedFunction, //该属性对应的值
  5. // enumerable: false,// 为true时,才能够出现在对象的枚举属性中
  6. // configurable: true,// 为true时,该属性描述符才能够被改变
  7. // writable: true // 为true时,value才能被赋值运算符改变
  8. // };
  9. descriptor.writable = false
  10. return descriptor
  11. }
  12.  
  13. class Person {
  14. @readonly
  15. say () {
  16. console.log("hellow!!")
  17. }
  18. }
  19.  
  20. let p = new Person()
  21. p.say = function () {
  22. console.log("你好!")
  23. }
  24.  
  25. // 由于设置了writable=false,所以不允许修改
  26. p.say() // hellow!!

上面代码中,修饰器readonly用来修饰“类”的name方法。

修饰器函数readonly一共可以接受三个参数。

  1. readonly(Person.prototype, 'say', descriptor);
  2. // 类似于
  3. Object.defineProperty(Person.prototype, 'say', descriptor);

修饰器第一个参数是类的原型对象,上例是Person.prototype,修饰器的本意是要“修饰”类的实例,但是这个时候实例还没生成,所以只能去修饰原型(这不同于类的修饰,那种情况时target参数指的是类本身);第二个参数是所要修饰的属性名,第三个参数是该属性的描述对象。

另外,上面代码说明,修饰器(readonly)会修改属性的描述对象(descriptor),然后被修改的描述对象再用来定义属性。

修饰器传参(用法同类的修饰器,可以在修饰器外面再封装一层函数):

  1. function dec(id){
  2. console.log('evaluated', id);
  3. return (target, property, descriptor) => console.log('executed', id);
  4. }
  5.  
  6. class Example {
  7. @dec(1)
  8. @dec(2)
  9. method(){}
  10. }
  11. // evaluated 1
  12. // evaluated 2
  13. // executed 2
  14. // executed 1

如果同一个方法有多个修饰器,会像剥洋葱一样,先从外到内进入,然后由内向外执行。上面代码中,外层修饰器@dec(1)先进入,但是内层修饰器@dec(2)先执行。

修饰器只能用于类和类的方法,不能用于函数,因为存在函数提升(如果一定要修饰函数,可以采用高阶函数的形式直接执行。)

借鉴阮一峰的Es6教程:http://es6.ruanyifeng.com/#docs/decorator

es6 Decorator修饰器的更多相关文章

  1. ES6(Decorator(修饰器))

    Decorator(修饰器) 1.基本概念 函数用来修改 类 的行为 1.Decorator 是一个函数 2.通过Decorator(修饰器)能修改 类 的行为(扩展 类 的功能)3.Decorato ...

  2. ES6 Decorator 修饰器

    目的:  修改类的一种方法,修饰器是一个函数 编译: 安装 babel-plugin-transform-decortators-legacy .babelrd      plugins: [&quo ...

  3. 19.Decorator修饰器

    Decorator 修饰器 类的修饰 许多面向对象的语言都有修饰器(Decorator)函数,用来修改类的行为.目前,有一个提案将这项功能,引入了 ECMAScript. @testable clas ...

  4. mobx中使用class语法或decorator修饰器时报错

    之前课程中老师用的babel的版本比较低,我在学习时安装的babel版本较高,因此每当使用class语法或decorator修饰器时都会出现一些报错的情况! ❌ ERROR in ./src/inde ...

  5. js基石之---es7的decorator修饰器

    es7的decorator修饰器 装饰器(Decorator)是一种与类(class)相关的语法,用来注释或修改类和类方法. decorator就是给类添加或修改类的变量与方法的. 装饰器是一种函数, ...

  6. python decorator 修饰器

    decorator 就是给函数加一层皮,好用! 1 from time import ctime 2 3 def deco(func): 4 def wrappedFunc(*args, **kwar ...

  7. 21.Decorator修饰器

    1.类的修饰 2.方法的修饰 3.为什么修饰器不能用于函数? 4.core-decorators.js 5.使用修饰器实现自动发布事件 6.Mixin 7.Trait 8.Babel转码器的支持

  8. mobx学习笔记03——mobx基础语法(decorator修饰器)

    在声明阶段实现类与类成员注解的一种语法. function log(target){ const desc = Object.getOwnPropertyDescriotors(target.prot ...

  9. ES6里的修饰器Decorator

    修饰器(Decorator)是一个函数,用来修改类的行为. 一.概述 ES6 引入了这项功能,目前 Babel 转码器已经支持Decorator 首先,安装babel-core和babel-plugi ...

随机推荐

  1. 洛谷P1523 旅行商简化版(DP)

    题目: P1523 旅行商简化版 解析 可以看做是两个人同时从西往东走,经过不一样的点,走到最东头的方案数 设\(f[i][j]\)表示一个人走到i,一个人走到j的最短距离(\(i<j\)) 第 ...

  2. 安装Docker报container-selinux >= 2.9错

    Docker装了无数次,还是会遇到如此熟悉的问题,知道他是版本需要更新,但是就是找不到对应的,在网上找了差不多一个下午都没弄好.发现平时还是要多动脑子才行,既然知道是版本需要更新,那么到官网直接找版本 ...

  3. mybatis中的高级查询

    Mybatis作为一个ORM框架,肯定是支持sql高级查询的. 下面的一个案例来为大家详细讲解mybatis中的高级查询. 案例说明: 此案例的业务关系是用户,订单,订单详情与商品之间的关系. 以订单 ...

  4. 利用DNS日志进行MySQL盲注

    0x01 技术原理 这里是利用load_file这个函数利用smb请求方式请求域名机器下的一个文件,由于计算机对该域名不熟悉所以需要优先请求DNS,所以我们通过DNS日志记录中的内容来获取回显.解决了 ...

  5. Html快速上手

    Html 概述 HTML文档 Doctype Meta Title Link Style Script 常用标签 各种符号 p 和 br a 标签 H 标签 select input:checkbox ...

  6. 03、磁盘管理+swap分区创建+磁盘配额+自动挂载

    磁盘管理 分区标识 一般用4位标识,前两位,磁盘类型,第3位,磁盘编号,第4位,分区编号 如: /dev/sda1     sd  磁盘类型    a  磁盘编号   1  分区编号 [root@s1 ...

  7. mac运行模拟器simulator突然很慢

    一直都正常,突然变慢,而且慢的离谱. 上网查了下,这里记录下,或许问题不仅限于此. simulator->Debug->Slow Animations. 这个Slow Animations ...

  8. 201871010109-胡欢欢《面向对象程序设计(java)》第二周学习总结

    开头: 项目 内容 这个作业属于哪个课程 <任课教师博客主页链接>     https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地 ...

  9. 201671010450-姚玉婷-实验十四 团队项目评审&课程学习总结

    项目 内容 所属科目 软件工程http://www.cnblogs.com/nwnu-daizh 作业要求 https://www.cnblogs.com/nwnu-daizh/p/11093584. ...

  10. 火车头data下任务文件夹的SpiderResult.db3文件用什么软件打开

    火车头采集器默认是用sqlite数据库来保存数据的,新建一个采集,打开data/任务/发现有一个SpiderResult.db3文件,.db3是sqlite的存储文件后缀,那么要如何查看这些文件呢?用 ...