1 全局
1.1 预处理:创建一个词法环境(LexicalEnvironment,LE),扫描JS中的用声明的方式声明的函数,用var定义的变量并将它们加到预处理阶段的词法环境中去
全局预处理中这个LexicalEnvironment==window对象
注意:预处理的函数必须是JS中用声明的方式声明的函数(不是函数表达式)eg: function d(){...} 而不是var e=function(){...} 这是一个函数表达式 ;但是这个方式会把e当作一个变量放入LE中。
也就是 全局预处理中的对象的声明可以写在使用的后面。
命名冲突处理:
(1)处理函数声明有冲突时,会覆盖;
(2)处理变量声明有冲突时,会忽略;
(3)在既有函数声明又有变量声明的时候,最终结果往往是指向函数声明的引用。
1.2 代码的执行阶段:
(1)代码会从上往下执行
(2)遇到存在于词法环境中的变量时进行赋值 eg:下例子中的g变为function
(3)遇到不存在词法环境中的变量时,js将一次性执行声明,即让变量成为词法作用域的成员并进行赋值操作。一步到位;eg:下例子中会把b:5加入LE
2 函数
2.1 预处理
函数每调用一次,都会产生一个词法环境对象LE,全局预处理中这个环境对象指的就是window对象,在函数预处理中,该对象不可见,无法访问,是解析器的东西。
函数的LE多了一个参数arguments 记录调用函数时,实际传入的参数个数。
全局作用域和函数作用域内变量、函数分别进行提升。
冲突处理:
(1)传入参数与内部函数名冲突时,函数是一等功名;
(2)而传入参数和内部自定义参数冲突时,使用的仍是调用时传入的参数值。
2.2 执行阶段
(1)给预处理阶段的成员赋值
(2)如果没有用var声明的变量,会成为最外部LE,即window的成员