Bem-vindos à nossa comunidade!

Junte-se a nós e faça parte hoje mesmo!

Aula: Aula: Imutabilidade #03

Raquel

Membro
Cadastro
24/9/20
Postagens
168
Curtidas
169
Pontuação
100
E vamos de estrear os fóruns! Hahaha

Recebi a seguinte pergunta hoje:

Posso usar o Object.freeze() para congelar os atributos de um objeto?

A ideia era criar um objeto dentro de um objeto e usar o Object.freeze() para impedir a modificação dos atributos. Dessa maneira:

JavaScript:
const pessoa = {
    dadosImutaveis: Object.freeze({  
    nome: 'Fulano',
    rg: 123587,
    cpf: 181482,
    telefone: 4781851,
    endereco: "....." ,
    grauEscolaridade: "..."
    })
}

Interessante a ideia, o problema é que isso não funciona!

JavaScript:
dadosImutaveis.nome = 'Sicrano'
console.log(dadosImutaveis.nome) //dá erro! diz que dadosImutaveis não está definido

O Object.freeze() só funciona quando usado em um único objeto, que contenha somente seus atributos e métodos. Dessa maneira:

JavaScript:
const pessoa = {
    nome: 'Fulano',
    rg: 123587,
    cpf: 181482,
    telefone: 4781851,
    endereco: "....." ,
    grauEscolaridade: "..."
}

pessoa.endereco = "Rua das Estrelas" //alterei o objeto e não é isso que queremos!
console.log(pessoa.endereco)

Object.freeze(pessoa) //congelando o objeto!
pessoa.cpf = 123456 //tentativa de alteração...
console.log(pessoa.cpf)//... não funcionou porque o objeto foi congelado!
 

mourabraz

Membro
Moderador
Cadastro
23/12/20
Postagens
106
Curtidas
155
Pontuação
100
Cidade
Leiria
Opa tudo bem?

Vamos por partes.

O função Object.freeze() serve para alterar algumas "flags" de todas as propriedades de um objecto, mais especificamente as flags configurable, writable (de cada propriedade)...
Cada propriedade do objecto possui as suas flags, mesmo nos objectos aninhados dentro de outros objectos, ou seja:
JavaScript:
const user = {
    name: 'Carlos',
    age: 39
}

const profile = {
    address: 'Rua de Leiria',
    photo: 'https://forum.cod3r.com.br/data/avatars/o/0/201.jpg?1608832599'
}

cada um dos objectos acima podem ter suas flags alteradas em cada propriedade, de forma independente, ou usando o Object.freeze(), ou seja, eu posso fazer isto:

JavaScript:
const user = {
    name: 'Carlos',
    age: 39
}
const profile = {
    address: 'Rua de Leiria',
    photo: 'https://forum.cod3r.com.br/data/avatars/o/0/201.jpg?1608832599'
}

Object.freeze(user)
Object.freeze(profile)
console.log(Object.isFrozen(user))    //true
console.log(Object.isFrozen(profile)) //true

outro exemplo seria este:

JavaScript:
const profile = {
    address: 'Rua de Leiria',
    photo: 'https://forum.cod3r.com.br/data/avatars/o/0/201.jpg?1608832599'
}

const user = {
    name: 'Carlos',
    age: 39,
    me: profile
}

Object.freeze(user.me)
console.log(Object.isFrozen(user))       //false
console.log(Object.isFrozen(user.me)) //true

console.log(Object.isFrozen(profile))  //true    // <-- este é interessante!!!

Ou seja, mesmo objectos aninhados podem ser "congelados"!

O legal é que ao aplicar Object.freeze a user.me o objecto profile também ficou "congelado"!

Isso acontece porque JS trata os objectos pela "referência" (sempre irei tentar me lembrar de usar aspas para dizer que JS usa referências - espero um dia poder falar sobre isso em um tópico mais avançado, mas usar essa palavra é comum e atende bem o que queremos dizer).

Resumindo: É possível "congelar" objectos mesmo quando aninhados.

dadosImutaveis.nome = 'Sicrano'
console.log(dadosImutaveis.nome) //dá erro! diz que dadosImutaveis não está definido
Neste caso, de fato dadosImutaveis não está definido. Para acessar os dadosImutaveis que foi "congelado" teria que acessar usando o objecto pessoa primeiro: pessoa.dadosImutaveis.nome

Mas, também é possível retirar só os [dadosMutaveis] dadosImutaveis, por exemplo:

JavaScript:
const pessoa = {
    dadosImutaveis: Object.freeze({
    nome: 'Fulano',
    rg: 123587,
    cpf: 181482,
    telefone: 4781851,
    endereco: "....." ,
    grauEscolaridade: "..."
    })
}
const dadosDeFora = pessoa.dadosImutaveis;
console.log(Object.isFrozen(pessoa))                           //false
console.log(Object.isFrozen(pessoa.dadosImutaveis)) //true
console.log(Object.isFrozen(dadosDeFora))                 //true



Espero ter ajudado.

Abraços!

PS em relação ao exemplo em específico, também poderíamos fazer algo assim:
JavaScript:
const pessoa = {
    nome: 'Fulano',  // apenas esta propriedade que queremos "congelar"
    rg: 123587,
    cpf: 181482,
    telefone: 4781851,
    endereco: "....." ,
    grauEscolaridade: "..."
}
Object.defineProperty(pessoa, "nome", {
  writable: false
});
Object.defineProperty(pessoa, "nome", {
  configurable: false
});

let descriptorNome = Object.getOwnPropertyDescriptor(pessoa, 'nome');
let descriptorRg = Object.getOwnPropertyDescriptor(pessoa, 'rg');
console.log(descriptorNome)
/*
configurable: false
enumerable: true
value: "Fulano"
writable: false
*/
console.log(descriptorRg)
/*
configurable: true
enumerable: true
value: 123587
writable: true
*/
 
Last edited:
Top