diff options
Diffstat (limited to 'files/pt-br/learn/javascript')
30 files changed, 6845 insertions, 0 deletions
diff --git a/files/pt-br/learn/javascript/asynchronous/escolhendo_abordagem_correta/index.html b/files/pt-br/learn/javascript/asynchronous/choosing_the_right_approach/index.html index 254bc41a99..254bc41a99 100644 --- a/files/pt-br/learn/javascript/asynchronous/escolhendo_abordagem_correta/index.html +++ b/files/pt-br/learn/javascript/asynchronous/choosing_the_right_approach/index.html diff --git a/files/pt-br/learn/javascript/asynchronous/conceitos/index.html b/files/pt-br/learn/javascript/asynchronous/concepts/index.html index f2e6759f41..f2e6759f41 100644 --- a/files/pt-br/learn/javascript/asynchronous/conceitos/index.html +++ b/files/pt-br/learn/javascript/asynchronous/concepts/index.html diff --git a/files/pt-br/learn/javascript/asynchronous/introdução/index.html b/files/pt-br/learn/javascript/asynchronous/introducing/index.html index b95a88d35c..b95a88d35c 100644 --- a/files/pt-br/learn/javascript/asynchronous/introdução/index.html +++ b/files/pt-br/learn/javascript/asynchronous/introducing/index.html diff --git a/files/pt-br/learn/javascript/building_blocks/build_your_own_function/index.html b/files/pt-br/learn/javascript/building_blocks/build_your_own_function/index.html new file mode 100644 index 0000000000..d701a63823 --- /dev/null +++ b/files/pt-br/learn/javascript/building_blocks/build_your_own_function/index.html @@ -0,0 +1,242 @@ +--- +title: Construa sua própria função +slug: Aprender/JavaScript/Elementos_construtivos/Build_your_own_function +translation_of: Learn/JavaScript/Building_blocks/Build_your_own_function +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">Com a maior parte da teoria essencial tratada no artigo anterior, este artigo fornece experiência prática. Aqui você terá algumas práticas construindo sua própria função personalizada. Ao longo do caminho, também explicaremos alguns detalhes úteis sobre como lidar com funções.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos:</th> + <td>Alfabetização básica em informática, um entendimento básico de HTML e CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">Primeiros passos do JavaScript</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Funções — blocos reutilizáveis de código</a>.</td> + </tr> + <tr> + <th scope="row">Objetiva:</th> + <td>Para fornecer alguma prática na criação de uma função personalizada e explicar alguns detalhes associados mais úteis.</td> + </tr> + </tbody> +</table> + +<h2 id="Aprendizagem_ativa_vamos_construir_uma_função">Aprendizagem ativa: vamos construir uma função</h2> + +<p>A função personalizada que vamos construir será chamada <code>displayMessage().</code> Ele exibirá uma caixa de mensagem personalizada em uma página da Web e atuará como um substituto personalizado para a função de <a href="/en-US/docs/Web/API/Window/alert">alert()</a> interna do navegador. Já vimos isso antes, mas vamos apenas refrescar nossas memórias. Digite o seguinte no console JavaScript do seu navegador, em qualquer página de sua preferência:</p> + +<pre class="brush: js notranslate">alert('This is a message');</pre> + +<p>A função <code>alert</code> leva um único argumento — a string exibida na caixa de alerta. Tente variar a string para mudar a mensagem.</p> + +<p>A função <code>alert</code> é limitada: você pode alterar a mensagem, mas não pode variar com facilidade nada, como cor, ícone ou qualquer outra coisa. Nós vamos construir um que se mostrará mais divertido.</p> + +<div class="note"> +<p><strong>Nota</strong>: Este exemplo deve funcionar bem em todos os navegadores modernos, mas o estilo pode parecer um pouco engraçado em navegadores um pouco mais antigos. Recomendamos que você faça esse exercício em um navegador moderno como o Firefox, o Opera ou o Chrome.</p> +</div> + +<h2 id="A_função_básica">A função básica</h2> + +<p>Para começar, vamos montar uma função básica.</p> + +<div class="note"> +<p><strong>Note</strong>: Para convenções de nomenclatura de função, você deve seguir as mesmas regras das <a href="/en-US/Learn/JavaScript/First_steps/Variables#An_aside_on_variable_naming_rules">convenções de nomenclatura de variáveis</a>. Algo bom é como você pode diferenciá-los — os nomes das funções aparecem com parênteses depois deles e as variáveis não.</p> +</div> + +<ol> + <li>Comece acessando o arquivo <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-start.html">function-start.html</a> e fazendo uma cópia local. Você verá que o HTML é simples — o corpo contém apenas um único botão. Também fornecemos algumas CSS básicas para estilizar a caixa de mensagem personalizada e um elemento {{htmlelement("script")}} vazio para colocar nosso JavaScript.</li> + <li>Em seguida, adicione o seguinte dentro do elemento <code><script></code> : + <pre class="brush: js notranslate">function displayMessage() { + +}</pre> + Começamos com a palavra-chave <code>function</code>, o que significa que estamos definindo uma função. Isto é seguido pelo nome que queremos dar à nossa função, um par de parênteses e um conjunto de chaves. Quaisquer parâmetros que queremos dar à nossa função vão dentro dos parênteses, e o código que é executado quando chamamos a função vai dentro das chaves.</li> + <li>Por fim, adicione o seguinte código dentro das chaves: + <pre class="brush: js notranslate">var html = document.querySelector('html'); + +var panel = document.createElement('div'); +panel.setAttribute('class', 'msgBox'); +html.appendChild(panel); + +var msg = document.createElement('p'); +msg.textContent = 'This is a message box'; +panel.appendChild(msg); + +var closeBtn = document.createElement('button'); +closeBtn.textContent = 'x'; +panel.appendChild(closeBtn); + +closeBtn.onclick = function() { + panel.parentNode.removeChild(panel); +}</pre> + </li> +</ol> + +<p>Isso é um monte de código para passar, então vamos guiá-lo pouco a pouco.</p> + +<p>A primeira linha usa uma função da API do DOM chamada {{domxref("document.querySelector()")}} para selecionar o elemento {{htmlelement("html")}} e armazenar uma referência a ele em uma variável chamada <code>html</code>, para que possamos fazer coisas com ela mais tarde:</p> + +<pre class="brush: js notranslate">var html = document.querySelector('html');</pre> + +<p>A próxima seção usa outra função da API do DOM chamada {{domxref("Document.createElement()")}} para criar um elemento {{htmlelement("div")}} elemento e armazenar uma referência a ele em uma variável chamada <code>panel</code>. Este elemento será o recipiente externo da nossa caixa de mensagens.</p> + +<p>Em seguida, usamos outra função da API do DOM chamada {{domxref("Element.setAttribute()")}} para setar o atributo <code>class</code> atributo no nosso painel com um valor de <code>msgBox</code>. Isso é para facilitar o estilo do elemento — se você olhar para o CSS na página, verá que estamos usando um seletor de classe <code>.msgBox</code> para estilizar a caixa de mensagem e seu conteúdo.</p> + +<p>Finalmente, chamamos uma função DOM chamada {{domxref("Node.appendChild()")}} na variável <code>html</code> vque armazenamos anteriormente, que nidifica um elemento dentro do outro como um filho dele. Nós especificamos o painel <code><div></code> como o filho que queremos acrescentar dentro do elemento <code><html></code> Precisamos fazer isso porque o elemento que criamos não aparecerá na página sozinho — precisamos especificar onde colocá-lo.</p> + +<pre class="brush: js notranslate">var panel = document.createElement('div'); +panel.setAttribute('class', 'msgBox'); +html.appendChild(panel);</pre> + +<p>As próximas duas seções fazem uso das mesmas funções <code>createElement()</code> e <code>appendChild()</code> que já vimos para criar dois novos elementos — um {{htmlelement("p")}} e um {{htmlelement("button")}} — e inseri-los na página como filhos do painel <code><div></code>. Nós usamos a sua propriedade {{domxref("Node.textContent")}} — que representa o conteúdo de texto de um elemento — para inserir uma mensagem dentro do parágrafo e um 'x' dentro do botão. Este botão será o que precisa ser clicado / ativado quando o usuário quiser fechar a caixa de mensagem.</p> + +<pre class="brush: js notranslate">var msg = document.createElement('p'); +msg.textContent = 'This is a message box'; +panel.appendChild(msg); + +var closeBtn = document.createElement('button'); +closeBtn.textContent = 'x'; +panel.appendChild(closeBtn);</pre> + +<p>Finalmente, usamos um manipulador eventos {{domxref("GlobalEventHandlers.onclick")}} para fazer com que, quando o botão é clicado, algum código seja executado para excluir todo o painel da página — para fechar a caixa de mensagem.</p> + +<p>Resumidamente, o manipulador <code>onclick</code> é uma propriedade disponível no botão (ou, na verdade, qualquer elemento na página) que pode ser definida para uma função para especificar qual código será executado quando o botão for clicado. Você aprenderá muito mais sobre isso em nosso artigo de eventos posteriores. Estamos tornando o manipulador <code>onclick</code> igual a uma função anônima, que contém o código a ser executado quando o botão é clicado. A linha dentro da função usa a função da API do DOM {{domxref("Node.removeChild()")}} para especificar que queremos remover um elemento filho específico do elemento HTML — nesse caso, o painel <code><div></code>.</p> + +<pre class="brush: js notranslate">closeBtn.onclick = function() { + panel.parentNode.removeChild(panel); +}</pre> + +<p>Basicamente, todo esse bloco de código está gerando um bloco de HTML semelhante a isso e inserindo-o na página:</p> + +<pre class="brush: html notranslate"><div class="msgBox"> + <p>This is a message box</p> + <button>x</button> +</div></pre> + +<p>Isso foi um monte de código para trabalhar — não se preocupe muito se você não se lembra exatamente como tudo funciona agora! A parte principal que queremos focar aqui é a estrutura e uso da função, mas queremos mostrar algo interessante para este exemplo.</p> + +<h2 id="Chamando_a_função">Chamando a função</h2> + +<p>Você tem sua própria definição de função escrita em seu elemento <code><script></code>, mas não fará nada do jeito que está.</p> + +<ol> + <li>Tente incluir a seguinte linha abaixo da sua função para chamá-lo: + <pre class="brush: js notranslate">displayMessage();</pre> + Esta linha chama a função, fazendo com que ela seja executada imediatamente. Quando você salvar seu código e recarregá-lo no navegador, verá a pequena caixa de mensagem aparecer imediatamente, apenas uma vez. Nós só estamos chamando uma vez, afinal.</li> + <li> + <p>Agora abra suas ferramentas de desenvolvedor do navegador na página de exemplo, vá para o console JavaScript e digite a linha novamente, você verá que ela aparece novamente! Então isso é divertido — agora temos uma função reutilizável que podemos chamar a qualquer momento que quisermos.</p> + + <p>Mas provavelmente queremos que apareça em resposta a ações do usuário e do sistema. Em um aplicativo real, essa caixa de mensagem provavelmente seria chamada em resposta a novos dados sendo disponibilizados, ou um erro ocorreria, ou o usuário tentando excluir seu perfil ("você tem certeza disso?") Ou o usuário adicionando um novo contato e a operação completando com sucesso ... etc.</p> + + <p>Nesta demonstração, faremos com que a caixa de mensagem apareça quando o usuário clicar no botão.</p> + </li> + <li>Exclua a linha anterior que você adicionou.</li> + <li>Em seguida, vamos selecionar o botão e armazenar uma referência a ele em uma variável. Adicione a seguinte linha ao seu código, acima da definição da função: + <pre class="brush: js notranslate">var btn = document.querySelector('button');</pre> + </li> + <li>Por fim, adicione a seguinte linha abaixo da anterior: + <pre class="brush: js notranslate">btn.onclick = displayMessage;</pre> + De maneira semelhante à nossa linha <code>closeBtn.onclick...</code> dentro da função, aqui estamos chamando algum código em resposta a um botão sendo clicado. Mas, neste caso, em vez de chamar uma função anônima contendo algum código, estamos chamando nosso nome de função diretamente.</li> + <li>Tente salvar e atualizar a página — agora você verá a caixa de mensagem quando clicar no botão.</li> +</ol> + +<p>Você pode estar se perguntando por que não incluímos os parênteses após o nome da função. Isso ocorre porque não queremos chamar a função imediatamente — somente depois que o botão foi clicado. Se você tentar mudar a linha para</p> + +<pre class="brush: js notranslate">btn.onclick = displayMessage();</pre> + +<p>e salvar e recarregar, você verá que a caixa de mensagem aparece sem que o botão seja clicado! Os parênteses neste contexto são às vezes chamados de "operador de invocação de função". Você só os usa quando deseja executar a função imediatamente no escopo atual. No mesmo sentido, o código dentro da função anônima não é executado imediatamente, pois está dentro do escopo da função.</p> + +<p>Se você tentou o último experimento, certifique-se de desfazer a última alteração antes de continuar.</p> + +<h2 id="Melhorando_a_função_com_parâmetros">Melhorando a função com parâmetros</h2> + +<p>Tal como está, a função ainda não é muito útil — nós não queremos apenas mostrar a mesma mensagem padrão todas as vezes. Vamos melhorar nossa função adicionando alguns parâmetros, permitindo-nos chamá-lo com algumas opções diferentes.</p> + +<ol> + <li>Primeiro de tudo, atualize a primeira linha da função: + <pre class="brush: js notranslate">function displayMessage() {</pre> + para isso:</li> + <li> + <pre class="brush: js notranslate">function displayMessage(msgText, msgType) {</pre> + Agora, quando chamamos a função, podemos fornecer dois valores de variáveis dentro dos parênteses para especificar a mensagem a ser exibida na caixa de mensagem e o tipo de mensagem que ela é.</li> + <li>Para utilizar o primeiro parâmetro, atualize a seguinte linha dentro da sua função: + <pre class="brush: js notranslate">msg.textContent = 'This is a message box';</pre> + to + + <pre class="brush: js notranslate">msg.textContent = msgText;</pre> + </li> + <li>Por último, mas não menos importante, você precisa atualizar sua chamada de função para incluir um texto de mensagem atualizado. Altere a seguinte linha: + <pre class="brush: js notranslate">btn.onclick = displayMessage;</pre> + para este bloco: + + <pre class="brush: js notranslate">btn.onclick = function() { + displayMessage('Woo, this is a different message!'); +};</pre> + Se quisermos especificar parâmetros dentro de parênteses para a função que estamos chamando, então não podemos chamá-la diretamente — precisamos colocá-lo dentro de uma função anônima para que não fique no escopo imediato e, portanto, não seja chamado imediatamente. Agora ele não será chamado até que o botão seja clicado.</li> + <li>Recarregue e tente o código novamente e você verá que ele ainda funciona muito bem, exceto que agora você também pode variar a mensagem dentro do parâmetro para obter mensagens diferentes exibidas na caixa!</li> +</ol> + +<h3 id="Um_parâmetro_mais_complexo">Um parâmetro mais complexo</h3> + +<p>Para o próximo parâmetro. Este vai envolver um pouco mais de trabalho — vamos configurá-lo para que, dependendo do parâmetro <code>msgType</code>, a função mostre um ícone diferente e uma cor de fundo diferente.</p> + +<ol> + <li>Primeiro de tudo, baixe os ícones necessários para este exercício (<a href="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/functions/icons/warning.png">aviso</a> e <a href="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/functions/icons/chat.png">batepapo</a>) do GitHub. Salve-os em uma nova pasta chamada <code>icons</code> no mesmo local que seu arquivo HTML. + + <div class="note"><strong>Nota</strong>: Os icones <a href="https://www.iconfinder.com/icons/1031466/alarm_alert_error_warning_icon">aviso</a> e <a href="https://www.iconfinder.com/icons/1031441/chat_message_text_icon">batepapo</a> são encontrado em iconfinder.com, e desenhados por <a href="https://www.iconfinder.com/nazarr">Nazarrudin Ansyari</a>. Obrigado!</div> + </li> + <li>Em seguida, encontre o CSS dentro do seu arquivo HTML. Faremos algumas alterações para abrir caminho para os ícones. Primeiro, atualize a largura do <code>.msgBox</code> de: + <pre class="brush: css notranslate">width: 200px;</pre> + para:</li> + <li> + <pre class="brush: css notranslate">width: 242px;</pre> + </li> + <li>Em seguida, adicione as seguintes linhas dentro da regra <code>.msgBox p { ... }</code>: + <pre class="brush: css notranslate">padding-left: 82px; +background-position: 25px center; +background-repeat: no-repeat;</pre> + </li> + <li>Agora precisamos adicionar código à nossa função <code>displayMessage()</code> para manipular a exibição dos ícones. Adicione o seguinte bloco logo acima da chave de fechamento (<code>}</code>) da sua função: + <pre class="brush: js notranslate">if (msgType === 'warning') { + msg.style.backgroundImage = 'url(icons/warning.png)'; + panel.style.backgroundColor = 'red'; +} else if (msgType === 'chat') { + msg.style.backgroundImage = 'url(icons/chat.png)'; + panel.style.backgroundColor = 'aqua'; +} else { + msg.style.paddingLeft = '20px'; +}</pre> + Aqui, se o parâmetro <code>msgType</code> estiver definido como <code>'warning'</code>, o ícone de aviso será exibido e a cor de fundo do painel será definida como vermelha. Se estiver definido para <code>'chat'</code>, o ícone de bate-papo é exibido e a cor de fundo do painel é definida como azul aqua. Se o parâmetro <code>msgType</code> não estiver definido (ou para algo diferente), então a parte <code>else { ... }</code> do código entra em jogo, e o parágrafo é simplesmente fornecido padding padrão e nenhum ícone, sem conjunto de cores do painel de fundo também. Isso fornece um estado padrão se nenhum parâmetro <code>msgType</code> for fornecido, significando que é um parâmetro opcional!</li> + <li>Vamos testar nossa função atualizada, tente atualizar a chamada <code>displayMessage()</code> a partir disso: + <pre class="brush: js notranslate">displayMessage('Woo, this is a different message!');</pre> + para um destes:</li> + <li> + <pre class="brush: js notranslate">displayMessage('Your inbox is almost full — delete some mails', 'warning'); +displayMessage('Brian: Hi there, how are you today?','chat');</pre> + Você pode ver como a nossa pequena função (agora nem tanto) está se tornando útil.</li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>: Se você tiver problemas para fazer o exemplo funcionar, sinta-se à vontade para verificar seu código na <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-stage-4.html">versão finalizada no GitHub</a> (<a href="http://mdn.github.io/learning-area/javascript/building-blocks/functions/function-stage-4.html">veja-a também em execução</a>), ou peça nos ajuda.</p> +</div> + +<h2 id="Conclusão">Conclusão</h2> + +<p>Parabéns por chegar ao final! Este artigo levou você ao longo de todo o processo de criação de uma função prática personalizada, que com um pouco mais de trabalho poderia ser transplantada em um projeto real. No próximo artigo, vamos encerrar as funções explicando outro conceito relacionado essencial — valores de retorno.</p> + +<ul> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Functions","Learn/JavaScript/Building_blocks/Return_values", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/building_blocks/conditionals/index.html b/files/pt-br/learn/javascript/building_blocks/conditionals/index.html new file mode 100644 index 0000000000..0fec6d40e7 --- /dev/null +++ b/files/pt-br/learn/javascript/building_blocks/conditionals/index.html @@ -0,0 +1,616 @@ +--- +title: Tomando decisões no seu código — condicionais +slug: Aprender/JavaScript/Elementos_construtivos/conditionals +tags: + - Artigo + - Condicionais + - Iniciante +translation_of: Learn/JavaScript/Building_blocks/conditionals +--- +<div>{{LearnSidebar}}</div> + +<div>{{NextMenu("Learn/JavaScript/Building_blocks/Looping_code", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">Em qualquer linguagem de programação, o código precisa tomar decisões e realizar ações de acordo, dependendo de diferentes entradas. Por exemplo, em um jogo, se o número de vidas do jogador é 0, então o jogo acaba. Em um aplicativo de clima, se estiver sendo observado pela manhã, ele mostra um gráfico do nascer do sol; Mostra estrelas e uma lua se for noite. Neste artigo, exploraremos como as chamadas declarações condicionais funcionam em JavaScript.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos:</th> + <td>Conhecimento básico de algoritmos, um entendimento básico de HTML e CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript </a>primeiros passos.</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Entender como usar estruturas condicionais em JavaScript.</td> + </tr> + </tbody> +</table> + +<h2 id="Você_pode_tê-lo_em_uma_condição_...!">Você pode tê-lo em uma condição ...!</h2> + +<p>Seres humanos (e outros animais) tomam decisões o tempo todo que afetam suas vidas, desde pequenas ("devo comer um biscoito ou dois?") até grandes ("devo ficar no meu país de origem e trabalhar na fazenda do meu pai ou devo mudar para a América e estudar astrofísica?").</p> + +<p>As declarações condicionais nos permitem representar tomadas de decisão como estas em <em>JavaScript</em>, a partir da escolha que deve ser feita (por exemplo, "um biscoito ou dois"), ao resultado obtido dessas escolhas (talvez o resultado de "comer um biscoito" possa ser "ainda sentido fome ", e o resultado de "comer dois biscoitos" pode ser "ter se sentido cheio, mas mamãe me falou para comer todos os biscoitos".)</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13703/cookie-choice-small.png" style="display: block; margin: 0 auto;"></p> + +<h2 id="Declarações_if_..._else">Declarações if ... else</h2> + +<p>De longe o tipo mais comum de declaração condicional que você usará em JavaScript — as modestas declarações <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else">if ... else</a></code>.</p> + +<h3 id="Sintaxe_básica_if_..._else">Sintaxe básica if ... else</h3> + +<p>Veja a sintaxe básica do <code>if...else</code> no {{glossary("pseudocódigo")}}:</p> + +<pre class="notranslate"><strong>if (</strong><em>condicao</em><strong>) {</strong> + <em>codigo para executar caso a condição seja verdadeira</em> +<strong>} else {</strong> + <em>senão, executar este código</em> +<strong>}</strong></pre> + +<p>Aqui nós temos:</p> + +<ol> + <li>A palavra reservada <code>if</code> seguida de um par de parênteses.</li> + <li>Um teste condicional, localizado dentro dos parênteses (normalmente "este valor é maior que esse", ou "este valor existe"). Esta condição pode fazer uso dos <a href="/en-US/Learn/JavaScript/First_steps/Math#Comparison_operators">operadores de comparação</a> que discutimos no último módulo, e podem retornar <code>true</code> ou <code>false</code>.</li> + <li>Um par de chaves, e dentro dele temos código — pode ser qualquer código que queiramos, e só vai ser executado se o teste condicional retornar <code>true</code>.</li> + <li>A palavra reservada <code>else</code>.</li> + <li>Outro par de chaves, dentro dele temos mais um pouco de código — pode ser qualquer código que queiramos, e só vai executar se o teste condicional retornar um valor diferente de <code>true</code>, neste caso <code>not true, </code>ou <code>false</code>. </li> +</ol> + +<p>Este tipo de código é bem legível por seres humanos — ele diz: "<strong>if</strong> a condição for <code>true</code>, execute o bloco de código A, <strong>else</strong> execute o bloco de código B" (<strong>se</strong> a condição for <strong>verdadeira</strong>, execute o bloco de código A, <strong>senão</strong> execute o bloco de código B).</p> + +<p>Você precisa saber que não é obrigado a colocar a palavra reservada <code>else</code> e e o segundo bloco de par de chaves. O código apresentado a seguir é perfeitamente válido e não produz erros:</p> + +<pre class="notranslate"><strong>if (</strong>condicao<strong>) {</strong> + codigo para executar se a condição for verdadeira +<strong>}</strong> + +código a ser executado</pre> + +<p>Entretanto, você precisa ser cauteloso aqui — neste caso, repare que o segundo bloco de código não é controlado pela declaração condicional, então ele vai executar <strong>sempre</strong>, independente do teste condicional retornar <code>true</code> ou <code>false</code>. É claro, isto não é necessariamente uma coisa ruim, mas isso pode não ser o que você quer — com muita frequência você vai querer executar ou um bloco de código ou outro, não os dois juntos.</p> + +<p>Por fim, você verá muitas vezes declarações <code>if...else</code> escritas sem as chaves, no seguinte estilo de escrita:</p> + +<pre class="notranslate">if (condicao) executar aqui se for verdadeira +else executar este outro codigo</pre> + +<p>Este é um código perfeitamente válido, mas não é recomendado — ele facilita que você escreva código fora do escopo do <code>if</code> e do <code>else</code>, o que seria mais difícil se você estivesse usando as chaves para delimitar os blocos de código, e usando multiplas linhas de código e identação.</p> + +<h3 id="Um_exemplo_real">Um exemplo real</h3> + +<p>Para entender bem a sintaxe, vamos considerar um exemplo real. Imagine um filhote de humanos sendo chamdo a ajudar com as tarefas do Pai ou da Mãe. Os pais podem falar: "Ei querido, se você me ajudar a ir e fazer as compras, eu te dou uma grana extra para que você possa comprar aquele brinquedo que você quer." Em JavaScript, nós podemos representar isso como:</p> + +<p>var comprasFeitas = false;</p> + +<p>if (comprasFeitas === true) {<br> + var granaFilhote = 10;<br> + } else {<br> + var granaFilhote = 5;<br> + }</p> + +<p>Esse código como mostrado irá sempre resultar na variável <code>comprasFeitas</code> retornando <code>false</code>, sendo um desapontamento para nossas pobres crianças. Cabe a nós fornecer um mecanismo para o pai definir a variável <code>comprasFeitas</code> como <code>true</code> se o filho fez as compras.</p> + +<div class="note"> +<p><strong>Nota</strong>: Você pode ver a versão completa desse exemplo no <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/allowance-updater.html">GitHub</a> (também veja <a href="http://mdn.github.io/learning-area/javascript/building-blocks/allowance-updater.html">live</a>.)</p> +</div> + +<h3 id="else_if">else if</h3> + +<p dir="ltr" id="tw-target-text">O último exemplo nos forneceu duas opções ou resultados - mas e se quisermos mais do que dois?</p> + +<p dir="ltr">Existe uma maneira de encadear escolhas/resultados extras ao seu <code>if...else</code> — usando <code>else if</code>. Cada escolha extra requer um bloco adicional para colocar entre <code>if() { ... }</code> e <code>else { ... }</code> — confira o seguinte exemplo mais envolvido, que pode fazer parte de um aplicativo simples de previsão do tempo:</p> + +<pre class="brush: html notranslate"><label for="weather">Select the weather type today: </label> +<select id="weather"> + <option value="">--Make a choice--</option> + <option value="sunny">Sunny</option> + <option value="rainy">Rainy</option> + <option value="snowing">Snowing</option> + <option value="overcast">Overcast</option> +</select> + +<p></p></pre> + +<pre class="brush: js notranslate">var select = document.querySelector('select'); +var para = document.querySelector('p'); + +select.addEventListener('change', setWeather); + +function setWeather() { + var choice = select.value; + + if (choice === 'sunny') { + para.textContent = 'It is nice and sunny outside today. Wear shorts! Go to the beach, or the park, and get an ice cream.'; + } else if (choice === 'rainy') { + para.textContent = 'Rain is falling outside; take a rain coat and a brolly, and don\'t stay out for too long.'; + } else if (choice === 'snowing') { + para.textContent = 'The snow is coming down — it is freezing! Best to stay in with a cup of hot chocolate, or go build a snowman.'; + } else if (choice === 'overcast') { + para.textContent = 'It isn\'t raining, but the sky is grey and gloomy; it could turn any minute, so take a rain coat just in case.'; + } else { + para.textContent = ''; + } +} + +</pre> + +<p>{{ EmbedLiveSample('else_if', '100%', 100) }}</p> + +<ol> + <li>Aqui, temos um elemento HTML {{htmlelement("select")}} que nos permite fazer escolhas de clima diferentes e um simples parágrafo.</li> + <li>No JavaScript, estamos armazenando uma referência para ambos os elementos {{htmlelement("select")}} e {{htmlelement("p")}}, e adicionando um listener de evento ao elemento <code><select></code> para que, quando o valor for alterado, a função <code>setWeather()</code> é executada.</li> + <li>Quando esta função é executada, primeiro definimos uma variável chamada <code>choice</code> para o valor atual selecionado no elemento <code><select></code>. Em seguida, usamos uma instrução condicional para mostrar um texto diferente dentro do parágrafo, dependendo de qual é o valor de <code>choice</code> . Observe como todas as condições são testadas nos blocos <code>else if() {...}</code>, com exceção do primeiro, que é testado em um bloco <code>if() {...}</code>.</li> + <li>A última escolha, dentro do bloco <code>else {...}</code>, é basicamente uma opção de "último recurso" — o código dentro dele será executado se nenhuma das condições for <code>true</code>. Nesse caso, ele serve para esvaziar o texto do parágrafo, se nada for selecionado, por exemplo, se um usuário decidir selecionar novamente a opção de espaço reservado "- Make a choice--" mostrada no início.</li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>: Você pode também <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/simple-else-if.html">encontrar este exemplo no GitHub</a> (<a href="http://mdn.github.io/learning-area/javascript/building-blocks/simple-else-if.html">veja ele sendo executado</a> lá também.)</p> +</div> + +<h3 id="Uma_nota_sobre_os_operadores_de_comparação">Uma nota sobre os operadores de comparação</h3> + +<p>Operadores de comparação são usados para testar as condições dentro de nossas declarações condicionais. Nós primeiro olhamos para operadores de comparação de volta em nosso artigo <a href="/en-US/Learn/JavaScript/First_steps/Math#Comparison_operators">Matemática básica em JavaScript - números e operadores</a>. Nossas escolhas são:</p> + +<ul> + <li><code>===</code> e <code>!==</code> — testar se um valor é idêntico ou não idêntico a outro.</li> + <li><code><</code> e <code>></code> — teste se um valor é menor ou maior que outro.</li> + <li><code><=</code> e <code>>=</code> — testar se um valor é menor ou igual a, ou maior que ou igual a outro.</li> +</ul> + +<div class="note"> +<p><strong>Nota</strong>: Revise o material no link anterior se quiser atualizar suas memórias sobre eles.</p> +</div> + +<p>Queríamos fazer uma menção especial do teste de valores boolean (<code>true</code>/<code>false</code>) , e um padrão comum que você vai encontrar de novo e de novo. Qualquer valor que não seja <code>false</code>, <code>undefined</code>, <code>null</code>, <code>0</code>, <code>NaN</code>, ou uma string vazia (<code>''</code>) retorna <code>true</code> quando testado como uma instrução condicional, portanto, você pode simplesmente usar um nome de variável para testar se é verdadeiro , ou mesmo que existe (ou seja, não é indefinido). Por exemplo:</p> + +<pre class="brush: js notranslate">var cheese = 'Cheddar'; + +if (cheese) { + console.log('Yay! Cheese available for making cheese on toast.'); +} else { + console.log('No cheese on toast for you today.'); +}</pre> + +<p>E, voltando ao nosso exemplo anterior sobre a criança fazendo uma tarefa para seu pai, você poderia escrevê-lo assim:</p> + +<pre class="brush: js notranslate">var shoppingDone = false; + +if (shoppingDone) { // don't need to explicitly specify '=== true' + var childsAllowance = 10; +} else { + var childsAllowance = 5; +}</pre> + +<h3 id="Aninhando_if_..._else">Aninhando if ... else</h3> + +<p>É perfeitamente correto colocar uma declaração <code>if...else</code> dentro de outra — para aninhá-las. Por exemplo, poderíamos atualizar nosso aplicativo de previsão do tempo para mostrar mais opções dependendo de qual é a temperatura:</p> + +<pre class="brush: js notranslate">if (choice === 'sunny') { + if (temperature < 86) { + para.textContent = 'It is ' + temperature + ' degrees outside — nice and sunny. Let\'s go out to the beach, or the park, and get an ice cream.'; + } else if (temperature >= 86) { + para.textContent = 'It is ' + temperature + ' degrees outside — REALLY HOT! If you want to go outside, make sure to put some suncream on.'; + } +}</pre> + +<p>Mesmo que o código trabalhe em conjunto, cada uma das instruções <code>if...else</code> funcionam completamente independente uma da outra.</p> + +<h3 id="Operadores_lógicos_AND_OR_e_NOT">Operadores lógicos: AND, OR e NOT</h3> + +<p>Se você quiser testar várias condições sem escrever instruções aninhadas <code>if...else</code>, os <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators">operadores lógicos</a> poderão ajudá-lo. Quando usado em condições, os dois primeiros fazem o seguinte:</p> + +<ul> + <li><code>&&</code> — AND; permite encadear duas ou mais expressões para que todas elas tenham que ser avaliadas individualmente como <code>true</code> assim toda a expressão retorna <code>true</code>.</li> + <li><code>||</code> — OR; permite encadear duas ou mais expressões para que uma ou mais delas tenham que ser avaliadas individualmente como <code>true</code> assim toda a expressão retorna <code>true</code>.</li> +</ul> + +<p>Para fornecer um exemplo AND, o fragmento de exemplo anterior pode ser reescrito assim:</p> + +<pre class="brush: js notranslate">if (choice === 'sunny' && temperature < 86) { + para.textContent = 'It is ' + temperature + ' degrees outside — nice and sunny. Let\'s go out to the beach, or the park, and get an ice cream.'; +} else if (choice === 'sunny' && temperature >= 86) { + para.textContent = 'It is ' + temperature + ' degrees outside — REALLY HOT! If you want to go outside, make sure to put some suncream on.'; +}</pre> + +<p>Então, por exemplo, o primeiro bloco de código só será executado se ambas as condições <code>choice === 'sunny'</code> <em>e </em><code>temperature < 86</code> retornarem <code>true</code>.</p> + +<p>Vamos ver um exemplo rápido de OR:</p> + +<pre class="brush: js notranslate">if (iceCreamVanOutside || houseStatus === 'on fire') { + console.log('You should leave the house quickly.'); +} else { + console.log('Probably should just stay in then.'); +}</pre> + +<p>O último tipo de operador lógico, NOT, expressado pelo operador <code>!</code>, pode ser usado para negar uma expressão. Vamos combiná-lo com OR no exemplo acima:</p> + +<pre class="brush: js notranslate">if (!(iceCreamVanOutside || houseStatus === 'on fire')) { + console.log('Probably should just stay in then.'); +} else { + console.log('You should leave the house quickly.'); +}</pre> + +<p>Nesse trecho, se a instrução OR retornar <code>true</code>, o operador NOT negará isso para que a expressão geral retorne <code>false</code>.</p> + +<p>Você pode combinar tantas instruções lógicas quanto quiser, em qualquer estrutura. O exemplo a seguir executa o código interno apenas se ambos os conjuntos de instruções OR retornarem true, significando que a instrução AND global também retornará true:</p> + +<pre class="brush: js notranslate">if ((x === 5 || y > 3 || z <= 10) && (loggedIn || userName === 'Steve')) { + // run the code +}</pre> + +<p>Um erro comum ao usar o operador OR lógico em instruções condicionais é tentar indicar a variável cujo valor você está verificando uma vez e, em seguida, fornecer uma lista de valores que poderia ser para retornar true, separados pelos operadores <code>||</code> (OR) . Por exemplo:</p> + +<pre class="example-bad brush: js notranslate">if (x === 5 || 7 || 10 || 20) { + // run my code +}</pre> + +<p>Nesse caso, a condição dentro de <code>if(...)</code> sempre será avaliada como verdadeira, já que 7 (ou qualquer outro valor diferente de zero) sempre é avaliado como verdadeiro. Esta condição está realmente dizendo "se x é igual a 5, ou 7 é verdade — o que sempre é". Isso logicamente não é o que queremos! Para fazer isso funcionar, você precisa especificar um teste completo ao lado de cada operador OR:</p> + +<pre class="brush: js notranslate">if (x === 5 || x === 7 || x === 10 ||x === 20) { + // run my code +}</pre> + +<h2 id="Instruções_switch">Instruções switch</h2> + +<p>As instruções <code>if...else</code> fazem o trabalho de habilitar o código condicional bem, mas elas também possuem suas desvantagens. Elas são boas principalmente para casos em que você tem algumas opções, e cada uma requer uma quantidade razoável de código para ser executado, e / ou as condições são complexas (por exemplo, vários operadores lógicos). Nos casos em que você deseja definir uma variável para uma determinada opção de valor ou imprimir uma determinada instrução dependendo de uma condição, a sintaxe pode ser um pouco incômoda, especialmente se você tiver um grande número de opções.</p> + +<p>As <a href="/en-US/docs/Web/JavaScript/Reference/Statements/switch">instruções<code>switch</code></a> são suas amigas aqui — elas tomam uma única expressão / valor como uma entrada e, em seguida, examinam várias opções até encontrarem um que corresponda a esse valor, executando o código correspondente que o acompanha. Aqui está mais um pseudocódigo, para você ter uma ideia:</p> + +<pre class="notranslate">switch (expression) { + case choice1: + run this code + break; + + case choice2: + run this code instead + break; + + // include as many cases as you like + + default: + actually, just run this code +}</pre> + +<p>Aqui nós temos:</p> + +<ol> + <li>A palavra-chave <code>switch</code>, seguido por um par de parênteses.</li> + <li>Uma expressão ou valor dentro dos parênteses.</li> + <li>A palavra-chave <code>case</code>, seguido por uma escolha que a expressão / valor poderia ser, seguido por dois pontos.</li> + <li>Algum código para ser executado se a escolha corresponder à expressão.</li> + <li>Uma instrução <code>break</code>, seguido de um ponto e vírgula. Se a opção anterior corresponder à expressão / valor, o navegador interromperá a execução do bloco de código aqui e passará para qualquer código que aparecer abaixo da instrução switch.</li> + <li>Como muitos outros casos (marcadores 3 a 5) que você quiser.</li> + <li>A palavra-chave <code>default</code>, seguido por exatamente o mesmo padrão de código de um dos casos (marcadores 3 a 5), exceto que o <code>default</code> não tem escolha após ele, e você não precisa da instrução <code>break</code>, pois não há nada para executar depois disso o bloco de qualquer maneira. Esta é a opção padrão que é executada se nenhuma das opções corresponder.</li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>: Você não precisa incluir a seção <code>default</code> — você pode omiti-la com segurança se não houver chance de que a expressão possa se igualar a um valor desconhecido. Se houver uma chance disso, você precisará incluí-lo para lidar com casos desconhecidos.</p> +</div> + +<h3 id="Um_exemplo_de_switch">Um exemplo de switch</h3> + +<p>Vamos dar uma olhada em um exemplo real — vamos reescrever nosso aplicativo de previsão do tempo para usar uma instrução switch:</p> + +<pre class="brush: html notranslate"><label for="weather">Select the weather type today: </label> +<select id="weather"> + <option value="">--Make a choice--</option> + <option value="sunny">Sunny</option> + <option value="rainy">Rainy</option> + <option value="snowing">Snowing</option> + <option value="overcast">Overcast</option> +</select> + +<p></p></pre> + +<pre class="brush: js notranslate">var select = document.querySelector('select'); +var para = document.querySelector('p'); + +select.addEventListener('change', setWeather); + + +function setWeather() { + var choice = select.value; + + switch (choice) { + case 'sunny': + para.textContent = 'It is nice and sunny outside today. Wear shorts! Go to the beach, or the park, and get an ice cream.'; + break; + case 'rainy': + para.textContent = 'Rain is falling outside; take a rain coat and a brolly, and don\'t stay out for too long.'; + break; + case 'snowing': + para.textContent = 'The snow is coming down — it is freezing! Best to stay in with a cup of hot chocolate, or go build a snowman.'; + break; + case 'overcast': + para.textContent = 'It isn\'t raining, but the sky is grey and gloomy; it could turn any minute, so take a rain coat just in case.'; + break; + default: + para.textContent = ''; + } +}</pre> + +<p>{{ EmbedLiveSample('A_switch_example', '100%', 100, "", "", "hide-codepen-jsfiddle") }}</p> + +<div class="note"> +<p><strong>Nota</strong>: Você pode <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/simple-switch.html">encontrar este exemplo no GitHub</a> (veja-o em <a href="http://mdn.github.io/learning-area/javascript/building-blocks/simple-switch.html">execução </a>lá também.)</p> +</div> + +<h2 id="Operador_ternário">Operador ternário</h2> + +<p>Há um bit final de sintaxe que queremos apresentar a você antes de começar a brincar com alguns exemplos. O <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator">operador ternário ou condicional</a> é um pequeno bit de sintaxe que testa uma condição e retorna um valor / expressão se for <code>true</code>, e outro caso seja <code>false</code> — isso pode ser útil em algumas situações e pode ocupar muito menos código que um bloco <code>if...else</code> se você simplesmente tiver duas opções escolhidas entre uma condição <code>true</code>/<code>false</code> condition. O pseudocódigo é assim:</p> + +<pre class="notranslate">( condition ) ? run this code : run this code instead</pre> + +<p>Então, vamos dar uma olhada em um exemplo simples:</p> + +<pre class="brush: js notranslate">var greeting = ( isBirthday ) ? 'Happy birthday Mrs. Smith — we hope you have a great day!' : 'Good morning Mrs. Smith.';</pre> + +<p>Aqui temos uma variável chamada <code>isBirthday</code> — se ela for <code>true</code>, nós damos ao nosso convidado uma mensagem de feliz aniversário; se não, damos a ela a saudação diária padrão.</p> + +<h3 id="Exemplo_de_operador_ternário">Exemplo de operador ternário</h3> + +<p>Você não precisa apenas definir valores de variáveis com o operador ternário; Você também pode executar funções ou linhas de código - qualquer coisa que você gosta. O exemplo ao vivo a seguir mostra um seletor de temas simples em que o estilo do site é aplicado usando um operador ternário.</p> + +<pre class="brush: html notranslate"><label for="theme">Select theme: </label> +<select id="theme"> + <option value="white">White</option> + <option value="black">Black</option> +</select> + +<h1>This is my website</h1></pre> + +<pre class="brush: js notranslate">var select = document.querySelector('select'); +var html = document.querySelector('html'); +document.body.style.padding = '10px'; + +function update(bgColor, textColor) { + html.style.backgroundColor = bgColor; + html.style.color = textColor; +} + +select.onchange = function() { + ( select.value === 'black' ) ? update('black','white') : update('white','black'); +} +</pre> + +<p>{{ EmbedLiveSample('Ternary_operator_example', '100%', 300) }}</p> + +<p>Aqui nós temos um elemento {{htmlelement('select')}} para escolher um tema (preto ou branco), além de um simples {{htmlelement('h1')}} para exibir um título do site. Nós também temos uma função chamada <code>update()</code>, que leva duas cores como parâmetros (entradas). A cor do plano de fundo do site é definida para a primeira cor fornecida e sua cor de texto é definida para a segunda cor fornecida.</p> + +<p>Finalmente, nós também temos um evento listener <a href="/en-US/docs/Web/API/GlobalEventHandlers/onchange">onchange</a> que serve para executar uma função que contém um operador ternário. Começa com uma condição de teste — <code>select.value === 'black'</code>. Se este retornar <code>true</code>, nós executamos a função <code>update()</code> com parâmetros de preto e branco, o que significa que acabamos com a cor de fundo do preto e cor do texto de branco. Se retornar <code>false</code>, nós executamos a função <code>update()</code> com parâmetros de branco e preto, o que significa que a cor do site está invertida.</p> + +<div class="note"> +<p><strong>Nota</strong>: Você pode também <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/simple-ternary.html">encontrar este exemplo no GitHub</a> (veja-o <a href="http://mdn.github.io/learning-area/javascript/building-blocks/simple-ternary.html">executando</a> lá também.)</p> +</div> + +<h2 id="Aprendizado_ativo_um_calendário_simples">Aprendizado ativo: um calendário simples</h2> + +<p>Neste exemplo, você nos ajudará a concluir um aplicativo de calendário simples. No código que você tem:</p> + +<ul> + <li>Um elemento {{htmlelement("select")}} para permitir que o usuário escolha entre diferentes meses.</li> + <li>Um evento manipulador <code>onchange</code> para detectar quando o valor selecionado no menu <code><select></code> é mudado.</li> + <li>Uma função chamada <code>createCalendar()</code> que desenha o calendário e exibe o mês correto no elemento {{htmlelement("h1")}} .</li> +</ul> + +<p>Precisamos que você escreva uma instrução condicional dentro da função do manipulador onchange, logo abaixo do comentário <code>// ADD CONDITIONAL HERE</code>. Ele deve:</p> + +<ol> + <li>Olhar para o mês selecionado (armazenado na variavel <code>choice</code>. Este será o valor do elemento <code><select></code> após o valor ser alterado, portanto, "Janeiro", por exemplo.</li> + <li>Definir uma variável chamada <code>days</code> para ser igual ao número de dias no mês selecionado. Para fazer isso, você terá que procurar o número de dias em cada mês do ano. Você pode ignorar anos bissextos para os propósitos deste exemplo.</li> +</ol> + +<p>Dicas:</p> + +<ul> + <li>É aconselhável usar o OR lógico para agrupar vários meses em uma única condição; muitos deles compartilham o mesmo número de dias.</li> + <li>Pense em qual número de dias é o mais comum e use isso como um valor padrão.</li> +</ul> + +<p>Se você cometer um erro, você sempre pode redefinir o exemplo com o botão "Reset". Se você ficar realmente preso, pressione "Mostrar solução" para ver uma solução.</p> + +<div class="hidden"> +<h6 id="Playable_code">Playable code</h6> + +<pre class="brush: html notranslate"><div class="output" style="height: 500px;overflow: auto;"> + <label for="month">Select month: </label> + <select id="month"> + <option value="January">January</option> + <option value="February">February</option> + <option value="March">March</option> + <option value="April">April</option> + <option value="May">May</option> + <option value="June">June</option> + <option value="July">July</option> + <option value="August">August</option> + <option value="September">September</option> + <option value="October">October</option> + <option value="November">November</option> + <option value="December">December</option> + </select> + + <h1></h1> + + <ul></ul> +</div> + +<hr> + +<textarea id="code" class="playable-code" style="height: 500px;"> +var select = document.querySelector('select'); +var list = document.querySelector('ul'); +var h1 = document.querySelector('h1'); + +select.onchange = function() { + var choice = select.value; + + // ADD CONDITIONAL HERE + + createCalendar(days, choice); +} + +function createCalendar(days, choice) { + list.innerHTML = ''; + h1.textContent = choice; + for (var i = 1; i <= days; i++) { + var listItem = document.createElement('li'); + listItem.textContent = i; + list.appendChild(listItem); + } +} + +createCalendar(31,'January'); +</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<pre class="brush: css notranslate">.output * { + box-sizing: border-box; +} + +.output ul { + padding-left: 0; +} + +.output li { + display: block; + float: left; + width: 25%; + border: 2px solid white; + padding: 5px; + height: 40px; + background-color: #4A2DB6; + color: white; +} +</pre> + +<pre class="brush: js notranslate">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + updateCode(); +}); + +solution.addEventListener('click', function() { + textarea.value = jsSolution; + updateCode(); +}); + +var jsSolution = 'var select = document.querySelector(\'select\');\nvar list = document.querySelector(\'ul\');\nvar h1 = document.querySelector(\'h1\');\n\nselect.onchange = function() {\n var choice = select.value;\n var days = 31;\n if(choice === \'February\') {\n days = 28;\n } else if(choice === \'April\' || choice === \'June\' || choice === \'September\'|| choice === \'November\') {\n days = 30;\n }\n\n createCalendar(days, choice);\n}\n\nfunction createCalendar(days, choice) {\n list.innerHTML = \'\';\n h1.textContent = choice;\n for(var i = 1; i <= days; i++) {\n var listItem = document.createElement(\'li\');\n listItem.textContent = i;\n list.appendChild(listItem);\n }\n }\n\ncreateCalendar(31,\'January\');'; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); +</pre> +</div> + +<p>{{ EmbedLiveSample('Playable_code', '100%', 1110) }}</p> + +<h2 id="Aprendizado_ativo_mais_opções_de_cores!">Aprendizado ativo: mais opções de cores!</h2> + +<p>Neste exemplo, você terá o exemplo de operador ternário que vimos anteriormente e converterá o operador ternário em uma instrução switch que nos permitirá aplicar mais opções ao site simples. Olhe para a {{htmlelement("select")}} — desta vez você verá que não tem duas opções de tema, mas cinco. Você precisa adicionar uma instrução switch abaixo do comentário <code>// ADD SWITCH STATEMENT</code>:</p> + +<ul> + <li>Ele deve aceitar a variável <code>choice</code> como sua expressão de entrada.</li> + <li>Para cada caso, a escolha deve ser igual a um dos valores possíveis que podem ser selecionados, ou seja, branco, preto, roxo, amarelo ou psicodélico.</li> + <li>Para cada caso, a função <code>update()</code> deve ser executada e receber dois valores de cor, o primeiro para a cor de segundo plano e o segundo para a cor do texto. Lembre-se de que valores de cores são strings, portanto, precisam ser agrupados entre aspas.</li> +</ul> + +<p>Se você cometer um erro, você sempre pode redefinir o exemplo com o botão "Reset". Se você ficar realmente travado, pressione "Show solution" para ver uma solução.</p> + +<div class="hidden"> +<h6 id="Playable_code_2">Playable code 2</h6> + +<pre class="brush: html notranslate"><div class="output" style="height: 300px;"> + <label for="theme">Select theme: </label> + <select id="theme"> + <option value="white">White</option> + <option value="black">Black</option> + <option value="purple">Purple</option> + <option value="yellow">Yellow</option> + <option value="psychedelic">Psychedelic</option> + </select> + + <h1>This is my website</h1> +</div> + +<hr> + +<textarea id="code" class="playable-code" style="height: 450px;"> +var select = document.querySelector('select'); +var html = document.querySelector('.output'); + +select.onchange = function() { + var choice = select.value; + + // ADD SWITCH STATEMENT +} + +function update(bgColor, textColor) { + html.style.backgroundColor = bgColor; + html.style.color = textColor; +}</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<pre class="brush: js notranslate">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + updateCode(); +}); + +solution.addEventListener('click', function() { + textarea.value = jsSolution; + updateCode(); +}); + +var jsSolution = 'var select = document.querySelector(\'select\');\nvar html = document.querySelector(\'.output\');\n\nselect.onchange = function() {\n var choice = select.value;\n\n switch(choice) {\n case \'black\':\n update(\'black\',\'white\');\n break;\n case \'white\':\n update(\'white\',\'black\');\n break;\n case \'purple\':\n update(\'purple\',\'white\');\n break;\n case \'yellow\':\n update(\'yellow\',\'darkgray\');\n break;\n case \'psychedelic\':\n update(\'lime\',\'purple\');\n break;\n }\n}\n\nfunction update(bgColor, textColor) {\n html.style.backgroundColor = bgColor;\n html.style.color = textColor;\n}'; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); +</pre> +</div> + +<p>{{ EmbedLiveSample('Playable_code_2', '100%', 850) }}</p> + +<h2 id="Conclusão">Conclusão</h2> + +<p>E isso é tudo que você realmente precisa saber sobre estruturas condicionais no JavaScript por agora! Tenho certeza que você terá entendido esses conceitos e trabalhou com os exemplos com facilidade; se houver algo que você não tenha entendido, sinta-se à vontade para ler o artigo novamente ou <a href="/en-US/Learn#Contact_us">contate-nos</a> para pedir ajuda.</p> + +<h2 id="Veja_também">Veja também</h2> + +<ul> + <li><a href="/en-US/Learn/JavaScript/First_steps/Math#Comparison_operators">Operadores de comparação</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Conditional_statements">Declarações condicionais em detalhes</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else">Referência if...else</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator">Referência do operador condicional (ternário)</a></li> +</ul> + +<h2 id="Teste_suas_habilidades!">Teste suas habilidades!</h2> + +<p>Você chegou ao final deste artigo, mas você consegue se lembrar das informações mais importantes? Você pode encontrar mais alguns testes para verificar se reteve essas informações antes de prosseguir — Veja <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Test_your_skills:_Conditionals">Teste suas habilidades: Condicionais</a>.</p> + +<p>{{NextMenu("Learn/JavaScript/Building_blocks/Looping_code", "Learn/JavaScript/Building_blocks")}}</p> diff --git a/files/pt-br/learn/javascript/building_blocks/events/index.html b/files/pt-br/learn/javascript/building_blocks/events/index.html new file mode 100644 index 0000000000..dd6e41f674 --- /dev/null +++ b/files/pt-br/learn/javascript/building_blocks/events/index.html @@ -0,0 +1,582 @@ +--- +title: Introdução a eventos +slug: Aprender/JavaScript/Elementos_construtivos/Events +tags: + - Aprender + - Artigo + - Guía + - Iniciante + - JavaScript + - Programando + - eventos +translation_of: Learn/JavaScript/Building_blocks/Events +--- +<div> +<div>{{LearnSidebar}}</div> +</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">Eventos são ações ou ocorrências que acontecem no sistema que estamos desenvolvendo, no qual este te alerta sobre essas ações para que você possa responder de alguma forma, se desejado. Por exemplo, se o usuário clica em um botão numa pagina web, você pode querer responder a esta ação mostrando na tela uma caixa de informações. Nesse artigo, nós iremos discutir sobre alguns conceitos importantes envolvendo eventos, e veremos como eles funcionam nos browsers. Isto não será algo cansativo para estudar; somente o que você precisar saber até agora.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos:</th> + <td>Conhecimentos básicos em informática, conhecimento básico em HTML e CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript, primeiros passos</a>.</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Entender a teoria fundamentos dos eventos, como eles funcionam nos browsers, e como eventos podem ser diferentes dependendo do ambiente de desenvolvimento.</td> + </tr> + </tbody> +</table> + +<h2 id="Aventuras_em_Série">Aventuras em Série</h2> + +<p>Como mencionado acima, <strong>eventos </strong>são ações ou ocorrências que acontecem no sistema que estamos desenvolvendo — o sistema irá disparar algum tipo de sinal quando o evento acontecer, além de prover um mecanismo pelo qual alguma ação automática possa ser executada (ou seja, rodar algum código) quando o evento ocorrer. Por exemplo, em um aeroporto, quando a pista está livre para um avião decolar, um sinal é repassado ao piloto, e como resultado, ele inicia a decolagem.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14077/MDN-mozilla-events-runway.png" style="display: block; margin: 0px auto;"></p> + +<p>No caso da web, eventos são disparados dentro da janela do navegador, e tende a estarem anexados a algum item especifico nele — pode ser um único elemento, um conjunto de elementos, o HTML carregado na guia atual, ou toda a janela do navegador. Existem vários tipos diferentes de eventos que podem vir a acontecer, por exemplo:</p> + +<ul> + <li>O usuário clicando com o mouse sobre um certo elemento ou passando o cursor do mouse sobre um certo elemento.</li> + <li>O usuário pressionando uma tecla do teclado.</li> + <li>O usuário redimensionando ou fechando a janela do navegador.</li> + <li>Uma pagina da web terminando de carregar.</li> + <li>Um formulário sendo enviado.</li> + <li>Um video sendo reproduzido, interrompido, ou terminando sua reprodução.</li> + <li>Um erro ocorrendo.</li> +</ul> + +<p>Você vai perceber com isso (e dando uma olhada no <a href="/en-US/docs/Web/Events">Event reference</a> MDN) que<strong> </strong>há uma <strong>série</strong> de eventos que podem ser utilizados.</p> + +<p>Cada evento disponivel possui um <strong>manipulador de eventos </strong>(event handler), que é um bloco de código (geralmente uma função JavaScript definida pelo usuário) que será executado quando o evento for disparado. Quando esse bloco de código é definido para rodar em resposta a um evento que foi disparado, nós dizemos que estamos <strong>registrando um manipulador de eventos</strong>. Note que manipuladores de eventos são, em alguns casos, chamados de <strong>ouvinte de eventos </strong>(event listeners) — <span id="result_box" lang="pt"><span>eles são praticamente intercambiáveis para nossos propósitos, embora estritamente falando, eles trabalhem juntos. Os ouvintes escutam o evento acontecendo, e o manipulador é o codigo que roda em resposta a este acontecimento.</span></span></p> + +<div class="note"> +<p><strong>Nota</strong>: É importante notar que eventos web não são parte do core da linguagem JavaScript — elas são definidas como parte das APIs JavaScript incorporadas ao navegador.</p> +</div> + +<h3 id="Um_exemplo_simples">Um exemplo simples</h3> + +<p>Vamos dar uma olhada em um simples exemplo para explicar o que nós queremos dizer aqui. Você já viu eventos e manipuladores de eventos sendo utilizados na maioria dos exemplos deste curso até agora, mas vamos recapitular somente para cimentar nosso conhecimento. No exemplo a seguir, nós temos um simples {{htmlelement("button")}} que quando pressionado, irá fazer com que o fundo mude para uma cor aleatória:</p> + +<pre class="brush: html"><button>Change color</button></pre> + +<div class="hidden"> +<pre class="brush: css">button { margin: 10px };</pre> +</div> + +<p>O JavaScript seria algo como:</p> + +<pre class="brush: js">var btn = document.querySelector('button'); + +function random(number) { + return Math.floor(Math.random()*(number+1)); +} + +btn.onclick = function() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +}</pre> + +<p>Nesse código, nós guardamos uma referência ao botão dentro de uma variável chamada <code>btn</code>, usando a função {{domxref("Document.querySelector()")}}. Também definimos uma função que retorna um número aleatório. A terceira parte do código é o manipulador de eventos. A variável <code>btn</code> aponta para um elemento <code><button></code>, e esse tipo de objeto tem um número de eventos que podem ser disparados nele, assim sendo, manipuladores de eventos estão disponíveis.</p> + +<p>Esse código rodará sempre que o evento de clique for disparado pelo elemento <code><button></code>, isto é, sempre que um usuário clicar nele.</p> + +<p>Um exemplo de saída seria:</p> + +<p>{{ EmbedLiveSample('A_simple_example', '100%', 200, "", "", "hide-codepen-jsfiddle") }}</p> + +<h3 id="Não_são_apenas_paginas_da_web">Não são apenas paginas da web</h3> + +<p>Outra coisa que vale mencionar a esse ponto é que eventos não são exclusivos ao JavaScript — muitas linguagens de programação possuem algum tipo de modelo de evento, e a maneira que elas funcionam irão, frequentemente, diferenciar-se da maneira que funciona em JavaScript. De fato, o modelo de evento no JavaScript para web pages difere dos outros modelos de evento do próprio JavaScript quando usados em outros ambientes.</p> + +<p>Por exemplo, <a href="/en-US/docs/Learn/Server-side/Express_Nodejs">Node.js</a> é um interpretador de código JavaScript muito popular que permite desenvolvedores a usarem JavaScript para construir aplicações de rede e do lado do servidor. O <a href="https://nodejs.org/docs/latest-v5.x/api/events.html">Node.js event model</a> depende dos ouvintes para escutar eventos e emissores para emitir eventos periodicamente. — não parece tão diferente, mas o código é bem diferente, fazendo uso de funções como <code>on()</code> para registrar um ouvinte de evento e <code>once()</code> para registrar um ouvinte de evento que cancela o registro depois de ter sido executado uma vez. Os <a href="https://nodejs.org/docs/latest-v8.x/api/http.html#http_event_connect">Documentos do evento de conexão HTTP</a> fornecem um bom exemplo de uso.</p> + +<p>Como outro exemplo, agora você também pode usar o JavaScript para criar complementos entre navegadores — aprimoramentos da funcionalidade do navegador — usando uma tecnologia chamada <a href="/en-US/docs/Mozilla/Add-ons/WebExtensions">WebExtensions</a>. O modelo de eventos é semelhante ao modelo de eventos da Web, mas um pouco diferente — as propriedades dos event listeners são camel-cased, onde cada palavra é iniciada com maiúsculas e unidas sem espaços (por exemplo, <code>onMessage</code> em vez de <code>onmessage</code>), e precisam ser combinadas com a função <code>addListener</code>. Veja a página <a href="/en-US/Add-ons/WebExtensions/API/runtime/onMessage#Examples">runtime.onMessage</a> para um exemplo.</p> + +<p>Você não precisa entender nada sobre outros ambientes nesse estágio do aprendizado; nós só queríamos deixar claro que os eventos podem diferir em diferentes ambientes de programação.</p> + +<h2 id="Formas_de_usar_eventos_da_web">Formas de usar eventos da web</h2> + +<p>Há várias maneiras diferentes de adicionar código de ouvinte de evento a páginas da Web para que ele seja executado quando o evento associado for disparado. Nesta seção, revisaremos os diferentes mecanismos e discutiremos quais devem ser usados.</p> + +<h3 id="Propriedades_do_manipulador_de_eventos">Propriedades do manipulador de eventos</h3> + +<p>Essas são as propriedades que existem para conter o código do manipulador de eventos que vimos com mais frequência durante o curso. Voltando ao exemplo acima:</p> + +<pre class="brush: js">var btn = document.querySelector('button'); + +btn.onclick = function() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +}</pre> + +<p>A propriedade <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onclick">onclick</a></code> é a propriedade do manipulador de eventos que está sendo usada nesta situação. É essencialmente uma propriedade como qualquer outra disponível no botão (por exemplo, <code><a href="/en-US/docs/Web/API/Node/textContent">btn.textContent</a></code>, ou <code><a href="/en-US/docs/Web/API/HTMLElement/style">btn.style</a></code>), mas é um tipo especial — quando você configura para ser igual a algum código, esse código será executado quando o evento é acionado no botão.</p> + +<p>Você também pode definir a propriedade handler para ser igual a um nome de função nomeado (como vimos em <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Construa sua própria função</a>). O seguinte funcionaria da mesma forma:</p> + +<pre class="brush: js">var btn = document.querySelector('button'); + +function bgChange() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +} + +btn.onclick = bgChange;</pre> + +<p>Há muitas propriedades diferentes de manipulador de eventos disponíveis. Vamos fazer um experimento.</p> + +<p>Primeiro de tudo, faça uma cópia local do <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventhandlerproperty.html">random-color-eventhandlerproperty.html</a>, e abra-o no seu navegador. É apenas uma cópia do exemplo de cor aleatória simples com o qual já estamos jogando neste artigo. Agora tente alterar <code>btn.onclick</code> para os seguintes valores diferentes, por sua vez, e observando os resultados no exemplo:</p> + +<ul> + <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onfocus">btn.onfocus</a></code> e <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onblur">btn.onblur</a></code> — A cor mudará quando o botão estiver focado e fora de foco (tente pressionar a guia para aba no botão e desligar novamente). Eles geralmente são usados para exibir informações sobre como preencher campos de formulário quando eles estão focalizados ou exibir uma mensagem de erro se um campo de formulário tiver acabado de ser preenchido com um valor incorreto.</li> + <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/ondblclick">btn.ondblclick</a></code> — A cor só será alterada quando for clicada duas vezes.</li> + <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeypress">window.onkeypress</a></code>, <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeydown">window.onkeydown</a></code>, <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onkeyup">window.onkeyup</a></code> — A cor mudará quando uma tecla for pressionada no teclado. <code>keypress</code> refere-se a um pressionamento geral (botão para baixo e depois para cima), enquanto <code>keydown</code> e <code>keyup</code> refere-se apenas a parte do pressionamento da tecla para baixo e de soltar a tecla para cima, respectivamente. Note que não funciona se você tentar registrar este manipulador de eventos no próprio botão — nós tivemos que registrá-lo no objeto <a href="/en-US/docs/Web/API/Window">window</a>, que representa toda a janela do navegador.</li> + <li><code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onmouseover">btn.onmouseover</a></code> e <code><a href="/en-US/docs/Web/API/GlobalEventHandlers/onmouseout">btn.onmouseout</a></code> — A cor mudará quando o ponteiro do mouse for movido, de modo que comece a passar o mouse sobre o botão, ou quando parar de passar o mouse sobre o botão e sair dele, respectivamente.</li> +</ul> + +<p>Alguns eventos são muito gerais e estão disponíveis praticamente em qualquer lugar (por exemplo, um manipulador <code>onclick</code> pode ser registrado em quase qualquer elemento), enquanto alguns são mais específicos e úteis apenas em certas situações (por exemplo, faz sentido usar <a href="/en-US/docs/Web/API/GlobalEventHandlers/GlobalEventHandlers.onplay">onplay</a> apenas em elementos específicos, como {{htmlelement("video")}}).</p> + +<h3 id="Manipuladores_de_eventos_in-line_-_não_use_esses">Manipuladores de eventos in-line - não use esses</h3> + +<p>Você também pode ver um padrão como este em seu código:</p> + +<pre class="brush: html"><button onclick="bgChange()">Press me</button> +</pre> + +<pre class="brush: js">function bgChange() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +}</pre> + +<div class="note"> +<p><strong>Nota</strong>: Você pode encontrar o <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventhandlerattributes.html">código fonte completo</a> para este exemplo no GitHub (também <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-eventhandlerattributes.html">veja isso executando em tempo real</a>).</p> +</div> + +<p>O método mais antigo de registrar manipuladores de eventos encontrados na Web envolveu <strong>atributos HTML de manipulador de eventos</strong> (também conhecidos como <strong>manipuladores de eventos inline</strong>) como o mostrado acima — o valor do atributo é literalmente o código JavaScript que você deseja executar quando o evento ocorre. O exemplo acima chama uma função definida dentro de um elemento {{htmlelement("script")}} na mesma página, mas você também pode inserir JavaScript diretamente dentro do atributo, por exemplo:</p> + +<pre class="brush: html"><button onclick="alert('Hello, this is my old-fashioned event handler!');">Press me</button></pre> + +<p>Você encontrará equivalentes de atributo HTML para muitas das propriedades do manipulador de eventos; no entanto, você não deve usá-los — eles são considerados uma prática ruim. Pode parecer fácil usar um atributo manipulador de eventos se você estiver apenas fazendo algo realmente rápido, mas eles se tornam rapidamente incontroláveis e ineficientes.</p> + +<p>Para começar, não é uma boa ideia misturar o seu HTML e o seu JavaScript, pois é difícil analisar — manter seu JavaScript em um só lugar é melhor; se estiver em um arquivo separado, você poderá aplicá-lo a vários documentos HTML.</p> + +<p>Mesmo em um único arquivo, os manipuladores de eventos in-line não são uma boa ideia. Um botão está OK, mas e se você tivesse 100 botões? Você teria que adicionar 100 atributos ao arquivo; isso rapidamente se tornaria um pesadelo de manutenção. Com JavaScript, você poderia facilmente adicionar uma função de manipulador de eventos a todos os botões da página, não importando quantos fossem, usando algo assim:</p> + +<pre class="brush: js">var buttons = document.querySelectorAll('button'); + +for (var i = 0; i < buttons.length; i++) { + buttons[i].onclick = bgChange; +}</pre> + +<div class="note"> +<p><strong>Nota</strong>: Separar sua lógica de programação do seu conteúdo também torna seu site mais amigável aos mecanismos de pesquisa.</p> +</div> + +<h3 id="addEventListener_e_removeEventListener">addEventListener() e removeEventListener()</h3> + +<p>O mais novo tipo de mecanismo de evento é definido na Especificação de Eventos Nível 2 do <a href="https://www.w3.org/TR/DOM-Level-2-Events/">Document Object Model (DOM)</a>, que fornece aos navegadores uma nova função — <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code>. Isso funciona de maneira semelhante às propriedades do manipulador de eventos, mas a sintaxe é obviamente diferente. Poderíamos reescrever nosso exemplo de cor aleatória para ficar assim:</p> + +<pre class="brush: js">var btn = document.querySelector('button'); + +function bgChange() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +} + +btn.addEventListener('click', bgChange);</pre> + +<div class="note"> +<p><strong>Nota</strong>: Você pode encontrar o <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-addeventlistener.html">código fonte completo</a> para este exemplo no GitHub (também <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-addeventlistener.html">veja isso executando em tempo real</a>).</p> +</div> + +<p>Dentro da função <code>addEventListener()</code>, especificamos dois parâmetros — o nome do evento para o qual queremos registrar esse manipulador, e o código que compreende a função do manipulador que queremos executar em resposta a ele. Note que é perfeitamente apropriado colocar todo o código dentro da função <code>addEventListener()</code>, em uma função anônima, assim:</p> + +<pre class="brush: js">btn.addEventListener('click', function() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + document.body.style.backgroundColor = rndCol; +});</pre> + +<p>Esse mecanismo tem algumas vantagens sobre os mecanismos mais antigos discutidos anteriormente. Para começar, há uma função de contraparte, <code><a href="/en-US/docs/Web/API/EventTarget/removeEventListener">removeEventListener()</a></code>, que remove um listener adicionado anteriormente. Por exemplo, isso removeria o listener definido no primeiro bloco de código nesta seção:</p> + +<pre class="brush: js">btn.removeEventListener('click', bgChange);</pre> + +<p>Isso não é significativo para programas pequenos e simples, mas para programas maiores e mais complexos, pode melhorar a eficiência para limpar antigos manipuladores de eventos não utilizados. Além disso, por exemplo, isso permite que você tenha o mesmo botão executando ações diferentes em circunstâncias diferentes — tudo o que você precisa fazer é adicionar / remover manipuladores de eventos conforme apropriado.</p> + +<p>Em segundo lugar, você também pode registrar vários manipuladores para o mesmo ouvinte. Os dois manipuladores a seguir não seriam aplicados:</p> + +<pre class="brush: js">myElement.onclick = functionA; +myElement.onclick = functionB;</pre> + +<p>Como a segunda linha sobrescreveria o valor de <code>onclick</code> definido pelo primeiro. Isso funcionaria, no entanto:</p> + +<pre class="brush: js">myElement.addEventListener('click', functionA); +myElement.addEventListener('click', functionB);</pre> + +<p>Ambas as funções serão executadas quando o elemento for clicado.</p> + +<p>Além disso, há vários outros recursos e opções poderosos disponíveis com esse mecanismo de eventos. Estes são um pouco fora do escopo deste artigo, mas se você quiser ler sobre eles, dê uma olhada nas páginas de referência <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code> e <code><a href="/en-US/docs/Web/API/EventTarget/removeEventListener">removeEventListener()</a></code>.</p> + +<h3 id="Qual_mecanismo_devo_usar">Qual mecanismo devo usar?</h3> + +<p>Dos três mecanismos, você definitivamente não deve usar os atributos do manipulador de eventos HTML — estas são desatualizadas e más práticas, como mencionado acima.</p> + +<p>Os outros dois são relativamente intercambiáveis, pelo menos para usos simples:</p> + +<ul> + <li>As propriedades do manipulador de eventos têm menos poder e opções, mas melhor compatibilidade entre navegadores (sendo suportado desde o Internet Explorer 8). Você provavelmente deve começar com estes como você está aprendendo.</li> + <li>Eventos DOM Nível 2 (<code>addEventListener()</code>, etc.) são mais poderosos, mas também podem se tornar mais complexos e menos bem suportados (suportados desde o Internet Explorer 9). Você também deve experimentá-los e tentar usá-los sempre que possível.</li> +</ul> + +<p>As principais vantagens do terceiro mecanismo são que você pode remover o código do manipulador de eventos, se necessário, usando <code>removeEventListener()</code>, e você pode adicionar vários listeners do mesmo tipo aos elementos, se necessário. Por exemplo, você pode chamar <code>addEventListener('click', function() { ... })</code> em um elemento várias vezes, com diferentes funções especificadas no segundo argumento. Isso é impossível com as propriedades do manipulador de eventos porque qualquer tentativa subseqüente de definir uma propriedade sobrescreverá as anteriores, por exemplo:</p> + +<pre class="brush: js">element.onclick = function1; +element.onclick = function2; +etc.</pre> + +<div class="note"> +<p><strong>Nota</strong>: Se você for chamado para oferecer suporte a navegadores anteriores ao Internet Explorer 8 em seu trabalho, poderá encontrar dificuldades, pois esses navegadores antigos usam modelos de eventos diferentes dos navegadores mais recentes. Mas não tenha medo, a maioria das bibliotecas JavaScript (por exemplo, <code>jQuery</code>) tem funções internas que abstraem as diferenças entre navegadores. Não se preocupe muito com isso neste estágio de sua jornada de aprendizado.</p> +</div> + +<h2 id="Outros_conceitos_de_evento">Outros conceitos de evento</h2> + +<p>Nesta seção, abordaremos brevemente alguns conceitos avançados que são relevantes para os eventos. Não é importante entendê-las totalmente neste momento, mas pode servir para explicar alguns padrões de código que você provavelmente encontrará ao longo do tempo.</p> + +<h3 id="Objetos_de_evento">Objetos de evento</h3> + +<p>Às vezes, dentro de uma função de manipulador de eventos, você pode ver um parâmetro especificado com um nome como <code>event</code>, <code>evt</code>, ou simplesmente <code>e</code>. Isso é chamado de <strong>event object</strong>, e é passado automaticamente para os manipuladores de eventos para fornecer recursos e informações extras. Por exemplo, vamos reescrever nosso exemplo de cor aleatória novamente:</p> + +<pre class="brush: js">function bgChange(e) { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + e.target.style.backgroundColor = rndCol; + console.log(e); +} + +btn.addEventListener('click', bgChange);</pre> + +<div class="note"> +<p><strong>Nota</strong>: Você pode encontrar o <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/random-color-eventobject.html">código fonte completo</a> para este exemplo no GitHub (também <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/random-color-eventobject.html">veja isso executando em tempo real</a>).</p> +</div> + +<p>Aqui você pode ver que estamos incluindo um objeto de evento, <strong>e</strong>, na função, e na função definindo um estilo de cor de fundo em <code>e.target</code> — que é o próprio botão. A propriedade <code>target</code> do objeto de evento é sempre uma referência ao elemento em que o evento acabou de ocorrer. Portanto, neste exemplo, estamos definindo uma cor de fundo aleatória no botão, não na página.</p> + +<div class="note"> +<p><strong>Note</strong>: Você pode usar qualquer nome que desejar para o objeto de evento — você só precisa escolher um nome que possa ser usado para referenciá-lo dentro da função de manipulador de eventos. <code>e</code>/<code>evt</code>/<code>event</code> são mais comumente usados pelos desenvolvedores porque são curtos e fáceis de lembrar. É sempre bom manter um padrão.</p> +</div> + +<p><code>e.target</code> é incrivelmente útil quando você deseja definir o mesmo manipulador de eventos em vários elementos e fazer algo com todos eles quando ocorre um evento neles. Você pode, por exemplo, ter um conjunto de 16 blocos que desaparecem quando são clicados. É útil poder sempre apenas definir a coisa para desaparecer como <code>e.target</code>, ao invés de ter que selecioná-lo de alguma forma mais difícil. No exemplo a seguir (veja <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/useful-eventtarget.html">useful-eventtarget.html</a> para o código-fonte completo; veja também a <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/useful-eventtarget.html">execução ao vivo</a> aqui), criamos 16 elementos {{htmlelement("div")}} usando JavaScript. Em seguida, selecionamos todos eles usando {{domxref("document.querySelectorAll()")}} e, em seguida, percorremos cada um deles, adicionando um manipulador onclick a cada um, de modo que uma cor aleatória seja aplicada a cada um deles quando clicados:</p> + +<pre class="brush: js">var divs = document.querySelectorAll('div'); + +for (var i = 0; i < divs.length; i++) { + divs[i].onclick = function(e) { + e.target.style.backgroundColor = bgChange(); + } +}</pre> + +<p>A saída é a seguinte (tente clicar em cima — divirta-se):</p> + +<div class="hidden"> +<h6 id="Hidden_example">Hidden example</h6> + +<pre class="brush: html"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Useful event target example</title> + <style> + div { + background-color: red; + height: 100px; + width: 25%; + float: left; + } + </style> + </head> + <body> + <script> + for (var i = 1; i <= 16; i++) { + var myDiv = document.createElement('div'); + document.body.appendChild(myDiv); + } + + function random(number) { + return Math.floor(Math.random()*number); + } + + function bgChange() { + var rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')'; + return rndCol; + } + + var divs = document.querySelectorAll('div'); + + for (var i = 0; i < divs.length; i++) { + divs[i].onclick = function(e) { + e.target.style.backgroundColor = bgChange(); + } + } + </script> + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_example', '100%', 400, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>A maioria dos manipuladores de eventos que você encontrará apenas tem um conjunto padrão de propriedades e funções (métodos) disponíveis no objeto de evento (consulte a referência de objeto {{domxref("Event")}} para obter uma lista completa). Alguns manipuladores mais avançados, no entanto, adicionam propriedades especializadas contendo dados extras que precisam para funcionar. A <a href="/en-US/docs/Web/API/MediaRecorder_API">Media Recorder API</a>, por exemplo, tem um evento <code>dataavailable</code> que é acionado quando algum áudio ou vídeo é gravado e está disponível para fazer algo com (por exemplo, salvá-lo ou reproduzi-lo). O objeto de evento do manipulador correspondente <a href="/en-US/docs/Web/API/MediaRecorder/ondataavailable">ondataavailable</a> tem uma propriedade de dados disponível contendo os dados de áudio ou vídeo gravados para permitir que você acesse e faça algo com ele.</p> + +<h3 id="Evitando_o_comportamento_padrão">Evitando o comportamento padrão</h3> + +<p>Às vezes, você se deparará com uma situação em que deseja interromper um evento fazendo o que ele faz por padrão. O exemplo mais comum é o de um formulário da Web, por exemplo, um formulário de registro personalizado. Quando você preenche os detalhes e pressiona o botão Enviar, o comportamento natural é que os dados sejam enviados para uma página específica no servidor para processamento, e o navegador seja redirecionado para uma página de "mensagem de sucesso" de algum tipo (ou a mesma página, se outra não for especificada.)</p> + +<p>O problema surge quando o usuário não submete os dados corretamente - como desenvolvedor, você deve interromper o envio para o servidor e fornecer uma mensagem de erro informando o que está errado e o que precisa ser feito para corrigir as coisas. Alguns navegadores suportam recursos automáticos de validação de dados de formulário, mas como muitos não oferecem isso, é recomendável não depender deles e implementar suas próprias verificações de validação. Vamos dar uma olhada em um exemplo simples.</p> + +<p>Primeiro, um formulário HTML simples que requer que você digite seu primeiro e último nome:</p> + +<pre class="brush: html"><form> + <div> + <label for="fname">First name: </label> + <input id="fname" type="text"> + </div> + <div> + <label for="lname">Last name: </label> + <input id="lname" type="text"> + </div> + <div> + <input id="submit" type="submit"> + </div> +</form> +<p></p></pre> + +<div class="hidden"> +<pre class="brush: css">div { + margin-bottom: 10px; +} +</pre> +</div> + +<p>Agora algum JavaScript — aqui nós implementamos uma verificação muito simples dentro de um manipulador de evento onsubmit (o evento submit é disparado em um formulário quando é enviado) que testa se os campos de texto estão vazios. Se estiverem, chamamos a função <code><a href="/en-US/docs/Web/API/Event/preventDefault">preventDefault()</a></code> no objeto de evento — que interrompe o envio do formulário — e, em seguida, exibir uma mensagem de erro no parágrafo abaixo do nosso formulário para informar ao usuário o que está errado:</p> + +<pre class="brush: js">var form = document.querySelector('form'); +var fname = document.getElementById('fname'); +var lname = document.getElementById('lname'); +var submit = document.getElementById('submit'); +var para = document.querySelector('p'); + +form.onsubmit = function(e) { + if (fname.value === '' || lname.value === '') { + e.preventDefault(); + para.textContent = 'You need to fill in both names!'; + } +}</pre> + +<p>Obviamente, isso é uma validação de forma bastante fraca — ela não impediria o usuário de validar o formulário com espaços ou números inseridos nos campos, por exemplo — mas está tudo bem, por exemplo. A saída é a seguinte:</p> + +<p>{{ EmbedLiveSample('Preventing_default_behavior', '100%', 140, "", "", "hide-codepen-jsfiddle") }}</p> + +<div class="note"> +<p><strong>Nota</strong>: para o código fonte completo, veja <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/preventdefault-validation.html">preventdefault-validation.html</a> (também veja isso <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/preventdefault-validation.html">executando em tempo real</a> aqui.)</p> +</div> + +<h3 id="Borbulhamento_e_captura_de_eventos">Borbulhamento e captura de eventos</h3> + +<p>O assunto final a ser abordado aqui é algo que você não encontrará com frequência, mas pode ser uma dor real se você não entender. Borbulhamento e captura de eventos são dois mecanismos que descrevem o que acontece quando dois manipuladores do mesmo tipo de evento são ativados em um elemento. Vamos dar uma olhada em um exemplo para facilitar isso — abra o exemplo show-video-box.html em uma nova guia (e o <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box.html">código-fonte</a> em outra guia). Ele também está disponível ao vivo abaixo:</p> + +<div class="hidden"> +<h6 id="Hidden_video_example">Hidden video example</h6> + +<pre class="brush: html"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Show video box example</title> + <style> + div { + position: absolute; + top: 50%; + transform: translate(-50%,-50%); + width: 480px; + height: 380px; + border-radius: 10px; + background-color: #eee; + background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,0.1)); + } + + .hidden { + left: -50%; + } + + .showing { + left: 50%; + } + + div video { + display: block; + width: 400px; + margin: 40px auto; + } + + </style> + </head> + <body> + <button>Display video</button> + + <div class="hidden"> + <video> + <source src="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/events/rabbit320.mp4" type="video/mp4"> + <source src="https://raw.githubusercontent.com/mdn/learning-area/master/javascript/building-blocks/events/rabbit320.webm" type="video/webm"> + <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p> + </video> + </div> + + <script> + + var btn = document.querySelector('button'); + var videoBox = document.querySelector('div'); + var video = document.querySelector('video'); + + btn.onclick = function() { + displayVideo(); + } + + function displayVideo() { + if(videoBox.getAttribute('class') === 'hidden') { + videoBox.setAttribute('class','showing'); + } + } + + videoBox.addEventListener('click',function() { + videoBox.setAttribute('class','hidden'); + }); + + video.addEventListener('click',function() { + video.play(); + }); + + </script> + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_video_example', '100%', 500, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>Este é um exemplo bastante simples que mostra e oculta um {{htmlelement("div")}} com um elemento {{htmlelement("video")}} dentro dele:</p> + +<pre class="brush: html"><button>Display video</button> + +<div class="hidden"> + <video> + <source src="rabbit320.mp4" type="video/mp4"> + <source src="rabbit320.webm" type="video/webm"> + <p>Your browser doesn't support HTML5 video. Here is a <a href="rabbit320.mp4">link to the video</a> instead.</p> + </video> +</div></pre> + +<p>Quando o {{htmlelement("button")}} é clicado, o vídeo é exibido, alterando o atributo de classe em <code><div></code> de <code>hidden</code> para <code>showing</code> (o CSS do exemplo contém essas duas classes, que posicione a caixa fora da tela e na tela, respectivamente):</p> + +<pre class="brush: js">btn.onclick = function() { + videoBox.setAttribute('class', 'showing'); +}</pre> + +<p>Em seguida, adicionamos mais alguns manipuladores de eventos <code>onclick</code> — o primeiro ao <code><div></code> e o segundo ao <code><video></code>. A ideia é que, quando a área do <code><div></code> fora do vídeo for clicada, a caixa deve ser ocultada novamente; quando o vídeo em si é clicado, o vídeo deve começar a tocar.</p> + +<pre>videoBox.onclick = function() { + videoBox.setAttribute('class', 'hidden'); +}; + +video.onclick = function() { + video.play(); +};</pre> + +<p>Mas há um problema — atualmente, quando você clica no vídeo, ele começa a ser reproduzido, mas faz com que o <code><div></code> também fique oculto ao mesmo tempo. Isso ocorre porque o vídeo está dentro do <code><div></code> — é parte dele — portanto, clicar no vídeo realmente executa os dois manipuladores de eventos acima.</p> + +<h4 id="Borbulhando_e_capturando_explicados">Borbulhando e capturando explicados</h4> + +<p>Quando um evento é acionado em um elemento que possui elementos pai (por exemplo, o {{htmlelement("video")}} no nosso caso), os navegadores modernos executam duas fases diferentes — a fase de <strong>captura </strong>e a fase de <strong>bubbling</strong>.</p> + +<p>Na fase de <strong>captura</strong>:</p> + +<ul> + <li>O navegador verifica se o ancestral mais externo do elemento ({{htmlelement("html")}}) tem um manipulador de eventos <code>onclick</code> registrado nele na fase de captura e o executa em caso afirmativo.</li> + <li>Em seguida, ele passa para o próximo elemento dentro de <code><html></code> e faz a mesma coisa, depois o próximo, e assim por diante até alcançar o elemento que foi realmente clicado.</li> +</ul> + +<p>Na fase de <strong>bubbling</strong>, ocorre exatamente o oposto:</p> + +<ul> + <li>O navegador verifica se o elemento que realmente foi clicado tem um manipulador de eventos <code>onclick</code> registrado nele na fase de bubbling e o executa em caso afirmativo.</li> + <li>Em seguida, ele passa para o próximo elemento ancestral imediato e faz a mesma coisa, depois o próximo, e assim por diante, até alcançar o elemento <code><html></code>.</li> +</ul> + +<p><a href="https://mdn.mozillademos.org/files/14075/bubbling-capturing.png"><img alt="" src="https://mdn.mozillademos.org/files/14075/bubbling-capturing.png" style="display: block; height: 452px; margin: 0px auto; width: 960px;"></a></p> + +<p>(Clique na imagem para um diagrama maior)</p> + +<p>Nos navegadores modernos, por padrão, todos os manipuladores de eventos são registrados na fase de bubbling. Portanto, em nosso exemplo atual, quando você clica no vídeo, o evento de clique passa do elemento <code><video></code> para o elemento <code><html></code> Pelo caminho:</p> + +<ul> + <li>Ele encontra o manipulador <code>video.onclick...</code> e o executa, então o vídeo começa a ser reproduzido pela primeira vez.</li> + <li>Em seguida, ele encontra o manipulador <code>videoBox.onclick...</code> e o executa, então o vídeo também está oculto.</li> +</ul> + +<h4 id="Corrigindo_o_problema_com_stopPropagation">Corrigindo o problema com stopPropagation()</h4> + +<p>Este é um comportamento irritante, mas existe uma maneira de corrigir isso! O objeto de evento padrão tem uma função disponível chamada <code><a href="/en-US/docs/Web/API/Event/stopPropagation">stopPropagation()</a></code>, que quando invocada no objeto de evento de um manipulador, faz com que o manipulador seja executado, mas o evento não borbulha mais acima na cadeia, portanto, mais nenhum manipulador rodará.</p> + +<p>Podemos, portanto, consertar nosso problema atual alterando a segunda função do manipulador no bloco de códigos anterior para isto:</p> + +<pre class="brush: js">video.onclick = function(e) { + e.stopPropagation(); + video.play(); +};</pre> + +<p>Você pode tentar fazer uma cópia local do código-fonte <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box.html">show-video-box.html source code</a> e tentar corrigi-lo sozinho, ou observar o resultado corrigido em <a href="http://mdn.github.io/learning-area/javascript/building-blocks/events/show-video-box-fixed.html">show-video-box-fixed.html</a> (veja também o <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/events/show-video-box-fixed.html">código-fonte</a> aqui).</p> + +<div class="note"> +<p><strong>Nota</strong>: Por que se preocupar em capturar e borbulhar? Bem, nos velhos tempos em que os navegadores eram muito menos compatíveis entre si do que são agora, o Netscape usava apenas captura de eventos, e o Internet Explorer usava apenas borbulhamento de eventos. Quando o W3C decidiu tentar padronizar o comportamento e chegar a um consenso, eles acabaram com esse sistema que incluía ambos, que é o único navegador moderno implementado.</p> +</div> + +<div class="note"> +<p><strong>Note</strong>: Como mencionado acima, por padrão, todos os manipuladores de eventos são registrados na fase de bubbling, e isso faz mais sentido na maioria das vezes. Se você realmente quiser registrar um evento na fase de captura, registre seu manipulador usando <code><a href="/en-US/docs/Web/API/EventTarget/addEventListener">addEventListener()</a></code>, e defina a propriedade terceira opcional como <code>true</code>.</p> +</div> + +<h4 id="Delegação_de_eventos">Delegação de eventos</h4> + +<p>O borbulhar também nos permite aproveitar a <strong>delegação de eventos</strong> — esse conceito depende do fato de que, se você quiser que algum código seja executado quando clicar em qualquer um de um grande número de elementos filho, você pode definir o ouvinte de evento em seu pai e ter os eventos que acontecem neles confluem com o pai, em vez de precisar definir o ouvinte de evento em cada filho individualmente.</p> + +<p>Um bom exemplo é uma série de itens de lista — Se você quiser que cada um deles apareça uma mensagem quando clicado, você pode definir o ouvinte de evento <code>click</code> no pai <code><ul></code>, e ele irá aparecer nos itens da lista.</p> + +<p>Este conceito é explicado mais adiante no blog de David Walsh, com vários exemplos — veja <a href="https://davidwalsh.name/event-delegate">Como funciona a delegação de eventos em JavaScript.</a></p> + +<h2 id="Conclusão">Conclusão</h2> + +<p>Agora você deve saber tudo o que precisa saber sobre os eventos da Web nesse estágio inicial. Como mencionado acima, os eventos não são realmente parte do núcleo do JavaScript — eles são definidos nas APIs da Web do navegador.</p> + +<p>Além disso, é importante entender que os diferentes contextos nos quais o JavaScript é usado tendem a ter diferentes modelos de evento — de APIs da Web a outras áreas, como WebExtensions de navegador e Node.js (JavaScript do lado do servidor). Não esperamos que você entenda todas essas áreas agora, mas certamente ajuda a entender os fundamentos dos eventos à medida que você avança no aprendizado do desenvolvimento da web.</p> + +<p>Se houver algo que você não entendeu, fique à vontade para ler o artigo novamente, ou <a href="/en-US/Learn#Contact_us">entre em contato conosco</a> para pedir ajuda.</p> + +<h2 id="Veja_também">Veja também</h2> + +<ul> + <li><a href="http://www.quirksmode.org/js/events_order.html">Event order</a> (discussion of capturing and bubbling) — an excellently detailed piece by Peter-Paul Koch.</li> + <li><a href="http://www.quirksmode.org/js/events_access.html">Event accessing</a> (discussion of the event object) — another excellently detailed piece by Peter-Paul Koch.</li> + <li><a href="/en-US/docs/Web/Events">Event reference</a></li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Return_values","Learn/JavaScript/Building_blocks/Image_gallery", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/building_blocks/functions/index.html b/files/pt-br/learn/javascript/building_blocks/functions/index.html new file mode 100644 index 0000000000..05e9ffcfea --- /dev/null +++ b/files/pt-br/learn/javascript/building_blocks/functions/index.html @@ -0,0 +1,394 @@ +--- +title: Funções — blocos reutilizáveis de código +slug: Aprender/JavaScript/Elementos_construtivos/Functions +translation_of: Learn/JavaScript/Building_blocks/Functions +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}</div> + +<p>Outro conceito essencial em código é função, que permitem que você armazene um pedaço de código que realiza uma simples tarefa dentro de um bloco, e então chama aquele código sempre que você precisar usá-lo com um curto comando — em vez de ter que escrever o mesmo código multiplas vezes. Neste artigo nós vamos explorar conceitos fundamentais por trás das funções como sintaxe básica, como invocá-las e defini-las, escopo, e parâmetros.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisitos:</th> + <td>Infrmática básica, um entendimento básico de HTML e CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">Primeiros passos em JavaScript</a>.</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Entender conceitos fundamentais por trás das funções em JavaScript.</td> + </tr> + </tbody> +</table> + +<h2 id="Onde_eu_encontro_funções">Onde eu encontro funções?</h2> + +<p>Em JavaScript, você encontrará funções em todos os lugares, de fato, nós vamos usar funções ao longo de todo o curso; nós só não falaremos sobre elas em damasia. Agora está na hora, contudo, para falarmos sobre funções explicitamente, e realmente explorar sua sintaxe.</p> + +<div id="gt-res-content"> +<div class="trans-verified-button-large" dir="ltr" id="gt-res-dir-ctr"><span class="short_text" id="result_box" lang="pt"><span>Praticamente sempre que você faz uso de um</span></span> uma estrutura JavaScript em que tem um par de parenteses — <code>()</code> — e você <strong>não</strong> está usando uma estrutura embutida da linguagem como um <a href="/en-US/Learn/JavaScript/Building_blocks/Looping_code#The_standard_for_loop">for loop</a>, <a href="/en-US/Learn/JavaScript/Building_blocks/Looping_code#while_and_do_..._while">while or do...while loop</a>, ou <a href="/en-US/Learn/JavaScript/Building_blocks/conditionals#if_..._else_statements">if...else statement</a>, você está fazendo uso de uma função.</div> +</div> + +<h2 id="Funções_embutidas_do_navegador">Funções embutidas do navegador</h2> + +<p>Nós fizemos bastante uso de funções embutidas do navegador neste curso. Toda vez que manipulamos uma string de texto, por exemplo:</p> + +<pre class="brush: js">var myText = 'I am a string'; +var newString = myText.replace('string', 'sausage'); +console.log(newString); +// the replace() string function takes a string, +// replaces one substring with another, and returns +// a new string with the replacement made</pre> + +<p>Ou toda vez que manipulamos uma lista:</p> + +<pre class="brush: js">var myArray = ['I', 'love', 'chocolate', 'frogs']; +var madeAString = myArray.join(' '); +console.log(madeAString); +// the join() function takes an array, joins +// all the array items together into a single +// string, and returns this new string</pre> + +<p>Ou toda vez que nós geramos um número aleatório:</p> + +<pre class="brush: js">var myNumber = Math.random(); +// the random() function generates a random +// number between 0 and 1, and returns that +// number</pre> + +<p>...nós usamos uma função!</p> + +<div class="note"> +<p><strong>Nota</strong>: Fique a vontade para inserir essas linhas no console JavaScript do navegador para refamiliarizar-se com suas funcionalidades, se necessário.</p> +</div> + +<p>A linguagem JavaScript tem muitas funções embutidas que o permitem fazer coisas úteis sem que você mesmo tenha que escrever aquele código. De fato, alguns dos códigos que você está chamando quando você <strong>invoca</strong> (uma palavra rebuscada para rodar, ou executar) uma função embutida de navegador não poderia ser escrita em JavaScript — muitas dessa funções são chamadas a partes de código base do navegador, que é escrita grandemente em linguages de<span class="short_text" id="result_box" lang="pt"><span> sistema de baixo nível</span></span> como C++, não linguagem Web como JavaScript.</p> + +<p>Tenha em mente que algumas funções embutidas de navegador não são parte do core da linguagem JavaScript — algumas são definidas como partes de APIs do navegador, que são construídas no topo da linguagem padão para prover ainda mais funcionalidades (recorra a <a href="/en-US/Learn/JavaScript/First_steps/What_is_JavaScript#So_what_can_it_really_do">esta seção inicial de nosso curso</a> para mais descrições). Nós olharemos o uso de APIs de navegador em mais detalhes em um módulo posterior.</p> + +<h2 id="Funções_versus_métodos">Funções versus métodos</h2> + +<p>Uma coisas que devemos esclarecer antes de seguir em frente — tecnicamente falando, funções embutidas de navegador não são funções — elas são <strong>métodos</strong>. Isso pode soar um pouco assustador e confuso, mas não se preocupe — as palavras funções e métodos são largamente intercambeáveis, ao menos para nossos propósitos, neste estágio de nosso aprendizado.</p> + +<p>A distinção é que métodos são funções definidas dentro de objetos. Funções embutidas de navegador (métodos) e variáveis (que são chamadas <strong>propriedades</strong>) são armazenadas dentro de objetos estruturados, para tornar o código mais estruturado e fácil de manipular.</p> + +<p>Você não precisa aprender sobre o<span class="short_text" id="result_box" lang="pt"><span> funcionamento interno</span></span> de objetos estruturados em JavaScript ainda — você pode esperar nosso módulo posterior que ensinará tudo sobre <span class="short_text" id="result_box" lang="pt"><span>funcionamento interno</span></span> de objetos, e como criar o seu próprio. Por hora, nós só queremos esclarecer qualquer confusão possível de método versus função — é pr<span class="short_text" id="result_box" lang="pt"><span>ovável que você encontre ambos</span></span> termos enquanto você olhar os recursos disponível pela Web.</p> + +<h2 id="Funções_personalizadas">Funções personalizadas</h2> + +<p>Nós vimos também várias funções personalizadas no curso até agora — funções definidas em seu código, não dentro do navegador. Sempre que você viu um nome personalizado com parênteses logo após ele, você estava usando funções personalizadas. em nosso exemplo <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/random-canvas-circles.html">random-canvas-circles.html</a> (veja também o <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/random-canvas-circles.html">código fonte</a> completo) de nosso <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">loops article</a>, nós incluimos a função personalizada <code>draw()</code> que era semelhante a essa:</p> + +<pre class="brush: js">function draw() { + ctx.clearRect(0,0,WIDTH,HEIGHT); + for (var i = 0; i < 100; i++) { + ctx.beginPath(); + ctx.fillStyle = 'rgba(255,0,0,0.5)'; + ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); + ctx.fill(); + } +}</pre> + +<p>Esta função desenha 100 círculos aleatórios dentro de um elemento {{htmlelement("canvas")}}. Toda vez que queremos fazer isso, nós podemos simplesmente invocar a função com isto</p> + +<pre class="brush: js">draw();</pre> + +<p>ao invés de ter que escrever todo o código novamente todas as vezes que queremos repetí-lo. <span class="short_text" id="result_box" lang="pt"><span>E funções podem conter qualquer código que você gosta</span></span> — você pode até chamar outra função dentro das funções. A função acima por exemplo chama a função <code>random()</code> três vezes, o qual é definido pelo seguinte código:</p> + +<pre class="brush: js">function random(number) { + return Math.floor(Math.random()*number); +}</pre> + +<p>Nós precisamos desta função porque a função embutida do navegador<a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a> só gera números decimais aleatórios entre 0 e 1. Nós queriamos um número aleatório inteiro entre 0 e um número especificado.</p> + +<h2 id="Invocando_funções">Invocando funções</h2> + +<p>Provavelmente você já tem conhecimento sobre iso agora, mas... para realmente usar uma função depois dela ter sido definida, você tem que rodá-la — ou invocá-la. Isso é feito ao se incluir o nome da função em algum lugar do código, seguido por parênteses.</p> + +<pre class="brush: js">function myFunction() { + alert('hello'); +} + +myFunction() +// Chama a função um vez</pre> + +<h2 id="Funções_anônimas">Funções anônimas</h2> + +<p>Você viu funções definidas e invocadas de maneiras ligeiramente diferentes. Até agora nós só criamos funções como esta:</p> + +<pre class="brush: js">function myFunction() { + alert('hello'); +}</pre> + +<p>Mas você também pode criar funções que não tem nome:</p> + +<pre class="brush: js">function() { + alert('hello'); +}</pre> + +<p>Isto é chamado<strong> Função anônima</strong> — não tem nome! E também não fará nada em si mesma. Você geralmente cria funções anônimas junto com um<span class="short_text" id="result_box" lang="pt"><span> manipulador de eventos</span></span>, o exemplo a seguir poderia rodar o código dentro da função sempre que o botão associado é clicado:</p> + +<pre class="brush: js">var myButton = document.querySelector('button'); + +myButton.onclick = function() { + alert('hello'); +}</pre> + +<p>O exemplo acima requer que exista um elemento {{htmlelement("button")}} diponível na página para selecionar e clicar. Você já viu essa estrutura algumas vezes ao longo do curso, e aprenderá mais a respeito disso e o verá no próximo artigo.</p> + +<p>Voce também pode atribuir uma função anônima para ser o valor de uma variável, por exemplo:</p> + +<pre class="brush: js">var myGreeting = function() { + alert('hello'); +}</pre> + +<p>Esta função agora poder ser invocada usando:</p> + +<pre class="brush: js">myGreeting();</pre> + +<p>Isso dá efetivamente um nome a função; você também pode atribuir uma função para ser o valor de múltiplas variáveis , por exemplo:</p> + +<pre class="brush: js">var anotherGreeting = function() { + alert('hello'); +}</pre> + +<p>Esta função agora pode ser invocada usando qualquer das funções abaixo</p> + +<pre class="brush: js">myGreeting(); +anotherGreeting();</pre> + +<p>Mas isso pode simplesmente ser confuso, então não faça! Quando criar funções, é melhor ficar com apenas uma forma:</p> + +<pre class="brush: js">function myGreeting() { + alert('hello'); +}</pre> + +<p>De modo geral você irá usar funções anônimas só para rodar um código em resposta a um disparo de evento — como um botão ao ser clicado — usando um gerenciador de eventos. Novamente, Isso é algo parecido com:</p> + +<pre class="brush: js">myButton.onclick = function() { + alert('hello'); + // Eu posso colocar código aqui + // dentro o quanto eu quiser +}</pre> + +<h2 id="Parâmetro_de_funções">Parâmetro de funções</h2> + +<p>Algumas funções requerem <strong>parâmetros</strong> <span class="short_text" id="result_box" lang="pt"><span>a ser especificado quando você está invocando-os</span></span> — esses são valores que precisam ser inclusos dentro dos parênteses da função, o que é necessário para fazer seu trabalho apropriado.</p> + +<div class="note"> +<p><strong>Nota</strong>: Parâmetros algumas vezes são chamados de argumentos, propriedades, ou até atributos.</p> +</div> + +<p>Como um exemplo, a função embutida de navegador <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random">Math.random()</a> não requer nenhum parâmetro. Quando chamada, ela sempre retorna um número aleatório entre 0 e 1:</p> + +<pre class="brush: js">var myNumber = Math.random();</pre> + +<p>A função embutida de navegador <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a> entretanto precisa de dois parâmetros — a substring para encotrar a string principal, e a substring para ser substituida com ela:</p> + +<pre class="brush: js">var myText = 'I am a string'; +var newString = myText.replace('string', 'sausage');</pre> + +<div class="note"> +<p><strong>Nota</strong>: Quando você precisa especificar multiplos parâmetros, eles são separados por vígulas.</p> +</div> + +<p>Nota-se também que algumas vezes os parâmetros são opcionais — você não tem que especificá-los. Se você não o faz, a função geralmente adota algum tipo de comportamento padrão. Como exemplo, a função <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join">join()</a> tem parâmetro opcional:</p> + +<pre class="brush: js">var myArray = ['I', 'love', 'chocolate', 'frogs']; +var madeAString = myArray.join(' '); +// returns 'I love chocolate frogs' +var madeAString = myArray.join(); +// returns 'I,love,chocolate,frogs'</pre> + +<p>Se nenhum parâmetro é incluído para especificar a combinação/delimitação de caractere, uma vírgula é usada por padrão.</p> + +<h2 id="Função_escopo_e_conflitos">Função escopo e conflitos</h2> + +<p>vamos falar um pouco sobre {{glossary("scope")}} — um conceito muito importante quando lidamos com funções. Quando você cria uma função, as variáveis e outras coisas definidas dentro da função ficam dentro de seu próprio e separado <strong>escopo</strong>, significando que eles estão trancados a parte em seu próprio compartimento, inacesível de dentro de outras funções ou de código fora das funções.</p> + +<p>O mais alto nível fora de todas suas funções é chamado de <strong>escopo global</strong>. Valores definidos no escopo global são acessíveis em todo lugar do código.</p> + +<p>JavaScript é configurado assim por várias razões — mas principalmente por segurança e organização. Algumas vezes você não quer que variáveis sejam acessadas de todo lugar no código — scripts externos que você chama de algum outro lugar podem iniciar uma bagunça no seu código e causar problemas porque eles estão usando os mesmos nomes de variáveis que em outras partes do código, provocando conflitos. Isso pode ser feito maliciosamente, ou só por acidente.</p> + +<p>Por exemplo, digamos que você tem um arquivo HTML que está chamando dois arquivos JavaScript externos, e ambos tem uma variável e uma função definidos que usam o mesmo nome:</p> + +<pre class="brush: html"><!-- Excerpt from my HTML --> +<script src="first.js"></script> +<script src="second.js"></script> +<script> + greeting(); +</script></pre> + +<pre class="brush: js">// first.js +var name = 'Chris'; +function greeting() { + alert('Olá ' + name + ': bem-vindo a nossa compania.'); +}</pre> + +<pre class="brush: js">// second.js +var name = 'Zaptec'; +function greeting() { + alert('Nossa compania é chamada ' + name + '.'); +}</pre> + +<p>Ambas as funções que você quer chamar são chamadas <code>greeting()</code>, mas você só pode acessar o arquivo <code>second.js</code> da função <code>greeting()</code> — Ele é aplicado no HTML depois no código fonte, então suas variáveis e funções sobrescrevem as de <code>first.js</code>.</p> + +<div class="note"> +<p><strong>Nota</strong>: Você pode ver este exemplo <a href="http://mdn.github.io/learning-area/javascript/building-blocks/functions/conflict.html">rodando no GitHub</a> (veja também <a href="https://github.com/mdn/learning-area/tree/master/javascript/building-blocks/functions">o código fonte</a>).</p> +</div> + +<p>Manter parte de seus código trancada em funções evita tais problemas, e é considerado boa prática.</p> + +<p>Parece um pouco com um zoológico. Os leões, zebras, tigres, e pinguins são mantidos em seus próprios cercados, e só tem acesso as coisas dentro de seu cercado — da mesma maneira que escopos de função. Se eles forem capazes de entrar em outros cercados, problemas podem acontecer. No melhor caso, diferentes animais poderiam sentir-se ralmente desconfortáveis dentro de habitats não familiares — um leão e um tigre poderiam sentir-se muito mal dentro de um úmido e gelado terreno. No pior caso, os leões e tigres poderiam tentar comer os pinguins!</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14079/MDN-mozilla-zoo.png" style="display: block; margin: 0 auto;"></p> + +<p>O zelador do zoológico é como o escopo global — ele ou ela tem as chaves para acessar cada cercado, reabastecer comida, tratar animais doentes, etc.</p> + +<h3 id="Aprendizado_ativo_Brincando_com_o_escopo">Aprendizado ativo: Brincando com o escopo</h3> + +<p>Vamos observar um exemplo real para mostrar escopo.</p> + +<ol> + <li>Primeiro, faça uma cópia local de nosso exmplo <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-scope.html">function-scope.html</a>. Isto contém duas funções chamadas <code>a()</code> e <code>b()</code>, e três variáveis — <code>x</code>, <code>y</code>, e <code>z</code> — duas das quais estão definidas dentro de funções, e uma no escopo global. Ele também contém uma terceira função chamada <code>output()</code>, que leva um simples parâmetro e mostra-o em um parágrafo na página.</li> + <li>Abra o exemplo em um navegador e em um editor de textos.</li> + <li>Abra o console JavaScript no developer tools de seu navegador. No console JavaScript, digite o seguinte comando: + <pre class="brush: js">output(x);</pre> + Você deve ver o valor da variável <code>x</code> exibida na página.</li> + <li>Agora tente digitar o seguinte no seu console: + <pre class="brush: js">output(y); +output(z);</pre> + Ambos dever retornar um erro com as seguintes linhas "<a href="/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: y is not defined</a>". Por que isso? Porque o escopo da função — <code>y</code> e <code>z</code> estão trancadas dentro das funções <code>a()</code> e <code>b()</code>, então <code>output()</code> não pode acessá-las quando chamadas do escopo global.</li> + <li>Contudo, que tal chamá-las de dentro de outra função? Tente editar <code>a()</code> e <code>b()</code> para que fiquem desta forma: + <pre class="brush: js">function a() { + var y = 2; + output(y); +} + +function b() { + var z = 3; + output(z); +}</pre> + Salve o código e atualize o navegador, então tente chamar as funções <code>a()</code> e <code>b()</code> do console JavaScript: + + <pre class="brush: js">a(); +b();</pre> + Você verá os valores de <code>y</code> e <code>z</code> mostrados na página. <span class="short_text" id="result_box" lang="pt"><span>Isso funciona bem</span></span>, desde que a função <code>output()</code> está sendo chamada dentro de outra função — <span id="result_box" lang="pt"><span>no mesmo escopo que as variáveis que estam imprimindo são definidas</span></span>, em cada caso. <code>output()</code> em si é acessível de qualquer lugar, <span class="short_text" id="result_box" lang="pt"><span>como é definido no escopo global.</span></span></li> + <li>Agora tente atualizar seu código como este: + <pre class="brush: js">function a() { + var y = 2; + output(x); +} + +function b() { + var z = 3; + output(x); +}</pre> + Salve e atualize novamente, e tente isso novamente em seu console JavaScript: </li> + <li> + <pre class="brush: js">a(); +b();</pre> + Ambas chamadas de <code>a()</code> e <code>b()</code> devem mostrar o valor de x — 1. Isso dá certo porque até mesmo a chamada de <code>output()</code> não está no mesmo escopo em que <code>x</code> é definido, <code>x</code> é uma variável global então é disponível dentro de todo código, em toda parte.</li> + <li>Finalmente, tente atualizar o código o seguinte: + <pre class="brush: js">function a() { + var y = 2; + output(z); +} + +function b() { + var z = 3; + output(y); +}</pre> + Salve e atualize novamente, e tente isso novamente em seu console JavaScript: </li> + <li> + <pre class="brush: js">a(); +b();</pre> + Desta vez as chamadas de <code>a()</code> e <code>b()</code> retornaram o irritante erro "<a href="/pt-BR/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: z is not defined</a>" — isto porque a chamada de <code>output()</code> e as variáveis que eles estão tentando imprimir não estão definidas dentro do mesmo escopo das funções — as variáveis são efetivamente invisíveis aquelas chamadas de função.</li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>: As mesmas regras de escopo não se aplicam a laços (ex.: <code>for() { ... }</code>) e blocos condicionais (ex.: <code>if() { ... }</code>) — eles parecem muito semelhantes, mas eles não são a mesma coisa! Tome cuidado para não confudir-se.</p> +</div> + +<div class="note"> +<p><strong>Nota</strong>: O erro <a href="/en-US/docs/Web/JavaScript/Reference/Errors/Not_defined">ReferenceError: "x" is not defined</a> é um dos mais comuns que você encontrará. Se você receber este erro e tem certeza que definiu a variável em questão, cheque em que escopo ela está.</p> +</div> + +<ul> +</ul> + +<h3 id="Funções_dentro_de_funções">Funções dentro de funções</h3> + +<p>Tenha em mente que você pode chamar uma função de qualquer lugar, até mesmo dentro de outra função. Isso é frenquentemente usado para manter o código organizado — se você tem uma função grande e complexa, é mais fácil de entendê-la se você quebrá-la em várias subfunções:</p> + +<pre class="brush: js">function myBigFunction() { + var myValue; + + subFunction1(); + subFunction2(); + subFunction3(); +} + +function subFunction1() { + console.log(myValue); +} + +function subFunction2() { + console.log(myValue); +} + +function subFunction3() { + console.log(myValue); +} +</pre> + +<p>Apenas certifique-se que os valores usados dentro da função estão apropriadamente no escopo. O exemplo acima deve lançar um erro <code>ReferenceError: myValue is not defined</code>, porque apesar da variável <code>myValue</code> estar definida no mesmo escopo da chamda da função, ela não está definida dentro da definição da função — o código real que está rodando quando as funções são chamadas. Para fazer isso funcionar, você deveria passar o valor dentro da função como um parâmetro, desta forma:</p> + +<pre class="brush: js">function myBigFunction() { + var myValue = 1; + + subFunction1(myValue); + subFunction2(myValue); + subFunction3(myValue); +} + +function subFunction1(value) { + console.log(value); +} + +function subFunction2(value) { + console.log(value); +} + +function subFunction3(value) { + console.log(value); +}</pre> + +<h2 id="Conclusão">Conclusão</h2> + +<p>Este arquivo explorou os conceitos fundamentais por trás das funções, pavimentando o caminho para o próximo no qual nos tornamos práticos e o levamos através de passos para construir suas próprias funções personalizadas.</p> + +<h2 id="Veja_também">Veja também</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Functions">Guia detalhado de funções</a> — cobre algumas características avançadas não includas aqui.</li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions">Referências de funções</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters">Parâmetros padrão</a>, <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Funções de flexa</a> — referências de conceito avançado</li> +</ul> + +<ul> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Looping_code","Learn/JavaScript/Building_blocks/Build_your_own_function", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="Neste_módulo">Neste módulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/building_blocks/image_gallery/index.html b/files/pt-br/learn/javascript/building_blocks/image_gallery/index.html new file mode 100644 index 0000000000..2e4fc27c4d --- /dev/null +++ b/files/pt-br/learn/javascript/building_blocks/image_gallery/index.html @@ -0,0 +1,140 @@ +--- +title: Galeria de Imagens +slug: Aprender/JavaScript/Elementos_construtivos/Image_gallery +translation_of: Learn/JavaScript/Building_blocks/Image_gallery +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">Agora que analisamos os blocos de construção fundamentais do JavaScript, testaremos seu conhecimento de loops, funções, condicionais e eventos, fazendo com que você crie um item bastante comum que você verá em muitos sites — uma galeria de imagens ativadas em JavaScript.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos:</th> + <td>Antes de tentar esta avaliação, você já deve ter trabalhado em todos os artigos deste módulo.</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Para testar a compreensão de loops, funções, condicionais e eventos de JavaScript.</td> + </tr> + </tbody> +</table> + +<h2 id="Ponto_de_partida">Ponto de partida</h2> + +<p>Para começar esta avaliação, você deve <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/gallery/gallery-start.zip?raw=true">pegar o arquivo ZIP</a> para o exemplo e descompactá-lo em algum lugar no seu computador.</p> + +<div class="note"> +<p><strong>Note</strong>: Como alternativa, você pode usar um site como o <a class="external external-icon" href="http://jsbin.com/">JSBin</a> ou <a class="external external-icon" href="https://thimble.mozilla.org/">Thimble</a> para fazer sua avaliação. Você pode colar o HTML, CSS e JavaScript em um desses editores on-line. Se o editor on-line que você está usando não tiver painéis JavaScript / CSS separados, sinta-se à vontade para colocar os elementos in-line <code><script><font face="x-locale-heading-primary, zillaslab, Palatino, Palatino Linotype, x-locale-heading-secondary, serif"><span style="background-color: #fff3d4;"> e </span></font></code><code><style></code> dentro da página HTML.</p> +</div> + +<h2 id="Resumo_do_projeto">Resumo do projeto</h2> + +<p>Você recebeu alguns recursos de HTML, CSS e imagem e algumas linhas de código JavaScript; você precisa escrever o JavaScript necessário para transformar isso em um programa de trabalho. O corpo do HTML se parece com isto:</p> + +<pre class="brush: html"><h1>Image gallery example</h1> + +<div class="full-img"> + <img class="displayed-img" src="images/pic1.jpg"> + <div class="overlay"></div> + <button class="dark">Darken</button> +</div> + +<div class="thumb-bar"> + +</div></pre> + +<p>O exemplo é assim:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13787/gallery.png" style="display: block; margin: 0 auto;"></p> + +<ul> +</ul> + +<p>As partes mais interessantes do arquivo CSS do exemplo:</p> + +<ul> + <li>Absolutamente posicione os três elementos dentro do <code>full-img <div></code> — o <code><img></code> no qual a imagem em tamanho normal é exibida, um <code><div></code> vazio que é dimensionado para ser do mesmo tamanho que o <code><img></code> e colocado sobre a parte superior (isso é usado para aplicar um efeito de escurecimento à imagem através de uma cor de fundo semitransparente) e um <code><button></code> que é usado para controlar o efeito de escurecimento.</li> + <li>Defina a largura de qualquer imagem dentro da thumb-bar <code>thumb-bar <div></code> (as chamadas imagens "thumbnail") para 20%, e flutue-as para a esquerda para que elas fiquem lado a lado em uma linha.</li> +</ul> + +<p>Seu JavaScript precisa:</p> + +<ul> + <li>Faça um loop em todas as imagens e, para cada uma, insira um elemento <code><img></code> dentro do <code>thumb-bar <div></code> que incorporará a imagem na página.</li> + <li>Anexe um manipulador <code>onclick</code> para cada <code><img></code> dentro do <code>thumb-bar <div></code> para que, quando clicados, a imagem correspondente seja exibida no elemento <code>displayed-img <img></code>.</li> + <li>Anexe um manipulador <code>onclick</code> ao <code><button></code> para que, ao ser clicado, um efeito de escurecimento seja aplicado à imagem em tamanho normal. Quando é clicado novamente, o efeito de escurecimento é removido novamente.</li> +</ul> + +<p>Para lhe dar mais uma ideia, dê uma olhada no <a href="http://mdn.github.io/learning-area/javascript/building-blocks/gallery/">exemplo finalizado</a> (não espreite o código-fonte!)</p> + +<h2 id="Passos_para_concluir">Passos para concluir</h2> + +<p>As seções a seguir descrevem o que você precisa fazer.</p> + +<h3 id="Looping_através_das_imagens">Looping através das imagens</h3> + +<p>Já fornecemos a você linhas que armazenam uma referência à <code>thumb-bar <div></code> dentro de uma variável chamada <code>thumbBar</code>, cria um novo elemento <code><img></code> define seu atributo <code>src</code> como um valor de espaço reservado <code>xxx</code>, e acrescenta essa nova <code><img></code> elemento dentro do <code>thumbBar</code>.</p> + +<p>Você precisa:</p> + +<ol> + <li>Coloque a seção de código abaixo do comentário "Looping through images" dentro de um loop que percorre todas as 5 imagens — você só precisa percorrer cinco números, um representando cada imagem.</li> + <li>Em cada iteração de loop, substitua o valor de espaço reservado <code>xxx</code> por uma string que seja igual ao caminho para a imagem em cada caso. Estamos definindo o valor do atributo <code>src</code> para esse valor em cada caso. Tenha em mente que, em cada caso, a imagem está dentro do diretório de imagens e seu nome é <code>pic1.jpg</code>, <code>pic2.jpg</code>, etc.</li> +</ol> + +<h3 id="Adicionando_um_manipulador_onclick_a_cada_imagem_em_miniatura">Adicionando um manipulador onclick a cada imagem em miniatura</h3> + +<p>Em cada iteração de loop, você precisa adicionar um manipulador <code>onclick</code> ao atual <code>newImage</code> — isso deve:</p> + +<ol> + <li>Encontre o valor do atributo <code>src</code> da imagem atual. Isto pode ser feito executando a função <code><a href="/en-US/docs/Web/API/Element/getAttribute">getAttribute()</a></code> no <code><img></code> em cada caso e passando um parâmetro de <code>"src"</code> em cada caso. Mas como conseguir a imagem? O uso do <code>newImage.getAttribute()</code> não funcionará, pois o loop é concluído antes de os manipuladores de eventos serem aplicados; fazer desta forma resultaria no retorno do valor <code>src</code> do último <code><img></code> para todos os casos. Para resolver isso, tenha em mente que, no caso de cada manipulador de eventos, o <code><img></code> é o destino do manipulador. Que tal obter as informações do objeto de evento?</li> + <li>Rode uma função, passando o valor <code>src</code> retornado como um parâmetro. Você pode chamar essa função como quiser.</li> + <li>Esta função do manipulador de eventos deve definir o valor do atributo <code>src</code> do <code>displayed-img <img></code> para o valor <code>src</code> passado como um parâmetro. Já fornecemos uma linha que armazena uma referência ao <code><img></code> relevante em uma variável chamada <code>displayedImg</code>. Note que queremos uma função nomeada definida aqui.</li> +</ol> + +<h3 id="Escrevendo_um_manipulador_que_executa_o_botão_escurecer_clarear">Escrevendo um manipulador que executa o botão escurecer / clarear</h3> + +<p>Isso só deixa o nosso escurecer / clarear <code><button></code> — nós já fornecemos uma linha que armazena uma referência ao <code><button></code> em uma variável chamada <code>btn</code>. Você precisa adicionar um manipulador <code>onclick</code> que:</p> + +<ol> + <li>Verifica o nome da classe atual definido no <code><button></code> — você pode novamente fazer isso usando <code>getAttribute()</code>.</li> + <li>Se o nome da classe for <code>"dark"</code>, altera a classe <code><button></code> para <code>"light"</code> (usando <code><a href="/en-US/docs/Web/API/Element/setAttribute">setAttribute()</a></code>), seu conteúdo de texto para "Lighten", e o {{cssxref("background-color")}} da sobreposição <code><div></code> para <code>"rgba(0,0,0,0.5)"</code>.</li> + <li>Se o nome da classe não for <code>"dark"</code>, a classe <code><button></code> será alterada para <code>"dark"</code>, o conteúdo de texto de volta para "Darken", e o {{cssxref("background-color")}} da sobreposição <code><div></code> para <code>"rgba(0,0,0,0)"</code>.</li> +</ol> + +<p>As linhas seguintes fornecem uma base para alcançar as mudanças estipuladas nos pontos 2 e 3 acima.</p> + +<pre class="brush: js">btn.setAttribute('class', xxx); +btn.textContent = xxx; +overlay.style.backgroundColor = xxx;</pre> + +<h2 id="Dicas_e_sugestões">Dicas e sugestões</h2> + +<ul> + <li>Você não precisa editar o HTML ou CSS de forma alguma.</li> +</ul> + +<h2 id="Avaliação">Avaliação</h2> + +<p>Se você está seguindo esta avaliação como parte de um curso organizado, você deve poder dar seu trabalho ao seu professor / mentor para marcação. Se você é auto-didata, então pode obter o guia de marcação com bastante facilidade, perguntando no tópico de <a href="https://discourse.mozilla.org/t/image-gallery-assessment/24687">discussão sobre este exercício</a>, ou no canal <a href="irc://irc.mozilla.org/mdn">#mdn</a> IRC da <a href="https://wiki.mozilla.org/IRC">Mozilla IRC</a>. Tente o exercício primeiro — não há nada a ganhar com a trapaça!</p> + +<p>{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}</p> + +<p> </p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> + +<p> </p> diff --git a/files/pt-br/learn/javascript/building_blocks/index.html b/files/pt-br/learn/javascript/building_blocks/index.html new file mode 100644 index 0000000000..cb8deab502 --- /dev/null +++ b/files/pt-br/learn/javascript/building_blocks/index.html @@ -0,0 +1,51 @@ +--- +title: Elementos construtivos do Javascript +slug: Aprender/JavaScript/Elementos_construtivos +tags: + - Artigo + - Condicionais + - Exercício + - Funções + - Iniciante + - JavaScript + - Loops + - eventos +translation_of: Learn/JavaScript/Building_blocks +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">Neste módulo, continuaremos nossa abordagem por todos os recursos-chave fundamentais de Javascript, voltando nossa atenção para os tipos de bloco de código comumente encontrados, tais como declarações condicionais, laços, funções e eventos. Você já viu isso no curso, mas apenas de passagem - aqui nós vamos discutir tudo isso explicitamente.</p> + +<h2 id="Pré-requisitos">Pré-requisitos</h2> + +<p>Antes de iniciar este módulo, você deve ter familiaridade com os conceitos básicos de <a href="https://developer.mozilla.org/pt-BR/docs/Aprender/HTML/Introducao_ao_HTML">HTML</a> e <a href="https://developer.mozilla.org/pt-BR/docs/Aprender/CSS/Introduction_to_CSS">CSS</a>, além de ter estudado nosso módulo anterior, <a href="https://developer.mozilla.org/pt-BR/docs/Learn/JavaScript/First_steps">primeiros passos no Javacript</a>.</p> + +<div class="note"> +<p><strong>Nota</strong>: Se você está trabalhando em um computador, tablet ou outro dispositivo onde você não tem a habilidade para criar seus próprios arquivos, você pode testar os exemplos de código (a maioria deles) em um programa de codificação online, tal como <a href="http://jsbin.com/">JSBin</a> ou <a href="https://thimble.mozilla.org/">Thimble</a>.</p> +</div> + +<h2 id="Guias">Guias</h2> + +<dl> + <dt><a href="/pt-BR/docs/Learn/JavaScript/Building_blocks/conditionals">Tomando decisões em seu código — condicionais</a></dt> + <dd>Em qualquer linguagem de programação, o código precisa tomar decisões e realizar ações de acordo com diferentes valores de entrada. Por exemplo, em um jogo, se o número de vidas de um jogador é 0, então é "fim de jogo". Em um aplicativo de previsão do tempo, se ele está sendo olhado de manhã, é exibido um gráfico de nascer do sol; se for noite, mostra estrelas e a lua. Neste artigo, vamos explorar como as estruturas condicionais funcionam em Javascript.</dd> + <dt><a href="/pt-BR/docs/Learn/JavaScript/Building_blocks/Looping_code">Re-executando código</a></dt> + <dd>Às vezes você precisa que uma tarefa seja feita mais de uma vez em uma linha. Por exemplo, percorrendo uma lista de nomes. Em programação, laços realizam esse trabalho muito bem. Aqui nós vamos ver estruturas de laço em Javascript.</dd> + <dt><a href="/pt-BR/docs/Learn/JavaScript/Building_blocks/Functions">Funções — blocos reutilizáveis de código</a></dt> + <dd>Outro conceito essencial em codificação são <strong>funções</strong>. <strong>Funções </strong>permitem que você armazene um trecho de código que executa uma única tarefa dentro de um bloco definido, e então chame aquele código em qualquer lugar que você precise dele usando um comando curto - em vez de ter que digitar o mesmo código múltiplas vezes. Neste artigo, vamos explorar conceitos fundamentais por trás das funções, tais como sintaxe básica, como invocar e definir funções, escopo e parâmetros.</dd> + <dt><a href="/pt-BR/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Construa sua própria função</a></dt> + <dd>Com a maior parte da teoria essencial tratada no artigo anterior, este artigo fornece uma experiência prática. Aqui você vai adquirir um pouco de prática construindo sua própria função personalizada. Junto com isso, vamos explicar mais alguns detalhes úteis sobre lidar com funções.</dd> + <dt><a href="/pt-BR/docs/Learn/JavaScript/Building_blocks/Return_values">Funções retornam valores</a></dt> + <dd>Há um último conceito essencial para discutirmos nesse curso, antes de encerrarmos nossa abordagem sobre funções — valores de retorno. Algumas funções não retornam nenhum valor significativo após executar, outras retornam. É importantes entender o que esses valores são, como utilizá-los em seu código, e como fazer suas próprias funções customizadas retornarem valores utilizáveis. </dd> + <dt><a href="/pt-BR/docs/Learn/JavaScript/Building_blocks/Events">Introdução a eventos</a></dt> + <dd>Eventos são ações ou ocorrências que acontecem no sistema que você está programando, sobre os quais o sistema te informa para que você possa reagir a eles de alguma forma se desejar. Por exemplo se o usuário clica em um botão numa página, você deve querer responder a essa ação exibindo uma caixa de informação. Neste artigo final nós discutiremos alguns conceitos importantes sobre eventos, e ver como eles funcionam em navegadores.</dd> +</dl> + +<h2 id="Exercícios">Exercícios</h2> + +<p>O exercício a seguir irá testar seu entendimento do básico de JavaScript abordado nos guias acima.</p> + +<dl> + <dt><a href="/pt-BR/docs/Learn/JavaScript/Building_blocks/Image_gallery">Galeria de imagens</a></dt> + <dd>Agora que demos uma olhada os elementos construtivos do JavaScript, vamos testar seu conhecimento sobre loops, funções, condicionais e eventos construindo um item bastante comum que você verá em muitos websites — uma galeria de imagens movida a JavaScript.</dd> +</dl> diff --git a/files/pt-br/learn/javascript/building_blocks/looping_code/index.html b/files/pt-br/learn/javascript/building_blocks/looping_code/index.html new file mode 100644 index 0000000000..058ce0385c --- /dev/null +++ b/files/pt-br/learn/javascript/building_blocks/looping_code/index.html @@ -0,0 +1,940 @@ +--- +title: Código em loop +slug: Aprender/JavaScript/Elementos_construtivos/Código_em_loop +tags: + - Artigo + - CodingScripting + - DO + - Guide + - Iniciante + - JavaScript + - Loop + - break + - continue + - for + - while +translation_of: Learn/JavaScript/Building_blocks/Looping_code +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">As linguagens de programação são muito úteis para concluir rapidamente tarefas repetitivas, desde vários cálculos básicos até praticamente qualquer outra situação em que você tenha muitos itens semelhantes para manipular. Aqui, veremos as estruturas de loop disponíveis no JavaScript que ajudam com essas necessidades..</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisitos:</th> + <td>Conhecimento básico em informática, um básico entendimento de HTML e CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript first steps</a>.</td> + </tr> + <tr> + <th scope="row">Objectivo:</th> + <td>Entender como usar loops em JavaScript.</td> + </tr> + </tbody> +</table> + +<h2 id="Mantenha-me_no_looplaço">Mantenha-me no loop(laço)</h2> + +<p>Loops, loops, loops. Além de estarem associados a <a href="https://en.wikipedia.org/wiki/Froot_Loops">populares cereais matinais</a>, <a href="https://pt.wikipedia.org/wiki/Montanha-russa">montanhas-russas</a> e <a href="https://pt.wikipedia.org/wiki/Loop_(m%C3%BAsica)">produção musical</a>, eles também são um conceito importante na programação. O loop de programação é como fazer a mesma coisa repetidas vezes - o que é chamado de <strong>iteração</strong> na linguagem de programação.</p> + +<p>Vamos considerar o caso de um agricultor que quer se certificar de que ele terá comida suficiente para alimentar sua família durante a semana. Ele pode usar o seguinte loop para conseguir isso:</p> + +<p><br> + <img alt="" src="https://mdn.mozillademos.org/files/13755/loop_js-02-farm.png" style="display: block; margin: 0 auto;"></p> + +<p>Um loop geralmente possui um ou mais dos seguintes itens:</p> + +<ul> + <li> O <strong>contador</strong>, que é inicializado com um certo valor - este é o ponto inicial do loop ("Iniciar: não tenho comida", figura acima).</li> + <li>A <strong>condição de saída</strong>, que é o critério no qual o loop pára - geralmente o contador atinge um certo valor. Isso é ilustrado por "Tenho comida suficiente?", na figura acima. Vamos dizer que ele precisa de 10 porções de comida para alimentar sua família.</li> + <li>Um <strong>iterador</strong>, que geralmente incrementa o contador em uma pequena quantidade a cada loop, sucessivamente, até atingir a condição de saída. Nós não ilustramos explicitamente isso acima, mas poderíamos pensar sobre o agricultor ser capaz de coletar 2 porções de comida por hora. Depois de cada hora, a quantidade de comida que ele coletou é incrementada em dois, e ele verifica se ele tem comida suficiente. Se ele atingiu 10 porções (a condição de saída), ele pode parar de coletar e ir para casa.</li> +</ul> + +<p>No seu {{glossary("pseudocode")}}, isso seria algo como o seguinte:</p> + +<pre>loop(food = 0; foodNeeded = 10) { + if (food = foodNeeded) { + exit loop; + // Nós temos comida o suficiente, Vamos para casa + } else { + food += 2; // Passe uma hora coletando mais 2 alimentos(food) + // loop será executado novamente + } +}</pre> + +<p>Assim, a quantidade de comida necessária é fixada em 10, e o montante que o agricultor tem atualmente é fixado em 0. Em cada iteração do ciclo, verificamos se a quantidade de alimento que o agricultor tem é igual à quantidade que ele precisa. Se assim for, podemos sair do loop. Se não, o agricultor gasta mais uma hora coletando duas porções de comida, e o laço é executado novamente.</p> + +<h3 id="Porque_se_importar">Porque se importar?</h3> + +<p>Neste ponto, você provavelmente já entendeu o conceito de alto nível por trás dos loops, mas provavelmente está pensando "OK, ótimo, mas como isso me ajuda a escrever um código JavaScript melhor?" Como dissemos anteriormente, <strong>os loops têm tudo a ver com fazer a mesma coisa repetidas vezes, o que é ótimo para concluir rapidamente tarefas repetitivas</strong>.</p> + +<p>Muitas vezes, o código será um pouco diferente em cada iteração sucessiva do loop, o que significa que você pode completar toda uma carga de tarefas que são semelhantes, mas não são totalmente iguais — se você tem muitos cálculos diferentes para fazer, e você quer fazer um diferente do outro, e não o mesmo repetidamente!</p> + +<p>Vejamos um exemplo para ilustrar perfeitamente por que os loops são uma coisa tão boa. Digamos que quiséssemos desenhar 100 círculos aleatórios em um elemento {{htmlelement("canvas")}} (pressione o botão Atualizar para executar o exemplo várias vezes para ver os conjuntos aleatórios diferentes):</p> + +<div class="hidden"> +<h6 id="Hidden_code">Hidden code</h6> + +<pre class="brush: html"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Random canvas circles</title> + <style> + html { + width: 100%; + height: inherit; + background: #ddd; + } + + canvas { + display: block; + } + + body { + margin: 0; + } + + button { + position: absolute; + top: 5px; + left: 5px; + } + </style> + </head> + <body> + + <button>Update</button> + + <canvas></canvas> + + + <script> + var btn = document.querySelector('button'); + var canvas = document.querySelector('canvas'); + var ctx = canvas.getContext('2d'); + + var WIDTH = document.documentElement.clientWidth; + var HEIGHT = document.documentElement.clientHeight; + + canvas.width = WIDTH; + canvas.height = HEIGHT; + + function random(number) { + return Math.floor(Math.random()*number); + } + + function draw() { + ctx.clearRect(0,0,WIDTH,HEIGHT); + for (var i = 0; i < 100; i++) { + ctx.beginPath(); + ctx.fillStyle = 'rgba(255,0,0,0.5)'; + ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); + ctx.fill(); + } + } + + btn.addEventListener('click',draw); + + </script> + + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_code', '100%', 400, "", "", "hide-codepen-jsfiddle") }}</p> + +<p>Você não precisa entender todo esse código por enquanto, mas vamos ver a parte do código que realmente desenha os 100 círculos:</p> + +<pre class="brush: js">for (var i = 0; i < 100; i++) { + ctx.beginPath(); + ctx.fillStyle = 'rgba(255,0,0,0.5)'; + ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); + ctx.fill(); +}</pre> + +<ul> + <li><code>random()</code>, definido anteriormente no código, retorna um número inteiro entre <code>0</code> e <code>x-1</code>.</li> + <li><code>WIDTH</code> e <code>HEIGHT</code> são a largura e a altura da janela interna do navegador. </li> +</ul> + +<p>Você deve ter notado - estamos usando um loop para executar 100 iterações desse código, cada uma delas desenhando um círculo em uma posição aleatória na página. A quantidade de código necessária seria a mesma se estivéssemos desenhando 100 círculos, 1.000 ou 10.000. Apenas um número tem que mudar.</p> + +<p>Se não estivéssemos usando um loop aqui, teríamos que repetir o seguinte código para cada círculo que queríamos desenhar:</p> + +<pre class="brush: js">ctx.beginPath(); +ctx.fillStyle = 'rgba(255,0,0,0.5)'; +ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); +ctx.fill();</pre> + +<p>Isso ficaria muito chato, difícil e lento de manter. Loops são realmente os melhores.</p> + +<h2 id="O_for_loop_padrão">O for loop padrão</h2> + +<p>Vamos começar a explorar alguns exemplos específicos de construções de loop. O primeiro e que você usará na maior parte do tempo, é o loop <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for">for</a> - ele tem a seguinte sintaxe:</p> + +<pre>for (inicializador; condição-saída; expressão-final) { + // código para executar +}</pre> + +<p>Aqui nós temos:</p> + +<ol> + <li>A palavra-chave <code>for</code>, seguido por parênteses.</li> + <li>Dentro do parênteses temos três itens, sepados por ponto e vírgula: + <ol> + <li>O<strong> inicializador</strong>— geralmente é uma variável configurada para um número, que é incrementado para contar o número de vezes que o loop foi executado. É também por vezes referido como uma <strong>variável de contador</strong>.</li> + <li>A <strong>condição-saída</strong> — como mencionado anteriormente, aqui é definido qundo o loop deve parar de executar. Geralmente, essa é uma expressão que apresenta um operador de comparação, um teste para verificar se a condição de saída foi atendida.</li> + <li>A <strong>expressão-final </strong>— isso sempre é avaliado (ou executado) cada vez que o loop passou por uma iteração completa. Geralmente serve para incrementar (ou, em alguns casos, decrementar) a variável do contador, aproximando-a do valor da condição de saída.</li> + </ol> + </li> + <li>Algumas chaves contêm um bloco de código - esse código será executado toda vez que o loop for iterado.</li> +</ol> + +<p>Vejamos um exemplo real para podermos visualizar o que isso faz com mais clareza.</p> + +<pre class="brush: js">var cats = ['Bill', 'Jeff', 'Pete', 'Biggles', 'Jasmin']; +var info = 'My cats are called '; +var para = document.querySelector('p'); + +for (var i = 0; i < cats.length; i++) { + info += cats[i] + ', '; +} + +para.textContent = info;</pre> + +<p>Isso nos dá a seguinte saída:</p> + +<div class="hidden"> +<h6 id="Hidden_code_2">Hidden code 2</h6> + +<pre class="brush: html"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Basic for loop example</title> + <style> + + </style> + </head> + <body> + + <p></p> + + + <script> + var cats = ['Bill', 'Jeff', 'Pete', 'Biggles', 'Jasmin']; + var info = 'My cats are called '; + var para = document.querySelector('p'); + + for (var i = 0; i < cats.length; i++) { + info += cats[i] + ', '; + } + + para.textContent = info; + + </script> + + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_code_2', '100%', 60, "", "", "hide-codepen-jsfiddle") }}</p> + +<div class="note"> +<p><strong>Nota: </strong>Você pode encontrar este <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/basic-for.html">código de exemplo no GitHub</a> (também <a href="https://mdn.github.io/learning-area/javascript/building-blocks/loops/basic-for.html">veja em execução </a>).</p> +</div> + +<p>Aqui mostra um loop sendo usado para iterar os itens em uma matriz e fazer algo com cada um deles - um padrão muito comum em JavaScript. Aqui:</p> + +<ol> + <li>O iterador, <code>i</code>, começa em <code>0</code> (<code>var i = 0</code>).</li> + <li>Foi dito para executar até que não seja menor que o comprimento do array dos gatos. Isso é importante - a condição de saída mostra a condição sob a qual o loop ainda será executado. No caso, enquanto <code>i < cats.length</code> for verdadeiro, o loop continuará executando.</li> + <li>Dentro do loop, nós concatenamos o item de loop atual (<code>cats[i]</code> é <code>cats[o nome do item que está iterado no momento]</code>) junto com uma vírgula e um espaço, no final da variável <code>info</code> . Assim: + <ol> + <li>Durante a primeira execução, <code>i = 0</code>, então <code>cats[0] + ', '</code> será concatenado na variável info ("Bill").</li> + <li>Durante a segunda execução, <code>i = 1</code>, so <code>cats[1] + ', '</code> será concatenado na variável info ("Jeff, ")</li> + <li>E assim por diante. Após cada execução do loop, 1 será adicionado à <code>i</code> (<code>i++</code>), então o processo será iniciado novamente.</li> + </ol> + </li> + <li>Quando <code>i</code> torna-se igual a <code>cats.length</code>, o loop é interrompido e o navegador passará para o próximo trecho de código abaixo do loop.</li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>:Nós fizemos a condição de saída <code>i < cats.length</code>, e não <code>i <= cats.length</code>, porque os computadores contam a partir de 0, não 1 - estamos começando <code>i</code> em <code>0</code>, e indo até <code>i = 4</code> (o index do último item do array). <code>cats.length</code> retorna 5, pois há 5 itens no array, mas não queremos chegar até <code>i = 5</code>, pois isso retornaria <code>undefined</code> para o último item (não há nenhum item no índice 5 do array). Então, portanto, queremos ir até 1 a menos de <code>cats.length</code> (<code>i <</code>), não é o mesmo que <code>cats.length</code> (<code>i <=</code>).</p> +</div> + +<div class="note"> +<p><strong>Nota</strong>: Um erro comum nas condições de saída é usá-las "igual a" (<code>===</code>) em vez de dizer "menor ou igual a" (<code><=</code>). Se quiséssemos executar nosso loop até <code>i = 5</code>, a condição de saída precisaria ser <code>i <= cats.length</code>. Se nós setarmos para <code>i === cats.length</code>, o loop não seria executado em todos, porque <code>i</code> não é igual a <code>5</code> na primeira iteração do loop, a execução pararia imediatamente.</p> +</div> + +<p>Um pequeno problema que nos resta é que a sentença de saída final não é muito bem formada:</p> + +<blockquote> +<p>Meus gatos se chamam: Bill, Jeff, Pete, Biggles, Jasmin,</p> +</blockquote> + +<p>Neste caso, queremos alterar a concatenação na iteração final do loop, para que não tenhamos uma vírgula no final da frase. Bem, não há problema - podemos muito bem inserir uma condicional dentro do nosso loop for para lidar com este caso especial:</p> + +<pre class="brush: js">for (var i = 0; i < cats.length; i++) { + if (i === cats.length - 1) { + info += 'and ' + cats[i] + '.'; + } else { + info += cats[i] + ', '; + } +}</pre> + +<div class="note"> +<p><strong>Nota: </strong>Você pode encontrar este <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/basic-for-improved.html">código de exemplo no GitHub</a> (também <a href="https://mdn.github.io/learning-area/javascript/building-blocks/loops/basic-for-improved.html">veja em execução </a>).</p> +</div> + +<div class="warning"> +<p><strong>Importante</strong>: Com <strong>for</strong> - como acontece com todos os loops - você deve certificar-se de que o inicializador está iterado(configurado) para que ele atinja a condição de saída. Caso contrário, o loop continuará indefinidamente executando e o navegador irá forçá-lo a parar ou falhará. Isso é chamado de<strong> loop infinito</strong>.</p> +</div> + +<h2 id="Saindo_do_loop_com_o_break">Saindo do loop com o break</h2> + +<p>Se você quiser sair de um loop antes que todas as iterações sejam concluídas, você poderá usar a instrução <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/break">break</a>. Nós já encontramos isso em um artigo anterior, quando observamos as instruções switch - quando um determinado caso é atendido em uma <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/conditionals#switch_statements">condição do switch</a> e que corresponde à expressão de entrada informada, a instrução break sai imediatamente da instrução switch e passa para o trecho de código seguinte.</p> + +<p>É o mesmo com loops — um comando <code>break</code> irá imediatamente sair do loop e fazer o navegador passar para o código seguinte.</p> + +<p>Digamos que quiséssemos pesquisar por uma variedade de contatos e números de telefone e retornar apenas o número que queríamos encontrar? Primeiro, algum HTML simples — um texto {{htmlelement("input")}} permitindo-nos iserir um nome para pesquisar, {{htmlelement("button")}} elemento para submeter a pesquisa e um {{htmlelement("p")}} elemento para mostrar o resultado em:</p> + +<pre class="brush: html"><label for="search">Search by contact name: </label> +<input id="search" type="text"> +<button>Search</button> + +<p></p></pre> + +<p>Agora para no JavaScript:</p> + +<pre class="brush: js">var contacts = ['Chris:2232322', 'Sarah:3453456', 'Bill:7654322', 'Mary:9998769', 'Dianne:9384975']; +var para = document.querySelector('p'); +var input = document.querySelector('input'); +var btn = document.querySelector('button'); + +btn.addEventListener('click', function() { + var searchName = input.value; + input.value = ''; + input.focus(); + for (var i = 0; i < contacts.length; i++) { + var splitContact = contacts[i].split(':'); + if (splitContact[0] === searchName) { + para.textContent = splitContact[0] + '\'s number is ' + splitContact[1] + '.'; + break; + } else { + para.textContent = 'Contact not found.'; + } + } +});</pre> + +<div class="hidden"> +<h6 id="Hidden_code_3">Hidden code 3</h6> + +<pre class="brush: html"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Simple contact search example</title> + <style> + + </style> + </head> + <body> + + <label for="search">Search by contact name: </label> + <input id="search" type="text"> + <button>Search</button> + + <p></p> + + + <script> + var contacts = ['Chris:2232322', 'Sarah:3453456', 'Bill:7654322', 'Mary:9998769', 'Dianne:9384975']; + var para = document.querySelector('p'); + var input = document.querySelector('input'); + var btn = document.querySelector('button'); + + btn.addEventListener('click', function() { + var searchName = input.value; + input.value = ''; + input.focus(); + for (var i = 0; i < contacts.length; i++) { + var splitContact = contacts[i].split(':'); + if (splitContact[0] === searchName) { + para.textContent = splitContact[0] + '\'s number is ' + splitContact[1] + '.'; + break; + } else if (i === contacts.length-1) + para.textContent = 'Contact not found.'; + } + }); + </script> + + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_code_3', '100%', 100, "", "", "hide-codepen-jsfiddle") }}</p> + +<ol> + <li>Primeiramente, temos algumas definições de variáveis — temos um array com as informações dos contatos, cada item é uma string e contém um nome e um número de telefone separados por dois pontos.</li> + <li>Em seguida, anexamos um ouvinte de evento ao botão (<code>btn</code>), de modo que quando ele é pressionado, algum código é invocado para executar a pesquisa e retornar os resultados.</li> + <li>Armazenamos o valor que foi inserido no input de texto em uma variável chamada <code>searchName</code>, antes de limpar a entrada de texto e focar novamente, deixando o campo pronto para a próxima pesquisa.</li> + <li>Agora, na parte interessante, o loop for: + <ol> + <li>Iniciamos o contador em <code>0</code>, executamos o loop até que o contador não seja menor que <code>contacts.length</code>, e incrementamos <code>i</code> com 1 depois e cada iteração do loop.</li> + <li>Dentro do loop, primeiro dividimos o contato atual (<code>contacts[i]</code>) no caractere " : " e armazenamos os dois valores resultantes em uma matriz chamada <code>splitContact</code>.</li> + <li>Em seguida, usamos uma instrução condicional para testar se o <code>splitContact[0]</code> (nome do contato) é igual ao <code>searchName</code>. Se for igual, inserimos uma string no parágrafo para mostrar em tela qual é o número do contato e usamos o <code>break</code> para encerrar o loop.</li> + </ol> + </li> + <li> + <p>Após <code>(contacts.length-1)</code> iterações, se o nome do contato não corresponder à pesquisa inserida, o texto do parágrafo será definido como "Contato não encontrado" e o loop continuará a iterar.</p> + </li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>: Você pode encontrar este <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/contact-search.html">código de exemplo no GitHub</a> (também <a href="https://mdn.github.io/learning-area/javascript/building-blocks/loops/contact-search.html">veja em execução</a> ).</p> +</div> + +<h2 id="Ignorando_iterações_com_continue">Ignorando iterações com continue</h2> + +<p>A instrução <a href="/en-US/docs/Web/JavaScript/Reference/Statements/continue">continue</a> funciona de maneira semelhante ao <code>break</code>, mas ao invés de sair inteiramente do loop, ele pula para a próxima iteração do loop. Vejamos outro exemplo que usa um número como entrada e retorna apenas os números que são quadrados de inteiros (números inteiros).</p> + +<p>O HTML é basicamente o mesmo do último exemplo - uma entrada de texto simples e um parágrafo para saída. O JavaScript é basicamente o mesmo, embora o próprio loop seja um pouco diferente:</p> + +<pre class="brush: js">var num = input.value; + +for (var i = 1; i <= num; i++) { + var sqRoot = Math.sqrt(i); + if (Math.floor(sqRoot) !== sqRoot) { + continue; + } + + para.textContent += i + ' '; +}</pre> + +<p>Aqui está a saída:</p> + +<div class="hidden"> +<h6 id="Hidden_code_4">Hidden code 4</h6> + +<pre class="brush: html"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"> + <title>Integer squares generator</title> + <style> + + </style> + </head> + <body> + + <label for="number">Enter number: </label> + <input id="number" type="text"> + <button>Generate integer squares</button> + + <p>Output: </p> + + + <script> + var para = document.querySelector('p'); + var input = document.querySelector('input'); + var btn = document.querySelector('button'); + + btn.addEventListener('click', function() { + para.textContent = 'Output: '; + var num = input.value; + input.value = ''; + input.focus(); + for (var i = 1; i <= num; i++) { + var sqRoot = Math.sqrt(i); + if (Math.floor(sqRoot) !== sqRoot) { + continue; + } + + para.textContent += i + ' '; + } + }); + </script> + + </body> +</html></pre> +</div> + +<p>{{ EmbedLiveSample('Hidden_code_4', '100%', 100, "", "", "hide-codepen-jsfiddle") }}</p> + +<ol> + <li>Nesse caso, a entrada deve ser um número (<code>num</code>). O loop <code>for</code> recebe um contador começando em 1 (como não estamos interessados em 0 neste caso), uma condição de saída que diz que o loop irá parar quando o contador se tornar maior que o input <code>num</code>, e um iterador que adiciona 1 ao contador a cada vez.</li> + <li>Dentro do loop, encontramos a raiz quadrada de cada número usando <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt">Math.sqrt(i)</a>, e, em seguida, verificamos se a raiz quadrada é um inteiro, testando se é igual a ela mesma quando foi arredondada para o inteiro mais próximo é o que <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor">Math.floor()</a> faz com o número que é passado).</li> + <li>Se a raiz quadrada e a raiz quadrada arredondada não forem iguais (<code>! ==</code>), isso significa que a raiz quadrada não é um número inteiro, portanto, não estamos interessados nela. Nesse caso, usamos a instrução <code>continue</code> para pular para a próxima iteração de loop sem registrar o número em nenhum lugar.</li> + <li>Se a raiz quadrada é um inteiro, nós pulamos o bloco if inteiramente para que a instrução <code>continue</code> não seja executada; em vez disso, concatenamos o valor <code>i</code> atual mais um espaço até o final do conteúdo do parágrafo.</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: Você pode encontrar este <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/integer-squares.html">código de exemplo no GitHub</a> (também <a href="https://mdn.github.io/learning-area/javascript/building-blocks/loops/integer-squares.html">veja em execução</a> ).</p> +</div> + +<h2 id="while_e_o_do_..._while">while e o do ... while</h2> + +<p><code>for</code> não é o único tipo de loop disponível em JavaScript. Na verdade, existem muitos outros, embora você não precise entender tudo isso agora, vale a pena dar uma olhada na estrutura dos outros tipos de loops para que você possa reconhecer a mesma lógica na funcionalidade porém empregada de uma forma diferente.</p> + +<p>Primeiro, vamos dar uma olhada no <a href="/en-US/docs/Web/JavaScript/Reference/Statements/while">while</a> loop. A sintaxe deste loop é assim:</p> + +<pre>inicializador +while (condição-saída) { + // code to run + + expressão-final +}</pre> + +<p>While funciona de maneira muito semelhante ao loop for, exceto que a variável inicializadora é definida antes do loop, e a expressão final é incluída dentro do loop após o código a ser executado - em vez de esses dois itens serem incluídos dentro dos parênteses. A condição de saída está incluída dentro dos parênteses, que são precedidos pela palavra-chave <code>while</code> e não por <code>for</code>.</p> + +<p>Os mesmos três itens ainda estão presentes, e eles ainda são definidos na mesma ordem do loop for - isso faz sentido, já que você ainda precisa ter um inicializador definido antes de poder verificar se ele atingiu a condição de saída ; a condição final é então executada após o código dentro do loop ser executado (uma iteração foi concluída), o que só acontecerá se a condição de saída ainda não tiver sido atingida.</p> + +<p>Vamos dar uma olhada novamente no nosso exemplo de lista de gatos, que reescrevemos para usar um loop while:</p> + +<pre class="brush: js">var i = 0; + +while (i < cats.length) { + if (i === cats.length - 1) { + info += 'and ' + cats[i] + '.'; + } else { + info += cats[i] + ', '; + } + + i++; +}</pre> + +<div class="note"> +<p><strong>Nota: </strong>Isso ainda funciona da mesma forma esperada — dê uma olhada no <a href="http://mdn.github.io/learning-area/javascript/building-blocks/loops/while.html">código em execução</a> (também veja o <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/while.html">código fonte completo</a>).</p> +</div> + +<p>O <a href="/en-US/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a> loop é muito semelhante, mas fornece uma variação na estrutura while:</p> + +<pre>initializer +do { + // code to run + + final-expression +} while (exit-condition)</pre> + +<p>Nesse caso, o inicializador novamente vem em primeiro lugar, antes que o loop seja iniciado. A palavra-chave precede diretamente as chaves que contêm o código a ser executado e a expressão final.</p> + +<p>O diferenciador aqui é que a condição de saída vem depois de todo o resto, envolvida em parênteses e precedida por uma palavra-chave while. Em um loop do ... while, o código dentro das chaves é sempre executado uma vez antes da verificação ser feita para ver se deve ser executada novamente (no while e para, a verificação vem primeiro, então o código pode nunca ser executado ).</p> + +<p>Vamos reescrever nosso exemplo de listagem de gato novamente para usar um loop do ... while:</p> + +<pre class="brush: js">var i = 0; + +do { + if (i === cats.length - 1) { + info += 'and ' + cats[i] + '.'; + } else { + info += cats[i] + ', '; + } + + i++; +} while (i < cats.length);</pre> + +<div class="note"> +<p><strong>Nota: </strong>Novamente, isso funciona exatamente como esperado - dê uma olhada nele <a href="https://mdn.github.io/learning-area/javascript/building-blocks/loops/do-while.html">executando no GitHub</a> (veja também o<a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/do-while.html"> código fonte completo</a>).</p> +</div> + +<div class="warning"> +<p><strong>Importante:</strong> Com while e do ... while - como em todos os loops - você deve certificar-se de que o inicializador esteja iterado para que ele atinja a condição de saída. Caso contrário, o loop continuará indefinidamente e o navegador irá forçá-lo a parar ou falhará. Isso é chamado de loop infinito.</p> +</div> + +<h2 id="Aprendizado_ativo_contagem_regressiva!">Aprendizado ativo: contagem regressiva!</h2> + +<p>Nesse exercício, nós queremos que você imprima uma simples contagem regressiva na caixa de saída, de 10 até terminar. Especificamente, queremos que você:</p> + +<ul> + <li>Faça um loop de 10 até 0. Fornecemos à você um inicializador — <code>var i = 10;</code>.</li> + <li>Para cada iteração, crie um novo parágrafo e o anexe à saída <code><div></code>, que selecionamos usando <code>var output = document.querySelector('.output');</code>. Nos comentários, nós providenciamos a você três linhas de código que precisam ser usadas em algum lugar dentro do loop: + <ul> + <li><code>var para = document.createElement('p');</code> — cria um novo parágrafo.</li> + <li><code>output.appendChild(para);</code> — anexa o parágrafo à saída <code><div></code>.</li> + <li><code>para.textContent =</code> — faz o texto dentro do parágrafo ser igual ao que você coloca do lado direito, depois do sinal de igual.</li> + </ul> + </li> + <li>Números de iteração diferentes exigem que texto diferente seja inserido no parágrafo para essa iteração (você precisará de uma declaração condicional e várias linhas <code>para.textContent =</code> ): + <ul> + <li>Se o número é 10, imprima "Contagem regressiva 10" no parágrafo.</li> + <li>Se o número é 0, imprima "Lançar!" no parágrafo.</li> + <li>Para qualquer outro número, apenas o imprima no parágrafo.</li> + </ul> + </li> + <li>Lembre-se de incluir um iterador! No entanto, neste exemplo, estamos em contagem regressiva após cada iteração, e não progressiva, então você não vai querer usar <code>i++</code> — como você itera para baixo?</li> +</ul> + +<p>Se você cometer um erro, sempre poderá redefinir o exemplo com o botão "Reset". Se você realmente ficar preso, pressione "Show solution" para ver uma solução.</p> + +<div class="hidden"> +<h6 id="Active_learning">Active learning</h6> + +<pre class="brush: html"><h2>Live output</h2> +<div class="output" style="height: 410px;overflow: auto;"> + +</div> + +<h2>Editable code</h2> +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> +<textarea id="code" class="playable-code" style="height: 300px;width: 95%"> +var output = document.querySelector('.output'); +output.innerHTML = ''; + +// var i = 10; + +// var para = document.createElement('p'); +// para.textContent = ; +// output.appendChild(para); +</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<p class="brush: js"></p> + +<p class="brush: js"></p> + +<p class="brush: js"></p> + +<pre class="brush: css">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +}</pre> + +<p class="brush: js"></p> + +<p class="brush: js"></p> + +<p class="brush: js"></p> + +<p class="brush: js"></p> + +<pre class="brush: js">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; +var userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +var jsSolution = 'var output = document.querySelector(\'.output\');\noutput.innerHTML = \'\';\n\nvar i = 10;\n\nwhile(i >= 0) {\n var para = document.createElement(\'p\');\n if(i === 10) {\n para.textContent = \'Contagem regressiva \' + i;\n } else if(i === 0) {\n para.textContent = \'Lançar!\';\n } else {\n para.textContent = i;\n }\n\n output.appendChild(para);\n\n i--;\n}'; +var solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + var scrollPos = textarea.scrollTop; + var caretPos = textarea.selectionStart; + + var front = (textarea.value).substring(0, caretPos); + var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> + +<p class="brush: js"></p> +</div> + +<p>{{ EmbedLiveSample('Active_learning', '100%', 880, "", "", "hide-codepen-jsfiddle") }}</p> + +<h2 id="Aprendizado_ativo_preenchendo_uma_lista_de_convidados">Aprendizado ativo: preenchendo uma lista de convidados</h2> + +<p>Nesse exercício, nós queremos que você pegue uma lista de nomes armazenados em um array, e os coloque em uma lista de convidados. Mas não tão fácil — nós não queremos que Phil e Lola estejam nela porque eles são gananciosos e rudes, e sempre comem a comida toda! Nós temos duas listas, uma para convidados aceitos, e uma para convidados recusados.</p> + +<p>Especificamente, nós queremos que você:</p> + +<ul> + <li>Escreva um loop que iterará de 0 até o comprimento do array <code>people</code>. Você precisará começar com um inicializador de <code>var i = 0;</code>, Mas qual condição de saída você precisa?</li> + <li>Durante cada iteração de loop, verifique se o item atual do array é igual a "Phil" ou "Lola" usando uma declaração condicional: + <ul> + <li>Se for, concatene o item do array no final do <code>textContent</code> do paragrafo <code>refused</code>, seguido por uma vírgula e um espaço.</li> + <li>Se não for, concatene o item do array no final do <code>textContent</code> do paragrafo <code>admitted</code>, seguido por uma vírgula e um espaço.</li> + </ul> + </li> +</ul> + +<p>Nós já fornecemos a você:</p> + +<ul> + <li><code>var i = 0;</code> — Seu inicializador.</li> + <li><code>refused.textContent +=</code> — o início de uma linha que concatenará algo no final de <code>refused.textContent</code>.</li> + <li><code>admitted.textContent +=</code> — o início de uma linha que concatenará algo no final de <code>admitted.textContent</code>.</li> +</ul> + +<p>Questão bônus extra — depois de completar as tarefas acima com sucesso, você terá duas listas de nomes, separados por vírgulas, mas eles estarão desarrumados — haverá uma vírgula no final decada um. Você pode descobrir como escrever linhas que que cortam a última vírgula em cada caso, e adicionar um ponto final? Dê uma olhada no artigo <a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods">Métodos úteis de string</a> para ajuda.</p> + +<p>Se você cometer um erro, sempre poderá redefinir o exemplo com o botão "Reset". Se você realmente ficar preso, pressione "Show solution" para ver uma solução.</p> + +<div class="hidden"> +<h6 id="Active_learning_2">Active learning 2</h6> + +<pre class="brush: html"><h2>Live output</h2> +<div class="output" style="height: 100px;overflow: auto;"> + <p class="admitted">Admit: </p> + <p class="refused">Refuse: </p> +</div> + +<h2>Editable code</h2> +<p class="a11y-label">Press Esc to move focus away from the code area (Tab inserts a tab character).</p> +<textarea id="code" class="playable-code" style="height: 400px;width: 95%"> +var people = ['Chris', 'Anne', 'Colin', 'Terri', 'Phil', 'Lola', 'Sam', 'Kay', 'Bruce']; + +var admitted = document.querySelector('.admitted'); +var refused = document.querySelector('.refused'); +admitted.textContent = 'Admit: '; +refused.textContent = 'Refuse: ' + +// var i = 0; + +// refused.textContent += ; +// admitted.textContent += ; + +</textarea> + +<div class="playable-buttons"> + <input id="reset" type="button" value="Reset"> + <input id="solution" type="button" value="Show solution"> +</div> +</pre> + +<pre class="brush: css">html { + font-family: sans-serif; +} + +h2 { + font-size: 16px; +} + +.a11y-label { + margin: 0; + text-align: right; + font-size: 0.7rem; + width: 98%; +} + +body { + margin: 10px; + background: #f5f9fa; +}</pre> + +<pre class="brush: js">var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var solution = document.getElementById('solution'); +var code = textarea.value; +var userEntry = textarea.value; + +function updateCode() { + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + userEntry = textarea.value; + solutionEntry = jsSolution; + solution.value = 'Show solution'; + updateCode(); +}); + +solution.addEventListener('click', function() { + if(solution.value === 'Show solution') { + textarea.value = solutionEntry; + solution.value = 'Hide solution'; + } else { + textarea.value = userEntry; + solution.value = 'Show solution'; + } + updateCode(); +}); + +var jsSolution = 'var people = [\'Chris\', \'Anne\', \'Colin\', \'Terri\', \'Phil\', \'Lola\', \'Sam\', \'Kay\', \'Bruce\'];\n\nvar admitted = document.querySelector(\'.admitted\');\nvar refused = document.querySelector(\'.refused\');\n\nadmitted.textContent = \'Admit: \';\nrefused.textContent = \'Refuse: \'\nvar i = 0;\n\ndo {\n if(people[i] === \'Phil\' || people[i] === \'Lola\') {\n refused.textContent += people[i] + \', \';\n } else {\n admitted.textContent += people[i] + \', \';\n }\n i++;\n} while(i < people.length);\n\nrefused.textContent = refused.textContent.slice(0,refused.textContent.length-2) + \'.\';\nadmitted.textContent = admitted.textContent.slice(0,admitted.textContent.length-2) + \'.\';'; +var solutionEntry = jsSolution; + +textarea.addEventListener('input', updateCode); +window.addEventListener('load', updateCode); + +// stop tab key tabbing out of textarea and +// make it write a tab at the caret position instead + +textarea.onkeydown = function(e){ + if (e.keyCode === 9) { + e.preventDefault(); + insertAtCaret('\t'); + } + + if (e.keyCode === 27) { + textarea.blur(); + } +}; + +function insertAtCaret(text) { + var scrollPos = textarea.scrollTop; + var caretPos = textarea.selectionStart; + + var front = (textarea.value).substring(0, caretPos); + var back = (textarea.value).substring(textarea.selectionEnd, textarea.value.length); + textarea.value = front + text + back; + caretPos = caretPos + text.length; + textarea.selectionStart = caretPos; + textarea.selectionEnd = caretPos; + textarea.focus(); + textarea.scrollTop = scrollPos; +} + +// Update the saved userCode every time the user updates the text area code + +textarea.onkeyup = function(){ + // We only want to save the state when the user code is being shown, + // not the solution, so that solution is not saved over the user code + if(solution.value === 'Show solution') { + userEntry = textarea.value; + } else { + solutionEntry = textarea.value; + } + + updateCode(); +};</pre> +</div> + +<p>{{ EmbedLiveSample('Active_learning_2', '100%', 680, "", "", "hide-codepen-jsfiddle") }}</p> + +<h2 id="Which_loop_type_should_you_use">Which loop type should you use?</h2> + +<p>For basic uses, <code>for</code>, <code>while</code>, and <code>do...while</code> loops are largely interchangeable. They can all be used to solve the same problems, and which one you use will largely depend on your personal preference — which one you find easiest to remember or most intuitive. Let's have a look at them again.</p> + +<p>First <code>for</code>:</p> + +<pre>for (initializer; exit-condition; final-expression) { + // code to run +}</pre> + +<p><code>while</code>:</p> + +<pre>initializer +while (exit-condition) { + // code to run + + final-expression +}</pre> + +<p>and finally <code>do...while</code>:</p> + +<pre>initializer +do { + // code to run + + final-expression +} while (exit-condition)</pre> + +<p>Nós recomendamos o uso do <code>for</code>, pelo menos no começo, já que ele é provavelmente a forma mais fácil de lembrar de tudo — o inicializador, a condição de saída, e a expressão final final tudo fica ordenadamente dentro dos parênteses, então é fácil de ver onde eles estão e para verifcar se você não os esqueceu.</p> + +<div class="note"> +<p><strong>Note</strong>: There are other loop types/features too, which are useful in advanced/specialized situations and beyond the scope of this article. If you want to go further with your loop learning, read our advanced <a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">Loops and iteration guide</a>.</p> +</div> + +<h2 id="Conclusion">Conclusion</h2> + +<p>This article has revealed to you the basic concepts behind, and different options available when, looping code in JavaScript. You should now be clear on why loops are a good mechanism for dealing with repetitive code, and be raring to use them in your own examples!</p> + +<p>If there is anything you didn't understand, feel free to read through the article again, or <a href="/en-US/Learn#Contact_us">contact us</a> to ask for help.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">Loops and iteration in detail</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/for">for statement reference</a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/while">while</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a> references</li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/break">break</a> and <a href="/en-US/docs/Web/JavaScript/Reference/Statements/continue">continue</a> references</li> + <li> + <p class="entry-title"><a href="https://www.impressivewebs.com/javascript-for-loop/">What’s the Best Way to Write a JavaScript For Loop?</a> — some advanced loop best practices</p> + </li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/conditionals","Learn/JavaScript/Building_blocks/Functions", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/building_blocks/return_values/index.html b/files/pt-br/learn/javascript/building_blocks/return_values/index.html new file mode 100644 index 0000000000..39d72a1660 --- /dev/null +++ b/files/pt-br/learn/javascript/building_blocks/return_values/index.html @@ -0,0 +1,168 @@ +--- +title: Valores de retorno de função +slug: Aprender/JavaScript/Elementos_construtivos/Return_values +translation_of: Learn/JavaScript/Building_blocks/Return_values +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Build_your_own_function","Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}</div> + +<p class="summary">Há um último conceito essencial para discutirmos neste curso, para fechar nossa visão das funções — valores de retorno. Algumas funções não retornam um valor significativo após a conclusão, mas outras o fazem, e é importante entender quais são seus valores, como utilizá-los em seu código e como fazer com que suas próprias funções personalizadas retornem valores úteis. Nós vamos cobrir tudo isso abaixo.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos:</th> + <td> + <p>Conhecimento básico de internet, compreenção básica de HTML e CSS, <a href="/en-US/docs/Learn/JavaScript/First_steps">JavaScript primeiros passos</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Funções — reutilizando blocos de código</a>.</p> + </td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Entender os valores de retorno de uma função, e como utilizá-los</td> + </tr> + </tbody> +</table> + +<h2 id="Quais_são_os_valores_de_retorno">Quais são os valores de retorno?</h2> + +<p><strong>Valores de retorno</strong> são exatamente como soam — valores retornados pela função quando são concluídos. Você já conheceu os valores de retorno várias vezes, embora possa não ter pensado neles explicitamente. Vamos voltar para algum código familiar:</p> + +<pre class="brush: js">var myText = 'I am a string'; +var newString = myText.replace('string', 'sausage'); +console.log(newString); +// the replace() string function takes a string, +// replaces one substring with another, and returns +// a new string with the replacement made</pre> + +<p>Nós vimos exatamente este bloco de código em nosso primeiro artigo de função. Estamos invocando a função <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a> na string <code>myText</code> e passando a ela dois parâmetros — a substring para localizar e a substring para substituí-la. Quando essa função é concluída (termina a execução), ela retorna um valor, que é uma nova string com a substituição feita. No código acima, estamos salvando esse valor de retorno como o valor da variável <code>newString</code>.</p> + +<p>Se você observar a página de referência MDN da função de substituição, verá uma seção chamada <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Return_value">Valor de retorno</a>. É muito útil conhecer e entender quais valores são retornados por funções, portanto, tentamos incluir essas informações sempre que possível.</p> + +<p>Algumas funções não retornam um valor de retorno como tal (em nossas páginas de referência, o valor de retorno é listado como <code>void</code> ou <code>undefined</code> em tais casos). Por exemplo, na <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-stage-4.html#L50">função displayMessage()</a> que criamos no artigo anterior, nenhum valor específico é retornado como resultado da função que está sendo chamada. Apenas faz uma caixa aparecer em algum lugar na tela — é isso!</p> + +<p>Geralmente, um valor de retorno é usado onde a função é uma etapa intermediária em um cálculo de algum tipo. Você quer chegar a um resultado final, que envolve alguns valores. Esses valores precisam ser calculados por uma função, que retorna os resultados para que possam ser usados no próximo estágio do cálculo.</p> + +<h3 id="Usando_valores_de_retorno_em_suas_próprias_funções">Usando valores de retorno em suas próprias funções</h3> + +<p>Para retornar um valor de uma função personalizada, você precisa usar ... aguarde por isso ... a palavra-chave <a href="/en-US/docs/Web/JavaScript/Reference/Statements/return">return</a>. Vimos isso em ação recentemente em nosso exemplo <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/loops/random-canvas-circles.html">random-canvas-circles.html</a>. Nossa função <code>draw()</code> desenha 100 círculos aleatórios em algum lugar em um HTML {{htmlelement("canvas")}}:</p> + +<pre class="brush: js">function draw() { + ctx.clearRect(0,0,WIDTH,HEIGHT); + for (var i = 0; i < 100; i++) { + ctx.beginPath(); + ctx.fillStyle = 'rgba(255,0,0,0.5)'; + ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); + ctx.fill(); + } +}</pre> + +<p>Dentro de cada iteração de loop, três chamadas são feitas para a função <code>random()</code> , para gerar um valor aleatório para a coordenada x do círculo atual, coordenada y e raio, respectivamente. A função <code>random()</code> recebe um parâmetro — um número inteiro — e retorna um número aleatório inteiro entre 0 e esse número. Se parece com isso:</p> + +<pre class="brush: js">function randomNumber(number) { + return Math.floor(Math.random()*number); +}</pre> + +<p>Isso pode ser escrito da seguinte maneira:</p> + +<pre class="brush: js">function randomNumber(number) { + var result = Math.floor(Math.random()*number); + return result; +}</pre> + +<p>Mas a primeira versão é mais rápida de escrever e mais compacta.</p> + +<p>Estamos retornando o resultado do cálculo <code>Math.floor(Math.random()*number)</code> cada vez que a função é chamada. Esse valor de retorno aparece no ponto em que a função foi chamada e o código continua. Então, por exemplo, se nós rodássemos a seguinte linha:</p> + +<pre class="brush: js">ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI);</pre> + +<p>e as três chamadas <code>random()</code> retornaram os valores 500, 200 e 35, respectivamente, a linha seria executada como se fosse isso:</p> + +<pre class="brush: js">ctx.arc(500, 200, 35, 0, 2 * Math.PI);</pre> + +<p>As chamadas de função na linha são executadas primeiro e seus valores de retorno substituem as chamadas de função, antes que a própria linha seja executada.</p> + +<h2 id="Aprendizagem_ativa_nossa_própria_função_de_valor_de_retorno">Aprendizagem ativa: nossa própria função de valor de retorno</h2> + +<p>Vamos escrever nossas próprias funções com valores de retorno.</p> + +<ol> + <li>Primeiro de tudo, faça uma cópia local do arquivo <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-library.html">function-library.html</a> do GitHub. Esta é uma página HTML simples contendo um campo de texto {{htmlelement("input")}} e um parágrafo. Há também um elemento {{htmlelement("script")}} no qual armazenamos uma referência a ambos os elementos HTML em duas variáveis. Esta pequena página permitirá que você insira um número na caixa de texto e exiba diferentes números relacionados a ele no parágrafo abaixo.</li> + <li>Vamos adicionar algumas funções úteis para este elemento <code><script></code>. Abaixo das duas linhas existentes de JavaScript, adicione as seguintes definições de função: + <pre class="brush: js">function squared(num) { + return num * num; +} + +function cubed(num) { + return num * num * num; +} + +function factorial(num) { + var x = num; + while (x > 1) { + num *= x-1; + x--; + } + return num; +}</pre> + As funções <code>squared()</code> e <code>cubed()</code> são bastante óbvias — elas retornam o quadrado ou cubo do número dado como um parâmetro. A função <code>factorial()</code> retorna o <a href="https://pt.wikipedia.org/wiki/Fatorial">fatorial</a> do número fornecido.</li> + <li>Em seguida, vamos incluir uma maneira de imprimir informações sobre o número digitado na entrada de texto. Digite o seguinte manipulador de eventos abaixo das funções existentes: + <pre class="brush: js">input.onchange = function() { + var num = input.value; + if (isNaN(num)) { + para.textContent = 'You need to enter a number!'; + } else { + para.textContent = num + ' squared is ' + squared(num) + '. ' + + num + ' cubed is ' + cubed(num) + '. ' + + num + ' factorial is ' + factorial(num) + '.'; + } +}</pre> + + <p>Aqui estamos criando um manipulador de eventos <code>onchange</code> que é executado sempre que o evento de mudança é acionado na entrada de texto — ou seja, quando um novo valor é inserido na entrada de texto e enviado (insira um valor e pressione tab por exemplo). Quando essa função anônima é executada, o valor existente inserido na entrada é armazenado na variável <code>num</code>.</p> + + <p>Em seguida, fazemos um teste condicional — se o valor inserido não for um número, imprimiremos uma mensagem de erro no parágrafo. O teste analisa se a expressão <code>isNaN(num)</code> retorna true. Usamos a função <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN">isNaN()</a> para testar se o valor num não é um número — se for, retorna <code>true</code>, e, se não, <code>false</code>.</p> + + <p>Se o teste retorna <code>false</code>, o valor <code>num</code> é um número, então imprimimos uma frase dentro do elemento de parágrafo informando o que é o quadrado, o cubo e o fatorial do número. A sentença chama as funções <code>squared()</code>, <code>cubed()</code>, e <code>factorial()</code> para obter os valores necessários.</p> + </li> + <li>Salve seu código, carregue-o em um navegador e experimente.</li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>: Se você tiver problemas para fazer o exemplo funcionar, sinta-se à vontade para verificar seu código na <a href="https://github.com/mdn/learning-area/blob/master/javascript/building-blocks/functions/function-library-finished.html">versão finalizada no GitHub</a> (<a href="http://mdn.github.io/learning-area/javascript/building-blocks/functions/function-library-finished.html">consulte também sua execução</a>), ou peça ajuda.</p> +</div> + +<p>Neste ponto, gostaríamos que você escrevesse algumas funções e as adicionasse à biblioteca. Como sobre o quadrado ou raiz cúbica do número, ou a circunferência de um círculo com um raio de comprimento <code>num</code>?</p> + +<p>Este exercício trouxe alguns pontos importantes além de ser um estudo sobre como usar a declaração de <code>return</code>. Além disso, temos:</p> + +<ul> + <li>Analisamos outro exemplo de como escrever erros em nossas funções. Geralmente, é uma boa ideia verificar se os parâmetros necessários foram fornecidos e, no tipo de dados correto, e se eles são opcionais, que algum tipo de valor padrão é fornecido para permitir isso. Desta forma, o seu programa terá menos probabilidade de lançar erros.</li> + <li>Pense na ideia de criar uma biblioteca de funções. À medida que você avança na sua carreira de programação, você começará a fazer o mesmo tipo de coisas uma e outra vez. É uma boa idéia começar a manter sua própria biblioteca de funções utilitárias que você usa com muita frequência — você pode então copiá-las para o seu novo código, ou até mesmo aplicá-las a qualquer página HTML onde você precisar.</li> +</ul> + +<h2 id="Conclusão">Conclusão</h2> + +<p>Então, temos isso — funções são divertidas, muito úteis e, embora haja muito o que falar em relação à sua sintaxe e funcionalidade, bastante compreensíveis, dados os artigos certos para se estudar.</p> + +<p>Se houver algo que você não entendeu, fique à vontade para ler o artigo novamente ou entre em <a href="/en-US/Learn#Contact_us">contato conosco</a> para pedir ajuda.</p> + +<h2 id="Veja_também">Veja também</h2> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions">Funções detalhadas</a> — um guia detalhado cobrindo informações relacionadas a funções mais avançadas.</li> + <li><a href="https://www.impressivewebs.com/callback-functions-javascript/">Funções de retorno de chamada em JavaScript</a> — um padrão JavaScript comum é passar uma função para outra função como um argumento, que é então chamado dentro da primeira função. Isso está um pouco além do escopo deste curso, mas vale a pena ser estudado em pouco tempo.</li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Building_blocks/Build_your_own_function","Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">Making decisions in your code — conditionals</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">Looping code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">Functions — reusable blocks of code</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">Build your own function</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">Function return values</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Image_gallery">Image gallery</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/client-side_web_apis/client-side_storage/index.html b/files/pt-br/learn/javascript/client-side_web_apis/client-side_storage/index.html new file mode 100644 index 0000000000..ce4d3c2a20 --- /dev/null +++ b/files/pt-br/learn/javascript/client-side_web_apis/client-side_storage/index.html @@ -0,0 +1,778 @@ +--- +title: Client-side storage +slug: Aprender/JavaScript/Client-side_web_APIs/Client-side_storage +translation_of: Learn/JavaScript/Client-side_web_APIs/Client-side_storage +--- +<p>{{LearnSidebar}}</p> + +<div>{{PreviousMenu("Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs", "Learn/JavaScript/Client-side_web_APIs")}}</div> + +<p class="summary">Os navegadores modernos oferecem suporte a várias maneiras de os sites armazenarem dados no computador do usuário - com a permissão do usuário - e depois recuperá-los quando necessário. Isso permite que você mantenha dados para armazenamento de longo prazo, salve sites ou documentos para uso offline, retenha configurações específicas do usuário para seu site e muito mais. Este artigo explica os princípios básicos de como eles funcionam.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos:</th> + <td>Noções básicas de JavaScript (consulte as <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps">primeiras etapas </a><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps"> </a>, <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks">blocos de construção</a> , <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects">objetos JavaScript</a> ), as <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">noções básicas de APIs do lado do cliente</a></td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Para aprender como usar APIs de armazenamento do lado do cliente para armazenar dados de aplicativos</td> + </tr> + </tbody> +</table> + +<h2 id="Armazenamento_do_lado_do_cliente">Armazenamento do lado do cliente?</h2> + +<p>Em outro lugar na área de aprendizagem MDN, falamos sobre a diferença entre <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview#Static_sites">sites estáticos</a> e <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Server-side/First_steps/Client-Server_overview#Dynamic_sites">sites dinâmicos</a> . A maioria dos principais sites modernos são dinâmicos - eles armazenam dados no servidor usando algum tipo de banco de dados (armazenamento do lado do servidor) e, em seguida, executam o código do <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/Server-side">lado do servidor</a> para recuperar os dados necessários, inserem-nos em modelos de página estática e fornecem o HTML resultante para o cliente a ser exibido pelo navegador do usuário.er.</p> + +<p>O armazenamento do lado do cliente funciona em princípios semelhantes, mas tem usos diferentes. Consiste em APIs JavaScript que permitem armazenar dados no cliente (ou seja, na máquina do usuário) e recuperá-los quando necessário. Isso tem muitos usos distintos, como:</p> + +<ul> + <li>Personalizar as preferências do site (por exemplo, mostrar a escolha do usuário de widgets personalizados, esquema de cores ou tamanho da fonte).</li> + <li>Atividade anterior persistente do site (por exemplo, armazenar o conteúdo de um carrinho de compras de uma sessão anterior, lembrando se um usuário estava conectado anteriormente).</li> + <li>Salvar dados e ativos localmente para que o download de um site seja mais rápido (e potencialmente mais barato) ou possa ser usado sem uma conexão de rede.</li> + <li>Salvar documentos gerados por aplicativos da web localmente para uso offline</li> +</ul> + +<p>Freqüentemente, o armazenamento do lado do cliente e do lado do servidor são usados juntos. Por exemplo, você pode baixar um lote de arquivos de música (talvez usados por um jogo da web ou aplicativo de reprodutor de música), armazená-los em um banco de dados do cliente e reproduzi-los conforme necessário. O usuário só teria que baixar os arquivos de música uma vez - em visitas subsequentes, eles seriam recuperados do banco de dados.</p> + +<div class="note"> +<p><strong>Nota</strong> : Existem limites para a quantidade de dados que você pode armazenar usando APIs de armazenamento do lado do cliente (possivelmente por API individual e cumulativamente); o limite exato varia dependendo do navegador e, possivelmente, com base nas configurações do usuário. Consulte <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Browser_storage_limits_and_eviction_criteria">Limites de armazenamento do navegador e critérios de despejo</a> para obter mais informações..</p> +</div> + +<h3 id="Old_school_Cookies">Old school: Cookies</h3> + +<p>The concept of client-side storage has been around for <strong>Nota</strong> : Existem limites para a quantidade de dados que você pode armazenar usando APIs de armazenamento do lado do cliente (possivelmente por API individual e cumulativamente); o limite exato varia dependendo do navegador e, possivelmente, com base nas configurações do usuário. Consultea long time. Since the early days of the web, sites have used <a href="/en-US/docs/Web/HTTP/Cookies">cookies</a> to store information to personalize user experience on websites. They're the earliest form of client-side storage commonly used on the web.</p> + +<p>These days, there are easier mechanisms available for storing client-side data, therefore we won't be teaching you how to use cookies in this article. However, this does not mean cookies are completely useless on the modern-day web — they are still used commonly to store data related to user personalization and state, e.g. session IDs and access tokens. For more information on cookies see our <a href="/en-US/docs/Web/HTTP/Cookies">Using HTTP cookies</a> article.</p> + +<h3 id="New_school_Web_Storage_and_IndexedDB">New school: Web Storage and IndexedDB</h3> + +<p>The "easier" features we mentioned above are as follows:</p> + +<ul> + <li>The <a href="/en-US/docs/Web/API/Web_Storage_API">Web Storage API</a> provides a very simple syntax for storing and retrieving smaller, data items consisting of a name and a corresponding value. This is useful when you just need to store some simple data, like the user's name, whether they are logged in, what color to use for the background of the screen, etc.</li> + <li>The <a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB API</a> provides the browser with a complete database system for storing complex data. This can be used for things from complete sets of customer records to even complex data types like audio or video files.</li> +</ul> + +<p>You'll learn more about these APIs below.</p> + +<h3 id="The_future_Cache_API">The future: Cache API</h3> + +<p>Some modern browsers support the new {{domxref("Cache")}} API. This API is designed for storing HTTP responses to specific requests, and is very useful for doing things like storing website assets offline so the site can subsequently be used without a network connection. Cache is usually used in combination with the <a href="/en-US/docs/Web/API/Service_Worker_API">Service Worker API</a>, although it doesn't have to be.</p> + +<p>Use of Cache and Service Workers is an advanced topic, and we won't be covering it in great detail in this article, although we will show a simple example in the {{anch("Offline asset storage")}} section below.</p> + +<h2 id="Storing_simple_data_—_web_storage">Storing simple data — web storage</h2> + +<p>The <a href="/en-US/docs/Web/API/Web_Storage_API">Web Storage API</a> is very easy to use — you store simple name/value pairs of data (limited to strings, numbers, etc.) and retrieve these values when needed.</p> + +<h3 id="Basic_syntax">Basic syntax</h3> + +<p>Let's show you how:</p> + +<ol> + <li> + <p>First, go to our <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/web-storage/index.html">web storage blank template</a> on GitHub (open this in a new tab).</p> + </li> + <li> + <p>Open the JavaScript console of your browser's developer tools.</p> + </li> + <li> + <p>All of your web storage data is contained within two object-like structures inside the browser: {{domxref("Window.sessionStorage", "sessionStorage")}} and {{domxref("Window.localStorage", "localStorage")}}. The first one persists data for as long as the browser is open (the data is lost when the browser is closed) and the second one persists data even after the browser is closed and then opened again. We'll use the second one in this article as it is generally more useful.</p> + + <p>The {{domxref("Storage.setItem()")}} method allows you to save a data item in storage — it takes two parameters: the name of the item, and its value. Try typing this into your JavaScript console (change the value to your own name, if you wish!):</p> + + <pre class="brush: js notranslate">localStorage.setItem('name','Chris');</pre> + </li> + <li> + <p>The {{domxref("Storage.getItem()")}} method takes one parameter — the name of a data item you want to retrieve — and returns the item's value. Now type these lines into your JavaScript console:</p> + + <pre class="brush: js notranslate">let myName = localStorage.getItem('name'); +myName</pre> + + <p>Upon typing in the second line, you should see that the <code>myName</code> variable now contains the value of the <code>name</code> data item.</p> + </li> + <li> + <p>The {{domxref("Storage.removeItem()")}} method takes one parameter — the name of a data item you want to remove — and removes that item out of web storage. Type the following lines into your JavaScript console:</p> + + <pre class="brush: js notranslate">localStorage.removeItem('name'); +let myName = localStorage.getItem('name'); +myName</pre> + + <p>The third line should now return <code>null</code> — the <code>name</code> item no longer exists in the web storage.</p> + </li> +</ol> + +<h3 id="The_data_persists!">The data persists!</h3> + +<p>One key feature of web storage is that the data persists between page loads (and even when the browser is shut down, in the case of <code>localStorage</code>). Let's look at this in action.</p> + +<ol> + <li> + <p>Open our web storage blank template again, but this time in a different browser to the one you've got this tutorial open in! This will make it easier to deal with.</p> + </li> + <li> + <p>Type these lines into the browser's JavaScript console:</p> + + <pre class="brush: js notranslate">localStorage.setItem('name','Chris'); +let myName = localStorage.getItem('name'); +myName</pre> + + <p>You should see the name item returned.</p> + </li> + <li> + <p>Now close down the browser and open it up again.</p> + </li> + <li> + <p>Enter the following lines again:</p> + + <pre class="brush: js notranslate">let myName = localStorage.getItem('name'); +myName</pre> + + <p>You should see that the value is still available, even though the browser has been closed and then opened again.</p> + </li> +</ol> + +<h3 id="Separate_storage_for_each_domain">Separate storage for each domain</h3> + +<p>There is a separate data store for each domain (each separate web address loaded in the browser). You will see that if you load two websites (say google.com and amazon.com) and try storing an item on one website, it won't be available to the other website.</p> + +<p>This makes sense — you can imagine the security issues that would arise if websites could see each other's data!</p> + +<h3 id="A_more_involved_example">A more involved example</h3> + +<p>Let's apply this new-found knowledge by writing a simple working example to give you an idea of how web storage can be used. Our example will allow you enter a name, after which the page will update to give you a personalized greeting. This state will also persist across page/browser reloads, because the name is stored in web storage.</p> + +<p>You can find the example HTML at <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/web-storage/personal-greeting.html">personal-greeting.html</a> — this contains a simple website with a header, content, and footer, and a form for entering your name.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/15735/web-storage-demo.png" style="display: block; margin: 0 auto;"></p> + +<p>Let's build up the example, so you can understand how it works.</p> + +<ol> + <li> + <p>First, make a local copy of our <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/web-storage/personal-greeting.html">personal-greeting.html</a> file in a new directory on your computer.</p> + </li> + <li> + <p>Next, note how our HTML references a JavaScript file called <code>index.js</code> (see line 40). We need to create this and write our JavaScript code into it. Create an <code>index.js</code> file in the same directory as your HTML file. </p> + </li> + <li> + <p>We'll start off by creating references to all the HTML features we need to manipulate in this example — we'll create them all as constants, as these references do not need to change in the lifecycle of the app. Add the following lines to your JavaScript file:</p> + + <pre class="brush: js notranslate">// create needed constants +const rememberDiv = document.querySelector('.remember'); +const forgetDiv = document.querySelector('.forget'); +const form = document.querySelector('form'); +const nameInput = document.querySelector('#entername'); +const submitBtn = document.querySelector('#submitname'); +const forgetBtn = document.querySelector('#forgetname'); + +const h1 = document.querySelector('h1'); +const personalGreeting = document.querySelector('.personal-greeting');</pre> + </li> + <li> + <p>Next up, we need to include a small event listener to stop the form from actually submitting itself when the submit button is pressed, as this is not the behavior we want. Add this snippet below your previous code:</p> + + <pre class="brush: js notranslate">// Stop the form from submitting when a button is pressed +form.addEventListener('submit', function(e) { + e.preventDefault(); +});</pre> + </li> + <li> + <p>Now we need to add an event listener, the handler function of which will run when the "Say hello" button is clicked. The comments explain in detail what each bit does, but in essence here we are taking the name the user has entered into the text input box and saving it in web storage using <code>setItem()</code>, then running a function called <code>nameDisplayCheck()</code> that will handle updating the actual website text. Add this to the bottom of your code:</p> + + <pre class="brush: js notranslate">// run function when the 'Say hello' button is clicked +submitBtn.addEventListener('click', function() { + // store the entered name in web storage + localStorage.setItem('name', nameInput.value); + // run nameDisplayCheck() to sort out displaying the + // personalized greetings and updating the form display + nameDisplayCheck(); +});</pre> + </li> + <li> + <p>At this point we also need an event handler to run a function when the "Forget" button is clicked — this is only displayed after the "Say hello" button has been clicked (the two form states toggle back and forth). In this function we remove the <code>name</code> item from web storage using <code>removeItem()</code>, then again run <code>nameDisplayCheck()</code> to update the display. Add this to the bottom:</p> + + <pre class="brush: js notranslate">// run function when the 'Forget' button is clicked +forgetBtn.addEventListener('click', function() { + // Remove the stored name from web storage + localStorage.removeItem('name'); + // run nameDisplayCheck() to sort out displaying the + // generic greeting again and updating the form display + nameDisplayCheck(); +});</pre> + </li> + <li> + <p>It is now time to define the <code>nameDisplayCheck()</code> function itself. Here we check whether the name item has been stored in web storage by using <code>localStorage.getItem('name')</code> as a conditional test. If it has been stored, this call will evaluate to <code>true</code>; if not, it will be <code>false</code>. If it is <code>true</code>, we display a personalized greeting, display the "forget" part of the form, and hide the "Say hello" part of the form. If it is <code>false</code>, we display a generic greeting and do the opposite. Again, put the following code at the bottom:</p> + + <pre class="brush: js notranslate">// define the nameDisplayCheck() function +function nameDisplayCheck() { + // check whether the 'name' data item is stored in web Storage + if(localStorage.getItem('name')) { + // If it is, display personalized greeting + let name = localStorage.getItem('name'); + h1.textContent = 'Welcome, ' + name; + personalGreeting.textContent = 'Welcome to our website, ' + name + '! We hope you have fun while you are here.'; + // hide the 'remember' part of the form and show the 'forget' part + forgetDiv.style.display = 'block'; + rememberDiv.style.display = 'none'; + } else { + // if not, display generic greeting + h1.textContent = 'Welcome to our website '; + personalGreeting.textContent = 'Welcome to our website. We hope you have fun while you are here.'; + // hide the 'forget' part of the form and show the 'remember' part + forgetDiv.style.display = 'none'; + rememberDiv.style.display = 'block'; + } +}</pre> + </li> + <li> + <p>Last but not least, we need to run the <code>nameDisplayCheck()</code> function every time the page is loaded. If we don't do this, then the personalized greeting will not persist across page reloads. Add the following to the bottom of your code:</p> + + <pre class="brush: js notranslate">document.body.onload = nameDisplayCheck;</pre> + </li> +</ol> + +<p>Your example is finished — well done! All that remains now is to save your code and test your HTML page in a browser. You can see our <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/web-storage/personal-greeting.html">finished version running live here</a>.</p> + +<div class="note"> +<p><strong>Note</strong>: There is another, slightly more complex example to explore at <a href="/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API">Using the Web Storage API</a>.</p> +</div> + +<div class="note"> +<p><strong>Note</strong>: In the line <code><script src="index.js" defer></script></code> of the source for our finished version, the <code>defer</code> attribute specifies that the contents of the {{htmlelement("script")}} element will not execute until the page has finished loading.</p> +</div> + +<h2 id="Storing_complex_data_—_IndexedDB">Storing complex data — IndexedDB</h2> + +<p>The <a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB API</a> (sometimes abbreviated IDB) is a complete database system available in the browser in which you can store complex related data, the types of which aren't limited to simple values like strings or numbers. You can store videos, images, and pretty much anything else in an IndexedDB instance.</p> + +<p>However, this does come at a cost: IndexedDB is much more complex to use than the Web Storage API. In this section, we'll really only scratch the surface of what it is capable of, but we will give you enough to get started.</p> + +<h3 id="Working_through_a_note_storage_example">Working through a note storage example</h3> + +<p>Here we'll run you through an example that allows you to store notes in your browser and view and delete them whenever you like, getting you to build it up for yourself and explaining the most fundamental parts of IDB as we go along.</p> + +<p>The app looks something like this:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/15744/idb-demo.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p> + +<p>Each note has a title and some body text, each individually editable. The JavaScript code we'll go through below has detailed comments to help you understand what's going on.</p> + +<h3 id="Getting_started">Getting started</h3> + +<ol> + <li>First of all, make local copies of our <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/notes/index.html">index.html</a></code>, <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/notes/style.css">style.css</a></code>, and <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/notes/index-start.js">index-start.js</a></code> files into a new directory on your local machine.</li> + <li>Have a look at the files. You'll see that the HTML is pretty simple: a web site with a header and footer, as well as a main content area that contains a place to display notes, and a form for entering new notes into the database. The CSS provides some simple styling to make it clearer what is going on. The JavaScript file contains five declared constants containing references to the {{htmlelement("ul")}} element the notes will be displayed in, the title and body {{htmlelement("input")}} elements, the {{htmlelement("form")}} itself, and the {{htmlelement("button")}}.</li> + <li>Rename your JavaScript file to <code>index.js</code>. You are now ready to start adding code to it.</li> +</ol> + +<h3 id="Database_initial_set_up">Database initial set up</h3> + +<p>Now let's look at what we have to do in the first place, to actually set up a database.</p> + +<ol> + <li> + <p>Below the constant declarations, add the following lines:</p> + + <pre class="brush: js notranslate">// Create an instance of a db object for us to store the open database in +let db;</pre> + + <p>Here we are declaring a variable called <code>db</code> — this will later be used to store an object representing our database. We will use this in a few places, so we've declared it globally here to make things easier.</p> + </li> + <li> + <p>Next, add the following to the bottom of your code:</p> + + <pre class="brush: js notranslate">window.onload = function() { + +};</pre> + + <p>We will write all of our subsequent code inside this <code>window.onload</code> event handler function, called when the window's {{event("load")}} event fires, to make sure we don't try to use IndexedDB functionality before the app has completely finished loading (it could fail if we don't).</p> + </li> + <li> + <p>Inside the <code>window.onload</code> handler, add the following:</p> + + <pre class="brush: js notranslate">// Open our database; it is created if it doesn't already exist +// (see onupgradeneeded below) +let request = window.indexedDB.open('notes_db', 1);</pre> + + <p>This line creates a <code>request</code> to open version <code>1</code> of a database called <code>notes_db</code>. If this doesn't already exist, it will be created for you by subsequent code. You will see this request pattern used very often throughout IndexedDB. Database operations take time. You don't want to hang the browser while you wait for the results, so database operations are {{Glossary("asynchronous")}}, meaning that instead of happening immediately, they will happen at some point in the future, and you get notified when they're done.</p> + + <p>To handle this in IndexedDB, you create a request object (which can be called anything you like — we called it <code>request</code> so it is obvious what it is for). You then use event handlers to run code when the request completes, fails, etc., which you'll see in use below.</p> + + <div class="note"> + <p><strong>Note</strong>: The version number is important. If you want to upgrade your database (for example, by changing the table structure), you have to run your code again with an increased version number, different schema specified inside the <code>onupgradeneeded</code> handler (see below), etc. We won't cover upgrading databases in this simple tutorial.</p> + </div> + </li> + <li> + <p>Now add the following event handlers just below your previous addition — again inside the <code>window.onload</code> handler:</p> + + <pre class="brush: js notranslate">// onerror handler signifies that the database didn't open successfully +request.onerror = function() { + console.log('Database failed to open'); +}; + +// onsuccess handler signifies that the database opened successfully +request.onsuccess = function() { + console.log('Database opened successfully'); + + // Store the opened database object in the db variable. This is used a lot below + db = request.result; + + // Run the displayData() function to display the notes already in the IDB + displayData(); +};</pre> + + <p>The {{domxref("IDBRequest.onerror", "request.onerror")}} handler will run if the system comes back saying that the request failed. This allows you to respond to this problem. In our simple example, we just print a message to the JavaScript console.</p> + + <p>The {{domxref("IDBRequest.onsuccess", "request.onsuccess")}} handler on the other hand will run if the request returns successfully, meaning the database was successfully opened. If this is the case, an object representing the opened database becomes available in the {{domxref("IDBRequest.result", "request.result")}} property, allowing us to manipulate the database. We store this in the <code>db</code> variable we created earlier for later use. We also run a custom function called <code>displayData()</code>, which displays the data in the database inside the {{HTMLElement("ul")}}. We run it now so that the notes already in the database are displayed as soon as the page loads. You'll see this defined later on.</p> + </li> + <li> + <p>Finally for this section, we'll add probably the most important event handler for setting up the database: {{domxref("IDBOpenDBRequest.onupgradeneeded", "request.onupgradeneeded")}}. This handler runs if the database has not already been set up, or if the database is opened with a bigger version number than the existing stored database (when performing an upgrade). Add the following code, below your previous handler:</p> + + <pre class="brush: js notranslate">// Setup the database tables if this has not already been done +request.onupgradeneeded = function(e) { + // Grab a reference to the opened database + let db = e.target.result; + + // Create an objectStore to store our notes in (basically like a single table) + // including a auto-incrementing key + let objectStore = db.createObjectStore('notes_os', { keyPath: 'id', autoIncrement:true }); + + // Define what data items the objectStore will contain + objectStore.createIndex('title', 'title', { unique: false }); + objectStore.createIndex('body', 'body', { unique: false }); + + console.log('Database setup complete'); +};</pre> + + <p>This is where we define the schema (structure) of our database; that is, the set of columns (or fields) it contains. Here we first grab a reference to the existing database from the <code>result</code> property of the event's target (<code>e.target.result</code>), which is the <code>request</code> object. This is equivalent to the line <code>db = request.result;</code> inside the <code>onsuccess</code> handler, but we need to do this separately here because the <code>onupgradeneeded</code> handler (if needed) will run before the <code>onsuccess</code> handler, meaning that the <code>db</code> value wouldn't be available if we didn't do this.</p> + + <p>We then use {{domxref("IDBDatabase.createObjectStore()")}} to create a new object store inside our opened database called <code>notes_os</code>. This is equivalent to a single table in a conventional database system. We've given it the name notes, and also specified an <code>autoIncrement</code> key field called <code>id</code> — in each new record this will automatically be given an incremented value — the developer doesn't need to set this explicitly. Being the key, the <code>id</code> field will be used to uniquely identify records, such as when deleting or displaying a record.</p> + + <p>We also create two other indexes (fields) using the {{domxref("IDBObjectStore.createIndex()")}} method: <code>title</code> (which will contain a title for each note), and <code>body</code> (which will contain the body text of the note).</p> + </li> +</ol> + +<p>So with this simple database schema set up, when we start adding records to the database; each one will be represented as an object along these lines:</p> + +<pre class="brush: js notranslate">{ + title: "Buy milk", + body: "Need both cows milk and soy.", + id: 8 +}</pre> + +<h3 id="Adding_data_to_the_database">Adding data to the database</h3> + +<p>Now let's look at how we can add records to the database. This will be done using the form on our page.</p> + +<p>Below your previous event handler (but still inside the <code>window.onload</code> handler), add the following line, which sets up an <code>onsubmit</code> handler that runs a function called <code>addData()</code> when the form is submitted (when the submit {{htmlelement("button")}} is pressed leading to a successful form submission):</p> + +<pre class="brush: js notranslate">// Create an onsubmit handler so that when the form is submitted the addData() function is run +form.onsubmit = addData;</pre> + +<p>Now let's define the <code>addData()</code> function. Add this below your previous line:</p> + +<pre class="brush: js notranslate">// Define the addData() function +function addData(e) { + // prevent default - we don't want the form to submit in the conventional way + e.preventDefault(); + + // grab the values entered into the form fields and store them in an object ready for being inserted into the DB + let newItem = { title: titleInput.value, body: bodyInput.value }; + + // open a read/write db transaction, ready for adding the data + let transaction = db.transaction(['notes_os'], 'readwrite'); + + // call an object store that's already been added to the database + let objectStore = transaction.objectStore('notes_os'); + + // Make a request to add our newItem object to the object store + let request = objectStore.add(newItem); + request.onsuccess = function() { + // Clear the form, ready for adding the next entry + titleInput.value = ''; + bodyInput.value = ''; + }; + + // Report on the success of the transaction completing, when everything is done + transaction.oncomplete = function() { + console.log('Transaction completed: database modification finished.'); + + // update the display of data to show the newly added item, by running displayData() again. + displayData(); + }; + + transaction.onerror = function() { + console.log('Transaction not opened due to error'); + }; +}</pre> + +<p>This is quite complex; breaking it down, we:</p> + +<ul> + <li>Run {{domxref("Event.preventDefault()")}} on the event object to stop the form actually submitting in the conventional manner (this would cause a page refresh and spoil the experience).</li> + <li>Create an object representing a record to enter into the database, populating it with values from the form inputs. note that we don't have to explicitly include an <code>id</code> value — as we explained earlier, this is auto-populated.</li> + <li>Open a <code>readwrite</code> transaction against the <code>notes_os</code> object store using the {{domxref("IDBDatabase.transaction()")}} method. This transaction object allows us to access the object store so we can do something to it, e.g. add a new record.</li> + <li>Access the object store using the {{domxref("IDBTransaction.objectStore()")}} method, saving the result in the <code>objectStore</code> variable.</li> + <li>Add the new record to the database using {{domxref("IDBObjectStore.add()")}}. This creates a request object, in the same fashion as we've seen before.</li> + <li>Add a bunch of event handlers to the <code>request</code> and the <code>transaction</code> to run code at critical points in the lifecycle. Once the request has succeeded, we clear the form inputs ready for entering the next note. Once the transaction has completed, we run the <code>displayData()</code> function again to update the display of notes on the page.</li> +</ul> + +<h3 id="Displaying_the_data">Displaying the data</h3> + +<p>We've referenced <code>displayData()</code> twice in our code already, so we'd probably better define it. Add this to your code, below the previous function definition:</p> + +<pre class="brush: js notranslate">// Define the displayData() function +function displayData() { + // Here we empty the contents of the list element each time the display is updated + // If you didn't do this, you'd get duplicates listed each time a new note is added + while (list.firstChild) { + list.removeChild(list.firstChild); + } + + // Open our object store and then get a cursor - which iterates through all the + // different data items in the store + let objectStore = db.transaction('notes_os').objectStore('notes_os'); + objectStore.openCursor().onsuccess = function(e) { + // Get a reference to the cursor + let cursor = e.target.result; + + // If there is still another data item to iterate through, keep running this code + if(cursor) { + // Create a list item, h3, and p to put each data item inside when displaying it + // structure the HTML fragment, and append it inside the list + const listItem = document.createElement('li'); + const h3 = document.createElement('h3'); + const para = document.createElement('p'); + + listItem.appendChild(h3); + listItem.appendChild(para); + list.appendChild(listItem); + + // Put the data from the cursor inside the h3 and para + h3.textContent = cursor.value.title; + para.textContent = cursor.value.body; + + // Store the ID of the data item inside an attribute on the listItem, so we know + // which item it corresponds to. This will be useful later when we want to delete items + listItem.setAttribute('data-note-id', cursor.value.id); + + // Create a button and place it inside each listItem + const deleteBtn = document.createElement('button'); + listItem.appendChild(deleteBtn); + deleteBtn.textContent = 'Delete'; + + // Set an event handler so that when the button is clicked, the deleteItem() + // function is run + deleteBtn.onclick = deleteItem; + + // Iterate to the next item in the cursor + cursor.continue(); + } else { + // Again, if list item is empty, display a 'No notes stored' message + if(!list.firstChild) { + const listItem = document.createElement('li'); + listItem.textContent = 'No notes stored.'; + list.appendChild(listItem); + } + // if there are no more cursor items to iterate through, say so + console.log('Notes all displayed'); + } + }; +}</pre> + +<p>Again, let's break this down:</p> + +<ul> + <li>First we empty out the {{htmlelement("ul")}} element's content, before then filling it with the updated content. If you didn't do this, you'd end up with a huge list of duplicated content being added to with each update.</li> + <li>Next, we get a reference to the <code>notes_os</code> object store using {{domxref("IDBDatabase.transaction()")}} and {{domxref("IDBTransaction.objectStore()")}} like we did in <code>addData()</code>, except here we are chaining them together in one line.</li> + <li>The next step is to use {{domxref("IDBObjectStore.openCursor()")}} method to open a request for a cursor — this is a construct that can be used to iterate over the records in an object store. We chain an <code>onsuccess</code> handler on to the end of this line to make the code more concise — when the cursor is successfully returned, the handler is run.</li> + <li>We get a reference to the cursor itself (an {{domxref("IDBCursor")}} object) using let <code>cursor = e.target.result</code>.</li> + <li>Next, we check to see if the cursor contains a record from the datastore (<code>if(cursor){ ... }</code>) — if so, we create a DOM fragment, populate it with the data from the record, and insert it into the page (inside the <code><ul></code> element). We also include a delete button that, when clicked, will delete that note by running the <code>deleteItem()</code> function, which we will look at in the next section.</li> + <li>At the end of the <code>if</code> block, we use the {{domxref("IDBCursor.continue()")}} method to advance the cursor to the next record in the datastore, and run the content of the <code>if</code> block again. If there is another record to iterate to, this causes it to be inserted into the page, and then <code>continue()</code> is run again, and so on.</li> + <li>When there are no more records to iterate over, <code>cursor</code> will return <code>undefined</code>, and therefore the <code>else</code> block will run instead of the <code>if</code> block. This block checks whether any notes were inserted into the <code><ul></code> — if not, it inserts a message to say no note was stored.</li> +</ul> + +<h3 id="Deleting_a_note">Deleting a note</h3> + +<p>As stated above, when a note's delete button is pressed, the note is deleted. This is achieved by the <code>deleteItem()</code> function, which looks like so:</p> + +<pre class="brush: js notranslate">// Define the deleteItem() function +function deleteItem(e) { + // retrieve the name of the task we want to delete. We need + // to convert it to a number before trying it use it with IDB; IDB key + // values are type-sensitive. + let noteId = Number(e.target.parentNode.getAttribute('data-note-id')); + + // open a database transaction and delete the task, finding it using the id we retrieved above + let transaction = db.transaction(['notes_os'], 'readwrite'); + let objectStore = transaction.objectStore('notes_os'); + let request = objectStore.delete(noteId); + + // report that the data item has been deleted + transaction.oncomplete = function() { + // delete the parent of the button + // which is the list item, so it is no longer displayed + e.target.parentNode.parentNode.removeChild(e.target.parentNode); + console.log('Note ' + noteId + ' deleted.'); + + // Again, if list item is empty, display a 'No notes stored' message + if(!list.firstChild) { + let listItem = document.createElement('li'); + listItem.textContent = 'No notes stored.'; + list.appendChild(listItem); + } + }; +}</pre> + +<ul> + <li>The first part of this could use some explaining — we retrieve the ID of the record to be deleted using <code>Number(e.target.parentNode.getAttribute('data-note-id'))</code> — recall that the ID of the record was saved in a <code>data-note-id</code> attribute on the <code><li></code> when it was first displayed. We do however need to pass the attribute through the global built-in <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number">Number()</a></code> object as it is of datatype string, and therefore wouldn't be recognized by the database, which expects a number.</li> + <li>We then get a reference to the object store using the same pattern we've seen previously, and use the {{domxref("IDBObjectStore.delete()")}} method to delete the record from the database, passing it the ID.</li> + <li>When the database transaction is complete, we delete the note's <code><li></code> from the DOM, and again do the check to see if the <code><ul></code> is now empty, inserting a note as appropriate.</li> +</ul> + +<p>So that's it! Your example should now work.</p> + +<p>If you are having trouble with it, feel free to <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/indexeddb/notes/">check it against our live example</a> (see the <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/indexeddb/notes/index.js">source code</a> also).</p> + +<h3 id="Storing_complex_data_via_IndexedDB">Storing complex data via IndexedDB</h3> + +<p>As we mentioned above, IndexedDB can be used to store more than just simple text strings. You can store just about anything you want, including complex objects such as video or image blobs. And it isn't much more difficult to achieve than any other type of data.</p> + +<p>To demonstrate how to do it, we've written another example called <a href="https://github.com/mdn/learning-area/tree/master/javascript/apis/client-side-storage/indexeddb/video-store">IndexedDB video store</a> (see it <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/indexeddb/video-store/">running live here also</a>). When you first run the example, it downloads all the videos from the network, stores them in an IndexedDB database, and then displays the videos in the UI inside {{htmlelement("video")}} elements. The second time you run it, it finds the videos in the database and gets them from there instead before displaying them — this makes subsequent loads much quicker and less bandwidth-hungry.</p> + +<p>Let's walk through the most interesting parts of the example. We won't look at it all — a lot of it is similar to the previous example, and the code is well-commented.</p> + +<ol> + <li> + <p>For this simple example, we've stored the names of the videos to fetch in an array of objects:</p> + + <pre class="brush: js notranslate">const videos = [ + { 'name' : 'crystal' }, + { 'name' : 'elf' }, + { 'name' : 'frog' }, + { 'name' : 'monster' }, + { 'name' : 'pig' }, + { 'name' : 'rabbit' } +];</pre> + </li> + <li> + <p>To start with, once the database is successfully opened we run an <code>init()</code> function. This loops through the different video names, trying to load a record identified by each name from the <code>videos</code> database.</p> + + <p>If each video is found in the database (easily checked by seeing whether <code>request.result</code> evaluates to <code>true</code> — if the record is not present, it will be <code>undefined</code>), its video files (stored as blobs) and the video name are passed straight to the <code>displayVideo()</code> function to place them in the UI. If not, the video name is passed to the <code>fetchVideoFromNetwork()</code> function to ... you guessed it — fetch the video from the network.</p> + + <pre class="brush: js notranslate">function init() { + // Loop through the video names one by one + for(let i = 0; i < videos.length; i++) { + // Open transaction, get object store, and get() each video by name + let objectStore = db.transaction('videos_os').objectStore('videos_os'); + let request = objectStore.get(videos[i].name); + request.onsuccess = function() { + // If the result exists in the database (is not undefined) + if(request.result) { + // Grab the videos from IDB and display them using displayVideo() + console.log('taking videos from IDB'); + displayVideo(request.result.mp4, request.result.webm, request.result.name); + } else { + // Fetch the videos from the network + fetchVideoFromNetwork(videos[i]); + } + }; + } +}</pre> + </li> + <li> + <p>The following snippet is taken from inside <code>fetchVideoFromNetwork()</code> — here we fetch MP4 and WebM versions of the video using two separate {{domxref("fetch()", "WindowOrWorkerGlobalScope.fetch()")}} requests. We then use the {{domxref("blob()", "Body.blob()")}} method to extract each response's body as a blob, giving us an object representation of the videos that can be stored and displayed later on.</p> + + <p>We have a problem here though — these two requests are both asynchronous, but we only want to try to display or store the video when both promises have fulfilled. Fortunately there is a built-in method that handles such a problem — {{jsxref("Promise.all()")}}. This takes one argument — references to all the individual promises you want to check for fulfillment placed in an array — and is itself promise-based.</p> + + <p>When all those promises have fulfilled, the <code>all()</code> promise fulfills with an array containing all the individual fulfillment values. Inside the <code>all()</code> block, you can see that we then call the <code>displayVideo()</code> function like we did before to display the videos in the UI, then we also call the <code>storeVideo()</code> function to store those videos inside the database.</p> + + <pre class="brush: js notranslate">let mp4Blob = fetch('videos/' + video.name + '.mp4').then(response => + response.blob() +); +let webmBlob = fetch('videos/' + video.name + '.webm').then(response => + response.blob() +); + +// Only run the next code when both promises have fulfilled +Promise.all([mp4Blob, webmBlob]).then(function(values) { + // display the video fetched from the network with displayVideo() + displayVideo(values[0], values[1], video.name); + // store it in the IDB using storeVideo() + storeVideo(values[0], values[1], video.name); +});</pre> + </li> + <li> + <p>Let's look at <code>storeVideo()</code> first. This is very similar to the pattern you saw in the previous example for adding data to the database — we open a <code>readwrite</code> transaction and get a reference to our <code>videos_os</code> object store, create an object representing the record to add to the database, then simply add it using {{domxref("IDBObjectStore.add()")}}.</p> + + <pre class="brush: js notranslate">function storeVideo(mp4Blob, webmBlob, name) { + // Open transaction, get object store; make it a readwrite so we can write to the IDB + let objectStore = db.transaction(['videos_os'], 'readwrite').objectStore('videos_os'); + // Create a record to add to the IDB + let record = { + mp4 : mp4Blob, + webm : webmBlob, + name : name + } + + // Add the record to the IDB using add() + let request = objectStore.add(record); + + ... + +};</pre> + </li> + <li> + <p>Last but not least, we have <code>displayVideo()</code>, which creates the DOM elements needed to insert the video in the UI and then appends them to the page. The most interesting parts of this are those shown below — to actually display our video blobs in a <code><video></code> element, we need to create object URLs (internal URLs that point to the video blobs stored in memory) using the {{domxref("URL.createObjectURL()")}} method. Once that is done, we can set the object URLs to be the values of our {{htmlelement("source")}} element's <code>src</code> attributes, and it works fine.</p> + + <pre class="brush: js notranslate">function displayVideo(mp4Blob, webmBlob, title) { + // Create object URLs out of the blobs + let mp4URL = URL.createObjectURL(mp4Blob); + let webmURL = URL.createObjectURL(webmBlob); + + ... + + const video = document.createElement('video'); + video.controls = true; + const source1 = document.createElement('source'); + source1.src = mp4URL; + source1.type = 'video/mp4'; + const source2 = document.createElement('source'); + source2.src = webmURL; + source2.type = 'video/webm'; + + ... +}</pre> + </li> +</ol> + +<h2 id="Offline_asset_storage">Offline asset storage</h2> + +<p>The above example already shows how to create an app that will store large assets in an IndexedDB database, avoiding the need to download them more than once. This is already a great improvement to the user experience, but there is still one thing missing — the main HTML, CSS, and JavaScript files still need to be downloaded each time the site is accessed, meaning that it won't work when there is no network connection.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/15759/ff-offline.png" style="border-style: solid; border-width: 1px; display: block; height: 307px; margin: 0px auto; width: 765px;"></p> + +<p>This is where <a href="/en-US/docs/Web/API/Service_Worker_API">Service workers</a> and the closely-related <a href="/en-US/docs/Web/API/Cache">Cache API</a> come in.</p> + +<p>A service worker is a JavaScript file that, simply put, is registered against a particular origin (web site, or part of a web site at a certain domain) when it is accessed by a browser. When registered, it can control pages available at that origin. It does this by sitting between a loaded page and the network and intercepting network requests aimed at that origin.</p> + +<p>When it intercepts a request, it can do anything you wish to it (see <a href="/en-US/docs/Web/API/Service_Worker_API#Other_use_case_ideas">use case ideas</a>), but the classic example is saving the network responses offline and then providing those in response to a request instead of the responses from the network. In effect, it allows you to make a web site work completely offline.</p> + +<p>The Cache API is a another client-side storage mechanism, with a bit of a difference — it is designed to save HTTP responses, and so works very well with service workers.</p> + +<div class="note"> +<p><strong>Note</strong>: Service workers and Cache are supported in most modern browsers now. At the time of writing, Safari was still busy implementing it, but it should be there soon.</p> +</div> + +<h3 id="A_service_worker_example">A service worker example</h3> + +<p>Let's look at an example, to give you a bit of an idea of what this might look like. We have created another version of the video store example we saw in the previous section — this functions identically, except that it also saves the HTML, CSS, and JavaScript in the Cache API via a service worker, allowing the example to run offline!</p> + +<p>See <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/">IndexedDB video store with service worker running live</a>, and also <a href="https://github.com/mdn/learning-area/tree/master/javascript/apis/client-side-storage/cache-sw/video-store-offline">see the source code</a>.</p> + +<h4 id="Registering_the_service_worker">Registering the service worker</h4> + +<p>The first thing to note is that there's an extra bit of code placed in the main JavaScript file (see <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/cache-sw/video-store-offline/index.js">index.js</a>). First we do a feature detection test to see if the <code>serviceWorker</code> member is available in the {{domxref("Navigator")}} object. If this returns true, then we know that at least the basics of service workers are supported. Inside here we use the {{domxref("ServiceWorkerContainer.register()")}} method to register a service worker contained in the <code>sw.js</code> file against the origin it resides at, so it can control pages in the same directory as it, or subdirectories. When its promise fulfills, the service worker is deemed registered.</p> + +<pre class="brush: js notranslate"> // Register service worker to control making site work offline + + if('serviceWorker' in navigator) { + navigator.serviceWorker + .register('/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/sw.js') + .then(function() { console.log('Service Worker Registered'); }); + }</pre> + +<div class="note"> +<p><strong>Note</strong>: The given path to the <code>sw.js</code> file is relative to the site origin, not the JavaScript file that contains the code. The service worker is at <code>https://mdn.github.io/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/sw.js</code>. The origin is <code>https://mdn.github.io</code>, and therefore the given path has to be <code>/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/sw.js</code>. If you wanted to host this example on your own server, you'd have to change this accordingly. This is rather confusing, but it has to work this way for security reasons.</p> +</div> + +<h4 id="Installing_the_service_worker">Installing the service worker</h4> + +<p>The next time any page under the service worker's control is accessed (e.g. when the example is reloaded), the service worker is installed against that page, meaning that it will start controlling it. When this occurs, an <code>install</code> event is fired against the service worker; you can write code inside the service worker itself that will respond to the installation.</p> + +<p>Let's look at an example, in the <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/client-side-storage/cache-sw/video-store-offline/sw.js">sw.js</a> file (the service worker). You'll see that the install listener is registered against <code>self</code>. This <code>self</code> keyword is a way to refer to the global scope of the service worker from inside the service worker file.</p> + +<p>Inside the <code>install</code> handler we use the {{domxref("ExtendableEvent.waitUntil()")}} method, available on the event object, to signal that the browser shouldn't complete installation of the service worker until after the promise inside it has fulfilled successfully.</p> + +<p>Here is where we see the Cache API in action. We use the {{domxref("CacheStorage.open()")}} method to open a new cache object in which responses can be stored (similar to an IndexedDB object store). This promise fulfills with a {{domxref("Cache")}} object representing the <code>video-store</code> cache. We then use the {{domxref("Cache.addAll()")}} method to fetch a series of assets and add their responses to the cache.</p> + +<pre class="brush: js notranslate">self.addEventListener('install', function(e) { + e.waitUntil( + caches.open('video-store').then(function(cache) { + return cache.addAll([ + '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/', + '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/index.html', + '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/index.js', + '/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/style.css' + ]); + }) + ); +});</pre> + +<p>That's it for now, installation done.</p> + +<h4 id="Responding_to_further_requests">Responding to further requests</h4> + +<p>With the service worker registered and installed against our HTML page, and the relevant assets all added to our cache, we are nearly ready to go. There is only one more thing to do, write some code to respond to further network requests.</p> + +<p>This is what the second bit of code in <code>sw.js</code> does. We add another listener to the service worker global scope, which runs the handler function when the <code>fetch</code> event is raised. This happens whenever the browser makes a request for an asset in the directory the service worker is registered against.</p> + +<p>Inside the handler we first log the URL of the requested asset. We then provide a custom response to the request, using the {{domxref("FetchEvent.respondWith()")}} method.</p> + +<p>Inside this block we use {{domxref("CacheStorage.match()")}} to check whether a matching request (i.e. matches the URL) can be found in any cache. This promise fulfills with the matching response if a match is found, or <code>undefined</code> if it isn't.</p> + +<p>If a match is found, we simply return it as the custom response. If not, we <a href="/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch">fetch()</a> the response from the network and return that instead.</p> + +<pre class="brush: js notranslate">self.addEventListener('fetch', function(e) { + console.log(e.request.url); + e.respondWith( + caches.match(e.request).then(function(response) { + return response || fetch(e.request); + }) + ); +});</pre> + +<p>And that is it for our simple service worker. There is a whole load more you can do with them — for a lot more detail, see the <a href="https://serviceworke.rs/">service worker cookbook</a>. And thanks to Paul Kinlan for his article <a href="https://developers.google.com/web/fundamentals/codelabs/offline/">Adding a Service Worker and Offline into your Web App</a>, which inspired this simple example.</p> + +<h4 id="Testing_the_example_offline">Testing the example offline</h4> + +<p>To test our <a href="https://mdn.github.io/learning-area/javascript/apis/client-side-storage/cache-sw/video-store-offline/">service worker example</a>, you'll need to load it a couple of times to make sure it is installed. Once this is done, you can:</p> + +<ul> + <li>Try unplugging your network/turning your Wifi off.</li> + <li>Select <em>File > Work Offline</em> if you are using Firefox.</li> + <li>Go to the devtools, then choose <em>Application > Service Workers</em>, then check the <em>Offline</em> checkbox if you are using Chrome.</li> +</ul> + +<p>If you refresh your example page again, you should still see it load just fine. Everything is stored offline — the page assets in a cache, and the videos in an IndexedDB database.</p> + +<h2 id="Summary">Summary</h2> + +<p>That's it for now. We hope you've found our rundown of client-side storage technologies useful.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/API/Web_Storage_API">Web storage API</a></li> + <li><a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB API</a></li> + <li><a href="/en-US/docs/Web/HTTP/Cookies">Cookies</a></li> + <li><a href="/en-US/docs/Web/API/Service_Worker_API">Service worker API</a></li> +</ul> + +<p>{{PreviousMenu("Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs", "Learn/JavaScript/Client-side_web_APIs")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">Introduction to web APIs</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Manipulating documents</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Fetching data from the server</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Third_party_APIs">Third party APIs</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing graphics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs">Video and audio APIs</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage">Client-side storage</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/client-side_web_apis/index.html b/files/pt-br/learn/javascript/client-side_web_apis/index.html new file mode 100644 index 0000000000..03477c04af --- /dev/null +++ b/files/pt-br/learn/javascript/client-side_web_apis/index.html @@ -0,0 +1,52 @@ +--- +title: APIs web do lado cliente +slug: Aprender/JavaScript/Client-side_web_APIs +tags: + - API + - Aprender + - Artigos + - DOM + - Iniciante + - Mídia + - WebAPI + - dados + - graficos + - modulo +translation_of: Learn/JavaScript/Client-side_web_APIs +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">Se você decidir usar JavaScript no lado do cliente para sites ou aplicativos, você rapidamente vai se deparar com as <strong>APIs</strong> - interfaces para manipular diferentes aspectos do navegador e do sistema operacional em que o site está sendo executado, ou mesmo dados de outros sites ou serviços. Neste módulo, descobriremos o que são APIs, e como usar algumas das APIs mais comuns, que serão úteis no seu trabalho de desenvolvimento.</p> + +<h2 id="Pré-requisitos">Pré-requisitos</h2> + +<p>Para tirar o máximo proveito deste módulo, é recomendável a leitura dos módulos anteriores de JavaScript da série (<a href="/en-US/docs/Learn/JavaScript/First_steps">Primeiros passos</a>, <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Construindo blocos</a>, e <a href="/en-US/docs/Learn/JavaScript/Objects">Objetos javaScript </a>). Esses módulos envolvem bastante uso de API simples, e não é facil escrever exemplos Javascript do lado do cliente sem eles. Aqui, subimos um nível, assumindo o conhecimento da linguagem core JavaScript e explorando as APIs comuns da Web com um pouco mais de detalhes.</p> + +<p>Conhecimento básico de <a href="/en-US/docs/Learn/HTML">HTML</a> e <a href="/en-US/docs/Learn/CSS">CSS</a> serão utéis.</p> + +<div class="note"> +<p><strong>Notes </strong>Se você estiver trabalhando de um dispositivo que não permita a criação de arquivos. Você pode tentar editar os arquivos em um editor online como <a href="http://jsbin.com/">JSBin</a> ou <a href="https://thimble.mozilla.org/">Thimble</a>.</p> +</div> + +<h2 id="Guias">Guias</h2> + +<dl> + <dt><a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">Introdução a APIs para a web</a></dt> + <dd>Primeiro, vamos começar com apis de alto nível — o que elas são, como elas funcionam, quando usar no seu código, como elas são estruturadas? Nós veremos diferentes tipos de classses principais e o que elas são, e quais são as possibilidades de uso.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Manipulando documentos</a></dt> + <dd>Quando estiver codificando páginas da web ou aplicações, uma das coisas mais comuns que você irá fazer será manipular documentos da web de alguma forma. Normalmente isso é feito usando o Document Object Model (DOM), um conjunto de APIs para controlar o HTML e a informação sobre os estilos que usa fortemente o objeto {{domxref("Document")}}. Neste artigo vamos ver como usar o DOM em detalhes, juntamente com outras APIs interessantes que podem alterar seu ambiente de desenvolvimento de modos interessantes.</dd> + <dt><a href="/pt-BR/docs/">Buscando dados do servidor</a></dt> + <dd>Outra tarefa muito comum em websites modernos e aplicações é recuperar dados individuais de um servidor para atualizar partes de uma página sem ter que recarregar uma página inteira novamente. Este aparentemente pequeno detalhe tem tido um impacto enorme sobre o desempenho e comportamento de websites, desse modo neste artigo, vamos explicar esse conceito, e observar as tecnologias que tornam isso possível, tais como {{domxref("XMLHttpRequest")}} e o <a href="/en-US/docs/Web/API/Fetch_API">Fetch API</a>.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Third_party_APIs">Third party APIs</a> </dt> + <dd>The APIs we've covered so far are built into the browser, but not all APIs are. Many large websites and services such as Google Maps, Twitter, Facebook, PayPal, etc. provide APIs allowing developers to make use of their data (e.g. displaying your twitter stream on your blog) or services (e.g. displaying custom Google Maps on your site, or using Facebook login to log in your users). This article looks at the difference between browser APIs and 3rd party APIs and shows some typical uses of the latter.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing graphics</a></dt> + <dd>The browser contains some very powerful graphics programming tools, from the Scalable Vector Graphics (<a href="/en-US/docs/Web/SVG">SVG</a>) language, to APIs for drawing on HTML {{htmlelement("canvas")}} elements, (see <a href="/en-US/docs/Web/API/Canvas_API">The Canvas API</a> and <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a>). Ths article provides an introduction to the Canvas API, and further resources to allow you to learn more.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs">Video and audio APIs</a></dt> + <dd>HTML5 comes with elements for embedding rich media in documents — {{htmlelement("video")}} and {{htmlelement("audio")}} — which in turn come with their own APIs for controlling playback, seeking, etc. This article shows you how to do common tasks such as creating custom playback controls.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage">Client-side storage</a></dt> + <dd>Modern web browsers feature a number of different technologies that allow you to store data related to web sites and retrieve it when necessary allowing you to persist data long term, save sites offline, and more. This article explains the very basics of how these work.</dd> +</dl> + +<div id="gtx-trans" style="position: absolute; left: 4px; top: 1072px;"> +<div class="gtx-trans-icon"></div> +</div> diff --git a/files/pt-br/learn/javascript/client-side_web_apis/introduction/index.html b/files/pt-br/learn/javascript/client-side_web_apis/introduction/index.html new file mode 100644 index 0000000000..dfab85143b --- /dev/null +++ b/files/pt-br/learn/javascript/client-side_web_apis/introduction/index.html @@ -0,0 +1,274 @@ +--- +title: Introdução às Web APIs +slug: Aprender/JavaScript/Client-side_web_APIs/Introdução +translation_of: Learn/JavaScript/Client-side_web_APIs/Introduction +--- +<div>{{LearnSidebar}}</div> + +<div>{{NextMenu("Learn/JavaScript/Client-side_web_APIs/Manipulating_documents", "Learn/JavaScript/Client-side_web_APIs")}}</div> + +<p class="summary">Primeiro, vamos ver as APIs a partir de um nível mais alto: o que são, como funcionam, como usá-las em seu código e como são estruturadas? Ainda, vamos entender quais são as principais classes de APIs e quais usos elas possuem.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos:</th> + <td> + <p>Conhecimentos básicos de computação, <a href="/pt-BR/docs/Aprender/HTML">HTML</a>, <a href="/pt-BR/docs/Aprender/CSS">CSS</a> e JavaScript (veja <a href="/pt-BR/docs/Learn/JavaScript/First_steps">primeiros passos</a>, <a href="/pt-BR/docs/Aprender/JavaScript/Elementos_construtivos">elementos construtivos</a> e <a href="/pt-BR/docs/Aprender/JavaScript/Objetos">introdução a objetos</a>).</p> + </td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Familiarizar-se com APIs, o que elas podem fazer, e como usá-las em seu código.</td> + </tr> + </tbody> +</table> + +<h2 id="O_que_são_APIs">O que são APIs?</h2> + +<p>As APIs (Application Programming Interfaces) são construções disponíveis nas linguagens de programação que permitem a desenvolvedores criar funcionalidades complexas mais facilmente. Tais construções abstraem o código mais complexo, proporcionando o uso de sintaxes mais simples em seu lugar.</p> + +<p>Pense no seguinte exemplo: o uso de energia elétrica em sua casa ou apartamento. Quando você deseja utilizar um eletrodoméstico, você precisa somente ligar o aparelho na tomada. Não é preciso conectar diretamente o fio do aparelho diretamente na caixa de luz. Isso seria, além de muito ineficiente, difícil e perigoso de ser feito (caso você não seja eletricista).</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14317/plug-socket.png" style="display: block; height: 472px; margin: 0px auto; width: 700px;"></p> + +<p><em>Fonte da imagem: <a href="https://www.flickr.com/photos/easy-pics/9518184890/in/photostream/lightbox/">Overloaded plug socket</a> por <a href="https://www.flickr.com/photos/easy-pics/">The Clear Communication People</a>, retirado do Flickr.</em></p> + +<p>Da mesma forma, caso você queira programar gráficos em 3D, é muito mais fácil usar uma API escrita em linguagem de alto nível como JavaScript ou Python, do que escrever em código de mais baixo nível (C ou C++) que controla diretamente a GPU ou outras funções gráficas.</p> + +<div class="note"> +<p><strong>Nota</strong>: para mais informações, consulte o <a href="/pt-BR/docs/Glossario/API">termo API</a> no glossário.</p> +</div> + +<h3 id="APIs_JavaScript_client-side">APIs JavaScript client-side</h3> + +<p>A linguagem JavaScript, especialmente client-side, possui diversas APIs disponíveis. Elas não fazem parte da linguagem em si, mas são escritas sobre o <em>core </em>da linguagem JavaScript, fornecendo superpoderes para serem utilizados em seu código. Geralmente, tais APIs fazem parte de uma das seguintes categorias:</p> + +<ul> + <li><strong>APIs de navegadores: </strong>fazem parte do seu navegador web, sendo capazes de expor dados do navegador e do ambiente ao redor do computador circundante, além de fazer coisas úteis com esses dados. Por exemplo, a <a href="/pt-BR/docs/Web/API/API_Web_Audio">API Web Áudio</a> fornece construções JavaScript simples para manipular áudio em seu navegador - pegar uma faixa de áudio, alterar o volume dela, aplicar efeitos, etc. Por trás dos panos, o navegador utiliza códigos complexos de baixo nível (ex: C++) para realizar o processamento de áudio de fato. Como foi dito anteriormente, essa complexidade toda é abstraída de você pela API. </li> + <li><strong>APIs de terceiros:</strong> geralmente, não fazem parte do navegador e você precisa recuperar seu código e suas informações de outro local da web. A <a href="https://developer.twitter.com/en/docs">API do Twitter</a>, por exemplo, permite mostrar os seus últimos tweets no seu site. Ela fornece um conjunto de construções especiais para ser usado de maneira a consultar o serviço do Twitter e retornar informações específicas.</li> +</ul> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13508/browser.png" style="display: block; height: 511px; margin: 0px auto; width: 815px;"></p> + +<h3 id="Relacionamento_entre_JavaScript_APIs_e_outras_ferramentas_JavaScript">Relacionamento entre JavaScript, APIs, e outras ferramentas JavaScript</h3> + +<p>Na seção anterior, abordamos as APIs JavaScript client-side e como elas se relacionam com a linguagem JavaScript. Esse ponto merece uma revisão e também uma breve menção de como outras ferramentas JavaScript encaixam-se nesse contexto:</p> + +<ul> + <li>JavaScript — linguagem de alto nível, embutida em navegadores, que permite implementar funcionalidades em páginas web/aplicativos. A linguagem também está disponível em outros ambientes de programação, tais como o <a href="/pt-BR/docs/Learn/Server-side/Express_Nodejs/Introdução">Node</a>.</li> + <li>APIs de navegadores — construções presentes no navegador, as quais são baseadas em linguagem JavaScript e permitem a implementação de funcionalidades de uma maneira mais fácil.</li> + <li>APIs de terceiros — construções presentes em plataformas de terceiros (ex: Twitter, Facebook), que permitem o uso de alguma funcionalidade da plataforma em suas páginas na web. Um exemplo é a possibilidade de mostrar os últimos tweets em sua página.</li> + <li>Bibliotecas JavaScript — em geral, um ou mais arquivos JavaScript contendo<a href="/pt-BR/docs/Aprender/JavaScript/Elementos_construtivos/Functions#Funções_personalizadas"> funções personalizadas</a>, as quais podem ser usadas em sua página web para acelerar ou permitir escrever funcionalidades comuns. Exemplos: jQuery, Mootools e React.</li> + <li>Frameworks JavaScript — uma evolução das bibliotecas. Frameworks JavaScript (ex: Angular e Ember), normalmente, são pacotes de tecnologias HTML, CSS, JavaScript e outras, que você instala e usa para escrever uma aplicação web completa do zero. A principal diferença entre uma biblioteca e um framework é a inversão de controle ("Inversion of Control"). Quando um método de uma biblioteca é chamado, a pessoa desenvolvedora está no controle. Em um framework, o controle inverte-se: é o framework que chama o código da pessoa desenvolvedora.</li> +</ul> + +<h2 id="O_que_as_APIs_podem_fazer">O que as APIs podem fazer?</h2> + +<p>Existem muitas APIs disponíveis, nos navegadores modernos, que permitem uma liberdade de ação na hora de codar. Você pode conferir isso na <a href="https://developer.mozilla.org/pt-BR/docs/Web/API">página de referência das APIs da MDN</a>.</p> + +<h3 id="APIs_comuns_de_navegadores">APIs comuns de navegadores</h3> + +<p>As categorias mais comuns de APIs de navegadores que você irá utilizar (e que veremos em detalhes neste módulo), são:</p> + +<ul> + <li><strong>APIs para manipular documentos </strong>carregados no navegador. O exemplo mais óbvio é a <a href="https://developer.mozilla.org/pt-BR/docs/DOM/Referencia_do_DOM">API DOM (Document Object Model)</a>, que permite manipular HTML e CSS — criando, removendo a alterando o HTML, aplicando dinamicamente novos estilos a sua página, etc. Toda vez que você vê uma janela pop-up em uma página, ou um novo conteúdo é mostrado, o DOM está em ação. Para saber mais sobre estes tipos de API, leia <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Manipulando documentos</a>.</li> + <li><strong>APIs</strong><strong> que buscam dados no servidor</strong> para atualizar pequenas seções da página, por conta própria, são bastante usadas. Isso, a princípio, parece ser um detalhe pequeno, mas tem um impacto enorme na performance e no comportamento dos sites. Se você precisa atualizar a cotação de uma ação ou listar novas histórias disponíveis, a possibilidade de fazer isso instantaneamente sem precisar atualizar a página dá a impressão de um site muito mais responsivo. Entre as APIs que tornam isso possível, podemos destacar o <a href="https://developer.mozilla.org/pt-BR/docs/Web/API/XMLHttpRequest" title="XMLHttpRequest is an API that provides client functionality for transferring data between a client and a server. It provides an easy way to retrieve data from a URL without having to do a full page refresh. This enables a Web page to update just a part of the page without disrupting what the user is doing."><code>XMLHttpRequest</code></a> e a <a href="https://developer.mozilla.org/pt-BR/docs/Web/API/Fetch_API">API Fetch</a>. Você pode também encontrar o termo <strong>Ajax</strong>, que descreve essa técnica. Para saber mais sobre essas APIs, leia <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Fetching data from the server</a>.</li> + <li><strong>APIs para desenhar e manipular elementos gráficos</strong> são completamente suportados nos browsers — os mais comuns são <a href="/en-US/docs/Web/API/Canvas_API">Canvas</a> e <a href="/en-US/docs/Web/API/WebGL_API">WebGL</a>, que possibilitam que você atualize os dados dos pixels em um elemento HTML de maneira programática. {{htmlelement("canvas")}} elemento para criar cenas 2d e 3d. Por exemplo, você poderia dezenhar formas como retangulos e circulos, importar uma imagem para o canvas, e aplicar um filtro para sepia ou grayscale usando o Canvas API, ou criar uma complexa cena 3d com brilho e texturas usando WebGL. Essas APIs são frequentemente combinar com APIs para criar loops de animações(como {{domxref("window.requestAnimationFrame()")}}) e outros para constantemente lançar cenas like como cartoons e jogos.</li> + <li><strong><a href="https://developer.mozilla.org/en-US/Apps/Fundamentals/Audio_and_video_delivery">Audio and Video APIs</a></strong> como {{domxref("HTMLMediaElement")}}, a <a href="/en-US/docs/Web/API/Web_Audio_API">Web Audio API</a>, e <a href="/en-US/docs/Web/API/WebRTC_API">WebRTC</a> permiten a você fazer coisas realmente interessantes com multimedia como a criação personalizada controles de UI para executar audio e video, exibindo faixas de texto como legendas e legendas ocultas junto com seus vídeos, capturando vídeo de sua câmera da web para ser manipulado por meio de uma tela (veja acima) ou exibido no computador de outra pessoa em uma webconferência,ou adicionar efeitos às trilhas de áudio (como ganho, distorção, panorâmica, etc.).</li> + <li><strong>Device APIs</strong> São basicamente APIs para manipulação e recuperação de dados de hardware de dispositivo moderno de uma forma que seja útil para aplicativos da web.Já falamos sobre a Geolocation API acessando o dispositivo dados de localização para que você possa marcar sua posição em um mapa.Outros exemplos incluem informar ao usuário que uma atualização útil está disponível em um aplicativo da web por meio de notificações do sistema(Veja em <a href="/en-US/docs/Web/API/Notifications_API">Notifications API</a>)ou hardware de vibração(Veja em <a href="/en-US/docs/Web/API/Vibration_API">Vibration API</a>).</li> + <li><strong>Client-side storage APIs</strong> estão se tornando muito mais difundidos em navegadores da web - a capacidade de armazenar dados no lado do cliente é muito útil se você quer criar um app que vai salvar seu estado entre carregamentos de página, e talvez até funcione quando o dispositivo estiver offline. Existem várias opções disponíveis, por exemplo, armazenamento simples de nome / valor com o <a href="/en-US/docs/Web/API/Web_Storage_API">Web Storage API</a>, e armazenamento de dados tabulares mais complexos com o <a href="/en-US/docs/Web/API/IndexedDB_API">IndexedDB API</a>.</li> +</ul> + +<h3 id="APIs_comuns_de_terceiros">APIs comuns de terceiros</h3> + +<p>APIs de terceiros são bastante variadas. Dentre as mais populares, que você eventualmente irá utilizar em algum momento, podermos destacar:</p> + +<ul> + <li>A <a href="https://dev.twitter.com/overview/documentation">Twitter API</a>, que permite coisas como mostrar seu últimos tweets no seu website.</li> + <li>O <a href="https://developers.google.com/maps/">Google Maps API</a> permite que você faça todo tipo de coisa com mapas nas suas páginas web (funnily enough, it also powers Google Maps). This is now an entire suite of APIs, which handle a wide variety of tasks, as evidenced by the <a href="https://developers.google.com/maps/documentation/api-picker">Google Maps API Picker</a>.</li> + <li>The <a href="https://developers.facebook.com/docs/">Facebook suite of APIs</a> enables you to use various parts of the Facebook ecosystem to benefit your app, for example by providing app login using Facebook login, accepting in-app payments, rolling out targetted ad campaigns, etc.</li> + <li>The <a href="https://developers.google.com/youtube/">YouTube API</a>, which allows you to embed YouTube videos on your site, search YouTube, build playlists, and more.</li> + <li>The <a href="https://www.twilio.com/">Twilio API</a>, which provides a framework for building voice and video call functionality into your app, sending SMS/MMS from your apps, and more.</li> +</ul> + +<div class="note"> +<p><strong>Note</strong>: Você pode encontrar informações sobre muitas outras APIs de terceiros no <a href="http://www.programmableweb.com/category/all/apis">Programmable Web API directory</a>.</p> +</div> + +<h2 id="Como_as_APIs_funcionam">Como as APIs funcionam?</h2> + +<p>APIs JavaScript possuem pequenas diferenças mas, em geral, possuem funcionalidades em comum e operam de maneira semelhante.</p> + +<h3 id="Elas_são_baseadas_em_objetos">Elas são baseadas em objetos</h3> + +<p>Your code interacts with APIs using one or more <a href="/en-US/docs/Learn/JavaScript/Objects">JavaScript objects</a>, which serve as containers for the data the API uses (contained in object properties), and the functionality the API makes available (contained in object methods).</p> + +<div class="note"> +<p><strong>Note</strong>: If you are not already familiar with how objects work, you should go back and work through our <a href="/en-US/docs/Learn/JavaScript/Objects">JavaScript objects</a> module before continuing.</p> +</div> + +<p>Let's return to the example of the Geolocation API — this is a very simple API that consists of a few simple objects:</p> + +<ul> + <li>{{domxref("Geolocation")}}, which contains three methods for controlling the retrieval of geodata.</li> + <li>{{domxref("Position")}}, which represents the position of a device at a given time — this contains a {{domxref("Coordinates")}} object that contains the actual position information, plus a timestamp representing the given time.</li> + <li>{{domxref("Coordinates")}}, which contains a whole lot of useful data on the device position, including latitude and longitude, altitude, velocity and direction of movement, and more.</li> +</ul> + +<p>So how do these objects interact? If you look at our <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/introduction/maps-example.html">maps-example.html</a> example (<a href="http://mdn.github.io/learning-area/javascript/apis/introduction/maps-example.html">see it live also</a>), you'll see the following code:</p> + +<pre class="brush: js notranslate">navigator.geolocation.getCurrentPosition(function(position) { + var latlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude); + var myOptions = { + zoom: 8, + center: latlng, + mapTypeId: google.maps.MapTypeId.TERRAIN, + disableDefaultUI: true + } + var map = new google.maps.Map(document.querySelector("#map_canvas"), myOptions); +});</pre> + +<div class="note"> +<p><strong>Note</strong>: When you first load up the above example, you should be given a dialog box asking if you are happy to share your location with this application (see the {{anch("They have additional security mechanisms where appropriate")}} section later in the article). You need to agree to this to be able to plot your location on the map. If you still can't see the map, you may need to set your permissions manually; you can do this in various ways depending on what browser you are using; for example in Firefox go to > <em>Tools</em> > <em>Page Info</em> > <em>Permissions</em>, then change the setting for <em>Share Location</em>; in Chrome go to <em>Settings</em> > <em>Privacy</em> > <em>Show advanced settings</em> > <em>Content settings</em> then change the settings for <em>Location</em>.</p> +</div> + +<p>We first want to use the {{domxref("Geolocation.getCurrentPosition()")}} method to return the current location of our device. The browser's {{domxref("Geolocation")}} object is accessed by calling the {{domxref("Navigator.geolocation")}} property, so we start off by using</p> + +<pre class="brush: js notranslate">navigator.geolocation.getCurrentPosition(function(position) { ... });</pre> + +<p>Isso é equivalente a fazer algo como</p> + +<pre class="brush: js notranslate">var myGeo = navigator.geolocation; +myGeo.getCurrentPosition(function(position) { ... });</pre> + +<p>But we can use the dot syntax to chain our property/method access together, reducing the number of lines we have to write.</p> + +<p>The {{domxref("Geolocation.getCurrentPosition()")}} method only has a single mandatory parameter, which is an anonymous function that will run when the device's current position has been successfully retrieved. This function itself has a parameter, which contains a {{domxref("Position")}} object representing the current position data.</p> + +<div class="note"> +<p><strong>Note</strong>: A function that is taken by another function as an argument is called a <a href="/en-US/docs/Glossary/Callback_function">callback function</a>.</p> +</div> + +<p>This pattern of invoking a function only when an operation has been completed is very common in JavaScript APIs — making sure one operation has completed before trying to use the data the operation returns in another operation. These are called <strong><a href="/en-US/docs/Glossary/Asynchronous">asynchronous</a> operations</strong>. Because getting the device's current position relies on an external component (the device's GPS or other geolocation hardware), we can't guarantee that it will be done in time to just immediately use the data it returns. Therefore, something like this wouldn't work:</p> + +<pre class="brush: js example-bad notranslate">var position = navigator.geolocation.getCurrentPosition(); +var myLatitude = position.coords.latitude;</pre> + +<p>If the first line had not yet returned its result, the second line would throw an error, because the position data would not yet be available. For this reason, APIs involving asynchronous operations are designed to use {{glossary("callback function")}}s, or the more modern system of <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promises</a>, which were made available in ECMAScript 6 and are widely used in newer APIs.</p> + +<p>We are combining the Geolocation API with a third party API — the Google Maps API — which we are using to plot the location returned by <code>getCurrentPosition()</code> on a Google Map. We make this API available on our page by linking to it — you'll find this line in the HTML:</p> + +<pre class="brush: html notranslate"><script type="text/javascript" src="https://maps.google.com/maps/api/js?key=AIzaSyDDuGt0E5IEGkcE6ZfrKfUtE9Ko_de66pA"></script></pre> + +<p>To use the API, we first create a <code>LatLng</code> object instance using the <code>google.maps.LatLng()</code> constructor, which takes our geolocated {{domxref("Coordinates.latitude")}} and {{domxref("Coordinates.longitude")}} values as parameters:</p> + +<pre class="brush: js notranslate">var latlng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);</pre> + +<p>This object is itself set as the value of the <code>center</code> property of an options object that we've called <code>myOptions</code>. We then create an object instance to represent our map by calling the <code>google.maps.Map()</code> constructor, passing it two parameters — a reference to the {{htmlelement("div")}} element we want to render the map on (with an ID of <code>map_canvas</code>), and the options object we defined just above it.</p> + +<pre class="brush: js notranslate">var myOptions = { + zoom: 8, + center: latlng, + mapTypeId: google.maps.MapTypeId.TERRAIN, + disableDefaultUI: true +} + +var map = new google.maps.Map(document.querySelector("#map_canvas"), myOptions);</pre> + +<p>With this done, our map now renders.</p> + +<p>This last block of code highlights two common patterns you'll see across many APIs. First of all, API objects commonly contain constructors, which are invoked to create instances of those objects that you'll use to write your program. Second, API objects often have several options available that can be tweaked to get the exact environment you want for your program. API constructors commonly accept options objects as parameters, which is where you'd set such options.</p> + +<div class="note"> +<p><strong>Note</strong>: Don't worry if you don't understand all the details of this example immediately. We'll cover using third party APIs in a lot more detail in a future article.</p> +</div> + +<h3 id="Possuem_pontos_de_entrada_reconhecíveis">Possuem pontos de entrada reconhecíveis</h3> + +<p>When using an API, you should make sure you know where the entry point is for the API. In The Geolocation API, this is pretty simple — it is the {{domxref("Navigator.geolocation")}} property, which returns the browser's {{domxref("Geolocation")}} object that all the useful geolocation methods are available inside.</p> + +<p>The Document Object Model (DOM) API has an even simpler entry point — its features tend to be found hanging off the {{domxref("Document")}} object, or an instance of an HTML element that you want to affect in some way, for example:</p> + +<pre class="brush: js notranslate">var em = document.createElement('em'); // create a new em element +var para = document.querySelector('p'); // reference an existing p element +em.textContent = 'Hello there!'; // give em some text content +para.appendChild(em); // embed em inside para</pre> + +<p>Other APIs have slightly more complex entry points, often involving creating a specific context for the API code to be written in. For example, the Canvas API's context object is created by getting a reference to the {{htmlelement("canvas")}} element you want to draw on, and then calling its {{domxref("HTMLCanvasElement.getContext()")}} method:</p> + +<pre class="brush: js notranslate">var canvas = document.querySelector('canvas'); +var ctx = canvas.getContext('2d');</pre> + +<p>Anything that we want to do to the canvas is then achieved by calling properties and methods of the content object (which is an instance of {{domxref("CanvasRenderingContext2D")}}), for example:</p> + +<pre class="brush: js notranslate">Ball.prototype.draw = function() { + ctx.beginPath(); + ctx.fillStyle = this.color; + ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI); + ctx.fill(); +};</pre> + +<div class="note"> +<p><strong>Note</strong>: You can see this code in action in our <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/introduction/bouncing-balls.html">bouncing balls demo</a> (see it <a href="http://mdn.github.io/learning-area/javascript/apis/introduction/bouncing-balls.html">running live</a> also).</p> +</div> + +<h3 id="Usam_eventos_para_lidar_com_mudanças_de_estado">Usam eventos para lidar com mudanças de estado</h3> + +<p>We already discussed events earlier on in the course, in our <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">Introduction to events</a> article — this article looks in detail at what client-side web events are and how they are used in your code. If you are not already familiar with how client-side web API events work, you should go and read this article first before continuing.</p> + +<p>Some web APIs contain no events, but some contain a number of events. The handler properties that allow us to run functions when events fire are generally listed in our reference material in separate "Event handlers" sections. As a simple example, instances of the <code><a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a></code> object (each one represents an HTTP request to the server to retrieve a new resource of some kind) have a number of events available on them, for example the <code>load</code> event is fired when a response has been successfully returned containing the requested resource, and it is now available.</p> + +<p>O código seguinte fornece um exemplo simples de como isso seria utilizado:</p> + +<pre class="brush: js notranslate">var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json'; +var request = new XMLHttpRequest(); +request.open('GET', requestURL); +request.responseType = 'json'; +request.send(); + +request.onload = function() { + var superHeroes = request.response; + populateHeader(superHeroes); + showHeroes(superHeroes); +}</pre> + +<div class="note"> +<p><strong>Note</strong>: You can see this code in action in our <a href="https://github.com/mdn/learning-area/blob/master/javascript/apis/introduction/ajax.html">ajax.html</a> example (<a href="http://mdn.github.io/learning-area/javascript/apis/introduction/ajax.html">see it live</a> also).</p> +</div> + +<p>The first five lines specify the location of resource we want to fetch, create a new instance of a request object using the <code>XMLHttpRequest()</code> constructor, open an HTTP <code>GET</code> request to retrieve the specified resource, specify that the response should be sent in JSON format, then send the request.</p> + +<p>The <code>onload</code> handler function then specifies what we do with the response. We know the response will be successfully returned and available after the load event has required (unless an error occurred), so we save the response containing the returned JSON in the <code>superHeroes</code> variable, then pass it to two different functions for further processing.</p> + +<h3 id="Possuem_mecanismos_de_segurança_adicionais_quando_apropriado">Possuem mecanismos de segurança adicionais, quando apropriado</h3> + +<p>WebAPI features are subject to the same security considerations as JavaScript and other web technologies (for example <a href="/en-US/docs/Web/Security/Same-origin_policy">same-origin policy</a>), but they sometimes have additional security mechanisms in place. For example, some of the more modern WebAPIs will only work on pages served over HTTPS due to them transmitting potentially sensitive data (examples include <a href="/en-US/docs/Web/API/Service_Worker_API">Service Workers</a> and <a href="/en-US/docs/Web/API/Push_API">Push</a>).</p> + +<p>In addition, some WebAPIs request permission to be enabled from the user once calls to them are made in your code. As an example, you may have noticed a dialog like the following when loading up our earlier <a href="/en-US/docs/Web/API/Geolocation">Geolocation</a> example:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14313/location-permission.png" style="border-style: solid; border-width: 1px; display: block; height: 188px; margin: 0px auto; width: 413px;"></p> + +<p>The <a href="/en-US/docs/Web/API/Notifications_API">Notifications API</a> asks for permission in a similar fashion:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/14315/notification-permission.png" style="border-style: solid; border-width: 1px; display: block; margin: 0px auto;"></p> + +<p>These permission prompts are given to users for security — if they weren't in place, then sites could start secretly tracking your location without you knowing it, or spamming you with a lot of annoying notifications.</p> + +<h2 id="Resumo">Resumo</h2> + +<p>Ao chegar aqui, você deve ter uma boa ideia do que são APIs, como funcionam e o que você pode fazer com elas em seu código JavaScript. Além do mais, você deve estar ansioso(a) para colocar a mão na massa e trabalhar com APIs. Na sequência, iremos ver como manipular documentos com o DOM (Document Object Model).</p> + +<p>{{NextMenu("Learn/JavaScript/Client-side_web_APIs/Manipulating_documents", "Learn/JavaScript/Client-side_web_APIs")}}</p> + +<h2 id="Neste_módulo">Neste módulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction">Introduction to web APIs</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents">Manipulating documents</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Fetching_data">Fetching data from the server</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Third_party_APIs">Third party APIs</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Drawing graphics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs">Video and audio APIs</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Client-side_storage">Client-side storage</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/client-side_web_apis/manipulating_documents/index.html b/files/pt-br/learn/javascript/client-side_web_apis/manipulating_documents/index.html new file mode 100644 index 0000000000..544deb8960 --- /dev/null +++ b/files/pt-br/learn/javascript/client-side_web_apis/manipulating_documents/index.html @@ -0,0 +1,140 @@ +--- +title: JavaScript e CSS +slug: Web/CSS/Getting_Started/JavaScript +translation_of: Learn/JavaScript/Client-side_web_APIs/Manipulating_documents +translation_of_original: Web/Guide/CSS/Getting_started/JavaScript +--- +<p>{{ CSSTutorialTOC() }}</p> +<p>Esta é a pirmeira sessão da Parte II do <a href="/en/CSS/Getting_Started" title="https://developer.mozilla.org/en/CSS/Getting_Started">Tutorial de CSS</a>. A parte II consém alguns exemplos que mostram o escopo do CSS usado com outras tecnologias web e Mozilla.</p> +<p>Cada página da Parte II ilustra como o CSS interagem com outras tecnologias. Essas páginas não destinam-se a ensiná-lo como usar outras tecnologias. Para aprender sobre elas com detalhes, vá para os outros tutoriais.</p> +<p>Em vez disso, estas páginas são usadas para ilustrar os diversos usos do CSS. Para usar estas páginas, você deve ter algum conhecimento de CSS, mas você não precisa de nenhum conhecimento de outras tecnologias.</p> +<p>Sessão Anterior (da Parte I): <a href="/en/CSS/Getting_Started/Media" title="https://developer.mozilla.org/en/CSS/Getting_Started/Media">Media</a><br> + Próxima sessão: <a href="/en/CSS/Getting_Started/SVG_graphics" title="https://developer.mozilla.org/en/CSS/Getting_Started/SVG_graphics">SVG</a></p> +<h3 id="Information:_JavaScript" name="Information:_JavaScript">Informação: JavaScript</h3> +<p>JavaScript é um <em>programming language</em>. JavaScript é largamente utilizado para pronmover interatividade em web sites e aplicações.</p> +<p>JavaScript pode interagir com stylesheets, permitindo a você criar programas que mudam o eastilo de um documento de forma dinâmica</p> +<p>Há três formas de fazer isso:</p> +<ul> + <li>Trabalhando com lista de documentos de stylesheets—por exemplo: adicionando, removendo ou adicionando uma stylesheet.</li> + <li>Trabalhando com as regras em uma stylesheet—por exemplo: adicionando, removendo ou modificando uma regra.</li> + <li>Trabalhando com um documento individual na DOM—modificando seu estilo independentemente do stylesheetsdo documento.</li> +</ul> +<table style="border: 1px solid #36b; padding: 1em; background-color: #f4f4f4; margin-bottom: 1em; width: 100%;"> + <caption> + Mais detalhes</caption> + <tbody> + <tr> + <td>Para mais informações sobre JavaScript, veja a página <a href="/en/JavaScript" title="en/JavaScript">JavaScript</a> nesta wiki.</td> + </tr> + </tbody> +</table> +<h3 id="Action:_A_JavaScript_demonstration" name="Action:_A_JavaScript_demonstration">Ação: Uma demonstração de JavaScript</h3> +<p>Faça um novo documento em HTML, <code>doc5.html</code>. Copie e cole o conteúdo daqui, tenha certeza de rolar para copiar todo o código:</p> +<div style="width: 48em;"> + <pre class="brush:html;"><!DOCTYPE html> +<html> + +<head> +<title>Mozilla CSS Getting Started - JavaScript demonstration</title> +<link rel="stylesheet" type="text/css" href="style5.css" /> +<script type="text/javascript" src="script5.js"></script> +</head> + +<body> +<h1>JavaScript sample</h1> + +<div id="square"></div> + +<button type="button" onclick="doDemo(this);">Click Me</button> + +</body> +</html> +</pre> +</div> +<p>Crie um novo arquivo CSS, <code>style5.css</code>. Copie e cole o conteúdo daqui:</p> +<div style="width: 48em;"> + <pre class="brush:css;">/*** JavaScript demonstration ***/ +#square { + width: 20em; + height: 20em; + border: 2px inset gray; + margin-bottom: 1em; +} + +button { + padding: .5em 2em; +} +</pre> +</div> +<p>Crie um novo arquivo de texto, <code>script5.js</code>. Coie e cole o conteúdo daqui:</p> +<div style="width: 48em;"> + <pre class="brush:js;">// JavaScript demonstration +function doDemo (button) { + var square = document.getElementById("square"); + square.style.backgroundColor = "#fa4"; + button.setAttribute("disabled", "true"); + setTimeout(clearDemo, 2000, button); +} + +function clearDemo (button) { + var square = document.getElementById("square"); + square.style.backgroundColor = "transparent"; + button.removeAttribute("disabled"); +} +</pre> +</div> +<p>Abra o documento no seu Browser e pressione o botão.</p> +<p>Esta wiki não suporta JavaScript nas páginas, então não é possível mostrar uma demonstração aqui. parece algo assim, antes e depois de você pressionar o botão:</p> +<table> + <tbody> + <tr> + <td style="padding-right: 2em;"> + <table style="border: 2px outset #36b; padding: 0 1em .5em .5em;"> + <tbody> + <tr> + <td> + <p><strong>JavaScript demonstration</strong></p> + </td> + </tr> + </tbody> + </table> + </td> + <td> + <table style="border: 2px outset #36b; padding: 0 1em .5em .5em;"> + <tbody> + <tr> + <td> + <p><strong>JavaScript demonstration</strong></p> + </td> + </tr> + </tbody> + </table> + </td> + </tr> + </tbody> +</table> +<div class="note"> + <strong>Notas importantes </strong>sobre esta demonstração: + <ul> + <li>Os links do documento HTML document linca a como usual, e também linca o script.</li> + <li>O script trabalha com elementos individuais no DOM. Ele modifica o square's style diretamente. Ele modifica o estilo dos botões indiretamente mudando um atributo.</li> + <li>Em JavaScript, <code>document.getElementById("square")</code> é similar em função ao seletor CSS <code>#square</code>.</li> + <li>Em JavaScript, <code>backgroundColor</code> corresponde à propriedade CSS<span style="line-height: 1.5em;"> </span><code style="font-size: 14px;">background-color</code><span style="line-height: 1.5em;">. JavaScript não permite hífens em nomes, então "camelCase" é usada no lugar dele.</span></li> + <li>Seu browser tem uma regra built-in CSS para<span style="line-height: 1.5em;"> </span><code style="font-size: 14px;">button{{ mediawiki.external('disabled=\"true\"') }}</code><span style="line-height: 1.5em;"> ela muda a aparência dos botões quando está disabilitado.</span></li> + </ul> +</div> +<table style="border: 1px solid #36b; padding: 1em; background-color: #fffff4; margin-bottom: .5em;"> + <caption> + Desafio</caption> + <tbody> + <tr> + <td> + <p>Mude o script e então o <span style="line-height: inherit;">square salta para a direita em 20 em quando muda as cores, e salta de volta depois.</span></p> + </td> + </tr> + </tbody> +</table> +<p><a href="/en/CSS/Getting_Started/Challenge_solutions#JavaScript" title="https://developer.mozilla.org/en/CSS/Getting_Started/Challenge_solutions#JavaScript">Veja a solução deste desafio.</a></p> +<p><span style="font-family: Georgia, Times, 'Times New Roman', serif; font-size: 1.428em; line-height: inherit;">O que vem agora?</span></p> +<p>Se você teve dificuldade para entender esta página, ou se tem algum coment[ario sobre, por favor, contribua nesta página de <a href="/Talk:en/CSS/Getting_Started/JavaScript" title="Talk:en/CSS/Getting_Started/JavaScript">Di</a>scussão.</p> +<p>Nesta deminstração, o arquivo HTML linca o the script apesar do botão de elementos usar script. Mozilla extende CSS então consegue lincar o código JavaScript (e também conteúdo e outras <span style="line-height: inherit;">stylesheets) para selecionar elementos. A próxima página demonstra isso: </span><strong style="line-height: inherit;"><a href="/en/CSS/Getting_Started/XBL_bindings" title="en/CSS/Getting_Started/XBL_bindings">XBL bindings</a></strong></p> diff --git a/files/pt-br/learn/javascript/first_steps/matematica/index.html b/files/pt-br/learn/javascript/first_steps/math/index.html index fce74528f7..fce74528f7 100644 --- a/files/pt-br/learn/javascript/first_steps/matematica/index.html +++ b/files/pt-br/learn/javascript/first_steps/math/index.html diff --git a/files/pt-br/learn/javascript/first_steps/gerador_de_historias_bobas/index.html b/files/pt-br/learn/javascript/first_steps/silly_story_generator/index.html index cc8a8cc542..cc8a8cc542 100644 --- a/files/pt-br/learn/javascript/first_steps/gerador_de_historias_bobas/index.html +++ b/files/pt-br/learn/javascript/first_steps/silly_story_generator/index.html diff --git a/files/pt-br/learn/javascript/first_steps/teste_suas_habilidades_colon__variaveis/index.html b/files/pt-br/learn/javascript/first_steps/test_your_skills_colon__variables/index.html index 1a14c86630..1a14c86630 100644 --- a/files/pt-br/learn/javascript/first_steps/teste_suas_habilidades_colon__variaveis/index.html +++ b/files/pt-br/learn/javascript/first_steps/test_your_skills_colon__variables/index.html diff --git a/files/pt-br/learn/javascript/first_steps/variáveis/index.html b/files/pt-br/learn/javascript/first_steps/variables/index.html index 1afd436622..1afd436622 100644 --- a/files/pt-br/learn/javascript/first_steps/variáveis/index.html +++ b/files/pt-br/learn/javascript/first_steps/variables/index.html diff --git a/files/pt-br/learn/javascript/first_steps/o_que_e_javascript/index.html b/files/pt-br/learn/javascript/first_steps/what_is_javascript/index.html index 771541b047..771541b047 100644 --- a/files/pt-br/learn/javascript/first_steps/o_que_e_javascript/index.html +++ b/files/pt-br/learn/javascript/first_steps/what_is_javascript/index.html diff --git a/files/pt-br/learn/javascript/howto/index.html b/files/pt-br/learn/javascript/howto/index.html new file mode 100644 index 0000000000..c06dbd4d3f --- /dev/null +++ b/files/pt-br/learn/javascript/howto/index.html @@ -0,0 +1,290 @@ +--- +title: Solve common problems in your JavaScript code +slug: Aprender/JavaScript/Howto +translation_of: Learn/JavaScript/Howto +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">Os links a seguir apontam soluções para problemas comuns do dia a dia, você precisará consertar em ordem para que seu código javascript execute corretamente.</p> + +<h2 id="Erros_comuns_de_iniciantes">Erros comuns de iniciantes</h2> + +<h3 id="Digitação_correta_and_casing">Digitação correta and casing</h3> + +<p>Se o seu código não funciona e/ou se seu navegador indicar que algo está indefinido, verifique se você declarou todas os nomes de suas variáveis, nomes de funções, etc. corretamente.</p> + +<p>Algumas funções comuns dos navegadores que causam problema são:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Correto</th> + <th scope="col">Incorreto</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>getElementsByTagName()</code></td> + <td><code>getElementbyTagName()</code></td> + </tr> + <tr> + <td><code>getElementsByName()</code></td> + <td><code>getElementByName()</code></td> + </tr> + <tr> + <td><code>getElementsByClassName()</code></td> + <td><code>getElementByClassName()</code></td> + </tr> + <tr> + <td><code>getElementById()</code></td> + <td><code>getElementsById()</code></td> + </tr> + </tbody> +</table> + +<h3 id="Posições_de_ponto_e_vírgula">Posições de ponto e vírgula</h3> + +<p>Você precisa ter certeza que você não colocou nenhum ponto e vírgula incorretamente. Por exemplo:</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Correct</th> + <th scope="col">Wrong</th> + </tr> + <tr> + <td><code>elem.style.color = 'red';</code></td> + <td><code>elem.style.color = 'red;'</code></td> + </tr> + </thead> +</table> + +<h3 id="Funções">Funções</h3> + +<p>Há uma série de coisas que podem dar errado com funções</p> + +<p>Um dos erros mais comuns é declarar a função, mas não chama-la em lugar nenhum. Por exemplo:</p> + +<pre class="brush: js">function myFunction() { + alert('This is my function.'); +};</pre> + +<p>Este código não fará nada a menos que você o chame, por exemplo com</p> + +<pre class="brush: js">myFunction();</pre> + +<h4 id="Escopo_da_função">Escopo da função</h4> + +<p>Lembre-se que <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Function_scope_and_conflicts">funções tem seu próprio escopo</a> — você não pode acessar um conjunto de valores de variáveis dentro de uma função fora da função, a não ser que você tenha declarado a variável globalmente (i.e. não dentro de nenhuma função), ou retorne o valor or <a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">retorne o valor</a> fora da função</p> + +<h4 id="Executar_o_código_antes_de_uma_declaração_de_retorno">Executar o código antes de uma declaração de retorno</h4> + +<p>Remember also that when you return a value out of a function, the JavaScript interpreter exits the function — no code declared after the return statement will run.</p> + +<p>In fact, some browsers (like Firefox) will give you an error message in the developer console if you have code after a return statement. Firefox gives you "unreachable code after return statement".</p> + +<h3 id="Object_notation_versus_normal_assignment">Object notation versus normal assignment</h3> + +<p>When you assign something normally in JavaScript, you use a single equals sign, e.g.:</p> + +<pre class="brush: js">var myNumber = 0;</pre> + +<p>This doesn't work in <a href="/en-US/docs/Learn/JavaScript/Objects">Objects</a>, however — with objects you need to separate member names from their values using colons, and separate each member with a comma, for example:</p> + +<pre class="brush: js">var myObject = { + name : 'Chris', + age : 38 +}</pre> + +<h2 id="Definições_básicas">Definições básicas</h2> + +<div class="column-container"> +<div class="column-half"> +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript#A_high-level_definition">O que é Javascript?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables#What_is_a_variable">O que é uma variável?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings">O que são strings?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#What_is_an_Array">O que é um vetor?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">O que é um laço?</a></li> +</ul> +</div> + +<div class="column-half"> +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions">O que é uma função?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events">O que é um evento?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#Object_basics">O que é um objeto?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON#No_really_what_is_JSON">O que é JSON?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Introduction#What_are_APIs">O que é uma web API?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents#The_document_object_model">O que é o DOM?</a></li> +</ul> +</div> +</div> + +<h2 id="Casos_de_uso_básicos">Casos de uso básicos</h2> + +<div class="column-container"> +<div class="column-half"> +<h3 id="Geral">Geral</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript#How_do_you_add_JavaScript_to_your_page">Como adicionar JavasScript para sua página?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_is_JavaScript#Comments">Como adicionar comentários em um código Javascript?</a></li> +</ul> + +<h3 id="Variáveis">Variáveis</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables#Declaring_a_variable">Como você declara uma variável?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables#Initializing_a_variable">Como você inicializa uma variável com um valor?</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Variables#Updating_a_variable">Como você atualiza o valor de uma variável</a> (ver também <a href="/en-US/docs/Learn/JavaScript/First_steps/Math#Assignment_operators">Operadores de atribuição</a>)</li> + <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Variables#Variable_types">Quais tipos de dados os valores podem ter em JavaScript?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Variables#Loose_typing">O que 'fracamente tipada' significa?</a></li> +</ul> + +<h3 id="Matemática">Matemática</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math#Types_of_numbers">Quais tipos de números você tem que lidar no desenvolvimento web?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math#Arithmetic_operators">Como você faz matemática básica em JavaScript?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math#Operator_precedence">Qual a precedência do operador, e como isso é tratado em JavaScript?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Math#Increment_and_decrement_operators">Como você incrementa e decrementa valores em JavaScript?</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps/Math#Comparison_operators">Como você compara valores em JavaScript?</a> (por exemplo, para ver qual é o maior, ou para ver se um valor é igual ao outro).</li> +</ul> + +<h3 id="Strings">Strings</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings#Creating_a_string">Como você cria uma string em JavaScript?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings#Single_quotes_versus_double_quotes">Do you have to use single quotes or double quotes?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings#Escaping_characters_in_a_string">How do you escape characters in strings?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings#Concatenating_strings">How do you join strings together?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Strings#Numbers_versus_strings">Can you join strings and numbers together?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods#Finding_the_length_of_a_string">How do you find the length of a string?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods#Retrieving_a_specific_string_character">How you find what character is at a certain position in a string?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods#Finding_a_substring_inside_a_string_and_extracting_it">How do you find and extract a specific substring from a string?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods#Changing_case">How do you change the case of a string?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Useful_string_methods#Updating_parts_of_a_string">How do you replace one specific substring with another?</a></li> +</ul> +</div> + +<div class="column-half"> +<h3 id="Arrays">Arrays</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#Creating_an_array">How do you create an array?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#Accessing_and_modifying_array_items">How do you access and modify the items in an array?</a> (this includes multidimensional arrays)</li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#Finding_the_length_of_an_array">How do you find the length of an array?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#Adding_and_removing_array_items">How you add and remove array items?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/Arrays#Converting_between_strings_and_arrays">How do you split a string into array items, or join array items into a string?</a></li> +</ul> + +<h3 id="Debugging_JavaScript">Debugging JavaScript</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong#Types_of_error">What are the basic types of error?</a></li> + <li><a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools">What are browser developer tools, and how do you access them?</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript#The_Console_API">How do you log a value to the JavaScript console?</a></li> + <li><a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript#Using_the_JavaScript_debugger">How do you use breakpoints, and other JavaScript debugging features?</a></li> +</ul> + +<p>For more information on JavaScript debugging, see <a href="/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/JavaScript">Handling common JavaScript problems</a>; also see <a href="/en-US/docs/Learn/JavaScript/First_steps/What_went_wrong#Other_common_errors">Other common errors</a> for a description of common errors.</p> + +<h3 id="Making_decisions_in_code">Making decisions in code</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals">How do you execute different blocks of code, depending on a variable's value or other condition?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals#if_..._else_statements">How do you use if ...else statements?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals#Nesting_if_..._else">How do nest one decision block inside another?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals#Logical_operators_AND_OR_and_NOT">How do you use AND, OR, and NOT operators in JavaScript?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/conditionals#switch_statements">How do you conveniently handle a large number of choices for one condition?</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/conditionals#Ternary_operator">How do you use a ternary operator to make a quick choice between two options based on a true or false test?</a></li> +</ul> + +<h3 id="Loopingiteration">Looping/iteration</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code">How do you run the same bit of code over and over again?</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code#Exiting_loops_with_break">How do you exit a loop before the end if a certain condition is met?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code#Skipping_iterations_with_continue">How do you skip to the next iteration of a loop if a certain condition is met?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code#while_and_do_..._while">How do you use while and do ... while loops?</a></li> + <li>How to iterate over the elements in an array</li> + <li>How to iterate over the elements in a multidimensional array</li> + <li>How to iterate over the members in an object</li> + <li>How to iterate over the members of an object nested inside an array</li> +</ul> +</div> +</div> + +<h2 id="Intermediate_use_cases">Intermediate use cases</h2> + +<div class="column-container"> +<div class="column-half"> +<h3 id="Functions">Functions</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Built-in_browser_functions">How do you find functions in the browser?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Functions_versus_methods">What is the difference between a function and a method?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Build_your_own_function">How do you create your own functions?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Invoking_functions">How do you run (call, or invoke) a function?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Anonymous_functions">What is an anonymous function?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Function_parameters">How do you specify parameters (or arguments) when invoking a function?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Functions#Function_scope_and_conflicts">What is function scope?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Return_values">What are return values, and how do you use them?</a></li> +</ul> + +<h3 id="Objects">Objects</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#Object_basics">How do you create an object?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#Dot_notation">What is dot notation?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#Bracket_notation">What is bracket notation?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#Setting_object_members">How do you get and set the methods and properties of an object?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics#What_is_this">What is <code>this</code>, in the context of an object?</a></li> + <li><a href="/docs/Learn/JavaScript/Objects/Object-oriented_JS#Object-oriented_programming_from_10000_meters">What is object-oriented programming?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS#Constructors_and_object_instances">What are constructors and instances, and how do you create them?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS#Other_ways_to_create_object_instances">What different ways are there to create objects in JavaScript?</a></li> +</ul> + +<h3 id="JSON">JSON</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON#JSON_structure">How do you structure JSON data, and read it from JavaScript?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON#Loading_our_JSON">How can you load a JSON file into a page?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON#Converting_between_objects_and_text">How do you convert a JSON object to a text string, and back again?</a></li> +</ul> +</div> + +<div class="column-half"> +<h3 id="Eventos">Eventos</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_handler_properties">What are event handlers and how do you use them?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Inline_event_handlers_%E2%80%94_don%27t_use_these">What are inline event handlers?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#addEventListener()_and_removeEventListener()">What does the <code>addEventListener()</code> function do, and how do you use it?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#What_mechanism_should_I_use">Which mechanism should I use to add event code to my web pages?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_objects">What are event objects, and how do you use them?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Preventing_default_behaviour">How do you prevent default event behaviour?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture">How do events fire on nested elements? (event propagation, also related — event bubbling and capturing)</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_delegation">What is event delegation, and how does it work?</a></li> +</ul> + +<h3 id="Javascript_Orientado_a_objetos">Javascript Orientado a objetos</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes"> Quais são protótipos de objetos?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes#The_constructor_property">Qual é a propriedade do construtor, e como você pode usa-la?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes#Modifying_prototypes">Como você adiciona métodos para o construtor?</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Como você cria um novo constructor que herda os membros do construtor pai? </a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance#Object_member_summary">Quando você deve usar herança em Javascript?</a></li> +</ul> + +<h3 id="Web_APIs">Web APIs</h3> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents#Active_learning_Basic_DOM_manipulation">Como você manipula o DOM (por exemplo, adicionando e removendo elementos) usando Javascript?</a></li> +</ul> + +<p> </p> +</div> +</div> diff --git a/files/pt-br/learn/javascript/index.html b/files/pt-br/learn/javascript/index.html new file mode 100644 index 0000000000..d1a9db5057 --- /dev/null +++ b/files/pt-br/learn/javascript/index.html @@ -0,0 +1,78 @@ +--- +title: JavaScript +slug: Aprender/JavaScript +tags: + - Beginner + - CodingScripting + - Iniciante Javascript + - JavaScript + - NeedsContent + - Principiante + - Tópico + - modulo +translation_of: Learn/JavaScript +--- +<p>{{LearnSidebar}}</p> + +<p>{{glossary('JavaScript')}} é uma linguagem de programação que permite implementar funcionalidades mais complexas em páginas web. Sempre que uma página web faz mais do que apenas mostrar informações estáticas para você - ela mostra em tempo real conteúdos atualizados, mapas interativos, animações gráficas em 2D/3D, vídeos, etc. - você pode apostar que o Javascript provavelmente está envolvido.</p> + +<h2 id="O_caminho_para_o_aprendizado">O caminho para o aprendizado</h2> + +<p>O JavaScript não é tão fácil de aprender como outras linguagens, como <a href="https://developer.mozilla.org/pt-BR/docs/Aprender/HTML">HTML</a> e <a href="https://developer.mozilla.org/pt-BR/docs/Aprender/CSS">CSS</a>, que são outros dois pilares do desenvolvimento front-end. Antes de tentar aprender JavaScript, é altamente recomendável que você aprenda e se familiarize com pelo menos estas duas tecnologias primeiro. Você pode começar através dos seguintes módulos:</p> + +<ul> + <li><a href="/pt-BR/docs/Aprender/Getting_started_with_the_web">Começando na Web</a></li> + <li><a href="/pt-BR/docs/Aprender/HTML/Introducao_ao_HTML">Introdução ao HTML</a></li> + <li><a href="/pt-BR/docs/Aprender/CSS/Introduction_to_CSS">Introdução ao CSS</a></li> +</ul> + +<p>Possuir experiência em outras linguagens de programação pode também ser útil.</p> + +<p>Depois de aprender o básico de JavaScript, você estará apto a estudar tópicos mais avançados, como:</p> + +<ul> + <li>JavaScript aprofundado, como ensinado em <a href="/pt-BR/docs/Web/JavaScript/Guide">Guia JavaScript</a></li> + <li><a href="/pt-BR/docs/Web/Reference/API">Referências API Web</a></li> +</ul> + +<h2 id="Módulos">Módulos</h2> + +<p>Este tópico contém os seguintes módulos, em uma ordem que sugerimos para estudá-los.</p> + +<dl> + <dt><a href="https://wiki.developer.mozilla.org/pt-BR/docs/Learn/JavaScript/First_steps">Primeiros passos em JavaScript</a></dt> + <dd>Em nosso primeiro módulo JavaScript, primeiro responderemos algumas questões fundamentais como "o que é JavaScript?", "Como ele se parece?" E "o que ele pode fazer?", antes de passar para sua primeira experiência prática de escrever JavaScript. Depois disso, discutimos alguns recursos chave do JavaScript em detalhes, como variáveis, cadeias de caracteres, números e matrizes.</dd> + <dt><a href="https://wiki.developer.mozilla.org/pt-BR/docs/Aprender/JavaScript/Elementos_construtivos">Blocos de codigo JavaScript</a></dt> + <dd>Neste módulo, continuaremos a falar sobre os principais recursos fundamentais do JavaScript, voltando nossa atenção para os tipos mais comuns de blocos de código<strong>,</strong> como instruções condicionais, funções e eventos. Você já viu essas coisas no curso, mas apenas de passagem, aqui discutiremos tudo explicitamente.</dd> + <dt><a href="https://wiki.developer.mozilla.org/pt-BR/docs/Aprender/JavaScript/Objetos">Introdução a objetos em JavaScript</a></dt> + <dd>Em JavaScript, a maioria das coisas são objetos, desde seus principais recursos até as APIs do navegador. Você pode até criar seus próprios objetos.É importante entender a natureza orientada a objetos do JavaScript se você quiser ir mais longe com seu conhecimento da linguagem e escrever um código mais eficiente, portanto, fornecemos este módulo para ajudá-lo. Aqui ensinamos a teoria e a sintaxe de objetos em detalhes, observamos como criar seus próprios objetos e explicamos quais são os dados JSON e como trabalhar com eles.</dd> + <dt><strong><a href="https://wiki.developer.mozilla.org/pt-BR/docs/Learn/JavaScript/Asynchronous">JavaScript Assíncrono</a></strong></dt> + <dd>Neste módulo, examinamos o JavaScript assíncrono, por que é importante e como ele pode ser usado para lidar efetivamente com possíveis operações de bloqueio, como a busca de recursos de um servidor.</dd> + <dt><a href="https://wiki.developer.mozilla.org/pt-BR/docs/Aprender/JavaScript/Client-side_web_APIs">API's Web do lado cliente</a></dt> + <dd>Ao escrever JavaScript para sites ou aplicativos da Web, você não vai muito longe antes de começar a usar APIs - interfaces para manipular diferentes aspectos do navegador e do sistema operacional em que o site está sendo executado, ou até dados de outros sites ou serviços. Neste módulo, vamos explorar o que são as APIs e como usar algumas das APIs mais comuns que você encontrará com frequência em seu trabalho de desenvolvimento.</dd> +</dl> + +<h2 id="Aprofundando">Aprofundando</h2> + +<p>Uma vez que você se acostumar com o mundo do JavaScript aqui estão alguns outros módulos em que você pode mergulhar:</p> + +<dl> + <dt><a href="/pt-BR/docs/Web/JavaScript/Reference">Biblioteca de referência JavaScript</a></dt> + <dd>Em nossa extensa biblioteca de referência você encontrará cada aspecto de Javascript tratado em detalhes: objetos globais, operadores, declarações e funções.</dd> + <dt><a href="/pt-BR/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript">Introdução à Orientação a Objetos (OO) em JavaScript</a></dt> + <dd>Introdução aos conceitos de {{glossary("OOP","Programação orientada a objetos")}} em JavaScript.</dd> +</dl> + +<h2 id="Resolvendo_problemas_comuns_com_Javascript">Resolvendo problemas comuns com Javascript</h2> + +<p><a href="https://developer.mozilla.org/pt-BR/docs/Learn/JavaScript/Howto">Use Javascript para resolver problemas comuns</a>, este link proporciona contéudos explicativos de como usar o JavaScript para solucionar problemas muito comuns ao criar uma página da Web.</p> + +<h2 id="Veja_também">Veja também</h2> + +<dl> + <dt><a href="/pt-BR/docs/Web/JavaScript">JavaScript</a></dt> + <dd>O ponto de entrada principal para a documentação básica do JavaScript no MDN - é aqui que você encontrará extensos documentos de referência em todos os aspectos do JavaScript e alguns tutoriais avançados destinados a JavaScripters experientes.</dd> + <dt><a href="https://www.youtube.com/user/codingmath">Matemática do programador</a></dt> + <dd>Uma excelente série de vídeos que ensina a matemática necessária para ser um bom programador, por <a href="https://twitter.com/bit101">Keith Peters</a>.</dd> + <dt></dt> +</dl> diff --git a/files/pt-br/learn/javascript/objects/adding_bouncing_balls_features/index.html b/files/pt-br/learn/javascript/objects/adding_bouncing_balls_features/index.html new file mode 100644 index 0000000000..b0e0c0d534 --- /dev/null +++ b/files/pt-br/learn/javascript/objects/adding_bouncing_balls_features/index.html @@ -0,0 +1,202 @@ +--- +title: Adicionando recursos à nossa demonstração de bolas pulantes +slug: Aprender/JavaScript/Objetos/Adding_bouncing_balls_features +translation_of: Learn/JavaScript/Objects/Adding_bouncing_balls_features +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">Nesta avaliação, espera-se que você use a demonstração de bolas saltantes do artigo anterior como ponto de partida e adicione alguns recursos novos e interessantes a ela.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisites:</th> + <td>Before attempting this assessment you should have already worked through all the articles in this module.</td> + </tr> + <tr> + <th scope="row">Objective:</th> + <td>To test comprehension of JavaScript objects and object-oriented constructs</td> + </tr> + </tbody> +</table> + +<h2 id="Ponto_de_partida">Ponto de partida</h2> + +<p>Para iniciar essa avaliação, faça uma cópia local de <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/index-finished.html">index-finished.html</a>, <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/style.css">style.css</a>, e <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main-finished.js">main-finished.js</a> do nosso último artigo em um novo diretório em seu computador local.</p> + +<div class="note"> +<p><strong>Note</strong>: Alternatively, you could use a site like <a class="external external-icon" href="http://jsbin.com/">JSBin</a> or <a class="external external-icon" href="https://thimble.mozilla.org/">Thimble</a> to do your assessment. You could paste the HTML, CSS and JavaScript into one of these online editors. If the online editor you are using doesn't have separate JavaScript/CSS panels, feel free to put them inline <code><script></code>/<code><style></code> elements inside the HTML page.</p> +</div> + +<h2 id="Resumo_do_projeto">Resumo do projeto</h2> + +<p>Nossa demo com bola saltitante é divertida, mas agora queremos torná-la um pouco mais interativa, adicionando um círculo maligno controlado pelo usuário, que vai comer as bolas se elas forem capturadas. Também queremos testar suas habilidades de construção de objetos criando um objeto <code>Shape()</code> genérico do qual nossas bolas e círculo maligno podem herdar. Por fim, queremos adicionar um contador de pontuação para rastrear o número de bolas a serem capturadas.</p> + +<p>A imagem seguinte dá-lhe uma ideia do que deve ser o programa final:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13875/bouncing-evil-circle.png" style="display: block; margin: 0 auto;"></p> + +<ul> +</ul> + +<p>Para lhe dar mais uma ideia, dê uma olhada no <a href="http://mdn.github.io/learning-area/javascript/oojs/assessment/">exemplo finalizado</a> (não espreitar o código-fonte!)</p> + +<h2 id="Passos_para_concluir">Passos para concluir</h2> + +<p>As seções a seguir descrevem o que você precisa fazer.</p> + +<h3 id="Criando_nossos_novos_objetos">Criando nossos novos objetos</h3> + +<p>Primeiro de tudo, altere seu construtor <code>Ball()</code> existente para que ele se torne um construtor <code>Shape()</code> e adicione um novo construtor <code>Ball()</code>:</p> + +<ol> + <li>O construtor <code>Shape()</code> deve definir as propriedades <code>x</code>, <code>y</code>, <code>velX</code>, e <code>velY</code> da mesma maneira que o construtor <code>Ball()</code> fez originalmente, mas não as propriedades de <code>color</code> e <code>size</code>.</li> + <li>Também deve definir uma nova propriedade chamada <code>exists</code>, que é usada para rastrear se as bolas existem no programa (não foram comidas pelo círculo do mal). Este deve ser um booleano (<code>true</code>/<code>false</code>).</li> + <li>O construtor <code>Ball()</code> deve herdar as propriedades <code>x</code>, <code>y</code>, <code>velX</code>, <code>velY</code>, e <code>exists</code> do construtor <code>Shape()</code>.</li> + <li>Ele também deve definir uma propriedade <code>color</code> e uma <code>size</code>, como fez o construtor <code>Ball()</code> original.</li> + <li>Lembre-se de definir o <code>prototype</code> e o <code>constructor</code> do construtor <code>Ball()</code> adequadamente.</li> +</ol> + +<p>As definições do método ball <code>draw()</code>, <code>update()</code>, e <code>collisionDetect()</code> devem permanecer exatamente iguais às anteriores.</p> + +<p>Você também precisa adicionar um novo parâmetro à nova chamada de construtor <code>new Ball() ( ... )</code> — o parâmetro <code>exists</code> deve ser o quinto parâmetro, e deve receber um valor <code>true</code>.</p> + +<p>Neste ponto, tente recarregar o código — ele deve funcionar da mesma forma que antes, com nossos objetos redesenhados.</p> + +<h3 id="Definindo_EvilCircle()">Definindo EvilCircle()</h3> + +<p>Agora é hora de conhecer o cara mau — o <code>EvilCircle()</code>! Nosso jogo só envolverá um círculo maligno, mas ainda vamos defini-lo usando um construtor que herda de <code>Shape()</code> para lhe dar alguma prática. Você pode querer adicionar outro círculo ao aplicativo mais tarde, que pode ser controlado por outro jogador, ou ter vários círculos malignos controlados por computador. Você provavelmente não vai dominar o mundo com um único círculo maligno, mas fará por essa avaliação.</p> + +<p>O construtor <code>EvilCircle()</code> deve herdar <code>x</code>, <code>y</code>, <code>velX</code>, <code>velY</code>, e <code>exists</code> de <code>Shape()</code>, mas <code>velX</code> e <code>velY</code> devem sempre ser iguais a 20.</p> + +<p>Você deveria fazer algo como <code>Shape.call(this, x, y, 20, 20, exists);</code></p> + +<p>Ele também deve definir suas próprias propriedades, da seguinte maneira:</p> + +<ul> + <li><code>color</code> — <code>'white'</code></li> + <li><code>size</code> — <code>10</code></li> +</ul> + +<p>Novamente, lembre-se de definir suas propriedades herdadas como parâmetros no construtor e defina as propriedades <code>prototype</code> e <code>constructor</code> corretamente.</p> + +<h3 id="Definindo_os_métodos_de_EvilCircle()">Definindo os métodos de EvilCircle()</h3> + +<p><code>EvilCircle()</code> deve ter quatro métodos, conforme descrito abaixo.</p> + +<h4 id="draw()"><code>draw()</code></h4> + +<p>Este método tem o mesmo propósito que o método <code>draw()</code> de <code>Ball()</code>: Ele desenha a instância do objeto na tela. Ele funcionará de maneira muito semelhante, portanto, você pode começar copiando a definição <code>Ball.prototype.draw</code>. Você deve então fazer as seguintes alterações:</p> + +<ul> + <li>Nós queremos que o círculo do mal não seja preenchido, mas apenas tenha uma linha externa (traço). Você pode conseguir isso atualizando <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle">fillStyle</a></code> e <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fill">fill()</a></code> para <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle">strokeStyle</a></code> e <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/stroke">stroke()</a></code>.</li> + <li>Também queremos tornar o traço um pouco mais espesso, para que você possa ver o círculo maligno com mais facilidade. Isso pode ser obtido definindo um valor para <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth">lineWidth</a></code> em algum lugar após a chamada <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath">beginPath()</a></code> (3 será suficiente).</li> +</ul> + +<h4 id="checkBounds()"><code>checkBounds()</code></h4> + +<p>Este método fará a mesma coisa que a primeira parte da função <code>update()</code> do <code>Ball()</code> — olhe para ver se o círculo do mal vai sair da borda da tela, e pare de fazer isso. Novamente, você pode simplesmente copiar a definição de <code>Ball.prototype.update</code>, mas há algumas alterações que você deve fazer:</p> + +<ul> + <li>Livre-se das duas últimas linhas - não queremos atualizar automaticamente a posição do círculo maligno em todos os quadros, pois estaremos mudando isso de alguma outra forma, como você verá abaixo.</li> + <li>Dentro das instruções <code>if()</code>, se os testes retornam true, não queremos atualizar o <code>velX</code>/<code>velY</code>; Em vez disso, queremos alterar o valor de <code>x</code>/<code>y</code> para que o círculo maligno seja devolvido na tela um pouco. Adicionar ou subtrair (conforme apropriado) a propriedade <code>size</code> do círculo maligno faria sentido.</li> +</ul> + +<h4 id="setControls()"><code>setControls()</code></h4> + +<p>Esse método adicionará um ouvinte de evento <code>onkeydown</code> ao objeto <code>window</code> para que, quando determinadas teclas do teclado forem pressionadas, possamos mover o círculo maligno ao redor. O bloco de código a seguir deve ser colocado dentro da definição do método:</p> + +<pre class="brush: js">var _this = this; +window.onkeydown = function(e) { + if (e.keyCode === 65) { + _this.x -= _this.velX; + } else if (e.keyCode === 68) { + _this.x += _this.velX; + } else if (e.keyCode === 87) { + _this.y -= _this.velY; + } else if (e.keyCode === 83) { + _this.y += _this.velY; + } + }</pre> + +<p>Assim, quando uma tecla é pressionada, a propriedade <a href="/en-US/docs/Web/API/KeyboardEvent/keyCode">keyCode</a> é consultada para ver qual tecla é pressionada. Se for um dos quatro representados pelos códigos de teclas especificados, o círculo maligno se moverá para a esquerda / direita / para cima / para baixo.</p> + +<ul> + <li>Para um ponto de bônus, deixe-nos saber a quais chaves os códigos de teclas específicos estão mapeados.</li> + <li>Para outro ponto de bônus, você pode nos dizer por que precisamos definir <code>var _this = this;</code> na posição em que está? É algo a ver com o escopo da função.</li> +</ul> + +<h4 id="collisionDetect()"><code>collisionDetect()</code></h4> + +<p>Este método irá agir de forma muito semelhante ao método<code><font face="Arial, x-locale-body, sans-serif"><span style="background-color: #ffffff;"> </span></font></code><code>collisionDetect()</code> do <code>Ball()</code>, então você pode usar uma cópia disso como base deste novo método. Mas há algumas diferenças:</p> + +<ul> + <li>Na declaração <code>if</code> externa, você não precisa mais verificar se a bola atual na iteração é igual à bola que está fazendo a verificação - porque ela não é mais uma bola, é o círculo do mal! Em vez disso, você precisa fazer um teste para ver se a bola que está sendo checada existe (com qual propriedade você poderia fazer isso?). Se não existe, já foi comido pelo círculo do mal, por isso não há necessidade de verificá-lo novamente.</li> + <li>Na instrução <code>if</code> interna, você não quer mais que os objetos mudem de cor quando uma colisão é detectada — em vez disso, você quer definir quaisquer bolas que colidam com o círculo maligno para não existir mais (novamente, como você pensa? d fazer isso?).</li> +</ul> + +<h3 id="Trazendo_o_círculo_do_mal_para_o_programa">Trazendo o círculo do mal para o programa</h3> + +<p>Agora nós definimos o círculo do mal, precisamos realmente fazer isso aparecer em nossa cena. Para fazer isso, você precisa fazer algumas alterações na função <code>loop()</code>.</p> + +<ul> + <li>Primeiro de tudo, crie uma nova instância de objeto do círculo do mal (especificando os parâmetros necessários) e, em seguida, chame seu método <code>setControls()</code>. Você só precisa fazer essas duas coisas uma vez, não em todas as iterações do loop.</li> + <li>No ponto em que você percorre todas as bolas e chama as funções <code>draw()</code>, <code>update()</code>, e <code>collisionDetect()</code> para cada uma, faça com que essas funções sejam chamadas apenas se a bola atual existir.</li> + <li>Chame os métodos <code>draw()</code>, <code>checkBounds()</code>, e <code>collisionDetect()</code> da instância do mal ball em cada iteração do loop.</li> +</ul> + +<h3 id="Implementando_o_contador_de_pontuação">Implementando o contador de pontuação</h3> + +<p>Para implementar o contador de pontuação, siga os seguintes passos:</p> + +<ol> + <li>No seu arquivo HTML, adicione um elemento {{HTMLElement("p")}} logo abaixo do elemento {{HTMLElement("h1")}} contendo o texto "Contagem de bolas:".</li> + <li>No seu arquivo CSS, adicione a seguinte regra na parte inferior: + <pre class="brush: css">p { + position: absolute; + margin: 0; + top: 35px; + right: 5px; + color: #aaa; +}</pre> + </li> + <li>Em seu JavaScript, faça as seguintes atualizações: + <ul> + <li>Crie uma variável que armazene uma referência ao parágrafo.</li> + <li>Mantenha uma contagem do número de bolas na tela de alguma forma.</li> + <li>Incrementar a contagem e exibir o número atualizado de bolas cada vez que uma bola é adicionada à cena.</li> + <li>Decrementar a contagem e exibir o número atualizado de bolas cada vez que o círculo maligno come uma bola (faz com que ele não exista).</li> + </ul> + </li> +</ol> + +<h2 id="Dicas_e_sugestões">Dicas e sugestões</h2> + +<ul> + <li>Essa avaliação é bastante desafiadora. Tome cada passo devagar e com cuidado.</li> + <li>Pode ser uma idéia manter uma cópia separada da demo depois que você fizer com que cada estágio funcione, para que você possa consultá-la caso se encontre em apuros mais tarde.</li> +</ul> + +<h2 id="Avaliação">Avaliação</h2> + +<p>Se você está seguindo esta avaliação como parte de um curso organizado, você deve poder dar seu trabalho ao seu professor / mentor para marcação. Se você é auto-didata, então você pode obter o guia de marcação com bastante facilidade, perguntando no tópico de <a href="https://discourse.mozilla.org/t/adding-features-to-our-bouncing-balls-demo-assessment/24689">discussão para este exercício</a>, ou no canal de <a href="irc://irc.mozilla.org/mdn">#mdn</a> IRC da <a href="https://wiki.mozilla.org/IRC">Mozilla IRC</a>. Tente o exercício primeiro — não há nada a ganhar com a trapaça!</p> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}</p> + +<p> </p> + +<h2 id="Neste_módulo">Neste módulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li> +</ul> + +<p> </p> diff --git a/files/pt-br/learn/javascript/objects/basics/index.html b/files/pt-br/learn/javascript/objects/basics/index.html new file mode 100644 index 0000000000..ef9cb18c95 --- /dev/null +++ b/files/pt-br/learn/javascript/objects/basics/index.html @@ -0,0 +1,258 @@ +--- +title: O básico sobre objetos JavaScript +slug: Aprender/JavaScript/Objetos/Básico +translation_of: Learn/JavaScript/Objects/Basics +--- +<div>{{LearnSidebar}}</div> + +<div>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">Neste artigo, veremos a sintaxe fundamental de objetos JavaScript e revisitaremos alguns recursos JavaScript vistos anteriormente no curso, reiterando o fato de que muitos dos recursos que você já utilizou são objetos.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos:</th> + <td>Interação básica com o computador, entendimento básico de HTML e CSS, familiaridade com o básico de JavaScript (ver <a href="/en-US/docs/Learn/JavaScript/First_steps">Primeiros passos</a> e <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Elementos construtivos</a>).</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Entender a teoria básica por trás da programação orientada a objetos, como isso se relaciona com o JavaScript ("quase tudo é objeto"), e como começar a trabalhar com objetos JavaScript.</td> + </tr> + </tbody> +</table> + +<h2 id="Objeto_noções_básicas">Objeto, noções básicas</h2> + +<p>Um objeto é uma coleção de dados e/ou funcionalidades relacionadas (que geralmente consistem em diversas variáveis e funções — que são chamadas de propriedades e métodos quando estão dentro de objetos). Vamos trabalhar com um exemplo para entender como eles são.</p> + +<p>Para começar, faça uma cópia do nosso arquivo <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a>. Isto contém muito pouco — um elemento {{HTMLElement("script")}} para escrevermos nosso código-fonte. Vamos usar isto como base para explorar a sintaxe básica do objeto. Ao trabalhar com este exemplo, você deve ter seu <a href="/en-US/docs/Learn/Common_questions/What_are_browser_developer_tools#The_JavaScript_console">console de ferramentas de desenvolvedor JavaScript</a> aberto e pronto para digitar alguns comandos.</p> + +<p>Como acontece com muitas coisas em JavaScript, a criação de um objeto geralmente começa com a definição e a inicialização de uma variável. Tente digitar o código a seguir no arquivo que você baixou, salve e atualize:</p> + +<pre class="brush: js notranslate">var pessoa = {};</pre> + +<p>Se você inserir <code>pessoa</code> no seu console JS e pressionar o botão, deverá obter o seguinte resultado:</p> + +<pre class="brush: js notranslate">[object Object]</pre> + +<p>Parabéns, você acabou de criar seu primeiro objeto. Tarefa concluída! Mas este é um objeto vazio, então não podemos fazer muita coisa com isso. Vamos atualizar nosso objeto para ficar assim:</p> + +<pre class="brush: js notranslate">var pessoa = { + nome: ['Bob', 'Smith'], + idade: 32, + sexo: 'masculino', + interesses: ['música', 'esquiar'], + bio: function() { + alert(this.nome[0] + ' ' + this.nome[1] + ' tem ' + this.idade + ' anos de idade. Ele gosta de ' + this.interesses[0] + ' e ' + this.interesses[1] + '.'); + }, + saudacao: function() { + alert('Oi! Eu sou ' + this.nome[0] + '.'); + } +}; +</pre> + +<p>Depois de salvar e atualizar, tente inserir alguns dos itens a seguir no console JavaScript no devtools do seu navegador:</p> + +<pre class="brush: js notranslate">pessoa.nome +pessoa.nome[0] +pessoa.idade +pessoa.interesses[1] +pessoa.bio() +pessoa.saudacao()</pre> + +<p>Agora você tem alguns dados e funcionalidades dentro de seu objeto e é capaz de acessá-los com uma sintaxe simples e agradável!</p> + +<div class="note"> +<p><strong>Nota</strong>: Se você está tendo problemas para fazer isto funcionar, tente comparar seu código com a nossa versão — veja <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-finished.html">oojs-finished.html</a> (ou <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-finished.html">veja um exemplo funcionando</a>). O exemplo lhe dará uma tela em branco, mas tudo bem — novamente, abra seu devtools e tente digitar os comandos acima para ver a estrutura do objeto.</p> +</div> + +<p>Então, o que está acontecendo? Bem, um objeto é composto de vários membros, cada um com um nome (ex.: <code>nome</code> e <code>idade</code> vistos acima), e um valor (ex.: <code>['Bob', 'Smith']</code> e <code>32</code>). Cada par nome/valor deve ser separado por uma vírgula e o nome e valor, em cada caso, separados por dois pontos. A sintaxe sempre segue esse padrão:</p> + +<pre class="brush: js notranslate">var nomeDoObjeto = { + nomeMembro1: valorMembro1, + nomeMembro2: valorMembro2, + nomeMembro3: valorMembro3 +};</pre> + +<p>O valor de um membro do objeto pode ser praticamente qualquer coisa. Em nosso objeto pessoa, temos uma string, um número, dois arrays e duas functions. Os primeiros quatro são data items (dados) e são referenciados como <strong>propriedades</strong> do objeto. Enquanto os dois últimos ítens são funções que permitem que o objeto faça algo com esses dados. São chamados de <strong>métodos </strong>do objeto.</p> + +<p>Um objeto como esse é chamado de <strong>objeto literal</strong> — ao pé da letra, escrevemos o conteúdo do objeto conforme o criamos. Isto está em contraste com objetos instanciados de classes, que veremos mais adiante.</p> + +<p>É muito comum criar um objeto usando um objeto literal quando você deseja transferir uma série de itens de dados relacionados estruturados de alguma maneira, por exemplo, enviando uma solicitação para o servidor para ser colocado em um banco de dados. Enviar um único objeto é muito mais eficiente do que enviar vários itens individualmente, e é mais fácil trabalhar com um array, quando você deseja identificar itens individuais pelo nome.</p> + +<h2 id="Notação_de_ponto">Notação de ponto</h2> + +<p>Acima, você acessou as propriedades de objetos e métodos usando <strong>notação de ponto</strong>. O objeto nome (pessoa) atua como <strong>namespace </strong>(espaço de nomes) — ele deve ser digitado primeiro para que você acesse qualquer coisa <strong>encapsulada </strong>dentro do objeto. Depois você escreve um ponto, então o item que quer acessar — isso pode ser o nome de uma simples propriedade, um item de um array ou a chamada para um dos métodos do objeto, por exemplo: </p> + +<pre class="brush: js notranslate">pessoa.idade +pessoa.interesse[1] +pessoa.bio()</pre> + +<h3 id="Sub-namespaces">Sub-namespaces</h3> + +<p>É até possível fazer o valor de um membro de um objeto ser outro objeto. Por exemplo, tente alterar o nome do membro de:</p> + +<pre class="brush: js notranslate">nome: ['Bob', 'Smith'],</pre> + +<p>para</p> + +<pre class="brush: js notranslate">nome : { + primeiro: 'Bob', + ultimo: 'Smith' +},</pre> + +<p>Aqui estamos efetivamente criando um <strong>sub-namespace</strong>. Parece difícil, mas não é — para acessar esses itens você apenas precisa encadear mais um passo ao final de outro ponto. Tente isso aqui no console:</p> + +<pre class="brush: js notranslate">pessoa.nome.primeiro +pessoa.nome.ultimo</pre> + +<p><strong>Importante</strong>: Nesse ponto você também precisará revisar seus métodos e mudar quaisquer instâncias de</p> + +<pre class="brush: js notranslate">nome[0] +nome[1]</pre> + +<p>para</p> + +<pre class="brush: js notranslate">nome.primeiro +nome.ultimo</pre> + +<p>Caso contrário seus métodos não funcionarão.</p> + +<h2 id="Notação_de_colchetes">Notação de colchetes</h2> + +<p>Há outra forma de acessar propriedades do objeto — usando notação de colchetes. Ao invés desses:</p> + +<pre class="brush: js notranslate">pessoa.idade +pessoa.nome.primeiro</pre> + +<p>Você pode usar:</p> + +<pre class="brush: js notranslate">pessoa['idade'] +pessoa['nome']['primeiro']</pre> + +<p>Fica muito parecido com a maneira que acessamos itens de um array, e é basicamente a mesma coisa, só que ao invés de usarmos um número de índice para selecionar um item, usamos o nome associado a cada valor. Não é por menos que objetos às vezes são chamados de <strong>arrays associativos</strong> — eles mapeiam strings a valores do mesmo modo que arrays mapeiam números a valores.</p> + +<h2 id="Setando_membros_do_objeto">Setando membros do objeto</h2> + +<p>Até agora nós apenas procuramos receber (ou <strong>apanhar</strong>) membros de objetos — podemos também <strong>setar </strong>(atualizar) o valor de membros de objetos simplesmente declarando o membro que queremos setar (usando notação de ponto ou colchete), tipo assim:</p> + +<pre class="brush: js notranslate">pessoa.idade = 45; +pessoa['nome']['ultimo'] = 'Cratchit';</pre> + +<p>Tente escrever as linhas acima e então apanhar seus membros novamente para ver como mudaram. Assim:</p> + +<pre class="brush: js notranslate">pessoa.idade +pessoa['nome']['ultimo']</pre> + +<p>Não podemos apenas atualizar valores existentes de propriedades e métodos; podemos também criar membros completamente novos. Tente isso aqui no console:</p> + +<pre class="brush: js notranslate">pessoa['olhos'] = 'castanho'. +pessoa.despedida = function() { alert( "Adeus a todos!" ); }</pre> + +<p>Podemos testar nossos novos membros:</p> + +<pre class="brush: js notranslate">pessoa['olhos']; +pessoa.despedida();</pre> + +<p>Um aspecto útil de notação de colchetes é que ela pode ser usadada não apenas para setar valores dinamicamente, mas também nomes de membros. Vamos dizer que queremos que usuários possam armazenar tipos de valores personalizados em seus dados de 'pessoa', digitando o nome e o valor do membro em dois inputs de texto. Podemos obter esses valores dessa forma:</p> + +<pre class="brush: js notranslate">var myDataName = nameInput.value; +var myDataValue = nameValue.value;</pre> + +<p>Podemos, então, adicionar esse novo nome e valor ao objeto <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">pessoa</span></font> assim:</p> + +<pre class="brush: js notranslate">pessoa[myDataName] = myDataValue;</pre> + +<p>Para testar isso, tente adicionar as seguinte linhas em seu código, abaixo do fechamento da chaves do objeto <code>pessoa</code> :</p> + +<pre class="brush: js notranslate">var myDataName = 'altura'; +var myDataValue = '1.75m'; +pessoa[myDataName] = myDataValue;</pre> + +<p>Agora tente salvar e atualizar, entrando o seguinte no seu input de texto:</p> + +<pre class="brush: js notranslate">pessoa.altura</pre> + +<p>Adicionar uma propriedade a um objeto usando o método acima não é possível com a notação ponto, que só aceita um nome de membro literal, não aceita valor de variável apontando para um nome.</p> + +<h2 id="O_que_é_o_this">O que é o "this"?</h2> + +<p>Você pode ter reparado algo levemente estranho em nossos métodos. Olhe esse aqui, por exemplo:</p> + +<pre class="brush: js notranslate">saudacao: function(){ + alert("Oi! Meu nome é " + this.nome.primeiro + "."); +}</pre> + +<p>Você deve estar se perguntando o que é o "this". A palavra-chave <code>this</code> se refere ao objeto atual em que o código está sendo escrito — nesse caso o <code>this</code> se refere a <code>pessoa</code>. Então por que simplesmente não escrever <code>pessoa</code>? Como verá no artigo <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Orientaçã a objeto em JavaScript para iniciantes</a>, quando começamos a criar funções construtoras, etc, o <code>this</code> é muito útil — sempre lhe assegurará que os valores corretos estão sendo usados quando o contexto de um mebro muda (exemplo: duas instâncias diferentes do objeto <code>pessoa</code> podem ter diferentes nomes, mas vão querer usar seu próprio nome ao usar a saudação).</p> + +<p>Vamos ilustrar o que queremos dizer com um par de objetos pessoa:</p> + +<pre class="brush: js notranslate">var pessoa1 = { + nome: 'Chris', + saudacao: function() { + alert('Oi! Meu nome é ' + this.nome + '.'); + } +} + +var pessoa2 = { + nome: 'Brian', + saudacao: function() { + alert('Oi! Meu nome é ' + this.nome + '.'); + } +} </pre> + +<p>Neste caso, <code>pessoa1.saudacao()</code><strong> </strong>gerará "Oi! Meu nome é Chris."; No entanto, <code>pessoa2.saudacao()</code><strong> </strong>retornará "Oi! Meu nome é Brian.", mesmo que os códigos dos métodos sejam idênticos. Como dissemos antes, o <code>this</code> é igual ao código do objeto dentro dele — não é exatamente útil quando estamos escrevendo objetos literais na mão, mas é realmente incrível quando adicionamos objetos gerados dinamicamente (por exemplo usando construtores). Tudo ficará mais claro mais para frente.</p> + +<h2 id="Você_vem_usando_objetos_o_tempo_todo">Você vem usando objetos o tempo todo</h2> + +<p>Enquanto passava por esses exemplos, você provavelmente andou pensando que essa notação de ponto que estamos usando é muito familiar. Isso é porque você vem usando isso durante todo o curso! Todas as vezes que trabalhamos num exemplo que usa uma API interna do navegador ou objetos Javascript, estamos usando objetos, porque esses recursos são construídos usando exatamente o mesmo tipo de estrutura de objetos que vimos aqui, embora mais complexos do que nossos exemplos básicos.</p> + +<p>Então quando usamos métodos de strings como:</p> + +<pre class="brush: js notranslate">minhaString.split(',');</pre> + +<p>Estamos usando um método disponível na instância da class <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code>. Toda vez que você cria uma string em seu código, essa string é automaticamente criada como uma instância de <code>String</code>, e, portanto, possui vários métodos e propriedades comuns que estão disponíveis para ela.</p> + +<p>Quando você acessa o document object model usando linhas como estas:</p> + +<pre class="brush: js notranslate">var minhaDiv = document.createElement('div'); +var meuVideo = document.querySelector('video');</pre> + +<p>Você está usando métodos disponíveis na instância da class <code><a href="/en-US/docs/Web/API/Document">Document</a></code>. Cada vez que a página é recarrecada, uma instância de <code>Document</code> é criada, chamando <code>document</code>, que representa a estrutura inteira da página, conteúdo e outros recursos como sua URL. Novamente, isso significa que ela tem vários métodos e propriedades disponíveis nela.</p> + +<p>O mesmo pode ser dito de basicamente qualquer outro objeto/API embutido que esteja usando — <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math">Math</a></code>, etc.</p> + +<p>Note que Objetos/APIs embutidos nem sempre criam instâncias de objetos automaticamente. Por exemplo, a <a href="/en-US/docs/Web/API/Notifications_API">API de Notificações </a>— que permite que navegadores modernos disparem notificações de sistema — requerem que você inicialize uma nova instância de objeto usando o construtor para cada notificação que queira disparar. Tente entrar o seguinte no seu console Javascript:</p> + +<pre class="brush: js notranslate">var minhaNotificacao = new Notification('Hello!');</pre> + +<p>Novamente, olharemos constructores num artigo mais na frente.</p> + +<div class="note"> +<p><strong>Nota</strong>: É útil pensar sobre como os objetos se comunicam <strong>passando mensagens</strong> - quando um objeto precisa de outro objeto para realizar algum tipo de ação, ele freqüentemente enviará uma mensagem para outro objeto através de um de seus métodos e aguardará uma resposta, que reconhecemos como um valor de retorno.</p> +</div> + +<h2 id="Teste_suas_habilidades_!">Teste suas habilidades !</h2> + +<p>Você chegou ao fim desse artigo,entretanto você consegue lembrar as informações mais importantes? Você pode encontrar mais testes para verificar se você consolidou as informações antes que você siga adiante — veja <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/Test_your_skills:_Object_basics">Test your skills: Object basics</a>.</p> + +<h2 id="Resumo">Resumo</h2> + +<p>Parabéns, você chegou ao final de nosso primeiro artigo sobre objetos JS - agora você deve ter uma boa ideia de como trabalhar com objetos em Javascript - incluindo criar seus próprio objetos simples. Você também deve perceber que objetos são muito úteis como estruturas para armazenar dados e funcionalidades relacionadas - se tentar rastrear todas as propriedades e métodos do nosso objeto <code>pessoa</code> como variáveis e funções separadas, isso seria ineficiente e frustrante e correríamos o risco de termos outras variáveis e funções com o mesmo nome. Objetos nos permite manter informações guardadas em segurança em seus próprios pacotes, fora de perigo.</p> + +<p>No próximo artigo vamos começar a ver a teoria de programação orientada a objetos (OOP) e em como suas técnicas podem ser usadas em Javascript.</p> + +<p>{{NextMenu("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects")}}</p> + +<h2 id="Nesse_módulo">Nesse módulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Noções Básicas de Objetos</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Orientação a objetos Javascript para iniciantes</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Protótipos de Objetos</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Herança no Javascript</a></li> + <li><a href="/pt-BR/docs/Aprender/JavaScript/Objetos/JSON">Trabalhando com JSON</a></li> + <li><a href="/pt-BR/docs/Aprender/JavaScript/Objetos/Object_building_practice">Prática de construção de Objetos</a></li> + <li><a href="/pt-BR/docs/Aprender/JavaScript/Objetos/Adding_bouncing_balls_features">Adicionando recursos à nossa demonstração de bolas pulantes</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/objects/index.html b/files/pt-br/learn/javascript/objects/index.html new file mode 100644 index 0000000000..4c19a1956b --- /dev/null +++ b/files/pt-br/learn/javascript/objects/index.html @@ -0,0 +1,44 @@ +--- +title: Introdução a objetos em Javascript +slug: Aprender/JavaScript/Objetos +tags: + - Iniciante + - JavaScript + - Objetos +translation_of: Learn/JavaScript/Objects +--- +<div>{{LearnSidebar}}</div> + +<p class="summary">Em JavaScript, quase tudo é objeto. Desde as funcionalidades padrão, como strings e arrays, até as APIs para navegadores baseadas na linguagem. Até você pode criar seus próprios objetos. Você pode encapsular funções e variáveis relacionadas de uma forma eficiente. Os objetos agem como uma espécie de manipuladores de dados. Compreender a natureza da orientação a objetos do JavaScript é crucial para aprofundar os conhecimentos acerca da linguagem. Por isso, nós elaboramos esse módulo para auxiliá-lo. Ensinaremos a teoria de objetos em detalhes. Crie seus próprios objetos!</p> + +<p>Antes de iniciar este módulo, você deve possuir alguma familiaridade com HTML e CSS. Se não possui, antes de continuar os estudos dos Objetos em Javascript, indicamos os módulos <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Introduction">Introdução ao HTML</a> e <a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS">Introdução ao CSS</a> .</p> + +<p>Você precisa possuir também alguma familiaridade com os conceitos básicos de Javascript. Para isso indicamos o módulo <a href="/en-US/docs/Learn/JavaScript/First_steps">Primeitos Passos: JavaScript</a> e <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Blocos de Construção do JavaScript</a>.</p> + +<div class="note"> +<p><strong>Nota</strong>: Se você está trabalhando em um computador/tablet/outros equipamentos , ao qual não é possível criar seus próprios arquivos , você pode testar (em grande parte) os nossos códigos de exemplo, em um editor de código online , tal como o JSBin ou o Thimble .</p> +</div> + +<h2 id="Guias">Guias</h2> + +<dl> + <dt><a href="https://developer.mozilla.org/pt-BR/docs/Aprender/JavaScript/Objetos/B%C3%A1sico">Objetos: O básico.</a></dt> + <dd>No primeiro artigo sobre objetos em Javascript, vamos analisar a sintaxe básica de objetos e rever algumas caracterísitcas. Nós já notamos, como mencionado anteriomente, que muitas funcionalidades que você já teve algum contato são, na verdade, Objetos .</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">JavaScript Orientado a Objetos para iniciantes</a></dt> + <dd>Com pelo menos o básico, agora vamos focar na Orientação a Objetos JavaScript (OOJS) — este artigo cobre uma visão básica da teoria da Programação Orientada a Objetos (POO). Depois iremos explorar como o JavaScript emula classes de objetos via funções construtoras e como criar instâncias de objetos.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Prototipação de Objetos</a></dt> + <dd>Prototypes é o mecanismo pelo qual os objetos JavaScript herdam características de outros e como eles funcionam de uma forma diferente dos mecanismos de herança de linguagens de programação clássicas. Neste artigo, vamos explorar essas diferenças, explicar como a cadeia de protótipos trabalha e perceber como a propriedade prototype pode ser usada para adicionar métodos a contrutores existentes.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Herança em JavaScript</a></dt> + <dd>Com a parte central da OOJS já explicada, este artigo mostra como criar classes de objetos "filhos" (construtores) que herdam características das suas classes "pais". Nós daremos ainda algumas dicas sobre quando e onde você pode usar OOJS.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Trabalhando com dados JSON</a></dt> + <dd>JavaScript Object Notation (JSON) é um formato padronizado para representar estruturas de dados em objetos JavaScript, que é comunmente usado para representar e transmitir dados em sites da web (i.e. enviar alguma informação do serviror para o cliente, para ser exibido na página). Neste artigo vamos mostrar o que você precisa para trabalhar com JSON usando JavaScript, inclusive acesso a itens de dados num objeto JSON. Além disso, mostraremos como criar seu próprio JSON.</dd> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Prática de Construção de Objetos</a></dt> + <dd>No artigo anterior, nós vimos toda a parte essencial da teoria de Objetos em JavaScript, além de detalhes de sintaxe, fornecendo assim uma base sólida para você seguir adiante. No presente artigo, vamos nos aprofundar com exercícios práticos na construção de objetos personalizados. Faremos algo divertido e colorido — algumas bolas coloridas saltitantes!</dd> +</dl> + +<h2 id="Aprender_mais...">Aprender mais...</h2> + +<dl> + <dt><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Acrescentando funcionalidades a nossa demo de bolas saltitantes </a></dt> + <dd>Nesse "aprenda mais...", incentivamos você a usar a demo das bolas saltitantes do artigo anterior como ponto de partida para acrescentar algumas novas e interessantes funcionalidades.</dd> +</dl> diff --git a/files/pt-br/learn/javascript/objects/inheritance/index.html b/files/pt-br/learn/javascript/objects/inheritance/index.html new file mode 100644 index 0000000000..81acc88a92 --- /dev/null +++ b/files/pt-br/learn/javascript/objects/inheritance/index.html @@ -0,0 +1,402 @@ +--- +title: Herança em JavaScript +slug: Aprender/JavaScript/Objetos/Herança +translation_of: Learn/JavaScript/Objects/Inheritance +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">Com a maior parte dos detalhes principais do OOJS agora explicados, este artigo mostra como criar classes de objetos "child" (construtores) que herdam recursos de suas classes "parent". Além disso, apresentamos alguns conselhos sobre quando e onde você pode usar o OOJS e veja como as classes são tratadas na sintaxe moderna do ECMAScript.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos:</th> + <td>Conhecimento básico de computação, conhecimento básico de HTML e CSS, familiaridade com com o básico de Javascript (veja <a href="/en-US/docs/Learn/JavaScript/First_steps">Primeiros passos</a> e <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Construindo blocos</a>) e OOJS básico (veja <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introdução a objetos</a>).</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Entender como é possível implementar a herança em Javascript.</td> + </tr> + </tbody> +</table> + +<h2 id="Herança_Prototipada">Herança Prototipada</h2> + +<p>Até agora vimos alguma herança em ação — vimos como funcionam as cadeias de protótipos e como os membros são herdados subindo em uma cadeia. Mas principalmente isso envolveu funções internas do navegador. Como criamos um objeto em JavaScript que herda de outro objeto?</p> + +<p>Vamos explorar como fazer isso com um exemplo concreto.</p> + +<h2 id="Começando">Começando</h2> + +<p>Primeiro de tudo, faça uma cópia local do arquivo <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-start.html">oojs-class-inheritance-start.html</a> (veja também <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-start.html">ao vivo</a>). Aqui dentro você encontrará o mesmo exemplo de construtor <code>Person()</code> que utilizamos durante todo o módulo, com uma pequena diferença — definimos apenas as propriedades dentro do construtor:</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; +};</pre> + +<p>Os métodos são <em>todos </em>definidos no protótipo do construtor. Por exemplo:</p> + +<pre class="brush: js">Person.prototype.greeting = function() { + alert('Hi! I\'m ' + this.name.first + '.'); +};</pre> + +<div class="note"> +<p><strong>Nota</strong>: No código fonte, você também verá os métodos <code>bio()</code> e <code>farewell()</code> definidos. Depois você verá como eles podem ser herdados por outros construtores.</p> +</div> + +<p>Digamos que quiséssemos criar uma classe <code>Teacher</code>, como a que descrevemos em nossa definição inicial orientada a objetos, que herda todos os membros de <code>Person</code>, mas também inclui:</p> + +<ol> + <li>Uma nova propriedade, <code>subject</code> — isso irá conter o assunto que o professor ensina.</li> + <li>Um método <code>greeting()</code> atualizado, que soa um pouco mais formal do que o método padrão <code>greeting()</code> — mais adequado para um professor que se dirige a alguns alunos da escola.</li> +</ol> + +<h2 id="Definindo_uma_função_construtora_Teacher">Definindo uma função construtora Teacher()</h2> + +<p>A primeira coisa que precisamos fazer é criar um construtor <code>Teacher()</code> — adicione o seguinte abaixo do código existente:</p> + +<pre class="brush: js">function Teacher(first, last, age, gender, interests, subject) { + Person.call(this, first, last, age, gender, interests); + + this.subject = subject; +}</pre> + +<p>Isto parece similar ao construtor Person de várias maneiras, mas há algo estranho aqui que nós não vimos antes — a função <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call">call()</a></code>. Esta função basicamente permite chamar uma função definida em outro lugar, mas no contexto atual. O primeiro parâmetro especifica o valor <code>this</code> que você deseja usar ao executar a função, e os outros parâmetros são aqueles que devem ser passados para a função quando ela é invocada.</p> + +<p>Nós queremos que o construtor <code>Teacher()</code> pegue os mesmos parâmetros que o construtor <code>Person()</code> de onde ele está herdando, então especificamos todos eles como parâmetros na chamada <code>call()</code>.</p> + +<p>A última linha dentro do construtor simplesmente define a nova propriedade <code>subject</code> que os professores terão, que pessoas genéricas não possuem.</p> + +<p>Como nota, poderíamos simplesmente ter feito isso:</p> + +<pre class="brush: js">function Teacher(first, last, age, gender, interests, subject) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; + this.subject = subject; +}</pre> + +<p>Mas isso é apenas redefinir as propriedades de novo, não herdá-las de <code>Person()</code>, de modo que ela derrota o ponto que estamos tentando fazer. Também leva mais linhas de código.</p> + +<h3 id="Herdando_de_um_construtor_sem_parâmetros">Herdando de um construtor sem parâmetros</h3> + +<p>Observe que, se o construtor do qual você está herdando não tomar seus valores de propriedade de parâmetros, não será necessário especificá-los como argumentos adicionais em <code>call()</code>. Então, por exemplo, se você tivesse algo realmente simples assim:</p> + +<pre class="brush: js">function Brick() { + this.width = 10; + this.height = 20; +}</pre> + +<p>Você pode herdar as propriedades <code>width</code> e <code>height</code> fazendo isso (assim como as outras etapas descritas abaixo, é claro):</p> + +<pre class="brush: js">function BlueGlassBrick() { + Brick.call(this); + + this.opacity = 0.5; + this.color = 'blue'; +}</pre> + +<p>Observe que apenas especificamos <code>this</code> dentro de <code>call()</code> — nenhum outro parâmetro é necessário, já que não estamos herdando propriedades do pai que são configuradas por meio de parâmetros.</p> + +<h2 id="Definindo_o_protótipo_e_referência_de_construtor_do_Teacher">Definindo o protótipo e referência de construtor do Teacher()</h2> + +<p>Tudo está bem até agora, mas nós temos um problema. Nós definimos um novo construtor, e ele tem uma propriedade <code>prototype</code>, que por padrão apenas contém uma referência à própria função construtora. Ele não contém os métodos da propriedade <code>prototype</code> do construtor Person. Para ver isso, insira <code>Object.getOwnPropertyNames(Teacher.prototype)</code> no campo de entrada de texto ou no seu console JavaScript. Em seguida, insira-o novamente, substituindo <code>Teacher</code> por <code>Person</code>. O novo construtor também não herda esses métodos. Para ver isso, compare as saídas de <code>Person.prototype.greeting</code> e <code>Teacher.prototype.greeting</code>. Precisamos obter <code>Teacher()</code> para herdar os métodos definidos no protótipo <code>Person()</code>. Então, como fazemos isso?</p> + +<ol> + <li>Adicione a seguinte linha abaixo da sua adição anterior: + <pre class="brush: js">Teacher.prototype = Object.create(Person.prototype);</pre> + Aqui nosso amigo <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code> vem para o resgate novamente. Nesse caso, estamos usando para criar um novo objeto e torná-lo o valor de <code>Teacher.prototype</code>. O novo objeto tem <code>Person.prototype</code> como seu protótipo e, portanto, herdará, se e quando necessário, todos os métodos disponíveis no <code>Person.prototype</code>.</li> + <li>Precisamos fazer mais uma coisa antes de prosseguirmos. Depois de adicionar a última linha, a propriedade <code>constructor</code> de <code>Teacher.</code><code>prototype</code> agora é igual a <code>Person()</code>, porque apenas definimos <code>Teacher.prototype</code> para fazer referência a um objeto que herda suas propriedades de <code>Person.prototype</code>! Tente salvar seu código, carregar a página em um navegador e inserir <code>Teacher.prototype.constructor</code> no console para verificar.</li> + <li>Isso pode se tornar um problema, então precisamos definir isso corretamente. Você pode fazer isso voltando ao seu código-fonte e adicionando a seguinte linha na parte inferior: + <pre class="brush: js">Object.defineProperty(Teacher.prototype, 'constructor', { + value: Teacher, + enumerable: false, // so that it does not appear in 'for in' loop + writable: true });</pre> + </li> + <li>Agora, se você salvar e atualizar, entrar em <code>Teacher.prototype.constructor</code> deve retornar <code>Teacher()</code>, conforme desejado, além de estarmos herdando de <code>Person()</code>!</li> +</ol> + +<h2 id="Dar_a_Teacher_uma_nova_função_greeting">Dar a Teacher() uma nova função greeting() </h2> + +<p>Para finalizar nosso código, precisamos definir uma nova função <code>greeting()</code> no construtor <code>Teacher()</code>.</p> + +<p>A maneira mais fácil de fazer isso é defini-lo no protótipo do <code>Teacher()</code> — adicione o seguinte na parte inferior do seu código:</p> + +<pre class="brush: js">Teacher.prototype.greeting = function() { + var prefix; + + if (this.gender === 'male' || this.gender === 'Male' || this.gender === 'm' || this.gender === 'M') { + prefix = 'Mr.'; + } else if (this.gender === 'female' || this.gender === 'Female' || this.gender === 'f' || this.gender === 'F') { + prefix = 'Mrs.'; + } else { + prefix = 'Mx.'; + } + + alert('Hello. My name is ' + prefix + ' ' + this.name.last + ', and I teach ' + this.subject + '.'); +};</pre> + +<p>Isso alerta a saudação do professor, que também usa um prefixo de nome apropriado para seu gênero, elaborado usando uma instrução condicional.</p> + +<h2 id="Testando_o_exemplo">Testando o exemplo</h2> + +<p>Agora que você digitou todo o código, tente criar uma instância de objeto do <code>Teacher()</code> colocando o seguinte na parte inferior do seu JavaScript (ou algo semelhante à sua escolha):</p> + +<pre class="brush: js">var teacher1 = new Teacher('Dave', 'Griffiths', 31, 'male', ['football', 'cookery'], 'mathematics');</pre> + +<p>Agora salve e atualize e tente acessar as propriedades e os métodos do novo objeto <code>teacher1</code>, por exemplo:</p> + +<pre class="brush: js">teacher1.name.first; +teacher1.interests[0]; +teacher1.bio(); +teacher1.subject; +teacher1.greeting(); +teacher1.farewell();</pre> + +<p>Tudo isso deve funcionar bem. As consultas nas linhas 1, 2, 3 e 6 acessam membros herdados do construtor genérico <code>Person()</code> (class). A consulta na linha 4 acessa um membro que está disponível somente no construtor mais especializado <code>Teacher()</code> (class). A consulta na linha 5 teria acessado um membro herdado de <code>Person()</code>, exceto pelo fato de que <code>Teacher()</code> tem seu próprio membro com o mesmo nome, portanto, a consulta acessa esse membro.</p> + +<div class="note"> +<p><strong>Note</strong>: If you have trouble getting this to work, compare your code to our <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-finished.html">finished version</a> (see it <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-finished.html">running live</a> also).</p> +</div> + +<p>A técnica que abordamos aqui não é a única maneira de criar classes herdadas em JavaScript, mas funciona bem e dá uma boa idéia sobre como implementar a herança em JavaScript.</p> + +<p>Você também pode estar interessado em conferir alguns dos novos recursos {{glossary("ECMAScript")}} que nos permitem fazer herança mais claramente em JavaScript (veja <a href="/en-US/docs/Web/JavaScript/Reference/Classes">Classes</a>). Nós não cobrimos esses aqui, pois eles ainda não são suportados amplamente pelos navegadores. Todas as outras construções de código que discutimos neste conjunto de artigos são suportadas desde o IE9 ou anterior, e existem maneiras de obter suporte anterior a isso.</p> + +<p>Uma maneira comum é usar uma biblioteca JavaScript — a maioria das opções populares tem um conjunto fácil de funcionalidade disponível para fazer herança com mais facilidade e rapidez. <a href="http://coffeescript.org/#classes">CoffeeScript</a> por exemplo, fornece <code>class</code>, <code>extends</code>, etc.</p> + +<h2 id="Um_exercício_adicional">Um exercício adicional</h2> + +<p>Em nossa <a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS#Object-oriented_programming_from_10000_meters">seção de teoria OOP</a>, incluímos também uma classe <code>Student</code> como um conceito, que herda todos os recursos de <code>Person</code>, e também tem um método <code>greeting()</code> diferente de <code>Person</code> que é muito mais informal do que a saudação do <code>Teacher</code>. Dê uma olhada na aparência da saudação do aluno nessa seção e tente implementar seu próprio construtor <code>Student()</code> que herda todos os recursos de <code>Person()</code>, e implemente a função <code>greeting()</code> diferente.</p> + +<div class="note"> +<p><strong>Note</strong>: If you have trouble getting this to work, have a look at our <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-inheritance-student.html">finished version</a> (see it <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-inheritance-student.html">running live</a> also).</p> +</div> + +<h2 id="Sumário_de_membro_do_objeto">Sumário de membro do objeto</h2> + +<p>Resumindo, você basicamente tem três tipos de propriedade / método para se preocupar:</p> + +<ol> + <li>Aqueles definidos dentro de uma função construtora que são dadas a instâncias de objetos. Estes são bastante fáceis de detectar — em seu próprio código personalizado, eles são os membros definidos dentro de um construtor usando as linhas <code>this.x = x</code> ; no código do navegador, eles são os membros disponíveis apenas para instâncias de objetos (geralmente criados chamando um construtor usando a palavra-chave <code>new</code>, por exemplo, <code>var myInstance = new myConstructor()</code>).</li> + <li>Aqueles definidos diretamente no próprio construtor, que estão disponíveis apenas no construtor. Geralmente, eles estão disponíveis apenas em objetos de navegador internos e são reconhecidos por serem encadeados diretamente em um construtor, não em uma instância. Por exemplo, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>.</li> + <li>Aqueles definidos no protótipo de um construtor, que são herdados por todas as instâncias e herdam as classes de objetos. Estes incluem qualquer membro definido na propriedade de protótipo de um Construtor, por ex. <code>myConstructor.prototype.x()</code>.</li> +</ol> + +<p>Se você não tem certeza de qual é qual, não se preocupe com isso ainda — você ainda está aprendendo e a familiaridade virá com a prática.</p> + +<h2 id="Classes_ECMAScript_2015">Classes ECMAScript 2015</h2> + +<p>O ECMAScript 2015 introduz a <a href="/en-US/docs/Web/JavaScript/Reference/Classes">sintaxe de classe</a> em JavaScript como uma maneira de escrever classes reutilizáveis usando uma sintaxe mais fácil e mais limpa, que é mais semelhante a classes em C ++ ou Java. Nesta seção, converteremos os exemplos Pessoa e Professor da herança protótipo para as classes, para mostrar como é feito.</p> + +<div class="note"> +<p><strong>Nota</strong>: Essa forma moderna de escrever classes é suportada em todos os navegadores modernos, mas ainda vale a pena saber como a herança prototípica subjacente, caso você trabalhe em um projeto que exija suporte a um navegador que não suporte essa sintaxe (mais notavelmente o Internet Explorer) .</p> +</div> + +<p>Vejamos uma versão reescrita do exemplo Person, estilo de classe:</p> + +<pre class="brush: js">class Person { + constructor(first, last, age, gender, interests) { + this.name = { + first, + last + }; + this.age = age; + this.gender = gender; + this.interests = interests; + } + + greeting() { + console.log(`Hi! I'm ${this.name.first}`); + }; + + farewell() { + console.log(`${this.name.first} has left the building. Bye for now!`); + }; +} +</pre> + +<p>A declaração <a href="/en-US/docs/Web/JavaScript/Reference/Statements/class">class</a> indica que estamos criando uma nova classe. Dentro deste bloco, definimos todos os recursos da classe:</p> + +<ul> + <li>O método <code><a href="/en-US/docs/Web/JavaScript/Reference/Classes/constructor">constructor()</a></code> define a função construtora que representa nossa classe <code>Person</code>.</li> + <li><code>greeting()</code> e <code>farewell()</code> são métodos de classe. Quaisquer métodos que você deseja associar à classe são definidos dentro dela, após o construtor. Neste exemplo, usamos <a href="/en-US/docs/Web/JavaScript/Reference/Template_literals">template literals</a> em vez de concatenação de string para facilitar a leitura do código.</li> +</ul> + +<p>Agora podemos instanciar instâncias de objeto usando o operador <a href="/en-US/docs/Web/JavaScript/Reference/Operators/new"><code>new</code></a>, da mesma maneira que fizemos antes:</p> + +<pre class="brush: js">let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']); +han.greeting(); +// Hi! I'm Han + +let leia = new Person('Leia', 'Organa', 19, 'female', ['Government']); +leia.farewell(); +// Leia has left the building. Bye for now +</pre> + +<div class="note"> +<p><strong>Nota</strong>: Sob o capô, suas classes estão sendo convertidas em modelos de herança protótipos — isso é apenas açúcar sintático. Mas tenho certeza que você concordará que é mais fácil escrever.</p> +</div> + +<h3 id="Herança_com_sintaxe_de_classe">Herança com sintaxe de classe</h3> + +<p>Acima nós criamos uma classe para representar uma pessoa. Eles têm uma série de atributos que são comuns a todas as pessoas; Nesta seção, criaremos nossa classe especializada <code>Teacher</code>, tornando-a herdada de <code>Person</code> usando a sintaxe de classe moderna. Isso é chamado de criação de uma subclasse ou subclasse.</p> + +<p>Para criar uma subclasse, usamos a palavra-chave <a href="/en-US/docs/Web/JavaScript/Reference/Classes/extends">extends</a> para informar ao JavaScript a classe na qual queremos basear nossa classe.</p> + +<pre class="brush: js">class Teacher extends Person { + constructor(first, last, age, gender, interests, subject, grade) { + this.name = { + first, + last + }; + + this.age = age; + this.gender = gender; + this.interests = interests; + // subject and grade are specific to Teacher + this.subject = subject; + this.grade = grade; + } +}</pre> + +<p>Podemos tornar o código mais legível definindo o operador <a href="/en-US/docs/Web/JavaScript/Reference/Operators/super"><code>super()</code> </a>como o primeiro item dentro do <code>constructor()</code>. Isso chamará o construtor da classe pai e herdará os membros que especificarmos como parâmetros de <code>super()</code>, desde que sejam definidos lá:</p> + +<pre class="brush: js">class Teacher extends Person { + constructor(first, last, age, gender, interests, subject, grade) { + super(first, last, age, gender, interests); + + // subject and grade are specific to Teacher + this.subject = subject; + this.grade = grade; + } +} +</pre> + +<p>Quando instanciamos instâncias de objeto <code>Teacher</code> , podemos agora chamar métodos e propriedades definidos em <code>Teacher</code> e <code>Person</code>, como seria de esperar:</p> + +<pre class="brush: js">let snape = new Teacher('Severus', 'Snape', 58, 'male', ['Potions'], 'Dark arts', 5); +snape.greeting(); // Hi! I'm Severus. +snape.farewell(); // Severus has left the building. Bye for now. +snape.age // 58 +snape.subject; // Dark arts +</pre> + +<p>Como fizemos com Teachers, poderíamos criar outras subclasses de <code>Person</code> para torná-las mais especializadas sem modificar a classe base.</p> + +<div class="note"> +<p><strong>Note</strong>: You can find this example on GitHub as <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/es2015-class-inheritance.html">es2015-class-inheritance.html</a> (<a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/es2015-class-inheritance.html">see it live also</a>).</p> +</div> + +<h2 id="Getters_e_Setters">Getters e Setters</h2> + +<p>Pode haver momentos em que queremos alterar os valores de um atributo nas classes que criamos ou não sabemos qual será o valor final de um atributo. Usando o exemplo <code>Teacher</code>, podemos não saber o assunto que o professor ensinará antes de criá-lo, ou o assunto pode mudar entre os termos.</p> + +<p>Podemos lidar com essas situações com getters e setters.</p> + +<p>Vamos melhorar a classe Professor com getters e setters. A aula começa da mesma forma que foi a última vez que olhamos para ela.</p> + +<p>Os getters e setters trabalham em pares. Um getter retorna o valor atual da variável e seu setter correspondente altera o valor da variável para o que ela define.</p> + +<p>A classe <code>Teacher</code> modificada é assim:</p> + +<pre class="brush: js">class Teacher extends Person { + constructor(first, last, age, gender, interests, subject, grade) { + super(first, last, age, gender, interests); + // subject and grade are specific to Teacher + this._subject = subject; + this.grade = grade; + } + + get subject() { + return this._subject; + } + + set subject(newSubject) { + this._subject = newSubject; + } +} +</pre> + +<p>Em nossa classe acima, temos um getter e setter para a propriedade <code>subject</code>. Usamos <strong><code>_</code> </strong> para criar um valor separado no qual armazenar nossa propriedade de nome. Sem usar essa convenção, obteríamos erros toda vez que chamássemos get ou set. Neste ponto:</p> + +<ul> + <li>Para mostrar o valor atual da propriedade <code>_subject</code> do objeto <code>snape</code> , podemos usar o método getter <code>snape.subject</code>.</li> + <li>Para atribuir um novo valor à propriedade <code>_subject</code> , podemos usar o método setter <code>snape.subject="new value"</code>.</li> +</ul> + +<p>O exemplo abaixo mostra os dois recursos em ação:</p> + +<pre class="brush: js">// Check the default value +console.log(snape.subject) // Returns "Dark arts" + +// Change the value +snape.subject="Balloon animals" // Sets _subject to "Balloon animals" + +// Check it again and see if it matches the new value +console.log(snape.subject) // Returns "Balloon animals" +</pre> + +<div class="note"> +<p><strong>Note</strong>: You can find this example on GitHub as <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/es2015-getters-setters.html">es2015-getters-setters.html</a> (<a href="https://mdn.github.io/learning-area/javascript/oojs/advanced/es2015-getters-setters.html">see it live also</a>).</p> +</div> + +<h2 id="Quando_você_usaria_a_herança_em_JavaScript">Quando você usaria a herança em JavaScript?</h2> + +<p>Particularmente após este último artigo, você pode estar pensando "woo, isso é complicado". Bem, você está certo. Protótipos e herança representam alguns dos aspectos mais complexos do JavaScript, mas muito do poder e flexibilidade do JavaScript vem de sua estrutura e herança de objetos, e vale a pena entender como ele funciona.</p> + +<p>De certa forma, você usa herança o tempo todo. Sempre que você usa vários recursos de uma API da Web ou métodos / propriedades definidos em um objeto de navegador interno que você chama em suas cadeias de caracteres, matrizes, etc., você está implicitamente usando herança.</p> + +<p>Em termos de usar a herança em seu próprio código, você provavelmente não a usará com frequência, principalmente no começo e em pequenos projetos. É uma perda de tempo usar objetos e herança apenas por causa dela quando você não precisa deles. Mas à medida que suas bases de código aumentam, é mais provável que você encontre uma necessidade para isso. Se você estiver começando a criar vários objetos com recursos semelhantes, criar um tipo de objeto genérico para conter toda a funcionalidade compartilhada e herdar esses recursos em tipos de objetos mais especializados pode ser conveniente e útil.</p> + +<div class="note"> +<p><strong>Nota</strong>: Por causa da maneira como o JavaScript funciona, com a cadeia de protótipos, etc., o compartilhamento de funcionalidade entre objetos é frequentemente chamado de <strong>delegação</strong>. Os objetos especializados delegam a funcionalidade a um tipo de objeto genérico.</p> +</div> + +<p>Ao usar a herança, você é aconselhado a não ter muitos níveis de herança, e manter um controle cuidadoso de onde você define seus métodos e propriedades. É possível começar a escrever código que modifica temporariamente os protótipos dos objetos do navegador interno, mas você não deve fazer isso a menos que tenha um bom motivo. Demasiada herança pode levar a confusão sem fim, e dor infinita quando você tenta depurar esse código.</p> + +<p>Em última análise, os objetos são apenas outra forma de reutilização de código, como funções ou loops, com seus próprios papéis e vantagens específicos. Se você estiver criando um monte de variáveis e funções relacionadas e quiser rastreá-las todas juntas e empacotá-las perfeitamente, um objeto é uma boa ideia. Objetos também são muito úteis quando você quer passar uma coleção de dados de um lugar para outro. Ambas as coisas podem ser alcançadas sem o uso de construtores ou herança. Se você precisa apenas de uma única instância de um objeto, provavelmente é melhor usar apenas um literal de objeto e certamente não precisa de herança.</p> + +<h2 id="Alternativas_para_estender_a_cadeia_de_protótipos">Alternativas para estender a cadeia de protótipos</h2> + +<p>Em JavaScript, existem várias maneiras diferentes de estender o protótipo de um objeto além do que mostramos acima. Para saber mais sobre as outras formas, visite nosso artigo <a href="/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Different_ways_to_create_objects_and_the_resulting_prototype_chain">Herança e a cadeia de protótipos</a>.</p> + +<h2 id="Sumário">Sumário</h2> + +<p>Este artigo cobriu o restante da teoria e sintaxe central do OOJS que achamos que você deveria saber agora. Neste ponto, você deve entender os princípios de objeto e OOP JavaScript, protótipos e herança prototypal, como criar classes (construtores) e instâncias de objetos, adicionar recursos a classes e criar subclasses que herdam de outras classes.</p> + +<p>No próximo artigo, veremos como trabalhar com JavaScript Object Notation (JSON), um formato comum de troca de dados escrito usando objetos JavaScript.</p> + +<h2 id="Veja_também">Veja também</h2> + +<ul> + <li><a href="http://www.objectplayground.com/">ObjectPlayground.com</a> — Um site de aprendizado interativo realmente útil para aprender sobre objetos.</li> + <li><a href="https://www.manning.com/books/secrets-of-the-javascript-ninja-second-edition">Segredos Ninja de JavaScript</a>, Capítulo 7 - Um bom livro sobre conceitos e técnicas avançadas de JavaScript, por John Resig, Bear Bibeault e Josip Maras. O Capítulo 7 aborda aspectos de protótipos e herança muito bem; Você provavelmente pode rastrear uma cópia impressa ou on-line com bastante facilidade.</li> + <li><a href="https://github.com/getify/You-Dont-Know-JS/blob/master/this%20&%20object%20prototypes/README.md#you-dont-know-js-this--object-prototypes">Você não sabe JS: this & Object Prototypes</a> — Parte da excelente série de manuais de JavaScript de Kyle Simpson, o Capítulo 5, em particular, analisa os protótipos com muito mais detalhes do que fazemos aqui. Nós apresentamos uma visão simplificada nesta série de artigos destinados a iniciantes, enquanto Kyle entra em grande profundidade e fornece uma imagem mais complexa, mas mais precisa.</li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/objects/json/index.html b/files/pt-br/learn/javascript/objects/json/index.html new file mode 100644 index 0000000000..e10e3e27a6 --- /dev/null +++ b/files/pt-br/learn/javascript/objects/json/index.html @@ -0,0 +1,350 @@ +--- +title: Trabalhando com JSON +slug: Aprender/JavaScript/Objetos/JSON +tags: + - JSON + - JavaScript + - assíncrono +translation_of: Learn/JavaScript/Objects/JSON +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">JavaScript Object Notation (JSON) é um formato baseado em texto padrão para representar dados estruturados com base na sintaxe do objeto JavaScript. É comumente usado para transmitir dados em aplicativos da Web (por exemplo, enviar alguns dados do servidor para o cliente, para que possam ser exibidos em uma página da Web ou vice-versa). Você se deparará com isso com bastante frequência, portanto, neste artigo, oferecemos tudo o que você precisa para trabalhar com o JSON usando JavaScript, incluindo a análise do JSON para que você possa acessar os dados dentro dele e criar o JSON.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos</th> + <td> + <p>Conhecimento básico em informática, conhecimento básico de HTML e CSS, conhecimento básico de JavaScript veja <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/First_steps">Primeiros passos</a> e <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks">Construindo blocos</a>) e o básico de OOJS (veja <a href="https://wiki.developer.mozilla.org/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introdução a objetos</a>).</p> + </td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td> + <p>Para entender como trabalhar com dados armazenados em JSON e criar seus próprios objetos JSON.</p> + </td> + </tr> + </tbody> +</table> + +<h2 id="Não_sério_o_que_é_o_JSON">Não, sério, o que é o JSON?</h2> + +<p>{{glossary("JSON")}} é um formato de dados baseado em texto seguindo a sintaxe do objeto JavaScript, que foi popularizada por <a href="https://en.wikipedia.org/wiki/Douglas_Crockford">Douglas Crockford</a>. Mesmo que se assemelhe à sintaxe literal do objeto JavaScript, ele pode ser usado independentemente do JavaScript, e muitos ambientes de programação possuem a capacidade de ler (analisar) e gerar JSON</p> + +<p>O JSON existe como uma string — útil quando você deseja transmitir dados por uma rede. Ele precisa ser convertido em um objeto JavaScript nativo quando você quiser acessar os dados. Isso não é um grande problema — o JavaScript fornece um objeto <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON</a> global que possui métodos disponíveis para conversão entre os dois.</p> + +<div class="note"> +<p><strong>Nota</strong>: Converter uma string em um objeto nativo é chamado de análise, enquanto a conversão de um objeto nativo em uma string para que possa ser transmitida pela rede é chamada de <em>stringification</em>.</p> +</div> + +<p>Um objeto JSON pode ser armazenado em seu próprio arquivo, que é basicamente apenas um arquivo de texto com uma extensão de <code>.json</code>, e um {{glossary("MIME type")}} de <code>application/json</code>.</p> + +<h3 id="Estrutura_JSON">Estrutura JSON</h3> + +<p>Conforme descrito acima, um JSON é uma string cujo formato se parece muito com o formato literal do objeto JavaScript. Você pode incluir os mesmos tipos de dados básicos dentro do JSON, como em um objeto JavaScript padrão — strings, números, matrizes, booleanos e outros literais de objeto. Isso permite que você construa uma hierarquia de dados, assim:</p> + +<pre class="brush: json">{ + "squadName": "Super hero squad", + "homeTown": "Metro City", + "formed": 2016, + "secretBase": "Super tower", + "active": true, + "members": [ + { + "name": "Molecule Man", + "age": 29, + "secretIdentity": "Dan Jukes", + "powers": [ + "Radiation resistance", + "Turning tiny", + "Radiation blast" + ] + }, + { + "name": "Madame Uppercut", + "age": 39, + "secretIdentity": "Jane Wilson", + "powers": [ + "Million tonne punch", + "Damage resistance", + "Superhuman reflexes" + ] + }, + { + "name": "Eternal Flame", + "age": 1000000, + "secretIdentity": "Unknown", + "powers": [ + "Immortality", + "Heat Immunity", + "Inferno", + "Teleportation", + "Interdimensional travel" + ] + } + ] +}</pre> + +<p>Se nós carregássemos esse objeto em um programa JavaScript, analisado em uma variável chamada <code>superHeroes</code> por exemplo, poderíamos então acessar os dados dentro dele usando a mesma notação dot / bracket que observamos no artigo básico do objeto <a href="/en-US/docs/Learn/JavaScript/Objects/Basics">JavaScript</a>. Por exemplo:</p> + +<pre class="brush: js">superHeroes.homeTown +superHeroes['active']</pre> + +<p>Para acessar os dados mais abaixo na hierarquia, basta encadear os nomes de propriedades e os índices de array necessários juntos. Por exemplo, para acessar o terceiro superpoder do segundo herói listado na lista de membros, você faria isso:</p> + +<pre class="brush: js">superHeroes['members'][1]['powers'][2]</pre> + +<ol> + <li>Primeiro temos o nome da variável — <code>superHeroes</code>.</li> + <li>Por dentro, queremos acessar a propriedade dos <code>members</code>, então usamos <code>["members"]</code>.</li> + <li><code>members</code> contém uma matriz preenchida por objetos. Queremos acessar o segundo objeto dentro da matriz, então usamos <code>[1]</code>.</li> + <li>Dentro deste objeto, queremos acessar a propriedade <code>powers</code>, então usamos <code>["powers"]</code>.</li> + <li>Dentro da propriedade <code>powers</code> está um array contendo os superpoderes do herói selecionado. Nós queremos o terceiro, então nós usamos<br> + <code>[2]</code>.</li> +</ol> + +<div class="note"> +<p>Nota: Nós fizemos o JSON visto acima disponível dentro de uma variável em nosso exemplo JSONTest.html (veja o código fonte). Tente carregar isso e depois acessar os dados dentro da variável pelo console JavaScript do seu navegador.</p> +</div> + +<h3 id="Matrizes_como_JSON">Matrizes como JSON</h3> + +<p>Acima, mencionamos que o texto JSON basicamente se parece com um objeto JavaScript, e isso é basicamente correto. A razão pela qual dissemos "principalmente certo" é que uma matriz também é válida como JSON, por exemplo:</p> + +<pre class="brush: json">[ + { + "name": "Molecule Man", + "age": 29, + "secretIdentity": "Dan Jukes", + "powers": [ + "Radiation resistance", + "Turning tiny", + "Radiation blast" + ] + }, + { + "name": "Madame Uppercut", + "age": 39, + "secretIdentity": "Jane Wilson", + "powers": [ + "Million tonne punch", + "Damage resistance", + "Superhuman reflexes" + ] + } +]</pre> + +<p>O código acima é um JSON perfeitamente válido. Você teria que acessar itens de matriz (em sua versão analisada) iniciando com um índice de matriz, por exemplo <code>[0]["powers"][0]</code>.</p> + +<h3 id="Outras_notas">Outras notas</h3> + +<ul> + <li>O JSON é puramente um formato de dados — contém apenas propriedades, sem métodos.</li> + <li>JSON requer aspas duplas para serem usadas em torno de strings e nomes de propriedades. Aspas simples não são válidas.</li> + <li>Mesmo uma única vírgula ou cólon perdidos podem fazer com que um arquivo JSON dê errado e não funcione. Você deve ter o cuidado de validar quaisquer dados que você esteja tentando usar (embora o JSON gerado por computador seja menos provável de incluir erros, desde que o programa gerador esteja funcionando corretamente). Você pode validar o JSON usando um aplicativo como o <a href="http://jsonlint.com/">JSONLint</a>.</li> + <li>O JSON pode realmente assumir a forma de qualquer tipo de dados que seja válido para inclusão dentro do JSON, não apenas matrizes ou objetos. Por exemplo, uma única string ou número seria um objeto JSON válido.</li> + <li>Ao contrário do código JavaScript no qual as propriedades do objeto podem estar sem aspas, em JSON, somente strings entre aspas podem ser usadas como propriedades.</li> +</ul> + +<h2 id="Aprendizado_ativo_trabalhando_por_meio_de_um_exemplo_de_JSON">Aprendizado ativo: trabalhando por meio de um exemplo de JSON</h2> + +<p>Então, vamos trabalhar em um exemplo para mostrar como poderíamos usar alguns dados JSON em um site.</p> + +<h3 id="Começando">Começando</h3> + +<p>Para começar, faça cópias locais de nossos arquivos <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes.html">heroes.html</a> e <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/style.css">style.css</a>. O último contém alguns CSS simples para estilizar nossa página, enquanto o primeiro contém um HTML muito simples:</p> + +<pre class="brush: html"><header> +</header> + +<section> +</section></pre> + +<p>Mais um elemento {{HTMLElement("script")}} para conter o código JavaScript que escreveremos neste exercício. No momento, ele contém apenas duas linhas, que pegam referências aos elementos {{HTMLElement("header")}} e {{HTMLElement("section")}} e os armazenam em variáveis:</p> + +<pre class="brush: js">var header = document.querySelector('header'); +var section = document.querySelector('section');</pre> + +<p>Disponibilizamos nossos dados JSON em nosso GitHub, em<a href="https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json">https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json</a>.</p> + +<p>Vamos carregá-lo em nossa página e usar algumas manipulações de DOM nifty para exibi-lo, assim:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13857/json-superheroes.png" style="display: block; margin: 0 auto;"></p> + +<h3 id="Obtendo_o_JSON">Obtendo o JSON</h3> + +<p>Para obter o JSON, vamos usar uma API chamada {{domxref("XMLHttpRequest")}} (geralmente chamada de XHR). Esse é um objeto JavaScript muito útil que nos permite fazer solicitações de rede para recuperar recursos de um servidor via JavaScript (por exemplo, imagens, texto, JSON e até trechos de código HTML), o que significa que podemos atualizar pequenas seções de conteúdo sem ter que recarregar todo página. Isso levou a páginas da Web mais responsivas e parece empolgante, mas está além do escopo deste artigo ensinar isso com muito mais detalhes.</p> + +<ol> + <li>Para começar, vamos armazenar a URL do JSON que queremos recuperar em uma variável. Adicione o seguinte na parte inferior do seu código JavaScript: + <pre class="brush: js">var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';</pre> + </li> + <li>Para criar uma solicitação, precisamos criar uma nova instância de objeto de solicitação a partir do construtor <code>XMLHttpRequest</code> usando a palavra-chave <code>new</code>. Adicione o seguinte abaixo sua última linha: + <pre class="brush: js">var request = new XMLHttpRequest();</pre> + </li> + <li>Agora precisamos abrir uma nova solicitação usando o método <code><a href="/en-US/docs/Web/API/XMLHttpRequest/open">open()</a></code> . Adicione a seguinte linha: + <pre class="brush: js">request.open('GET', requestURL);</pre> + + <p>Isso leva pelo menos dois parâmetros — existem outros parâmetros opcionais disponíveis. Nós só precisamos dos dois obrigatórios para este exemplo simples:</p> + + <ul> + <li>O método HTTP a ser usado ao fazer a solicitação de rede. Neste caso, <code><a href="/en-US/docs/Web/HTTP/Methods/GET">GET</a></code> é bom, pois estamos apenas recuperando alguns dados simples.</li> + <li>O URL para fazer a solicitação — esta é a URL do arquivo JSON que armazenamos anteriormente.</li> + </ul> + </li> + <li>Em seguida, adicione as duas linhas a seguir — aqui estamos definindo o <code><a href="/en-US/docs/Web/API/XMLHttpRequest/responseType">responseType</a></code> como JSON, para que o XHR saiba que o servidor retornará o JSON e que isso deve ser convertido nos bastidores em um objeto JavaScript. Em seguida, enviamos a solicitação com o método <code><a href="/en-US/docs/Web/API/XMLHttpRequest/send">send()</a></code>: + <pre class="brush: js">request.responseType = 'json'; +request.send();</pre> + </li> + <li>A última parte desta seção envolve aguardar a resposta retornar do servidor e, em seguida, lidar com ela. Adicione o seguinte código abaixo do seu código anterior: + <pre class="brush: js">request.onload = function() { + var superHeroes = request.response; + populateHeader(superHeroes); + showHeroes(superHeroes); +}</pre> + </li> +</ol> + +<p>Aqui estamos armazenando a resposta ao nosso pedido (disponível na propriedade <code><a href="/en-US/docs/Web/API/XMLHttpRequest/response">response</a></code>) em uma variável chamada <code>superHeroes</code>; essa variável agora conterá o objeto JavaScript com base no JSON! Então, estamos passando esse objeto para duas chamadas de função — a primeira preencherá o <<code>header></code> com os dados corretos, enquanto a segunda criará uma ficha de informações para cada herói da equipe e a inserirá na <code><section></code>.</p> + +<p>Envolvemos o código em um manipulador de eventos que é executado quando o evento de carregamento é acionado no objeto de solicitação (consulte <code><a href="/en-US/docs/Web/API/XMLHttpRequestEventTarget/onload">onload</a></code>) — isso ocorre porque o evento load é acionado quando a resposta é retornada com sucesso; Fazê-lo desta forma garante que <code>request.response</code> estará definitivamente disponível quando chegarmos a tentar fazer algo com ele.</p> + +<h3 id="Preenchendo_o_Cabeçalho">Preenchendo o Cabeçalho</h3> + +<p>Agora, recuperamos os dados JSON e os convertemos em um objeto JavaScript, vamos usá-lo escrevendo as duas funções mencionadas acima. Primeiro de tudo, adicione a seguinte definição de função abaixo do código anterior:</p> + +<pre class="brush: js">function populateHeader(jsonObj) { + var myH1 = document.createElement('h1'); + myH1.textContent = jsonObj['squadName']; + header.appendChild(myH1); + + var myPara = document.createElement('p'); + myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed']; + header.appendChild(myPara); +}</pre> + +<p>Nós chamamos o parâmetro <code>jsonObj</code>, para nos lembrarmos que esse objeto JavaScript foi originado do JSON. Aqui, primeiro criamos um elemento {{HTMLElement("h1")}} como <code><a href="/en-US/docs/Web/API/Document/createElement">createElement()</a></code>, definimos seu <code><a href="/en-US/docs/Web/API/Node/textContent">textContent</a></code> para igualar a propriedade <code>squadName</code> do objeto e, em seguida, o adicionamos ao cabeçalho usando <code><a href="/en-US/docs/Web/API/Node/appendChild">appendChild()</a></code>. Em seguida, fazemos uma operação muito semelhante com um parágrafo: criá-lo, definir seu conteúdo de texto e anexá-lo ao cabeçalho. A única diferença é que seu texto é definido como uma string concatenada contendo as propriedades <code>homeTown</code> e <code>formed</code> do objeto.</p> + +<h3 id="Criando_os_cartões_de_informações_do_herói">Criando os cartões de informações do herói</h3> + +<p>Em seguida, adicione a seguinte função na parte inferior do código, que cria e exibe as cartas de super-heróis:</p> + +<pre class="brush: js">function showHeroes(jsonObj) { + var heroes = jsonObj['members']; + + for (var i = 0; i < heroes.length; i++) { + var myArticle = document.createElement('article'); + var myH2 = document.createElement('h2'); + var myPara1 = document.createElement('p'); + var myPara2 = document.createElement('p'); + var myPara3 = document.createElement('p'); + var myList = document.createElement('ul'); + + myH2.textContent = heroes[i].name; + myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity; + myPara2.textContent = 'Age: ' + heroes[i].age; + myPara3.textContent = 'Superpowers:'; + + var superPowers = heroes[i].powers; + for (var j = 0; j < superPowers.length; j++) { + var listItem = document.createElement('li'); + listItem.textContent = superPowers[j]; + myList.appendChild(listItem); + } + + myArticle.appendChild(myH2); + myArticle.appendChild(myPara1); + myArticle.appendChild(myPara2); + myArticle.appendChild(myPara3); + myArticle.appendChild(myList); + + section.appendChild(myArticle); + } +}</pre> + +<p>Para começar, armazenamos a propriedade <code>members</code> do objeto JavaScript em uma nova variável. Esta matriz contém vários objetos que contêm as informações para cada herói.</p> + +<p>Em seguida, usamos um<a href="/en-US/docs/Learn/JavaScript/Building_blocks/Looping_code#The_standard_for_loop"> loop for</a> para percorrer cada objeto na matriz. Para cada um, nós:</p> + +<ol> + <li>Criamos vários novos elementos: um <code><ar</code><code>ticle></code>, um <code><h2></code>, três <code><p></code>s, e um <code><ul></code>.</li> + <li>Definimos o <h2> para conter o <code>name</code> do herói atual.</li> + <li>Preenchemos os três parágrafos com sua <code>secretIdentity</code>, <code>age</code>, e uma linha dizendo "Superpoderes:" para introduzir as informações na lista.</li> + <li>Armazenamos a propriedade <code>powers</code> em outra nova variável chamada <code>superPowers</code> — isso contém uma matriz que lista os superpoderes do herói atual.</li> + <li>Usamos outro loop <code>for</code> para percorrer os superpoderes do herói atual — para cada um criamos um elemento <code><li></code> colocamos o super poder dentro dele e colocamos o <code>listItem</code> dentro do elemento <code><ul></code> (<code>myList</code>) usando <code>appendChild()</code>.</li> + <li>A última coisa que fizemos foi acrescentar os <code><h2></code>, <code><p></code>s, e <code><ul></code> dentro do <code><article></code> (<code>myArticle</code>), depois acrescentar o <code><article></code> dentro do <code><section></code>. A ordem em que as coisas são anexadas é importante, pois essa é a ordem em que elas serão exibidas dentro do HTML.</li> +</ol> + +<div class="note"> +<p><strong>Nota</strong>: Se você está com problemas pegue um exemplo para trabalhar, tente nosso código fonte <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes-finished.html">heroes-finished.html</a> (veja isso <a href="http://mdn.github.io/learning-area/javascript/oojs/json/heroes-finished.html">ao vivo</a> também.)</p> +</div> + +<div class="note"> +<p><strong>Nota</strong>: Se você está tendo problemas para seguir a notação ponto / colchete que estamos usando para acessar o objeto JavaScript, pode ajudar a abrir o arquivo <a href="http://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json">superheroes.json</a> em outra guia ou em seu editor de texto, e consultá-lo enquanto observa nosso JavaScript. Você também pode consultar o artigo sobre conceitos <a href="/en-US/docs/Learn/JavaScript/Objects/Basics">O básico de objetos JavaScript</a> para obter mais informações sobre a notação de pontos e colchetes.</p> +</div> + +<h2 id="Conversão_entre_objetos_e_texto">Conversão entre objetos e texto</h2> + +<p>O exemplo acima foi simples em termos de acesso ao objeto JavaScript, porque definimos a solicitação XHR para converter a resposta JSON diretamente em um objeto JavaScript usando:</p> + +<pre class="brush: js">request.responseType = 'json';</pre> + +<p>Mas às vezes não temos muita sorte — às vezes recebemos uma string JSON bruta e precisaremos convertê-la em um objeto por conta própria. E quando queremos enviar um objeto JavaScript pela rede, precisamos convertê-lo em JSON (uma string) antes de enviá-lo. Felizmente, esses dois problemas são tão comuns no desenvolvimento da Web que um objeto <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON">JSON</a> interno está disponível nos navegadores, o que contém os dois métodos a seguir:</p> + +<ul> + <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse">parse()</a></code>: Aceita uma string JSON como um parâmetro e retorna o objeto JavaScript correspondente.</li> + <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify">stringify()</a></code>: Aceita um objeto como um parâmetro e retorna o formato equivalente de string JSON.</li> +</ul> + +<p>Você pode ver o primeiro em ação em nosso exemplo <a href="http://mdn.github.io/learning-area/javascript/oojs/json/heroes-finished-json-parse.html">heroes-finished-json-parse.html</a> (veja o <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/json/heroes-finished-json-parse.html">source code</a>) — isso faz exatamente a mesma coisa que o exemplo que construímos anteriormente, exceto pelo fato de configurarmos o XHR para retornar texto JSON bruto, em seguida, usado <code>parse()</code> para convertê-lo em um objeto JavaScript real. O trecho principal do código está aqui:</p> + +<pre class="brush: js">request.open('GET', requestURL); +request.responseType = 'text'; // now we're getting a string! +request.send(); + +request.onload = function() { + var superHeroesText = request.response; // get the string from the response + var superHeroes = JSON.parse(superHeroesText); // convert it to an object + populateHeader(superHeroes); + showHeroes(superHeroes); +}</pre> + +<p>Como você pode imaginar, <code>stringify()</code> funciona da maneira oposta. Tente inserir as seguintes linhas no console JavaScript de seu navegador, uma por uma, para vê-lo em ação:</p> + +<pre class="brush: js">var myJSON = { "name": "Chris", "age": "38" }; +myJSON +var myString = JSON.stringify(myJSON); +myString</pre> + +<p>Aqui estamos criando um objeto JavaScript, em seguida, verificando o que ele contém, convertendo-o em uma string JSON usando <code>stringify()</code> — salvando o valor de retorno em uma nova variável — e, em seguida, verificando-o novamente.</p> + +<h2 id="Sumário">Sumário</h2> + +<p>Neste artigo, fornecemos um guia simples para usar o JSON em seus programas, incluindo como criar e analisar o JSON e como acessar dados bloqueados nele. No próximo artigo começaremos a analisar o JavaScript orientado a objetos.</p> + +<h2 id="Veja_também">Veja também</h2> + +<ul> + <li><a href="/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/JSON">Objeto JSON página de refência</a></li> + <li><a href="/pt-BR/docs/Web/API/XMLHttpRequest">Objeto XMLHttpRequest página de refência</a></li> + <li><a href="/pt-BR/docs/Web/API/XMLHttpRequest/Usando_XMLHttpRequest">Usando XMLHttpRequest</a></li> + <li><a href="/pt-BR/docs/Web/HTTP/Methods">Métodos de requisição HTTP</a></li> + <li><a href="http://json.org">Site oficial JSON com o link para o padrão ECMA</a></li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects/Object_building_practice", "Learn/JavaScript/Objects")}}</p> + +<h2 id="Nesse_módulo">Nesse módulo</h2> + +<ul> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Basics">O básico de objetos</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Object-oriented_JS">Orientação a objetos em JavaScript para iniciantes</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Object_prototypes">Protótipos de objetos</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Inheritance">Herança em JavaScript</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/JSON">Trabalhando com dados em JSON</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Object_building_practice">Prática de construção de objetos</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adicionando melhorias para nossa demo bolas saltitantes</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/objects/object-oriented_js/index.html b/files/pt-br/learn/javascript/objects/object-oriented_js/index.html new file mode 100644 index 0000000000..7772eec5cf --- /dev/null +++ b/files/pt-br/learn/javascript/objects/object-oriented_js/index.html @@ -0,0 +1,275 @@ +--- +title: JavaScript orientado a objetos para iniciantes +slug: Aprender/JavaScript/Objetos/Object-oriented_JS +translation_of: Learn/JavaScript/Objects/Object-oriented_JS +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">Com o básico fora do caminho, agora vamos nos concentrar no JavaScript orientado a objetos (OOJS) — Este artigo apresenta uma visão básica da teoria de programação orientada a objeto (OOP), em seguida, explora como o JavaScript emula as classes de objetos através de funções de construtor e como criar instâncias de objeto.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos:</th> + <td>Alfabetização básica em informática, um entendimento básico de HTML e CSS, familiaridade com o básico do JavaScript (consulte <a href="/en-US/docs/Learn/JavaScript/First_steps">Primeiros passos</a> e <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Blocos de construção</a>) e noções básicas do OOJS (consulte <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introdução aos objetos</a>).</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Para entender a teoria básica por trás da programação orientada a objetos, como isso se relaciona com JavaScript ("tudo é um objeto") e como criar construtores e instâncias de objetos.</td> + </tr> + </tbody> +</table> + +<h2 id="Programação_orientada_a_objetos_-_o_básico">Programação orientada a objetos - o básico</h2> + +<p>Para começar, vamos dar uma visão simplista e de alto nível do que é programação orientada a objeto (OOP). Dizemos simplista, porque a OOP pode rapidamente se tornar muito complicada, e dar a ela um tratamento completo agora provavelmente confundiria mais do que ajuda. A idéia básica da OOP é que usamos objetos para modelar coisas do mundo real que queremos representar dentro de nossos programas, e / ou fornecer uma maneira simples de acessar funcionalidades que de outra forma seriam difíceis ou impossíveis de usar.</p> + +<p>Os objetos podem conter dados e códigos relacionados, que representam informações sobre o que você está tentando modelar e a funcionalidade ou o comportamento que você deseja ter. Dados de objeto (e muitas vezes, funções também) podem ser armazenados ordenadamente (a palavra oficial é <strong>encapsulados</strong>) dentro de um pacote de objetos (que pode ser dado um nome específico para se referir, que é às vezes chamado de <strong>namespace</strong>), tornando fácil de estruturar e acessar; objetos também são comumente usados como armazenamentos de dados que podem ser facilmente enviados pela rede.</p> + +<h3 id="Definindo_um_modelo_de_objeto">Definindo um modelo de objeto</h3> + +<p>Vamos considerar um programa simples que exibe informações sobre os alunos e professores de uma escola. Aqui vamos olhar para a teoria OOP em geral, não no contexto de qualquer linguagem de programação específica.</p> + +<p>Para começar, poderíamos retornar ao nosso tipo de objeto Person do nosso <a href="/en-US/docs/Learn/JavaScript/Objects/Basics">primeiro artigo de objetos</a>, que define os dados genéricos e a funcionalidade de uma pessoa. Há muitas coisas que você poderia saber sobre uma pessoa (endereço, altura, tamanho do sapato, perfil de DNA, número de passaporte, traços de personalidade significativos ...), mas neste caso estamos interessados apenas em mostrar seu nome, idade, sexo e interesses, e também queremos ser capazes de escrever uma breve introdução sobre eles com base nesses dados e fazê-los dizer oi. Isso é conhecido como <strong>abstração</strong> — criando um modelo simples de uma coisa mais complexa, que representa seus aspectos mais importantes de uma forma que é fácil trabalhar com os objetivos do nosso programa.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13889/person-diagram.png" style="display: block; height: 219px; margin: 0px auto; width: 610px;"></p> + +<h3 id="Criando_objetos_reais">Criando objetos reais</h3> + +<p>De nossa classe, podemos criar <strong>instâncias de objeto</strong> — objetos que contêm os dados e a funcionalidade definidos na classe. Da nossa classe Person, podemos criar algumas pessoas reais:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/15163/MDN-Graphics-instantiation-2-fixed.png" style="display: block; height: 702px; margin: 0px auto; width: 695px;"></p> + +<p>Quando uma instância de objeto é criada a partir de uma classe, a <strong>função construtora</strong> da classe é executada para criá-la. Esse processo de criação de uma instância de objeto de uma classe é chamado de <strong>instanciação</strong> — a instância do objeto é <strong>instanciada </strong>a partir da classe.</p> + +<h3 id="Classes_especialistas">Classes especialistas</h3> + +<p>Neste caso, não queremos pessoas genéricas — queremos professores e alunos, que são tipos mais específicos de pessoas. Em OOP, podemos criar novas classes com base em outras classes — essas novas <strong>classes filhas</strong> podem <strong>herdar </strong>os recursos de dados e código de sua <strong>classe pai</strong>, para que você possa reutilizar a funcionalidade comum a todos os tipos de objetos em vez de duplicá-los. Onde a funcionalidade difere entre as classes, você pode definir recursos especializados diretamente sobre eles, conforme necessário.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13881/MDN-Graphics-inherited-3.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p> + +<p>Isso é realmente útil — professores e alunos compartilham muitos recursos comuns, como nome, sexo e idade, por isso é conveniente definir apenas esses recursos uma vez. Você também pode definir o mesmo recurso separadamente em classes diferentes, já que cada definição desse recurso estará em um namespace diferente. Por exemplo, a saudação de um aluno pode estar no formato "Yo, I'm [firstName]" (por exemplo, <em>Yo, I'm Sam</em>), enquanto um professor pode usar algo mais formal, como "Olá, meu nome é [Prefixo [lastName], e eu ensino [Subject]. " (por exemplo <em>Olá, Meu nome é Mr Griffiths, e eu ensino Química</em>).</p> + +<div class="note"> +<p><strong>Nota</strong>: A palavra chique para a capacidade de múltiplos tipos de objeto de implementar a mesma funcionalidade é o <strong>polimorfismo</strong>. Apenas no caso de você estar se perguntando.</p> +</div> + +<p>Agora você pode criar instâncias de objetos de suas classes filhas. Por exemplo:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13885/MDN-Graphics-instantiation-teacher-3.png" style="display: block; height: 743px; margin: 0px auto; width: 700px;"></p> + +<p>No restante do artigo, começaremos a analisar como a teoria da POO pode ser colocada em prática no JavaScript.</p> + +<h2 id="Construtores_e_instâncias_de_objeto">Construtores e instâncias de objeto</h2> + +<p>O JavaScript usa funções especiais chamadas <strong>funções construtoras</strong> para definir objetos e seus recursos. Eles são úteis porque muitas vezes você encontrará situações em que não sabe quantos objetos estará criando; Os construtores fornecem os meios para criar quantos objetos forem necessários de forma eficaz, anexando dados e funções a eles, conforme necessário.</p> + +<p>Vamos explorar a criação de classes por meio de construtores e criar instâncias de objeto a partir deles em JavaScript. Primeiro de tudo, gostaríamos que você fizesse uma nova cópia local do arquivo <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs.html">oojs.html</a> que vimos em nosso primeiro artigo Objetos.</p> + +<h3 id="Um_exemplo_simples">Um exemplo simples</h3> + +<ol> + <li>Vamos começar observando como você pode definir uma pessoa com uma função normal. Adicione esta função dentro do elemento <code>script</code>: + + <pre class="brush: js">function createNewPerson(name) { + var obj = {}; + obj.name = name; + obj.greeting = function() { + alert('Hi! I\'m ' + obj.name + '.'); + }; + return obj; +}</pre> + </li> + <li>Agora você pode criar uma nova pessoa chamando essa função — tente as seguintes linhas no console JavaScript do seu navegador: + <pre class="brush: js">var salva = createNewPerson('Salva'); +salva.name; +salva.greeting();</pre> + Isso funciona bem o suficiente, mas é um pouco prolixo; Se sabemos que queremos criar um objeto, por que precisamos criar explicitamente um novo objeto vazio e devolvê-lo? Felizmente, o JavaScript nos fornece um atalho útil, na forma de funções de construtor — vamos criar um agora!</li> + <li>Substitua sua função anterior pelo seguinte: + <pre class="brush: js">function Person(name) { + this.name = name; + this.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); + }; +}</pre> + </li> +</ol> + +<p>A função de construtor é a versão do JavaScript de uma classe. Você notará que ela tem todos os recursos que você espera em uma função, embora ela não retorne nada ou crie explicitamente um objeto — ela basicamente define propriedades e métodos. Você verá a palavra-chave <code>this</code> sendo usada aqui também — é basicamente dizer que sempre que uma dessas instâncias de objeto é criada, a propriedade <code>name</code> do objeto será igual ao valor do nome passado à chamada do construtor, e o método <code>greeting()</code> usará o valor do nome passado para a chamada do construtor também.</p> + +<div class="note"> +<p><strong>Nota</strong>: Um nome de função de construtor geralmente começa com uma letra maiúscula — essa convenção é usada para tornar as funções do construtor mais fáceis de reconhecer no código.</p> +</div> + +<p>Então, como podemos chamar um construtor para criar alguns objetos?</p> + +<ol> + <li>Adicione as seguintes linhas abaixo da sua adição de código anterior: + <pre class="brush: js">var person1 = new Person('Bob'); +var person2 = new Person('Sarah');</pre> + </li> + <li>Salve seu código e recarregue-o no navegador e tente inserir as seguintes linhas em seu console JS: + <pre class="brush: js">person1.name +person1.greeting() +person2.name +person2.greeting()</pre> + </li> +</ol> + +<p>Legal! Você verá agora que temos dois novos objetos na página, cada um deles armazenado em um namespace diferente — quando você acessa suas propriedades e métodos, é necessário iniciar chamadas com <code>person1</code> ou <code>person2</code>; a funcionalidade contida é cuidadosamente empacotada para que não entre em conflito com outras funcionalidades. Eles, no entanto, têm a mesma propriedade de <code>name</code> e o método <code>greeting()</code> disponível. Observe que eles estão usando seu próprio valor de <code>name</code> que foi atribuído a eles quando foram criados; Esta é uma razão pela qual é muito importante usar <code>this</code>, então eles usarão seus próprios valores e não algum outro valor.</p> + +<p>Vamos ver novamente as chamadas do construtor:</p> + +<pre class="brush: js">var person1 = new Person('Bob'); +var person2 = new Person('Sarah');</pre> + +<p>Em cada caso, a palavra-chave <code>new</code> é usada para informar ao navegador que queremos criar uma nova instância de objeto, seguida pelo nome da função com seus parâmetros obrigatórios contidos entre parênteses, e o resultado é armazenado em uma variável — muito semelhante a como uma função padrão é chamada. Cada instância é criada de acordo com esta definição:</p> + +<pre class="brush: js">function Person(name) { + this.name = name; + this.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); + }; +}</pre> + +<p>Após a criação dos novos objetos, as variáveis <code>person1</code> e <code>person2</code> contêm os seguintes objetos:</p> + +<pre class="brush: js">{ + name: 'Bob', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +} + +{ + name: 'Sarah', + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +}</pre> + +<p>Note que quando estamos chamando nossa função de construtor, estamos definindo <code>greeting()</code> toda vez, o que não é ideal. Para evitar isso, podemos definir funções no protótipo, que veremos mais adiante.</p> + +<h3 id="Criando_nosso_construtor_acabado">Criando nosso construtor acabado</h3> + +<p>O exemplo que vimos acima foi apenas um exemplo simples para começarmos. Vamos agora começar e criar nossa função final do construtor <code>Person()</code>.</p> + +<ol> + <li>Remova o código que você inseriu até agora e inclua este construtor de substituição — isso é exatamente o mesmo que o exemplo simples em princípio, com um pouco mais de complexidade: + <pre class="brush: js">function Person(first, last, age, gender, interests) { + this.name = { + 'first': first, + 'last' : last + }; + this.age = age; + this.gender = gender; + this.interests = interests; + this.bio = function() { + alert(this.name.first + ' ' + this.name.last + ' is ' + this.age + ' years old. He likes ' + this.interests[0] + ' and ' + this.interests[1] + '.'); + }; + this.greeting = function() { + alert('Hi! I\'m ' + this.name.first + '.'); + }; +}</pre> + </li> + <li>Agora adicione a seguinte linha abaixo, para criar uma instância de objeto a partir dela: + <pre class="brush: js">var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre> + </li> +</ol> + +<p>Agora você verá que pode acessar as propriedades e os métodos exatamente como fizemos anteriormente — Tente isso no seu console JS:</p> + +<pre class="brush: js">person1['age'] +person1.interests[1] +person1.bio() +// etc.</pre> + +<div class="note"> +<p><strong>Nota</strong>: Se você está tendo problemas para fazer isso funcionar, tente comparar seu código com a nossa versão — veja o código em <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-finished.html">oojs-class-finished.html</a> (também <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-finished.html">você pode ve-lo sendo executado aqui</a>).</p> +</div> + +<h3 id="Exercícios_adicionais">Exercícios adicionais</h3> + +<p>Para começar, tente adicionar mais algumas linhas de criação de objetos e tente obter e configurar os membros das instâncias de objetos resultantes.</p> + +<p>Além disso, há alguns problemas com nosso método <code>bio()</code> — a saída sempre inclui o pronome "Ele", mesmo que sua pessoa seja do sexo feminino ou alguma outra classificação de gênero preferida. E a biografia incluirá apenas dois interesses, mesmo que mais sejam listados na matriz <code>interests</code>. Você pode descobrir como corrigir isso na definição de classe (construtor)? Você pode colocar qualquer código que você gosta dentro de um construtor (você provavelmente precisará de alguns condicionais e um loop). Pense em como as sentenças devem ser estruturadas de maneira diferente dependendo do gênero e dependendo se o número de interesses listados é 1, 2 ou mais de 2.</p> + +<div class="note"> +<p><strong>Note</strong>: If you get stuck, we have provided an <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">answer inside our GitHub repo</a> (<a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">see it live</a>) — try writing it yourself first though!</p> +</div> + +<h2 id="Outras_maneiras_de_criar_instâncias_de_objeto">Outras maneiras de criar instâncias de objeto</h2> + +<p>Até agora, vimos duas maneiras diferentes de criar uma instância de objeto — <a href="/en-US/docs/Learn/JavaScript/Objects/Basics#Object_basics">declarar um literal de objeto</a>, e usar uma função de construtor (veja acima).</p> + +<p>Isso faz sentido, mas existem outras maneiras — queremos familiarizá-lo com essas informações caso você as encontre em suas viagens pela Web.</p> + +<h3 id="O_construtor_Object">O construtor Object() </h3> + +<p>Primeiro de tudo, você pode usar o construtor <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object()</a></code> para criar um novo objeto. Sim, até objetos genéricos possuem um construtor, o que gera um objeto vazio.</p> + +<ol> + <li>Tente inserir isso no console JavaScript do seu navegador: + <pre class="brush: js">var person1 = new Object();</pre> + </li> + <li>Isso armazena um objeto vazio na variável <code>person1</code>. Você pode adicionar propriedades e métodos a esse objeto usando a notação de pontos ou colchetes conforme desejado; tente estes exemplos no seu console: + <pre class="brush: js">person1.name = 'Chris'; +person1['age'] = 38; +person1.greeting = function() { + alert('Hi! I\'m ' + this.name + '.'); +};</pre> + </li> + <li>Você também pode passar um literal de objeto para o construtor <code>Object()</code> como um parâmetro, para preenchê-lo com propriedades / métodos. Tente isso no seu console JS: + <pre class="brush: js">var person1 = new Object({ + name: 'Chris', + age: 38, + greeting: function() { + alert('Hi! I\'m ' + this.name + '.'); + } +});</pre> + </li> +</ol> + +<h3 id="Usando_o_método_create">Usando o método create()</h3> + +<p>Os construtores podem ajudá-lo a fornecer seu pedido de código — você pode criar construtores em um único local e, em seguida, criar instâncias conforme necessário, e fica claro de onde eles vieram.</p> + +<p>No entanto, algumas pessoas preferem criar instâncias de objeto sem primeiro criar construtores, especialmente se estiverem criando apenas algumas instâncias de um objeto. JavaScript tem um método embutido chamado <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">create()</a></code> que permite que você faça isso. Com ele, você pode criar um novo objeto com base em qualquer objeto existente.</p> + +<ol> + <li>Com o exercício concluído das seções anteriores carregadas no navegador, tente isso no seu console JavaScript: + <pre class="brush: js">var person2 = Object.create(person1);</pre> + </li> + <li>Agora tente estes: + <pre class="brush: js">person2.name +person2.greeting()</pre> + </li> +</ol> + +<p>Você verá que a <code>person2</code> foi criada com base na <code>person1</code> — ela tem as mesmas propriedades e métodos disponíveis para ela.</p> + +<p>Uma limitação do <code>create()</code> é que o IE8 não o suporta. Então os construtores são mais efetivos se você quiser que funcione em navegadores antigos.</p> + +<p>Vamos explorar os efeitos de <code>create()</code> em mais detalhes posteriormente.</p> + +<h2 id="Sumário">Sumário</h2> + +<p>Este artigo forneceu uma visão simplificada da teoria orientada a objetos — isso não é toda a história, mas dá uma idéia do que estamos lidando aqui. Além disso, começamos a analisar diferentes maneiras de gerar instâncias de objetos.</p> + +<p>No próximo artigo, vamos explorar os protótipos de objetos JavaScript.</p> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Basics", "Learn/JavaScript/Objects/Object_prototypes", "Learn/JavaScript/Objects")}}</p> + +<h2 id="Neste_módulo">Neste módulo</h2> + +<ul> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Basics">O básico de objetos</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Object-oriented_JS">Orientação a objetos em JavaScript para iniciantes</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Object_prototypes">Protótipos de objetos</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Inheritance">Herença em JavaScript</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/JSON">Trabalhando com dados em JSON</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Object_building_practice">Prática de construção de objetos</a></li> + <li><a href="/pt-BR/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adicionando melhorias no nossa demo bolas saltitantes</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/objects/object_building_practice/index.html b/files/pt-br/learn/javascript/objects/object_building_practice/index.html new file mode 100644 index 0000000000..4c4ab6c629 --- /dev/null +++ b/files/pt-br/learn/javascript/objects/object_building_practice/index.html @@ -0,0 +1,300 @@ +--- +title: Prática de construção de objetos +slug: Aprender/JavaScript/Objetos/Object_building_practice +translation_of: Learn/JavaScript/Objects/Object_building_practice +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">Nos artigos anteriores, analisamos todos os detalhes essenciais da teoria e da sintaxe do objeto JavaScript, fornecendo uma base sólida para começar. Neste artigo, vamos mergulhar em um exercício prático, dando a você mais prática na construção de objetos JavaScript personalizados, com um resultado divertido e colorido.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Prerequisites:</th> + <td>Conhecimentos básicos de informática, conhecimento básico de HTML e CSS, familiaridade com o básico de JavaScript (veja <a href="/en-US/docs/Learn/JavaScript/First_steps">First steps</a> e <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Building blocks</a>) e o básico de OOJS (veja <a href="/en-US/docs/Learn/JavaScript/Object-oriented/Introduction">Introduction to objects</a>).</td> + </tr> + <tr> + <th scope="row">Objective:</th> + <td>Adiquirir alguma prática no uso de objetos e técnicas de orientação a objetos num contexto real.</td> + </tr> + </tbody> +</table> + +<h2 id="Vamos_saltitar_algumas_bolas">Vamos saltitar algumas bolas</h2> + +<p>Neste artigo, vamos escrever uma demo clássica de "bolas saltitantes", para mostrar o quão úteis os objetos podem ser em JavaScript. Nossas bolinhas vão saltar pela tela e mudam de cor quando se tocam. O exemplo acabado vai parecer um pouco assim:<img alt="" src="https://mdn.mozillademos.org/files/13865/bouncing-balls.png" style="display: block; height: 614px; margin: 0px auto; width: 800px;"></p> + +<ol> +</ol> + +<p>Este exemplo fará uso da <a href="/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics">Canvas API</a>, para desenhar as bolas na tela, e da <a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame</a> API para animar toda a exibição — você não precisa ter nenhum conhecimento prévio dessas APIs e esperamos que, no momento em que você terminar este artigo, você esteja interessado em explorá-los mais. Ao longo do caminho, faremos uso de alguns objetos bacanas, e mostraremos algumas técnicas legais, como bolas quicando nas paredes, e verificando se elas se chocaram (também conhecidas como <strong>detecção de colisão</strong>).</p> + +<h2 id="Começando">Começando</h2> + +<p>Para começar, faça cópias locais de nossos arquivos <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/index.html">index.html</a></code>, <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/style.css">style.css</a></code>, e <code><a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main.js">main.js</a></code>. Estes contêm o seguinte, respectivamente:</p> + +<ol> + <li>Um documento HTML muito simples com um elemento {{HTMLElement("h1")}}, um elemento {{HTMLElement("canvas")}} para desenhar nossas bolas e elementos para aplicar nosso CSS e JavaScript em nosso HTML.</li> + <li>Alguns estilos muito simples, que servem principalmente para estilizar e posicionar o <code><h1></code>, e se livrar de qualquer barra de rolagem ou margem ao redor da borda da página (para que fique bonito e arrumado).</li> + <li>Algum JavaScript que serve para configurar o elemento <code><canvas></code> e fornecer uma função geral que vamos usar.</li> +</ol> + +<p>A primeira parte do script é assim:</p> + +<pre class="brush: js">const canvas = document.querySelector('canvas'); + +const ctx = canvas.getContext('2d'); + +const width = canvas.width = window.innerWidth; +const height = canvas.height = window.innerHeight;</pre> + +<p>Esse script obtém uma referência ao elemento <code><canvas></code> e, em seguida, chama o método <code><a href="/en-US/docs/Web/API/HTMLCanvasElement/getContext">getContext()</a></code> para nos fornecer um contexto no qual podemos começar a desenhar. A variável resultante (<code>ctx</code>) é o objeto que representa diretamente a área de desenho da tela e nos permite desenhar formas 2D nela.</p> + +<p>Em seguida, definimos variáveis chamadas <code>width</code> e <code>height</code>, e a largura e altura do elemento canvas (representado pelas propriedades <code>canvas.width</code> e <code>canvas.height</code>) para igualar a largura e a altura da viewport do navegador (a área em que a página da Web aparece — isso pode ser obtido das propriedades {{domxref("Window.innerWidth")}} e {{domxref("Window.innerHeight")}} ).</p> + +<p>Você verá aqui que estamos encadeando várias tarefas juntas, para que as variáveis sejam todas mais rápidas — isso é perfeitamente aceitável.</p> + +<p>A última parte do script inicial é a seguinte:</p> + +<pre class="brush: js">function random(min, max) { + const num = Math.floor(Math.random() * (max - min + 1)) + min; + return num; +}</pre> + +<p>Essa função usa dois números como argumentos e retorna um número aleatório no intervalo entre os dois.</p> + +<h2 id="Modelando_uma_bola_no_nosso_programa">Modelando uma bola no nosso programa</h2> + +<p>Nosso programa contará com muitas bolas saltando ao redor da tela. Como todas essas bolas se comportarão da mesma maneira, faz sentido representá-las com um objeto. Vamos começar adicionando o construtor a seguir ao final do código.</p> + +<pre class="brush: js">function Ball(x, y, velX, velY, color, size) { + this.x = x; + this.y = y; + this.velX = velX; + this.velY = velY; + this.color = color; + this.size = size; +}</pre> + +<p>Aqui incluímos alguns parâmetros que definem as propriedades que cada bola precisa para funcionar em nosso programa:</p> + +<ul> + <li>coordenadas <code>x</code> e <code>y</code> — coordenadas horizontal e vertical onde a bola vai começar na tela. Isso pode variar entre 0 (canto superior esquerdo) à largura e altura da janela de visualização do navegador (canto inferior direito).</li> + <li>velocidade horizontal e vertical (<code>velX</code> e <code>velY</code>) — cada bola recebe uma velocidade horizontal e vertical; em termos reais, esses valores serão adicionados regularmente aos valores das coordenadas <code>x</code>/<code>y</code> quando começarmos a animar as bolas, para movê-las tanto em cada quadro.</li> + <li><code>color</code> — cada bola recebe uma cor.</li> + <li><code>size</code> — cada bola recebe um tamanho — este será o seu raio, em pixels.</li> +</ul> + +<p>Isso classifica as propriedades, mas e os métodos? Queremos realmente fazer com que nossas bolas façam algo em nosso programa.</p> + +<h3 id="Desenhando_a_bola">Desenhando a bola</h3> + +<p>Primeiro adicione o seguinte método <code>draw()</code> ao <code>prototype</code> do <code>Ball()</code>:</p> + +<pre class="brush: js">Ball.prototype.draw = function() { + ctx.beginPath(); + ctx.fillStyle = this.color; + ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI); + ctx.fill(); +}</pre> + +<p>Usando esta função, podemos dizer a nossa bola para desenhar-se na tela, chamando uma série de membros do contexto de tela 2D que definimos anteriormente (<code>ctx</code>). O contexto é como o papel, e agora queremos comandar nossa caneta para desenhar algo nela:</p> + +<ul> + <li>Primeiro, usamos <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath">beginPath()</a></code> para declarar que queremos desenhar uma forma no papel.</li> + <li>Em seguida, usamos <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle">fillStyle</a></code> para definir a cor que queremos que a forma seja — nós a definimos como a propriedade <code>color</code> da nossa bola.</li> + <li>Em seguida, usamos o método <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/arc">arc()</a></code> para traçar uma forma de arco no papel. Seus parâmetros são: + <ul> + <li>A posição <code>x</code> e <code>y</code> do centro do arco — estamos especificando as propriedades <code>x</code> e <code>y</code> da nossa bola.</li> + <li>O raio do nosso arco — estamos especificando a propriedade <code>size</code> da nossa bola.</li> + <li>Os dois últimos parâmetros especificam o número inicial e final de graus em volta do círculo em que o arco é desenhado entre eles. Aqui nós especificamos 0 graus e <code>2 * PI</code>, que é o equivalente a 360 graus em radianos (irritantemente, você tem que especificar isso em radianos). Isso nos dá um círculo completo. Se você tivesse especificado apenas <code>1 * PI</code>, você obteria um semicírculo (180 graus).</li> + </ul> + </li> + <li>Por último, usamos o método <code><a href="/en-US/docs/Web/API/CanvasRenderingContext2D/fill">fill()</a></code>, que basicamente diz "terminar de desenhar o caminho que começamos com <code>beginPath()</code>, e preencher a área que ocupa com a cor que especificamos anteriormente em <code>fillStyle</code>."</li> +</ul> + +<p>Você pode começar a testar seu objeto já.</p> + +<ol> + <li>Salve o código até o momento e carregue o arquivo HTML em um navegador.</li> + <li>Abra o console JavaScript do navegador e, em seguida, atualize a página para que o tamanho da tela mude para a viewport menor visível deixada quando o console for aberto.</li> + <li>Digite o seguinte para criar uma nova instância de bola: + <pre class="brush: js">let testBall = new Ball(50, 100, 4, 4, 'blue', 10);</pre> + </li> + <li>Tente chamar seus membros: + <pre class="brush: js">testBall.x +testBall.size +testBall.color +testBall.draw()</pre> + </li> + <li>Quando você entra na última linha, você deve ver a bola se desenhando em algum lugar na sua tela.</li> +</ol> + +<h3 id="Atualizando_os_dados_da_bola">Atualizando os dados da bola</h3> + +<p>Podemos desenhar a bola na posição, mas para começar a mover a bola, precisamos de uma função de atualização de algum tipo. Adicione o seguinte código na parte inferior do seu arquivo JavaScript, para adicionar um método <code>update()</code> ao <code>prototype</code> do <code>Ball()</code>:</p> + +<pre class="brush: js">Ball.prototype.update = function() { + if ((this.x + this.size) >= width) { + this.velX = -(this.velX); + } + + if ((this.x - this.size) <= 0) { + this.velX = -(this.velX); + } + + if ((this.y + this.size) >= height) { + this.velY = -(this.velY); + } + + if ((this.y - this.size) <= 0) { + this.velY = -(this.velY); + } + + this.x += this.velX; + this.y += this.velY; +}</pre> + +<p>As primeiras quatro partes da função verificam se a bola atingiu a borda da tela. Se tiver, invertemos a polaridade da velocidade relevante para fazer a bola viajar na direção oposta. Assim, por exemplo, se a bola estava viajando para cima (positivo <code>velY</code>), então a velocidade vertical é alterada de forma que ela comece a viajar para baixo (negativo <code>velY</code>).</p> + +<p>Nos quatro casos, estamos verificando se:</p> + +<ul> + <li>Se a coordenada <code>x</code> é maior que a largura da tela (a bola está saindo da borda direita).</li> + <li>Se a coordenada <code>x</code> é menor que 0 (a bola está saindo da borda esquerda).</li> + <li>Se a coordenada <code>y</code> é maior que a altura da tela (a bola está saindo da borda inferior).</li> + <li>Se a coordenada <code>y</code> é menor que 0 (a bola está saindo da borda superior).</li> +</ul> + +<p>Em cada caso, estamos incluindo o <code>size</code> da bola no cálculo, porque as coordenadas <code>x</code>/<code>y</code> estão no centro da bola, mas queremos que a borda da bola saia do perímetro — não queremos a bola para fique no meio da tela antes de quicar de volta.</p> + +<p>As duas últimas linhas adicionam o valor <code>velX</code> à coordenada <code>x</code>, e o valor <code>velY</code> à coordenada <code>y</code> — a bola é efitivamente movida cada vez que este método é chamado.</p> + +<p>Isso é o que será feito por ora; vamos continuar com alguma animação!</p> + +<h2 id="Animando_a_bola">Animando a bola</h2> + +<p>Agora vamos tornar isso divertido. Vamos começar a adicionar bolas à tela e a animá-las.</p> + +<ol> + <li>Primeiro, precisamos de um lugar para armazenar todas as nossas bolas. O array a seguir fará esse trabalho — adicione-o ao final do seu código agora: + <pre class="brush: js">let balls = [];</pre> + + <p>Todos os programas que animam as coisas geralmente envolvem um loop de animação, que serve para atualizar as informações no programa e renderizar a visualização resultante em cada quadro da animação; esta é a base para a maioria dos jogos e outros programas.</p> + </li> + <li>Adicione o seguinte ao final do seu código agora: + <pre class="brush: js">function loop() { + ctx.fillStyle = 'rgba(0, 0, 0, 0.25)'; + ctx.fillRect(0, 0, width, height); + + while (balls.length < 25) { + let size = random(10,20); + let ball = new Ball( + // ball position always drawn at least one ball width + // away from the edge of the canvas, to avoid drawing errors + random(0 + size,width - size), + random(0 + size,height - size), + random(-7,7), + random(-7,7), + 'rgb(' + random(0,255) + ',' + random(0,255) + ',' + random(0,255) +')', + size + ); + balls.push(ball); + } + + for (let i = 0; i < balls.length; i++) { + balls[i].draw(); + balls[i].update(); + } + + requestAnimationFrame(loop); +}</pre> + + <p>Nossa função <code>loop()</code> faz o seguinte:</p> + + <ul> + <li>Define a cor de preenchimento da tela como preto semitransparente e desenha um retângulo com a cor em toda a largura e altura da tela, usando <code>fillRect()</code> (os quatro parâmetros fornecem uma coordenada de início e uma largura e altura para o retângulo desenhado ). Isso serve para encobrir o desenho do quadro anterior antes que o próximo seja desenhado. Se você não fizer isso, você verá apenas longas cobras se movimentando ao redor da tela, em vez de mover as bolas! A cor do preenchimento é definida como semitransparente, <code>rgba(0,0,0,0.25)</code>, para permitir que os poucos quadros anteriores brilhem levemente, produzindo as pequenas trilhas atrás das bolas à medida que elas se movem. Se você mudou 0,25 para 1, você não vai mais vê-los. Tente variar esse número para ver o efeito que ele tem.</li> + <li>Cria uma nova instância de nossa <code>Ball()</code> usando valores aleatórios gerados com a nossa função <code>random()</code> então <code>push()</code>para o final de nosso array de bolas, mas somente enquanto o número de bolas no array é menor que 25. Então quando temos 25 bolas na tela, não aparecem mais bolas. Você pode tentar variar o número em<code>balls.length < 25</code> para obter mais ou menos bolas na tela. Dependendo de quanto poder de processamento seu computador / navegador possui, especificar vários milhares de bolas pode retardar bastante a animação!</li> + <li>Faz um loop em todas as <code>balls</code> no array de bolas e executa a função <code>draw()</code> e <code>update()</code> de cada bola para desenhar cada uma delas na tela, depois faz as atualizações necessárias para a posição e a velocidade no tempo para o próximo quadro.</li> + <li>Executa a função novamente usando o método <code>requestAnimationFrame()</code> — quando esse método é executado constantemente e passa o mesmo nome de função, ele executará essa função um número definido de vezes por segundo para criar uma animação suave. Isso geralmente é feito de forma recursiva — o que significa que a função está chamando a si mesma toda vez que é executada, portanto, ela será executada repetidas vezes.</li> + </ul> + </li> + <li>Por último mas não menos importante, adicione a seguinte linha à parte inferior do seu código — precisamos chamar a função uma vez para iniciar a animação. + <pre class="brush: js">loop();</pre> + </li> +</ol> + +<p>É isso para o básico — tente salvar e atualizar para testar suas bolas quicando!</p> + +<h2 id="Adicionando_detecção_de_colisão">Adicionando detecção de colisão</h2> + +<p>Agora, para um pouco de diversão, vamos adicionar alguma detecção de colisão ao nosso programa, para que nossas bolas saibam quando bateram em outra bola.</p> + +<ol> + <li>Primeiro de tudo, adicione a seguinte definição de método abaixo onde você definiu o método <code>update()</code> (ou seja, o bloco <code>Ball.prototype.update</code>). + + <pre class="brush: js">Ball.prototype.collisionDetect = function() { + for (let j = 0; j < balls.length; j++) { + if (!(this === balls[j])) { + const dx = this.x - balls[j].x; + const dy = this.y - balls[j].y; + const distance = Math.sqrt(dx * dx + dy * dy); + + if (distance < this.size + balls[j].size) { + balls[j].color = this.color = 'rgb(' + random(0, 255) + ',' + random(0, 255) + ',' + random(0, 255) +')'; + } + } + } +}</pre> + + <p>Esse método é um pouco complexo, então não se preocupe se você não entender exatamente como isso funciona agora. Uma explicação a seguir:</p> + + <ul> + <li>Para cada bola, precisamos checar todas as outras bolas para ver se ela colidiu com a bola atual. Para fazer isso, abrimos outro loop <code>for</code> para percorrer todas as bolas no array <code>balls[]</code>.</li> + <li>Imediatamente dentro de nosso loop for, usamos uma instrução <code>if</code> para verificar se a bola atual em loop é a mesma bola que estamos verificando no momento. Não queremos verificar se uma bola colidiu consigo mesma! Para fazer isso, verificamos se a bola atual (ou seja, a bola cujo método collisionDetect está sendo invocado) é a mesma que a bola de loop (ou seja, a bola que está sendo referenciada pela iteração atual do loop for no collisionDetect método). Nós então usamos <code>!</code> para negar a verificação, para que o código dentro da instrução if seja executado apenas se eles não forem iguais.</li> + <li>Em seguida, usamos um algoritmo comum para verificar a colisão de dois círculos. Estamos basicamente verificando se alguma das áreas dos dois círculos se sobrepõe. Isso é explicado ainda mais na <a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D collision detection</a>.</li> + <li>Se uma colisão for detectada, o código dentro da instrução <code>if</code> interna será executado. Neste caso, estamos apenas definindo a propriedade <code>color</code> de ambos os círculos para uma nova cor aleatória. Poderíamos ter feito algo muito mais complexo, como fazer com que as bolas saltassem umas das outras de forma realista, mas isso teria sido muito mais complexo de implementar. Para essas simulações físicas, os desenvolvedores tendem a usar jogos ou bibliotecas físicas, como <a href="http://wellcaffeinated.net/PhysicsJS/">PhysicsJS</a>, <a href="http://brm.io/matter-js/">matter.js</a>, <a href="http://phaser.io/">Phaser</a>, etc.</li> + </ul> + </li> + <li>Você também precisa chamar esse método em cada quadro da animação. Adicione o seguinte abaixo do <code>balls[i].update();</code>: + <pre class="brush: js">balls[i].collisionDetect();</pre> + </li> + <li>Salve e atualize a demonstração novamente, e você verá suas bolas mudando de cor quando colidirem!</li> +</ol> + +<div class="note"> +<p><strong>Note</strong>: If you have trouble getting this example to work, try comparing your JavaScript code against our <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main-finished.js">finished version</a> (also see it <a href="http://mdn.github.io/learning-area/javascript/oojs/bouncing-balls/index-finished.html">running live</a>).</p> +</div> + +<h2 id="Sumário">Sumário</h2> + +<p>Esperamos que você tenha se divertido escrevendo seu próprio exemplo de bolas saltitantes aleatórias do mundo real, usando várias técnicas orientadas a objetos e objetos de todo o módulo! Isso deve ter lhe dado alguma prática útil no uso de objetos e um bom contexto do mundo real.</p> + +<p>É isso para artigos de objetos — tudo o que resta agora é para você testar suas habilidades na avaliação de objetos.</p> + +<h2 id="Veja_também">Veja também</h2> + +<ul> + <li><a href="/en-US/docs/Web/API/Canvas_API/Tutorial">Canvas tutorial</a> — um guia para iniciantes sobre o uso de telas (canvas) 2D .</li> + <li><a href="/en-US/docs/Web/API/window/requestAnimationFrame">requestAnimationFrame()</a></li> + <li><a href="/en-US/docs/Games/Techniques/2D_collision_detection">2D collision detection</a></li> + <li><a href="/en-US/docs/Games/Techniques/3D_collision_detection">3D collision detection</a></li> + <li><a href="/en-US/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript">2D breakout game using pure JavaScript</a> — um ótimo tutorial para iniciantes que mostra como criar um jogo 2D.</li> + <li><a href="/en-US/docs/Games/Tutorials/2D_breakout_game_Phaser">2D breakout game using Phaser</a> — explica conceitos básicos da criação de um jogo 2D utilizando uma biblioteca JavaScript.</li> +</ul> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/JSON", "Learn/JavaScript/Objects/Adding_bouncing_balls_features", "Learn/JavaScript/Objects")}}</p> + +<h2 id="In_this_module">In this module</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li> +</ul> diff --git a/files/pt-br/learn/javascript/objects/object_prototypes/index.html b/files/pt-br/learn/javascript/objects/object_prototypes/index.html new file mode 100644 index 0000000000..c574781301 --- /dev/null +++ b/files/pt-br/learn/javascript/objects/object_prototypes/index.html @@ -0,0 +1,269 @@ +--- +title: Protótipos de objetos +slug: Aprender/JavaScript/Objetos/Object_prototypes +translation_of: Learn/JavaScript/Objects/Object_prototypes +--- +<div>{{LearnSidebar}}</div> + +<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</div> + +<p class="summary">Protótipos são o mecanismo pelo qual objetos JavaScript herdam recursos uns dos outros. Neste artigo, explicamos como as cadeias de protótipos funcionam e observamos como a propriedade prototype pode ser usada para adicionar métodos aos construtores existentes.</p> + +<table class="learn-box standard-table"> + <tbody> + <tr> + <th scope="row">Pré-requisitos:</th> + <td>Entender como funções em JavaScript funcionam, familiaridade com o básico de JavaScript (veja <a href="/en-US/docs/Learn/JavaScript/First_steps">Primeiros Passos</a> e <a href="/en-US/docs/Learn/JavaScript/Building_blocks">Elementos Construtivos</a>), e o básico de Orientação a Objetos em JavaScript (veja <a href="/pt-BR/docs/Aprender/JavaScript/Objetos">Introdução a Objetos</a>).</td> + </tr> + <tr> + <th scope="row">Objetivo:</th> + <td>Entender protótipos de objetos JavaScript, como a cadeia de protótipos funciona, e como adicionar novos métodos à propriedade <em>prototype.</em></td> + </tr> + </tbody> +</table> + +<h2 id="Uma_linguagem_baseada_em_protótipos">Uma linguagem baseada em protótipos?</h2> + +<p>O JavaScript é frequentemente descrito como uma <strong>linguagem baseada em protótipos</strong> — para fornecer herança, os objetos podem ter um <strong>objeto de protótipo</strong>, que atua como um objeto de modelo do qual herda métodos e propriedades. O objeto de protótipo de um objeto também pode ter um objeto de protótipo, do qual herda métodos e propriedades, e assim por diante. Isso geralmente é chamado de <strong>cadeia de protótipos</strong> e explica por que objetos diferentes têm propriedades e métodos definidos em outros objetos disponíveis para eles.</p> + +<p>Bem, para ser exato, as propriedades e os métodos são definidos na propriedade <code>prototype</code> nas funções construtoras dos Objetos, não nas próprias instâncias do objeto.</p> + +<p>Em JavaScript, é feito um link entre a instância do objeto e seu protótipo (sua propriedade <code>__proto__</code>, que é derivada da propriedade <code>prototype</code> no construtor), e as propriedades e os métodos são encontrados percorrendo a cadeia de protótipos.</p> + +<div class="note"> +<p><strong>Note:</strong> É importante entender que há uma distinção entre o protótipo de um objeto (que está disponível por meio de <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf">Object.getPrototypeOf(obj)</a></code>, ou por meio da propriedade <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">__proto__</a></code> ) e a propriedade <code>prototype</code> em funções construtoras. O primeiro é a propriedade em cada instância e o último é a propriedade no construtor. Ou seja, <code>Object.getPrototypeOf(new Foobar())</code> efere-se ao mesmo objeto que <code>Foobar.prototype</code>.</p> +</div> + +<p>Vejamos um exemplo para tornar isso um pouco mais claro.</p> + +<h2 id="Noções_básicas_sobre_objetos_de_protótipo">Noções básicas sobre objetos de protótipo</h2> + +<p>Aqui voltaremos ao exemplo em que terminamos de escrever nosso construtor <code>Person()</code> — carregamos o exemplo em seu navegador. Se você ainda não o conseguiu trabalhar no último artigo, use nosso exemplo <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> (veja também o <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">código-fonte</a>).</p> + +<p>Neste exemplo, definimos uma função construtora, assim:</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + + // property and method definitions + this.first = first; + this.last = last; +//... +}</pre> + +<p>Nós criamos então uma instância de objeto como esta:</p> + +<pre class="brush: js">var person1 = new Person('Bob', 'Smith', 32, 'male', ['music', 'skiing']);</pre> + +<p>Se você digitar "<code>person1.</code>" em seu console JavaScript, você deve ver o navegador tentar concluir automaticamente isso com os nomes de membros disponíveis neste objeto:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13853/object-available-members.png" style="display: block; margin: 0 auto;"></p> + +<p>Nesta lista, você verá os membros definidos no construtor de <code>person1</code>'s constructor — <code>Person()</code> — <code>name</code>, <code>age</code>, <code>gender</code>, <code>interests</code>, <code>bio</code>, e <code>greeting</code>. No entanto, você também verá alguns outros membros — <code>watch</code>, <code>valueOf</code>, etc — estes estão definidos no objeto de protótipo do <code>Person()</code>, que é <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code>.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/13891/MDN-Graphics-person-person-object-2.png" style="display: block; height: 150px; margin: 0px auto; width: 700px;"></p> + +<p>O que acontece se você chamar um método em <code>person1</code>, que é realmente definido em <code>Object</code>? Por exemplo:</p> + +<pre class="brush: js">person1.valueOf()</pre> + +<p>Este método — <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">Object.valueOf()</a></code> é herdado por <code>person1</code> porque seu construtor é <code>Person()</code>, e o protótipo de <code>Person()</code> é <code>Object()</code>. <code>valueOf()</code> retorna o valor do objeto em que é chamado — experimente e veja! Nesse caso, o que acontece é:</p> + +<ul> + <li>O navegador verifica inicialmente se o objeto <code>person1</code> tem um método <code>valueOf()</code> disponível nele, conforme definido em seu construtor, <code>Person()</code>.</li> + <li>Se não tem, então o navegador verifica se o objeto (<code>Object()</code>) de protótipo do construtor <code>Person()</code> tem um método <code>valueOf()</code> disponível, então ele é chamado, e tudo está bem!</li> +</ul> + +<div class="note"> +<p><strong>Nota</strong>: Queremos reiterar que os métodos e as propriedades <strong>não </strong>são copiados de um objeto para outro na cadeia de protótipos — eles são acessados ao percorrer a cadeia como descrito acima.</p> +</div> + +<div class="note"> +<p><strong>Nota</strong>: Não existe uma maneira oficial de acessar diretamente o objeto protótipo de um objeto — os "links" entre os itens da cadeia são definidos em uma propriedade interna, chamada de <code>[[prototype]]</code> na especificação da linguagem JavaScript (veja {{glossary("ECMAScript")}}). A maioria dos navegadores modernos, no entanto, tem uma propriedade disponível neles chamada <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto">__proto__</a></code> (que é sublinhada em ambos os lados), que contém o objeto de protótipo do construtor do objeto. Por exemplo, tente <code>person1.__proto__</code> and <code>person1.__proto__.__proto__</code> para ver como a cadeia se parece no código!</p> + +<p>Desde ECMAScript 2015 você pode acessar o objeto protótipo de um objeto indiretamente via <code>Object.getPrototypeOf(obj)</code>.</p> +</div> + +<h2 id="A_propriedade_prototype_Onde_os_membros_herdados_são_definidos">A propriedade prototype: Onde os membros herdados são definidos</h2> + +<p>Então, onde estão as propriedades e os métodos herdados definidos? Se você observar a página de referência do <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object">Object</a></code>, verá, à esquerda, um grande número de propriedades e métodos — muito mais do que o número de membros herdados que vimos disponíveis no objeto <code>person1</code>. Alguns são herdados e outros não — por que isso acontece?</p> + +<p>Como mencionado acima, os herdados são os definidos na propriedade <code>prototype</code> (você poderia chamá-lo de um subespaço de nomes) — ou seja, aqueles que começam com <code>Object.prototype.</code>, e não os que começam com apenas <code>Object.</code> O valor da propriedade <code>prototype</code> é um objeto, que é basicamente um bucket para armazenar propriedades e métodos que queremos que sejam herdados por objetos mais abaixo na cadeia de protótipos.</p> + +<p>Portanto, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch">Object.prototype.watch()</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf">Object.prototype.valueOf()</a></code>, etc., estão disponíveis para qualquer tipo de objeto que herda de <code>Object.prototype</code>, incluindo novas instâncias de objeto criadas a partir do construtor <code>Person()</code>.</p> + +<p><code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is">Object.is()</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys">Object.keys()</a></code>, e outros membros não definidos dentro do bloco <code>prototype</code> não são herdados por instâncias de objetos ou tipos de objetos que herdam de <code>Object.prototype</code>. Eles são métodos / propriedades disponíveis apenas no próprio construtor <code>Object()</code>.</p> + +<div class="note"> +<p><strong>Nota</strong>: Isso parece estranho — como você pode ter um método definido em um construtor, que é em si uma função? Bem, uma função também é um tipo de objeto — veja a referência do construtor <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function">Function()</a></code> se você não acredita em nós.</p> +</div> + +<ol> + <li>Você pode conferir as propriedades de protótipo existentes para si mesmo — volte ao nosso exemplo anterior e tente inserir o seguinte no console JavaScript: + <pre class="brush: js">Person.prototype</pre> + </li> + <li>A saída não mostrará muito porque não definimos nada no protótipo do nosso construtor personalizado! Por padrão, o <code>prototype</code> de um construtor sempre começa vazio. Agora tente o seguinte: + <pre class="brush: js">Object.prototype</pre> + </li> +</ol> + +<p>Você verá um grande número de métodos definidos na propriedade <code>prototype</code> do <code>Object</code>, que estão disponíveis em objetos que herdam <code>Object</code>, como mostrado anteriormente.</p> + +<p>Você verá outros exemplos de herança de cadeia de protótipos em todo o JavaScript — tente procurar os métodos e propriedades definidos no protótipo dos objetos globais <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String">String</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number">Number</a></code>, e <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array">Array</a></code>, por exemplo. Estes todos têm um número de membros definidos em seu protótipo, e é por isso que, por exemplo, quando você cria uma string, como esta:</p> + +<pre class="brush: js">var myString = 'This is my string.';</pre> + +<p><code>myString</code> imediatamente tem vários métodos úteis disponíveis, como <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split">split()</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf">indexOf()</a></code>, <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace">replace()</a></code>, etc.</p> + +<div class="note"> +<p><strong>Nota</strong>: Vale a pena ler nosso guia mais aprofundado sobre <a href="/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain#Using_prototypes_in_JavaScript">Como usar protótipos em JavaScript</a>, uma vez que você tenha entendido esta seção e queira saber mais. Esta seção é intencionalmente simplificada para tornar esses conceitos um pouco mais fáceis de entender quando você os conhecer pela primeira vez.</p> +</div> + +<div class="warning"> +<p><strong>Importante</strong>: A propriedade <code>prototype</code> é uma das partes com o nome mais confuso do JavaScript — você pode pensar que <code>this</code> aponta para o objeto de protótipo do objeto atual, mas não (esse é um objeto interno que pode ser acessado por <code>__proto__</code>, lembra?) . Em vez disso, <code>prototype</code> é uma propriedade que contém um objeto no qual você define os membros que deseja herdar.</p> +</div> + +<h2 id="Revisitando_create">Revisitando create()</h2> + +<p>Anteriormente mostramos como o método <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create()</a></code> pode ser usado para criar uma nova instância de objeto.</p> + +<ol> + <li>Por exemplo, tente isso no console JavaScript do seu exemplo anterior: + <pre class="brush: js">var person2 = Object.create(person1);</pre> + </li> + <li>O que <code>create()</code> realmente faz é criar um novo objeto a partir de um objeto de protótipo especificado. Aqui, <code>person2</code> está sendo criado usando <code>person1</code> como um objeto de protótipo. Você pode verificar isso inserindo o seguinte no console: + <pre class="brush: js">person2.__proto__</pre> + </li> +</ol> + +<p>Isso retornará o <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">person1</span></font>.</p> + +<h2 id="A_propriedade_do_construtor">A propriedade do construtor</h2> + +<p>Toda função de construtor possui uma propriedade prototype cujo valor é um objeto que contém uma propriedade <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">constructor</a></code>. Esta propriedade construtora aponta para a função construtora original. Como você verá na próxima seção, as propriedades definidas na propriedade Person.prototype (ou, em geral, na propriedade prototype de uma função construtora, que é um objeto, conforme mencionado na seção acima) tornam-se disponíveis para todos os objetos de instância criados usando Construtor Person(). Portanto, a propriedade constructor também está disponível para os objetos person1 e person2.</p> + +<ol> + <li>Por exemplo, tente estes comandos no console: + <pre class="brush: js">person1.constructor +person2.constructor</pre> + + <p>Estes devem retornar o construtor <code>Person()</code>, pois contém a definição original dessas instâncias.</p> + + <p>Um truque inteligente é que você pode colocar parênteses no final da propriedade do <code>constructor</code> (contendo quaisquer parâmetros necessários) para criar outra instância de objeto daquele construtor. O construtor é uma função depois de tudo, então pode ser chamado usando parênteses; você só precisa incluir a palavra-chave <code>new</code> para especificar que deseja usar a função como um construtor.</p> + </li> + <li>Tente isso no console: + <pre class="brush: js">var person3 = new person1.constructor('Karen', 'Stephenson', 26, 'female', ['playing drums', 'mountain climbing']);</pre> + </li> + <li>Agora tente acessar os recursos do seu novo objeto, por exemplo: + <pre class="brush: js">person3.name.first +person3.age +person3.bio()</pre> + </li> +</ol> + +<p>Isso funciona bem. Você não precisará usá-lo com frequência, mas pode ser realmente útil quando você deseja criar uma nova instância e não tem uma referência ao construtor original facilmente disponível por algum motivo.</p> + +<p>A propriedade do <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">constructor</a></code> tem outros usos. Por exemplo, se você tiver uma instância de objeto e desejar retornar o nome do construtor do qual ela é uma instância, use o seguinte:</p> + +<pre class="brush: js">instanceName.constructor.name</pre> + +<p>Tente isso, por exemplo:</p> + +<pre class="brush: js">person1.constructor.name +</pre> + +<div class="note"> +<p><strong>Nota</strong>: O valor de <code>constructor.name</code> pode mudar (devido à herança prototípica, ligação, pré-processadores, transpilers, etc.), portanto, para exemplos mais complexos, você desejará usar o operador <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/instanceof">instanceof</a></code>. </p> +</div> + +<ol> +</ol> + +<h2 id="Modificando_Protótipos">Modificando Protótipos</h2> + +<p>Vamos dar uma olhada em um exemplo de modificação da propriedade <code>prototype</code> de uma função construtora — os métodos adicionados ao protótipo estão então disponíveis em todas as instâncias de objeto criadas a partir do construtor. Neste ponto, finalmente adicionaremos algo ao protótipo do nosso construtor <code>Person()</code>.</p> + +<ol> + <li>Volte para o nosso exemplo de <a href="http://mdn.github.io/learning-area/javascript/oojs/introduction/oojs-class-further-exercises.html">oojs-class-further-exercises.html</a> e faça uma cópia local do <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/introduction/oojs-class-further-exercises.html">código-fonte</a>. Abaixo do JavaScript existente, adicione o seguinte código, que adiciona um novo método à propriedade <code>prototype</code> do construtor: + + <pre class="brush: js">Person.prototype.farewell = function() { + alert(this.name.first + ' has left the building. Bye for now!'); +};</pre> + </li> + <li>Salve o código e carregue a página no navegador e tente inserir o seguinte na entrada de texto: + <pre class="brush: js">person1.farewell();</pre> + </li> +</ol> + +<p>Você deve receber uma mensagem de alerta, mostrando o nome da pessoa, conforme definido dentro do construtor. Isso é realmente útil, mas o que é ainda mais útil é que toda a cadeia de herança foi atualizada dinamicamente, disponibilizando automaticamente esse novo método em todas as instâncias de objeto derivadas do construtor.</p> + +<p>Pense nisso por um momento. Em nosso código, definimos o construtor, então criamos um objeto de instância a partir do construtor, então adicionamos um novo método ao protótipo do construtor:</p> + +<pre class="brush: js">function Person(first, last, age, gender, interests) { + + // property and method definitions + +} + +var person1 = new Person('Tammi', 'Smith', 32, 'neutral', ['music', 'skiing', 'kickboxing']); + +Person.prototype.farewell = function() { + alert(this.name.first + ' has left the building. Bye for now!'); +};</pre> + +<p>Mas o método <code>farewell()</code> ainda está disponível na instância do objeto <code>person1</code> — seus membros foram atualizados automaticamente para incluir o método <code>farewell()</code>.</p> + +<div class="note"> +<p><strong>Note</strong>: Se você está tendo problemas para fazer este exemplo funcionar, dê uma olhada no nosso exemplo <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/advanced/oojs-class-prototype.html">oojs-class-prototype.html</a> (veja também <a href="http://mdn.github.io/learning-area/javascript/oojs/advanced/oojs-class-prototype.html">running live</a>).</p> +</div> + +<p>Você raramente verá propriedades definidas na propriedade <code>prototype</code>, porque elas não são muito flexíveis quando definidas dessa forma. Por exemplo, você poderia adicionar uma propriedade assim:</p> + +<pre class="brush: js">Person.prototype.fullName = 'Bob Smith';</pre> + +<p>sso não é muito flexível, pois a pessoa pode não ser chamada assim. Seria muito melhor construir o <code>fullName</code> fora do <code>name.first</code> e <code>name.last</code>:</p> + +<pre class="brush: js">Person.prototype.fullName = this.name.first + ' ' + this.name.last;</pre> + +<p>No entanto, isso não funciona, pois <code>this</code> fará referência ao escopo global nesse caso, não ao escopo da função. Chamar essa propriedade retornaria <code>undefined undefined</code>. Isso funcionou bem no método que definimos anteriormente no protótipo porque ele está dentro um escopo de função, que será transferido com sucesso para o escopo da instância do objeto, portanto, você pode definir propriedades constantes no protótipo (ou seja, aquelas que nunca precisam ser alteradas), mas geralmente funciona melhor definir propriedades dentro do construtor.</p> + +<p>Na verdade, um padrão bastante comum para mais definições de objetos é definir as propriedades dentro do construtor e os métodos no protótipo. Isso torna o código mais fácil de ler, pois o construtor contém apenas as definições de propriedade e os métodos são divididos em blocos separados. Por exemplo:</p> + +<pre class="brush: js">// Constructor with property definitions + +function Test(a, b, c, d) { + // property definitions +} + +// First method definition + +Test.prototype.x = function() { ... }; + +// Second method definition + +Test.prototype.y = function() { ... }; + +// etc.</pre> + +<p>Esse padrão pode ser visto em ação no exemplo de <a href="https://github.com/zalun/school-plan-app/blob/master/stage9/js/index.js">aplicativo de plano escolar</a> de Piotr Zalewa.</p> + +<h2 id="Sumário">Sumário</h2> + +<p>Este artigo abrangeu protótipos de objetos JavaScript, incluindo como cadeias de objetos de protótipos permitem que objetos herdem recursos uns dos outros, a propriedade prototype e como ela pode ser usada para adicionar métodos a construtores e outros tópicos relacionados.</p> + +<p>No próximo artigo, veremos como você pode implementar a herança de funcionalidade entre dois dos seus próprios objetos personalizados.</p> + +<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object-oriented_JS", "Learn/JavaScript/Objects/Inheritance", "Learn/JavaScript/Objects")}}</p> + + + +<h2 id="Neste_módulo">Neste módulo</h2> + +<ul> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li> + <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li> +</ul> |