<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>闭包</title>
	</head>
	<body id="body">
		<div id="1"></div>
		<div id="2"></div>
		<div id="3"></div>
		<hr color='red'/>
		<div id="4"></div>
		<div id="5"></div>
		<div id="6"></div>
		<hr color='red'/>
		<div id="7"></div>
		<div id="8"></div>
		<div id="9"></div>
		<script>
		//创建元素
		function cre(namee){
			return document.createElement(namee);
		}
		//根据id查找元素
		function $(id){
			return document.getElementById(id);
		}
			function fun1(){
				return function(){
					return "something";
				}
			}
			$("1").innerHTML=fun1;//返回整个fun1函数
			$("2").innerHTML=fun1();//返回整个内部匿名函数,加个()相当于调用该函数
			$("3").innerHTML=fun1()();//内部匿名函数返回的结果,加个()相当于调用该函数
		//效果同上
			var f1 = fun1;
			var f2 = f1();
			var result = f2();
			$("4").innerHTML=f1;
			$("5").innerHTML=f2;
			$("6").innerHTML=result;
			
		
		//通过对象实现累加(不使用全局变量)
			function Add(){
				this.num = 100;
				this.fadd = function(){
					this.num++;
				}
			}
			var ad = new Add();
			ad.fadd();
			ad.fadd();
			$("7").innerHTML=ad.num;
		//通过闭包来实习累加(不使用全局变量),可以让局部变量驻留在内存中
			//如果使用全局变量,如果全局变量过多,而且所有函数都可以使用,容易出问题。
			function add2(){
				var no = 9;
				return function(){
					return ++no;
				}
			}
			var add2_1 = add2();//返回的是函数内部的匿名函数,并初始化no的值
			$("8").innerHTML=add2_1();//10,调用该函数,每调用一次,no+1
			$("9").innerHTML=add2_1();//11
			add2_1 = null;//使用完设为空,让系统回收内存。
			
		//	用匿名函数给数组的元素赋值
			function arrfun(){
				var arr = [];
				for(var i = 0;i<5;i++){
					//给数组元素赋值(元素是匿名函数的返回值,所以创建该匿名函数就马上执行,并返回值),
					arr[i] = (function(){
						return "函数的返回值"+i;
					})()
					
				}
				return arr;
			}
		// 使用闭包,两个匿名函数嵌套,外层匿名函数(带参数)定义的时候就立即执行(将i作为参数传递进去),返回一个匿名函数(带参数,该参数和外层函数一致),赋值给a[i]
			function arrfun2(){
				var arr = [];
				for(var i = 0;i < 5;i++){
					arr[i] = (function(n){
						return (function(n){
							return "元素"+n;
						})
					})(i)					
				}
				return arr;
			}
		//	var arrfuns = arrfun();
			var arrfuns = arrfun2();
			for(i in arrfuns){				
				var div1 = cre("div");
				
				div1.innerHTML = i+"==="+arrfuns[i](i);
				//添加子节点
				$("body").appendChild(div1);
			}
			
		//闭包中的全局变量
			var name = "window";//全局变量
			var obj = {
				name:"obj",
				get:function(){
					return function(){
						return this.name;//window
					}
				}
			}
			var div2 = cre("div");
			//div2.innerHTML=obj.get()();//window
			div2.innerHTML=obj.get().call(obj);//obj,通过call(obj)指定该匿名函数的作用域为obj,所以this.name就变成了obj.name,即obj
			$("body").appendChild(div2);
		</script>
	</body>
</html>