函数就像一个屋子一样,这个屋子的形成就好像形成了一个单独的域,和外界有一些阻隔,里面可以看到外面的,外面的不能看到里面。
可以把函数所生成的空间叫做作用域,但是不精准。作用域是因为函数的产生而产生的一种特殊的东西,也就是说作用域属于一个函数,一个函数产生了一样的作用域。
每一个对象都有属性和方法。
函数也是一种特殊的对象。
作用域
var a = 123;
function test(){
document.write(a); // 123
var b = 456;
}
test();
document.write(b); // b is not defined
函数里面可以访问函数外面的东西,a是全局变量;
函数外面不能访问函数里面的东西 ,b是局部变量
test.[[scope]]
这个属性访问不了 [[scope]]
里面存的就是因为这个函数产生而产生的作用域,是隐式的属性。系统可以用,但是我们不能自己调用。
执行期上下文
当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行期上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生的执行上下文被销毁。
(AO,GO就是执行期上下文)
[[scope]] 每个javascript函数都是一个对象,对象中有些属性我们可以访问,有些不可以,这些属性仅供javascript引擎存取,[[scope]]就是其中一个。
[[scope]] 指的就是我们所说的作用域,其中存储了运行期上下文的集合。
作用域链
[[scope]]中所存储中执行期上下文对象的集合,这个集合呈链式链接,我们把这种链式链接叫做作用域链。
定义
变量(变量作用域又称上下文)和函数生效(能被访问)的区域。
查找变量
从作用域链的顶端依次向下查找
function a(){
function b() {
var b = 234;
// a = 0;
}
var a = 123;
b();
// console.log(a);
}
var glob = 100;
a();
// 函数a在全局的作用域里面,还有一个glob
// a defined a.[[scope]] --> 0:GO{}
// a被执行,产生一个AO,把自己的AO放在作用域的最顶端,形成一个新的作用域链
// a doing a.[[scope]] --> 0:AO{}
// a.[[scope]] --> 1:GO{}
// 此时在a里面访问一个变量,是访问a的scope,自顶向下
// 由于a执行产生了一个b的定义 b能看到a所拥有的东西 b拥有的是a的劳动成果
// b执行 产生自己的执行期上下文
// b执行完之后,要销毁自己的AO;相当于a也执行完了 要销毁自己的AO
问题
1.图4的1里面的AO和图2的0里面的AO是一个东西嘛?是把人家的引用挂到自己身上还是一个独一无二的东西?
他们是一个人
2.生成的一系列过程什么时候是个终点?
案例
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
c doing c.[[scope]] -- > 0:cAO
-- > 1:bAO
-- > 2:aAo
-- > 3:GO