• 方法一

    原理:

    • 利用 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. Nice Jquery Validator 【从 jQuery Validation 迁移】

    1. 初始化表单验证 .validate VS .validator jquery-validation : $("#myform").validate(options) nice ...

  2. Selenium和ChromeDriver的安装与配置

    安装安装selenium: win: pip install seleniumliunx: pip3 install selenium12安装ChromeDriver, 该工具供selenium使用C ...

  3. shellcode 免杀(一)

    工具免杀 选择了几个简单或者近期还有更新的免杀工具进行学习 ShellcodeWrapper https://github.com/Arno0x/ShellcodeWrapper 该工具的原理是使用异 ...

  4. hdoj3791

    题目: Problem Description 判断两序列是否为同一二叉搜索树序列   Input 开始一个数n,(1<=n<=20) 表示有n个需要判断,n= 0 的时候输入结束.接下去 ...

  5. RedHat服务器安装

    为什么选择 RedHat 市场占有率商业化比较高 厂商的支持比较丰富 新手建议ubuntu 进行上手 等熟悉了Linux环境可以选择自己喜欢的发行版 (有些Geeker就是认为Ubuntu太易于使用了 ...

  6. WeChair项目Alpha冲刺(7/10)

    团队项目进行情况 1.昨日进展    Alpha冲刺第七天 昨日进展: 前端:页面修改和完善,安排页面美化 后端:和前端成功交互,数据解密成功 数据库:修改数据表属性,与后端部署数据库交互 2.今日安 ...

  7. SpringCloud Alibaba (三):Sentinel 流量控制组件

    SpringCloud Alibaba (三):Sentinel 流量控制组件 Sentinel 是什么 随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentinel 是面向分布式服务架构 ...

  8. Python 简明教程 --- 17,Python 模块与包

    微信公众号:码农充电站pro 个人主页:https://codeshellme.github.io 正确的判断来源于经验,然而经验来源于错误的判断. -- Fred Brooks 目录 我们已经知道函 ...

  9. 主线程用afxBeginThread()创建多个线程安全退出的办法

    HANDLE hand[]; CCriticalSection m_crisecoin; CEvent m_event; struct Student { int nNO; int nYear; CW ...

  10. 如何使用PL/SQL工具批量导出表、存储过程、序列

    PLSQL作为Oracle数据库进行操作常用工具,可以很方便的对表以及数据进行处理.工作中如果遇到数据库转移,需要将老数据库中的建表.建序列和存储过程语句导出,然后导入到新的数据库中这样序列号会自动, ...