JavaScript预编译的基本概念和过程

1,029 阅读2分钟

预编译

JavaScript在执行代码前,会进行一个预编译的过程,这个过程主要用于处理变量和函数声明。预编译分为全局预编译和函数预编译。

全局预编译

  1. 创建全局对象(Global Object, GO)
    • 在浏览器中,全局对象是window对象。
  2. 处理变量声明
    • 找到所有的变量声明,将变量名作为全局对象的属性名,初始值为undefined
  3. 处理函数声明
    • 找到所有的函数声明,将函数名作为全局对象的属性名,值为函数对象(整个函数体)。

示例:

console.log(a); // undefined
var a = 10;
console.log(foo); // Function: foo
function foo() {
    return "hello";
}

全局预编译后的全局对象:

1.创建GO对象
GO{
    // 空对象
}

2.处理变量声明
GO = {
    a: undefined
}

3.处理函数声明
GO = {
    a: undefined,
    fn: function() {}
}

函数预编译

  1. 创建活动对象(Activation Object, AO)
    • 每次调用函数时,都会创建一个新的活动对象。
  2. 处理形参和变量声明
    • 将形参和变量名作为活动对象的属性名,初始值为undefined
  3. 形参和实参统一
    • 将实参值赋值给对应的形参。
  4. 处理函数声明
    • 找到所有的函数声明,将函数名作为活动对象的属性名,值为函数对象。

示例:

function bar(x, y) {
    console.log(x); // Function: x
    var x = 20;
    console.log(x); // 20
    function x() {}
    console.log(x); // 20
    var y = function() {};
    console.log(y); // Function: y
}
bar(2);

函数预编译后的活动对象:

1.创建AO对象
AO{
    //空对象
}

2.处理形参和变量声明,值为undefined
AO = {
    x: undefined,
    y: undefined,
}

3.实参和形参统一
AO = {
    x: 2,
    y: undefined
}

4.处理函数声明
AO = {
    x: 2,
    y: function() {},
    x: function() {}
}

总结

通过预编译,JavaScript确保在代码执行时,所有变量和函数都已经声明完毕,避免引用错误。这一机制是理解JavaScript作用域和提升(hoisting)的基础。