Как использовать пятизначные длинные символы Unicode в JavaScript

В JavaScript я могу сделать это:

foo = "\u2669" // 1/4 note

Но я не могу этого сделать

foo = "\u1D15D" // full note  -five hex digits

Он будет интерпретирован как «ᴕ», за которым следует «D».

Есть ли обходные пути для этого?

ОБНОВЛЕНИЕ 9 июля 2012 г.: Предложение по ECMAScript Harmony теперь включает поддержку для всех символов Юникода.


person itpastorn    schedule 16.05.2012    source источник
comment
Контекстом является небольшое приложение о музыкальных нотах в Canvas, которое пытается создать мой студент: keryx .se/dev/html5/noter/noter.html (Ничего особенного. Он программирует всего 2 месяца, несколько часов в неделю.)   -  person itpastorn    schedule 16.05.2012
comment
Возможный дубликат строк JavaScript вне BMP.   -  person Frédéric Hamidi    schedule 16.05.2012
comment
Узнал в Твиттере: вы должны использовать суррогатные пары   -  person itpastorn    schedule 17.05.2012
comment
Javascript все еще застрял в Unicode 1 до 1995 года. Он жалкий для современной обработки текста.   -  person tchrist    schedule 26.05.2012


Ответы (5)


В документации MDN для fromCharCode отмечается, что javascript естественно обрабатывает только символы до 0xFFFF. Однако у них также есть реализация фиксированного метода для fromCharCode, который может делать то, что вы хотите (воспроизведено ниже):

function fixedFromCharCode (codePt) {
    if (codePt > 0xFFFF) {
        codePt -= 0x10000;
        return String.fromCharCode(0xD800 + (codePt >> 10), 0xDC00 + (codePt & 0x3FF));
    }
    else {
        return String.fromCharCode(codePt);
    }
}

foo = fixedFromCharCode(0x1D15D);
person mpdaugherty    schedule 16.05.2012
comment
Если у вас установлен правильный шрифт, выполнение String.fromCharCode( 0x01D15D ) отобразит вам этот символ. - person Andre Steenveld; 16.05.2012
comment
У вас есть пример шрифта, для которого это работает? Я бы хотел, чтобы fromCharCode теперь поддерживал коды вне BMP, но все, что я прочитал сегодня, казалось, указывало на то, что это не так. (Также см. комментарий Фредерика Хамиди выше) - person mpdaugherty; 16.05.2012
comment
Я только что сделал быстрый тест в опере, и он выдал не может отобразить символ. Так что это заставило меня поверить, что вам нужен шрифт, который действительно отображает персонажа. - person Andre Steenveld; 16.05.2012
comment
Это ужасный взлом. Невозможность указать полный диапазон кодовых точек Unicode является серьезной проблемой. Javascript все еще застрял в мире до 1995 года. Это скандал. - person tchrist; 16.05.2012
comment
Извините за опоздание с ответом на это. Мне нужно, чтобы мой ученик сначала установил подходящий шрифт, чтобы он попробовал его. Я вернусь через день или два и дам кредит, если это сработает. - person itpastorn; 17.05.2012
comment
@Dre String.fromCharCode(0x01D15D) сам по себе не работает. По крайней мере, не в Firefox — пока это мой единственный протестированный браузер. - person itpastorn; 17.05.2012
comment
Загрузил шрифт Code2001 и провел тесты. fixFromCharCode работает. - person itpastorn; 17.05.2012
comment
Ссылка: Алгоритм, описанный в Википедии - person itpastorn; 17.05.2012

Попробуйте поместить юникод между фигурными скобками: '\u{1D15D}'.

person Manuel Dipre    schedule 24.10.2018
comment
Это путь! Подробнее читайте здесь: dmitripavlutin.com/ - person b00t; 09.01.2019

В настоящее время вы можете просто использовать String.fromCodePoint(), как описано в МДН. Например:

> String.fromCodePoint(0x1f0a1)
"????"
person Pedro Asad    schedule 09.03.2020

Я немного проверил, и оказалось, что рядом с 0x2669 нет полной записи. (таблица символов Юникода)

Хотя использование 0x01D15D дает мне неизвестный символ Юникода, это может быть потому, что у меня нет музыкального шрифта. Javascript будет пытаться анализировать как можно больше байтов, а 0x1D15D составляет 2,5 байта, дополняя его 0, сделает его 3 и разборчивым.

Также это было очень удобно: unicode.org/charts/PDF/U1D100.pdf.

person Andre Steenveld    schedule 16.05.2012

Вы можете использовать это:

function fromOutsideBMP(cp) {
// 0x01D120
  var x=cp-0x10000;
  var top10=parseInt("11111111110000000000",2);
  var end10=parseInt("1111111111",2);
  var part1=(x&top10)/1024+0xD800;
  var part2=(x&end10)+0xDC00;
  var s=String.fromCharCode(part1)+String.fromCharCode(part2);
  return s;
}

Пример:

> fromOutsideBMP(0x01d122)
  "????"
>
person dda    schedule 27.05.2012