1. 基本形式

@decorator
class A {} // 等同于 class A {}
A = decorator(A);

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

2. 装饰器的执行顺序

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

function dec(id){
console.log('evaluated', id);
return (target, property, descriptor) => console.log('executed', id);
} class Example {
@dec(1)
@dec(2)
method(){}
}
// evaluated 1
// evaluated 2
// executed 2
// executed 1

3. 常见的装饰器的例子

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

@testable
class MyTestableClass {
// ...
} function testable(target) {
target.isTestable = true;
} MyTestableClass.isTestable // true

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

//testable是一个Factory
function testable(isTestable) {
return function(target) {
target.isTestable = isTestable;
}
} @testable(true)
class MyTestableClass {}
MyTestableClass.isTestable // true @testable(false)
class MyClass {}
MyClass.isTestable // false

2. 属性readonly装饰器

class Person {
@readonly
name() { return `${this.first} ${this.last}` }
} function readonly(target, name, descriptor){
// descriptor对象原来的值如下
// {
// value: specifiedFunction,
// enumerable: false,
// configurable: true,
// writable: true
// };
descriptor.writable = false;
return descriptor;
}

3. 日志装饰器

class Math {
@log
add(a, b) {
return a + b;
}
} function log(target, name, descriptor) {
var oldValue = descriptor.value; descriptor.value = function() {
console.log(`Calling "${name}" with`, arguments);
return oldValue.apply(null, arguments);
}; return descriptor;
} const math = new Math(); // passed parameters should get logged now
math.add(2, 4);

3. 实现memoize,备用录模式

class Person {
@memoize
get name() { return `${this.first} ${this.last}` }
set name(val) {
let [first, last] = val.split(' ');
this.first = first;
this.last = last;
}
} let memoized = new WeakMap();
function memoize(target, name, descriptor) {
let getter = descriptor.get, setter = descriptor.set; descriptor.get = function() {
let table = memoizationFor(this);
if (name in table) { return table[name]; }
return table[name] = getter.call(this);
} descriptor.set = function(val) {
let table = memoizationFor(this);
setter.call(this, val);
table[name] = val;
}
} function memoizationFor(obj) {
let table = memoized.get(obj);
if (!table) { table = Object.create(null); memoized.set(obj, table); }
return table;
}

参考: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. Python3安装pywin32模块

    假如你安装的是Python3.6, 那么可以直接用PyCharm或者pip安装pywin32模块: 但是, 由于我安装的是Python3.7, 所以PyCharm或者pip都无法成功安装pywin32 ...

  2. Linux命令应用大词典-第26章 模块和内核管理

    26.1 lsmod:显示内核中模块的状态 26.2 get_module:查看内核模块详细信息 26.3 modinfo:显示内核模块信息

  3. 第5章 Linux网络编程基础

    第5章 Linux网络编程基础 5.1 socket地址与API 一.理解字节序 主机字节序一般为小端字节序.网络字节序一般为大端字节序.当格式化的数据在两台使用了不同字节序的主机之间直接传递时,接收 ...

  4. Unity OBB分包(基础APK+OBB) 与apk签名

    1.OBB (Opaque Binary Blob)文件格式,是安卓游戏通用数据包.在一些大型游戏上较为常见,同时还附以Data文件,亦或是md5.dat文件出现 产生原因:由于某些平台对于apk上传 ...

  5. C 计算员工工资

    #include <stdio.h> int main(int argc, char **argv) { //定义四个变量 g每小时固定的工资 40 固定工作时间 pay工资 hours员 ...

  6. 深入理解java虚拟机学习笔记(一)

    第二章 Java内存区域与内存溢出异常 运行时数据区域 程序计数器(Program Counter Register) 程序计数器:当前线程所执行的字节码行号指示器.各条线程之间计数器互不影响,独立存 ...

  7. (python)leetcode刷题笔记04 Median of Two Sorted Arrays

    4. Median of Two Sorted Arrays There are two sorted arrays nums1 and nums2 of size m and n respectiv ...

  8. 三:Fair Scheduler 公平调度器

    参考资料: http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/FairScheduler.html http://h ...

  9. Thunder团队第三周 - Scrum会议3

    Scrum会议3 小组名称:Thunder 项目名称:i阅app Scrum Master:代秋彤 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传 ...

  10. Java学习个人备忘录之构造函数&this

    构造函数 概念:构建创造对象时调用的函数. 作用:可以给对象进行初始化,创建对象都必须要通过构造函数初始化. 一个类中如果没有定义过构造函数,那么该类中会有一个默认的空参数构造函数.如果在类中定义了指 ...