JavaScript中的变量提升与函数提升

相信大家在学习JS的过程中,会遇到一个词,叫做“预解析”,什么是预解析呢,预解析就是说我程序在执行前,会先检查代码有没有语法错误,就是说相当于电脑先整体瞥一眼你的代码,如果有语法错误的话,会直接终止程序。我们接下来要讲的声明提升,就是预解析中的一个环节。因为之前不是说
那么我们为什么要做声明提升呢?声明提升又有什么作用呢?。声明提升可以把所有需要和内存交互的行为提前,这样一来,我们把所有的内存操作集中在一起的话,可以提升代码效率。目的就是可以达到优化代码执行效率的一个作用。
介绍了这么多,接下来我们开始说一下如何实现声明提升。声明提升包括两个部分,就是变量提升与函数提升。
首先我们先来看变量提升,何为变量提升呢?我们首先要了解变量包括哪两个部分

  1. 变量的声明 例如 var a;
  2. 变量的赋值 例如 a=666;

而我们所说的变量提升呢,其实就是指把变量的声明部分提到当前作用域的最前面去。记住,是当前作用域的最前面,不是说你想提到哪就能提到哪的。光说的话可能不好理解,下面我们直接上代码。
第一段是正常写的一个变量。

<script>
var a=111;
var b=222;
var c=333;
</script>

接下来再看变量提升后的一个变量

<script>var a,b,c;
a=111;
b=222;
c=333;
</script>

其实可以看出来,就是前面说的,我们把变量的声明部分给提到了当前作用域的最前面,而把函数的赋值部分,给留到了原地。这就是我们所说的变量提升,是不是很简单呢。但变量提升会导致一个问题的出现,下面我们看一段代码与运行结果。

<script>var a,b,c;
console.log(a);
a=111;
b=222;
c=333;
</script>

在这里插入图片描述
就是说当你在变量赋值之前调用它的话,控制台只会显示”undefined”,那么导致这个问题的出现也是因为通过var声明的变量,进行预解析的时候会先声明变量,不管变量有没有赋值,声明时都赋值为undefined。这时候可能会有人说了,你这一目了然啊,在赋值之前就调用,肯定得不到任何东西的,可是你想象一下,这是在代码极少的情况下很容易看出来,但如果我现在是上千行,或者更多的代码量的时候呢?在提升以后,保不齐什么时候会出现一个上面这样情况的出现,所以说这也是变量提升的一个缺点。
说完了变量提升,接下来咱们再说说什么是函数提升,有了前面变量提升的基础,再看函数提升也更容易理解。如果说变量提升是局部提升的话(因为只提升了声明部分),那么函数提升的话就是整体提升了。什么是整体提升呢,下面我们先写一个函数aa

<script>var a,b,c;
console. log(a);
a=111;
b=222;
c=333;
function aa(){
console.log(" 66666666");
}
</script>

在编译你的程序的时候,系统一路从上往下看代码,看到你这边发现你声明了一个函数aa,就会给你提升到最前面。也就是说,与之前变量提升不同的是,我无论在什么地方调用这个函数aa,都可以。什么意思呢?就是说我不管函数的调用是写在函数定义的前面,还是函数定义的后面,都可以执行。比如下面一段代码

<script>var a,b,c;
aa();
a=111;
b=222;
c=333;
function aa(){
console. log(666666666);
}
</script>

我在函数前面,直接进行了一次调用,我们来看看结果
在这里插入图片描述
可以看到成功的执行了函数aa,这就是函数提升,是整体提升的。
那么问题来了,变量提升和函数提升谁的优先级更高呢?就是说局部提升和整体提升哪个优先级更高一点呢?我们来测试一下。在测试之前,我们要先了解如果判断测试的结果,首先我们都知道,后面的肯定会覆盖前面的,也就是说显示的结果是后提升那个。下面我们来看代码

<script>
console.log(aa);
var aa=11111111;
function aa(){
console.log(6666666");
}
</script>

那么按照我们之前说的,如果是函数的提升优先级比变量高的话,显示结果会是变量,而如果变量提升的优先级比函数的高的话,显示的结果会是一个函数。那么我们来执行看一下结果。
在这里插入图片描述
可以看到执行的结果是显示了函数,说明变量提升的优先级比函数的高,导致变量先提升上去以后,后面的函数才再进行提升,这样覆盖了前面变量提升的结果,导致了最后打印结果是函数的情况。
在预解析的角度来看,预解析的过程中,当声明式函数和var声明的变量重名时,函数的优先级高于变量,所以这也是为什么会导致上面情况发生的原因。
最后,我们通过预解析底层原理再来看待变量提升与函数提升。在系统预解析的过程中,会先找到当前作用域下所有var声明的变量,并将这些变量拉取到当前执行上下文的最前端,并以声明不赋值的状态保存。这就是变量提升为什么是局部提升,只提升变量声明那一部分的原理,而在系统操作完变量以后,会找到当前上下文环境中所有function声明的函数,将函数整体接取到顶端,这就是为什么函数提升和变量提升不同,为什么是整体提升的原因。

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值