Introdução à programação em JS - elementos básicos parte 1
Tags: javascript, beginners, programming
Published: 2021-10-08 16:17:57

Programação, para muitos que não estudaram o tópico, pode parecer extremamente complexo. Entretanto, todo programa é construído a partir de conceitos muito simples. A combinação desses elementos gera os mais diversos resultados e, assim, conseguimos criar os diferentes programas que conhecemos.

Assim, quero dar uma pequena introdução sobre programação utilizando a linguagem JavaScript, que é uma das linguagens de programação mais utilizadas hoje em dia.

---

Neste texto, vou falar sobre os tipos de dados básicos que existem em JavaScript e como utilizar variáveis. Caso não tenha entendido algum dos termos que utilizei, siga lendo, pois tentarei aprofundar todos eles ao longo do texto.

## Índice da série:

Introdução à programação em JS - elementos básicos parte 1 (você está aqui)
[Introdução à programação em JS - elementos básicos parte 2](https://dev.to/brunomoutinho/introducao-a-programacao-em-js-elementos-basicos-parte-2-530o)

## Tipos de dados

Dados são quaisquer informações. Tipos de dados são grupos de dados que compartilham características em comum. Cada tipo de dados representa algum conceito abstrato.

Em JavaScript, temos os tipos de dados primitivos e os tipos de dados estruturais.

Os tipos de dados primitivos são tipos que não podem ser modificados, enquanto os tipos estruturais podem. Uma explicação mais clara sobre esse conceito será discutida nos exemplos.

Os tipos de dados *primitivos* são:

- `undefined` - tradução: indefinido. Esse tipo de dados indica que algum valor não foi definido em algum momento. Por convenção, esse valor acontece quando, não intencionalmente, um valor não foi inicializado;
- `null` - tradução: nulo. Esse tipo de dados indica que algum valor foi inicializado com um valor inexistente. Assim como indefinido, indica que não existe um valor naquele espaço, mas, ao contrário de indefinido, isso é intencional.
- `Boolean` - tradução: booleano. Esses são valores lógicos de verdadeiro (`true`) ou falso (`false`). O nome deriva de Boole (sobrenome do matemático George Boole) que criou um sistema baseado nesses dois valores lógicos e conectores lógicos (como "e", "ou", "não"). Não entraremos a fundo nesse tópico no momento. Por ora, memorize os valores possíveis: `true` (verdadeiro) e `false` (falso).
- `Number` - tradução: número. Números são quaisquer números reais. Valores como `0`, `0,5`, `3,14`, `42`, ficam nessa categoria.
- `BigInt` - contração de Big Integer; tradução - inteiro grande. Eventualmente, nossa aplicação pode precisar lidar com valores matemáticos muito grandes. Para indicar para o computador que precisamos de mais espaço de memória para usar esses valores, podemos utilizar esse tipo de dados.
- `String` - tradução: texto. Apesar de "texto" não ser a tradução literal da palavra *string*, é a tradução que faz sentido. A tradução literal de *string* seria "fio" ou "corda". Esse nome existe por que a representação em memória do computador de um texto é de um "fio" ou "corda" de caracteres. Um caractere, em várias linguagens de programação, é um tipo de dados básico, enquanto o texto deriva desse tipo de dados. Quando se junta vários caracteres, se tem um fio de caracteres, ou *string*. Ainda assim, é possível ter uma *string* vazia (`""`) ou uma *string* de um só caractere (`"a"`),
- `Symbol` - tradução: símbolo. Símbolos são valores únicos e randômicos. Toda vez que um símbolo é criado, ele será diferente de outros símbolos já criados. Seus usos comuns serão discutidos em um post futuro.

Os tipos *estruturais* são:

- `Object` - tradução: objeto. Objetos são como objetos do mundo real. Se pensamos em uma bola, ela vai ter propriedades, como diâmetro, material, cor, peso... Objetos podem ter essas propriedades e podemos dar um valor para cada uma delas.
- `Function` - tradução: função. São procedimentos ou métodos que guardam uma série de passos para que sejam executados quando for conveniente. Ainda não vou aprofundar este tema.

A grande diferença entre tipos primitivos e tipos estruturais é que os tipos primitivos são *imutáveis*, enquanto os tipos estruturais apenas têm uma referência imutável. Isso significa que não podemos mudar o valor do número `1`, por exemplo, ou da letra `A`. Tipos estruturais, entretanto, podem ter seu valor modificado, mas continuarão sendo referenciados pelo mesmo endereço de memória. É como se eu fizesse uma reforma na minha casa: alguma coisa mudou na casa, mas ela ainda fica na mesma rua e número.

## Variáveis

Variáveis são como caixas. Em JavaScript elas podem "guardar" quaisquer valores - um de cada vez, não interessando o tipo que está sendo guardado. Assim, o valor pode ser utilizado em diferentes partes do programa.

Quando guardamos um valor em uma variável, dizemos que a variável foi *inicializada* com o valor escolhido. Assim, toda vez que fizermos referência a essa variável, receberemos o valor que atribuímos a ela.

Como o nome sugere, o valor de uma variável pode mudar durante a execução do programa. Não devemos confundir essa mudança de valor com uma alteração do valor dos tipos primitivos, que, como definimos anteriormente, não podem ser alterados.

Na prática, todo valor de um tipo primitivo que for usado no programa é guardado em uma posição de memória. Se eu inicializo uma variável com um valor primitivo, eu vou alocar um espaço da memória do computador para esse valor e a variável receberá esse endereço - dizemos que a variável *aponta* para esse endereço ou valor.

Se duas variáveis são inicializadas com o valor `0`, por exemplo, as duas apontarão para o mesmo endereço de memória, que guarda o valor primitivo `0`.

Se uma dessas variáveis posteriormente *recebe* o valor `1` (aqui, *recebe* indica que estamos atribuindo à variável um valor diferente), ela deixa de apontar para o endereço de memória que guarda o valor `0`, e passa a apontar para o endereço de memória que guarda o valor `1`. A outra variável segue apontando para o mesmo endereço onde o valor `0` se encontra.

Quando uma variável é inicializada com um tipo estrutural (objeto ou função), mesmo que os valores mudem, ela ainda apontará para o mesmo endereço de memória.

Citei anteriormente o exemplo de uma casa em um endereço. Digamos que a casa tenha as propriedades `material` , com o valor `tijolo`, `andares`, com o valor `1`, e `cor` com o valor `amarela`. No caso da reforma feita, se eu pintasse as paredes externas de azul, poderia expressar isso modificando o valor da propriedade `cor` para `azul`. A variável que guarda esse objeto vai continuar apontando para o mesmo endereço de memória, mas o conteúdo daquele espaço vai ser diferente.

## Exemplos

Bom, até o momento procurei passar bastante da teoria de como tipos (primitivos e estruturais) e variáveis funcionam, mas pode ser muito complicado entender todos esses conceitos sem exemplos. Aqui vou dar exemplos e você pode reproduzir cada um deles no seu computador. Para que seja possível executar o código, você deve abrir as ferramentas de desenvolvedor no seu navegador apertando a tecla `f12` do seu teclado. Então, procure pela aba `Console`. Caso tudo carregar da forma correta, ela se parecerá com isso:

![https://s3-us-west-2.amazonaws.com/secure.notion-static.com/451f7319-2d48-4b45-a5b0-fffd3f87ae1c/Untitled.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/451f7319-2d48-4b45-a5b0-fffd3f87ae1c/Untitled.png)

É possível que existam mensagens na área inferior, mas não se preocupe. Ao lado da seta (`>`), você pode clicar e começar a digitar (ou colar) comandos em JavaScript que serão executados.

Ainda antes de começarmos, sempre que vocês virem os símbolos `//` no código, isso indica que tudo o que está à direita deles, é um comentário e será ignorado. Eu utilizarei isso para ajudar na compreensão de tudo que estamos fazendo.  Após cada linha que não estiver comentada, a primeira linha comentada será o retorno que o interpretador de JavaScript irá retornar. 

Em primeiro lugar, vamos testar usar valores de tipos primitivos:

```jsx
// Vamos começar utilizando Números! Escolha um
// número e o digite ao lado do símbolo > no console:
42
// 42
// Você verá que o console imprimirá uma nova linha
// na sequência com o mesmo valor que foi colocado
// como um comentário acima.
```

Toda vez que escrevemos algo no console, o interpretador do JavaScript tentará avaliar o que foi digitado. Esses comandos são chamados de *expressões*. Uma expressão, em JavaScript, pode ser um valor de um tipo primitivo, um valor de um tipo estrutural, uma variável, ou uma combinação entre eles (lembrando que funções também são um tipo estrutural que não discutimos ainda). Quando a expressão é interpretada, ela retornará um resultado, que, no caso de colocarmos um valor primitivo, será o próprio valor primitivo.

```jsx
// Vamos testar colocar outros valores primitivos que
// aprendemos e ver o resultado:
// Textos, em JavaScript, podem ser declarados de
// duas formas:
// Usando aspas simples:
'JavaScript'
// "Javascript"
// Usando aspas duplas:
"JavaScript"
// "Javascript"

// Booleanos:
true
// true
false
// false

// Nulo:
null
// null

// Indefinido:
undefined
// undefined

// Inteiros grandes também podem ser declarados de
// duas formas:
123456789n
// 123456789n
BigInt(123456789)
// 123456789n

// Símbolo:
Symbol()
// Symbol()
```

Também podemos ter expressões com tipos estruturais, conforme falamos antes. Vamos testar com objetos:

```jsx
// Assim como textos são identificados com aspas simples
// ou duplas e inteiros grandes podem ser identificados
// pelo n no final ou com a função BigInt(), objetos são
// declarados de uma forma específica:
{}
// > {}
// Você verá que o retorno dessa expressão será diferente
// de outros retornos. A grande diferença aqui é a seta
// que tem antes do retorno {}. Essa seta indica que você
// pode clicar ali e ver alguma nova informação. No caso 
// de objetos, você poderá ver propriedades e, nesse caso 
// em particular, a única propriedade disponível é a
// propriedade __proto__: Object. A propriedade __proto__
// identifica o *protótipo* do objeto. Trataremos disso
// mais pra frente.
{ material: 'tijolo', andares: 1, cor: 'amarela' }
// > { material: 'tijolo', andares: 1, cor: 'amarela' }
// Clicando na seta nesse exemplo, veremos cada uma das
// propriedades que listamos assim como a propriedade
// __proto__.
```

Quando queremos usar um mesmo valor várias vezes em nosso programa, é interessante utilizarmos as variáveis. Em JavaScript, temos 3 formas de criar (ou declarar) uma variável.

```jsx
// Ao executar cada uma dessas linhas, o retorno será o
// valor undefined. Sempre que uma variável é declarada,
// a expressão resolve para o valor indefinido (undefined).
var minhaVariavel
// undefined
let outraVariavel
// undefined
// Uma variável declarada com a palavra const não pode
// ser declarada sem um valor explícito, então
// inicializaremos a variável abaixo com o valor
// null
const maisUmaVariavel = null
// undefined
```

A palavra `var` é uma contração da palavra `variable`, cuja tradução é "variável". Até o ano de 2015, essa era a única forma de se declarar uma variável em JavaScript. Em 2015, foram introduzidas as palavras `let`, que pode ser traduzida como "dado", do verbo "dar", e `const`, que é uma contração de `constant`, cuja tradução é "constante". A `const` é chamada assim pois é a única cujo endereço apontado não pode ser alterado, ou seja, se a variável aponta para um valor primitivo, ela não pode ser alterada. Caso a variável aponte para um valor estrutural, o conteúdo do objeto ou da função pode ser alterado, mas não podemos ter uma nova atribuição de valor à variável.

Como mostramos antes, quando uma variável tem um valor primitivo e nós atribuímos outro valor para ela, o endereço para o qual a variável aponta, muda. Vamos ver o que isso significa na prática:

```jsx
// No exemplo acima, criamos as variáveis:
// * minhaVariavel, utilizando a palavra "var"
//   (que é uma contração de "variable", cuja
//   tradução é "variável";
// * outraVariavel, utilizando a palavra "let"
//  (cuja tradução mais próxima, acredito,
//   seja "dado", do verbo "dar"); e
// * maisUmaVariavel, utilizando a palavra "const"
//   (que é uma contração de "constant",
//   cuja tradução é "constante").
// Agora, iremos tentar modificar o valor de cada
// uma delas:
minhaVariavel = 1;
// 1
// Perceba que, quando a variável recebe um novo
// valor, o resultado da expressão é o valor que
// foi atribuído à variável, e não mais indefinido.

outraVariavel = 'JavaScript';
// "JavaScript"

// Não se assuste! A expressão abaixo irá disparar
// um erro. Isso acontece por que não é permitido
// alterar o endereço para o qual uma variável
// inicializada com const aponta.
maisUmaVariavel = true;
// > Uncaught TypeError: Assignment to constant variable.
// A tradução do erro acima é:
// > Erro de tipo não capturado: Atribuição a variável
// constante.

// Agora veja a diferença se criarmos uma variável
// com o exemplo da casa que citamos:
const casa = {
  material: 'tijolo',
  andares: 1,
  cor: 'amarela',
};
// undefined

// Quando queremos ver o valor de uma propriedade
// de um objeto, podemos escrever isso de duas
// maneiras:
casa.cor;
// "amarela"
casa['cor'];
// "amarela"

// Na segunda forma, utilizamos um texto (ou string)
// para acessar a propriedade do objeto.
// O resultado das duas formas de acessar propriedades
// de um objeto é exatamente o mesmo.
// O caso onde usamos um texto pode ser usado quando
// o nome da propriedade contém caracteres que podem
// ser confundidos pelo interpretador de código (como
// um ponto, um hífen) ou ainda quando, no momento que
// estamos escrevendo o código, não sabemos qual o nome
// do campo que queremos acessar.
// No caso de não sabermos o valor previamente, ao
// invés de colocar o valor do texto diretamente,
// utilizamos uma variável, por exemplo:
let propriedade = 'cor';
// undefined
casa[propriedade];
// "amarela"

// A expressão acima é equivalente às duas formas de
// acesso que citamos antes, mas, se mudamos o valor
// da variável propriedade, podemos acessar uma
// propriedade diferente:
propriedade = 'material';
// "material"
casa[propriedade];
// "tijolo"

// Vamos tentar, então, modificar a propriedade "cor":
casa.cor = 'azul';
// "azul"

// Perceba que, dessa vez, não aconteceu erro nenhum!
// Poderíamos, sem problema algum, utilizar as outras
// formas de acesso da propriedade:
casa['cor'] = 'verde';
// "verde"
propriedade = 'cor';
// "cor"
casa[propriedade] = 'rosa';
// "rosa"

// Como discutimos antes, os tipos estruturais podem
// ser alterados, mas seu endereço continua o mesmo.
// Por isso é possível alterar propriedades de objetos
// que foram declarados com a palavra const.
```

Não fizemos nenhum teste apenas com as funções até o momento. Vamos falar sobre funções em mais detalhes em um próximo texto, mas podemos mostrar qual o modo padrão de se definir uma função:

```jsx
// A expressão abaixo irá criar uma função com o nome
// minhaFuncao, que pode ser executada sempre que
// quisermos.
function minhaFuncao() {}
// undefined

// Temos aqui 4 partes na declaração:
// A palavra function, que indica que vamos declarar uma
//   função;
// O nome da função, que é opcional (podemos criar uma
//   função sem nome);
// Os parênteses indicam o espaço para parâmetros; e
// As chaves delimitam o corpo da função, ou a sequência
//   de expressões que serão executadas.
// Esse caso em especial não executa expressões.
// Podemos executar a expressão assim:
minhaFuncao();
// undefined

// Nesse caso, o retorno da expressão será indefinido
// (undefined), já que não declaramos explicitamente o
// retorno da função.
```

## Conclusão

Parabéns! Você acabou de dar o primeiro passo para aprender a programar!

Nesse texto, aprendemos que existem tipos de dados que podem ser representados em JavaScript. Esses tipos estão divididos em 2 grupos: *primitivos* e *estruturais*.

Os tipos primitivos são:

- `undefined` - para indicar a ausência não intencional de valor;
- `null` - para indicar a ausência intencional de valor;
- `Boolean` - valor lógico, podendo ser verdadeiro (`true`) ou falso (`false`);
- `Number` - um número real;
- `BigInt` - um número inteiro muito grande;
- `String` - um texto; e
- `Symbol` - um valor único;

Os tipos estruturais são:

- `Object` - estrutura que guarda mais de um valor, cada um em uma propriedade; e
- `Function` - bloco de código que pode ser executado quando conveniente.

Aprendemos também que podemos usar variáveis para guardar quaisquer valores que possam ser representados pelos tipos citados. Essas variáveis podem ser criadas usando uma de 3 palavras:

- `var` - declara uma variável que pode ter o endereço a que ela se refere alterado;
- `let` - declara uma variável que pode ter o endereço a que ela se refere alterado; e
- `const` - declara uma variável cujo endereço não pode ser alterado.

Nós vimos, também, que determinadas expressões podem gerar erros de execução, como quando tentamos atribuir um valor diferente a uma variável declarada com a palavra `const`.

É muita coisa!

Todos os conceitos que tratamos nesse texto são conceitos fundamentais e entender eles plenamente vai ajudar você conforme nós avançarmos em tópicos mais avançados. Reler o texto pode ajudar a desenvolver essa compreensão e a criar a relação entre os termos em português e inglês. Caso o texto não tenha sido claro em algum ponto, envie uma mensagem por alguma das formas de contato na página Contato no menu.

Nos próximos textos iremos explorar mais as expressões do JavaScript assim como criar funções simples!