词法分析--一个函数的执行过程

本文详细介绍了JavaScript中函数的执行过程,包括词法分析阶段和执行阶段。在词法分析时,会创建活动对象(AO),处理函数参数、变量声明和函数声明。在执行过程中,AO用于存储变量和函数,形成作用域链,以便在不同作用域中查找变量。通过示例解释了变量提升的原理,并探讨了当变量在当前作用域找不到时,如何沿着作用域链向上搜索的过程。

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

前言

先出一个十分常见的题目, 如下:

var age = 99;
function t() {
    console.log(age)
    var age = 100
}
t()

很明显, 这个题目会打印出undefined。 那么为什么呢?

很多人都会说: 因为变量提升啊, 这个时候没有赋值啊, 所以是undefined。 说的对, 那么变量提升又是怎样产生的呢?

一个函数的执行过程

很多书上说javascript是解释性语言, 但是javascript其实在执行之前是有一个编译过程的——词法分析。

对于一个函数执行分为了两个部分:
1. 编译过程——词法分析
2. 执行过程

词法分析需要分析三个内容:
1. 分析函数参数
2. 分析变量声明
3. 分析函数声明

具体步骤:

  1. 函数运行前的一瞬间, 生成Active Object(活动对象), 一下简称AO
  2. 函数声明的参数, 形成AO的属性, 值为实参, 未传值为undefined
  3. 分析变量声明, 如var age,
    1. 如果AO上还没有age属性, 则添加AO属性吗值为undefined
    2. 如果AO上已经有age属性, 则不做任何影响
  4. 分析函数声明, 如function foo(){}, 则把函数赋值给AO.foo属性; 如果foo存在则无情覆盖掉

具体分析最开时的代码

var age = 99;
function t() {
    console.log(age)
    var age = 100
}
t()
  1. 在调用f函数时, 形成一个AO
  2. 没有参数, 不做参数分析, 此时AO没有属性
  3. 分析变量age,将age属性添加到AO上,此时age的值为undefined
  4. 分析函数声明, 此时没有函数声明, 跳过
  5. 经过分析最终形成了一个AO={age:undefined}
  6. 进入执行过程
  7. 执行console.log(age), 此时为undefined, 所以打印undefined
  8. 执行age = 100
  9. 此时AO={age:100}
  10. 结束

以上就是一个函数的玩笑执行过程。 也可以理解变量提升真正的原因。

作用域链

其实可以看到, 当我们在函数内部使用一个变量时, 需要在AO对象上查找这个变量属性。 那么如果没有这个变量属性呢?这时怎么办?

按以往的经验,应该不难理解函数会到外层函数的AO上查找, 如此递归直到window对象,所以由这些AO所形成的一条链, 叫做作用域链

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值