1. 程式人生 > 實用技巧 >Decorator學習(一)----- 基礎知識

Decorator學習(一)----- 基礎知識

1、Decorator基礎

  • 裝飾器本質就是編譯時執行的函式;
  • 特點
    • 不更改原有物件的結構和功能;
    • 為已有物件新增新的功能;
  • Decorator型別
    • 類的裝飾(所要修飾的目標類將會作為裝飾器函式的第一個引數
      • 含有一個引數(新增靜態屬性,只能在類上訪問,無法在例項上訪問,例項訪問為undefined)
        <template>
            <div id="decorator">
                decorator學習
            </div>
        </template>
        
        <script>
            @testDecorator
            class
        Person { constructor(name, age) { this.name = 'wxh'; this.age = '18' } eat() { console.log("我會吃~~~~") } } function testDecorator(target) { target.job = "I'm a teacher" } export default { name: 'decorator
        ', components: {}, data() { return {}; }, computed: {}, methods: { }, mounted() { console.log(Person.job)//I'm a teacher } }; </script> <style></style>
      • 含有多個引數(新增靜態屬性,只能在類上訪問,無法在例項上訪問,例項訪問為undefined)
        <template>
            <div id="
        decorator"> decorator學習 </div> </template> <script> import { JOB_GRADE } from './index'//是一個常量 @testDecorator(JOB_GRADE) class Person { constructor(name, age) { this.name = 'wxh'; this.age = '18' } eat() { console.log("我會吃~~~~") } } function testDecorator(jobGrade) { return function (target) { target.job = jobGrade } } export default { name: 'decorator', components: {}, data() { return { }; }, computed: {}, methods: { }, mounted() { console.log(Person.job)//I'm a junior teacher } }; </script> <style></style>
      • 新增例項屬性
        function testDecorator(jobGrade) {
            return function (target) {
                target.prototype.job = jobGrade
            }
        }
        
        console.log(new Person().job)//I'm a junior teacher
      • <template>
            <div id="decorator">
                decorator學習
            </div>
        </template>
        
        <script>
            import { projectHandler } from './index'
            @mixinsMethod(projectHandler)
            class Person {
                constructor(name, age) {
                    this.name = 'wxh';
                    this.age = '18'
                }
                eat() {
                    console.log("我會吃~~~~")
                }
            }
            function mixinsMethod(...params) {
                return function (target) {
                    Object.assign(target.prototype, ...params)
                }
            }
            export default {
                name: 'decorator',
                components: {},
                data() {
                    return {
        
                    };
                },
                computed: {},
                methods: {
          
                },
                mounted() {
                    console.log(new Person().projectHandler())//The subject I teach is mathematics
                }
            };
        </script>
        <style></style>
        
        
        //index.js
        export let projectHandler = {
            projectHandler() {
                console.log("The subject I teach is mathematics")
            }
        }
        View Code
    • 類的方法的裝飾:如果同一個方法有多個裝飾器,會像剝洋蔥一樣,先從外到內進入,然後由內向外執行。
      <template>
          <div id="decorator">
              decorator學習
          </div>
      </template>
      
      <script>
          class Person {
              constructor(name, age) {
                  this.name = 'wxh';
                  this.age = '18'
              }
              @testDecorator(1)
              @testDecorator(2)
              eat() {
                  console.log("我會吃~~~~")
              }
          }
          function testDecorator(id) {
              console.log(`enter${id}`)
              return (target, name, descriptor) => {
                  console.log(`execute${id}`)
                  console.log(target)//類的原型物件,Person.prototype
                  console.log(name)//修飾的屬性名,即類的方法 eat 
                  console.log(descriptor)//該屬性的描述物件,物件如下
                  // {
                  //     configurable: true//能否使用delete、能否需改屬性特性、或能否修改訪問器屬性、,false為不可重新定義,預設值為true
                  //     enumerable: false//物件屬性是否可通過for-in迴圈,flase為不可迴圈,預設值為true
                  //     value: ƒ eat()
                  //     writable: true//物件屬性是否可修改,flase為不可修改,預設值為true
                  // }
                  console.log("結束------")
              }
          }
          export default {
              name: 'decorator',
              components: {},
              data() {
                  return {
      
                  };
              },
              computed: {},
              methods: {
               
              },
              mounted() {
                  console.log(new Person().eat())
              }
          };
      </script>
      <style></style>
      View Code

      執行結果為:

      enter1
      enter2
      
      execute2
      {constructor: ƒ, eat: ƒ}
      eat
      {value: ƒ, writable: true, enumerable: false, configurable: true}
      結束------
      
      execute1
      {constructor: ƒ, eat: ƒ}
      eat
      {value: ƒ, writable: true, enumerable: false, configurable: true}
      結束------
      
      我會吃~~~~
    • 為什麼裝飾器不能用於函式:由於存在函式提升,使得裝飾器不能用於函式,而類是不會提升的,所以沒有這方面的問題;

2、利用裝飾器實現自動釋出事件

暫時有緊急的任務,稍後繼續補充~~

3、遇到的問題

暫無