原文地址:https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf(需要翻墙)
随着javascript变得越来越流行,很多团队的技术栈都开始使用它,比如前端、后端、hybrid、嵌入式设备等。
这篇文章是一个系列旨在深入了解JavaScript它实际上是如何运行的,我们认为,通过了解JavaScript的运行原理可以让你编写更好的代码和应用程序
如GitHut统计数据所示,JavaScript是活跃在顶部对于Repositories和Pushes,它不会落后太多其他类别。
如果项目越来越依赖于JavaScript,这意味着开发人员必须利用语言和生态系统提供的所有内容,对内部进行更深入的了解,以便构建出色的软件。
事实证明,有很多开发人员每天都在使用JavaScript,但却不了解幕后发生的事情。
概述
几乎每个人都已经听说过V8引擎作为一个引擎,大多数人都知道JavaScript是单线程的,或者它使用的是回调队列。
如果您对JavaScript比较陌生,那么这篇博文将帮助您理解为什么JavaScript与其他语言相比如此“奇怪”。
如果您是一位经验丰富的JavaScript开发人员,希望它会为您提供一些关于JavaScript的新见解。
JavaScript 引擎
Google的V8是使用最广泛的JavaScript引擎,它被使用在node.js和chrome浏览器当中,这是简化后的样子:
这个引擎包含两个组件:
- 内存堆——这个是内存分配发生的地方
- 调用堆栈——这是JavaScript代码执行的数据帧所在的地方
运行时
有些API在浏览器中已经被几乎所有的JavaScript开发人员使用过(比如:setTimeout),这些API并不是引擎所提供的。
那么是来自哪儿的呢?事实证明,它是有点复杂。
调用堆栈
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的工作原理”系列中的第2部分进行更详细的解释:“V8引擎内部+关于如何编写优化代码的5个技巧”。
后续文档翻译会陆续跟进!!
欢迎关注玄说前端公众号,后续将推出系列文章《一个大型图形化应用0到1的过程》,此账户也将同步更新