博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript | 剖析engine、runtime、call stack
阅读量:4083 次
发布时间:2019-05-25

本文共 1544 字,大约阅读时间需要 5 分钟。

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

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

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

  1. JavaScript 引擎

 

 

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

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

  • Memory Heap -- 分配内存的地⽅
  • Call Stack -- 执⾏代码时,存放栈帧的地⽅
  1. Runtime

 

 

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

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

  1. 3. JavaScript引擎和Runtime的区别

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

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

  1. 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

转载地址:http://yqani.baihongyu.com/

你可能感兴趣的文章
路由选择算法
查看>>
Objective-C 基础入门(一)
查看>>
Objective-C 基础入门(三) 读写文件与回调
查看>>
C++ STL标准库与泛型编程(一)概述
查看>>
C++ STL标准库与泛型编程(四)Deque、Queue、Stack 深度探索
查看>>
C++ STL标准库 算法
查看>>
JVM内存模型_Minor GC笔记
查看>>
SpringCloud学习之PassCloud——(一)PassCloud源代码下载
查看>>
Linux下安装Python环境并部署NLP项目
查看>>
Nginx篇-springCloud配置Gateway+Nginx进行反向代理和负载均衡
查看>>
Nginx篇-Nginx配置动静分离
查看>>
缓存篇-Redis缓存失效以及解决方案
查看>>
缓存篇-使用Redis进行分布式锁应用
查看>>
缓存篇-Redisson的使用
查看>>
phpquery抓取网站内容简单介绍
查看>>
找工作准备的方向(4月22日写的)
查看>>
关于fwrite写入文件后打开查看是乱码的问题
查看>>
用结构体指针前必须要用malloc,不然会出现段错误
查看>>
Linux系统中的美
查看>>
一些实战项目(linux应用层编程,多线程编程,网络编程)
查看>>