ECMAScript 6 類的修飾器使用和理解

decorator 類的裝飾器


許多面向對象的語言都有修飾器(Decorator)函數,用來修改類的行爲。

目前瀏覽器或者最近的node 8.x + 均不支持裝飾器;可採用babel轉譯:

相關文檔:

下面已babel7配置爲例:

@babel/plugin-proposal-decorators
@babel/plugin-proposal-class-properties

.babelrc 

{
    "presets": ["@babel/preset-env"],
    "plugins": [
        ["@babel/plugin-transform-runtime",{"corejs": 2}],
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        ["@babel/plugin-proposal-class-properties", { "loose" : true }]
    ]
  }

裝飾器分爲:

類的裝飾器

/**
 * @class 類的修飾器
 */
@controller('/admin')
class Point {
    constructor(obj){
       
    }
    
 }

function controller(router){
     return function (target){
         //在Point 的原型對象上添加共享屬性decorator
        target.prototype.name = `我是裝飾器${router}`
     }
 }

 console.log(new Point().name) //我是裝飾器/admin

 /**
  * 原生方法
  */

  function Point(){
    let controller= (router) =>{
        return `我是裝飾器${router}`
    }
    this.name = controller('/admin')
  }

  console.log(new Point().name) //我是裝飾器/admin

類屬性的裝飾器


class Point {
    constructor(obj){
        var {x,y} = obj
        this.x = x;
        this.y = y;
    }
    @readonly
    name(a,b){
        return  (`${this.x} ${this.y}`)
         
    }
 }
/**
 * 
 * @param {*} target 原始對象
 * @param {*} name 屬性
 * @param {*} descriptor 值
 * 類似:Object.defineProperty(Person.prototype, 'name', descriptor);
 */
 function readonly(target, name, descriptor){
    var oldValue = descriptor.value;
    
  descriptor.value = function() {
    let [a,b] = arguments;
    console.log(a) //3
    console.log(`Calling ${name} with`, arguments);
    console.log(this.x) //小明
    return oldValue.apply(this, arguments);
  };

  return descriptor;
  }
 
var b = new Point({x:'小明',y:123})
console.log(b.name(3,888))

 

下面是使用案例:

/**
 * @class 類的修飾器
 */
@testable
class Point {
    constructor(obj){
        var {x,y} = obj
        this.x = x;
        this.y = y;
    }
    @readonly
    name(a,b){
        return  (`${this.x} ${this.y}`)
         
    }
 }
/**
 * 
 * @param {*} target 原始對象
 * @param {*} name 屬性
 * @param {*} descriptor 值
 * 類似:Object.defineProperty(Person.prototype, 'name', descriptor);
 */
 function readonly(target, name, descriptor){
    var oldValue = descriptor.value;
    
  descriptor.value = function() {
    let [a,b] = arguments;
    console.log(a) //3
    // console.log(`Calling ${name} with`, arguments);
    // console.log(this.x)
    return oldValue.apply(this, arguments);
  };

  return descriptor;
  }
  /**
   * 
   * @param {*} target 類的修飾器
   * 類似:Object.prototype | Object.xxx
   * 可以給原型鏈添加屬性和方法讓實例共享其屬性 | 可以給類添加靜態屬性方法
   */
  function testable(target) {
    target.prototype.isTestable = true;
  }
var b = new Point({x:'小明',y:123})
console.log(b.name(3,888))

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章