2023-01-29 自己理解下的JS 闭包
2023-01-28 本文已影响0人
本泽锅
在理解闭包前,首先要搞清楚两个概念,作用域和作用域链。
一、作用域
简单理解:作用域就是变量的可用范围(scope)。
目的:防止不同范围内的变量之间相互干扰。
js中的作用域有两种:
1.全局作用域。
不属于任何函数的外部范围。
全局变量:保存在全局作用域的变量。
全局变量 优点:可反复使用。 缺点:全局污染。
2.函数作用域。(ES6的块级作用域实际上也是函数作用域)
在函数内部的范围。
局部变量:保存在函数内部的变量。
函数内部的局部变量只有两种情况:一种是函数的形参,一种是函数内部var,let 声明的变量。
局部变量 优点:不会被污染。缺点:不能重复使用。
说明:只有函数的{},才能形成作用域。
比如 对象
二、作用域链
简单理解:每个函数在定义时,就已经规划好了自己专属的查找变量的路线图,称为作用域链。
内部作用域访问外部作用域的变量,采取的是链式查找的方式决定取哪个值,原则是就近查找,向上一级一级的作用域来查找变量,最顶部就是全局作用域。如果全局作用域没有找到,那么就会报错。
三、作用域的本质:
全局作用域:其实是一个window的对象,所有的全局变量和全局函数都是window对象的成员。
函数作用域:js引擎调用函数时才临时创建的一个作用域对象。里面保存着局部变量,当函数调用完毕后,函数作用域对象随之也被释放掉。(函数作用域对象还有个别名:活动的对象 Actived Object 简称AO),因此局部变量不可重复使用。
四、闭包
简单理解:既可以重复使用变量,又保护变量不被污染的一种编程方法。
以后:只希望给一个函数,保存一个既可以反复使用,又不被外界污染的专属局部变量时,就用闭包。
闭包三部曲:
1.用外层函数包裹,要保护的局部变量和使用变量的内层函数。
2.在外层函数内部,返回内层函数对象。
3.调用外层函数,用变量借助返回的内层函数对象。
image.png
什么是闭包:
闭包也是一个对象,就是每次调用外层函数时,临时创建的函数作用域对象。
为什么外层函数的作用域对象能留下来,因为被内层函数的作用域链引用着,无法释放。
一句话形容闭包:外层函数调用后,外层函数的作用域对象,被内层函数的作用域链引用着,无法释放,因此形成了闭包。
缺点:因为无法释放,容易造成内存泄漏。
解决办法:将保存内层函数的对象变量赋值为null。