JS进阶之闭包

105 阅读1分钟

1. 闭包的特点

在函数外部可以使用函数内部的变量

2. 实现思路

函数内返回一个匿名函数,匿名函数中引用需要传递到函数外的变量

3. 使用场景之去抖动

  • 去抖动: 一个事件被触发还没有执行完成,在指定时间内又再次被触发,则重新开始计时;如果一直重复触发,则一直重新计时.
  • 练习要求: 鼠标在盒子上移动,鼠标停止500ms之后,盒子里面的数字才会+1.
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div
      id="box"
      style="
        width: 200px;
        height: 200px;
        background-color: skyblue;
        text-align: center;
      "
    ></div>
  </body>
  <script>
    /* 
    防抖:一个事件开始执行还没有结束,在指定时间内又触发事件,则重新开始计时,一直触发则一直重新计时.
    练习要求:鼠标在盒子上移动,鼠标停止500ms之后,盒子里面的数字才会+1
    */
    // 获取元素
    let box = document.querySelector("#box");
    // 设置盒子数据初始值
    let i = 0;
    function mousemoveHandler() {
      // 改变盒子数据
      box.innerHTML = i++;
    }
    // 去抖动处理函数,鼠标移动一次,执行一次,使用setTimeout
    function debounce(fn, time) {
      // 声明延时器变量
      let timer;
      // 每次触发事件时,先判断延时器是否存在,如果存在则清除以前的延时器,重新开始计时
      return function () {
        if (timer) {
          clearTimeout(timer);
        }
        // 如果没有延时器,则开启延时器,开始计时
        else {
          // 接收延时器,便于清除
          timer = setTimeout(function () {
            fn();//将函数当作参数
          }, time);
        }
      };
    }
    // 添加鼠标移动事件的事件监听器,每次触发事件,返回一个匿名函数,执行匿名函数里的程序
    box.addEventListener("mousemove", debounce(mousemoveHandler, 500));
  </script>
</html>