全局代码的执行过程。当JavaScript引擎开始执行脚本时,首先会创建全局执行上下文,并将其推入调用栈顶部。这时候,全局上下文会经历两个阶段:创建阶段和执行阶段。在创建阶段,会创建全局对象(在浏览器中是window,Node.js中是global),建立作用域链,确定this的指向(全局中this指向全局对象),然后进行变量和函数的声明提升。这时候,变量被初始化为undefined,函数声明则被完全提升,可以直接调用。
创建时机
- 全局上下文:在脚本开始执行时立即创建,是第一个被推入调用栈的上下文。
- 函数上下文:在函数被调用时动态创建,每次调用都会生成新的上下文。
作用域
-
全局上下文:
- 作用域链仅包含全局变量对象(如
window或global)。 - 无法访问任何外部作用域(因为它是顶层)。
- 作用域链仅包含全局变量对象(如
-
函数上下文:
- 作用域链包含当前函数的活动对象(AO)、外层作用域(可能是其他函数或全局上下文)。
- 形成闭包时,外层函数的活动对象会被保留(即使外层函数已执行完毕)。 示例:
var name = "why"
foo()
function foo() {
console.log("foo")
}
执行过程:会先创建一个全局对象,但是如果是函数会另外开启一块空间来存储函数
第一步:
除了创建全局对象,还会分配一块存储函数的空间
第二步:
执行前五行,打印结构为 undefiend foo
会创建一个函数上下文入栈,和AO(包含函数里边的变量)
第三步:
执行到第七行
将变量的值赋值到AO中
第四步:
函数执行完毕之后函数上下文会出栈然后销毁,AO也会被销毁,如果下边继续调用函数会创新创建函数上下文入栈,创建AO按照上边的步骤执行