-
Notifications
You must be signed in to change notification settings - Fork 110
nullish-coalescing-operator finished #195
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit
Hold shift + click to select a range
1e8e103
Primeiros parágrafos
ermogenes 85fa0ee
Conclui tradução
ermogenes 8bcb495
Ajustes após comparação
ermogenes b89e2cb
Ajustes após comparação
ermogenes eec6a2a
Ajustes após comparação
ermogenes 61f78fb
Equipara termos com MDN
ermogenes 37f1dbd
Ajustes finais
ermogenes 54546cf
Ajustes finais
ermogenes 1b4c6df
Ajustes finais
ermogenes efdf7bf
Ajustes finais
ermogenes 190fee3
Ajustes finais
ermogenes bdb5d94
Ajustes finais
ermogenes b7880e6
Traduz últimas alterações
ermogenes 5e198f7
Aceita demais alterações
ermogenes 9c92c4d
Merge https://github.com/javascript-tutorial/pt.javascript.info into …
ermogenes 92fa95e
Update 1-js/02-first-steps/12-nullish-coalescing-operator/article.md
ermogenes f756172
Update 1-js/02-first-steps/12-nullish-coalescing-operator/article.md
ermogenes 025b51b
Update 1-js/02-first-steps/12-nullish-coalescing-operator/article.md
ermogenes 1ec73c8
Remove blank lines.
odsantos 0aeb36f
Merge branch 'master' into master
odsantos ef825fa
Resolve conflitos
ermogenes 095b85f
Aplica sugestões do revisor
ermogenes File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
[html src="index.html"] | ||
|
||
[html src="index.html"] | ||
162 changes: 82 additions & 80 deletions
162
1-js/02-first-steps/12-nullish-coalescing-operator/article.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,169 +1,171 @@ | ||
# Nullish coalescing operator '??' | ||
# Operador de coalescência nula '??' | ||
|
||
[recent browser="new"] | ||
|
||
The nullish coalescing operator is written as two question marks `??`. | ||
O operador de coalescência nula é escrito usando dois sinais de interrogação `??`. | ||
|
||
As it treats `null` and `undefined` similarly, we'll use a special term here, in this article. We'll say that an expression is "defined" when it's neither `null` nor `undefined`. | ||
Como ele trata `null` e `undefined` da mesma forma, nós iremos usar um termo especial aqui, neste artigo. Diremos que uma expressão está definida quando não é `null` nem `undefined`. | ||
|
||
The result of `a ?? b` is: | ||
- if `a` is defined, then `a`, | ||
- if `a` isn't defined, then `b`. | ||
O resultado de `a ?? b` é: | ||
|
||
In other words, `??` returns the first argument if it's not `null/undefined`. Otherwise, the second one. | ||
- se `a` é definido, então `a`, | ||
- se `a` não é definido, então `b`. | ||
|
||
The nullish coalescing operator isn't anything completely new. It's just a nice syntax to get the first "defined" value of the two. | ||
Em outras palavras, `??` retorna o primeiro argumento se ele não for `null/undefined`. Caso contrário, o segundo. | ||
|
||
We can rewrite `result = a ?? b` using the operators that we already know, like this: | ||
O operador de coalescência nula não é algo completamente novo. É somente uma sintaxe bacana para obter o primeiro valor "definido" entre os dois. | ||
|
||
Podemos reescrever `result = a ?? b` usando os operadores que já conhecemos, assim: | ||
|
||
```js | ||
result = (a !== null && a !== undefined) ? a : b; | ||
result = a !== null && a !== undefined ? a : b; | ||
``` | ||
|
||
Now it should be absolutely clear what `??` does. Let's see where it helps. | ||
Agora, deveria estar completamente claro o que `??` faz. Vamos ver onde ele é útil. | ||
|
||
The common use case for `??` is to provide a default value for a potentially undefined variable. | ||
O caso de uso comum para `??` é obter um valor padrão para uma variável potencialmente indefinida. | ||
|
||
For example, here we show `user` if defined, otherwise `Anonymous`: | ||
Por exemplo, aqui exibimos `Anônimo` se `usuario` não for definido: | ||
|
||
```js run | ||
let user; | ||
let usuario; | ||
|
||
alert(user ?? "Anonymous"); // Anonymous (user not defined) | ||
alert(usuario ?? "Anônimo"); // Anônimo (usuario não definido) | ||
``` | ||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Here's the example with `user` assigned to a name: | ||
Aqui está o exemplo com um nome atribuido a `user`: | ||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
```js run | ||
let user = "John"; | ||
let usuario = "João"; | ||
|
||
alert(user ?? "Anonymous"); // John (user defined) | ||
alert(usuario ?? "Anônimo"); // João (usuario está definido) | ||
``` | ||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
We can also use a sequence of `??` to select the first value from a list that isn't `null/undefined`. | ||
Podemos também usar uma sequência de `??` para selecionar o primeiro valor em uma lista que não seja `null/undefined`. | ||
|
||
Let's say we have a user's data in variables `firstName`, `lastName` or `nickName`. All of them may be not defined, if the user decided not to enter a value. | ||
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. | ||
|
||
We'd like to display the user name using one of these variables, or show "Anonymous" if all of them aren't defined. | ||
Gostaríamos de exibir o nome do usuário usando uma dessas variáveis, ou exibir "Anônimo" se todas elas forem indefinidas. | ||
|
||
Let's use the `??` operator for that: | ||
Para isso usaremos o operador `??`: | ||
|
||
```js run | ||
let firstName = null; | ||
let lastName = null; | ||
let nickName = "Supercoder"; | ||
let nome = null; | ||
let sobrenome = null; | ||
let apelido = "Supercoder"; | ||
|
||
// shows the first defined value: | ||
// exibe o primeiro valor definido: | ||
*!* | ||
alert(firstName ?? lastName ?? nickName ?? "Anonymous"); // Supercoder | ||
alert(nome ?? sobrenome ?? apelido ?? "Anônimo"); // Supercoder | ||
*/!* | ||
``` | ||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Comparison with || | ||
## Comparação com || | ||
|
||
The OR `||` operator can be used in the same way as `??`, as it was described in the [previous chapter](info:logical-operators#or-finds-the-first-truthy-value). | ||
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). | ||
|
||
For example, in the code above we could replace `??` with `||` and still get the same result: | ||
Por exemplo, no código acima podemos substituir `??` por `||` e o resultado se mantém: | ||
|
||
```js run | ||
let firstName = null; | ||
let lastName = null; | ||
let nickName = "Supercoder"; | ||
let nome = null; | ||
let sobrenome = null; | ||
let apelido = "Supercoder"; | ||
|
||
// shows the first truthy value: | ||
// exibe o primeiro valor avaliado como verdadeiro: | ||
*!* | ||
alert(firstName || lastName || nickName || "Anonymous"); // Supercoder | ||
alert(nome || sobrenome || apelido || "Anônimo"); // Supercoder | ||
*/!* | ||
``` | ||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Historically, the OR `||` operator was there first. It exists since the beginning of JavaScript, so developers were using it for such purposes for a long time. | ||
Historicamente, o operador OU `||` foi o primeiro a existir. Ele existe desde a criação do JavaScript, e vem sendo utilizado para este propósito desde então. | ||
|
||
Por outro lado, o operador de coalescência nula `??` foi adicionado ao JavaScript recentemente, e a razão para isso foi o descontentamento com `||`. | ||
|
||
On the other hand, the nullish coalescing operator `??` was added to JavaScript only recently, and the reason for that was that people weren't quite happy with `||`. | ||
A principal diferença entre eles é: | ||
|
||
The important difference between them is that: | ||
- `||` returns the first *truthy* value. | ||
- `??` returns the first *defined* value. | ||
- `||` retorna o primeiro valor avaliado como `true`. | ||
- `??` retorna o primeiro valor _definido_. | ||
|
||
In other words, `||` doesn't distinguish between `false`, `0`, an empty string `""` and `null/undefined`. They are all the same -- falsy values. If any of these is the first argument of `||`, then we'll get the second argument as the result. | ||
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. | ||
|
||
In practice though, we may want to use default value only when the variable is `null/undefined`. That is, when the value is really unknown/not set. | ||
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. | ||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
For example, consider this: | ||
Por exemplo, considere isso: | ||
|
||
```js run | ||
let height = 0; | ||
let altura = 0; | ||
|
||
alert(height || 100); // 100 | ||
alert(height ?? 100); // 0 | ||
alert(altura || 100); // 100 | ||
alert(altura ?? 100); // 0 | ||
``` | ||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- The `height || 100` checks `height` for being a falsy value, and it's `0`, falsy indeed. | ||
- so the result of `||` is the second argument, `100`. | ||
- The `height ?? 100` checks `height` for being `null/undefined`, and it's not, | ||
- so the result is `height` "as is", that is `0`. | ||
- `altura || 100` verifica se `altura` é um valor avaliado como falso, e como é `0`, de fato é. | ||
- então o resultado de `||` é o segundo argumento, `100`. | ||
- `altura ?? 100` verifica se `altura` é `null/undefined`, e não é, | ||
- então o resultado é o valor atual de `altura`, que é `0`. | ||
|
||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
In practice, the zero height is often a valid value, that shouldn't be replaced with the default. So `??` does just the right thing. | ||
Na prática, a altura igual a zero é um valor válido que não deve ser substituído pelo valor padrão, então usar `??` é o correto. | ||
|
||
## Precedence | ||
## Precedência | ||
|
||
The precedence of the `??` operator is the same as `||`. They both equal `4` in the [MDN table](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). | ||
A precedência do operador `??` é a mesma que a de `||`. Ambos são iguais a '4' na [tabela MDN](https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Operator_Precedence#Table). | ||
|
||
That means that, just like `||`, the nullish coalescing operator `??` is evaluated before `=` and `?`, but after most other operations, such as `+`, `*`. | ||
Isto significa que, tal como `||`, o operador de coalescência nula `??` é avaliado antes de `=` e `?`, mas após a maioria dos outros operadores, como `+` e `*`. | ||
|
||
So if we'd like to choose a value with `??` in an expression with other operators, consider adding parentheses: | ||
Então, se quiser selecionar um valor com `??` em uma expressão com outros operadores, considere o uso de parênteses: | ||
|
||
```js run | ||
let height = null; | ||
let width = null; | ||
let altura = null; | ||
let largura = null; | ||
|
||
// important: use parentheses | ||
let area = (height ?? 100) * (width ?? 50); | ||
// importante: use parênteses | ||
let area = (altura ?? 100) * (largura ?? 50); | ||
|
||
alert(area); // 5000 | ||
``` | ||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Otherwise, if we omit parentheses, then as `*` has the higher precedence than `??`, it would execute first, leading to incorrect results. | ||
Caso contrário, se omitirmos os parênteses, como `*` tem maior precedência que `??`, ele será executado primeiro, levando a resultados incorretos. | ||
|
||
```js | ||
// without parentheses | ||
let area = height ?? 100 * width ?? 50; | ||
// sem parênteses | ||
let area = altura ?? 100 * largura ?? 50; | ||
|
||
// ...works the same as this (probably not what we want): | ||
let area = height ?? (100 * width) ?? 50; | ||
// ...funciona desta forma (provavelmente não como gostaríamos): | ||
let area = altura ?? 100 * largura ?? 50; | ||
``` | ||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Using ?? with && or || | ||
### Usando ?? com && ou || | ||
|
||
Due to safety reasons, JavaScript forbids using `??` together with `&&` and `||` operators, unless the precedence is explicitly specified with parentheses. | ||
Por razões de segurança, o JavaScript proíbe o uso de `??` juntamente com os operadores `&&` e `||`, a menos que a precedência seja explicitamente especificada usando parênteses. | ||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The code below triggers a syntax error: | ||
O código abaixo dispara um erro de sintaxe: | ||
|
||
```js run | ||
let x = 1 && 2 ?? 3; // Syntax error | ||
let x = 1 && 2 ?? 3; // Erro de sintaxe | ||
``` | ||
|
||
The limitation is surely debatable, it was added to the language specification with the purpose to avoid programming mistakes, when people start to switch from `||` to `??`. | ||
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 `||`. | ||
|
||
Use explicit parentheses to work around it: | ||
Use parênteses explícitos para corrigi-la: | ||
|
||
```js run | ||
*!* | ||
let x = (1 && 2) ?? 3; // Works | ||
let x = (1 && 2) ?? 3; // Funciona | ||
*/!* | ||
|
||
alert(x); // 2 | ||
``` | ||
|
||
## Summary | ||
## Resumo | ||
|
||
- The nullish coalescing operator `??` provides a short way to choose the first "defined" value from a list. | ||
- O operador de coalescência nula `??` disponibiliza uma sintaxe curta para obter um valor "definido" em uma lista. | ||
|
||
It's used to assign default values to variables: | ||
É usado para atribuir valores a variáveis: | ||
|
||
```js | ||
// set height=100, if height is null or undefined | ||
height = height ?? 100; | ||
``` | ||
```js | ||
// grava altura=100, se altura é null ou undefined | ||
altura = altura ?? 100; | ||
``` | ||
jonnathan-ls marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
- The operator `??` has a very low precedence, only a bit higher than `?` and `=`, so consider adding parentheses when using it in an expression. | ||
- It's forbidden to use it with `||` or `&&` without explicit parentheses. | ||
- 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. | ||
- É proibido usá-lo com `||` ou `&&` sem parênteses explícitos. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.