Skip to content

Latest commit

 

History

History
407 lines (283 loc) · 11.2 KB

02-pt.md

File metadata and controls

407 lines (283 loc) · 11.2 KB

Tipos de dados

No JavaScript se utilizam 8 tipos de dados

Number (números inteiros e decimais)

String (cadeias de caracteres, ou seja, textos)

Boolean (indicativo de verdadeiro ou falso)

Null (valor não-setado pelo usuário)

Undefined (valor não-setado pelo JS)

Object (estruturas de dados complexas - arrays, datas, literais, etc)

Symbol (utilizado com objetos)

BigInt (utilizado para manipular números muito grandes)

1) Strings

Strings são armazenadas entre aspas simples ou aspas duplas

'hello, world'
"hello, world"

Strings podem ser "juntadas" (concatenadas) por meio do +

let hello = "hello"
let world = "world"

let greeting = hello + ' ' + world

Para acessar determinados caracteres podemos abrir e fechar [ ] para sinalizar a localização que queremos. JS é uma linguagem 'zero based', ou seja, a contagem começa de 0.

Se quisermos acessar a posição do o em hello:

greeting[4]

Strings possuem métodos e propriedades:

Para especificar uma propriedade, utilizamos . seguido da propriedade.

.length é uma propriedade que realiza a contagem dos caracteres e retorna o número de caracteres de uma string.

let name = 'Ana'
name.length // 3

As funções que estão restritas ao escopo de um objeto são chamadas de métodos - da mesma forma que funções, são blocos de código que realizam uma ação específica.

.toUpperCase() torna todos os caracteres maiúsculos, mas sem alterar a string original.

name.toUpperCase() // ANA

.toLowerCase() torna todos os caracteres minúsculos, mas sem alterar a string original.

name.toLowerCase() // ana

.indexOf('argument') busca a posição do argumento passado como parâmetro na função, mas sem alterar a string original.

name.indexOf('n') // 1

.lastIndexOf('argument') busca a última ocorrência da string passada no argumento.

name.lastIndexOf('a') // 2

.slice( index1, index2 ) retorna um recorte que inicia no primeiro argumento (é passado o número do index) e vai até um index anterior ao segundo argumento (também um número). O slice não altera a string original.

name.slice(0, 2) // An

.replace( index1, index2 ) subtitui um caracter da string por outro. No primeiro argumento é passada a string que se quer substituir, no segundo argumento se passa a string substituta. O replace não altera a string original. Repare que o replace altear somente a primeira ocorrência (para alterar todas é preciso utilizar Regex).

name.replace('n', 'd') // Ada

2) Números

Números podem ser armazenados em variáveis, sendo que decimais devem levar . ao invés de ,

const radius = 10
const pi = 3.14

Operadores aritméticos

* multiplicador

+ adição

- subtração

/ divisão

** expoente

Ordem de operação: obedece a mesma lei da matemática (1o parênteses, 2o expoentes ou raízes, 3o multiplicação ou divisão, 4o adição e subtração)

Operadores de incremento

let postLikes = 10
postLikes++ 
// postLikes = postLikes + 1 
// 11

postLikes--
// postLikes = postLikes - 1 
// 9

postLikes += 10
// postLikes = postLikes + 10 
// 20

Operações que não resultam em um número: NaN

(7 / 'hi') // NaN

Concatenação de string com número: JS converte o número em string, então o resultado de uma concatenação entre string e número sempre será uma string.

const likesMessage = 'The post has' + postLikes + 'likes.' // 'The post has 10 likes.'

3) Objetos

Arrays são utilizados para armazenar uma lista de valores que estão relacionados entre si

let heroes = ['Batman', 'Catwoman', 'Iron Man']

Para atribuir valores sobrescrevendo posições dos arrays:

heroes[2] = 'SpiderMan'

É possível armazenar vários tipos de dados em um array:

const randomArray = ['Parker', 'Diana', 19, 18]

Propriedades e métodos de arrays

.length retorna a quantidade de itens dos arrays

let heroes = ['Batman, 'Catwoman', 'Iron Man']
heroes.length // 3

.join() retorna uma nova string com todos os items do array concatenados e separados por vírgulas. Pode receber argumento opcional que atua como separador ao invés da vírgula.

heroes.join() // Batman,Catwoman,Iron Man

heroes.join('|') // Batman|Catwoman|Iron Man

.indexOf() retorna o index do argumento passado. Se o argumento não existir, ele retorna -1

heroes.indexOf('Batman') // 0

heroes.indexOf('Hulk') // -1

.concat() junta o array onde o método foi invocado mais o que for passado como argumento. Não altera o array original.

heroes.concat(['SpiderMan', 'Wolverine']) // ['Batman, 'Catwoman', 'Iron Man', 'SpiderMan', 'Wolverine']

.push() inclui os itens passados como argumento no array original. Retorna o novo número de itens que o array tem depois da soma (mutação de valores).

heroes.push('Cyclops', 'Superman') // ['Batman, 'Catwoman', 'Iron Man', 'Cyclops', 'Superman']

.pop() remove o último item do array e retorna esse item. Também modifica o array original.

heroes.pop() // 'Superman'

4 & 5) Null e Undefined

Estes dois tipos são similares e ambos representam a falta de um valor. A diferença é que o null diferente do undefined, precisa ser intencionalmente atribuído.

Todas as vezes que declaramos uma variável sem atribuir valor, o JavaScript atribui undefined

let emptiness 
console.log(emptiness)  // undefined

Se tentarmos utilizar undefined em uma expressão numerica, obtemos NaN

emptiness + 3 // NaN

Para indicar propositalmente que não existe valor em uma variável utiliza-se o null

let emptiness = null
console.log(emptiness)  // null

Quando executamos alguma operação matemática com null ele é interpretado como zero.


emptiness + 3 // 3

6) Booleans

true e false são palavras reservadas, e tipos de dados que são utilizados para verificar condições - se um trecho de código é verdadeiro ou falso.

const email = '[email protected]'
const includes = email.includes('@')

console.log(includes)  // true

Operadores de Comparação

São utilizados para comparar um valor com o outro, e a comparação retorna um boolean.

const age = 31

console.log(age == 31)  // true

Lembrando: = significa atribuição e == significa comparação.

Para negar a igual usa-se !=

console.log(age != 31)  // false

Outros comparativos de números:

console.log(age > 10)  // true
console.log(age < 10)  // false
console.log(age <= 31>)  // true
console.log(age >= 31>)  // true

Comparações com strings:

const name = 'ana'

console.log(name == 'ana')  // true
console.log(name == 'Ana')  // false
console.log(name > 'bel' )  // false ('a' vem antes do 'b')
console.log(name > 'Ana' )  // true (letra minúscula vem antes da letra maiúscula)

Comparações estritas

Quando utilizamos == corremos o risco de ter uma igualdade numa expressão que envolve tipos diferentes.

// 'Igual a' e 'diferente de'
console.log( 31 == 31 ) // true
console.log( 31 == '31' ) // true
console.log( 31 != 31 ) // false
console.log( 31 != '31' ) // false

Para evitar isso, utilizamos === para comparação estrita.

// 'Igual a, e do mesmo tipo' e 'diferente de, e do mesmo tipo'
console.log( 31 === 31 ) // true
console.log( 31 === '31' ) // false - pois estamos verificando o valor e o tipo

console.log( 31 !== 31 ) // false
console.log( 31 !== '31' ) // true

É portanto mais seguro utilizar comparação estrita.

Conversão de tipos

Significa que é possivel transformar um tipo de dado em outro. Em alguns momentos isso é importante para conseguir resultados específicos.

let score = '100'

console.log(score + 1) // 1001 concatenação entre string e número, resultando em outra string.

É possível converter a string em um número, e depois realizar a operação.

score = Number(score)  // referenciar score, reatribuir o valor transformando a string em número invocando uma função construtura.

Passando uma string como argumento dessa função construtora, o tipo é modificado.

console.log(score) // 101
console.log(typeof score) // number

Convertendo vários tipos de dados

const crazyConversion = Number('Apple') // NaN (operação matemática que não faz sentido)

const convertedNumber = String(97) // '97' (string)

const booleanConversion == Boolean(10) // true (valor truthy)

Valores Truthy e Falsy

JavaScript atribuiu valores true e false para determinados valores/tipos.

Valores Falsy

false 0 "" ou '' null undefined NaN

Qualquer outro valor retorna true

Tipos Primitivos vs Tipos de Referência

São tipos primitivos:

Numbers Strings Booleans Null Undefined Symbol BigInt

São tipos de referência:

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

A diferença entre eles está na forma como são armazenados na memória. Quando criamos um tipo primitivo e atribuímos a uma variável, ele fica salvo na stack ("pilha" de diferentes valores na memória). Esse valores podem ser acessados rapidamente, mas o espaço na stack é limitado.

Quando criamos um tipo de referência ele é armazenado no heap ("amontoado"). O heap tem mais espaço disponível para armazenar objetos maiores e mais complexos (como objetos literais e arrays), só que é um pouco mais lento.

São duas partes da memória para duas coisas diferentes.

Ao armazenar um valor primitivo numa variável ele fica na stack e é acessado através do nome da variável. Mas ao armazenar um tipo de referência em uma variável, como um objeto, ele fica armazenado no heap e um ponteiro fica na stack apontando para o objeto no heap.

Isso tem implicações em como escrevemos nosso código. Veja o que acontece quando copiamos tipos primitivos:

let scoreOne = 50  // tipo primitivo, com variável (identificador) que nos permite acessar o valor.

let scoreTwo = scoreOne // uma cópia do valor primitivo é criado na stack em posições diferentes na memória com identificadores diferentes.

console.log(scoreOne)
console.log(scoreTwo)

// 50
// 50

scoreOne = 100  // quando alteramos o valor da primeira variável nada é afetado na variável scoreTwo

console.log(scoreOne)
console.log(scoreTwo)

// 100
// 50

Porém quando criamos cópias de tipos de referências, o comportamento é diferente:

let userOne = {name: 'ana', score: 100} 
\\ é um tipo de referência e portanto armazenado no `heap`. Na `stack` temos um ponteiro armazenado na variável userOne que aponta para o objeto criado na `heap`.

let userTwo = userOne 
\\ não foi criado um novo objeto no `heap`. A nova variável armazena um novo ponteiro que aponta para o mesmo objeto no heap.

userOne.score = 50  

console.log(userOne.score)
console.log(userTwo.score)

\\ 50
\\ 50

Quando criamos uma cópia de valores primitivos, armazenamos em espaços diferentes da memória na stack. Mas ao criar cópias de valores de referência, estamos copiando apenas o ponteiro, que aponta para o mesmo objeto na heap. Isso faz com que quando modificamos o objeto, a alteração se reflita também na cópia, pois o ponteiro está indicando o mesmo objeto.