【问题标题】:Javascript Closures: Understanding difference between let and var with an example [duplicate]Javascript闭包:通过示例了解let和var之间的区别[重复]
【发布时间】:2017-05-08 02:11:57
【问题描述】:

虽然我知道 let 允许您声明范围限制在块中的变量,但我遇到了 letvar 之间的奇怪区别strong> 同时将它与 javascript 闭包一起使用。这是我的例子:

用 let

function buildFunction() {

  var arr = [];
  for(var i = 0; i < 3; i++) {
    let j = i;  //Using let to assign j
    arr.push(
      function(){
        console.log(j);
      }
    )
  }
   return arr;
}

var fs = buildFunction();
fs[0]();
fs[1]();
fs[2]();

上面的代码 sn -p 返回输出为: 0 1 2

带变量

function buildFunction() {

  var arr = [];
  for(var i = 0; i < 3; i++) {
    var j = i;  //Using var to assign j
    arr.push(
      function(){
        console.log(j);
      }
    )
  }
   return arr;
}

var fs = buildFunction();
fs[0]();
fs[1]();
fs[2]();

上面的代码 sn -p 返回输出为: 2 2 2

我的问题是:

  1. 如果我在块中使用 var 并在执行期间为其分配一个值,它不应该完全像 let 一样工作并将 j 的不同副本存储在内存中吗?

  2. javascript 在闭包中处理 let 和 var 的方式不同吗?

对此的任何澄清将不胜感激。

【问题讨论】:

  • @oen44:不,这不是重复的。请仔细阅读问题
  • 我认为它回答了“如果我在块内使用 var,它不应该像 let 一样工作吗?”非常好。第二个问题(No)的答案就变得无关紧要了。

标签: javascript jquery


【解决方案1】:

var 作用于函数; let 作用于代码块。

在您的示例中,当您使用 var 时,j 的作用域为函数 buildFunction()。这意味着您在每个函数中都使用“相同的”j。当你的 for 循环运行时,j 被设置为 0,然后是 1,然后是 2。然后当你运行控制台时,你引用的 j 被设置为 2,所以你得到2 2 2

当您使用let 时,您将j 限定为for 循环的该迭代。这意味着每次迭代都有一个“不同的”j,并且控制台日志会打印您期望它们打印的内容。

如果你使用的是 ES5 并且需要使用 var,你可以复制 let 效果(让它打印 0 1 2),方法是用一个自执行函数包装你的原始匿名函数并将 j 作为参数传入.这将在自执行函数中为j 创建一个新作用域,其值为当前迭代中 j 的值。

function buildFunction() {

  var arr = [];
  for(var i = 0; i < 3; i++) {
    var j = i;  //Using var to assign j
    arr.push(
      //self executing function
      (function(j) { //j here is scoped to the self executing function and has the value of j when it was called in the loop. Any changes to j here will not affect the j scope outside this function, and any changes to j outside this function will not affect the j scoped inside this function.
        //original function
        return function() {
          console.log(j);
        }
      })(j) //call with the value of j in this iteration
    )
  }

  return arr;
}

var fs = buildFunction();
fs[0]();
fs[1]();
fs[2]();

【讨论】:

    猜你喜欢
    • 2016-09-04
    • 2017-01-16
    • 1970-01-01
    • 2018-05-14
    • 2018-12-09
    • 1970-01-01
    • 2019-03-29
    • 2020-06-04
    • 2016-07-01
    相关资源
    最近更新 更多