W3docs

Membros de Classe Privados e Protegidos em JavaScript

Aprenda a usar membros privados com prefixo `#` e a convenção `_` para membros protegidos em classes JavaScript, com getters e setters.

Uma classe frequentemente precisa ocultar parte de seu funcionamento interno para que o código externo não possa lê-los ou alterá-los diretamente. Esta página aborda as duas formas que o JavaScript oferece para isso: membros verdadeiramente privados declarados com o prefixo #, e a convenção de underscore _ que os desenvolvedores usam para marcar membros como "protegidos" (destinados apenas à classe e suas subclasses).

Você verá quando usar cada um, por que os campos # são genuinamente inacessíveis de fora, e como combinar campos privados com getters e setters para expor uma interface controlada e validada. Se classes são novidade para você, comece pelo capítulo Sintaxe básica de classes primeiro.

Introdução ao Encapsulamento em JavaScript

O encapsulamento é um princípio fundamental da programação orientada a objetos (POO): ele agrupa os dados (variáveis) e os métodos (funções) que operam sobre esses dados em uma única unidade — um object — e controla o acesso aos internos desse object. O objetivo é expor uma interface pública pequena e deliberada, ocultando os detalhes de implementação por trás dela.

Por que isso importa? Quando o estado interno está oculto, o código externo não pode colocar seu object em um estado inválido, e você é livre para alterar o funcionamento interno da classe sem quebrar o código que a usa. Em JavaScript, o encapsulamento é alcançado com campos e métodos privados #. JavaScript não possui um modificador protected nativo, então os desenvolvedores o simulam com uma convenção de nomenclatura (o prefixo _), conforme explicado abaixo.

Propriedades e Métodos Privados

Um membro privado de classe é declarado com o prefixo # em seu nome. Ele só pode ser acessado de dentro do corpo da classe — qualquer tentativa de lê-lo ou escrevê-lo de fora é um erro de sintaxe real, não apenas undefined. Esta é uma privacidade real, imposta pela linguagem.

Um campo deve ser declarado no corpo da classe antes de ser usado (você não pode criar um campo # dinamicamente dentro do construtor como faria com uma propriedade pública). Note também que os campos privados # são não-enumeráveis: eles não aparecem em Object.keys(), for...in, ou na saída de JSON.stringify().

javascript— editable

Por que # é verdadeiramente privado

Ao contrário da convenção de underscore, um campo # é invisível fora da classe. Você não pode acessá-lo através de user.#name, por acesso de colchetes como user["#name"], ou por Object.keys(). A primeira forma é um erro de sintaxe; as outras simplesmente não encontram o campo.

javascript— editable

Métodos Privados

Os métodos também podem ser privados: prefixe o nome do método com #. Um método privado é útil para auxiliares internos que os chamadores nunca devem invocar diretamente — por exemplo, lógica de validação ou formatação que suporta a API pública, mas não faz parte dela.

javascript— editable

Propriedades e Métodos Protegidos (a convenção _)

JavaScript não possui a palavra-chave protected. Por convenção, um membro destinado a ser usado pela classe e suas subclasses — mas não pelo código externo — é prefixado com um único underscore _. Isso é puramente um sinal para outros desenvolvedores; um membro _ permanece totalmente legível e gravável de qualquer lugar. Use-o quando as subclasses precisam de acesso (um campo # não é acessível a partir de subclasses), e aceite que a proteção é por acordo, não por imposição.

javascript— editable

Como os membros _ são herdados como qualquer propriedade normal, uma subclasse pode depender deles. Esta é a razão prática para usar a convenção em vez de # ao projetar para herança:

javascript— editable

Encapsulamento Baseado em Acessores: Boas Práticas

Ao incorporar propriedades e métodos privados e protegidos em seus projetos JavaScript, considere as seguintes boas práticas para maximizar seus benefícios:

  • Use campos privados para dados sensíveis ou invariáveis: Armazene qualquer coisa que não deva ser tocada diretamente — contadores internos, valores em cache, estado bruto — como um campo #. Isso garante integridade e evita efeitos colaterais indesejados.
  • Aproveite getters e setters: Mantenha o campo privado e exponha-o por meio de um getter e setter. O setter é a sua oportunidade de validar ou transformar a entrada antes que ela alcance o campo privado, para que o object nunca possa conter um valor inválido.

No exemplo abaixo, #age só pode ser alterado por meio do setter, que rejeita números negativos:

javascript— editable

Você também pode expor o estado como somente leitura definindo um getter sem um setter correspondente — o consumidor pode ler o valor, mas não tem como sobrescrever o campo privado subjacente.

  • Aplique membros protegidos para herança: Use propriedades e métodos protegidos quando pretender que sejam acessíveis dentro das subclasses. Esta estratégia facilita uma estrutura mais flexível e hierárquica em suas aplicações.

Técnicas e Padrões Avançados

Além do básico, JavaScript permite padrões e técnicas sofisticadas para encapsular e estruturar seu código de forma mais eficaz:

  • Padrão de módulo: Utilize closures e expressões de função imediatamente invocadas (IIFE) para criar escopos privados.
  • Funções de fábrica: Essas funções retornam novos objects, permitindo dados privados por meio de closures, sem a necessidade da palavra-chave new.
  • Proxies: Proxies em JavaScript podem ser usados para criar envoltórios protetores em torno de objects, controlando o acesso às suas propriedades e métodos.

Conclusão

Use campos e métodos # quando quiser privacidade genuína e imposta que nenhum código externo possa alcançar. Use a convenção de underscore _ quando as subclasses precisam de acesso e a proteção pode ser por acordo. Combine campos privados com getters e setters para expor uma interface controlada e validada — e getters somente leitura quando o estado deve ser observável, mas não mutável.

Tópicos relacionados

Prática

Prática
Quais são afirmações verdadeiras sobre propriedades e métodos privados e protegidos em JavaScript?
Quais são afirmações verdadeiras sobre propriedades e métodos privados e protegidos em JavaScript?
Was this page helpful?