JavaScript 数据类型
总览
JavaScript 共有 8 种数据类型,分为两大类:
JavaScript 数据类型
├── 原始类型(Primitive)— 7 种
│ ├── number
│ ├── string
│ ├── boolean
│ ├── undefined
│ ├── null
│ ├── symbol (ES6)
│ └── bigint (ES2020)
│
└── 引用类型(Reference)— 1 种
└── object
├── 普通对象 {}
├── 数组 Array
├── 函数 Function
├── 日期 Date
├── 正则 RegExp
├── Map / Set / WeakMap / WeakSet
└── …
原始类型 vs 引用类型
这是最核心的区别:
| 存储内容 | 直接存储值本身 | 存储内存地址(引用) |
| 存放位置 | 栈(Stack) | 堆(Heap),栈中存地址 |
| 赋值行为 | 拷贝值(独立副本) | 拷贝引用(指向同一对象) |
| 比较方式 | 值比较 | 引用比较 |
| 可变性 | 不可变(immutable) | 可变(mutable) |
赋值与比较的差异
// 原始类型 — 值拷贝,互不影响
let a = 10;
let b = a; // b 拷贝了 a 的值
b = 20;
console.log(a); // 10(a 不受影响)
// 引用类型 — 引用拷贝,共享同一对象
let obj1 = { name: 'Tom' };
let obj2 = obj1; // obj2 拷贝了 obj1 的引用
obj2.name = 'Jerry';
console.log(obj1.name); // 'Jerry'(obj1 也变了)
// 比较差异
console.log(1 === 1); // true — 值相同
console.log({} === {}); // false — 不同引用
可变性差异
// 原始类型不可变 — "修改"实际是创建新值
let str = 'hello';
str[0] = 'H'; // 静默失败(严格模式下报错)
console.log(str); // 'hello'(原值不变)
str = str.toUpperCase(); // 返回新字符串,原字符串不变
console.log(str); // 'HELLO'
// 引用类型可变 — 直接修改原对象
let arr = [1, 2, 3];
arr.push(4); // 修改原数组
console.log(arr); // [1, 2, 3, 4]
各类型详解
1. number
双精度 64 位浮点数(IEEE 754),整数和小数不区分:
let int = 10;
let float = 3.14;
let hex = 0xff; // 255
let octal = 0o77; // 63
let binary = 0b1010; // 10
let exp = 2.5e3; // 2500
// 特殊值
Infinity // 正无穷
–Infinity // 负无穷
NaN // Not a Number(NaN !== NaN)
Number.MAX_SAFE_INTEGER // 9007199254740991 (2^53 – 1)
精度问题:
0.1 + 0.2 === 0.3 // false → 0.30000000000000004
// 解决方案
Number((0.1 + 0.2).toFixed(1)) === 0.3 // true
2. string
UTF-16 编码的字符序列,不可变:
let single = 'hello';
let double = "world";
let template = `${single} ${double}`; // 模板字符串
'hello'.length; // 5
'你好'.length; // 2(UTF-16 code unit 数量)
'𠮷'.length; // 2( surrogate pair,需用 […str] 计数)
3. boolean
只有 true 和 false 两个值。
假值(falsy)列表——其余全为 truthy:
// 这 8 个值在布尔上下文中为 false
false, 0, –0, 0n, '', null, undefined, NaN
// 常见陷阱
Boolean('false') // true(非空字符串)
Boolean([]) // true(空数组是对象)
Boolean({}) // true(空对象是对象)
4. undefined vs null
| 含义 | 声明未赋值 / 不存在 | 空值 / 故意置空 |
| 类型 | typeof undefined === 'undefined' | typeof null === 'object'(历史遗留 bug) |
| 转数字 | NaN | 0 |
| 出现场景 | 变量未初始化、函数无返回值、不存在的属性 | 主动赋值表示"无值" |
let a;
console.log(a); // undefined(未赋值)
console.log(typeof b); // undefined(未声明,typeof 安全)
let c = null; // 主动置空
console.log(null == undefined); // true(宽松相等)
console.log(null === undefined); // false(严格相等)
5. symbol
ES6 引入,表示唯一且不可变的标识符:
const s1 = Symbol('desc');
const s2 = Symbol('desc');
console.log(s1 === s2); // false — 每次都唯一
// 主要用途:定义对象的唯一属性键
const key = Symbol('id');
const user = { [key]: 123, name: 'Tom' };
console.log(user[key]); // 123
// Symbol 属性不参与常规遍历
Object.keys(user); // ['name']
Object.getOwnPropertySymbols(user); // [Symbol(id)]
// 全局 Symbol 注册表
const g1 = Symbol.for('app.id'); // 创建或获取
const g2 = Symbol.for('app.id'); // 获取同一个
console.log(g1 === g2); // true
6. bigint
ES2020 引入,表示任意精度整数,解决 number 的安全整数限制:
const big = 9007199254740993n; // 后缀 n
const fromStr = BigInt('9007199254740993');
// number 的精度丢失
console.log(9007199254740992 === 9007199254740993); // true(丢失精度)
// bigint 精确
console.log(9007199254740992n === 9007199254740993n); // false
// bigint 与 number 不可混合运算
10n + 20n; // 30n ✓
10n + 20; // TypeError ✗
Number(10n) + 20; // 30 ✓(显式转换)
7. object
引用类型的统称,一切非原始类型皆为对象:
// 普通对象
const obj = { key: 'value' };
// 数组
const arr = [1, 2, 3];
// 函数(也是对象,可有属性)
function fn() {}
fn.customProp = 'hello';
// 内置对象
const map = new Map();
const set = new Set();
const date = new Date();
const regex = /pattern/;
类型检测
| typeof | 原始类型(除 null) | typeof null === 'object',typeof [] === 'object' |
| instanceof | 引用类型 | 跨 iframe 失效,原始类型返回 false |
| Object.prototype.toString.call() | 最准确 | 写法稍长 |
| === | null / undefined 检测 | 仅此用途 |
// typeof
typeof 10 // 'number'
typeof 'hi' // 'string'
typeof true // 'boolean'
typeof undefined // 'undefined'
typeof Symbol() // 'symbol'
typeof 10n // 'bigint'
typeof null // 'object' ← bug
typeof {} // 'object'
typeof [] // 'object' ← 无法区分数组
typeof function(){} // 'function'
// instanceof
[] instanceof Array // true
{} instanceof Object // true
// Object.prototype.toString.call() — 最可靠
Object.prototype.toString.call(10) // '[object Number]'
Object.prototype.toString.call(null) // '[object Null]'
Object.prototype.toString.call([]) // '[object Array]'
Object.prototype.toString.call(/regex/) // '[object RegExp]'
类型转换速查
// → string
String(123) // '123'
(123).toString() // '123'
123 + '' // '123'
// → number
Number('42') // 42
parseInt('42px') // 42
parseFloat('3.14') // 3.14
+'42' // 42
'42' – 0 // 42
// → boolean
Boolean(0) // false
!!'hello' // true
一句话总结:JavaScript 有 7 种原始类型(number、string、boolean、undefined、null、symbol、bigint)和 1 种引用类型(object),核心区别在于原始类型按值存储且不可变,引用类型按引用存储且可变。


