js基石之---es7的decorator修饰器

es7的decorator修饰器

装饰器(Decorator)是一种与类(class)相关的语法,用来注释或修改类和类方法。

decorator就是给类添加或修改类的变量与方法的。

装饰器是一种函数,写成@ + 函数名。它可以放在类和类方法的定义前面。

@frozen class Foo {
  @configurable(false)
  @enumerable(true)
  method() {}

  @throttle(500)
  expensiveMethod() {}
}

上面代码一共使用了四个装饰器,一个用在类本身,另外三个用在类方法。它们不仅增加了代码的可读性,清晰地表达了意图,而且提供一种方便的手段,增加或修改类的功能。

1.修改类

@addType
class human{}
function addType(target){
  target.age=27;
  target.name=hyh;
  target.sex=male;
  target.hight=178;
  console.log('此对象被修改了')
}
console.log(new human())

上面代码中,@addType就是一个装饰器。它修改了human这个类的行为,为它加上了静态属性age name sex hight等等。addType函数的参数target是human类本身。

2.修改类的方法

class Dabao {
    @setAttr
    cxh(){
        return true
    } 
}
function setAttr(targt, name, decorator) {
    decorator.writable = false
    return 
}

var dabao = new Dabao;
console.log(dabao.cxh)
dabao.cxh = () => {
    return false
}
console.log(dabao.cxh)

3. 装饰器可接受多个传参,第一个参数为修饰target  ,如果觉得一个参数不够用,可以在装饰器外面再封装一层函数。

装饰器testable可以接受参数,这就等于可以修改装饰器的行为。

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

@testable(true)
class MyTestableClass {}
MyTestableClass.isTestable // true

@testable(false)
class MyClass {}
MyClass.isTestable // false

上面代码中,装饰器函数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'

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

class MyReactComponent extends React.Component {}

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

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

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

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

4.装饰器不能用于装饰函数

5.Mixin

在装饰器的基础上,可以实现Mixin模式。所谓Mixin模式,就是对象继承的一种替代方案,中文译为“混入”(mix in),意为在一个对象之中混入另外一个对象的方法。

请看下面的例子。

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

class MyClass {}

Object.assign(MyClass.prototype, Foo);

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

上面代码之中,对象Foo有一个foo方法,通过Object.assign方法,可以将foo方法“混入”MyClass类,导致MyClass的实例obj对象都具有foo方法。这就是“混入”模式的一个简单实现。

下面,我们部署一个通用脚本mixins.js,将 Mixin 写成一个装饰器。

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

然后,就可以使用上面这个装饰器,为类“混入”各种方法。

import { mixins } from './mixins';

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

@mixins(Foo)
class MyClass {}

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

猜你喜欢

转载自blog.csdn.net/m0_61243965/article/details/120916350
ES7