Javascript(六十五)闭包

凡是满足以下三个特点,都属于闭包

1.函数嵌套函数

2.内部函数使用外部函数的形参和变量

3.被引用的形参和变量就不会被垃圾回收机制所回收

垃圾回收机制:

调用函数时,系统会分配一定的内存空间给这个函数使用(空间大小由这个函数里声明的变量和形参决定)。调用完毕之后,这个内存空间要释放,还给系统。

var a=0
			function show(){
				console.log(a);
				a++;
			}
			show()
			show()
			//a的空间没被释放
			alert(a)//不报错,正常显示

在这里插入图片描述

function show(){
					var a=0
					console.log(a);
					a++;
				}
			show()
			show()
		//a的空间被释放
			alert(a)//报错 not defined

一般情况下,函数外部是无法访问函数内定义的形参和变量的。
在这里插入图片描述
但是当我们将内部函数调用外部函数的变量和形参时,再将内部函数作为外部函数返回值,此时执行返回值函数时,是可以访问到函数内的变量和形参的。证明,在外部函数调用完毕之后,其定义的形参和变量并没有被立即销毁掉,而是保存在内部函数里了。只要内部函数没有被销毁,内部函数就能够不断地引用外部函数的变量和形参。
在这里插入图片描述
闭包的作用

1.希望一个变量常驻在内存中 2.避免全局变量污染,避免声明全局变量 3.可以声明私有成员

全局变量污染:当我们在一个页面内声明了很多变量和函数在全局作用域下,当我们将多个代码合成一个代码时,有可能就出现,全局作用下的变量和函数出现重名的情况,导致整个程序崩溃。
在这里插入图片描述
上图中,全局变量被不断的更改,但是如果其他人想要引用整个a的话,就是一个被更改了的a。

引起为了避免这种情况的发生,我们尽量去设置局部变量
在这里插入图片描述
如果要实现函数内的变量一直驻留在内存中,此时就需要闭包了
在这里插入图片描述
立即执行函数

原理:
在这里插入图片描述
但是因为()的优先级是最高的,这样就会出现,括号内为空,就会报错,因此真正执行时,需要将前面的函数也加上()
在这里插入图片描述
更改我们第一个例子

let res=(function (){
				var a=10
				function show2(){
					a++;
					console.log(a);
				}
				return show2
			})()
			
			res()
			res()

声明私有变量
在这里插入图片描述
案例:

保存变量:
在这里插入图片描述
将外部变量以形参的形式传入,并立即执行
在这里插入图片描述
优化:
在这里插入图片描述
闭包注意事项

内存泄漏:被闭包占用的内存,已经被永久占用了,其他人无法再使用了,也就是所谓的钉子户
在这里插入图片描述
上图中,window.onload和obtn.onclick就构成了一个闭包。这样obtn就会一直驻留在内存当中。就造成内存泄漏。并且对象占用的内存比较大。

解决内存泄漏:主要出现在IE浏览器

解决方式一:减少内存泄漏,在外部函数使用变量存储需要用到值
在这里插入图片描述
解决方式二:利用IE浏览器独有的window.onunload 当页面解构的时候触发(刷新页面,关闭当前页面),在刷新的时候就释放内存
在这里插入图片描述

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值