作用域精解
[[scope]]:每个Javascript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供JavaScript引擎存取,[[scope]]就是其中一个。[[scope]]指的就是我们所说的作用域,其中存储了运行期上下文的集合。
作用域链:[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式连接,我们把这种链式链接叫做作用域链。
运行期上下文:当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行器上下文定义了一个函数执行时的环境。函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生得执行上下文被销毁。
查找变量:查找哪个函数的作用域链,就从哪个函数的作用域链的顶端依次向下查找。
function a () {
function b () {
function c() {
}
c();
}
b();
}
a();
a defined a.[[scope]] --> 0: GO
a doing a.[[scope]] -- > 0:aAO
1:GO
b defined b.[[scope]] --> 0: aAO
1:GO
b doing b.[[scope]] -- > 0:bAO
1:aAO
2:GO
c defined c.[[scope]] --> 0: bAO
1:aAO
2.GO
b doing c.[[scope]] -- > 0:cAO
1:bAO
2:aAO
3.GO
在此 ,所有的ao和bo~~~都是一个 只不过互相
借用了而已 另外 每次函数被执行完都会删除上下
文,如果函数又被执行就会产生新的执行上下文
b doing c.[[scope]] -- > 0:newcAO
1:bAO
2:aAO
3.GO
function a() {
function b(){
var bbb = 234;
console.log(aaa);
}
var aaa = 123;
return b;
}
var glob = 100;
var demo = a();
demo();
在此,b已经被返回出来了,a被销毁了,b还没有
执行呢,但是b已经拿到了a的执行期上下文(AO)。
- 闭包:当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄漏。
var obj = {}
function a (){
var aa = 123;
function b (){
console.log(aa);
}
obj.fun = b;
}
a(); 在这里b被保存出去了不一定非得return 在
obj里 a执行完被销毁了 但b还能访问a里面得 形
成了闭包