22 pontos por GN⁺ 2025-07-15 | 3 comentários | Compartilhar no WhatsApp
  • As declarações de função em JavaScript podem ser feitas de várias formas, como declaração com a palavra-chave function, expressão de função e arrow function
  • Declarações de função passam por hoisting, então podem ser referenciadas em qualquer ponto do código
  • Arrow functions têm como vantagem a sintaxe concisa, mas apresentam diferenças importantes, como não terem vinculação própria de this/arguments/super
  • Funções construtoras, generators e métodos não são casos adequados para uso de arrow functions
  • Para callbacks simples ou funções anônimas, as arrow functions são mais apropriadas

Function Declarations, Function Expressions, and Arrow Functions

  • Em JavaScript, é possível definir funções de três formas: declaração de função (statement), expressão de função (expression) e arrow function
  • A declaração de função faz a vinculação direta do nome, como em function isVowel(chr) { ... }, e pode ser referenciada em qualquer lugar do código (hoisting). Em stack traces e durante a depuração, o nome da função aparece de forma clara
  • A expressão de função é a forma de atribuir uma função anônima a uma variável, como em const takeWhile = function(predicate, arr) { ... }
  • Também é possível dar um nome interno a uma expressão de função, mas esse nome não é vinculado ao escopo externo e é usado principalmente para rastrear erros em stack traces

Hoisting and Naming

  • Declarações de função são içadas (hoisted) pelo mecanismo do JavaScript, então funcionam mesmo se forem chamadas antes da declaração
  • Expressões de função anônimas só podem ser chamadas depois da atribuição à variável
  • Para depuração, dar um nome explicitamente à função pode ser vantajoso nos stack traces

Arrow Functions

  • Sintaxe curta e concisa: escritas na forma (parâmetros) => { ... }, sem a palavra-chave function
  • São sempre funções anônimas (embora possam ser atribuídas a variáveis e usadas como se tivessem nome)
  • Só podem ser usadas como expressão (expression), não como statement
  • Não têm vinculação própria de this/arguments/super: diferente das declarações/expressões de função, elas capturam o this do escopo externo
  • No caso de uma única expressão, é possível omitir chaves e return; se houver apenas 1 parâmetro, os parênteses também podem ser omitidos
  • Não podem ser usadas como construtoras: arrow functions não podem ser chamadas com a palavra-chave new e não funcionam como funções construtoras
  • Não podem ser generators: não é possível usar yield, então não dá para criar funções generator com elas
  • Exemplos de código:
    const sum = (a, b) => a + b;  
    const square = x => x * x;  
    

Exemplo prático: this, construtores e generators

  • É apresentado um exemplo da diferença de comportamento do this entre funções normais e arrow functions
    • Ao usar como método dentro de um objeto, uma função normal faz com que this aponte para o próprio objeto, enquanto uma arrow function aponta para undefined ou para o this do escopo externo
  • Ao definir uma função construtora como arrow function, ocorre um TypeError
  • Funções generator obrigatoriamente precisam usar a sintaxe function*

Que sintaxe de função escolher e quando?

  • Se você precisa de generator (uso de yield) → use function*
  • Se precisa usar this → use a palavra-chave function ou um método de classe
  • Se precisa de hoisting ou quer melhor legibilidade em nível mais alto → use declaração de função
  • Se nenhuma dessas condições se aplica → arrow functions são vantajosas por deixarem o código mais conciso

Conclusão

  • Em JavaScript, a sintaxe da função deve ser escolhida de acordo com o objetivo, a necessidade de this e se ela será construtora ou generator
  • Para callbacks do dia a dia e funções simples, arrow functions são a melhor escolha
  • Para métodos de objeto, construtores e generators, é necessário usar a sintaxe com function
  • Se você precisa de hoisting ou de mais liberdade na ordem das declarações, a declaração de função é mais vantajosa

3 comentários

 
ng0301 2025-07-15

Tão fundamental quanto isso também é a presença ou ausência de prototype ...
E também a forma de referenciar as funções de ordem superior que são geradas ...

 
bichi 2025-07-15

const a = (a: () => null): (() => () => null) =>() => a

 
bichi 2025-07-15

() => ❤️