本来以为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. Log4php 使用心得

    使用log4php 记录系统日志: 1.自动拦截php报出的错误,写日志 2.手动打印错误 set_error_handler('captureNormal',E_ERROR | E_PARSE); ...

  2. 一款基于jquery带百分比的响应式进度加载条

    今天要给大家带来一款基于jquery带百分比的响应式进度加载条.这款加载条非常漂亮,而且带有进度的百度比,且在不同的百分比用的是不同的颜色.而且这款加载条采用了响应式设计,在不同的分辨率的显示器下完美 ...

  3. r画饼图

    原始图样: library(ggplot2) dt = data.frame(A = c(2, 7, 4, 10, 1), B = c('B','A','C','D','E')) p = ggplot ...

  4. 原生javascript星级评分

    写个最简单的原生js的星级评分: <div id="rank" class="pingfen"> <ul> <li>< ...

  5. 以下哪个Hibernate主键生成策略是实现主键按数值顺序递增的?

    A.increment B.identity C.sequence D.native 解答:A

  6. 一种是CI(Constructor Injection)构造方法注入,另一种是SI(Set Injection) set 注入

    一:这里先说一下DI(Dependency Injection)依赖注入有种表现形式:一种是CI(Constructor Injection)构造方法注入,另一种是SI(Set Injection) ...

  7. e665. 在图像中过滤三元色

    This example demonstrates how to create a filter that can modify any of the RGB pixel values in an i ...

  8. 【Java面试题】53 能不能自己写个类,也叫java.lang.String?

    可以,但是即使你写了这个类,也没有用. 这个问题涉及到加载器的委托机制,在类加载器的结构图(在下面)中,BootStrap是顶层父类,ExtClassLoader是BootStrap类的子类,ExtC ...

  9. 【Java面试题】47 heap和stack有什么区别

    java的内存分为两类,一类是栈内存,一类是堆内存.栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个 ...

  10. Windows下安装Scrapy

    安装python 根据你的需求下载python安装包,安装python(本文基于python27)https://www.python.org/downloads/ 在 环境变量---"Pa ...