在使用 .normalize()
的 Unicode 标准化函数时,我在Firefox中遇到了一些严重的字符串行为问题。
这里是一个演示,在Firefox浏览器中查看控制台可见问题。
假设我有一个id为“NFKC”的按钮:
<button id="NFKC">NFKC</button>
获取对它的引用,很容易:
document.querySelector('#NFKC')
// <button id="NFKC">
现在,由于此按钮具有NFKC的id,我们可以按以下方式获取该字符串:
document.body.querySelector('#NFKC').id
// "NFKC"
将该字符串存入一个变量中:
var s1 = document.body.querySelector('#NFKC').id
与之相比,直接将同样的字符串赋值给一个变量:
var s2 = 'NFKC'
当然:
s1 === s2
// true
与:
s1 == s2
// true
现在该是我头爆炸的时候了。
要对字符串进行规范化,您需要将 NFC
、NFD
、NFKC
或 NFKD
之一传递给 .normalize()
方法,像这样:
'á'.normalize('NFKC')
// "á"
当然,根据您选择的规范化形式,您会得到不同的码点,但无论如何。
'á'.normalize('NFC').length == 1
// true
'á'.normalize('NFD').length == 2
// true
无论如何,重点是将四个字符串中的一个传递给.normalize()
,然后你将得到一个规范化的字符串。
既然我们知道s1
(从DOM检索出来的字符串)和s2
是相同的字符串(s1 === s2
为true
),那么显然我们可以使用任何一个字符串来规范化一个字符串:
'á'.normalize(s2)
"á"
// well yeah, because s2 IS 'NFKC'.
自然,s1
会以完全相同的方式运作,对吗?
'á'.normalize(s1)
// RangeError: form must be one of 'NFC', 'NFD', 'NFKC', or 'NFKD'
不好意思。
那么问题是:为什么在使用.normalize()
时,s1 === s2
成立但s1
和s2
看起来却不相等?
这种情况在我目前测试的其他浏览器中没有发生,只有在Firefox中出现了这个问题。
更新
这是Firefox中的一个错误,已经被修复了,请查看这个链接。
String.prototype.normalize
的C++实现代码。看起来问题与formStr
的设置有关。 - apsillersvar s2 = 'NFKC'.split('').join('');
和var s2= 'NFKCabc'.replace('abc','');
。但是这个没有问题:var s2= 'N'+'F'+'K'+'C';
。很奇怪。 - Rick Hitchcock