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)先执行

    注意事项

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

    优秀文章首发于聚享小站,欢迎关注!
  • 相关阅读:
    带权并查集
    Dungeon Master (luo 三维 BFS )
    迷宫问题 (最短路径保存输出)
    Aggressive cows (北京大学ACM-ICPC竞赛训练暑期课 )
    滑雪 (北京大学ACM-ICPC竞赛训练暑期课 )
    棋盘问题 (北京大学ACM-ICPC竞赛训练暑期课 )
    简单的整数划分问题 ( 北京大学ACM-ICPC竞赛训练暑期课 )
    马走日 (DFS)
    蓝桥杯 (计算路径)
    最长单词 (分割字符串)(蓝桥杯-算法提高)
  • 原文地址:https://www.cnblogs.com/yesyes/p/15352371.html
Copyright © 2011-2022 走看看