资讯专栏INFORMATION COLUMN

JavaScript工作机制:第1部分

xiaodao / 2465人阅读

摘要:工作机制第部分本文转载自众成翻译译者网络埋伏纪事链接原文随着越来越受欢迎,开发团队正在将其用在技术栈的各个方面,包括前端后端混合应用嵌入式设备等等。之后,步骤将是如下这样调用栈中的每个条目称为栈帧。

JavaScript工作机制:第1部分

本文转载自:众成翻译
译者:网络埋伏纪事
链接:http://www.zcfy.cc/article/3965
原文:https://blog.sessionstack.com/how-does-javascript-actually-work-part-1-b0bacc073cf

随着JavaScript越来越受欢迎,开发团队正在将其用在技术栈的各个方面,包括 - 前端、后端、混合应用、嵌入式设备等等。

如GitHut统计所示,JavaScript在GitHub中的活动存储库和总推送方面位于前列,在其他方面也不差。

(查看最新的GitHub语言统计信息)。

如果项目越来越依赖于JavaScript,这意味着开发人员必须更深入地了解内部机制,才能利用语言和生态系统提供的所有技术,构建出惊艳的软件。

事实证明,虽然有很多开发人员每天都在使用JavaScript,但并不知道它的工作机制。

概述

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

在这篇文章中,我们将详细介绍所有这些概念,并解释JavaScript的工作机制。通过了解这些细节,您将能够正确利用提供的API,编写更好的非阻塞应用程序。

如果您是一个JavaScript新手,此博文将帮助您了解为什么JavaScript与其他语言相比是如此“怪异”。

而如果您是一位经验丰富的JavaScript开发人员,希望能够提供与您每天使用的JavaScript运行时有关的一些新鲜见解。

JavaScript引擎

JavaScript引擎的一个流行示例是Google的V8引擎。例如,V8引擎在Chrome和Node.js中使用。如下是它看起来像什么的一个简单视图:

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

内存堆 - 这是内存分配发生的地方

调用栈 - 这是您的代码执行所在的栈帧

运行时

浏览器中已经有几个几乎所有JavaScript开发人员都会使用的API(比如 setTimeout)。不过,这些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,这会出问题。

而这不是唯一的问题。一旦浏览器开始处理调用栈中的许多任务,它可能会停止响应很长时间。大多数浏览器通过引发一个错误来采取行动,询问您是否要终止网页。

现在,这不是最好的用户体验,对吧?

那么,如何执行繁重的代码,而不阻塞UI并且不会使浏览器无响应呢?好吧,解决方案是异步回调

我将在教程的第2部分中详细介绍。敬请关注 :)

欢迎关注我的公众号,关注前端文章:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/84847.html

相关文章

  • JavasScript重难点知识

    摘要:忍者级别的函数操作对于什么是匿名函数,这里就不做过多介绍了。我们需要知道的是,对于而言,匿名函数是一个很重要且具有逻辑性的特性。通常,匿名函数的使用情况是创建一个供以后使用的函数。 JS 中的递归 递归, 递归基础, 斐波那契数列, 使用递归方式深拷贝, 自定义事件添加 这一次,彻底弄懂 JavaScript 执行机制 本文的目的就是要保证你彻底弄懂javascript的执行机制,如果...

    forsigner 评论0 收藏0
  • JavaScript 运行机制详解(理解同步、异步和事件循环)

    摘要:从异步过程的角度看,函数就是异步过程的发起函数,事件监听函数就是异步过程的回调函数。事件触发时,表示异步任务完成,会将事件监听器函数封装成一条消息放到消息队列中,等待主线程执行。 1.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊。JavaScrip...

    loonggg 评论0 收藏0
  • PHP程序员学习路线

    摘要:第一阶段基础阶段基础程序员重点把搞熟练核心是安装配置基本操作目标能够完成基本的系统安装,简单配置维护能够做基本的简单系统的开发能够在中型系统中支持某个功能模块的开发。本项不做重点学习,除非对前端有兴趣。 第一阶段:基础阶段(基础PHP程序员) 重点:把LNMP搞熟练(核心是安装配置基本操作) 目标:能够完成基本的LNMP系统安装,简单配置维护;能够做基本的简单系统的PHP开发;能够在P...

    genedna 评论0 收藏0
  • Event Loop - JS执行机制

    摘要:心塞塞根据规范,事件循环是通过任务队列的机制来进行协调的。等便是任务源,而进入任务队列的是他们指定的具体执行任务回调函数。然后当前本轮的结束,主线程可以继续取下一个执行。 依然是:经济基础决定上层建筑。 说明 首先,旨在搞清常用的同步异步执行机制 其次,暂时不讨论node.js的Event Loop执行机制,以下关于浏览器的Event Loop执行机制 最后,借鉴了很多前辈的研究文...

    muddyway 评论0 收藏0
  • 十分钟快速了解《你不知道的 JavaScript》(上卷)

    摘要:最近刚刚看完了你不知道的上卷,对有了更进一步的了解。你不知道的上卷由两部分组成,第一部分是作用域和闭包,第二部分是和对象原型。附录词法这一章并没有说明机制,只是介绍了中的箭头函数引入的行为词法。第章混合对象类类理论类的机制类的继承混入。 最近刚刚看完了《你不知道的 JavaScript》上卷,对 JavaScript 有了更进一步的了解。 《你不知道的 JavaScript》上卷由两部...

    赵春朋 评论0 收藏0

发表评论

0条评论

xiaodao

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<