// 引例
<script type="text/javascript">
// 闭包
function t1() {
var age = 20;
function t2() {
alert(age);
}
return t2;
}
var tmp = t1();
var age = 99;
tmp(); //20
</script>
/*
1:在大部分的语言中,t1被调用执行,则申请内存并把其局部变量push入栈。
t1函数执行完平,内部的局部变量随着函数的退出而销毁
因此,age = 20的局部变量,依靠已经消失了。
但是在js中,age- 20这个变量,却被t2捕捉,
即便t1执行完毕,通过t2,依然能访问该变量
这种情况—返回的函数,并非孤立的函数.甚至把其周围的变量环境,形成了一封闭的“环境包”,共同返回,所人可“闭包”
一句话概括—-函数的作用域取决于声明时,而不取决于调用时
*/
// 闭包例一:穿越清宫
<script type="text/javascript">
// 函数的作用域取决于声明时
function closure() {
var sister = '大桃花';
var mysister = function() {
return sister;
}
return mysister; // 这个人出生的时候就已经有个sister 叫做大桃花了
}
function place() { // 大清宫殿内
var sister = '大福晋';
var mysister = closure(); // 调用closure,mysister函数穿越到宫内
alert(mysister()); // 大桃花
}
place();
</script>
// 闭包例二:计数器
/*
闭包计数器
多个人开发js程序,需要一个全局的计数器
–多个人的函数共同用一个计数器,计数器一直增长
解诀办法:
1: 设立一个全局变量
window.cnt = 0;
调用++window.cnt;
这个办法可行,
但是,污染了全部变量.
扫描二维码关注公众号,回复:
1016607 查看本文章
其次,引入了多入的程序,别人的程序里,也有一个window.cnt=’he11o’ ;
该计数器就损坏了.(所以要尽量避免用全局变量)
2: 闭包维护一个别人污染不到的变量,做计数器
*/
<script type="text/javascript">
// 第1版计数器
function counter() {
var cnt = 0; // 当counter执行完毕后,除了返回的cnter函数,谁都别想碰cnt变量.
var cnter = function() {
return ++cnt;
}
return cnter;
}
var inc = counter();
alert(inc()); //1
alert(inc()); //2
alert(inc()); //3
</script>
<script type="text/javascript">
// 第2版简化
var cnt = (function() {
var cnt = 0;
return function() {
return ++cnt;
}
})();
alert(cnt()); //1
alert(cnt()); //2
alert(cnt()); //3
// 在这里:cnt依然是全局变量
</script>
<script type="text/javascript">
/*
第3版 --在工作中,一般如何避免全局污染或冲突
1、统一放在一个全局对象上,如jQuery->$
2、每人用自己的命名空间.
*/
// jquery的计数器插件形式
$ = {};
$.cnt = (function() {
var cnt = 0;
return function() {
return ++cnt;
}
})();
alert($.cnt()); //1
alert($.cnt()); //2
alert($.cnt()); //3
// 个人命名空间
// 将自己的变量,函数都放在一个对象里.
var DYW = {}; // 跟团队说清,这是我的空间,别人不要用了
DYW.cnt = (function() {
var cnt = 0;
return function() {
return ++cnt;
}
})();
alert(DYW.cnt()); //1
alert(DYW.cnt()); //2
alert(DYW.cnt()); //3
</script>
// 课后作业
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="description" content="" />
<meta name="keywords" content="" />
<style type="text/css"></style>
</head>
<body>
<ul>
<li>男</li>
<li>女</li>
<li>老</li>
<li>少</li>
</ul>
</body>
<script type="text/javascript">
// 要求: 点击li,分别弹出0,1,2,3
/*
for(var i=0,lis=document.getElementsByTagName('li'),len=lis.length; i<len; i++)
{
lis[i].onclick = function()
{
alert(i);
}
} //结果是4,4,4,4
*/
for(var i=0,lis=document.getElementsByTagName('li'),len=lis.length; i<len; i++)
{
lis[i].onclick = (function(i)
{
return function()
{
alert(i++);
}
})(i);
} //结果是0,1,2,3
</script>
</html>