JavaScript 基本类型与引用类型的内存机制解析

作者:代码拾荒

时间:2026-10-23

浏览:91

本文深入解析JavaScript中基本类型与引用类型的内存分配机制。详细阐述Number、String等五种基本类型在栈内存中的值不可变特性,以及Object、Array等引用类型通过栈中指针指向堆内存数据的存储方式。通过传值与传址的对比,说明变量赋值、修改及比较时的行为差异,帮助开发者理解JS数据底层逻辑。

文章目录

1. 基础类型

1. 基础类型

A. JavaScript 中的基本类型包含五种:Number(数字)、String(字符串)、Boolean(布尔值)、Null(空值)和 Undefined(未定义)。

B. 基本类型不涉及堆内存的概念,堆内存主要服务于引用类型。

所有基本类型的值都以键值对(key-value)的形式存储在栈内存(Stack)中。需要注意的是,基本类型的值是不可变的,除非执行重新赋值操作,否则其值保持不变。

例如:


var a = "1234";
a[0] = "k";//对值本身修改,无效
console.log(a)//1234

a = "k";//重新赋值
console.log(a)//k

2. 引用类型

2. 引用类型

常见的引用类型包括 Array(数组)、Object(对象)、Function(函数)、Date(日期)和 RegExp(正则表达式)等。

所有引用类型同样以键值对形式在栈内存中存储,但其 value 存储的是指向堆内存(Heap)中具体空间的指针地址。该堆内存空间实际存放着引用类型的数据值。

注意:

引用数据的实际值被称为“堆值”,记为 value1。堆值对象内部的键值对中的 value 称为“值中值”,记为 value2。在当前示例语境下,value1 是可变的(通过重新赋值改变引用),而 value2 是不可变的,除非进行重新赋值。

例如:


// 堆值,即value1,可改变
var a = {"name":"jack"};
a = [];//重新赋值
console.log(a)// []
 
// 堆值中值,即value2,与基本数据类型一样不可改变
var a = {"name":"jack"};
a.name[0] = "0";
console.log(a)// {"name":"jack"}

3. 传值与传址

3. 传值与传址

如下图所示:

3.1 A 代码块演示传值机制

当执行 A 代码块时,变量 a 和 b 都会在栈区开辟独立的空间来存放值 10,并以键值对形式存储。A 代码块体现的是传值行为。

3.2 B 代码块演示传址机制

当执行 B 代码块时,变量 a1 会开辟一个空间存放指针地址,随后该指针地址被赋值给 b1。此时,b1 也会开辟一个空间来存放这个指针地址。a1 和 b1 的指针地址均指向堆区中的“堆值”,即 value1。

4. 比较机制

4. 比较机制

4.1 基本类型的比较基于值的大小

例如:


var a = 1;
var b = 1;
console.log(a == b);//true

4.2 引用类型的比较基于引用地址

同一个引用的比较结果为相等,而不同引用的比较结果不相等。

例如:


//不同引用的比较
var p1 = {};
var p2 = {};
console.log(p1 == p2) //false
 
//不同引用的比较
var p3 = {"name":{},"age":30};
var p4 = {"name":{},"age":30};
console.log(p3.name == p4.name);//false(这个是引用比较)
console.log(p3.age == p4.age);//true(这个是值比较)
 
//同引用的比较
var p5 = {};
var p6 = p5;
console.log(p5 == p6)//true

如果引用被重新赋值为其他类型,那么当前引用与原值的指针地址联系将被切断。

如下图所示:

1. 基础类型

当 a1 被重新赋值时,a1 与原“堆值 --> {}”的联系被替换为新的指针地址,即指向“堆值 --> []”。

至此,关于 JavaScript 基本类型和引用类型的介绍结束,更多相关内容请继续往下阅读相关文章。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章