var与let的爱恨情仇?

161 阅读3分钟

在JavaScript中,varlet都是用来声明变量的关键字,但它们之间存在一些显著的区别。他们之间又有什么爱恨情仇呢?我们一起看一看

作用域不同

-   `var`声明的变量具有函数作用域,即变量在声明它的函数体内部有效。如果在函数外部尝试访问该变量,将会得到`undefined`(如果未声明全局变量)或报错(如果严格模式下)。
-   `let`声明的变量具有块级作用域,即变量仅在声明它的代码块(如`if``for``while`等语句块或单独的大括号`{}`内)内有效。在块外部尝试访问该变量将会导致语法错误。

重复声明

-   使用`var`可以在同一个函数作用域内多次声明同一个变量,此时不会报错,而是会覆盖之前的声明。
-   使用`let`则不能在同一作用域内重复声明同一个变量,否则会导致语法错误。

变量提升

-   `var`声明的变量具有变量提升特性,即变量可以在声明之前被访问,此时变量的值为`undefined`-   `let`声明的变量不存在变量提升,如果在声明之前尝试访问该变量,将会导致语法错误。这也被称为暂时性死区(Temporal Dead Zone, TDZ)。

全局作用域中的行为

-   在全局作用域中使用`var`声明变量时,该变量会成为全局对象(如`window`对象)的属性。
-   使用`let`在全局作用域中声明变量时,该变量不会成为全局对象的属性,而是保持在全局作用域中。

初始化要求

-   `var`声明的变量可以不进行初始化,即可以先声明后赋值。
-   虽然`let`也可以先声明后赋值,但由于其块级作用域和不存在变量提升的特性,通常建议在声明时同时进行初始化以避免潜在的错误。
-   初始化要求这里又要注意let一个小细节--暂时性死区。

所以什么是暂时性死区

当使用let声明一个变量时,这个变量在声明之前的代码区域(包括整个代码块)是“不可访问”的。如果在声明之前尝试访问这个变量,JavaScript会抛出一个错误,因为这个变量在“暂时性死区”内是不可访问的。

这与var的变量提升(Variable Hoisting)特性形成了鲜明对比。在函数作用域内,var声明的变量在声明之前就可以访问,尽管它们的值会是undefined

这种“暂时性死区”规则使得letconst声明的变量在作用域内更加安全,减少了变量名冲突的可能性,并提供了更清晰的代码结构和意图。我们来看下面的例子

image.png 现在我们终于详细的了解了let与var的爱恨情仇