AO GO
AO和 GO,说白了就是局部变量对象和全局变量对象。
-
AO(Activation Object ):其包含了函数执行期的上下文内容。
-
GO(Clobal Object)):其包含全局执行的上下文内容。
AO是一个即时的存储容器,函数执行完毕以后,AO是要销毁的。(但是有一种情况例外,那就是闭包)
这个具体过程,需要根据js文件进行逐步讲解
var a=1;
function test(){
var b=2;
}
#执行了下面这句才会有AO
test()
如果不执行test()方法,那么只有一个GO:
GO {
a : 1
test : [fucntion] # 这个地方只有方法的方法体,但是没有AO
}
#这个时候又会形成一个作用域链
socpe 作用域链
0: GO
AO是什么时候才会生成的呢?只有再调用方法的时候,那个时候才会形参AO;
执行test()的时候。
#执行了test()
AO {
scope域存: GO // 在其顶部会存在这个 GO 的信息,满足寻找全局中的变量,如果自家也有相同变量名会用自己的。
b : 2
}
#这个时候又会形参一个作用域链
socpe 作用域链
0: AO // 所以才会优先用自己的变量
1: GO
执行完毕test()方法后,AO就会销毁。
闭包
闭包就是能够读取其他函数内部变量的函数。在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成定义在一个函数内部的函数。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
听起来是不是很晕,还是老规矩用代码演示。
var a=1;
function test(){
var b=2;
function test1(){
console.log("在test1调用b=",b)
}
//#执行了下面这句才会test1有AO
return test1;
}
//执行了下面这句才会有AO
var c=test();
// 调用c方法会发现
console.log(c());
前面说过AO和 GO的时候说AO明明已经执行完毕,不是应该销毁吗?为什么再最后又可以得到呢?
这个需要分两部分看,第一部将test方法中的执行 return的时候,暂时不不返回,指运行到test1这个方面名,会变成下面:
如果执行return的时候,会如何呢?
因为test这个函数已经执行完毕,所以test1的scope域就不存在,但是其返回给了c,所以说其函数的体还被其他地方使用,所以其test1的scope域销毁,但是其地址内容暂时保留。同样的道理,test的AO的地址内容暂时保留。
说白就是将函数内部的函数通过return到全局或者是外部函数之外的地方都会形成闭包。
- 好处:返回到外部,然后其所在的变量不会被修改。
- 坏处:过多的闭包会造成内存泄漏,或加载过慢。
- 场景:其很多时候和立即函数一起用将一些不能被污染的逻辑通过闭包实现。
立即执行函数下一篇聊。