栈与堆:理解JS 原始类型与引用类型

80 阅读2分钟
前言

设计目的不同 想象一下计算机的内存就像一个大仓库,里面有两种不同的储物架:

  • 栈(Stack): 像整齐排列的小储物柜,存取快但空间有限
  • 堆(Heap)

数据类型

原始类型(简单类型)

  • string(字符串)
  • number (数字)
  • boolean (布尔值)
  • null
  • undefined
  • symbol
  • bigint
// 原始类型示例
let name = "小明";       // string
let age = 18;           // number
let isStudent = true;   // boolean
let score = null;       // null
let address;           // undefined
特点
  1. 值直接存储在栈中
  2. 大小固定,占用空间小
  3. 按值访问,操作的是实际值
  4. 不可变,修改会创建新值

第四点说明:

let a = 10;
let b = a;  // 把a的值10复制给b
b = 20;     // 修改b,a不受影响
console.log(a); // 10,a没变

引用类型(复杂类型)

  • Object(对象):线性存储节后,靠下标来操作里面的元素
  • Array(数组):键值对存储结构,通过访问属性来操作里面的值
  • Function(函数)
  • Date(日期)
  • 其他内置对象
let person = {                 //object
name:'小牛'
age:18
}

let hobbies = ["洗脚",“音乐”]  // array

function greet() {             //function
      console.log("你好");
}

特点
  1. 值储存在栈中,栈只存引用地址
  2. 大小不固定,可动态扩展
  3. 按引用访问,操作的是内存地址
  4. 可变,可直接修改内容

栈存储的具体流程示例

var a = 2 
function add() {
  var b = 10
  return a + b
}
console.log(add());

在 ES6 中GO改成了变量环境,AO改成了词法环境

相信看过上一篇文章的小伙伴,已经知道了这段代码的编译过程是什么样子的,所以以栈的形式表现出来如图

4cb45a2660947158982d4db5fb83d57e.jpg

编译到第六行时,栈中发生了变化

cc882a5b079f27a6f6f147513250d73a.jpg

最后执行

栈为什么不设计成无限大?

想象一下栈就像便当和,而堆就像自助餐厅

便当为什么不能无限大?

  1. 便当盒:快速取餐
  2. 自助餐台:容量巨大,找东西稍慢

关键限制原因

  • 速度要求:保证你可以秒取到你最爱吃的菜
  • 空间规划:每个格子固定,提前规划好
  • 顺序保证:最后放的先吃,不能乱序

无限大会爆栈

栈与堆的对比表

1245cce1d698fc85c885a1babfa1dca5.jpg

感谢您的观看,咱们下篇文章不见不散!