资讯专栏INFORMATION COLUMN

JavaScript如何工作:引擎,运行时和调用堆栈的概述

wwolf / 780人阅读

摘要:如果我们进入一个函数,我们在堆栈的顶部。看看下面的代码当引擎开始执行此代码时,调用堆栈将为空。之后,步骤如下调用堆栈中的每个条目称为堆栈帧。这正是抛出异常时构造堆栈跟踪的方式当异常发生时,它基本上是调用堆栈的状态。

随着JavaScript越来越受欢迎,团队正在利用这个技术栈在多个层次- 前端,后端,混合应用程序,嵌入式设备等等提供支持。

这篇文章旨在成为系列中第一个旨在深入挖掘JavaScript及其实际工作的系列文章:我们认为,通过了解JavaScript的构建方式以及它们如何协同构建,您将能够编写更好的代码和 应用。

如GitHub统计所示,JavaScript在GitHub中的活跃库数量和总推送数量位居前列。 在其他类别中也不会落后于很多。

(查看最新的GitHub语言统计信息)。

如果项目越来越依赖JavaScript,这意味着开发人员必须利用语言和生态系统提供的所有内容来更深入地了解内部内容,以便构建出令人惊艳的软件。

事实证明,有很多开发人员每天都在使用JavaScript,但不知道什么会发生什么。

概览

几乎所有人都已经听说过V8引擎的概念,大多数人都知道JavaScript是单线程的,或者是使用回调队列。

在这篇文章中,我们将详细介绍所有这些概念,并解释JavaScript如何运行。 通过了解这些细节,您将能够编写更好的非阻塞应用程序,正确利用提供的API。

如果您接触JavaScript不久,此博文将帮助您了解为什么JavaScript与其他语言相比是如此“奇怪”。

如果您是一位经验丰富的JavaScript开发人员,希望能够为您提供一些新的见解,了解您每天使用的JavaScript运行时间是否真的有效。

JavaScript引擎

JavaScript引擎的一个流行示例是Google的V8引擎。 例如,V8引擎在Chrome和Node.js中使用。 这是一个很简单的视图:

引擎由两个主要组成部分组成:

内存堆 - 这是内存分配发生的地方

调用堆栈 - 这是您的代码执行的堆栈帧

运行时

浏览器中已经有几个JavaScript开发人员使用的API(例如“setTimeout”)。 然而,引擎不提供这些API。

那么他们从哪里来?

事实证明,现实有点复杂。

所以,我们有引擎,但实际上还有更多。 我们有一些称为Web API的东西,由浏览器提供,如DOM,AJAX,setTimeout等等。

还有就是非常时髦的事件循环和回调队列。

调用堆栈

JavaScript是单线程编程语言,这意味着它有一个单一的调用堆栈。 因此,它可以一次做一件事。

调用堆栈是一个数据结构,它基本上记录了我们在程序中什么位置。 如果我们进入一个函数,我们在堆栈的顶部。 如果我们从一个函数返回,我们从堆栈的顶部弹出。 这就是堆栈可以做的。

我们来看一个例子。 看看下面的代码:

function multiply(x, y) {
    return x * y;
}
function printSquare(x) {
    var s = multiply(x, x);
    console.log(s);
}
printSquare(5);

当引擎开始执行此代码时,调用堆栈将为空。 之后,步骤如下:

调用堆栈中的每个条目称为堆栈帧。

这正是抛出异常时构造堆栈跟踪的方式 - 当异常发生时,它基本上是调用堆栈的状态。 看看下面的代码:

function foo() {
    throw new Error("SessionStack will help you resolve crashes :)");
}
function bar() {
    foo();
}
function start() {
    bar();
}
start();

如果这是在Chrome中执行的(假设此代码位于一个名为foo.js的文件中),则会产生以下堆栈跟踪:

“Blowing the stack”  - 当您达到最大调用堆栈大小时,会发生这种情况。 这可能会很容易发生,特别是如果您在不经常地对代码进行测试的情况下使用递归。 看看这个示例代码:

function foo() {
    foo();
}
foo();

当引擎开始执行这个代码时,它首先调用函数“foo”。 然而,这个函数是递归的,并且开始调用自身而没有任何终止条件。 所以在执行的每个步骤中,相同的功能被一次又一次地添加到调用堆栈中。 看起来像这样:

然而,在某些时候,调用堆栈中的函数调用次数超过了调用堆栈的实际大小,并且浏览器决定采取行动,通过抛出一个错误,看起来像这样:

在单个线程上运行代码可能非常容易,因为您不必处理在多线程环境中出现的复杂场景,例如死锁。

但是在单线程上运行也是非常有限的。 由于JavaScript有一个调用堆栈,当运行缓慢时会发生什么?

并发和事件循环

当您在调用堆栈中进行函数调用需要大量时间才能处理时会发生什么? 例如,假设您想在浏览器中使用JavaScript进行一些复杂的图像转换。

你可能会问 - 为什么这甚至是一个问题? 问题是,虽然调用堆栈具有执行的功能,但浏览器实际上不能做任何事情 - 它被阻止。 这意味着浏览器无法渲染,它不能运行任何其他代码,它只是卡住了。 如果您想要在应用中使用流畅的UI,这会产生问题。

这不是唯一的问题。 一旦您的浏览器开始处理Call Stack中的这么多任务,它可能会停止响应很长时间。 大多数浏览器通过提出错误来采取行动,询问您是否要终止网页。

现在,这不是最好的用户体验,是吗?

那么,如何在不阻塞UI并使浏览器无响应的情况下执行繁重的代码呢? 那么解决方案是异步回调。

这将在“JavaScript如何实际工作”教程的第2部分中更详细地解释:“V8引擎内有关如何编写优化代码的5个提示”。

翻译自How JavaScript works: an overview of the engine, the runtime, and the call stack

关注我的公众号,更多优质文章定时推送

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

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

相关文章

  • JavaScript如何工作引擎运行时和调用堆栈概述

    摘要:调用栈是一种单线程编程语言,这意味着它只有一个调用堆栈。调用栈是一种数据结构,它记录了我们在程序中的位置。而且这不是唯一的问题,一旦你的浏览器开始处理调用栈中的众多任务,它可能会停止响应相当长一段时间。 本文是旨在深入研究JavaScript及其实际工作原理的系列文章中的第一篇:我们认为通过了解JavaScript的构建块以及它们是如何工作的,将能够编写更好的代码和应用程序。我们还将分...

    PiscesYE 评论0 收藏0
  • JavaScript如何工作系列文章已更新到22篇

    摘要:为了方便大家共同学习,整理了之前博客系列的文章,目前已整理是如何工作这个系列,可以请猛戳博客查看。以下列出该系列目录,欢迎点个星星,我将更友动力整理理优质的文章,一起学习。 为了方便大家共同学习,整理了之前博客系列的文章,目前已整理 JavaScript 是如何工作这个系列,可以请猛戳GitHub博客查看。 以下列出该系列目录,欢迎点个星星,我将更友动力整理理优质的文章,一起学习。 J...

    lx1036 评论0 收藏0
  • JavaScript如何工作JavaScript 内存模型

    摘要:调用堆栈是存放原始数据类型的地方除了函数调用之外。上一节中声明变量后调用堆栈的粗略表示如下。解释改变的正确方法是更改内存地址。在声明时,将在调用堆栈上分配内存地址,该值是在堆上分配的内存地址。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第 21 篇。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 如果你错过了前面的章节,可以在这里找到它们:...

    baoxl 评论0 收藏0
  • JavaScript如何工作:解析、抽象语法树(AST)+ 提升编译速度5个技巧

    摘要:无论你使用的是解释型语言还是编译型语言,都有一个共同的部分将源代码作为纯文本解析为抽象语法树的数据结构。和抽象语法树相对的是具体语法树,通常称作分析树。这是引入字节码缓存的原因。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第 14 篇。 想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你! 如果你错过了前面的章节,可以在这里找到它们: JavaS...

    raoyi 评论0 收藏0
  • 【译】JavaScript 如何工作:对引擎运行时、调用堆栈概述

    摘要:调用栈是一种数据结构,它记录了我们在程序中的位置。当从这个函数返回的时候,就会将这个函数从栈顶弹出,这就是调用栈做的事情。而且这不是唯一的问题,一旦你的浏览器开始处理调用栈中的众多任务,它可能会停止响应相当长一段时间。 原文地址: https://blog.sessionstack.com... PS: 好久没写东西了,最近一直在准备写一个自己的博客,最后一些技术方向已经敲定了,又可以...

    Warren 评论0 收藏0

发表评论

0条评论

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