谁执行unicode规范化以及何时执行?

时间:2017-07-23 18:43:46

标签: javascript unicode

根据 JavaScript - 权威指南

  

JavaScript假定它正在解释的源代码已经规范化,并且没有尝试规范化标识符,字符串或正则表达式本身。

     

Unicode标准定义了所有字符的首选编码,并指定了将文本转换为适合比较的规范形式的规范化过程。

如果JS没有规范化Unicode,那么谁来做它以及什么时候?

如果JavaScript没有规范化Unicode,那么

是怎样的
"café" === "caf\u00e9"   // => true

为什么

"café" === "cafe\u0301"   // => false

由于两者(\u00e9e\u0301)都是Unicode方式来形成é

1 个答案:

答案 0 :(得分:3)

您正在混淆unicode规范化和字符串转义。

"café"

...是由code points 0x63,0x61,0x66,0xe9的字符组成的字符串。

您可以使用转义表示

来获取完全相同的字符串
"caf\u00e9"
// or even
"\u0063\u0061\u0066\u00e9"
// or why not
"\u0063\u0061fé"

当读取这样的字符串时,javascript un-escapes字符串。也就是说,它用匹配的字符替换转义序列。这是用新行替换“\ n”的完全相同的过程。

现在,你的第二个例子实际上是另一个字符串,因为它没有规范化。它是由字符0x63,0x61,0x66,0x65,0x301组成的字符串。由于没有发生规范化,因此它不是相同的字符串。

现在尝试使用相同的字符串,使用您无法使用键盘输入的序列,但我会在此复制粘贴:"café"。现在测试一下:

> a = "café"     // this one is copy-pasted with the combining acute
> b = "café"     // this one is typed using the "é" key on my keyboard
> a === "cafe\u0301"
<- true
> b === "cafe\u0301"
<- false
> a === "caf\u00e9"
<- false
> b === "caf\u00e9"
<- true
> a === b
<- false
// Now just making sure...
> a.length
<- 5
> b.length
<- 4

“café”和“café”呈现相同的事实并不能使它们成为相同的字符串。 JavaScript会比较字符串,发现0x63, 0x61, 0x66, 0xe90x63, 0x61, 0x66, 0x65, 0x301不同并返回false。