如何在JavaScript中检测不同对象类型?(数组、JSON、日期等)
我之前在处理递归遍历JSON和MongoDB返回的数据时也遇到过一模一样的问题——typeof简直是个“懒家伙”,对数组、日期、普通对象统一返回object,根本没法区分。先把你的问题场景贴出来方便大家理解:
var aJSON = {"foo" : 1, "bar" : 2}; var anArray = [1,2,3,4,5]; var aDate = new Date('2013-03-10T02:00:00Z'); var anISODate = user.timesTheyLoggedIn[0] // 来自MongoDB console.log(typeof aJSON); // object console.log(typeof anArray); // object console.log(typeof aDate); // object console.log(typeof anISODate); // object
下面分享几个实用的区分方法,完全可以直接用到递归遍历逻辑里:
1. 用Array.isArray()快速区分数组
这是ES5新增的API,专门用来判断数组类型,简单靠谱:
console.log(Array.isArray(anArray)); // true console.log(Array.isArray(aJSON)); // false
如果要兼容极低版本的浏览器,也可以用Object.prototype.toString.call(obj) === '[object Array]'来替代。
2. 用Object.prototype.toString.call()精准识别所有类型
这个方法是区分内置对象类型的“万能钥匙”,能返回最准确的类型标识:
function getExactType(obj) { // 截取`[object Type]`里的Type部分 return Object.prototype.toString.call(obj).slice(8, -1); } console.log(getExactType(aJSON)); // Object console.log(getExactType(anArray)); // Array console.log(getExactType(aDate)); // Date // MongoDB的ISODate对象通常会返回"Date"或者特定的"ISODate",取决于驱动版本 console.log(getExactType(anISODate)); // Date / ISODate
这个方法几乎能区分所有JS内置类型(比如RegExp、Map、Set等),非常适合递归遍历里的类型判断。
3. 针对MongoDB ISODate的特殊判断
如果是MongoDB返回的ISODate对象,除了上面的方法,还可以通过构造函数或者专属特征来判断:
function isMongoISODate(obj) { // 先判断是Date实例,再检查toString是否包含ISODate标识 return obj instanceof Date && obj.toString().startsWith('ISODate('); } // 或者直接检查构造函数名称 function isMongoISODateAlt(obj) { return typeof obj === 'object' && obj.constructor.name === 'ISODate'; }
4. 整合到递归遍历的完整示例
把上面的判断逻辑整合到递归函数里,就能轻松处理不同类型的对象了:
function traverseObject(obj) { const type = getExactType(obj); switch(type) { case 'Array': console.log(`📋 遍历数组,长度:${obj.length}`); obj.forEach((item, index) => { console.log(` 索引${index}:`); traverseObject(item); }); break; case 'Date': // 区分普通Date和MongoDB ISODate const isMongoDate = obj.toString().startsWith('ISODate('); console.log(`📅 ${isMongoDate ? 'MongoDB ISODate' : '普通Date'}:${obj.toISOString()}`); break; case 'Object': console.log(`🔍 遍历普通JSON对象,键数量:${Object.keys(obj).length}`); for (const key of Object.keys(obj)) { console.log(` 键${key}:`); traverseObject(obj[key]); } break; default: console.log(`🔹 基本类型(${type}):${obj}`); } } // 测试调用 traverseObject(aJSON); traverseObject(anArray); traverseObject(aDate); traverseObject(anISODate);
内容的提问来源于stack exchange,提问作者Félix Paradis
相关产品推荐
相关产品推荐

