[[scope]]
- 函数创建时,生成的一个JS内部的隐式属性
- 函数存储作用域链的容器,作用域链
AO / GO
AO 函数的执行期上下文
GO 全局的执行期上下文
函数执行完成以后,AO是要销毁的
AO是一个即时的存储容器
function a () {
function b () {
var b = 2;
}
var a = 1;
b();
}
var c = 3;
a();
总结:
当函数被定义时,生成作用域,作用域链,当函数被执行那一刻,生成AO
- 当a函数被定义时,系统生成[[scope]]属性,[[scope]]保存该函数的作用域链,该作用域链的第0位存储当前环境下的全局执行上下文GO,GO里存储全局下的所有对象,其中包含函数a和全局变量c
2.当a函数被执行时(前一刻),作用域链的顶端(第0位)存储a函数生成的函数执行期上下文AO,同时第1位存储GO,查找变量是到a函数存储的作用域链中从顶端开始依次向下查找- 当b函数被定义时,是在a函数环境下,所以b函数这时的作用域链就是a函数被执行期的作用域链
- 当b函数被执行时(前一刻),生成函数b的[[scope]],存储函数b的作用域链,顶端第0位存储b函数的AO,a函数的AO和全局的GO依次向下排列
- 当b函数被执行结束后,b函数的AO被销毁,回归被定义时的状态
- 当a函数被执行结束时,a函数的AO被销毁的同时,b函数的[[scope]]也将不存在,a函数回归到被定义时的状态
// 例子
function a () {
function b () {
function c () {
}
c();
}
b();
}
a();
// 以上代码执行全过程
/*
a定义 a.[[scope]] -> 0 : GO
a执行 a.[[scope]] -> 0 : a -> AO
1 : GO
b定义 b.[[scope]] -> 0 : a -> AO
1 : GO
b执行 b.[[scope]] -> 0 : b -> AO
1 : a -> AO
2 : GO
c定义 c.[[scope]] -> 0 : c -> AO
1 : b -> AO
2 : a -> AO
3 : GO
c结束 c.[[scope]] -> 1 : b -> AO
2 : a -> AO
3 : GO
b结束 b.[[scope]] -> 0 : a -> AO
1 : GO
c.[[scope]] 销毁
c结束 c.[[scope]] -> 0 : GO
b.[[scope]] 销毁
*/
AO查找规则:
第一步:寻找形参和变量声明
第二步:实参值赋值给形参
第三步:找函数声明,赋值
第四步:执行
// 例子
function test (a) {
console.log(a);
var a = 1;
console.log(a);
function a () {}
console.log(a);
var b = function () {}
console.log(b);
function d () {}
}
test(2);
/*
AO 活跃对象 函数上下文
AO = {
a: undefined -> 2 -> function () {} -> 1
b: undefined -> function () {}
d: function d () {}
}
*/
GO查找规则:
第一步:找变量
第二步:找函数声明
第三步:执行
// 例子
var a = 1;
function a () {
console.log(2);
}
console.log(a);
/*
GO = {
a: undefined -> function a () {} -> 1
}
*/