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

作者:小括号时间:2026-10-30 19:01:11浏览:82

全面解析JavaScript中的7种基本原始数据类型(Number、String、Boolean、Undefined、Null、Symbol、BigInt),涵盖内存机制、类型判定、常见陷阱与实用对比。

在当前 ECMAScript 标准规范中,JavaScript 的数据类型被划分为两大体系:原始数据类型(Primitive Types,亦称基本数据类型)与引用数据类型(Reference Types)。截至目前的 ECMAScript 规范,JavaScript 共有 7 种基本数据类型,分别是:Number、String、Boolean、Undefined、Null、Symbol 和 BigInt。理解这 7 种原始类型的存储机制、取值范围与判定细节,是掌握 JavaScript 运行时与避免隐式类型转换陷阱的基础。

一、原始类型与引用类型的核心机制差异

原始类型之所以被称为“基本”或“原始”,是因为它们在底层内存分配与操作机制上具备三项核心特征:

  • 按值存储与访问:原始类型的值占据固定大小的内存空间,在现代 JavaScript 引擎(如 V8)中,除部分字符串优化外,基本类型通常直接存储在执行上下文的栈内存(Stack)中;而对象、数组等引用类型则存储在堆内存(Heap)中,变量仅持有堆地址引用。
  • 不可变性(Immutability):原始值一旦被创建,其本身的内容不可被修改。对字符串或数字的任何操作(如调用方法或拼接),返回的都是全新创建的副本,原始数据分毫未变。
  • 按值比较:对两个原始类型变量进行相等性判断(===)时,直接比对底层存储的具体数值,而非内存地址指针。
JavaScript有哪些基本数据类型?7种原始类型详解
图 1:JavaScript 原始数据类型与引用类型的分类与内存模型

二、7 种原始数据类型逐一详解

1. Number(数字类型)

不同于 C、Java 等区分 int、float、double 的语言,JavaScript 的 Number 统一采用 IEEE 754 双精度 64 位二进制浮点数格式存储。这意味着在底层,所有常规数字都以浮点形式表示。

该格式导致在处理超大整数或小数运算时具有固定的物理边界:

  • 安全整数区间:范围在 Number.MIN_SAFE_INTEGER(-(253 - 1))到 Number.MAX_SAFE_INTEGER(253 - 1)之间。超过此范围的整数计算会出现精度丢失。
  • 浮点精度误差:著名的 0.1 + 0.2 === 0.30000000000000004 问题源于十进制小数转为二进制时的无限循环舍入。在财务或精确计算中需使用整数化乘除或三方精确库。
  • 特殊数值常量:包含 Infinity(正无穷)、-Infinity(负无穷)以及 NaN(Not a Number,非数)。特别注意:NaN 属于 Number 类型,且具有自身不等于自身的特性(NaN === NaN 返回 false)。
// 示例:Number 的常用判定与特殊值
const regularNum = 42;
const floatNum = 3.14159;
const notANumber = Number("abc"); // 结果为 NaN

console.log(typeof notANumber); // "number"
console.log(notANumber === NaN); // false(切勿直接全等比较)
console.log(Number.isNaN(notANumber)); // true(标准推荐判断方式)
console.log(1 / 0); // Infinity

2. String(字符串类型)

String 表示字符序列。JavaScript 中的字符串使用 UTF-16 编码单元序列表示,长度计算以 16 位代码单元为基准。

必须时刻牢记字符串的不可变性。例如对一个字符串变量进行切片或替换时,原字符串不会被篡改:

let text = "JavaScript";
let transformed = text.toUpperCase();

console.log(text); // 依然输出 "JavaScript"(原值未改变)
console.log(transformed); // 输出新字符串 "JAVASCRIPT"

// 试图修改字符串单个字符是无效的(严格模式下抛错,非严格模式下静默失效)
text[0] = "Y";
console.log(text); // 依然是 "JavaScript"

3. Boolean(布尔类型)

Boolean 仅有两个字面量值:true 和 false,用于逻辑控制与条件分支判定。在条件表达式中,所有其他数据类型均可在隐式转换规则下被折叠为布尔真值(Truthy)或假值(Falsy)。

注意事项:JavaScript 中严格对应 false 的假值(Falsy)仅有 8 个:false、0、-0、0n(BigInt 零)、""(空字符串)、null、undefined 以及 NaN。除此以外的所有值(包括空数组 []、空对象 {}、字符串 "0")均为真值。

4. Undefined(未定义)

Undefined 类型只有一个取值,即字面量 undefined。它代表变量已完成声明但尚未被赋予具体值的自然状态。当尝试访问未赋值的变量、未传参的函数形参,或是未定义的属性时,引擎统一返回 undefined。

let score;
console.log(score); // 输出 undefined
console.log(typeof score); // 输出 "undefined"

function calculateTotal(price, taxRate) {
  console.log(taxRate); // 如果调用时不传第二个参数,此处输出 undefined
}
calculateTotal(100);

5. Null(空值)

Null 类型也仅有一个取值,即字面量 null。从设计初衷来看,null 代表有意赋予的“无值”或“空对象指针”。它常用于手动切断变量对对象的引用以便垃圾回收,或是作为函数可能返回“空结果”的显式占位。

在 JavaScript 中,typeof null 会返回 "object"。这是 JavaScript 1.0 版本由于底层二进制标签设计引发的历史遗留 Bug(早期使用 32 位单元存储值,低 3 位为 000 即被当作对象标签,而 null 全为 0),标准委员会为了向下兼容旧有代码逻辑,选择永久保留该行为。

6. Symbol(符号类型)

Symbol 是在 ECMAScript 2015 (ES6) 规范中引入的原始类型。每次通过 Symbol() 函数创建的值都是全局唯一的。其核心定位是作为对象属性的防碰撞唯一键,避免团队多人协作或第三方库扩展对象时发生属性覆盖冲突。

// 即使传入相同的描述字符串,两者的内存标识也完全独立
const key1 = Symbol("token");
const key2 = Symbol("token");

console.log(key1 === key2); // false

// 作为对象属性键
const user = {
  name: "Alice",
  [key1]: "secret_12345"
};

// 常规的 Object.keys() 或 for...in 无法遍历 Symbol 属性
console.log(Object.keys(user)); // ["name"]
// 需通过专门 API 读取
console.log(Object.getOwnPropertySymbols(user)); // [Symbol(token)]

7. BigInt(大整数类型)

BigInt 是在 ECMAScript 2020 (ES11) 正式标准化的原始类型。由于传统的 Number 只能安全表示最大为 9007199254740991(253 - 1)的整数,在处理高精度时间戳、区块链哈希计算或分布式雪花 ID(Snowflake ID)时极易发生精度截断。BigInt 提供了无上限的任意精度整数运算能力。

在数字末尾添加 n 或调用 BigInt() 构造函数即可创建 BigInt 实例:

// 传统 Number 遇到大整数精度丢失:
console.log(9007199254740991 + 1); // 9007199254740992
console.log(9007199254740991 + 2); // 9007199254740992(计算失真)

// 使用 BigInt 精确计算:
const bigA = 9007199254740991n;
console.log(bigA + 1n); // 9007199254740992n
console.log(bigA + 2n); // 9007199254740993n(保持绝对精确)

// 注意事项:BigInt 与 Number 不能直接进行隐式混合算术运算,需显式转换
// console.log(10n + 5); // 抛出 TypeError: Cannot mix BigInt and other types
console.log(10n + BigInt(5)); // 15n

三、容易混淆的关键对比:Undefined 与 Null

初学者常常无法准确区分 undefined 与 null 的适用场景与行为差异。在一致的使用条件下,两者的关键技术差异如下:

JavaScript有哪些基本数据类型?7种原始类型详解
图 2:Undefined 与 Null 的技术细节及边界行为对比

代码验证两者的双等(宽松相等)与三等(严格相等)关系:

console.log(null == undefined);  // true(宽松比较下引擎认定语义相通)
console.log(null === undefined); // false(分属不同的原始数据类型)

// 默认参数触发差异验证:
function greet(user = "访客") {
  return `你好,${user}`;
}
console.log(greet(undefined)); // "你好,访客"(触发默认值)
console.log(greet(null));      // "你好,null"(未触发默认值)

四、工程实践中如何准确判断基本数据类型?

在业务逻辑开发中,对输入变量进行防御性类型校验是一项高频操作。使用单一工具难以应对所有场景,推荐采用如下清晰排查路径:

JavaScript有哪些基本数据类型?7种原始类型详解
图 3:JavaScript 基本数据类型判定决策流程

实现该判定逻辑的标准化工具函数示例:

/**
 * 精确判断变量数据类型
 * @param {*} val 待检测值
 * @returns {string} 类型名称(如 "number", "null", "array" 等)
 */
function getExactType(val) {
  // 1. 优先排除 null
  if (val === null) return "null";

  // 2. 对于原始类型,typeof 均能准确识别
  const baseType = typeof val;
  if (baseType !== "object") {
    return baseType;
  }

  // 3. 对引用类型使用 Object 原型方法精准拆分
  return Object.prototype.toString.call(val).slice(8, -1).toLowerCase();
}

console.log(getExactType(100));          // "number"
console.log(getExactType("hello"));      // "string"
console.log(getExactType(true));         // "boolean"
console.log(getExactType(undefined));    // "undefined"
console.log(getExactType(null));         // "null"
console.log(getExactType(Symbol("id"))); // "symbol"
console.log(getExactType(100n));         // "bigint"
console.log(getExactType([]));           // "array"
console.log(getExactType({}));           // "object"

五、7 种原始类型全维度总结速查

为了便于速查与记忆,下表对这 7 种基本数据类型的关键属性、引入规范、字面量语法与工程避坑点进行了系统汇总:

JavaScript有哪些基本数据类型?7种原始类型详解
图 4:7 种原始数据类型全特性对比总结

总结而言,JavaScript 的 7 种基本数据类型构成了语言底层的值系统基石。在日常编码与重构中,牢记 typeof null === 'object' 的特殊表现、NaN 的非自反性,并在大数运算与私有属性键场景主动运用 BigInt 和 Symbol,可以有效编写出更健壮、更可维护的高质量前端与 Node.js 应用程序。

作者最新文章
相关文章
更多