执行上下文
一、执行上下文
执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。JavaScript中的运行环境大概包括三种情况:
(1)全局环境:JavaScript代码运行起来会首先进入该环境
(2)函数环境:当函数被调用时,会进入当前函数中执行代码
(3)eval(不建议使用,忽略)
只要遇到以上三种情况,都会生成一个执行上下文,放入栈中。
上文提到,JavaScript引擎会以栈的方式处理执行上下文,这个栈被称为调用栈(call stack)。栈是先入后出的方式,所以栈底永远是全局上下文(global context),栈顶是当前正在执行的上下文。栈顶的上下文执行完毕后,会自动出栈。全局上下文在浏览器窗口关闭后出栈。
执行上下文的一些结论:
(1)单线程
(2)同步执行,只有栈顶的上下文处于执行中,其它上下文需要等待
(3)全局上下文只有唯一的一个,在浏览器关闭后出栈
(4)函数的执行上下文没有限制
(5)每次某个函数被调用,就会有个新的执行上下位为其创建,即使是调用自身的函数,也是如此
一个闭包的例子:
function f1(){ var n=999; function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999
具体演变过程如下:
注意,首先进入全局上下文,执行全局上下文中可执行代码,执行到var result=f1()时,调用了f1函数,创建f1函数的上下文。而f1中的函数f2在f1的可执行代码中并没有被调用执行,因此执行f1时,f2不会创建新的上下文。f1出栈后,代码继续执行,到下一句result()时,创建result的上下文。
二、执行上下文生命周期
当调用一个函数的时候,一个新的执行上下文就会被创建,而一个执行上下文的生命周期可以分为两个阶段:
1.创建阶段。在这个阶段中,执行上下文会分别创建变量对象,建立作用域链,确定this指向。
2.代码执行阶段。创建完成后,就会开始执行代码,这时会完成变量赋值,函数引用,以及执行其它代码。
重点(※):