资讯专栏INFORMATION COLUMN

javasctipt 工作原理之调用栈

Pines_Cheng / 3301人阅读

摘要:译者注翻译一个对新手比较友好的工作原理解析系列文章注意以下全部是概念经验丰富的老鸟可以离场啦正文从这里开始随着的流行团队们正在利用来支持多个级别的技术栈包括前端后端混合开发嵌入式设备以及更多这篇文章旨在成为深入挖掘和实际上他是怎么工作的系列

译者注

翻译一个对新手比较友好的 JavaScript 工作原理解析系列文章

注意: 以下全部是概念,经验丰富的老鸟可以离场啦

正文从这里开始

随着 javascript 的流行,团队们正在利用javascript来支持多个级别的技术栈,包括前端,后端,混合开发,嵌入式设备,以及更多

这篇文章旨在成为深入挖掘JavaScript和实际上他是怎么工作的系列文章中的第一篇:我们通过知道javascript的模块(Building blocks)和他们如何组合在一起工作来写更好的代码和应用.我们还会分享一些我们构建sessionStarck(这是一款主打反馈功能的产品)时的经验法则,一款轻量级的javascript应用为了保持竞争力,必须时要健壮和高性能.

据githut stats(这是一个统计网站,根据gihub的数据来进行语言统计)的数据来看 , JavaScript 是github 上 活跃库最多的,和提交数最多的语言,这让他不会落后于其他类别.

如果项目变得如此依赖于JavaScript,这就意味着,为了开发惊艳的软件(可以理解为程序),开发者不得不利用这个语言和生态系统(JavaScript生态)提供的一切,对内部的更深入和更深入的了解.

事实证明,有很大一部分的开发者每天都在使用javascript,但是却不知道javascript 在底层干了啥(原文很长,其实就是这个意思,英文还真的是...)

Overview

基本上每个人都知道 v8 引擎这个概念了,大多数人知道javascript 是一个单线程语言 或者是那个使用回调队列的语言.

这篇文章,我们将跑通哪些概念的细节和说明javascript是如何运行的,通过知道这些细节,你能够正确的使用提供的api书写更好的,非阻塞的应用.

如果你是一个javascript新手,这篇文章能让你知道为什么javascript对比与其他语言,为什么如此神奇.

如果你是一个有经验的javascript开发者,我也希望如此,这会给你一些关于javascript运行时是怎么工作的闪亮的灵感(或者说新的见解).

javascript引擎

google v8 引擎是一个了流行的例子,nodejs 和 chrome 都是使用这个引擎,这里是一个简单的他看起来是什么的图

这个引擎看起来像是两个组件.

memory Heap: 这是内存分配的位置

call Stack: 这是你的代码执行时,堆栈帧(starck frame)的位置

运行时

在浏览器中有一些api已经被几乎所有的javascript开发者使用了,例如 setTimeout 这些api,然而,他们不是又引擎提供的.

那么,他们从哪里来的呢?

其实这有点复杂.

看,我们有引擎,但是其实我们还有很多东西.我们有那些浏览器提供的web apis,例如 DOM, AJAX, setTimeout等等.

而且,我们还有流行的事件循环(even loop)和回调队列(callback queue)

调用栈(回调队列跟调用栈其实意思差不多,不过栈跟队列是两种不同的数据结构)

javascript是一个单线程的编程语言(repeat又repeat,都说几次了),这意味着他有一个调用栈,因此,他一次只能做一件事情.

调用栈是一个记录了我们在程序中的位置的数据结构,如果我们跳进一个function,我们把这个函数放进栈的顶部(栈是一种先进后出的数据结构),如果我们从function中return出来,我们就从栈的顶部跳了出来,这就是栈能做的事情.

让我们来看一个例子:

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

当引擎执行这段代码的时候,调用栈(call stack)是空的,当进入printSquare的时候,栈上添加了一个函数,在printSquare中我们又进入了multiply中,此时栈的顶部又添加了一个函数,当我们从multiply中return的时候,栈就把顶部的函数弹出,此时我们就回到了printSquare里,然后执行完printSquare后引擎自动return undefined 以结束这个函数的执行.

栈的每一次变化就想下面这样:


栈中的每一个条目(entry)叫坐堆栈帧(stack frames)上面有提到

这就是一个异常抛出时,栈追踪是如何被构造的(how stack traces are being constructed)---这取决于异常发生的时候,回调栈的状态.(突然跑异常去了,其实是想说明,异常就是通过调用栈实现的)

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

如果这段代码在chrome执行,会产生下边的栈追踪(其实就是一个错误)

"栈坏了"(blowing the stack) --- 这发生在当你把栈放满了的时候(下面还说了一大推,还贴了代码,其实就是死递归)

当引擎执行死递归的时候,会不停的调用同一个方法.看起来像下面这样.

然而,函数在调用栈上调用的数量超过了调用栈的实际大小,浏览器决定要采取行动了,所以他抛出了一个错误,看起来是这样的

在单线程上运行代码可以很容易,因为你不用去处理多线程中的复杂场景,例如,死锁.

但是,运行在单线程上也有他的限制,由于javascript只有一个调用栈,若是程序执行得很慢怎么办?

并发和事件循环(even loop)

当你有函数调用在调用栈(call stack)里为了一个任务花费了大额的时间会发生什么?例如,想象一下,你要在浏览器了做一个复杂的图片转性(transfromation).

你可能会问--为什么这是一个问题?问题是调用栈有函数在运行,浏览器就不能做其他的事情,这就造成了阻塞,这意味这浏览器不能渲染,它不能运行任何的其他代码,它卡住了,如果你想你的app 的ui界面流畅,那么这就是一个问题.

然而,这不是唯一的问题,一旦你的浏览器在调用栈开始了很多的任务,这可能会在很长的一段时间内失去响应.而很多的浏览器会抛出一个错误,然后问你是否要关闭网页.

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

那么,我们要如何处理这种需要很长时间执行的代码呢?嗯~,解决办法就是异步回调

这会再第二篇文章中详细说明.

下面开始买他们产品的广告了,就不翻译了.

原文第二篇我会尽快翻译,尽量不拖太久.

写作新手,还望大家多多关注,多多点赞.

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

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

相关文章

  • jQuery源码分析系列调用匿名函数

    摘要:自调用匿名函数打开源码,首先你会看到这样的代码结构这是一个自调用匿名函数。这样子最大程度防止外界的变量定义对内部造成影响 自调用匿名函数 打开jQuery源码,首先你会看到这样的代码结构: (function(window,undefined){ //jquery code })(window); 这是一个自调用匿名函数。在第一个括号内,创建一个匿名函数;第二个括号内,立...

    psychola 评论0 收藏0
  • [译文] JavaScript工作原理:引擎、运行时、调用概述

    摘要:调用栈是单线程编程语言,意味着它只有单一的调用栈。调用栈是一种数据结构,基本记录了程序运行的位置。举个例子,先来看如下所示的代码当引擎开始执行这段代码时,调用栈将是空的。这正是抛出异常时栈追踪的构造过程这基本上就是异常抛出时调用栈的状态。 原文 How JavaScript works: an overview of the engine, the runtime, and the c...

    PAMPANG 评论0 收藏0
  • javascript基础判断变量类型

    摘要:判断变量类型数据类型种操作符可能返回的值如下注意的能力有限,其对于类型返回的都是使用场景区分对象和原始类型要区分一种对象类型和另一种对象类型可以使用运算符或对象属性运算符用法左边的运算数是一个右边运算数是对象类的名字或者构造函数返回或如果是 判断变量类型 javaSctipt数据类型7种: Number, String, Boolean, Null, Undefined, Object...

    jsdt 评论0 收藏0
  • 理解Node.js(译文)

    摘要:译者觉得作者的比喻很适合初学者理解,特此翻译。进一步说,回调触发的顺序是不能被保证的。所以我不必担心代码在同一时间访问同一个数据结构你确实理解了,这就是的单进程事件循环设计美丽的地方。 前言 总括 :这篇文章十分生动形象的的介绍了Node,满足了读者想去了解Node的需求。作者是Node的第一批贡献者之一,德国前端大神。译者觉得作者的比喻很适合初学者理解Node,特此翻译。 译者 :原...

    SegmentFault 评论0 收藏0
  • JavaScript深入执行上下文

    摘要:深入系列第三篇,讲解执行上下文栈的是如何执行的,也回答了第二篇中的略难的思考题。 JavaScript深入系列第三篇,讲解执行上下文栈的是如何执行的,也回答了第二篇中的略难的思考题。 顺序执行? 如果要问到 JavaScript 代码执行顺序的话,想必写过 JavaScript 的开发者都会有个直观的印象,那就是顺序执行,毕竟: var foo = function () { ...

    codecraft 评论0 收藏0

发表评论

0条评论

Pines_Cheng

|高级讲师

TA的文章

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