返回

JS 预编译:解密 JS 编译的奥秘

前端

JS 预编译的时机

JS 预编译分为全局预编译和函数预编译两个阶段,它们发生在不同的时间点:

  • 全局预编译:

    • 全局预编译发生在页面加载完成时执行。
    • 此时,JavaScript 引擎会解析整个脚本文件,将所有的函数声明提升到脚本文件的最顶部,变量声明提升到当前作用域的顶部。
    • 这使得函数和变量可以在声明之前被引用,从而避免了变量提升导致的错误。
  • 函数预编译:

    • 函数预编译发生在函数执行的前一刻。
    • 此时,JavaScript 引擎会分析函数体,将函数体内的变量声明提升到函数体的顶部。
    • 这使得函数体内的变量可以在函数执行之前被引用,从而避免了变量提升导致的错误。

全局预编译的详细解析

全局预编译是一个非常重要的过程,它可以避免变量提升导致的错误。

变量提升

变量提升是指 JavaScript 在执行代码之前,会将所有的变量声明提升到当前作用域的顶部。

console.log(a); // undefined
var a = 10;

在上面的代码中,变量 a 在声明之前就被使用了,这会导致 console.log(a) 输出 undefined

为了避免这种情况,JavaScript 引擎会在执行代码之前,将所有的变量声明提升到当前作用域的顶部。

var a; // undefined
console.log(a); // undefined
a = 10;

在上面的代码中,变量 a 在声明之前就被使用了,但是由于全局预编译,变量 a 已经被提升到了当前作用域的顶部,因此 console.log(a) 输出 undefined

函数提升

函数提升是指 JavaScript 在执行代码之前,会将所有的函数声明提升到脚本文件的最顶部。

function foo() {
  console.log('foo');
}

foo(); // foo

在上面的代码中,函数 foo 在调用之前被声明,这会导致 foo() 输出 foo

为了避免这种情况,JavaScript 引擎会在执行代码之前,将所有的函数声明提升到脚本文件的最顶部。

function foo() {
  console.log('foo');
}

// foo 已经被提升到最顶部
foo(); // foo

在上面的代码中,函数 foo 在调用之前被声明,但是由于全局预编译,函数 foo 已经被提升到了脚本文件的最顶部,因此 foo() 输出 foo

函数预编译的详细解析

函数预编译是一个相对简单的过程,它可以避免变量提升导致的错误。

变量提升

函数预编译也会将函数体内的变量声明提升到函数体的顶部。

function foo() {
  console.log(a); // undefined
  var a = 10;
}

foo(); // undefined

在上面的代码中,变量 a 在声明之前就被使用了,这会导致 console.log(a) 输出 undefined

为了避免这种情况,JavaScript 引擎会在执行函数之前,将函数体内的变量声明提升到函数体的顶部。

function foo() {
  var a; // undefined
  console.log(a); // undefined
  a = 10;
}

foo(); // undefined

在上面的代码中,变量 a 在声明之前就被使用了,但是由于函数预编译,变量 a 已经被提升到了函数体的顶部,因此 console.log(a) 输出 undefined

总结

JS 预编译是一个非常重要的过程,它可以避免变量提升导致的错误。全局预编译发生在页面加载完成时执行,而函数预编译发生在函数执行的前一刻。全局预编译会将所有的函数声明提升到脚本文件的最顶部,变量声明提升到当前作用域的顶部。函数预编译会将函数体内的变量声明提升到函数体的顶部。