Solucionado (ver solução)
Solucionado
(ver solução)
5
respostas

A data ainda é mutável

Ao aplicar este código (mesmo tendo feito as técnicas de programação defensiva da vídeo aula) consigo alterar minha data:

var n1 = new Negociacao(new Date(), 5, 200.5);
    console.log(n1.data);
    n1._data.setDate(11);
    console.log(n1.data);

Pois minha "_data" também é um objeto e mesmo com o freeze o congelamento é superficial.

Para este caso, há alguma maneira de protegê-la?

Obrigado! \o

5 respostas

O método Object.freeze() congela um objeto: isto é, impede que novas propriedades sejam adicionadas a ele; impede que as propriedades existentes sejam removidas; e impede que propriedades existentes, ou sua inumerabilidade, configurabilidade, ou capacidade de escrita sejam alteradas. Em essência o objeto é efetivamente imutável. O método retorna o objeto congelado.

Link pra documentação esta AQUI

solução!

Opa, Lucas! Como vai?

O problema é que dessa forma vc está quebrando a convenção de não acessar diretamente os atributos de sua classe! Justamente por isso o instrutor coloca o "_" antes dos nomes dos atributos para indicar ao programador que não deve acessar eles diretamente e sim através dos métodos getter e setter. A solução nesse seu caso é seguir a convenção que o instrutor acordou durante o curso.

Mas, a boa notícia, é que nas próximas versões do EcmaScript pode ser que surja a possibilidade de criar atributos privados de modo que a solução não seja apenas uma conveção de colocar um "_" antes do nome do atributo.

Pegou a ideia? Qualquer coisa é só falar!

Grande abraço e bons estudos!

Boa tarde Lucas,

No curso aprendemos que propriedades com o underline "_" antes do nome são propriedades privadas e não devem ser diretamente manipuladas fora de suas classes, ou seja ao mexer nessas variáveis você já estaria fazendo uma prática ruim.

Mas vamos lá como fazemos pra tornar um objeto realmente imutável no javascript? Existem vários jeitos um deles é declarar essa variável como uma const, ou utilizar recursos externos como o deepfreeze, que basicamente faz um loop em todas as propriedades de um objeto e aplica o object.freeze nelas.

Uma vez eu precisei armazenar o resultado que vinha de uma API para preservar o resultado de uma tela que era alterada pelo usuário, mas que em seguida poderia voltar ao estado original. Depois de quebrar um pouco a cabeça descobri que você pode transformar um objeto em uma string. Dessa maneira essa string fica armazenada como o estado original daquele objeto, e depois quando você quiser recuperar aquele objeto basta fazer o parse da string. Pra entender o motivo de eu quebrar tanto a cabeça recomendo estudar a diferença de "passagem por valor" e "passagem por referência".

Exemplo de como armazenar o resultado original de um objeto:

var objeto = { 
            "name":"John", 
      "age":30, 
      "city":"New York"
};

//Transformando objeto em String
var objetoEstadoOriginal = JSON.stringify(objeto);

//Mudando objeto
objeto.name = "Oswaldo";

//Recuperando o objeto original
var novoObjeto = JSON.parse(objetoEstadoOriginal);

// Imprimindo objeto original
console.log(novoObjeto);

Abraços

Obrigado pelas explicações. Em relação a boa prática eu havia entendido, apenas queria saber se tinha como tornar imutável de fato. A solução do Vinicius foi bem show! Obrigado por compartilhar.

Valeu gente \o

Por nada, Lucas! Sempre que tiver qualquer dúvida é só mandar aqui no fórum!

Grande abraço e bons estudos!