Когда строка не является строкой? Юникодная нормализация в Javascript
Я столкнулся с тем, что для меня представляет собой серьезную странность со строковым поведением в Firefox при использовании функции .normalize()
Unicode.
Здесь - демонстрационная версия, просмотрите консоль в Firefox, чтобы увидеть проблему.
Предположим, что у меня есть кнопка с идентификатором "NFKC":
<button id="NFKC">NFKC</button>
Получить ссылку на это, достаточно просто:
document.querySelector('#NFKC')
// <button id="NFKC">
Теперь, поскольку эта кнопка имеет идентификатор NFKC, который мы можем получить в этой строке следующим образом:
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
is 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, единственный проверенный на данный момент браузер Ive.
UPDATE
Это была ошибка в Firefox и исправлено.
Ответы
Ответ 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
Однако последнее обновление этой страницы было 18 ноября 2014 года.