暂时性死区
上篇文章我们了解到了let和var之间的细微差别,同时它们之间还有一个区别就是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>
最后
最近还整理一份JavaScript与ES的笔记,一共25个重要的知识点,对每个知识点都进行了讲解和分析。能帮你快速掌握JavaScript与ES的相关知识,提升工作效率。
有需要的小伙伴,可以点击下方卡片领取,无偿分享