You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中Array.map遍历带重音字符串时全等判断异常问题

问题现象

对包含带重音符号的字符串数组调用.map方法遍历时,会出现视觉上完全一致的字符串相等判断返回false的异常,复现代码如下:

const types: string[] = ['Fée']

types.map(type => {
   const str = 'Fée'

   if(str === type){
       console.log(`str true : ${str}`)
   } 

   if(type === 'Fée'){
       console.log('type true')
   } else {
       console.log(`type false : ${type}`)
   }
})

控制台实际输出:

"str true : Fée"
"type false : Fée"

补充特征:异常的重音字符可以正常保存到UTF-8编码的JSON文件中,在VSCode中该异常字符所在行不会被正常语法高亮。

根本原因

问题出在重音字符的Unicode编码差异上:JavaScript的===严格相等是逐字符码位比对,不会自动识别视觉等价但编码不同的字符,而带重音的é存在两种完全合法、渲染效果完全一致的Unicode表示:

  • 预组合单码位形式:码位为U+00E9,本身就是独立的“带尖重音的小写e”字符
  • 分解双码位形式:由普通小写e(U+0065)+ 组合尖重音符号(U+0301)两个码位拼接而成

两种形式视觉上没有任何区别,但码位序列完全不同,所以严格相等判断会返回false。
上述代码里,数组types中存储的Fée、函数内定义的str变量的Fée用的是同一种编码形式,所以第一个判断返回true;而if条件里写的字面量'Fée'用的是另一种编码形式的é,所以第二个判断返回false。VSCode的语法高亮对分解式组合字符的适配存在缺陷,就会出现对应行不高亮的现象。

解决方案

做包含重音、特殊符号的字符串相等判断前,统一调用字符串的.normalize()方法做Unicode归一化,推荐统一使用NFC(标准预组合)格式,将所有视觉等价的字符转为相同码位序列再比对:

const types: string[] = ['Fée']

types.map(type => {
   const str = 'Fée'
   // 统一归一化后再做相等判断
   if(str.normalize('NFC') === type.normalize('NFC')){
       console.log(`str true : ${str}`)
   } 

   if(type.normalize('NFC') === 'Fée'.normalize('NFC')){
       console.log('type true')
   } else {
       console.log(`type false : ${type}`)
   }
})

如果需要确认字符串的实际编码,可以用以下代码打印每个字符的十六进制码点,区分两种编码形式:

// 输出码点序列,长度为2说明是预组合形式é,长度为3说明是分解形式é
console.log(Array.from(type).map(char => char.codePointAt(0)?.toString(16)))

内容的提问来源于stack exchange,提问作者Ganor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.16 16:15:41