听小野森森的作用域链,播种颇丰。
函数在申明的时候会创立一个js外部的隐式属性,[[scope]],保留以后的作用域链,默认第一位是GO。
函数在执行的时候会创立本人的AO,保留在作用域链的第一位,之前保留的作用域往后排。
函数执行结束后,会销毁本人AO,如果这个AO还保留在别的函数的作用域中,则不会被销毁。
函数再次执行,会从新创立AO。
function a() { function b() { var b = 2; } var a = 1; b();}var c = 3;a();
当程序执行时,a函数被定义,零碎为起生成[[scope]]属性,[[scope]]保留该函数的作用域链,该作用域链的第0位保留以后环境下的全局上下文GO,GO里存储全局下的所有对象,其中蕴含函数 a 和全局变量 c 。
- 函数执行的前一刻
b函数被定义
b函数被执行
b函数执行完结时
a函数执行完结时
练习
function a() { function b() { function c() { } c(); } b();}a();// a定义 a.[[scope]] -> 0 : G0// a执行 a.[[scope]] -> 0 : a-A0 1 : G0// b定义 b.[[scope]] -> 0: a-A0 1: G0// b执行 b.[[scope]] -> 0: b-A0 1: a-A0 2:G0// c定义 c.[[scope]] -> 0: b-A0 1: a-A0 2:G0// c执行 c.[[scope]] -> 0: c-A0 1: b-A0 2: a-A0 3:GO// c执行完 c.[[scope]] -> 0: b-AO 1: a-AO 2:GO// b执行完 b.[[scope]] -> 0: a-A0 1:G0// c.[[scope]] X// a执行完 a.[[scope]] -> 0:G0// b.[[scope]] X
闭包
function test1() { function test2() { var b = 2; console.log(a); } var a = 1; return test2;}var c = 3;var test3 = test1();test();