在循环内使用闭包(Closures)

闭包的本质是一个内部函数访问其作用域之外的变量。闭包可以用于实现诸如 私有变量 和 创建工厂函数之类的东西。

我们可能经常会见到一段这样的代码:

for (var i = 0; i < 4; i++) {

  setTimeout(function() {

    console.log(i);

  }, 1000);

}

运行上面的代码控制台会在1秒后打印4个4,而不是0,1,2,3。

其原因是因为setTimeout函数创建了一个可以访问其外部作用域的函数(也就是我们经常说的闭包),每个循环都包含了索引i。

1秒后,该函数被执行并且打印出i的值,其在循环结束时为4,因为它的循环周期经历了0,1,2,3,4,并且循环最终在4时停止。

下面列举两种方案解决这个问题:

for (var i = 0; i < 4; i++) {

  // 通过传递变量 i

  // 在每个函数中都可以获取到正确的索引

  setTimeout(function(j) {

    return function() {

      console.log(j);

    }

  }(i), 1000);

}

for (let i = 0; i < 4; i++) {

  // 使用ES6的let语法,它会创建一个新的绑定

  // 每个方法都是被单独调用的

  setTimeout(function() {

    console.log(i);

  }, 1000);

}

原文发布于微信公众号 - 前端迷(love_frontend)

原文发表时间:2018-10-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

Golang语言社区--【基础知识】范围规则

在任何编程程序的作用域,其中一个定义的变量可以有它的存在,超出该变量的区域就不能访问。有三个地方变量可以在Go编程语言声明如下: 内部函数或这就是所谓的局部变量...

337140
来自专栏别先生

Javascript提升阶段学习

JavaScript 1:javascript简介   JavaScript是一种脚本语言,能实现网页内容的交互显示,当用户在客户端显示该网页时,浏览器就会执...

22580
来自专栏Golang语言社区

Golang语言社区--【基础知识】循环

可能有一种情况,当你需要执行的代码块多次。在一般情况下,语句顺序执行:在一个函数的第一条语句,首先执行,然后是第二个等等。 编程语言提供了各种控制结构,允许更多...

36670
来自专栏企鹅号快讯

Python中的while循环

原创第13篇~while循环 阅读本文大概15分钟。 文章‍结构: while定义 普通while练习 while和input函数 while 和 else w...

43960
来自专栏数据结构与算法

P2085 最小函数值(minval)

题目描述 有n个函数,分别为F1,F2,...,Fn。定义Fi(x)=Aix^2+Bix+Ci (x∈N*)。给定这些Ai、Bi和Ci,请求出所有函数的所有函数...

33650
来自专栏小筱月

JavaScript delete 操作符

如果 expression 不是一个对象的引用,那么 delete 则不会起任何作用

14650
来自专栏项勇

笔记76 | Java中break、continue与return的区别

15840
来自专栏HTML5学堂

JavaScript中的this详解

HTML5学堂:this属于JS的底层知识,了解this之后,能够实现一些基本的功能,但是感觉最重要的是,this是面向对象必不可少的组成部分,如果希望能够逐渐...

29240
来自专栏互联网杂技

JS中Null与Undefined的区别

Undefined类型只有一个值,即undefined。当声明的变量还未被初始化时,变量的默认值为undefined。 Null类型也只有一个值,即null。n...

33340
来自专栏程序员阿凯

java中“53”个关键字(含2个保留字)

17350

扫码关注云+社区

领取腾讯云代金券