【JS学习笔记】 匿名函数和闭包

晓石头的博客
邮箱:[email protected]
转载请注明出处,原文链接:http://blog.csdn.net/qiulanzhu/article/details/50612274


index.html:

<!DOCTYPE HEML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
 <head>
 <meta http-equiv="Content-Type" content="text/html;charset=gb2312"/>
   <title>使用JS</title>

 </head>
 <body>
	<div id="oDiv">Lee</div>
 </body>

 
</html>
    <script type="text/javascript" src="demo.js"></script>


demo.js

/*=============================匿名函数和闭包============================*/
//普通函数
function box(){
	return "qiu";
};

//匿名函数
//把匿名函数赋值给变量
var fun1 = function (){
	return "yi";
};

document.write(fun1() +"<br>");//这里有括号

//通过表达式自我执行
(function(){
	document.write("qiuyi<br>");
})();

//把匿名函数执行结果赋值给变量
var fun2 = (function(){
	return "qiuyi";
})();

document.write(fun2 +"<br>");//这里没有括号

//直接打印匿名函数的运行结果
document.write( (function(){
	return "direct printf<br>";
})() );

// 匿名函数传参运行
(function(age){
	document.write(age +"<br>");
})(27);

//函数里放一个匿名函数
function desk(){
	return function(){			//闭包
		return "qiuqiu";
	}
}

document.write(desk + "<br>");
document.write(desk() + "<br>");
document.write(desk()() + "<br>");

/*==========================闭包===========================*/
//闭包的含义:闭包说白了就是函数的嵌套,内层的函数可以使用外层函数的所有变量,即使外层函数已经执行完毕(这点涉及JavaScript作用域链)。
//闭包是指有权访问另一个函数作用域的变量的函数。
//创建闭包的常见方式:一个函数内创建另外一个函数

//通过闭包返回局部变量
function flower(){
	var age = 100;
	
	return function(){
		return age;
	}
}

document.write(flower()());

//闭包实现累加,让局部变量驻留内存中

function add(){
	var num = 100;
	return function(){
		return ++num;
	}
}

var myadd = add();
document.write( myadd() +"<br>");
document.write( myadd() +"<br>");
document.write( myadd() +"<br>");   //实现局部变量的累加
myadd = null;						//结束引用,等待垃圾回收

//循环里,匿名函数的取值问题
function loop(){
	var arr = [];
	
	for(var i=0; i<5; i++){
		arr[i] = function(){
			return i;
		}
	}
	
	return arr;
}

document.write(loop() + "<br>");
document.write(loop()[0] +"<br>");
document.write(loop()[0]() + "<br>");

//实现匿名函数里返回0,1,2,3,4,5
//改版1
function loop1(){
	var arr = [];
	
	for(var i=0; i<5; i++){
		arr[i] = (function(i){				//通过及时执行匿名函数,()():能够实现及时执行。在赋给一个变量时,可以不用前一个()。
			return i;
		})(i)
	}
	
	return arr;
}

for(var i=0; i<5; i++){
	document.write(loop1()[i]);
}
document.write("<br>");

//改版2
function loop2(){
	var arr = [];
	
	for(var i=0; i<5; i++){
		arr[i] = (function(num){		//num为传入的参数,等于i;
			return function(){
				return num;
			}
		})(i)
	}
	return arr;
}

for(var i=0; i<5; i++){
	document.write(loop2()[i]());
}
document.write("<br>");



/*============================this对象==============================*/
//全局:this指window
//对象内部:this指这个对象
//闭包:this指window,因为闭包不属于这个函数的属性或者方法。

//全局
document.write(this +"<br>");

//对象内部
var testThis = {
	getThis : function(){
		return this;
	}
}
document.write(testThis.getThis() +"<br>");

//闭包
var testThis1 = {
	getThis : function(){
		return function(){
			return this;
		}
	}
}
document.write(testThis1.getThis()() +"<br>");

var usr = "this window";

var bibao = {
	usr : "this inner",
	
	run : function(){
		return function(){
			return this.usr;			//返回this window
		}
	}
}

document.write(bibao.run()() +"<br>");

//让闭包里的this 指向对象
//方法一:对象冒充
document.write(bibao.run().call(bibao) +"<br>");

//方法二:变量替换
var usrs = "window";
var bibao2 = {
	usrs : "inner",
	run : function(){
		var that = this;
		return function(){
			return that.usrs;
		}
	}
}

document.write(bibao2.run()() +"<br>");


/*============================内存泄漏===============================*/
//内存泄漏:对象引用没有办法释放掉
function leak(){
	var oDiv = document.getElementById("oDiv");
	oDiv.onclick = function(){
		alert(oDiv.innerHTML);				//IE会存在内存泄漏
	}
}
//leak();

//修改
function leak1(){
	var oDiv = document.getElementById("oDiv");
	var tmp = oDiv.innerHTML;
	oDiv.onclick = function(){
		alert(tmp);
	}
	oDiv = null;		//解除应用,等待垃圾回收
}
leak1();

/*==========================模拟块级作用域==============================*/
//JS没有真实的块级作用域
function testi(){
	for(var i=0; i<5; i++){
		document.write(i);
	}
	document.write("<br>" +i+"<br>");   //i依然能够访问到,证实了JS没有块级作用域
}
testi();
  

//匿名函数模拟块级作用域
//匿名函数中定义的任何变量,都在执行结束后被销毁
//减少闭包占用内存问题
function testi2(){
	(function(){
		for(var j=0; j<5; j++){
			document.write(j);
		}
	})()
	
//	document.write(j);				//j不可见
}

testi2();

//私有数据
//get和set
function Night(){
	var age = 100;				//私有变量
	function run(){				//私有函数
		return "运行中...";
	}
	
	this.getAll = function(){
		return age + run();
	}
	
	this.setAge = function(num){
		age = num;
	}
}

var night = new Night();
night.setAge(200);
document.write(night.getAll());


//静态私有变量
//实现私有数据共享
(function(){
	var age = 100;
	Qiu = function(iage){					//全局的构造函数,外部能够访问
		age = iage;
	}
	
	Qiu.prototype.getAge = function(){
		return age;
	}
})()

var age1 = new Qiu(27);
document.write(age1.getAge());
var age2 = new Qiu(28);
document.write(age1.getAge());	//age1中的age也发生了变换

/*==============================模块模式=============================*/
//之前都是用构造函数的方式来创建私有变量和特权方法。
//对象字面量方式就采用模块模式来创建。
//字面量被看作一种单例模式,永远保持一个对象实例
var phone = (function(){
	var age = 100;
	function run(){
		return "运行中..";
	}
	
	var obj = {
		getAll : function(){
			return age + run();
		}
	}
	return obj;
})()
document.write(phone.getAll());

//增强型的模块模式,这种模式适合返回自定义对象,也就是构造函数
function Pen(){};

var pen = (function(){
	var age= 100;
	function run(){
		return "运行中..."
	}
	
	var myPen = new Pen();
	myPen.getAge = function(){
		return age;
	}
	
	return myPen;
})()

document.write(pen.getAge());


你可能感兴趣的:(JavaScript,匿名函数,闭包)