美文网首页
ES6学习笔记(30)之 Decorator

ES6学习笔记(30)之 Decorator

作者: 苦苦修行 | 来源:发表于2019-09-30 10:22 被阅读0次

参考:ECMAScript 6 入门

Decorator还没有定案

什么是装饰器?

  • 装饰器(Decorator)是一种与类(class)相关的语法,用来注释或修改类和类方法
  • 装饰器是一种函数,写成@函数名。它可以放在类和类方法的定义前面

举例:

@frozen class Foo {
  @configurable(false)
  @enumerable(true)
  method() {}

  @throttle(500)
  expensiveMethod() {}
}

解释:
位置:@frozen用在类本身,@configurable(false) @enumerable(true) @throttle(500)用在类方法。
目的:增加或修改类的功能。

装饰器什么时候起作用?

装饰器能在编译阶段运行代码。也就是说,装饰器本质就是编译时执行的函数。

类装饰器

  • 如何写一个类装饰器?
@testable
class MyTestableClass {
  // ...
}
MyTestableClass.isTestable // true

// 这就是装饰器的实现,target代码目标类,它本质是一个函数
function testable(target) {
  target.isTestable = true;
}

基本上,装饰器的行为就是下面这样:

function decorator(target){
    target.hasDecorator = true;
}

@decorator
class A {}

// 等同于

class A {}
A = decorator(A) || A; 

分析最后一段代码:很显然,decorator(A)没有返回值,或decorator(A)返回值为undefined,根据||运算的特点,首先会运行decorator(A),于是操作了target,然后发现返回undefined,于是使用||后面的A进行赋值,又因为在decorator(A)A就是target,所以A = decorator(A) || A就等到了最新的A

  • 如果我想给 Decorator 传参数怎么办?那就再包一层
function testable(isTestable) {
  return function(target) {
    target.isTestable = isTestable;
  }
}

@testable(true)
class MyTestableClass {}
MyTestableClass.isTestable // true

@testable(false)
class MyClass {}
MyClass.isTestable // false

方法装饰器

与类装饰器大同小异,主要看实现

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;
}

// 以下是装饰器是如何执行的
// class的方法都是绑定到类的原型对象上的,所以target是Person.prototype

readonly(Person.prototype, 'name', descriptor);
// 类似于
Object.defineProperty(Person.prototype, 'name', descriptor);

如果有多个 Decorator 如何执行,顺序是怎样的?

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

上面代码中,外层装饰器@dec(1)先进入,但是内层装饰器@dec(2)先执行。

Proxy 与 Decorator 的异同

proxy 和 decorator 都可以改变行为,不同的是,proxy 是通过一个中间件对象实现的,原对象没有改变;而decorator是直接改变原对象。

Mixin 与 Trait 模式是 Decorator 的编排方式,在此不再详解

相关文章

  • ES6学习笔记(30)之 Decorator

    参考:ECMAScript 6 入门 Decorator还没有定案 什么是装饰器? 装饰器(Decorator)是...

  • 用Decorator优化React

    什么是decorator decorator是ES6的一个新特性,可以修改class的属性 通过decorator...

  • [总结]ES6 Array

    学习es6时做得小笔记

  • ES6之修饰器Decorator

    ES6为类提供修改行为的修饰器函数Decorator,修饰器是一个对类进行处理的函数,它的第一个参数就是要修...

  • ES6学习笔记

    ES6学习笔记之字符串模板 对运算的支持let a=1;let b=2;let result=${a+b};doc...

  • spark_learn

    Angular2学习笔记——NgModule es6 新增的map和foreach AngularJS2.0 学习...

  • JavaScript(ES6) - Decorator

    类的修饰 修饰器(Decorator)是一个函数,用来修改类的行为。这是ES7的一个提案,目前Babel转码器已经...

  • [Decorator] 学习

    # Javascript 中的装饰器 # ES6 系列之我们来聊聊装饰器

  • Traits-decorator

    traits-decorator 本文主要为基于 Decorator 的 Mixin 的实现,学习或使用过类(cl...

  • Ant Design Pro的知识储备

    Less 笔记 Less 官方文档 ReactJs笔记 ReactJs官方文档 ES6笔记 ES6文档 dvaJs...

网友评论

      本文标题:ES6学习笔记(30)之 Decorator

      本文链接:https://www.haomeiwen.com/subject/fxpcuctx.html