【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述

栏目: JavaScript · 发布时间: 6年前

内容简介:原文地址:https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf(需要翻墙)随着javascript变得越来越流行,很多团队的技术栈都开始使用它,比如前端、后端、hybrid、嵌入式设备等。这篇文章是一个系列旨在深入了解JavaScript它实际上是如何运行的,我们认为,通过了解JavaScript的运行原理可以让你编写更好的代码和应用程序

原文地址:https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf(需要翻墙)

随着javascript变得越来越流行,很多团队的技术栈都开始使用它,比如前端、后端、hybrid、嵌入式设备等。

这篇文章是一个系列旨在深入了解JavaScript它实际上是如何运行的,我们认为,通过了解JavaScript的运行原理可以让你编写更好的代码和应用程序

如GitHut统计数据所示,JavaScript是活跃在顶部对于Repositories和Pushes,它不会落后太多其他类别。

【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述

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

事实证明,有很多开发人员每天都在使用JavaScript,但却不了解幕后发生的事情。

概述

几乎每个人都已经听说过V8引擎作为一个引擎,大多数人都知道JavaScript是单线程的,或者它使用的是回调队列。

在这篇文章中,我们将详细介绍这些概念,并解释JavaScript实际运行的方式。通过了解这些详细信息,您将能够编写更好的、非阻塞的应用程序,以及正确地利用所提供的API。

如果您对JavaScript比较陌生,那么这篇博文将帮助您理解为什么JavaScript与其他语言相比如此“奇怪”。

如果您是一位经验丰富的JavaScript开发人员,希望它会为您提供一些关于JavaScript的新见解。

JavaScript 引擎

Google的V8是使用最广泛的JavaScript引擎,它被使用在node.js和chrome浏览器当中,这是简化后的样子:

【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述

这个引擎包含两个组件:

  • 内存堆——这个是内存分配发生的地方
  • 调用堆栈——这是JavaScript代码执行的数据帧所在的地方

运行时

有些API在浏览器中已经被几乎所有的JavaScript开发人员使用过(比如:setTimeout),这些API并不是引擎所提供的。

那么是来自哪儿的呢?事实证明,它是有点复杂。

【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述

有一些叫做Web API的东西,它们是由浏览器提供的,比如DOM,AJAX,setTimeout等等。

然后,它还有 事件循环回调队列

调用堆栈

JavaScript是一种单线程编程语言,这意味着它只有一个Call Stack(调用堆栈)。因此,它只能一次做一件事。调用栈是一种数据结构,它基本上记录了代码运行在程序中的位置。如果我们运行函数,将把它放在堆栈的顶部。如果我们从函数返回,我们会从堆栈的顶部弹出来。

这就是所有堆栈都可以做到的。

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

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

当这个引擎开始执行这个代码的时候,堆栈目前是空的,之后,步骤如下:

【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述

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

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

function foo() {
    throw new Error('SessionStack will help you resolve crashes :)');
}function bar() {
    foo();
}function start() {
    bar();
}start();复制代码

如果这份代码在chrome当中执行(代码文件被命名成foo.js),堆栈将会报出如下错误:

【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述

爆栈 ”——当达到最大调用堆栈大小时会发生这种情况,这很容易发生,特别是如果你使用递归而没有测试你的代码。

看看这个示例代码:

function foo() {
    foo();
}foo();复制代码

当引擎开始执行这份代码的时候,它将开始调用“foo”函数,然而这个函数是一个调用自身并且没有任何终止条件的递归函数,因此,每一步执行,相同的函数会一遍又一遍被添加到调用堆栈,如下图:

【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述

在某种程度上,函数调用在调用堆栈的数量超过实际的调用堆栈的大小,浏览器会决定采取行动,通过抛出一个错误,如下:

【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述

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

由于JavaScript只有一个Call Stack,在单个线程上运行也是非常有限的。当运行变慢时会发生什么?

并发和事件循环

如果在调用堆栈中有函数调用需要花费大量时间才能处理,会发生什么?

例如,假设您想在浏览器中使用JavaScript进行一些复杂的图像转换。

你可能会问 - 这怎么会是一个问题?

问题是,虽然调用堆栈具有执行功能,但浏览器实际上无法执行任何其他操作当它在执行其他代码的时候 - 它会被阻塞。这意味着浏览器无法渲染,它无法运行任何其他代码,它被卡住了。如果您想在应用中使用流畅的UI,这也是一个问题。

这不是唯一的问题。

一旦您的浏览器开始在调用堆栈中处理很多的任务,它可能会在相当长的时间内停止响应。

大多数浏览器通过引发错误来采取行动,询问您是否要终止网页。

【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述

这样用户体验会变得很不好。

那么,如何在不阻止UI并使浏览器无响应的情况下执行繁重的代码呢?

好吧,解决方案是 异步回调

这将在“JavaScript的工作原理”系列中的第2部分进行更详细的解释:“ V8引擎内部+关于如何编写优化代码的5个技巧 ”。

后续文档翻译会陆续跟进!!

欢迎关注玄说前端公众号,后续将推出系列文章《一个大型图形化应用0到1的过程》,此账户也将同步更新

【译】JavaScript的工作原理:引擎,运行时和调用堆栈的概述


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

现代编译原理

现代编译原理

Andrew W.Appel、Maia Ginsburg / 人民邮电 / 2005-9 / 59.00元

《现代编译原理:C语言描述(英文版)(本科)》全面讲述了现代编译器的各个组成部分,包括:词法分析、语法分析、抽象语法、语义检查、中间代码表示、指令选择、数据流分析、寄存器分配以及运行时系统等。与大多数编译原理的教材不同,《现代编译原理:C语言描述(英文版)(本科)》采用了函数语言和面向对象语言来描述代码生成和寄存器分配,对于编译器中各个模块之间的接口都给出了实际的 C 语言头文件。 全书分成两部分......一起来看看 《现代编译原理》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

SHA 加密
SHA 加密

SHA 加密工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具