Skip to content

JavaScript数据类型与内存管理

前言

JavaScript中的数据类型和内存管理是理解这门语言的基础。本文将详细介绍JavaScript的数据类型体系及其在内存中的存储机制。

一、数据类型概述

JavaScript中的数据类型可以分为两大类:

  1. 基本数据类型(原始类型)
  2. 引用数据类型(对象类型)
javascript
// 数据类型示意图
基本类型                    引用类型
┌──────────┐              ┌──────────┐
│ Number   │              │ Object   │
│ String   │              │ Array    │
│ Boolean  │              │ Function │
│ Undefined│              │ Date     │
│ Null     │              │ RegExp   │
│ Symbol   │              │ Map/Set  │
└──────────┘              └──────────┘

二、基本数据类型详解

2.1 Number类型

javascript
// 整数
const int = 42;
const binary = 0b101;  // 二进制
const octal = 0o744;   // 八进制
const hex = 0xFF;      // 十六进制

// 浮点数
const float = 3.14;
const scientific = 1e-10;

// 特殊值
const infinity = Infinity;
const minusInfinity = -Infinity;
const notANumber = NaN;

// 数值范围
console.log(Number.MAX_VALUE);  // 1.7976931348623157e+308
console.log(Number.MIN_VALUE);  // 5e-324

2.2 String类型

javascript
// 字符串创建方式
const str1 = 'Hello';           // 单引号
const str2 = "World";          // 双引号
const str3 = `Hello World`;    // 模板字符串

// 字符串不可变性演示
let str = 'Hello';
str = str + ' World';  // 创建新字符串,原字符串被垃圾回收

2.3 Symbol类型

javascript
// Symbol的基本使用
const sym1 = Symbol('description');
const sym2 = Symbol('description');
console.log(sym1 === sym2);  // false

// 作为对象属性
const obj = {
    [sym1]: 'value1',
    [sym2]: 'value2'
};

三、引用数据类型详解

3.1 Object类型

javascript
// 对象字面量
const person = {
    name: 'John',
    age: 30,
    sayHi() {
        console.log(`Hi, I'm ${this.name}`);
    }
};

// 构造函数
const car = new Object();
car.brand = 'Toyota';
car.model = 'Camry';

3.2 Array类型

javascript
// 数组创建
const arr1 = [1, 'string', { obj: true }, [1, 2]];
const arr2 = new Array(3);  // 长度为3的空数组

// 数组方法
arr1.push(5);         // 尾部添加
arr1.unshift(0);      // 头部添加
const item = arr1.pop();  // 尾部删除

四、内存管理机制

4.1 内存分配图解

栈内存(Stack)              堆内存(Heap)
┌──────────────┐         ┌──────────────┐
│ 基本类型变量  │         │  对象数据     │
│ a = 10       │         │ { name: 'John'│
│ b = 'string' │    ┌───>│   age: 30 }  │
│ c = ▲──────────────┘    │              │
└──────────────┘         └──────────────┘

4.2 赋值操作的内存表现

javascript
// 基本类型赋值
let a = 10;
let b = a;  // 复制值
b = 20;     // a仍然是10

// 引用类型赋值
let obj1 = { name: 'John' };
let obj2 = obj1;  // 复制引用
obj2.name = 'Jane';  // obj1.name也变成'Jane'

4.3 内存分配示例

javascript
// 基本类型
let num = 42;        // 栈内存分配
let str = 'Hello';   // 栈内存分配

// 引用类型
let obj = {          // 堆内存分配,栈内存保存引用
    name: 'John',
    age: 30
};

let arr = [1, 2, 3]; // 堆内存分配,栈内存保存引用

五、实际应用中的注意事项

5.1 性能优化

javascript
// 不好的写法
for(let i = 0; i < 1000; i++) {
    const obj = { value: i };  // 每次循环都创建新对象
}

// 好的写法
const obj = { value: 0 };
for(let i = 0; i < 1000; i++) {
    obj.value = i;  // 复用对象
}

5.2 内存泄漏预防

javascript
// 可能导致内存泄漏的写法
let elements = {
    button: document.getElementById('button')
};
document.body.removeChild(document.getElementById('button'));

// 正确的写法
let elements = {
    button: document.getElementById('button')
};
document.body.removeChild(elements.button);
elements.button = null;

总结

  1. 基本类型存储在栈内存,值直接存储
  2. 引用类型存储在堆内存,栈内存存储引用
  3. 赋值操作的区别:
    • 基本类型复制值
    • 引用类型复制引用

理解这些概念对于:

  • 代码性能优化
  • 内存泄漏预防
  • 变量操作行为预测 都有重要帮助。