zoukankan      html  css  js  c++  java
  • 【翻译】JavaScript循环和作用域

    我的翻译小站:https://www.zcfy.cc/article/javascript-loops-and-scope

    翻译原文链接:https://flaviocopes.com/javascript-loops-and-scope/

    JavaScript有一个特点,也许会让开发者头痛, 是与循环和作用域相关的.

    举个例子:

    const operations = []
    
    for (var i = 0; i < 5; i++) {
      operations.push(() => {
        console.log(i)
      })
    }
    
    for (const operation of operations) {
      operation()
    }

    它基本是循环了5次,将一个函数添加到operations数组里面。这个函数可打印出循环变量索引值i.

    运行这些函数后

    期望的结果应该是:

    0
    1
    2
    3
    4

    但实际发生的是这样的:

    5
    5
    5
    5
    5

    为什么会有这种情况? 因为使用的是var.

    由于提升了var变量, 上面的代码等同于

    var i;
    const operations = []
    
    for (i = 0; i < 5; i++) {
      operations.push(() => {
        console.log(i)
      })
    }
    
    for (const operation of operations) {
      operation()
    }

    因此,在for-of循环中, i 依然是可见的, 它等于5,并且每次在函数中涉及到i ,都将使用这个值。

    那么我们应该如何做让其变成我们想的这样呢?

    最简单的方案是用 let 声明. 在ES2015中介绍到, 它们有很大的帮助,能避免关于使用var声明的一些奇怪问题。

    简单的在循环变量时将var 变成 let ,能够很好的运行:

    const operations = []
    
    for (let i = 0; i < 5; i++) {
      operations.push(() => {
        console.log(i)
      })
    }
    
    for (const operation of operations) {
      operation()
    }

    这是输出结果:

    0
    1
    2
    3
    4

    这是怎么实现的呢?这是因为每次循环重复的时候,都将重新创造i ,同时每个函数添加operations数组时,能获取它本身的i

    记住你不能使用 const在这种情况下, 因为这会导致for在第二次循环时, 尝试赋新值报错。

    另外一个非常普遍的解决这个问题是使用pre-ES6代码, 同时它被称作即时调用函数表达式 (IIFE).

    在这种情况下,你可以包装整个函数,并将i 绑定在它上面。自这种方式,你正在创造一个能立即执行的函数,你从其返回的一个新的函数。因此我们可以稍后执行它。

    const operations = []
    
    for (var i = 0; i < 5; i++) {
      operations.push(((j) => {
        return () => console.log(j)
      })(i))
    }
    
    for (const operation of operations) {
      operation()
    }

     

  • 相关阅读:
    go并发和并行
    goroutine
    go并发
    wampserver配置问题
    获取字符串的长度
    mysql中事件失效如何解决
    Go语言中Goroutine与线程的区别
    Mosquitto服务器的日志分析
    phpexcel导出数据 出现Formula Error的解决方案
    Centos6.X 手动升级gcc
  • 原文地址:https://www.cnblogs.com/jtjds/p/9619492.html
Copyright © 2011-2022 走看看