js 闭包解析

闭包概念

闭包:当内部函数被保存到外部时,将会生成闭包。

闭包会导致原有的作用域链不释放,造成内存泄漏(作用域链一直不释放,占用内存,可用内存就小了,指内存泄漏)。

例子说明

利用上一节的作用域链可以非常好理解闭包,下面来看一个例子:

function a() {
	function b() {
		var bbb = 234;
		console.log(aaa); //打印123
	}
	var aaa = 123;
	return b;
}
var glob = 100;
var demo = a();
demo();
  • 首先生成GO:
GO: {
	glob:undefined,
	a: function a() {……函数里面的代码……},
	demo: undefined
}

接着给glob赋值100,之后,给demo赋值,执行a函数前,对a进行预b编译,得到a-AO:

a-AO: {
	aaa:undefined,
	b: function b() {……函数里面的代码……}
}

接着执行a函数,此时,a函数的作用域链为:

a.[[scope]]---->scopechain[0]---->a-AO;

                  ---->scopechain[1]---->GO;

给a赋值123后,返回b函数体,此时b函数的作用域链为:

b.[[scope]]---->scopechain[0]---->a-AO;

                  ---->scopechain[1]---->GO;

b函数体返回后,a函数执行完毕,a函数作用域链被销毁,但注意,只是解除了对a-AO及GO的引用,并没有销毁a-AO。但由于在a函数结束前返回了b函数,b函数包含了对a-AO及GO的引用,也即b“继承”了a的作用域链,即使a函数执行完毕,但其作用域链仍不会释放。

扫描二维码关注公众号,回复: 9856377 查看本文章
  • 最后,回到全局环境,执行demo(),即执行b函数,在执行b函数前,对b进行预编译,得到b-AO:
b-AO: {
	bbb:undefined
}

然后执行b函数,此时b函数作用域链为:

b.[[scope]]---->scopechain[0]---->b-AO;

                  ---->scopechain[1]---->a-AO;

                  ---->scopechain[2]---->GO;

得 :

b-AO: {
	bbb:234
}

因此 ,打印aaa回到a-AO中寻找aaa的值,打印为123。

发布了53 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/bingqise5193/article/details/99710864