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))

 

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