首页 > 小白学js遇到的一个疑惑?

小白学js遇到的一个疑惑?

var a = [];
for(var i=0; i<10; i++){
  a[i] = function(){
    console.log(i);
  };
}
a[6]();

上述代码浏览器运行后输出结果:10 。问题一:此处为啥是10而不是6呢?

"use strict";
var a = [];
for(let i=0; i<10; i++){
  a[i] = function(){
    console.log(i);
  };
}
a[6]();

上述代码(即使用es6的语法)浏览器运行后输出结果:6 。问题二:此处为啥是6而不是10了呢?
前面有几位仁兄热情回答,可是我还是心有疑惑。有木有大神能用通俗易懂的语言解答下呢?


`var funcs=[];

var a = function(){
    for (var i = 0; i < 10; i++) {
        (function(j){
            funcs.push(function(){console.log(j)});
        })(i);
    }
}` 利用非严格模式下的闭包,可以得到和块级作用域一样的结果

一切都是作用域的锅
1、var i = 0,此时定义的i是属于全局的,也就是说你循环完成,i = 10,所有输出10
2、let i = 0,注意了,这个i是有作用域的,只是属于for循环里面,外面是无法访问的,console.log(i)这个i又是一个独立的作用域,只属于自身,所有最后输出6


第一个:10个函数共享同一个i
第二个:因为使用了严格模式中的let来定义i,所以i具有了块级作用域的属性,因此10个函数都有一个独立的i(函数里面的i和外面的不是同一个,里面的是外面的拷贝)


问题一:来来本人告诉你,在for循环的时候啊,其实你得到的是 10个 function a[1](console.log(i)); fucntion a[2](){console.log(i)};...,就是是个这样的东西,说白了 里面的 i 根本没有进去,为什么没有进去呢?嘿嘿,你得到的是十个函数,而函数根本没有调用执行!!最后你调用了 a[6] 这个函数;这个时候开始执行函数里面的代码,但是这个时候的 i, 你觉得是几呢?我觉得是 10~;第二个问题,你顺着我的思路想想应该就懂了吧!


问题一:第一个结果的产生中间涉及到作用域链和闭包这两个概念,具体解释恕我不能详细介绍,题主可以按图索骥找相关的资料,推荐《JavaScript高级程序设计第二版》。

问题二:至于第二个结果中的let命令就是ECMAScript2015(简称ES6)用来解决第一种情况下产生的不好的影响。然后就是刚才测试了一下去掉格式限制在FF无影响。

BTW,这段代码好像阮老师书里的一段内容,里面其实有详细的解释,地址:http://es6.ruanyifeng.com/#docs/let


因为使用的模式不同,前面的是非严格模式,后面的是严格模式


其实这里要说明一下,你使用let,也就是引入了es6的一个新特性。在es5中,定义元素的作用域很容易就变为全局变量,比如你在一个函数内定义一个i,如果你没有给i加上var,那么这个i就变成了全局变量。而使用let,你限制了当前使用的作用域。使用在for循环这个作用域里面,所以赋值就为6。

【热门文章】
【热门文章】