JavaScript是如何工作的:引擎,运行时和调用堆栈的概述!

摘要: 理解JS执行原理。

  • 原文:JavaScript是如何工作的:引擎,运行时和调用堆栈的概述!
  • 作者:前端小智

Fundebug经授权转载,版权归原作者所有。

本文是旨在深入研究JavaScript及其实际工作原理的系列文章中的第一篇:我们认为通过了解JavaScript的构建块以及它们是如何工作的,将能够编写更好的代码和应用程序。我们还将分享构建 SeStHealsStad 时使用的一些经验法则,这是一个轻量级的 JavaScript 应用程序,必须保持健壮和高性能以保持竞争力。

如 GitHut 统计 数据所示,在GitHub中的活动存储库和总推送方面,JavaScript处于顶部。它也不落后于其他类别。

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

事实证明,有很多开发人员每天都在使用JavaScript,但却不知道背后发生了什么。

概述

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

在本文中,我们将详细介绍这些概念,并解释 JavaScrip 实际如何运行。通过了解这些细节,你将能够适当地利用所提供的 API 来编写更好的、非阻塞的应用程序。

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

如果你是一个有经验的JavaScript开发人员,希望它能让您对每天使用的JavaScript运行时的实际工作方式有一些新的见解。

JavaScript引擎

JavaScript引擎的一个流行示例是Google的V8引擎。例如,在Chrome和Node.js中使用V8引擎,下面是一个非常简化的视图:

V8引擎由两个主要部件组成:

  • emory Heap(内存堆) — 内存分配地址的地方
  • Call Stack(调用堆栈) — 代码执行的地方

Runtime(运行时)

有些浏览器的 API 经常被使用到(比如说:setTimeout),但是,这些 API 却不是引擎提供的。那么,他们是从哪儿来的呢?事实上这里面实际情况有点复杂。

所以说我们还有很多引擎之外的 API,我们把这些称为浏览器提供 API 称为 Web API,比如说 DOM、AJAX、setTimeout等等。

然后我们还拥有如此流行的事件循环和回调队列。

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

调用栈

JavaScript是一种单线程编程语言,这意味着它只有一个调用堆栈。因此,它一次只能做一件事。

调用栈是一种数据结构,它记录了我们在程序中的位置。如果我们运行到一个函数,它就会将其放置到栈顶,当从这个函数返回的时候,就会将这个函数从栈顶弹出,这就是调用栈做的事情。

来个栗子:

当程序开始执行的时候,调用栈是空的,然后,步骤如下:

每一个进入调用栈的都称为调用帧。

这能清楚的知道当异常发生的时候堆栈追踪是怎么被构造的,堆栈的状态是如何的,让我们看一下下面的代码:

如果这发生在 Chrome 里(假设这段代码实在一个名为 foo.js 的文件中),那么将会生成以下的堆栈追踪:

"堆栈溢出",当你达到调用栈最大的大小的时候就会发生这种情况,而且这相当容易发生,特别是在你写递归的时候却没有全方位的测试它。我们来看看下面的代码:

当引擎开始执行这段代码时,它首先调用函数“foo”。然而,这个函数是递归的,并且在没有任何终止条件的情况下开始调用自己。因此,在执行的每一步中,相同的函数都会被一次又一次地添加到调用堆栈中,如下所示:

然而,在某些时候,调用堆栈中的函数调用数量超过了调用堆栈的实际大小,浏览器决定采取行动,抛出一个错误,它可能是这样的:

在单个线程上运行代码很容易,因为你不必处理在多线程环境中出现的复杂场景——例如死锁。
但是在一个线程上运行也非常有限制,由于 JavaScript 只有一个调用堆栈,当某段代码运行变慢时会发生什么?

并发与事件循环

当调用堆栈中的函数调用需要花费大量时间来处理时会发生什么情况? 例如,假设你希望在浏览器中使用JavaScript进行一些复杂的图像转换。

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

而且这不是唯一的问题,一旦你的浏览器开始处理调用栈中的众多任务,它可能会停止响应相当长一段时间。大多数浏览器都会这么做,报一个错误,询问你是否想终止 web 页面。

这并不是最好的用户体验,不是吗?

那么,我们怎样才能在不阻塞UI和不使浏览器失去响应的情况下执行大量代码呢?解决方案是异步回调。

这个在下一篇说明,我尽快把原作者的内容整理好!

原文:How JavaScript works: an overview of the engine, the runtime, and the call stack

关于Fundebug

Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有Google、360、金山软件、百姓网等众多品牌企业。欢迎大家免费试用!

JavaScript是如何工作的:引擎,运行时和调用堆栈的概述!相关推荐

  1. JavaScript 对引擎、运行时、调用堆栈的概述理解

    JavaScript 对引擎.运行时.调用堆栈的概述理解  随着JavaScript越来越流行,越来越多的团队广泛的把JavaScript应用到前端.后台.hybrid 应用.嵌入式等等领域. 这篇文 ...

  2. JavaScript是如何工作的:引擎,运行时间以及调用栈的概述

    JavaScript是如何工作的:引擎,运行时以及调用栈的概述 原文:How JavaScript works: an overview of the engine, the runtime, and ...

  3. JVM运行时内存概念-堆栈及新生代、老年代、持久代

    JVM内存有一些按不同标准划分的概念,这里来理清一下. 一.首先java虚拟机规范定义了java运行时数据区在概念上应该有的分区,这是抽象概念不对应也不限制物理上的具体实现,不同的虚拟机可以有不同的实 ...

  4. linux backtrack函数,Linux调用backtrack函数打印程序崩溃时的调用堆栈

    可以给自己的程序都加上这个东西,便于快速的找到错误吧,看到别人都是这么用的 #include #include #include #include //signal 函数用法参考http://www. ...

  5. 经验:VS2017运行时出现“调用目标发生了异常”时的解决方法

    VS2017环境具备代码提示功能,与之前的版本相比,不用再安装编程助手,这是使用中感觉最方便的地方. 不稳定的地方有很多,其中一条是:"调用目标发生了异常" 暂时的解决办法: 1. ...

  6. 运行时动态调用子程序的例子

    代码比较简单,就没有写注释. 处理逻辑就是要求用户输入一个子程序名,然后动态调用,并且用异常机制处理输入的子程序不存在的情况. 当然,如果在 PERFORM 最后用 IF FOUND 就可以不用 TR ...

  7. linux程序崩溃时调用链,Linux 获取并分析程序崩溃时的调用堆栈

    下面是一个小例子,说明了程序出现段错误时,如何打印程序的堆栈信息. #include #include #include #include static void WidebrightSegvHand ...

  8. JavaScript是如何工作的:编写自己的Web开发框架 + React及其虚拟DOM原理

    摘要: 深入JS系列19. 原文:JavaScript是如何工作的:编写自己的Web开发框架 + React及其虚拟DOM原理 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这是专门 ...

  9. JavaScript是如何工作的:与WebAssembly比较及其使用场景

    摘要: WebAssembly未来可期. 原文:JavaScript是如何工作的:与WebAssembly比较及其使用场景 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 这是专门探索 ...

最新文章

  1. 奇瑞a3中控按键图解_纷纷亮相,奇瑞众多黑科技悄然现身,焦点全在星途VX智能座舱上...
  2. linux如何查看硬件驱动,linux查看硬件信息及驱动设备相关整理
  3. layer之jquery 弹窗插件 (最后版本v1.8.5)
  4. 百度android广告sdk下载,IS_Freedom
  5. HTML 5 中的新元素
  6. 互利网上数字金融典型场景: 网络借贷
  7. 再见,中关村“金三角”!
  8. 安裝MAVEN插件(轉)
  9. 无法安装Visual Studio 2010 Service Pack 1
  10. default在php定义什么,default(T)的含义
  11. 【VBA】excel客户数据打印录入控件
  12. python网易云_Python分析网易云音乐近5年热门歌单
  13. python矩形法计算定积分_矩形、梯形法计算定积分的黎曼和
  14. 音视频开发之基于某三方音效的Android native层四声道音频输出
  15. Linux网络入侵检测软件
  16. UVM入门与进阶学习笔记1——UVM概述、类库地图、工厂机制、覆盖方法
  17. NBA球员出手位置分布图
  18. payjs 源码_WordPress插件:Payjs For Ponits基于Payjs开发的积分充值微信支付插件
  19. SCORM课程对接线上课程学习平台
  20. Ntrip通讯协议1.0

热门文章

  1. 树莓派python gpio 模仿iic_树莓派高级GPIO库,wiringpi2 for python使用笔记(五)i2c读取测试...
  2. JAVA day15 Collection(集合)、Iterator迭代器、泛型<E>
  3. html 自定义属性_五道自测题-你我都应知道的HTML小知识
  4. 水箱建模最小二乘法_Comsol Multiphysics for Mac(建模仿真软件)
  5. 期刊计算机仿真地址在哪,计算机仿真杂志社地址
  6. vivo硬件测试员干什么的_vivo的新年礼物:用APEX 2019告诉你5G旗舰机该长啥样
  7. c mysql分页存储过程_mysql 分页存储过程调用报错
  8. c mysql用户登录_SQL语句及5.7.2 mysql 用户管理 c_G
  9. python 发邮件 timeout_python3 发送邮件 出现的问题(新手)
  10. docker部署express项目