遇到闭包,用防抖解释!再也不用瑟瑟发抖啦

1,004 阅读2分钟

名词解释:

  • 闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
  • 防抖指的是多次执行同一个函数时,只产生一次执行结果的函数

优缺点:

优点
  • 可以重复使用变量,并且不会造成变量污染。
  • 可以用来定义私有属性和私有方法

变量的作用域无非就两种:全局变量和局部变量。全局变量可以重复使用,但是容易造成变量污染。局部变量仅在局部作用域内有效,不可以重复使用,不会造成变量污染。闭包结合了全局变量和局部变量的优点。当我们需要让局部变量发挥全局变量的作用时,可以考虑使用闭包

缺点
  • 比普通函数更占用内存,会导致网页性能变差,在IE下容易造成内存泄露。(由于闭包是驻留在内存中,会增大内存使用量,使用不当很容易造成内存泄露,)

举栗子:

/**
 * 防抖函数
 * @author vision
 * @param {执行函数} fn
 * @param {延迟} delay
 */
export function debounce(fn, delay) {
  let timer = null;
  return function() {
    let context = this;
    let arg = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, arg);
    }, delay);
  };
}
  • timer就是闭包函数调用的外部变量
  • arguments是每一个funcation函数都会有的对象,在函数调用时,浏览器每次都会传递进两个隐式参数this和arguments,封装实参的对象arguments,在ES6中的箭头函数中使用…rest作为arguments.
  • 函数debounce 返回的匿名函数调用了timer,导致timer脱离debounce函数的作用域存活于内存中,直到匿名函数也执行完毕,才会被回收。故当点击间隔小于delay毫秒时,timer就会不断更新值,导致setTimeout内的匿名函数无法执行(因为setTimeout内的函数会延迟delay毫秒执行),直到没有新的调用事件时,fn才会正常延迟到delay毫秒后执行。