先来复习一下,执行上下文的构成
bash
执行上下文函数
以前说了变量对象
,如今来讲下另外两个this
通俗地讲,当声明一个函数时,局部做用域一级一级向上包起来,就是做用域链。spa
咱们从函数定义到执行一步一步来讲明code
当函数被定义的时候,会读取函数内部的一个属性,[[scope]]属性来保存就会保存全部父变量对象到其中,能够理解 [[scope]] 就是全部父变量对象的层级链对象
function a(){
function b(){
}
}
复制代码
分析一下,当函数建立时,各自的[[scope]]为
作用域
a.[[scope] = [
globalContext.VO
]
b.[[scope]] = [
aContext.AO,
globalContext.VO
];
复制代码
当函数激活的时候,建立VO/AO。并将其加入做用域链的第一位,做用域链(scope)到如今就建立完毕了string
var global = '全局变量'
function abs(){
a = 1
console.log(a)
}
abs()
复制代码
1.函数abs被建立,将做用域链保存到[[scope]]中
it
abs.[[scope]] = [
globalContext.VO
]
复制代码
2.abs函数开始执行,此时建立abs函数的执行上下文,并入栈
io
ECstack = [
absContext
globalContext
]
复制代码
3.abs作正式执行前的准备工做,将[[scope]]属性做为做用域链,此时的abs执行上下文
absContext = {
Scope: abs.[[scope]],
}
复制代码
4.初始化变量对象,VO/AO
absContext = {
AO: {
arguments: {
length: 0
},
a: undefined
},
Scope:abs.[[scope]]
}
复制代码
5.将活动对象AO加到做用域链的顶端
absContext = {
AO: {
arguments: {
length: 0
},
a: undefined
},
Scope:[AO,abs.[[scope]]]
}
复制代码
至此,准备工做完成
6.随着函数的进行,AO开始进行赋值工做
checkscopeContext = {
AO: {
arguments: {
length: 0
},
a: 1
},
Scope: [AO, [[Scope]]]
}
复制代码
7.在做用域链中找到a的值并打印
8.abs执行完毕,abs的执行上下文栈弹出
ECstack = [
globalContext
]
复制代码