var,let,const的区别

107 阅读3分钟

var

  • var是js最早引入的用于声明变量的关键字,在 ES6 之前一直被广泛使用。

  • var 声明的变量具有函数级作用域,在函数体内可见。

  • 存在变量提升特性。

function varFun() {
    if(true) {
        var x = 10;
    }
    console.log(x);  // 输出 10,因为 var 声明的变量是函数级作用域
} 
varFun();
console.log(x); // 输出 undefined
var x = 10;
// 以上代码等价于下面的代码
var x;
console.log(x);
x = 5

let

  • let是ES6引入的块级作用域变量声明关键字,解决了var在作用域方面的一些问题。

  • let声明的变量具有块级作用域,只在离定义最近的{}中才可见。

  • 不存在变量提升特性。

  • 同一作用域中不允许重复命名(报错),但能够重新赋值。

function letFun() {
    if(true) {
        let y = 20;
    }
    console.log(y);  // 报错,y 在{}外不可见
}
letFun();

const

  • const也是ES6引入的关键字,用于声明常量,一旦被赋值就不能再修改其值。
  • const声明的常量是块级作用域,类似let
  • let不同的是,const声明的变量必须在声明时赋值,且后续不可以重新赋值。
function constFun() {
    const z = 30;
    // z = 40;   // 报错, 无法重新赋值
    console.log(z);
}
constFun();

总结:

  • 开发中尽量使用let代替var声明变量,因为块级作用域可以让变量的声明更加可控:

    • 只有在当前块中可见,在不同块中就算使用了相同名称的变量也不会有所干扰,但是如果在同一个函数的不同块中用var声明变量,名称相同,就可能发生覆盖或逻辑混乱。
    • let声明的变量在块级作用域结束时会被销毁,从而释放内存,可以避免内存泄漏和不必要的变量持久化。
  • 如果需要声明一个可以重新赋值的变量,使用 let;如果需要声明一个不可变的常量,使用 const

拓展

词法环境变量环境理解变量提升

console.log(x); // undefined
var x = 5;

console.log(y); // 报错: y 未初始化
let y = 10;

console.log(z); // 报错: z 未初始化
const z = 15;

预编译代码如下:

GlobalExecutionContent = {  // 全局上下文
  LexicalEnvironment: {  // 词法环境
    EnvironmentRecord: {  // 词法环境的环境记录
      Type: "Object",
      y: <uninitialized>,  // let声明,未初始化
      z: <uninitialized>,  // const声明,未初始化
      // 剩余标识符
    },
    Outer: null,  // 词法环境的外部环境引用,因为当前为全局上下文,所以没有外部环境
  },
  VariableEnvironment: {  // 变量环境
    EnvironmentRecord: { // 变量环境的环境记录
      Type: "Object",
      x: undefined,
      // 剩余标识符
    },
    Outer: null,   // 变量环境的外部环境引用,因为当前为全局上下文,所以没有外部环境
  }
}

上面的代码在执行的时候,会创建全局上下文对象,然后再创建词法环境和变量环境,var声明的变量在变量环境中创建一开始就被赋值undefined,而let声明的变量在词法环境中创建一开始为未初始化。因此,在未给let声明的变量赋值前就对其进行访问会报错,而var则不会。

image-20240326211706068.png

附:参考文章:zhuanlan.zhihu.com/p/302840261t.csdnimg.cn/CvB6c