1. 基本形式

  1. @decorator
  2. class A {}
  3.  
  4. // 等同于
  5.  
  6. class A {}
  7. A = decorator(A);

装饰器在javascript中仅仅可以修饰类和属性,不能修饰函数。
装饰器对类的行为的改变,是代表编译时发生的,而不是在运行时。
装饰器能在编译阶段运行代码。
装饰器是经典的AOP模式的一种实现方式。

2. 装饰器的执行顺序

同一处的多个装饰器是按照洋葱模型,由外到内进入,再由内到外执行

  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

3. 常见的装饰器的例子

1. 类可测试,添加一个属性

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

若要进行更多的配置,可以使用高阶函数,增加参数,相当于一个工厂方法,用于生产特定类型的装饰器,例如:

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

2. 属性readonly装饰器

  1. class Person {
  2. @readonly
  3. name() { return `${this.first} ${this.last}` }
  4. }
  5.  
  6. function readonly(target, name, descriptor){
  7. // descriptor对象原来的值如下
  8. // {
  9. // value: specifiedFunction,
  10. // enumerable: false,
  11. // configurable: true,
  12. // writable: true
  13. // };
  14. descriptor.writable = false;
  15. return descriptor;
  16. }

3. 日志装饰器

  1. class Math {
  2. @log
  3. add(a, b) {
  4. return a + b;
  5. }
  6. }
  7.  
  8. function log(target, name, descriptor) {
  9. var oldValue = descriptor.value;
  10.  
  11. descriptor.value = function() {
  12. console.log(`Calling "${name}" with`, arguments);
  13. return oldValue.apply(null, arguments);
  14. };
  15.  
  16. return descriptor;
  17. }
  18.  
  19. const math = new Math();
  20.  
  21. // passed parameters should get logged now
  22. math.add(2, 4);

3. 实现memoize,备用录模式

  1. class Person {
  2. @memoize
  3. get name() { return `${this.first} ${this.last}` }
  4. set name(val) {
  5. let [first, last] = val.split(' ');
  6. this.first = first;
  7. this.last = last;
  8. }
  9. }
  10.  
  11. let memoized = new WeakMap();
  12. function memoize(target, name, descriptor) {
  13. let getter = descriptor.get, setter = descriptor.set;
  14.  
  15. descriptor.get = function() {
  16. let table = memoizationFor(this);
  17. if (name in table) { return table[name]; }
  18. return table[name] = getter.call(this);
  19. }
  20.  
  21. descriptor.set = function(val) {
  22. let table = memoizationFor(this);
  23. setter.call(this, val);
  24. table[name] = val;
  25. }
  26. }
  27.  
  28. function memoizationFor(obj) {
  29. let table = memoized.get(obj);
  30. if (!table) { table = Object.create(null); memoized.set(obj, table); }
  31. return table;
  32. }

参考:https://www.cnblogs.com/goloving/p/8001530.html
     https://www.cnblogs.com/whitewolf/p/details-of-ES7-JavaScript-Decorators.html

ES6装饰器Decorator基本用法的更多相关文章

  1. es6 装饰器decorator的使用 +webpack4.0配置

    decorator 装饰器 许多面向对象都有decorator(装饰器)函数,比如python中也可以用decorator函数来强化代码,decorator相当于一个高阶函数,接收一个函数,返回一个被 ...

  2. Python装饰器的另类用法

    之前有比较系统介绍过Python的装饰器(请查阅<详解Python装饰器>),本文算是一个补充.今天我们一起探讨一下装饰器的另类用法. 语法回顾 开始之前我们再将Python装饰器的语法回 ...

  3. Python装饰器的高级用法(翻译)

    原文地址 https://www.codementor.io/python/tutorial/advanced-use-python-decorators-class-function 介绍 我写这篇 ...

  4. Python函数装饰器原理与用法详解《摘》

    本文实例讲述了Python函数装饰器原理与用法.分享给大家供大家参考,具体如下: 装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值 ...

  5. python 装饰器(decorator)

    装饰器(decorator) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 装饰器(decorator)是一种高级Python语 ...

  6. python语法32[装饰器decorator](转)

    一 装饰器decorator decorator设计模式允许动态地对现有的对象或函数包装以至于修改现有的职责和行为,简单地讲用来动态地扩展现有的功能.其实也就是其他语言中的AOP的概念,将对象或函数的 ...

  7. Python的程序结构[8] -> 装饰器/Decorator -> 装饰器浅析

    装饰器 / Decorator 目录 关于闭包 装饰器的本质 语法糖 装饰器传入参数 1 关于闭包 / About Closure 装饰器其本质是一个闭包函数,为此首先理解闭包的含义. 闭包(Clos ...

  8. Python_高阶函数、装饰器(decorator)

    一.变量: Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对象的,对变量赋值就是把数据和变量给关联起来. 对变量赋值x = y是把变量 ...

  9. python 语法之 装饰器decorator

    装饰器 decorator 或者称为包装器,是对函数的一种包装. 它能使函数的功能得到扩充,而同时不用修改函数本身的代码. 它能够增加函数执行前.执行后的行为,而不需对调用函数的代码做任何改变. 下面 ...

随机推荐

  1. spring + mybatis 注解 @Transactional失效

    1.问题 在使用@Transactional注解管理事务的时候会出现很多错误,比如: *** was not registered for synchronization because synchr ...

  2. jmeter多台压力机测试

    jmeter控制机会自动将脚本发送至压力机 1.控制机配置 jmeter.properties中配置: remote_hosts=ip1:1099,ip2:1022,ip3:1099 将压力机ip+p ...

  3. 获取ip地址以及获取城市等信息

    class Program { static void Main(string[] args) { string ip = GetIP(); if (ip != null) { string city ...

  4. Unity热更新文件的服务器部署(IIS)

    1.VS新建一个"ASP.NET空网站" 工程结构如下 最好设置.Net FrameWork版本为 V4.0或者V4.5版本的,因为我们的程序最后是要部署到阿里云的虚拟服务器上的, ...

  5. 【转】APP推广什么是cpa,cps,cpm

    转载自:http://www.apptg.cn 经常做做APP推广和做运营的同学对于cpa,cps,cpm,cpc这些名词肯定不会陌生,也基本都知道其表示的含义,但是对于新手来说,这几个词的含义还是不 ...

  6. 【system.file】使用说明

    对象:system.file 说明:提供一系列针对文件操作的方法. 注意:参数中的filePath 均为相对网站根目录路径 目录: 方法 返回 说明 system.file.exists(filePa ...

  7. JDK源码分析:Short.java

    Short是基本数据类型short的包装类. 1)声明部: public final class Short extends Number implements Comparable<Short ...

  8. n! 阶乘

    其实1.2.3.4.6.7…都是可以不用考虑的,因此选择以5为迭代步数即可. 首先,这些数字都可以不用进行%5(对5取余数)运算,因此每次循环时可以直接将函数的count变量直接加1.其次,考虑25. ...

  9. C语言 命令行参数 函数指针 gdb调试

    . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21551397 | http://www.hanshul ...

  10. java中多种方式读文件

    转自:http://www.jb51.net/article/16396.htm java中多种方式读文件 一.多种方式读文件内容. 1.按字节读取文件内容 2.按字符读取文件内容 3.按行读取文件内 ...