本来以为for循环可以很好的解决一切问题,直到今天遇到了这段代码,刷新了我对for循环的认识,话不多说,直接上代码

var arr = [];
for(var i = 0;i<10;i++) {
arr[i] = function()
{
console.log(i)
}
}
arr[3]();

大家看上面这段代码,我先声明了一个空数组,然后把它放在循环里面,循环添加函数作为arr数组的数据,第一印象看到的时候,肯定不少人会毫不犹豫的说出3这个答案,

因为索引为3的时候console.log刚好是3吗,想想差点自己都信了,但是,结果呢?

结果明显是10,那么原因是什么呢?由于for循环中的i变量是用var声明的,此时的 i 在全部范围内都有效,所以每一次循环,新的i值会覆盖旧的i值,导致最后输出是最后一轮的i的值,当最后输出的时候i 已经变为10了

那么,有没有解决的办法呢,办法是有的,且听我慢慢道来:

方法一:闭包

再用闭包的时候,你首先要了解什么是闭包,所谓“闭包”,指得是拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),它可以访问局部变量,并且在访问的同时使局部变量的内存不被释放。那么,怎么用闭包呢,简单点来讲,就是嵌套函数。代码如下:

   var arr = [];
for(var i = 0;i<;i++){
(function(val) {
arr[i] = function() {
console.log(val)
}
})(i)
}
arr[3]();

将for的循环内容方法放在一个自调用的匿名函数里面,这个时候的val是由 i 来传递的,此时的变量val可以被访问,而且内存不被释放,也就是说,val没有覆盖一说,所以自然而然的输出结果是3

方法二:ES6当中的let

ES6现在的推行范围不是很广,而且许多低版本的浏览器无法识别ES6,所以此方法用的时候是有局限性的,建议你把浏览器的版本升为高版本;

好嘞,言归正真,我们先来了解一下什么是ES6当中的let:

let全称为代码块作用域,顾名思义他是作用域代码块的,它和var的用法相似,但是在同一个代码快中不能出现重名的let变量;代码如下:

 var arr = [];
for(let i = 0;i<;i++) {
arr2[i] = function() {
console.log(i)
}
}
arr[3]();
变量i是let声明的,当前i只在本轮循环中有效所以每次循环的i其实是一个新的变量,所以最后输出的是3

才疏学浅,目前只发现了这两种方法,如果有新方法或者不对的地方,请指教。

你知道js当中for循环当中的bug吗,如何解决它的更多相关文章

  1. Chrome谷歌浏览器中js代码Array.sort排序的bug乱序解决办法

    [现象] 代码如下: var list = [{ n: "a", v: 1 }, { n: "b", v: 1 }, { n: "c", v ...

  2. sql 游标循环当中重新赋值

    sql 游标循环当中的变量必须重新赋值不然变量的值就是前次循环的值

  3. js 控制Div循环显示 非插件版

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. js种的循环语句

    //js种的循环语句 //while与do while的区别是while是满足条件后才执行 //do while是不管满不满足条件都会执行一次 //for 循环与while,do while相比循环结 ...

  5. js中的循环语句

    js中的循环语句可分为三种:1.while:2.do……while:3.for. while的语法为 while (exp) {    //statements;} var a=1,b=0; whil ...

  6. js的事件循环绑定和jQuery的隐式迭代

    js的事件循环绑定和jQuery的隐式迭代 js事件循环绑定 jQuery隐式迭代 先举一个例子:给定一个ul,点击列表内的每一个li元素,使它的背景色变红,下边分别用js代码和jQuery实现. & ...

  7. 原生JS—实现图片循环切换的两种方法

    今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法.多余的话我们就不多说了,我们一个一个开始讲吧. 1  原生JS实现图片循环切换 -- 方法一 在上栗子之前我们先简单介绍一下所用的一些知识点. ...

  8. 原生JS—实现图片循环切换及监测鼠标滚动切换图片

    今天我们主要讲讲如何使用原生JS实现图片的循环切换的方法以及如何检测鼠标滚动循环切换图片.多余的话我们就不多说了,我们一个一个开始讲吧. 1  原生JS实现图片循环切换 -- 方法一 在上栗子之前我们 ...

  9. js中的循环

    js中的循环是我们经常要用到的,现在进行一些归纳. 一.javascript种的循环. 1.循环对象 var o = { name: 'Jack', age: 20, city: 'Beijing' ...

随机推荐

  1. Clock函数用法

    clock()是C/C++中的计时函数,而与其相关的数据类型是clock_t.在MSDN中,查得对clock函数定义如下: clock_t clock(void) ; 这个函数返回从“开启这个程序进程 ...

  2. ASP.new GridView获取隐藏列值的几种方法

    解决方法: 原文来自:http://www.tzwhx.com/NewShow/newBodyShow/控件_32933.html 作者:lerit  1.隐藏列前获取数据 看这样一个例子(以下均以此 ...

  3. 【WPF】MVVM前台绑定一组RadioButton按钮

    需求:制作一组RadioButton,像下面这样的效果: [MVVM]要显示一组RadioButton按钮,想法是Controller层联网获取到数据后,将数据进行处理,然后加到一个Observabl ...

  4. OpenWRT中的按键和灯的GPIO控制实现

    基于BarrierBreaker版本,基于AR9331 AP121 Demo单板 来进行描述 1.灯 A.在mach-ap121.c中,定义了灯所对应的GPIO定义: #define AP121_GP ...

  5. 常用的百度API地图操作

    常用的百度API地图操作,包括模糊搜索,放大缩小,并支持移动端 效果图如下 完整代码: http://download.csdn.net/detail/jine515073/8778167

  6. Python:基本运算、基本函数(包括复数)、Math模块、NumPy模块

    基本运算 x**2 : x^2 若x是mat矩阵,那就表示x内每个元素求平方 inf:表示正无穷 逻辑运算符:and,or,not 字典的get方法 a.get(k,d) 1 1 get相当于一条if ...

  7. 关于用Cocos2d-x.3.10运行别人游戏项目的步骤

    1.首先打开Cocos那个一体化软件. 2.创建工程,取名字,选择路径. 3.用VS2013打开新建的项目. 4.打开cocosdata(我自己放游戏项目的文件目录)的相应项目(自己刚创建的). 5. ...

  8. 选择列表中的列……无效,因为该列没有包含在聚合函数或 GROUP BY 子句中

    今天用SQL Server尝试实现一个SQL语句的时候,报了如标题所示的错误,通过在百度里面搜索,并亲自动手实现,终于发现问题所在,现在把它记录下来. 语句如下: select [OrderID],[ ...

  9. ubuntu下android源码的下载(最新)

    在ubuntu下下载android源码我断断续续搞了好几个月,希望大家不要向我学习啊!一次性搞定! 这里给大家一些建议啊,如果是看书的话看下书的出版日期,超过一年的基本上失效,网上的也是,特别是在国内 ...

  10. 清理SYSAUX表空间的WRH$_LATCH_CHILDREN表

    周六 被突然起来的短信 轰醒. 一看有63条短信. 都是来之与监控中的.有关表空间大小超过某个警戒值. 发现 SYSAUX表空间超过了15GB 通过以下代码查看SYSAUX表空间的功能占用情况 SEL ...