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. 内存管理:栈空间自动释放,堆空间由垃圾回收机制管理
相关推荐
Hoshizola5 分钟前
uniapp与蓝牙设备连接详细步骤
前端·uni-app
优雅格子衫10 分钟前
uniapp 拍照相册选取后超级好用的裁剪组件,增加水印完全自定义
开发语言·前端·javascript·uni-app·vue
Dxy123931021614 分钟前
HTML如何写鼠标事件
前端·html·计算机外设
AI砖家26 分钟前
前端 JavaScript 异步处理全方案详解:从回调到 Observable
开发语言·前端·javascript
用户7138742290032 分钟前
构建现代 Web 应用的令牌安全体系:Refresh Token Rotation、HttpOnly Cookie 与 Grace Period 全解析
前端
柒和远方41 分钟前
每日一学V010: 从 Python 回到前端:一个 AI Native 开发者的 JavaScript 底层基础补全
javascript
之歆1 小时前
Day21_电商详情页核心技术实战:从LESS预处理到复杂交互实现
开发语言·前端·javascript·css·交互·less
海鸥两三1 小时前
基于 Vue 3 + 高德地图的网格规划系统实战(有源码)
前端·javascript·vue.js
逸A1 小时前
某里v2反混淆 codec 化路上踩到的两个隐蔽坑:被清零的 salt 与 opaque loop bound
javascript·人工智能·目标跟踪
丷丩1 小时前
MapLibre GL JS第11课:获取鼠标指针坐标
前端·javascript·gis·地图·mapbox·maplibre gl js