前端学习之面试题系列:(一)var、let、const的区别

305 阅读3分钟

写在前面

var、let、const三者之间的区别是面试中常遇到的题目。其中var是ES5提出的,let和const是ES6提出的,他们三个之间主要有以下区别需要注意和理解~

  • 变量提升

    • var声明的变量存在变量提升,在使用var声明变量前,可以使用该变量,值为undefinded。

    • let/const声明的变量不存在变量提升,在使用let/const声明变量前,不可以使用该变量,否则会报错。

    console.log(f) //undefined
    var f = 1;
    
    console.log(g) //ReferenceError: g is not defined
    let g = 2;
    
    console.log(h) //ReferenceError: h is not defined
    const h = 3;
    
    
  • 暂时性死区

    • let和const声明的变量存在暂时性死区,即只要块级作用域内存在let/const声明的变量,那么这个变量就“绑定”(binding)这个区域,不受外部影响。
    let x = 'global'
    {
      console.log(x) // Uncaught ReferenceError: x is not defined
      let x = 1
    }
    
    • console.log(x)中的x指的是代码块中let声明的x(let x = 1),不是指全局的x(let x = 'global')
    • 执行console.log(x)时,x还没有被初始化,因此报错。
  • 重复声明变量

    • var允许重复声明变量,let和const不允许在同一作用域内重复声明变量。
    var f = 4;
    var f = 5;
    console.log(f) //5
    
    let g = 6;
    let g = 7;
    console.log(g) //SyntaxError: Identifier 'g' has already been declared
    
    const h = 8;
    const h = 9;
    console.log(h) //SyntaxError: Identifier 'h' has already been declared
    
  • 块级作用域

    • var声明的变量没有块级作用域的概念

    • let和const声明的变量存在块级作用域

    • ES5中只有全局作用域和函数作用域,没有块级作用域的概念

    • ES6中新增了块级作用域,块级作用域就是指{},if和for语句的{}也是块级作用域。

    //var声明的变量可以跨块作用域访问,不能跨函数作用域访问
    var a = 2
    (function fun(){
        console.log(a) //undefined  内层变量覆盖外层变量
        //console.log(a) //2
        if(true){
            var a = 3 //变量提升
            //let a = 3 //不存在变量提升
            console.log(a) //3
        }
        console.log(a) //3
    })()
    console.log(a) //2
    
    //用于计数的变量泄露为全局变量
    for(var i = 0; i < 5; i ++) {
        var d = 10
    }
    console.log(i) // 5  (循环结束i已经是5,所以此处i为5)
    console.log(d) // 10 -> 将var改为let,就会报错 Uncaught ReferenceError: i is not defined
    
  • 变量修改

    • var和let声明的变量可以修改

    • const声明的是常量,不可以修改

      • 声明时需要立即初始化,不能留到以后赋值

        const obj //Uncaught SyntaxError: Missing initializer in const declaration
        obj = {}
        
      • 声明的常量是引用类型时(数组和对象),只要在栈内存保存的地址值不变即可,其属性和结构可以改变。

        //对象的属性和结构可以改变
        const obj = {
            name: 'crystal',
            age: 25
        }
        obj.age = 26
        obj.height = 1.60
        console.log(obj) //{name: "crystal", age: 26, height: 1.6}
        
        //地址不能改变,不能指向新对象
        obj = {
            name: 'wjj'
        } //Uncaught TypeError: Assignment to constant variable.
        
        // 数组的结构可以改变
        const arr = [0, 1]
        arr[2] = 2
        console.log(arr); //(3) [0, 1, 2]
        arr.pop()
        console.log(arr); //(2) [0, 1]
        
        //地址不能改变,不能指向新数组
        arr = [1,1,1] //Uncaught TypeError: Assignment to constant variable.
        
  • 参考文章

    我用了两个月时间才理解let

    【ES6】var、let、const三者的区别

    let、const、var 的区别有哪些?