一文搞定var、let、const

188 阅读3分钟

附:「这是我参与2022首次更文挑战的第10天,活动详情查看:2022首次更文挑战

区别

1.1 变量提升

(1)JS中变量提升说的是在程序中可以在变量声明之前进行使用。示例代码如下:

function test(){
    console.log(a); // undefined
    var a = 10;
}
test()

可以看到,在变量a声明之前我们可以正常访问a。实际代码运行是这样的:

var a;
console.log(a); // undefined
a = 1;

(2)在JS的变量提升中,除了var有变量提升,let、const也有。以下代码分别使用了三种定义变量的方式。看下不同定义变量的方式,提前访问变量会输出什么?

function test1(){
    console.log(a); // undefined
    var a = 10
}
test1()

function test2(){
    console.log(b); //  Cannot access 'b' before initialization -> 翻译中文为:在初始化之前无法访问"a"
    let b = 10;
}
test2()

function test3(){
    console.log(c); //  Cannot access 'c' before initialization -> 翻译中文为:在初始化之前无法访问"a"
    const c = 20;
}
test3()

解析:使用 var 声明的变量,在词法环境中会被初始化为 undefined ,但用 let 和 const 声明的变量并不会被初始化。使用 let 和 const 声明的变量只有在执行到赋值那行代码的时候才会真正给他赋值,这也意味着在执行到变量声明的那行代码之前访问那个变量都会报错,这就是我们常说的暂时性死区(TDZ)。即在变量声明之前都不能对变量进行访问。

小总结:

  1. 两个概念
  • 变量提升:在JS程序中可以在变量声明之前进行使用。
  • 暂存性死区:变量声明之前都不能对变量进行访问。
  1. var、let、const都有变量提升。但是在词法环境中用var声明的变量会被初始化为undefined,而let、const声明的变量并不会初始化。使用 let 和 const 声明的变量只有在执行到赋值那行代码的时候才会真正给他赋值,这就意味着在执行到变量声明的那行代码之前访问那个变量都会报错,这也是我们常说的暂时性死区(TDZ)。即在变量声明之前都不能对变量进行访问。

1.2 值是否可变

(1)var、let声明变量的值可变

(2)const声明变量的值不可变(简单数据类型),如果是复杂数据类型(Array、Object),则内部数据可变。示例代码如下:

var a = 10;
a = 12;
console.log(a) // 12

let b = 20;
b = 22;
console.log(b); // 22

const c = 30;
c = 40;
console.log(c); // TypeError: Assignment to constant variable. -> 类型错误:赋值到常量变量

解析:可以看到 const 常量声明变量的值(简单数据类型)重新赋值,是不能够改变的。但如果是一个复杂数据类型,那就不一样了,虽然不能修改复杂数据类型的内存地址,但是可以修改内部的数据。示例代码如下:

const person = {
    name: 'xiaohe',
    age: 18
}

person.name = 'xiaoming'
person.age = 19;
console.log(person.name) // xiaoming
console.log(person.age) // 19

补充知识点:const 声明变量之后必须马上赋值,否则会报错。

const a;
console.log(a); // SyntaxError: Missing initializer in const declaration - 语法错误:const 声明中缺少初始值设定项

小总结:

  1. var、let声明变量的值可变。const声明变量的值(简单数据类型)不可变,如果是复杂数据类型,内部数据可变。

1.3 是否可以重复声明变量

(1)var声明的变量可以重复声明,let、const不能重复声明变量。示例代码如下:

var a = 10;
var a = 20;
console.log(a);

let b = 20;
let b = 20;  // Identifier 'b' has already been declared


const c = 30;
const c = 20;  // Identifier 'c' has already been declared

1.4 是否会挂载到window对象上

(1)var声明的变量会被挂载到顶层对象(window)身上,let、const声明的变量不会。示例代码如下:

总结

  1. 补充其他知识点:
var x; // 声明x
var y = 10; // 初始化y
  1. 思维导图