JavaScript 中的数据类型是一个非常重要的核心概念。
它主要分为两大类:原始类型(基本类型) 和引用类型(对象类型)。
一、原始类型 (Primitive Types)
原始类型的值是不可变的,直接存储在栈内存中。在比较时,比较的是它们的值。
JavaScript 中有 7 种原始数据类型:
-
number:用于整数和浮点数。- 例如:
let age = 25;,let price = 99.99; - 还包括一些特殊的数值:
Infinity(无穷大)、-Infinity(负无穷大)和NaN(不是一个数字)。
- 例如:
-
string:用于表示文本数据。- 例如:
let name = "Alice";,let msg = 'Hello'; - 可以使用单引号
''、双引号""或反引号``(模板字符串)表示。
- 例如:
-
boolean:逻辑实体,只有两个值:true和false。- 例如:
let isLogged = true;,let isEmpty = false;
- 例如:
-
undefined:表示一个未被赋值的变量。当一个变量被声明但未初始化时,它的默认值就是undefined。- 例如:
let x; console.log(x); // undefined
- 例如:
-
null:表示一个“空”或“不存在”的值。它是一个特殊的关键字。- 例如:
let data = null; - 注意:
typeof null的结果是"object",这是 JavaScript 语言设计上的一个历史遗留错误,但它本身是原始类型。
- 例如:
-
symbol(ES6 新增):表示唯一的、不可变的值。主要用于创建对象的唯一属性键,避免命名冲突。- 例如:
let id = Symbol('id');
- 例如:
-
bigint(ES2020 新增):用于表示任意长度的整数。通过在整数末尾加n来创建。- 例如:
const bigNumber = 123456789012345678901234567890n;
- 例如:
二、引用类型 (Reference Types)
引用类型的值是可变的,存储在堆内存中。变量实际存储的是指向堆内存中对象的地址(引用)。在比较时,比较的是它们在内存中的地址,而不是值本身。
object:是最主要的引用类型。用于存储各种键值对和更复杂的实体。- 普通对象:
{ key: value }- 例如:
let person = { name: 'Bob', age: 30 };
- 例如:
- 数组 (
Array):一种特殊的有序对象,用于存储有序集合。- 例如:
let list = [1, 2, 3]; typeof []的结果是"object"。
- 例如:
- 函数 (
Function):一种特殊的对象,可以被调用。- 例如:
function greet() { console.log('Hi!'); } typeof function() {}的结果是"function"。虽然它是对象,但typeof操作符对其做了特殊处理。
- 例如:
- 其他内置对象:如
Date,RegExp,Map,Set等都属于object类型。
- 普通对象:
关键区别:原始类型 vs 引用类型
| 特征 | 原始类型 (Primitive) | 引用类型 (Reference) |
|---|---|---|
| 存储方式 | 值本身存储在栈中 | 地址存储在栈中,值存储在堆中 |
| 可变性 | 不可变 | 可变 |
| 比较方式 | 按值比较 | 按引用比较(比较地址) |
| 复制方式 | 复制后会创建一个新的独立值 | 复制的是地址引用,指向同一个对象 |
示例说明区别:
1. 可变性 (Mutability)
// 原始类型 - 不可变
let a = "hello";
a.toUpperCase(); // 返回 "HELLO",但不会改变 a 本身
console.log(a); // 输出 "hello"
// 引用类型 - 可变
let b = { count: 1 };
b.count = 2; // 直接修改了对象的内容
console.log(b); // 输出 { count: 2 }
2. 比较 (Comparison)
// 原始类型 - 按值比较
let num1 = 5;
let num2 = 5;
console.log(num1 === num2); // true
// 引用类型 - 按引用比较
let obj1 = { name: "John" };
let obj2 = { name: "John" }; // 这是一个新对象,在内存中位于不同地址
console.log(obj1 === obj2); // false!因为地址不同
let obj3 = obj1; // obj3 和 obj1 指向同一个对象(同一个地址)
console.log(obj1 === obj3); // true
3. 复制 (Copying)
// 原始类型 - 复制值
let x = 10;
let y = x; // y 是 x 的值的一个全新副本
y = 20;
console.log(x); // 10 (x 未受影响)
// 引用类型 - 复制引用
let arr1 = [1, 2, 3];
let arr2 = arr1; // arr2 和 arr1 指向同一个数组
arr2.push(4);
console.log(arr1); // [1, 2, 3, 4] (arr1 也被修改了!)
如何检查数据类型?
-
typeof操作符:最适合判断原始类型(除了null)。typeof 42; // "number" typeof 'blubber'; // "string" typeof true; // "boolean" typeof undefined; // "undefined" typeof Symbol(); // "symbol" typeof 123n; // "bigint" typeof null; // "object" (著名的历史bug) typeof {}; // "object" typeof []; // "object" typeof function(){};// "function" -
instanceof操作符:用于检查一个对象是否属于某个特定的引用类型(如 Array, Date 等)。[] instanceof Array; // true {} instanceof Object; // true new Date() instanceof Date; // true -
Array.isArray()方法:专门用于安全地检查一个值是否为数组。Array.isArray([]); // true Array.isArray({}); // false
总结
| 类型 | 分类 | 说明 |
|---|---|---|
number, string, boolean, undefined, null, symbol, bigint | 原始类型 | 值不可变,按值比较和存储 |
object (包括 Array, Function, Date 等) | 引用类型 | 值可变,按引用比较和存储 |


被折叠的 条评论
为什么被折叠?



