为了账号安全,请及时绑定邮箱和手机立即绑定

var和let的区别,为什么这两个函数执行的结果不一样呢

var和let的区别,为什么这两个函数执行的结果不一样呢

沧海一幻觉 2019-02-27 21:52:29
var arr = [];for(**var** i = 0; i < 10; i++){        arr[i] = function(){        return i;    };}for(var j = 0; j < arr.length; j++){    console.log(arr[j]() + " ");     } //10个10var和let的区别在哪呢,为什么声明不一样就会变成不一样的结果呢?还有第一个函数为什么i最后都等于10了?i这里是局部变量还是全局变量呢?局部变量不应该for循环完就自动被GC了吗 还是说第一个函数存在闭包所以保留了对i的引用,所以i不会被GC了var arr = [];for(**let** i = 0; i < 10; i++){    arr[i] = function(){        console.log(i);    };}for(var j = 0; j < arr.length; j++){    console.log(arr[j]());}//0-9
查看完整描述

2 回答

?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

var 存在变量提升,所以你写的


for(var i = 0; i < 10; i++){

        arr[i] = function(){

        return i;

    };

}

等同于


var i

for(i = 0; i < 10; i++){

        arr[i] = function(){

        return i;

    };

}

实际上就是定义了一个全局变量。


虽然你return的是i,但是你在调用arr[i]这个函数的时候,会沿着作用域链找到arr[i]这个函数的上一层作用域,在这里即是全局作用域。所以你调用的时候var已经是10了,可以在 for循环后面添加一个console.log(i)验证。


let 会创建一个作用域。则,这里就会形成一个闭包

所以,使用let定义时,则分成了三层 Global --> Closure --> Local 作用域

所以你在调用arr[i]这个函数时,其实会根据作用域链找到Closure(闭包)中的 变量 i 。

使用下面这行代码,打开浏览器中的Source面板并查看右侧的Scope(作用域链)验证。



        var arr = []

        for(let i = 0 ;i<10 ;i++){

            arr[i] = function(){

                debugger

                console.log(i);

            };



        }



        for(var j = 0; j < arr.length; j++){

            console.log(arr[j]());

        }//0-9

ps:个人理解,如有错误,希望指出


查看完整回答
反对 回复 2019-03-06
  • 2 回答
  • 0 关注
  • 458 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信