以下是JavaScript数据类型的详细归纳:
原始类型 (Primitive Types)
String (字符串)
- 类型分类: 原始类型
- 存储位置: 栈内存
- 可变性: 不可变
- 默认值:
""(空字符串) - 比较方式: 值比较
- 关键特性: 创建后无法修改,任何修改都会创建新字符串
Number (数字)
- 类型分类: 原始类型
- 存储位置: 栈内存
- 可变性: 不可变
- 默认值:
0 - 比较方式: 值比较
- 关键特性: 包含整数、浮点数、NaN、Infinity
Boolean (布尔)
- 类型分类: 原始类型
- 存储位置: 栈内存
- 可变性: 不可变
- 默认值:
false - 比较方式: 值比较
- 关键特性: 只有两个值:true和false
null
- 类型分类: 原始类型
- 存储位置: 栈内存
- 可变性: 不可变
- 默认值:
null - 比较方式: 值比较
- 关键特性: 表示空值,typeof返回"object"(历史遗留问题)
undefined
- 类型分类: 原始类型
- 存储位置: 栈内存
- 可变性: 不可变
- 默认值:
undefined - 比较方式: 值比较
- 关键特性: 变量声明但未赋值时的默认值
Symbol (符号)
- 类型分类: 原始类型
- 存储位置: 栈内存
- 可变性: 不可变
- 默认值: 无默认值
- 比较方式: 值比较(每个Symbol都是唯一的)
- 关键特性: ES6新增,用于创建唯一标识符
BigInt (大整数)
- 类型分类: 原始类型
- 存储位置: 栈内存
- 可变性: 不可变
- 默认值: 无默认值
- 比较方式: 值比较
- 关键特性: ES2020新增,用于表示任意精度的整数
引用类型 (Reference Types)
Object (对象)
- 类型分类: 引用类型
- 存储位置: 堆内存,栈中存储引用地址
- 可变性: 可变
- 默认值:
null或{} - 比较方式: 引用比较
- 关键特性: 键值对集合,所有引用类型的基类
Array (数组)
- 类型分类: 引用类型(Object的特殊形式)
- 存储位置: 堆内存,栈中存储引用地址
- 可变性: 可变
- 默认值:
[] - 比较方式: 引用比较
- 关键特性: 有序的元素集合,有length属性
Function (函数)
- 类型分类: 引用类型
- 存储位置: 堆内存,栈中存储引用地址
- 可变性: 可变
- 默认值:
null - 比较方式: 引用比较
- 关键特性: 可执行对象,有一等公民地位
Date (日期)
- 类型分类: 引用类型
- 存储位置: 堆内存,栈中存储引用地址
- 可变性: 可变
- 默认值:
null - 比较方式: 引用比较
- 关键特性: 表示日期和时间的内置对象
RegExp (正则表达式)
- 类型分类: 引用类型
- 存储位置: 堆内存,栈中存储引用地址
- 可变性: 可变
- 默认值:
null - 比较方式: 引用比较
- 关键特性: 用于模式匹配的正则表达式对象
Map
- 类型分类: 引用类型
- 存储位置: 堆内存,栈中存储引用地址
- 可变性: 可变
- 默认值:
null - 比较方式: 引用比较
- 关键特性: 键值对集合,键可以是任意类型
Set
- 类型分类: 引用类型
- 存储位置: 堆内存,栈中存储引用地址
- 可变性: 可变
- 默认值:
null - 比较方式: 引用比较
- 关键特性: 值唯一的集合
WeakMap
- 类型分类: 引用类型
- 存储位置: 堆内存,栈中存储引用地址
- 可变性: 可变
- 默认值:
null - 比较方式: 引用比较
- 关键特性: 键必须是对象,弱引用,不影响垃圾回收
WeakSet
- 类型分类: 引用类型
- 存储位置: 堆内存,栈中存储引用地址
- 可变性: 可变
- 默认值:
null - 比较方式: 引用比较
- 关键特性: 值必须是对象,弱引用,不影响垃圾回收
总结对比
| 特性 | 原始类型 | 引用类型 |
|---|---|---|
| 存储位置 | 栈内存 | 堆内存(值)+栈内存(引用) |
| 可变性 | 不可变 | 可变 |
| 比较方式 | 值比较 | 引用比较 |
| 复制行为 | 深拷贝 | 浅拷贝(复制引用) |
| 内存管理 | 自动回收 | 通过引用计数和垃圾回收 |
一、JavaScript 数据类型概览
数据类型
├── 原始类型 (Primitive Types)
│ ├── String (字符串)
│ ├── Number (数字)
│ ├── Boolean (布尔)
│ ├── null
│ ├── undefined
│ ├── Symbol (符号)
│ └── BigInt (大整数)
└── 引用类型 (Reference Types)
├── Object (对象)
├── Array (数组)
├── Function (函数)
├── Date (日期)
├── RegExp (正则表达式)
├── Map
├── Set
├── WeakMap
└── WeakSet
二、原始类型详解
1. String (字符串)
- 表示文本数据
- 创建方式:
let str1 = "双引号" let str2 = '单引号' let str3 = `模板字符串${变量}`
2. Number (数字)
- 表示整数和浮点数
- 特殊值:
Infinity/-InfinityNaN(Not a Number)
- 示例:
let num1 = 42 let num2 = 3.14 let num3 = Infinity
3. Boolean (布尔)
- 逻辑值:
true或false - 示例:
let isTrue = true let isFalse = false
4. null 和 undefined
null: 表示空值或不存在的对象undefined: 变量已声明但未赋值- 示例:
let empty = null let notDefined console.log(notDefined) // undefined
5. Symbol (符号)
- ES6新增,唯一且不可变
- 示例:
let sym1 = Symbol('id') let sym2 = Symbol('id') console.log(sym1 === sym2) // false
6. BigInt
- ES2020新增,任意精度整数
- 示例:
let bigNum = 123456789012345678901234567890n
三、引用类型详解
1. Object (对象)
let person = {
name: "张三",
age: 30,
city: "北京"
}
2. Array (数组)
let fruits = ["苹果", "香蕉", "橙子"]
console.log(fruits[0]) // "苹果"
3. Function (函数)
function greet(name) {
return `Hello, ${name}!`
}
4. 其他引用类型
- Date:
new Date() - RegExp:
/abc/ - Map/Set:
new Map(),new Set() - WeakMap/WeakSet:
new WeakMap()
四、类型判断方法
1. typeof 运算符
返回一个字符串,表示未经计算的操作数的类型。
typeof "hello" → "string"
typeof 42 → "number"
typeof true → "boolean"
typeof undefined → "undefined"
typeof null → "object" // 注意!
typeof Symbol() → "symbol"
typeof 123n → "bigint"
typeof {} → "object"
typeof [] → "object" // 注意!
typeof function(){} → "function"
注意:typeof null 返回 "object" 是JavaScript的一个已知错误。why?
2. instanceof 运算符
检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
[] instanceof Array // true
{} instanceof Object // true
function(){} instanceof Function // true
3. Object.prototype.toString.call()
最准确的类型判断方法,返回格式为 [object Type] 的字符串。
Object.prototype.toString.call("hello") // [object String]
Object.prototype.toString.call(42) // [object Number]
Object.prototype.toString.call([]) // [object Array]
Object.prototype.toString.call({}) // [object Object]
五、类型转换
1. 隐式转换规则
在某些操作中,JavaScript会自动进行类型转换。
- 字符串拼接:
"5" + 1 // "51" "5" + true // "5true" - 数学运算:
"5" - 2 // 3 "5" * "2" // 10 true + 1 // 2 - 比较运算:
"5" == 5 // true (宽松相等) "5" === 5 // false (严格相等)
2. 显式转换方法
- 转字符串:
String(123) // "123" (123).toString() // "123" - 转数字:
Number("123") // 123 parseInt("123") // 123 parseFloat("12.34") // 12.34 +"123" // 123 - 转布尔值:
Boolean(0) // false Boolean("") // false Boolean(null) // false Boolean(undefined) // false Boolean(NaN) // false Boolean(1) // true Boolean("hello") // true
六、重要注意事项
-
原始类型 vs 引用类型
- 原始类型:存储在栈内存,按值访问
- 引用类型:存储在堆内存,按引用访问
-
类型判断陷阱
typeof null返回 "object"typeof []返回 "object"- 使用
Array.isArray()判断数组
-
相等比较
- 推荐使用
===和!==避免隐式转换
- 推荐使用
-
布尔转换假值
false,0,"",null,undefined,NaN
建议使用严格相等(===)避免隐式转换带来的意外结果。
在if条件中,JavaScript会自动进行布尔转换。