zoukankan      html  css  js  c++  java
  • js-使用装饰器去抖

    • 装饰器装饰类

    修改类了的行为,为它添加了静态属性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;
      }
    
    }
    
    
  • 相关阅读:
    Yii2 在模块modules间跳转时,url自动加模块名
    PHP 变量的间接引用(将某一字符串转化为变量)
    windows鼠标悬停任务栏 延迟时间 修改
    dede 常用标签和调用方法汇总
    dedecms ---m站功能基础详解
    apache 2.2 和2.4 目录权限访问设置的区别
    apache httpd.conf 配置局域网访问
    ajax php 点击加载更多
    dede调用当前栏目名 、dede sql
    dede 添加 栏目缩略图
  • 原文地址:https://www.cnblogs.com/hideonbush/p/10928140.html
Copyright © 2011-2022 走看看