本篇文章收录于我的专栏:前端精进之路
同时收录于我的github前端笔记仓库中,持续更新中,欢迎star~
👉https://github.com/mengqiuleo/myNote
变量提升和函数提升发生在什么时候?
上篇文章中我们介绍了JavaScript代码的执行过程,在预编译阶段,首先会创建执行上下文,此时对变量和函数进行声明,对var声明的变量赋值为undefined。此时会发生变量提升和函数提升。
变量提升
变量提升是将变量的声明提升到函数顶部的位置,而变量的赋值并不会被提升。需要注意的一点是,会产生提升的变量必须是通过var关键字定义的,而不通过var关键字定义的全局变量是不会产生变量提升的。
函数提升
使用函数声明方式定义的函数会出现提升,如下面一段代码所示。
foo(); // 函数提升
function foo(){
console.log('foo函数');
}
在上面的代码中,foo()函数的声明在调用之后,但是却可以调用成功,因为foo()函数被提升至作用域顶部,相当于如下所示代码。
function foo(){
console.log('foo函数');
}
foo();
需要注意的是函数提升会将整个函数体一起进行提升,包括里面的执行逻辑。
而对于函数表达式,是不会进行函数提升的。
foo(); // TypeError: foo is not a function
var foo = function foo(){
console.log('foo函数');
}
二者同时使用
show();//hello
var show;
//函数声明,会被提升
function show(){
console.log('hello');
}
//函数表达式,不会被提升
show = function(){
console.log('hello world');
}
变量提升与函数提升的应用
1. 关于函数提升
function foo(){
function bar(){
return 3;
}
return bar();
function bar(){
return 8;
}
}
console.log(foo());//8
代码中使用函数声明定义了两个相同的bar()函数。由于变量提升的存在,两段代码都会被提升至foo()函数的顶部,而且后一个函数会覆盖前一个bar()函数,因此最后输出值为“8”。
2. 变量提升和函数提升同时使用
var a = true;
foo();
function foo(){
if(a){
var a = 10;
}
console.log(a);//undefined
}
在foo()函数内部,首先判断变量a的值,由于变量a在函数内部重新通过var关键字声明了一次,因此a会出现变量提升,a会提升至foo()函数的顶部,此时a的值为undefined。那么通过if语句进行判断时,返回“false”,并未执行a = 10的赋值语句,因此最后输出“undefined”。
var a;
a = true;
function foo(){
var a;
if(a) {
a = 10;
}
console.log(a);//undefined
}
foo();
3. 变量提升和函数提升优先级⭐
function fn(){
console.log(typeof foo);//function
//变量提升
var foo = 'variable';
//函数提升
function foo(){
return 'function';
}
console.log(typeof foo);//string
}
fn();
在上面的代码中,同时存在变量提升和函数提升,但是变量提升的优先级要比函数提升的优先级高,因此实际执行过程可以改写为以下代码段。
改写后的代码:
function fn(){
//变量提升至函数首部
var foo;
//函数提升,但是优先级低,出现在变量声明后面,则foo是一个函数
function foo(){
return 'function';
}
console.log(typeof foo);//function
foo = 'variable';
console.log(typeof foo);//string
}
fn();
第二个🌰
foo(); // foo2
var foo = function() {
console.log('foo1');
}
foo(); // foo1,foo重新赋值
function foo() {
console.log('foo2');
}
foo(); // foo1
实际执行过程可以改写为以下代码段。
var foo;//变量提升
function foo() { //函数提升:同名,函数覆盖变量
console.log('foo2');
}
foo(); // foo2
foo = function() {
console.log('foo1');
}
foo(); // foo1
foo(); // foo1
![img](https://img-blog.csdnimg.cn/img_convert/e6d6d02211aa36948351417bd14d51e5.png)
![img](https://img-blog.csdnimg.cn/img_convert/baaffb3203ca6f50231f9e7563dc4f53.png)
![img](https://img-blog.csdnimg.cn/img_convert/8a88138653eb4846751650a12b0d8405.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**
51)]
[外链图片转存中...(img-7awS2c4z-1714266281552)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**
**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**