什么是闭包,如何应用闭包

一、作用域和作用域链

当函数声明的时候,函数会通过内部属性[scope]来记录创建范围

DEMO1:

var str = '123';

function fn(){

	var str = '456';

	console.log( str );
}

fn();
输出结果:456

二、闭包

什么是闭包:闭包是一个函数加上到创建函数的作用域的连接,闭包“关闭”了函数的自由变量。
第一句话(得到的理解):2个函数,2个函数作用域[scope]还要连接上;
第二句话(得到的理解):关闭函数的变量自由:它暂时不会销毁;
(比如DEMO2中的变量n,DEMO3中的变量idx
因为有引用,所以不会暂时销毁,
原理:JS垃圾回收机制https://blog.csdn.net/qq_43540219/article/details/107519917)
DEMO2:

	function fun(n){
		return function (m){
			n+=m;
			return n;
		}	
	}
	//第一步
	var f = fun(5);
	//变量n=5,被闭包给“关闭”了(暂时不会被销毁)
	/*现在f=function (m){
			n+=m;//n=5
			return n;
	}*/
	//第二步
	console.log(  f(1)  );//执行前n=5,执行后n=6
	console.log(  f(1)  );//执行前n=6,执行后n=7
	console.log(  f(1)  );//执行前n=7,执行后n=8
输出结果:6 7 8  

三、无意间共享环境[可以通过闭包解决](闭包的实际应用)

DEMO3:

<body>

<ul>
	<li>111</li>0
	<li>111</li>1
	<li>111</li>2
</ul>


<script type="text/javascript">
var lis = document.getElementsByTagName('li');
for(var i=0;i<lis.length;i++){
	(function(){

		var idx = i;
		//idx保留当前循环的i值,用闭包“关闭”idx,使其一直存在
		lis[i].onclick = function(){
		//当点击的时候调用外层的idx(当函数内部没有则去外层找)
		//如果不这么做闭包,直接循环,则会导致所有的i都=3
		//原因参考js单线程和消息队列(循环不可能等onlick事件
		//否则js代码将会停在循环这里,直到onclick触发才到下一步)
			console.log(idx);
		}
	})();
}
</script>

猜你喜欢

转载自blog.csdn.net/qq_43540219/article/details/107520552