这个系列是我读冴羽老师博客的感悟,
加入了个人的解读和练习题的解答
上篇说到,当javascript代码执行一段可执行代码(executable code)时,会创建对应的执行上下文(execution context)
那对于每个执行上下文,都有三个重要属性:
- 变量对象(Variable object, VO)
- 作用域链(Scope chain)
- this
本文主要讲执行上下文中的作用域链,注意本章将会把之前的内容穿起来很重要
在之前第2篇作用域和第4篇变量对象中有提到,
当查到变量时首先从当前上下文的变量对象中查到,
如果没有找到会从父级(词法静态层面上的)执行上下文的变量对象中查找,
一直找到全局变量对象(全局对象)
这样由多个执行上下文的变量对象构成的链表就叫做作用域链
函数创建
在第2篇中提到js中函数的作用域在函数定义的时候就决定了
这是因为函数有一个内部属性`[[scope]]``, 当函数创建的时候会把函数的父变量对象保存到其中,但不是完整的作用链
如:
|
|
此时函数的各自作用域为:
|
|
函数激活
当函数激活的时候,进入函数上下文,创建VO/AO后,就会将函数活动对象加到作用域的最前端,
|
|
此时作用域链创建完毕
总结事例
例子:
|
|
函数执行上下文中作用域和变量对象创建过程如下:
1.checkscope函数被创建,保存作用域到内部属性[[scope]]
|
|
2.执行checkscope函数,创建checkscope函数执行上下文,checkscope函数执行上下文压入执行上下栈
|
|
3.checkscope函数进入准备阶段
3.1 复制函数内部属性[[scope]]
到函数执行上文中
|
|
3.2 用函数的arguments属性创建活动对象,随后初始化活动对象,加入形参、函数声明、变量声明
|
|
3.3 将活动对象压入作用域顶端
|
|
准备工作完毕
4.开始执行checkscope函数,随着函数执行,修改AO的属性值
|
|
5.查找到scope2的值,返回后函数执行完毕,checkscope函数上下文从执行上下文中弹出
|
|