<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>时生闭包的学习,教程来自妙味课堂</title>
<script>
//-------------------------------------------------------------------------------------------
//1.什么是闭包
//函数嵌套函数,内部函数可以引用外部函数的参数和变量,变量和参数不会被垃圾回收机制所收回
/*
function aaa(a){
var b = 5;
function bbb(){
console.log(a); //a,b可以访问到,并不会被垃圾回收机制回收
console.log(b);
}
}
aaa();
*/
/*JS中的垃圾回收机制
function aaa(){
var a = 1;
}
这个函数执行完,这个变量a就会被回收机制回收了。*/
//测试
/*
function aaa(){
var a = 5;
function bbb(){
console.log(a);
}
return bbb;
}
var c = aaa();
c();//c = bbb(); 弹出5
*/
//-------------------------------------------------------------------------------------------
/*
2.闭包的好处
1)希望一个变量长期驻扎在内存中
2)避免全局变量的污染
3)私有成员的存在
*/
//用法1.模块化代码
//用法2.在循环中直接找到对应元素的索引
/*var a = 1;
function aaa(){
a++;
alert(a);
}
aaa(); //2
aaa(); //3
alert(a);//在函数外可以调用。*/
/*function aaa(){
var a = 1; //局部变量
a++;
alert(a);
}
aaa(); //2
aaa(); //2 每次都重新执行了
*/
/*function aaa(){
var a = 1;
return function(){
a++;
alert(a);
}
}
var c = aaa();
c(); //2
c(); //3*/
//alert(a); //a is not defined
//用法1.模块化代码
/*
(function(){}) //函数表达式
(function(){})() //调用*/
/*
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 {
b:bbb,
c:ccc
}
})()
aaa.b(); //2
aaa.c(); //3
alert(a); //没有找到 is not defined
alert(bbb); //没有找到 is not defined
alert(ccc); //没有找到 is not defined
*/
//用法2.在循环中直接找到对应元素的索引
window.onload = function(){
var _li = document.getElementsByTagName("li");
/*for(var i = 0 ; i < _li.length ; i++){
//循环执行结束制还没执行onclick
_li[i].onclick = function(){
alert(i); //点击都为3
}
}*/
//写法一
/*
for(var i = 0 ; i < _li.length ; i++){
(function(i){
//利用闭包将i作为参数传进来
_li[i].onclick = function(){
alert(i); // 0,1,2
}
})(i)
}
*/
//写法二
/*
for(var i = 0 ; i < _li.length ; i++){
_li[i].onclick = (function(i){
return function(){
alert(i); // 0,1,2
}
})(i)
}
*/
//--------------------------------------------------------------------------------
//3.使用闭包需要注意什么?
//闭包在IE下容易引发内存泄漏
//内存泄漏会导致页面跳转时变量还没释放导致CPU一直增加,只有关闭浏览器才会释放。
//引发原因
//当一个变量(oDiv)是DOM节点或数组对象的时候,他的一个属性(oDiv.onclick)去引用一个内部函数,而内部函数里的变量又去引用外部的(oDiv.id)
var oDiv = document.getElementById('div1');
oDiv.onclick = function(){
alert(oDiv.id);
};
//解决方法1. 变量属性为NULL;
window.onunload = function(){
oDiv.onclick = null;
}
//解决方法2.将对象为NULL;
var oDiv = document.getElementById('div1');
var id = oDiv.id;
oDiv.onclick = function(){
alert(id);
};
oDiv = null;
}
</script>
</head>
<body>
<ul id="myul">
<li>11111</li>
<li>22222</li>
<li>33333</li>
</ul>
<div id="div1">aaaa</div>
</body>
</html>