概述
- 简单来说,JS 执行分为预编译和执行两个阶段。
- 预编译
- 预编译阶段,可以理解为浏览器引擎读取并分析 JS 代码,而在这个过程中,遇到var 关键字 声明的变量和函数声明,就会触发变量提升和函数提升。
- 会将变量或函数,提升到当前所在全局作用域或函数作用域的顶部
变量提升
-
只提升变量的声明部分,变量的初始化部分不会被提升
//原JS代码 console.log(a); var a=1; //经过预编译之后,实际执行时的代码如下 var a;//变量声明 console.log(a)//undefined a=1;//变量初始化
函数提升
-
函数声明,会触发函数提升;但是,函数表达式不会触发函数提升
//函数声明 function a(){} //函数表达式 var a=function(){} -
函数提升
- 函数提升,会将函数声明部分和函数初始化部分一起提升
-
例
//原JS代码 a(); function a(){ console.log(1); } //经过预编译后,实际执行时的JS代码 function a(){ console.log(1); } a()
变量提升与函数提升的优先级
-
先触发变量提升,再触发函数提升
//原JS代码 console.log(a); a(); var a = 1; function a(){ console.log('666') } a(); //经过预编译,实际执行时的JS代码 var a ;//先触发 变量提升 function a() { console.log('666') } //然后是 函数提升 console.log(a) //输出:ƒ a() { console.log("666"); } //执行完 上面三行代码,a此时是个函数 a = 1; //执行完这行代码,a被重新赋值为了1 a() //输出: Uncaught TypeError: a is not a function
补充说明
- 以上整理内容不涉及 ES6 的块级作用域,因为还没学~
- 只为方便理解、学习,欢迎大佬纠错、指点迷津~