JavaScript中的数据类型可以分为两大类,分别是原始类型和引用类型,不同的数据类型在存储方式、赋值逻辑和判断方法上都有明显差异,掌握这些差异是写出稳定代码的基础。

JavaScript包含的所有数据类型
JavaScript目前共有8种内置数据类型,按照存储和特性可以分为原始类型和引用类型两个大类:
- 原始类型(基本数据类型):Undefined、Null、Boolean、Number、String、Symbol、BigInt
- 引用类型(复杂数据类型):Object,常见的Array、Function、Date、RegExp等都属于Object的子类型
原始类型与引用类型的核心差异
存储方式不同
原始类型的值直接存储在栈内存中,每个变量对应一块独立的栈空间,修改一个变量的值不会影响其他变量。引用类型的值存储在堆内存中,变量在栈内存中保存的是指向堆内存中实际数据的引用地址,多个变量可以指向同一个引用地址。
赋值逻辑不同
原始类型赋值时,会把当前变量的值复制一份给新变量,之后两个变量互不影响。引用类型赋值时,只是把栈中的引用地址复制给新变量,两个变量指向同一个堆内存数据,修改其中一个变量的属性,另一个变量也会受到影响。
我们可以通过下面的代码示例直观看到两者的赋值差异:
// 原始类型赋值示例
let a = 10;
let b = a; // 复制a的值给b
b = 20;
console.log(a); // 输出10,a的值没有被修改
console.log(b); // 输出20
// 引用类型赋值示例
let obj1 = { name: '张三', age: 20 };
let obj2 = obj1; // 复制obj1的引用地址给obj2
obj2.age = 25;
console.log(obj1.age); // 输出25,obj1的age属性被修改了
console.log(obj2.age); // 输出25
比较方式不同
原始类型比较的是值本身,只要两个变量的值相等,就认为它们相等。引用类型比较的是引用地址,即使两个对象的内容完全相同,只要它们的引用地址不同,比较结果就是不相等。
对应的代码示例如下:
// 原始类型比较 let num1 = 100; let num2 = 100; console.log(num1 === num2); // 输出true,值相等 // 引用类型比较 let arr1 = [1, 2, 3]; let arr2 = [1, 2, 3]; console.log(arr1 === arr2); // 输出false,引用地址不同 let arr3 = arr1; console.log(arr1 === arr3); // 输出true,引用地址相同
如何判断数据类型
使用typeof判断原始类型
typeof可以判断大部分原始类型,但是有两个特殊情况:typeof null返回object,typeof 函数返回function。
console.log(typeof undefined); // 输出undefined
console.log(typeof null); // 输出object,这是历史遗留问题
console.log(typeof true); // 输出boolean
console.log(typeof 123); // 输出number
console.log(typeof 'abc'); // 输出string
console.log(typeof Symbol()); // 输出symbol
console.log(typeof 123n); // 输出bigint
console.log(typeof function(){}); // 输出function
使用instanceof判断引用类型
instanceof可以判断一个对象是否是某个构造函数的实例,适合判断引用类型的细分类型,但是不能判断原始类型,且如果原型链被修改,结果可能不准确。
console.log([] instanceof Array); // 输出true
console.log({} instanceof Object); // 输出true
console.log(new Date() instanceof Date); // 输出true
// 原始类型使用instanceof返回false
console.log(123 instanceof Number); // 输出false
使用Object.prototype.toString精准判断
这种方法可以精准判断所有数据类型,包括null和undefined,是实际开发中最常用的精准判断方式。
function getType(target) {
return Object.prototype.toString.call(target).slice(8, -1).toLowerCase();
}
console.log(getType(undefined)); // 输出undefined
console.log(getType(null)); // 输出null
console.log(getType(123)); // 输出number
console.log(getType('abc')); // 输出string
console.log(getType([])); // 输出array
console.log(getType({})); // 输出object
console.log(getType(function(){})); // 输出function
常见注意事项
需要注意NaN是Number类型的特殊值,typeof NaN返回number,但是NaN不等于自身,判断NaN需要使用Number.isNaN()方法。另外原始类型的变量没有属性,给原始类型添加属性不会报错,但是也不会生效,因为原始类型不是对象,操作时会被临时包装成对应的包装对象,操作完成后包装对象就会被销毁。
let str = 'hello'; str.age = 20; // 不会报错,但是属性不会被保存 console.log(str.age); // 输出undefined console.log(NaN === NaN); // 输出false console.log(Number.isNaN(NaN)); // 输出true
JavaScript数据类型原始类型引用类型类型判断修改时间:2026-07-03 00:15:29