Tipos Primitivos e Tipos de Referência
Published: 2021-03-29 23:03:40

Chegamos a mais um post da minha [saga de estudos](https://dev.to/inando85/bem-vindo-de-novo-javascript-1b48) em JavaScript.

No post de hoje irei falar sobre tipos primitivos e tipos de referência.

### Tipos Primitivos

O tipo primitivo, refere-se a um dado que **não** é representado por um `objeto`.

No JavaScript, existem 6 tipos de dados primitivos:
- Numbers
- Strings
- Booleans
- Null
- Undefined
- Symbol
- BigInt

Na maioria das vezes, um valor primitivo é representado diretamente no nível mais baixo da implementação da linguagem.

Todos os tipos primitivos são imutáveis, ou seja, não podem ser alterados. 

É importante não confundir um tipo primitivo em si com uma variável atribuída a um valor primitivo. A variável pode ser reatribuída a um novo valor, mas o valor existente não pode ser alterado das mesmas formas que fazemos com objetos, matrizes e funções.

### Tipos de Referência

No contexto de objetos, é uma referência de objeto. 

No JavaScript, os tipos de referência são:

- Todos os tipos de objetos:
 - Objetos literais
 - Arrays
 - Funções
 - Datas
 - Todos os outros objetos

### Diferença entre Tipos Primitivos e Tipos por Referência

A diferença entre eles está relacionada na forma como são armazenados na memória.

Quando criamos algum tipo primitivo, a gente atribui uma variável, esse valor é armazenado na `stack` que na tradução significa pilha.

A `stack` é uma pilha de diferentes valores na memória que podem ser acessados rapidamente quando precisamos utiliza-los, porém, o espaço dentro dela é limitado.

Já quando criamos um tipo de referência (objetos), esse valor ficar armazenado no `heap` que na tradução significa amontoado.

O `heap` tem mais espaço disponível, permitindo armazenar objetos maiores e mais complexos, porém, ele é um pouquinho mais lento que a `stack`.

Exemplo de como funciona o tipo primitivo na `stack`:

```js
let scoreOne = 50
let scoreTwo = scoreOne

console.log(`ScoreOne: ${scoreOne} | ScoreTwo: ${scoreTwo}`) // scoreOne: 50 | scoreTwo: 50

scoreOne = 100

console.log(`ScoreOne: ${scoreOne} | ScoreTwo: ${scoreTwo}`) // scoreOne: 100 | scoreTwo: 50
```

Perceba que mesmo atribuindo novo valor a variável `scoreOne`, o valor atribuído a variável `scoreTwo` não foi alterado, mesmo que o seu valor na criação tenha sido referente a `scoreOne`. 

Exemplo de como funciona o tipo por referência:

```js
let userOne = {
  name: 'Roger',
  age: 31
}

let userTwo = userOne

console.log(userOne, userTwo) // Object { name: "Roger", age: 31 } Object { name: "Roger", age: 31 }

userOne.age = 35

console.log(userOne, userTwo) // Object { name: "Roger", age: 35 } Object { name: "Roger", age: 35 }
```

Já nos tipos por referência isso não ocorre, pois o JavaScript, utiliza um ponteiro na atribuição, que faz com que esse ponteiro sempre aponte pro objeto original no `heap`.

Por isso quando alterei a idade do `userOne`, o reflexo foi percebido no `userTwo`, pois por baixo dos panos, o ponteiro está somente apontando para o mesmo objeto.

E chegamos ao fim de mais um post da minha saga de estudos em JavaScript.

________________________________________________________________

Esse foi mais um post da minha saga de estudos em JavaScript Vanilla. Espero que estejam gostando!

Qualquer dúvida ou sugestão, vocês me encontram nas minhas redes sociais:

[LinkedIn](https://linkedin.com/in/inando85)
[GIthub](https://github.com/inando85)
[Twitter](https://twitter.com/inando85)