zoukankan      html  css  js  c++  java
  • 解决for循环里获取到的索引是最后一个的问题

    • 方法一

      原理:

      • 利用 setTimeout 函数的第三个参数,会作为回调函数的第一个参数传入
      • 利用 bind 函数部分执行的特性

      代码 1:

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

      代码 2:

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

      代码 3:

      for (var i = 0; i < 10; i++) {
        setTimeout(console.log.bind(Object.create(null), i), 1000)
      }
    • 方法二

      原理:

      • 利用 let 变量的特性 — 在每一次 for 循环的过程中,let 声明的变量会在当前的块级作用域里面(for 循环的 body 体,也即两个花括号之间的内容区域)创建一个文法环境(Lexical Environment),该环境里面包括了当前 for 循环过程中的 i具体链接

      代码 1:

      for (let i = 0; i < 10; i++) {
        setTimeout(() => {
          console.log(i);
        }, 1000)
      }

      等价于

      for (let i = 0; i < 10; i++) {
        let _i = i;// const _i = i;
        setTimeout(() => {
          console.log(_i);
        }, 1000)
      }
    • 方法三

      原理:

      代码 1:

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

      代码 2:

      for (var i = 0; i < 10; i++) {
        try {
          throw new Error(i);
        } catch ({
          message: i
        }) {
          setTimeout(() => {
            console.log(i);
          }, 1000)
        }
      }
    • 方法四

      原理:

      • 很多其它的方案只是把 console.log(i) 放到一个函数里面,因为 setTimeout 函数的第一个参数只接受函数以及字符串,如果是 js 语句的话,js 引擎应该会自动在该语句外面包裹一层函数

      代码 1:

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

      代码 2:

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

      代码 3:

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

      代码 4:

      for (var i = 0; i < 10; i++) {
        setTimeout((i => {
          console.log(i);
        }).call(Object.create(null), i), 1000)
      }

      代码 5:

      for (var i = 0; i < 10; i++) {
        setTimeout((i => {
          console.log(i);
        }).apply(Object.create(null), [i]), 1000)
      }

      代码 6:

      for (var i = 0; i < 10; i++) {
        setTimeout((i => {
          console.log(i);
        }).apply(Object.create(null), { length: 1, '0': i }), 1000)
      }
    • 方法五

      原理:

      • 利用 eval 或者 new Function 执行字符串,然后执行过程同方法四

      代码 1:

      for (var i = 0; i < 10; i++) {
        setTimeout(eval('console.log(i)'), 1000)
      }

      代码 2:

      for (var i = 0; i < 10; i++) {
        setTimeout(new Function('i', 'console.log(i)')(i), 1000)
      }

      代码 3:

      for (var i = 0; i < 10; i++) {
        setTimeout(new Function('console.log(i)')(), 1000)
      }
    好记性不如烂笔头,看到自己觉得应该记录的知识点,结合自己的理解进行记录,用于以后回顾。
  • 相关阅读:
    Android ClearEditText:输入用户名、密码错误时整体删除及输入为空时候晃动提示
    Activity界面切换动画特效。
    点击事件的确认取消对话框。
    安卓菜单的实现,各种添加菜单的方法。
    联系人的侧边字母索引ListView 将手机通讯录姓名通过首字母排序。
    获取手机屏幕密度。
    Android统计图表MPAndroidChart.
    性能测试
    自动化框架
    排序算法
  • 原文地址:https://www.cnblogs.com/wangxi01/p/11208824.html
Copyright © 2011-2022 走看看