Dia 1 — Como o JavaScript roda no navegador
O que e JavaScript e onde ele roda
O que é JavaScript e onde ele roda
JavaScript é uma linguagem de programação. Não é HTML, que marca a estrutura da página, nem CSS, que cuida da aparência. É o que responde: o que acontece quando a pessoa clica num botão.
O nome vem de Java, linguagem da Sun, e o roteiro do produto era escrever algo que rodasse em qualquer máquina e em qualquer navegador. A linguagem ficou com o nome, a proposta não se sustenta: JavaScript roda em todo navegador, mas é uma linguagem só, e não tem nada a ver com a outra.
Onde ele roda
Um mesmo arquivo .js roda em três lugares, com a mesma linguagem e ambientes diferentes em volta.
| Onde | O que existe em volta | Serve para |
|---|---|---|
| Navegador | window, document, a página | interface, evento, requisição |
| Node.js | process, arquivos, rede | servidor, automação, script |
| Planilha, ferramenta, celular | o que o produto oferecer | extensão |
A distinção prática: código que mexe na tela não roda no Node.js, e código que lê arquivo do disco não roda no navegador. O erro clássico é escrever require('fs') numa página e ver a tela branca, ou escrever document num script de servidor e ver document is not defined.
Engine e padrão: quem decide o que é válido
A engine é o programa que executa o seu código — o interpretador que lê cada sentença e faz o que ela manda. Node.js e Chrome usam a mesma: a V8, da Google. Firefox tem a SpiderMonkey, Safari tem a JavaScriptCore. Trocar de navegador não troca a linguagem, troca a engine.
O padrão da linguagem é o ECMAScript, mantido pela ECMA International e atualizado todo ano. A engine implementa esse padrão; quem escreve código consulta o padrão, não a documentação de um navegador.
O que muda a forma de compilar não é o nome da engine: o caminho pode ser o de um interpretador (o Node.js nasce assim, lendo e executando linha por linha) ou o compilado para a máquina antes de rodar. Isso não muda a linguagem — nenhum sintaxe novo entra por trocar de caminho.
ECMAScript é o nome do padrão, JavaScript é o nome da linguagem. Todo navegador fala JavaScript, e todo JavaScript segue o ECMAScript. Nenhum navegador pode inventar sintaxe nova só nele.
O programa é o arquivo inteiro
Não existe ponto de entrada obrigatório, como public static void main em Java. O arquivo inteiro é o programa, lido de cima para baixo, sentença por sentença.
A página HTML é que carrega o script. É a tag <script> que liga o arquivo .js à página — e é ela que o navegador encontra para executar.
const nome = 'Ana'; // sentença: declarar console.log(nome); // sentença: imprimir console.log('fim'); // cada uma termina em ;
A JavaScript diferencia maiúscula de minúscula: nome e Nome são duas variáveis diferentes. Separar valor do nome com espaço em volta do = é convenção do curso e ajuda a ler.
Do navegador para o servidor
Rodar JavaScript no navegador é o padrão. O Node.js é o mesmo motor, rodando fora do navegador, e foi criado em 2009 porque a linguagem já existia e só faltava um lugar para rodar do lado do servidor.
O exemplo desta aula roda pelo Node.js, porque é lá que dá para ver qual engine está executando a linha. A mesma sintaxe, o mesmo console.log, o mesmo ponto e vírgula.
Exemplo
'use strict'; // ============================================================ // AULA 1 - O que é JavaScript e onde ele roda // // JavaScript é a linguagem que roda dentro do navegador. Este // exemplo foi executado pelo Node.js, que é o mesmo motor com // outro ambiente em volta, e por isso consegue responder à // pergunta que a aula faz: quem está executando esta linha. // ============================================================ // O `process` existe no Node e não existe no navegador. O operador // `typeof` pergunta o tipo sem quebrar quando o objeto não está // ali — é assim que o código descobre em que ambiente roda. console.log('--- quem está executando este arquivo ---'); console.log('typeof process:', typeof process); console.log('versão do runtime:', process.version); // A engine é o programa que traduz o código em algo que a máquina // executa. Node e Chrome usam a mesma: a V8, da Google. console.log('engine:', 'V8 ' + process.versions.v8); // A engine implementa o padrão da linguagem, o ECMAScript, mantido // pela ECMA International. O padrão é atualizado todo ano, e é ele // que decide o que é sintaxe válida — não quem distribui o navegador. console.log(''); console.log('--- o padrão da linguagem ---'); console.log('process.versions.modules:', process.versions.modules, '(versão do padrão)'); // O mesmo arquivo roda nos dois lugares. O que muda é o que existe // em volta da linguagem: no Node há `process`, arquivos e rede; no // navegador há a página. Por isso o código que salva arquivo não // roda no navegador, e o que mexe na tela não roda no Node. console.log(''); console.log('--- o que existe em cada ambiente ---'); console.log('no Node existe process:', typeof process !== 'undefined'); console.log('no navegador existe a página: ve a aula 11'); // Um programa de JavaScript é uma sequência de sentenças lidas de // cima para baixo. Não existe ponto de entrada obrigatório, como // em Java ou C: o arquivo inteiro é o programa. console.log(''); console.log('--- o arquivo inteiro é o programa ---'); console.log('primeira sentença'); console.log('segunda sentença'); // Cada sentença termina com ponto e vírgula. Sem ele, a próxima // linha continuaria a mesma sentença e o programa quebraria. console.log('terceira sentença;'); console.log(''); console.log('--- o JavaScript diferencia maiúscula de minúscula ---'); const nome = 'minúsculo'; const Nome = 'maiúsculo'; console.log('nome =', nome, '| Nome =', Nome, '| são duas variáveis diferentes');
Saída real
--- quem está executando este arquivo --- typeof process: object versão do runtime: v24.21.0 engine: V8 13.6.233.17-node.53 --- o padrão da linguagem --- process.versions.modules: 137 (versão do padrão) --- o que existe em cada ambiente --- no Node existe process: true no navegador existe a página: ve a aula 11 --- o arquivo inteiro é o programa --- primeira sentença segunda sentença terceira sentença; --- o JavaScript diferencia maiúscula de minúscula --- nome = minúsculo | Nome = maiúsculo | são duas variáveis diferentes
O primeiro script: console e alert
O primeiro script: console e alert
O primeiro programa do curso é uma linha que escreve um texto. console é o objeto que dá acesso ao console, e console.log é o método que escreve nele. Abrir o arquivo e rodá-lo é o que se chama de executar script — no Node.js, node arquivo.js; no navegador, o F12 e o botão de rodar.
console.log('meu primeiro script');
O que está entre parênteses é o que aparece. Pode ser texto entre aspas, um número, uma variável, ou vários separados por vírgula — o método monta a linha sozinho, sem precisar virar tudo em texto antes.
Os quatro métodos de console
| Método | Assinatura | Quando usar |
|---|---|---|
console.log | console.log(...valores: unknown[]): void | a saída normal do programa |
console.warn | console.warn(...valores: unknown[]): void | aviso: algo vai dar errado |
console.error | console.error(...valores: unknown[]): void | erro: deu errado agora |
console.table | console.table(valores: unknown[]): void | ver lista de objetos alinhada |
Os quatro escrevem no mesmo console. No navegador a diferença é visual: o DevTools pinta a linha de amarelo no warn e de vermelho no error. No terminal, eles saem no fim da saída, separados do texto normal — por isso a página mostra só as linhas de console.log, e as de aviso e erro aparecem logo depois delas.
console.error não para o programa. A única coisa que para o programa é o erro não tratado.
Onde a saída aparece
No navegador: F12 (ou Ctrl + Shift + I, ou botão direito e Inspecionar), depois a aba Console — a pestana Console do painel. No Node.js: o terminal onde o comando node arquivo.js rodou. Nos dois é o mesmo método, e é por ele que se olha o valor de uma variável enquanto se programa.
Um programa que não imprime nada é um programa que não se pode conferir. Para o resto do curso, todo script imprime.
alert, confirm e prompt
São as três caixas de diálogo do navegador. Elas aparecem, travam o script até a pessoa responder, e por isso não servem para nada que o programa precise fazer sozinho.
| Função | Assinatura | Devolve | |
|---|---|---|---|
alert | alert(mensagem?: any): void | nada, só mostra | |
confirm | confirm(mensagem?: any): boolean | true ou false | |
prompt | `prompt(mensagem?: any, padrão?: string): string \ | null` | o texto digitado, ou null |
As três vivem na página, não no Node.js. Chamá-las fora do navegador quebra com ReferenceError: alert is not defined. É a diferença entre rodar no navegador e rodar no servidor, aparecendo na primeira aula.
Comentário
Comentário é texto que o motor ignora. Serve para escrever por que o código faz algo, não o que ele faz. A forma de bloco é o /* */: abre com barra-asterisco, fecha com asterisco-barra, e o que estiver entre eles é ignorado até o fechamento.
// uma linha inteira, vai até o fim da linha const taxa = 0.15; // comentário no fim da linha /* várias linhas: o bloco abre com barra-asterisco e fecha com asterisco-barra */
A crase não é comentário. É o delimitador de texto que aceita interpolação, e é assunto da aula 4.
O
alerttrava a página inteira, inclusive o botão que o abriu. Para o curso inteiro, a saída vai porconsole.log, e a caixa de diálogo fica reservada para o teste rápido no DevTools.
Exemplo
'use strict'; // ============================================================ // AULA 2 - O primeiro script: console e alert // // Todo script começa imprimindo alguma coisa. `console.log` é o // método que escreve no console; `console.warn` e `console.error` // escrevem no mesmo console, só que em outro fluxo. // Executado pelo Node.js, onde as caixas de diálogo do navegador // não existem — e essa ausência faz parte do exemplo. // ============================================================ // O comentário de uma linha abre em // e vai até o fim da linha. console.log('--- console.log: a saída normal ---'); console.log('texto solto'); console.log('varias', 'partes', 'juntas', 'por', 'espaço'); console.log('número e texto juntos:', 42, 'anos'); // Separar com vírgula é o jeito seguro de juntar valores de tipos // diferentes: o método monta o texto sem converter nada antes. const usuario = { nome: 'Ana', idade: 30 }; console.log('objeto impresso:', usuario); console.log('a expressão continua inteira:', 1 + 2 + 3, '=', 1 + 2 + 3); // console.warn e console.error vão para o mesmo console, mas em // outro fluxo. No navegador o DevTools pinta a linha de amarelo ou // de vermelho para chamar o olho; neste terminal eles saem separados, // no fim da saída. Por isso a página mostra só as quatro linhas // abaixo, e as de aviso e erro aparecem logo depois delas. console.log(''); console.log('--- os quatro métodos de console ---'); console.log('linha 1, saída normal'); console.warn('linha 2, aviso: amarela no DevTools'); console.error('linha 3, erro: vermelha no DevTools'); console.log('linha 4, saída normal de novo'); // O comentário de várias linhas abre em barra-asterisco e fecha em // asterisco-barra. Ocupa quantas linhas for. console.log(''); /* Os três comentários: - barra dupla: uma linha só - barra e asterisco: várias linhas - a crase não é comentário */ // No navegador, `alert`, `confirm` e `prompt` abrem uma caixa de // diálogo e travam o script até a pessoa responder. Chamadas: // alert('texto') só mostra // confirm('texto') mostra e devolve true ou false // prompt('texto') mostra e devolve o que a pessoa digitou // Fora do navegador elas não existem, e a tentativa quebra com // ReferenceError. O erro é de propósito. console.log(''); console.log('--- as caixas de diálogo só existem no navegador ---'); console.log('typeof alert:', typeof alert); try { alert('isto abriria uma caixa de diálogo no navegador'); } catch (erro) { console.error(erro.constructor.name + ': ' + erro.message); console.log('a tentativa deu:', erro.constructor.name + ',', erro.message); } // O `try` e o `catch` pegaram a exceção, então o script continua. // Sem o `catch`, o programa pararia na linha do `alert`. console.log('o script continua rodando depois do erro'); // O mesmo `console.log` mostra o valor das coisas. No DevTools do // navegador (F12, aba Console) e no terminal do Node, é o mesmo // método, com os mesmos outros por trás: .warn, .error, .table, .time. console.log(''); console.log('--- onde a saída aparece ---'); console.log('no navegador: F12 > aba Console'); console.log('no Node: o terminal onde o comando `node arquivo.js` rodou'); console.log(''); console.log('somar(2, 3) =', 2 + 3, '| itens:', ['Ana', 'Bia', 'Cau'].join(', '));
Saída real
--- console.log: a saída normal ---
texto solto
varias partes juntas por espaço
número e texto juntos: 42 anos
objeto impresso: { nome: 'Ana', idade: 30 }
a expressão continua inteira: 6 = 6
--- os quatro métodos de console ---
linha 1, saída normal
linha 4, saída normal de novo
--- as caixas de diálogo só existem no navegador ---
typeof alert: undefined
a tentativa deu: ReferenceError, alert is not defined
o script continua rodando depois do erro
--- onde a saída aparece ---
no navegador: F12 > aba Console
no Node: o terminal onde o comando `node arquivo.js` rodou
somar(2, 3) = 5 | itens: Ana, Bia, Cau