Skip to content

Commit 388db2a

Browse files
authored
Update article.md
1 parent f6111a5 commit 388db2a

File tree

1 file changed

+48
-48
lines changed

1 file changed

+48
-48
lines changed

1-js/99-js-misc/07-unicode/article.md

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
Как мы уже знаем, строки в JavaScript основаны на [Юникоде](https://ru.wikipedia.org/wiki/Юникод): каждый символ представляет из себя последовательность байтов из 1-4 байтов.
99

10-
JavaScript позволяет нам вставить символ в строку, указав его шестнадцатеричный код Юникода с помощью одной из этих трех нотаций:
10+
JavaScript позволяет нам вставить символ в строку, указав его шестнадцатеричный Юникод с помощью одной из этих трех нотаций:
1111

1212
- `\xXX`
1313

@@ -23,7 +23,7 @@ JavaScript позволяет нам вставить символ в строк
2323
```
2424

2525
- `\uXXXX`
26-
Вместо `XXXX` должны быть указаны ровно 4 шестнадцатеричные цифры со значением от `0000` до `FFFF`. В этом случае `\uXXXX` - это символ, код Юникода которого равен `XXXX`.
26+
Вместо `XXXX` должны быть указаны ровно 4 шестнадцатеричные цифры со значением от `0000` до `FFFF`. В этом случае `\uXXXX` - это символ, Юникод которого равен `XXXX`.
2727
2828
Символы со значениями Юникода, превышающими `U+FFFF`, также могут быть представлены с помощью этой нотации, но в таком случае нам придется использовать так называемую суррогатную пару (о ней мы поговорим позже в этой главе).
2929
@@ -35,7 +35,7 @@ JavaScript позволяет нам вставить символ в строк
3535

3636
- `\u{X…XXXXXX}`
3737
38-
Вместо `XXXXXXX` должно быть шестнадцатеричное значение от 1 до 6 байт от `0` до `10FFFF` (самая высокая точка кода, определенная стандартом Юникод). Эта нотация позволяет нам легко представлять все существующие символы Юникода.
38+
Вместо `XXXXXXX` должно быть шестнадцатеричное значение от 1 до 6 байт от `0` до `10FFFF` (максимальная точка кода, определенная стандартом Юникод). Эта нотация позволяет нам легко представлять все существующие символы Юникода.
3939
4040
```js run
4141
alert( "\u{20331}" ); // 佫, редкий китайский иероглиф (длинный Юникод)
@@ -44,129 +44,129 @@ JavaScript позволяет нам вставить символ в строк
4444

4545
## Суррогатные пары
4646

47-
All frequently used characters have 2-byte codes (4 hex digits). Letters in most European languages, numbers, and the basic unified CJK ideographic sets (CJK -- from Chinese, Japanese, and Korean writing systems), have a 2-byte representation.
47+
Все часто используемые символы имеют 2-байтовые коды (4 шестнадцатеричные цифры). В большинстве европейских языков буквы, цифры и основные унифицированные идеографические наборы CJK (CJK -- от китайской, японской и корейской систем письма) имеют 2-байтовое представление.
4848

49-
Initially, JavaScript was based on UTF-16 encoding that only allowed 2 bytes per character. But 2 bytes only allow 65536 combinations and that's not enough for every possible symbol of Unicode.
49+
Изначально JavaScript был основан на кодировке UTF-16, которая предусматривала только 2 байта на один символ. Однако 2 байта допускают только 65536 комбинаций, и этого недостаточно для всех возможных символов Юникода.
5050

51-
So rare symbols that require more than 2 bytes are encoded with a pair of 2-byte characters called "a surrogate pair".
51+
Поэтому редкие символы, требующие более 2 байт, кодируются парой 2-байтовых символов, которые называются "суррогатной парой".
5252

53-
As a side effect, the length of such symbols is `2`:
53+
Побочным эффектом является то, что длина таких символов равна `2`:
5454

5555
```js run
5656
alert( '𝒳'.length ); // 2, MATHEMATICAL SCRIPT CAPITAL X
5757
alert( '😂'.length ); // 2, FACE WITH TEARS OF JOY
58-
alert( '𩷶'.length ); // 2, a rare Chinese character
58+
alert( '𩷶'.length ); // 2, редкий китайский иероглиф
5959
```
6060

61-
That's because surrogate pairs did not exist at the time when JavaScript was created, and thus are not correctly processed by the language!
61+
Это происходит потому, что суррогатные пары не существовали в то время, когда был создан JavaScript, и поэтому они не обрабатываются языком корректно.
6262

63-
We actually have a single symbol in each of the strings above, but the `length` property shows a length of `2`.
63+
На самом деле в каждой из приведенных строк у нас по одному символу, но свойство `length` показывает длину `2`.
6464

65-
Getting a symbol can also be tricky, because most language features treat surrogate pairs as two characters.
65+
Получить такой символ также может быть непросто, поскольку большинство языковых функций рассматривают суррогатные пары как два символа.
6666

67-
For example, here we can see two odd characters in the output:
67+
Например, здесь мы видим два странных символа в выводе:
6868

6969
```js run
70-
alert( '𝒳'[0] ); // shows strange symbols...
71-
alert( '𝒳'[1] ); // ...pieces of the surrogate pair
70+
alert( '𝒳'[0] ); // показывает странные символы...
71+
alert( '𝒳'[1] ); // ...части суррогатной пары
7272
```
7373

74-
Pieces of a surrogate pair have no meaning without each other. So the alerts in the example above actually display garbage.
74+
Части суррогатной пары не имеют никакого значения друг без друга.
7575

76-
Technically, surrogate pairs are also detectable by their codes: if a character has the code in the interval of `0xd800..0xdbff`, then it is the first part of the surrogate pair. The next character (second part) must have the code in interval `0xdc00..0xdfff`. These intervals are reserved exclusively for surrogate pairs by the standard.
76+
Технически, суррогатные пары также можно определить по их кодам: если символ имеет код в интервале `0xd800...0xdbff`, то он является первой частью суррогатной пары. Следующий символ (вторая часть) должен иметь код в интервале `0xdc00...0xdfff`. Эти интервалы зарезервированы стандартом исключительно для суррогатных пар.
7777

78-
So the methods `String.fromCodePoint` and `str.codePointAt` were added in JavaScript to deal with surrogate pairs.
78+
Поэтому для работы с суррогатными парами в JavaScript были добавлены методы `String.fromCodePoint` и `str.codePointAt`.
7979

80-
They are essentially the same as [String.fromCharCode](mdn:js/String/fromCharCode) and [str.charCodeAt](mdn:js/String/charCodeAt), but they treat surrogate pairs correctly.
80+
По сути, они аналогичны [String.fromCharCode](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode) и [str.charCodeAt](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt), но они правильно обрабатывают суррогатные пары.
8181

82-
One can see the difference here:
82+
Здесь можно увидеть разницу:
8383

8484
```js run
85-
// charCodeAt is not surrogate-pair aware, so it gives codes for the 1st part of 𝒳:
85+
// charCodeAt не учитывает суррогатные пары, поэтому он выдает коды для 1-й части 𝒳:
8686
8787
alert( '𝒳'.charCodeAt(0).toString(16) ); // d835
8888
89-
// codePointAt is surrogate-pair aware
90-
alert( '𝒳'.codePointAt(0).toString(16) ); // 1d4b3, reads both parts of the surrogate pair
89+
// codePointAt учитывает суррогатные пары
90+
alert( '𝒳'.codePointAt(0).toString(16) ); // 1d4b3, считывает обе части суррогатной пары
9191
```
9292

93-
That said, if we take from position 1 (and that's rather incorrect here), then they both return only the 2nd part of the pair:
93+
При этом, если брать с позиции 1 (а это здесь скорее неверно), то они оба возвращают только 2-ю часть пары:
9494

9595
```js run
9696
alert( '𝒳'.charCodeAt(1).toString(16) ); // dcb3
9797
alert( '𝒳'.codePointAt(1).toString(16) ); // dcb3
98-
// meaningless 2nd half of the pair
98+
// бессмысленная 2-я половина пары
9999
```
100100

101-
You will find more ways to deal with surrogate pairs later in the chapter <info:iterable>. There are probably special libraries for that too, but nothing famous enough to suggest here.
101+
Другие способы работы с суррогатными парами вы найдете в главе <info:iterable>. Возможно, для этого тоже существуют специальные библиотеки, но они не настолько известные, чтобы предлагать их в учебнике.
102102

103-
````warn header="Takeaway: splitting strings at an arbitrary point is dangerous"
104-
We can't just split a string at an arbitrary position, e.g. take `str.slice(0, 4)` and expect it to be a valid string, e.g.:
103+
````warn header="Разделение строки в случайном месте может быть опасным!"
104+
Разделив строку в случайном месте, например, с помощью `str.slice(0, 4)`, мы не можем гарантировать валидность полученного значения. Например:
105105

106106
```js run
107107
alert( 'hi 😂'.slice(0, 4) ); // hi [?]
108108
```
109109

110-
Here we can see a garbage character (first half of the smile surrogate pair) in the output.
110+
Здесь мы видим мусорный символ (первая половина суррогатной пары 😂) в выводе.
111111

112-
Just be aware of it if you intend to reliably work with surrogate pairs. May not be a big problem, but at least you should understand what happens.
112+
Просто имейте это в виду, если вы намерены надежно работать с суррогатными парами. Может быть, это не очень большая проблема, но, по крайней мере, вы должны понимать, что происходит.
113113
````
114114

115-
## Diacritical marks and normalization
115+
## Диакритические знаки и нормализация
116116

117-
In many languages, there are symbols that are composed of the base character with a mark above/under it.
117+
Во многих языках есть символы, состоящие из основного символа и знака над/под ним.
118118

119-
For instance, the letter `a` can be the base character for these characters: `àáâäãåā`.
119+
Например, буква `a` может быть основой для этих символов: `àáâäãåā`.
120120

121-
Most common "composite" characters have their own code in the Unicode table. But not all of them, because there are too many possible combinations.
121+
Большинство распространенных "составных" символов имеют свой собственный код в таблице Юникода. Но не все, потому что существует слишком большое количество возможных комбинаций.
122122

123-
To support arbitrary compositions, the Unicode standard allows us to use several Unicode characters: the base character followed by one or many "mark" characters that "decorate" it.
123+
Для поддержки любых комбинаций стандарт Юникод позволяет нам использовать несколько Юникодных символов: основной символ, за которым следует один или много символов-"меток", которые "украшают" его.
124124

125-
For instance, if we have `S` followed by the special "dot above" character (code `\u0307`), it is shown as Ṡ.
125+
Например, если за `S` следует специальный символ "точка сверху" (код `\u0307`), то он отобразится как Ṡ.
126126

127127
```js run
128128
alert( 'S\u0307' ); // Ṡ
129129
```
130130

131-
If we need an additional mark above the letter (or below it) -- no problem, just add the necessary mark character.
131+
Если нам нужен дополнительный знак над буквой (или под ней) -- нет проблем, просто добавляем соответствующий символ.
132132

133-
For instance, if we append a character "dot below" (code `\u0323`), then we'll have "S with dots above and below": `Ṩ`.
133+
Например, если мы добавим символ "точка снизу" (код `\u0323`), то получим "S с точками сверху и снизу": ``.
134134

135-
For example:
135+
Вот, как это будет выглядеть:
136136

137137
```js run
138138
alert( 'S\u0307\u0323' ); // Ṩ
139139
```
140140

141-
This provides great flexibility, but also an interesting problem: two characters may visually look the same, but be represented with different Unicode compositions.
141+
Это обеспечивает большую гибкость, но при этом возникает определенная проблема: два символа могут визуально выглядеть одинаково, но при этом они будут представлены разными комбинациями Юникода.
142142

143-
For instance:
143+
Например:
144144

145145
```js run
146-
let s1 = 'S\u0307\u0323'; // Ṩ, S + dot above + dot below
147-
let s2 = 'S\u0323\u0307'; // Ṩ, S + dot below + dot above
146+
let s1 = 'S\u0307\u0323'; // Ṩ, S + точка сверху + точка снизу
147+
let s2 = 'S\u0323\u0307'; // Ṩ, S + точка снизу + точка сверху
148148
149149
alert( `s1: ${s1}, s2: ${s2}` );
150150
151-
alert( s1 == s2 ); // false though the characters look identical (?!)
151+
alert( s1 == s2 ); // false, хотя символы выглядят одинаково (?!)
152152
```
153153

154-
To solve this, there exists a "Unicode normalization" algorithm that brings each string to the single "normal" form.
154+
Для решения этой проблемы предусмотрен алгоритм "Юникодной нормализации", приводящий каждую строку к единому "нормальному" виду.
155155

156-
It is implemented by [str.normalize()](mdn:js/String/normalize).
156+
Его реализует метод [str.normalize()](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/String/normalize).
157157

158158
```js run
159159
alert( "S\u0307\u0323".normalize() == "S\u0323\u0307".normalize() ); // true
160160
```
161161

162-
It's funny that in our situation `normalize()` actually brings together a sequence of 3 characters to one: `\u1e68` (S with two dots).
162+
Забавно, но в нашем случае `normalize()` "схлопывает" последовательность из трёх символов в один: `\u1e68` S с двумя точками.
163163

164164
```js run
165165
alert( "S\u0307\u0323".normalize().length ); // 1
166166
167167
alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true
168168
```
169169

170-
In reality, this is not always the case. The reason is that the symbol `` is "common enough", so Unicode creators included it in the main table and gave it the code.
170+
В действительности это не всегда так. Причина в том, что символ `` является "достаточно распространенным", поэтому создатели стандарта Юникод включили его в основную таблицу и присвоили ему код.
171171

172-
If you want to learn more about normalization rules and variants -- they are described in the appendix of the Unicode standard: [Unicode Normalization Forms](https://www.unicode.org/reports/tr15/), but for most practical purposes the information from this section is enough.
172+
Если вы хотите узнать больше о правилах и вариантах нормализации -- они описаны в дополнении к стандарту Юникод: [Unicode Normalization Forms](https://www.unicode.org/reports/tr15/), но для большинства практических целей достаточно информации из этого раздела.

0 commit comments

Comments
 (0)