js闭包
关于JS的闭包,也没有一个很好的定义。我对它的理解 就是外部变量/函数可以访问内部函数的变量。
如下面代码输出
<script> var n = 0; function a1(){ console.log(n) // 0 } a1(); function a2() { var b = 1; } console.log(b) //error:b is not defined </script>
这是因为函数内部可以直接读取全局变量,而外部却是无法读取内部变量的。那么,怎么才能读取内部的变量呢,只要把作为一个返回
值就可以了。
function a2() { var b = 1; return b } var b = a2(); console.log(b) //1
也可以返回一个函数
function a3(){ var i = 0; function bbb(){ console.log(i++) } return bbb } var fn = a3(); fn()//0 fn()//1
上面的代码fn再次执行时不再是0,因为a3函数执行完后理论上是回收内存,但是return返回bbb,这就导致了始终在内存中,不会在调用结束后被垃圾回收机制回收。
关于闭包的用途,它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
如下面的代码
<ul id="ul"> <li>1111</li> <li>1111</li> <li>1111</li> <li>1111</li> </ul> <script> var oUl = document.getElementById("ul"); var oLi = oUl.getElementsByTagName('li'); for (var index = 0; index < oLi.length; index++) { oLi[index].onclick = function () { console.log(index)//4 } } </script>
我们想要的结果是点击当前 就是显示当前index,但是每次点击都是输出4,为什么?因为for循环,当等于4时不满足条件,没有执行。而这些都是瞬间执行完的,所以每次都是输出4;那么 这时可以用闭包就可以解决了,如下面代码。
<ul id="ul"> <li>1111</li> <li>1111</li> <li>1111</li> <li>1111</li> </ul> <script> var oUl = document.getElementById("ul"); var oLi = oUl.getElementsByTagName('li'); for (var index = 0; index < oLi.length; index++) { oLi[index].onclick = function (i) { return function () { console.log(i) } }(index) } </script>
使用闭包有以下几大好处:
1:希望一个变量长期驻扎在内存中。
2:避免全局变量的污染。
3:私有成员的存在。
当然了,有好处也是 有坏处。闭包使用不当会导致内存泄露问题,特别是IE浏览器下