var a = 10;
function fn(){
var b = 10
function fun1(){
console.log(c);//undefined
b += 5;
var c = 20;//此处给c赋值
function fun2(){
var c = 99;
}
fun2();
console.log(c);//20
}
console.log(b);//10
fun1();
console.log(b);//15
}
fn();
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191223200054279.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L09yYW5nZV9TaGVlcA==,size_16,color_FFFFFF,t_70)
首先创建执行环境栈:ECS
向执行环境栈压入第一个默认函数main() 创建全局作用域对象window main() ---->引用 window GO
GO{
a:,
fn:
}
fn ---->引用function fn(){
var b = 10
function fun1(){
console.log©;//undefined
b += 5;
var c = 20;//此处给c赋值
function fun2(){
var c = 99;
}
fun2();
console.log©;//20
}
console.log(b);//10
fun1();
console.log(b);//15
}
当函数fn调用时 往ECS中压入一个新的元素fn() 生成一个自己的活动对象AO 以此类推
// [[scope]]中存储的是作用域的数组链式结构,且有访问的顺序,越在上的,越先访问
fn defined fn.[[scope]] 0 : GO {} 可访问变量a
fn doing fn.[[scope]] 0 : fnAO{} 可以用自己的变量b
1 : GO {}
fun1 defined fun1.[[scope]] 0 : fnAO{} 可以访问到b
1 : GO{}
fun1 doing fun1.[[scope]] 0 : fun1AO{}
1 : fnAO{}
2 : GO{}
fun2 defined fun2.[[scope]] 0 : fun1AO{}
1 : fnAO{}
2 : GO{}
fun2 doing fun2.[[scope]] 0 : fun2AO{}
1 : fun1AO{}
2 : fnAO{}
3 : GO{}
执行结束后,挨个出栈 后入的先出,生成的活动对象AO消失