2020-11-03 var与函数的变量提升问题

本文解析了JavaScript的执行顺序,包括变量和函数的声明提升、函数表达式的提升、嵌套函数中的声明提升以及变量与函数同名时的提升规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章为学习之后的笔记,如有不正确的地方,欢迎大家指正,以作修改

JS执行顺序

  • 因为JS是单线程,所有代码都是从上往下执行,但是在代码执行之前,JS会将整个代码粗略的扫描一遍,低级的语法错误会报错
  • JS代码中所有通过 var 关键字声明的变量都会被提前拿出来进行定义,但是不赋值
  • 所有的字面量函数整体都会被提前声明
fun();
function fun(){
	console.log(a);//undefined
}
var a = 10;

在以上的代码中,首先 fun() 的调用写在函数声明之前,却可以调用,也就说明了函数声明确实是被提前了,打印出的 a 是 undefined ,因为 var 关键字也会声明提前,但是只定义,不赋值,相当于以下代码

function fun(){//声明提前
	console.log(a);
}
var a;//只有定义声明提前,未赋值就是 undefined
fun();
a = 10;

函数表达式的提升

fun();
var fun = function (){
	console.log(a);
}
var a = 10;

有没有很意外?结果不是 undefined ,而是报错。
上面讲到函数会声明提升,但是为什么这里调用函数会报错?因为这里用的不是字面量声明,而是表达式声明,除了函数提升,上面还讲了一个通过 var 关键字的声明提升,这里就属于 var 关键字的声明提升,只是提升变量定义,并没有赋值,所以 fun 还不是一个函数。

嵌套函数中的声明提升

函数嵌套会不会影响声明提升?代码测试:

var a = 10;
function fun1(){
	fun2();
	function fun2(){
		console.log(a);
		var a = 20;
	}
}
fun1();

打印的结果:undefined

  • a 能被打印,说明声明提升除了在全局作用域中生效,在函数作用域中同样生效。
  • 作用域链是从自身向外一层一层的找,所以在打印 a 的时候,fun2 先在自身找 a ,因为声明提升,a 是已经被定义了,只是未赋值,所以结果未 undefined

变量和函数同名时声明提升

这句话的意思是,有一个变量是 a ,有一个函数是 a ,那么打印 a 输出什么结果?

function a(){
}
var a;
console.log(a);//a(){};

大家肯定认为是打印函数,正好印证了上面说的函数的提升优先级大于变量,这里确实打印出了函数,那如果我将代码再修改一下。

function a(){
}
var a = 10;//**注意,这里修改了**
console.log(a);//10

打印的结果变成了 10 ,上下的代码区别很明显,上面个代码的 a 并没有赋值,所以打印的是函数,下面个赋值了,所以打印的是 10

  • 在JS代码中,如果函数变量同名,变量赋值了就优先提升变量
  • 如果变量未赋值,就优先提升函数
  • 注意:这里的结果不会受到变量与函数位置的影响,就算变量声明在函数的上面,只要赋值了就会得到变量的值,哪怕赋值为 undefined
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值