===比较JavaScript字符串是否安全
当字符来自基本多语言平面时,可以直接比较字符串 ,但是,如果字符串可以包含组合字符,那么使用 string.normalize ()函数将比

为了更好的描述观点,首先让我们来比较2个正常的字符串str1和str2:
js
const str1 = 'Hello!';
const str2 = 'Hello!';
str1 === str2; // => true
因为str1和str2具有相同的字符,所以这些字符串相等
总是看起来两个相同的字符串相等吗?让我们尝试另一个示例:
js
const str1 = 'café';
const str2 = 'café';
str1 === str2; // => false
如果有小伙伴不相信,自己打开浏览器测试就知道
虽然str1和str2看起来是一样的,比较str1 === str2计算结果为false。那怎么可能
让我们详细介绍如何正确比较JavaScript中的字符串。在开始之前,需要熟悉javascript是如何去完成比较一个字符串的
一个字母是什么
来看看下面的字符串
js
const str1 = 'café';
可以很容易地看到它有4个字母: 小写的 c,小写的 a,小写的 f,小写的 e
下面是一个关于字符的定义:
"Grapheme is a minimally distinctive unit of writing in the context of a particular writing system."
在特定的书写系统中,字符是一个最小的独特的书写单位
什么是组合字符
组合字符包括重音符号、发音符号、希伯来语点、阿拉伯语元音符号和印度语母音符号
例如,é 是一个原子字素。使用小写字母 e (基本字符) ,并将它与锐角重音符 something (组合字符)结合起来呈现字符: e + something = é
js
const e1 = 'e\u0301';
e1; // "é"
其中 u0301是组合字符 something 的 unicode 转义序列
所以,尽管 e1和 e2呈现的是相同的字形,但它们是不同的字符串值:
js
const e1 = 'e\u0301';
const e2 = 'é';
e1 === e2; // => false
如何安全比较
首先,可以使用正则比较运算符 = = 、 = = 或效用函数 Object.is ()比较包含来自基本 Multilangual 平面的字符(包括 ASCII 字符)的字符串
js
const str1 = 'Hello!';
const str2 = 'Hello!';
str1 === str2; // => true
Str1和 str2都包含 ASCII 字符,因此可以安全地使用比较运算符比较它们
其次,如果您处理基本多语言平面之上的字符,包括组合字符,那么使用 = = 、 = = 和 Object.is ()比较字符串是不安全的。另外需要做的是规范化比较的字符串。
js
const str1 = 'café';
const str2 = 'cafe\u0301'; // same as 'café'
str1 === str2; // => false
str1.normalize() === str2.normalize(); // => true
简单地说,字符串规范化使规范等效字符串(‘ café’和‘ cafe u0301’等效,因为它们表示相同的字符串)具有唯一的表示形式(‘ café’和‘ cafe u0301’都规范化为唯一的‘ café’),使用normalize来序列化
总结
1、当字符来自基本多语言平面时,可以直接比较字符串
2、但是,如果字符串可以包含组合字符,那么使用 string.normalize ()函数将比较字符串规范化为相同的形式会更安全。然后对规范化字符串执行比较。
文章来自:dmitripavlutin
翻译:羊先生