zccst整理
总结:
1,闭包是什么
闭包
2,闭包好处:
(1)希望一个变量长期驻扎在内存中。
(2)避免全局变量的污染。
(3)私有成员的存在
3,怎么用
模块化代码
例子
在循环中直接找到对应元素的索引
例子
4,可能存在的问题
内存泄露。外部变量与内部变量互相引用。导致内存越来越大。
解决办法:
1,及时释放dom结点对象。
闭包
定义:函数嵌套函数,内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制收回。
结论:变量一直存在。由于其参数和变量由于被内部函数使用,所以不会被收回。
垃圾回收机制
而我们既想使用局部变量,又想像全局变量一样累加(即闭包),则可如下所示:
更进一步,把函数变私有,,即模块化代码。
在循环中直接找到对应元素的索引
IE下引发内存泄露
总结:
1,闭包是什么
闭包
2,闭包好处:
(1)希望一个变量长期驻扎在内存中。
(2)避免全局变量的污染。
(3)私有成员的存在
3,怎么用
模块化代码
例子
在循环中直接找到对应元素的索引
例子
4,可能存在的问题
内存泄露。外部变量与内部变量互相引用。导致内存越来越大。
解决办法:
1,及时释放dom结点对象。
闭包
定义:函数嵌套函数,内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制收回。
- function aaa(){
- var a = 5;
- function bbb(){
- alert(a);
- }
- return bbb;
- }
- var c = aaa();
- c();//5
- c();//5
结论:变量一直存在。由于其参数和变量由于被内部函数使用,所以不会被收回。
垃圾回收机制
- function aaa(){
- var a = 12;
- a++;
- alert(a);
- }
- aaa();//13 即函数执行完之后,局部变量被回收。
- aaa();//13 再次调用时,重新赋值。
- alert(a);//a未定义,即离开作用域后,局部变量已被回收(外部不能访问)。
- var a = 12;
- function aaa(){
- a++;
- alert(a);
- }
- aaa();
- aaa();
- //问题是:污染了全局变量。如果连续调用aaa();则变量a的值会递增。
而我们既想使用局部变量,又想像全局变量一样累加(即闭包),则可如下所示:
- //第一版:
- function aaa(){
- var a = 1;
- return function(){
- a++;
- alert(a);
- }
- }
- var b = aaa();
- b();//2
- b();//3
- //第二版:把函数声明改写为函数表达式
- var aaa = (function(){
- var a = 1;
- return function(){
- a++;
- alert(a);
- }
- })();
- aaa();
- aaa();
更进一步,把函数变私有,,即模块化代码。
- var aaa = (function(){
- var a = 1;
- function bbb(){
- a++;
- alert(a);
- }
- function ccc(){
- a++;
- alert(a);
- }
- return { //json格式
- b:bbb,
- c:ccc
- }
- })();
- aaa.b();//2
- aaa.c();//3 a对于两个函数,相当于全局。
- alert(a); //异常,未定义
- alert(bbb);//异常,未定义
- alert(ccc);//异常,未定义
在循环中直接找到对应元素的索引
- window.onload = function(){
- var aLi = document.getElementsByTagName("li");
- //方式一:有问题
- for (var i = 0; i < aLi.length; i++){
- aLi[i].onclick = function(){
- alert(i);
- };
- //问题:for循环后,i已经是4,所以所有li的click都是4。
- }
- //方式二:
- for (var i = 0; i < aLi.length; i++){
- (function(i){
- //内部函数可以使用外包函数的参数和变量。
- //外包函数执行完毕后,内部函数依然存在。
- aLi[i].onclick = function(){alert(i);}
- })(i);
- }
- //方式三:
- for (var i = 0; i < aLi.length; i++){
- aLi[i].onclick = (function(i){
- //内部函数可以使用外包函数的参数和变量。
- //外包函数执行完毕后,内部函数依然存在。
- return function(){
- alert(i);
- }
- })(i);
- }
- };
- <ul>
- <li>1111111111111</li>
- <li>1111111111111</li>
- <li>1111111111111</li>
- <li>1111111111111</li>
- </ul>
IE下引发内存泄露
- window.onload = function(){
- var oDiv = document.getElementById("div1");
- oDiv.onclick = function(){
- alert(oDiv.id);
- }
- //方法一:
- window.unonload = function(){
- oDiv.onclick = null;
- }
- }
- //方法二:
- window.onload = function(){
- var oDiv = document.getElementById("div1");
- var id = oDiv.id;//然后在内部函数中使用id,而不是oDiv即可解决
- oDiv.onclick = function(){
- alert(oDiv.id);
- }
- oDiv = null;
- }