如何用JS的.find()方法实现类似MongoDB的嵌套对象查询?
问题拆解与解决
你的代码之所以返回undefined,以及想要实现类似MongoDB的嵌套对象查询,核心问题和解决方法如下:
1. 类数组用错了
Array.prototype.find处理类数组时,只认**数字索引(0、1、2...)**和length属性。你的arrayLike里只有length:1,但没有0这个属性,所以find遍历的时候拿不到任何有效数据,回调(x)=>x永远返回false,自然返回undefined。
而且你把people作为自定义键塞到类数组里,这完全不符合类数组的规则——类数组的成员必须是数字索引对应的属性,不是自定义命名的键。
2. 对象重复键会被覆盖
你的people对象里写了三个同名的person键,JS对象不允许重复键,后面的会直接覆盖前面的,最后people里只会剩下最后一个{first name: 'mario', ...}的对象,这是基础语法错误。
实现嵌套对象的条件查询
如果要从嵌套结构里按条件找目标对象,得自己写递归遍历函数,不能硬套数组的find方法。比如下面的示例:
// 先修正数据结构,把重复的person改成数组(这是合理的结构) const data = { people: [ { firstName: 'rafa', lastName: 'rivas', age: 20 }, { firstName: 'miguel', lastName: 'blades', age: 23 }, { firstName: 'mario', lastName: 'perez', age: 93 } ] }; // 递归遍历的查找函数,支持数组和嵌套对象 function deepFind(obj, condition) { // 先处理数组:遍历每个元素递归查找 if (Array.isArray(obj)) { for (const item of obj) { const match = deepFind(item, condition); if (match) return match; } } // 处理对象:先检查自身是否符合条件,再遍历属性值递归 else if (typeof obj === 'object' && obj !== null) { if (condition(obj)) return obj; for (const key of Object.keys(obj)) { const match = deepFind(obj[key], condition); if (match) return match; } } // 无匹配返回null return null; } // 示例:查找年龄为23的对象 const target = deepFind(data, item => item.age === 23); console.log(target); // 输出 {firstName: 'miguel', lastName: 'blades', age: 23}
如果一定要用数组的find方法,得把数据改成标准的类数组或数组:
// 标准类数组结构(数字索引+length) const arrayLike = { length: 3, 0: { firstName: 'rafa', lastName: 'rivas', age: 20 }, 1: { firstName: 'miguel', lastName: 'blades', age: 23 }, 2: { firstName: 'mario', lastName: 'perez', age: 93 } }; // 现在用Array.prototype.find.call可以正常工作 const result = Array.prototype.find.call(arrayLike, item => item.age === 23); console.log(result); // 输出对应的miguel对象
内容的提问来源于stack exchange,提问作者Kingsman10
相关产品推荐
相关产品推荐

