• 方法一

    原理:

    • 利用 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)
    }

解决for循环里获取到的索引是最后一个的问题的更多相关文章

  1. 利用闭包解决for循环里onclick事件不能捕捉实时i值问题

    问题描述 我们都知道,如果我们对于一组元素(相同的标签)同时进行onclick事件处理的时候(在需要获取到索引的时候),一般是写一个for循环,但是onclick是一个异步调用的,所以会带来一个问题, ...

  2. uni-app如何解决在for循环里调用异步请求获取数据顺序混乱问题?

    总结/朱季谦 先前有一次做uni-app的js接口对接时,遇到过这样的情况,在for循环里,调用一个异步请求时,返回来的值顺序是乱的,因此,在以下的代码里,push到数组里的值,每次的顺序可能都是不一 ...

  3. JavaScript闭包理解【关键字:普通函数、闭包、解决获取元素标签索引】

    以前总觉得闭包很抽象,很难理解,所以百度一下"闭包"概览,百度的解释是:“闭包是指可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的 ...

  4. JavaScript闭包理解【关键字:普通函数、变量访问作用域、闭包、解决获取元素标签索引】

        一.闭包(Closure)模糊概述 之前总觉得闭包(Closure)很抽象而且难理解,百度一下"闭包"名词,百度的解释是:“闭包是指可以包含自由(未绑定到特定对象)变量的代 ...

  5. php 循环里面套sql怎么解决

    功能要求: 企业列表(展示企业的基本信息,这里只获取了名称.logo.和服务类型), 服务类型说明: 服务类型一共3级,1.2级是必填的,3级是非必填,如果填的话最多3个, 服务类型1.2.3保存在一 ...

  6. Day_11【集合】扩展案例2_使用普通for循环获取集合中索引为3的元素并打印,统计集合中包含字符串"def"的数量,删除集合中的所有字符串",将集合中每个元素中的小写字母变成大写字母def",

    分析以下需求,并用代码实现 1.定义ArrayList集合,存入多个字符串"abc" "def" "efg" "def" ...

  7. 百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:

    原文:百度地图API详解之事件机制,function"闭包"解决for循环和监听器冲突的问题: 百度地图API详解之事件机制 2011年07月26日 星期二 下午 04:06 和D ...

  8. 【vue】vue使用Element组件时v-for循环里的表单项验证方法

    转载至:https://www.jb51.net/article/142750.htm标题描述看起来有些复杂,有vue,Element,又有表单验证,还有v-for循环?是不是有点乱?不过我相信开发中 ...

  9. Spring 循环依赖的三种方式(三级缓存解决Set循环依赖问题)

    本篇文章解决以下问题: [1] . Spring循环依赖指的是什么? [2] . Spring能解决哪种情况的循环依赖?不能解决哪种情况? [3] . Spring能解决的循环依赖原理(三级缓存) 一 ...

随机推荐

  1. [原创][开源] SunnyUI.Net 系列文章目录

    SunnyUI.Net, 基于 C# .Net WinForm 开源控件库.工具类库.扩展类库.多页面开发框架 Blog: https://www.cnblogs.com/yhuse Gitee: h ...

  2. Telegraf和Grafana监控多平台上的SQL Server-自定义监控数据收集

    问题 在上一篇文章中,我们使用Telegraf自带的Plugin配置好了的监控,但是自带的Plugin并不能完全覆盖我们想要的监控指标,就需要收集额外的自定义的监控数据,实现的方法有: 开发自己的Te ...

  3. 使用PyQtGraph绘制图形(2)

    采用addplot()方法将多个图形添加到一个窗口. 首先利用numpy模块创建两个随机数组,用来作为图形绘制的数据: import pyqtgraph as pg import numpy as n ...

  4. HttpClient 常用方法封装

    简介 在平时写代码中,经常需要对接口进行访问,对于 http 协议 rest 风格的接口请求,大多使用 HttpClient 工具进行编写,想着方便就寻思着把一些常用的方法进行封装,便于平时快速的使用 ...

  5. 使用Apache Spark和Apache Hudi构建分析数据湖

    1. 引入 大多数现代数据湖都是基于某种分布式文件系统(DFS),如HDFS或基于云的存储,如AWS S3构建的.遵循的基本原则之一是文件的"一次写入多次读取"访问模型.这对于处理 ...

  6. 041.Kubernetes集群网络-K8S网络策略

    一 Kubernetes网络策略 1.1 策略说明 为实现细粒度的容器间网络访问隔离策略,Kubernetes发布Network Policy,目前已升级为networking.k8s.io/v1稳定 ...

  7. 【JMeter_09】JMeter逻辑控制器__临界部分控制器<Critical Section Controller>

    临界部分控制器<Critical Section Controller> 业务逻辑: 根据锁名来控制并发,同一个锁名之下,在同一时间点只能存在一个运行中,适用于控制并发的场景 锁名类型: ...

  8. Kubernetes学习笔记(九):StatefulSet--部署有状态的多副本应用

    StatefulSet如何提供稳定的网络标识和状态 ReplicaSet中的Pod都是无状态,可随意替代的.又因为ReplicaSet中的Pod是根据模板生成的多副本,无法对每个副本都指定单独的PVC ...

  9. Oracle调用Java方法(下)复杂Jar包封装成Oracle方法以及ORA-29521错误

    上一篇随笔中已经说了简单的Jar是如何封装的,但是我的需求是根据TIPTOP的查询条件产生XML文件并上传到FTP主机中,那么就要涉及到XML生成的方法和FTP上传的方法 所以在Eclipse写的时候 ...

  10. idea 2018版/2019版的破解

    idea 2019版破解的穿越隧道:https://www.jianshu.com/p/09c9afae9a05 idea 2018版破解的穿越隧道:https://www.jianshu.com/p ...