Funções em JavaScript
Funções são blocos de código reutilizáveis — escreva uma vez, use infinitamente. Pense nelas como receitas: defina os passos uma vez, depois siga-os toda vez que cozinhar. Um programador que não usa funções é como alguém reinventando cada prato do zero — exaustivo e propenso a erros.
O Que É uma Função?
Uma função "encapsula" um pedaço de lógica, dá um nome a ela e permite que você a chame quando precisar:
<!DOCTYPE html>
<html lang="pt-br">
<head><meta charset="UTF-8"><title>Chamando Funções</title></head>
<body>
<div id="output"></div>
<script>
function sayHello() {
document.getElementById('output').textContent += 'Olá!\n';
}
sayHello();
sayHello();
</script>
</body>
</html>
Benefícios das funções:
- Reutilizabilidade: escreva uma vez, chame em qualquer lugar
- Encapsulamento: esconde complexidade, expõe apenas a interface
- Manutenibilidade: altere em um lugar, todos os chamadores se beneficiam
Declaração de Função vs Expressão de Função
Existem duas maneiras principais de criar funções:
<script>
// Declaração de função
function greet(name) {
return `Olá, ${name}!`;
}
// Expressão de função
let greet2 = function(name) {
return `Olá, ${name}!`;
};
</script>
Diferença-chave: declarações de função são elevadas (hoisted) — você pode chamá-las antes de aparecerem no código. Expressões de função não são elevadas; você deve defini-las primeiro.
<script>
// Declaração de função: chamar antes da definição — funciona
hello(); // Executa sem erro
function hello() { console.log('oi'); }
// Expressão de função: chamar antes da definição — erro
// hi(); // TypeError: hi is not a function
// let hi = function() { console.log('oi'); };
</script>
let antes de sua declaração dispara um erro de "zona morta temporal" (TDZ) — não undefined. Então sempre defina expressões de função antes de usá-las.
Parâmetros e Parâmetros Padrão
Funções aceitam dados externos através de parâmetros:
<script>
function add(a, b) {
return a + b;
}
add(1, 2); // 3
</script>
Parâmetros que você não passa são undefined. O ES6 introduziu parâmetros padrão:
<script>
function greet(name, greeting = 'Olá') {
return `${greeting}, ${name}!`;
}
greet('Alice'); // 'Olá, Alice!'
greet('Alice', 'Oi'); // 'Oi, Alice!'
</script>
Valores de Retorno
return envia um resultado de volta ao chamador e imediatamente para a função:
<script>
function square(n) {
return n * n;
}
let result = square(5); // 25
</script>
Uma função sem return (ou com apenas return;) retorna undefined.
<script>
function doNothing() {
// sem return
}
doNothing(); // undefined
</script>
return causa inserção automática de ponto e vírgula, fazendo-o retornar undefined:
return // vira: return; undefined
obj; // esta linha nunca executa
Solução: mantenha o valor de retorno na mesma linha, ou envolva-o em parênteses.
Arrow Functions (=>)
Arrow functions são uma sintaxe mais curta introduzida no ES6:
<script>
// Função regular
let double = function(n) {
return n * 2;
};
// Arrow function
let double2 = (n) => n * 2;
// Múltiplas instruções requerem chaves e return explícito
let greet = (name) => {
let msg = `Olá, ${name}!`;
return msg;
};
</script>
Regras de sintaxe:
- Parâmetro único: parênteses opcionais —
n => n * 2 - Zero ou múltiplos parâmetros: parênteses obrigatórios —
() => 'oi',(a, b) => a + b - Expressão de uma linha: auto-retorna; múltiplas linhas: precisa de
{}+return
Exemplo: Uso Básico de Funções
<!DOCTYPE html>
<html lang="pt-br">
<body>
<h2>Uso Básico de Funções</h2>
<div id="output"></div>
<script>
function add(a, b) {
return a + b;
}
function greet(name, greeting) {
if (greeting === undefined) greeting = 'Olá';
return greeting + ', ' + name + '!';
}
let multiply = (a, b) => a * b;
let square = n => n * n;
let html = '';
html += 'add(3, 5) = ' + add(3, 5) + '<br>';
html += 'add(10, 20) = ' + add(10, 20) + '<br>';
html += "greet('Alice') = " + greet('Alice') + '<br>';
html += "greet('Alice', 'Oi') = " + greet('Alice', 'Oi') + '<br>';
html += 'multiply(4, 6) = ' + multiply(4, 6) + '<br>';
html += 'square(7) = ' + square(7) + '<br>';
document.getElementById('output').innerHTML = html;
</script>
</body>
</html>
Exemplo: Calculadora Simples
<!DOCTYPE html>
<html lang="pt-br">
<body>
<h2>Calculadora Simples</h2>
<input type="number" id="numA" placeholder="Número 1">
<select id="op">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">×</option>
<option value="/">÷</option>
</select>
<input type="number" id="numB" placeholder="Número 2">
<button onclick="calc()">Calcular</button>
<p id="result"></p>
<script>
function calc() {
let a = Number(document.getElementById('numA').value);
let b = Number(document.getElementById('numB').value);
let op = document.getElementById('op').value;
let res;
switch (op) {
case '+': res = a + b; break;
case '-': res = a - b; break;
case '*': res = a * b; break;
case '/':
if (b === 0) {
document.getElementById('result').innerHTML = 'Não é possível dividir por zero!';
return;
}
res = a / b;
break;
}
document.getElementById('result').innerHTML =
a + ' ' + op + ' ' + b + ' = <strong>' + res + '</strong>';
}
</script>
</body>
</html>
Escopo de Função
Variáveis declaradas dentro de uma função são locais — elas só existem dentro daquela função. Isso é escopo:
<script>
function test() {
let x = 10; // variável local
const y = 20;
var z = 30;
}
test();
// console.log(x); // ReferenceError: x is not defined
</script>
Funções podem acessar variáveis externas (a base dos closures), mas o código externo não pode acessar variáveis dentro de uma função:
<!DOCTYPE html>
<html lang="pt-br">
<head><meta charset="UTF-8"><title>Escopo de Função</title></head>
<body>
<pre id="output"></pre>
<script>
let global = 'Variável global';
function show() {
let local = 'Variável local';
document.getElementById('output').textContent +=
'Dentro da função — global: ' + global + '\n' +
'Dentro da função — local: ' + local + '\n';
}
show();
document.getElementById('output').textContent +=
'Fora da função — global: ' + global + '\n' +
'Fora da função — local: não acessível (variável local)';
</script>
</body>
</html>
let/const/var cria uma variável global — uma fonte comum de bugs. Sempre declare variáveis com let ou const.
Exemplo: Demonstração de Escopo
<!DOCTYPE html>
<html lang="pt-br">
<body>
<h2>Escopo de Função</h2>
<div id="output"></div>
<script>
let outer = 'Variável externa';
function demo() {
let inner = 'Variável interna';
let html = '';
html += 'Dentro da função — outer: ' + outer + '<br>';
html += 'Dentro da função — inner: ' + inner + '<br>';
function nested() {
let deep = 'Variável aninhada';
html += 'Função aninhada — outer: ' + outer + '<br>';
html += 'Função aninhada — inner: ' + inner + '<br>';
html += 'Função aninhada — deep: ' + deep + '<br>';
}
nested();
return html;
}
let result = demo();
result += 'Fora da função — outer: ' + outer + '<br>';
result += 'Fora da função — inner: não acessível (local)';
document.getElementById('output').innerHTML = result;
</script>
</body>
</html>
Introdução a Callbacks
JavaScript permite que você passe uma função como argumento para outra função — a função passada é chamada de callback:
<!DOCTYPE html>
<html lang="pt-br">
<head><meta charset="UTF-8"><title>Callbacks</title></head>
<body>
<pre id="output"></pre>
<script>
function processArray(arr, callback) {
for (let item of arr) {
callback(item);
}
}
let names = ['Alice', 'Bob', 'Charlie'];
processArray(names, function(name) {
document.getElementById('output').textContent += 'Olá, ' + name + '\n';
});
</script>
</body>
</html>
Você já usou callbacks — os argumentos de forEach, map e filter são todos funções de callback:
<script>
// A função anônima aqui é um callback
[1, 2, 3].forEach(function(n) {
console.log(n);
});
// Arrow functions tornam mais conciso
[1, 2, 3].forEach(n => console.log(n));
</script>
Exemplo: Callbacks em Ação
<!DOCTYPE html>
<html lang="pt-br">
<body>
<h2>Funções de Callback</h2>
<div id="output"></div>
<script>
function processList(items, action) {
let results = [];
for (let item of items) {
results.push(action(item));
}
return results;
}
let nums = [1, 2, 3, 4, 5];
let doubled = processList(nums, n => n * 2);
let squared = processList(nums, n => n * n);
let labeled = processList(nums, n => 'Item ' + n);
let html = '';
html += 'Original: [' + nums.join(', ') + ']<br><br>';
html += '<strong>Callback: n => n * 2</strong><br>';
html += 'Resultado: [' + doubled.join(', ') + ']<br><br>';
html += '<strong>Callback: n => n * n</strong><br>';
html += 'Resultado: [' + squared.join(', ') + ']<br><br>';
html += '<strong>Callback: n => "Item " + n</strong><br>';
html += 'Resultado: [' + labeled.join(', ') + ']<br><br>';
html += '<strong>Callback do setTimeout (aparece após 2 segundos):</strong><br>';
html += '<span id="timer">Aguardando...</span>';
document.getElementById('output').innerHTML = html;
setTimeout(function() {
document.getElementById('timer').textContent = "Tempo esgotado! Callback executado.";
document.getElementById('timer').style.color = 'green';
}, 2000);
</script>
</body>
</html>
📖 Resumo
- Declarações de função são elevadas; expressões de função não — definir antes de usar é mais seguro
- Parâmetros padrão adicionam flexibilidade; coloque-os no final da lista de parâmetros
returnencerra a função e devolve um valor; sem ele, a função retornaundefined- Arrow functions
(a, b) => a + bsão atalhos — de uma linha auto-retorna; múltiplas linhas precisam de{} - Variáveis declaradas dentro de uma função são locais e invisíveis do lado de fora
- Callbacks = passar uma função como argumento — usado por
forEach,setTimeoute muitos outros
❓ Perguntas Frequentes
P:Qual a diferença entre arrow functions e funções regulares? R:Além da sintaxe mais curta, arrow functions não têm seu próprio
this— elas herdam do escopo circundante. Quando você precisa quethisse refira ao objeto atual (em métodos ou manipuladores de eventos), use uma função regular. Para funções utilitárias simples, a sintaxe arrow funciona muito bem.
P:Uma função pode retornar múltiplos valores? R:Não diretamente, mas você pode retornar um array ou objeto e desestruturá-lo:
function getInfo() { return [nome, idade]; }— depois chame comlet [nome, idade] = getInfo().
P:E se eu tiver parâmetros demais? R:Quando você tem mais de 3 parâmetros, considere usar um objeto:
function createUser({ nome, idade, cidade }) {}— chame comcreateUser({ nome: 'Alice', idade: 20, cidade: 'SP' }). A ordem não importa, e é muito mais legível.
📝 Atividades
- Escreva uma função
isEven(n)que retornatruese um número é par,falsecaso contrário. Teste com múltiplos valores na página. - Escreva uma função
formatPrice(preco)que recebe um número e retorna uma string de preço formatada (ex:formatPrice(9.9)retorna"R$9,90"). Use sintaxe de arrow function. - Construa um "gerador de saudações": use uma função de callback que recebe um array de nomes e uma função de saudação, depois exiba saudações personalizadas para cada pessoa na página.



