Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Unicode, String internals#426

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
nazarepiedady merged 3 commits intojavascript-tutorial:masterfromnotFaceroll:master
Mar 24, 2024
Merged
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 67 additions & 72 deletions1-js/99-js-misc/06-unicode/article.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,172 +1,167 @@

# Unicode,String internals
# Unicode,detalhes internos da String

```warn header="Advanced knowledge"
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.
```warn header="Conhecimento avançado"
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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Eu odeio a palavra "hieróglifos" usada em diversos trechos que tratam de Unicode, sinto que é um pouco xenofóbico. Eu sempre traduzo por "logogramas" ou outros nomes mais apropriados.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@peruibeloko, não é xenofóbico, é um termo muito usado na arqueologia.
Recomendo as pessoas a entenderem as coisas e dos porquês (se existirem) antes de partilharem opiniões sobre assuntos fora do seu domínio, mas geralmente se está fora do seu domínio não dê opiniões.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@nazarepiedady sim, é um termo muito usado na arqueologia, mas nos trechos que me refiro, o autor não usa a palavra nesse sentido.

Repare que é possível ver pelo contexto, não só nesse artigo mas em outros também, que o terno hieróglifos está sendo usado no lugar de logogramas. Hieróglifos são especificamente os usados pelos egípcios antigos, logogramas são qualquer sistema de escrita que usa um único caractere para representar um morfema, palavra ou conceito.

Hieróglifos são um tipo de logograma, mais especificamente ideograma, já que usam representações visuais dos conceitos.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@peruibeloko entendo, obrigado pelo esclarecimento!
Mas agora,@nazarepiedady e@peruibeloko, o que não ficou muito claro pra mim é: mantenho como está ou faço a alteração para "logograma"?

Copy link
Member

@nazarepiedadynazarepiedadyMar 9, 2024
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@notFaceroll, keep it as it is.

```

As we already know, JavaScript stringsare based on[Unicode](https://en.wikipedia.org/wiki/Unicode):each character is represented by a byte sequence of 1-4 bytes.
Já sabemos que, as stringsdo JavaScript são baseadas no[Unicode](https://en.wikipedia.org/wiki/Unicode):cada caractere é representado por uma sequência de bytes de 1 a4 bytes.

JavaScriptallows us to insert a character into astringby specifying its hexadecimalUnicodecode with one of these three notations:
JavaScriptnos permite inserir um caractere em umastringao especificar o seu códigoUnicodehexadecimal com uma dessas três notações:

- `\xXX`

`XX`must be two hexadecimal digits with a value between`00`and `FF`,then `\xXX`is the character whose Unicode code is `XX`.
`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`.

Because the`\xXX`notation supports only two hexadecimal digits, it can be used only for the first 256Unicode characters.
Uma vez que a notação`\xXX`suporta apenas dois dígitos hexadecimais, ela pode ser usada apenas para os primeiros 256caracteres Unicode.

These first 256characters include the Latin alphabet, most basic syntax characters, and some others. For example, `"\x7A"`is the same as `"z"` (Unicode `U+007A`).
Esses primeiros 256caracteres 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`).

```js run
alert( "\x7A" ); // z
alert( "\xA9" ); // ©,the copyright symbol
alert( "\xA9" ); // ©,O símbolo de direitos autorais.
```

- `\uXXXX`
`XXXX`must be exactly 4 hex digits with the value between`0000`and `FFFF`,then `\uXXXX`is the character whose Unicode code is `XXXX`.
`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`.

Characters withUnicodevalues 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).
Carateres com valoresUnicodemaiores 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).

```js run
alert( "\u00A9" ); // ©,the same as \xA9,using the 4-digit hex notation
alert( "\u044F" ); // я,the Cyrillic alphabet letter
alert( "\u2191" ); // ↑,the arrow up symbol
alert( "\u00A9" ); // ©,o mesmo que \xA9,usando a notação hexadecimal de 4 dígitos
alert( "\u044F" ); // я,a letra do alfabeto cirílico
alert( "\u2191" ); // ↑,o símbolo da seta para cima
```

- `\u{X…XXXXXX}`

`XXXXXXX`must be ahexadecimalvalue of 1 to 6 bytesbetween `0`and `10FFFF` (the highest code point defined byUnicode).This notation allows us to easily represent all existing Unicodecharacters.
`X...XXXXXX`deve ser um valorhexadecimalde 1 a 6 bytesentre `0`e `10FFFF` (o maior ponto de código definido peloUnicode).Esta notação nos permite representar facilmente todos os caracteres Unicodeexistentes.

```js run
alert( "\u{20331}" ); // 佫,a rare Chinese character (longUnicode)
alert( "\u{1F60D}" ); // 😍,a smiling face symbol (another longUnicode)
alert( "\u{20331}" ); // 佫,um caractere chinês raro (Unicode longo)
alert( "\u{1F60D}" ); // 😍,um símbolo de rosto sorridente (outroUnicode longo)
```

##Surrogate pairs
##Pares substitutos

All frequently used characters have 2-byte codes (4hex 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.
Todos os caracteres usados frequentemente têm códigos de 2 bytes (4dí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.

Initially,JavaScriptwas based onUTF-16encoding that only allowed2 bytesper character. But 2 bytesonly allow 65536combinations and that's not enough for every possible symbol of Unicode.
Inicialmente, oJavaScriptera baseado na codificaçãoUTF-16que permitia apenas2 bytespor caractere. Mas 2 bytessó permitem 65536combinações e isso não é suficiente para todos os símbolos possíveis do Unicode.

So rare symbols that require more than 2 bytesare encoded with a pair of 2-byte characters called "a surrogate pair".
Então, símbolos raros que requerem mais de 2 bytessão codificados com um par de caracteres de 2 bytes chamados de "par substituto".

As a side effect, the length of such symbols is `2`:
Como efeito colateral, o comprimento de tais símbolos é `2`:

```js run
alert( '𝒳'.length ); // 2,MATHEMATICAL SCRIPT CAPITAL X
alert( '😂'.length ); // 2,FACE WITH TEARS OF JOY
alert( '𩷶'.length ); // 2,a rare Chinese character
alert( '𝒳'.length ); // 2,caractere matemático X maiúsculo
alert( '😂'.length ); // 2,rosto com lágrimas de alegria
alert( '𩷶'.length ); // 2,um caractere chinês raro
```

That's because surrogate pairs did not exist at the time whenJavaScriptwas created, and thus are not correctly processed by the language!
Isso ocorre porque pares substitutos não existiam na época em que oJavaScriptfoi criado e, portanto, não são processados corretamente pela linguagem!

We actually have a single symbol in each of the stringsabove, but the`length`property shows a length of `2`.
Na verdade, temos um único símbolo em cada uma das stringsacima, mas a propriedade`length`mostra um comprimento de `2`.

Getting a symbol can also be tricky, because most language features treat surrogate pairs as two characters.
Obter um símbolo também pode ser complicado, porque a maioria dos recursos da linguagem tratam pares substitutos como dois caracteres.

For example, here we can see two odd characters in the output:
Por exemplo, aqui podemos ver dois caracteres estranhos na saída:

```js run
alert( '𝒳'[0] ); //shows strange symbols...
alert( '𝒳'[1] ); // ...pieces of the surrogate pair
alert( '𝒳'[0] ); //mostra símbolos estranhos...
alert( '𝒳'[1] ); // ...partes de um par substituto
```

Pieces of a surrogate pair have no meaning without each other. So the alerts in the example above actually display garbage.
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.

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.
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.

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 JavaScriptto deal with surrogate pairs.
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 JavaScriptpara lidar com pares substitutos.

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.
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.

One can see the difference here:
Podemos ver a diferença aqui:

```js run
// charCodeAtis not surrogate-pair aware, so it gives codes for the 1st part of 𝒳:
// charCodeAtnão reconhece pares substitutos, então fornece códigos para a 1ª parte de 𝒳:

alert( '𝒳'.charCodeAt(0).toString(16) ); // d835

// codePointAtis surrogate-pair aware
alert( '𝒳'.codePointAt(0).toString(16) ); // 1d4b3,reads both parts of the surrogate pair
// codePointAtreconhece pares substitutos
alert( '𝒳'.codePointAt(0).toString(16) ); // 1d4b3,lê ambas as partes do par substituto
```

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:
Dito isto, se partirmos da posição 1 (e isso está bastante incorreto aqui), então ambos retornam apenas a 2ª parte do par:

```js run
alert( '𝒳'.charCodeAt(1).toString(16) ); // dcb3
alert( '𝒳'.codePointAt(1).toString(16) ); // dcb3
//meaningless 2nd half of the pair
//segunda parte do par sem sentido
```
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.

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.

````warn header="Takeaway: splitting strings at an arbitrary point is dangerous"
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.:
````warn header="Conclusão: dividir strings em um ponto arbitrário é perigoso"
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:

```js run
alert( 'hi 😂'.slice(0, 4) ); // hi [?]
```
Aqui podemos ver um caractere inválido (primeira metade do par substituto) na saída.

Here we can see a garbage character (first half of the smile surrogate pair) in the output.

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.
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.
````

##Diacritical marks and normalization
##Marcas diacríticas e normalização

In many languages, there are symbols that are composed of thebasecharacter with a mark above/under it.
Em várias linguagens, existem símbolos que são compostos do caracterebasecom uma marca acima/abaixo dele.

For instance, the letter `a`can be thebasecharacter for these characters: `àáâäãåā`.
Por exemplo, a letra `a`pode ser o caracterebasepara esses caracteres: `àáâäãåā`.

Most common "composite" characters have their own code in the Unicode table. But not all of them, because there are too many possible combinations.
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.

To support arbitrary compositions, theUnicodestandard allows us to use severalUnicode characters: thebasecharacter followed by one or many "mark" characters that "decorate" it.
Para auxiliar composições arbitrárias, o padrãoUnicodenos permite usar vários caracteresUnicode: o caracterebaseseguido por um ou vários caracteres "marca" que o "decoram".

For instance, if we have`S`followed by the special "dot above" character (code `\u0307`),it is shown as Ṡ.
Por exemplo, se tivermos`S`seguido pelo caractere especial "ponto acima" (código `\u0307`),ele será mostrado como Ṡ.

```js run
alert( 'S\u0307' ); // Ṡ
```
Se precisarmos de uma marca adicional acima da letra (ou abaixo dela) -- sem problemas, apenas adicione o caractere de marca necessário.

If we need an additional mark above the letter (or below it) -- no problem, just add the necessary mark character.
Por exemplo, se anexarmos o caractere "ponto abaixo" (código `\u0323`), então teremos "S com pontos acima e abaixo": `Ṩ`.

For instance, if we append a character "dot below" (code `\u0323`), then we'll have "S with dots above and below": `Ṩ`.

For example:
Por exemplo:

```js run
alert( 'S\u0307\u0323' ); // Ṩ
```
Isso fornece grande flexibilidade, mas também um problema interessante: dois caracteres podem parecer visualmente iguais, mas serem representados com diferentes composições Unicode.

This provides great flexibility, but also an interesting problem: two characters may visually look the same, but be represented with different Unicode compositions.

For instance:
Por exemplo:

```js run
let s1 = 'S\u0307\u0323'; // Ṩ, S +dot above +dot below
let s2 = 'S\u0323\u0307'; // Ṩ, S +dot below +dot above
let s1 = 'S\u0307\u0323'; // Ṩ, S +ponto acima +ponto abaixo
let s2 = 'S\u0323\u0307'; // Ṩ, S +ponto abaixo +ponto acima

alert( `s1: ${s1}, s2: ${s2}` );

alert( s1 == s2 ); //false though the characters look identical (?!)
alert( s1 == s2 ); //falso embora os caracteres pareçam identicos (?!)
```

To solve this, there exists a "Unicode normalization" algorithm that brings eachstringto the single"normal" form.
Para resolver isso, existe um algoritmo de "normalização Unicode" que traz cadastringpara a única forma"normal".

It is implemented by [str.normalize()](mdn:js/String/normalize).
Ele é implementado por [str.normalize()](mdn:js/String/normalize).

```js run
alert( "S\u0307\u0323".normalize() == "S\u0323\u0307".normalize() ); //true
alert( "S\u0307\u0323".normalize() == "S\u0323\u0307".normalize() ); //verdadeiro
```

It's funny that in our situation `normalize()`actually brings together a sequence of 3 characters to one: `\u1e68` (Swith two dots).
É engraçado que na nossa situação `normalize()`realmente junta uma sequência de 3 caracteres em um: `\u1e68` (Scom dois pontos).

```js run
alert( "S\u0307\u0323".normalize().length ); // 1

alert( "S\u0307\u0323".normalize() == "\u1e68" ); //true
alert( "S\u0307\u0323".normalize() == "\u1e68" ); //verdadeiro
```

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.
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.

If you want to learn more about normalization rules and variants --they are described in the appendix of theUnicode standard: [Unicode Normalization Forms](https://www.unicode.org/reports/tr15/),but for most practical purposes the information from this section is enough.
Se você deseja aprender mais sobre regras de normalização e variantes --elas são descritas no apêndice do padrãoUnicode: [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.

[8]ページ先頭

©2009-2025 Movatter.jp