Object.defineProperty
Em bibliotecas e APIs reais, você frequentemente precisa proteger propriedades internas contra alterações acidentais ou ocultá-las de iterações. Com Object.defineProperty, você define exatamente como cada propriedade se comporta: se pode ser modificada, se aparece em laços for...in ou se pode ser deletada. Esse controle fino evita bugs e garante que contratos de interface sejam respeitados.
O PROBLEMA
Use Object.defineProperty para criar propriedade não-enumerável e somente-leitura.
EXEMPLO
Object.defineProperty(obj, "versao", {value:"1.0", writable:false, enumerable:false});SOBRE O CONCEITO
Object.defineProperty permite definir ou modificar descritores de propriedade. Os principais atributos são: value (valor), writable (se pode ser reatribuída), enumerable (se aparece em for...in ou Object.keys), configurable (se pode ser deletada ou ter seus descritores alterados). No exemplo, writable:false e enumerable:false criam uma propriedade somente leitura e invisível em iterações. O erro comum é confundir writable com configurable: writable controla apenas a alteração de valor via atribuição; configurable controla a remoção da propriedade e a alteração dos descritores (exceto writable se já for false). Se você quer proteger contra exclusão, precisa de configurable:false também. Sempre verifique com Object.getOwnPropertyDescriptor para inspecionar os descritores atuais.
RESOLUÇÃO