Appearance
JavaScript数据类型与内存管理
前言
JavaScript中的数据类型和内存管理是理解这门语言的基础。本文将详细介绍JavaScript的数据类型体系及其在内存中的存储机制。
一、数据类型概述
JavaScript中的数据类型可以分为两大类:
- 基本数据类型(原始类型)
- 引用数据类型(对象类型)
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;
总结
- 基本类型存储在栈内存,值直接存储
- 引用类型存储在堆内存,栈内存存储引用
- 赋值操作的区别:
- 基本类型复制值
- 引用类型复制引用
理解这些概念对于:
- 代码性能优化
- 内存泄漏预防
- 变量操作行为预测 都有重要帮助。