JS:作用域链
作用域链,就是代码在作用域中运行时,,会自动生成一个变量对象作用域(AO),从而形成的作用域链。
*全局作用域叫做(GO)。
变量对象的作用域会从当前对象作用域嵌套外层对象作用域再嵌套外层对象作用域,以此类推到全局对象的作用域。
因此这就是内部作用域可以访问外层作用域、全局作用域的变量的原因。
function fn (b){ var a = 1; function fm(){}; }
fn(2);
==>他们的变量对象作用域链形成:
AO(fm):{AO(fn):{b=undefined -->2;a = undefined -->1;function fm (){ }};GO{ } }
这个例子也说明了访问局部变量会快于全局变量,因为查找时间短。
函数执行代码,产生一个AO对象,叫做函数执行期上下文
全局执行代码,将产生一个GO对象,叫做全局执行期上下文
scopes(作用域)
js对象有两种成员
一种是上文成员(js语法可以直接访问的成员)
另一种是下文成员(底层语法访问的成员)[[scopes]] 括起来的成员名 就是下文成员
*[[scopes]]这是函数的一个内部属性,就是我们所说的作用域,仅供JS引擎存取
function fn() {
}
console.dir(fn)
这个 "对象"
内部保存的就是函数的作用域
函数在定义 / 声明的时候 就有了[[scopes]] 里面保存了上层的AO对象。==> AO(本层):{ AO(上一层):{ } }
函数调用时会生成本层的AO对象 AO保存在scopes对象内部里。
每个函数scopes数组中生成就有一个AO对象,AO是本函数的上层AO。
function fn() { var a = 30; function fm() { var b = 20; console.log(a); } fm();
console.dir(fm); } fn(); console.dir(fn);
打印fn的结构:
fn中的上一层是GO
打印fm的结构:
fm的上一层有fn的AO和全局的GO,因此访问到了fn中的变量a值;