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. Qt官方开发环境生成的exe发布方式

    本来想自己写一个打包程序的文章了,但是我发现了宝贝,在这里,大神写的比我牛逼的多了,这里做一下搬运工 一是为了方便大家 二是为了以后方便自己找 原文链接:http://tieba.baidu.com/ ...

  2. 【CSV数据文件】

    文件参数化设置方法

  3. Java进阶知识点:并发容器背后的设计理念

    一.背景 容器是Java编程中使用频率很高的组件,但Java默认提供的基本容器(ArrayList,HashMap等)均不是线程安全的.当容器和多线程并发编程相遇时,程序员又该何去何从呢? 通常有两种 ...

  4. Python3 迭代器,生成器,装饰器

    1.迭代器 迭代器有两个基本方法,iter()和next(),next()完成后会引发StopIteration异常 a='abcdef' b=iter(a) #创建迭代器对象 print(type( ...

  5. 十面阿里,七面头条,六个Offer,春招结束

    作者:jkgeekjack链接:https://www.nowcoder.com/discuss/80156?type=0&order=0&pos=13&page=2来源:牛客 ...

  6. 阿里云服务器 操作实战 部署C语言开发环境(vim配置,gcc) 部署J2EE网站(jdk,tomcat)

    . 作者 :万境绝尘  转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/18964835 . 博客总结 : 设置SecureCRT ...

  7. java — JVM调优

    数据类型 Java虚拟机中,数据类型可以分为两类:基本类型和引用类型.基本类型的变量保存原始值,即:他代表的值就是数值本身:而引用类型的变量保存引用值.“引用值”代表了某个对象的引用,而不是对象本身, ...

  8. iOS开发UIColor,CGColor,CIColor三者的区别和联系

    最近看了看CoreGraphics的东西,看到关于CGColor的东西,于是就想着顺便看看UIColor,CIColor,弄清楚它们之间的区别和联系.下面我们分别看看它们三个的概念: 一.UIColo ...

  9. 身份证验证php

    /**  * 验证身份证号  * @param $vStr  * @return bool  */ function isCreditNo($vStr) {     $vCity = array(   ...

  10. 第三部分shell编程3(shell脚本2)

    7. if 判断一些特殊用法 if [ -z $a ] 这个表示当变量a的值为空时会怎么样if grep -q '123' 1.txt; then 表示如果1.txt中含有'123'的行时会怎么样if ...