zoukankan      html  css  js  c++  java
  • ES6功能扩展装饰器

    修饰器(Decorator)是一个函数,用来修改类的行为。

    @testable
    class Person {
      // ...
    }
    
    function testable(target) {
      target.isTestable = true
    }
    console.log(Person.isTestable); // true
    

    示例中的@testable就是一个修饰器,修改了Person类的行为,为其添加了一个静态属性isTestable

    修饰器对类的行为的改变,发生在代码编译阶段而非运行阶段。修饰器的本质其实就是编译时执行的函数

    示例中修饰器的行为类似下面这样

    class Person {
      // ...
    }
    
    function testable(target) {
      target.isTestable = true
      return target
    }
    
    Person = testable(Person) || {}
    console.log(Person.isTestable); // true
    

    参数

    修饰器的第一个参数表示要修饰的目标类

    function testable(target) {
      target.isTestable = true
    }
    

    如果还需要其他参数,可以在修饰器外面再封装一层函数

    @testable(true)
    class Person {
      // ...
    }
    
    function testable(isTestable) {
      return function(target){
        target.isTestable = isTestable
      }
    }
    console.log(Person.isTestable); // true
    

    mixins

    利用修饰器实现一个简单的mixins

    function mixins (...list) {
      return function(target) {
        Object.assign(target.prototype, ...list)
      }
    }
    
    const Age = {
      sayAge() {
        console.log(10)
      }
    }
    
    const Name = {
      sayName() {
        console.log('wmui')
      }
    }
    
    @mixins(Age,Name)
    class Person {
      // ...
    }
    
    let o = new Person();
    o.sayName() // wmui
    o.sayAge() // 10
    

    通过mixins修饰器,把Age对象和Name对象的方法添加到Person类的实例上

    方法修饰

    修饰器还可以修饰类的方法

    class Person {
      @readonly
      name() {
        return 'wmui'
      }
    }
    

    readonly修饰器函数可以接收三个参数,第一个是要修饰的目标对象,第二个是要修饰的属性名,第三个是该属性的描述对象

    class Person {
      @readonly
      sayName() {
        return 'wmui'
      }
    }
    
    function readonly(target, name, descriptor) {
      descriptor.writable = false;
      return descriptor
    }
    
    let p = new Person()
    p.sayName = 1 
    // Cannot assign to read only property 'sayName' of object
    

    由于readonly修饰器设置了sayName()方法为只读的,所以强行改变该方法会报错

    执行顺序

    如果同一个方法有多个修饰器,会像剥洋葱一样,先从外到内进入,然后由内向外执行

    function test(id) {
      console.log('进入',id)
      return function(target, name, descriptor) {
        console.log('执行',id)
      }
    }
    
    class Person {
      @test(1)
      @test(2)
      sayName(){}
    }
    // 进入 1
    // 进入 2
    // 执行 2
    // 执行 1
    

    上面示例中,外层修饰器@test(1)先进入,但是内层修饰器@test(2)先执行

    注意事项

    修饰器只能用于类和类的方法,不能用于函数,因为存在函数提升

    优秀文章首发于聚享小站,欢迎关注!
  • 相关阅读:
    This theme is released under creative commons licence, all links in the footer should remain intact解决方法 Fred
    增加ubuntu的内存——设置Swap增加内存
    OpenFlow硬件交换机制作及刷机教程
    ubuntu设置中文
    配置树莓派/Linux默认声卡设备
    github基础操作
    Linux手动添加系统环境共享库路径
    Ubuntu登录界面添加root用户登录选项
    python实现树莓派开机自动发送IP到指定邮箱
    语音信号实时采集与处理
  • 原文地址:https://www.cnblogs.com/yesyes/p/15352371.html
Copyright © 2011-2022 走看看