一、何为变量声明提升?
通过var定义(声明)的变量,在定义语句之前就可以被访问到,并且它的值为undefined.
如下示例代码,在函数fn中,按照代码正常思维,输出语句之前的a并未定义,按理说应该会找到外部的全局变量a,或者是报错。而现实的结果却是 浏览器输出a为undefined。这其中的原因是,函数内部进行了变量的声明提升,也即在输出语句之前,严格来说是函数定义时,会将a提前声明,可以理解为输出语句前有一行代码 var a; 因此在输出语句执行时,是有a这个变量的,并且值为undefined。
<script>
var a = 5;
// 变量提升
function fn (){
console.log('a :>> ', a);
var a = 7;
}
fn()
</script>
二、何为函数声明提升?
通过function声明的函数,在其声明的地方之前就能够进行调用。
如下示例代码,函数 fn 在其声明之前就进行调用,在其他语言中,这可能会报编译错误。在JS中能够正常执行。这其中就涉及到了函数声明(定义)提升,在JS代码执行之前,函数会被提前定义,相当于function这一段代码块会被提前执行,因此,在当前作用域中已经存在fn这一函数对象,函数能够正常调用执行。
<script>
// 函数提升
fn();
function fn() {
console.log('fn');
}
</script>
三、函数声明提升与变量声明提升的优先级
代码的执行结果竟然出现了报错,按照正常思维,fn在后续是被定义为一个函数,正常调用时没问题的。但结果显然相反,竟然给出了报错 Uncaught TypeError: fn is not a function 。这其中便涉及到了函数与变量声明提升的优先级。
函数提升优先级比变量提升要高,被变量赋值覆盖。
<script>
var fn = 'abc'
function fn() {
console.log('test')
}
fn()
</script>
小结:
- 函数提升优先级比变量提升要高,会被变量赋值覆盖。
- 变量和函数的声明会被提前执行。
- 函数声明提升的优先级要高于变量声明提升。
- 在函数内部用 var 声明了相同名称的外部变量,函数不会向上寻找。(在函数内部中已找到该变量,不会再往外寻找,只是此时可能还未被赋值)