var与let、const的区别
本文最后更新于:1 年前
var 与 let、const 的区别
什么是变量提升?
JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明
暂时性死区
- 暂时性死区的本质就是,只要进入当前作用域,所要使用的变量就己经存在,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
在解析代码时,JavaScript 引擎也会注意出现在块后面的 let 声明。只不过在此声明之前不能以任何方式来引用未声明的变量。
在 let 声明之前的执行瞬间被称为“暂时性死区”,在此阶段引用任何后面才声明的变量都会抛出 ReferenceError
1 |
|
全局声明
与 var 关键字不同,使用 let 在全局作用域中声明变量不会成为 windows 对象的属性(var 声明的变量则会编程 windows 对象的属性)
1 |
|
不过 let 声明仍然是在全局作用域中发生的
for 循环中的 let 声明
在 let 出现之前, for 循环定义的迭代变量会渗透到循环体外部:
1 |
|
改成使用 let 之后,这个问题就消失了,因为迭代变量的作用 域仅限于 for 循环块内部:
1 |
|
在使用 var 的时候,最常见的问题就是对迭代变量的奇特声明 和修改:
1 |
|
之所以会这样,是因为在退出循环时,迭代变量保存的是导致循环退出的值:5。
在之后执行超时逻辑时,所有的 i 都是同一个变量,因而输出的都是同一个最终值。 而在使用 let 声明迭代变量时,JavaScript 引擎在后台会为每个迭代循环声明一个新的迭代变量。每个 setTimeout 引用的都是不同的变量实例,所以 console.log 输出的是我们期望的值,也就是循环执行过程中每个迭代变量的值。
1 |
|
这种每次迭代声明一个独立变量实例的行为适用于所有风格的 for 循环,包括 for-in 和 for-of 循环。
for 循环还有一个特别之处,就是设置循环变量的那部分是一个父作用域,而循环体内部是一个单独的子作用域。
1 |
|
正确运行以上代码将输出 3 次 abc 。这表明函数内部的变量 i 与循环变量土不在同一个作用域,而是有各自单独的作用域。
一、var 声明变量存在变量提升,let 和 const 不存在变量提升
1 |
|
1.const 定义的常量不可以修改,而且必须初始化。
1 |
|
2.var 定义的变量可以修改,如果不初始化会输出 undefined,不会报错。
1 |
|
3.let 是块级作用域,函数内部使用 let 定义后,对函数外部无影响。
1 |
|
再来看这段代码
1 |
|
我们发现不执行的代码也会影响会执行的代码,因为 var a 会提升到 if 语句的前面
undefined 可以翻译为不明确,not defined 可以翻译为未定义
在 Java 中变量的分为全局变量(成员变量)或者局部变量,在方法体中定义的变量都是局部变量,否则是全局变量(即在方法体外,在类中定义的变量)
在 JavaScript 中,在方法体外外用 var 定义的变量其它方法可以共享,在方法中用 var 定义的变量只有该方法内生效。
var 定义变量没有块级作用域的概念,定义变量会被提升到全局和全局变量没有什么区别
let 定义变量有块级作用域,外部无法访问
建议弃用 var,多使用 let 定义变量
二、let、const 都是块级局部变量
let(定义变量,有块级作用域)
const(定义常量,不能被修改)
顾名思义,就是只在当前代码块起作用
1 |
|
const 的行为与 let 基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改 const 声明的变量会导致运行时错误。
1)const 声明时候必须赋值
1 |
|
编译器报错
1 |
|
2)const 只能进行一次赋值,即声明后不能再修改
1 |
|
控制台报错
1 |
|
3)const 如果声明的是复合类型数据(主要是对象和数组),可以修改其属性
const 声明的限制只适用于它指向的变量的引用。换句话说, 如果 const 变量引用的是一个对象,那么修改这个对象内部的属性并不违反 const 的限制。
1 |
|
const 声明一个只读的常量。一旦声明,常量的值就不能改变 。const 实际上保证的并不是变量的值不得改动,而是变量指向的那个内存地址不得改动。
对于简单类型的数据(数值、字符串、布尔值〉而言,值就保存在变量指向的内存地址中,因此等同于常量。
但对于复合类型的数据(主要是对象和数组)而言,变量指向的内存地址保存的只是一个指针, const 只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,这完全不能控制 。 因此,将一个对象声明为常量时必须非常小心。
1 |
|
三、同一作用域下 let 和 const 不能声明同名变量,而 var 可以
1 |
|
控制台报错
1 |
|
let 和 const 的区别:
相似:
- 都是块级作用域
- 都不能和它所在作用域内的其他变量或函数拥有相同的名称
区别:
- const 声明的常量必须初始化,而 let 声明的变量不用。
- const 定义常量的值不能通过再赋值修改,也不能再次声明。
- 而 let 定义的变量值可以修改。
什么时候用 let,什么时候用 const
定义函数、对象和不变的值用 const
1 |
|
计算或者需要修改的值用 let
1 |
|
一般推荐 const 优先,let 次之
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!