JavaScript基本数据类型有哪些:7种原始类型详解

作者:木棉

时间:2026-10-30

浏览:649

系统解析JavaScript中的7种基本数据类型(原始类型):Number、String、Boolean、Undefined、Null、Symbol与BigInt,深入讲解内存模型、类型检测方法、自动装箱原理与高频避坑指南。

文章目录
在 JavaScript(ECMAScript 规范)中,数据类型被划分为两大范畴:原始类型(Primitive Types,又称基本数据类型)与引用类型(Reference Types,即 Object 及其衍生类型)。截至现代 ECMAScript 标准,JavaScript 中共有 7 种基本数据类型:Number、String、`Boolean`、`Undefined`、`Null`、`Symbol` 以及 `BigInt`。原始类型直接存储值本身且具备严格的不可变性。掌握这 7 种类型各自的边界、存储机制与判断方式,是编写健壮前端与 Node.js 应用程序的基础底座。

一、原始类型的核心本质:值与内存机制

很多初学者容易将“变量保存的值”与“对象”相混淆。原始类型之所以被称为“基本”,是因为它们在底层设计和运算上具备以下三个本质特征:

  • 按值存储与比较:原始类型的值直接保存在栈内存(Stack)中。当我们将一个原始值赋值给另一个变量时,计算机会完整复制一份具体的值;使用 === 进行对比时,比较的也是这两个值本身是否相等。
  • 不可变性(Immutability):原始值一旦被创建,其内容本身永远无法被修改。我们对字符串或数值执行的截取、替换、相加等操作,实际上都是返回了一个全新的原始值,绝不可能改变原值。
  • 无属性挂载:原始值本身没有属性和方法。平时我们在字符串或数值后直接调用 .length 或 .toFixed(),依赖的是 JavaScript 引擎在后台瞬间触发的“自动装箱(Auto-boxing)”机制。
JavaScript基本数据类型有哪些:7种原始类型详解
图 1:JavaScript 数据类型体系架构与内存特征概览

二、7种原始类型深度拆解

1. Number(数值)

JavaScript 中的 Number 类型不区分整型与浮点型,统一采用 IEEE 754 标准的双精度 64 位二进制浮点数 实现。由于只有 53 位有效二进制数位(包含隐藏位),能够安全表示的整数区间被限制在 [-(2^53 - 1), 2^53 - 1] 之间,即 -9007199254740991 到 9007199254740991。

const count = 42;          // 整数
const price = 19.99;       // 浮点数
const hex = 0xFF;          // 十六进制(255)
const binary = 0b1010;     // 二进制(10)

// 安全整数边界常量
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
console.log(9007199254740991 + 1 === 9007199254740991 + 2); // true(超出精度丢失!)
关键特例与高频陷阱:
  1. 浮点数运算精度:0.1 + 0.2 === 0.3 返回 false(实际为 0.30000000000000004),涉及金额核算时应放大为整分计算或使用专用精度计算库。
  2. 特殊标识值:包含 +Infinity(正无穷)、-Infinity(负无穷)以及 NaN(Not-a-Number)。typeof NaN 返回 "number",且 NaN === NaN 恒为 false。必须使用 Number.isNaN(val) 判定。

2. String(字符串)

String 用于表示文本序列,由 16 位无符号整数值(UTF-16 码元)构成。字符串字面量支持单引号、双引号以及 ES6 引入的模板字面量(反引号 `)。

const single = 'JavaScript';
const double = "Hello World";
const template = `当前数值为: ${single}`;

// 原始值的只读与不可变特性示例
let title = "hello";
title[0] = "H"; // 在非严格模式下静默失效,严格模式下抛出 TypeError
console.log(title); // 输出 "hello",绝不会变成 "Hello"

// 所有的字符串方法均返回一个全新的字符串,不修改原值
const upper = title.toUpperCase();
console.log(upper); // "HELLO"
console.log(title); // "hello"

自动装箱(Auto-boxing)机制:字符串明明是原始类型,为什么可以直接调用 title.toUpperCase()?当引擎检测到对原始字符串执行属性访问时,会临时创建一个 new String(title) 包装对象并调用其原型方法,调用完毕后立即将该包装对象销毁并回收。这一过程完全透明,使用者既享受了面向对象的 API 便利,又避免了常驻对象带来的额外内存开销。

JavaScript基本数据类型有哪些:7种原始类型详解
图 2:原始数据类型的自动装箱(Auto-boxing)与生命周期

3. Boolean(布尔值)

Boolean 类型仅有两个字面量值:true 与 false,通常用于条件判断与逻辑控制。

需要特别注意 Truthy(真值) 与 Falsy(假值) 的区分。在 JavaScript 中,能够被隐式转换为 false 的值全语言总共只有 8 个:

  • false
  • 0、-0、0n(BigInt 零)
  • ""(空字符串)
  • null
  • undefined
  • NaN
  • document.all(历史遗留特性)

除上述以外的一切值(包括空数组 []、空对象 {}、负数 -1、字符串 "false")在布尔上下文中均为 true。切勿使用 new Boolean(false) 创建包装对象,因为对象在布尔条件中始终判定为真!

4. Undefined(未定义)

Undefined 类型只有一个唯一的值,即 undefined。它在语义上表示“缺少值(未初始化)”。

在以下典型场景中,变量或属性会被自动赋予 undefined:

  • 使用 let 或 var 声明了变量但未赋予初始值:let val; // val 为 undefined
  • 函数没有通过 return 显式返回值,或直接写 return;
  • 调用函数时没有提供足够的形参实参对应:未传递的实参形参值为 undefined
  • 访问对象上不存在的属性:{ a: 1 }.b // undefined

在编写工程代码时,建议使用 void 0 代替全局 undefined 字面量(在极老环境或局部作用域中 undefined 曾可能被篡改,void 0 始终稳定计算出 undefined)。

5. Null(空值)

Null 类型同样只有一个唯一的值,即 null。与 undefined 的“未分配”不同,null 在语义上表示“意料之中的空值,或空对象指针”。通常由开发者主动显式赋值,用于表示一个本应引用对象的位置当前无任何有效指向,或作为清空对象引用的手段以便垃圾回收。

历史缺陷剖析:为什么 typeof null === "object"?
在 1995 年 JavaScript 第一代版本实现中,值在底层的机器字长由 1-3 位的类型标签(Type Tag)与实际值组成。当时设计规范将标签 000 分配给对象(Object)。而系统用于表示 null 的空指针恰好全为 0,导致底层读取类型标签时错误落入了 000,从而使 typeof null 返回了 "object"。
虽然这被确认为纯粹的设计缺陷,但由于过多的早期 Web 网站依赖了这一特征,TC39 委员会为保持向后兼容(Web 兼容性),决定永久保留该行为。因此,绝不能使用 typeof 来判断一个值是否为 null,必须使用全等比较 val === null。

6. Symbol(符号,ES6)

ECMAScript 2015(ES6)正式引入了第 6 种原始类型 Symbol。每个由 Symbol() 函数创建的 symbol 实例都是全局绝对唯一且不可变的,即使给它们传入完全相同的描述符也是独立的存在。

const id1 = Symbol("userId");
const id2 = Symbol("userId");
console.log(id1 === id2); // false(即使描述一致也绝不相等)

// 核心使用场景:作为私有或防冲突的对象属性键
const USER_KEY = Symbol("user_key");
const user = {
  [USER_KEY]: "secret_token",
  name: "Alice"
};

// 常规的 Object.keys() 或 for...in 无法遍历到 Symbol 键
console.log(Object.keys(user)); // ["name"]
// 必须通过专有 API 获取
console.log(Object.getOwnPropertySymbols(user)); // [Symbol(user_key)]

如果需要在不同文件或模块间共享同一个 Symbol,可借助全局 Symbol 注册表使用 Symbol.for(key) 与 Symbol.keyFor(sym) API。

7. BigInt(大整数,ES2020)

ECMAScript 2020 引入了第 7 种原始类型 BigInt,用于支持任意精度的大整数。它的诞生解决了 64 位双精度浮点数无法精准表示超过 53 位大整数(如分布式雪花 ID、高精度时间戳、加密货币金额)的致命痛点。

// 两种声明方式:字面量后缀 n 或 BigInt() 构造调用
const big1 = 9007199254740995n;
const big2 = BigInt("9007199254740995");

console.log(big1 + 1n); // 9007199254740996n(精度完全保持!)

// 常见注意事项:
// 1. 运算不能与普通 Number 混合,必须显式转换
// 10n + 5; // 抛出 TypeError: Cannot mix BigInt and other types
console.log(10n + BigInt(5)); // 15n

// 2. 除法会自动向零舍入(丢弃小数)
console.log(5n / 2n); // 2n(而不是 2.5)

// 3. 不支持单目正号运算符
// +10n; // 抛出 TypeError

三、推导流程:如何准确判定数据类型?

由于 typeof 存在历史遗留偏差,且不能细分复合类型,在实际业务判断中必须严格遵循判定流程。

JavaScript基本数据类型有哪些:7种原始类型详解
图 3:严谨的原始数据类型检测排查路径

四、7种原始类型特性全景对照表

为了让不同场景下的类型选型和排查一目了然,下表系统总结了这 7 种原始类型的字面量格式、引入标准、默认初始表现及易踩误区:

数据类型 规范版本 典型声明写法 typeof 结果 核心使用场景与防护提醒
Number ES1 (1997) 42, 3.14 "number" 数值计算与计数。需注意浮点舍入与 NaN 判定。
String ES1 (1997) 'hi', `txt` "string" 文本展示与处理。值严格不可变,方法均产生新值。
Boolean ES1 (1997) true, false "boolean" 分支开关。警惕 Truthy 规则,严禁使用 new Boolean()。
Undefined ES1 (1997) undefined, void 0 "undefined" 变量声明未赋值的默认状态,无需人为主动赋予。
Null ES1 (1997) null "object"(历史Bug) 表示有意预留的空对象引用。判定必须用 === null。
Symbol ES6 (2015) Symbol("key") "symbol" 对象独一无二的属性键名,杜绝键名覆盖与命名碰撞。
BigInt ES11 (2020) 100n, BigInt("100") "bigint" 超过 53 位的超长整数精度运算。不能直接与 Number 混合算术运算。
JavaScript基本数据类型有哪些:7种原始类型详解
图 4:7 种基本数据类型思维模型与避坑法则总结

五、结语

JavaScript 的数据类型体系在历经二十多年的演进后,形成了以 Number、String、Boolean、Undefined、Null、Symbol、BigInt 7 种原始类型为底层基石,以 Object 引用类型为复合拓展的成熟结构。掌握原始类型的栈内存分配、不可变性本质与自动装箱机制,并清醒避开 typeof null、浮点数精度丢失与包装对象假真值等经典陷阱,能够帮助开发者在日常编码与架构设计中建立清晰的数据流直觉,编写出高效、安全且易于维护的高质量代码。

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章