作用域,作用域链
function test () {
}
1.作用域
test.[[scope]] ==> 这里面就存储着函数的作用域 //隐式属性,我们不能直接用,仅能让js引擎存取
[[scope]] : 每个js函数都是一个对象,对象中有些属性我们可以访问(函数名,test.name),但有些不可以([[scope]]),这些属性仅供js引擎存取,[[scope]]就是其中一个
[[scope]] 指的就是我们所说的作用域,其中存储了运行期上下文的集合
2.执行期上下文
(那什么又是运行期上下文呢? 其实就是 GO AO)
执行期上下文的官方定义:当函数执行时,会创建一个称为执行期上下文的内部对象,一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生的执行上下文被销毁
查找变量:在哪个函数里面,就从哪个函数里面从作用域链的顶端依次向下查找
作用域链:[[scope]] 中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链
例子:
function a() {
function b() {
}
b();
}
var glob = 100;
a();
//a defined a.[[scope]] --> 0 : GO {}
//a doing a.[[scope]] --> 0 : AO {}
// 1 : GO {}
//b defined b.[[scope]] -- > 0 : AO {}
// 1 : GO {}
//b doing b.[[scope]] -- > 0 : bAO{}
// 1 : AO {}
// 2 : GO {}
例子:
function a( ) {
var num = 100;
function b( ) {
num ++;
console.log(num);
}
return b;//把b的值保存到函数外边去了
}
var demo = a();
demo();
demo();
// a defined a.[[scope]] 0 : GO
// a doing a.[[scope]] 0 : AO
// 1 : GO
// b defined b.[[scope]] 0 : AO
// 1 : GO
解释:在以上这个例子里,由于没有运行b函数,所以没有生成b的AO,所以b函数定义时还是拿的a函数的成果,
当函数运行完一遍后,就会砍断AO,所以这里这是a函数把自己的AO砍断了,但是由于b函数的已经保存出去了,所以b函数仍然续用着a函数的 作用链,也就是 AO GO
再理解一下,每个函数执行(不执行是没办法访问函数里面的东西),都会产生作用域链
要访问,就在具体哪个函数的作用域链里面进行访问