js 闭包

原创
2014/05/16 10:54
阅读数 1.2K


<html>
	<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
		<title>test</title>
	</head>
	<body>
		<script>
		/*
		* 零零碎碎的,等明白了之后再整理
		*js闭包涉及到几个其它特性:作用域链、垃圾(内存)回收机制,函数嵌套等
		*/

		//作用域链:把函数内变量放在最前面,把自身的父级函数中的变量放在其次,把再高一级函数中的变量放在更后面,以此类推直至全局对象为止.
		//js解释器在遇到函数定义的时候,会自动把函数和他可能使用的变量(包括本地变量和父级和祖先级函数的变量(自由变量))一起保存起来.也就是构建一个闭包

		//1、作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
		//2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
		// var a = "aaa";
		// function Atest(){
		// 	var a = "function a";
		// 	alert(a);
		// 	function Btest(){
		// 		var a = "function b";
		// 		alert(a);
		// 		return function(){
		// 			var a = "function c";
		// 			alert(a);
		// 		}
		// 	}
		// 	return Btest();
		// }
		// Atest()();

		

		// var result = [];
		// function foo(){
		// 	var i=0;
		// 	for(;i<3;i++){
		// 		result[i] = (function(j){
		// 			return function(){alert(j);}
		// 		})(i);
		// 	}
		// }
		// foo();
		// result[0]();
		// result[1]();
		// result[2]();

		/*先从闭包特点解释,应该更好理解.

		闭包的两个特点:

		1、作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
		2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。

		其实上面两点可以合成一点,就是闭包函数返回时,该函数内部变量处于激活状态,函数所在栈区依然保留.

		我们所熟知的主流语言,像C,java等,在函数内部只要执行了return,函数就会返回结果,然后内存中删除该函数所在的区域.生命周期也就停止了.一般的js函数也是这样.
		但是有闭包特性的js函数有点特殊.
		就例子来说:
		function a(){
		 var i=0;
		 function b(){
		 alert(++i);
		 }
		 return b;
		}
		var c = a();
		c();

		这是个标准的闭包.在函数a中定义了函数b,a又return了b的值.这些可以先不管.
		var c = a();
		c();
		这两句执行很重要.
		在var c = a();这行里,执行了a函数,那么肯定a经过了return.按照主流语言的函数特性,现在c的值就是a的返回值.
		第二行c()的执行实际执行的就是b函数.最后不管执行的是谁,会弹出一个值为0的窗口,到此为止,所有的生命周期按理论来说就算全部结束了.
		可是,如果我们再多执行一行.
		var c = a();
		c();
		c();
		第一次弹出0,第二次执行却弹出了1.

		也就是说,第一次c()后,a中的i依然保留.自然a在内存的栈区依然保留.

		a是return过了,但是,a及内部值却依然存在,这就是闭包.

		好了,总结下,
		1,闭包外层是个函数.
		2,闭包内部都有函数.
		3,闭包会return内部函数.
		4,闭包返回的函数内部不能有return.(因为这样就真的结束了)
		5,执行闭包后,闭包内部变量会存在,而闭包内部函数的内部变量不会存在.

		闭包的应用场景(呵呵,复制的参考资料)
		1、保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。
		2、在内存中维持一个变量。依然如前例,由于闭包,函数a中i的一直存在于内存中,因此每次执行c(),都会给i自加1。

		根据参考资料的应用场景,我们会自然的想到java或是c++的类.虽然JS没有类的概念,但是有了类的相似执行结果.

		另外,还有一种格式颇受争议:
		(function(a,b))(a,b);
		如果你使用过jquery,并且观察过他的代码,你就会很奇怪他的写法,网上有人也把这种格式叫做闭包.*/
	</script>
	</body>
</html>



展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
6 收藏
0
分享
返回顶部
顶部