在 JavaScript 中,数据类型检测是开发中的常见需求。以下是主要检测方法及其优缺点:
1. typeof 操作符
最基础的检测方式,返回类型字符串:
javascript
typeof 42; // "number"
typeof "hello"; // "string"
typeof true; // "boolean"
typeof undefined; // "undefined"
typeof function() {}; // "function"
typeof Symbol(); // "symbol"
typeof {}; // "object"
typeof []; // "object" (注意!)
typeof null; // "object" (历史遗留问题)
缺点:
- 无法区分数组、对象、null(都返回 "object")
2. instanceof 操作符
检测对象是否属于某个构造函数的实例:
javascript
[] instanceof Array; // true
{} instanceof Object; // true
new Date() instanceof Date; // true
function Person() {}
const p = new Person();
p instanceof Person; // true
缺点:
- 不适用于原始值类型(数字、字符串等)
- 多窗口/iframe 环境下失效(不同全局环境)
3. Object.prototype.toString.call()
最可靠的检测方法,返回 [object Type] 格式:
javascript
Object.prototype.toString.call(42); // "[object Number]"
Object.prototype.toString.call("hello"); // "[object String]"
Object.prototype.toString.call([]); // "[object Array]"
Object.prototype.toString.call(null); // "[object Null]"
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(/regex/); // "[object RegExp]"
封装工具函数:
javascript
function getType(obj) {
return Object.prototype.toString.call(obj)
.slice(8, -1)
.toLowerCase();
}
getType([]); // "array"
getType(null); // "null"
4. 特殊类型检测
- 数组检测:
javascript
Array.isArray([]); // true (ES5+ 最佳方案)
// 旧浏览器兼容方案:
Object.prototype.toString.call([]) === "[object Array]";
- NaN 检测:
javascript
isNaN(NaN); // true (注意: isNaN("abc") 也返回 true)
Number.isNaN(NaN); // true (ES6 推荐,严格检测)
- null/undefined 检测:
javascript
let foo = null;
foo === null; // true (精确检测 null)
typeof bar === "undefined"; // 检测未定义
终极解决方案
结合多种方式实现全类型检测:
javascript
function detectType(value) {
// 处理 null 和 undefined
if (value === null) return "null";
if (value === undefined) return "undefined";
// 处理其他类型
const type = typeof value;
if (type !== "object") return type; // 原始类型直接返回
// 对象类型细化
return Object.prototype.toString.call(value)
.slice(8, -1)
.toLowerCase();
}
// 测试
detectType([]); // "array"
detectType(new Map()); // "map"
detectType(Symbol()); // "symbol"
detectType(42); // "number"
总结对比
方法 | 优点 | 缺点 |
---|---|---|
typeof | 简单快速,适合原始类型 | 无法区分数组/对象/null |
instanceof | 检测自定义对象 | 不适用原始类型,多窗口环境失效 |
Object.prototype.toString | 精准识别所有类型(推荐) | 语法稍复杂 |
Array.isArray() | 数组检测最优解 | 仅适用于数组 |
最佳实践:
- 基础类型检测 → typeof
- 数组检测 → Array.isArray()
- 完整类型检测 → Object.prototype.toString.call()
- null 检测 → value === null