var,const,let的区别
关于 var、let 和 const 三个关键字的区别,是一个老生常谈的问题,也是经典的面试题。本篇文章将全面讲解三者的特性,以及它们之间的区别,由浅入深让你彻底搞懂这个知识点。
什么是变量提升?
在JavaScript中,变量提升(Hoisting)是一种特殊的现象,它指的是变量和函数声明在代码执行之前就被提升到当前作用域的顶部。这意味着无论声明在何处,都会被视为在当前作用域的开始处声明。这个概念对于理解JavaScript代码的执行顺序非常重要。
作用域有哪些?
1.全局作用域:在代码的任何地方都能访问到的变量被定义在全局作用域。需要注意的是所有未定义直接赋值的变量,自动声明为拥有全局作用域,例如:
function fn()
{
a=10;//这种情况a视为全局变量
}
2.函数作用域:在函数内部定义的变量只能在函数内部访问,这就是函数作用域。这意味着,如果你在一个函数内部定义了一个变量,那么这个变量在函数外部是不可见的。比如:
function Sum(){
var sum=0;//sum只有在函数内部才能访问
}
3.块级作用域:块级作用域可通过新增命令 let 和 const 声明,所声明的变量在指定块的作用域外无法被访问。块级作用域在如下情况被创建: 在一个函数内部或者在一个代码块(由一对花括号包裹)内部
if(true){
//块级作用域
}
function(){
//块级作用域
}
1.var
我们先来看一段代码:
console.log(myName);
var myName='曾同学'
这时候新手会以为输出的是变量未定义。实际上输出的是undefined,这实际上是因为var这个关键字。我们在全局作用域中或局部作用域中,使用var关键字声明的变量,都会被提升到该作用域的最顶部,这就是我们常说的变量提升。
var myName;
console.log(myName);
myName='曾同学'
这两段JS代码本质上是一样的。
2.let
- 作用域:
let具有块级作用域,即在{}包围的代码块内声明的变量仅在该块中有效。块级作用域包括函数、循环、条件语句等。 - 变量提升:
let声明的变量也会被提升,但由于存在暂时性死区(TDZ),在变量声明之前访问会导致错误。
下面是一个展示 let 变量提升和暂时性死区(TDZ)的代码示例:
// 尝试在 let 声明前访问变量
console.log(x); // 报错:Cannot access 'x' before initialization
let x = 10;
console.log(x); // 正常输出:10
这个例子中: 1. 第一行尝试访问 x 时,由于 x 已被提升但还未完成初始化(处于 TDZ 中),会抛出错误 2. 第三行正式声明并初始化 x 后,后续访问就能正常获取值 这体现了 let 变量虽然存在提升,但 TDZ 机制阻止了在声明前的访问。
3.const
- 作用域:
const同样具有块级作用域,与let一致。 - 可变性:
const声明的变量是常量,即声明时必须初始化,并且在其- 生命周期内不能重新赋值。不过,如果const声明的是对象或数组等引用类型,虽然引用本身不能变更,但其内部的属性或元素是可以改变的。 - 变量提升: 与
let一样,const变量存在暂时性死区(TDZ),在声明之前访问会导致错误。 - 用途:
const用于声明那些在整个程序执行过程中不应修改的常量。它提供了更多的安全性和代码可读性。
4.注意事项
能用const的情况下尽量使用const,大多数情况使用let,避免使用var。 const > let > var const声明的好处,一让阅读代码的人知道该变量不可修改,二是防止在修改代码的过程中无意中修改了该变量导致报错,减少bug的产生。let声明没有产生预编译和变量提升的问题,先声明再使用可以让代码本身更加规范,let是个块级作用域,也不会污染到全局的变量声明。 最后说一点就是使用的场景说明:let一般应用于基本数据类型;const 一般应用于引用数据类型,也就是函数对象等。