介绍
JavaScript 中的数据类型分为两大类:原始类型(Primitive Types)和引用类型(Reference Types)。当然也能成为基本数据类型和复杂数据类型。
当然,不论是在使用还是在读取堆栈,判断数据类型俩种数据类型还是有很大的区别的。
下面详细介绍这两种类型及其区别,并给出具体的例子。
数据类型
原始类型
原始类型包括以下几种:
Number
: 数字
String
: 字符串
- Boo`lean: 布尔值
Null
: 空值
Undefined
: 未定义
Symbol
: 符号
BigInt
: 大整数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| let num = 123; console.log(num);
let str = "Hello, world!"; console.log(str);
let bool = true; console.log(bool);
let undef; console.log(undef);
let n = null; console.log(n);
let sym = Symbol("unique"); console.log(sym);
let bigInt = 123456789012345678901234567890n; console.log(bigInt);
|
引用类型
引用类型包括以下几种:
Object
: 对象
Array
: 数组
Function
: 函数
Date
: 日期
Map
: 映射
Set
: 集合
WeakMap
: 弱映射
WeakSet
: 弱集合
RegExp
: 正则表达式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| let obj = { name: "Alice", age: 30 }; console.log(obj);
let arr = [1, 2, 3]; console.log(arr);
let func = function () { console.log("Hello"); }; func();
let date = new Date(); console.log(date);
let map = new Map(); map.set("key1", "value1"); console.log(map);
let set = new Set(); set.add(1).add(2).add(3); console.log(set);
let weakMap = new WeakMap(); weakMap.set(obj, "value"); console.log(weakMap);
let weakSet = new WeakSet(); weakSet.add(obj); console.log(weakSet);
let regex = /hello/; console.log(regex);
|
堆栈使用
栈(Stack)
栈是一种先进后出(Last In First Out, LIFO)的数据结构。栈主要用于存储函数调用时的局部变量和执行上下文。
特性:
- 操作简单:只有两个操作:压入(push)和弹出(pop)。
- 内存分配和释放速度快。
- 通常用于函数调用和局部变量。
1 2 3 4 5 6 7
| function stackExample() { let localVar = "local"; console.log(localVar); }
stackExample(); console.log(localVar);
|
堆(Heap)
堆是一种动态内存区域,用于存储对象。堆中的内存分配和释放相对复杂,但提供了更大的灵活性。
特性:
- 动态分配:可以在运行时动态创建和销毁对象。
- 内存分配和释放较慢。
- 通常用于存储对象和全局变量。
1 2 3 4 5 6 7 8 9 10
| function heapExample() { let obj = { name: "Alice", age: 30 }; console.log(obj); }
heapExample();
let globalObj = { name: "Bob", age: 25 }; console.log(globalObj);
|
区别
- 原始类型:存储在栈中,直接存储值。
- 引用类型:存储在堆中,栈中存储的是指向堆中对象的引用。
- 栈:先进后出的数据结构,主要用于存储函数调用时的局部变量和执行上下文。
- 堆:动态内存区域,用于存储对象,提供了更大的灵活性。
如何更加清晰的理解呢?
举个例子来讲:
1 2 3 4 5 6 7 8 9 10
| let name = "Tom";
let obj1 = { a: 1 }; let obj2 = obj1;
obj1.a = 3;
|
可以参考下面图片:

判断数据类型
在 JavaScript 中,判断数据类型有多种方法,每种方法都有其适用场景和局限性。以下是几种常用的方法及其区别
typeof
typeof
是最简单的判断数据类型的方法,主要用于判断基本数据类型。它能准确地识别 string、number、boolean、undefined
和 symbol。
1 2 3 4 5 6 7 8 9 10
| console.log(typeof "hello"); console.log(typeof 123); console.log(typeof true); console.log(typeof undefined); console.log(typeof Symbol("sym"));
console.log(typeof null); console.log(typeof {}); console.log(typeof []);
|
instanceof
instanceof
是 JavaScript 中的一个运算符,用于判断一个对象是否是某个类的实例。它主要用于判断引用类型。
1 2 3 4
| console.log([] instanceof Array); console.log({} instanceof Object); console.log(function () {} instanceof Function); console.log(new Date() instanceof Date);
|
Object.prototype.toString.call()
Object.prototype.toString.call()
可以准确判断所有类型的数据,包括 null
和 undefined
。
1 2 3 4 5 6 7 8 9
| console.log(Object.prototype.toString.call("hello")); console.log(Object.prototype.toString.call(123)); console.log(Object.prototype.toString.call(true)); console.log(Object.prototype.toString.call(undefined)); console.log(Object.prototype.toString.call(null)); console.log(Object.prototype.toString.call([])); console.log(Object.prototype.toString.call({})); console.log(Object.prototype.toString.call(function () {})); console.log(Object.prototype.toString.call(new Date()));
|
Array.isArray()
Array.isArray()
专门用于判断一个值是否为数组。
1 2 3
| console.log(Array.isArray([])); console.log(Array.isArray({})); console.log(Array.isArray([1, 2, 3]));
|
Buffer.isBuffer() (Node.js)
Buffer.isBuffer()
是 Node.js 中的一个方法,用于判断一个值是否为 Buffer 对象。
1 2 3 4
| const buffer = Buffer.from("hello"); console.log(Buffer.isBuffer(buffer)); console.log(Buffer.isBuffer({})); console.log(Buffer.isBuffer([]));
|
总结
typeof
:简单易用,适用于基本数据类型。
instanceof
:适用于复杂对象类型,但需要考虑原型链的问题。
Object.prototype.toString.call()
:适用于所有类型的数据,最准确。
Array.isArray()
:专门用于判断数组。
Buffer.isBuffer()
:仅在 Node.js
中使用,用于判断 Buffer
对象。