学习目标:
1.闭包详解
闭包
一、什么是闭包?
特点:
1、函数嵌套函数
2、内部函数可以引用外部函数的参数和变量
3、参数和变量不会被【垃圾回收机制】所收回
闭包的写法:
也就是在外部调用子级函数
function show(a){
var b = 20;
function bbb(){
alert(a + "," + b);
}
return bbb;
}
var ccc = show(5);
//此处ccc的值是show()函数执行完之后的返回值,也就是bbb函数
ccc();
闭包的自增:
普通函数:
/*普通函数*/
/*var a = 2;
function show(){
a++;
alert(a);
}
show();
show();*/
闭包
/*闭包*/
function show(){
var a = 2;
function add(){
a++;
alert(a);
}
return add;
}
var res = show();
//多次调用,实现递增
res();
res();
神奇的闭包写法
【注】第一个小括号是函数声明
解析:如果不写第一个函数的话,因为小括号的优先级高,先执行小括号,就会报错;
所以解决方法就是给前面的函数也加一个小括号(相当于提高他的优先级)
给函数前面加 ! 也可以提高优先级
第二个小括号是函数调用
注意:浏览器更新后,若什么都不写也可以,而加!则不行
1.第一个提高函数的优先级的方法 (加小括号)
var ccc = (function(){
var a = 2;
return function(){
a++;
alert(a);
}
})() ;
2.第二个提高函数优先级的方法 (加感叹号)
var ccc = !function(){
var a = 2;
return function(){
a++;
alert(a);
}
}() ;
ccc(); // 3
ccc(); // 4
二、闭包有什么好处,应用在哪里?
好处:
1、希望一个变量常驻在内存当中
解析:子级函数要用到父级函数的参数与变量,所以不会发生【垃圾回收机制】
2、避免全局变量污染
解析:当子级函数获取父级函数的参数和变量的时候,外部不能对变量就行修改
3、可以声明私有成员
解析:通过闭包实现变量和函数的私有化
【注】私有方法可以访问私有成员
function show(){
var a = 2; //私有成员
function aaa(){ //私有方法
a++;
alert("a+1之后的结果:" + a);
}
function bbb(){
a += 10;
alert("a+10之后的结果:" + a);
}
return {
//返回函数的时,以对象的形式,所以调用的时候直接调用a / b
a:aaa,
b:bbb
}
}
//调用
var xiaoming = show();
xiaoming.a(); //3
xiaoming.b();//这里面的a是,函数aaa执行完之后的a的值 //13
简化
还可以使用匿名函数,这样不用给每个函数都起名字(简写并直接调用)
var xiaoming = (function(){
var a = 2;//私有成员
function aaa(){ //私有方法
a++;
alert("a+1之后的结果:" + a);
}
function bbb(){
a += 10;
alert("a+10之后的结果:" + a);
}
return {
a:aaa,
b:bbb
}
})(); //函数调用
xiaoming.a();
xiaoming.b();
【注】只要父函数的函数名称不同,子级函数的名称相同无所谓,并且不会互相影响(模块化开发)
用法:
1、模块化代码 详情在上面的代码
2、在循环中直接找到对应元素的索引。
三、必要需要注意的地方?闭包有什么用?
IE下会引发内存泄漏
【注】事实上,通过使用闭包,我们可以做很多事情。比如模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的执行效率,同时避免对命名空间的污染,最重要的是可以从一个域中取出原本访问不到的变量去使用。
例题:
在循环中找到索引下标
/*普通写法*/
window.onload = function(){
var aBtn = document.getElementsByTagName('button');
for(var i = 0; i < aBtn.length; i++){
aBtn[i].index = i;//添加属性
aBtn[i].onclick = function(){
alert(this.index);
}
}
}
/*闭包写法*/
window.onload = function(){
var aBtn = document.getElementsByTagName('button');
for(var i = 0; i < aBtn.length; i++){
//会通过循环调用三次函数
aBtn[i].onclick = show(i);
//因为变量不会被回收,所以都会被存在自己的函数中,使用的时候调用即可
}
function show(index){
return function(){
alert(index);
}
【注】 /*show(0) 0存在show(0)中
show(1)
show(2)*/
}
}