JavaScript是如何工作的:引擎的概述、运行时、调用栈

译者:Ar0nW

译文地址:https://ar0n.wang/2017/08/31/how-does-javascript-actually-work-part-1/

原文地址:https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf

由于JavaScript越来越受欢迎,许多开发团队也将其利用在许多层面上,前端,后端,混合型应用,嵌入式设备等等。

Githutstats, JavaScript在github的活跃仓库和Push统计上名列前茅。在其他排行上,也没有落后于其他仓库的活跃程度。

查看最新的GitHub语言统计

如果项目较多地依赖于JavaScript,那么意味着开发人员必须更深入的了解内部机制,然后利用JavaScript语言的一切和生态系统去构建一个令人惊奇的应用。

事实证明,有很多的开发人员每天都在使用JavaScript,但并不知道底层做了哪些操作。

概述


大多数人已经知道V8引擎是一个什么样的概念,并且大多数人都知道JavaScript单线程的,或者说它使用了一个回调队列。

在这篇文章中,我们会详细讲解一下这些概念并解释JavaScript是如何运行的。通过了解这些细节,你将可以正确地利用提供的API写出更好的、非阻塞的应用。

如果你是JavaScript新手,这篇文章将会让你明白为什么JavaScript与其他语言对比起来有如此多的“怪异”特性。

如果你是个有经验的JavaScript开发人员,希望它会带给你一些关于JavaScript运行时的新看法。

JavaScript引擎


一个流行的JavaScript引擎的例子是google的V8引擎, 被应用在Chrome和Node.js的内部。这里有一个简化的例子:

这个引擎由两个主要的组件构成:

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

调用栈 — 这是你的代码在栈帧中执行的地方

运行时


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

所以,它们是从哪儿来的呢?

事实证明,现实是有点儿复杂的。

因此,实际上除了JavaScript引擎以外,还有其他的组件。其中有个组件就是由浏览器提供的,叫Web APIs,像DOM,AJAX,setTimeout等等。

然后还有就是非常受欢迎的事件循环回调队列

调用栈


JavaScript是单线程的编程语言,意味着它有一个单一的调用栈。因此它只能在同一时间做一件事情。

调用栈是一种数据结构,它基本上记录了我们在程序中的什么位置。如果我们步入一个函数中,我们会把这些数据放在堆栈的顶部。如果我们从一个函数中返回,这些数据将会从栈顶弹出。这就是堆栈的用途。

我们来看个例子:

function multiply(x, y) {

     return x * y;

}

function printSquare(x) {

     vars = multiply(x, x);

     console.log(s);

}

printSquare(5);

当JavaScript引擎开始执行这段代码的时候,调用栈是空的。

之后将会执行如下的步骤:

调用栈中的每个条目叫做栈帧

这就是当一个异常抛出时,堆栈跟踪是如何被构造的 — 当异常发生时,这基本上是 调用栈的状态。让我们来看如下的代码:

function foo() {

     thrownewError('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去做一些复杂的图像变换。

你可能会问 — 这为什么是一个问题?问题是当调用栈上有函数在执行时,浏览器实际上还不能做其他事 — 因为它被阻塞了。这意味着浏览器不能做渲染,它不能运行任何其他的代码,它只是卡住了。如果你想要在你的应用中有一个流畅的界面,这就产生了问题。

而且这不是仅有的问题。一旦你的浏览器开始在调用栈上处理非常多的事务时,它可能会停止响应很长一段时间。和大多数浏览器一样会引发一个错误,问你是否要终止这个web页面。

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

因此, 我们怎样才能在执行大量代码的时候不会阻塞用户界面并造成浏览器的未响应?解决办法是异步回调

这将在《JavaScript是如何工作的》第2部分中详细解释,请继续关注:)

在此期间,如果你正在为你的JavaScript Web应用重现和理解某些问题处于困难期,那就去SessionStack看一看。SessionStack会记录你的Web应用上的任何东西:所有DOM的变化,用户交互,JavaScript异常,堆栈追踪,失败的网络请求,和调试信息。

使用SessionStack,你可以重放在web应用中的问题,并且你将看到发生在你的用户那儿的所有问题。

有一个免费使用的计划允许你使用它

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,135评论 6 514
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,317评论 3 397
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,596评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,481评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,492评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,153评论 1 309
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,737评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,657评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,193评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,276评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,420评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,093评论 5 349
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,783评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,262评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,390评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,787评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,427评论 2 359

推荐阅读更多精彩内容