变量提升与函数提升
一、变量提升
变量提升即将变量声明提升到它所在作用域的最开始的部分。
- 通过var定义(声明)的变量,在定义语句之前就可以访问到;
- 值:undefined;
-
console.log(a); //undefined var a = 1;
因为有变量提升的缘故,上面代码实际的执行顺序为:
-
var a; console.log(a); a = 1;
二、函数提升
js中创建函数有两种方式:函数声明式和函数表达式
1、函数声明提升function fun() { console.log('函数声明式'); }
js在执行之前,会把foo函数提升到最前面,所以我们在fun函数定义之前就可以使用fun函数。
举个栗子来说明下:fun(); function fun(){ console.log("aa"); }
打印结果为aa;说明以函数声明来定义函数时,可以在定义函数之前访问到定义的函数。
- 2、函数表达式提升
-
var fun = function() { console.log('函数表达式'); };
此种声明方式我们可以理解为一个普通变量的提升,在js代码执行之前会把fun提升带最前面,在函数赋值之前,fun是undefined,如果调用fun(),将会报错。
再举个栗子来理解下:
-
fun(); var fun = function (){ console.log("aa"); }
此时打印的结果为报错Uncaught TypeError: fun is not a function,因为在js代码执行之前,会把fun提升到最前面,值为undefined,不是一个函数,以函数的形式来进行调用时将会报错。
三、面试题
把上面这些基本知识理清楚后,在看几道面试题,检测是否真的学明白了。1、第一题
var a = 4 function fn () { console.log(a) var a = 5 } fn()
输出结果:
undefined
说明: 在上面这段代码中有两个作用域,window
全局作用域和fn
函数作用域,在打印变量a
时,会先在fn
函数作用域里面查找,因为在执行fn
函数时,在函数内部也会先进行变量提升,所以最终的打印结果为undefined
。
代码实际的执行顺序为: -
var a = 4 function fn () { var a; console.log(a); //undefined a = 5 } fn()
2、第二题
-
function a() {} var a; console.log(typeof a)
输出结果:
function
-
function a() {} var a = 1; console.log(typeof a)
输出结果:
number
说明:函数提升优先级高于变量提升,且不会被同名变量声明时覆盖,但是会被同名变量赋值后覆盖。 - 3、第三题
-
console.log(typeof a) function a() {} var a = 1;
输出结果:
function
说明: 函数提升的优先级高于变量提升。4、第四题
大家可以看下这个例子最后的输出结果,检测下自己理解的如何。至于打印输出的结果我就不透露了,大家可以在控制台打印输出下,看看是否和自己预想的一样。 -
console.log(v1); var v1 = 100; function foo() { console.log(v1); var v1 = 200; console.log(v1); } foo(); console.log(v1);