在 JavaScript 中,数据类型可以分为两大类:原始类型(基本类型) 和引用类型(对象类型) 。
原始类型 的值是直接存储在栈内存中的简单数据段,它们是按值访问的。操作的是实际的值。
引用类型 的值是存储在堆内存中的对象,栈内存中存储的是对象的引用地址。操作的是对象的引用。
一、七种基本数据类型(ES6 之后)
ES5 中有5种基本数据类型,ES6 新增了 Symbol
,ES2020 新增了 BigInt
。所以目前共有 7种:
- Undefined
- Null
- Boolean
- Number
- String
- Symbol (ES6 新增)
- BigInt (ES2020 新增)
二、每种类型详解
1. Undefined 类型
含义 :表示一个变量已被声明但尚未被赋值,或者根本不存在。
值 :只有一个值,就是 undefined
。
javascript
let a;
console.log(a); // 输出:undefined
console.log(typeof a); // 输出:"undefined"
// 访问一个未声明的变量会报错,但使用 typeof 是安全的
// console.log(b); // 会报错:ReferenceError: b is not defined
console.log(typeof b); // 输出:"undefined" (这是一个历史遗留的"安全特性")
2. Null 类型
含义 :表示一个"空"值,即"没有对象"。
值 :只有一个值,就是 null
。
javascript
let empty = null;
console.log(empty); // 输出:null
console.log(typeof empty); // 输出:"object" (这是一个著名的 JavaScript 历史 Bug)
注意 :typeof null
返回 "object"
是语言本身的一个错误,但它已被广泛使用,无法修复。
Undefined 与 Null 的区别:
undefined
是表示系统级的、出乎意料的或类似错误的"空值"。null
是表示程序级的、正常的或意料之中的"空值"。- 在非严格相等(
==
)下,undefined == null
为true
;在严格相等(===
)下,undefined === null
为false
。
3. Boolean 类型
含义 :表示逻辑实体,真或假。
值 :只有两个值:true
和 false
。
javascript
let isLoggedIn = true;
let isEmpty = false;
布尔转换(Falsy Values) :
在条件判断(如 if
语句)中,其他类型的值会自动转换为布尔值。以下值会被转换为 false
,称为 "假值" :
false
undefined
null
0
、-0
、NaN
""
(空字符串)document.all
(一个历史遗留特性)
所有其他值(包括空数组 []
、空对象 {}
)都会被转换为 true
。
javascript
console.log(Boolean(0)); // false
console.log(Boolean("hello")); // true
console.log(Boolean("")); // false
console.log(Boolean({})); // true (注意!)
console.log(Boolean([])); // true (注意!)
4. Number 类型
含义 :表示整数和浮点数(双精度 64 位二进制格式 IEEE 754)。
特殊值 :NaN
(Not a Number)、+Infinity
(正无穷)、-Infinity
(负无穷)。
javascript
let integer = 42;
let float = 3.14159;
let negative = -10;
let scientific = 2.998e8; // 2.998 * 10^8
// 特殊值
let notANumber = NaN;
let infinity = Infinity;
NaN 的特点:
NaN
是唯一一个不等于自身的值。- 使用
isNaN()
或更现代的Number.isNaN()
来判断一个值是否为NaN
。
javascript
console.log(NaN === NaN); // false
console.log(isNaN(NaN)); // true
console.log(isNaN("abc")); // true (会先尝试转换为数字)
console.log(Number.isNaN("abc")); // false (只有确实是 NaN 时才返回 true,推荐使用)
5. String 类型
含义 :表示文本数据,由 16 位无符号整数值(UTF-16 编码)的"元素"组成。
表示 :可以用单引号('
)、双引号("
)或反引号(`````)表示。
javascript
let name1 = 'Alice';
let name2 = "Bob";
let greeting = `Hello, ${name1}!`; // 模板字符串,可以嵌入变量和表达式
console.log(greeting); // 输出:Hello, Alice!
特点:
- 字符串是不可变的(immutable)。一旦创建,无法直接修改其中的字符。所有字符串方法(如
toUpperCase()
,slice()
)都会返回一个新字符串,而不会改变原字符串。
javascript
let str = "hello";
str[0] = "H"; // 这个操作是无效的
console.log(str); // 输出仍然是 "hello"
let newStr = str.toUpperCase();
console.log(newStr); // 输出 "HELLO"
console.log(str); // 输出仍然是 "hello"
6. Symbol 类型 (ES6)
含义 :表示唯一的、不可变的值,主要用于对象的属性名,以避免属性名冲突。
创建 :通过 Symbol()
函数创建。
javascript
let sym1 = Symbol();
let sym2 = Symbol("description"); // 可以传入一个可选的描述字符串
let sym3 = Symbol("description");
console.log(sym2 === sym3); // false,每个 Symbol 都是唯一的,即使描述相同
console.log(sym2.description); // 输出 "description"
主要用途:
- 作为对象的唯一属性键。
- 用于定义对象的"元"属性或内部方法(例如,
Symbol.iterator
用于定义迭代器)。
javascript
const MY_KEY = Symbol();
let obj = {};
obj[MY_KEY] = "secret value"; // 使用 Symbol 作为键
console.log(obj[MY_KEY]); // 输出 "secret value"
// 常规的 for...in 循环或 Object.keys() 无法遍历到 Symbol 键
for (let key in obj) {
console.log(key); // 无输出
}
7. BigInt 类型 (ES2020)
含义 :用于表示任意精度的整数。解决了 Number
类型无法安全表示大于 2^53 - 1
(Number.MAX_SAFE_INTEGER
)的整数的问题。
创建 :在一个整数字面量后面加 n
,或者调用 BigInt()
函数。
javascript
const bigNumber = 9007199254740991n; // 字面量加 n
const alsoBig = BigInt(9007199254740991); // 使用 BigInt 函数
console.log(typeof bigNumber); // "bigint"
// 超出 Number 安全范围的计算
console.log(9007199254740991n + 1n); // 正确:9007199254740992n
console.log(Number(9007199254740991) + 1); // 错误:可能得到 9007199254740992 或精度丢失的结果
注意:
BigInt
不能和Number
直接进行混合数学运算,需要先转换为同一类型。
javascript
// console.log(1n + 2); // 报错:TypeError: Cannot mix BigInt and other types
console.log(1n + BigInt(2)); // 正确:3n
console.log(Number(1n) + 2); // 正确:3
三、如何检测数据类型:typeof
操作符
typeof
操作符返回一个字符串,表示未经计算的操作数的类型。
类型 | typeof 返回值 |
示例 |
---|---|---|
Undefined | "undefined" |
typeof undefined |
Null | "object" (历史 Bug) |
typeof null |
Boolean | "boolean" |
typeof true |
Number | "number" |
typeof 42 |
String | "string" |
typeof "hello" |
Symbol | "symbol" |
typeof Symbol() |
BigInt | "bigint" |
typeof 9007199254740991n |
Function (对象) | "function" |
typeof function(){} |
其他所有对象 | "object" |
typeof {} 、typeof [] |
注意 :typeof
对于数组和普通对象都返回 "object"
。要区分它们,需要使用 Array.isArray()
或其他方法。
javascript
console.log(typeof []); // "object"
console.log(Array.isArray([])); // true
console.log(typeof {}); // "object"
console.log(typeof null); // "object"
总结
数据类型 | 含义 | 关键特性 |
---|---|---|
Undefined |
未定义 | 变量声明未赋值 |
Null |
空值 | typeof null === 'object' (Bug) |
Boolean |
布尔值 | true / false , falsy values 需注意 |
Number |
数字 | 双精度浮点数,包含 NaN , Infinity |
String |
字符串 | 不可变,可用模板字符串 |
Symbol |
唯一值 | 用于创建对象的唯一属性键 |
BigInt |
大整数 | 表示任意精度的整数,后缀 n |