You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/04-object-basics/08-symbol/article.md
+29-33Lines changed: 29 additions & 33 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,22 +1,22 @@
1
1
2
2
# O tipo Symbol
3
3
4
-
Segundo a especificação, as chaves das propriedades dos objetos podem ser quer do tipo *string* como do tipo *symbol*. Não números, não booleanos, apenas *strings* (cadeias-de-carateres) ou *symbols* (símbolos), estes dois tipos.
4
+
Segundo a especificação, as chaves das propriedades dos objetos podem ser quer do tipo *string* como do tipo *symbol*. Não números, nem booleanos, mas apenas *strings* ou *symbols* (símbolos), estes dois tipos.
5
5
6
-
Até agora, vimos apenas utilizando*strings*. Então, vejamos os benefícios que *symbols* nos podem dar.
6
+
Até agora, apenas utilizámos*strings*. Então, vamos ver os benefícios que *symbols* nos podem dar.
7
7
8
8
## Símbolos
9
9
10
-
Um "símbolo" representa um único identificador.
10
+
Um "símbolo" representa um identificador único .
11
11
12
-
Um valor deste tipo, pode ser criado utilizando`Symbol()`:
12
+
Um valor deste tipo pode ser criado usando`Symbol()`:
13
13
14
14
```js
15
15
// 'id' é um novo símbolo
16
16
let id =Symbol();
17
17
```
18
18
19
-
Quando o criamos, podemos dar ao símbolo uma descrição (também chamada de nome do símbolo), que é mais útil para fins de *debugging* (depuração de erros):
19
+
Quando o criamos, podemos dar ao símbolo uma descrição (também chamada de nome do símbolo), sendo ela mais útil para propósitos de *debugging* (depuração de erros):
Se você tiver familiaridade com Ruby, ou outra linguagem que também tenha algum tipo de "símbolos" -- por favor, não se confunda. Em JavaScript, os símbolos são diferentes.
39
+
Se você tiver familiaridade com Ruby, ou outra linguagem que também tenha alguma espécie de "símbolos" -- por favor, não se confunda. Os símbolos em JavaScript, são diferentes.
40
40
41
41
````warn header="Símbolos não são auto-convertidos para strings"
42
42
A maior parte dos valores em JavaScript suporta conversão implícita para *string*. Por exemplo, podemos usar `alert` com quase qualquer valor, e irá funcionar. Símbolos são especiais. Eles não são automaticamente convertidos.
@@ -46,15 +46,13 @@ Por exemplo, este `alert` irá mostrar um erro:
46
46
```js run
47
47
let id = Symbol("id");
48
48
*!*
49
-
alert(id); // TypeError: Cannot convert a Symbol value to a string
50
-
// (TypeError: Não é possível converter um valor 'Symbol' para uma 'string')
49
+
alert(id); // TypeError: Cannot convert a Symbol value to a string (ErroDeTipo: Não é possível converter um valor 'Symbol' para uma 'string')
51
50
*/!*
52
51
```
53
52
54
-
Existe uma "salvaguarda na linguagem" contra a confusão, porque *strings* e *symbols* são fundamentalmente diferentes, e não deveriam ser acidentalmente convertidos de um destes tipos para o outro.
55
-
56
-
Se realmente quisermos mostrar um *symbol*, teremos que explicitamente invocar `.toString()` sobre ele, como aqui:
53
+
Esta é uma "salvaguarda na linguagem" contra tal mistura, porque *strings* e *symbols* são fundamentalmente diferentes, e não deveriam ser acidentalmente convertidos de um tipo para o outro.
57
54
55
+
Se realmente quisermos exibir um *symbol*, teremos que explicitamente invocar `.toString()` sobre ele, como aqui:
Ou usar a propriedade `symbol.description` para mostrar apenas a sua descrição:
66
-
67
64
```js run
68
65
let id = Symbol("id");
69
66
*!*
@@ -77,7 +74,7 @@ alert(id.description); // 'id'
77
74
78
75
Símbolos nos permitem criar propriedades "ocultas" num objeto, que nenhuma outra parte do código possa acidentalmente aceder ou alterar.
79
76
80
-
Por exemplo, se estivermos a trabalhar com um objeto `user`, que pertence a um código de terceiros, e quisermos adicionar identificadores a ele.
77
+
Por exemplo, se estivermos a trabalhar com um objeto `user`, que pertença a um código de terceiros, e quisermos adicionar identificadores a ele.
81
78
82
79
Vamos utilizar uma chave *symbol* para isso:
83
80
@@ -95,17 +92,17 @@ alert( user[id] ); // podemos aceder aos dados usando o 'symbol' como chave (key
95
92
96
93
Qual o benefício de se usar `Symbol("id")` sobre uma *string*`"id"`?
97
94
98
-
Como o objeto `user` pertence a outro código, e aquele código trabalha bem com ele, não deveríamos sómente adicionar quaisquer propriedades a ele. Isso não é seguro. Mas, um símbolo não pode ser acedido acidentalmente, o código de terceiros provavelmente nem o irá ver, então talvez seja a coisa certa a fazer.
95
+
Como o objeto `user` pertence a outro código, e aquele código funciona bem com ele, não deveríamos sómente adicionar quaisquer propriedades a ele. Isso não é seguro. Mas, um símbolo não pode ser acedido acidentalmente, o código de terceiros provavelmente nem o irá ver, então talvez seja a coisa certa a fazer.
99
96
100
-
De igual modo, imagine que ainda um outro programa (*script*) quer ter o seu próprio identificador dentro de `user`, para seus próprios fins. Isto pode estar noutra biblioteca (*library*) de JavaScript, por isso os*scripts* podem não ter nenhum conhecimento um do outro.
97
+
De igual modo, imagine que ainda um outro programa (*script*) quer ter o seu próprio identificador dentro de `user`, para seus próprios fins. Isto pode estar noutra biblioteca (*library*) de JavaScript, por isso estes*scripts* podem não ter nenhum conhecimento um do outro.
101
98
102
99
Então, aquele programa pode criar o seu próprio `Symbol("id")`, desta forma:
103
100
104
101
```js
105
102
// ...
106
103
let id =Symbol("id");
107
104
108
-
user[id] ="O valor 'id' do outro programa";
105
+
user[id] ="O valor 'id' dos outros";
109
106
```
110
107
111
108
Não haverá conflito entre o nosso identificador e o dos outros, porque símbolos são sempre diferentes, mesmo que tenham o mesmo nome.
@@ -140,7 +137,6 @@ let user = {
140
137
*/!*
141
138
};
142
139
```
143
-
144
140
Isto, porque precisamos do valor que está na variável `id` como chave, não da *string* "id".
145
141
146
142
### Símbolos são saltados num *for..in*
@@ -165,7 +161,7 @@ for (let key in user) alert(key); // 'name', 'age' (nenhum símbolo)
165
161
alert( "Direct: "+ user[id] );
166
162
```
167
163
168
-
`Object.keys(user)` também os ignora. Isto, é uma parte do conceito geral de "ocultação de propriedades simbólicas". Se, um outro programa ou uma biblioteca percorrer o nosso objeto com um ciclo (*loop*), não irá inadvertidamente aceder a uma propriedade simbólica.
164
+
`Object.keys(user)` também os ignora. Isto, faz uma parte do conceito geral de "ocultação de propriedades simbólicas". Se, um outro programa ou uma biblioteca percorrer o nosso objeto com um ciclo (*loop*), não irá inadvertidamente aceder a uma propriedade simbólica.
169
165
170
166
Em contraste, [Object.assign](mdn:js/Object/assign) copia ambas as propriedades *string* e *symbol*:
171
167
@@ -180,17 +176,17 @@ let clone = Object.assign({}, user);
180
176
alert( clone[id] ); // 123
181
177
```
182
178
183
-
Não existe nenhum paradoxo aqui. Essa é a implementação. A ideia é que ao clonar ou fundir (*merge*) objetos, queremos geralmente *todas* as propriedades copiadas (incluindo símbolos como `id`).
179
+
Não existe nenhum paradoxo aqui. Assim está concebido. A ideia é que ao clonar um objeto ou fundir (*merge*) objetos, geralmente queremos*todas* as propriedades copiadas (incluindo símbolos como `id`).
184
180
185
181
## Símbolos globais
186
182
187
-
Como vimos, geralmente todos os *symbols* são diferentes, mesmo que tenham o mesmo nome. Mas, por vezes queremos que *symbols* com o mesmo nome se refiram às mesmas entidades. Por exemplo, diferentes partes na nossa aplicação pretendem aceder ao *symbol*`"id"`, sendo este exatamente a mesma propriedade.
183
+
Como nós vimos, geralmente todos os *symbols* são diferentes, mesmo que tenham o mesmo nome. Mas, por vezes queremos que *symbols* com o mesmo nome sejam entidades únicas. Por exemplo, diferentes partes da nossa aplicação querem aceder ao *symbol*`"id"`, sendo este exatamente a mesma propriedade.
188
184
189
-
Para alcançar isso, existe um *registo global de símbolos* (*global symbol registry*). Podemos criar *symbols* nele e os aceder mais tarde, e ele garante que acessos repetidos ao mesmo nome retornem exatamente o mesmo *symbol*.
185
+
Para alcançar isto, existe um *registo global de símbolos* (*global symbol registry*). Nós podemos criar *symbols* nele e os aceder mais tarde, e ele garante que acessos repetidos ao mesmo nome retornem exatamente o mesmo *symbol*.
190
186
191
-
Para ler (e criar, se ausente) um *symbol* do registo, use `Symbol.for(key)`.
187
+
Para ler (criar, se ausente) um *symbol* do registo, use `Symbol.for(key)`.
192
188
193
-
Essa chamada verifica o registo global, e se houver um *symbol* descrito como `key`, ele o retorna, senão cria um novo *symbol* com `Symbol(key)` e o armazena no registo sob a chave `key`.
189
+
Esta chamada verifica o registo global, e se houver um *symbol* descrito como `key`, ele o retorna, senão cria um novo *symbol* com `Symbol(key)` e o armazena no registo sob a chave `key`.
194
190
195
191
Por exemplo:
196
192
@@ -205,17 +201,17 @@ let idAgain = Symbol.for("id");
205
201
alert( id === idAgain ); // true (verdadeiro)
206
202
```
207
203
208
-
Símbolos dentro do registo são chamados de *símbolos globais* (*global symbols*). Quando queremos um *symbol* para toda a aplicação, acessível em qualquer parte do código -- é para isso que eles servem.
204
+
Símbolos dentro do registo são chamados de *símbolos globais* (*global symbols*). Quando queremos um *symbol* para toda a aplicação, acessível em qualquer lugar no código -- é para isso que eles servem.
209
205
210
-
```smart header="Isto parece Ruby"
206
+
```smart header="Isso parece Ruby"
211
207
Em algumas linguagens de programação, como Ruby, existe um único *symbol* por nome.
212
208
213
209
Em JavaScript, como podemos ver, esses são os símbolos globais.
214
210
```
215
211
216
212
### Symbol.keyFor
217
213
218
-
Para símbolos globais, não apenas `Symbol.for(key)` retorna um *symbol* por nome, mas existe uma chamada inversa: `Symbol.keyFor(sym)`, que faz ao contrário - retorna um nome de um símbolo global.
214
+
Para símbolos globais, não apenas `Symbol.for(key)` retorna um *symbol* por nome, mas existe uma chamada inversa: `Symbol.keyFor(sym)`, que faz ao contrário - retorna o nome de um símbolo global.
219
215
220
216
Por exemplo:
221
217
@@ -257,25 +253,25 @@ Eles vêm listados na especificação, na tabela [Well-known symbols](https://tc
257
253
-`Symbol.toPrimitive`
258
254
- ... e assim por diante.
259
255
260
-
Por exemplo, `Symbol.toPrimitive` nos permite descrever a conversão objeto-para-primitivo. Veremos o seu uso muito em breve.
256
+
Por exemplo, `Symbol.toPrimitive` nos permite descrever a conversão objeto-para-primitivo. Iremos ver o seu uso muito em breve.
261
257
262
-
Outros *symbols* também se tornarão familiares quando estudarmos as funcionalidades correspondentes na linguagem.
258
+
Outros *symbols* também se irão tornar familiares quando estudarmos as funcionalidades correspondentes na linguagem.
263
259
264
260
## Resumo
265
261
266
262
`Symbol`, é um tipo primitivo para identificadores únicos.
267
263
268
-
Símbolos são criados pela chamada a `Symbol()`, com uma descrição opcional.
264
+
Símbolos são criados pela chamada a `Symbol()`, com uma descrição (nome) opcional.
269
265
270
266
Símbolos são sempre valores diferentes, mesmo que tenham o mesmo nome. Se quisermos que símbolos com o mesmo nome sejam iguais, teremos de utilizar o registo global: `Symbol.for(key)` retorna (cria, se necessário) um símbolo global com `key` como nome. Múltiplas chamadas a `Symbol.for` com a mesma `key` retornam exatamente o mesmo símbolo.
271
267
272
268
Símbolos têm dois principais casos práticos:
273
269
274
270
1. "Ocultação" de propriedades de objetos.
275
-
Se quisermos adicionar uma propriedade a um objeto, "pertencendo" este a outro programa ou biblioteca, podemos criar um símbolo e o usar como a chave dessa propriedade. Uma propriedade simbólica não aparece num `for..in`, por isso não será acidentalmente processada juntamente com outras propriedades. Também, não será acedida diretamente, porque um outro programa não terá o nosso símbolo. Assim, a propriedade estará protegida contra uso acidental ou alteração.
271
+
Se quisermos adicionar uma propriedade a um objeto, "pertencendo" este a outro programa ou biblioteca, podemos criar um símbolo e o usar como a chave dessa propriedade. Uma propriedade simbólica não aparece num `for..in`, por isso não será acidentalmente processada juntamente com outras propriedades. Também, não será acedida diretamente, porque um outro programa não terá o nosso símbolo. Assim, a propriedade estará protegida contra uso ou alteração acidentais.
276
272
277
-
Assim, podemos "secretamente" esconder nos objetos algo que precisemos, que outros não devam ver, empregando propriedades simbólicas.
273
+
Assim, nós podemos "secretamente" esconder nos objetos algo que precisamos, mas que outros não devam ver, empregando propriedades simbólicas.
278
274
279
-
2. Existem muitos símbolos de sistema usados por JavaScript que podem ser acedidos com `Symbol.*`. Podemos os utilizar para alterar alguns comportamentos pré-definidos (*built-in*). Por exemplo, mais adiante no tutorial iremos usar `Symbol.iterator` para [iterables](info:iterable) (iteráveis), `Symbol.toPrimitive` para configurar a [object-to-primitive conversion](info:object-toprimitive) (conversão objeto-para-primitivo), e assim por diante.
275
+
2. Existem muitos símbolos do sistema usados pelo JavaScript que podem ser acedidos com `Symbol.*`. Podemos os utilizar para alterar alguns comportamentos pré-definidos (*built-in*). Por exemplo, mais adiante no tutorial iremos usar `Symbol.iterator` para [iterables](info:iterable) (iteráveis), `Symbol.toPrimitive` para configurar a [object-to-primitive conversion](info:object-toprimitive) (conversão objeto-para-primitivo), e assim por diante.
280
276
281
-
Tecnicamente, símbolos não são 100% ocultados. Existe um método incorporado (*built-in*) [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) que nos permite obter todos os símbolos. Também, existe um método chamado [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) que retorna *todas* as chaves de um objeto, incluindo as simbólicas. Assim, eles não estão realmente ocultos. Mas, tanto muitas bibliotecas, como métodos e construções sintáticas incorporados não usam esses métodos.
277
+
Tecnicamente, símbolos não são 100% ocultados. Existe um método incorporado (*built-in*) [Object.getOwnPropertySymbols(obj)](mdn:js/Object/getOwnPropertySymbols) que nos permite obter todos os símbolos. Também, existe um método chamado [Reflect.ownKeys(obj)](mdn:js/Reflect/ownKeys) que retorna *todas* as chaves de um objeto, incluindo as simbólicas. Assim, eles não estão realmente ocultos. Mas, muitas bibliotecas, assim como métodos e construções sintáticas incorporados não usam esses métodos.
0 commit comments