JavaScript变量提升和函数提升简单谈一下自己的看法有啥不对向各位大佬请教

405 阅读4分钟

一:变量提升

1:js程序的运行分为编译阶段和执行阶段。
2:在编译阶段会把JS的变量声明提升到当前作用域的顶端,给var声明的属性定义成undefined值。生成一个scop存储所有的变量
3:首先我们来看看变量提升的例子:

图片1.png 我们执行这个文件时,是由引擎加载js文件,此过程有两个步骤:
第一步是读取js代码,将所有的变量声明和函数声明提升到全局作用域的顶端,就是我所说的变量提升。但是只是提升变量声明,并不赋值初始化提升。
第二步就是代码是从上到下执行的
下面我们来解释一下第一个例子:经过变量提升后的代码如图 image.png

我们再来看一个例子

image.png 变量提升后的代码: image.png 从此我们可以得出变量声明只是给变量声明undefined而不包括赋值,代码也是由上而下执行。所以你们看懂了吗?懂了的话我们再来看看函数提升(暂且不包括变量提升)

函数提升

第一种:函数声明,使用函数声明的函数会存在函数提升,即将声明的函数提升到当前作用域顶部
例:

image.png 函数提升后: image.png 第二种:函数表达式: image.png 这种函数表达式声明提升后: image.png 下面我们来看函数表达式和函数声明放在一起的结果: image.png 再看看函数提升后的代码: image.png 观察两幅图片的不同之处,你们可以得出什么结论呢?
从此我们可以得出函数声明会把整个函数都读取到最顶部也就是作用域中,而函数表达式就是把函数名做了个声明。所以函数声明的showName存了个1值,执行阶段第一个showName输出1,但执行到函数表达式时,由于编译阶段只是给showName声明,在执行阶段执行表达式函数,所以表达式函数showName得到第二个值2。就是用函数表达式showName覆盖了函数声明showName。

我们再来看看函数和变量放一起的提升: image.png 来我们看看这些代码,在没有学习之前,我们想一想会输出什么呢?
根据变量提升:console.log(f)是不是应该输出undefined?对,根据变量提升,结论是没有错的。根据函数提升:第一个console.log(f()),也就是执行f(),函数应该输出undefined,第二个应该输出10.最后一个输出console.log()该输出什么呢?没有返回结果,那是不是也该输出undefined?是的这些推断都没有错。那我们来看看正确的输出结果。 image.png 根据我们的猜想输出结果应该是:undefined;undefined;10;undefined
但是结果为什么会不一样呢?
这就应该注意了:其实函数提升是优于变量提升的,同名的变量和函数同时声明了,首先执行的是函数的声明。 我们来分析一下这个结果:声明了同名的一个变量和函数,因为函数提升的优先级大于变量提升,所以首先输出的是一个函数体方式[function: f],函数体中的内容为undefined和10,最后输出的undefined是因为函数没有返回值,则默认输出undefined。

最后让我们总结一下今天学的: 1:变量提升和函数提升,我们有一个作用域专门存放变量提升(编译后)的值,并且编译时会把提升调到作用域的顶端。
2:文件的执行顺序是由上往下顺序执行的
3:函数提升的优先级大于变量提升
4:变量提升时只会声明,并不会赋值提升
5:有多个同名变量声明时,函数声明会覆盖其他的声明
6:有多个同名函数声明,则是由最后的一个函数声明覆盖之前所有的声明。