在 TypeScript 中,两个看似相同的字符串用 `==` 比较返回 `false`
不可见字符或空格差异
- 字符串可能包含隐藏的控制字符(如零宽空格
\u200B
)、制表符或多余的空格。 - 示例:
const str1 = 'hello'; const str2 = 'hello\u200B'; // 末尾含零宽空格 console.log(str1 == str2); // false
Unicode 组合字符差异
- 同一字符可能由不同的 Unicode 组合方式表示。例如,
é
可以是直接字符\u00E9
,或组合形式e\u0301
。 - 示例:
const str3 = 'café'; // 直接字符 'é' (\u00E9) const str4 = 'cafe\u0301'; // 组合形式 'e´' console.log(str3 == str4); // false // 标准化后比较: console.log(str3.normalize() === str4.normalize()); // true
全角与半角字符混淆
- 全角字符(如
A
,UnicodeFF21
)与半角字符(A
,Unicode0041
)视觉相似但编码不同。 - 示例:
const str5 = 'A'; // 全角 A const str6 = 'A'; // 半角 A console.log(str5 == str6); // false
换行符或空白符差异
- 不同操作系统使用不同换行符(如
\n
vs\r\n
)。 - 示例:
const str7 = 'hello\nworld'; const str8 = 'hello\r\nworld'; console.log(str7 == str8); // false
字符串对象 vs 原始字符串
- 使用
new String()
创建的是对象,与字面量字符串比较时,==
会触发类型转换,但需注意对象引用的差异。 - 示例:
const str9: String = new String('hello'); const str10 = 'hello'; console.log(str9 == str10); // true(类型转换后值相同) console.log(str9 === str10); // false(类型不同)
排查方法
- 检查字符编码:
console.log(Array.from(str1).map(c => c.codePointAt(0)));
- 标准化字符串:
const normalized = str.normalize(); // 处理 Unicode 组合字符
- 严格比较:
使用===
避免隐式类型转换,但需确保类型一致。