我的编程空间,编程开发者的网络收藏夹
学习永远不晚

JavaScript内部原理是怎样的

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

JavaScript内部原理是怎样的

本篇文章给大家分享的是有关JavaScript内部原理是怎样的,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

简介

Javascript  是一种奇怪语言,有些人喜欢它,有些人讨厌它。它有许多独特的机制,这些机制在其他流行语言中不存在,也没有对应的机制,还有突出明显的就是代码的执行顺序。

了解浏览器环境,它的组成以及它的工作原理会让我们在编写 JS 时更加自信,并为可能发生的潜在问题做好了充分的准备。

JavaScript引擎

最流行的JavaScript引擎是V8,它是用c++编写的,并被基于Chrome的浏览器使用,如Chrome、Opera甚至Edge。基本上,这个引擎是一个将  JS 转换成机器码并在计算机的中央处理器(CPU)上执行结果的程序。

编译

当浏览器加载 JS  文件时,V8的解析器将其转换为一个抽象语法树(AST)。该树用于生成字节码的解释器。字节码是一种可以通过编译成非优化的机器码来执行的机器码的抽象。V8在主线程中执行它,而优化编译器TurboFan在另一个线程中进行一些优化并生成优化的机器码。

这个管道称为即时(JIT)编译。

JavaScript内部原理是怎样的

调用堆栈

JavaScript  是一种单线程编程语言,只有一个调用堆栈。它意味着我们的代码是同步执行的。每当一个函数运行时,它将在任何其他代码运行之前完全运行。

当V8调用 JS  函数时,它必须将运行时数据存储在某个地方。调用堆栈是内存中由堆栈帧组成的位置。每个堆栈帧对应于一个尚未被调用函数。堆栈结构由以下组成:

  • 局部变量

  • argument 参数

  • 返回地址

如果我们执行一个函数,V8 会将帧推到栈顶。当我们从一个函数返回时,V8 会跳出帧。

JavaScript内部原理是怎样的

如上例所示,在每次函数调用时都会创建一个帧,并在每个return语句中将其删除。

其他所有内容都动态地分配到一个称为堆的大型非结构化内存块中。

堆(Heap)

有时V8在编译时不知道对象变量需要多少内存。此类数据的所有内存分配都发生在堆中。退出分配内存的函数后,堆上的对象继续存在。

V8有一个内置的垃圾收集器(GC)。垃圾收集是内存管理的一种形式。它就像一个收集器,试图释放不再使用的对象占用的内存。换句话说,当一个变量失去所有引用时,GC将该内存标记为不可访问并释放它。

我们可以通过在Chrome开发工具中创建快照来研究堆。

JavaScript内部原理是怎样的

实例化的每个 JS 对象都分组在其构造函数类下。括号中的分组表示不能直接调用的原生构造函数。可以看到有很多(编译代码)和(系统)实例,但也有一些传统的  JS 对象,如Math、String、Array等。

浏览器运行时

V8可以根据标准,同步地使用一个调用堆栈来执行 JS  。但,我们需要渲染UI,需要处理用户与UI的交互。此外,我们还需要在发出网络请求时处理用户交互,对此却无能为力。当所有代码都是同步的时候,我们如何实现并发呢?  这还得感谢浏览器引擎。

浏览器引擎负责用 HTML 和 CSS 渲染页面。在 Chrome 中它被称为Blink。它是WebCore的一个分支,Blink  是一个布局、渲染和文档对象模型(DOM)库。Blink 是用 c++  中实现的,它提供了DOM元素和事件、XMLHttpRequest、fetch、setTimeout、setInterval等 Web api,这些api可以通过  JS 访问。

我们一起思考下面带有setTimeout(onTimeout, 0)的示例:

JavaScript内部原理是怎样的

可以看到,浏览器首先将f1()和f2()函数推入堆栈,然后执行onTimeout。那么上面的示例如何工作?

并发性

setTimeout函数执行后,浏览器引擎立即将setTimeout的回调函数放入一个事件表中。它是一个数据结构,将注册的回调映射到事件,在我们的例子中是onTimeout函数映射到timeout事件。

一旦计时器到时,在本例中,我们将延迟设为0  ms,则立即触发事件,并将onTimeout函数放入事件队列(又名回调队列,消息队列或任务队列)中。事件队列是一种数据结构,由将来要处理的回调函数(任务)组成。

最后且重要的是,事件循环(一个不断运行的循环)检查调用堆栈是否为空。如果是,则执行从事件队列中添加的第一个回调,从而移动到调用堆栈。

函数的处理将继续,直到调用堆栈再次为空。然后,事件循环将处理事件队列中的下一个回调(如果有的话)。

JavaScript内部原理是怎样的

JavaScript内部原理是怎样的

注意onResolve1、onResolve2和onTimeout回调的执行顺序。

阻塞和非阻塞

简单地说,所有 JS 代码都被认为是阻塞的。当 V8 忙于处理堆栈帧时,浏览器被卡住了,应用程序的 UI 被阻塞。用户将无法单击、导航或滚动。直到 V8  完成它的工作,才会处理来自网络请求的响应。

想象一下,我们如果在浏览器中运行的程序中解析图像。

JavaScript内部原理是怎样的

JavaScript内部原理是怎样的

在上面的示例中,事件循环被阻止。它无法处理事件/作业队列中的回调,因为调用堆栈包含这一帧。

Web API  为我们提供了通过异步回调来编写非阻塞代码的可能性。当调用像setTimeout或fetch这样的函数时,我们把所有的工作委托给c++原生代码,它在一个单独的线程中运行。一旦操作完成,回调就被放入事件队列。同时,V8可以继续执行  JS 代码。

使用这种并发模型,我们可以处理网络请求、用户与UI的交互等等,而不会阻塞 JS 执行线程。


对于希望能够解决复杂任务的每个开发人员来说,理解 JS  环境由什么组成是至关重要的。现在我们知道了异步JavaScript是如何工作的,调用堆栈、事件循环、事件队列和作业队列在其并发模型中的角色。

你可能已经猜到的,在V8引擎和浏览器引擎后面还有很多工作要做。然而,我们大多数人只是需要对所有这些概念有一个基本的理解。

以上就是JavaScript内部原理是怎样的,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

JavaScript内部原理是怎样的

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Linq内部执行原理是怎么样的

这篇文章主要介绍了Linq内部执行原理是怎么样的,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Linq内部执行原理LINQ(Language Integrated Query
2023-06-17

Container内部进程监控是怎样的

这篇文章主要介绍“Container内部进程监控是怎样的”,在日常操作中,相信很多人在Container内部进程监控是怎样的问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Container内部进程监控是怎样的
2023-06-05

JavaScript内存泄漏的情况是怎样的

这期内容当中小编将会给大家带来有关JavaScript内存泄漏的情况是怎样的,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1、意外的全局变量。function foo(arg) { bar = "t
2023-06-25

PHP原理和安装是怎样的

PHP原理和安装是怎样的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。PHP 是免费的,并且使用非常广泛。同时,对于像微软 ASP 这样的竞争者来说,PHP 无疑是另一种高
2023-06-04

kubernetes API Server原理分析是怎样的

这篇文章将为大家详细讲解有关kubernetes API Server原理分析是怎样的,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。一:简介k8s API Server提供了k8s各类资源对
2023-06-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录