JavaScript中array.includes匹配'sku'始终返回false的异常问题排查
问题原因
字符编码65279对应的是零宽度无断空格(Unicode 编码 U+FEFF),也就是常说的UTF-8 BOM(字节顺序标记)。这个字符是不可见的,所以控制台打印两个字符串时看起来都是sku,但实际feedProduct中的字段开头多了这个BOM字符,自然和requiredFields中正常的sku字符串做严格相等判断时返回false。
Array.prototype.includes()和Array.prototype.indexOf()内部都是用严格相等(===)做匹配,所以两者都会返回找不到的结果。把代码复制到开发者工具运行正常,是因为手动输入的字符串不会自带BOM标记。
这个问题通常出现在数据来源是带BOM的UTF-8文件、部分老旧接口返回、或者从Excel/CSV等文档导出内容的场景,读取解析时没有自动过滤开头的BOM标记导致。
解决方案
核心思路是对输入的字段做归一化处理,移除不可见的BOM字符,也可以同时处理前后空格避免其他类似匹配问题:
- 预处理输入字段(推荐)
在执行匹配逻辑前,先把两个入参数组的每一项都清理掉BOM和前后空格,修改后的函数示例如下:
function hasAllRequiredFields(requiredFields, feedProduct) { let missing_required = []; // 字段归一化处理:移除开头BOM+去前后空格 const normalize = str => str.replace(/^\ufeff/, '').trim(); const normalizedFeed = feedProduct.map(normalize); const normalizedRequired = requiredFields.map(normalize); normalizedRequired.forEach(wf => { if (!normalizedFeed.includes(wf)) { missing_required.push(wf); } }) return missing_required; }
- 从源端解决(可选)
如果feedProduct是从文件读取得到,可以在读取阶段就去掉BOM:
- Node.js环境可以直接使用
strip-bom包处理读取到的字符串,或者手动替换内容开头的\ufeff字符 - 前端从接口获取的话可以和后端协商,调整接口返回内容不带BOM即可
内容的提问来源于stack exchange,提问作者Valor_
相关产品推荐
相关产品推荐

