javascript 关于for循环里面的闭包问题

时间:2017-09-22
今天写了一个简单实用javascript例子,该例子主要是通过循环来输出一组数字,例子的特点是在for循环里面定义匿名函数,这些匿名函数的功能是输出当前的数值,然后我们在使用另一个for循环来调用这些函数并执行他们从而达到输出数值的目的。

今天写了一个简单实用javascript例子,该例子主要是通过循环来输出一组数字,例子的特点是在for循环里面定义一个函数数组,这些函数的功能是输出当前的数值,然后我们在使用另一个for循环来调用这些函数并执行他们从而达到输出数值的目的。具体代码如下:

var funcs = [];
//循环里面包含闭包函数
for (var i = 0; i < 3; i++) {      // let's create 3 functions
  funcs[i] = function() {          // and store them in funcs
    console.log("My value: " + i); // each should log its value.
  };
}
for (var j = 0; j < 3; j++) {
  funcs[j]();                      // and now let's run each one to see
}

输出结果为:

My value:3
My value:3
My value:3

而我想要输出:

My value:0
My value:1
My value:2

这个基本问题的解决方法是什么?

首先我们先了解一下javascript的闭包。

什么是闭包? 各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂。我的理解是,闭包就是能够读取其他函数内部变量的函数。

由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成"定义在一个函数内部的函数"。

所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

for (var i = 0; i < 3; i++) {      // let's create 3 functions
  funcs[i] = function() {          // and store them in funcs
    console.log("My value: " + i); // each should log its value.
  };
}

由于闭包的关系,他是循环完毕之后才返回,最终结果是2++是5, 这个匿名函数里面根本没有i这个变量,所以匿名函数会从父级函数中去找i,当找到这个i的时候,for循环已经循环完毕了,所以最终会返回3.

解决方法:

你要做的是将每个函数中的变量绑定到函数之外单独的不变的值:

var funcs = [];
function createfunc(i) {
    return function() { console.log("My value: " + i); };
}

for (var i = 0; i < 3; i++) {
    funcs[i] = createfunc(i);
}

for (var j = 0; j < 3; j++) {
    funcs[j]();                        // and now let's run each one to see
}

运行结果:

My value:0
My value:1
My value:2