zoukankan      html  css  js  c++  java
  • 闭包典型-for循环

    一、闭包的概念

    • 闭包就是有权访问另一个函数作用域中变量的函数,闭包的主要存在形式就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量

    二、for循环按顺序顺出

    • for (var i = 0; i < 5; i++) {
        setTimeout(() => {
          console.log(i);
        }, 1000);
      }

      执行结果:输出五个5

            

            解析:for循环的时候,你并没有执行这个函数,你这个函数是过一秒才执行的,当执行这个函数的时候,

                       它发现它自己没有这个变量i,于是向它的作用域链中查找这个变量i,因为这个时候已经for循环完了,
                       所以储存在作用域链里面的i的值就是5,最后就打印出来5了。
    • 如何按顺序打印索引呢?
      • 使用let
        for (let i = 0; i < 5; i++) {
          setTimeout(() => {
            console.log(i);
          }, 1000);
        }
        //等价于
        // for (let i = 0; i < 5; i++) {
        //   let index = i;
        //   setTimeout(() => {
        //     console.log(index);
        //   }, 1000);
        // }

                         执行结果:

                         

                         解析:

                                 利用 let 变量的特性 — 在每一次 for 循环的过程中,let 声明的变量会在当前的块级作用域里面
                               (for 循环的 body 体,也即两个花括号之间的内容区域)创建一个文法环境(Lexical Environment),
                                 该环境里面包括了当前 for 循环过程中的 i
      •  自执行函数
        // for (var i = 0; i < 5; i++) {
        //   (function (i) {
        //     setTimeout(() => {
        //       console.log(i);
        //     }, 1000);
        //   })(i);
        // }
        //等价于  因为你在循环变量i的时候已经执行了函数,自然变量i是什么就打印出来什么
        for (var i = 0; i < 5; i++) {
          function temp(i) {
            setTimeout(() => {
              console.log(i);
            }, 1000);
          }
          temp(i);
        }

        执行结果:

                       

                         解析:

                                  利用函数自执行的方式,把当前 for 循环过程中的 i 传递进去,变量i保存到这个自执行函数构建出的块级作用域中,IIFE 其实并不属于闭包的范畴
      • 使用定时器的第三个参数
        for (var i = 0; i < 5; i++) {
          setTimeout(
            (i) => {
              console.log(i);
            },
            1000,
            i
          );
        }

        执行结果:

                       

                         解析:

                                   利用 setTimeout 函数的第三个参数,会作为回调函数的第一个参数传入     

    三、for循环中每隔一秒打印一次   0  1  2  3   4  5

    • es5的方法:1000*i是重点
      for (var i = 0; i < 5; i++) {
        (function (i) {
          setTimeout(() => {
            console.log(i);
          }, 1000 * i);
        })(i);
      }
      setTimeout(function () {
        console.log(i);
      }, 1000 * i);
    • es6的方法
      let tasks = [];
      function sleep(i) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            console.log(i);
            resolve();
          }, 1000 * i);
        });
      }
      for (let i = 0; i < 5; i++) {
        tasks.push(sleep(i));
      }
      Promise.all(tasks).then(() => {
        setTimeout(() => {
          console.log(i);
        }, 1000);
      });
    • es7的方法:
      function sleep(time) {
        return new Promise((resolve, reject) => {
          setTimeout(() => {
            resolve();
          }, time);
        });
      }
      (async function () {
        for (var i = 0; i < 5; i++) {
          await sleep(1000);
          console.log(i);
        }
        setTimeout(() => {
          console.log(i);
        }, 1000);
      })();
     
     
     
     
     
     
     
     
    北栀女孩儿
  • 相关阅读:
    robots协议
    Java Script学习 4(转)
    Java Script学习 3(转)
    HTML 8 总结(转)
    HTML 7 (转)
    HTML 6 (转)
    HTML 5 (转)
    python类方法/实例方法/静态方法
    chromedriver下载地址
    字符编码表
  • 原文地址:https://www.cnblogs.com/wxh0929/p/15047790.html
Copyright © 2011-2022 走看看