谈谈Js闭包的那些事儿

闭包这个问题吧,说来也奇怪,懂得人吧,觉得这个东西也就那么回事儿,而不懂的人,就觉得讳若莫深。在我的理解中,闭包的使用,是为了解决Js语言中没有块级作用域这一问题的,也就是说,为了避免污染全局作用域,我们不得不尽量将变量的作用域缩小(当然也是为了性能着想,毕竟局部变量的访问速度要比全局变量来得快),据此,闭包这一技术得以诞生,简单地说,闭包就是利用函数内部作用域的特性来模拟块级作用域的一种方法


怎样使用闭包呢?说句大白话,就是外部函数里面套内部函数,然后将你想要的变量 return 返回外部函数就好了。是不是有点晕,现在就以代码的形式,好好地给您说道说道:

			var f1 = function(){
				var test1 = 9;
			}
			alert(test1 );    //==>error: test1 undefined

对于会Js的人,一看就知道test1f1的局部(私有)变量,而在f1的外部是无法访问的(实际上的内部机制,就是当f1这个方法执行完毕后,test1变量就与其他变量或方法没有任何关系了,当然就会被垃圾回收器当做垃圾处理),那么此时如果我们要访问test1会怎样做呢?通常我们要用returntest1返回给f1,即

			var f1 = function(){
				var test1 = 9;
				return test1;
			}
			alert(f1());     //==>9

上述代码,相信大家应该都能理解。。。这种获取test1的方法,我称为‘一次性读取’。什么叫‘一次性读取’呢?就是说test1只能被我们以这种读取一次,而想要改变test1的值只能在f1内操作完,然后被我们一次性提取,而不是像全局变量那种,可以被我们反复蹂躏。看不明白?那我还是乖乖上代码吧~~~

			var f1 = function(){
				var test1 = 9;
				test1++;
				test1 += test1;
				return test1;
			}
			alert(f1());      //==>20
                        alert(f1());      //==>20

经过对test1的一番折腾后,发现f1()确实也返回了我们想要的值,但这真正是我们想要的么?显然不是,我们想要的是每执行一次函数,我们想要的值(本例中为test1)应该(像全局变量一样)发生迭代变化,也就是说执行一次f1(),得到的值是20,再执行一次f1(),得到的值应该是42,以此类推。。。。

注意注意。。。。。。重点闭了个包来了。。。。。。

使用闭包只需要将上述函数改造一下:

			var f1 = function(){
				var test1 = 9;
				return function(){
					test1++;
					test1 += test1;
					return test1;
				};		
			}
			var temp = f1();
			alert(temp());    //==>20
			alert(temp());	   //==>42		

仔细看看,我们做了什么就使结果发生了改变呢?

我们加了一个匿名函数,

                       function(){
			     test1++;
			     test1 += test1;
			     return test1;
			};	

这一步就是我们的核心,当我们执行完,temp = f1()这一步后,实际上是在全局环境中,return(驻留)了一个匿名函数,就相当于我们人为地添加了一段块级作用域,怎么说呢?虽然Js语言是没有块级作用域将变量封装成局部变量的,但Js有函数,我们都知道函数内部就是一段小小的内部作用域,这个作用域里面的变量就是我们俗称的局部变量,这里的匿名函数就为test1模拟了一个块级作用域,使得test1在全局环境中贮存,这就相当于在全局环境中声明了一个全局变量test1

这里需要提醒,刚开始使用闭包的新手们,var temp = f1();是不可少的,如果你图省事,直接就

alert(f1());      //==>20
alert(f1());      //==>20

得到结果就是你创造两个独立的匿名函数区块,这里的test1就不能迭代使用了。

补充一个新知识点就是let关键字,它有什么用呢?简单明了的说,它的出现就是为了代替闭包的ps:仿佛听到了广大Js代码工作者的心声~~~上帝啊~~~let的作用就是为变量隐式提供一个块级作用域,奉上代码:

<html>
    <ul>
	<li><input type="button" value="0"></li>
	<li><input type="button" value="1"></li>
	<li><input type="button" value="2"></li>
    </ul>
</html>
<script>
	var input = document.getElementsByTagName('li');
	var len = input.length;
	for(let i=0;i<len;i++){
		input[i].onclick = function(){
		alert(i);
		};   
	} 
/*这段代码就是一个简单的let应用,将每个按钮的索引值贮存在内存当中,以便点击时显示*/
</script>

最后再说一句,let虽好用,可不要贪杯哦,因为不是所有浏览器都叫特仑苏。。。哦不对,是不是所有浏览器都支持let


完结!










  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值