人只有献身于社会,才能找出那短暂而有风险的生命的意义。 ——<爱因斯坦>
作者:Ashish Lahoti
译者:cl9000
原文:https://codingnconcepts.com/javascript/difference-between-var-let-and-const/
ES2015 (ES6)
中新增的一个不错的特性是为变量声明引入了 let
和 const
关键字。可以互换地使用 var、let和const
关键字来声明变量,尽管这在它们的作用域、用法和提升方面有所不同。如果
你还没有意识到这些差异,请继续阅读…
Scope 作用域
作用域基本上是指变量的可访问性。变量可以有三种作用域:-
1. 全局作用域 Global Scope
当变量定义在函数外部并且在任何地方都可以访问时。所有的var, let和const
都是全局作用域。
2. 函数作用域 Function Scope
使用 var
定义的变量是函数作用域的,因为如果它是在函数内部定义的,那么它们的可见性仅限于函数或嵌套函数。当你尝试在函数外使用它时,你会得到一个错误。
1 | function myFn() { |
3. 块作用域 Block Scope
使用 let或const
定义的变量是块范围的,因为如果它定义在代码块内(在花括号{}
之间的代码),它们的可见性仅限于代码块,任何嵌套的块。当你尝试在块之外使用它时,你会得到一个错误。
1 | if (true) { |
使用
1. var
在 ES6
之前,var
是变量声明的唯一关键字。
在 for
循环之外执行 var
操作
1 | for (var i = 0; i < 3; i++) { |
因为 var
是函数作用域的。变量i
可以在for
循环之外被访问(代码块).
var
重新分配
使用var的变量可以重新赋值,也可以重新定义。
1 | function myFn() { |
2. let
在 for
循环之外执行 let
操作
1 | for (let i = 0; i < 3; i++) { |
因为 let
是块范围的。变量 i
在 for
循环之外是不可访问的(代码块).
let
重新分配和重新定义
使用let的变量可以重新赋值,但不能重新定义。
1 | function myFn() { |
Output
Uncaught SyntaxError: Identifier ‘foo’ has already been declared
但是,如果 let
变量在不同的作用域中定义,就不会出现错误。
1 | let foo = 1; |
Output
1
2
3
为什么没有错误? 这是因为这三个实例都被视为不同的变量,因为它们具有不同的作用域。
3. const
关键字 const
类似于 let
,它是块作用域的,但是你不能给它重新赋值。
1 | const PI = 3.1415; |
但是,仍然可以将新项推入数组常量或添加到对象中。下面的两个代码段可以毫无怨言地工作,因为我们并没有试图重新分配变量:
1 | const someArr = [3, 4, 5]; |
1 | const someObj = { |
提升 Hoisting
提升是一种 ·JavaScript` 机制,在代码执行之前将变量和函数声明移动到其作用域的顶部
对于 var
变量,它们的值在提升过程中被初始化为 undefined
。
1 | console.log(foo); |
被解释为:
1 | var foo; |
你能猜到下面代码片段的输出是什么吗?
1 | var foo = 1; |
你猜 foo = 1
还是 foo = 2
?
都不是。它将打印未定义。让我们看看在提升过程中编译器是如何解释它的
1 | var foo; |
就像 var
一样,let
声明也被挂起在顶部,但不像 var
被初始化为 undefined
, let
变量没有初始化。因此,如果你尝试在声明之前使用 let
变量,你会得到一个引用错误。const
变量在提升方面与let
变量相似。
1 | console.log(foo); |
Output
ReferenceError: foo is not defined
你能猜到下面代码片段的输出是什么吗?
1 | let foo = 1; |
你猜 foo = undefined
吗?
不 它不是。让我们看看在提升过程中编译器是如何解释它的
1 | let foo; |
总结 Summary
作用域 | 值更新 | 重新定义变量 | 提升 | |
---|---|---|---|---|
var | 函数作用域 | yes | yes(在作用域内) | 初始化为undefined |
let | 块作用域 | yes | no(在块作用域内)但yes(块作用域外) | 变量未初始化 |
const | 块作用域 | no | no | 未初始化的变量 |
var
变量是函数作用域,而let和const
是块作用域。- var变量可以在其作用域内更新和重新声明;
let
变量可以更新,但不能重新声明;const
变量既不能更新也不能重新声明。
- 它们都被悬挂在作用域的顶部,但是当
var
变量用undefined
初始化时,let和const
变量则不初始化。 var和let
可以在声明时不进行初始化,而const
则必须在声明时进行初始化。
参考
原文 - https://codingnconcepts.com/javascript/difference-between-var-let-and-const/
赞赏一下 坚持原创技术分享,您的支持将鼓励我继续创作!