首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

剖析engine、runtime、call stack

⼏乎每个⼈都听说过V8引擎这个概念,并且每个⼈都知道JavaScript是单线程或者它使⽤⼀个callback队列。

在这篇⽂章中,我将要深⼊这些细节并且解释JavaScript是如何运⾏的。通过了解这些,有助于帮你写出更好且⽆阻塞的应⽤。

如果你对JavaScript了解尚少,这篇⽂章将要帮你理解为什么JavaScript会显得如此“与众不同”。⽽如果你是⼀位有经验的开发者,这篇⽂章将要给你不同的视⻆理解JavaScript。

JavaScript 引擎

最为⼈熟知的JavaScript引擎是Google V8。它现在是⽤在Chrome和Node内部。下⾯是⼀个很简单的概述图:

通过以上视图,可得知JavaScript引擎包含两个组件:

Memory Heap -- 分配内存的地⽅

Call Stack -- 执⾏代码时,存放栈帧的地⽅

Runtime

⼀些JavaScript开发者使⽤了⼀些“特殊”的api (⽐如setTimeout)。但是这些api却不是由引擎提供的。⽽它们的来历有点复杂。

⽐如DOM、AJAX、setTimeout等是由浏览器提供的,我们称之为WEB APIs。

3. JavaScript引擎和Runtime的区别

⾸先在某些情况下,这两个概念不是明确的,有时甚⾄是可以互换的。

从概念上讲engine负责解析和JIT编译,例如: 把JavaScript中的语⾔编译成机器码。⽽ runtime提供内建的库,可以在程序运⾏时使⽤。所以可以在浏览器中使⽤Window 对象或者DOM API,这些存在于浏览器的runtime。⽽node runtime包含不同的库,⽐如Cluster 和FileSystem API。两个runtime都包含内置的数据类型和常⽤的⼯具,⽐如Console对象。因此Chrome和Node.js共享相同的引擎(V8),但是它们具有不同的Runtime。

Call Stack

JavaScript是单线程,只有⼀个Call Stack。意味着只能在同⼀时间做⼀件事情。Call Stack 是⼀个记录程序运⾏到确定位置的数据结构。⽐如执⾏到某个函数时,函数⼊栈。⽽执⾏完后,函数出栈。这就是Call Stack所要做的⼯作,让我们看看以下例⼦:

开始阶段,Call Stack 是空的。后来,按照以下流程运⾏

stack frame (栈帧): 调⽤栈中的每个条⽬(包括该函数本身,函数运⾏的变量)

在发⽣异常时,Call Stack 运⾏流程可以被打印出来,运⾏以下代码(foo.js)

栈溢出-- 当栈帧数量达到Call Stack最⼤值时就会发⽣。⽽栈溢出是很容易发⽣的,执⾏以下代码

以上函数递归调⽤⾃⼰没有终⽌条件,每⼀次执⾏foo函数,Call Stack就会添加⼀个栈帧。这就像下⾯显示的那样:

当栈帧超过 Call Stack 最⼤限制,浏览器会通过抛出错误终⽌程序,⽐如以下

在单线程上运⾏代码是轻松的,因为不必考虑复杂的场景,⽐如由多线程情况引发的死锁。

但是运⾏单线程也是有缺陷的,因为javascript仅仅有⼀个Call Stack。当处理耗时业务时应该怎么办呢,总不能⼀直等待被处理吧。这时就需要异步。通过EventLoop和Callback Queue构成的异步处理效率就会⼤⼤提⾼。

How JavaScript works: an overview of the engine, the runtime, and the call stack What-is-the-difference-between-javascript-engine-and-javascript-runti

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190618A0AUUA00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券