likes
comments
collection
share

一篇文章带你深入了解JavaScript中let+var的特性

作者站长头像
站长
· 阅读数 11

暂时性死区

上篇文章我们了解到了letvar之间的细微差别,同时它们之间还有一个区别就是let声明的变量不会在作用域中被提升

<script>
  //name会被提升
  console.log(name);  //undefined
  var name = "Matt";
​
  //age不会被提升
  console.log(age);   //ReferenceError   age未定义
  let age = 26 ;
</script>

浏览器在解析代码的时候,JavaScript引擎也会注意出现在块后面的let声明,只不过在此之前不能以任何方式来引用未声明的变量,在let声明之前的之星瞬间都被称为暂时性死区,在此阶段引用任何后面才声明的变量都会抛出ReferenceError

全局声明

与var关键字不同,使用let在全局作用域中声明的变量不会成为window对象的属性(var声明的变量会)

<script>
  var name = 'Matt';
  console.log(window.name);  // 'Matt'
  
  let age = 26 ;
  console.log(window.age);  // undefined
</script>

let声明是在全局作用域里面发生的,响应变量会在页面的生命周期内存续,为了避免SyntaxError,我们必须确保页面不会重复声明同一个变量

条件声明

我们在使用var声明变量的时候,由于声明会被提升,JavaScript引擎会自动将多余的声明在作用域顶部合并为一个声明,因为let的作用域是块,所以不可能检查前面是否已经使用let声明过同名变量,同时也就不可能在没有声明的情况下使用它

<script>
    var name = 'Nicholas'
    let age = 26;
</script>

注意注意注意!!!

对于let这个新的ES6关键字,不能依赖条件声明模式

不能使用let进行条件式声明是件好事,因为条件声明是一种反模式,它让程序变得更难理解

for循环中的let声明

let出现之前,for循环定义的迭代变量会渗透到循环体外部

<script>
    for(var i = 0 ; i < 5 ; ++i){
        //逻辑循环
    }
    console.log(i);
</script>

如果我们改成使用let,这个问题将会迎刃解决,因为迭代变量的作用域仅适用于for循环块内部

<script>
    for(let i = 0 ; i < 5 ; ++i){
        //逻辑循环
    }
    console.log(i);   //ReferenceError:  i没有定义
</script>

我们在使用var的时候,最常见的问题就是对迭代变量的奇特声明和修改

<script>
   for(var i = 0 ; i < 5 ; ++i ){
       setTimeout(() => console.log(i),0);        // 5 5 5 5 5
   }
</script>

之所以会这样,是因为退出循环的时候,迭代变量保存的都是循环退出的值:5。在执行超过逻辑时,所有的i都是同一个变量,因而输出的都是同一个最终值

而在使用let声明迭代变量的时候,JavaScript引擎在后台会为每个迭代循环声明一个新的迭代变量,每个setTimeout引用的都是不同的变量实例

<script>
   for(var i = 0 ; i < 5 ; ++i ){
       setTimeout(() => console.log(i),0);        // 1 2 3 4 5
   }
</script>
转载自:https://juejin.cn/post/7150667832034852894
评论
请登录