当前位置: 代码迷 >> JavaScript >> 奇怪的闭环行为
  详细解决方案

奇怪的闭环行为

热度:95   发布时间:2023-06-07 16:41:07.0

所以我已经在这里学到了很多关于闭包的知识。

但是我仍然找到一个我自己无法解释的例子:

       function buildList(list){
            var result = [];
            for(var i = 0; i < list.length; i++) {
                var item = "item: " + list[i] + " i's value: " + i;  //i has the value of 2 here, but why?
                result.push( function(){document.write(item + ", list[i]:" + list[i] + ", i's value in the anonymous function:" + i + "<br>")});
            } //i = 3 here
            return result;
        }

        function testList(){
            var testTheList = buildList([1,2,3]);
            for (var j = 0; j < testTheList.length; j++) {
                testTheList[j]();
            }
        }

        testList();

正如我期望的那样,当我执行testList()时应该为3。

但是结果是:

项目:3我的值:2,列表[i]:未定义,我在匿名函数中的值:3

项目:3我的值:2,列表[i]:未定义,我在匿名函数中的值:3

项目:3我的值:2,列表[i]:未定义,我在匿名函数中的值:3

为什么我要为var item => 2而我要在匿名函数=> 3中? 在我阅读时,闭包创建了新的执行环境,但是我不应该为闭包使用相同的值吗?

编辑

这不是的重复 ,我不知道如何创建新的执行环境。

我想知道为什么同一变量i(循环)的值在同一范围内不同?

当您将新函数添加到result列表中时,它会保留对item变量的引用,并且i计数。 buildList函数内部的循环期间,您不会创建几个item变量,但是您会覆盖现有的变量,在buildList函数的itemi变量执行值的末尾看起来像这样:

  • 3
  • “项目:3我的价值:2”

并且list[i]undefined因为您的列表长度是3,没有list[3]项。 因此,当您从testList的循环中调用匿名函数时,将testList运行您与itemi变量保留的值完全相同的值。 还要在循环中创建匿名函数不是最佳实践,我建议您像这样修改buildList函数:

 function buildList(list) { var index = 0; return function () { if (index >= list.length) return var item = "item: " + list[index] + " i's value: " + index; document.body.innerHTML += [ item, ", list[i]:", list[index], ", i's value in the anonymous function:", index, "<br>" ].join('') index++ } } function testList() { var list = [1, 2, 3]; var testTheList = buildList(list); document.body.innerHTML = ''; for (var j = 0; j < list.length; j++) { testTheList(); } } testList(); 

  相关解决方案