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/02-first-steps/12-nullish-coalescing-operator/article.md
+82-30Lines changed: 82 additions & 30 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,52 +2,95 @@
2
2
3
3
[recent browser="new"]
4
4
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 `??`.
6
8
7
9
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.
10
15
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:
12
19
13
20
```js
14
-
x= (a !==null&& a !==undefined) ? a : b;
21
+
result= (a !==null&& a !==undefined) ? a : b;
15
22
```
16
23
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
+
17
45
Veja um exemplo mais longo.
18
46
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.
20
48
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 `??`:
22
52
23
53
```js run
24
54
let nome =null;
25
55
let sobrenome =null;
26
56
let apelido ="Supercoder";
27
57
28
-
// exibe a primeira variável com valor diferente de null ou undefined
É 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).
39
67
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:
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.
49
82
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:
51
94
52
95
```js run
53
96
let altura =0;
@@ -56,17 +99,18 @@ alert(altura || 100); // 100
56
99
alert(altura ??100); // 0
57
100
```
58
101
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`.
60
106
61
-
Já `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.
62
108
63
109
## Precedência
64
110
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 `*`.
66
112
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:
70
114
71
115
```js run
72
116
let altura =null;
@@ -78,27 +122,35 @@ let area = (altura ?? 100) * (largura ?? 50);
78
122
alert(area); // 5000
79
123
```
80
124
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.
82
126
83
127
```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):
85
132
let area = altura ?? (100* largura) ??50;
86
133
```
87
134
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.
89
138
90
139
O código abaixo dispara um erro de sintaxe:
91
140
92
141
```js run
93
142
let x =1&&2??3; // Erro de sintaxe
94
143
```
95
144
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 `||`.
97
146
98
147
Use parênteses explícitos para corrigí-la:
99
148
100
149
```js run
150
+
*!*
101
151
let x = (1&&2) ??3; // Funciona
152
+
*/!*
153
+
102
154
alert(x); // 2
103
155
```
104
156
@@ -113,5 +165,5 @@ alert(x); // 2
113
165
altura = altura ??100;
114
166
```
115
167
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.
117
169
- É proibido usá-lo com `||` ou `&&` sem parênteses explícitos.
0 commit comments