【问题标题】:When a string is not a string? Unicode normalization weirdness in Javascript当字符串不是字符串时? Javascript中的Unicode规范化怪异
【发布时间】:2015-05-23 02:17:06
【问题描述】:

在我看来,在使用 .normalize() Unicode 规范化函数时,Firefox 中的字符串行为出现了一些严重的奇怪现象。

Here 是一个演示,在 Firefox 中查看控制台可以看到问题。

假设我有一个 id 为“NFKC”的按钮:

<button id="NFKC">NFKC</button>

得到一个参考,很容易:

document.querySelector('#NFKC')
// <button id="NFKC">

现在,由于此按钮的 id 为 NFKC,我们可以通过以下方式获取该字符串:

document.body.querySelector('#NFKC').id
// "NFKC"

将该字符串粘贴到变量中:

var s1 = document.body.querySelector('#NFKC').id

通过比较,直接将相同的字符串分配给变量:

var s2 = 'NFKC'

当然:

s1 === s2
// true

还有:

s1 == s2
// true

现在是我的头爆炸的部分。

要规范化字符串,请将@​​987654334@、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'

没有。

所以问题是:当s1 === s2 为真时,为什么就.normalize() 而言s1 不等于s2?

这在 Chrome 中不会发生,这是我迄今为止测试过的唯一其他浏览器。

更新

这是 Firefox 和 has been fixed 中的一个错误。

【问题讨论】:

  • @pat 我想说这显然不是正确的行为;对于 FF 错误跟踪器来说,这看起来是一个非常明显的错误。
  • 我在bugzilla.mozilla.org/show_bug.cgi?id=1145326添加了一个错误报告
  • 我找到了C++ implementation of String.prototype.normalize for Firefox。看起来问题与设置了 formStr 有关。
  • 这不仅仅是一个 DOM 问题。这些也失败了:var s2 = 'NFKC'.split('').join(''); 和 var s2= 'NFKCabc'.replace('abc','');。但这不是:var s2= 'N'+'F'+'K'+'C';。很奇怪。
  • 您能否发布您的更新作为答案并接受它?顺便说一句,恭喜你找到了这个错误!

标签: javascript string firefox unicode unicode-normalization


【解决方案1】:

我不确定这是否会有所帮助,但文档指出

这是一项实验性技术,是 Harmony (ECMAScript 6) 提案的一部分。 由于该技术的规格尚未稳定,请查看兼容性表以了解在各种浏览器中的使用情况。另请注意,随着规范的变化,实验技术的语法和行为可能会在未来版本的浏览器中发生变化。

并且兼容性表是

Feature         Chrome  Firefox (Gecko) Internet Explorer           Opera   Safari
Basic support   34      31 (31)         11 on Windows 10 Preview    (Yes)   Not supported

不过,此页面的最后一次更新是 2014 年 11 月 18 日。

【讨论】:

    猜你喜欢
    • 2018-09-29
    • 2011-12-10
    • 2011-06-20
    • 2018-04-16
    • 2010-10-10
    • 2019-04-19
    • 2012-02-07
    • 2016-08-29
    • 2020-02-12
    相关资源
    最近更新 更多