JavaScript:学习笔记(7)——VAR、LET、CONST三种变量声明的区别
ES2015(ES6)带来了许多闪亮的新功能,自2017年以来,许多JavaScript开发人员已经熟悉并开始使用这些功能。虽然这种假设可能是正确的,但仍有可能其中一些功能对某些人来说仍然是一个谜。
ES6带来的一个新特性是新增了通过使用let、const来声明变量。在本文中,我们将讨论var,let和const的范围,使用和提升。在您阅读时,请注意它们之间的差异,我会指出。
VAR
VAR的范围
范围本质是意味着这些变量可供使用的位置。var声明的范围是全局作用于或者本地函数作用域。当一个var变量声明在函数外面时它的作用域是全局的,这意味着在整个窗口中可以使用在函数块外部使用var声明的任何变量。var变量在函数内声明时是函数作用域。这意味着它可用,只能在该函数中访问。
我们举一个例子:
<script> var greeter = "Hello"; function hello() { var hi = "Hi"; } </script>
在这里,greeter是全局范围的,因为它存在于函数外部,而hello是函数作用域。所以我们不能在函数外部访问变量hi。所以,如果我们这样做:
var变量可以重新声明和更新
这个是比较好理解的
var变量提升
变量提升是什么意思呢?比如我们看下面这段代码
当f()执行后,输出的结果是什么?可能你会说是日期,因为函数f()中,虽然想对tmp进行字符串赋值,但是被if制止了,所以还是以前的Date类型,其实是错误的。这里涉及到一个问题,就是变量提升(Hoisting),它是一种JavaScript机制,它规定变量和函数声明在代码执行之前被移动到其作用域的顶部。所以上面代码等同于下面代码:
所以,结果就是undefined。
var变量带来的问题
var有一个弱点。我将使用下面的例子来解释这一点。
这段代码看起来是没有任何问题的,但是却是一个巨大的隐患,虽然如果您故意要求重新定义greeter,这不是问题,但如果您没有意识到之前已经定义过变量greeter,则会成为一个问题。如果您在代码的其他部分使用了greeter,那么您可能会对可能获得的输出感到惊讶。这可能会导致代码中出现很多错误。这就是let和const必要的原因。
也即是说,如果定义在全局作用域的var变量,极有可能对以前定义的同名变量进行覆盖,从而引发问题,而这一切我们都茫然不知。
LET
如果要定义变量,let现在是首选。毫不奇怪,因为它是对var声明的改进。它还解决了最后一个小标题中提出的这个问题。让我们考虑为什么会这样
Let是块作用域
块是由{}限定的代码块。一个块生活在花括号中。花括号内的任何东西都是块。因此,在带有let的块中声明的变量仅可在该块中使用。让我用一个例子解释一下。
这个是上面例子的改写,if语句构成了一个块,在外面我们无法访问hello,故报错。
Let可以更新但是不能重新声明
正如下面例子我们看到的,无法重新定义a变量。
在这里很明显两个a在同一个作用域下,如果我们放在不同的块中是可以的,但是切记这不是重新声明,他们隶属于不同的块,对每个块来说都是第一次定义:
Let变量提升
就像var一样,让声明被提升到顶部。与初始化为undefined的var不同,let关键字未初始化。因此,如果您在声明之前尝试使用let变量,则会出现参考错误。
CONST
用const声明的变量保持常量值。 const声明与let声明共享一些相似之处。
const声明是块作用域
与let声明一样,const声明只能在声明的块中访问。
const无法更新或重新声明
因此,每个const变量必须在声明时初始化。
虽然无法更新const对象,但可以更新此对象的属性。因此,如果我们声明一个const对象
CONST变量提升
就像let一样,const声明被提升到顶部但未初始化。
总结
让我们来梳理一下三者的区别
- var声明是全局作用域或函数作用域,而let和const是块作用域。
- var变量可以在其范围内更新和重新声明;let变量可以更新但不能重新声明; const变量既不能更新也不能重新声明。
- 它们全部被提升到其范围的顶部,但是变量初始化为undefined时,let和const变量不会被初始化。
- 虽然可以声明var和let而不进行初始化,但必须在声明期间初始化const。
来源:https://www.cnblogs.com/MrSaver/p/10019493.html