Encapsulamento Real em JavaScript com Campos Privados (#field)
Garantir o encapsulamento de dados no JavaScript tradicionalmente dependia de convenções visuais (como o prefixo _) ou Closures, que não impediam o acesso externo direto às propriedades. O uso de campos e métodos privados nativos com o prefixo # resolve esse problema ao fornecer verdadeiro isolamento de estado diretamente na sintaxe de classes ES6+.
JavaScript
class ContaBancaria {
// Declaração de campos privados (devem ser declarados no topo da classe)
#saldo = 0;
#senha;
constructor(titular, senhaInicial) {
this.titular = titular; // Propriedade pública
this.#senha = senhaInicial;
}
/**
* Método público para depositar valores com validação
*/
depositar(valor) {
if (valor <= 0) return 'Valor de depósito inválido.';
this.#saldo += valor;
this.#validarTransacao('Depósito');
return `Depósito realizado. Novo saldo: R$ ${this.#saldo}`;
}
/**
* Método privado: inacessível fora do escopo desta classe
*/
#validarTransacao(tipo) {
console.log(`[LOG INTERNO] Transação '${tipo}' registrada para ${this.titular}.`);
}
}
// --- Exemplo Prático de Uso ---
const minhaConta = new ContaBancaria('Ana Silva', '1234');
console.log(minhaConta.depositar(500));
// Saída: [LOG INTERNO]... | Depósito realizado. Novo saldo: R$ 500
console.log(minhaConta.titular); // Saída: 'Ana Silva' (Propriedade pública)
// Tentativas de acesso externo a membros privados disparam erro de sintaxe:
// console.log(minhaConta.#saldo); // SyntaxError: Private field '#saldo' must be declared in an enclosing class
// minhaConta.#validarTransacao('Teste'); // SyntaxError
Pontos-chave
- Garantia de Erro em Tempo de Compilação/Parsing: Tentar acessar ou modificar uma propriedade com
#fora do escopo da classe resulta em umSyntaxErrorimediato, impedindo o bypass acidental. - Obrigatoriedade de Declaração Prévia: Diferente das propriedades públicas, todos os campos privados devem ser declarados explicitamente no corpo da classe antes de serem atribuídos dentro do
constructorou de métodos. - Incompatibilidade com Operador
inDinâmico: Não é possível checar dinamicamente a presença de campos privados usandoObject.keys()ou inspeção de objetos, o que impede vazamentos de abstração e reflexão não autorizada. - Suporte Nativo Amplo: Funciona nativamente no Node.js (v12+) e em todos os navegadores modernos sem a necessidade de compiladores externos como Babel ou linguagens auxiliares como TypeScript.
