【学习笔记】javaScript的闭包

什么是闭包

两个例子:

例子1
function bar(){
	console.log(a);
}
function fn() {
	var a=100
	bar()
}
var a=200
fn()
// 200
例子2
function fn2() {
	var a=100
	function bar2(){
		console.log(a);
	}
	bar()
}
var a=200
fn2()
// 100

这两个例子区别是 bar 函数声明在外部,bar2 函数声明在了 fn2 的内部,所以很明显例子2是形成了一个闭包。

在例子1中,fn() 函数已经执行完了,在调用栈里被删除了,所以里面的a不会被访问到,当 bar() 函数要输出a但是其内部没有a时,就会去到它的 outer 的词法作用域中寻找 a=200,所以最终输出 200

再看例子2,外部函数声明了 foo 函数,和a变量 ,在 foo 函数内部,bar 函数被声明了。按理说,fn2函数执行完,内部的a应该被回收掉,但是bar函数输出的a却是100。因为内部函数引用了外部函数中的变量,所以内部函数没有被释放,依旧被保存在了内存中。

简单来说就是:一个内部函数访问了其外部函数的变量时,形成了闭包。

再来一个例子

function fn3() {
	var a=100
	function bar3(){
		console.log(a);
	}
	return bar3
}
var a=200
var myFn3 = fn3();
myFn3();
//100

这段代码的效果和之前 fn2 函数的示例完全一样。不同在于内部函数 bar3 在执行前,从fn3外部函数返回了。

当通过调用一个外部函数返回的一个内部函数后,即使外部函数执行已经结束了,但是内部函数引用了外部函数中的变量也依旧需要被保存在内存中,所以 bar3 依旧能够访问到fn3中定义的变量的值并输出

闭包的应用

闭包可以将变量封装在函数内部,保护变量不被外部访问和修改,实现数据的私有。

有效减少全局作用域的污染,保持代码的整洁和可维护性。

可以存储计算结果,避免重复计算,提高程序效率。

var makeCounter = function () {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function () {
      changeBy(1);
    },
    decrement: function () {
      changeBy(-1);
    },
    value: function () {
      return privateCounter;
    },
  };
};

var Counter1 = makeCounter();
var Counter2 = makeCounter();
console.log(Counter1.value()); /* logs 0 */
Counter1.increment();
Counter1.increment();
console.log(Counter1.value()); /* logs 2 */
Counter1.decrement();
console.log(Counter1.value()); /* logs 1 */
console.log(Counter2.value()); /* logs 0 */

每次调用其中一个计数器时,通过改变这个变量的值,会改变这个闭包的词法环境。然而在一个闭包内对变量的修改,不会影响到另外一个闭包中的变量。

闭包的缺陷

除特定情况下,尽量减少闭包的使用,因为闭包可能会导致这些变量及相关的整个作用域长时间驻留在内存中,从而引发内存泄漏。

如果是大量使用闭包或者循环中创建闭包的情况下,必须谨慎处理,确保不再使用的变量能够适时释放,避免不必要的内存占用。

消除闭包

解除 bar 对外部函数变量的引用,回收相应的内存空间,避免不必要的内存占用。

function fn() {
	var a=100
	function bar(){
		console.log(a);
	}
	return bar
}
var a=200
var myFn = fn();
myFn();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值