作用域精解
[[scope]]:每个 javascript 函数都是一个对象,对象中有些属性我们可以访问,但有些
不可以,这些属性仅供 javascript 引擎存取,[[scope]]就是其中一个。[[scope]]指的就
是我们所说的作用域,其中存储了运行期上下文的集合。
作用域链:[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我
们把这种链式链接叫做作用域链。
运行期上下文:当函数在执行的前一刻,会创建一个称为执行期上下文的内部对象。
一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下
文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执
行完毕,执行上下文被销毁。
查找变量:在哪个函数里面查找变量,就从哪个函数作用域链的顶端依次向下查找。
函数类对象,我们能访问 test.name
test.[[scope]]隐式属性——作用域
例 function test (){
}
第一次执行 test(); → AO{} //AO 是用完就不要的
第二次执行 test(); → AO{} //这是另外的 AO
例 function a (){
function b (){
var bb = 234;
aa = 0;
}
var aa = 123;
b();
console.log(aa)
}
var glob = 100;
a();
0 是最顶端,1 是次顶端,查找顺序是从最顶端往下查
理解过程
a 被定义 a.[[scope]] → 0 : GO{}
a 被执行 a.[[scope]] → 0 : aAO{}
1 : GO{}
b 被定义 b.[[scope]] → 0 : aAO{}
1 : GO{}
b 被执行 b.[[scope]] → 0 : bAO{}
1 : aAO{}
2 : GO{}
c 被定义 c.[[scope]] → 0 : bAO{}
1 : aAO{}
2 : GO{}
c 被执行 c.[[scope]] → 0 : cAO{}
1 : bAO{}
2 : aAO{}
3 : GO{}
当 c 执行完后,会干掉自己的 cAO,回到 c 被定义的状态,当 c 再被执行时,会生
成一个新的 newcAO{},其余都一样,因为基础都是 c 的被定义状态
c 被执行 c.[[scope]] → 0 : newcAO{}
1 : bAO{}
2 : aAO{}
3 : GO{}
如果 function a 不被执行,下面的 function b 和 function c 都是看不到的(也不会被执
行,被折叠)。只有 function a 被执行,才能执行 function a 里面的内容
a();不执行,根本看不到 function a (){}里面的内容