基础类型和引用类型

194 阅读4分钟

在JavaScript中,基础类型和引用类型有哪些?存放于哪里?

JavaScript中的数据类型分为两大类:基本类型(原始类型)和引用类型(对象类型)。

基本类型(Primitive types)是直接存储在栈内存中的简单数据段,它们按值访问,具有不可变性。引用类型(Reference types)则是对象,存储在堆内存中,变量实际上存储的是指向堆内存中对象的引用地址(指针)。

重要区别:

  1. 存储方式

    • 基本类型:值直接存储在变量访问的位置(栈内存)。
    • 引用类型:变量存储的是对象的引用地址(指针),实际对象存储在堆内存中。
  2. 复制行为

    • 基本类型:复制时,会在栈内存中创建一个新的值副本。
    • 引用类型:复制时,复制的是引用地址(指针),因此两个变量指向同一个对象。
  3. 比较方式

    • 基本类型:比较时比较值是否相等。
    • 引用类型:比较时比较引用地址是否相等(即是否指向同一个对象)。
  4. 传递方式

    • 函数参数传递时,基本类型传递的是值的副本,引用类型传递的是引用地址的副本(所以函数内部修改引用类型对象的属性会影响原对象,但重新赋值不会影响原引用)。

以下是详细梳理:

一、基础类型(Primitive Types)

基础类型是不可变(Immutable)的值,直接存储在栈内存(Stack)中(栈帧内),传递时按值拷贝。 ECMAScript标准定义的基础类型有7种:

类型描述例子typeof 返回值
String字符序列(不可变)'hello'"world"'string'
Number整数/浮点数(双精度)1233.14NaN'number'
Boolean逻辑值truefalse'boolean'
Undefined未定义(变量未初始化)let a;'undefined'
Null空值(故意表示无对象)let b = null;'object'(历史遗留)
Symbol唯一标识符(ES6+)Symbol('id')'symbol'
BigInt大整数(ES2020+)123nBigInt(456)'bigint'

二、引用类型(Reference Types)

引用类型是可变(Mutable)的对象,存储在堆内存(Heap)中,栈内存仅存储指向堆的引用地址(类似指针)。 常见的引用类型包括:

类型描述例子typeof 返回值
Object通用对象(基类){ name: '小天' }'object'
Array有序列表[1, 2, 3]'object'
Function可执行代码块(一等公民)function() {}() => {}'function'(特殊)
Date日期对象new Date()'object'
RegExp正则表达式对象/^[a-z]+$/'object'
Map键值对集合(ES6+)new Map()'object'
Set唯一值集合(ES6+)new Set()'object'
WeakMap弱引用键映射(ES6+)new WeakMap()'object'
WeakSet弱引用值集合(ES6+)new WeakSet()'object'
Error错误对象new Error('出错了')'object'
Promise异步操作对象(ES6+)new Promise((res) => res())'object'

三、核心差异对比

特征基础类型引用类型
可变性不可变(无法修改原值)可变(可修改属性/元素)
存储位置栈内存(直接存储值)堆内存(存储值)+ 栈内存(存储引用)
比较方式值比较(===比较值)引用比较(===比较地址)
传递方式按值传递(拷贝值)按共享传递(拷贝引用地址)

四、关键细节说明

  • null的特殊处理:

null是基础类型,但typeof null返回'object'(历史遗留bug,ECMAScript未修复以保持兼容性)。 正确判断null应使用=== null: typeof null; // 'object' null === null; // true

  • Function的特殊地位:

Function是引用类型(继承自Object),但typeof Function返回'function'(ECMAScript为方便区分函数类型做的特殊处理)。

  • 包装对象(Wrapper Objects):

基础类型有对应的包装对象(如String、Number、Boolean),用于提供方法(如str.length)。但原始值本身不是对象: let str = 'hello'; // 基础类型(string) str.length; // 5(自动装箱为String对象,调用后销毁) typeof str; // 'string' typeof new String(str); // 'object'(包装对象)

  • 总结

基础类型:简单、不可变、直接存储值,适合表示原子数据。 引用类型:复杂、可变、通过引用访问,适合表示结构化数据。 理解两者的差异是掌握JavaScript内存管理、变量传递、状态管理的关键(比如Vue的data函数设计就依赖于引用类型的特性)。