本来以为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. 完成wamp安装后Mysql配置记录

    注意:下面如没有特殊说明,默认都是修改my.ini配置,修改完配置需要重启mysql服务. 1.安装完wamp后输入命令有乱码提示: 运行mysql命令时,出现的错误提示是乱码 :    ERROR ...

  2. 【C#/WPF】限制GridSplitter分隔栏的滑动范围

    GridSplitter可以自由滑动,例如一个水平方向的分隔栏,可以从屏幕顶端滑到屏幕底端. 现在的需求是:限制GridSplitter在一定范围内滑动. 例如,现在有如下的横竖两个GridSplit ...

  3. Ubuntu通过apt-get安装指定版本和查询指定软件有多少个版本

    一.通过apt-get安装指定版本 apt-get install <<package name>>=<<version>> 二.查询指定软件有多少个版 ...

  4. ExtJs Ext.form.field.TextArea+Ckeditor 扩展富文本编辑器

    Ext.define("MyApp.base.BaseTextArea", { extend: "Ext.form.field.TextArea", xtype ...

  5. 简单文件系统构建ramdisk

    1.  BusyBox编译工具,包含bin, sbin, usr,  linuxrc. 2.  添加相关重要目录:dev,  etc,  mnt, proc,  sys, lib, var, tmp. ...

  6. scala实现彩票算法

    scala实现彩票算法 (1)具体实现代码如下: package hw1 import scala.util.control._ /** * @author BIGDATA */ object Cp ...

  7. Linux 克隆虚拟机引起的“Device eth0 does not seem to be present, delaying initialization”

    Linux 克隆虚拟机引起的“Device eth0 does not seem to be present, delaying initialization” 虚拟机Vmware上克隆了一个Red ...

  8. input输入框用el对数字格式化

    <input name="doubleInput" type="text" maxlength="32" id="doubl ...

  9. 【转】Mac下升级python2.7到python3.6

    1. 前言 Mac系统自带python2.7,本文目的是将自带的python升级到3.6版本. 网上有本多的做法是让python2.7和python3.X两个版本共存,博主并不知道,是两版本共存好,还 ...

  10. 关于Unity的入门游戏飞机大战的开发(上)

    每个组件都是一个类的实例,要获得某个组件,要先创建一个同类型的组件类实例,然后把实例传引用过去,就可以对想要的组件实例进行操作. 做游戏一般创建一个逻辑节点,里面只管逻辑,再创建一个动画节点,里面有好 ...