什么是闭包?(以防抖函数作为示例)

什么是闭包?
  • 简单来说,就是能够读取其他函数内部变量的函数就是闭包。例如:防抖和节流函数就是很好的闭包例子
  • 闭包的产生其实来自于js的变量作用域。在js中,变量的作用域属于函数作用域,当函数执行完成之后,作用域就会被清理,内存也就随之被回收。但是由于闭包函数是建立在函数内部的子函数,闭包函数又能够访问父函数的变量,所以就会导致当父函数执行完成时,其作用域不会销毁,该变量永久的保存在内存中直到闭包函数也不存在时才进行销毁(_防抖函数中的计时器一直存在于内存,所以每次执行都需要进行_clearTimeout)。

js变量分为全局变量和局部变量,所以闭包往往会导致变量提升(局部变量变为全局变量)
仔细思考发现这么理解是错误的,等周末写个函数实验一下修改结论
疑问:

  1. 闭包一定会导致变量提升吗?
  2. 使用let、const修饰变量也会提升吗?

《JavaScript高级程序设计》的描述:

闭包是指有权访问另一个函数作用域中的变量的函数;

《JavaScript权威指南》的描述:

从技术的角度讲,所有的JavaScript函数都是闭包:它们都是对象,它们都关联到作用域链。

《你不知道的JavaScript》的描述:

当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。

/**
 * 防抖函数
 * @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毫秒后执行。
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值