函数无法正常使用外部循环的变量值

函数无法正常使用外部循环的变量值

当我们在for循环中用了一个setTimeout函数,会发现每次函数在用外部循环的变量会有问题,js代码如下:

初始代码:

<script>
    var arr=[1,2,3]
    for (var i = 0; i <arr.length; i++) {
        setTimeout(function(){
           console.log(arr[i])
        })
    }
</script>

初始代码输出:

我们在控制台输出结果为:
在这里插入图片描述

初始代码整理:

出现这个问题是因为for循环是一个同步任务,而setTimeout为一个异步函数,在代码执行时,for循环会先执行直到条件不满足,然后才执行setTimeout里面的 异步任务。我们将代码整理一下,其实它是这样的:

<script>
var arr=[1,2,3];
var i;
i=0;
i=1;
i=2;
i=3;
setTimeout(function () {
            console.log(arr[i])
        })
setTimeout(function () {
            console.log(arr[i])
        })     
setTimeout(function () {
            console.log(arr[i])
        })
</script>

当for循环结束时变量i的值为3,最后控制台输出了3次arr[3],即输出3次undefind,解决办法:

方法一:使用自调用函数

方法一代码:

<script>
    var arr = [1, 2, 3]
    for (var i = 0; i < arr.length; i++) {
        (function(i){
            setTimeout(function () {
            console.log(arr[i])
        }) 
        }(i))
    }
</script>

方法一代码输出:

在这里插入图片描述

方法一代码整理:

问题解决,因为当我们使用一个函数将异步函数包起来并传入参数时,相当于每次都在函数里面重新定义了一个变量并赋值,整理代码如下:

<script>
var arr=[1,2,3];
var i;
i=0;
i=1;
i=2;
i=3;
(function(i){
    vari;
    i=0;
    setTimeout(function () {
    console.log(arr[i])
        }) 
        }(i))
(function(i){
    vari;
    i=1;
     setTimeout(function () {
    console.log(arr[i])
        }) 
        }(i))
(function(i){
    vari;
    i=2;
    setTimeout(function () {
    console.log(arr[i])
        }) 
        }(i))
</script>

方法二:使用let定义循环变量

方法二代码:

<script>
    var arr = [1, 2, 3];
    for (let i = 0; i < arr.length; i++) {
        setTimeout(function () {
                console.log(arr[i])
        })
    }
</script>

输出结果与自调用函数一样;因为我们定义变量时将var换成let就限定了变量的作用域,代码执行过程与自调用函数类似,也是最简便的方法。

方法三:使用index记录下标

方法三代码:

<script>
    var arr = [1, 2, 3];
    for (let i = 0; i < arr.length; i++) {
        arr[i].index=i;
        setTimeout(function () {
                console.log(arr[i])
        })
    }
</script>

此时控制台输出同样为1,2,3

总结:

其实出现这个问题的关键在于使用var定义变量会有一个变量提升的过程,使之成为了全局变量,我们就想办法限定变量的作用域,把它变成一个局部变量来使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值