资讯专栏INFORMATION COLUMN

前端进阶系列(七):什么是执行上下文?什么是调用栈?

leone / 2063人阅读

摘要:什么是中的调用栈调用栈就像是程序当前执行的日志。当函数执行结束时,将从调用栈中出去。了解全局和局部执行上下文是掌握作用域和闭包的关键。总结引擎创建执行上下文,全局存储器和调用栈。

原文作者:Valentino
原文链接:https://www.valentinog.com/blog/js-execution-context-call-stack
什么是Javascript中的执行上下文?

我打赌你不知道答案。

编程语言中最基础的组成部分是什么?

变量和函数对吗?每个人都可以学习这些板块。

但除了基础知识之外还有什么?

在称自己为中级(甚至是高级)Javascript开发人员之前,你应该掌握的Javascript的核心是什么?

有很多:Scope(作用域)Closure(闭包)Callbacks(回调)Prototype(原型)等等。

但在深入研究这些概念之前,您至少应该了解Javascript引擎的工作原理。

在这篇文章中,我们将介绍每个Javascript引擎的两个基本部分:执行上下文和调用堆栈。

(不要害怕。它比你想象的容易)。

准备好了吗?

目录

你会学到什么?

Javascript如何执行您的代码?

Javascript引擎

它是如何工作的?

全局存储器?

什么是调用栈?

什么是局部执行上下文?

总结

你会学到什么?

在这篇文章中你将学到:

Javascript引擎是如何工作的?

Javascript中执行上下文

什么是调用栈

全局执行上下文和局部执行上下文之间的区别

Javascript如何执行您的代码?

通过查看Javascript内部功能,您将成为更好的Javascript开发人员,即使您无法掌握每一个细节。

现在,看看下面的代码:

var num = 2;

function pow(num) {
    return num * num;
}

现在告诉我:你认为在浏览器里以何种顺序执行这段代码?

换句话说,如果您是浏览器,您将如何阅读该代码?

这听起来很简单。

大多数人认为“是的,浏览器执行功能pow并返回结果,然后将2分配给num。”

在接下来的部分中,您将发现那些看似简单的代码行背后的机制。

Javascript引擎

要了解Javascript如何运行您的代码,我们应该遇到第一件可怕的事情:

执行上下文

在Javascript中什么是执行上下文?

每次在浏览器(或Node)中运行Javascript时,引擎都会执行一系列步骤。

其中一个步骤涉及创建全局执行上下文。

什么是引擎?

也就是说,Javascript引擎是运行Javascript代码的“引擎”。

如今有两个突出的Javascript引擎:Google V8和SpiderMonkey。

V8是Google开源的Javascript引擎,在Google Chrome和Nodejs中使用。

SpiderMonkey是Mozilla的JavaScript引擎,用于Firefox。

到目前为止,我们有Javascript引擎和执行上下文。

现在是时候了解它们如何协同工作了。

它是如何工作的?

每次运行一些Javascript代码是,引擎都会创造一个全局执行上下文。

执行上下文是一个比喻的词,用于描述运行Javascript代码的环境。

我觉得你很难想象出这些抽象的东西。

现在将全局执行上下文视为一个框:

让我们再看看我们的代码:

var num = 2;

function pow(num) {
    return num * num;
}

引擎如何读取该代码?

这是一个简化版本:

引擎:第一行,它是变量!让我们将它存储在全局存储器中。

引擎:第三行,我看到了一个函数声明。让我们也把它存储在全局存储器中。

引擎:看起来我已经完成了。

如果我再次问你:浏览器如何“看到”以下代码,你会怎么说?

是的,它有点自上而下......

正如你所看到的那样,引擎没有运行功能pow!

这是一个函数声明,而不是函数调用。

上面的代码将转换为存储在全局存储器中的一些值:函数声明和变量。

全局存储器?

我已经对执行上下文感到困惑,现在还要问我什么是全局存储器?

接下来让我们看看什么是全局存储器

全局存储器

Javascript引擎也有一个全局存储器。

全局内存包含全局变量和函数声明供以后使用。

如果您阅读Kyle Simpson的“作用域和闭包”,您可能会发现全局存储器与全局作用域的概念重叠。

实际上它们是一回事。

这是些很难得概念。

但你现在不应该担心。

我希望你能理解我们难题的两个重要部分。

当Javascript引擎运行您的代码时,它会创建:

全局执行上下文

全局存储器(也称为全局作用域或全局变量环境)

一切都清楚了吗?

如果我在这一点上,我会:

写下一些Javascript代码

当你是引擎时,一步一步地解析代码

在执行期间创建全局执行上下文和全局存储器的图形表示

您可以在纸上或使用原型制作工具编写练习。

对于我的小例子,图片看起来如下:

在下一节中,我们将看另一个可怕的事情:调用栈。

什么是调用栈?

您是否清楚地了解了执行上下文,全局存储器和Javascript引擎如何组合在一起?

如果没有,花时间查看上一节。

我们将在我们的难题中介绍另一篇文章:调用栈。

让我们首先回顾一下Javascript引擎运行代码时会发生什么。 它创建:

全局执行上下文

全局存储器

除了我们的例子,没有更多的事情发生:

var num = 2;

function pow(num) {
    return num * num;
}

代码是纯粹的值分配。

让我们更进一步。

如果我调用该函数会发生什么?

var num = 2;

function pow(num) {
    return num * num;
}

var res = pow(num)

有趣的问题。

在Javascript中调用函数的行为使引擎寻求帮助。

这个帮助来自Javascript引擎的朋友:调用栈。

它听起来可能并不明显,但Javascript引擎需要跟踪发生的情况。

它依赖于调用栈。

什么是Javascript中的调用栈?

调用栈就像是程序当前执行的日志。

实际上它是一个数据结构:堆栈。

调用栈的工作原理是什么?

不出所料,它有两种方法:push和pop。

push是将某些东西放入堆栈的行为。

也就是说,当您在Javascript中运行函数时,引擎会将该函数push到调用堆栈中。

每个函数调用都被push到调用栈中。

push的第一件事是main()(或global()),它是Javascript程序执行的主要线程。

现在,上一张图片看起来像这样:

pop另一端是从堆栈中删除某些东西的行为。

当函数执行结束时,将从调用栈中pop出去。

我们的调用栈将如下所示:

现在?您已准备好从那里掌握每个Javascript概念。

请看下一部分。

局部执行上下文

到目前为止,一切似乎都很清楚。

我们知道Javascript引擎创建了一个全局执行上下文和一个全局存储器。

然后,当您在代码中调用函数时:

Javascript引擎请求帮助

这个帮助来自Javascript引擎的朋友:调用栈

调用栈会跟踪代码中调用的函数

当你在Javascript中运行一个函数时,还有另一件事情发生。

首先,该功能出现在全局执行上下文中。

然后,另一个迷你上下文出现在函数旁边:

那个迷你上下文叫做局部执行上下文。

如果您注意到,在上一张图片中,全局存储器中会出现一个新变量:var res。

变量res的值首先是undefined。

然后,只要pow出现在全局执行上下文中,该函数就会执行并且res将获取其返回值。

在执行阶段,创建局部执行上下文以保存局部变量。

记住这一点。

了解全局和局部执行上下文是掌握作用域和闭包的关键。

总结

Javascript引擎创建执行上下文,全局存储器和调用栈。但是一旦你调用一个函数,引擎就会创建一个局部执行上下文。

经常被忽视的是,新的开发人员总是将Javascript内部视为神秘的东西。

然而,它们是掌握高级Javascript概念的关键。

如果你学习执行上下文,全局存储器和调用栈,那么Scope,Closures,Callbacks和其他东西将变得轻而易举。

特别是,理解调用堆栈是至关重要的。

一旦你想象它,所有的Javascript将开始有意义:你将最终理解为什么Javascript是异步的以及我们为什么需要回调。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98295.html

相关文章

  • 前端基础进阶(二):执行下文详细图解

    摘要:执行上下文可以理解为当前代码的执行环境,它会形成一个作用域。栈底永远都是全局上下文,而栈顶就是当前正在执行的上下文。我们用来表示处理执行上下文组的堆栈。因此第三步是的执行上下文入栈。前端基础进阶系列目录 showImg(https://segmentfault.com/img/remote/1460000008315046);我们在JS学习初期或者面试的时候常常会遇到考核变量提升的思考...

    cjie 评论0 收藏0
  • 前端基础进阶目录

    摘要:不过其实简书文章评论里有很多大家的问题以及解答,对于进一步理解文中知识帮助很大的,算是有点可惜吧。不过也希望能够对正在学习前端的你有一些小帮助。如果在阅读中发现了一些错误,请在评论里告诉我,我会及时更改。 前端基础进阶(一):内存空间详细图解 前端基础进阶(二):执行上下文详细图解 前端基础进阶(三):变量对象详解 前端基础进阶(四):详细图解作用域链与闭包 前端基础进阶(五):全方位...

    mo0n1andin 评论0 收藏0
  • 进阶2-2期】JavaScript深入之从作用域链理解闭包

    摘要:使用上一篇文章的例子来说明下自由变量进阶期深入浅出图解作用域链和闭包访问外部的今天是今天是其中既不是参数,也不是局部变量,所以是自由变量。 (关注福利,关注本公众号回复[资料]领取优质前端视频,包括Vue、React、Node源码和实战、面试指导) 本周正式开始前端进阶的第二期,本周的主题是作用域闭包,今天是第7天。 本计划一共28期,每期重点攻克一个面试重难点,如果你还不了解本进阶计...

    simpleapples 评论0 收藏0
  • 文章分享(持续更新)

    摘要:文章分享持续更新更多资源请文章转自一前端文章基础篇,,前端基础进阶一内存空间详细图解前端基础进阶二执行上下文详细图解前端基础进阶三变量对象详解前端基础进阶四详细图解作用域链与闭包前端基础进阶五全方位解读前端基础进阶六在开发者工具中观察函数调 文章分享(持续更新) 更多资源请Star:https://github.com/maidishike... 文章转自:https://gith...

    whlong 评论0 收藏0
  • 前端基础进阶(一):内存空间详细图解

    摘要:一栈数据结构与不同,中并没有严格意义上区分栈内存与堆内存。引用数据类型的值是保存在堆内存中的对象。不允许直接访问堆内存中的位置,因此我们不能直接操作对象的堆内存空间。为了更好的搞懂变量对象与堆内存,我们可以结合以下例子与图解进行理解。 showImg(https://segmentfault.com/img/remote/1460000009784102?w=1240&h=683); ...

    _Suqin 评论0 收藏0

发表评论

0条评论

leone

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<