W3docs

Objeto Function e Expressões de Função Nomeadas (NFE) em JavaScript

Aprenda que funções em JavaScript são objetos: leia as propriedades name e length, adicione propriedades personalizadas e use Expressões de Função Nomeadas (NFE) para auto-referência confiável e recursão.

Funções São Objetos

Em JavaScript, toda função é um object. Esse único fato explica muito do comportamento que, de outra forma, parece mágico: você pode passar uma função como qualquer valor, armazená-la em uma variável, ler propriedades dela e até adicionar suas próprias propriedades a ela.

Você já cria funções o tempo todo com declarações e expressões de função. Este capítulo analisa o que uma função é depois de criada: um object com propriedades internas úteis (name e length), a capacidade de armazenar propriedades personalizadas e uma forma especial — a Expressão de Função Nomeada — que permite a uma função se referenciar de forma confiável.

Esta página pressupõe que você está familiarizado com Expressões de Função. Se let f = function() {...} é algo novo para você, leia isso primeiro.

A Propriedade name

Toda função tem uma propriedade name que armazena o nome da função como uma string. A parte inteligente é que o JavaScript a preenche mesmo quando não há um nome no lugar óbvio — um comportamento chamado nomenclatura contextual.

javascript— editable

O motor analisa a atribuição e copia o nome da variável para a função anônima. Isso também funciona para parâmetros padrão e métodos de object:

javascript— editable

Porém, não existe mágica que funcione sempre. Se não há nome e nenhuma fonte de onde copiar um — por exemplo, uma função criada dentro de um array — name é uma string vazia:

javascript— editable

A propriedade name é útil para logging e depuração: um rastreamento de pilha que diz at sayHi é muito mais útil do que at <anonymous>.

A Propriedade length

A propriedade length de uma função retorna o número de parâmetros que ela declara em sua definição. Parâmetros rest (...rest) e parâmetros com valores padrão não são contados, e a contagem para no primeiro desses parâmetros.

javascript— editable

Um uso real comum de length é introspectar um callback. Algumas bibliotecas chamam um handler de forma diferente dependendo de quantos argumentos ele espera — por exemplo, tratando um handler sem argumentos como "executar uma vez para todos" e um handler com um argumento como "executar uma vez por item".

Propriedades Personalizadas

Como uma função é um object, você pode adicionar suas próprias propriedades a ela. Isso é diferente de uma variável local: uma propriedade vive na função e sobrevive entre chamadas, sendo uma maneira organizada de dar a uma função seu próprio estado persistente.

Um exemplo clássico é um contador de chamadas:

javascript— editable

Uma propriedade de função não é o mesmo que uma variável dentro da função. Uma variável local é redefinida a cada chamada; uma propriedade persiste, e também é legível e gravável externamente, o que a torna útil para configuração (como armazenar resultados em cache na própria função).

Expressões de Função Nomeadas (NFE)

Uma Expressão de Função Nomeada é uma expressão de função que carrega um nome após a palavra-chave function:

let sayHi = function func(who) {
  console.log("Hello, " + who);
};

Isso parece incomum — por que dar um nome a algo já atribuído a sayHi? O nome func aqui é especial de duas formas:

  • Ele permite que a função se referencie de forma confiável a partir do seu próprio corpo.
  • Ele é visível apenas dentro da função — você não pode chamar func() externamente.

Por que o nome interno importa

Você pode pensar que poderia usar a variável externa sayHi para auto-referência. O problema é que a variável externa pode mudar. Com uma NFE, o nome interno sempre aponta para a função atual, independentemente do que aconteça com a variável:

javascript— editable

Se a função tivesse chamado sayHi("Guest") em vez de func("Guest"), a chamada lançaria um TypeError porque sayHi foi definido como null. O nome interno é imune a isso.

NFE e recursão

Essa auto-referência é exatamente o que a recursão precisa. Uma NFE mantém uma chamada recursiva funcionando mesmo que a função seja posteriormente reatribuída ou passada com outro nome — veja Recursão e Pilha em JavaScript para o panorama completo.

javascript— editable

Observe que o truque do nome interno se aplica apenas a Expressões de Função. Uma Declaração de Função não pode ter um nome interno separado e não tem como ocultar um nome do escopo externo, portanto não pode manter uma auto-referência privada da mesma forma.

Quando Usar Esses Recursos

  • Use name para logs mais claros e saída de depuração.
  • Use length ao escrever bibliotecas que se adaptam à aridade de um callback.
  • Use propriedades personalizadas para dar a uma função estado persistente (contadores, caches, configuração) sem um closure envolvente ou uma variável global.
  • Use uma Expressão de Função Nomeada sempre que uma expressão de função precisar se chamar — especialmente para recursão ou handlers destacáveis — para que a chamada sobreviva à reatribuição de variáveis.

Resumo

Uma função JavaScript é um object que você pode inspecionar e estender. A propriedade name fornece seu nome (muitas vezes preenchido contextualmente), length informa a contagem de parâmetros declarados e você pode adicionar propriedades personalizadas para estado persistente. Uma Expressão de Função Nomeada adiciona um nome interno exclusivo que permite a uma função se chamar de forma confiável, sendo a maneira mais segura de escrever expressões de função auto-referenciais e recursivas.

Prática

Prática
O que é uma NFE (Expressão de Função Nomeada) em JavaScript?
O que é uma NFE (Expressão de Função Nomeada) em JavaScript?
Was this page helpful?