Javascript闭包:通过示例

时间:2017-05-07 17:49:52

标签: javascript jquery

虽然我明白允许你声明范围有限的变量到块,但我遇到了 var 使用它与javascript闭包。这是我的例子:

使用

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]();

上面的代码片段将输出返回为: 0 1 2

使用var

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]();

上面的代码片段将输出返回为: 2 2 2

我的问题是:

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

  2. javascript是否在闭包中处理let和var?

  3. 对此的任何澄清都将受到高度赞赏。

1 个答案:

答案 0 :(得分:2)

var范围到函数; let范围是一段代码。

在您的示例中,当您使用var时,j的范围限定为函数buildFunction()。这意味着您使用相同的&#39;每项功能j。当你的for循环运行时,j被设置为0,然后是1,然后是2.当你运行控制台时,记录引用设置为2的j,这样你得到2 2 2

使用let时,将j范围扩展到for循环的迭代。这意味着每次迭代都有一个不同的&#39; j,控制台日志打印出您希望打印的内容。

如果您使用的是ES5并且需要使用var,则可以通过使用自执行函数包装原始匿名函数并传递0 1 2来复制let效果(将其打印为j)作为一个论点。这将在自执行函数中为j创建一个新范围,其值为当前迭代中的j值。

&#13;
&#13;
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]();
&#13;
&#13;
&#13;