深入理解词法作用域和动态作用域

1.引子

无意间在掘金上看到了一篇关于如何使用vue造轮子的框架, 里边有9到考察js和vue基础的题, 自己错了4道, 其中一道和箭头函数的this有关, 回头查了一下, 发现箭头函数的this总是指向词法作用域的, 遂写篇文章记录一下.

2.js作用域查找原理

js运行主要分为五部分: 1.编译 2.执行 3.查询 4.嵌套 5.异常

  • 编译: 1.分词 - 词法单元 - 词法单元流数组 2.解析 - 抽象语法树(AST) 3.生成代码 - 生成机器指令
  • 执行: 引擎寻找变量的过程 - 优先在当前作用域查找
  • 查询: 分为LHS查询(查询变量, 赋值的左边)和RHS查询(查询赋值, 赋值的右边)
  • 嵌套: 当前作用域查找不到, 则回去外层作用域查找, 直到全局作用域 -> 返回not define
  • 异常: 如果LHS找不到, 就会返回not define

3.什么是词法

js的内部编译过程总共分3步

  • 1.分词: 将字符组成的字符串, 分解成有意义的代码块, 这些代码块就叫 - 词法单元
// 词法分析后的结果
[
  "var" : "keyword",
  "a" : "identifier",
  "="   : "assignment",
  "2"  : "integer",
  ";"   : "eos" (end of statement)
]
复制代码

总结来说: 词法作用域就是块作用域

4.动态作用域

词法作用域实在书写代码时候就确定的, 而动态作用域不关心函数是在何处声明的, 只关心函数是在哪里调用的. 举例:

let a = 10
function func1() {
    console.log(a)
}
function func2() {
    let a = 5
    func1()
}
复制代码

上例中: 如果按词法作用域, 从func1里查找a, 没找到后, 去嵌套层查找, 找到最外层的a = 10 上例中: 动态作用域, 首先会在func1里查找a, 没找到后, 会顺着调用栈在func2中查找, 找到a = 5 *词法作用域是在赋值阶段确定, 动态作用域是在调用阶段确定

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值