目录
相信大家在面试中经常遇到这样的问题,什么是变量提升?var、let 及 const 区别?什么是暂时性死区?下面我们具体了解下,方便大家参考,不足之处欢迎大家补充。
一、什么是变量提升(hoisting)
?我们先看一段代码:
console.log(a) // undefined
var a = 1
从上述代码中我们可以发现,虽然变量还没有被声明,但是我们却可以使用这个未被声明的变量,这种情况就叫做变量提升,并且提升的是声明。
对于这种情况,我们可以把代码这样来看
var a
console.log(a) // undefined
a = 1
?接下来我们再来看一个例子
var a = 10
var a
console.log(a)
对于这个例子,如果你认为打印的值为?undefined
?那么就错了,答案应该是?10
,对于这种情况,我们这样来看代码
var a
var a
a = 10
console.log(a)
到这里为止,我们已经了解了?var
?声明的变量会发生提升的情况,其实不仅变量会提升函数也会被提升。
console.log(a) // ? a() {}
function a() {}
var a = 1
对于上述代码,打印结果会是?? a() {}
,即使变量声明在函数之后,这也说明了函数会被提升,并且优先于变量提升。
存在的根本原因就是为了解决函数间互相调用的情况
function test1() {
test2()
}
function test2() {
test1()
}
test1()
假如不存在提升这个情况,那么就实现不了上述的代码,因为不可能存在?test1
?在?test2
?前面然后?test2
?又在?test1
?前面。
二、var、let 及 const 区别?
let
声明和var声明用法是一样,都是定义变量,使用let声明的变量没有var那样的变量提升,let声明的变量只在当前作用域中有效。
{ // 块级作用域
let a1 = 2;
}
console.log(a1); // 报错:a1 is not defined
const声明被称为常量,为了更好理解,下文还是用变量进行介绍
const和let非常相似:不能声明重名变量、存在暂时性死区、没有变量提升、有块级作用域限制
。这些都是非常nice的规则,在此基础上,const还增加了两个规则:1、声明时必须赋值;2、值不可修改;
声明时必须赋值这个很好理解,就是在创建的时候必须给这个变量一个初始值。我们详细说一下值不可修改
这一点:
const a = '2';
a = 2; // 报错a变量已经声明,不能重复创建:entifier 'a' has already been declared
上面代码首先我们创建了const变量并为其赋值字符串类型的’2’,在第二行代码实际上是想把数字类型的2赋值给刚刚创建的const变量中,这时候确保错了,由此可见const变量适合用在值不会变的场景。还有一种情况就是给const变量赋值数组和对象类型的值,因为这两个数据类型属于引用类型,所以只要在引用地址值不变的情况下,更改、新增、删除对象或数组中的元素是不会报错的。?
相同点:var,let,const三者都可以声明变量
不同点:?
三、什么是暂时性死区
我们先来看一个例子:
var a = 1
let b = 1
const c = 1
console.log(window.b) // undefined
console.log(window. c) // undefined
function test(){
console.log(a)
let a
}
test()
首先在全局作用域下使用?let
?和?const
?声明变量,变量并不会被挂载到?window
?上,这一点就和?var
?声明有了区别。
再者当我们在声明?a
?之前如果使用了?a
,就会出现报错的情况
报错的原因是因为存在暂时性死区,我们不能在声明前就使用变量,这也是?let
?和?const
?优于?var
?的一点。然后这里你认为的提升和?var
?的提升是有区别的,虽然变量在编译的环节中被告知在这块作用域中可以访问,但是访问是受限制的。
四、总结
var
?存在提升,我们能在声明之前使用。let
、const
?因为暂时性死区的原因,不能在声明前使用。var
?在全局作用域下声明变量会导致变量挂载在?window
?上,其他两者不会。let
?和?const
?作用基本一致,但是后者声明的变量不能再次赋值。欢迎在评论区交流。
如果文章对你有所帮助,??关注+点赞??鼓励一下!博主会持续更新。。。。
我的博客:https://code-nav.top