在ES5中使用lexical environment来管理静态作用域,而不再是ES3中的AO/VO
词法环境就是描述环境的对象,主要包含两个部分:
- 环境记录(Environment Record)
记录相应环境中的形参,函数声明,变量声明等
- 对外部环境的引用(out reference)
代码示例 :
var x = 10;
function foo(y){
var z = 30;
function bar(q){
return x + y + z + q;
}
return bar;
}
var bar = foo(20);
bar(40);
环境初始化 : 在执行函数/全局代码之前进行环境初始化
**设置outer reference**
先确定当前环境的外部引用(函数环境与该函数的scope属性有关)
**环境记录初始化:就是我们常遇到的声明提前**
在执行全局代码或者函数代码之前,先扫描相应环境中的形参,函数声明,变量声明并将其记录在环境记录中(Environment Record)
全局代码执行前,先初始化全局环境
函数代码执行前,先初始化函数环境
图解上述代码中foo()函数的环境记录初始化 :
var bar = foo(20);
//foo()函数在执行之前会进行foo环境的环境初始化
//先设置foo环境的外部引用(通过foo()函数的scope属性)
//将形参y:20,z:undefined记录在环境记录中
//在初始化环境记录遇到函数声明时会创建一个内部函数对象,这个函数对象有一个scope属性指向函数声明所在的环境,如在该代码示例中,扫描到bar()函数声明时会在foo environment中创建一个内部函数对象,其scope属性指向bar()函数声明所在的foo environment,重要的一点是:当开始执行bar()函数前初始化bar()函数的环境时,就把bar()函数的scope属性指向的foo environment 赋值给bar环境的out reference作为其外部引用.
如图所以:
环境初始化完成之后,就开始执行环境中的代码