单元一之第二章堆和栈概念

84 阅读2分钟

内存堆和调用栈

  • 内存分配有关

  • Heap

    • 定义变量,对象,函数存放的位置
      • 其中value放在内存堆中
  • Call Stack

    1. 使用场景运行代码时
    2. 是什么内存中的一个位置,用于跟踪,执行和正在执行的功能 => 之后将会被执行
    3. 调用规则先进后出
    4. 注意
      1. js 引擎只有一个调用堆栈来处理正在执行的命令
        1. 原因 JS 是单线程
        2. 导致 JS 引擎一次只能执行程序一部分
          1. 所以 调用堆栈一次处理一个命令 => JS 是同步命令

问题

1.如果调用一串很长的代码,如何放置阻塞其他代码?

  • 提示
    • 使用异步

解析代码

// 1.保存在内存堆中
let a = "Hello";
let b = "World";

// 2.保存在内存堆中
function helloWorld() {
  // 4. 运行函数 => 放置在调用堆栈中 => 执行函数 => 执行完成 => 从调用堆栈中删除
  console.log("a");

  // 5. 将setTimeout添加到调用堆栈中 => 因为这个函数是 WebAPIs 中,所以将它发送到浏览器并告诉浏览器收到一个设置超时的调用 => JS现在并不关心它已经把它忘掉了,因为他放心的丢给WebAPIs
  setTimeout(() => {
    console.log("!");
  }, 0);
  // 6. 执行下一个命令,这是对这个函数的另一次调用 => 并且添加到调用栈中  => 从调用栈中删除
  console.log("b");
}
// 3.运行函数 => 调用堆栈开始执行 => 来到代码内部
helloWorld();
  1. 什么是 Event Loop
  1. 是处理这些 Web API 项的事件循环和消息队列

JS中的角色

  1. Heap
  2. Call Stack 调用栈
  3. Web APIs 浏览器自身存在的函数
  4. Event Loop 处理_Web API_项的事件循环
  5. Message Queue 处理Web API消息队列

Call Stack

  1. 特殊情况

    1.调用栈填满

    1. 原因 无法删除命令并且不断添加更多命令
    2. 额外知识 嵌套函数可以向调用堆栈(Call Stack)添加很多内容
    3. 后果 导致错误
    4. 造成填满方法
// 递归调用试遇到的问题:超过最大调用堆栈大小
function recursion(num) {
  num = num + num;
  // 解决
  if (num > 99999) {
    console.log(num);
    // 跳出循环
    return;
  }
  // 常犯错误:如果不传入num则该数字不会变大
  recursion(num);
}

recursion();
// Uncaught RangeError:Maximum call stack size exceeded 超过最大调用堆栈大小