写出下列代码的输出结果:
let a=0,
b=0;
function A(a){
A=function(b){
alert(a+b++);
};
alert(a++);
}
A(1);
A(2);
此题的图解:
函数执行会形成上下文,如果当前这个上下文中的内容(一般是堆内存)被之外的变量占有,那么当前这个执行上下文不被释放。
- 全局的执行上下文EC(G)中有一个存储全局变量的对象VO(G):创建值0,创建变量名a,两者关联;创建值0,创建变量名b,两者关联;创建函数堆内存0X001[此函数堆的作用域:EC(G)/形参:a],创建函数名A,两者关联。
- 【A(1);】函数A第一次执行,形成一个私有的执行上下文EC(A1),代码执行过程中创建一个内部堆函数0X002,将此函数堆复制给变量A,变量A不是当前这个执行上下文中AO(A1)中的私有变量,顺着作用域链向上找,A是全局作用域中的全局变量VO(G)的。
- 变量名A与函数堆0X002关联,函数堆0X001不再与函数名A关联,所以会出栈释放
- 因为全局变量A与私有的执行上下文EC(A1)中的函数堆0X002关联,这个执行上下文一个堆内存被外界占用,所以当前这个私有的执行上下文EC(A1)不被释放出栈,将自己上下文中的私有变量【比如函数堆0X002和形参a】保护和保存起来,形成闭包。
- 【A(2)】第一次执行函数A,在执行过程中把函数A重构了,第二次执行的时候是重构后的函数即函数堆0X002这个函数执行。此函数执行过程中遇到变量a、b,变量a不是自已私有的,AO(A2)中只有b,顺着作用域链向上查找,找到EC(A1)这个执行上下文的AO(A1)中有。执行完成后当前这个执行上下文EC(A2)会出栈释放掉。