JavaScript闭包
什么是闭包?
闭包就是能够读取其他函数内部变量的函数。在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
除此之外,我们还需要了解作用域(scope)
作用域分为两种:全局作用域和局部作用域
全局作用域:
最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的:
1 <script> 2 var a = 1; 3 function fun(){ 4 console.log(a); 5 } 6 fun(); 7 </script>
控制台打印 1
局部作用域:
和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部
<script> function fun(){ var a = 1; } fun(); console.log(a); </script>
在控制台中会打印 a is not defined
值得一提的是,如果在声明变量的时候不使用var,就等于声明了一个全局变量
只要函数内定义了一个局部变量,函数在解析的时候都会将这个变量提前声明
例如:
1 <script> 2 var a = 1; 3 function fun(){ 4 console.log(a); 5 var a = 2; 6 console.log(a); 7 } 8 fun(); 9 </script>
控制台会打印第一个console.log(a)为undefined,
第二个console.log(a)为 2 。
1 <script> 2 var a = 1; 3 function fun(){ 4 var a; 5 console.log(a); 6 a = 2; 7 console.log(a); 8 } 9 fun(); 10 </script>
控制台会打印第一个console.log(a)为undefined,
第二个console.log(a)为 2 。
什么是作用域链(scope chain)?
JavaScript中,一切都是对象,包括函数。函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性。
其中一个内部属性是作用域,包含了函数被创建的作用域中对象的集合,称为函数的作用域链。
作用域链决定了哪些数据能被函数访问。当一个函数创建后,它的作用域链会被创建此函数的作用域中可访问的数据对象填充。
要了解链式查找,还得先了解js的执行环境
理解了作用域链后我们回归正题
闭包
闭包有两个作用:
第一个就是可以读取自身函数外部的变量(沿着作用域链寻找)
第二个就是让这些外部变量始终保存在内存中