美文网首页
ES6的装饰器-Decorator

ES6的装饰器-Decorator

作者: 眸晓 | 来源:发表于2020-07-03 10:39 被阅读0次

装饰器(Decorator)是一种与类(class)相关的语法,用来注释或修改类和类方法。许多面向对象的语言都有这项功能。
装饰器是一种函数,写成@ + 函数名。它可以放在类和类方法的定义前面。

装饰器可以用来装饰整个类

@testable
class MyTestableClass {
  // ...
}

function testable(target) {
  target.isTestable = true;
}

MyTestableClass.isTestable // true

上面代码中,@testable就是一个装饰器。它修改了MyTestableClass这个类的行为,为它加上了静态属性isTestabletestable函数的参数targetMyTestableClass类本身。

前面的例子是为类添加一个静态属性,如果想添加实例属性,可以通过目标类的prototype对象操作。

function testable(target) {
  target.prototype.isTestable = true;
}

@testable
class MyTestableClass {}

let obj = new MyTestableClass();
obj.isTestable // true

上面代码中,装饰器函数testable是在目标类的prototype对象上添加属性,因此就可以在实例上调用。
下面是另外一个例子。

// mixins.js
export function mixins(...list) {
  return function (target) {
    Object.assign(target.prototype, ...list)
  }
}

// main.js
import { mixins } from './mixins'

const Foo = {
  foo() { console.log('foo') }
};

@mixins(Foo)
class MyClass {}

let obj = new MyClass();
obj.foo() // 'foo'

上面代码通过装饰器mixins,把Foo对象的方法添加到了MyClass的实例上面。可以用Object.assign()模拟这个功能。

const Foo = {
  foo() { console.log('foo') }
};

class MyClass {}

Object.assign(MyClass.prototype, Foo);

let obj = new MyClass();
obj.foo() // 'foo'

实际开发中,React 与 Redux 库结合使用时,常常需要写成下面这样。

class MyReactComponent extends React.Component {}

export default connect(mapStateToProps, mapDispatchToProps)(MyReactComponent);

有了装饰器,就可以改写上面的代码。

@connect(mapStateToProps, mapDispatchToProps)
export default class MyReactComponent extends React.Component {}

相对来说,后一种写法看上去更容易理解。

装饰类方法:

class Boy{
    @log
    add(a,b){
        return a+b
    }
}
function log(target,name,descriptor){
    //target是类本身
    //name 是所要装饰的类的属性名(其实就是类的方法名)
   //descriptor是该属性(方法)的描述对象
   
   let oldValue=descriptor.value;  // 先留存初始的类方法的内容
  descriptor.value=function(){
      
      //装饰这个类,给这个类新增一些要装饰的逻辑
      console.log(`calling ${name} with`,arguments);
      
      //执行原本的方法
      oldValue.apply(this,arguments)
  }
  // 返回新的描述对象,修改类方法的值
  return descriptor
}
 const math =new Boy();
console.log(math.add(2,3))
//calling add with [Arguments] { '0': 2, '1': 3 }
//5

相关文章

网友评论

      本文标题:ES6的装饰器-Decorator

      本文链接:https://www.haomeiwen.com/subject/bsgjqktx.html