装饰器应用demo

  1. log
    为一个方法添加 log 函数,检查输入的参数:
class Math {
  @log
  add(a, b) {
    return a + b;
  }
}

function log(target, name, descriptor) {
  var oldValue = descriptor.value;

  descriptor.value = function(...args) {
    console.log(`Calling ${name} with`, args);
    return oldValue.apply(this, args);
  };

  return descriptor;
}

const math = new Math();

// Calling add with [2, 4]
math.add(2, 4);
  1. debounce
    有的时候,我们需要对执行的方法进行防抖处理:
class Toggle extends React.Component {

  @debounce(500)
  handleClick() {
    console.log('toggle')
  }

  render() {
    return (
      <button onClick={this.handleClick}>
        button
      </button>
    );
  }
}

我们来实现一下:

function _debounce(func, wait) {
    var timeout;
    return function () {
        var context = this;
        var args = arguments;
        if (timeout) clearTimeout(timeout);
        timeout = setTimeout(function(){
            func.apply(context, args)
        }, wait);
    }
}

function debounce(wait) {
  return function handleDescriptor(target, key, descriptor) {
    const callback = descriptor.value;
    var fn = _debounce(callback, wait)
    return {
      ...descriptor,
      value:fn
    };
  }
}
  1. time
    用于统计方法执行的时间:
function time(prefix) {
  return function handleDescriptor(target, key, descriptor) {
    const fn = descriptor.value;
    if (prefix == null) {
      prefix = `${target.constructor.name}.${key}`;
    }

    return {
      ...descriptor,
      value() {
        const label = `${prefix}-${count}`;
        console.time(label);
		fn.apply(this, arguments);
        console.timeEnd(label);
      }
    }
  }
}
  1. mixin
    用于将对象的方法混入 Class 中:
const SingerMixin = {
  sing(sound) {
    alert(sound);
  }
};

const FlyMixin = {
  get speed() {},
  fly() {},
  land() {}
};

@mixin(SingerMixin, FlyMixin)
class Bird {
  singMatingCall() {
    this.sing('tweet tweet');
  }
}

var bird = new Bird();
bird.singMatingCall();
// alerts "tweet tweet"

mixin 的一个简单实现如下:

function mixin(...mixins) {
  return target => {
    for (let i = 0, l = mixins.length; i < l; i++) {
      const descs = Object.getOwnPropertyDescriptors(mixins[i]);
      const keys = Object.getOwnPropertyNames(descs);

      for (let j = 0, k = keys.length; j < k; j++) {
        const key = keys[j];
        if (!target.prototype.hasOwnProperty(key)) {
          Object.defineProperty(target.prototype, key, descs[key]);
        }
      }
    }
  };
}

  1. redux
    实际开发中,React 与 Redux 库结合使用时,常常需要写成下面这样。
class MyReactComponent extends React.Component {}

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

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

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

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

完结撒花,有问题留言讨论哈~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值