JavaScript 数据存储机制:栈与堆的奥秘

JavaScript 数据存储机制:栈与堆的奥秘

一、JavaScript 的数据类型

JavaScript 的数据类型分为两大类:

原始类型(基本类型)

ini 复制代码
let str = 'hello';        // 1. string
let num = 123;            // 2. number
let flag = true;          // 3. boolean
let nu = null;            // 4. null
let un;                   // 5. undefined (未定义)
let sy = Symbol('hello'); // 6. symbol (唯一值)
let bi = BigInt(123);     // 7. bigint (大整数)

引用类型(复杂类型)

javascript 复制代码
let obj = { name: '梅老板' }; // 1. Object
let arr = [1, 2, 3];          // 2. Array
function fn() {}              // 3. Function
let date = new Date();        // 4. Date

二、JavaScript 语言特性

  • 动态语言:变量类型在运行时确定

    ini 复制代码
    let dynamicVar = 10;     // 数字类型
    dynamicVar = 'hello';     // 变为字符串类型
  • 弱类型:支持隐式类型转换

    arduino 复制代码
    console.log(10 + '10'); // "1010" (数字转字符串)
    console.log(10 - '5');  // 5 (字符串转数字)

三、内存空间结构

JavaScript 引擎管理的内存空间分为三个区域:

  1. 代码空间:存储可执行代码
  2. 栈空间:存储原始类型值和引用地址
  3. 堆空间:存储引用类型实际数据

栈空间的特点:

  • 存储原始类型值
  • 存储引用类型的地址指针
  • 空间小,访问速度快
  • 自动分配和释放

堆空间的特点:

  • 存储引用类型实际数据
  • 空间大,访问速度相对较慢
  • 需要垃圾回收机制管理

四、数据存储机制

1. 原始类型的存储(栈空间)

ini 复制代码
function demo() {
  let a = 1;     // 在栈中创建值 1
  let b = a;     // 在栈中创建值 1 的副本
  a = 2;         // 修改栈中的 a 值
  console.log(a); // 2
  console.log(b); // 1 (b 保持原值)
}
demo();

2. 引用类型的存储(堆空间)

ini 复制代码
function demo() {
  let obj1 = { name: '成哥' }; // 1. 在堆中创建对象
                              // 2. 栈中存储指向堆的地址
  
  let obj2 = obj1;          // 复制栈中的地址
  obj1.name = '周圣';        // 修改堆中对象
  
  console.log(obj1); // { name: '周圣' }
  console.log(obj2); // { name: '周圣' } (共享同一对象)
}
demo();

五、关键概念解析

1. 按值传递 vs 按引用传递

JavaScript 中所有函数参数都是按值传递

  • 原始类型:传递值的副本
  • 引用类型:传递地址的副本
ini 复制代码
function modify(obj) {
  obj.name = '修改后的值';  // 修改原对象
  obj = { value: 100 };    // 创建新对象(不影响原变量)
}

let myObj = { name: '原始值' };
modify(myObj);
console.log(myObj.name); // "修改后的值"

2. 经典示例分析

ini 复制代码
function foo(person) {
  person.age = 20;         // 修改原对象的属性
  person = {               // 给参数重新赋值新对象
    name: '刘洋'           // (不影响外部变量)
  };
  return person;
}

let p1 = { name: '张三', age: 18 };
let p2 = foo(p1);

console.log(p1); // {name: '张三', age: 20}
console.log(p2); // {name: '刘洋'}

执行过程解析

  1. p1 传入函数时,复制其地址到 person 参数
  2. person.age = 20 修改堆中原对象
  3. person = {...} 使参数指向新对象
  4. 返回的新对象赋值给 p2

六、特殊类型注意事项

1. Symbol 的唯一性

ini 复制代码
let s1 = Symbol('key');
let s2 = Symbol('key');
console.log(s1 === s2); // false (每个Symbol都是唯一的)

2. BigInt 的使用

arduino 复制代码
const bigNumber = 9007199254740991n; // 超过Number安全整数范围
console.log(bigNumber + 1n); // 9007199254740992n

3. typeof 检测的特别情况

javascript 复制代码
console.log(typeof null);      // "object" (历史遗留问题)
console.log(typeof function(){}); // "function"

七、总结

JavaScript 的数据存储机制遵循以下核心原则:

  1. 原始类型:值直接存储在栈空间,赋值时创建值副本
  2. 引用类型:数据存储在堆空间,栈中存储指向堆的地址指针
  3. 参数传递:始终按值传递(原始值或地址值的副本)
  4. 动态特性:变量类型在运行时确定,可自由转换
  5. 内存管理:栈空间自动释放,堆空间由垃圾回收机制管理
相关推荐
小小小小宇2 小时前
前端 Service Worker
前端
只喜欢赚钱的棉花没有糖2 小时前
http的缓存问题
前端·javascript·http
小小小小宇2 小时前
请求竞态问题统一封装
前端
loriloy2 小时前
前端资源帖
前端
源码超级联盟2 小时前
display的block和inline-block有什么区别
前端
GISer_Jing3 小时前
前端构建工具(Webpack\Vite\esbuild\Rspack)拆包能力深度解析
前端·webpack·node.js
让梦想疯狂3 小时前
开源、免费、美观的 Vue 后台管理系统模板
前端·javascript·vue.js
海云前端3 小时前
前端写简历有个很大的误区,就是夸张自己做过的东西。
前端
葡萄糖o_o3 小时前
ResizeObserver的错误
前端·javascript·html
AntBlack3 小时前
Python : AI 太牛了 ,撸了两个 Markdown 阅读器 ,谈谈使用感受
前端·人工智能·后端