JavaScript新手必看系列之预编译
前言
预编译是JavaScript的核心概念,也是新手向中级进阶的必经之路。理解它,意味着你能:
- 彻底搞懂变量提升
- 理解函数声明的“特权”
- 避免常见的作用域陷阱
本文用最简单的语言和示例,带你快速掌握全局预编译与函数预编译的完整过程。
What's that?
简单说,JS在执行代码前会进行“准备工作” —— 预编译。在这个阶段JS的V8引擎会进行变量声明,函数声明的提升
预编译的两种场景
1. 全局作用域下的预编译
分三步:
1.创建 GO(Global Object)
-
在浏览器中就是 window 对象
-
在 Node.js 中就是 global 对象
2.找到变量声明,作为作为GO属性名,值为undefined
-
找到函数声明,作为GO属性名,值为函数体
举个简单的例子:
console.log(a) // undefined
var a = 1
console.log(a) // 1
发什么了什么?
- 创建 GO ={}
- 找到变量声明 var a ,GO = { a : undefined }
- 找函数声明,没有函数声明就不找
执行过程如下:
//预编译后就相当于:
var a = undefined
console.log(a) //输出 undefined
a = 1
console.log(a) //输出 1
2.函数作用域下的预编译
函数较为复杂,四步:
-
创建AO(Activation Object)
-
找形参和变量声明,作为AO属性名,值为 undefined
-
将实参赋给形参
-
找函数声明,作为AO 属性名,值为函数体
举例:
function fn(a) {
console.log(a);
var a = 123
console.log(a);
function a() {}
var b = function() {}
console.log(b);
function c() {}
var c = a
console.log(c);
}
fn(1)
干了什么?
- 创建AO = {
2.找形参和变量声明,作为AO属性名,值为 undefined
AO = { a : undefined
b : undefined
c : undefined }
3.将实参赋给形参
AO = { a : 1
b : undefined
c : undefined
}
4.找函数声明,作为AO 属性名,值为函数体
AO = { a : function a() {}
b : undefined
c : function c() {}
}
函数体内执行过程:
// 预编译后的状态:
var c
var b
var a
console.log(a); // function a() {}
a = 123
console.log(a); // 123
b = function() {}
console.log(b); //function b() {}
c = a
console.log(c); //123
掌握了预编译,你就真正理解了 JavaScript 的执行机制,这对后续学习闭包、作用域链等概念至关重要!
希望这篇文章能帮助你彻底理解 JavaScript 预编译,如果有任何疑问,欢迎在评论区讨论!