概要
在javascript中当使用var声明变量和function声明函数变量名发生冲突时,那个优先级会更高?
例如:下面代码输出什么?
变量提升与函数提升
当我们使用var关键字来声明一个变量并赋值时,这个变量的声明与赋值本质上是分开的。程序执行时首先会将var声明变量的代码提升到所在作用域顶部执行,而原来的位置只进行变量的赋值。例如如下代码:
本质上这行代码执行如下:
无论var变量声明在哪个位置,都会提升至所在作用域顶部。
在javascript中通过function声明的函数也会有函数提升(使用函数表达式或者箭头函数没有函数提升),将函数的定义提升至所在作用域的顶部。
这里要注意的是函数提升会将函数定义整体提升,而var变量提升只会提升声明,不会提升赋值。
而在javascript中函数声明的优先性会高于var变量提升。
这个代码首先会将声明一个a变量并提升,但由于函数提升优先级高于var,因此提升之后a变量本质是存储这个函数的。然后当代码执行到第一行时将a变量的赋值为1,此时a变量的函数被覆盖,最后打印输出的其实是1。实际执行顺序如下:
我们来看一道面试题:
请问如下代码输出什么?
这道题就是考察变量提升与作用域,首先由变量提升和函数提升优先级可知代码执行到第一行前a变量已经存储了函数,第一行将a赋值为1,后续打印a输出1。然后调用a时,由于a此时是number类型的值,故代码执行到这里时就会报错:TypeError: a is not a function。
小结
函数声明的优先级高于变量声明,即使变量声明在函数声明之前编写。所以,当尝试访问这个变量时,实际上访问的是同名的函数,而不是你预期的变量值。
这种行为可能会导致一些混淆和错误(一般只会出现在面试题中),因此通常建议避免在同一作用域内声明同名的变量和函数。如果你需要定义一个函数并稍后给它赋值,可以将函数声明放在变量声明之前,或者使用不同的命名。