首页 > Web开发 > 详细

js-使用装饰器去抖

时间:2019-05-26 23:59:42      阅读:100      评论:0      收藏:0      [点我收藏+]

标签:number   ebo   ext   方法   对象   utils   extends   ins   enume   

  • 装饰器装饰类

    修改类了的行为,为它添加了静态属性zs。

function test (target) {
  target.zs = true;
}

@test
class App {}

App.zs // true
  • 装饰器装饰类的方法

    装饰类的方法与Object.defineProperty有些许类似。

function test (target, key, descriptor) {
  /*
  * ...do something for descriptor...
  */
  return descriptor;
}


class App {

  @test
  sayHi(){}

}

装饰器的应用

import { debounce } from './utils.js';

class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      count: 1,
    };
    this.handleClick = this.handleClick.bind(this);
  }

  /*
  * 装饰器可以装饰类和类的方法,需要注意的是装饰方法是原型对象方法
  * no fn(){}
  * ok fn = () => {}
   */
  @debounce(200)
  handleClick() {
    this.setState({ count: this.state.count + 1 });
  }


  render() {
    return (
      <div>
        <button onClick={this.handleClick}>add-click</button>
        <p>{this.state.count}</p>
      </div>
    )
  }
}

export default App;
utils.js

/**
 * 去抖
 * @param {Number} timeout
 */
export function debounce(timeout) {

  // https://segmentfault.com/a/1190000015970099
  // return function (target, key, descriptor) {
  //   // 创建一个Map的数据结构,将实例化对象作为key
  //   const instanceMap = new Map();
  //   return Object.assign({}, descriptor, {
  //     value() {
  //       // 清除延时器
  //       clearTimeout(instanceMap.get(this));
  //       // 设置延时器
  //       instanceMap.set(this, setTimeout(() => {
  //         // 调用该方法
  //         // descriptor.value.call(this, ...arguments);
  //         descriptor.value.apply(this, arguments);
  //         // 将延时器设置为 null
  //         instanceMap.set(this, null);
  //       }, timeout));
  //     }
  //   });
  // }

  // 简单实现去抖
  /*
  descriptor与Object.defineProperty的第三个参数相等
  相当于劫持了这个对象中的一个属性,但这个属性值是一个方法。
  eg:
  var student = {
    age: 14,
    sayHi: function (name) {
      console.log('hi~' + name);
    }
  }
  const fn = student.sayHi;
  Object.defineProperty(student, 'sayHi', {
    configurable: true,
    enumerable: true,
    writable: true,
    value() {
      setTimeout(() => {
        // 不能在此复制方法,会引起爆栈 const fn = st..Hi;
        console.log('重写当前方法');
        fn.apply(this, arguments)
      }, 2000)
    }
  })
   */

  return function (target, key, descriptor) {
    // 获取被装饰的方法
    const oldValue = descriptor.value;
    // 初始timerID
    let timer = null;
    // 覆盖被装饰的方法
    descriptor.value = function () {
      clearTimeout(timer);
      timer = setTimeout(() => {
        oldValue.apply(this, arguments)
      }, timeout);
    };
    return descriptor;
  }

}

js-使用装饰器去抖

标签:number   ebo   ext   方法   对象   utils   extends   ins   enume   

原文:https://www.cnblogs.com/hideonbush/p/10928140.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 bubuko.com 版权所有 鲁ICP备09046678号-4
打开技术之扣,分享程序人生!
             

鲁公网安备 37021202000002号