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

 随着JavaScript越来越流行,越来越多的团队广泛的把JavaScript应用到前端、后台、hybrid 应用、嵌入式等等领域。

这篇文章旨在深入挖掘JavaScript,以及向大家解释JavaScript是如何工作的。我们通过了解它的底层构建以及它是怎么发挥作用的,可以帮助我们写出更好的代码与应用。据 GitHut 统计显示,JavaScript 长期占据GitHub中 Active Repositories 和 Total Pushes 的榜首,并且在其他的类别中也不会落后太多。

如果一个项目越来越依赖 JavaScript,这就意味着开发人员必须利用这些语言和生态系统提供更深层次的核心内容去构建一个令人振奋的应用。然而,事实证明,有很多的开发者每天都在使用 JavaScript,但是却不知道在底层 JavaScript 是怎么运作的。

概述

几乎每个人听说过 V8 引擎的概念,而且,大多数人都知道 JavaScript 是单线程的,或者是它是使用回调队列的。
在这篇文章中,我们将详细的介绍这些概念,并解释 JavaScript 是怎么工作的。通过了解这些细节,你就能利用这些提供的 API 来写出更好的,非阻塞的应用来。如果你对 JavaScript 比较陌生,那么这篇文章将帮助您理解为什么 JavaScript 相较于其他语言显得如此“怪异”。如果您是一位经验丰富的 JavaScript 开发人员,希望它能给你带来一些新的见解,说明 JavaScript 的运行时,尽管你可能每天都会用到它。

JavaScript 引擎

JavaScript 引擎说起来最流行的当然是谷歌的 V8 引擎了, V8 引擎使用在 Chrome 以及 Node 中,下面有个简单的图能说明他们的关系:

这个引擎主要由两部分组成:

  • 内存堆:这是内存分配发生的地方
  • 调用栈:这是你的代码执行时的地方

运行时

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

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

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

调用栈

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

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

让我们来看一看下面的例子:

function multiply(x, y) {
return x * y;
}
function printSquare(x) {
var s = multiply(x, x);
console.log(s);
}
printSquare(5);

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

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

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

function foo() {
throw new Error('SessionStack will help you resolve crashes :)');
}
function bar() {
foo();
}
function start() {
bar();
}
start();

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

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

function foo() {
foo();
}
foo();

当我们的引擎开始执行这段代码的时候,它从 foo 函数开始。然后这是个递归的函数,并且在没有任何的终止条件的情况下开始调用自己。因此,每执行一步,就会把这个相同的函数一次又一次地添加到调用堆栈中。然后它看起来就像是这样的:

然后,在某一时刻,调用栈中的函数调用的数量超过了调用栈的实际大小,浏览器决定干掉它,抛出一个错误,它看起来就像是这样:

 

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

并发与事件循环

调用栈中的函数调用需要大量的时间来处理,那么这会发生什么情况呢?例如,假设你想在浏览器中使用 JavaScript 进行一些复杂的图片转码。

你可能会问?这算什么问题?事实上,问题是当调用栈有函数要执行,浏览器就不能做任何事,它会被堵塞住。这意味着浏览器不能渲染,不能运行其他的代码,它被卡住了。如果你想在应用里让 UI 很流畅的话,这就会产生问题。

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

总结

以上所述是小编给大家介绍的JavaScript 对引擎、运行时、调用堆栈的概述理解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章:

  • 漫谈JS引擎的运行机制 你应该知道什么
  • JavaScript实现显示函数调用堆栈的方法
  • JS实现队列与堆栈的方法
  • java自带的工具Jstack截取进程中的堆栈信息
  • 输出java进程的jstack信息示例分享 通过线程堆栈信息分析java线程
  • JavaScript调用堆栈及setTimeout使用方法深入剖析

文章同步发布: https://www.geek-share.com/detail/2751296348.html

转载于:https://www.cnblogs.com/xxcn/p/9847878.html

JavaScript 对引擎、运行时、调用堆栈的概述理解相关推荐

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

    JavaScript是如何工作的:引擎,运行时和调用堆栈的概述! 摘要: 理解JS执行原理. 原文:JavaScript是如何工作的:引擎,运行时和调用堆栈的概述! 作者:前端小智 Fundebug经 ...

  2. Deno不只是个Javascript运行时

    Deno 是一个安全的 JavaScript 和 TypeScript 运行时,作者是 Ryan Dahl(也是 Node.js 的原作者).Deno 的诞生之初是为了解决 2009 年首次设计 No ...

  3. JavaScript 工作原理(一):引擎,运行时,调用堆栈

    From:https://segmentfault.com/a/1190000014587266 概述 几乎每个人都已经听说过V8引擎这个概念,而且大多人都知道JavaScript是单线程的,并且使用 ...

  4. javascript 堆栈_JavaScript调用堆栈-它是什么以及为什么它是必需的

    javascript 堆栈 The JavaScript engine (which is found in a hosting environment like the browser), is a ...

  5. mfc函数调用堆栈溢出_01 JavaScript 调用堆栈

    什么是 JavaScript  调用栈,为什么它是必要的? JavaScript 引擎是一个单线程解析器,而单线程解析器由堆和单一调用栈组成.浏览器提供 Web APIs,比如:DOM,AJAX 和 ...

  6. JavaScript内存相关初了解:堆栈、引擎、闭包隐患

    目录 闭包 内存简介 内存销毁 内存泄漏 闭包导致内存泄漏 垃圾回收 补充对象池来实现P100 关于Google V8引擎 分析实例 JavaScript引擎 离开作用域的变量被标记为可清理 执行上下 ...

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

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

  8. python调用命令行获取pid_命令行命令/命令运行时的pid及获取

    命令行输入的命令,和命令运行时的PID并不是同一个. 例如有如下一段代码perf_test.py: 1 importsubprocess2 importtime3 importos4 importsi ...

  9. Deep Learning部署TVM Golang运行时Runtime

    Deep Learning部署TVM Golang运行时Runtime 介绍 TVM是一个开放式深度学习编译器堆栈,用于编译从不同框架到CPU,GPU或专用加速器的各种深度学习模型.TVM支持来自Te ...

最新文章

  1. DataGrid 或 DataView 中删除项时告知是否删除
  2. 007-SDK框架之LYWSDKInterfaceProtocol.cpp
  3. 【渝粤教育】电大中专电大中专沟通技巧考试考核试题 (2)作业 题库
  4. OpenCV_04 几何变换:图像缩放+图像平移+图像旋转+仿射变换+透射变换+图像金字塔
  5. 【Python】Numpy中对向量、矩阵的使用
  6. Java进阶 | Proxy动态代理机制详解
  7. 玛丽卡(codevs 1021)
  8. SQL数据库的多表查询
  9. 最新MATLAB R2020b超详细安装教程---亲自安装成功!!!
  10. QT QDir(获取当前路径下的所有文件)
  11. 利用StretchDIBits、CreateDIBSection、CreateDIBitmap三种方法显示内存位图
  12. Telink/BDT使用说明
  13. 【LaTex】 Font “FandolSong-Regular“ does not contain requested(fontspec)Script “CJK“.如何抑制此种警告?
  14. iOS 相机开发总结
  15. 利用接口检查日期是否为法定节假日
  16. 机器学习专有名词归纳
  17. JAVA多线程:龟兔赛跑
  18. bigworld源码分析(3)——dbMgr分析
  19. 信息系统项目管理师考前10天极限冲刺+答案(七)
  20. LORA芯片ASR6505无线远距离传输8位MCU

热门文章

  1. oracle重命名日志成员出错,Oracle日志文件
  2. php pecl memcached,php – 安装PECL Memcached错误
  3. phpsocket服务端和VC客户端通信实例
  4. 一份详尽的IPC$入侵资料
  5. 库存生产-实用sql知识:如何在保证去重分组的情况下获取组内最新数据(可按时间排序),distinct +group by +嵌套结果 的联合妙用
  6. 第二章 PX4-Pixhawk-RCS启动文件解析
  7. MIPS 汇编指令学习
  8. C++11库中 steady_clock , system_clock和high_resolution_clock的区别
  9. nginx 源码调试
  10. Docker环境下报错:unknown group ‘mlocate‘ in statoverride file E: Sub-process /usr/bin/dpkg