这个变量i,有点不太懂

for (let i = 0; i < 5; i++) {
            a[i] = function() {
                console.log(i)
            }
        }

        a[2]() //2

i为什么不是undefined,for循环里面我只是创建了一个函数,为什么我执行a[2]的时候还是能拿到i的值

阅读 4.6k
7 个回答

因为let具有块级作用域的特性,因此i只会在当前循环有效。
实际上你的循环创建了5个块级作用域,每一个i值都只在当前的块级作用域中有效果。

你的代码等同于如下:

"use strict";

var _loop = function _loop(i) {
    a[i] = function () {
        console.log(i);
    };
};

for (var i = 0; i < 5; i++) {
    _loop(i);
}

a[2]();

这里就很容易能看出:
实际上let的存在让每一个i值都保存在了一个闭包中。因此这个循环创建了5个闭包。
而a数组里则保存了一堆函数,每一个函数都访问了对应的闭包中的i值。

所以i的值肯定是存在的而不undefined。

当你看不懂ES6语法相关的代码时,可以利用babel的在线工具将ES6的例子转换成ES5的代码。 在线地址

你这不是创建了5个函数吗?

a[0] = function(){
console.log(0);
}
a[1] = function(){
console.log(1);
}
a[2] = function(){
console.log(2);
}
.....

let 关键字会将for循环形成闭包,从console.log(i) 这里的i就是0,1,2,3,4。那么你执行就会打印出相应的值
可以变相看:

var i,
    a = [];
for(i=0; i<5; i++){
  (() => {
    a[i] = () => { console.log(i); }   //这里面的所有i都是外面传入进来的,循环一次创建一次函数。
  })(i);
}

clipboard.png

clipboard.png
阮老师解释的很清楚了吧

新手上路,请多包涵

这个是let用法问题,首先需要指出的是不管怎么样都不会是undefined

  • 如果for循环中使用的是var声明i,那么i是一个全局变量,for循环后i值为5,执行任意一个a中的函数结果都是打印5

  • 问题中使用的是let声明,let具有块级作用域,每个i都是其对应循环的局部变量。你执行a[2]能拿到值的原理就是闭包,可以获取每一次循环所代表的块级作用域中的局部变量

es6中每一次循环都是一个独立的块级作用域,块级作用域中的变量被全局变量引用了,当前这个块级作用域不销毁,所以在全局作用域,a[2]函数执行的时候,能够往a[2]函数定义的上级作用域找到i

let是es6中的东西;在es6中for循环会形成一个独立的块级作用域;let具有块级作用域,每个i都是其对应循环的局部变量。你执行a[2]能拿到值的循环的值,可以获取每一次循环所代表的块级作用域中的局部变量

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题