From 074785cea106179cb3305637055ab0a009ca74f2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:52 -0500 Subject: initial commit --- .../javascript/asynchronous/conceitos/index.html | 155 +++++ .../escolhendo_abordagem_correta/index.html | 523 ++++++++++++++++ .../pt-br/learn/javascript/asynchronous/index.html | 67 ++ .../introdu\303\247\303\243o/index.html" | 283 +++++++++ .../javascript/asynchronous/promises/index.html | 586 ++++++++++++++++++ .../asynchronous/timeouts_and_intervals/index.html | 624 +++++++++++++++++++ .../first_steps/a_first_splash/index.html | 683 +++++++++++++++++++++ .../learn/javascript/first_steps/arrays/index.html | 662 ++++++++++++++++++++ .../gerador_de_historias_bobas/index.html | 123 ++++ .../pt-br/learn/javascript/first_steps/index.html | 73 +++ .../javascript/first_steps/matematica/index.html | 418 +++++++++++++ .../first_steps/o_que_e_javascript/index.html | 435 +++++++++++++ .../javascript/first_steps/strings/index.html | 284 +++++++++ .../index.html | 85 +++ .../first_steps/useful_string_methods/index.html | 484 +++++++++++++++ .../first_steps/vari\303\241veis/index.html" | 332 ++++++++++ .../first_steps/what_went_wrong/index.html | 245 ++++++++ 17 files changed, 6062 insertions(+) create mode 100644 files/pt-br/learn/javascript/asynchronous/conceitos/index.html create mode 100644 files/pt-br/learn/javascript/asynchronous/escolhendo_abordagem_correta/index.html create mode 100644 files/pt-br/learn/javascript/asynchronous/index.html create mode 100644 "files/pt-br/learn/javascript/asynchronous/introdu\303\247\303\243o/index.html" create mode 100644 files/pt-br/learn/javascript/asynchronous/promises/index.html create mode 100644 files/pt-br/learn/javascript/asynchronous/timeouts_and_intervals/index.html create mode 100644 files/pt-br/learn/javascript/first_steps/a_first_splash/index.html create mode 100644 files/pt-br/learn/javascript/first_steps/arrays/index.html create mode 100644 files/pt-br/learn/javascript/first_steps/gerador_de_historias_bobas/index.html create mode 100644 files/pt-br/learn/javascript/first_steps/index.html create mode 100644 files/pt-br/learn/javascript/first_steps/matematica/index.html create mode 100644 files/pt-br/learn/javascript/first_steps/o_que_e_javascript/index.html create mode 100644 files/pt-br/learn/javascript/first_steps/strings/index.html create mode 100644 files/pt-br/learn/javascript/first_steps/teste_suas_habilidades_colon__variaveis/index.html create mode 100644 files/pt-br/learn/javascript/first_steps/useful_string_methods/index.html create mode 100644 "files/pt-br/learn/javascript/first_steps/vari\303\241veis/index.html" create mode 100644 files/pt-br/learn/javascript/first_steps/what_went_wrong/index.html (limited to 'files/pt-br/learn/javascript') diff --git a/files/pt-br/learn/javascript/asynchronous/conceitos/index.html b/files/pt-br/learn/javascript/asynchronous/conceitos/index.html new file mode 100644 index 0000000000..f2e6759f41 --- /dev/null +++ b/files/pt-br/learn/javascript/asynchronous/conceitos/index.html @@ -0,0 +1,155 @@ +--- +title: Conceitos gerais da programação assíncrona +slug: Learn/JavaScript/Asynchronous/Conceitos +translation_of: Learn/JavaScript/Asynchronous/Concepts +--- +
{{LearnSidebar}}{{NextMenu("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous")}}
+ +

Neste artigo, nós vamos ver um número de conceitos importantes relativos à programação assíncrona e como ela se parece em navegadores modernos e em JavaScript. Você deve entender estes conceitos antes de trabalhar com outros artigos neste módulo.

+ + + + + + + + + + + + +
Pré-requisitos:Conhecimentos básicos de informática e compreensão dos fundamentos de JavaScript.
Objetivo:Entender os conceitos básicos da programação assíncrona e como ela se manifesta em navegadores e JavaScript.
+ +

Assíncrono?

+ +

Normalmente, o código de um programa é executado de forma direta, com uma coisa acontecendo por vez. Se uma função depende do resultado de outra função, ela tem que esperar o retorno do resultado, e até que isso aconteça, o programa inteiro praticamente para de funcionar da perspectiva do usuário.

+ +

Usuários do Mac, por exemplo, conseguem ver isso como o cursor giratório em arco-íris (ou "beachball", como normalmente é chamado). Este cursor é o jeito do sistema operacional dizer: "o programa atual que você está usando teve que parar e esperar algo terminar de ser executado, e estava demorando tanto que fiquei preocupado se você estava pensando no que aconteceu."

+ +

Multi-colored macOS beachball busy spinner

+ +

Essa é uma situação frustrante, e não faz bom uso do poder de processamento do computador — especialmente em uma era em que computadores tem múltiplos núcleos de processamento disponíveis. Não há sentido em ficar esperando por algo quando você pode deixar outra tarefa ser executada em um núcleo de processador diferente e deixar que ele te avise quando terminar. Isso te permite fazer mais coisas por enquanto, o que é a base da programação assincrona. Depende do ambiente de programação que você está usando (navegadores da Web, no caso de desenvolvimento da Web) para fornecer APIs que permitem executar essas tarefas de forma assíncrona.

+ +

Bloqueio de código

+ +

Técnicas async (assíncronas) são muito úteis, principalmente na programação web. Quando um aplicativo web é executado em um navegador e executa um pedaço de código rigoroso sem retornar o controle para o navegador, ele pode parecer que travou. Isso é chamado de blocking; o navegador está bloqueado de continuar a manusear a entrada do usuário e de realizar outras tarefas até que o aplicativo web retorne o controle do processador.

+ +

Vamos dar uma olhadinha em alguns exemplos para que você entenda o blocking.

+ +

No nosso exemplo simple-sync.html (veja aqui), nós adicionamos um evento de click em um botão para que, quando clicado, ele executa uma tarefa pesada (calcula 10 milhões de datas e depois imprime a última delas no console) e depois adiciona um parágrafo no DOM:

+ +
const btn = document.querySelector('button');
+btn.addEventListener('click', () => {
+  let myDate;
+  for(let i = 0; i < 10000000; i++) {
+    let date = new Date();
+    myDate = date
+  }
+
+  console.log(myDate);
+
+  let pElem = document.createElement('p');
+  pElem.textContent = 'This is a newly-added paragraph.';
+  document.body.appendChild(pElem);
+});
+ +

Quando o exemplo for executado, abra seu console JavaScript e depois clique no botão  — você verá qua o parágrafo não aparece até que o programa termine de calcular as datas e imprimir a última no console. O código é executado na ordem em que ele aparece na fonte, e a operação seguinte só é executada depois que a primeira for terminada.

+ +
+

Nota: O exemplo anterior não é muito realistico. Você nunca calcularia 10 milhões de datas em um aplicativo real! Mas isso serve par te dar um apoio sobre o assunto.

+
+ +

No nosso segundo exemplo simple-sync-ui-blocking.html (veja aqui), nós simulamos algo mais realistico que você pode encontrar em uma página real. Nós bloqueamos a interatividade do usuário na renderização da UI. Neste exemplo, nós temos dois botões:

+ + + +
function expensiveOperation() {
+  for(let i = 0; i < 1000000; i++) {
+    ctx.fillStyle = 'rgba(0,0,255, 0.2)';
+    ctx.beginPath();
+    ctx.arc(random(0, canvas.width), random(0, canvas.height), 10, degToRad(0), degToRad(360), false);
+    ctx.fill()
+  }
+}
+
+fillBtn.addEventListener('click', expensiveOperation);
+
+alertBtn.addEventListener('click', () =>
+  alert('You clicked me!')
+);
+ +

Se você clicar no primeiro botão e imediatamente no segundo, você verá que a mensagem de alerta não aparece até que os círculos sejam totalmente renderizados. A primeira operação bloqueia a segunda até a sua finalização.

+ +
+

Nota: OK, no nosso caso, isso é ruim e estamos bloqueando o código de propósito, mas isso é um problema comum que desenvolvedores de aplicativos reais sempre tentam resolver.

+
+ +

E por quê isso acontece? A resposta é que o JavaScript é single threaded. E é neste ponto que precisamos introduzir a você o conceito de threads.

+ +

Threads

+ +

Uma thread é basicamente um único processo que um programa pode usar para concluir tarefas. Cada thread só pode fazer uma tarefa de cada vez:

+ +
Tarefa A --> Tarefa B --> Tarefa C
+ +

Cada tarefa será executada sequencialmente; uma tarefa tem que ser concluída antes que a próxima possa ser iniciada.

+ +

Como foi dito anteriormente, muitos computadores possuem múltiplos núcleos, para que possam fazer múltiplas coisas de uma vez só. Linguagens de programação que podem suportar múltiplas threads podem usar múltiplos processadores para concluir múltiplas tarefas simultâneamente:

+ +
Thread 1: Tarefa A --> Tarefa B
+Thread 2: Tarefa C --> Tarefa D
+ +

JavaScript é single threaded

+ +

JavaScript é tradicionalmente single-threaded. Mesmo com múltiplos núcleos de processamento, você só pode fazê-lo executar tarefas em uma única thread, chamada de main thread (thread principal). Nosso exemplo de cima é executado assim:

+ +
Main thread: Renderizar circulos no canvas --> Mostrar alert()
+ +

Depois de um tempo, o JavaScript ganhou algumas ferramentas para ajudar em tais problemas. As Web workers te permitem mandar parte do processamento do JavaScript para uma thread separada. Você geralmente usaria uma worker para executar um processo pesado para que a UI não seja bloqueada.

+ +
  Main thread: Tarefa A --> Tarefa C
+Worker thread: Tarefa pesada B
+ +

Com isso em mente, dê uma olhada em simple-sync-worker.html (veja aqui), com o seu console JavaScript aberto. Isso é uma nova versão do nosso exemplo que calcula 10 milhões de datas em uma tread worker separada. Agora, quando você clica no botão, o navegador é capaz de mostrar o parágrafo antes que as datas sejam terminadas. A primeira opreção não bloqueia a segunda.

+ +

Código assíncrono

+ +

Web workers podem ser bem úteis, mas elas tem as suas limitações. Uma delas é que elas não são capazes de acessar a {{Glossary("DOM")}} — você não pode fazer com que uma worker faça algo diretamente para atualizar a UI. Nós não poderíamos renderizar nossos 1 milhão de círculos azuis na nossa worker; basicamente ela pode apenas fazer cálculos de números.

+ +

O segundo problema é que, mesmo que o código executado em uma worker não cause um bloqueio, ele ainda é um código síncrono. Isso se torna um problema quando uma função depende dos resultados de processos anteriores para funcionar. Considere os diagramas a seguir:

+ +
Main thread: Tarefa A --> Tarefa B
+ +

Nesse caso, digamos que a tarefa A está fazendo algo como pegar uma imagem do servidor e que a tarefa B faz algo com essa imagem, como colocar um filtro nela. Se você iniciar a tarefa A e depois tentar executar a tarefa B imediatamente, você obterá um erro, porque a imagem não estará disponível ainda.

+ +
  Main thread: Tarefa A --> Tarefa B --> |Tarefa D|
+Worker thread: Tarefa C ---------------> |      |
+ +

Neste caso, digamos que a tarefa D faz uso dos resultados das tarefas B e C. Se nós pudermos garantir que esses resultados estejam disponíveis ao mesmo tempo, então tudo talvez esteja bem, mas isso não é garantido. Se a tarefa D tentar ser executada quando um dos resultados não estiver disponível, ela retornará um erro.

+ +

Para consertarmos tais problemas, os browsers nos permitem executar certas operações de modo assíncrono. Recursos como Promises te permitem executar uma operação e depois esperar pelo resultado antes de executar outra operação: 

+ +
Main thread: Tarefa A                   Tarefa B
+    Promise:       |___operação async___|
+ +

Já que a operação está acontecendo em outro lugar, a main thread não está bloqueada enquanto a operação assíncrona está sendo processada.

+ +

Nós vamos começar a olhar em como podemos escrever código assíncrono no próximo artigo.

+ +

Conclusão

+ +

O design moderno de software gira em torno do uso de programação assíncrona, para permitir que os programas façam mais de uma coisa por vez. Ao usar APIs mais novas e mais poderosas, você encontrará mais casos em que a única maneira de fazer as coisas é assincronamente. Costumava ser difícil escrever código assíncrono. Ainda é preciso se acostumar, mas ficou muito mais fácil. No restante deste módulo, exploraremos ainda mais por que o código assíncrono é importante e como projetar o código que evita alguns dos problemas descritos acima.

+ +

Nesse módulo

+ + diff --git a/files/pt-br/learn/javascript/asynchronous/escolhendo_abordagem_correta/index.html b/files/pt-br/learn/javascript/asynchronous/escolhendo_abordagem_correta/index.html new file mode 100644 index 0000000000..254bc41a99 --- /dev/null +++ b/files/pt-br/learn/javascript/asynchronous/escolhendo_abordagem_correta/index.html @@ -0,0 +1,523 @@ +--- +title: Escolhendo a abordagem correta +slug: Learn/JavaScript/Asynchronous/Escolhendo_abordagem_correta +translation_of: Learn/JavaScript/Asynchronous/Choosing_the_right_approach +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}
+ +

To finish this module off, we'll provide a brief discussion of the different coding techniques and features we've discussed throughout, looking at which one you should use when, with recommendations and reminders of common pitfalls where appropriate. We'll probably add to this resource as time goes on.

+ + + + + + + + + + + + +
Prerequisites:Basic computer literacy, a reasonable understanding of JavaScript fundamentals.
Objective:To be able to make a sound choice of when to use different asynchronous programming techniques.
+ +

Asynchronous callbacks

+ +

Generally found in old-style APIs, involves a function being passed into another function as a parameter, which is then invoked when an asynchronous operation has been completed, so that the callback can in turn do something with the result. This is the precursor to promises; it's not as efficient or flexible. Use only when necessary.

+ + + + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoYes (recursive callbacks)Yes (nested callbacks)No
+ +

Code example

+ +

An example that loads a resource via the XMLHttpRequest API (run it live, and see the source):

+ +
function loadAsset(url, type, callback) {
+  let xhr = new XMLHttpRequest();
+  xhr.open('GET', url);
+  xhr.responseType = type;
+
+  xhr.onload = function() {
+    callback(xhr.response);
+  };
+
+  xhr.send();
+}
+
+function displayImage(blob) {
+  let objectURL = URL.createObjectURL(blob);
+
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+}
+
+loadAsset('coffee.jpg', 'blob', displayImage);
+ +

Pitfalls

+ + + +

Browser compatibility

+ +

Really good general support, although the exact support for callbacks in APIs depends on the particular API. Refer to the reference documentation for the API you're using for more specific support info.

+ +

Further information

+ + + +

setTimeout()

+ +

setTimeout() is a method that allows you to run a function after an arbitrary amount of time has passed.

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
YesYes (recursive timeouts)Yes (nested timeouts)No
+ +

Code example

+ +

Here the browser will wait two seconds before executing the anonymous function, then will display the alert message (see it running live, and see the source code):

+ +
let myGreeting = setTimeout(function() {
+  alert('Hello, Mr. Universe!');
+}, 2000)
+ +

Pitfalls

+ +

You can use recursive setTimeout() calls to run a function repeatedly in a similar fashion to setInterval(), using code like this:

+ +
let i = 1;
+setTimeout(function run() {
+  console.log(i);
+  i++;
+
+  setTimeout(run, 100);
+}, 100);
+ +

There is a difference between recursive setTimeout() and setInterval():

+ + + +

When your code has the potential to take longer to run than the time interval you’ve assigned, it’s better to use recursive setTimeout() — this will keep the time interval constant between executions regardless of how long the code takes to execute, and you won't get errors.

+ +

Browser compatibility

+ +

{{Compat("api.WindowOrWorkerGlobalScope.setTimeout")}}

+ +

Further information

+ + + +

setInterval()

+ +

setInterval() is a method that allows you to run a function repeatedly with a set interval of time between each execution. Not as efficient as requestAnimationFrame(), but allows you to choose a running rate/frame rate.

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoYesNo (unless it is the same one)No
+ +

Code example

+ +

The following function creates a new Date() object, extracts a time string out of it using toLocaleTimeString(), and then displays it in the UI. We then run it once per second using setInterval(), creating the effect of a digital clock that updates once per second (see this live, and also see the source):

+ +
function displayTime() {
+   let date = new Date();
+   let time = date.toLocaleTimeString();
+   document.getElementById('demo').textContent = time;
+}
+
+const createClock = setInterval(displayTime, 1000);
+ +

Pitfalls

+ + + +

Browser compatibility

+ +

{{Compat("api.WindowOrWorkerGlobalScope.setInterval")}}

+ +

Further information

+ + + +

requestAnimationFrame()

+ +

requestAnimationFrame() is a method that allows you to run a function repeatedly, and efficiently, at the best framerate available given the current browser/system. You should, if at all possible, use this instead of setInterval()/recursive setTimeout(), unless you need a specific framerate.

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoYesNo (unless it is the same one)No
+ +

Code example

+ +

A simple animated spinner; you can find this example live on GitHub (see the source code also):

+ +
const spinner = document.querySelector('div');
+let rotateCount = 0;
+let startTime = null;
+let rAF;
+
+function draw(timestamp) {
+    if(!startTime) {
+        startTime = timestamp;
+    }
+
+    rotateCount = (timestamp - startTime) / 3;
+
+    if(rotateCount > 359) {
+        rotateCount %= 360;
+    }
+
+    spinner.style.transform = 'rotate(' + rotateCount + 'deg)';
+
+    rAF = requestAnimationFrame(draw);
+}
+
+draw();
+ +

Pitfalls

+ + + +

Browser compatibility

+ +

{{Compat("api.Window.requestAnimationFrame")}}

+ +

Further information

+ + + +

Promises

+ +

Promises are a JavaScript feature that allows you to run asynchronous operations and wait until it is definitely complete before running another operation based on its result. Promises are the backbone of modern asynchronous JavaScript.

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoNoYesSee Promise.all(), below
+ +

Code example

+ +

The following code fetches an image from the server and displays it inside an {{htmlelement("img")}} element; see it live also, and see also the source code:

+ +
fetch('coffee.jpg')
+.then(response => response.blob())
+.then(myBlob => {
+  let objectURL = URL.createObjectURL(myBlob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+})
+.catch(e => {
+  console.log('There has been a problem with your fetch operation: ' + e.message);
+});
+ +

Pitfalls

+ +

Promise chains can be complex and hard to parse. If you nest a number of promises, you can end up with similar troubles to callback hell. For example:

+ +
remotedb.allDocs({
+  include_docs: true,
+  attachments: true
+}).then(function (result) {
+  let docs = result.rows;
+  docs.forEach(function(element) {
+    localdb.put(element.doc).then(function(response) {
+      alert("Pulled doc with id " + element.doc._id + " and added to local db.");
+    }).catch(function (err) {
+      if (err.name == 'conflict') {
+        localdb.get(element.doc._id).then(function (resp) {
+          localdb.remove(resp._id, resp._rev).then(function (resp) {
+// et cetera...
+ +

It is better to use the chaining power of promises to go with a flatter, easier to parse structure:

+ +
remotedb.allDocs(...).then(function (resultOfAllDocs) {
+  return localdb.put(...);
+}).then(function (resultOfPut) {
+  return localdb.get(...);
+}).then(function (resultOfGet) {
+  return localdb.put(...);
+}).catch(function (err) {
+  console.log(err);
+});
+ +

or even:

+ +
remotedb.allDocs(...)
+.then(resultOfAllDocs => {
+  return localdb.put(...);
+})
+.then(resultOfPut => {
+  return localdb.get(...);
+})
+.then(resultOfGet => {
+  return localdb.put(...);
+})
+.catch(err => console.log(err));
+ +

That covers a lot of the basics. For a much more complete treatment, see the excellent We have a problem with promises, by Nolan Lawson.

+ +

Browser compatibility

+ +

{{Compat("javascript.builtins.Promise")}}

+ +

Further information

+ + + +

Promise.all()

+ +

A JavaScript feature that allows you to wait for multiple promises to complete before then running a further operation based on the results of all the other promises.

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoNoNoYes
+ +

Code example

+ +

The following example fetches several resources from the server, and uses Promise.all() to wait for all of them to be available before then displaying all of them — see it live, and see the source code:

+ +
function fetchAndDecode(url, type) {
+  // Returning the top level promise, so the result of the entire chain is returned out of the function
+  return fetch(url).then(response => {
+    // Depending on what type of file is being fetched, use the relevant function to decode its contents
+    if(type === 'blob') {
+      return response.blob();
+    } else if(type === 'text') {
+      return response.text();
+    }
+  })
+  .catch(e => {
+    console.log(`There has been a problem with your fetch operation for resource "${url}": ` + e.message);
+  });
+}
+
+// Call the fetchAndDecode() method to fetch the images and the text, and store their promises in variables
+let coffee = fetchAndDecode('coffee.jpg', 'blob');
+let tea = fetchAndDecode('tea.jpg', 'blob');
+let description = fetchAndDecode('description.txt', 'text');
+
+// Use Promise.all() to run code only when all three function calls have resolved
+Promise.all([coffee, tea, description]).then(values => {
+  console.log(values);
+  // Store each value returned from the promises in separate variables; create object URLs from the blobs
+  let objectURL1 = URL.createObjectURL(values[0]);
+  let objectURL2 = URL.createObjectURL(values[1]);
+  let descText = values[2];
+
+  // Display the images in <img> elements
+  let image1 = document.createElement('img');
+  let image2 = document.createElement('img');
+  image1.src = objectURL1;
+  image2.src = objectURL2;
+  document.body.appendChild(image1);
+  document.body.appendChild(image2);
+
+  // Display the text in a paragraph
+  let para = document.createElement('p');
+  para.textContent = descText;
+  document.body.appendChild(para);
+});
+ +

Pitfalls

+ + + +

Browser compatibility

+ +

{{Compat("javascript.builtins.Promise.all")}}

+ +

Further information

+ + + +

Async/await

+ +

Syntactic sugar built on top of promises that allows you to run asynchronous operations using syntax that's more like writing synchronous callback code.

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoNoYesYes (in combination with Promise.all())
+ +

Code example

+ +

The following example is a refactor of the simple promise example we saw earlier that fetches and displays an image, written using async/await (see it live, and see the source code):

+ +
async function myFetch() {
+  let response = await fetch('coffee.jpg');
+  let myBlob = await response.blob();
+
+  let objectURL = URL.createObjectURL(myBlob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+}
+
+myFetch();
+ +

Pitfalls

+ + + +

Browser compatibility

+ +

{{Compat("javascript.statements.async_function")}}

+ +

Further information

+ + + +

{{PreviousMenu("Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}

+ +

In this module

+ + diff --git a/files/pt-br/learn/javascript/asynchronous/index.html b/files/pt-br/learn/javascript/asynchronous/index.html new file mode 100644 index 0000000000..67c3f8e466 --- /dev/null +++ b/files/pt-br/learn/javascript/asynchronous/index.html @@ -0,0 +1,67 @@ +--- +title: JavaScript Assíncrono +slug: Learn/JavaScript/Asynchronous +tags: + - Beginner + - CodingScripting + - Guide + - Guía + - Iniciante + - JavaScript + - Landing + - NeedsTranslation + - Promises + - TopicStub + - async + - asynchronous + - await + - callbacks + - requestAnimationFrame + - setInterval + - setTimeout +translation_of: Learn/JavaScript/Asynchronous +--- +
{{LearnSidebar}}
+ + + +
Neste módulo vamos entender {{Glossary("JavaScript")}} Assíncrono, porque isso é importante e como pode ser usado para lidar com operações potencialmente bloqueantes, como a busca de recursos em um servidor remoto.
+ +

Pre requisitos

+ +

Javascript Assíncrono é um tópico razoavelmente avançado e é aconselhada a leitura dos módulos Primeiros Passos com Javascript e Elementos construtivos do Javascript antes de continuar.

+ +

Se você não estiver familiarizado com os conceitos de programação assíncrona, a sugestão é iniciar com o artigo Conceitos gerais da programação assíncrona desse módulo. Caso contrário, você pode provavelmente pular para o módulo Introdução ao Javascript Assíncrono.

+ +
+

Note: Se você está estudando a partir de um computador/tablet/ outro dispositivo onde não é capaz de criar seus próprios arquivos, é possível executar os códigos de exemplo (a maioria deles) em plataformas como JSBin ou  Thimble.

+
+ +

Guias

+ +
+
Conceitos gerais da programação assíncrona
+
+

Nesse artigo vamos explorar um número de conceitos importantes relacionados à programação assíncrona e como aparece nos browsers Web. Você deve entender estes conceitos antes de seguir adiante através dos outros artigos neste módulo.

+
+
Introdução ao Javascript Assíncrono
+
Nesse artigo vamos recapitular brevemente os problemas associados ao Javascript síncrono e introduzir algumas das diferentes técnicas do Javascript assícrono que irá encontrar mais a frente, mostrando como essas técnicas podem nos ajudar a resolver tais problemas.
+
Javascript assícrono cooperativo: Timeouts e intervalos
+
Aqui contemplamos os métodos tradicionais que o Javascript possui disponível para executar código de forma assíncrona após decorrido um certo periodo de tempo ou em um intervalo regular (e.g. um determinado número de vezes por segundo), discutir sua utilidade e perceber alguns problemas inerentes a eles.
+
Manipulando elegantemente operações assíncronas com Promises
+
Promises são um novo recurso da linguagem Javascript que permitem adiar ações até que a ação anterior esteja concluída ou responder com falha. Isso é extremamente útil para montar uma sequência de operações para que funcione corretamente. Este artigo lhe orienta como as Promises funcionam, onde verá elas sendo utilizadas em WebAPIs. Também aprenderá como escrever suas próprias promises.
+
Facilitando a programação assícrona com async e await
+
Promises podem ser um pouco complexas de construir e entender. Por esse motivo, os navegadores modernos implementado funções async e o operador await. O primeiro permite que funções padrão se comportem implicitamente de forma assíncrona com promises, enquanto que o último pode ser usado dentro de funções async para esperar por 'promessas' antes que a função continue. Isso faz com que o encadeamento de 'promessas' seja mais fácil de ler.
+
Escolhendo a abordagem correta
+
Para concluir este módulo, vamos considerar as diferentes técnicas de programação e as features que abordamos do começo ao fim, considerando quais e quando utilizar, com recomendações e advertências das armadilhas mais comuns.
+
+ +

Veja Também

+ + + +
+

Nota do tradutor: A segunda edição do Eloquent Javascript foi traduzida pela comunidade brasileira do Javascript e está disponível em Javascript Eloquente - 2ª Edição. Até o momento da tradução deste artigo, a comunidade está trabalhando na conclusão da 3ª edição.

+
diff --git "a/files/pt-br/learn/javascript/asynchronous/introdu\303\247\303\243o/index.html" "b/files/pt-br/learn/javascript/asynchronous/introdu\303\247\303\243o/index.html" new file mode 100644 index 0000000000..b95a88d35c --- /dev/null +++ "b/files/pt-br/learn/javascript/asynchronous/introdu\303\247\303\243o/index.html" @@ -0,0 +1,283 @@ +--- +title: Introdução ao JavaScript Async +slug: Learn/JavaScript/Asynchronous/Introdução +translation_of: Learn/JavaScript/Asynchronous/Introducing +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Concepts", "Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous")}}
+ +
Neste artigo nós recapitulamos brevemente os problemas que são associados com o JavaScript síncrono, e dar  uma primeira olhada em algumas das diferentes técnicas assíncronas que você vai encontrar, mostrando como elas podem nos ajudar a resolver tais problemas.
+ +
+ + + + + + + + + + + + +
Pré-requisitos:Conhecimentos básicos de informática e sobre os fundamentos do JavaScript.
Objetivo:Ganhar familiaridade com o que é o Js assíncrono e como ele se difere do Js síncrono.
+ +

JavaScript síncrono

+ +

Para entendermos o que é o {{Glossary("asynchronous")}} JavaScript, nós primeiro temos que ter certeza que entedemos o que é o {{Glossary("synchronous")}} JavaScript. Essa seção revê um pouco das informações que nós vimos no artigo anterior.

+ +

Muitas das funcionalidades que nós vimos em áreas anteriores são síncronas — você executa um código, e o reultado é retornado assim que o navegador puder. Vamos ver um exemplo simples (veja aqui, e veja o código fonte):

+ +
const btn = document.querySelector('button');
+btn.addEventListener('click', () => {
+  alert('Você clicou em mim!');
+
+  let pElem = document.createElement('p');
+  pElem.textContent = 'Este é um novo parágrafo adicionado';
+  document.body.appendChild(pElem);
+});
+
+ +

Neste bloco, as linhas são executadas uma após a outra:

+ +
    +
  1. Nós damos referência à um elemento {{htmlelement("button")}} que já está disponível na DOM.
  2. +
  3. Nós adicionamos um evento de click, e quando ele for clicado ele fará o seguinte: +
      +
    1. Mostrar uma mensagem no alert().
    2. +
    3. Uma vez que o alert for dispensado, nós criamos um elemento {{htmlelement("p")}}.
    4. +
    5. Depois nós o preenchemos com um texto.
    6. +
    7. E finalmente, o adicionamos no body.
    8. +
    +
  4. +
+ +

Enquanro cada operação é processada, nada mais pode acontecer — a renderização é pausada. Isso acontece porque o JavaScript opera em uma única thread (JavaScript é single threaded). Apenas uma coisa pode acontecer por vez, em uma única thread principal, e tudo é bloqueado até que a operação seja concluída.

+ +

Então, no exemplo acima, depois que você tenha clicado no botão, o parágrafo não vai aparecer até que o botão OK do alert seja pressionado. Tente isso com o botão a seguir:

+ + + +

{{EmbedLiveSample('Synchronous_JavaScript', '100%', '70px')}}

+ +
+

Nota: É importante lembrar que, mesmo sendo muito útil para demonstar uma situação de blocking, o alert() não é de bom uso em aplicativos reais.

+
+ +

Asynchronous JavaScript

+ +

Por razões esclarecidas anteriormente (e.g. relativas ao blocking), muitas funcionalidades de APIs da Web agora usam código assíncrono na execução, especialmente aquelas que acessam ou buscam algum tipo de recurso de um dispositivo externo, como pegar um arquivo da rede, acessar um banco de dados e retornar dados dele, acessar uma stream de uma web cam, ou transmitir uma tela para um dispositivo VR.

+ +

Por que é tão difícil trabalhar com isso usando códigos síncronos? Vamos dar uma olhada em um exemplo rápido. Quando você pega uma imagem de um servidor, você não pode retornar o resultado imediatamente. Isso significa que o pseudocódigo a seguir não poderia funcionar:

+ +
let resposta = fetch('myImage.png');
+let blob = resposta.blob();
+// Mostra sua imagem na UI
+ +

Isso acontece por que você não sabe quanto tempo a imagem levará para ser baixada, então quando você executar a segunda linha, ela vai resultar em um erro (provalvelmente sempre) porque a  resposta não estará disponível ainda. Você precisa que o seu código espere até que a resposta seja retornada antes de fazer algo com ela.

+ +

Existem dois tipos principais de estilo de código assíncrono que você encontrará no código JavaScript, as callbacks com um estilo old-school e código em um estilo das promises mais recente. Nas seções abaixo, revisaremos cada um deles por vez.

+ +

Callbacks assíncronas

+ +

Callback são funções que são passada como parâmetros na chamada de outra função que vai executar código por trás do panos. Quando esse código por trás dos panos terminar de ser executado, a função callback será chamada para te informar que a tarefa foi finalizada ou que algo do seu interesse aconteceu. O uso das callbacks é um pouco antiquado agora, mas você ainda pode vê-las em um número de APIs comumente usadas.

+ +

Um exemplo de uma callback async é o segundo parâmetro do método {{domxref("EventTarget.addEventListener", "addEventListener()")}} (como vimos em ação anteriormente):

+ +
btn.addEventListener('click', () => {
+  alert('Você clicou em mim!');
+
+  let pElem = document.createElement('p');
+  pElem.textContent = 'Este é um novo parágrafo.';
+  document.body.appendChild(pElem);
+});
+ +

O primeiro parâmetro é o tipo de evento a ser executado e o segundo parâmetro é uma função callback que é chamada quando o evento é disparado.

+ +

Quando passamos uma função callback como um parâmetro em outra função, nós apenas estamos passando a rêferencia da função como argumento, ou seja, a função callback não é executada imediatamente. Ela é chamada de volta assíncronamente dentro do corpo da função que a contém, que é responsável por executar a função callback quando for necessário.

+ +

Você pode escrever a sua própria função que contém uma callback facilmente. Vamos dar uma olhada em outro exemplo que carrega uma arquivo usando a API XMLHttpRequest (veja aqui, and veja o código fonte):

+ +
function loadAsset(url, type, callback) {
+  let xhr = new XMLHttpRequest();
+  xhr.open('GET', url);
+  xhr.responseType = type;
+
+  xhr.onload = function() {
+    callback(xhr.response);
+  };
+
+  xhr.send();
+}
+
+function displayImage(blob) {
+  let objectURL = URL.createObjectURL(blob);
+
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+}
+
+loadAsset('coffee.jpg', 'blob', displayImage);
+ +

Aqui nós criamos uma função displayImage() que simplesmente representa um blob que foi passada à ela como uma URL de objeto, e depois cria uma imagem para mostrar a URL, adicionando-a ao <body> do documento. Entretando, nós criamos depois uma função loadAsset() que pega uma callback como parâmetro, junto com uma URL a ser buscada e um tipo para o conteúdo. Ela usa o XMLHttpRequest (abreviação: "XHR") para buscar o recurso na URL dada, para depois passar a resposta para a callback para fazer algo com isso. Neste caso a callback está esperando o XHR  terminar de baixar o recurso (usando o manipulador de eventos onload) antes de passá-lo para a callback.

+ +

Callback são versáteis — elas não apenas lhe permitem controlar a ordem em que as funções são executadas e quais dados são passados entre elas, elas também podem passar dados para diferentes funçoes dependendo das circunstâncias. Então você pode ter ações diferentes para executar na resposta baixada, como processJSON(), displayText(), etc.

+ +

Note que nem todas as callback são assíncronas — algumas são executadas de um modo síncrono. Um exemplo é quando nós usamos o método {{jsxref("Array.prototype.forEach()")}} para iterar sobre os itens de uma array (veja aqui, e a fonte):

+ +
const gods = ['Apollo', 'Artemis', 'Ares', 'Zeus'];
+
+gods.forEach(function (eachName, index){
+  console.log(index + '. ' + eachName);
+});
+ +

Neste exemplo nós iteramos sobra uma array de Deuses Gregos e imprimos o índice e seus valores no console. O parâmetro de forEach() é uma callback function, que por si só toma dois parâmetros: uma refêrencia ao nome da array e e os valores dos índices. Entretanto, ela não espera por algo para fazer a execução, pois isso acontece imediatamente

+ +

Promises

+ +

Promises são uma nova maneira de escrever código assíncrono que você verá em APIs Web modernas. Um bom exemplo disso é a API fetch(), que é basicamente uma versão mais moderna e eficiente de {{domxref("XMLHttpRequest")}}. Vamos dar uma olhada em um exemplo rápido, do nosso artigo de Pegando dados do servidor:

+ +
fetch('products.json').then(function(response) {
+  return response.json();
+}).then(function(json) {
+  products = json;
+  initialize();
+}).catch(function(err) {
+  console.log('Fetch problem: ' + err.message);
+});
+ +
+

Nota: Você pode encontrar a versão finalizada no GitHub (veja aqui, e também seja a execução).

+
+ +

Aqui nós vemos fetch() pegando um único parâmetro — a URL de um recurso que você quer pegar da rede — e retornando uma promise. A promise é um objeto que representa a conclusão ou falha da operação assíncrona. Ela represente um estado intermediário, por assim dizer. É praticamente o jetio do navegador de dizer "Eu prometo voltar para você com a resposta o mais rápido possível", daí o nome "promessa".

+ +

Você pode levar um tempo para se acostumar com esse conceito; Ele se parece um pouco com o {{interwiki("wikipedia", "Gato de Schrödinger")}} em ação. Nenhum dos possíveis resultados aconteceu ainda, então a operação fetch está esperando pelo resultado do navegador que vai completar a operação em algum ponto no futuro.

+ +

Nós temos três blocos de código encadeados ao fim do fetch():

+ + + +
+

Nota: Você vai aprender mais sobre promises mais tarde no módulo, então não se preocupe se você não entendeu muito bem.

+
+ +

A fila de eventos

+ +

Operações assíncronas como as promises são colocadas em uma fila de eventos, que é executada depois que a main thread terminar de ser processada. As operações serão completadas assim que for possível e depois retornam seus resultados para o ambiente JavaScript.

+ +

Promises versus callbacks

+ +

As promises tem algumas semelhanças com as callbacks. Elas são basicamente um objeto retornado em que você vincula funções callback, ao invés de passar as callbacks para uma função.

+ +

Entretanto, as promises são feitas especificamente para lidarmos com operações async, e ter muitas vantagens sobre as velhas callbacks:

+ + + +

A natureza do código assíncrono

+ +

Vamos explorar um exemplo que ilustra a natureza do código assíncrono, mostrando o que pode acontecer quando nós não estamos cientes da ordem de execução e dos problemas em tentar tratar código async como código síncrono. O exemplo a seguir é muito similar ao que vimos antes (veja aqui, e a fonte). Uma diferença e que nós icluimos um número de declarações {{domxref("console.log()")}} para ilustrar na ordem que você pensa que o código fosse executado.

+ +
console.log ('Starting');
+let image;
+
+fetch('coffee.jpg').then((response) => {
+  console.log('It worked :)')
+  return response.blob();
+}).then((myBlob) => {
+  let objectURL = URL.createObjectURL(myBlob);
+  image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+}).catch((error) => {
+  console.log('There has been a problem with your fetch operation: ' + error.message);
+});
+
+console.log ('All done!');
+ +

O navegador vai começar a executar o código, veja a primeira declaração console.log()(Starting) e a execute, e depois crie a variável image.

+ +

Depois a segunda linha vai começar a ser executada começando com o bloco fetch(), mas desde que fetch() é executado assíncronamente sem bloquear nada, a execução do código continua mesmo depois do código promise, alcançando a última declaração console.log()(All done!) e imprimindo a no console.

+ +

Uma vez que o bloco fetch() tenha terminado a sua execução e retornado seu resultado com os blocos .then(), nós finalmente veremos a segunda mensagem console.log() (It worked :)) appear. Então as mensagens aparecem nessa ordem:

+ + + +

Se isso te deixa confuso, então considere o exemplo a seguir:

+ +
console.log("registering click handler");
+
+button.addEventListener('click', () => {
+  console.log("get click");
+});
+
+console.log("all done");
+ +

Isso é bem similar no comportamento — a primeira e a terceira mensagens console.log() são mostradas imediatamente, mas a segunda está bloqueada até alguém clique no botão. O exemplo anterior funciona da mesma forma, exceto que no caso a segunda mensagem está bloqueada na promise pegando um recurso e depois o mostra na tela.

+ +

Em um exemplo mais superficial, esse tipo de configuração poderia causar um problema — você não pode incluir um bloco async que retorna um resultado, que depois depende de um código síncrono. Você não pode garantir que a função async vai retornar antes que o navegador processou o bloco síncrono.

+ +

Para ver isso em ação, tente fazer uma cópia local do nosso exemplo, e mudar o terceiro console.log() para o seguinte:

+ +
console.log ('Tudo Feito! ' + image.src + 'mostrada.');
+ +

Agora você deve ter um erro no seu console ao invés da terceira mensagem:

+ +
TypeError: image is undefined; can't access its "src" property
+ +

Isso acontece porque o navegador tenta executar o terceiro console.log() e o bloco fetch() não terminou de ser executado e não foi dado  um valor para a variável image.

+ +
+

Nota:Por razões de segurança, você não pode usar o fetch()  com arquivos do seu sistema local (ou executar operações localmente); para executar o exemplo acima você teria que rodá-lo em um servidor local.

+
+ +

Aprendizado ativo: faça tudo async!

+ +

Faça que o exemplo problemático de fetch() imprima três mensagens console.log() na tela na ordem desejada, você pode fazer a útima declaração console.log() assíncrona também. Isso pode ser feito colocando ela em outro bloco .then() encadeamo no final do segundo bloco, ou por simplesmente movê-lo para dentro do segundo bloco then().

+ +
+

Note: If you get stuck, you can find an answer here (see it running live also). You can also find a lot more information on promises in our Graceful asynchronous programming with Promises guide, later on in the module.

+
+ +

Conclusion

+ +

In its most basic form, JavaScript is a synchronous, blocking, single-threaded language, in which only one operation can be in progress at a time. But web browsers define functions and APIs that allow us to register functions that should not be executed synchronously, and should instead be invoked asynchronously when some kind of event occurs (the passage of time, the user's interaction with the mouse, or the arrival of data over the network, for example). This means that you can let your code do several things at the same time without stopping or blocking your main thread.

+ +

Whether we want to run code synchronously or asynchronously will depend on what we're trying to do.

+ +

There are times when we want things to load and happen right away. For example when applying some user-defined styles to a webpage you'll want the styles to be applied as soon as possible.

+ +

If we're running an operation that takes time however, like querying a database and using the results to populate templates, it is better to push this off the main thread and complete the task asynchronously. Over time, you'll learn when it makes more sense to choose an asynchronous technique over a synchronous one.

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Concepts", "Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous")}}

+ +

In this module

+ + diff --git a/files/pt-br/learn/javascript/asynchronous/promises/index.html b/files/pt-br/learn/javascript/asynchronous/promises/index.html new file mode 100644 index 0000000000..1fdd746d9d --- /dev/null +++ b/files/pt-br/learn/javascript/asynchronous/promises/index.html @@ -0,0 +1,586 @@ +--- +title: Programação elegante com Promises +slug: Learn/JavaScript/Asynchronous/Promises +translation_of: Learn/JavaScript/Asynchronous/Promises +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}
+ +

Promises são uma nova implementação do JavaScript que permite você adiar ações até que determinada ação finalize. Isso é realmente bastante útil para uma sequência de operações assíncronas trabalharem corretamente. Neste artigo irá mostrar para você como Promises trabalham, como elas são usadas em web APIs e como escrever a sua Promise.

+ + + + + + + + + + + + +
Prerequisitos:Conhecimentos básicos em informática, um básico entendimento do JavaScript e seus fundamentos.
Objetivo:Entender promises e como elas funcionam.
+ + + +

O que são promises?

+ +

Nós vimos apenas um resumo do que são Promises até agora, a partir daqui iremos explorar mais a fundo sobre elas.

+ +

Essencialmente, uma Promise é um objeto que representa um estado intermediário de uma operação — de fato, uma promessa que  um resultado irá ser retornado em um ponto no futuro, mas isso não é garantia de que o resultado estará disponível, ou a promise falhará, o código será executado em ordem para fazer alguma coisa que o resultado seja sucesso, ou tratar uma falha.

+ +

Generally you are less interested in the amount of time an async operation will take to return its result (unless of course it takes far too long!), and more interested in being able to respond to it being returned, whenever that is. And of course, it's nice that it doesn't block the rest of the code execution.

+ +

One of the most common engagements you'll have with promises is with web APIs that return a promise. Let's consider a hypothetical video chat application. The application has a window with a list of the user's friends, and clicking on a button next to a user starts a video call to that user.

+ +

That button's handler calls {{domxref("MediaDevices.getUserMedia", "getUserMedia()")}} in order to get access to the user's camera and microphone. Since getUserMedia() has to ensure that the user has permission to use those devices and ask the user which microphone to use and which camera to use (or whether to be a voice only call, among other possible options), it can block until not only all of those decisions are made, but also the camera and microphone have been engaged. In addition, the user may not respond immediately to these permission requests. This can potentially take a long time.

+ +

Since the call to getUserMedia() is made from the browser's main thread, the entire browser is blocked until getUserMedia() returns! Obviously, that's not an acceptable option; without promises, everything in the browser becomes unusable until the user decides what to do about the camera and microphone. So instead of waiting for the user, getting the chosen devices enabled, and directly returning the {{domxref("MediaStream")}} for the stream created from the selected sources, getUserMedia() returns a {{jsxref("promise")}} which is resolved with the {{domxref("MediaStream")}} once it's available.

+ +

The code that the video chat application would use might look something like this:

+ +
function handleCallButton(evt) {
+  setStatusMessage("Calling...");
+  navigator.mediaDevices.getUserMedia({video: true, audio: true})
+    .then(chatStream => {
+      selfViewElem.srcObject = chatStream;
+      chatStream.getTracks().forEach(track => myPeerConnection.addTrack(track, chatStream));
+      setStatusMessage("Connected");
+    }).catch(err => {
+      setStatusMessage("Failed to connect");
+    });
+}
+
+ +

This function starts by using a function called setStatusMessage() to update a status display with the message "Calling...", indicating that a call is being attempted. It then calls getUserMedia(), asking for a stream that has both video and audio tracks, then once that's been obtained, sets up a video element to show the stream coming from the camera as a "self view," then takes each of the stream's tracks and adds them to the WebRTC {{domxref("RTCPeerConnection")}} representing a connection to another user. After that, the status display is updated to say "Connected".

+ +

If getUserMedia() fails, the catch block runs. This uses setStatusMessage() to update the status box to indicate that an error occurred.

+ +

The important thing here is that the getUserMedia() call returns almost immediately, even if the camera stream hasn't been obtained yet. Even if the handleCallButton() function has already returned to the code that called it, when getUserMedia() has finished working, it calls the handler you provide. As long as the app doesn't assume that streaming has begun, it can just keep on running.

+ +
+

Note: You can learn more about this somewhat advanced topic, if you're interested, in the article Signaling and video calling. Code similar to this, but much more complete, is used in that example.

+
+ +

The trouble with callbacks

+ +

To fully understand why promises are a good thing, it helps to think back to old-style callbacks, and to appreciate why they are problematic.

+ +

Let's talk about ordering pizza as an analogy. There are certain steps that you have to take for your order to be successful, which don't really make sense to try to execute out of order, or in order but before each previous step has quite finished:

+ +
    +
  1. You choose what toppings you want. This can take a while if you are indecisive, and may fail if you just can't make up your mind, or decide to get a curry instead.
  2. +
  3. You then place your order. This can take a while to return a pizza, and may fail if the restaurant does not have the required ingredients to cook it.
  4. +
  5. You then collect your pizza and eat. This might fail if, say, you forgot your wallet so can't pay for the pizza!
  6. +
+ +

With old-style callbacks, a pseudo-code representation of the above functionality might look something like this:

+ +
chooseToppings(function(toppings) {
+  placeOrder(toppings, function(order) {
+    collectOrder(order, function(pizza) {
+      eatPizza(pizza);
+    }, failureCallback);
+  }, failureCallback);
+}, failureCallback);
+ +

This is messy and hard to read (often referred to as "callback hell"), requires the failureCallback() to be called multiple times (once for each nested function), with other issues besides.

+ +

Improvements with promises

+ +

Promises make situations like the above much easier to write, parse, and run. If we represented the above pseudo-code using asynchronous promises instead, we'd end up with something like this:

+ +
chooseToppings()
+.then(function(toppings) {
+  return placeOrder(toppings);
+})
+.then(function(order) {
+  return collectOrder(order);
+})
+.then(function(pizza) {
+  eatPizza(pizza);
+})
+.catch(failureCallback);
+ +

This is much better — it is easier to see what is going on, we only need a single .catch() block to handle all the errors, it doesn't block the main thread (so we can keep playing video games while we wait for the pizza to be ready to collect), and each operation is guaranteed to wait for previous operations to complete before running. We're able to chain multiple asynchronous actions to occur one after another this way because each .then() block returns a new promise that resolves when the .then() block is done running. Clever, right?

+ +

Using arrow functions, you can simplify the code even further:

+ +
chooseToppings()
+.then(toppings =>
+  placeOrder(toppings)
+)
+.then(order =>
+  collectOrder(order)
+)
+.then(pizza =>
+  eatPizza(pizza)
+)
+.catch(failureCallback);
+ +

Or even this:

+ +
chooseToppings()
+.then(toppings => placeOrder(toppings))
+.then(order => collectOrder(order))
+.then(pizza => eatPizza(pizza))
+.catch(failureCallback);
+ +

This works because with arrow functions () => x is valid shorthand for () => { return x; }.

+ +

You could even do this, since the functions just pass their arguments directly, so there isn't any need for that extra layer of functions:

+ +
chooseToppings().then(placeOrder).then(collectOrder).then(eatPizza).catch(failureCallback);
+ +

This is not quite as easy to read, however, and this syntax might not be usable if your blocks are more complex than what we've shown here.

+ +
+

Note: You can make further improvements with async/await syntax, which we'll dig into in the next article.

+
+ +

At their most basic, promises are similar to event listeners, but with a few differences:

+ + + +

Explaining basic promise syntax: A real example

+ +

Promises are important to understand because most modern Web APIs use them for functions that perform potentially lengthy tasks. To use modern web technologies you'll need to use promises. Later on in the chapter we'll look at how to write your own promise, but for now we'll look at some simple examples that you'll encounter in Web APIs.

+ +

In the first example, we'll use the fetch() method to fetch an image from the web, the {{domxref("Body.blob", "blob()")}} method to transform the fetch response's raw body contents into a {{domxref("Blob")}} object, and then display that blob inside an {{htmlelement("img")}} element. This is very similar to the example we looked at in the first article of the series, but we'll do it a bit differently as we get you building your own promise-based code.

+ +
    +
  1. +

    First of all, download our simple HTML template and the sample image file that we'll fetch.

    +
  2. +
  3. +

    Add a {{htmlelement("script")}} element at the bottom of the HTML {{htmlelement("body")}}.

    +
  4. +
  5. +

    Inside your {{HTMLElement("script")}} element, add the following line:

    + +
    let promise = fetch('coffee.jpg');
    + +

    This calls the fetch() method, passing it the URL of the image to fetch from the network as a parameter. This can also take an options object as a optional second parameter, but we are just using the simplest version for now. We are storing the promise object returned by fetch() inside a variable called promise. As we said before, this object represents an intermediate state that is initially neither success or failure — the official term for a promise in this state is pending.

    +
  6. +
  7. +

    To respond to the successful completion of the operation whenever that occurs (in this case, when a {{domxref("Response")}} is returned), we invoke the .then() method of the promise object. The callback inside the .then() block (referred to as the executor) runs only when the promise call completes successfully and returns the {{domxref("Response")}} object — in promise-speak, when it has been fulfilled. It is passed the returned {{domxref("Response")}} object as a parameter.

    + +
    +

    Note: The way that a .then() block works is similar to when you add an event listener to an object using AddEventListener(). It doesn't run until an event occurs (when the promise fulfills). The most notable difference is that a .then() will only run once for each time it is used, whereas an event listener could be invoked multiple times.

    +
    + +

    We immediately run the blob() method on this response to ensure that the response body is fully downloaded, and when it is available transform it into a Blob object that we can do something with. The result of this is returned like so:

    + +
    response => response.blob()
    + +

    which is shorthand for

    + +
    function(response) {
    +  return response.blob();
    +}
    + +

    OK, enough explanation for now. Add the following line below your first line of JavaScript.

    + +
    let promise2 = promise.then(response => response.blob());
    +
  8. +
  9. +

    Each call to .then() creates a new promise. This is very useful; because the blob() method also returns a promise, we can handle the Blob object it returns on fulfillment by invoking the .then() method of the second promise. Because we want to do something a bit more complex to the blob than just run a single method on it and return the result, we'll need to wrap the function body in curly braces this time (otherwise it'll throw an error).

    + +

    Add the following to the end of your code:

    + +
    let promise3 = promise2.then(myBlob => {
    +
    +})
    +
  10. +
  11. +

    Now let's fill in the body of the executor function. Add the following lines inside the curly braces:

    + +
    let objectURL = URL.createObjectURL(myBlob);
    +let image = document.createElement('img');
    +image.src = objectURL;
    +document.body.appendChild(image);
    + +

    Here we are running the {{domxref("URL.createObjectURL()")}} method, passing it as a parameter the Blob returned when the second promise fulfills. This will return a URL pointing to the object. Then we create an {{htmlelement("img")}} element, set its src attribute to equal the object URL and append it to the DOM, so the image will display on the page!

    +
  12. +
+ +

If you save the HTML file you've just created and load it in your browser, you'll see that the image is displayed in the page as expected. Good work!

+ +
+

Note: You will probably notice that these examples are somewhat contrived. You could just do away with the whole fetch() and blob() chain, and just create an <img> element and set its src attribute value to the URL of the image file, coffee.jpg. We did however pick this example because it demonstrates promises in a nice simple fashion, rather than for its real world appropriateness.

+
+ +

Responding to failure

+ +

There is something missing — currently there is nothing to explicitly handle errors if one of the promises fails (rejects, in promise-speak). We can add error handling by running the .catch() method of the previous promise. Add this now:

+ +
let errorCase = promise3.catch(e => {
+  console.log('There has been a problem with your fetch operation: ' + e.message);
+});
+ +

To see this in action, try misspelling the URL to the image and reloading the page. The error will be reported in the console of your browser's developer tools.

+ +

This doesn't do much more than it would if you just didn't bother including the .catch() block at all, but think about it — this allows us to control error handling exactly how we want. In a real app, your .catch() block could retry fetching the image, or show a default image, or prompt the user to provide a different image URL, or whatever.

+ +
+

Note: You can see our version of the example live (see the source code also).

+
+ +

Chaining the blocks together

+ +

This is a very longhand way of writing this out; we've deliberately done this to help you understand what is going on clearly. As shown earlier on in the article, you can chain together .then() blocks (and also .catch() blocks). The above code could also be written like this (see also simple-fetch-chained.html on GitHub):

+ +
fetch('coffee.jpg')
+.then(response => response.blob())
+.then(myBlob => {
+  let objectURL = URL.createObjectURL(myBlob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+})
+.catch(e => {
+  console.log('There has been a problem with your fetch operation: ' + e.message);
+});
+ +

Bear in mind that the value returned by a fulfilled promise becomes the parameter passed to the next .then() block's executor function.

+ +
+

Note: .then()/.catch() blocks in promises are basically the async equivalent of a try...catch block in sync code. Bear in mind that synchronous try...catch won't work in async code.

+
+ +

Promise terminology recap

+ +

There was a lot to cover in the above section, so let's go back over it quickly to give you a short guide that you can bookmark and use to refresh your memory in the future. You should also go over the above section again a few more time to make sure these concepts stick.

+ +
    +
  1. When a promise is created, it is neither in a success or failure state. It is said to be pending.
  2. +
  3. When a promise returns, it is said to be resolved. +
      +
    1. A successfully resolved promise is said to be fulfilled. It returns a value, which can be accessed by chaining a .then() block onto the end of the promise chain. The executor function inside the .then() block will contain the promise's return value.
    2. +
    3. An unsuccessful resolved promise is said to be rejected. It returns a reason, an error message stating why the promise was rejected. This reason can be accessed by chaining a .catch() block onto the end of the promise chain.
    4. +
    +
  4. +
+ +

Running code in response to multiple promises fulfilling

+ +

The above example showed us some of the real basics of using promises. Now let's look at some more advanced features. For a start, chaining processes to occur one after the other is all fine, but what if you want to run some code only after a whole bunch of promises have all fulfilled?

+ +

You can do this with the ingeniously named Promise.all() static method. This takes an array of promises as an input parameter and returns a new Promise object that will fulfill only if and when all promises in the array fulfill. It looks something like this:

+ +
Promise.all([a, b, c]).then(values => {
+  ...
+});
+ +

If they all fulfill, then chained .then() block's executor function will be passed an array containing all those results as a parameter. If any of the promises passed to Promise.all() reject, the whole block will reject.

+ +

This can be very useful. Imagine that we’re fetching information to dynamically populate a UI feature on our page with content. In many cases, it makes sense to receive all the data and only then show the complete content, rather than displaying partial information.

+ +

Let's build another example to show this in action.

+ +
    +
  1. +

    Download a fresh copy of our page template, and again put a <script> element just before the closing </body> tag.

    +
  2. +
  3. +

    Download our source files (coffee.jpg, tea.jpg, and description.txt), or feel free to substitute your own.

    +
  4. +
  5. +

    In our script we'll first define a function that returns the promises we want to send to Promise.all(). This would be easy if we just wanted to run the Promise.all() block in response to three fetch() operations completing. We could just do something like:

    + +
    let a = fetch(url1);
    +let b = fetch(url2);
    +let c = fetch(url3);
    +
    +Promise.all([a, b, c]).then(values => {
    +  ...
    +});
    + +

    When the promise is fulfilled, the values passed into the fullfillment handler would contain three Response objects, one for each of the fetch() operations that have completed.

    + +

    However, we don't want to do this. Our code doesn't care when the fetch() operations are done. Instead, what we want is the loaded data. That means we want to run the Promise.all() block when we get back usable blobs representing the images, and a usable text string. We can write a function that does this; add the following inside your <script> element:

    + +
    function fetchAndDecode(url, type) {
    +  return fetch(url).then(response => {
    +    if (type === 'blob') {
    +      return response.blob();
    +    } else if (type === 'text') {
    +      return response.text();
    +    }
    +  })
    +  .catch(e => {
    +    console.log('There has been a problem with your fetch operation: ' + e.message);
    +  });
    +}
    + +

    This looks a bit complex, so let's run through it step by step:

    + +
      +
    1. First of all we define the function, passing it a URL and a string representing the type of resource it is fetching.
    2. +
    3. Inside the function body, we have a similar structure to what we saw in the first example — we call the fetch() function to fetch the resource at the specified URL, then chain it onto another promise that returns the decoded (or "read") response body. This was always the blob() method in the previous example.
    4. +
    5. However, two things are different here: +
        +
      • First of all, the second promise we return is different depending on what the type value is. Inside the executor function we include a simple if ... else if statement to return a different promise depending on what type of file we need to decode (in this case we've got a choice of blob or text, but it would be easy to extend this to deal with other types as well).
      • +
      • Second, we have added the return keyword before the fetch() call. The effect this has is to run the entire chain and then run the final result (i.e. the promise returned by blob() or text()) as the return value of the function we've just defined. In effect, the return statements pass the results back up the chain to the top.
      • +
      +
    6. +
    7. +

      At the end of the block, we chain on a .catch() call, to handle any error cases that may come up with any of the promises passed in the array to .all(). If any of the promises reject, the catch block will let you know which one had a problem. The .all() block (see below) will still fulfill, but just won't display the resources that had problems. If you wanted the .all to reject, you'd have to chain the .catch() block on to the end of there instead.

      +
    8. +
    + +

    The code inside the function body is async and promise-based, therefore in effect the entire function acts like a promise — convenient.

    +
  6. +
  7. +

    Next, we call our function three times to begin the process of fetching and decoding the images and text, and store each of the returned promises in a variable. Add the following below your previous code:

    + +
    let coffee = fetchAndDecode('coffee.jpg', 'blob');
    +let tea = fetchAndDecode('tea.jpg', 'blob');
    +let description = fetchAndDecode('description.txt', 'text');
    +
  8. +
  9. +

    Next, we will define a Promise.all() block to run some code only when all three of the promises stored above have successfully fulfilled. To begin with, add a block with an empty executor inside the .then() call, like so:

    + +
    Promise.all([coffee, tea, description]).then(values => {
    +
    +});
    + +

    You can see that it takes an array containing the promises as a parameter. The executor will only run when all three promises resolve; when that happens, it will be passed an array containing the results from the individual promises (i.e. the decoded response bodies), kind of like [coffee-results, tea-results, description-results].

    +
  10. +
  11. +

    Last of all, add the following inside the executor. Here we use some fairly simple sync code to store the results in separate variables (creating object URLs from the blobs), then display the images and text on the page.

    + +
    console.log(values);
    +// Store each value returned from the promises in separate variables; create object URLs from the blobs
    +let objectURL1 = URL.createObjectURL(values[0]);
    +let objectURL2 = URL.createObjectURL(values[1]);
    +let descText = values[2];
    +
    +// Display the images in <img> elements
    +let image1 = document.createElement('img');
    +let image2 = document.createElement('img');
    +image1.src = objectURL1;
    +image2.src = objectURL2;
    +document.body.appendChild(image1);
    +document.body.appendChild(image2);
    +
    +// Display the text in a paragraph
    +let para = document.createElement('p');
    +para.textContent = descText;
    +document.body.appendChild(para);
    +
  12. +
  13. +

    Save and refresh and you should see your UI components all loaded, albeit in a not particularly attractive way!

    +
  14. +
+ +

The code we provided here for displaying the items is fairly rudimentary, but works as an explainer for now.

+ +
+

Note: If you get stuck, you can compare your version of the code to ours, to see what it is meant to look like — see it live, and see the source code.

+
+ +
+

Note: If you were improving this code, you might want to loop through a list of items to display, fetching and decoding each one, and then loop through the results inside Promise.all(), running a different function to display each one depending on what the type of code was. This would make it work for any number of items, not just three.

+ +

In addition, you could determine what the type of file is being fetched without needing an explicit type property. You could for example check the {{HTTPHeader("Content-Type")}} HTTP header of the response in each case using response.headers.get("content-type"), and then react accordingly.

+
+ +

Running some final code after a promise fulfills/rejects

+ +

There will be cases where you want to run a final block of code after a promise completes, regardless of whether it fulfilled or rejected. Previously you'd have to include the same code in both the .then() and .catch() callbacks, for example:

+ +
myPromise
+.then(response => {
+  doSomething(response);
+  runFinalCode();
+})
+.catch(e => {
+  returnError(e);
+  runFinalCode();
+});
+ +

In more recent modern browsers, the .finally() method is available, which can be chained onto the end of your regular promise chain allowing you to cut down on code repetition and do things more elegantly. The above code can now be written as follows:

+ +
myPromise
+.then(response => {
+  doSomething(response);
+})
+.catch(e => {
+  returnError(e);
+})
+.finally(() => {
+  runFinalCode();
+});
+ +

For a real example, take a look at our promise-finally.html demo (see the source code also). This works exactly the same as the Promise.all() demo we looked at in the above section, except that in the fetchAndDecode() function we chain a finally() call on to the end of the chain:

+ +
function fetchAndDecode(url, type) {
+  return fetch(url).then(response => {
+    if(type === 'blob') {
+      return response.blob();
+    } else if(type === 'text') {
+      return response.text();
+    }
+  })
+  .catch(e => {
+    console.log(`There has been a problem with your fetch operation for resource "${url}": ` + e.message);
+  })
+  .finally(() => {
+    console.log(`fetch attempt for "${url}" finished.`);
+  });
+}
+ +

This logs a simple message to the console to tell us when each fetch attempt has finished.

+ +
+

Note: finally() allows you to write async equivalents to try/catch/finally in async code.

+
+ +

Building your own custom promises

+ +

The good news is that, in a way, you've already built your own promises. When you've chained multiple promises together with .then() blocks, or otherwise combined them to create custom functionality, you are already making your own custom async promise-based functions. Take our fetchAndDecode() function from the previous examples, for example.

+ +

Combining different promise-based APIs together to create custom functionality is by far the most common way you'll do custom things with promises, and shows the flexibility and power of basing most modern APIs around the same principle. There is another way, however.

+ +

Using the Promise() constructor

+ +

It is possible to build your own promises using the Promise() constructor. The main situation in which you'll want to do this is when you've got code based on an an old-school asynchronous API that is not promise-based, which you want to promis-ify. This comes in handy when you need to use existing, older project code, libraries, or frameworks along with modern promise-based code.

+ +

Let's have a look at a simple example to get you started — here we wrap a setTimeout() call with a promise — this runs a function after two seconds that resolves the promise (using the passed resolve() call) with a string of "Success!".

+ +
let timeoutPromise = new Promise((resolve, reject) => {
+  setTimeout(function(){
+    resolve('Success!');
+  }, 2000);
+});
+ +

resolve() and reject() are functions that you call to fulfill or reject the newly-created promise. In this case, the promise fulfills with a string of "Success!".

+ +

So when you call this promise, you can chain a .then() block onto the end of it and it will be passed a string of "Success!". In the below code we simply alert that message:

+ +
timeoutPromise
+.then((message) => {
+   alert(message);
+})
+ +

or even just

+ +
timeoutPromise.then(alert);
+
+ +

Try running this live to see the result (also see the source code).

+ +

The above example is not very flexible — the promise can only ever fulfill with a single string, and it doesn't have any kind of reject() condition specified (admittedly, setTimeout() doesn't really have a fail condition, so it doesn't matter for this simple example).

+ +
+

Note: Why resolve(), and not fulfill()? The answer we'll give you for now is it's complicated.

+
+ +

Rejecting a custom promise

+ +

We can create a promise that rejects using the reject() method — just like resolve(), this takes a single value, but in this case it is the reason to reject with, i.e., the error that will be passed into the .catch() block.

+ +

Let's extend the previous example to have some reject() conditions as well as allowing different messages to be passed upon success.

+ +

Take a copy of the previous example, and replace the existing timeoutPromise() definition with this:

+ +
function timeoutPromise(message, interval) {
+  return new Promise((resolve, reject) => {
+    if (message === '' || typeof message !== 'string') {
+      reject('Message is empty or not a string');
+    } else if (interval < 0 || typeof interval !== 'number') {
+      reject('Interval is negative or not a number');
+    } else {
+      setTimeout(function(){
+        resolve(message);
+      }, interval);
+    }
+  });
+};
+ +

Here we are passing two methods into a custom function — a message to do something with, and the time interval to pass before doing the thing. Inside the function we then return a new Promise object — invoking the function will return the promise we want to use.

+ +

Inside the Promise constructor, we do a number of checks inside if ... else structures:

+ +
    +
  1. First of all we check to see if the message is appropriate for being alerted. If it is an empty string or not a string at all, we reject the promise with a suitable error message.
  2. +
  3. Next, we check to see if the interval is an appropriate interval value. If it is negative or not a number, we reject the promise with a suitable error message.
  4. +
  5. Finally, if the parameters both look OK, we resolve the promise with the specified message after the specified interval has passed using setTimeout().
  6. +
+ +

Since the timeoutPromise() function returns a Promise, we can chain .then(), .catch(), etc. onto it to make use of its functionality. Let's use it now — replace the previous timeoutPromise usage with this one:

+ +
timeoutPromise('Hello there!', 1000)
+.then(message => {
+   alert(message);
+})
+.catch(e => {
+  console.log('Error: ' + e);
+});
+ +

When you save and run the code as is, after one second you'll get the message alerted. Now try setting the message to an empty string or the interval to a negative number, for example, and you'll be able to see the promise reject with the appropriate error messages! You could also try doing something else with the resolved message rather than just alerting it.

+ +
+

Note: You can find our version of this example on GitHub as custom-promise2.html (see also the source code).

+
+ +

A more real-world example

+ +

The above example was kept deliberately simple to make the concepts easy to understand, but it is not really very async. The asynchronous nature is basically faked using setTimeout(), although it does still show that promises are useful for creating a custom function with sensible flow of operations, good error handling, etc.

+ +

One example we'd like to invite you to study, which does show a useful async application of the Promise() constructor, is Jake Archibald's idb library. This takes the IndexedDB API, which is an old-style callback-based API for storing and retrieving data on the client-side, and allows you to use it with promises. If you look at the main library file you'll see the same kind of techniques we discussed above being used there. The following block converts the basic request model used by many IndexedDB methods to use promises:

+ +
function promisifyRequest(request) {
+  return new Promise(function(resolve, reject) {
+    request.onsuccess = function() {
+      resolve(request.result);
+    };
+
+    request.onerror = function() {
+      reject(request.error);
+    };
+  });
+}
+ +

This works by adding a couple of event handlers that fulfill and reject the promise at appropriate times:

+ + + +

Conclusion

+ +

Promises are a good way to build asynchronous applications when we don’t know the return value of a function or how long it will take to return. They make it easier to express and reason about sequences of asynchronous operations without deeply nested callbacks, and they support a style of error handling that is similar to the synchronous try...catch statement.

+ +

Promises work in the latest versions of all modern browsers; the only place where promise support will be a problem is in Opera Mini and IE11 and earlier versions.

+ +

We didn't touch on all promise features in this article, just the most interesting and useful ones. As you start to learn more about promises, you'll come across further features and techniques.

+ +

Most modern Web APIs are promise-based, so you'll need to understand promises to get the most out of them. Among those APIs are WebRTC, Web Audio API, Media Capture and Streams, and many more. Promises will be more and more important as time goes on, so learning to use and understand them is an important step in learning modern JavaScript.

+ +

See also

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}

+ +

In this module

+ + diff --git a/files/pt-br/learn/javascript/asynchronous/timeouts_and_intervals/index.html b/files/pt-br/learn/javascript/asynchronous/timeouts_and_intervals/index.html new file mode 100644 index 0000000000..2c399201e5 --- /dev/null +++ b/files/pt-br/learn/javascript/asynchronous/timeouts_and_intervals/index.html @@ -0,0 +1,624 @@ +--- +title: Timeouts e intervalos +slug: Learn/JavaScript/Asynchronous/Timeouts_and_intervals +translation_of: Learn/JavaScript/Asynchronous/Timeouts_and_intervals +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}
+ +

Este tutorial é sobre os métodos tradicionais que o JavaScript tem disponíveis para executar códigos assíncronamente depois que um dado período de tempo tenha passado, ou em um intervalo (um número de segundos por segundo), discute suas utilidades e considera seus problemas.

+ + + + + + + + + + + + +
Pré-requisitos:Entendimento básico sobre informáticas e fundamentos do JavaScript.
Objetivo:Entender loops e intervalos assíncronos e para o que eles servem.
+ +

Introdução

+ +

Por um longo tempo, a plataforma web tem oferecido à programadores JavaScript um número de funções que permitem que eles executem código assíncronamente depois de um determinado intervalo de tempo, e executar um bloco de código de modo assíncrono repetidamente até que você o mande parar.

+ +

Essas funções são:

+ +
+
setTimeout()
+
Executa um bloco específico uma vez depois de um determinado tempo
+
setInterval()
+
Executa um bloco específico repetidamente com um intervalo fixo entre cada chamada.
+
requestAnimationFrame()
+
Uma versão moderna de setInterval(). Ela executa um  bloc de código específico antes do navegador renderizar a tela novamento, permitindo que seja executada em uma taxa de quadros adequada, independentemente do ambiente em que está sendo executado.
+
+ +

O código executado por estas funções é executado na main thread (depois do dado intervalo).

+ +
+

É importante saber que você pode (e irá) executar outros códigos antes que uma chamada setTimeout() é executada, ou entre iterações de setInterval(). Dependendo de como essas operações são intensas, elas podem atrasar o seu código async ainda mais, já que o código async só é executado depois que a main thread terminar seu processamento (ou seja, quando a fila estiver vazia). Você aprenderá mais sobre isso enquanto fazemos nosso progresso neste artigo.

+
+ +

De qualquer forma, essas funções são usadas para executar animações constantes e outros processamentos em um web site ou aplicação. Nas seções a seguir, nós vamos te mostrar como elas podem ser usadas.

+ +

setTimeout()

+ +

Como foi dito anteriormente, o setTimeout() executa um bloco de código particular depois que um determinado período de tempo passou. Ele toma os seguintes parâmetros:

+ + + +
+

NOTA: O tempos especificafo não é o tempo garantido de execução, mas sim o tempo míniimo de execução. As callback que você passa para essas funções não podem ser executadas até que a main thread esteja vazia.

+ +

Como consequência, códigos como setTimeout(fn, 0) serão executados assim que a fila estiver vazia, não imediatamente. Se você executar código como setTimeout(fn, 0) e depois imediatamente executar um loop que conta de 1 a 10 bilhões, sua callback será executada depois de alguns segundos.

+
+ +

No exemplo a seguir, o navegador vai esperar dois segundos antes de executar a função anônima, e depois vai mostrar a mensagem de alerta (veja aqui, e veja o código):

+ +
let myGreeting = setTimeout(function() {
+  alert('Hello, Mr. Universe!');
+}, 2000)
+ +

As funções especificadas não tem que  ser anônimas. Você pode dar o nome da função, e até mesmo definir ela em outro lugar e passar uma referência para o timeout setTimeout(). As versões a seguir do código são equivalentes à primeira:

+ +
// With a named function
+let myGreeting = setTimeout(function sayHi() {
+  alert('Hello, Mr. Universe!');
+}, 2000)
+
+// With a function defined separately
+function sayHi() {
+  alert('Hello Mr. Universe!');
+}
+
+let myGreeting = setTimeout(sayHi, 2000);
+ +

Isso pode ser útil se você tem uma função que precisa ser chamada de um timeout e também em resposta à um evento, por exemplo. Mas também pode servir para manter seu código organizado, especialmente se a callback timetout é mais do que algumas linhas de código.

+ +

setTimeout() retorna um valor identificador que pode ser usado para se referir ao timeout depois, como em quando você que pará-lo. Veja {{anch("Cancelando timetous")}} (abaixo) e aprenda como fazer isso.

+ +

Passando parâmetros para uma função setTimeout()

+ +

Quaisquer parâmetros que você quiser passar para a função sendo executada dentro do setTimeout() devem ser passados como parâmetros adicionais no final da lista.

+ +

Por exemplo, você pode mudar a função anterior para que ela diga oi para qualquer nome que foi passada para ela:

+ +
function sayHi(who) {
+  alert(`Hello ${who}!`);
+}
+ +

Agora, você pode passar o nome da pessoa no setTimeout() como um terceiro parâmetro:

+ +
let myGreeting = setTimeout(sayHi, 2000, 'Mr. Universe');
+ +

Cancelando timeouts

+ +

Finalmente, se um timeout foi criado, você pode cancelá-lo antes que o tempo especificado tenha passado chamando clearTimeout(), passando para o identificador a chamada setTimeout() como um parâmetreo. então para cancelar o timeout acima, você fará isso:

+ +
clearTimeout(myGreeting);
+ +
+

Nota: Veja greeter-app.html para uma demonstração mais desenvolvida que te permite colocar o nome da pessoa a dizer oi em um formulário, e cancelar a saudação usando um botão separado (veja aqui o código fonte).

+
+ +

setInterval()

+ +

setTimeout() funciona perfeitamento quando você precisa executar algum código depois de um período de tempo. Mas o que acontece quando voc~e precisa executar o código de novo e de novo — por exemplo, no caso de uma animação?

+ +

É aí que o setInterval() entra. Ele funciona de uma maneira muito similar à setTimeout(), exceto que a função que você passar como primeiro parâmetro é executada repetidamente em não menos que um número determinado de milissegundos dado no segundo parâmetro, ao invés de apenas uma vez. Você também pode passar qualquer parâmetro sendo executado como um parâmetro subsequente da chamada de setInterval().

+ +

Vamos dar uma olhada em um exemplo. A função a seguir cria um novo objeto Date(), tira uma string de tempo usando toLocaleTimeString(), e depois a mostra naUI. Em seguida, ela executa a função uma vez por segundo usando setInterval(), criando o efeito de um relógio digital que é atualizado uma vez por segundo (veja aqui, e também veja o código):

+ +
function displayTime() {
+   let date = new Date();
+   let time = date.toLocaleTimeString();
+   document.getElementById('demo').textContent = time;
+}
+
+const createClock = setInterval(displayTime, 1000);
+ +

Assim como o setTimeout(), o setInterval() também retorna um valor identificador que você pode usar depois para cancelar o intervalo.

+ +

Cancelando intervalos

+ +

setInterval() continua sua execução para sempre, a menos que você faça algo sobre isso. Você provavelmente quer um jeito de parar tais tarefas, do contrário você pode acabar com error quando o navegador não puder completar outras versões futuras da tarefa, ou se a animação acabar. Você pode fazer isso do mesmo jeito que você para timeouts — passando o identificador retornado por setInterval() para a função clearInterval():

+ +
const myInterval = setInterval(myFunction, 2000);
+
+clearInterval(myInterval);
+ +

Aprendizado ativo: Criando seu próprio cronômetro!

+ +

Com tudo isso dito, nós temos um desafio para você. Faça uma cópia do nosso exemplo setInterval-clock.html, e o modifique para criar seu próprio cronômetro.

+ +

Você precisa mostrar um tempo na tela como antes, mas nesse ememplo você vai precisar de:

+ + + +

Here's a few hints for you:

+ + + +
+

Note: If you get stuck, you can find our version here (see the source code also).

+
+ +

Coisas para se manter em mente sobre o setTimeout() e o setInterval()

+ +

Existem algumas coisinhas que devemos sempre lembrar quando estamos trabalhando com setTimeout() esetInterval():

+ +

Timeouts recursivos

+ +

Há outra maneira de usar o  setTimeout(): você pode chamá-lo recusivamnete para executar o mesmo código repetidas vezes, ao invés de usar o setInterval().

+ +

O exemplo abaixo usa um setTimeout() recursivo para executar a função passada a cada 100 millissegundos:

+ +
let i = 1;
+
+setTimeout(function run() {
+  console.log(i);
+  i++;
+  setTimeout(run, 100);
+}, 100);
+ +

Compare the above example to the following one — this uses setInterval() to accomplish the same effect:

+ +
let i = 1;
+
+setInterval(function run() {
+  console.log(i);
+  i++
+}, 100);
+ +

Qual a diferença entre o setTimeout() recursivo e o setInterval()?

+ +

A diferença entre as duas versões é bem sútil.

+ + + +

Quando seu código tem o potencial para levar mais tempo do que lhe foi atribuido, é melhor usar o setTimeout() recursivo — isso irá manter o intervalo de tempo constant entre execuções independente do quanto tempo o código levar para ser executado, e você não terá erros.

+ +

Timeouts imediatos

+ +

Usar zero como o valor para setTimeout() faz a execução da callback ser o mais rápido o possível, mas apenas depois que a main thread for terminada.

+ +

Por exemplo, o código abaixo (veja funcionar aqui) mostra um alert que contém um "Hello", depois um  alert que contém "World" assim que você clicar em OK no primeiro alerta.

+ +
setTimeout(function() {
+  alert('World');
+}, 0);
+
+alert('Hello');
+ +

Isso pode ser útil em casos onde você quer fazer um bloco de código ser executado assim que a main thread acabar o seu processamento — colocar no loop de eventos async, assim ele vai ser executado logo depois.

+ +

Cancelando com clearTimeout() ou clearInterval()

+ +

clearTimeout() e clearInterval() usam a mesma lista de entradas para cancelamento. Isso significa que você pode usar os dois para cancelar um setTimeout() ou setInterval().

+ +

Mas mesmo assim, você deve usar o clearTimeout() para entradas setTimeout() e clearInterval() para entradas setInterval(). Isso evita confusões.

+ +

requestAnimationFrame()

+ +

requestAnimationFrame() é uma função de loop especializada criada para executar animações com eficiência no navegador. Ela é basicamente a versão moderna de setInterval() — ela executa um bloco de código específico antes que o navegador renove o display, permitindo que uma animação seja executada em um framerate adequado independente do ambiente em que está sendo executada.

+ +

Ela foi criada em resposta à problemas ocorridos com setInterval(), que por exemplo não roda em uma taxa de quadros otimizada para o dispositivo, e às vezes diminui os frames, continua a rodar mesmo se a guia não esiver ativa ou se a animação for rolada para fora da página, etc.

+ +

(Leia mais sobre isso em CreativeJS.)

+ +
+

Nota: Você pode encontrar exemplos do uso de requestAnimationFrame() em outros lugares do curso — por exemplo em Drawing graphics, e Object building practice.

+
+ +

O método toma como argumentos uma callback a  ser invocada antes da renovação. Esse é o padrão geral que você verá usado em:

+ +
function draw() {
+   // Drawing code goes here
+   requestAnimationFrame(draw);
+}
+
+draw();
+ +

A ideia é definir uma função em que sua animação é atualizada (e.g. seus spritas se movem, a pontuação é atuializada, dados são recarregados, etc). Depois, você inicia o processo. No final do bloco da função você chama  requestAnimationFrame() com a referência da função passada como parâmetro, e isso instrui o navegador a chamar a função de novo na próxima renovação. Isso é executado continuamente, já que o código está chamando requestAnimationFrame() recursivamente.

+ +
+

Nota: Se você quer realizar algum tipo de animação na DOM constantemente, Animações CSS são provavelemente mais rápidas. elas são calculadas diretamente pelo código interno do navegador, ao invés de JavaScript.

+ +

Se, no entanto, você está fazendo algo mais complexo e envolvendo objetos que não são diretamente assessados da DOM (como 2D Canvas API ou objetos WebGL), requestAnimationFrame() é a melhor opção na maioria dos casos

+
+ +

Qual a velocidade da sua animação?

+ +

A suavidade da sua animação é diretamente dependente na frame rate da sua animação e é medida em frames per second (fps). The smoothness of your animation is directly dependent on your animation's frame rate and it is measured in frames per second (fps). Quanto maior esse número, mais suave será a sua animação, até certo ponto.

+ +

Já que a maioria das tela tem uma taxa de atualização de 60Hz, a frame rate mais rápida que você pode ter é de 60fps quando trabalhando com web browsers. No entanto, mais frames significa mais processamento, o que pode ser causar uma queda de quadros e travamento.

+ +

Se você tem um monitos com uma taxa de atualização de 60Hz e você quer atingir 60FPS você tem pelo menos 16.7 milissegundos (1000 / 60) para executar sua animação em cada frame. Isso é um lembrete de que você vai precisar estar atento à quantidade de código que você vai tentar executar em cada iteração do loop de animação.

+ +

requestAnimationFrame() sempre tenta ficar o mais próximo possível de 60 FPS. Às vezes, isso não é possível — se você tem uma animação bem complexa e você está executando ela em um computador lento, sua frame rate será menor. Em todos os casos, o requestAnimationFrame() sempre vai fazer o melhor que pode com o que ele tem dísponivel.

+ +

Como o requestAnimationFrame() se diferencia de setInterval() e setTimeout()?

+ +

Vamos falar um pouco sobre como o método requestAnimationFrame() se diferencia dos outros métodos vistos anteriormente. Olhando com o código anterior:

+ +
function draw() {
+   // Drawing code goes here
+   requestAnimationFrame(draw);
+}
+
+draw();
+ +

Vamos ver isso usando o setInterval():

+ +
function draw() {
+   // Drawing code goes here
+}
+
+setInterval(draw, 17);
+ +

Como foi dito anteriormente, você não especifica um intervalo de tempo para requestAnimationFrame(). O método se executa o mais rápido e suave o possível nas condições atuais. O navegador também não perde tempo executando uma animação se ela está fora da tela por algum motivo, etc.

+ +

setInterval(), por outro lado, exige que um  intervalo de tempo seja especificado. Nós chegamos ao valor final de 17 por meio da formula 1000 milliseconds / 60Hz, e depois arredondamos o resultado. Arredondar é uma boa ideia; se você tivesse arredondado para baixo, o navegador pode tentar executar a animação mais rápido do que 60  FPS, e não faria nenhuma diferênça na suavidade da animação de qualquer forma. Como foi dito antes, 60Hz é a taxa de atualização padrão.

+ +

Incluindo um timestamp

+ +

A callback passada para a função requestAnimationFrame() pode ser dada um parâmetro támbem: um valor timestamp, que representa o tempo desde que o  requestAnimationFrame() começou a rodar.

+ +

Isso é útil, permite que você execute coisas em  um tempo específico e em passo constante, independente do quão rápido ou lento é o seu dispositivo. O padão geral que você usaria se parece um pouco com isso:

+ +
let startTime = null;
+
+function draw(timestamp) {
+    if (!startTime) {
+      startTime = timestamp;
+    }
+
+   currentTime = timestamp - startTime;
+
+   // Do something based on current time
+
+   requestAnimationFrame(draw);
+}
+
+draw();
+ +

Suporte do navegador

+ +

requestAnimationFrame() é suportado em navegadores mais recentes do que setInterval()/setTimeout().  Curiosamente, está disponível no Internet Explorer 10 e além.

+ +

Então, você não precisa dar suporte para versões mais velhas do IE, não há poruqe não usar o  requestAnimationFrame().

+ +

Um exemplo simples

+ +

Enough with the theory! Let's build your own personal requestAnimationFrame() example. You're going to create a simple "spinner animation"—the kind you might see displayed in an app when it is busy connecting to the server, etc.

+ +
+

Note: In a real world example, you should probably use CSS animations to run this kind of simple animation. However, this kind of example is very useful to demonstrate requestAnimationFrame() usage, and you'd be more likely to use this kind of technique when doing something more complex such as updating the display of a game on each frame.

+
+ +
    +
  1. +

    Grab a basic HTML template (such as this one).

    +
  2. +
  3. +

    Put an empty {{htmlelement("div")}} element inside the {{htmlelement("body")}}, then add a ↻ character inside it. This is circular arrow character will act as our spinner for this example.

    +
  4. +
  5. +

    Apply the following CSS to the HTML template (in whatever way you prefer). This sets a red background on the page, sets the <body> height to 100% of the {{htmlelement("html")}} height, and centers the <div> inside the <body>, horizontally and vertically.

    + +
    html {
    +  background-color: white;
    +  height: 100%;
    +}
    +
    +body {
    +  height: inherit;
    +  background-color: red;
    +  margin: 0;
    +  display: flex;
    +  justify-content: center;
    +  align-items: center;
    +}
    +
    +div {
    +  display: inline-block;
    +  font-size: 10rem;
    +}
    +
  6. +
  7. +

    Insert a {{htmlelement("script")}} element just above the </body> tag.

    +
  8. +
  9. +

    Insert the following JavaScript inside your <script> element. Here, you're storing a reference to the <div> inside a constant, setting a rotateCount variable to 0, setting an uninitialized variable that will later be used to contain a reference to the requestAnimationFrame() call, and setting a startTime variable to null, which will later be used to store the start time of the requestAnimationFrame().

    + +
    const spinner = document.querySelector('div');
    +let rotateCount = 0;
    +let startTime = null;
    +let rAF;
    +
    +
  10. +
  11. +

    Below the previous code, insert a draw() function that will be used to contain our animation code, which includes the timestamp parameter:

    + +
    function draw(timestamp) {
    +
    +}
    +
  12. +
  13. +

    Inside draw(), add the following lines. They will define the start time if it is not defined already (this will only happen on the first loop iteration), and set the rotateCount to a value to rotate the spinner by (the current timestamp, take the starting timestamp, divided by three so it doesn't go too fast):

    + +
      if (!startTime) {
    +   startTime = timestamp;
    +  }
    +
    +  rotateCount = (timestamp - startTime) / 3;
    +
    +
  14. +
  15. +

    Below the previous line inside draw(), add the following block — this checks to see if the value of rotateCount is above 359 (e.g. 360, a full circle). If so, it sets the value to its modulo of 360 (i.e. the remainder left over when the value is divided by 360) so the circle animation can continue uninterrupted, at a sensible, low value. Note that this isn't strictly necessary, but it is easier to work with values of 0–359 degrees than values like "128000 degrees".

    + +
    if (rotateCount > 359) {
    +  rotateCount %= 360;
    +}
    +
  16. +
  17. Next, below the previous block add the following line to actually rotate the spinner: +
    spinner.style.transform = `rotate(${rotateCount}deg)`;
    +
  18. +
  19. +

    At the very bottom inside the draw() function, insert the following line. This is the key to the whole operation — you are setting the variable defined earlier to an active requestAnimation() call, which takes the draw() function as its parameter. This starts the animation off, constantly running the draw() function at a rate as near 60 FPS as possible.

    + +
    rAF = requestAnimationFrame(draw);
    +
  20. +
+ +
+

Note: You can find this example live on GitHub. (You can see the source code, also.)

+
+ +

Clearing a requestAnimationFrame() call

+ +

Clearing a requestAnimationFrame() call can be done by calling the corresponding cancelAnimationFrame() method. (Note that the function name starts with "cancel", not "clear" as with the "set..." methods.) 

+ +

Just pass it the value returned by the requestAnimationFrame() call to cancel, which you stored in the variable rAF:

+ +
cancelAnimationFrame(rAF);
+ +

Active learning: Starting and stopping our spinner

+ +

In this exercise, we'd like you to test out the cancelAnimationFrame() method by taking our previous example and updating it, adding an event listener to start and stop the spinner when the mouse is clicked anywhere on the page.

+ +

Some hints:

+ + + +
+

Note: Try this yourself first; if you get really stuck, check out of our live example and source code.

+
+ +

Throttling a requestAnimationFrame() animation

+ +

One limitation of requestAnimationFrame() is that you can't choose your frame rate. This isn't a problem most of the time, as generally you want your animation to run as smoothly as possible. But what about when you want to create an old school, 8-bit-style animation?

+ +

This was a problem, for example, in the Monkey Island-inspired walking animation from our Drawing Graphics article:

+ +

{{EmbedGHLiveSample("learning-area/javascript/apis/drawing-graphics/loops_animation/7_canvas_walking_animation.html", '100%', 260)}}

+ +

In this example, you have to animate both the position of the character on the screen, and the sprite being shown. There are only 6 frames in the sprite's animation. If you showed a different sprite frame for every frame displayed on the screen by requestAnimationFrame(), Guybrush would move his limbs too fast and the animation would look ridiculous. This example therefore throttles the rate at which the sprite cycles its frames using the following code:

+ +
if (posX % 13 === 0) {
+  if (sprite === 5) {
+    sprite = 0;
+  } else {
+    sprite++;
+  }
+}
+ +

So the code only cycles the sprite once every 13 animation frames.

+ +

...Actually, it's about every 6.5 frames, as we update posX (character's position on the screen) by two each frame:

+ +
if (posX > width/2) {
+  newStartPos = -( (width/2) + 102 );
+  posX = Math.ceil(newStartPos / 13) * 13;
+  console.log(posX);
+} else {
+  posX += 2;
+}
+ +

This is the code that calculates how to update the position in each animation frame.

+ +

The method you use to throttle your animation will depend on your particular code. For instance, in the earlier spinner example, you could make it appear to move slower by only increasing rotateCount by one on each frame, instead of two.

+ +

Active learning: a reaction game

+ +

For the final section of this article, you'll create a 2-player reaction game. The game will have two players, one of whom controls the game using the A key, and the other with the L key.

+ +

When the Start button is pressed, a spinner like the one we saw earlier is displayed for a random amount of time between 5 and 10 seconds. After that time, a message will appear saying "PLAYERS GO!!" — once this happens, the first player to press their control button will win the game.

+ +

{{EmbedGHLiveSample("learning-area/javascript/asynchronous/loops-and-intervals/reaction-game.html", '100%', 500)}}

+ +

Let's work through this:

+ +
    +
  1. +

    First of all, download the starter file for the app. This contains the finished HTML structure and CSS styling, giving us a game board that shows the two players' information (as seen above), but with the spinner and results paragraph displayed on top of one another. You just have to write the JavaScript code.

    +
  2. +
  3. +

    Inside the empty {{htmlelement("script")}} element on your page, start by adding the following lines of code that define some constants and variables you'll need in the rest of the code:

    + +
    const spinner = document.querySelector('.spinner p');
    +const spinnerContainer = document.querySelector('.spinner');
    +let rotateCount = 0;
    +let startTime = null;
    +let rAF;
    +const btn = document.querySelector('button');
    +const result = document.querySelector('.result');
    + +

    In order, these are:

    + +
      +
    1. A reference to the spinner, so you can animate it.
    2. +
    3. A reference to the {{htmlelement("div")}} element that contains the spinner, used for showing and hiding it.
    4. +
    5. A rotate count. This determines how much you want to show the spinner rotated on each frame of the animation.
    6. +
    7. A null start time. This will be populated with a start time when the spinner starts spinning.
    8. +
    9. An uninitialized variable to later store the {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}} call that animates the spinner.
    10. +
    11. A reference to the Start button.
    12. +
    13. A reference to the results paragraph.
    14. +
    +
  4. +
  5. +

    Next, below the previous lines of code, add the following function. It simply takes two numbers and returns a random number between the two. You'll need this to generate a random timeout interval later on.

    + +
    function random(min,max) {
    +  var num = Math.floor(Math.random()*(max-min)) + min;
    +  return num;
    +}
    +
  6. +
  7. +

    Next add  the draw() function, which animates the spinner. This is very similar to the version from the simple spinner example, earlier:

    + +
    function draw(timestamp) {
    +  if(!startTime) {
    +   startTime = timestamp;
    +  }
    +
    +  rotateCount = (timestamp - startTime) / 3;
    +
    +  if(rotateCount > 359) {
    +    rotateCount %= 360;
    +  }
    +
    +  spinner.style.transform = 'rotate(' + rotateCount + 'deg)';
    +  rAF = requestAnimationFrame(draw);
    +}
    +
  8. +
  9. +

    Now it is time to set up the initial state of the app when the page first loads. Add the following two lines, which simply hide the results paragraph and spinner container using display: none;.

    + +
    result.style.display = 'none';
    +spinnerContainer.style.display = 'none';
    +
  10. +
  11. +

    Next, define a reset() function, which sets the app back to the original state required to start the game again after it has been played. Add the following at the bottom of your code:

    + +
    function reset() {
    +  btn.style.display = 'block';
    +  result.textContent = '';
    +  result.style.display = 'none';
    +}
    +
  12. +
  13. +

    Okay, enough preparation!  It's time to make the game playable! Add the following block to your code. The start() function calls draw() to start the spinner spinning and display it in the UI, hides the Start button so you can't mess up the game by starting it multiple times concurrently, and runs a setTimeout() call that runs a setEndgame() function after a random interval between 5 and 10 seconds has passed. The following block also adds an event listener to your button to run the start() function when it is clicked.

    + +
    btn.addEventListener('click', start);
    +
    +function start() {
    +  draw();
    +  spinnerContainer.style.display = 'block';
    +  btn.style.display = 'none';
    +  setTimeout(setEndgame, random(5000,10000));
    +}
    + +
    +

    Note: You'll see this example is calling setTimeout() without storing the return value. (So, not let myTimeout = setTimeout(functionName, interval).) 

    + +

    This works just fine, as long as you don't need to clear your interval/timeout at any point. If you do, you'll need to save the returned identifier!

    +
    + +

    The net result of the previous code is that when the Start button is pressed, the spinner is shown and the players are made to wait a random amount of time before they are asked to press their button. This last part is handled by the setEndgame() function, which you'll define next.

    +
  14. +
  15. +

    Add the following function to your code next:

    + +
    function setEndgame() {
    +  cancelAnimationFrame(rAF);
    +  spinnerContainer.style.display = 'none';
    +  result.style.display = 'block';
    +  result.textContent = 'PLAYERS GO!!';
    +
    +  document.addEventListener('keydown', keyHandler);
    +
    +  function keyHandler(e) {
    +    console.log(e.key);
    +    if(e.key === 'a') {
    +      result.textContent = 'Player 1 won!!';
    +    } else if(e.key === 'l') {
    +      result.textContent = 'Player 2 won!!';
    +    }
    +
    +    document.removeEventListener('keydown', keyHandler);
    +    setTimeout(reset, 5000);
    +  };
    +}
    + +

    Stepping through this:

    + +
      +
    1. First, cancel the spinner animation with {{domxref("window.cancelAnimationFrame", "cancelAnimationFrame()")}} (it is always good to clean up unneeded processes), and hide the spinner container.
    2. +
    3. Next, display the results paragraph and set its text content to "PLAYERS GO!!" to signal to the players that they can now press their button to win.
    4. +
    5. Attach a keydown event listener to the document. When any button is pressed down, the keyHandler() function is run.
    6. +
    7. Inside keyHandler(), the code includes the event object as a parameter (represented by e) — its {{domxref("KeyboardEvent.key", "key")}} property contains the key that was just pressed, and you can use this to respond to specific key presses with specific actions.
    8. +
    9. Log e.key to the console, which is a useful way of finding out the key value of different keys you are pressing.
    10. +
    11. When e.key is "a", display a message to say that Player 1 won, and when e.key is "l", display a message to say Player 2 won. (Note: This will only work with lowercase a and l — if an uppercase A or L is submitted (the key plus Shift), it is counted as a different key!)
    12. +
    13. Regardless of which one of the player control keys was pressed,  remove the keydown event listener using {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} so that once the winning press has happened, no more keyboard input is possible to mess up the final game result. You also use setTimeout() to call reset() after 5 seconds — as explained earlier, this function resets the game back to its original state so that a new game can be started.
    14. +
    +
  16. +
+ +

That's it—you're all done!

+ +
+

Note: If you get stuck, check out our version of the reaction game (see the source code also).

+
+ +

Conclusion

+ +

So that's it — all the essentials of async loops and intervals covered in one article. You'll find these methods useful in a lot of situations, but take care not to overuse them! Because they still run on the main thread, heavy and intensive callbacks (especially those that manipulate the DOM) can really slow down a page if you're not careful.

+ +

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}

+ +

In this module

+ + diff --git a/files/pt-br/learn/javascript/first_steps/a_first_splash/index.html b/files/pt-br/learn/javascript/first_steps/a_first_splash/index.html new file mode 100644 index 0000000000..1d5498ab11 --- /dev/null +++ b/files/pt-br/learn/javascript/first_steps/a_first_splash/index.html @@ -0,0 +1,683 @@ +--- +title: Um primeiro mergulho no JavaScript +slug: Learn/JavaScript/First_steps/A_first_splash +translation_of: Learn/JavaScript/First_steps/A_first_splash +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/What_is_JavaScript", "Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps")}}
+ +

Agora você poderá aprender um pouco sobre a Teoria do Javascript e o que você poderá fazer com ele. Nós vamos lhe fornecer aqui um Curso rápido sobre as características básicas do JavaScript através de um tutorial completamente prático. Você irá construir um simples jogo de "Adivinhe o número", passo a passo. 

+ + + + + + + + + + + + +
Pré-requisitos:Conhecimentos básicos de informática, uma compreensão básica de HTML e CSS, uma compreensão do que é JavaScript.
Objetivo: +

Ter um primeiro bit de experiência em escrever um pouco de  JavaScript, e adquirir  pelo menos uma compreensão básica do que envolve escrever um programa em JavaScript.

+
+ +

Nós não esperamos que você entenda todo o código imediatamente - Apenas queremos ensinar-lhe os melhores conceitos por enquanto e dar a você uma idéia de como o JavaScript (e outras linguagens de programação) funcionam. Em artigos posteriores você vai rever todos esses recursos com muito mais detalhes!

+ +
+

Nota: Muitos dos recursos de código que você verá no JavaScript são iguais aos de outra linguagem de programação - funções, loops, etc. A sintaxe do código parece diferente, mas os conceitos ainda são praticamente os mesmos.

+
+ +

Pensando como um Programador

+ +

Uma das coisas mais difíceis de aprender na programação não é a sintaxe que você precisa aprender, mas como aplicá-la para resolver problemas do mundo real. Você precisa começar a pensar como um programador - isso geralmente envolve olhar para as descrições do que seu programa precisa fazer e analisar como eles podem ser aplicados na solução real (prática), quais recursos de código são necessários para alcançar esse objetivo, e como fazê-los trabalhar em conjunto.

+ +

Isso requer um mistura de trabalho duro, experiência com a sintaxe de programação utilizada e prática, além de um pouco de criatividade, é claro. Quanto mais você programa, melhor programador se torna. Nós não prometemos transformar seu cérebro em um "cérebro de programador" em 5 minutos, mas vamos te dar todas as oportunidades para pensar na prática como um programador ao longo deste curso. 

+ +

Com isso em mente, vejamos o exemplo que estaremos construindo neste artigo e analisaremos o processo geral de dissecá-lo em tarefas tangíveis.

+ +

 

+ +

Exemplo — Jogo adivinhe um número

+ +

Neste artigo vamos mostrar a você como construir este simples jogo, que pode ser visto abaixo:

+ + + +

{{ EmbedLiveSample('Top_hidden_code', '100%', 320) }}

+ +

Vá em frente e jogue por um tempo para se familiarizar com o jogo antes de continuar.

+ +

Vamos imaginar que o seu chefe te deu as seguintes diretrizes para criar este jogo:

+ +
+

Quero que você crie um jogo simples do tipo adivinhe um número. Ele deve gerar um número aleatório de 1 a 100, depois desafiar o jogador a adivinhar o número em 10 rodadas. A cada rodada deve ser dito ao jogador se ele está certo ou errado, se estiver errado, deve ser dito se o palpite é muito baixo ou muito alto. Também deve ser mostrado ao jogador os números que ele tentou adivinhar anteriormente. O jogo termina se o jogador acertar o número ou acabarem o número de tentativas. Quando o jogo acabar, deve ser dado ao jogador a opção de jogar novamente.

+
+ +

Olhando para o enunciado, a primeira coisa que devemos fazer é quebrá-lo em pequenas tarefas, da forma mais parecida com o pensamento de um programador quanto possível:

+ +
    +
  1. Gerar um número aleatório entre 1 e 100.
  2. +
  3. Gravar o número do turno que o jogador está. Iniciar em 1.
  4. +
  5. Dar ao jogador uma forma de adivinhar o número.
  6. +
  7. Após a tentativa ter sido submetida, primeiro gravar em algum lugar para que o usuário possa ver as tentativas anteriores.
  8. +
  9. Depois, verificar se o palpite está correto.
  10. +
  11. Se estiver correto: +
      +
    1. Escrever mensagem de parabéns.
    2. +
    3. Impedir que o jogador insira mais respostas (isso pode bugar o jogo).
    4. +
    5. Mostrar controle que permita ao jogador reiniciar o jogo.
    6. +
    +
  12. +
  13. Se o palpite estiver errado e o jogador ainda tem turnos sobrando: +
      +
    1. Dizer ao jogador que ele está errado.
    2. +
    3. Permitir que ele insira outra resposta.
    4. +
    5. Incrementar o número do turno em 1.
    6. +
    +
  14. +
  15. Se o jogador está errado mas não tem turnos sobrando: +
      +
    1. Dizer ao jogador que o jogo acabou.
    2. +
    3. Impedir que o jogador insira mais respostas (isso pode bugar o jogo).
    4. +
    5. Mostrar controle que permita ao jogador reiniciar o jogo.
    6. +
    +
  16. +
  17. Quando reiniciar, tenha certeza de resetar todas as variáveis e a interface do jogo, então volte para o passo 1.
  18. +
+ +

Então vamos em frente, olhando como podemos transformar esses passos em código, construindo esse exemplo e explorando as ferramentas do JavaScript ao longo do caminho.

+ +

Configuração Inicial

+ +

Para iniciar este tutorial, gostaríamos que você fizesse uma cópia do arquivo jogo-adivinhe-o-numero-inicio.html (ver demonstração). Abra-o em um editor de texto e também no seu browser. No momento você vai apenas ver um simples cabeçalho, parágrafo de instruções e um formulário para entrada de informações, mas o formulário não fará nada por enquanto.

+ +

O lugar em que começaremos a escrever nosso código será dentro da tag {{htmlelement("script")}} na parte inferior do HTML:

+ +
<script>
+
+  // Seu JavaScript vai aqui
+
+</script>
+
+ +

Adicionando variáveis para armazenar nossos dados

+ +

Vamos começar. Primeiramente, adicione as seguintes linhas na sua tag {{htmlelement("script")}} :

+ +
var numeroAleatorio= Math.floor(Math.random() * 100) + 1;
+
+var palpites = document.querySelector('.palpites');
+var ultimoResultado = document.querySelector('.ultimoResultado');
+var baixoOuAlto = document.querySelector('.baixoOuAlto');
+
+var envioPalpite = document.querySelector('.envioPalpite');
+var campoPalpite = document.querySelector('.campoPalpite');
+
+var contagemPalpites = 1;
+var botaoReinicio;
+ +

Aqui estamos setando as variáveis que precisamos para guardar os dados que nosso programa irá utilizar. Variáveis são basicamente recipientes para valores (como números, ou strings ou textos). Variáveis são criadas com a palavra-chave var seguida de um nome para sua variável. Você pode atribuir um valor para sua variável com um sinal de igual (=) seguido do valor que você quer dar a ela.

+ +

No nosso exemplo:

+ + + +
+

Nota: Você irá aprender muito mais sobre variáveis a partir do próximo artigo.

+
+ +

Funções

+ +

Em seguida, adicione o seguinte código abaixo do JavaScript anterior:

+ +
function conferirPalpite() {
+  alert('Eu sou um placeholder');
+}
+ +

Funções são blocos reutilizáveis de código que você pode escrever uma vez e executá-lo de novo e de novo, eliminando a necessidade de repetir o código todas as vezes. Isso é realmente útil. Há várias formas de se definir funções, mas, por agora, vamos nos concentrar em um tipo simples. Aqui nós definimos uma função usando a palavra chave function, seguida de um nome, com parênteses colocados na sequência. Depois disso nós colocamos duas chaves ({ }). Dentro das chaves vai todo o código que queremos executar sempre que chamarmos a função.

+ +

O código é executado digitando o nome da função seguido pelos parênteses.

+ +

Tente salvar o seu código agora e atualizá-lo no navegador.

+ +

Vá até o console JavaScript, e insirá a seguinte linha:

+ +
conferirPalpite();
+ +

Você deverá ver um alerta aparecer dizendo "Eu sou um placeholder"; nós definimos uma função em nosso código que cria um alerta a qualquer hora em que a chamarmos.

+ +
+

Nota: Você irá aprender muito mais sobre funções mais tarde no curso.

+
+ +

Operadores

+ +

Os operadores JavaScript nos permite realizar testes, fazer cálculos matemáticos, unir sequências de texto, e outras coisas do tipo.

+ +

Vamos salvar nosso código e atualizar a página exibida em nosso navegador. Abra o console JavaScript se você ainda não o tiver aberto, para que possamos digitar os exemplos mostrados abaixo — digite cada um exatamente como mostrado na coluna "Exemplo", pressionando Return/Enter na sequência, e veja quais resultados são retornados. Se você não tiver fácil acesso às ferramentas de desenvolvimento do navegador você pode sempre utilizar o console embutido simples, como no exemplo abaixo:

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

+ +

Primeiro vamos ver os operadores matemáticos, como por exemplo:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperadorNomeExemplo
+Adição6 + 9
-Subtração20 - 15
*Multiplicação3 * 7
/Divisão10 / 5
+ +

Você também pode usar o operador + para unir sequências de texto (isso é chamado de concatenação em programação). Tente inserir as seguintes linhas:

+ +
var nome = 'Bingo';
+nome;
+var ola = ' diz olá!';
+ola;
+var cumprimento = nome + ola;
+cumprimento;
+ +

Há também alguns atalhos para operadores disponíveis, chamados de operadores de atribuição ampliada (ou atribuição composta). Por exemplo, se você quer adicionar uma nova sequência de texto à uma existente e retornar o resultado, você pode fazer o seguinte:

+ +
nome += ' diz olá!';
+ +

Isso é equivalente a:

+ +
nome = nome + ' diz olá!';
+ +

Quando estamos rodando testes de verdadeiro/falso (por exemplo, condicinais internas — veja {{anch("Conditionals", "abaixo")}}, usamos operadores de comparação, por exemplo:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperadorNomeExemplo
===Igualdade estrita (é estritamente o mesmo?)5 === 2 + 4
!==Não-igualdade (não é o mesmo?)'Chris' !== 'Ch' + 'ris'
<Menor que10 < 6
>Maior que10 > 20
+ +

Condicionais

+ +

Voltando à nossa função conferirPalpite(), imagino que seja seguro dizer que não queremos que ela apenas exiba uma mensagem de teste (placeholder). Nós queremos verificar se o palpite do jogador está correto ou não, e responder apropriadamente.

+ +

Neste ponto, substitua sua função conferirPalpite() atual por esta versão:

+ +
function conferirPalpite() {
+  var palpiteUsuario = Number(campoPalpite.value);
+  if (contagemPalpites === 1) {
+    palpites.textContent = 'Palpites anteriores: ';
+  }
+  palpites.textContent += palpiteUsuario + ' ';
+
+  if (palpiteUsuario === numeroAleatorio) {
+    ultimoResultado.textContent = 'Parabéns! Você acertou!';
+    ultimoResultado.style.backgroundColor = 'green';
+    baixoOuAlto.textContent = '';
+    configFimDeJogo();
+  } else if (contagemPalpites === 10) {
+    ultimoResultado.textContent = '!!!FIM DE JOGO!!!';
+    baixoOuAlto.textContent = '';
+    configFimDeJogo();
+  } else {
+    ultimoResultado.textContent = 'Errado!';
+    ultimoResultado.style.backgroundColor = 'red';
+    if(palpiteUsuario < numeroAleatorio) {
+      baixoOuAlto.textContent = 'Seu palpite está muito baixo!';
+    } else if(palpiteUsuario > numeroAleatorio) {
+      baixoOuAlto.textContent = 'Seu palpite está muito alto!';
+    }
+  }
+
+  contagemPalpites++;
+  campoPalpite.value = '';
+  campoPalpite.focus();
+}
+ +

Isso é bastante código — ufa! Vamos abordar cada seção e explicar o que faz.

+ + + +

Eventos

+ +

Neste ponto temos uma função conferirPalpite() bem implementada, mas ela não irá fazer nada pois nós não a chamamos ainda. Idealmente nós queremos que ela seja acionada quando o botão "Enviar palpite" for pressionado, e para fazer isso precisamos usar um evento. Eventos são ações que acontencem no navegador, como um botão sendo clicado, ou uma página carregada, ou um vídeo tocando; ações as quais podemos responder executando blocos de código. Os construtores que monitoram os acontecimentos de eventos são chamados de event listeners, e os blocos de código executados em resposta ao acontecimento do evento são chamados de event handlers.

+ +

Adicione a seguinte linha abaixo da chave de fechamento da sua função conferirPalpite():

+ +
envioPalpite.addEventListener('click', conferirPalpite);
+ +

Aqui nós estamos adicionando um event listener ao botão envioPalpite. Esse é um método que aceita a inserção de dois valores (chamados de argumentos) — o tipo de envento que estamos monitorando (neste caso o evento click) como um string (sequência de texto), e o código que queremos executar quando o evento ocorrer (neste caso a função conferirPalpite() — note que não temos que especificar os parênteses quando estivermos escrevendo dentro de {{domxref("EventTarget.addEventListener", "addEventListener()")}}).

+ +

Tente agora salvar e atualizar seu código, e seu exemplo deve funcionar agora, até um ponto. O único problema agora é que se você acertar o palpite ou ficar sem mais tentativas o jogo irá falhar, porque ainda não definimos a função configFimDeJogo() que deve ser executada uma vez que o jogo terminar. Vamos adicionar agora o código restante e completar a funcionalidade do nosso exemplo.

+ +

Finalizando a funcionalidade do jogo

+ +

Vamos adicionar a função configFimDeJogo() ao final do nosso código e então explorá-lo. Adicione agora isso, abaixo do restante do seu JavaScript:

+ +
function configFimDeJogo() {
+  campoPalpite.disabled = true;
+  envioPalpite.disabled = true;
+  botaoReinicio = document.createElement('button');
+  botaoReinicio.textContent = 'Iniciar novo jogo';
+  document.body.appendChild(botaoReinicio);
+  botaoReinicio.addEventListener('click', reiniciarJogo);
+}
+ + + +

Agora precisamos definir essa função também! Adicione o seguinte código, novamente ao final do nosso JavaScript:

+ +
function reiniciarJogo() {
+  contagemPalpites = 1;
+
+  var reiniciarParas = document.querySelectorAll('.resultadoParas p');
+  for (var i = 0 ; i < reiniciarParas.length ; i++) {
+    reiniciarParas[i].textContent = '';
+  }
+
+  botaoReinicio.parentNode.removeChild(botaoReinicio);
+
+  campoPalpite.disabled = false;
+  envioPalpite.disabled = false;
+  campoPalpite.value = '';
+  campoPalpite.focus();
+
+  ultimoResultado.style.backgroundColor = 'white';
+
+  numeroAleatorio = Math.floor(Math.random() * 100) + 1;
+}
+ +

Esse longo bloco de código redefine completamente tudo do modo como era no início do jogo, para que o jogador possa jogá-lo novamente. Ele:

+ + + +

Neste ponto você deve ter um jogo (simples) completamente funcional — parabéns!

+ +

Tudo o que temos que fazer agora neste artigo é falar sobre alguns outros recursos importantes que você já viu, mesmo que não os tenha notado ainda.

+ +

Loops

+ +

Uma parte do código acima que precisamos olhar mais detalhadamente é o loop for. Loop é um conceito muito importante em programação, que permite a você continuar executando um pedaço do código repetidamente, até que determinada condição seja satisfeita.

+ +

Para começar, vá novamente até o console JavaScript do seu navegador, e insira o seguinte:

+ +
for (var i = 1 ; i < 21 ; i++) { console.log(i) }
+ +

O que aconteceu? Os números de 1 a 20 foram exibidos no seu console. Isso acontece por causa do loop. Um loop for utiliza a inserção de três valores (argumentos):

+ +
    +
  1. Um valor inicial: Nesse caso estamos iniciando a contagem em 1, mas poderia ser qualquer outro número que quisesse utilizar. Você pode substituir i por qualquer número que quiser também, mas i é utilizado por convenção porque é curto e fácil de lembrar.
  2. +
  3. Uma condição de saída: Aqui nós especificamos i < 21 — o loop irá continuar rodando até que i não seja mais menor que 21. Quando i alcançar 21, o loop não será mais executado.
  4. +
  5. Incremento: Nós especificamos i++, que siginifica "adicione 1 à i". O loop irá rodar uma vez para cada valor de i, até que i alcance o valor de 21 (como abordado acima). Nesse caso, nós estamos simplesmente imprimindo o valor de i no console em cada iteração usando {{domxref("Console.log", "console.log()")}}.
  6. +
+ +

Agora vamos olhar o loop em nosso jogo de adivinhar o número — o código seguinte pode ser encontrado dentro da função reiniciarJogo():

+ +
var reiniciarParas = document.querySelectorAll('.resultadoParas p');
+for (var i = 0 ; i < reiniciarParas.length ; i++) {
+  reiniciarParas[i].textContent = '';
+}
+ +

Esse código cria uma variável contendo uma lista de todos os parágrafos dentro de <div class="resultadoParas"> usando o método {{domxref("Document.querySelectorAll", "querySelectorAll()")}}, e então faz o loop em cada um, removendo o conteúdo de texto dos mesmos.

+ +

Uma pequena discussão sobre objetos

+ +

Vamos adicionar uma melhoria final antes de chegarmos a essa discussão. Adicione a linha seguinte logo abaixo da linha var botaoReinicio; próximo ao topo do seu JavaScript, em seguida salve nosso arquivo:

+ +
campoPalpite.focus();
+ +

Essa linha usa o método {{domxref("HTMLElement.focus", "focus()")}} para automaticamente colocar o cursor dentro campo de texto do {{htmlelement("input")}} assim que a página carrega, significando que o usuário já pode começar a digitar o primeiro palpite, e não precisa clicar no campo do formulário primeiro. É apenas uma pequena adição, mas melhora a usabilidade — dando ao usuário uma boa dica visual do que ele deve fazer para jogar o jogo.

+ +

Vamos analisar o que está acontencedo aqui com um pouco mais de detalhes. Em JavaScript, tudo é um objeto. Um objeto é uma coleção de funcionalidades relacionadas armazenadas em um único agrupamento. Você pode criar seus próprios objetos, mas isso é bastante avançado e nós não iremos abordar até mais tarde no curso. Por agora, vamos apenas discutir brevemente os objetos pré-construídos presentes em seu navegador, que lhe permite fazer várias coisas úteis.

+ +

Neste caso particular, nós primeiro criamos a variável campoPalpite que armazena uma referência ao campo de inserção de texto do formulário em nosso HTML — a linha seguinte pode ser achada entre nossas declarações de variáveis próximas ao topo:

+ +
var campoPalpite = document.querySelector('.campoPalpite');
+ +

Para pegar essa referência, usamos o método {{domxref("document.querySelector", "querySelector()")}} do objeto {{domxref("document")}}. querySelector() pega um pedaço de informação — um seletor CSS que seleciona o elemento ao qual você quer referenciar.

+ +

Como agora campoPalpite contém referência ao elemento {{htmlelement("input")}}, ele terá agora acesso a um número de propriedades (basicamente variáveis armazenadas dentro de objetos, sendo que alguns não podem ter seus valores alterados) e métodos (basicamente, funções armazenadas dentro de objetos). Um método disponível para elementos de inserção <input>, é o focus(), então agora podemos usar essa linha para focar o campo de inserção de texto:

+ +
campoPalpite.focus();
+ +

Variáveis que não contém referências a elementos de formulário não terão focus() disponível para elas. Por exemplo, a variável palpites contém referência de um elemento {{htmlelement("p")}}, e contagemPalpites contém um número.

+ +

Brincando com objetos do navegador

+ +

Vamos brincar um pouco com alguns objetos do navegador.

+ +
    +
  1. Primeiro abra seu programa em um navegador.
  2. +
  3. Em seguida, abra as ferramentas de desenvolvimento do navegador, e certifique-se de que a aba do console JavaScript esteja aberta.
  4. +
  5. Digite campoPalpite e o console irá lhe mostrar que a variável contém um elemento {{htmlelement("input")}}. Você também irá notar que o console completa automaticamente os nomes de objetos existentes dentro do ambiente de execução, incluindo suas variáveis! +
      +
    1. Agora digite o seguinte: +
      campoPalpite.value = 'Olá';
      + A propriedade value representa o valor atual inserido no campo de texto. Você verá que inserindo esse comando, nós mudamos o valor desse objeto!
    2. +
    +
  6. +
  7. Agora tente digitar palpites e pressione return. O console irá mostrar que a variável contém um elemento {{htmlelement("p")}}.
  8. +
  9. Agora tente inserir a linha seguinte: +
    palpites.value
    + O navegador irá retornar undefined, porque value não existe em parágrafos.
  10. +
  11. Para mudar o texto dentro de um parágrafo, você precisa da propriedade {{domxref("Node.textContent", "textContent")}}. Tente isso: +
    palpites.textContent = 'Onde está meu parágrafo?';
    +
  12. +
  13. Agora algo divertido. Tente inserir as linhas abaixo, uma por uma: +
    palpites.style.backgroundColor = 'yellow';
    +palpites.style.fontSize = '200%';
    +palpites.style.padding = '10px';
    +palpites.style.boxShadow = '3px 3px 6px black';
    + Cada elemento em uma página tem uma propriedade style, que contém um objeto no qual estão inseridos em suas propriedades todos os estilos incorporados de CSS aplicados ao respectivo elemento. Isso nos permite configurar dinamicamente novos estilos CSS nos elementos usando JavaScript.
  14. +
+ +

Finalizado por enquanto...

+ +

Então é isso, para construir o exemplo — você chegou ao final, muito bem! Teste o resultado do seu código, ou jogue com nossa versão finalizada aqui. Se você não conseguir fazer o exemplo funcionar, compare com o código fonte.

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/What_is_JavaScript", "Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps")}}

diff --git a/files/pt-br/learn/javascript/first_steps/arrays/index.html b/files/pt-br/learn/javascript/first_steps/arrays/index.html new file mode 100644 index 0000000000..823b4c21f7 --- /dev/null +++ b/files/pt-br/learn/javascript/first_steps/arrays/index.html @@ -0,0 +1,662 @@ +--- +title: Arrays +slug: Learn/JavaScript/First_steps/Arrays +translation_of: Learn/JavaScript/First_steps/Arrays +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps/Silly_story_generator", "Learn/JavaScript/First_steps")}}
+ +

Neste artigo final do módulo, nós vamos dar uma olhada em arrays - um elegante meio de armazenar uma lista de itens em uma mesmo variável. Aqui nós vemos o porquê isto é útil, depois exploraremos como criar uma array, recuperar, adicionar e remover itens armazenados em uma array, e mais.

+ + + + + + + + + + + + +
Pré-requisitos:Leitura básica sobre computadores, um básico entendimento de HTML e CSS, e conhecimento sobre o que é JavaScript.
Objetivo:Entender o que é array e como manipular ela em JavaScript.
+ +

O que é uma array?

+ +

Arrays são geralmente descritas como "lista de objetos"; elas são basicamente objetos que contem múltiplos valores armazenados em uma lista. Um objeto array pode ser armazenado em variáveis e ser tratado de forma muito similar a qualquer outro tipo de valor, a diferença está em podermos acessar cada valor dentro da lista individualmente, e fazer super úteis e eficientes coisas com a lista, como laço através da lista e fazer a mesma coisa para cada valor. Talvez nós pegamos uma série de produtos e seus preços armazenados em uma array, e nós queremos fazer um laço através de todos eles e mostrar em um recibo, enquanto somamos todos os preços e mostramos o preço total ao final.

+ +

Se nós não tivessemos arrays, teríamos que armazenar cada item em uma variável separada, então chamar o código para mostrar e adicionar separadamente cada item. Isto seria muito mais longo de escrever, menos eficiente e mais suscetível a erros. Se nós temos 10 itens para adicionar na fatura, isto é ruim o bastante, mas e se fosse 100 itens ou 1000? Nós vamos retornar a este exemplo mais tarde neste artigo.

+ +

Como no artigo anterior, vamos aprender o básico de arrays introduzindo com alguns exemplos dentro de um console JavaScript. Nós fornecemos um abaixo (você também pode abrir este console em uma aba separada ou janela, ou usar o console de desenvolvedor do navegador se preferir).

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

+ +

Criando uma array

+ +

Arrays são contruídas de colchetes, os quais contém uma lista de itens separada por vírgulas.

+ +
    +
  1. Vamos supor que queremos armazenar uma lista de compras em uma array — nós temos algo como o seguinte. Digite as linhas abaixo no seu console: +
    var shopping = ['bread', 'milk', 'cheese', 'hummus', 'noodles'];
    +shopping;
    +
  2. +
  3. Neste caso, cada item na array é uma string, mas tenha em mente que você pode armazenar qualquer item em uma array — string, número, objeto, outra variável, até outra array. Você pode também misturar e combinar tipos de itens — eles não têm que ser todos números, strings, etc. Tente isto: +
    var sequence = [1, 1, 2, 3, 5, 8, 13];
    +var random = ['tree', 795, [0, 1, 2]];
    +
  4. +
  5. Tente criar um par de arrays você mesmo, antes de seguir em frente.
  6. +
+ +

Acessando e modificando itens de uma array

+ +

Você pode acessar itens individuais em uma array usando a notação de colchetes, da mesma forma que você acessa as letras em uma string.

+ +
    +
  1. Digite o seguinte no seu console: +
    shopping[0];
    +// returns "bread"
    +
  2. +
  3. Você também pode modificar um item em uma array simplesmente dando um novo valor ao item. Tente isto: +
    shopping[0] = 'tahini';
    +shopping;
    +// shopping vai retornar agora [ "tahini", "milk", "cheese", "hummus", "noodles" ]
    + +
    Note: Nós dissemos isto antes, mas como lembrete — computadores começam a contar do 0!
    +
  4. +
  5. Note que uma array dentro de uma array é chamada de array multidimensional. Você pode acessar um item dentro de uma array que está localizada dentro de outra array, colocando dois conjuntos de colchetes juntos. Por exemplo, para acessar um dos itens dentro de uma array, que é o terceiro item dentro da array random (veja a seção anterior), nós podemos fazer algo tipo isto: +
    random[2][2];
    +
  6. +
  7. Antes de continuar, faça algumas modificações nos exemplos, crie seus próprios arrays e veja o que funciona e o que não funciona. Divirta-se!
  8. +
+ +

Encontrando o comprimento de uma array

+ +

Você pode encontrar o comprimento de uma array (quantos itens existem nela) exatamente do mesmo jeito que você encontra o comprimento (em caracteres) de uma string — usando a propriedade {{jsxref("Array.prototype.length","length")}}. Tente o seguinte:

+ +
sequence.length;
+// deve retornar 7
+ +

Isto tem outras funcionalidades, mas é mais comum usar em um laço para seguir todos os itens em uma array. Então, por exemplo:

+ +
var sequence = [1, 1, 2, 3, 5, 8, 13];
+for (var i = 0; i < sequence.length; i++) {
+  console.log(sequence[i]);
+}
+ +

Você irá aprender sobre laços propriamente em um artigo futuro, mas, brevemente, este código está dizendo:

+ +
    +
  1. Comece o laço no item número 0 na array.
  2. +
  3. Pare o laço no item de número igual ao comprimento da array. Isto funcionará para uma array de qualquer tamanho, mas neste caso vai parar o laço no item 7 (isto é bom, como o último item — que nós queremos que o laço cubra — é 6.
  4. +
  5. Para cada item, imprima no console do navegador com console.log().
  6. +
+ +

Alguns métodos úteis em array

+ +

Nesta seção vamos ver alguns métodos relacionados a array úteis que nos permitem dividir strings em itens de array e vice-versa, e adicionar novos itens em arrays.

+ +

Convertendo entre strings e arrays

+ +

Frequentemente você vai se deparar com alguns dados contidos em uma grande e longa string, e você pode querer separar os itens em uma forma mais útil e então manipular eles, como mostrar em uma tabela. Para fazer isto, nós podemos usar o método {{jsxref("String.prototype.split()","split()")}}. Nesta forma mais simples, ela pega um parâmetro solitário, o caracter que você deseja separar da string e retorna o restante antes e depois do item separado na array.

+ +
+

Nota: Ok, isto é tecnicamente um método de string, não um método de array, mas nós podemos colocar em arrays já que cai bem.

+
+ +
    +
  1. Vamos brincar com isto para ver como funciona. Primeiro, crie uma string no seu console: +
    var myData = 'Manchester,London,Liverpool,Birmingham,Leeds,Carlisle';
    +
  2. +
  3. Agora vamos dividir isto em cada vírgula: +
    var myArray = myData.split(',');
    +myArray;
    +
  4. +
  5. Finalmente, tentamos encontrar o comprimento da sua nova array, e recuperar alguns itens dela: +
    myArray.length;
    +myArray[0]; // the first item in the array
    +myArray[1]; // the second item in the array
    +myArray[myArray.length-1]; // the last item in the array
    +
  6. +
  7. Você também pode ir no sentido oposto usando o método {{jsxref("Array.prototype.join()","join()")}}. Tente o seguinte: +
    var myNewString = myArray.join(',');
    +myNewString;
    +
  8. +
  9. Outro jeito de converter uma array em uma string é usar o método {{jsxref("Array.prototype.toString()","toString()")}}. toString() é indiscutivelmente mais simples join() pois não necessita um parâmetro, mas mais limitado. Com join() você pode especificar diferentes separadores (tente o passo 4 com um caracter diferente da vírgula). +
    var dogNames = ['Rocket','Flash','Bella','Slugger'];
    +dogNames.toString(); //Rocket,Flash,Bella,Slugger
    +
  10. +
+ +

Adicionando e removendo itens de arrays

+ +

Nós ainda não falamos sobre adicionar e remover itens de uma array — vamos dar uma olhada agora. Nós vamos usar a array myArray que acabamos de criar na última seção. Se você não viu a última seção, primeiro crie a array no seu console:

+ +
var myArray = ['Manchester', 'London', 'Liverpool', 'Birmingham', 'Leeds', 'Carlisle'];
+ +

Antes de tudo, para adicionar ou remover um item no final de uma array, nós podemos usar {{jsxref("Array.prototype.push()","push()")}} e {{jsxref("Array.prototype.pop()","pop()")}} respectivamente.

+ +
    +
  1. note que você precisa para incluir um ou mais itens ao final da sua array. Tente isto: +
    myArray.push('Cardiff');
    +myArray;
    +myArray.push('Bradford', 'Brighton');
    +myArray;
    +
    +
  2. +
  3. O novo comprimento da array é retornado quando a chamada do método completa. Se você quer armazenar o novo comprimento da array em uma variável, você poderia fazer algo como isto: +
    var newLength = myArray.push('Bristol');
    +myArray;
    +newLength;
    +
  4. +
  5. Removendo o último item da array é tão simples como um pop() nele. Tente isto: +
    myArray.pop();
    +
  6. +
  7. O item que foi removido é retornado quando a chamada do método completa. Para salvar o item em uma nova variável, você poderia fazer isto: +
    var removedItem = myArray.pop();
    +myArray;
    +removedItem;
    +
  8. +
+ +

{{jsxref("Array.prototype.unshift()","unshift()")}} e {{jsxref("Array.prototype.shift()","shift()")}} funciona exatamente do mesmo modo que push() e pop(), respectivamente, exceto que eles funcionam no começo da array, não no final.

+ +
    +
  1. Primeiro unshift() — tente os seguintes comandos: + +
    myArray.unshift('Edinburgh');
    +myArray;
    +
  2. +
  3. Agora shift();Tente estes! +
    var removedItem = myArray.shift();
    +myArray;
    +removedItem;
    +
  4. +
+ +

Aprendizado ativo: Imprimindo aqueles produtos!

+ +

Vamos retornar ao exemplo que descrevemos antes — imprimindo nomes de produtos e preços em uma fatura, então totalizando os preços e imprindindo eles ao final. No exemplo editável abaixo há comentários contendo números — cada um deles marcam um lugar onde você tem que acidionar algo ao código. Eles são como segue:

+ +
    +
  1. Abaixo do comentário // number 1 está um número de strings, cada uma contendo um nome de produto e preço separado por uma vírgula. Nós gostaríamos que você colocasse eles dentro de uma array e armazenasse eles na array chamada products.
  2. +
  3. Na mesma linha o comentário // number 2 está no começo de um laço for. Nesta linha nós temos i<=0, o qual é um teste condicional que faz o laço for parar imediatamente, porque está dizendo "pare quando i for menor ou igual a 0", e  i começa em 0. Nós gostaríamos de substituir isto com um teste condicional que termina o laço quando o i for menor que o tamanho da array products.
  4. +
  5. Logo abaixo do comentário // number 3 nós queremos que você escreva uma linha de código que divide o item da array (name:price) em dois itens separados, um contendo somente o nome e outro só com o preço. Se você não tem certeza de como fazer isto, consulte o artigo Métodos úteis em string para alguma ajuda, ou ainda melhor, veja a seção {{anch("Converting between strings and arrays")}} neste artigo.
  6. +
  7. Como parte da linha de código acima, você também quer converter o preço de string para número. Se você não se lembra como fazer isto, veja o artigo primeiras strings.
  8. +
  9. Há uma variável chamada total que é criada e atribuída o valor 0 no começo do código. Dentro do loop (abaixo // number 4) nós queremos que você escreva uma linha que adicione o preço atual ao total em cada iteração do laço, então ao final do código o preço total é impresso na fatura. Você pode precisar de um operador aritiméticos para isto.
  10. +
  11. Nós queremos que você mude a linha logo abaixo de // number 5 para que a variável itemText seja igual a "nome do item atual - $preço do item atual", por exemplo "Shoes - $23.99" em cada caso, então a informação correta para cada item é impressa na fatura. Esta é uma simples concatenação de string, a qual deveria ser familiar para você.
  12. +
+ + + +

{{ EmbedLiveSample('Playable_code', '100%', 730, "", "", "hide-codepen-jsfiddle") }}

+ +

Aprendizado ativo: Top 5 buscadores

+ +

Um bom uso para os métodos de array como {{jsxref("Array.prototype.push()","push()")}} e {{jsxref("Array.prototype.pop()","pop()")}} está quando você está mantendo um registro de itens atuais ativos em um aplicativo web. Em uma cena animada, por exemplo, você pode ter uma array de objetos representando o gráfico de fundo mostrado atualmente, e você pode querer somente mostrar 50 por vez, para performace ou alguma razão de ordem. Como novos objetos são criados e adicionados na array, os antigos podem ser deletados da array para manter o número desejado.

+ +

Neste exemplo nós vamos mostrar um uso bem mais simples — aqui nós estamos dando a você um falso site de busca, com uma caixa de busca. A idéia é que quando termos são digitados na caixa de busca, os 5 principais termos de busca anterior sejam mostrados na lista. Quando o número de termos passar de 5, o último termo começa sendo deletado. A cada vez um novo termo é adicionado ao topo, então os 5 termos anteriores são sempre mostrados.

+ +
+

Nota: Em um aplicativo de busca real, você seria, provavelmente, habilitado a clicar nos termos anteriores para retornar às pesquisas, e isto iria mostrar o reusltado atual! Nós estamos só mantendo simples, por agora.

+
+ +

Para completar o aplicativo, nós precisamos que você:

+ +
    +
  1. Adicione uma linha abaixo do comentário // number 1 que adicione o valor digitado atual na busca ao começo da array. Isto pode ser recuperado usando searchInput.value.
  2. +
  3. Adicione uma linha abaixo do comentário // number 2 que remova o último valor no fim da array.
  4. +
+ + + +

{{ EmbedLiveSample('Playable_code_2', '100%', 700, "", "", "hide-codepen-jsfiddle") }}

+ +

Conclusão

+ +

Depois de ler este artigo, nós temos certeza que você concordará que arrays parecem muito úteis; você verá elas surgirem em todo lugar em JavaScript, frequentemente associadas com laços para fazer a mesma coisa para cada item de uma array. Nós estaremos ensinando a você todo o básico que há para saber sobre laços no próximo módulo, mas por agora você deve se dar uma palmada de incentivo e dar uma bem merecida parada; você trabalhou durante todo os artigos neste módulo!

+ +

A única coisa que resta a fazer é trabalhar na avaliação deste módulo, a qual vai testar seu entendimento dos artigos anteriores a este.

+ +

Veja também

+ + + +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps/Silly_story_generator", "Learn/JavaScript/First_steps")}}

+ +

Neste módulo

+ + diff --git a/files/pt-br/learn/javascript/first_steps/gerador_de_historias_bobas/index.html b/files/pt-br/learn/javascript/first_steps/gerador_de_historias_bobas/index.html new file mode 100644 index 0000000000..cc8a8cc542 --- /dev/null +++ b/files/pt-br/learn/javascript/first_steps/gerador_de_historias_bobas/index.html @@ -0,0 +1,123 @@ +--- +title: Gerador de histórias bobas +slug: Learn/JavaScript/First_steps/Gerador_de_historias_bobas +translation_of: Learn/JavaScript/First_steps/Silly_story_generator +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}
+ +

Nesta avaliação, você será encarregado de utilizar parte do conhecimento que você adquiriu nos artigos deste módulo e aplicá-lo para criar um aplicativo divertido que gera histórias bobas aleatórias. Divirta-se!

+ + + + + + + + + + + + +
Pré-requisitos:Antes de tentar esta avaliação, você já deve ter trabalhado com todos os artigos deste módulo.
Objetivo:Testar a compreensão dos fundamentos de JavaScript, como variáveis, números, operadores, cadeias de caracteres e matrizes.
+ +

Ponto de partida

+ +

Para começar esta avaliação, você deve:

+ + + +
+

Nota: Alternativamente, você pode utilizar um site como JSBin ou Thimble para fazer a sua avaliação. Você pode colar o HTML, CSS e javaScript em um desses editores online. Se o editor online que você estiver utilizando não possuir um painel separado para javaScript, sinta-se a vontade para inseri-lo em um elemento <script> dentro da página HTML.

+
+ +

Resumo do projeto

+ +

Você recebeu algum HTML/CSS em bruto e algumas strings de texto e funções de JavaScript; Você precisa escrever o JavaScript necessário para transformar este em um programa funcional, que faz o seguinte:

+ + + +

A seguinte captura de tela mostra um exemplo do que o programa concluído deve produzir:

+ +

+ +

Para dar-lhe mais uma ideia, dê uma olhada no exemplo concluído (sem espreitar o código fonte!)

+ +

Passos para completar

+ +

As seções a seguir descrevem o que você precisa fazer.

+ +

Configuração básica:

+ +
    +
  1. Crie um novo arquivo chamado main.js, no mesmo diretório que o arquivo index.html.
  2. +
  3. Aplique o arquivo JavaScript externo ao seu HTML inserindo um elemento {{htmlelement ("script")}} no seu HTML referenciando o main.js. Coloque-o antes da etiqueta de fechamento {{htmlelement("body")}}.
  4. +
+ +

Variáveis e funções iniciais:

+ +
    +
  1. No arquivo de texto cru, copie todo o código abaixo do cabeçalho "1. COMPLETE VARIABLE AND FUNCTION DEFINITIONS" e cole-o no topo do arquivo main.js. Isso dá a você três variáveis que armazenam referências ao campo de texto "Inserir nome personalizado" (customName), o botão "Gerar história aleatória" (randomizar), E o elemento {{htmlelement ("p")}} na parte inferior do corpo HTML para onde a história será copiada (história), respectivamente. Além disso, você tem uma função chamada randomValueFromArray () que recebe um vetor e retorna um dos itens armazenados dentro do vetor aleatoriamente.
  2. +
  3. Agora, veja a segunda seção do arquivo de texto bruto - "2. RAW TEXT STRINGS". Ele contém strings de texto que atuarão como entrada em nosso programa. Gostaríamos que você armazenasse essas strings dentro de variáveis no main.js: +
      +
    1. Armazene a primeira, grande e longa linha de texto dentro de uma variável chamada storyText.
    2. +
    3. Armazene o primeiro conjunto de três strings dentro de um vetor chamado insertX.
    4. +
    5. Armazene o segundo conjunto de três strings dentro de um vetor chamado insertY.
    6. +
    7. Armazene o terceiro conjunto de três strings dentro de um vetor chamado insertZ.
    8. +
    +
  4. +
+ +

Colocando o manipulador de eventos e a função incompleta:

+ +
    +
  1. Agora volte ao arquivo de texto bruto.
  2. +
  3. Copie o código encontrado abaixo do cabeçalho "3. EVENT LISTENER AND PARTIAL FUNCTION DEFINITION" E cole ele na parte inferior do arquivo main.js. Isto: +
      +
    • Adicione um ouvinte de evento de clique à variável randomize para que, quando o botão que ele representa, for clicado, a função result() seja executada.
    • +
    • Adicione a função result() parcialmente concluída ao seu código. Para o restante da avaliação, você estará preenchendo linhas dentro desta função para completá-la e fazê-la funcionar corretamente.
    • +
    +
  4. +
+ +

Completando a função result():

+ +
    +
  1. Crie uma nova variável chamada newStory, e defina seu valor como igual a storyText. Isso é necessário para que possamos criar uma nova história aleatória toda vez que o botão for pressionado e a função for executada. Se fizermos alterações diretamente no storyText, só poderemos gerar uma nova história uma vez.
  2. +
  3. Crie três novas variáveis chamadas xItem, yItem, e zItem, e torne-as iguais ao resultado da chamada da função randomValueFromArray() em seus três arrays (o resultado em cada caso será um item aleatório de cada array em que é chamado). Por exemplo, você pode chamar a função e fazer com que ela retorne uma string aleatória de insertX escrevendo randomValueFromArray(insertX).
  4. +
  5. Em seguida, queremos substituir os três espaços reservados na variável newStory — :insertx:, :inserty:, e :insertz: — com strings armazenadas em xItem, yItem, e zItem. Existe um método de string específico que irá ajudá-lo aqui - em cada caso, faça a chamada para o método igual a newStory,então cada vez que é chamado, newStory é igual a si mesmo, mas com substituições feitas. Assim, cada vez que o botão é pressionado, esses espaços reservados são substituídos por uma string boba aleatória. Como uma dica adicional, o método em questão substitui apenas a primeira ocorrência da subseqüência de caracteres encontrada, portanto, talvez seja necessário fazer uma das chamadas duas vezes.
  6. +
  7. Dentro do primeiro bloco if, adicione outra chamada de método de substituição de string para substituir o nome 'Bob' encontrado na string newStory pela variável name. Neste bloco estamos dizendo "Se um valor foi inserido na entrada de texto customName, substitua Bob na história por esse nome personalizado ".
  8. +
  9. Dentro do segundo bloco if, estamos verificando se o botão de opção uk foi selecionado. Se assim for, converteremos os valores de peso e temperatura na história de libras e Fahrenheit em graus centígrados. O que você precisa fazer é o seguinte: +
      +
    1. Procure as fórmulas para converter libras em pedras e Fahrenheit em centígrados.
    2. +
    3. Dentro da linha que define a variável weight, substitua 300 por um cálculo que converta 300 libras em pedras. Concatene ' stone' no final do resultado da chamada geral Math.round().
    4. +
    5. Dentro da linha que define a variável temperature, substitua 94 por um cálculo que converta 94 graus Fahrenheit em graus centígrados. Concatene ' centigrade' no resultado da chamada geral Math.round().
    6. +
    7. Apenas sob as duas definições de variáveis, adicione mais duas linhas de substituição de string que substituem '94 fahrenheit' pelo conteúdo da variável temperature, e '300 libras' com o conteúdo da variável weight.
    8. +
    +
  10. +
  11. Finalmente, na segunda e última linha da função, torne a propriedadetextContent da variável story  (que faz referência ao parágrafo) igual a newStory.
  12. +
+ +

Dicas e sugestões

+ + + +

Avaliação

+ +

Se você estiver seguindo esta avaliação como parte de um curso organizado, você está apto a entregar seu trabalho ao seu professor/mentor para avaliação. Se você é auto-didata, então você pode consultar o guia de marcação com bastante facilidade perguntando  no tópico do Discurso da área de aprendizagem, ou no no canal #mdn IRC no IRC Mozilla. Tente realizar o exercício primeiro  — não há nada a ganhar com a trapaça!

+ +

{{PreviousMenu("Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}

diff --git a/files/pt-br/learn/javascript/first_steps/index.html b/files/pt-br/learn/javascript/first_steps/index.html new file mode 100644 index 0000000000..a7b30d2ad0 --- /dev/null +++ b/files/pt-br/learn/javascript/first_steps/index.html @@ -0,0 +1,73 @@ +--- +title: Primeiros passos com JavaScript +slug: Learn/JavaScript/First_steps +tags: + - Arrays + - Artigo + - Assessment + - Beginner + - CodingScripting + - Guia(2) + - Guide + - Iniciante + - JavaScript + - Landing + - Matrizes + - Module + - NeedsTranslation + - Numbers + - Operadores + - Operators + - TopicStub + - Variables + - maths + - strings +translation_of: Learn/JavaScript/First_steps +--- +
{{LearnSidebar}}
+ +

Em nosso primeiro módulo de JavaScript, vamos responder algumas questões fundamentais como "o que é JavaScript?", "com o que se parece?", e "o que ele pode fazer?", antes de levá-lo a sua primeira experiência em escrever JavaScript. Depois disso, vamos discutir em detalhes algumas peças chaves, como variáveis, cadeias de caracteres (strings), números (numbers) e matrizes (arrays).

+ +

Pré-requisitos

+ +

Antes de iniciar esse módulo, você não precisa de nenhum conhecimento prévio de JavaScript, mas você deve ter alguma familiaridade com HTML e CSS. Te recomendamos a estudar os seguintes módulos antes de começar com o JavaScript:

+ + + +
+

Nota: Se você está trabalhando em um computador/tablet/outro dispositivo onde você não pode criar os seus próprio arquivos, você pode experimentar (em sua maioria) os códigos de exemplo em um programa de codificação online como JSBin ou Thimble.

+
+ +

Guias

+ +
+
O que é JavaScript?
+
Bem vindo ao curso para iniciantes em JavaScript do MDN! No primeiro artigo nós visualizaremos o JavaScript de uma perspectiva de alto nível, respondendo a questões como "o que é?" e "o que ele pode fazer?", permitindo-lhe entender confortavelmente o objetivo do JavaScript.
+
Um primeiro mergulho no JavaScript
+
Agora que você tem uma noção teórica do JavaScript e o que você pode fazer com ele, nós vamos lhe dar um curso intensivo sobre as funcionalidades básicas do JavaScript através de um tutorial completamente prático. Aqui você ira construir, passo a passo, um jogo simples de "Advinhe o número".
+
O que deu errado? Solucionando problemas em JavaScript
+
Quando você construiu o jogo "Adivinhe o número" no artigo anterior, talvez tenha notado que ele não funcionou. Nunca tema — este artigo visa preservá-lo de ter que arrancar seus cabelos devido a esses problemas por prover-lhe alguns exemplos simples de como consertar erros em programas JavaScript.
+
Armazenando a informação necessária — Variáveis
+
Após ler os últimos artigos, você agora deve saber o que é o JavaScript, o que ele pode fazer para você, como usa-lo junto a com outras tecnologias web, e como sua funcionalidade principal se parece de um alto nível. Nesse artigo nós vamos ver o que é realmente básico, vendo como trabalhar com os mais básicos blocos de construção do JavaScript — Variáveis.
+
Matemática básica com JavaScript — números e operadores
+
Nesse ponto do curso nós iremos discutir matemática no JavaScript — como nós combinamos operadores e outras funcionalidades para manipular números para fazer nosso comando.
+
Manuseando textos — cadeia de caracteres (strings) em JavaScript
+
Em seguida nós colocaremos nossa atenção em strings — isso é como pedaços de texto são chamados na programação. Nesse artigos nós vamos ver todas as coisas comuns que você realmente deve saber sobre strings quando estiver aprendendo JavaScript, como criar strings, manusear aspas nas strings, e juntando elas.
+
Métodos úteis sobre cadeias de caracteres (strings)
+
Agora nós vemos o mais básico sobre strings, vamos começar a pensar sobre quais operações úteis nós podemos fazer com elas com os metótos internos, como por exemplos encontrar o tamanho do texto em uma strings, juntar e separar strings, substrituir um caractere de uma string e mais.
+
Matrizes
+
No artigo final desse módulo, nós iremos ver matrizes (arrays) — um jeito fácil de armazenar lista de dados em apenas um nome de variável. Aqui nós veremos o por quê disso ser útil, então exploraremos como criar uma matriz, retornar seus dados, adicionar e remover itens armazenas em um array, e mais além disso.
+
+ +

Avaliação

+ +

A avaliação seguinte vai testar o que você entendeu sobre o básico de JavaScript coberto pelos guias acima.

+ +
+
Gerador de histórias bobas
+
Nessa avaliação você será a desafiado a usar seu conhecimento adquirido nesse módulo e aplicará criando um divertido aplicativo que gerará histórias bobas aleatórias. Divirta-se.
+
diff --git a/files/pt-br/learn/javascript/first_steps/matematica/index.html b/files/pt-br/learn/javascript/first_steps/matematica/index.html new file mode 100644 index 0000000000..fce74528f7 --- /dev/null +++ b/files/pt-br/learn/javascript/first_steps/matematica/index.html @@ -0,0 +1,418 @@ +--- +title: Matemática básica no JavaScript — números e operadores +slug: Learn/JavaScript/First_steps/Matematica +tags: + - Artigo + - Código + - Guía + - Iniciante + - JavaScript + - Matemática + - Operadores + - Script + - aprenda + - aumentada + - incremento + - modulo +translation_of: Learn/JavaScript/First_steps/Math +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps")}}
+ +

Neste ponto do curso estaremos discutindo matemática em JavaScript — Como podemos usar {{Glossary("Operador","operadores")}} e outros recursos para manipular números e fazer cálculos.

+ + + + + + + + + + + + +
Pré-requisitos:Conhecimento básico em informática, uma compreensão básica de HTML e CSS, uma compreensão do que é o JavaScript.
Objetivo:Ganhar familiaridade com o básico em matemática no JavaScript.
+ +

Todo mundo ama matemática

+ +

Ok, talvez não. Alguns de nós gostam de matemática, alguns de nós tem a odiado desde que tivemos que aprender a tabuada de multiplicação e divisão na escola, e alguns de nós estão em algum lugar no meio dos dois cenários. Mas nenhum de nós pode negar que a matemática é uma parte fundamental da vida sem a qual não poderíamos ir muito longe. Isso é especialmente verdadeiro quando estamos aprendendo a programar em  JavaScript (ou em qualquer outra linguagem, diga-se de passagem) — muito do que fazemos se baseia no processamento de dados numéricos, cálculo de novos valores, etc. Assim você não ficará surpreso em aprender que o JavaScript tem uma configuração completa de funções matemáticas disponíveis.

+ +

Este artigo discute apenas as partes básicas que você precisa saber agora.

+ +

Tipos de números

+ +

Em programação, até mesmo o humilde sistema de números decimais que todos nós conhecemos tão bem é mais complicado do que você possa pensar. Usamos diferentes termos para descrever diferentes tipos de números decimais, por exemplo:

+ + + +

Temos até mesmo diferentes tipos de sistemas numéricos! O decimal tem por base 10 (o que significa que ele usa um número entre 0–9 em cada casa), mas temos também algo como:

+ + + +

Antes de se preocupar com seu cérebro estar derretendo, pare agora mesmo! Para um começo, vamos nos ater aos números decimais no decorrer desse curso; você raramente irá se deparar com a necessidade de começar a pensar sobre os outros tipos, se é que vai precisar algum dia.

+ +

A segunda boa notícia é que, diferentemente de outras linguagens de programação, o JavaScript tem apenas um tipo de dados para números, você advinhou, {{jsxref("Number")}}. Isso significa que qualquer que seja o tipo de números com os quais você está lidando em JavaScript, você os manipula do mesmo jeito.

+ +

Tudo é número para mim

+ +

Vamos brincar rapidamente com alguns números para nos familiarizarmos com a sintaxe básica que precisamos. Insira os comandos listados abaixo em seu console JavaScript, ou use o console simples incorporado abaixo, se preferir.

+ +

{{EmbedGHLiveSample("learning-area-pt-br/javascript/introduction-to-js-1/variables/index.html", '100%', 300)}}

+ +

Abra em uma nova janela

+ +
    +
  1. Primeiramente, vamos declarar duas variáveis e as inicializar com um integer e um float, respectivamente, então digitaremos os nomes das variávei para verificar se está tudo em ordem: + +
    var meuInt = 5;
    +var meuFloat = 6.667;
    +meuInt;
    +meuFloat;
    +
  2. +
  3. Valores numéricos são inseridos sem aspas — tente declarar e inicializar mais duas variáveis contendo números antes de seguir em frente.
  4. +
  5. Agora vamos checar se nossas duas variáveis originais são do mesmo tipo de dados. Há um operador chamado {{jsxref("Operators/typeof", "typeof")}} no JavaScript que faz isso. Insira as duas linhas conforme mostradas abaixo: +
    typeof meuInt;
    +typeof meuFloat;
    + Você deve obter "number" de volta nos dois casos — isso torna as coisas muito mais fáceis para nós do que se diferentes tipos de números tivessem diferentes tipos de dados, e tivéssemos que lidar com eles em diferentes maneiras. Ufa!
  6. +
+ +

Operadores aritméticos

+ +

São os operadores que utilizamos para fazer as operações aritiméticas básicas:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperadorNomePropósitoExemplo
+AdiçãoAdiciona um número a outro.6 + 9
-SubtraçãoSubtrai o número da direita do número da esquerda.20 - 15
*MultiplicaçãoMultiplica um número pelo outro.3 * 7
/DivisãoDivide o número da esquerda pelo número da direita.10 / 5
%Restante (Remainder - as vezes chamado de modulo) +

Retorna o resto da divisão em números inteiros do número da esquerda pelo número da direita.

+
8 % 3 (retorna 2; como três cabe duas vezes em 8, deixando 2 como resto.)
+ +
+

Nota: Você verá algumas vezes números envolvidos em aritimética chamados de {{Glossary("Operando", "operandos")}}.

+
+ +

Nós provavelmente não precisamos ensinar a você como fazer matemática básica, mas gostaríamos de testar seu entendimento da sintaxe envolvida. Tente inserir os exemplos abaixo no seu console JavaScript, ou use o console incorporado visto anteriormente, se preferir, para familiarizar-se com a sintaxe.

+ +
    +
  1. Primeiro tente inserir alguns exemplos simples por sua conta, como +
    10 + 7
    +9 * 8
    +60 % 3
    +
  2. +
  3. Você pode tentar declarar e inicializar alguns números dentro de variáveis, e tentar usá-los nas operações — as variáveis irão se comportar exatamente como os valores que elas armazenam para a finalidade das operações. Por exemplo: +
    var num1 = 10;
    +var num2 = 50;
    +9 * num1;
    +num2 / num1;
    +
  4. +
  5. Por último, nesta seção, tente inserir algumas expressões mais complexas, como: +
    5 + 10 * 3;
    +num2 % 9 * num1;
    +num2 + num1 / 8 + 2;
    +
  6. +
+ +

Alguns dos exemplos do último bloco podem não ter retornado os valores que você estava esperando; a seção abaixo pode lhe explicar o porquê.

+ +

Precedência de operador

+ +

Vamos olhar para o último exemplo, assumindo que num2 guarda o valor 50 e num1 possui o valor 10 (como iniciado acima):

+ +
num2 + num1 / 8 + 2;
+ +

Como um ser humano, talvez você leia isso como "50 mais 10 é igual a 60", depois "8 mais 2 é igual a 10", e então "60 dividido por 10 é igual a 6".

+ +

No entanto seu navegador vai ler "10 dividido por 8 é igual a 1.25", então "50 mais 1.25 mais 2 é igual a 53.25".

+ +

Isto acontence por causa da precedência de operadores — algumas operações serão aplicadas antes de outras quando calcularmos o resultado de uma soma (referida em programação como uma expressão).  A precedência de operadores em JavaScript é semelhante ao ensinado nas aulas de matemática na escola — Multiplicação e divisão são realizados primeiro, depois a adição e subtração (a soma é sempre realizada da esquerda para a direita).

+ +

Se você quiser substituir a precedência do operador, poderá colocar parênteses em volta das partes que desejar serem explicitamente tratadas primeiro. Então, para obter um resultado de 6, poderíamos fazer isso:

+ +
(num2 + num1) / (8 + 2);
+ +

Tente fazer e veja como fica.

+ +
+

Nota: Uma lista completa de todos os operadores JavaScript e suas precedências pode ser vista em Expressões e operadores.

+
+ +

Operadores de incremento e decremento

+ +

Às vezes você desejará adicionar ou subtrair, repetidamente, um valor de uma variável numérica. Convenientemente isto pode ser feito usando os operadores incremento ++ e decremento --. Usamos ++  em nosso jogo "Adivinhe o número" no primeiro artigo  Um primeiro mergulho no JavaScript, quando adicionamos 1 ao nosso contagemPalpites para saber quantas adivinhações o usuário deixou após cada turno.

+ +
contagemPalpites++;
+ +
+

Nota: Eles são mais comumente usado em Laços e iterações, que será visto no curso mais tarde. Por exemplo, digamos que você queira passar por uma lista de preços e adicionar imposto sobre vendas a cada um deles. Você usaria um loop para passar por cada valor e fazer o cálculo necessário para adicionar o imposto sobre vendas em cada caso. O incrementador é usado para mover para o próximo valor quando necessário. Na verdade, fornecemos um exemplo simples mostrando como isso é feito - verifique ao vivo e observe o código-fonte para ver se consegue identificar os incrementadores! Veremos os loops detalhadamente mais adiante no curso.

+
+ +

Vamos tentar brincar com eles no seu console. Para começar, note que você não pode aplicá-las diretamente a um número, o que pode parecer estranho, mas estamos atribuindo a variável um novo valor atualizado, não operando no próprio valor. O seguinte retornará um erro:

+ +
3++;
+ +

Então, você só pode incrementar uma variável existente. Tente isto: 

+ +
var num1 = 4;
+num1++;
+ +

Ok, segunda coisa estranha! Quando você fizer isso, verá um valor 4 retornado - isso ocorre porque o navegador retorna o valor atual e, em seguida, incrementa a variável. Você pode ver que ele foi incrementado se você retornar o valor da variável novamente:

+ +
num1;
+ +

Acontece a mesma coisa com -- : tente o seguinte

+ +
var num2 = 6;
+num2--;
+num2;
+ +
+

Nota: Você pode fazer o navegador fazer o contrário - incrementar/decrementar a variável e depois retornar o valor, colocando o operador no início da variável ao invés do final. Tente os exemplos acima novamente, mas desta vez use  ++num1 e --num2.

+
+ +

Operadores de atribuição

+ +

Operadores de atribuição são os que atribuem um valor à uma variável. Nós já usamos o básico, =, muitas vezes, simplesmente atribuindo à variável do lado ersquerdo o valor indicado do lado direito do operador:

+ +
var x = 3; // x contém o valor 3
+var y = 4; // y contém o valor 4
+x = y; // x agora contém o mesmo valor de y, 4
+ +

Mas existem alguns tipos mais complexos, que fornecem atalhos úteis para manter seu código mais puro e mais eficiente. Os mais comuns estão listados abaixo:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperatorNamePurposeExampleShortcut for
+=Atribuição de adiçãoAdiciona o valor à direita ao valor da variável à esquerda e, em seguida, retorna o novo valor da variávelx = 3;
+ x += 4;
x = 3;
+ x = x + 4;
-=Atribuição de subtraçãoSubtrai o valor à direita do valor da variável à esquerda e retorna o novo valor da variávelx = 6;
+ x -= 3;
x = 6;
+ x = x - 3;
*=Atribuição de multiplicaçãoMultiplica o valor da variável à esquerda pelo valor à direita e retorna o novo valor da variávelx = 2;
+ x *= 3;
x = 2;
+ x = x * 3;
/=Atribuição de divisãoDivide o valor da variável à esquerda pelo valor à direita e retorna o novo valor da variávelx = 10;
+ x /= 5;
x = 10;
+ x = x / 5;
+ +

Tente digitar alguns dos exemplos acima em seu console para ter uma ideia de como eles funcionam. Em cada caso, veja se você pode adivinhar qual é o valor antes de digitar a segunda linha.

+ +

Note que você pode muito bem usar outros valores ​​no lado direito de cada expressão, por exemplo:

+ +
var x = 3; // x contém o valor 3
+var y = 4; // y contém o valor 4
+x *= y; // x agora contém o valor 12
+ +
+

Nota: Existem muitos outros operadores de atribuição disponíveis, mas estes são os básicos que você deve aprender agora.

+
+ +

Aprendizado ativo: dimensionando uma canvas box

+ +

Neste exercício, você manipulará alguns números e operadores para alterar o tamanho de uma caixa. A caixa é desenhada usando uma API do navegador chamada {{domxref("Canvas API", "", "", "true")}}. Não há necessidade de se preocupar sobre como isso funciona, apenas concentre-se na matemática por enquanto. A largura e altura da caixa (em pixels) são definidas pelas variáveis x e y, que recebem um valor inicial de 50.

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/editable_canvas.html", '100%', 520)}}

+ +

Abrir em nova janela

+ +

Na caixa de código editável acima, há duas linhas marcadas com um comentário que gostaríamos que você atualizasse para aumentar/diminuir a caixa para determinados tamanhos, usando determinados operadores e/ou valores em cada caso. Vamos tentar o seguinte:

+ + + +

Não se preocupe se você estragar totalmente o código. Você sempre pode pressionar o botão Reset para fazer as coisas funcionarem novamente. Depois de ter respondido corretamente a todas as perguntas acima, sinta-se à vontade para brincar um pouco com o código ou crie seus próprios desafios.

+ +

Operadores de comparação

+ +

Às vezes, queremos executar testes verdadeiro / falso e, em seguida, agir de acordo, dependendo do resultado desse teste, para fazer isso, usamos operadores de comparação.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OperatorNamePurposeExample
===Igualdade estritaVerifica se o valor da esquerda e o da direita são idênticos entre si.5 === 2 + 4
!==Não-igualdade-estritaVerifica se o valor da esquerda e o da direita não são idênticos entre si.5 !== 2 + 3
<Menor queVerifica se o valor da esquerda é menor que o valor da direita.10 < 6
>Maior queVerifica se o valor da esquerda é maior que o valor da direita.10 > 20
<=Menor ou igual queVerifica se o valor da esquerda é menor que ou igual ao valor da direita.3 <= 2
>=Maior ou igual queVerifica se o valor da esquerda é maior que ou igual ao valor da direita.5 >= 4
+ +
+

Nota: Talvez você já tenha visto alguém usando == e!= afim de testar igualdade ou desigualdade em JavaScript. Estes são operadores válidos em JavaScript, mas que diferem de ===/!==. As versões anteriores testam se os valores são os mesmos, mas não se os tipos de dados dos valores são os mesmos. As últimas versões estritas testam a igualdade de ambos os valores e seus tipos de dados. Elas tendem a resultar em menos erros, por isso recomendamos que você as use.

+
+ +

Se você tentar inserir alguns desses valores em um console, verá que todos eles retornam true/false — aqueles booleanos que mencionamos no último artigo. Eles são muito úteis, pois nos permitem tomar decisões em nosso código, e eles são usados ​​toda vez que queremos fazer uma escolha de algum tipo. Por exemplo, booleanos podem ser usados ​​para:

+ + + +

Veremos como codificar essa lógica quando examinarmos instruções condicionais em um artigo futuro. Por enquanto, vamos dar uma olhada em um exemplo rápido:

+ +
<button>Iniciar máquina</button>
+<p>A máquina está parada.</p>
+
+ +
var btn = document.querySelector('button');
+var txt = document.querySelector('p');
+
+btn.addEventListener('click', updateBtn);
+
+function updateBtn() {
+   if (btn.textContent === 'Iniciar máquina') {
+       btn.textContent = 'Parar máquina';
+       txt.textContent = 'A máquina iniciou!';
+   } else {
+       btn.textContent = 'Iniciar máquina';
+       txt.textContent = 'A máquina está parada.';
+   }
+}
+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/maths/conditional.html", '100%', 100)}}

+ +

Abrir em nova janela

+ +

Você pode ver o operador de igualdade sendo usado apenas dentro da função updateBtn(). Neste caso, não estamos testando se duas expressões matemáticas têm o mesmo valor, estamos testando se o conteúdo de texto de um botão contém uma certa string , mas ainda é o mesmo princípio em funcionamento. Se o botão estiver dizendo "Iniciar máquina" quando for pressionado, mudaremos o rótulo para "Parar máquina" e atualizaremos o rótulo conforme apropriado. Se o botão estiver dizendo "Parar máquina" quando for pressionado, nós trocamos a tela de volta.

+ +
+

Nota: Esse controle que troca entre dois estados geralmente é chamado de toggle. Ele alterna entre um estado e outro - acender, apagar, etc.

+
+ +

Resumo

+ +

Neste artigo, cobrimos as informações fundamentais que você precisa saber sobre números em JavaScript, por enquanto. Você verá os números sendo usados ​​de novo e de novo, durante todo o aprendizado de JavaScript. Portanto, é uma boa ideia tirar isso do caminho agora. Se você é uma daquelas pessoas que não gosta de matemática, pode se consolar com o fato de este capítulo ser muito curto.

+ +

No próximo artigo, vamos explorar o texto e como o JavaScript nos permite manipulá-lo.

+ +
+

Nota: Se você gosta de matemática e quer saber mais sobre como ela é implementada em JavaScriot, você pode encontrar muito mais detalhes na seção principal de JavaScript do MDN. Ótimos lugares para começar são os artigos Números e datas e Expressões e operadores .

+
+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps")}}

diff --git a/files/pt-br/learn/javascript/first_steps/o_que_e_javascript/index.html b/files/pt-br/learn/javascript/first_steps/o_que_e_javascript/index.html new file mode 100644 index 0000000000..771541b047 --- /dev/null +++ b/files/pt-br/learn/javascript/first_steps/o_que_e_javascript/index.html @@ -0,0 +1,435 @@ +--- +title: O que é JavaScript? +slug: Learn/JavaScript/First_steps/O_que_e_JavaScript +tags: + - API + - Aprender + - Artigo + - Código Script + - Iniciante + - JavaScript + - Navegador + - Núcleo + - O que + - Script + - comentários + - externo + - inline + - 'l10n:prioridade' + - terceiros +translation_of: Learn/JavaScript/First_steps/What_is_JavaScript +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps")}}
+ +

Sejam bem-vindos ao curso de JavaScript para iniciantes do MDN! Neste primeiro artigo vamos fazer uma análise profunda da linguagem, respondendo questões como "O que é JavaScript?", e "O que ele faz?", para você se sentir confortável com a proposta da linguagem.

+ + + + + + + + + + + + +
Pré requisitos:Interação básica com o computador, entendimento básico de HTML e CSS.
Objetivo:Se familiarizar com a linguagem, com o que ela pode fazer, e como tudo isso pode ser utilizado em um website.
+ +

Definição de alto nível

+ +

JavaScript é uma linguagem de programação que permite a você implementar itens complexos em páginas web — toda vez que uma página da web faz mais do que simplesmente mostrar a você informação estática — mostrando conteúdo que se atualiza em um intervalo de tempo, mapas interativos ou gráficos 2D/3D animados, etc. — você pode apostar que o JavaScript provavelmente está envolvido. É a terceira camada do bolo das tecnologias padrões da web, duas das quais (HTML e CSS) nós falamos com muito mais detalhes em outras partes da Área de Aprendizado.

+ +

+ + + +

As três camadas ficam muito bem uma em cima da outra. Vamos exemplificar com um simples bloco de texto. Nós podemos marcá-lo usando HTML para dar estrutura e propósito: 

+ +
<p>Jogador 1: Chris</p>
+ +

+ +

Nós podemos adicionar um pouco de CSS na mistura, para deixar nosso parágrafo um pouco mais atraente:

+ +
p {
+  font-family: 'helvetica neue', helvetica, sans-serif;
+  letter-spacing: 1px;
+  text-transform: uppercase;
+  text-align: center;
+  border: 2px solid rgba(0,0,200,0.6);
+  background: rgba(0,0,200,0.3);
+  color: rgba(0,0,200,0.6);
+  box-shadow: 1px 1px 2px rgba(0,0,200,0.4);
+  border-radius: 10px;
+  padding: 3px 10px;
+  display: inline-block;
+  cursor:pointer;
+}
+ +

+ +

E finalmente, nós podemos adicionar JavaScript para implementar um comportamento dinâmico:

+ +
const para = document.querySelector('p');
+
+para.addEventListener('click', atualizarNome);
+
+function atualizarNome() {
+  var nome = prompt('Insira um novo nome');
+  para.textContent = 'Jogador 1: ' + nome;
+}
+
+ +

{{ EmbedLiveSample('Definição_de_alto_nível', '100%', 80) }}

+ +

Experimente clicar no botão acima para ver o que acontece (note também que você pode encontrar essa demonstração no GitHub — veja o código fonte ou veja funcionar)!

+ +

JavaScript pode fazer muito mais do que isso — vamos explorar com mais detalhes.

+ +

Então o que ele pode realmente fazer?

+ +

O núcleo da linguagem JavaScript consiste em alguns benefícios comuns da programação que permite a você fazer coisas como:

+ + + +

O que é ainda mais empolgante é a funcionalidade construída no topo do núcleo da linguagem JavaScript. As APIs (Application Programming Interfaces - Interface de Programação de Aplicativos) proveem a você superpoderes extras para usar no seu código JavaScript.

+ +

APIs são conjuntos prontos de blocos de construção de código que permitem que um desenvolvedor implemente programas que seriam difíceis ou impossíveis de implementar. Eles fazem o mesmo para a programação que os kits de móveis prontos para a construção de casas - é muito mais fácil pegar os painéis prontos e parafusá-los para formar uma estante de livros do que para elaborar o design, sair e encontrar a madeira, cortar todos os painéis no tamanho e formato certos, encontrar os parafusos de tamanho correto e depois montá-los para formar uma estante de livros.

+ +

Elas geralmente se dividem em duas categorias.

+ +

APIs de terceiros e APIs do navegador

+ +

APIs de navegadores já vem implementadas no navegador, e são capazes de expor dados do ambiente do computador, ou fazer coisas complexas e úteis. Por exemplo:

+ + + +
+

Nota: Muitas demonstrações acima não vão funcionar em navegadores antigos — quando você for experimentar, é uma boa ideia usar browsers modernos como Firefox, Edge ou Opera para ver o código funcionar. Você vai precisar estudar testes cross browser com mais detalhes quando você estiver chegando perto de produzir código (código real que as pessoas vão usar).

+
+ +

APIs de terceiros não estão implementados no navegador automaticamente, e você geralmente tem que pegar seu código e informações em algum lugar da Web. Por exemplo:

+ + + +
+

Note: Essas APIs são avançadas e nós não vamos falar sobre nenhuma delas nesse módulo.Vo cê pode achar muito mais sobre elas em nosso módulo APIs web no lado cliente.

+
+ +

Tem muito mais coisas disponíveis! Contudo, não fique animado ainda. Você não estará pronto para desenvolver o próximo Facebook, Google Maps ou Instagram depois de estudar JavaScript por 24 horas — há um monte de coisas básicas para estudar primeiro. E é por isso que você está aqui — vamos começar! 

+ +

O que JavaScript está fazendo na sua página web?

+ +

Aqui nós vamos realmente começar a ver algum código, e enquanto fazemos isso vamos explorar o que realmente acontece quando você roda algum código JavaScript na sua página.

+ +

Vamos recaptular brevemente a história do que acontece quando você carrega uma página web em um navegador (falamos sobre isso no nosso artigo Como o CSS funciona). Quando você carrega uma página web no seu navegador, você está executando seu código (o HTML, CSS e JavaScript) dentro de um ambiente de execução (a guia do navegador). Isso é como uma fábrica que pega a matéria prima (o código) e transforma em um produto (a página web).

+ +

+ +

Um uso muito comum do JavaScript é modificar dinamicamente HTML e CSS para atualizar uma interface do usuário, por meio da API do Document Object Model (conforme mencionado acima). Observe que o código em seus documentos web geralmente é carregado e executado na ordem em que aparece na página. Se o JavaScript carregar e tentar executar antes do carregamento do HTML e CSS afetado, poderão ocorrer erros. Você aprenderá maneiras de contornar isso mais adiante neste artigo, na seção Estratégias de carregamento de scripts .

+ +

Segurança do navegador

+ +

Cada guia do navegador tem seu próprio espaço para executar código (esses espaços são chamados de "ambientes de execução", em termos técnicos) — isso significa que na maioria dos casos o código em cada guia está sendo executado separadamente, e o código em uma guia não pode afetar diretamente o código de outra guia — ou de outro website. Isso é uma boa medida de segurança — se esse não fosse o caso, então hackers poderiam começar a escrever código para roubar informações de outros websites, e fazer outras coisas más.

+ +
+

Nota: Há muitas maneiras de trocar código e conteúdo entre diferentes websites/guias de uma forma segura, mas são técnicas avançadas que não serão estudadas nesse curso.

+
+ +

Ordem de execução do JavaScript

+ +

Quando o navegador encontra um bloco de código JavaScript, ele geralmente executa na ordem, de cima para baixo. Isso significa que você precisa ter cuidado com a ordem na qual você coloca as coisas. Por exemplo, vamos voltar ao bloco JavaScript que nós vimos no primeiro exemplo:

+ +
const para = document.querySelector('p');
+
+para.addEventListener('click', atualizarNome);
+
+function atualizarNome() {
+  ;et nome = prompt('Informe um novo nome:');
+  para.textContent = 'Jogador 1: ' + nome;
+}
+ +

Aqui nós estamos selecionando um parágrafo (linha 1) e anexando a ele um event listener (linha 3). Então, quando o parágrafo recebe um clique, o bloco de código atualizarNome() (linhas 5 a 8) é executado. O bloco de código atualizarNome()(esses tipos de bloco de código reutilizáveis são chamados "funções") pede ao usuário que informe um novo nome, e então insere esse nome no parágrafo, atualizando-o.

+ +

Se você inverte a ordem das duas primeiras linhas de código, ele não fucionaria — em vez disso, você receberia um erro no console do navegador — TypeError: para is undefined. Isso significa que o objeto para não existe ainda, então nós não podemos adicionar um event listener a ele.

+ +
+

Nota: Esse é um erro muito comum — você precisa verificar se os objetos aos quais você se refere no seu código existem antes de você tentar anexar coisas a eles.

+
+ +

Código interpretado x compilado

+ +

Você pode ouvir os termos interpretado compilado no contexto da programação. JavaScript é uma linguagem interpretada — o código é executado de cima para baixo e o resultado da execução do código é imediatamente retornado. Você não tem que transformar o código em algo diferente antes do navegador executa-lo.

+ +

Linguagens compiladas, por outro lado, são transformadas (compiladas) em algo diferente antes que sejam executadas pelo computador. Por exemplo, C/C++ são compiladas em linguagem Assembly, e depois são executadas pelo computador.

+ +

JavaScript é uma linguagem de programação leve e interpretada. O navegador recebe o código JavaScript em sua forma de texto original e executa o script a partir dele. Do ponto de vista técnico, a maioria dos intérpretes modernos de JavaScript realmente usa uma técnica chamada compilação just-in-time para melhorar o desempenho; o código-fonte JavaScript é compilado em um formato binário mais rápido enquanto o script está sendo usado, para que possa ser executado o mais rápido possível. No entanto, o JavaScript ainda é considerado uma linguagem interpretada, pois a compilação é manipulada em tempo de execução, e não antes.

+ +

Há vantagens em ambos os tipos de linguagem, mas nós não iremos discutir no momento.

+ +

Lado do servidor x Lado do cliente

+ +

Você pode também ouvir os termos lado do servidor (server-side) e lado do cliente (client-side), especialmente no contexto de desenvolvimento web. Códigos do lado do cliente são executados no computador do usuário — quando uma página web é visualizada, o código do lado do cliente é baixado, executado e exibido pelo navegador. Nesse módulo JavaScript nós estamos explicitamente falando sobre JavaScript do lado do cliente.

+ +

Códigos do lado do servidor, por outro lado, são executados no servidor e o resultado da execução é baixado e exibido no navegador. Exemplos de linguagens do lado do servidor populares incluem PHP, Python, Ruby, e ASP.NET. E JavaScript! JavaScript também pode ser usada como uma linguagem server-side, por exemplo, no popular ambiente Node.js — você pode encontrar mais sobre JavaScript do lado do servidor no nosso tópico Websites dinâmicos - Programação do lado do servidor.

+ +

Código dinâmico x estático

+ +

A palavra dinâmico é usada para descrever tanto o JavaScript client-side como o server-side — essa palavra se refere a habilidade de atualizar a exibição de uma página web/app para mostrar coisas diferentes em circunstâncias diferentes, gerando novo conteúdo como solicitado. Código do lado do servidor dinamicamente gera novo conteúdo no servidor, puxando dados de um banco de dados, enquanto que JavaScript do lado do cliente dinamicamente gera novo conteúdo dentro do navegador do cliente, como criar uma nova tabela HTML com dados recebidos do servidor e mostrar a tabela em uma página web exibida para o usuário. Os significados são ligeiramente diferente nos dois contextos, porém relacionados, e ambos (JavaScript server-side e client-side) geralmente trabalham juntos.

+ +

Uma página web sem atualizações dinâmicas é chamada de estática — ela só mostra o mesmo conteúdo o tempo todo.

+ +

Como você adiciona JavaScript na sua página?

+ +

O JavaScript é inserido na sua página de uma maneira similar ao CSS. Enquanto o CSS usa o elemento {{htmlelement("link")}} para aplicar folhas de estilo externas e o elemento {{htmlelement("style")}} para aplicar folhas de estilo internas, o JavaScript só precisa de um amigo no mundo do HTML — o elemento {{htmlelement("script")}}. Vamos aprender como funciona.

+ +

JavaScript interno

+ +
    +
  1. Antes de tudo, faça uma cópia local do nosso arquivo de exemplo aplicando-javascript.html. Salve-o em alguma pasta, de uma forma sensata.
  2. +
  3. Abra o arquivo no seu navegador web e no seu editor de texto. Você verá que o HTML cria uma simples página web contendo um botão clicável.
  4. +
  5. Agora, vá até o seu editor de texto e adicione o código a seguir antes da tag de fechamento </body>: +
    <script>
    +
    +  // O JavaScript fica aqui
    +
    +</script>
    +
  6. +
  7. Agora nós vamos adicionar um pouco de JavaScript dentro do nosso elemento {{htmlelement("script")}} para que a página faça algo mais interessante — adicione o seguinte código abaixo da linha "// O JavaScript fica aqui": +
    function criarParagrafo() {
    +  let para = document.createElement('p');
    +  para.textContent = 'Você clicou no botão!';
    +  document.body.appendChild(para);
    +}
    +
    +const botoes = document.querySelectorAll('button');
    +
    +for(var i = 0; i < botoes.length ; i++) {
    +  botoes[i].addEventListener('click', criarParagrafo);
    +}
    +
  8. +
  9. Salve seu arquivo e recarregue a página — agora você deveria ver que quando você clique no botão, um novo parágrafo é gerado e colocado logo abaixo.
  10. +
+ +
+

Nota: Se seu exemplo não parece funcionar, leia cada passo novamente e confira que você fez tudo certo. Você salvou sua cópia local do código inicial como um arquivo .html? Você adicionou o elemento {{htmlelement("script")}} imediatamente antes da tag </body>? Você digitou o código JavaScript exatamente como ele está sendo mostrado? JavaScript é uma linguagem case sensitive (isso significa que a linguagem vê diferença entre letras maiúsculas e minúsculas) e muito confusa, então você precisa digitar a sintaxe exatamente como foi mostrada, senão não vai funcionar.

+
+ +
+

Nota: Você pode ver essa versão no GitHub como apicando-javascript-interno.html (veja funcionar também).

+
+ +

JavaScript externo

+ +

Isso funciona muito bem, mas e se nós quiséssemos colocar nosso JavaScript em um arquivo externo? Vamos explorar isso agora.

+ +
    +
  1. Primeiro, crie um novo arquivo na mesma pasta que está o arquivo HTML de exemplo. Chame-o de script.js — tenha certeza de que o nome do arquivo tem a extensão .js, pois é assim que ele será reconhecido como JavaScript.
  2. +
  3. Agora substitua o elemento atual {{htmlelement("script")}} pelo seguinte código: +
    <script src="script.js" defer></script>
    +
  4. +
  5. Em script.js, adidione o seguinte script: +
    function createParagraph() {
    +  let para = document.createElement('p');
    +  para.textContent = 'Você clicou no botão!';
    +  document.body.appendChild(para);
    +}
    +
    +const buttons = document.querySelectorAll('button');
    +
    +for(let i = 0; i < buttons.length ; i++) {
    +  buttons[i].addEventListener('click', createParagraph);
    +}
    +
  6. +
  7. Salve e atualize seu navegador, e você deverá ver a mesma coisa! Funciona igualmente, mas agora nós temos o JavaScript em um arquivo externo. Isso é geralmente uma coisa boa em termos de organização de código, e faz com que seja possível reutilizar o código em múltiplos arquivos HTML. Além disso, o HTML fica mais legível sem grandes pedaços de script no meio dele.
  8. +
+ +
+

Nota: Você pode ver essa versão no GitHub como aplicando-javascript-externo.html e script.js (veja funcionar também).

+
+ +

Manipuladores de JavaScript inline

+ +

Note que às vezes você vai encontrar código JavaScript escrito dentro do HTML. Isso deve ser algo como:

+ +
+
function criarParagrafo() {
+  let para = document.createElement('p');
+  para.textContent = 'Você clicou o botao!';
+  document.body.appendChild(para);
+}
+ +
+
<button onclick="criarParagrafo()">Me clique!</button>
+
+ +

Você pode tentar essa versão na nossa demonstração abaixo.

+ +

+ +

Essa demonstração tem exatamente a mesma funcionalidade que vimos nas primeiras duas seções, exceto que o elemento {{htmlelement("button")}} inclui um manipulador inline onclick para fazer a função ser executada quando o botão é clicado.

+ +

Contudo, por favor, não faça isso. É uma má prática poluir seu HTML com JavaScript, e isso é ineficiente — você teria que incluir o atributo onclick="criarParagrafo()" em todo botão que você quisesse aplicar JavaScript.

+ +

Usando uma estrutura feita de puro JavaScript permite a você selecionar todos os botões usando uma instrução. O código que nós usamos acima para servir a esse propósito se parece com isso:

+ +
const botoes = document.querySelectorAll('button');
+
+for(var i = 0; i < botoes.length ; i++) {
+  botoes[i].addEventListener('click', criarParagrafo);
+}
+ +

Isso talvez parece ser mais do que o atributo onclick, mas isso vai funcionar para todos os botões, não importa quantos tem na página, e quantos forem adicionados ou removidos. O JavaScript não precisará ser mudado.

+ +
+

Nota: Tente editar a sua versão do arquivo aplicar-javascript.html, adicionando alguns botões a mais. Quando você recarregar, você deverá ver que todos os botões, quando clicados, irão criar parágrafos. Agradável, não?

+
+ +

Estratégias para o carregamento de scripts

+ +

Há um considerável número de problemas envolvendo o carregamento de scripts na ordem correta. Infelizmente, nada é tão simples quanto parece ser! Um problema comum é que todo o HTML de uma página é carregado na ordem em que ele aparece. Se você estiver usando Javascript para manipular alguns elementos da página (sendo mais preciso, manipular o Document Object Model), seu código não irá funcionar caso o JavaScript for carregado e executado antes mesmo dos elementos HTML estarem disponíveis.

+ +

Nos exemplos acima, tanto nos scripts internos ou externos, o JavaScript é carregado e acionado dentro do cabeçalho do documento, antes do corpo da página ser completamente carregado. Isso poderá causar algum erro. Assim, temos algumas soluções para isso.

+ +

No exemplo interno, você pode ver essa estrutura em volta do código:

+ +
document.addEventListener("DOMContentLoaded", function() {
+  ...
+});
+ +

Isso é um event listener (ouvidor de eventos), que ouve e aguarda o disparo do evento "DOMContentLoaded" vindo do browser, evento este que significa que o corpo do HTML está completamente carregado e pronto. O código JavaScript que estiver dentro desse bloco não será executado até que o evento seja disparado, portanto, o erro será evitado (você irá aprender sobre eventos mais tarde).

+ +

No exemplo externo, nós usamos um recurso moderno do JavaScript para resolver esse problema: Trata-se do atributo defer, que informa ao browser para continuar renderizando o conteúdo HTML uma vez que a tag <script> foi atingida.

+ +
<script src="script.js" defer></script>
+ +

Neste caso, ambos script e HTML irão carregar de forma simultânea e o código irá funcionar.

+ +
+

Nota: No caso externo, nós não precisamos utilizar o evento DOMContentLoaded porque o atributo defer resolve o nosso problema. Nós não utilizamos defer como solução para os exemplos internos pois defer funciona apenas com scripts externos.

+
+ +

Uma solução à moda antiga para esse problema era colocar o elemento script bem no final do body da página (antes da tag </body>). Com isso, os scripts iriam carregar logo após todo o conteúdo HTML. O problema com esse tipo de solução é que o carregamento/renderização do script seria completamente bloqueado até que todo o conteúdo HTML fosse analisado. Em sites de maior escala, com muitos scripts, essa solução causaria um grande problema de performance e deixaria o site lento. 

+ +

async e defer

+ +

Atualmente, há dois recursos bem modernos que podermos usar para evitar o problema com o bloqueio de scripts — asyncdefer (que vimos acima). Vamos ver as diferenças entre esses dois?

+ +

Os scripts que são carregados usando o atributo async (veja abaixo) irão baixar o script sem bloquear a renderização da página e irão executar imediatamente após o script terminar de ser disponibilizado. Nesse modo você não tem garantia nenhuma que os scripts carregados irão rodar em uma ordem específica, mas saberá que dessa forma eles não irão impedir o carregamento do restante da página. O melhor uso para o async é quando os scripts de uma página rodam de forma independente entre si e também não dependem de nenhum outro script.

+ +

Por exemplo, se você tiver os seguintes elementos script:

+ +
<script async src="js/vendor/jquery.js"></script>
+
+<script async src="js/script2.js"></script>
+
+<script async src="js/script3.js"></script>
+ +

Você não pode garantir que o script. jquery.js carregará antes ou depois do script2.jsscript3.js . Nesse caso, se alguma função desses scripts dependerem de algo vindo do jquery, ela produzirá um erro pois o jquery ainda não foi definido/carregado quando os scripts executaram essa função.

+ +

async deve ser usado quando houver muitos scripts rodando no background, e você precisa que estejam disponíveis o mais rápido possível. Por exemplo, talvez você tenha muitos arquivos de dados de um jogo para carregar que serão necessários assim que o jogo iniciar, mas por enquanto, você só quer entrar e ver a tela de carregamento, a do titulo do jogo e o lobby, sem ser bloqueado pelo carregamento desses scripts.

+ +

Scripts que são carregados utilizando o atributo defer (veja abaixo) irão rodar exatamente na ordem em que aparecem na página e serão executados assim que o script e o conteúdo for baixado.

+ +
<script defer src="js/vendor/jquery.js"></script>
+
+<script defer src="js/script2.js"></script>
+
+<script defer src="js/script3.js"></script>
+ +

Todos os scripts com o atributo defer irão carregar na ordem que aparecem na página. No segundo exemplo, podemos ter a certeza que o script jquery.js irá carregar antes do script2.jsscript3.js e o script2.js irá carregar antes do script3.js. Os scripts não irão rodar sem que antes todo o conteúdo da página seja carregado, que no caso, é muito útil se os seus scripts dependem de um DOM completamente disponibilizado em tela (por exemplo, scripts que modificam um elemento).

+ +

Resumindo:

+ + + +

Comentários

+ +

Assim como HTML e CSS, é possível escrever comentários dentro do seu código JavaScript que serão ignorados pelo navegador, e existirão simplesmente para prover instruções aos seus colegas desenvolvedores sobre como o código funciona (e pra você, se você tiver que voltar ao seu código depois de 6 meses e não se lembrar do que fez). Comentários são muito úteis, e você deveria usá-los frequentemente, principalmente quando seus códigos forem muito grandes. Há dois tipos:

+ + + +

Então, por exemplo, você poderia fazer anotações na nossa última demonstração de código JavaScript, da seguinte forma:

+ +
// Função: Cria um novo parágrafo e o insere no fim do arquivo HTML.
+
+function criarParagrafo() {
+  var para = document.createElement('p');
+  para.textContent = 'Você clicou no botão!';
+  document.body.appendChild(para);
+}
+
+/*
+  1. Captura referências de todos os botões na página e armazena isso em um array.
+  2. Vai até todos os botões e adiciona um event listener click a cada um deles.
+
+  Quando cada botão é clicado, a função criarParagrafo() será executada.
+*/
+
+const botoes = document.querySelectorAll('button');
+
+for(var i = 0; i < botoes.length ; i++) {
+  botoes[i].addEventListener('click', criarParagrafo);
+}
+ +
+

Nota: Em geral mais comentários são melhores que menos, porém você deve tomar cuidado para não adicionar comentários de mais tentando explicar o que uma variável é (o nome da sua variável deve ser mais intuitivo), ou tentando explicar uma operação simples (talvez seu código seja muito complicado denecessariamente).

+
+ +

Sumário

+ +

Então, esse foi o seu primeiro passo no mundo do JavaScript. Nós iniciamos apenas com teoria, então te ensinamos porque usar JavaScript e que tipo de coisa você pode fazer com ele. Pelo caminho você viu alguns códigos de exemplo e aprendeu como JavaScript se encaixa com o resto do código do seu site, entre outras coisas.

+ +

O JavaScript talvez pareça um pouco assustador agora, mas não se preocupe — nesse curso você será guiado passo a passo, e tudo vai começar a fazer sentido. No próximo artigo vamos mergulhar direto para a prática, levando você a construir seu próprio código JavaScript.

+ +

{{NextMenu("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps")}}

+ +

Neste módulo:

+ + +
diff --git a/files/pt-br/learn/javascript/first_steps/strings/index.html b/files/pt-br/learn/javascript/first_steps/strings/index.html new file mode 100644 index 0000000000..299c6e33a8 --- /dev/null +++ b/files/pt-br/learn/javascript/first_steps/strings/index.html @@ -0,0 +1,284 @@ +--- +title: Trabalhando com texto — strings em JavaScript +slug: Learn/JavaScript/First_steps/Strings +translation_of: Learn/JavaScript/First_steps/Strings +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps")}}
+ +

Agora vamos dar atenção às strings - isto é como é chamado em programação qualquer parte de texto. Neste artigo nós veremos tudo que você realmente deve saber sobre strings quando está aprendendo JavaScript. Como criar, fazer citações e como juntar strings.

+ + + + + + + + + + + + +
Pré-requisitos:Computação básica, um entendimento básico de HTML e CSS, e sobre o que é JavaScript.
Objetivo:Ganhar familiaridade com o básico de strings em JavaScript.
+ +

O poder das palavras

+ +

Palavras são muito importante para humanos - elas são uma grande parte de como nos comunicamos. Desde que a Web é largamente baseada em texto, projetada para permitir humanos a comunicar e compartilhar infomação, isto é útil para nós termos controle sobre como apresentar isso. {{glossary("HTML")}} fornece estrutura e significado para nosso texto, {{glossary("CSS")}} nos permite estilizar precisamente ele, e JavaScript contem um número de funcionalidades para manipular strings, criar mensagens de boas-vindas customizadas, mostrando rótulos quando preciso, sorteando termos de acordo como desejado e muito mais.

+ +

Muitos dos programas que temos visto até agora no curso está envolvido em alguma parte com manipulação de string.

+ +

Strings — O básico

+ +

Em um primeiro relance, strings são tratadas de forma parecida como números, mas quando vamos mais a fundo, você começa a ver algumas diferenças importantes. Vamos começar a entrar em linhas básicas no console para nos familiarizar. Nós vamos fornecer abaixo (você pode também abrir isto no console em uma guia ou janela separada, ou usar o  console do navegador se você preferir).

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300, "", "", "hide-codepen-jsfiddle") }}

+ +

Criando uma string

+ +
    +
  1. Para começar, digite as linhas seguintes: +
    var string = 'The revolution will not be televised.';
    +string;
    + Como fizemos com números, nós declaramos uma variável, inicializando-a com um valor string, e então retornamos o valor. A única diferença aqui é que quando escrevemos uma string, você precisa colocá-la entre aspas.
  2. +
  3. Se você não fez isso, ou esqueceu uma das aspas, você recebeu um erro. Experimente digitar as linhas seguintes: +
    var badString = This is a test;
    +var badString = 'This is a test;
    +var badString = This is a test';
    + Estas linhas não funcionam porque todo texto sem aspas são interpretados como um nome de variável, propriedade do nome, palavra reservada ou algo assim. Se o navegador não puder encontrar, então um é erro é apresentado (ex.: "faltando; declaração anterior"). Se o navegador puder ver onde a string começa, mas não conseguir encontrar o fim, como indicado com as segundas aspas, é retornado um erro (com "string não terminada"). Se seu programa retorna tais erros, então volte e verifique todas suas strings para ter certeza que não faltam aspas.
  4. +
  5. O seguinte funcionará se você definiu previamente a variável string - tente isto agora: +
    var badString = string;
    +badString;
    + badString é agora definido para ter o mesmo valor de string.
  6. +
+ +

Aspas simples x aspas duplas

+ +
    +
  1. Em JavaScript, você pode escolher aspas simples ou duplas para envolver suas strings. Ambas linhas abaixo funcionará bem: +
    var sgl = 'Single quotes.';
    +var dbl = "Double quotes";
    +sgl;
    +dbl;
    +
  2. +
  3. Há poucas diferenças entre as duas, e qual você usar é de preferência pessoal. Você deve escolher uma e permanecer nela, entretanto; diferentes aspas no código pode ser confuso, especialmente se você usa diferentes aspas na mesma string! O seguinte retornará erro: +
    var badQuotes = 'What on earth?";
    +
  4. +
  5. O navegador interpretará como a string não tivesse fechada, porque o outro tipo de aspas pode aparecer dentro da sua string. Por exemplo, ambos exemplos abaixo são okay: +
    var sglDbl = 'Would you eat a "fish supper"?';
    +var dblSgl = "I'm feeling blue.";
    +sglDbl;
    +dblSgl;
    +
  6. +
  7. Entretanto, você não pode incluir o mesmo tipo de aspas dentro da sua string, se você usa para conter seu texto. O seguinte será um erro, como é confuso para o navegador onde a string termina: +
    var bigmouth = 'I've got no right to take my place...';
    + Isto nos leva muito bem ao nosso próximo assunto.
  8. +
+ +

Caracteres de escape na string

+ +

Para corrigir o problema anterior, nós precisamos escapar o problema da aspa. Caracteres de escape significa que nós fazemos algo para ter certeza que eles são reconhecidos como texto, não parte do código. Em JavaScript, nós fazemos isso colocando uma barra invertida logo antes do caracter.Tente isso:

+ +
var bigmouth = 'I\'ve got no right to take my place...';
+bigmouth;
+ +

Isto funciona bem. Você pode escapar outros caracteres do mesmo jeito, ex.: \",  e há alguns códigos especiais também. Veja Notação de escape para mais detalhes.

+ +

Concatenando strings

+ +
    +
  1. Concatenar é uma palavra chique da programação que significa "colocar junto". Para colocar strings juntas em JavaScript, usamos o operador (+), o mesmo usamos para adicionar números, mas neste contexto é algo diferente. Vamos tentar este exemplo no console. +
    var one = 'Hello, ';
    +var two = 'how are you?';
    +var joined = one + two;
    +joined;
    + O resultado disso é uma variável chamada joined, que contém o valor "Hello, how are you?".
  2. +
  3. No último exemplo, nós somente juntamos duas strings, mas você pode fazer quantas quiser, contanto que inclua um + entre cada uma.Experimente isso: +
    var multiple = one + one + one + one + two;
    +multiple;
    +
  4. +
  5. Você pore usar um mix de variáveis e strings reais. Tente isso: +
    var response = one + 'I am fine — ' + two;
    +response;
    +
  6. +
+ +
+

Nota: Quando você coloca uma string atual no seu código dentro de aspas simples ou duplas, é chamada uma string literal.

+
+ +

Concatenação em contexto

+ +

Vamos dar uma olhada na concatenação em ação — aqui está um exemplo do curso anterior:

+ +
<button>Pressione-me</button>
+ +
var button = document.querySelector('button');
+
+button.onclick = function() {
+  var nome = prompt('Qual é o seu nome?');
+  alert('Olá ' + nome + ', prazer em conhecê-lo!');
+}
+ +

{{ EmbedLiveSample('Concatenation_in_context', '100%', 50, "", "", "hide-codepen-jsfiddle") }}

+ +

Aqui estamos usando uma função {{domxref("Window.prompt()", "Window.prompt()")}} na linha 4, a qual pergunta ao usuário para responder uma questão via uma caixa de diálogo, então armazena o texto em uma variável — neste caso nome. Nós então usamos uma função {{domxref("Window.alert()", "Window.alert()")}} na linha 5 para mostrar outra caixa de diálogo contendo nossa string montada de duas strings literais e a variável name,via concatenação.

+ +

Números x strings

+ +
    +
  1. Então o que acontece quando tentamos adicionar (ou concatenar) uma string e um número? Vamos tentar isso no console: +
    'Front ' + 242;
    +
    + Você pode esperar um erro disto, mas funciona correto. Tentando representar  uma string como um número, realmente não faz sentido. Mas representando um número como string, faz. Então o navegador espertamente converte o número em string e concatena as duas.
  2. +
  3. Você pode fazer isto até com dois números — você pode forçar um número a ser string colocando ele entre aspas. Experimente o seguinte (nós estamos usando o operador typeof para checar o que a variável é, se um número ou string): +
    var myDate = '19' + '67';
    +typeof myDate;
    +
  4. +
  5. Se você tem uma variável numérica que precisa converter em string, mas não mudar completamente, ou uma string e quer converter em número, você pode usar a construção seguinte: +
      +
    • O objeto {{jsxref("Number")}} converterá qualquer coisa passada em um número, se for possível. Tente o seguinte: +
      var myString = '123';
      +var myNum = Number(myString);
      +typeof myNum;
      +
    • +
    • Por outro lado, todo número tem um método chamado toString() que converterá para a string equivalente. Tente isto: +
      var myNum = 123;
      +var myString = myNum.toString();
      +typeof myString;
      +
    • +
    + Estas construções podem ser bem úteis em algumas situações. Por exemplo, se o usuário colocar um número em um campo de texto, isso será uma string. Entretanto, se você quiser adicionar este número a algo, você precisa que seja um número, então você pode passar isto através do Number() para poder manipular.Nós fizemos exatamente isto no nosso Number Guessing Game, in line 61.
  6. +
+ +

Conclusão

+ +

Então isto é o basico sobre strings em JavaScript. No próximo artigo nós iremos continuar daqui, vendo alguns métodos de construção de strings disponíveis em JavaScript e como nós podemos usá-los para manipular nossa string da forma como quisermos.

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps/Useful_string_methods", "Learn/JavaScript/First_steps")}}

+ + + +

Neste módulo

+ + 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/teste_suas_habilidades_colon__variaveis/index.html new file mode 100644 index 0000000000..1a14c86630 --- /dev/null +++ b/files/pt-br/learn/javascript/first_steps/teste_suas_habilidades_colon__variaveis/index.html @@ -0,0 +1,85 @@ +--- +title: 'Teste suas habilidades: variáveis' +slug: 'Learn/JavaScript/First_steps/Teste_suas_habilidades:_variaveis' +tags: + - Aprender + - Habilidades + - Iniciante + - JavaScript + - Teste suas habilidades + - Variáveis +translation_of: 'Learn/JavaScript/First_steps/Test_your_skills:_variables' +--- +
{{learnsidebar}}
+ +

O objetivo deste teste de habilidade é avaliar se você entendeu nosso artigo Armazenando as informações que você precisa — Variáveis.

+ +
+

Nota: Você pode experimentar soluções nos editores interativos abaixo. No entanto, pode ser útil fazer o download do código e usar uma ferramenta on-line como CodePen, jsFiddle, ou Glitch para realizar as tarefas.
+
+ Se você travar, peça ajuda — veja a seção {{anch("Assessment or further help")}} na parte inferior desta página.

+
+ +
+

Note: Nos exemplos abaixo, se houver um erro no seu código, ele será exibido no painel de resultados da página, para ajudá-lo a tentar descobrir a resposta (ou no console JavaScript do navegador, no caso da versão para download).

+
+ +

Variáveis 1

+ +

Nesta tarefa, queremos que você:

+ + + +

Tente atualizar o código ativo abaixo para recriar o exemplo final:

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/variables/variables1.html", '100%', 400)}}

+ +
+

Faça o download do ponto de partida para esta tarefa funcionar em seu próprio editor ou em um editor online.

+
+ +

Variáveis 2

+ +

Nesta tarefa, você precisa adicionar uma nova linha para corrigir o valor armazenado na variável meuNome existente para seu próprio nome.

+ +

Tente atualizar o código ativo abaixo para recriar o exemplo final:

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/variables/variables2.html", '100%', 400)}}

+ +
+

Faça o download do ponto de partida para esta tarefa funcionar em seu próprio editor ou em um editor online.

+
+ +

Variáveis 3

+ +

A tarefa final por enquanto — neste caso, você recebe um código existente, que possui dois erros. O painel de resultados deve exibir o nome Chris, e uma declaração sobre quantos anos Chris terá daqui a 20 anos. Como você pode corrigir o problema e corrigir a saída?

+ +

Tente atualizar o código ativo abaixo para recriar o exemplo final:

+ +

{{EmbedGHLiveSample("learning-area/javascript/introduction-to-js-1/tasks/variables/variables3.html", '100%', 400)}}

+ +
+

Faça o download do ponto de partida para esta tarefa funcionar em seu próprio editor ou em um editor online.

+
+ +

Avaliação ou ajuda adicional

+ +

Você pode praticar esses exemplos nos editores interativos acima.

+ +

Se você gostaria que seu trabalho fosse avaliado, ou está travado e quer pedir ajuda:

+ +
    +
  1. Coloque seu trabalho em um editor compartilhável on-line, como CodePen, jsFiddle, ou Glitch. Você pode escrever o código você mesmo ou usar os arquivos de ponto de partida vinculados nas seções acima.
  2. +
  3. Escreva um post pedindo avaliação e/ou ajuda na categoria MDN Discourse forum Learning. Seu post deve incluir: +
      +
    • Um título descritivo como "Avaliação desejada para o teste de habilidade Variáveis 1".
    • +
    • Detalhes do que você já tentou e o que gostaria que fizéssemos. Por exemplo, se você está travado e precisa de ajuda ou deseja uma avaliação.
    • +
    • Um link para o exemplo que você deseja que seja avaliado ou precisa de ajuda, em um editor compartilhável online (conforme mencionado na etapa 1 acima). Esta é uma boa prática para entrar - é muito difícil ajudar alguém com um problema de codificação se você não conseguir ver o código.
    • +
    • Um link para a página real de tarefas ou avaliações, para que possamos encontrar a pergunta com a qual você deseja ajuda.
    • +
    +
  4. +
diff --git a/files/pt-br/learn/javascript/first_steps/useful_string_methods/index.html b/files/pt-br/learn/javascript/first_steps/useful_string_methods/index.html new file mode 100644 index 0000000000..3304dd800e --- /dev/null +++ b/files/pt-br/learn/javascript/first_steps/useful_string_methods/index.html @@ -0,0 +1,484 @@ +--- +title: Métodos úteis de string +slug: Learn/JavaScript/First_steps/Useful_string_methods +translation_of: Learn/JavaScript/First_steps/Useful_string_methods +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}
+ +

Agora que nós vimos o básico de strings, vamos engatar a próxima marcha e começar a pensar sobre as operações úteis que podemos fazer em strings com métodos embutidos, como encontrar o comprimento de um string, unir e dividir sequências de caracteres, substituindo um caracter em uma string por outro, e muito mais.

+ + + + + + + + + + + + +
Pré-requisitos:Conhecimento básico de computador, uma compreensão básica de HTML e CSS, uma compreensão do que é o JavaScript.
Objetivo: +

Entender que strings são objetos e aprender a usar alguns do métodos básicos disponíveis nesses objetos para manipular strings.

+
+ +

Strings como objetos

+ +

Como dissemos antes e diremos novamente — tudo é um objeto em JavaScript. Quando você cria um string, usando por exemplo

+ +
var string = 'This is my string';
+ +

sua variável torna-se uma instância do objeto string e, como resultado, tem um grande número de propriedades e métodos diponíveis para ela. Você pode ver isso se você for na página do objeto {{jsxref("String")}} e olhar para baixo na lista do lado da página!

+ +

Agora, antes de seu cérebro começar a derreter, não se preocupe! Você não precisa saber sobre a maioria deles no início da sua jornada de aprendizado. Mas há alguns que você potencialmente usará com bastante frequência que veremos aqui.

+ +

Vamos digitar alguns exemplos em um console novo. Nós fornecemos um abaixo (você também pode abrir este console em uma guia ou janela separada, ou usar o console do desenvolvedor do navegador, se preferir).

+ +

Nós fornecemos um abaixo (você também pode abrir esse console em uma aba ou janela separada, ou usar o console do navegador do desenvolvedor se você preferir).

+ + + +

{{ EmbedLiveSample('Hidden_code', '100%', 300) }}

+ +

Descobrindo o comprimento de uma string

+ +

Essa é fácil  — você simplesmente usa a propriedade {{jsxref("String.prototype.length", "length")}}. Tente digitar as linhas a seguir:

+ +
var browserType = 'mozilla';
+browserType.length;
+ +

Isso deve retornar o número 7, porque "mozilla"  tem 7 caracteres. Isso é útil por vários motivos; por exemplo, você pode querer encontrar os comprimentos de uma série de nomes para que você possa exibi-los em ordem de comprimento, ou deixar um usuário saber que um nome de usuário que ele informou em um campo de formulário é muito longo se este for maior do que um certo comprimento.

+ +

Recuperando um caractere de string específico

+ +

Nota complementar: você pode retornar qualquer caractere dentro de uma string usando a notação colchete - isso significa que você inclui colchetes ([]) no final do nome da variável. Dentro dos colchetes, você inclui o número do caractere que deseja retornar, por exemplo, para recuperar a primeira letra, faça o seguinte:

+ +
browserType[0];
+ +

Computadores contam a partir de 0, não 1! Para recuperar o último caractere de qualquer string, nós podemos usar a linha a seguir, combinando essa técnica com a propriedade length que vimos anteriormente:

+ +
browserType[browserType.length-1];
+ +

O comprimento de "mozilla" é 7, mas porque a contagem começa de 0, a posição do caractere é 6, daí precisamos usar length-1. Você pode usar isso para, por exemplo, encontrar a primeira letra de uma série de strings e ordená-los alfabeticamente.

+ +

Encontrando uma substring dentro de uma string e extraindo-a

+ +
    +
  1. Às vezes você quer sabe se uma string menor está presente dentro de uma maior (geralmente dizemos se uma substring está presente dentro de uma string). Isso pode ser feito usando o método {{jsxref ("String.prototype.indexOf ()", "indexOf ()")}}, que leva um único {{glossary ("parameter")}} - a substring que deseja procurar. Experimente isso: + +
    browserType.indexOf('zilla');
    + Isso nos dá o resultado 2, porque a substring "zilla" se inicia na posição 2 (0, 1, 2  — então, 3 caraceteres) dentro de "mozilla". Esse código poderia ser usado para filtrar cadeias de caracteres. Por exemplo, podemos ter uma lista de endereços da web e apenas queremos imprimir aqueles que contenham "mozilla".
  2. +
  3. Isso pode ser feito de outro jeito, que é possivelmente mais eficaz. Experimente isso: +
    browserType.indexOf('vanilla');
    + Isso deve lhe dar um resultado -1 — isso é retornado quando a substring, neste caso 'vanilla', não é encontrada na string principal.
    +
    + Você pode usar isso para encontrar todas as instâncias de strings que não contém a substring 'mozilla', ou contém, se você usar o operador de negação, conforme mostrado abaixo. Você poderia fazer algo assim: + +
    if(browserType.indexOf('mozilla') !== -1) {
    +  // faz coisas com a string
    +}
    +
  4. +
  5. Quando você sabe onde uma substring começa dentro de uma string e você sabe em qual caractere você deseja que ela termine, {{jsxref ("String.prototype.slice ()", "slice ()")}} pode ser usado para extrair isto. Tente o seguinte: +
    browserType.slice(0,3);
    + Isso retorna "moz" — o primeiro parâmetro é a posição do caractere a partir da qual será iniciada a extração, e o segundo parâmetro é a posição seguinte do último caractere a ser extraído. Então, a fatia ocorre da primeira posição, até a última posição, mas não incluindo. Você também pode dizer que o segundo parâmetro é igual ao comprimento da string que está sendo retornada.
  6. +
+ +

Também, se você sabe que você deseja extrair todos os caracteres restantes em uma string após um certo caracter, você não tem que incluir o segundo parametro! Você apenas precisa incluir a posição do caracter a partir de onde você deseja extrar os caracteres restantes em uma string. Tente o seguinte: 

+ +
browserType.slice(2);
+ +

Isso retornará "zilla" — isso é porque a posição de caracter 2 é a letra z, e porque você não incluiu o segundo parametro, a substring retornou todos os caracteres restantes na string. 

+ +
+

Note: O segundo parametro do slice() é opcional: Se você não incluir ele, o slice finaliza no fim da string original. Existem outras opções também; estude a {{jsxref("String.prototype.slice()", "slice()")}} pagina para ver o que mais você pode descobrir.

+
+ +

Mudando entre maiúsculas e minúsculas

+ +

O método string {{jsxref("String.prototype.toLowerCase()", "toLowerCase()")}} e {{jsxref("String.prototype.toUpperCase()", "toUpperCase()")}} toma a string e converte todos os caracteres para minusculo - ou maiusculo, respectivamente. Este pode ser util, por exemplo, se você quer normalizar todas as entradas de dados do usuário antes de armazenar em um banco de dados.

+ +

Vamos testar inserindo as seguintes linhas para ver o que acontece:

+ +
var radData = 'My NaMe Is MuD';
+radData.toLowerCase();
+radData.toUpperCase();
+ +

Atualizando partes de uma string

+ +

Você pode substituir uma substring dentro de uma string com uma outra substring usando o método {{jsxref("String.prototype.replace()", "replace()")}}. Este funciona muito simples em um nível básico, apesar haver algumas coisas avançadas que você pode fazer com ele, nós não iremos tão longe ainda.

+ +

Ele toma dois parametros — A string que você quer substituir e a string que você quer que substitua o primeiro parametro. Tente este exemplo:

+ +
browserType.replace('moz','van');
+ +

Observe que para realmente obter o valor atualizado refletido na variavel browserType em um programa real, você teria que setar o valor da variavel para ser o resultado da operação; não apenas atualizar o valor da substring automaticamente. Assim você teria que realmente escrever isso: browserType = browserType.replace('moz','van');

+ +

Exemplos para aprendizado ativo

+ +

Nesta seção, tentaremos escrever um código de manipulação de string. Em cada exercício abaixo, temos uma matriz de strings e um loop que processa cada valor na matriz e o exibe em uma lista com marcadores. Você não precisa entender matrizes ou loops agora - isso será explicado em artigos futuros. Tudo o que você precisa fazer em cada caso é escrever o código que produzirá as strings no formato em que as queremos.

+ +

Cada exemplo vem com um botão "Reset", que você pode usar para redefinir o código original, isso se cometer um erro e não conseguir faze-lo funcionar novamente, e um botão "Show Solution" que você pode pressionar para ver aresposta em potencial se realmente estiver travado.

+ +

Filtrando mensagens de saudação

+ +

No primeiro exercício, começaremos com simplicidade - temos várias mensagens de cartão, mas queremos classificá-las para listar apenas as mensagens de Natal. Queremos que você preencha um teste condicional dentro da estrutura if (...), para testar cada string e apenas imprimi-la na lista se for uma mensagem de Natal.

+ +
    +
  1. Primeiro pense em como você poderia testar se a mensagem em cada caso é uma mensagem de Natal. Qual string está presente em todas essas mensagens e que método você poderia usar para testar se ela está presente?
  2. +
  3. Em seguida, você precisará escrever um teste condicional do formulario operando2 operador operando1. A coisa à esquerda é igual à coisa à direita? Ou neste caso, o método chama à esquerda retorna o resultado à direita?
  4. +
  5. Dica: Nesse caso, é provavelmente mais útil testar se a chamada do método não é igual a um determinado resultado.
  6. +
+ + + +

{{ EmbedLiveSample('Playable_code', '100%', 490) }}

+ +

Corrigindo a capitalização

+ +

Neste exercício, temos os nomes das cidades no Reino Unido, mas a capitalização está toda desarrumada. Nós queremos que você as altere para que elas sejam todas minúsculas, exceto pela primeira letra maiúscula. Uma boa maneira de fazer isso é:

+ +
    +
  1. Converta toda a cadeia contida na variável de entrada para minúscula e armazene-a em uma nova variável.
  2. +
  3. Pegue a primeira letra da string nesta nova variável e armazene-a em outra variável.
  4. +
  5. Usando esta última variável como substring, substitua a primeira letra da string em minúsculas pela primeira letra da string em minúsculas alterada para maiúscula. Armazene o resultado desse procedimento de substituição em outra nova variável.
  6. +
  7. Altere o valor da variável  result para igual ao resultado final, não a input.
  8. +
+ +
+

Nota: Uma dica — os parâmetros dos métodos de string não precisam ser literais de string; eles também podem ser variáveis, ou mesmo variáveis com um método sendo invocado nelas.

+
+ + + +

{{ EmbedLiveSample('Playable_code_2', '100%', 450) }}

+ +

Fazendo novas strings a partir de partes antigas

+ +

Neste último exercício, o array contém um monte de strings contendo informações sobre estações de trem no norte da Inglaterra. As strings são itens de dados que contêm o código da estação de três letras, seguido por alguns dados legíveis por máquina, seguidos por um ponto-e-vírgula, seguido pelo nome da estação legível por humanos. Por exemplo:

+ +
MAN675847583748sjt567654;Manchester Piccadilly
+ +

Queremos extrair o código e o nome da estação e juntá-los em uma string com a seguinte estrutura:

+ +
MAN: Manchester Piccadilly
+ +

Nós recomendamos que faça assim:

+ +
    +
  1. Extraia o código da estação de três letras e armazene-o em uma nova variável.
  2. +
  3. Encontre o número de índice do caractere do ponto e vírgula.
  4. +
  5. Extraia o nome da estação legível usando o número do índice de caracteres de ponto-e-vírgula como ponto de referência e armazene-o em uma nova variável.
  6. +
  7. Concatene as duas novas variáveis e uma string literal para fazer a string final.
  8. +
  9. Altere o valor da variável result para igual à string final, não a input.
  10. +
+ + + +

{{ EmbedLiveSample('Playable_code_3', '100%', 485) }}

+ +

Conclusão

+ +

Você não pode escapar do fato de que ser capaz de lidar com palavras e frases em programação é muito importante — particularmente em JavaScript, pois os sites são todos sobre comunicação com pessoas. Este artigo forneceu os fundamentos que você precisa saber sobre a manipulação de strings por enquanto. Isso deve atendê-lo bem ao abordar tópicos mais complexos no futuro. Em seguida, vamos ver o último tipo de dados importante que precisamos focar no curto prazo — arrays.

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/Strings", "Learn/JavaScript/First_steps/Arrays", "Learn/JavaScript/First_steps")}}

+ +

Neste módulo

+ + diff --git "a/files/pt-br/learn/javascript/first_steps/vari\303\241veis/index.html" "b/files/pt-br/learn/javascript/first_steps/vari\303\241veis/index.html" new file mode 100644 index 0000000000..1afd436622 --- /dev/null +++ "b/files/pt-br/learn/javascript/first_steps/vari\303\241veis/index.html" @@ -0,0 +1,332 @@ +--- +title: Armazenando as informações que você precisa — Variáveis +slug: Learn/JavaScript/First_steps/Variáveis +translation_of: Learn/JavaScript/First_steps/Variables +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Math", "Learn/JavaScript/First_steps")}}
+ +

Depois de ler os últimos artigos, você deve saber agora o que é o JavaScript, o que ele pode fazer para você, como você usa isso junto com outras tecnologias da web e as características principais de alto nível. Neste artigo, iremos ao básico, vendo como trabalhar com a maioria dos blocos de construção básicos de JavaScript - Variáveis.

+ + + + + + + + + + + + +
Pré-requisitos:Conhecimento básico em informática, uma compreensão básica de HTML e CSS, uma compreensão do que é o JavaScript.
Objetivo:Familiarizar-se com o básico de variáveis em JavaScript.
+ +

Ferramentas que você precisa

+ +

Ao longo deste artigo, pediremos que você digite linhas de código para testar seu entendimento do conteúdo. Se você estiver utilizando um navegador em um computador, o melhor lugar para digitar seus código de exemplos é o console JavaScript do seu navegador (veja o artigo O que são as ferramentas de desenvolvimento do navegador para mais informações sobre como acessar essa ferramenta).

+ +

No entanto, nós também providenciamos um simples console JavaScript incorporado à página logo abaixo para que você inserir o código, caso não esteja usando um navegador com um console JavaScript facilmente disponível, ou se achar o console incorporado mais confortável.

+ +

O que é uma variável?

+ +

Uma variável é um container para um valor, como um número que podemos usar em uma operação de adição, ou uma sequência de texto que possamos usar como parte de uma oração. Mas uma coisa especial a respeito das variáveis é que seu conteúdo pode mudar. Vamos ver um exemplo simples:

+ +
<button>Aperte-me</button>
+ +
var button = document.querySelector('button');
+
+button.onclick = function() {
+  var nome = prompt('Qual é o seu nome?');
+  alert('Olá ' + nome + ', é um prazer te ver!');
+}
+ +

{{ EmbedLiveSample('O_que_é_uma_variável', '100%', 50, "", "", "hide-codepen-jsfiddle" ) }}

+ +

Nesse exemplo, apertar o botão executa algumas linhas de código. A primeira linha exibe uma caixa pop-up na tela que pede ao leitor para inserir o seu nome, e então armazena o valor na variável. A segunda linha exibe uma mensagem de boas vindas que inclui seu nome, obtido do valor da variável.

+ +

Para entender porque isso é útil, vamos pensar sobre como nós escreveríamos esse exemplo sem usar uma variável. Iria acabar se parecendo com algo do tipo:

+ +
var nome = prompt('Qual é o seu nome?');
+
+if (nome === 'Adão') {
+  alert('Olá Adão, é um prazer te ver!');
+} else if (nome === 'Alan') {
+  alert('Olá Alan, é um prazer te ver!');
+} else if (nome === 'Bella') {
+  alert('Olá Bella, é um prazer te ver!');
+} else if (nome === 'Bianca') {
+  alert('Olá Bianca, é um prazer te ver!');
+} else if (nome === 'Chris') {
+  alert('Olá Chris, é um prazer te ver !');
+}
+
+// ... e assim por diante ...
+ +

Você talvez não entenda totalmente a sintaxe que estamos usando (ainda!), mas deve ter pegado a ideia — se nós não tivermos variáveis disponíveis teríamos que implementar um bloco de código gigantesco para conferir qual era o nome inserido, e então exibir a mensagem apropriada para aquele nome. Isso é obviamente muito ineficiente (o código é muito maior, mesmo para apenas quatro opções de nome), e simplesmente não funcionaria — você não poderia armazenar todas as possíveis opções de nome.

+ +

Variáveis simplesmente fazem sentido, e a medida que você for aprendendo mais sobre JavaScript elas começarão a se tornar uma coisa natural.

+ +

Outra coisa especial sobra as variáveis é que elas podem conter praticamente qualquer coisa — não apenas cadeias de texto e números. Variáveis também podem conter dados complexos e até mesmo funções completas para fazer coisas incríveis. Você irá aprender mais sobre isso a medida que continuarmos.

+ +
+

Nota: Perceba que dissemos que as variáveis contém valores. Essa é uma distinção importante a se fazer. Elas não são os valores; e sim os containers para eles. Você pode pensar nelas sendo pequenas caixas de papelão nas quais você pode guardar coisas..

+
+ +

+ +

Declarando uma variável

+ +

Para usar uma variável primeiro tem que criá-la — mais precisamente, chamamos isso de declarar a variável. Para fazê-lo digitamos a palavra chave var seguido do nome que desejamos dar à variável:

+ +
var meuNome;
+var minhaIdade;
+ +

Aqui, estamos criando duas variáveis chamadas meuNome e minhaIdade. Tente agora digitar essas linhas no console do seu navegador. Depois disso, tente criar uma variável (ou duas) com suas próprias escolhas de nomes.

+ +
+

Nota: No JavaScript, todas as intruções em código deve terminar com um ponto e vírgula (;) — seu código pode até funcionar sem o ponto e vírgula em linhas únicas, mas provavelmente não irá funcionar quando estiver escrevendo várias linhas de código juntas. Tente pegar o hábito de sempre incluir o ponto e vírgula.

+
+ +

Você pode testar se os valores agora existem no ambiente de execução digitando apenas os nomes das variáveis, ex.:

+ +
meuNome;
+minhaidade;
+ +

Elas atualmente não possuem valor; são containers vazios. Quando você insere o nome de uma variável, você deve obter em retorno ou um valor undefined (indefinido), ou se a variável não existir, você recebe uma mensagem de erro — tente digitar:

+ +
scoobyDoo;
+ +
+

Nota: Não confunda uma variável que existe mas não tenho valor definido com uma variável que não existe — são coisas bem diferentes.

+
+ +

Inicializando uma variável

+ +

Uma vez que você declarou uma variável, você pode inicializá-la com um valor. Você faz isso digitando o nome da variável, seguido do sinal de igual (=) e o valor que deseja atribuir a ela. Por exemplo:

+ +
meuNome = 'Chris';
+minhaIdade = 37;
+ +

Tente voltar ao console agora e digitar essas linhas acima. Você deve ver o valor que atribuiu à variável retornado no console confirmando-o, em cada caso. De novo, você pode retornar os valores de suas variáveis simplesmente digitando seus nomes no console — tente isso novamente:

+ +
meuNome;
+minhaIdade;
+ +

Você pode declarar e inicializar uma variável ao mesmo tempo, assim:

+ +
var meuNome = 'Chris';
+ +

Isso provavelmente é como irá fazer na maioria das vezes, já que é mais rápido do que fazer as duas ações em duas linhas separadas.

+ +

A diferença entre var e let

+ +

Agora você pode estar pensando "por que precisamos de duas palavras-chave para definir variáveis? Por que var e let?".

+ +

As razões são um tanto históricas. Quando o JavaScript foi criado, havia apenas var. Isso funciona basicamente bem na maioria dos casos, mas tem alguns problemas na maneira como funciona — seu design pode ser confuso ou totalmente irritante. Portanto, let foi criada nas versões modernas de JavaScript, uma nova palavra-chave para criar variáveis que funcionam de maneira um pouco diferente para  var, corrigindo seus problemas no processo.

+ +

Algumas diferenças simples são explicadas abaixo. Não abordaremos todas as diferenças agora, mas você começará a descobri-las à medida que aprender mais sobre JavaScript (se realmente quiser ler sobre elas agora, fique à vontade para conferir nossa página de referência let).

+ +

Para começar, se você escrever um programa JavaScript de várias linhas que declare e inicialize uma variável, poderá realmente declarar uma variável com var depois de inicializá-la e ainda funcionará. Por exemplo:

+ +
meuNome = 'Chris';
+
+function logNome() {
+  console.log(meuNome);
+}
+
+logNome();
+
+var meuNome;
+ +
+

Nota: Isso não funcionará ao digitar linhas individuais em um console JavaScript, apenas ao executar várias linhas de JavaScript em um documento da web.

+
+ +

Isso funciona por causa do hoisting — leia var hoisting pra mais detalhes.

+ +

Hoisting não funciona mais com let. Se mudássemos de var para let no exemplo acima, teríamos um erro. Isso é bom — declarar uma variável depois que você a inicializa resulta em código confuso e difícil de entender.

+ +

E depois, ao usar var, você pode declarar a mesma variável quantas vezes quiser, mas com let você não consegue. Isso pode funcionar:

+ +
var meuNome = 'Chris';
+var meuNome = 'Bob';
+ +

Mas isso geraria um erro na segunda linha:

+ +
let meuNome = 'Chris';
+let meuNome = 'Bob';
+ +

Você precisaria fazer assim:

+ +
let meuNome = 'Chris';
+meuNome = 'Bob';
+ +

Novamente, essa é uma decisão sensata da linguagem. Não há razão para redeclarar variáveis — isso apenas torna as coisas mais confusas.

+ +

Por esses motivos e mais, recomendamos que você use let o máximo possível em seu código, em vez de var. Não há motivo para usar var, a menos que você precise oferecer suporte para versões antigas do Internet Explorer com seu código (ele não suporta let até a versão 11; o navegador mais moderno do Windows, o Edge, suporta let).

+ +

Atualizando uma variável

+ +

Uma vez que uma tenha um valor atribuido, você pode atualizar esse valor simplesmente dando a ela um valor diferente. Tente inserir as seguintes linhas no seu console:

+ +
meuNome = 'Bob';
+minhaIdade = 40;
+ +

Um adendo sobre regras de nomeação de variáveis

+ +

Você pode chamar uma variável praticamente qualquer nome que queira, mas há limitações. Geralmente você deve se limitar a utilizar somente caracteres latinos (0-9, a-z, A-Z) e o caractere underline ( _ ).

+ + + +
+

Nota: Você pode encontrar uma lista bem completa de palavras reservadas para evitar em Gramática léxica — Palavras-chave.

+
+ +

Exemplos de bons nomes:

+ +
idade
+minhaIdade
+inicio
+corInicial
+valorFinalDeSaida
+audio1
+audio2
+ +

Exemplos ruins de nomes:

+ +
1
+a
+_12
+minhaidade
+MINHAIDADE
+var
+Document
+skjfndskjfnbdskjfb
+esseeumnomedevariavelbemlongoeestupido
+
+ +

Tente criar mais  algumas variáveis agora, com a orientação acima em mente.

+ +

Tipos de variáveis

+ +

Existem alguns diferentes tipos de dados que podemos armazenar em variáveis. Nessa seção iremos descrevê-los brevemente, e então em artigos futuros você aprenderá sobre eles em mais detalhes.

+ +

Até agora nós vimos os dois primeiros, mas há outros.

+ +

Números

+ +

Você pode armazenar números em variáveis, tanto números inteiros, como por exemplo 30 (também chamados de integers) como números decimais, por exemplo 2.456 (também chamados de floats ou floating point numbers). Você não precisa declarar tipos de variáveis no JavaScript, diferentemente de outras linguagens de programação. Quando você atribui a uma variável o valor em número, você não inclui as aspas:

+ +
var minhaIdade = 17;
+ +

Strings (cadeias de texto)

+ +

Strings são sequências de texto. Quando você dá a uma variável um valor em texto (string), você precisa envolver o texto em aspas simples ou duplas; caso contrário, o JavaScript vai tentar interpretá-lo como sendo outro nome de variável.

+ +
var despedidaGolfinho = 'Até logo e obrigado por todos os peixes!';
+ +

Booleans (boleanos)

+ +

Booleans são valores verdadeiro/falso (true/false) — eles podem ter dois valores, true (verdadeiro) ou false (falso). São geralmente usados para verificar uma condição, que em seguida o código é executado apopriadamente. Por exemplo, um caso simples seria:

+ +
var estouVivo = true;
+ +

Enquanto na realidade seria utlizado mais da seguinte forma:

+ +
var teste = 6 < 3;
+ +

Esse exemplo está usando o operador "menor que" (<) para testar se 6 é menor que 3. Como você pode esperar, irá retornar false (falso), porque 6 não é menor que 3! Você aprenderá mais sobre tais operadores mais tarde no curso.

+ +

Arrays

+ +

Um array é um único objeto que contém valores múltiplos inseridos entre colchetes e separados por vírgulas. Tente inserir as seguintes linhas de código no seu console:

+ +
var meuNomeArray = ['Chris', 'Bob', 'Jim'];
+var meuNumeroArray = [10,15,40];
+ +

Uma vez que esses arrays estejam definidos, você pode acessar cada um de seus valores através de sua localização dentro do array. Tente essas linhas:

+ +
meuNomeArray[0]; // deve retornar 'Chris'
+meuNumeroArray[2]; // deve retornar 40
+ +

Os colchetes especificam um valor do índice correspondente à posição do valor que você deseja retornado. Você talvez tenha notado que os arrays em JavaScript são indexados a partir do zero: o primeiro elemento está na posíção 0 do índice.

+ +

Você aprenderá mais sobre arrays em um artigo futuro.

+ +

Objetos

+ +

Em programação, um objeto é uma estrutura de código que representa um objeto da vida real. Você pode ter um simples objeto que representa um estacionamento de carro contendo informações sobre sobre sua largura e comprimento, ou você poderia ter um objeto que representa uma pessoa, e contém dados sobre seu nome, altura, peso, que idioma ela fala, como dizer olá a ela, e mais.

+ +

Tente inserir a seguinte linha em seu console:

+ +
var cachorro = { nome : 'Totó', raca : 'Dálmata' };
+ +

Para obeter a informação armazenada no objeto, você pode usar a seguinte sintaxe:

+ +
cachorro.nome
+ +

Nós não iremos ver mais sobre objetos por agora — você pode aprender mais sobre eles em um artigo futuro.

+ +

Digitação permissiva

+ +

JavaScript é uma "dynamically typed language", o que significa que, diferente de outras linguagens, você não precisa especificar que tipo de dados uma variável irá conter (ex.: números, cadeias de texto, arrays, etc).

+ +

Por exemplo, se você declarar uma variável e dar a ela um valor encapsulado em aspas, o navegador irá tratar a variável como sendo uma string (cadeia de texto):

+ +
var minhaString = 'Olá';
+ +

Irá continuar sendo uma string, mesmo que dentro das apas contenha um número, então seja cuidadoso:

+ +
var meuNumero = '500'; // opa, isso continua sendo uma string
+typeof(meuNumero);
+meuNumero = 500; // bem melhor — agora isso é um número
+typeof(meuNumero);
+ +

Tente inserir as quatro linhas acima em seu console uma por uma, e veja quais são os resultados. Você notará que estamos usando uma função especial chamada typeof() — ela irá retornar o tipo de dado da variável que você passar. Da primeira vez que for executada, deve retornar string, como naquele ponto a variável meuNumero contém uma string, '500'. Dê uma olhada e veja o que é retornado da segunda vez que você a utilizar.

+ +

Constants em JavaScript

+ +

Muitas linguagens de programação têm o conceito de constant —  um valor que uma vez declarado não pode ser alterado. Há muitas razões pelas quais você deseja fazer isso, desde segurança (se um script de terceiros alterou esses valores, poderia causar problemas)  até a depuração e a compreensão do código (é mais difícil alterar acidentalmente valores que não devem ser alterados e bagunçar as coisas).

+ +

Nos primeiros dias do JavaScript, não existiam constants. No JavaScript moderno, temos a palavra-chave const, que nos permite armazenar valores que nunca podem ser alterados:

+ +
const diasNaSemana = 7;
+const horasNoDia = 24;
+ +

const funciona exatamente da mesma maneira que let, exceto que você não pode atribuir um novo valor a const. No exemplo a seguir, a segunda linha geraria um erro:

+ +
const diasNaSemana = 7;
+diasNaSemana = 8;
+ +

Teste suas habilidades!

+ +

Você chegou ao final deste artigo, mas consegue se lembrar das informações mais importantes? Você pode encontrar alguns testes adicionais para verificar se você reteve essas informações antes de prosseguir — veja Teste suas habilidades: variáveis.

+ +

Sumário

+ +

Por agora você deve saber razoavelmente sobre variáveis JavaScript e como criá-las. No próximo artigo Vamos focar nos números em mais detalhes, vendo como fazer matemática básica no JavaScript.

+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/What_went_wrong", "Learn/JavaScript/First_steps/Maths", "Learn/JavaScript/First_steps")}}

+ +

Neste módulo

+ + diff --git a/files/pt-br/learn/javascript/first_steps/what_went_wrong/index.html b/files/pt-br/learn/javascript/first_steps/what_went_wrong/index.html new file mode 100644 index 0000000000..ee121e8773 --- /dev/null +++ b/files/pt-br/learn/javascript/first_steps/what_went_wrong/index.html @@ -0,0 +1,245 @@ +--- +title: O que deu errado? Resolvendo problemas no JavaScript +slug: Learn/JavaScript/First_steps/What_went_wrong +translation_of: Learn/JavaScript/First_steps/What_went_wrong +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps")}}
+ +

Quando você construiu o jogo "Adivinhe o número" no artigo anterior, você talvez tenha descoberto que ele não funcionou. Não tema — este artigo tem como objetivo impedir que você arranque os cabelos por causa desses problemas, fornecendo-lhe algumas dicas simples de como encontrar e corrigir erros nos programas JavaScript.

+ + + + + + + + + + + + +
Pré-requesitos: +

Conhecimentos básicos de informática, uma compreensão básica de HTML e CSS, uma compreensão do que é JavaScript.

+
Objetivo:Ganhar habilidade e confiança para começar a resolver problemas simples em seu próprio código.
+ +

Tipos de erros

+ +

De um modo geral, quando você faz algo errado no código, existem dois tipos principais de erros que você encontrará:

+ + + +

Ok, então não é assim tão simples - há alguns outros diferenciadores à medida que você aprofunda. Mas as classificações acima serão bem úteis nesta fase inicial da sua carreira. Examinaremos esses dois tipos a seguir.

+ +

Um exemplo errôneo

+ +

Para começar, voltemos ao nosso jogo de adivinhação - porém desta vez estaremos explorando uma versão que tem alguns erros inseridos propositalmente. Vá até o Github e faça uma cópia local de jogo-numero-erros.html (veja-o em execução aqui).

+ +
    +
  1. Para começar, abra a cópia local dentro do seu editor de texto favorito, e em seu navegador.
  2. +
  3. Tente jogar o jogo - você notará que, quando você pressiona o botão "Enviar palpite", ele não funciona!
  4. +
+ +
+

Nota: Talvez você tenha sua própria versão de exemplo do jogo que não funciona, e pode querer consertá-la! Nós ainda gostaríamos que você trabalhasse no artigo com a nossa versão, para que possa aprender as técnicas que estamos ensinando aqui. Daí então você pode voltar e tentar consertar seu exemplo.

+
+ +

Neste ponto, vamos consultar o console do desenvolvedor para ver se identificamos qualquer erro de sintaxe, e então tentar consertá-lo. Você irá aprender como, logo abaixo.

+ +

Consertando erros de sintaxe

+ +

Anteriormente no curso, nós fizemos você digitar alguns comandos simples de JavaScript no console JavaScript (se você não se lembra como, abra o link anterior). O que é ainda mais útil é o fato do console lhe mostrar mensagens de erro sempre que existir algo errado na sintaxe dentro do JavaScript enviado ao motor de JavaScript do navegador. Agora vamos à caça.

+ +
    +
  1. Vá até a aba onde você tem aberto o arquivo jogo-numero-erros.html e abra o console JavaScript. Você deverá ver uma mensagem de erro sendo exibida:
    +
  2. +
  3. Esse é um erro bem fácil de identifcar, e o navegador lhe fornece várias informações úteis para lhe ajudar (a captura de tela acima foi feita no Firefox, mas os outros navegadores oferecem informações similares). Da esquerda para a direita, nós temos: +
      +
    • Um "x" laranja para indicar que esse é um erro.
    • +
    • Uma mensagem de erro para indicar o que está errado: "TypeError: envioPalpite.addeventListener is not a function"
    • +
    • Um link "Learn More" que encaminha à uma página no MDN docs explicando o que esse erro significa em uma quantidade enorme de detalhes.
    • +
    • O nome do arquivo JavaScript, que direciona à aba Debugger das ferramentas de desenvolvimento. Se você clicar nesse link, verá a linha exata onde o erro está destatacada.
    • +
    • O número da linha onde o erro se encontra, e o número do caractere na linha onde o erro é encontrado primeiro. Neste caso nós temos, linha 86, caractere número 3.
    • +
    +
  4. +
  5. Se olharmos para a linha 86 em nosso nosso código de código, vamos encontrar a seguinte linha: +
    envioPalpite.addeventListener('click', conferir Palpite);
    +
  6. +
  7. O erro diz o seguinte "envioPalpite.addeventListener is not a function", que significa envioPalpite.addeventListener não é uma funçao. Então provavelmente digitamos algo errado. Se você não estiver certo da digitação correta de parte da sintaxe, é uma boa ideia procurar a funcionalidade no MDN docs. A melhor forma de fazer isso atualmente é pesquisar por "mdn nome-da-funcionalidade" em seu mecanismo de buscas favorito. Aqui está um atalho para te salvar algum tempo nesse caso: addEventListener().
  8. +
  9. Então, olhando nessa essa página, o erro parece ser termos digitado o nome da função errado! Lembre-se de que o JavaScript diferencia letras maiúsculas de minúsculas, então qualquer diferença na digitação ou no uso de letras maiúsculas irá causar um erro. Alterar addeventListener para addEventListener deverá corrigir esse erro. Faça essa alteração no código do seu arquivo.
  10. +
+ +
+

Nota: Veja nossa página de referência TypeError: "x" is not a function para mais detalhes sobre esse erro.

+
+ +

Erros de sintaxe - segundo round

+ +
    +
  1. Salve o arquivo e atualize a aba do navegador, e você poderá ver que o erro foi corrigido.
  2. +
  3. Agora se você tentar enviar um palpite e pressionar o botão !Enviar palpite" você verá... outro erro!
    +
  4. +
  5. Dessa vez o erro informado é "TypeError: baixoOuAlto is null", na linha 78. +
    Nota: Null é um valor especial que significa "nada", ou "sem valor". Então baixoOuAlto foi declarado e inicializado, mas não com algum valor significativo — não possui nenhum caractere ou valor.
    + +
    Nota: Esse erro não apareceu assim que a página foi carregada porque esse erro ocorreu dentro de uma função (dentro do bloco conferirPalpite() { ... } ). Como você irá aprender com mais detalhes no nosso artigo de funções mais tarde, o código localizado dentro de funções roda em um escopo separado do código presente fora das funções. Nesse caso, o código não estava rodando e o erro não estava aparecendo até a função conferirPalpite() ser executada na linha 86.
    +
  6. +
  7. Dê uma olhada na linha 78, e você verá o seguinte código: +
    baixoOuAlto.textContent = 'Seu palpite foi muito alto!';
    +
  8. +
  9. Essa linha está tentando definir a propriedade textContent (conteúdo de texto) da variável baixoOuAlto como uma sequência de texto, mas isso não está funcionando porque baixoOuAlto não contém o que deveria conter. Vamos ver o porquê — tente localizar outras instâncias de baixoOuAlto no código. A instância que aparece primeiro no código  JavaScript é na linha 48: +
    var baixoOuAlto = document.querySelector('baixoOuAlto');
    +
  10. +
  11. Nesse ponto estamos tentando fazer com que a variável contenha uma referência a um elemento no documento HTML. Vamos conferir se o valor é null (nulo) depois que essa linha é executada. Adicione o seguinte código na linha 49: +
    console.log(baixoOuAlto);
    + +
    +

    Nota: console.log() é uma função de debugging (correção de erros) realmente útil que exibe um valor na tela do console. Então ela irá imprimir o valor da variável baixoOuAlto na tela do console assim que tentarmos defini-la na linha 48.

    +
    +
  12. +
  13. Salve o arquivo e o atualize no navegador, e você deverá ver agora o resultado do console.log() na tela do seu console.
    +
    + Pois bem, nesse ponto o valor de baixoOuAlto e null, então definitivamente há um problema com a linha 48.
  14. +
  15. Vamos pensar em qual poderia ser o problema. A linha 48 está usando um método document.querySelector() para pegar a referência do elemento selecionado com um seletor CSS selector (CSS selector). Olhando mais acima no nosso código, podemos encontrar o parágrafo em questão: +
    <p class="baixoOuAlto"></p>
    +
  16. +
  17. Então nós precisamos de um seletor de classe aqui, que começa com um ponto (.), mas o seletor passado pelo método querySelector() na linha 48 não tem o ponto. Esse pode ser o problema! Tente mudar baixoOuAlto para .baixoOuAlto na linha 48.
  18. +
  19. Tente salvar o arquivo e atualizá-lo no navegador de novo, e a sua declaração console.log() deverá retornar o elemento <p> que queremos. Ufa! Outro erro resolvido! Você pode deletar a linha do seu  console.log() agora, ou mantê-la para referência posterior — a escolha é sua.
  20. +
+ +
+

Nota: Veja nossa página de referência TypeError: "x" is (not) "y" para mais detalhes sobre esse erro.

+
+ +

Erros de sintaxe - terceiro round

+ +
    +
  1. Agora se você tentar jogar novamente, você deve ter mais sucesso — o jogo deve continuar normalmente, até você terminar, ou adivinhando o número, ou ficando sem mais chances.
  2. +
  3. Nesse ponto, o jogo falha mais uma vez, e o mesmo erro do início é exibido — "TypeError: botaoReinicio.addeventListener is not a function"! No entanto, dessa vez é listado vindo da linha 94.
  4. +
  5. Olhando a linha 94, é fácil de ver que nós cometemos o mesmo erro novamente. Só precisamos alterar mais uma vez addeventListener para addEventListener. Faça isso.
  6. +
+ +

Um erro de lógica

+ +

Nesse ponto, o jogo deve rodar normalmente, porém depois de jogá-lo algumas vezes você irá notar que o número "aleatório" que você tem que adivinhar é sempre igual a 1. Definitivamente não é como queremos que o jogo funcione!

+ +

Há sem dúvida um problema na lógica do jogo em algum lugar — o jogo não está retornando nenhum erro;simplesmente não está funcionando corretamente.

+ +
    +
  1. Procure pela variável numeroAleatorio, e as linhas onde o número aleatório é definido primeiro. A instância que armazena o número aleatório que queremos adivinhar no começo do jogo deve estar na linha 44 ou próximo a ela: + +
    var numeroAleatorio = Math.floor(Math.random()) + 1;
    +
  2. +
  3. E a linha que gera o número aleatório antes de cada jogo subsequente está na linha 113, ou próximo a ela: +
    numeroAleatorio = Math.floor(Math.random()) + 1;
    +
  4. +
  5. Para checar se essas linhas são mesmo o problema, vamos recorrer ao nosso amigo console.log() de novo — insira a seguinte linha diretamente abaixo de cada uma das duas linhas: +
    console.log(numeroAleatorio);
    +
  6. +
  7. Salve o arquivo e atualize o navegador, então jogue algumas vezes — você verá que o numeroAleatorio é igual a 1 cada vez em que é exibido no console.
  8. +
+ +

Trabalhando através da lógica

+ +

Para consertar isso, vamos considerar como essa linha está trabalhando. Primeiro, nós invocamos Math.random(), que gera um número decimal aleatório entre 0 e 1, ex. 0.5675493843.

+ +
Math.random()
+ +

Em seguida, passamos o resultado invocando Math.random() através de  Math.floor(), que arredonda o número passado para o menor número inteiro mais próximo. E então adicionamos 1 ao resultado:

+ +
Math.floor(Math.random()) + 1
+ +

Arredondando um número decimal aleatório entre 0 e 1 para baixo irá sempre retornar 0, então adicionando 1 a ele sempre retornará 1. Precisamos multiplicar o número aleatório por 100 antes de o arredondarmos para baixo. O código seguinte nos daria um número aleatório entre 0 and 99:

+ +
Math.floor(Math.random()*100);
+ +

Por isso, queremos adicionar 1, para nos dar um número aleatório entre 1 e 100:

+ +
Math.floor(Math.random()*100) + 1;
+ +

Tente atualizar as duas linhas dessa forma, então salve e atualize o navegador — o jogo deve agora funcionar como nós queremos que funcione!

+ +

Outros erros comuns

+ +

Existem outros erros comuns com os quais você irá esbarrar em seu código. Essa seção destaca a maioria deles.

+ +

SyntaxError: missing ; before statement

+ +

Erro de sintaxe: faltando ";" antes da declaração. Esse erro geralmente significa que você deixou de inserir um ponto e vírgula ao final de uma de suas linhas de código, mas algumas vezes pode ser mais crítico. Por exemplo, se mudarmos essa linha (número 58) dentro da função conferirPalpite():

+ +
var palpiteUsuario = Number(campoPalpite.value);
+ +

para

+ +
var palpiteUsuario === Number(campoPalpite.value);
+ +

Exibe esse erro porque pensa que você está fazendo algo diferente. Você deve se certificar de não misturar o operador de atribuição (=) — que configura uma variável para ser igual a determinado valor — com o operador de igualdade restrita (===), que testa se um valor é exatamente igual a outro, e retorna um resultado true/false (verdadeiro ou falso).

+ +
+

Nota: Veja nossa página de referência SyntaxError: missing ; before statement para mais detalhes sobre esse erro.

+
+ +

O programa sempre diz que você ganhou, independentemente do palpite que insira

+ +

Isso pode ser outro sintoma de confusão entre o operador de atribuição e o operador de igualdade restrita. Por exemplo, se nós quiséssemos essa linha dentro de conferirPalpite():

+ +
if (palpiteUsuario === numeroAleatorio) {
+ +

para

+ +
if (palpiteUsuario = numeroAleatorio) {
+ +

o teste retornaria sempre true (verdadeiro), causando o programa a reportar que o jogo foi vencido. Tome cuidado!

+ +

SyntaxError: missing ) after argument list

+ +

Erro de sintaxe: faltando ")" depois de listar uma declaração. Esse é bem simples — geralmente significa que deixamos de fechar o parênteses no final ao invocar uma função/método.

+ +
+

Nota: Veja nossa página de referência SyntaxError: missing ) after argument list para mais detalhes sobre o erro.

+
+ +

SyntaxError: missing : after property id

+ +

Erro de sintaxe: faltando ":" depois da propriedade id. Esse erro geralmente se relaciona à formação incorreta de um objeto de JavaScript, mas nesse caso o obtivemos alterando:

+ +
function conferirPalpite() {
+ +

para

+ +
function conferirPalpite( {
+ +

Isso levou o navegador a pensar que estávamos tentando passar todo o conteúdo da função como se fosse um argumento dessa função. Seja cuidadoso com esses parênteses!

+ +

SyntaxError: missing } after function body

+ +

Erro de sintaxe: faltando "}" depois do corpo da função. Isso é fácil — geralmente significa que você deixou de colocar uma das chaves de uma função ou de uma estrutura condicional. Nós obtemos esse erro deletando uma das chaves de fechamento próximas ao final da função conferirPalpite().

+ +

SyntaxError: expected expression, got 'string' ou SyntaxError: unterminated string literal

+ +

Erro de sintaxe: esperado uma expressão, obtido uma 'string' e Erro de sintaxe: string literal não terminada. Esses erros geralmente significam que você deixou de colocar aspas no início ou no final da declaração de uma cadeia de texto. No primeiro erro acima, 'string' seria substituído pelo(s) caractere(s) encontrado(s) pelo navegador ao invés da aspa no início de uma cadeia de texto. O segundo erro quer dizer que a cadeia de texto não foi finalizada com o caractere de aspa.

+ +

Para todos esses erros, pense em como nós abordamos os exemplos em que olhamos no passo a passo. Quando um erro surge, olha o número da linha que é informado, vá até essa linha e veja se consegue localizar o que há de errado. Mantenha em mente que o erro não estará necessariamente nessa linha, e também que o erro pode não ter sido causado exatamente  pelo mesmo problema que citamos acima!

+ +
+

Nota: Veja nossas páginas de referência SyntaxError: Unexpected token e SyntaxError: unterminated string literal para mais detalhes sobre esses erros.

+
+ +

Sumário

+ +

Então aqui temos, o básico de como resolver erros em programas simples de JavaScript. Não será sempre tão fácil de solucionar o que está errado em seu código, mas pelo menos isso irá te poupar algumas horas de sono e lhe permitir progredir um pouco mais rápido quando as coisas não saírem certas no início da sua jornada de aprendizado.

+ +

Veja também

+ +
+ +
+ +

{{PreviousMenuNext("Learn/JavaScript/First_steps/A_first_splash", "Learn/JavaScript/First_steps/Variables", "Learn/JavaScript/First_steps")}}

-- cgit v1.2.3-54-g00ecf