JavaScript闭包详解

学习目标:
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)*/
			}
		}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值