在面试中,我们经常会碰见这样一道面试题:请说下let var const区别?当你听到这道题时,你是否答出面试官想要的呢?有没有模棱两可呢? 又或者在平时开发中对他们三不太清楚到底怎么使用,怎么取舍呢?接下来,带你彻底搞懂他们区别吧。
var
1. var 申明作用域---函数作用域
function testVar(){
var message = "杨幂";
}
testVar();
console.log(message); //出错
这里的message是在函数内部使用var定义的,当调用了testVar()函数结束后,变量message随即会被销毁,再使用时就会报错
📢;注意:如果在函数内部申明message 时省略了var,此时相当于创建一个全局的message变量,再次使用时也就不会出错了
function testVar(){
message = "杨幂";
}
testVar();
console.log(message); //杨幂
注意:虽然可以通过省略var操作符定义全局变量,但不推荐这么做。在局部作用域中定义的全局变量,很难维护,也会造成很多莫名其妙的bug,在严格模式下,如果像这样给未声明的变量赋值,则会到处抛出RefrenceError的错误。
开发小技巧: 如果同时定义多个变量,可以在一条语句中用逗号分隔每个变量,后面变量可以省略var 如:
var person = "赵丽颖",
age = 19,
message = "你好";
2. var声明提升
function test(){
console.log(name); //undefined
var name = "杨幂"
}
test(); //undefined
使用上面代码不会报错,这是因为使用var申明的变量,会自动提升到函数作用域的顶部。等价于以下代码
function test(){
var name;
console.log(name); //undefined
name = "杨幂"
}
test(); //undefined
多次反复申明同一个变量,也是没有问题的
function test(){
var name = "张杰";
var name = "谢娜";
var name = "何炅";
console.log(name);
}
test(); //何炅
let
1.let申明作用域(块级作用域)
let 与var的一个重要区别就是 let声明的范围是块级作用域,而var声明的范围是函数作用域 块级作用域是函数作用域的子集。
if(true){
let person = "欧阳娜娜"
cosole.log(person); //欧阳娜娜
}
cosole.log(person); //RefrenceError: person没有定义
在这里person之所以不能在if代码块之外使用,因为let的作用域仅限于if代码块内
if(true){
var name = "欧阳娜娜"
cosole.log(name); //欧阳娜娜
}
cosole.log(name); //欧阳娜娜
let不允许同一块级作用域内重复声明同一个变量
let age;
let age; //SyntaxError: 标识符age已经声明过了
2. 暂时性死区(在let声明之前的执行瞬间被称为“暂时性死区”)
let和var的另一个区别,就是let声明的变量不会在作用域内提升
cosole.log(name); //undefined
var name = "章子怡"
cosole.log(name); //RefrenceError: name没有定义
let name = "章子怡"
3.全局声明
let在全局作用域中声明的变量 不会成为window对象的属性
var在全局作用域中声明的变量 会成为window对象的属性
var name ="鹿晗"
console.log(window.name); //鹿晗
let name ="鹿晗"
console.log(window.name); //undefined
4.条件声明
在使用var声明变量时,由于声明的变量会被提升,Javascript引擎会自动将多余的声明在作用域顶部合并为一个声明,因为let的作用域是块级作用域,所以不能够检查前面是否已经使用过let声明过同名变量了,同时也不可能在没有声明的情况下声明它
<script>
var name = "一鸣";
let age = 11;
</script>
<script>
var name = "张杰"; //这里不会报错 因为被作为一个变量提升来处理了
let age = 22; //如果之前声明过 此处将会报错
</script>
使用try/catch语句或者typeof也是不能解决let重复申明报错的 因为let申明的作用域仅限于代码块
5. for循环中的let申请
for(let i = 0;i<5;i++){
//代码
}
console.log(i); //ReferenceError:没有定义
for(var k = 0; k<5;k++){
//代码
}
console.log(k); //5
使用var最常见的问题
for(var i = 0;i<5;i++){
setTimeout(() => {
console.log(i); //5,5,5,5,5
},0)
}
你以为会打印0,1,2,3,4,其实并不是这样,之所以出现这种情况,是因为在退出循环时,迭代变量保存的是循环退出时的值,在之后执行超时逻辑时,所有的i都是同一个变量5,因此你看到了全部是5.
而使用let声明迭代变量时,js引擎会在后台会为每个迭代循环声明一个新的迭代变量。每次setTimeout引用的都是不同的变量,因此打印01234
const声明
- const与let的行为基本一致,唯一一个重要的区别就是 声明const变量时必须要同时给变量进行赋值,给一个初始值,否则会报错。
- const也不允许重复声明
- const的作用域也是块级作用域
总结: 那我们平时开发时,该怎么合理取舍选择他们呢
- 尽量不适用var
- const优先,let次之
好了 ,到这里告一段落了,想必你也对这三个变量的区别有所了解,以后怎么使用也得心应手了,愿我们在开发的时候不再有任何困扰了,在面试时能手撕面试官,😄