如何为JS的Array.includes()传入自定义相等/哈希比较函数?
核心结论
原生Array.prototype.includes() 不支持传入自定义相等判断谓词,它内部固定使用SameValueZero相等性算法,对于非原始类型的对象,只会对比内存引用地址,这也是你示例代码输出false的原因。
方案1:直接使用原生Array.some()方法(最推荐)
这是无需额外封装、无副作用的标准实现,直接传入自定义判断逻辑即可:
const list = [{id:111},{id:222},{id:333}]; // 传入自定义相等判断逻辑 const isExist = list.some(item => item.id === 333); console.log(isExist); // 输出:true
方案2:封装自定义工具方法(适合高频使用场景)
如果项目中需要大量做类似判断,可以封装统一的工具方法,可控场景下也可以扩展数组原型:
// 自定义扩展方法,命名可自行调整,避免和未来原生方法冲突 Array.prototype.includesWith = function (compareFn) { if (typeof compareFn !== 'function') { throw new TypeError('参数必须为判断函数'); } return this.some(compareFn); }; // 调用示例 console.log(list.includesWith(item => item.id === 333)); // 输出:true
注意:非必要不建议修改原生原型,避免全局污染、和第三方库逻辑冲突。
方案3:大数组场景下用Map做预索引(性能最优)
如果数组长度大、需要多次做包含判断,可以先把判断字段提取为索引,后续查询时间复杂度为O(1):
const list = [{id:111},{id:222},{id:333}]; // 以id为key生成Map const idIndex = new Map(list.map(item => [item.id, item])); // 直接查询key是否存在 console.log(idIndex.has(333)); // 输出:true
内容的提问来源于stack exchange,提问作者ccpizza
相关产品推荐
相关产品推荐

