JavaScript的预编译过程

本文深入探讨了JavaScript的预编译过程,包括语法分析、预编译和解析执行三个阶段。通过具体示例展示了如何创建激活对象(AO),并解释了参数、变量声明及函数声明在预编译阶段的行为差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文地址:https://finget.github.io/2018/03/01/javascriptPrecompile/


JavaScript在运行时,要经历三步
1. 语法分析 2.预编译 3.解析执行(自上而下)

JavaScript预编译

先思考这么一个题

function fn (a) {
  console.log(a);

  var a = 123;

  console.log(a);

  function a(){};

  console.log(a);

  var b =function (){};

  console.log(b);
}
fn(1);

预编译四部曲

  1. 创建AO对象 Activation Object(执行期上下文)
  2. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
  3. 将实参值和形参统一
  4. 在函数体里面找函数声明,值赋予函数体

这四步的权重比4>3>2>1,也就是一个覆盖的过程.
函数声明在变量声明的前面

函数声明才存在变量提升。即function a(){};,而var b =function (){};不会提升。

详细分析

先看一个面试中常遇到的问题
console.log(a); // function a(){}
var a = 1;
function a(){};

逐行执行,在AO中是:

AO{
  a: undefied
}
AO{
  a: function(){}
}
换一换
var a = 1;
console.log(a); // 1
function a(){};

逐行执行,在AO中是:

AO{
  a: undefied
}

AO{
  a: function(){}
}

// js是自上而下执行的,先执行var a = 1; 所有AO中的a就被覆盖
AO{
  a: 1
}
按步骤分析文章开头的例子
  • 第一步
AO{
}
  • 第二步
AO{
  a: undefined,
  b: undefined
}
  • 第三步
AO{
  a: 1,
  b: undefined
}
  • 第四步
AO{
  a: function a(){},
  b: undefined
}

解释执行

执行的时候:

AO{
  a: function a(){},
  b: undefined
}
// a = 123;
AO{
  a: 123,
  b: undefined
}

结果:

function fn (a) {
  console.log(a); // function(){}

  var a = 123;

  console.log(a); // 123

  function a(){};

  console.log(a); // 123

  var b =function (){};

  console.log(b); // function(){}
}
fn(1);

加入window,全局环境

global = 100;
function fn() {
  console.log(global);
  global = 200;
  console.log(global);
  var global = 300;
}
fn();
var global;

在全局环境中会生成一个 GO对象 (Global Object),还是按照上面的四步执行。

GO {
  global: undefined  
}

// 执行到 global = 100 :

GO {
  global: 100  
}

当执行fn之前会先生成一个AO:

AO {
  global: undefined  
}

所以第一次打印globalundefined

这个时候虽然全局变量中的global已经是100,但是fn函数中自己有global变量,所以不会引用全局中的。

当执行到global = 200 :

AO {
  global: 200  
}

所以第二次打印global200

最后思考一个问题

function fn(){
  var a = b = 100;
  console.log(window.a);
  console.log(window.b);
}

var a = b =100;
先将100赋值给b,即b=100,此时b没有声明就被赋值,在JavaScript中如果一个变量未声明就直接赋值,那么这个变量就是个全局变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值