李志成的个人网站
  • 博客
  • 关于
  • 音乐
  • Rss
首页前端调用堆栈原理

调用堆栈原理

发表于2019-01-20 11:20:28分类于前端0条评论阅读次数236

概述

JavaScript是一种异步单线程编程语言,它只有一个调用栈,也意味着在同一时刻只能处理一件事情。

堆栈,它是一种数据结构,是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除。

要点:

堆,队列优先,先进先出(FIFO—first in first out)。

栈,先进后出(FILO—First-In/Last-Out)。

什么时候用堆,什么时候用栈?

  1. 基本类型变量都是存放在栈中,大小是固定的,栈中直接存放的基本类型变量的值(基本类型:Undefined,Null,Boolean,Number和String)

  2. Object,Array,Function,Date等对应的是引用类型值,存放在堆内存中。

  3. 要申请内存空间的放堆内存中。

调用堆栈

在程序中,堆栈记录了当前程序中执行到的基本位置。当我们往堆栈中,存入逻辑操作,它都会把它放在堆栈的顶部。如果操作完成,就会将它从堆栈的顶部弹出。

举个栗子:

function increase(x) {
    return x + 1;
}
function printNum(x) {
    var s = increase(x);
    console.log(s);
}
printNum(5);

当引擎开始执行上面的代码时,调用堆栈将为空。接下来的步骤是(我将用数组模拟堆栈):

step1: [ ]  // 空堆栈

step2: [ printNum(5) ]

step3: [ increase(x), printNum(5) ]

// 此时执行increase,结束后弹出。

step4: [ console.log(s), printNum(5) ]

// 调用console.log,结束后弹出。

step5: [ printNum(5) ] 

// 调用printNum, 结束后弹出

step6: [ ] // 空堆栈

分析了上面的堆栈调度过程,下面来验证一下引擎是否是这样子工作的。

function increase(x) {
    throw new Error('选择在这里抛出异常,打断引擎执行,形成错误快照');
}
function printNum(x) {
    var s = increase(x);
    console.log(s);
}
printNum(5);

调用堆栈

除此之外呢,每个堆都有一定的大小限制,一旦超过了限制将会报错。举个简单例子:

function a() {
    a();
}
a();

调用堆栈

了解了那么多,究竟有什么用呢?

由于在单个线程上运行代码非常简单,不需要考虑资源的竞争,只需按顺序执行完毕即可,然而在单线程上,如果存在了大量的逻辑处理,而堆栈只有一个的时候,那么整个线程的处理效率将会变慢,从而造成卡顿。所有,了解堆栈有以下作用:

  1. 优化浏览器渲染页面,减少需要花费大量时间才能处理的函数调用,防止浏览器卡住,而无法进行ui渲染

  2. 避免过多的递归调用,从而造成堆栈溢出。

  3. 多使用异步回调,避免同步函数。

  4. 更多。。。

后言

如果文章有错误的地方,请指出,感谢你的帮助。

--发表评论--

🚀support markdown (* ̄▽ ̄*)ブ
    相关文章