`

for循环 闭包

    博客分类:
  • js
阅读更多

a='xxxx';
                        for (var i = 0; i < o.length; i++) {
                            (function() {
                                var obj = o[i];
                                popMenu.addMenuItem({
                                    menuId : obj.stateId,
                                    text : obj.stateName,
                                    disabled : false,
                                    clickF : function(menu) {
                                        alert(obj.stateName+a);
                                    }
                                });
                            })();
                        }

 

 

----------------------------------------------------------------------------------------

<div id="test">
<div>第一个</div>
<div>第二个</div>
<div>第三个</div>
<div>第四个</div>
</div>
<script>
function test()
{
var els = document.getElementById("test").getElementsByTagName("div");
for (var i = 0; i < els.length; i++)
{
var div = els[i];
div.onclick = function()
{
alert(div.innerHTML);
return false;
}
}
}
test();
</script>
无论我们点击哪个div,反馈的都是第4个div的内容。究其原因,在于每个div的点击事件都与test方法形成了闭包,且每个div的点击事件都共享同一个闭包作用域链。当事件被触发时,变量i所代表的下标已经指向第4个div。可以采用以下几种方式避免由于闭包引起的问题。
(1)使用this转换闭包的作用域链上下文,上例的闭包可以改写为:
for (var i = 0; i < els.length; i++)
{
var div = els[i];
div.onclick = function()
{
alert(this.innerHTML);
return false;
}
}
当点击div的事件被触发时,查找的作用域已经是“this”所指定的上下文。尽管该事件仍然处于“test”闭包内,但由于不访问或不使用闭包的上下文环境,也就不存在由于闭包作用域内变量被引用所引发的问题。
(2)使点击div的事件与for循环形成闭包,而使得for循环内的变量div不被回收。如:
//for循环内定义闭包方法
for (var i = 0; i < els.length; i++)
{
var div = els[i];
a(div);
function a(o)
{
o.onclick = function()
{
alert(o.innerHTML);
}
}
}
//for循环外定义闭包方法
for (var i = 0; i < els.length; i++)
{
var div = els[i];
a(div);
}
function a(o)
{
o.onclick = function()
{
alert(o.innerHTML);
}
}
//使用匿名方法,其原理与for循环内定义类似
for (var i = 0; i < els.length; i++)
{
var div = els[i];
(function(o)
{
o.onclick = function()
{
alert(o.innerHTML);
}
})(div);
}
通过中间方法a或者匿名方法,使for循环体与onclick事情产生闭包。
(3)控制变量的作用域,使点击div的事件所需变量与外层作用域无关。如:
for (var i = 0; i < els.length; i++)
{
(function()
{
var div = els[i];
div.onclick = function()
{
alert(div.innerHTML);
}
})();
}
内部函数自身也可能有内部函数。每次作用域链嵌套,都会增加由创建内部函数对象的执行环境所引发的新活动对象。ECMA262规范要求作用域链是临时性的,但对作用域链的长度却没有加以限制。闭包的潜规则即Function与内部定义的Function之间的相互作用域链上下文环境的关系。如果运用得当,嵌套的内部函数所拥有的潜能将超出了我们的想象力。

分享到:
评论

相关推荐

    浅谈JavaScript for循环 闭包_.docx

    浅谈JavaScript for循环闭包 在JavaScript中,for循环和闭包是两个非常重要的概念。本文将对JavaScript for循环和闭包进行浅谈,并提供六种解决方案来解决for循环中的闭包问题。 首先,让我们来看一个例子。我们有...

    浅谈JavaScript for循环 闭包

    然而,在处理JavaScript中的闭包时,for循环常常会带来一些特别的问题。闭包是指有权访问另一个函数作用域中的变量的函数。这个问题通常出现在循环结构中,比如在为DOM元素的事件处理器(如点击事件)绑定函数时。这...

    采用自执行的匿名函数解决for循环使用闭包的问题

    然而,当闭包与循环结合时,可能会遇到一些预期之外的问题,正如标题和描述中提到的那样。本文将深入探讨这个问题,并介绍如何通过使用自执行的匿名函数来解决。 首先,让我们看一个简单的例子,这个例子展示了在不...

    for循环_作用域_闭包.html

    for循环_作用域_闭包.html

    详解Python循环作用域与闭包

    ### 详解Python循环作用域与闭包 #### 前言 本文主要探讨Python中循环作用域的概念以及如何利用闭包解决循环作用域所带来的问题。文章通过实例代码深入浅出地解析了Python作用域机制,并提供了两种解决方案:避免...

    动态循环给onclick赋值(解决闭包问题)

    然而,当涉及到动态循环给onclick事件赋值时,闭包问题可能会出现,导致意外的结果。这个问题通常出现在创建多个事件处理函数,而每个函数都需要访问循环中的变量时。 在描述中提到的"动态循环给onclick赋值"是指在...

    传递闭包matlab程序

    ### 传递闭包Matlab程序知识点详解 ...上述代码示例详细展示了如何利用Matlab实现传递闭包算法的过程,包括初始化变量、主循环以及终止条件的设置。这些内容对于理解和应用传递闭包算法于实际问题解决具有重要意义。

    迭代器、代码块、闭包

    使用`for`循环或内置的`iter()`和`next()`函数可以轻松地与迭代器交互。例如,自定义类可以通过实现迭代器协议来成为可迭代的,这使得在处理大量数据时能有效节省内存。 接下来,我们探讨代码块。在编程中,代码块...

    (Swift)闭包作为属性

    闭包作为属性时,闭包会强引用持有它的对象,可能导致循环引用(Strong Reference Cycle)。为了解决这个问题,我们可以使用`weak`或`unowned`修饰符来弱引用或无主引用对象,防止循环引用。 总之,Swift中的闭包...

    浅谈js for循环输出i为同一值的问题

    在JavaScript编程中,for循环是常见的迭代工具,用于遍历数组或对象的元素。然而,在处理事件绑定,尤其是涉及到异步操作时,如点击事件,可能会遇到一个常见问题:循环内的变量共享导致输出不按预期进行。这个问题...

    3.var处理for循环.md

    ### 3.var处理for循环.md #### 知识点概览 本文档主要探讨了在JavaScript中使用`var`关键字处理`for`循环时的一些特殊技巧及其背后的原理。此外,文档还简要提及了`let`关键字的使用,并通过一个具体的示例来展示...

    离散闭包运算

    它通过三层循环遍历关系矩阵,检查是否存在 (i, j) 和 (j, k),则添加 (i, k) 来确保传递性。 ```c void chuandi(int y[100][100], int b) { // 添加传递对 for (int j = 0; j ; j++) { for (int i = 0; i ; i++...

    离散数学-闭包运算-.net

    然后,通过嵌套循环遍历所有节点对,用当前节点对的关系去更新所有可能的间接关系。以下是简化的C#代码实现: ```csharp bool[,] graph = new bool[V, V]; // V是节点数 // 初始化邻接矩阵 for (int k = 0; k ; k+...

    javascript循环变量注册dom事件 之强大的闭包

    今天遇到了这个问题: 代码如下: //伪代码 for (var i=0; i&lt;n; i++) { addEvent(obj[i], “click”, func(i)); } 结果出现了问题,所有的dom都被注册了 i=n 的时候的事件,查了一些资料,说是在循环过程过this被...

    离散数学编程之用C++编写的求自反闭包程序

    在这个例子中,我们首先读取集合的大小和关系矩阵,然后通过简单的循环操作,将对角线元素设置为1,从而得到自反闭包。最后,我们输出自反闭包矩阵。 "求自反闭包2(改进)"可能是对上述代码的优化版本,可能包括更...

Global site tag (gtag.js) - Google Analytics