Skip to content

Commit b7880e6

Browse files
committed
Traduz últimas alterações
2 parents bdb5d94 + 6d245f5 commit b7880e6

File tree

1 file changed

+82
-30
lines changed
  • 1-js/02-first-steps/12-nullish-coalescing-operator

1 file changed

+82
-30
lines changed

1-js/02-first-steps/12-nullish-coalescing-operator/article.md

Lines changed: 82 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,52 +2,95 @@
22

33
[recent browser="new"]
44

5-
O operador de coalescência nula `??` disponibiliza uma sintaxe curta para obter a primeira variável "definida" em uma lista.
5+
Neste artigo diremos que uma expressão é "definida" quando não é igual a `null` nem a `undefined`.
6+
7+
O operador de coalescência nula é escrito usando dois sinais de interrogação `??`.
68

79
O resultado de `a ?? b` é:
8-
- `a` se ele não é `null` ou `undefined`,
9-
- `b`, nos demais casos.
10+
- se `a` é definido, então `a`,
11+
- se `a` não é definido, então `b`.
12+
13+
14+
Em outras palavras, `??` retorna o primeiro argumento se ele não for `null/undefined`. Caso contrário, o segundo.
1015

11-
Então, `x = a ?? b` é um equivalente curto a:
16+
O operador de coalescência nula não é algo completamente novo. É somente uma sintaxe bacana para obter o primeiro valor "definido" entre os dois.
17+
18+
Podemos reescrever `result = a ?? b` usando os operadores que já conhecemos, assim:
1219

1320
```js
14-
x = (a !== null && a !== undefined) ? a : b;
21+
result = (a !== null && a !== undefined) ? a : b;
1522
```
1623

24+
O caso de uso comum para `??` é obter um valor padrão para uma variável potencialmente indefinida.
25+
26+
Por exemplo, aqui exibimos `Anônimo` se `usuario` não for definido:
27+
28+
```js run
29+
let usuario;
30+
31+
alert(usuario ?? "Anônimo"); // Anônimo
32+
```
33+
34+
Claro, se `usuario` possuir qualquer valor diferente de `null/undefined`, então será ele que veremos:
35+
36+
```js run
37+
let usuario = "João";
38+
39+
alert(usuario ?? "Anônimo"); // João
40+
```
41+
42+
Podemos também usar uma sequência de `??` para selecionar o primeiro valor em uma lista que não seja `null/undefined`.
43+
44+
1745
Veja um exemplo mais longo.
1846
19-
Digamos que temos `nome`, `sobrenome` ou `apelido`, todos opcionais.
47+
Digamos que temos dados de um usuário nas variáveis `nome`, `sobrenome` ou `apelido`. Todos eles podem ser indefinidos, se o usuário optar por não entrar com um valor.
2048
21-
Vamos selecionar e exibir o que estiver definido (ou "Anônimo" caso nenhum esteja).
49+
Gostaríamos de exibir o nome do usuário usando uma dessas variáveis, ou exibir "Anônimo" se todas elas forem indefinidas.
50+
51+
Para isso usaremos o operador `??`:
2252
2353
```js run
2454
let nome = null;
2555
let sobrenome = null;
2656
let apelido = "Supercoder";
2757

28-
// exibe a primeira variável com valor diferente de null ou undefined
58+
// exibe o primeiro valor definido:
59+
*!*
2960
alert(nome ?? sobrenome ?? apelido ?? "Anônimo"); // Supercoder
61+
*/!*
3062
```
3163
3264
## Comparação com ||
3365
34-
É muito parecido com o operador OU `||`. Na verdade, podemos substituir `??` por `||` no código acima e obter o mesmo resultado.
35-
36-
A principal diferença é:
37-
- `||` retorna o primeiro valor avaliado como `true` (_truthy_).
38-
- `??` retorna o primeiro valor _definido_.
66+
O operador OU `||` pode ser utilizado da mesma forma que `??`, como descrito no [capítulo anterior](info:logical-operators#or-finds-the-first-truthy-value).
3967
40-
Isso é muito significativo quando queremos tratar `null/undefined` de forma diferente de `0`.
68+
Por exemplo, no código acima podemos substitiur `??` por `||` e o resultado se mantém:
4169
42-
Por exemplo:
70+
```js run
71+
let nome = null;
72+
let sobrenome = null;
73+
let apelido = "Supercoder";
4374

44-
```js
45-
altura = altura ?? 100;
75+
// exibe primeiro valor avaliado como verdadeiro:
76+
*!*
77+
alert(nome || sobrenome || apelido || "Anônimo"); // Supercoder
78+
*/!*
4679
```
4780
48-
Grava `100` em `altura` se ela não estiver definida. Mas se `altura` é `0`, então ela mantém seu valor.
81+
O operador OU `||` existe desde a criação do JavaScript, e vem sendo utilizado para este propósito desde então.
4982
50-
Vamos comparar com `||`:
83+
Por outro lado, o operador de coalescência nula `??` foi adicionado ao JavaScript recentemente, e a razão para isso foi o descontentamento com `||`.
84+
85+
A principal diferença entre eles é:
86+
- `||` retorna o primeiro valor avaliado como `true`.
87+
- `??` retorna o primeiro valor _definido_.
88+
89+
Em outras palavras, `||` não diferencia entre `false`, `0`, uma string vazia `""` e `null/undefined`. Todos são igualmente valores avaliados como falsos. Se algum desses for o primeiro argumento de `||`, então teremos o segundo argumento como resultado.
90+
91+
Na prática, porém, gostaríamos de usar valores padrão somente se a variável é `null/undefined`. Ou seja, quando o valor realmente seja desconhecido/não definido.
92+
93+
Por exemplo, considere isso:
5194
5295
```js run
5396
let altura = 0;
@@ -56,17 +99,18 @@ alert(altura || 100); // 100
5699
alert(altura ?? 100); // 0
57100
```
58101
59-
Aqui, `altura || 100` trata zero na altura como não definida, assim como `null`, `undefined` ou outro valor avaliado como falso; dependendo do caso de uso isso pode ser incorreto.
102+
- `altura || 100` verifica se `altura` é um valor avaliado como falso, e de fato é.
103+
- então o resultado é o segundo argumento, `100`.
104+
- `altura ?? 100` verifica se `altura` é `null/undefined`, e não é,
105+
- então o resultado é o valor atual de `altura`, que é `100`.
60106
61-
`altura ?? 100` retorna `100` somente se `altura` é exatamente `null` ou `undefined`.
107+
Se altura igual a zero é um valor válido que não deve ser substituído pelo valor padrão, então usar `??` é o correto.
62108
63109
## Precedência
64110
65-
A precedência do operador `??` é bastante baixa: `7` na [tabela MDN](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table).
111+
A precedência do operador `??` é bastante baixa: `5` na [tabela MDN](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). Portanto `??` é avaliado antes de `=` e `?`, mas após a maioria dos outros operadores, como `+` e `*`.
66112
67-
É menor que a maioria dos operadores e um pouco maior que `=` e `?`.
68-
69-
Portanto, ao usar `??` em uma expressão complexa, considere o uso de parênteses:
113+
Então, se quiser selecionar um valor com `??` em uma expressão com outros operadores, considere o uso de parênteses:
70114
71115
```js run
72116
let altura = null;
@@ -78,27 +122,35 @@ let area = (altura ?? 100) * (largura ?? 50);
78122
alert(area); // 5000
79123
```
80124
81-
Caso contrário, se omitirmos os parênteses, `*` tem a precedência e será executado primeiro. Isso seria o mesmo que:
125+
Caso contrário, se omitirmos os parênteses, como `*` tem maior precedência que `??`, ele será executado primeiro, levando a resultados incorretos.
82126
83127
```js
84-
// incorreto
128+
// sem parênteses
129+
let area = altura ?? 100 * largura ?? 50;
130+
131+
// ...funciona desta forma (provavelmente não como gostaríamos):
85132
let area = altura ?? (100 * largura) ?? 50;
86133
```
87134
88-
Há ainda uma limitação da linguagem relacionada. Por razões de segurança, é proibido o uso de `??` juntamente com os operadores `&&` e `||`.
135+
### Usando ?? com && ou ||
136+
137+
Por razões de segurança, o JavaScript proibe o uso de `??` juntamente com os operadores `&&` e `||`, a menos que a precedência seja explicitamente especificada usando parênteses.
89138
90139
O código abaixo dispara um erro de sintaxe:
91140
92141
```js run
93142
let x = 1 && 2 ?? 3; // Erro de sintaxe
94143
```
95144
96-
A limitação é certamente discutível, mas por alguma razão foi incluída na especificação da linguagem.
145+
A limitação é certamente discutível, mas foi incluída na especificação da linguagem com o propósito de evitar erros de programação, quando as pessoas começaram a usar `??` em vez de `||`.
97146
98147
Use parênteses explícitos para corrigí-la:
99148
100149
```js run
150+
*!*
101151
let x = (1 && 2) ?? 3; // Funciona
152+
*/!*
153+
102154
alert(x); // 2
103155
```
104156
@@ -113,5 +165,5 @@ alert(x); // 2
113165
altura = altura ?? 100;
114166
```
115167
116-
- O operador `??` possui uma precedência muito baixa, um pouco maior que `?` e `=`.
168+
- O operador `??` possui uma precedência muito baixa, um pouco maior que `?` e `=`, portanto considere adicionar parênteses quando utilizá-lo em uma expressão.
117169
- É proibido usá-lo com `||` ou `&&` sem parênteses explícitos.

0 commit comments

Comments
 (0)