作用域
在调用栈中创建出了执行上下文,我们称这个上下文为作用域(函数会给自己创建作用域)
当函数执行时会创建一个成为执行期上下文的内部对象,一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应得执行上下文都是独一无二的,所以调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生的执行上下文会被销毁
作用域链
[[scope]]中存储的执行期上下文对象的集合,这个集合呈链式连接,我们把这种链式连接叫做作用域链
我们先看代码:
function a(){
function b(){
var b=222
}
var a=111
b()
console.log(a);
}
var glob = 100
a()
复制代码
首先我们看代码,代码是一行行执行下去的。
我们来复习一下作用域:先是全局作用域GO
创建一个GO对象:找形参和变量声明,将形参和变量声明作为AO对象的属性名,值为undefined
GO{
Glob:undefined
}
复制代码
全局局里的函数声明,将函数名作为GO的属性名,值赋予函数体
GO{
Glob:undefined
a:function
}
复制代码
再看函数体:找形参和变量声明,将形参和变量声明作为AO对象的属性名,值为undefined
AO{
a:undefined
b:undefined
}
复制代码
将实参和形参统一(也就是把实参的值赋给形参)
AO{
a:undefined
b:undefined
}
复制代码
在函数体里找函数声明,将函数名作为AO的属性名,值赋予函数体
AO{
a:undefined
b:undefined,function
}
复制代码
代码执行:
GO{
Glob:undefined,100
a:function }
AO{
a:undefined,111
b:undefined,function,222
}
复制代码
因为console.log(a)在函数体所以先在AO里寻找a的值,a=111所以输出111
下面我们来看看作用域链:
a 定义 a.[[scope]]——–>0:GO{ }
a 执行 a.[[scope]]——–>0:a:AO{ } 1:GO{ }
b 定义 b.[[scope]]——–>0:AO{ } 1:GO{ }
b 执行 b.[[scope]]——–>0:b:AO{ } 1:a:AO{ } 2:GO{ }
作用域链 | |
---|---|
0 | bAO |
1 | aAO |
2 | GO |
GO | |
---|---|
this | window |
golb | 100 |
a | function |
aAO | |
---|---|
this | window |
a | 111 |
b | function |
arguments(函数自带) |
bAO | |
---|---|
this | window |
b | 222 |
arguments(函数自带) | |
— | — |
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END