js----闭包

[code]
一、什么是闭包?

内部function会close-over外部function的变量直到内部function结束
funA 里面return 了个funB ,funB持有了funA的变量,因为被return出去,funB将负责管理funA的那个变量,并且这个变量变成了一个公共的变量,每次使用后都不会消亡,值还在。


闭合的表达式,或称闭包;
意义:闭包可以用来在一个函数与一组“私有”变量之间创建关联关系。在给定函数被多次调用的过程中,这些私有变量能够保持其持久性。

  “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

  相信很少有人能直接看懂这句话,因为他描述的太学术。我想用如何在Javascript中创建一个闭包来告诉你什么是闭包,因为跳过闭包的创建过程直接理解闭包的定义是非常困难的。看下面这段代码:

function a(){
var i=0;
function b(){
alert(++i);
}
return b;
}
var c = a();
c();

  这段代码有两个特点:

  1、函数b嵌套在函数a内部;

  2、函数a返回函数b。

  这样在执行完var c=a()后,变量c实际上是指向了函数b,再执行c()后就会弹出一个窗口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数a外的变量c引用了函数a内的函数b,就是说:

  当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。

$(function(){ ---1
var local=1;
window.setInterval(function(){--2
local ++;
window.stats=local;
},3000);
});

注意 函数1执行一次就结束了,但是由于函数2还得执行,所以函数1中的变量并没有被回收

注意:函数的上下文决不被包含为闭包的一部分
...
this.id='someID';
$('*').each(function(){
alert(this.id); //这个this和上面的this显然不是同一个this。。。不能这么用
});
改:
this.id='someID';
var outer=this;
$('*').each(function(){
alert(outer.id);
});

陷阱:
var k = [];
for (var x = 1; x < 4; x++) {
k.push(function () { return x; });
}
alert(k[0]())
这里居然是三个3 ,迭代过程中共用了同一个context,导致k中的三个闭包都引用了同一个变量x,他实际上记录的是内存的地址


------------------------------------------------------------------------------
有个网友问了个问题,如下的html,为什么每次输出都是5

1.<html >2.<head>3.<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />4.<title>闭包演示</title>5.<style type="text/css">6.</style>7.<script type="text/javascript">8.9.function init() {
10. var pAry = document.getElementsByTagName("p");
11. for( var i=0; i<pAry.length; i++ ) {
12. pAry[i].onclick = function() {
13. alert(i);
14. }
15. }
16.}
17.</script>18.</head>19.<body οnlοad="init();">20.<p>产品一</p>21.<p>产品一</p>22.<p>产品一</p>23.<p>产品一</p>24.<p>产品一</p>25.</body>26.</html>


解决方式有两种,
1、将变量 i 保存给在每个段落对象(p)上

1.2.
3.function init() {
4. var pAry = document.getElementsByTagName("p");
5. for( var i=0; i<pAry.length; i++ ) {
6. pAry[i].i = i;
7. pAry[i].onclick = function() {
8. alert(this.i);
9. }
10. }
11.}

12.

13.14.
2、将变量 i 保存在匿名函数自身

1.
2.function init2() {
3. var pAry = document.getElementsByTagName("p");
4. for( var i=0; i<pAry.length; i++ ) {
5. (pAry[i].onclick = function() {
6. alert(arguments.callee.i);
7. }).i = i;
8. }
9.
10.}

再增加3种

3、加一层闭包,i以函数参数形式传递给内层函数

1.
2.function init3() {
3. var pAry = document.getElementsByTagName("p");
4. for( var i=0; i<pAry.length; i++ ) {
5. (function(arg){
6. pAry[i].onclick = function() {
7. alert(arg);
8. };
9. })(i);//调用时参数10. } -----这种方式不错。。。
11.}

12.


4、加一层闭包,i以局部变量形式传递给内存函数

1.
2.function init4() {
3. var pAry = document.getElementsByTagName("p");
4. for( var i=0; i<pAry.length; i++ ) {
5. (function () {
6. var temp = i;//调用时局部变量7. pAry[i].onclick = function() {
8. alert(temp);
9. }
10. })();
11. }
12.}

13.

5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)

1.
2.function init5() {
3. var pAry = document.getElementsByTagName("p");
4. for( var i=0; i<pAry.length; i++ ) {
5. pAry[i].onclick = function(arg) {
6. return function() {//返回一个函数7. alert(arg);
8. }
9. }(i);
10. }
11.}
12.

又有一种方法

6、用Function实现,实际上每产生一个函数实例就会产生一个闭包

1.function init6() {
2. var pAry = document.getElementsByTagName("p");
3. for( var i=0; i<pAry.length; i++ ) {
4. pAry[i].onclick = new Function("alert(" + i + ");");//new一次就产生一个函数实例5. }
6.}




本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zhouruitao/archive/2008/09/11/2913936.aspx


[/code]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值