在上一节ES6核心知识解析02:var被淘汰的三大缺点中,我们谈到了var的缺陷。
在ES6出现之前,我们都是使用var这个关键字来声明变量,那么它被let和const取而代之肯定是因为有弊端。而let和const就是为了弥补这些弊端,或者说解决这些痛点的。
那么因此let和const的3个非常重要的特点
1、只在块级作用域内有效,并且不允许重复声明
2、不存在变量提升
3、不会成为window属性
接着咱们一个一个分析↓
1、只在块级作用域内有效,并且不允许重复声明
声明的变量只在其所在的代码块内有效,在代码块外访问会报错
javascript
if(true){
let tt = "天天向上"; //只在代码块内有效
}
console.log(tt); //代码块外访问报错:Uncaught ReferenceError:tt is not defined
//而同样的变量换做var来声明
if(true){
var tt = "天天向上"; //var没有块级作用域
}
console.log(tt);
//控制台输出
天天向上
内层变量和外层同名变量互不影响
javascript
let title = "天天快乐";
if(true){
let title = "天天发财";
console.log(title);
}
console.log(title);
//由于只在代码块内有效,内层变量不会覆盖外层变量
//控制台输出结果为
天天发财
天天快乐
//同样的变量换做var来声明
var title = "天天快乐";
if(true){
var title = "天天发财";
console.log(title);
}
console.log(title);
//先声明的变量值被后声明的变量值覆盖
//控制台输出结果为
天天发财
天天发财
同一代码块中,不允许重复声明
javascript
if(true){
let title = "天天快乐";
let title = "天天发财";
console.log(title);
}
//控制台报错
Uncaught SyntaxError: Identifier 'title' has already been declared.
2、不存在变量提升
如果在声明之前使用,就会报错(这个东西还不存在呢,你怎么使用?更符合正常思维。而var在存在之前使用,则是不会报错的)
javascript
console.log(tt);
let tt = "天天开心";
//报错
Uncaught ReferenceError: Cannot access 'tt' before initialization.
3、不会成为window属性
javascript
// var → 会变成 window 的属性
var a = 100;
console.log(window.a); // 100 ✅
// let → 不会挂到 window
let b = 200;
console.log(window.b); // undefined ❌
关于用let还是用const的最佳实践
以上3个特点都是 let 和 const 共有的,那什么时候用let?什么时候用const呢?
它俩有非常重要的一点区别
let 用于声明变量,可以被重新赋值
const 用于声明常量,不可以被重新赋值
javascript
if(true){
let title = "天天快乐";
title = "天天发财";
console.log(title); //控制台将输出 天天发财
const tt = "好运来"
tt = "哇哈哈"; //会报错:Uncaught TypeErroe: Assignment to constant variable.
}
最佳实践的代码规范:优先使用const,主要有以下几个原因:
1.当我们无法判断一个变量的值究竟会不会再改变,无脑用const,等到后期需要改变时,再将const声明改为let声明。
2.如果一个变量的值是不允许修改的,但是我们却用let声明了,后期改变就会导致程序出现难以觉察的bug,而用const声明就可以有效避免无意间修改变量导致的bug。
【注】:这个最佳实践也是被ESlint收录的,如果用let声明的某个变量值没有发生改变,它会提示我们使用const来代替。
加餐:经典面试题
某次面试,本程序媛真的遇到过*......*
javascript
for(var i = 0; i < 4; i++){
setTimeout(function(){
console.log(i);
},1000)
}
以上代码的运行过程和输出结果是什么样的?
如果前端基础知识不好的小伙伴,肯定会一眼觉得是:每隔1秒输出1个数字,分别是0123
但
其实
肯定
不是这样的
正确答案:循环1秒后,一次性输出4个4。
这里边会涉及到++事件循环机制++(这个以后会细说,此次暂且不讲)
简单来说就是程序先执行了for循环,由于 i 具有全局作用域 ,因此整个循环只有一个 i ,循环执行完,变量 i 由0变成了4,再执行setTimeout,然后console打印的是同一个 i即输出4个4。
那同样的代码,变量换做let来声明,又将会是什么样的结果呢?
javascript
for(let i = 0; i < 4; i++){
setTimeout(function(){
console.log(i);
},1000)
}
正确答案:循环1秒后,一次性输出0123
程序执行过程:先执行for循环,let 是块级作用域,每一轮循环都会创建一个新的 i,独立保存 ,定时器里引用的是当前轮次的 i
由于以上两种结果都是一次性输出的,那么想要实现每隔一秒输出一个数字,并且分别输出0123,该怎么做呢?
各位小伙伴可以讨论一下哈,我先在这留个小尾巴,以后我们还会再聊这道经典题哈😃