1. 聊一聊什么是调用栈

  比较官方的术语是: 调用栈是解释器(比如浏览器中的 JavaScript 解释器)追踪函数执行流的一种机制。

白话文解释一下, 无论何种语言,

  在程序调用的过程中总会从一个方法调用到另外一个方法中,这种调用关系的执行在内存中会有一个栈的先进后出的过程。

  最初是一个空栈,最终也会得到一个空栈,如果调用层级特别多,会出现栈溢出错误。

2. 尾调用优化

  在开发过程可能会见到过方法的最后一行返回的结果是另外一个方法,或者方法的最后一行调用的另外一个方法。这就叫做尾调用。

我们知道,函数调用会在内存形成一个"调用记录",又称"调用帧"(call frame)。但是在方法最后调用其他方法,自身方法已经没有可执行

其他逻辑代码,因而可以优化为提出来,也就是说减少一层栈内存的使用。也就是说不必写在方法内部的最后,如果可以,我们最后将其提取处理

一定程度上可以大大节省内存空间。

3. 执行上下文和执行栈

  执行上下文的类型:  全局、函数、Eval函数(独立的执行区域)

  执行上下文的两个阶段: 创建阶段和执行阶段

  创建阶段:1. this的绑定,全局环境默认指向Window对象,函数中,要看函数是如何被调用的。

          2. 词法环境是一种规范,基于ECMAScript。

       3. 变量环境,其环境记录器持有变量声明语句在执行上下文中创建的绑定关系。

4. 单线程异步事件循环

 关于javascriptjavascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变。所以一切javascript版的"多线程"都是用单线程模拟出来的,一切javascript多线程都是纸老虎!

当我们打开网站时,网页的渲染过程就是一大堆同步任务,比如页面骨架和页面元素的渲染。而像加载图片音乐之类占用资源大耗时久的任务,就是异步任务。

  • 同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。
  • 当指定的事情完成时,Event Table会将这个函数移入Event Queue。
  • 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。
  • 上述过程会不断重复,也就是常说的Event Loop(事件循环)。

     

  • javascript是一门单线程语言
  • Event Loop是javascript的执行机制

 

  • macro-task(宏任务):包括整体代码script,setTimeout,setInterval
  • micro-task(微任务):Promise,process.nextTick

整体js代码执行时先走宏任务,如果事件队列里面有微任务,执行,然后走微任务。然后再走下一个宏任务如此循环

如下图片,别的地方copy来的

ios调用堆栈 js 调用堆栈_ios调用堆栈