• JS 闭包


    一个你可能觉得很奇怪的现象

        var batch = [];
        var i = 0;
        for (; i < 5; i++) {
            batch.push(function closureFn() {
                console.log(i);
            });
        }
        batch.forEach(function(item){item()});

    输出

    5个5  值都是i最后的结果

    先来看看上面一段代码都做了什么
    这里循环做的事情是向push数组中存放元素 这个元素是函数
    所以输出一下batch得到
    [function closureFn(){
    console.log(i);
    }, ...]
    最后对batch的每一项进行遍历并执行  故item() 运行的话就是输出i的值

    既然如此为什么都是输出的5呢?
    batch这个数组中的forEach的回调函数中变量i是全局变量i
    所以for循环执行完后 i的值就已经是5  之后forEach每一项再执行的话  返回函数的时候i就是5

    闭包也是同样的道理

        function outer(){
            var batch = [];
            var i = 0;
            for (; i < 5; i++) {
                batch.push(function closureFn() {
                    console.log(i);
                });
            }
            batch.forEach(function(item){item()});
        }
        outer();

    得到5个5  根据scope chain的原则  在执行closureFn这个函数中发现并没有变量i  所以会查找到父函数outer中的i

    此时for循环已经执行完毕..  i的值就是5  

    PS  闭包引用了外部函数的变量  (引用!)

    那么如何得到01234呢?

    可以使用立即执行函数来解决这个问题

            var batch = [];
            var i = 0;
            for (; i < 5; i++) {
                batch.push(function closureFn(index) {
                    return index;
                }(i));
            }
            console.log(batch); //[0, 1, 2, 3, 4]

    这里使用了立即执行函数 所以每一次循环参数index得到的都是该轮循环的索引值
    和前面不同 这里并没有把闭包(内部函数)直接赋值给数组 而是将该内部函数的执行结果赋值给数组
    PS index不是i的引用 而是每次循环的时候i将自己的值传给index (传参的时候都是按值传递的)
    数组中每个元素都有index变量的一个副本 因此就有01234

    其他的博客:http://web.jobbole.com/82053/

    更深刻的例子:http://www.cnblogs.com/cart55free99/p/3624489.html

  • 相关阅读:
    【SpringBoot】04.SpringBoot整合Filter的两种方式
    【SpringBoot】03.SpringBoot整合Servlet的两种方式
    【SpringBoot】02.编写HelloWorld
    【SpringBoot】01.创建Springboot项目及启动器
    Nginx——安装Nginx(二)
    Nginx——Nginx概述(一)
    与、或、异或的运算
    设计模式——单例模式
    MYSQL在当前日期的基础上加上N(年月日分秒)
    阿里云简单的HTTPS配置
  • 原文地址:https://www.cnblogs.com/cart55free99/p/3805974.html
Copyright © 2020-2023  润新知