在从事前端行业之后,再次回来打基础,对以前没有搞懂的东西重新梳理
以前一直对函数执行上下文不理解,再浏览很多文章之后慢慢有了点理解,希望大家能指出理解不对的地方,谢谢!!
在《JavaScript深入之词法作用域和动态作用域》中讲到,函数的作用域在函数定义的时候就决定了。
这是因为函数有一个内部属性 [[scope]],当函数创建的时候,就会保存所有父变量对象到其中,你可以理解 [[scope]] 就是所有父变量对象的层级链,但是注意:[[scope]] 并不代表完整的作用域链!
var g = 'g'
function f (){
var a = 'a'
console.log(a)
}
一、函数创建
函数 f 创建的时候
f[[scope]] = [glabalContext.VO]
二、函数执行
执行开始之前创建函数执行上下文,并且将其压入执行上下文栈
Stack = [fContext,glabalContext]f
1、复制[scope]到函数执行上下文的scope上
fContext = {
scope : f[[scope]]
}
2、创建AO,并且初始化形参,函数声明和变量声明提升
fContext = {
AO:{
argument:{
length:0
},
a:undefined
}
scope : f[[scope]]
}
3、将AO压入到执行上下文scope栈顶
fContext = {
AO:{
argument:{
length:0
},
a:undefined
}
scope : [AO,f[[scope]]]
}
函数开始执行,开始设置AO的参数
fContext = {
AO:{
argument:{
length:0
},
a:'a'
}
scope : [AO,f[[scope]]]
}
三、函数执行上下文销毁
当函数打印完结果,函数执行完毕,将函数执行上下文推出栈
Stack=[ galbalContext ]
自此函数执行上下文的周期就结束了