一种是上文成员(js语法可以直接访问的成员)
一种是下文成员(底层语法访问的成员)
[[scopes]]括起来的成员名 就是下文成员
function fn () {
}
console.dir(fn)
这个"对象"内部保存的就是函数的作用域
函数在定义/声明的时候 就有了[[scopes]] 里面保存了上层的AO对象
函数调用时会生成AO对象 AO保存在scopes对象内部的
function fn (n) {
var a=20
function fm () {
}
}
fn(100)//AO:{n:undef==>100,a:undef==>20,function fm(){}}
fn()//AO:{n:undef,a:undef==>20,function fm(){}}
函数的预编译
函数在定义的时候就有了一些固定的属性 比如 length name
然后我们来了解了解scope这个属性
scope里面保存的就是作用域 也就是AO对象我们(不了解AO对象的可以看看前一篇预编译)
scope类似一个栈 先进后出
我们举一个例子来讲解
<script>
function a() {
function b() {
var bb = 234
aa = 0;
}
var aa = 123;
b();
console.log(a);
}
var glob = 100;
a();
</script>
在全局作用下声明的a
然后执行a 然后执行b 在执行a 最后终止
在创建b的时候
这就是scope 因为最先有的go作用域 然后执行的a 在执行a是创建了b 所以创建b时b的scope就诞生成立了 因为类似于先进后出的道理 所以GO 对象最下面然后是a的AO对象 一直到b执行
也就添加了b的AO对象在最上层 当b的执行完毕之后b的AO对象被销毁
就像这样形成了作用域链 当在本层作用域里面查找不到x变量时 就在上层作用域去找 也就是scope的下一层