从理论角度:所有的函数,因为它们都在创建的时候就将上层上下文的数据保存起来了。哪怕是简单的全局变量也是如此,因为函数中访问全局变量就相当于是在访问自由变量,这个时候使用最外层的作用域。简而言之:闭包是指能够访问自由变量的函数
当一个外部函数里面定义了一个内部函数,内部函数使用了外部函数的变量,并且将内部函数返还给外部函数
如下:
function outer() { //外部函数
let arr = ['上', '山', '打', '老', '虎']
let index = -1
return function () { //内部函数
index++
if (index == arr.length) index = 0 //使用了外部变量
return arr[index]
}
}
这时返回的函数是?
let getElement = outer();
console.log(getElement); //ƒ () {
index++
if (index == arr.length) index = 0
return arr[index]
}
返回的函数是内部函数,这时调用函数getElement()
得到的是
console.log(getElement()); // 上
"上"是外部函数outer()里面的数据,然而当函数outer赋值给getElement后,outer函数不再保存在内存之中,这时内部函数存在于全局的载体就是getElement = f( );
且外部函数的变量还可以调用,这就是闭包的用处所在;
调用getElement时
let arr = ['1','2','3','4','5']
let index = 2
btn.onclick = function () {
console.log(getElement()); //依次输出 上, 山, 打, 老, 虎
}
优点:如上可知,当全局重新定义了arr和index时,无法影响闭包的内部函数对之前存在的外部函数的的调用和内部函数的运行
证明当闭包使用时:
内部函数结构及其稳定,被销毁的外部函数的变量在全局调用的时候仍然可以使用,并且函数仍然可以调用,安全性很高,不易受到外部污染
缺点:占用内存
将getElement的值变为null,也就是释放占用的内部函数,函数一旦没有被变量应用,会被回收
getElement = null
个人学习笔记,如有错误,敬请指点,十分感谢
另外有关于用作用域链来理解闭包的推文,一篇大佬的文章,感觉受益匪浅,
JavaScript深入理解闭包