美文网首页
关于let和var作用域不同导致在异步操作中的不同表现

关于let和var作用域不同导致在异步操作中的不同表现

作者: 宝石龙 | 来源:发表于2017-07-20 14:04 被阅读0次

今天在写代码时遇到了个奇怪的问题。

for(var i = 0; i < 10; i++){   
       setTimeout(function() {
           console.log(i)
       }, 1000); 
}

输出为

10
10
10
10
...

这是个在JavaScript中十分常见的异步问题,出现这种输出的根本原因在于:

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

中var i实际上是将i挂载到了全局变量上,当settimeout的回调函数执行时,i已经被for循环累加到了10,读取并输出的自然就是十个10了。
如果想依次输出0~9该如何呢?在es5之前,有个取巧的方法,就是将i包裹在一个闭包中,将i作为一个函数的私有变量保存起来,这样每次settimeout的回调函数就可以输出属于自己的i了。

但 let 指令可以帮助我们完美的解决这个问题,将上述代码做一下改造。

for(let i = 0; i < 10; i++){   
       setTimeout(function() {
           console.log(i)
       }, 1000); 
}

可以看出,与最初的代码唯一的不同,就是将 var i= 0 改为了,let i = 0
测试一下,输出为

0
1
2
3
..

为什么改了i的声明方式输出结果就会截然不同了呢?
那就要从var与let的不同点说起。
let 与 var 最大的区别就在于,var 与let 生命的变量的作用域不同。
var 是以函数作为自己的作用域。
而 let 则是以{ }为作用域。
具体是什么意思呢?就以上边的代码为例,for循环展开后等价于

{
    let i = 0;
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
{
    let i = 1;
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
{
    let i = 2;
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
...

而使用var时则是

var i = 0;
i++;
i++;
i++;
...

{
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
{
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
{
    setTimeout(function() {
    console.log(i);
    }, 1000);
}
...

这么看是不是就直观了许多?使用let生命的变量,作用域只存在于一个{}之间,所以for循环一共循环几遍,就会有几个{},每一个{}都会有自己独有的 i 。
而var则是以函数为单位,如果没有外层函数就会挂载到全局变量上,所有的{}都会共有1个i,自然就会输出同样的值了。

相关文章

  • 关于let和var作用域不同导致在异步操作中的不同表现

    今天在写代码时遇到了个奇怪的问题。 输出为 这是个在JavaScript中十分常见的异步问题,出现这种输出的根本原...

  • let 与 var区别

    变量提升,let没有,var有。 重复声明,表现不同 作用域不同

  • js面试题

    1、let、var、const区别 1、作用域不同,var是函数作用域,而let是块作用域2、 let不能在定义之...

  • 4-JavaScript-学一点es6基础知识

    es6 学习 let的作用域-块级作用域 //let和var的区别在于作用域不同 //let的另外一个常用的地方在...

  • ES6语法新特性

    一、let和const命名 let命令是用来申明变量的。用法和var类似,不同的是let作用域只在{}之间,var...

  • cocosCreator this 与 this.node 区别

    先说 为什么我们要用var self = this;因为作用域不同 在异步执行回调中 ,this的作用域已经变更,...

  • js中的let和var

    [toc] js中let和var区别 1. 作用域不同 let定义的变量作用域仅限于定义该变量的代码块中。比如:i...

  • js相关

    时间戳转字符格式 let和var对比: let允许把变量的作用域限制在块级域中。与 var 不同处是:var 申明...

  • 20190301 es6学习—let和const命令

    let命令 let与var之间的不同 声明变量的作用域 作用:声明变量 类似var与var的区别:var声明的变量...

  • let和var的区别

    作用域不同 let的作用域制作用于当前代码块 let就会报错。因为var作用的是函数作用域,let作用的是块级作用...

网友评论

      本文标题:关于let和var作用域不同导致在异步操作中的不同表现

      本文链接:https://www.haomeiwen.com/subject/aqwdkxtx.html