整理入坑学习记录
全局预处理
先扫描函数声明,再扫描变量声明:
- 函数:用声明的方式创建的函数;
- 变量:用 var 定义的变量;初始化为 undefined;
如果出现命名冲突 时:
- 函数声明:覆盖;
- 变量声明:忽略;
1 | f(); //fff |
f()函数是声明方式创建的函数,g()是函数表达式,全局预处理时词法环境中,只能是用声明的方式创建的函数。
因此,全局预处理时 g()从语义上看,应该是函数,但是由于 g()是函数表达式,不会在词法环境中,所以调用时会报错。
1 | console.log(a); // undefined |
同理,词法环境中只有用 var 定义的变量。
1 | alert(f); //function f(){alert('567');} |
命名冲突时,函数具有“优先权”,变量会直接被忽略,而函数会被覆盖。
全局执行过程
1 | alert(a); //undefined |
为了分析方便我们可以使用词法环境:
1 | LexicalEnvironment {} === window; |
全局预处理时:
1 | window { |
全局执行时:
1 | window { |
函数预处理阶段
- 每调用一次,产生一个词法环境(或执行上下文
Execution Context
); - 先传入函数的参数,若参数值为空,初始化
undefined
; - 然后是内部函数声明,若发生命名冲突,会覆盖;
- 接着就是内部
var
变量声明,若发生命名冲突,会忽略;
函数执行阶段
- 给预处理阶段的成员赋值;
- 无 var 声明的变量,会成为全局成员;
1 | function f(a, b) { |
VO(Variable Object)
——> 变量对象
函数中的激活对象:VO(functionContext)=== AO;
1 | AO(f) { |
例如:
1 | function test(a, b) { |
函数预处理时:
1 | AO(test) { |
函数执行时:
1 | AO(test) { |