You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// global contextvarsayHello='sayHello'functionperson(){varfirst='webb'varlast='wang'functionfirstName(){returnfirst}functionlastName(){returnlast}console.log(sayHello+firstName()+''+lastName())}
(function(){console.log(typeoffoo);// function pointerconsole.log(typeofbar);// undefinedvarfoo='hello',bar=function(){return'world';};functionfoo(){return'hello';}}());
JavaScript中的执行上下文和堆栈是什么
在这篇文章中,将深入研究JavaScript最基本的部分之一,即执行上下文。在这篇文章的最后,你应该更清楚地理解解释器要做什么,为什么在声明一些函数/变量之前可以使用它们,以及它们的值是如何确定的。
什么是执行上下文
当JavaScript代码运行时,执行代码的环境是相当重要的。一般有以下三种情况:
把执行上下文看作是当前代码正在执行的环境/作用域
以上代码没什么特别的地方,它包括1个全局上下文和3个不同的函数上下文,全局上下文可以被程序中的其它任何上下文访问。
你可以有任意数量的函数上下文,每个函数被调用的时候都会创建一个新的上下文。每个下文都有一个不能被外部函数直接访问到的内部变量的私有作用域。在上面代码的例子中,一个函数可以访问当前上下文外部声明的变量,但是一个外部上下文不可以访问函数内部声明的变量。
执行上下文堆栈
浏览器中的JavaScript解释器是作为一个单线程实现的,这实际上意味着,在浏览器中,一次只能发生一件事,其他操作或事件将排队在所谓的执行堆栈中。
当浏览器开始执行脚本时,首先会默认进入全局执行上下文,如果在全局代码中调用了函数,程序会按照顺序进入被调用函数,创建一个新的执行上下文,并推入到执行栈的栈顶。
如果你在当前执行的函数中,调用了另外的函数,代码的执行流将会进入函数内部,并创建一个新的执行上下文推入到执行栈顶。浏览器总是会先执行栈顶的代码,并且一旦函数完成执行当前执行上下文,他就会从栈顶弹出,将控制权返回到当前堆栈中的上下文。
关于执行堆栈有以下关键点
深入理解执行上下文
现在我们知道每当有函数被调用时,都会创建一个新的执行上下文。在js内部,每个执行上文创建都要经历下面2个阶段
1.创建阶段(函数被调用,但还没有执行内部代码)
2.代码执行阶段
可以将每个执行上下文概念上表示为一个具有3个属性的对象:
活动对象/变量对象(AO/VO)
当函数被调用时,在创建阶段解释器会创建包含有函数内部变量,参数的一个变量对象
下面是解释器如何评估代码的概述
声明提升
你可以在网上找到许多用JavaScript定义术语提升的资源,解释变量和函数声明被提升到函数作用域的顶部。但是,没有人详细解释为什么会发生这种情况,而且有了解释器如何创建激活对象的新知识,就很容易理解为什么会发生这种情况。以下面的代码为例:
为什么在变量声明之前可以访问到foo
如果我们遵循创建阶段,我们就知道在代码执行阶段之前已经创建了变量。因此,当函数流开始执行时,foo已经在活动对象中定义。
Foo声明了两次,为什么Foo是函数而不是未定义或字符串?
尽管foo声明了两次,但从创建阶段我们就知道函数是在变量之前在变量对象上创建的,如果变量对象上的属性名已经存在,那么我们只需绕过。
因此,首先在变量对象上创建对函数foo()的引用,当解释器到达var foo时,我们已经看到了属性名foo的存在,所以代码什么也不做,继续执行
为什么bar是undefined
bar实际上是一个具有函数赋值的变量,我们知道这些变量是在创建阶段创建的,但是它们是用undefined值初始化的。
总结
希望现在你已经很好地理解了JavaScript解释器是如何执行代码的。理解执行上下文和堆栈可以让你了解代码没有按照预期执行的原因
The text was updated successfully, but these errors were encountered: