谈谈你对闭包的理解以及闭包的使用场景

1、为什么使用闭包

引入:如果需要在页面上显示一个浏览时间,从打开页面的瞬间开始计时,每过一秒钟加一。(实质为累加器)
非闭包写法:
定义了一个全局变量,每次累加都是更新这个全局变量,but编程语言有一条不成文的铁律,就是尽可能少定义全局变量
为什么呢???

1、全局变量难以控制,可以在任何地方进行读写,意味着可能会被不相干的程序改写。
2、回收机制会每隔一段时间进行一次回收操作,释放不需要被占用的内存。一般局部变量(定义在函数中的变量),在函数调用完成后与之对应的执行环境会被推出执行栈。而全局变量因为随时可以被任何程序在任何地方读写,所以回收机制很难统计何时需要释放全局变量所占用的内存,也就导致全局变量一般是在全局执行环境被销毁时才会释放,占用内存的生命周期长。

// 秒数
let second = 0;

// 累加器
function counter() {
  second += 1;
  return second;
}

const recordSecond = setInterval(function () {
  // 到达10秒后停止
  if (second === 10) {
    clearInterval(recordSecond);
    console.log('计时结束!');
    return;
  }
  // 调用累加器,输出当前秒数
  console.log(`${counter()}`);
}, 1000);

闭包写法:

// 累加器
function counter() {
  // 秒数
  let second = 0;

  function doCounter() {
    // 到达10秒后停止
    if (second === 10) {
      clearInterval(recordSecond);
      console.log('计时结束!');
      return;
    }
    second += 1;
    console.log(`${second}`);
  }

  return doCounter;
}

// 得到累加器
const doCounterFn = counter();

const recordSecond = setInterval(function () {
  // 调用累加器
  doCounterFn();
}, 1000);

分析:
当我们将函数调用的返回值赋值给一个变量时,如果调用的这个函数返回的是一个函数,那么变量得到的则是对这个返回函数的引用(返回函数的内存地址),当一个函数存在被引用的关系,垃圾回收机制则不会回收它所占的内存,也就是保留该函数的整个执行上下文占用的内存(变量对象,作用域链等)。而因为返回的这个函数同时又是某个函数的内部函数,产生了作用域嵌套,形成了闭包,返回函数的作用域链上包括了外部函数的作用域,也就是返回函数中可以访问外部函数中定义的变量。
所以,当我们通过 doCounterFn 间接调用 doCounter 时,虽然 doCounterFn 的作用域链上并不存在变量 second,但 doCounter 被执行时依旧能访问它的作用域链上的变量,也就是它声明时所在的作用域内的任何变量,这就是作用域延长的典型例子。

2、总结

闭包的使用场景:

  • 创建私有变量
  • 延长变量的生命周期

(当我们需要重复使用一个对象,但又想保护这个对象不被其他代码污染。)
闭包的作用:
使得一个外部函数有权访问一个内部函数作用域。
闭包的形成条件:

需要访问作用域
函数嵌套(物理条件)
被嵌套函数在另一个外部作用域中被调用

闭包的缺点:
比起普通函数闭包对内存的占用更多,闭包在处理速度和内存消耗方面对脚本性能具有负面影响。因此使用完毕手动赋空标志回收dodoCounterFn=null
闭包的应用:
1、防抖

function debounce(fn, wait) {
	let timer = null
	return function(...args) {
		clearTimeout(timer)
		timer = setTimeout(() => {
			fn.apply(this, args)
		}, wait)
	}
}

2、节流

function throttle(fn, wait) {
	let timer = null
	return function(...args) {
		if (timer) return
		timer = setTimeout(() => {
			fn.apply(this, args)
			timer = null
		}, wait)
	}
}

可结合博文:防抖为什么使用闭包?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值