Следующий метод (или аналогичный) обычно используется для обращения строки в JavaScript:
// Don’t use this!
var naiveReverse = function(string) {
return string.split('').reverse().join('');
}
На самом деле, все ответы, опубликованные до сих пор, являются вариацией этой схемы. Однако есть некоторые проблемы с этим решением. Например:
naiveReverse('foo ? bar');
// → 'rab �� oof'
// Where did the `?` symbol go? Whoops!
Если вам интересно, почему это происходит, читайте о внутренней кодировке JavaScript . (TL; DR: ?
является астральным символом, и JavaScript представляет его как две отдельные единицы кода.)
Но есть еще:
// To see which symbols are being used here, check:
// http://mothereff.in/js-escapes#1ma%C3%B1ana%20man%CC%83ana
naiveReverse('mañana mañana');
// → 'anãnam anañam'
// Wait, so now the tilde is applied to the `a` instead of the `n`? WAT.
Хорошей строкой для тестирования реализаций обратной строки является следующее :
'foo ? bar mañana mañana'
Почему? Поскольку он содержит астральный символ (?
) (которые представлены суррогатными парами в JavaScript ) и знак объединения (ñ
в последнем mañana
фактически состоит из двух символов: U + 006E ЛАТИНСКОЕ МАЛЕНЬКОЕ ПИСЬМО N и U + 0303 КОМБИНИРОВАННАЯ ТИЛЬДА).
Порядок, в котором появляются суррогатные пары, изменить нельзя, иначе астральный символ больше не будет отображаться в «перевернутой» строке. Вот почему вы видели эти ��
отметки в выводе для предыдущего примера.
Комбинированные метки всегда применяются к предыдущему символу, поэтому вы должны рассматривать оба основных символа (U + 006E LATIN SMALL LETTER N) как комбинирующие метки (U + 0303 COMBINING TILDE) в целом. Изменение их порядка приведет к объединению метки объединения с другим символом в строке. Вот почему выходной пример имел ã
вместо ñ
.
Надеюсь, это объясняет, почему все опубликованные до сих пор ответы неверны .
Чтобы ответить на ваш первоначальный вопрос - как [правильно] перевернуть строку в JavaScript - я написал небольшую библиотеку JavaScript, которая способна переворачивать строки с поддержкой Юникода. У него нет ни одной из проблем, которые я только что упомянул. Библиотека называется Esrever ; его код находится на GitHub, и он работает практически в любой среде JavaScript. Он поставляется с утилитой shell / binary, так что вы можете легко перезаписывать строки с вашего терминала, если хотите.
var input = 'foo ? bar mañana mañana';
esrever.reverse(input);
// → 'anañam anañam rab ? oof'