zoukankan      html  css  js  c++  java
  • Decorator [ˈdekəreɪtə(r)] 修饰器/装饰器 -- 装饰模式

    装饰模式 -- 原先没有,后期添加的属性和方法

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

    需要先安装一个插件:

    npm install babel-plugin-transform-decorators-legacy --save-dev

    然后在项目根目录下,找到:.babelrc => 修改为

    "plugins": ["transform-runtime","transform-decorators-legacy"],
    

    // 添加属性,添加方法,在方法执行之前添加动作

    1.给添加一个静态方法(属性)

    function chooseCourse(target){   // 定义一个方法
      target.course = '物理';
    }
    
    function setStudy(target){
      target.study = function(){
        console.log("学习" + target.course);
      }
    }
    
    @chooseCourse    // 通过@ + 函数名,表示 用函数 chooseCourse 来修饰 类 Student,这样就给student添加了一个course,值为'物理'
    @classroom   // 因为修饰的是类,所以相当于添加了静态属性和静态方法
    class Student{};   // 定义一个类
    Student.study();

    2.修饰器带参数

    function chooseCourse(courseName){
      return function(target){   // 闭包  返回一个闭包函数
        target.courseName = courseName;
      }
    }
    
    function classroom(roomName){
      return function(target){
        target.study = function(){
          console.log('在' + roomName + '学习' + target.courseName);
        }
      }
    }
    
    @chooseCourse('物理')  // 传参  通过添加参数的方式,来添加属性和方法
    @classroom('第1教室')   // 传参
    class Student{}
    Student.study();

    3.修饰器不仅可以修饰类,还可以修饰类的方法(属性)

    function chooseCourse(courseName){
      return function(target){
        console.log('检查准考证' + target.uid);  // target中的this发生指针转移
        target.courseName = courseName;
      }
    }
    
    class Student{
      constructor(){
        this.uid = 15;
      }
      @chooseCourse('物理')   // 对类里面的属性和方法直接进行修饰 , 此处的@chooseCourse 表示 修饰 exam()方法 // 代码运行到此行才进行修饰
      exam(){  // 定义一个方法
        console.log(this.uid + '考试,考:' + this.courseName);
      }
    }  // 后面不能加 ';'
    
    let student = new Student();  // 用new方法创建一个 类的实例  new 一个 student,将student作为target传递到方法中
    student.exam();

    4.修饰器只能用于类和类的方法,不能用于函数,会导致函数提升而发生错误

    //-------------错误---------------

    @chooseCourse('物理')
    
    function Teacher(){
      teach(){
        console.log('讲师教:' + this.courseName);
      }
    }
    
    Teacher.teach();

    5.装饰模式与代理模式的差别

    装饰器模式(从外边注入属性和方法)关注于在一个对象上动态的添加方法,然而代理模式(proxy 屏蔽了原有的类,对代理进行操作,实现方法重新)关注于控制对对象的访问。换句话说,用代理模式,代理类(proxy class)可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例,并且,当我们使用装饰器模式的时候,我们通常的做法是将原始对象作为一个参数传给装饰者的构造器。

    使用代理模式,代理和真实对象之间的关系通常在编译时就已经确定了,而装饰者能够在运行时递归地被构造。

  • 相关阅读:
    250 浅拷贝Object.assign(target, ...sources),深拷贝
    249 递归:概念,利用递归求1~n的阶乘,利用递归求斐波那契数列,利用递归遍历数据
    248 闭包:概念,作用,案例,思考题案例,chrome 中调试闭包
    247 高阶函数 之 函数可以作为参数传递
    246 JavaScript严格模式
    245 改变函数内部 this 指向:call,apply,bind,call、apply、bind 三者的异同
    244 函数内部的this指向:6种
    243 函数:函数的3种定义方式,函数的6种调用方式
    242 Object.defineProperty
    241 获取对象的属性名:Object.keys(对象)
  • 原文地址:https://www.cnblogs.com/crazycode2/p/6684290.html
Copyright © 2011-2022 走看看