每个函数被声明时候,就会携带着作用域。
默认声明状态下,其域中有一个全局对象(Global Object),简称go。因为此函数是包含在window中的,包括在内。当函数被执行时,就会产生自己本身的执行上下文(Activation Object),简称ao。
如果函数中再放入一层函数,那么新的函数在被声明时依然产生一个作用域,不过里面继承了外层函数的劳动成果,即刚被声明时,里面就有了全局对象ao,和外层函数本身的ao。如果此函数被执行,也会形成一个自己的ao,并放在作用域链顶端。这是作用域的规则,每增加一个新的执行上下文,都会放入顶端,所以按照此逻辑关系,里层函数可以读取外层。当一个函数执行完后,自身的执行上下文即被销毁,不会重复使用,如果还需执行,即会创建一个新的执行上下文。
列举函数举例:
function a() {
function b() {
var testA = 1;
console.log(testB);
}
var testB = 2;
return b;
}
var testC = a();
testC();
执行打印结果为2;
分析过程:函数“b”仅仅在函数“a”中被声明,并未有执行事件,所以函数“b”仅携带着全局对象go与函数“a”的ao,在程序执行完函数“a”之前,因为“return”语句,返回了“b”,所以函数“b”携带着声明时候的作用域被安全送出。此过程称为“闭包”。
函数“b”携带的作用域在外界被执行语句执行,因为“变量testB”并未在其内部声明,但是由于作用域中作用域链关系,它携带了外界函数“a”的ao,所以可以访问外部“testB的赋值”,所以打印结果为“2”。