谈谈闭包中的 - 变量

  前面几篇文章中提到过,作用域链以及闭包的概念,这里就不一一重复了,

  作用域链的这种配置机制引出了一个值得注意副作用,既闭包只能取得包含函数中任何变量的最后一个值。别忘了闭包所保存的是整个变量对象,而不是某个特殊的变量。

        function createFunctions(){

            var result = new Array();

            for(var i=0;i<10;i++){

                result[i] = function(){

                    return i;

                }

            }

            

            return result;

        }  

                        

        从上面的代码,这个函数会返回一个函数数组。表面上看,似乎每个函数都应该返回自己的索引值,既位置0的函数返回0,依次类推。但实例每个函数都会返回10.

        因为每个函数的作用域链中都保存着 createFunctions() 函数的活动对象,所以它们引用的都是同一个变量i.

        那怎么解决这个问题尼? 可以通过创建另一个匿名函数强制让闭包的行为符合预期,如下所示

 

        function createFunctions(){

            var result = new Array();

            for(var i=0;i<10;i++){

                result[i] = function(num){

                   return function(){

                        return num;

                    }

                }(i);

            }

            return result;

        }        

 

        代码修改为上面的时候,似乎符合我们的初衷了,

        
     

        var result = createFunctions();

        alert(result[0]()); //0

        alert(result[1]()); //1

 

        使用一个外部匿名函数,并且自己内部定义了num 变量,在执行外部匿名函数时传递的i

        参数赋值给了num变量(值传递 也可以说是cope一个值),这样返回回去的函数访问就外部匿名函数中保存的 num 变量保存的变量值。

   上面须要注意的是:
      红色部分,循环一次就相当于声明一个函数(相当于 变量对象 个数就是循环次数),
      而不像 createFunctions 在整个循环执行完成的时候都是同一个变量对象(活动对象);所以在外部执行result保存的函数时,返回值都10的原因;
      记得前面提到过,当每个函数执行时,都会有一个对应的变量对象作(活动对象)其内部的 num 保存的是 i的副本值 ;所以蓝色部分匿名函数的作用域链中包含的外部匿名外部函数活动对象都是不一样,
      这也就是其返回的结果和我们预期一样的原因。

 

时间: 2024-11-10 07:47:27

谈谈闭包中的 - 变量的相关文章

谈谈java中静态变量与静态方法继承的问题

谈谈java中静态变量与静态方法继承的问题 学习的中如果遇到不明白或者不清楚的的时候,就是自己做些测试,自己去试试,这次我就做一个关于静态变量的继承和静态方法继承问题的测试. 首先我先建一个父类: 这样我在建一个子类: 这些都准备好以后,我对子类创建对象,然后用  类名.静态变量/静态方法  和  对象名.静态方法/静态变量  对他们输出的结果进行测试. 这样输出种类有: 这样我输出的结果是: 这样来总结一下: 1. 通过类名来调用子类中的静态变量和静态方法,当父类与子类相同时是,子类会隐藏父类

谈谈java中成员变量与成员方法继承的问题

谈谈java中成员变量与成员方法继承的问题 关于成员变量和成员方法的的继承问题,我也可以做一个小测试,来看看结果. 首先我们先创建一个父类: 其次再创建一个子类,子类中要比父类中少一个成员方法: 这样我们对子类创建对象,如果不创建对象,我们是无法访问子类的成员变量和成员方法的,因为“无法从静态上下文中引用非静态方法”.我们要输出有: 从以上的数据中,我们就可以得出的输出结果是 这样我们就可以得出结论. 总结: 1.   在结果中可以看出,子类的成员变量和成员方法,与其父类的相同的时候,子类就会覆

用闭包解决 js 循环中函数变量暂存问题

需求:有一个数组,根据数组的值渲染对应的数字div,单击对应的div 在控制台打印对应的数字.如点击1,控制台打印1. 问题: 不管点击哪个值 打出来都是4 代码如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>testFor</title> </head> <body> &l

闭包中的 内存泄漏

内存泄漏 如果闭包的作用域链中保存着一个HTML元素,那么就意味着该元素将无法被销毁. 1 function assignHandler(){ 2 var element = document.getElementById("someElement"); 3 element.onclick = function(){ 4 alert(element.id); 5 } 6 } 而这个闭包则又创建另一个循环引用.由于匿名函数保存了一个对 assignHandler()的活动对象的引用,因此

闭包中的 this 对象

关于this对象 在闭包中使用this对象也可能会导致一些问题.this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this等于window, function createFunction(){ alert(this); }; createFunction(); // window 而当函数被作为某个对象的方法调用时,this等于那个对象.不过,匿名函数的执行环节具有全局性,因此其this对象通常指向 window. 但有时候由于编写闭包的方式不同,这一点可能不会那么明显. var

python 闭包中引用的变量值变更问题

python的闭包的特点是返回的函数还引用了外层函数的局部变量,所以,要正确使用闭包,就要确保引用的局部变量在函数返回后不能变. 如下: def count():     fs = []     for i in range(1, 4):         def lazy_count(j):             def cou():                 return j*j             return cou         r = lazy_count(i)     

关于javascript闭包中的this对象

我们知道, this对象是运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象.<Javascript高级程序设计> 在下面的例子中,理解闭包中的this对象. var name = "The Window"; var object = { name: "My object", getNameFunc: function() { return function() { retur

以window作为Global目标函数效果域中的变量的函数

匿名函数与闭包运用函数表达式界说函数时,形如varfunctionNam=functionarg0,agr1{}即为匿名函数,由于function关键词后边没有标识符.闭包是指有权拜访另一个函数效果域中的变量的函数.经过在一个函数内创建另一个函数,可以创建闭包.?javascript中,只要办法是有效果域的办法中声明的变量在外部是无法拜访的2.BOMwindow目标表明浏览器的一个实例.既是经过javascript拜访浏览器窗口的一个接口,又是? ECMA Script规则的Global目标.

匿名方法中的变量

前面一篇文章看到了C# 2.0中通过匿名方法来简化委托,下面来看看匿名方法中的变量. 闭包和不同的变量类型 闭包的基本概念是:一个函数除了能够通过提供给它的参数与环境交互之外,还能同环境进行更大程度的互动.对于C# 2.0中出现的匿名方法的闭包表现为,匿名方法能使用在声明该匿名方法的方法内部定义的局部变量. 在进一步了解闭包之前,我们先看看下面两个术语: 外部变量(outer variable):是指其作用域(scope)包括一个匿名方法的局部变量或参数(ref和out参数除外) 被捕捉的外部变