|
1 | 1 |
|
2 |
| -# Unicode, String internals |
| 2 | +# Unicode, detalhes internos da String |
3 | 3 |
|
4 |
| -```warn header="Advanced knowledge" |
5 |
| -The section goes deeper into string internals. This knowledge will be useful for you if you plan to deal with emoji, rare mathematical or hieroglyphic characters, or other rare symbols. |
| 4 | +```warn header="Conhecimento avançado" |
| 5 | +Esta seção aprofunda nos detalhes internos das strings. Este conhecimento será útil se você planeja lidar com emojis, caracteres matemáticos raros, hieróglifos ou outros símbolos raros. |
6 | 6 | ```
|
7 | 7 |
|
8 |
| -As we already know, JavaScript strings are based on [Unicode](https://en.wikipedia.org/wiki/Unicode): each character is represented by a byte sequence of 1-4 bytes. |
| 8 | +Já sabemos que, as strings do JavaScript são baseadas no [Unicode](https://en.wikipedia.org/wiki/Unicode): cada caractere é representado por uma sequência de bytes de 1 a 4 bytes. |
9 | 9 |
|
10 |
| -JavaScript allows us to insert a character into a string by specifying its hexadecimal Unicode code with one of these three notations: |
| 10 | +JavaScript nos permite inserir um caractere em uma string ao especificar o seu código Unicode hexadecimal com uma dessas três notações: |
11 | 11 |
|
12 | 12 | - `\xXX`
|
13 | 13 |
|
14 |
| - `XX` must be two hexadecimal digits with a value between `00` and `FF`, then `\xXX` is the character whose Unicode code is `XX`. |
| 14 | + `XX` deve ser composto por dois digitos hexadecimais com um valor entre `00` e `FF`, assim `\xXX` representa o caractere cujo o código Unicode é `XX`. |
15 | 15 |
|
16 |
| - Because the `\xXX` notation supports only two hexadecimal digits, it can be used only for the first 256 Unicode characters. |
| 16 | + Uma vez que a notação `\xXX` suporta apenas dois dígitos hexadecimais, ela pode ser usada apenas para os primeiros 256 caracteres Unicode. |
17 | 17 |
|
18 |
| - These first 256 characters include the Latin alphabet, most basic syntax characters, and some others. For example, `"\x7A"` is the same as `"z"` (Unicode `U+007A`). |
| 18 | + Esses primeiros 256 caracteres incluem o alfabeto latino, a maioria dos caracteres de sintaxe básica e alguns outros. Por exemplo, `"\x7A"` é o mesmo que `"z"` (Unicode `U+007A`). |
19 | 19 |
|
20 | 20 | ```js run
|
21 | 21 | alert( "\x7A" ); // z
|
22 |
| - alert( "\xA9" ); // ©, the copyright symbol |
| 22 | + alert( "\xA9" ); // ©, O símbolo de direitos autorais. |
23 | 23 | ```
|
24 | 24 |
|
25 | 25 | - `\uXXXX`
|
26 |
| - `XXXX` must be exactly 4 hex digits with the value between `0000` and `FFFF`, then `\uXXXX` is the character whose Unicode code is `XXXX`. |
| 26 | + `XXXX` deve ser composto por exatamente quatro dígitos hexadecimais com um valor entre `0000` e `FFFF`, assim `\uXXXX` representa o caractere cujo o código Unicode é `XXXX`. |
27 | 27 |
|
28 |
| - Characters with Unicode values greater than `U+FFFF` can also be represented with this notation, but in this case, we will need to use a so called surrogate pair (we will talk about surrogate pairs later in this chapter). |
| 28 | + Carateres com valores Unicode maiores que `U+FFFF` também podem ser representados com essa notação, mas nesse caso, precisaremos usar o chamado par de substitutos (falaremos sobre pares de substitutos mais tarde neste capítulo). |
29 | 29 |
|
30 | 30 | ```js run
|
31 |
| - alert( "\u00A9" ); // ©, the same as \xA9, using the 4-digit hex notation |
32 |
| - alert( "\u044F" ); // я, the Cyrillic alphabet letter |
33 |
| - alert( "\u2191" ); // ↑, the arrow up symbol |
| 31 | + alert( "\u00A9" ); // ©, o mesmo que \xA9, usando a notação hexadecimal de 4 dígitos |
| 32 | + alert( "\u044F" ); // я, a letra do alfabeto cirílico |
| 33 | + alert( "\u2191" ); // ↑, o símbolo da seta para cima |
34 | 34 | ```
|
35 | 35 |
|
36 | 36 | - `\u{X…XXXXXX}`
|
37 | 37 |
|
38 |
| - `X…XXXXXX` must be a hexadecimal value of 1 to 6 bytes between `0` and `10FFFF` (the highest code point defined by Unicode). This notation allows us to easily represent all existing Unicode characters. |
| 38 | + `X...XXXXXX` deve ser um valor hexadecimal de 1 a 6 bytes entre `0` e `10FFFF` (o maior ponto de código definido pelo Unicode). Esta notação nos permite representar facilmente todos os caracteres Unicode existentes. |
39 | 39 |
|
40 | 40 | ```js run
|
41 |
| - alert( "\u{20331}" ); // 佫, a rare Chinese character (long Unicode) |
42 |
| - alert( "\u{1F60D}" ); // 😍, a smiling face symbol (another long Unicode) |
| 41 | + alert( "\u{20331}" ); // 佫, um caractere chinês raro (Unicode longo) |
| 42 | + alert( "\u{1F60D}" ); // 😍, um símbolo de rosto sorridente (outro Unicode longo) |
43 | 43 | ```
|
44 | 44 |
|
45 |
| -## Surrogate pairs |
| 45 | +## Pares substitutos |
46 | 46 |
|
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 | +Todos os caracteres usados frequentemente têm códigos de 2 bytes (4 dígitos hexadecimais). Letras na maioria das linguagens Europeias, números e os conjuntos ideográficos unificados básicos CJK (CJK -- dos sistemas de escrita Chinês, Japonês e Coreano), têm uma representação de 2 bytes. |
48 | 48 |
|
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 | +Inicialmente, o JavaScript era baseado na codificação UTF-16 que permitia apenas 2 bytes por caractere. Mas 2 bytes só permitem 65536 combinações e isso não é suficiente para todos os símbolos possíveis do Unicode. |
50 | 50 |
|
51 |
| -So rare symbols that require more than 2 bytes are encoded with a pair of 2-byte characters called "a surrogate pair". |
| 51 | +Então, símbolos raros que requerem mais de 2 bytes são codificados com um par de caracteres de 2 bytes chamados de "par substituto". |
52 | 52 |
|
53 |
| -As a side effect, the length of such symbols is `2`: |
| 53 | +Como efeito colateral, o comprimento de tais símbolos é `2`: |
54 | 54 |
|
55 | 55 | ```js run
|
56 |
| -alert( '𝒳'.length ); // 2, MATHEMATICAL SCRIPT CAPITAL X |
57 |
| -alert( '😂'.length ); // 2, FACE WITH TEARS OF JOY |
58 |
| -alert( '𩷶'.length ); // 2, a rare Chinese character |
| 56 | +alert( '𝒳'.length ); // 2, caractere matemático X maiúsculo |
| 57 | +alert( '😂'.length ); // 2, rosto com lágrimas de alegria |
| 58 | +alert( '𩷶'.length ); // 2, um caractere chinês raro |
59 | 59 | ```
|
60 | 60 |
|
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 | +Isso ocorre porque pares substitutos não existiam na época em que o JavaScript foi criado e, portanto, não são processados corretamente pela linguagem! |
62 | 62 |
|
63 |
| -We actually have a single symbol in each of the strings above, but the `length` property shows a length of `2`. |
| 63 | +Na verdade, temos um único símbolo em cada uma das strings acima, mas a propriedade `length` mostra um comprimento de `2`. |
64 | 64 |
|
65 |
| -Getting a symbol can also be tricky, because most language features treat surrogate pairs as two characters. |
| 65 | +Obter um símbolo também pode ser complicado, porque a maioria dos recursos da linguagem tratam pares substitutos como dois caracteres. |
66 | 66 |
|
67 |
| -For example, here we can see two odd characters in the output: |
| 67 | +Por exemplo, aqui podemos ver dois caracteres estranhos na saída: |
68 | 68 |
|
69 | 69 | ```js run
|
70 |
| -alert( '𝒳'[0] ); // shows strange symbols... |
71 |
| -alert( '𝒳'[1] ); // ...pieces of the surrogate pair |
| 70 | +alert( '𝒳'[0] ); // mostra símbolos estranhos... |
| 71 | +alert( '𝒳'[1] ); // ...partes de um par substituto |
72 | 72 | ```
|
73 | 73 |
|
74 |
| -Pieces of a surrogate pair have no meaning without each other. So the alerts in the example above actually display garbage. |
| 74 | +Partes de um par substituto não têm significado sem o outro. Então, os alertas no exemplo acima na verdade exibem caracteres inválidos. |
75 | 75 |
|
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 | +Tecnicamente, pares substitutos também são detectáveis pelos seus códigos: se um caractere tem o código no intervalo de `0xd800..0xdbff`, então ele é a primeira parte do par substituto. O próximo caractere (segunda parte) deve ter o código no intervalo `0xdc00..0xdfff`. Esses intervalos são reservados exclusivamente para pares substitutos por padrão. |
77 | 77 |
|
78 |
| -So the methods [String.fromCodePoint](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) and [str.codePointAt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) were added in JavaScript to deal with surrogate pairs. |
| 78 | +Então, os métodos [String.fromCodePoint](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint) e [str.codePointAt](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) foram adicionados no JavaScript para lidar com pares substitutos. |
79 | 79 |
|
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 | +Eles são essencialmente os mesmos que [String.fromCharCode](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode) e [str.charCodeAt](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt), mas eles tratam pares substitutos corretamente. |
81 | 81 |
|
82 |
| -One can see the difference here: |
| 82 | +Podemos ver a diferença aqui: |
83 | 83 |
|
84 | 84 | ```js run
|
85 |
| -// charCodeAt is not surrogate-pair aware, so it gives codes for the 1st part of 𝒳: |
| 85 | +// charCodeAt não reconhece pares substitutos, então fornece códigos para a 1ª parte de 𝒳: |
86 | 86 |
|
87 | 87 | alert( '𝒳'.charCodeAt(0).toString(16) ); // d835
|
88 | 88 |
|
89 |
| -// codePointAt is surrogate-pair aware |
90 |
| -alert( '𝒳'.codePointAt(0).toString(16) ); // 1d4b3, reads both parts of the surrogate pair |
| 89 | +// codePointAt reconhece pares substitutos |
| 90 | +alert( '𝒳'.codePointAt(0).toString(16) ); // 1d4b3, lê ambas as partes do par substituto |
91 | 91 | ```
|
92 |
| - |
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: |
| 92 | +Dito isto, se partirmos da posição 1 (e isso está bastante incorreto aqui), então ambos retornam apenas a 2ª parte do par: |
94 | 93 |
|
95 | 94 | ```js run
|
96 | 95 | alert( '𝒳'.charCodeAt(1).toString(16) ); // dcb3
|
97 | 96 | alert( '𝒳'.codePointAt(1).toString(16) ); // dcb3
|
98 |
| -// meaningless 2nd half of the pair |
| 97 | +// segunda parte do par sem sentido |
99 | 98 | ```
|
| 99 | +Você encontrará mais maneiras de lidar com pares substitutos mais tarde no capítulo <info:iterable>. Provavelmente existem bibliotecas especiais para isso também, mas nada famoso o suficiente para sugerir aqui. |
100 | 100 |
|
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. |
102 |
| -
|
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.: |
| 101 | +````warn header="Conclusão: dividir strings em um ponto arbitrário é perigoso" |
| 102 | +Nós não podemos simplesmente dividir uma string em uma posição arbitrária, por exemplo, pegar `str.slice(0, 4)` e esperar que seja uma string válida, por exemplo: |
105 | 103 |
|
106 | 104 | ```js run
|
107 | 105 | alert( 'hi 😂'.slice(0, 4) ); // hi [?]
|
108 | 106 | ```
|
| 107 | +Aqui podemos ver um caractere inválido (primeira metade do par substituto) na saída. |
109 | 108 |
|
110 |
| -Here we can see a garbage character (first half of the smile surrogate pair) in the output. |
111 |
| - |
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. |
| 109 | +Apenas fique ciente disso se você pretende trabalhar de forma confiável com pares substitutos. Pode não ser um grande problema, mas pelo menos você deve entender o que acontece. |
113 | 110 | ````
|
114 | 111 |
|
115 |
| -## Diacritical marks and normalization |
| 112 | +## Marcas diacríticas e normalização |
116 | 113 |
|
117 |
| -In many languages, there are symbols that are composed of the base character with a mark above/under it. |
| 114 | +Em várias linguagens, existem símbolos que são compostos do caractere base com uma marca acima/abaixo dele. |
118 | 115 |
|
119 |
| -For instance, the letter `a` can be the base character for these characters: `àáâäãåā`. |
| 116 | +Por exemplo, a letra `a` pode ser o caractere base para esses caracteres: `àáâäãåā`. |
120 | 117 |
|
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. |
| 118 | +Os caracteres "compostos" mais comuns têm seu próprio código na tabela Unicode. Mas nem todos eles, porque existem muitas combinações possíveis. |
122 | 119 |
|
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. |
| 120 | +Para auxiliar composições arbitrárias, o padrão Unicode nos permite usar vários caracteres Unicode: o caractere base seguido por um ou vários caracteres "marca" que o "decoram". |
124 | 121 |
|
125 |
| -For instance, if we have `S` followed by the special "dot above" character (code `\u0307`), it is shown as Ṡ. |
| 122 | +Por exemplo, se tivermos `S` seguido pelo caractere especial "ponto acima" (código `\u0307`), ele será mostrado como Ṡ. |
126 | 123 |
|
127 | 124 | ```js run
|
128 | 125 | alert( 'S\u0307' ); // Ṡ
|
129 | 126 | ```
|
| 127 | +Se precisarmos de uma marca adicional acima da letra (ou abaixo dela) -- sem problemas, apenas adicione o caractere de marca necessário. |
130 | 128 |
|
131 |
| -If we need an additional mark above the letter (or below it) -- no problem, just add the necessary mark character. |
| 129 | +Por exemplo, se anexarmos o caractere "ponto abaixo" (código `\u0323`), então teremos "S com pontos acima e abaixo": `Ṩ`. |
132 | 130 |
|
133 |
| -For instance, if we append a character "dot below" (code `\u0323`), then we'll have "S with dots above and below": `Ṩ`. |
134 |
| -
|
135 |
| -For example: |
| 131 | +Por exemplo: |
136 | 132 |
|
137 | 133 | ```js run
|
138 | 134 | alert( 'S\u0307\u0323' ); // Ṩ
|
139 | 135 | ```
|
| 136 | +Isso fornece grande flexibilidade, mas também um problema interessante: dois caracteres podem parecer visualmente iguais, mas serem representados com diferentes composições Unicode. |
140 | 137 |
|
141 |
| -This provides great flexibility, but also an interesting problem: two characters may visually look the same, but be represented with different Unicode compositions. |
142 |
| -
|
143 |
| -For instance: |
| 138 | +Por exemplo: |
144 | 139 |
|
145 | 140 | ```js run
|
146 |
| -let s1 = 'S\u0307\u0323'; // Ṩ, S + dot above + dot below |
147 |
| -let s2 = 'S\u0323\u0307'; // Ṩ, S + dot below + dot above |
| 141 | +let s1 = 'S\u0307\u0323'; // Ṩ, S + ponto acima + ponto abaixo |
| 142 | +let s2 = 'S\u0323\u0307'; // Ṩ, S + ponto abaixo + ponto acima |
148 | 143 |
|
149 | 144 | alert( `s1: ${s1}, s2: ${s2}` );
|
150 | 145 |
|
151 |
| -alert( s1 == s2 ); // false though the characters look identical (?!) |
| 146 | +alert( s1 == s2 ); // falso embora os caracteres pareçam identicos (?!) |
152 | 147 | ```
|
153 | 148 |
|
154 |
| -To solve this, there exists a "Unicode normalization" algorithm that brings each string to the single "normal" form. |
| 149 | +Para resolver isso, existe um algoritmo de "normalização Unicode" que traz cada string para a única forma "normal". |
155 | 150 |
|
156 |
| -It is implemented by [str.normalize()](mdn:js/String/normalize). |
| 151 | +Ele é implementado por [str.normalize()](mdn:js/String/normalize). |
157 | 152 |
|
158 | 153 | ```js run
|
159 |
| -alert( "S\u0307\u0323".normalize() == "S\u0323\u0307".normalize() ); // true |
| 154 | +alert( "S\u0307\u0323".normalize() == "S\u0323\u0307".normalize() ); // verdadeiro |
160 | 155 | ```
|
161 | 156 |
|
162 |
| -It's funny that in our situation `normalize()` actually brings together a sequence of 3 characters to one: `\u1e68` (S with two dots). |
| 157 | +É engraçado que na nossa situação `normalize()` realmente junta uma sequência de 3 caracteres em um: `\u1e68` (S com dois pontos). |
163 | 158 |
|
164 | 159 | ```js run
|
165 | 160 | alert( "S\u0307\u0323".normalize().length ); // 1
|
166 | 161 |
|
167 |
| -alert( "S\u0307\u0323".normalize() == "\u1e68" ); // true |
| 162 | +alert( "S\u0307\u0323".normalize() == "\u1e68" ); // verdadeiro |
168 | 163 | ```
|
169 | 164 |
|
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. |
| 165 | +Na realidade, isso nem sempre é o caso. O motivo é que o símbolo `Ṩ` é "comum o suficiente", então os criadores do Unicode o incluíram na tabela principal e deram o código. |
171 | 166 |
|
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. |
| 167 | +Se você deseja aprender mais sobre regras de normalização e variantes -- elas são descritas no apêndice do padrão Unicode: [Unicode Normalization Forms](https://www.unicode.org/reports/tr15/), mas para a maioria dos propósitos práticos a informação desta seção é suficiente. |
0 commit comments