javasctipt 工作原理之调用栈

# 译者注

medium 是一个国外高质量论坛,里面的文章主打高质量,涉及的领域广泛,笔者于翻墙后不久,在学习react的时候,有一些动画问题百度不出来,然后去了google,最后搜到一篇,真正解决了我的问题的文章,经过一翻查阅,发现能在这个网站发布文章的人,都是有实力的人,而且文章都是原创,由于需要翻墙,而且是全英,小弟就在此为国内新手,且英文能力欠缺的开发者提供一丁点的帮助.(本人英文能力也是水得一匹,没把握的点我会以自己的理解翻译并且把原文或者解释写在圆括号里)

注意: 以下全部是概念,经验丰富的老鸟可以离场啦

------------------------

正文从这里开始

随着 javascript 的流行,团队们正在利用javascript来支持多个级别的技术栈,包括前端,后端,混合开发,嵌入式设备,以及更多

这篇文章旨在成为`深入挖掘JavaScript和实际上他是怎么工作的`系列文章中的第一篇:我们通过知道javascript的模块(Building blocks)和他们如何组合在一起工作来写更好的代码和应用.我们还会分享一些我们构建sessionStarck(这是一款主打反馈功能的产品)时的经验法则,一款轻量级的javascript应用为了保持竞争力,必须时要健壮和高性能.

据githut stats(这是一个统计网站,根据gihub的数据来进行语言统计)的数据来看 , JavaScript 是github 上 活跃库最多的,和提交数最多的语言,这让他不会落后于其他类别.

如果项目变得如此依赖于JavaScript,这就意味着,为了开发惊艳的软件(可以理解为程序),开发者不得不利用这个语言和生态系统(JavaScript生态)提供的一切,对内部的更深入和更深入的了解.

事实证明,有很大一部分的开发者每天都在使用javascript,但是却不知道javascript 在底层干了啥(原文很长,其实就是这个意思,英文还真的是...)

## 上面在扯(外国人也挺喜欢扯的),现在应该开始了(原文这个标题叫Overview)

基本上每个人都知道 v8 引擎这个概念了,大多数人知道javascript 是一个单线程语言 或者是那个使用回调队列的语言.

这篇文章,我们将跑通哪些概念的细节和说明javascript是如何运行的,通过知道这些细节,你能够正确的使用提供的api书写更好的,非阻塞的应用.

如果你是一个javascript新手,这篇文章能让你知道为什么javascript对比与其他语言,为什么如此神奇.

如果你是一个有经验的javascript开发者,我也希望如此,这会给你一些关于javascript运行时是怎么工作的闪亮的灵感(或者说新的见解).

## javascript引擎(尼玛现在才开始)

google v8 引擎是一个了流行的例子,nodejs 和 chrome 都是使用这个引擎,这里是一个简单的他看起来是什么的图


这个引擎看起来像是两个组件.

* memory Heap: 这是内存分配的位置

* call Stack: 这是你的代码执行时,堆栈帧(starck frame)的位置

## 运行时

在浏览器中有一些api已经被几乎所有的javascript开发者使用了,例如 setTimeout 这些api,然而,他们不是又引擎提供的.

那么,他们从哪里来的呢?

其实这有点复杂.(下面怕是要听不懂了)


看,我们有引擎,但是其实我们还有很多东西.我们有那些浏览器提供的web apis,例如 DOM, AJAX, setTimeout等等.

而且,我们还有流行的事件循环(even loop)和回调队列(callback queue)

## 调用栈(回调队列跟调用栈其实意思差不多,不过栈跟队列是两种不同的数据结构)

javascript是一个单线程的编程语言(repeat又repeat,都说几次了),这意味着他有一个调用栈,因此,他一次只能做一件事情.

调用栈是一个记录了我们在程序中的位置的数据结构,如果我们跳进一个function,我们把这个函数放进栈的顶部(栈是一种先进后出的数据结构),如果我们从function中return出来,我们就从栈的顶部跳了出来,这就是栈能做的事情.

让我们来看一个例子:

```js

function multiply(x, y) {

    return x * y;

}

function printSquare(x) {

    var s = multiply(x, x);

    console.log(s);

}

printSquare(5);

```

当引擎执行这段代码的时候,调用栈(call stack)是空的,当进入printSquare的时候,栈上添加了一个函数,在printSquare中我们又进入了multiply中,此时栈的顶部又添加了一个函数,当我们从multiply中return的时候,栈就把顶部的函数弹出,此时我们就回到了printSquare里,然后执行完printSquare后引擎自动return undefined 以结束这个函数的执行.

栈的每一次变化就想下面这样:


栈中的每一个条目(entry)叫坐堆栈帧(stack frames)上面有提到

这就是一个异常抛出时,栈追踪是如何被构造的(how stack traces are being constructed)---这取决于异常发生的时候,回调栈的状态.(突然跑异常去了,其实是想说明,异常就是通过调用栈实现的)

```js

function foo() {

    throw new Error('SessionStack will help you resolve crashes :)');

}

function bar() {

    foo();

}

function start() {

    bar();

}

start();

```

如果这段代码在chrome执行,会产生下边的栈追踪(其实就是一个错误)

"栈坏了"(blowing the stack) --- 这发生在当你把栈放满了的时候(下面还说了一大推,还贴了代码,其实就是死递归)

当引擎执行死递归的时候,会不停的调用同一个方法.看起来像下面这样.


然而,函数在调用栈上调用的数量超过了调用栈的实际大小,浏览器决定要采取行动了,所以他抛出了一个错误,看起来是这样的


在单线程上运行代码可以很容易,因为你不用去处理多线程中的复杂场景,例如,死锁.

但是,运行在单线程上也有他的限制,由于javascript只有一个调用栈,若是程序执行得很慢怎么办?

## 并发和事件循环(even loop)

当你有函数调用在调用栈(call stack)里为了一个任务花费了大额的时间会发生什么?例如,想象一下,你要在浏览器了做一个复杂的图片转性(transfromation).

你可能会问--为什么这是一个问题?问题是调用栈有函数在运行,浏览器就不能做其他的事情,这就造成了阻塞,这意味这浏览器不能渲染,它不能运行任何的其他代码,它卡住了,如果你想你的app 的ui界面流畅,那么这就是一个问题.

然而,这不是唯一的问题,一旦你的浏览器在调用栈开始了很多的任务,这可能会在很长的一段时间内失去响应.而很多的浏览器会抛出一个错误,然后问你是否要关闭网页.

现在,这不是一个最好的用户体验,对吧?

那么,我们要如何处理这种需要很长时间执行的代码呢?嗯~,解决办法就是异步回调

这会再第二篇文章中详细说明.

下面开始买他们产品的广告了,就不翻译了.

原文第二篇我有尽快找时间翻译,尽量不让读者等太久.

写作新手,还望大家多多关注,多多点赞.让我小小的开心一下呗.

原文

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

推荐阅读更多精彩内容

  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,150评论 0 13
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,490评论 1 45
  • 过去上年纪的人总爱对年轻人说:“咱是山西洪洞县老鹳窝底下的人。”为了证实这种说法,老人们总是让孩子们看小脚趾甲,说...
    3d9e9483439f阅读 707评论 0 1
  • 我叫孙文宇,今年八岁了。我们家有三口人,我,爸爸和妈妈,住在小河转弯的地方。村子里有很多小伙伴,我们一起上学,一起...
    尹向阳阅读 621评论 0 0
  • 今日感恩 1.感恩今早按时到达会场,当门神的感觉蛮好。 2.感恩红力姐的午饭邀请,心里暖。 3.感恩陈姐的关注和关...
    露颖_阅读 85评论 0 0