面试官:说下var let const的区别?你真的答对了吗?

222 阅读4分钟

在面试中,我们经常会碰见这样一道面试题:请说下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次之

好了 ,到这里告一段落了,想必你也对这三个变量的区别有所了解,以后怎么使用也得心应手了,愿我们在开发的时候不再有任何困扰了,在面试时能手撕面试官,😄