🔏 Imutabilidade de Atribuição VS Imutabilidade de Valor
Tags: javascript, braziliandevs, imutabilidade
Published: 2024-06-28 11:34:10

Sim! Podemos alterar o valor de uma `const` quando o tipo de dado atribuído a ela é de um array ou objeto. No código abaixo podemos ver que o valor do array foi modificado. **Isso não é imutabilidade de valor!**

![alterando o valor de um array atribuído a uma const](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bkhcxgfrw7mujl9y72wt.png)

Já no código abaixo podemos ver a **imutabilidade de atribuição**:

![tentando atribuir outro valor a uma const](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w885d26ks3qlpz9k1v97.png)

Vamos entender melhor como isso funciona por debaixo dos panos; sobre imutabilidade no JavaScript e **como evitar** que um array ou objeto atribuído em uma `const` seja alterado.

[![A Jornada do Autodidata em Inglês](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pkoqkmh9hic17tnddjf6.png)](https://go.hotmart.com/R93865620U)

* [Mutabilidade VS Imutabilidade](#mutabilidade-vs-imutabilidade)
* [Data Types](#data-types)
  - [O que é Stack?](#o-que-e-stack)
  - [O que é Heap?](#o-que-e-heap)
  - [Tipos de dados primitivos](#tipos-de-dados-primitivos)
  - [Tipos de dados de referência](#tipos-de-dados-referencia)
* [Mutabilidade no JavaScript](#mutabilidade-no-javascript)
  - [Como clonar propriedades de objetos](#como-clonar-propriedades-de-objetos)
  - [Usando o Spread Operator](#usando-o-spread-operator)
* [Imutabilidade no JavaScript](#imutabilidade-no-javascript)
* [Como evitar a mutabilidade de objetos](#como-evitar-a-mutabilidade-de-objetos)
  - [Como usar o método `Object.preventExtensions`](#como-usar-o-metodo-object-prevent-extensions)
  - [Como usar o método `Object.seal()`](#como-usar-o-metodo-object-seal)
  - [Como usar o método `Object.freeze()`](#como-usar-o-metodo-object-freeze)
  - [Como usar `Deep Freeze`](#como-usar-deep-freeze)
* [Como evitar a mutabilidade de arrays](#como-evitar-a-mutabilidade-de-arrays)
* [Considerações finais](#considerações-finais)


{% youtube https://youtu.be/LALVj4MnNkA %}


## Mutabilidade VS Imutabilidade <a name="mutabilidade-vs-imutabilidade">

No JavaScript, diferentes tipos de dados (data types em inglês) têm diferentes comportamentos e locais na memória. Portanto, **para reduzir as chances de ter bugs em seu código**, você precisa entender o conceito de mutabilidade e imutabilidade em JavaScript.

**Mutabilidade** refere-se a tipos de dados que podem ser acessados e alterados após serem criados e armazenados na memória. A **imutabilidade**, por outro lado, refere-se a tipos de dados que não podem ser alterados após a criação, mas que ainda podem ser acessados na memória.

---------------------------------------------------------------

## Data Types <a name="data-types">

Os tipos de dados (data types em inglês) são categorizados em **tipos primitivos** e **de referência** no JavaScript. Antes de explicar essas categorias, vamos dar uma olhada em dois termos importantes relacionados à memória que você precisará conhecer: a **Stack** e a **Heap**.

### O que é a Stack? <a name="o-que-e-stack">

A Stack (pilha em português) é uma estrutura de dados que obedece ao princípio **Last In First Out (LIFO)**. Isso significa que o último item a entrar na pilha sai primeiro.

![Last In First Out (LIFO)](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eaothkf0kxqztfrmvg44.png)
_Imagem acima da Wikipédia._


### O que é Heap? <a name="o-que-e-heap">

O **Heap** é usado apenas em variáveis do `tipo de dados de referência`.

O **Heap** guarda o **valor real** atribuído à variável. A variável guarda o endereço de memória do Heap. Quando o valor é atribuído à variável, a variável (armazenando o endereço de memória do Heap) é colocada na pilha por cima, por último.

![Exemplo Heap e Stack](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eau8oxlkhq8li7t5fjlh.png)

### Tipos de dados primitivos <a name="tipos-de-dados-primitivos">

Os tipos de dados primitivos são imutáveis e não são objetos porque não têm propriedades e métodos: `string`, `number`, `BigInt`, `boolean`, `undefined`, `Symbol`, `null`.

🤔 Espere um minuto, você pode pensar – eu mudo os valores das variáveis ​​primitivas o tempo todo!

Bem, pode parecer que você está modificando um valor, mas esse não é realmente o caso. Vamos mostrar um exemplo:

```javascript
let greet = "Hello";
greet += ", World";  
console.log(greet); // Hello, World
```

A primeira linha deste código cria a string `Hello` e a atribui à variável `greet`. A segunda linha anexa `, World` a essa string. Parece que estamos mudando a string `greet`, mas o JavaScript não altera a string, em vez disso, ele cria uma nova string.

![atribuindo valor a variavel greet](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y0usjv8flw8y3bkhqy67.png)



### Tipos de dados de referência <a name="tipos-de-dados-referencia">

Por padrão, os `tipos de dados de referência` **são mutáveis**. Os tipos de dados de referência consistem em **funções**, **arrays** e **objetos**.

Os `tipos de dados de referência` colocam a variável na **stack**. A variável funciona como um ponteiro que aponta para o objeto localizado na **heap**.

A principal diferença entre essas categorias é que os **tipos primitivos são `imutáveis`**, mas os **tipos de referência são `mutáveis`**.

---------------------------------------------------------------

## Mutabilidade no JavaScript <a name="mutabilidade-no-javascript">

Se um tipo de dado for mutável, significa que você pode alterá-lo. A mutabilidade permite que você modifique os valores existentes sem criar novos valores.

Para cada **objeto**, um ponteiro é adicionado à `stack`, e esse ponteiro aponta para o **objeto** no `heap`.

Veja, por exemplo, o código a seguir:

```javascript
const person = {
         name: "Mike Shinoda",
         age: 47,
         Hobbies: ["cantar", "tocar guitarra"]
   }
```

Na **stack**, você encontrará `person`, que é um ponteiro para o objeto real no **heap**.

```javascript
const person2 = person

console.log(person)

console.log(person2)
```

![person2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/less9um77fp8vo66fhr4.png)

Outro ponteiro é colocado na **stack** quando `person` é atribuído a `person2`. Agora, **esses ponteiros apontam para um único objeto** no **heap**.

Os dados de referência **não copiam valores**, mas sim **ponteiros**.

```javascript
person2.age = 53;

console.log(person)

console.log(person2)
```

![Alterando a idade](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pqrrd93inyzuid4k1sl8.png)

Alterar a idade de `person2` atualiza a idade do objeto `person`. Agora você sabe que isso ocorre **porque ambos apontam para o mesmo objeto**.

-----------------------------------------------------------------

## Como clonar propriedades de objetos <a name="como-clonar-propriedades-de-objetos">

O método `object.assign` copia propriedades de um objeto (a origem) para outro objeto (o destino) e retorna o objeto de destino modificado.

Veja a seguir a sintaxe:

```javascript
Object.assign(target, source)
```

O método tem dois argumentos, `target` e `source`. O `target` é o objeto que recebe as novas propriedades, enquanto a `source` é de onde vêm as propriedades. O `target` pode ser um objeto vazio `{}`.

Em uma situação em que o `source` e o `target` compartilham a mesma chave (key em inglês), o objeto de origem substitui o valor da chave no `target`.

```javascript
const person = {
         name: "Mike Shinoda",
         age: 47,
         Hobbies: ["cantar", "tocar guitarra"]
   }

const person2 = Object.assign({}, person);
```

As propriedades do objeto `person` foram clonadas em um `target` vazio.

`person2` agora tem suas próprias propriedades. Você pode comprovar isso alterando o valor de qualquer uma de suas propriedades. Essa alteração não afetará os valores das propriedades do objeto de `person`.

![Alterando person2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/df497nc1hg5cf9eog4n1.png)

O valor de `person2.age` que foi alterado para 53 não afeta de forma alguma o valor de `person.age` porque ambos têm suas próprias propriedades.

### Usando o Spread Operator <a name="usando-o-spread-operator">

Esta é a sintaxe do Spread Operator:

```javascript
const newObj = {...obj}
```


Usar o operador `spread` é bastante simples. Você precisa colocar três pontos `...` antes do nome do objeto cujas propriedades você pretende clonar:

```javascript
const person = {
         name: "Mike Shinoda",
         age: 47,
         Hobbies: ["cantar", "tocar guitarra"]
   }

const person2 = {...person};

person2.age = 53;

console.log(person)

console.log(person2)
```

![Usando o Spread Operator](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v46xqptl1zy70r7gaocv.png)

-----------------------------------------------------------------

## Imutabilidade no JavaScript <a name="imutabilidade-no-javascript">

Imutabilidade é o estado em que os valores são imutáveis (ou seja, não podem ser alterados). Um valor é imutável quando é impossível alterá-lo. Os tipos de dados primitivos são imutáveis, como discutimos acima.

Vamos dar uma olhada em um exemplo:

```javascript
let student1 = "Maiqui";

let student2 = student1;
```

No código acima, uma variável chamada `student1` foi criada e atribuída a `student2`.

```javascript
 student1 = "Mike"

 console.log(student1);

 console.log(student2)
```

A alteração de `student1` para `Mike` não altera o valor inicial de `student2`. Isso prova que, nos tipos de dados primitivos, os valores reais são copiados, portanto, ambos têm seus próprios valores. Na memória **stack**, `student1` e `student2` são diferentes.

![Alterando student1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ecoar9bhm1efnmvskb6s.png)

A **stack** obedece ao princípio **Last-In-First-Out** (último a entrar, primeiro a sair). O primeiro item que entra na **stack** é o último a sair e vice-versa. Assim, acessar aos itens armazenados na **stack** fica fácil.

-----------------------------------------------------------------

## Como evitar a mutabilidade de objetos <a name="como-evitar-a-mutabilidade-de-objetos">

Até agora, você aprendeu que os **objetos são mutáveis por padrão**.

```javascript
const people = {
           person1: 'Mike',
           person2: 'Chester',
           person3: 'Joe'
   }


   Object.defineProperty(people, "person4", {
      value: "Brad",
   })

   console.log(people);
```

Agora adicionamos o `person4`.

Para evitar a mutabilidade do objeto, você pode usar os métodos `Object.preventExtensions()`, `Object.seal()` e `Object.freeze()`.

Para todos os três métodos, exploraremos a **adição de propriedades** usando a `notação de ponto` e a propriedade `define`, a **modificação de propriedades** usando `defineProperty` e a **exclusão de propriedades**.

Isso lhe dará uma melhor compreensão dos recursos e das limitações de cada método e, por fim, o ajudará a determinar qual método é mais adequado para um caso de uso específico.

Portanto, vamos nos aprofundar e explorar esses métodos com mais detalhes.


### Como usar o método `Object.preventExtensions` <a name="como-usar-o-metodo-object-prevent-extensions">


Veja a seguir a sintaxe desse método:

```javascript
Object.preventExtensions(obj)
```

O uso do `Object.preventExtensions` **impede que novas propriedades entrem no objeto**. O objeto não aumenta de tamanho e mantém suas propriedades. **Por padrão, todos os objetos em JavaScript são extensíveis**. Com esse método, você pode excluir propriedades do seu objeto.

#### Tentando adicionar novas propriedades (`Object.preventExtensions`)

* usando a `notação de ponto (dot notation)`:

```javascript
const makeNonExtensive = {
           firstname: "Maiqui",
           lastname: "Tomé"
   }

   Object.preventExtensions(makeNonExtensive)

   makeNonExtensive.designation = "Software Engineer";
   
   console.log(makeNonExtensive)
```
Verifique o console - a propriedade `designation` não foi adicionada e não há nenhuma mensagem de erro:

![usando `dot notation` em preventExtensions](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ftjupl96hgwtsmrqfs0k.png)

* usando o método `defineProperty`

Aqui está a sintaxe:

```javascript
Object.defineProperty(obj, prop, descriptor)
```

Veja o que está acontecendo no código acima:
  1. `obj`: O objeto ao qual você deseja adicionar propriedades.
  2. `prop`: Você define o nome da propriedade que deseja adicionar ou alterar. Deve ser uma cadeia de caracteres ou um símbolo
  3. `descriptor`: você inclui o valor da propriedade.

```javascript
const makeNonExtensive = {
           firstname: "Maiqui",
           lastname: "Tomé"
   }

   Object.preventExtensions(makeNonExtensive)

   Object.defineProperty(makeNonExtensive, "age", {
      value: 18,
   })

   console.log(makeNonExtensive)
```

A **adição de novas propriedades** usando a propriedade `define` gera esta mensagem de erro: `Uncaught TypeError: Cannot define property age, object is not extensible`

![Usando defineProperty para adicionar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hbca3a7scwmze7tis2hb.png)

#### Como modificar uma propriedade existente usando `defineProperty` (`Object.preventExtensions`)

```javascript
const makeNonExtensive = {
            firstname: "Maiqui",
            lastname: "Tomé"
    }

Object.preventExtensions(makeNonExtensive)

Object.defineProperty(makeNonExtensive, 'firstname', {
  value: 'Mike',
})

console.log(makeNonExtensive)
```
 
O valor da propriedade de um objeto não extensível pode ser alterado:

![Usando defineProperty para modificar](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uougsvoq80xi7uhjy7j1.png)

#### Como excluir uma propriedade (`Object.preventExtensions`)

Aqui está a sintaxe:

```javascript
delete object.propertyname
```

```javascript
const makeNonExtensive = {
   firstname: "Maiqui",
   lastname: "Tomé"
}

Object.preventExtensions(makeNonExtensive)

delete makeNonExtensive.lastname

console.log(makeNonExtensive)
```

Apesar de o objeto não ser extensível, a propriedade `lastname` foi excluída:

![excluindo uma propriedade](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o4tjqbed7pqmkxh857jo.png)

### Como usar o método `Object.seal()` <a name="como-usar-o-metodo-object-seal">

Todos os objetos em Javascript são extensíveis por padrão. Como o nome sugere, esse método **sela** um objeto. Não é possível adicionar novas propriedades a um objeto selado ou excluir uma propriedade existente de um objeto selado. Mas o `object.seal` permite modificar as propriedades existentes.

Aqui está a sintaxe:

```javascript
Object.seal(obj)
```

#### Como adicionar novas propriedades (`Object.seal()`)


```javascript
const people = {
  person1: 'Maiqui',
  person2: "Maria", 
  person3: "Eduardo"
}

Object.seal(people)

console.log(Object.isSealed(people))
```

`Object.isSealed(people)` é usado para verificar se um objeto está selado.

* Como usar a `notação de ponto`


```javascript
people.person4 = "Patrick"

console.log(people)
```

**Sem produzir um erro**, a `notação de ponto` **falha** ao adicionar a nova propriedade `person4`:

![people.person4 = "Patrick"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/no5bl4kzr3dmfui0yiex.png)


* Usando o método `defineProperty` (`Object.seal()`)

```javascript
const people = {
  person1: 'Maiqui',
  person2: "Maria", 
  person3: "Eduardo"
}

Object.seal(people)

Object.defineProperty(people, 'person4', {
  value: 'Patrick'
})

console.log(people)
```

A mensagem de erro `"Uncaught TypeError: Cannot define property student4, the object is not extendable"` é lançada quando se tenta adicionar a mesma propriedade usando o método `defineProperty`.

![Usando o método `defineProperty`](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/019th7avwuzxzncpatrc.png)

#### Como modificar uma propriedade existente usando `defineProperty` (`Object.seal()`)

```javascript
const people = {
  person1: 'Maiqui',
  person2: "Maria", 
  person3: "Eduardo"
}

Object.seal(people)

Object.defineProperty(people, 'person2', {
  value: 'Maria Clara',
})

console.log(people)
```

Agora, o `person2` foi alterado de `"Maria"` para `"Maria Clara"`:


![alterando de `"Maria"` para `"Maria Clara"`](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9tf4qmlnmpu87vqtkwwh.png)

#### Tentando remover uma propriedade existente (`Object.seal()`)

```javascript
const people = {
  person1: 'Maiqui',
  person2: "Maria", 
  person3: "Eduardo"
}

Object.seal(people)

delete people.person1

console.log(people)
```

As propriedades não podem ser removidas dos objetos selados. No console, `person1` ainda permanece:

![tentando remover propriedade](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0kp2w8bx66ju2m7ts3km.png)


### Como usar o método `Object.freeze()` <a name="como-usar-o-metodo-object-freeze">

Aqui está a sintaxe:

```javascript
Object.freeze(obj)
```

O método `Object.freeze()` congela um objeto. O uso desse método **garante alta integridade** ao assegurar que não será possível extrair, modificar propriedades existentes ou adicionar novas propriedades ao objeto.

Para verificar se um objeto está congelado, use a sintaxe abaixo:

```javascript
Object.isFrozen(obj);
```

> **ATENÇÃO** 🚨
Mesmo quando você aplica o `Object.freeze()` a um objeto, é possível adicionar uma nova propriedade, modificar uma propriedade existente ou excluir propriedades de objetos **aninhados sob ele**.

Assim como fizemos com outros métodos, vamos explorar o método `Object.freeze()` em relação à adição de novas propriedades, modificação de valores ou exclusão de propriedades de um objeto.

#### Tentando adicionar novas propriedades (`Object.freeze()`)

* Usando `dot notation`

```javascript
const sportClubInternacional = {
  player1: "Enner Valencia",
  player2: "Sergio Rochet", 
  player3: "Rafael Borré"
}

Object.freeze(sportClubInternacional)

sportClubInternacional.player4 = "Alan Patrick"

console.log(sportClubInternacional)
```

Observe que o `player4` não foi adicionado:

![sportClubInternacional.player4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wcsohttl4xvgwkju7f2b.png)

* Usando o método `defineProperty`

```javascript
const sportClubInternacional = {
  player1: "Enner Valencia",
  player2: "Sergio Rochet", 
  player3: "Rafael Borré"
}

Object.freeze(sportClubInternacional)

Object.defineProperty(sportClubInternacional, 'player4', {
  value: "Alan Patrick"
})

console.log(sportClubInternacional)
```

A notação de ponto falha silenciosamente ao tentar adicionar uma propriedade, mas `defineproperty` gera um `TypeError`:

![defineproperty gera um TypeError](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3lj6sonxpmuvzp2uh3x.png)

#### Tentando modificar propriedades (`Object.freeze()`)

```javascript
const sportClubInternacional = {
  player1: "Enner Valencia",
  player2: "Sergio Rochet", 
  player3: "Rafael Borré"
}

Object.freeze(sportClubInternacional)

sportClubInternacional.player1 = "Enner Valencia - Atacante"

console.log(sportClubInternacional)
```

![sportClubInternacional.player1 = "Enner Valencia - Atacante"](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/k4jpnx6smexy7tbcn9lk.png)

O código acima falhou silenciosamente, mas com a propriedade `defineProperty` abaixo, um `typeError` é lançado.

```javascript
const sportClubInternacional = {
  player1: "Enner Valencia",
  player2: "Sergio Rochet", 
  player3: "Rafael Borré"
}

Object.freeze(sportClubInternacional)

Object.defineProperty(sportClubInternacional, 'player1', {
  value: "Enner Valencia - Atacante"
})

console.log(sportClubInternacional)
```

![Object.defineProperty](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0mu0e8pz85orkk94xeyv.png)

#### Tentando deletar propriedades (`Object.freeze()`)

```javascript
const sportClubInternacional = {
  player1: "Enner Valencia",
  player2: "Sergio Rochet", 
  player3: "Rafael Borré"
}

Object.freeze(sportClubInternacional)

delete sportClubInternacional.player1

console.log(sportClubInternacional)
```

A tentativa de excluir uma propriedade em um objeto congelado também falha silenciosamente:

![delete sportClubInternacional.player1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d2tyypyw0i010fqtjmca.png)

--------------------------------------------------------

## Como usar Deep Freeze <a name="como-usar-deep-freeze">

```javascript
const sportClubInternacional = {
  player1: "Enner Valencia",
  player2: "Sergio Rochet", 
  player3: "Rafael Borré",
      substitutes: {
         player4: "Lucas Alario",
         player5: "Thiago Maia"
      }
}

Object.freeze(sportClubInternacional)

Object.defineProperty(sportClubInternacional.substitutes, 'player6', {
  value: "Alan Patrick"
})

console.log(sportClubInternacional)
```

O `player6` foi adicionado aos `substitutos aninhados`, embora o método `Object.freeze()` tenha sido aplicado aos jogadores da equipe principal.

![O player6 foi adicionado](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xwyqnr69b7uw0gsb7j1s.png)

#### Deletando o jogador reserva aninhado


```javascript
const sportClubInternacional = {
  player1: "Enner Valencia",
  player2: "Sergio Rochet", 
  player3: "Rafael Borré",
      substitutes: {
         player4: "Lucas Alario",
         player5: "Thiago Maia"
      }
}

Object.freeze(sportClubInternacional)

delete sportClubInternacional.substitutes.player5

console.log(sportClubInternacional)
```

O `player5` foi removido. Tudo o que o `object.freeze` impede no objeto pai pode ser feito no objeto filho que está aninhado:

![Deletando o jogador reserva aninhado player5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5vq74xw8glu964pigkwg.png)

Para evitar isso, empregamos a técnica de congelamento profundo (Deep Freeze em inglês), conforme mostrado abaixo:

#### Aplicando o Deep Freeze


```javascript
const deepVal = obj => {
   Object.keys(obj).forEach(prop => {
      if (typeof obj[prop] === 'object') deepVal(obj[prop]);
   });

   return Object.freeze(obj);
};

const sportClubInternacional = deepVal({
  player1: "Enner Valencia",
  player2: "Sergio Rochet", 
  player3: "Rafael Borré",
      substitutes: {
         player4: "Lucas Alario",
         player5: "Thiago Maia"
      }
})

Object.freeze(sportClubInternacional)

console.log(Object.isFrozen(sportClubInternacional));
```

![adicionando deepVal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zoodg48mtztngbnz5p9r.png)

#### Tentando adicionar uma nova propriedade ao objeto filho

```javascript
const deepVal = obj => {
   Object.keys(obj).forEach(prop => {
      if (typeof obj[prop] === 'object') deepVal(obj[prop]);
   });

   return Object.freeze(obj);
};

const sportClubInternacional = deepVal({
  player1: "Enner Valencia",
  player2: "Sergio Rochet", 
  player3: "Rafael Borré",
      substitutes: {
         player4: "Lucas Alario",
         player5: "Thiago Maia"
      }
})

Object.freeze(sportClubInternacional)

Object.defineProperty(sportClubInternacional.substitutes, 'player6', {
   value: "Alan Patrick"
})

console.log(sportClubInternacional);
```

Agora, quando você tentar adicionar uma propriedade, receberá este erro `Uncaught TypeError: Cannot define property player6, object is not extensible`:

![deep freeze funcionando](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jp90mwu550oysovkuoh5.png)

Além disso, o Deep Freeze também impede que você altere e exclua propriedades de um objeto.

--------------------------------------------------------

## Como evitar a mutabilidade de arrays <a name="como-evitar-a-mutabilidade-de-arrays">

A mutabilidade em arrays segue o mesmo princípio dos objetos. Vou mostrar aqui só um exemplo pois é bem parecido com os exemplos de objetos já que ambos são `tipos de dados de referência`:

![Exemplos com array](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xnefl3mm7w7kz7x5ae81.png)

--------------------------------------------------------

## Considerações finais <a name="considerações-finais">

Neste artigo você viu sobre os vários tipos de dados e se eles são imutáveis ou mutáveis por padrão.

Você viu que quando você usa `const` você deve se preocupar com os `tipos de dados de referencia` que são mutáveis.

Os objetos podem ser alterados por padrão. Mas o uso de métodos específicos, como `Object.seal`, `Object.freeze` e `preventExtensions`, pode impedir a mutabilidade.

O nível de imutabilidade fornecido por esses métodos varia, portanto, certifique-se de usar aquele que corresponde ao nível de integridade que você deseja atingir. 

Era isso... obrigado por ler e até a próxima 🙂👋

--------------------------------------------------------

Para a construção deste artigo foi utilizado os seguintes conteúdos como base: 
* [Mutability vs Immutability in JavaScript – Explained with Code Examples](https://www.freecodecamp.org/news/mutability-vs-immutability-in-javascript)
* [Immutability in JavaScript – Explained with Examples](https://www.freecodecamp.org/news/immutability-in-javascript-with-examples)
* [Defining Primitive and Non-Primitive Data Types in JavaScript](https://dev.to/thecharacterv/defining-primitive-and-non-primitive-data-types-in-javascript-40gk)
* [Primitive vs Reference Data Types in JavaScript](https://www.freecodecamp.org/news/primitive-vs-reference-data-types-in-javascript)

[![Formação TS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/isxopdurvofcx18iptvb.png)](https://go.hotmart.com/H93763859E)