1.什么是闭包?
闭包就是能够读取其他函数内部变量的函数。
在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。
在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
2.闭包的模式
(1)函数模式的闭包:在函数中有一个函数
<script> function f1() { var num = 10; function f2(){ console.log(num) } f2(); } f1(); //10 </script>
函数f2在函数f1内部,并且可以访问num变量,这里的num和f2的总和就是一个闭包
(2)对象模式的闭包:函数中有一个对象
<script> function f1() { var num = 10; var obj = { age:num } console.log(obj.age) } f1(); </script>
对象obj在函数f1内部,且可以访问num变量,这里的num和obj的总和就是一个闭包
3.闭包的优缺点?
优点:缓存数据,延长作用域链;间接访问一个变量;让代码更加规范、简洁
缺点:缓存数据,没有及时的释放内存变量;内存消耗大,造成内存泄漏
有的人会说闭包的缺点是:内存泄漏;但我查阅资料有的说内存泄漏不是闭包的问题,是IE浏览器的问题
内存泄漏:用不到的变量依然占据着内存空间,不能被再次利用
一般来说:函数中的变量在函数执行完就会被释放;由于闭包会频繁的调用函数中的变量,导致函数中的变量不被释放
全局变量有可能会被误改,不安全;使用局部变量,暴露一个函数让别人“间接访问”
4.闭包的应用场景:
ajax请求成功的回调
一个事件绑定的回调方法
setTimeout的延时回调
一个函数内部返回另一个匿名函数
5.闭包的练习
(1)
<script> function f1() { var num = 10; return function(){ //f1函数返回了一个函数 function(){console.log(num)} console.log(num) } } var ff = f1(); //ff接受了f1,所以ff接收了函数 function(){console.log(num)} ff(); //10 调用ff,就是执行上面的函数 </script>
(2)
<script> function f2() { var num = 10; return { age:num } } var obj = f2(); console.log(obj.age) </script>
(3)为什么三次都是输出11?因为调用了三次ff
<script> function f1() { var num = 10; num++; console.log(num) } f1() //11 f1() //11 f1() //11 </script>
(4) 这次为什么三次输入的结果不同了呢?因为f1函数中返回了一个function形成了闭包,缓存了数据num
<script> function f1() { var num = 10; return function () { num++; return num; } } var ff = f1() console.log(ff()) //11 console.log(ff()) //12 console.log(ff()) //13 </script>
(5)无闭包无缓存数据,相当于调用了3此f1()
<script> function f1() { var num = 10; num++; return num; } console.log(f1()) //11 console.log(f1()) //11 console.log(f1()) //11 </script>