JavaScript 中判断数据类型的方法
JavaScript 的数据类型
JavaScript 中有 8 种数据类型:
- 基本数据类型(原始类型):
- Number(数字)
- String(字符串)
- Boolean(布尔值)
- Null(空值)
- Undefined(未定义)
- Symbol(ES6 新增,符号)
- BigInt(ES10 新增,大整数)
- 引用数据类型:
- Object(对象,包括普通对象 Object、数组 Array、函数 Function、日期 Date、正则 RegExp 等)
判断数据类型的方法
1. typeof 操作符
typeof 123; // "number"
typeof "abc"; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof Symbol(); // "symbol"
typeof 123n; // "bigint"
typeof {}; // "object"
typeof []; // "object"
typeof null; // "object" (这是一个历史遗留问题,实际上null不是对象)
typeof console.log; // "function"
特点:
- 简单易用,但对于引用类型的判断不够精确
- 不能区分 Array、null 和普通 Object
- 但能单独识别 Function 类型
2. instanceof 操作符
检测构造函数的 prototype 属性是否出现在对象的原型链中。
[] instanceof Array; // true
[] instanceof Object; // true (因为Array继承自Object)
new Date() instanceof Date; // true
/regex/ instanceof RegExp; // true
({}) instanceof Object; // true
特点:
- 适合用于检测引用类型
- 考虑了原型链,所以会检测到继承关系
- 无法正确判断基本数据类型,除非是通过构造函数创建的基本类型
3. Object.prototype.toString.call()
最准确的判断方法。
Object.prototype.toString.call(123); // "[object Number]"
Object.prototype.toString.call("abc"); // "[object String]"
Object.prototype.toString.call(true); // "[object Boolean]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(Symbol()); // "[object Symbol]"
Object.prototype.toString.call(123n); // "[object BigInt]"
Object.prototype.toString.call({}); // "[object Object]"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call(function () {}); // "[object Function]"
Object.prototype.toString.call(new Date()); // "[object Date]"
Object.prototype.toString.call(/regex/); // "[object RegExp]"
特点:
- 最准确、全面的类型检测方法
- 可以检测所有的数据类型,包括基本类型和引用类型
- 返回格式为"[object Type]",需要处理字符串提取真正的类型
4. Array.isArray()
专门用于判断数组类型的方法。
Array.isArray([]); // true
Array.isArray({}); // false
特点:
- 专门用于检测数组类型
- ES5 新增的方法,旧浏览器可能不支持
5. 构造函数名(constructor)
通过查看实例的 constructor 属性来判断类型。
(123).constructor === Number; // true
"abc".constructor === String; // true
true.constructor === Boolean; // true
({}).constructor === Object; // true
[].constructor === Array; // true
(function () {}).constructor === Function; // true
特点:
- 简单易用
- 但 constructor 属性可以被修改,不够可靠
- null 和 undefined 没有 constructor 属性
封装通用的类型判断函数
function getType(value) {
// 处理null特殊情况
if (value === null) {
return "null";
}
// 处理基本类型和函数
const typeOfResult = typeof value;
if (typeOfResult !== "object") {
return typeOfResult;
}
// 处理引用类型
const objectTypeString = Object.prototype.toString.call(value);
const type = objectTypeString.slice(8, -1).toLowerCase();
return type;
}
// 使用示例
getType(123); // "number"
getType("abc"); // "string"
getType(true); // "boolean"
getType(undefined); // "undefined"
getType(null); // "null"
getType(Symbol()); // "symbol"
getType(123n); // "bigint"
getType({}); // "object"
getType([]); // "array"
getType(function () {}); // "function"
getType(new Date()); // "date"
getType(/regex/); // "regexp"
延伸问题
- typeof null 为什么会返回 "object"?
- instanceof 操作符的工作原理是什么?
- 如何可靠地检测数组类型?
- 如何区分普通对象和其他引用类型如数组、日期等?
- 实现一个通用的类型检测函数。