程序员的 JavaScript 代码该如何让计算机搞懂?
myzbx 2024-12-08 16:39 29 浏览
出自程序员之手的 JavaScript 代码,该如何变成计算机所能理解的机器语言呢?本文将带你走进 JavaScript 引擎内部,一探究竟。
作者 | Lydia Hallie
译者 | 弯月,责编 | 屠敏
以下为译文:
JavaScript 很酷(这一点不用我说),但一台机器究竟是怎样理解我们编写的代码呢?作为JavaScript 开发者,我们通常不需要处理编译器的东西。但是,了解 JavaScript 引擎的基础知识,知道它如何将人类能看懂的JS代码变成机器能理解的东西,是绝对是有好处的!
注意:这篇文章主要根据 Node.js 和基于 Chromium 的浏览器使用的V8引擎撰写。
当HTML解析器遇到代码中的script标签时,就会从网络、缓存或者已安装的service worker里加载源代码。这一步的结果就是脚本内容,以字节流的形式返回,这个字节流需要解码器来处理!字节流解码器会在字节流下载的时候进行解码。
字节流解码器根据流中的字节数据来创建符号(token)。例如,0066解码成f,0075解码成u,006e解码成n,0063解码成c,0074解码成t,0069解码成i,006f解码成o,006e解码成n,然后是一个空格。似乎你写了一个function!这是JavaScript的保留关键字,因此就会创建一个符号,然后发给解析器(以及预解析器,我的GIF图里没有说,但我会稍后解释)。字节流中的其余内容也会类似处理。
引擎有两个解析器:一个是预解析器(pre-parser),另一个是解析器(parser)。预解析器只负责尽早检查符号,找出其中的语法错误。这样可以减少在代码中发现错误所需的时间。否则这些错误就要由解析器负责发现了!
如果没有错误,解析器就会根据它从字节流解码器收到的符号创建节点,然后使用这些节点创建一颗抽象语法树,简称AST。
接下来就是解释器(interpreter)出场了!解释器会遍历整个AST,根据AST的内容生成字节码。字节码生成完成后,就会删除AST以释放更多的内存。这样就得到了机器能够运行的代码!
虽然字节码很快,但它还可以更快。字节码在运行的时候会生成信息。它可以检测到哪些行为会更频繁发生,哪些类型的数据会更经常被使用。如果某个函数被调用了许多次,那么就可以通过优化加快速度!
字节码会连同生成的类型反馈一起发送到优化编译器(optimizing compiler)。优化编译器会处理负责处理字节码和类型反馈,然后生成高度优化过的机器码。
JavaScript 是一个动态类型语言,这意味着数据类型经常会变化。如果 JavaScript 引擎每次都必须检查值的类型,那就会非常慢。
然而,JavaScript 的引擎使用了一种叫做内联缓存(inline caching)的方法。它会在内存中缓存代码,期待着以后会用同样的行为返回同样的值!比如,一个函数被调用100次,到目前为止每次都返回同样的值。那么引擎就会假设该函数在第101次调用时依然会返回同样的值。
我们假设有一个函数sum,到目前为止每次调用都使用两个数值作为参数:
上面的调用会返回3!下次被调用时,引擎就会假设我们依然会用两个数值进行调用。
如果这个假设正确,那就不需要进行动态查找,可以直接使用内存中保存的值。否则,如果假设错误,就会进行反优化,将代码从优化过的机器码恢复成原始的字节码。
例如,假设下次调用时传递了一个字符串而不是数值。由于 JavaScript 是动态类型,这样做不会产生任何错误!
这意味着数字2会被强制转换成字符串,然后函数会返回字符串"12"。因此引擎会去执行字节码,然后更新类型反馈。
希望这篇文章对你有帮助性!当然,引擎还有许多其他方面我没有讨论到(如JS heap,call stack等),也许以后会讨论!如果你对JavaScript的内部原理有兴趣,我强烈建议你自己做一些研究,V8是开源的,关于其工作原理的文档也非常好!
原文:https://dev.to/lydiahallie/javascript-visualized-the-javascript-engine-4cdf
本文为 CSDN 翻译,转载请注明来源出处。
【End】
【成就一亿技术人】各位撸代码的大佬们,CSDN重磅推出升级版原力计划。只要是原创,只要你首发,现在,都拥有上首页的幸运可能。我们衷心地希望,这一代程序员网红就是你,详情戳海报~~
- 上一篇:一文带你搞懂搭建企业级的 npm 私有仓库
- 下一篇:JavaScript 简史
相关推荐
- 资深架构师亲授,从堆栈到GC,一篇文章打通任督二脉!
-
“又双叒OOM了?”“服务半夜崩了,日志全是`java.lang.OutOfMemoryError`...”“GC停顿太长,用户投诉卡顿!”如果你也常被这些问题折磨,根本症结往往在于:你对Java...
- Java JAR 启动内存参数配置指南:从基础设置到性能优化
-
在启动Java可执行JAR文件时,合理配置JVM内存参数是保障应用稳定性和性能的关键。本文将系统讲解如何通过命令行参数、环境变量等方式指定内存配置,并结合实际场景提供优化建议。一、核心内存...
- 浏览器存储"四大家族":谁才是你的数据管家?
-
当你关闭浏览器再重新打开,登录状态为何还在?购物车商品为何不会消失?这些"记忆"背后,藏着浏览器存储的"四大家族"——Cookie、localStorage、sessi...
- SOP与SIP深度解析(sop与soic)
-
SOP(标准作业程序)与SIP(标准检验程序)是确保产品质量和生产效率的两大支柱,分别聚焦于生产执行和质量验证。一、核心区别:目标与作用域维度SOP(标准作业程序)SIP(标准检验程序)定位指导“如何...
- Java 技术岗面试全景备战!从基础到架构的系统性通关攻略分享
-
Java技术岗的面试往往是一项多维度的能力检验。本文将会从核心知识点、项目经验到面试策略,为你梳理一份系统性的备战攻略!需要的同学可以私信小编【学习】一、技术基础:面试的“硬性指标”1.最重要的还是...
- C++11 新特性(c++11新特性 pdf)
-
一、核心语言革新移动语义与右值引用通过&&标识临时对象(右值),实现资源转移而非复制。例如移动构造函数将原对象资源指针转移后置空,避免深拷贝,极大优化容器操作性能。12类型推导auto:自动推导变量类...
- 2026年前每个开发者都应该学习的技能
-
优秀开发者和伟大开发者之间的差距正在快速扩大。随着AI工具的爆炸式增长、自动化工作流程和日益复杂的技术栈,开发者不能再仅仅"知道如何编码"了。在2026年及以后,您的优势不仅仅是编写代...
- 看一看,Python这四种作用域你都知道吗?
-
点赞、收藏、加关注,下次找我不迷路一、啥是作用域?先打个比方比如说,你在自己的卧室(相当于一个小空间)里放了一本书,这本书在卧室里随便你怎么看,这就是这本书在卧室这个"作用域"内...
- 抛弃立即执行函数 (IIFE),拥抱现代 JavaScript 块级作用域
-
IIFE(ImmediatelyInvokedFunctionExpression)曾是JavaScript开发中的重要工具,但随着ES6+的块级作用域特性,我们现在有了更优雅的替代...
- 2025 年是时候重新认识 Symbol 的八大特性了?
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!1.什么是Symbol原始类型在J...
- 函数、表达式与控制流:Rust 的核心语法构建块
-
在上一篇中我们了解了变量与类型,本篇将深入函数、表达式与控制流的使用,让你的代码更具逻辑性。一、函数定义与调用函数是组织和复用代码的基本单元。在Rust中,使用fn关键字定义函数:///计算...
- 所有权、借用与生命周期:理解 Rust 的核心机制
-
上一篇我们学习了函数、表达式和控制流,这一篇将正式进入Rust最核心、最独特的语言机制:所有权系统。一、为什么需要所有权机制?在C/C++中,内存管理依赖开发者手动操作,容易出现野指针、重复...
- Rust 语言的借用规则:构筑安全内存管理体系的核心保障机制
-
前言在系统级编程范畴内,内存安全始终是一项极具挑战性的关键议题。Rust语言凭借其独树一帜的「借用规则」(BorrowingRules),于编译阶段便有效规避了诸如空指针、野指针以及数据竞争等一系...
- 函数编写指南:参数、返回值与作用域实战详解
-
你是否在编写函数时遇到过参数传递混乱、返回值逻辑不清晰,或者变量作用域导致的奇怪bug?别担心,这篇文章将用最通俗的语言和实战案例,带你彻底搞懂函数的核心三要素:参数、返回值与作用域。一、参数:灵活...
- 服务器频繁报错?5 步教你快速排查修复!运维必看!
-
服务器突然报错、网站打不开、数据库连不上……这些问题是不是让你头大?别慌!今天教你一套「望闻问切」的排查法,90%的服务器故障都能轻松解决!一、定位错误类型:先看日志再动手1.日志是关键系统日志...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (32)
- 时钟启动 (33)
- HTML 游戏 (34)
- JS Loop For (32)