<h2>Declaração de Funções (Function Declaration)</h2>
<p>A declaração de função é a forma mais tradicional e direta de criar uma função em JavaScript. Você utiliza a palavra-chave <code>function</code>, seguida do nome, parâmetros entre parênteses e o corpo entre chaves. Essa forma é amplamente usada em código legado e continua sendo excelente para funções de escopo global ou para quando você precisa de hoisting.</p>
<pre><code class="language-javascript">function calcularDesconto(preco, percentual) {
const desconto = preco * (percentual / 100);
return preco - desconto;
}
console.log(calcularDesconto(100, 20)); // 80</code></pre>
<p>Em ambiente de produção, essa abordagem é útil quando você precisa que a função seja acessível antes de sua declaração no código — graças ao hoisting. Porém, evite depender disso; é melhor manter código organizado e legível.</p>
<h2>Expressões de Funções e Arrow Functions</h2>
<h3>Expressão de Função (Function Expression)</h3>
<p>Aqui você atribui uma função a uma variável. Diferentemente da declaração, essa função não sofre hoisting de forma total — apenas a variável é hoisted, não seu conteúdo.</p>
<pre><code class="language-javascript">const calcularIMC = function(peso, altura) {
return peso / (altura * altura);
};
console.log(calcularIMC(70, 1.75)); // ~22.86</code></pre>
<h3>Arrow Functions (ES6)</h3>
<p>Introduzidas em 2015, as arrow functions oferecem sintaxe concisa e binding léxico de <code>this</code>. São a escolha moderna padrão para código de produção.</p>
<pre><code class="language-javascript">// Múltiplos parâmetros
const saudacao = (nome, sobrenome) => {
return Olá, ${nome} ${sobrenome}!;
};
// Um parâmetro (parênteses opcionais)
const dobro = x => x * 2;
// Sem parâmetros
const getId = () => Math.random();
console.log(saudacao('João', 'Silva')); // Olá, João Silva!
console.log(dobro(5)); // 10</code></pre>
<p><strong>Dica importante:</strong> Arrow functions não têm seu próprio <code>this</code>. Isso é crucial em callbacks e métodos de objeto — use expressões de função tradicionais se precisar de <code>this</code> dinâmico.</p>
<pre><code class="language-javascript"></code></pre>
<h2>Hoisting: Como JavaScript Trata Funções</h2>
<p>Hoisting é o comportamento onde JavaScript "move" declarações de função e variáveis para o topo de seu escopo durante a compilação. Entender isso é crítico para evitar bugs em produção.</p>
<h3>Comportamento por Tipo de Função</h3>
<p><strong>Function Declaration:</strong> Completamente hoisted. Você pode chamar a função antes dela ser declarada.</p>
<pre><code class="language-javascript">console.log(somar(2, 3)); // 5 — funciona!
function somar(a, b) {
return a + b;
}</code></pre>
<p><strong>Function Expression e Arrow Functions:</strong> Apenas a variável é hoisted, não a função. Chamá-la antes da declaração resulta em erro.</p>
<pre><code class="language-javascript">console.log(multiplicar(2, 3)); // ❌ TypeError: multiplicar is not a function
const multiplicar = (a, b) => a * b;</code></pre>
<p><strong>Variáveis <code>var</code>:</strong> São hoisted, mas inicializadas como <code>undefined</code>. Com <code>let</code> e <code>const</code>, há hoisting mas há o "Temporal Dead Zone" — acesso antes da declaração causa erro.</p>
<pre><code class="language-javascript">console.log(x); // undefined
var x = 5;
console.log(y); // ❌ ReferenceError: Cannot access 'y' before initialization
let y = 10;</code></pre>
<blockquote><p><strong>Boas práticas:</strong> Sempre declare funções antes de usá-las, independente do tipo. Use <code>const</code> com arrow functions — é mais seguro e torna o código previsível.</p></blockquote>
<h2>Funções em Produção: Padrões e Boas Práticas</h2>
<p>Em código de produção real, você não escolhe um tipo de função apenas por sintaxe — contexto importa. Aqui estão padrões que realmente funcionam:</p>
<p><strong>Callbacks e Promises:</strong> Arrow functions são ideais porque evitam problemas com <code>this</code>.</p>
<pre><code class="language-javascript">fetch('/api/usuarios')
.then(res => res.json())
.then(dados => console.log(dados))
.catch(erro => console.error('Erro:', erro));</code></pre>
<p><strong>Funções Construtoras e Métodos de Classe:</strong> Use expressões de função tradicional ou métodos de classe.</p>
<pre><code class="language-javascript">class Usuario {
constructor(nome) {
this.nome = nome;
}
saudar() {
return Olá, sou ${this.nome};
}
// Não use arrow aqui se precisar de 'this'
}
const user = new Usuario('Pedro');
console.log(user.saudar()); // Olá, sou Pedro</code></pre>
<p><strong>Funções Puras e Utilitários:</strong> Arrow functions são perfeitas.</p>
<pre><code class="language-javascript">const filtrarPares = (numeros) => numeros.filter(n => n % 2 === 0);
const mapearIds = (usuarios) => usuarios.map(u => u.id);
console.log(filtrarPares([1, 2, 3, 4])); // [2, 4]</code></pre>
<p><strong>Evite Confusão de Hoisting:</strong> Em projetos grandes, erros de hoisting são silenciosos e perigosos. Mantenha consistência: declare antes de usar, use <code>const</code> por padrão.</p>
<h2>Conclusão</h2>
<p>Dominar funções em JavaScript é fundamental para escrever código profissional. Resumindo o aprendizado: <strong>(1)</strong> Use <code>const</code> com arrow functions como padrão em código moderno — sintaxe clara, <code>this</code> previsível, sem surpresas de hoisting. <strong>(2)</strong> Entenda hoisting completamente: declarações são hoisted, expressões não; <code>let</code> e <code>const</code> são seguros; <code>var</code> causa caos. <strong>(3)</strong> Escolha o tipo de função conforme o contexto: callbacks, promises e utilidades ganham com arrow functions; métodos e construtores se beneficiam de expressões tradicionais. Esses três pilares, aliados ao código organizado e consistente, levam você a produção confiável.</p>
<h2>Referências</h2>
<ul>
<li><a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Guide/Functions" target="_blank" rel="noopener noreferrer">MDN Web Docs - Funções JavaScript</a></li>
<li><a href="https://tc39.es/ecma262/#sec-arrow-function-definitions" target="_blank" rel="noopener noreferrer">ECMAScript Specification - Arrow Functions</a></li>
<li><a href="https://github.com/getify/You-Dont-Know-JS/tree/2nd-ed/scope-closures" target="_blank" rel="noopener noreferrer">You Don't Know JS - Scope & Closures</a></li>
<li><a href="https://pt.javascript.info/function-basics" target="_blank" rel="noopener noreferrer">JavaScript.info - Funções</a></li>
<li><a href="https://google.github.io/styleguide/jsguide.html" target="_blank" rel="noopener noreferrer">Google JavaScript Style Guide</a></li>
</ul>