diff options
Diffstat (limited to 'files/pt-br/web/javascript/reference/operators/optional_chaining/index.html')
-rw-r--r-- | files/pt-br/web/javascript/reference/operators/optional_chaining/index.html | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/files/pt-br/web/javascript/reference/operators/optional_chaining/index.html b/files/pt-br/web/javascript/reference/operators/optional_chaining/index.html new file mode 100644 index 0000000000..f3ed1042fa --- /dev/null +++ b/files/pt-br/web/javascript/reference/operators/optional_chaining/index.html @@ -0,0 +1,192 @@ +--- +title: Encadeamento opcional +slug: Web/JavaScript/Reference/Operators/Optional_chaining +translation_of: Web/JavaScript/Reference/Operators/Optional_chaining +--- +<div>{{JSSidebar("Operators")}}</div> + +<p>O operador de <strong>encadeamento opcional</strong> <strong><code>?.</code></strong> permite a leitura do valor de uma propriedade localizada internamente em uma cadeia de objetos conectados, sem que a validação de cada referência da cadeia seja expressivamente realizada.</p> + +<p>O operador <strong><code>?.</code></strong> funciona de maneira similar ao operador <span class="seoSummary"><code>.</code> de encadeament, exceto que, ao invés de causar um erro se a referência é <a href="/en-US/docs/Glossary/nullish">nullish</a> ({{JSxRef("null")}} ou {{JSxRef("undefined")}}), a expressão sofre um "curto-circuito" e retorna com um valor de <code>undefined</code>.</span> Quando utilizado com uma chamada de função, retorna <code>undefined</code> se a função executada não existir.</p> + +<p>Isso resulta em expressões mais curtas e simples ao acessar propriedades encadeadas quando a possibilidade de uma referência ser inexistente. Isso também pode auxiliar ao explorar o conteúdo de um objeto quando não existe garantia da existência de determinadas propriedades obrigatórias.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-optionalchainingoperator.html", "taller")}}</div> + +<div class="hidden">A fonte desse exemplo interativo está armazenada em um repositório no GitHub. Se você gostaria de contribuir para esses exemplos interativos, por favor, clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> e nos envie um pull request.</div> + +<h2 id="Sintaxe">Sintaxe</h2> + +<pre class="syntaxbox notranslate"><var>obj.val</var>?.<var>prop</var> +<var>obj.val</var>?.[<var>expr</var>] +<em>obj.arr</em>?.[<var>index</var>] +<var>obj.func</var>?.(<var>args</var>) +</pre> + +<h2 id="Descrição">Descrição</h2> + +<p>O operador de encadeamento opcional provê uma forma de simplificar o acesso a valores através de objetos conectados, quando é possível que uma referência ou função possa ser <code>undefined</code> ou <code>null</code>.</p> + +<p>Por exemplo, considere um objeto <code>obj</code> que possui uma estrutura aninhada. Sem o encadeamento opcional, verificar proriedades profundamente aninhadas requer uma validação de referências intermediárias, algo como:</p> + +<pre class="brush: js notranslate">let nestedProp = obj.first && obj.first.second;</pre> + +<p>O valor de <code>obj.first</code> é confirmadamente não-<code>null</code> (e não-<code>undefined</code>) antes de acessar o valor de <code>obj.first.second</code>. Isso previne o erro que ocorreria se você simplesmente acessasse <code>obj.first.second</code> diretamente sem testar <code>obj.first</code>.</p> + +<p>Com o operador de encadeamento opcional (<code>?.</code>), entretanto, você não precisa explicitamente testar e aplicar curto-circuito baseado no estado de <code>obj.first</code> antes de tentar acessar <code>obj.first.second</code>:</p> + +<pre class="brush: js notranslate">let nestedProp = obj.first?.second;</pre> + +<p>Ao utilizar o operador <code>?.</code> ao invés de apenas <code>.</code>, o JavaScript sabe que deve implicitamente checar e ter certeza que <code>obj.first</code> não é <code>null</code> ou <code>undefined</code> antes de tentar acessar <code>obj.first.second</code>. Se <code>obj.first</code> é <code>null</code> ou <code>undefined</code>, a expressão automaticamente sofrerá curto-circuito, retornando <code>undefined</code>.</p> + +<p>Isso é equivalente ao seguinte, exceto que a variável temporária, de fato, não é criada:</p> + +<pre class="brush: js notranslate">let temp = obj.first; +let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second); +</pre> + +<h3 id="Encadeamento_opcional_com_chamadas_de_funções">Encadeamento opcional com chamadas de funções</h3> + +<p>Você pode usar o encadeamento opcional ao tentar chamar um método que pode não existir. Isso pode auxiliar, por exemplo, ao utilizar uma API em que o método está indisponível, seja pela época da implementação ou por causa de uma funcionalidade que ainda não está disponível no dispositivo do usuário.</p> + +<p>Usar encadeamento opcional com chamadas de função faz com que a expressão automaticamente retorne <code>undefined</code> ai invés de lançar uma exceção se o método não é encontrado:</p> + +<pre class="brush: js notranslate">let result = someInterface.customMethod?.();</pre> + +<div class="blockIndicator note"> +<p><strong>Note:</strong> Se existe uma propriedade com tal nome e que não é uma função, usando <code>?.</code> ainda lançará a exceção {{JSxRef("TypeError")}} (<code>x.y</code><code> is not a function</code>).</p> +</div> + +<h4 id="Lidando_com_callbacks_opcionais_ou_manipuladores_de_eventos">Lidando com callbacks opcionais ou manipuladores de eventos</h4> + +<p>Se você usa callbacks ou consulta métodos de objetos com <a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/Atribuicao_via_desestruturacao#Object_destructuring">atribuição via desestruturação</a>, você pode ter valores não-existentes que você não conseguirá chamar como funções, a menos que você tenha testado sua existência. Usando <code>?.</code>, você pode evitar esse teste extra:</p> + +<pre class="brush: js notranslate">// Escrito como ES2019 +function doSomething(onContent, onError) { + try { + // ... faz algo com os dados + } + catch (err) { + if (onError) { // teste se onError realmente existe + onError(err.message); + } + } +} +</pre> + +<pre class="brush: js notranslate">// Usando encadeamento opcional com chamadas de função +function doSomething(onContent, onError) { + try { + // ... faz algo com os dados + } + catch (err) { + onError?.(err.message); // Nenhuma exceção se onError for undefined + } +} +</pre> + +<h3 id="Encadeamento_opcional_com_expressões">Encadeamento opcional com expressões</h3> + +<p>Você também pode usar o operador de encadeamento opcional ao acessar propriedades com uma expressão usando <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors#Bracket_notation">assessores de propriedade</a>:</p> + +<pre class="brush: js notranslate">let nestedProp = obj?.['prop' + 'Name']; +</pre> + +<h3 id="Encadeamento_opcional_não_valid_no_lado_esquerdo_de_uma_atribuição">Encadeamento opcional não valid no lado esquerdo de uma atribuição</h3> + +<pre class="brush: js notranslate"><code>let object = {}; +object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment</code></pre> + +<h3 id="Acesso_a_item_de_Array_com_encadeamento_opcional">Acesso a item de Array com encadeamento opcional</h3> + +<pre class="brush: js notranslate">let arrayItem = arr?.[42];</pre> + +<h2 id="Exemplos">Exemplos</h2> + +<h3 id="Exemplo_básico">Exemplo básico</h3> + +<p>Esse exemplo busca plo valor da propriedade <code>name</code> para o membro <code>bar</code> em um map quando não existe tal membro. Portanto, o resultado é <code>undefined</code>.</p> + +<pre class="brush: js notranslate">let myMap = new Map(); +myMap.set("foo", {name: "baz", desc: "inga"}); + +let nameBar = myMap.get("bar")?.name;</pre> + +<h3 id="Avaliação_com_curto-circuito">Avaliação com curto-circuito</h3> + +<p>Ao usar o encadeamento opcional com expressões, se o operador do lado esquerdo é <code>null</code> ou <code>undefined</code>, a expressão não será avaliada. Por exemplo:</p> + +<pre class="brush: js notranslate">let potentiallyNullObj = null; +let x = 0; +let prop = potentiallyNullObj?.[x++]; + +console.log(x); // 0 já que x não foi incrementado +</pre> + +<h3 id="Empilhando_o_operator_de_encadeamento_opcional">Empilhando o operator de encadeamento opcional</h3> + +<p>Com estruturadas aninhadas, é possível usar encadeamento opcional múltiplas vezes:</p> + +<pre class="brush: js notranslate">let customer = { + name: "Carl", + details: { + age: 82, + location: "Paradise Falls" // endereço detalhado é desconhecido + } +}; +let customerCity = customer.details?.address?.city; + +// … isso também funcional com encadeamento opcional em chamada de função +let duration = vacations.trip?.getTime?.(); +</pre> + +<h3 id="Combinando_com_o_operador_de_coalescência_nula_nullish_coalescing">Combinando com o operador de coalescência nula (nullish coalescing)</h3> + +<p>O {{JSxRef("Operators/Nullish_Coalescing_Operator", "operador de coalescência nula", '', 1)}} pode ser usado após o encadeamento opcional, para construir um valor padrão quando nada é encontrado:</p> + +<pre class="brush: js notranslate">let customer = { + name: "Carl", + details: { age: 82 } +}; +const customerCity = customer?.city ?? "Cidade desconhecida"; +console.log(customerCity); // Cidade desconhecida</pre> + +<h2 id="Especificações">Especificações</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="https://tc39.es/proposal-optional-chaining/#sec-scope">Proposal for the "optional chaining" operator</a></td> + <td>Stage 4</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilidade_de_Navegadores">Compatibilidade de Navegadores</h2> + +<div> + + +<p>{{Compat("javascript.operators.optional_chaining")}}</p> +</div> + +<h3 id="Progresso_de_implementação">Progresso de implementação</h3> + +<p>The following table provides a daily implementation status for this feature, because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in <a href="https://github.com/tc39/test262">Test262</a>, the standard test suite of JavaScript, in the nightly build, or latest release of each browser's JavaScript engine.</p> + +<div>{{EmbedTest262ReportResultsTable("optional-chaining")}}</div> + +<h2 id="Veja_também">Veja também</h2> + +<ul> + <li>O {{JSxRef("Operators/Nullish_Coalescing_Operator", "Nullish Coalescing Operator", '', 1)}}</li> + <li><a href="https://github.com/tc39/proposals">TC39 proposals</a></li> +</ul> |