函数执行过程与作用域链
执行上下文
在调用函数的之后,在函数执行之前,需要创建一个执行上下文。
这个执行上下文有三个重要属性:
-
作用域链
-
变量对象
-
this
作用域链与变量对象
当代码执行,解析标识符(查找变量) 的时候,首先从当前的变量对象(活动对象 )中搜索,如果没有找到,就会往后逐层搜索各个父级执行上下文的变量对象,直到全局上下文的变量对象——全局对象。
这个由各级执行上下文的变量对象组成的链表就是作用域链。
函数从创建到执行的七个过程
前言
因为在函数执行之前,需要创建它的执行上下文。创建执行上下文之后,还要设置它的三个重要属性:变量对象,作用域链,this 。因此,在函数执行之前,需要几个过程来创建它的执行上下文,并逐步设置执行上下文的三个重要属性:变量对象,作用域链,this。
思考(个人)
执行上下文是在函数被调用之后才创建的,如果在函数被调用,创建执行上下文之后才从零开始设置它的变量对象、作用域链,需要耗费很多时间,能否在调用函数并创建执行上下文之前就设置好它的变量对象和作用域链呢?变量对象中包含了函数的形参、变量声明等属性,因此只能在调用函数之后再设置,但是作用域链中的大部分内容(除了最前端的活动对象)在函数定义的时候就可以却确定了,因此可以在函数声明后就可以设置函数的大部分作用域链。
过程
-
函数声明后,设置函数的 [[scope]] 内部属性(即作用域) ,里面包含了各级父级执行上下文的变量对象, 此时的作用域链还不完整,因为作用域链的最前端还没有包含这个函数的变量对象,接下来在函数被调用的时候,就要逐步设置执行上下文的变量对象,完善作用域链
-
函数被调用之后,创建一个执行上下文,并压入执行上下文栈中
-
复制函数的 [[scope]] 属性为执行上下文创建作用域链
-
通过函数的 argument 创建活动对象(用作变量对象), 随后初始化活动对象,加入形参,变量声明,函数声明
-
将活动对象加入到作用域链的前端
-
执行上下文配置完成,执行函数
-
函数执行完毕,执行上下文出栈,销毁活动对象