JavaScript学习笔记

闭包概念

声明在一个函数里的函数叫闭包.在闭包的内部可以访问其外部函数里定义的局部变量.

闭包的两个作用:
1.可以通过闭包获取函数内的局部变量.
2.通过闭包可以保证局部变量的生命周期与整个网页的生命周期一样.

function t1(){
	var age = 20;
	function t2(){
		alert(age);
	}
	return t2;
}
var tmp = t1();
var age = 99;
tmp();//20

在大部分的语言中,t1被调用执行,则申请内存,并把局部变量push入栈。
t1函数执行完毕,内部的局部变量随着函数的退出而销毁。因此,age = 20这个局部变量就消失了。

但是在js中,age = 20这个变量却被t2捕捉,
即使t1执行完毕,通过t2依然能够访问该变量。
这种情况返回的函数,并非孤立的函数,甚至把其周围的变量环境,形成了封闭的“环境包”,共同返回,所以叫闭包。

概括:函数的作用域取决于声明时,而不取决于调用时。

闭包的应用-闭包计数器

多个人开发js程序,需要一个全局计数器,多个人的函数共同用一个计数器,计数器一直增长

解决办法:
设立一个全局变量,window.cnt = 0;
调用:++window.cnt;

这个方法可行,但是应该避免过多的使用全局变量,防止全局变量被污染。
当你引用其他人的js程序时,如果他的程序内也有一个全局变量window.cnt = 'hello';
那么你的全局变量就会被无情的改变了。

那么可以考虑使用闭包维护一个别人污染不到的变量,做计数器。

function counter(){
	var cnt = 0;//当counter执行完毕后,除了返回的cnter函数谁也访问不到cnt变量了
	var cnter = function (){
		return ++cnt;
	}
	return cnter;
}
var inc = counter();
alert(inc());
alert(inc());
alert(inc());

// 但是还是产生了2个变量,counter和inc

简化版本:

var cnt = (function (){
	var cnt = 0;
	return function(){
		return ++cnt;
	}
})();

alert(cnt());
alert(cnt());

// cnt 不依然是全局变量吗?

那么在工作中,该如何避免全局变量的污染。

1:统一放在一个全局对象上,如:jquery ->$
2:每人用自己的命名空间。

jquery的计数器插件形式

$ = {};
$.cnt = (function (){
	var cnt = 0;
	return function(){
		return ++cnt;
	}
})();
alert($.cnt());

2.个人命名空间,在团队开发中也很常见。
var YK = {};
YK.cnt = (function (){
	var cnt = 0;
	return function(){
		return ++cnt;
	}
})();
alert(YK.cnt());

闭包练习题

<ul>
	<li></li>
	<li></li>
	<li></li>
	<li></li>
</ul>
<script type="text/javascript">
// 要求:点击li分别弹出 0 1 2 3
window.onload=function(){
	 var lis=document.getElementsByTagName("li");

	 for(var i=0;i<lis.length;i++){
		lis[i].onclick=function(i){
			return function(){alert(i)};
			//return alert(i);为什么这么写不可以?
		}(i);
	 }
}
</script>