分享

前端|在JS里有关于闭包的一些问题

 算法与编程之美 2020-08-08

问题描述

首先我们先来欣赏一段代码

function  test() {

var arr = [];

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

arr[i] = function (){

document.write(i + "  ");

        }

    }

    return arr;

}

var  Myarr = test();

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

Myarr[j]();

}

我们首先定义了一个test函数,然后在这个函数里面定义了一个数组,再通过for循环给数组里面的每一位变成一个函数,作用就是打印当前i的值。再然后return这个数组,最后在test函数外部定义Myarr,就等于test函数的执行结果,最后再执行Myarr数组的每一位。按之前的理解是执行的结果应该是0-9十个数字。但是实际结果是十个10.

解决方案

我们先来分析,为什么会打印出10,按道理说应该是9。问题就在于第一个for循环,i从1执行到了9,此时又重新开始一次循环,此时9<10,所以i就变成10了。但是此时i不满足for循环了,所以不执行里面的函数了。我们可以用以下代码解释

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

            document.write(i)

        }

        document.write(i)

我们再来看为什么会输出10个10呢。这个问题在于arr[i] = function(){document.write(i + " ")。代码在执行for循环的时候,前面i的值发生变化,但是在后面的这个function里面的i并不会发生变化,因为在循环的时候这个function只是一个赋值语句,它并不会去看里面的内容,只有在最后调用Myarr的时候在来看里面的内容,而此时i的值已经全部循环结束变成10了。那我们要是想要它输出0-9十个数字怎么办呢?

此时闭包已经形成了,闭包也分好的和不好的,出现这种情况就属于不好的。那么我们要怎么去避免呢。我们想要的就是for循环里面的function里的i能够跟随外面的i一起变化。此时我们可以采用立即执行函数,完整代码如下

    <script>

        function test() {

            var arr = [];

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

                (function (j) {

                    arr [j] = function () {

                    document.write(j + " ");

                    }

                }(i)); 

            }

            return arr;

        }

        var Myarr = test();

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

            Myarr[j]();

        }

    </script>


END

主  编   |   张祯悦

责  编   |  刘玉江

 where2go 团队


微信号:算法与编程之美          

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多