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. 内存管理:栈空间自动释放,堆空间由垃圾回收机制管理
相关推荐
前端摸鱼匠6 小时前
Vue 3 的v-bind合并行为:讲解v-bind与普通属性合并的规则
前端·javascript·vue.js·前端框架·ecmascript
REDcker6 小时前
浏览器端Web程序性能分析与优化实战 DevTools指标与工程清单
开发语言·前端·javascript·vue·ecmascript·php·js
donecoding8 小时前
一个 sudo 引发的血案:npm 全局包权限错乱彻底修复
前端·node.js·前端工程化
风骏时光牛马8 小时前
Raku正则匹配与数据批量处理实操案例
前端
nbwenren8 小时前
2026实测:Gemini 3 镜像站视觉能力实践——拍照原型图,一键生成 HTML+CSS 代码
前端·css·html
Lee川8 小时前
Prisma 实战指南:像搭积木一样设计古诗词数据库
前端·数据库·后端
Linsk8 小时前
Java和JavaScript的关系真是雷峰和雷峰塔的关系吗?
java·javascript·oracle
当时只道寻常8 小时前
浏览器文本复制到剪贴板:企业级最佳实践
javascript
jinanwuhuaguo8 小时前
(第二十九篇)OpenClaw 实时与具身的跃迁——从异步孤岛到数字世界的“原住民”
前端·网络·人工智能·重构·openclaw