zoukankan      html  css  js  c++  java
  • setTimeout 与 闭包。。。

    先看下面一个比较坑的代码

    for (var i=1; i<=5; i++) {
        setTimeout( function timer() {
            console.log(i);
        }, i*1000 );
    }

    首先一个for循环, 会执行五次, setTimeout被执行了五次

    但里面的timer这时候并没有执行, 而是依次在1 2 3 4 5秒后执行

    此时只建立了全局上下文;

    timer放在了事件队列里面执行; timer执行时, for循环已经完成

    全局作用域中的i变量值变成了6, 此时创建timer的作用域和作用域链

    因为timer里面并没有定义i, 也没有给i赋值, 所以timer 在自己的作用域是找不到i的,

    只能沿着作用域往上找, 找到全局作用域的i, 

    timeri 获取全局作用域i, 也就是6, 所以5次timer都是输出6

    当加入闭包的时候, 情况就不一样了。

    for (var i=1; i<=5; i++) {
              
                (function(j) {
                    window.setTimeout(function(){console.log(j)}, j*1000);
                })(i)
            }
     

    第一次 for循环的时候, 同时又有自执行函数

    也就是在for执行的同时, 执行了匿名函数, 创建了匿名函数的作用域, 此时建立了匿名函数的上下文环境;

    进入匿名函数的作用域的时候, 包含了一个内部函数 function(){console.log(j)}

    同时这个函数被全局变量 window.setTimeout引用,这就形成了闭包!

    在匿名函数执行完后,匿名函数的执行上下文出栈

    也就是在for循环第一次执行完后,

    匿名函数的的活动变量 j , 由于闭包的关系,并没有被销毁,

    而是保存在第一个window.setTimeout定时器中, 此时i 是1; j也是1; 这个值会一直保存在第一个定时器属性中;

    直到第一个定时器被销毁;

    然后进入第二次循环, 同理 又进入匿名函数, 创建了第二个闭包, 闭包的活动变量j 被第二个定时器引用;

    也会保存在在第二个定时器中, 此时 i,j都是2;

    依次类推, 3 4 5; 完成需求!

  • 相关阅读:
    P2121 拆地毯
    ※P1194 买礼物
    P1991 无线通讯网
    P2872 [USACO07DEC]Building Roads S
    python+pycharm+selenium+谷歌浏览器驱动 自动化环境部署(一)
    from bs4 import BeautifulSoup 引入需要安装的文件和步骤
    小菜鸟的python3.8.5+RobotFramework+RIDE的安装之路
    IntelliJ IDEA 之 工具箱(Tool Box)
    RobotFrameWork Web自动化测试环境搭建
    Python pip 安装与使用
  • 原文地址:https://www.cnblogs.com/dhsz/p/8444046.html
Copyright © 2011-2022 走看看