Galera abaixo está algumas notas de JavaScript que fiz mediante ao aprendizado com o passar do tempo. Espero que gostem, e o repo está publico, então se quiser contribuir com alguma nota fique avontade! É tudo nosso! 🚀📚
- Notas delicinhas de Js :3
- Tópicos
- Console log
- Comentários
- Variáveis
- Tipos de dados primitivos
- Operadores aritimeticos
- Conversão de tipo de dados
- Alert
- String
- Expressões regulares
- Numbers
- Math
- Arrays
- Obter valores do array
- Mudando os valores do array
- Passando valores entre arrays
- Comprimento do array - length
- Inserir valores no array - push/unshift
- Romover valores do array - pop/shift/delete
- Fatiar um array - slice
- Checkar instancia de array
- Retirar valores de um determinado range - Splice
- Concatenar array
- Filtrar o array
- Mapear o array
- Reduce
- Foreach
- Funções
- Objetos
- Criar objeto
- Acessar valores do objeto
- Atribuição via desestruturação (Objetos)
- Fabrica de objetos
- Factory Functions
- Contructor functions
- Congelar objeto - freeze
- Métodos do objeto
- Propriedades do objeto
- Propiedades do objeto com getters e setters
- Metodos uteis para objetos
- Prototypes
- Herança
- Polimorfismo
- Factory Functions + Prototype
- Composing / Mixing
- Object map
- Class
- Valores primitivos e por referencia
- JavaScript Lógica de programação
- Estruturas condicionais
- Objeto date
- Switchs
- Estrutura de repetição
- DOM - Document object model
- Try Catch finally
- Errors
- Interval e Time outs
- JSON
- LocalStorage
- Promise
- Requisições
- Import & Export
- Compiladores e transpiladores
- WebPack
console.log('Vamos printar algo');
console.log("print 'com aspas simples'");
console.log('print "com aspas duplas"');
console.log(1234, 56.789, 'Números');
console.log(` 'tudo isso' "é um print" ${123}`);
console.log(` 'tudo isso' "é um print" ${variable}`);
// Comentário na linha
/*
Comentário
Longo
*/
Em váriaveis geralmente se utiliza camelCase, por exemplo: nomeVariavel
- Podem ser iniciliadas vazias
- Seus valores podem ser alterados no decorrer do código
- Só existe dentro do escopo em que foi criada
let nome;
nome = 'Albert';
let sobreNome = 'Einstein';
- Não pode ser inicializada vazia
- Seu valor não pode ser diretamente alterado (Seu endereço de memória não pode ser alterado)
- Só existe dentro do escopo informado
const nome = 'Einstein';
const dez = 10;
- Não utilize var
- Utilize let ou const :)
- Var é global, oque pode trazer problemas para sua aplicação
var teste = 'teste'
const nome = 'Einstein' // string
const numero = 10 // number
const numero = 2.5 // number
let teste // undefined
const nulo = null // null
const aprovado = true // boolean
//symbol
const nome = 'Einstein'
typeof nome // string
const numero = 10
typeof numero // number
typeof nome, numer // string number
Aqui os valores trabalham como ponteiros, onde uma variavel aponta para o mesmo endereço de memória que a outra. Dessa forma quando uma variavel que faz referencia a outra for alterada, tanto a variavél ponteiro quanto a varaivel referenciada será alterada.
Confuso? Dale exemplo abaixo :)
const a = [1,2,3]
const b = a
console.log(a,b) // [1,2,3] [1,2,3]
b.push(4)
console.log(a,b) // [1,2,3,4] [1,2,3,4]
// tando 'a' como 'b' apontam para os mesmos valores
- ( ) - Primeiro - Resolve oque está no parênteses
- / * % - Segundo - Resolve oque aparecer primeiro desses
- - Terceiro
- + Quarto
console.log('Albert' + ' ' + 'Einstein') // 'Albert Einstein'
console.log('Albert ' + 1) // 'Albert 1'
console.log(10 + 10) //20
console.log('10' + 10) // 20 Ele faz algumas conversões sozinho
console.log(20 - 10) // 10
console.log('10' - 10) // 0 Conversão novamente
console.log(2**2) // 4
console.log(10 % 3) // 1
let num = 10
num++ // 11
num-- // 9
++num // 11
--num // 9
num = num + 10 // 20
num += 10 // 20
num = num - 10 // 0
num -= 10 // 0
num *= 10 // 100
num **= 2 // 10000
NaN = not a number
parseInt('5') //number - 5
parseInt('5.2') //number - 5 - Remove a casa decimal
parseFloat('5.2') //number - 5.2
// Melhor maneira
Number('5') //number - 5
Number('5.2') //number - 5.2
String(50) //string - '50'
É utilizado para trazer mensagens para o usuário na tela. Porém existem jeitos mais elegantes para se fazer isso :3
Ele habita dentro do objeto window, assim como o método console.log.
- retorna undefined
window.alert('alerta')
alert('alerta')
alert(123)
É bem parecido com o Alert, porém neste existe botões para aceitar, então você pode aceitar ou não oque a caixa flutuante de texto diz.
- retorna um boolean
window.confirm('mensagem')
confirm('mensagem')
Igualmente parecido com os outros dois citados anteriormente (Alert, Confirm). Aqui é possível inserir valores na caixa de texto flutuante
- retorna uma string, então se você inserir um Number, terá que converter
window.prompt('mensagem')
confirm('mensagem')
É um tipo de dado que representa um texto.
typeof 'Isso é um texto' // string
typeof "Isso também é um texto" // string
typeof `Isso é um texto com números ${123}` // string
typeof 'Isso também é um texto com números ' + {123} // string
Beleza, as vezes queremos printar esse caracter '', e se você fizer isso dará problema, pois esse caracter representa outra coisa dentro de uma string, então para isso você utiliza ele da forma abaixo:
'Barra invertida \\' // Barra invertida \
'Posso pegar a aspa \' assim' // Posso pegar a aspa ' assim
Uma string tem um tamanho e cada caracter tem um posição.
Uma Srting sempre começa no index 0
012345678
'Meu texto'
Então para obter o valor de uma determinada posição podemos fazer da seguinte forma
const meuTexto = 'Meu texto'
meuTexto[0] // M
meuTexto[1] // e
meuTexto[2] // u
meuTexto[3] //
meuTexto[4] // t
meuTexto[5] // e
meuTexto[6] // x
meuTexto[7] // t
meuTexto[8] // o
Usado para buscar a posição de um valor informado na String
Ele retornará a primeira posição que achar com o valor que for informado
const texto = 'teste'
texto.indexOf('e') //1
texto.indexOf('w') //-1 - Retorna -1 quando valor não é encontrado
Faz a mesma coisa que o indexOf, porém ele começa a percorrer as posições de trás para frente
const valor = 'teste'
valor.lastIndexOf('e') // 1
valor.lastIndexOf('s') // 2
Usado para juntar as coisas - Concatenar
'string' + 'string' // Primeira forma
`${umaString} mais outra string` // Forma mais utilizada
umaString.concat('outraString') // Terceira forma
Para checar se a string acaba com o valor que você informar
Retorna um boolean
'string'.endsWith('a') // false
Usado para trocar valores
'teste'.replace('s', 'x') // texte
Pegar o comprimento das coisas
'teste'.length //5
Quando a string é fatiada pelo metodo slice, ela não tem o seu valor realmente modificado, slice apenas retorna os valores entre o intervalo que você informar.
'teste'.slice(2,4) // 's'
'teste'.slice(1,-1) // este
Retorna os valores dentro de um range informado
'teste'.subString(0, 2) // te
Esse cara aqui consegue fatiar sua string, você informar em qual caracter ele vai fatiar e pronto :3
Retorna um array
'isso vai cortar'.split(' ') // ['isso', 'vai', 'cortar']
Função utilizada para deixar em maiusculo
'teste'.toUpperCase() // 'TESTE'
função utilizada para deixar em minusculo
'TESTE'.toLowerCase()
Usado para encontrar uma cadeia de caracteres (Regex) em uma string.
Retorna um array
//Encontrar somente as letras minusculas
'teste'.match(/[a-z]/g) // ['t', 'e', 's', 't', 'e']
//Encontrar letras minusculas e maisculas
'Teste'.match(/[a-zA-Z]/g) //['T', 'e', 's', 't', 'e']
//Encontrar números
'tenho 1 número'.match(/[0-9]/g) // [1]
Usado para encontrar um valor, passando como parametro uma cadeia de caracteres (Regex)
Retonar o index / posição do elemento encontrado
'Teste'.search(/s/) 2
Da para utilizar as cadeias de carateres no replace também
// Trocar a primeira letra 's' para 'x'
'tesssste'.replace(/s/, 'x') // texssste
// Trocar todas as letras 's' para 'x'
'tesssste'.replace(/s/g, 'x') // texxxxte
JavaScript faz as contas com base no padrão IEEE 754-2008. Existe sempre uma pequena imprecisão na hora de calcular numéros flutuantes abaixo de 1 (Com cadas decimais).
let num1 = 10 // number
let num2 = 10.0123012 // number
let num = 10
num.toString() // '10'
let num = 10.123124324
num.toFixed(2) // 10.12
//number.toFixed(numero_casas_decimais)
let num1 = 10
Number.isInteger(num1) // true
let num2 = 10.312
Number.isInterger(num2) //false - É um Number (Casas decimais)
const ola = 'ola'
Number.isNaN(ola) //true
const num = 10
Number.isNaN(num) //false
Toma cuidado com calculos aqui, que o bixo não é tão preciso @-@
Até a nubank teve problema com isso
Tem que lascar tratativas
let num1 = 0.1
let num2 = 0.3
console.log(num1 + num2) //0.399999999999 - Aqui está a imprecisão
// Solução
console.log(parseFloat((num1 + num2).toFixed(2)) //Pouco elegante mas funciona
console.log(Number((num1 + num2).toFixed(2)) //Pouco elegante mas funciona
(num1 * 100) + (num2 * 100) / 100 // 0.4 - Muito pouco elegante, mas funciona
Math.floor(9.123) // 9
Math.ceil(9.123) // 10
- Abaixo de 50 arredonda par abaixo
- Acima de 0.49 arredonda para cima
Math.round(0.49) // 0
Math.round(0.50) // 1
let numbers = [1,2,3,4,5,6]
Math.min(numbers) //1
Math.max(numbers) // 6
Math.random() // 0.56487434
//gerar aleatório em um intervalo
Math.random() * (max - min) + min
//exemplo
const number = Math.random()* (10 - 5) + 5 // numeros entre 5 e 10
Math.pow(2,2) // 4
// Mas assim também da certo
2**2 // 4
É necessário tomar cuidado, pois o JavaScript permite a divisão por zero classificando a variavel como infinity e true
10 / 0 // Infinity - true
Maneira citada StackOverflow por Mike Samuel
function notZero(n) {
n = +n; // Coerce to number.
if (!n) { // Matches +0, -0, NaN
throw new Error('Invalid dividend ' + n);
}
return n;
}
numerator / notZero(denominator)
Deve tomar cuidado com atribuições diretas, isso ocasiona em ponteiros. Então tudo oque você fizer em uma variavel ira refletir na outra. Para isso existem maneiras corretas descritas abaixo para fazer a atribuição de valores.
const users = ['Albert', 'Nikola', 'Leonardo', 1, 2, 3] //Da para colocar oque quiser aqui no meio
users[0] //Albert
users[0] = 'Einstein'
users[0] // Einstein
const users = ['Albert']
users[0] // Albert
const users = ['Albert']
users[0] = ['Nikola']
users[0] // Nikola
Aqui é necessário ter atenção, para não referenciar diretamente um array a outra variavél. Pois dessa forma a variavel vai apontar para o mesmo endereco de memoria do array.
Exemplo
const array_1 = [1,2,3]
const array_2 = array_1
array_2[2] = 123123123
// Eles teram os mesmo valores, pois as duas variaveis apontam para o mesmo endereço de memoria
array_1 // [1,2,123123123]
array_2 // [1,2,123123123]
Uma das maneiras correta de se passar o valor do array para outra variavél
const array_1 = [1,2,3]
const array_2 = [...array_1] // maneira correta de se fazer
array_2[2] = 123123123
array_1 // [1,2,3]
array_2 // [1,2,123123123]
//exemplo simples
let a
let b
let c
[a,b,c] = [1,2,3]
a //1
b //2
c //3
//desestruturação
const numbers = [1,2,3,4]
const [first, second, ...rest] = numbers
first // 1
second // 2
rest // [3, 4]
//pulando valores
const [number1 , , number3] = numbers
number1 // 1
number3 // 3
Esses ... que está antes de array_1 [...array_1] significa que todo o valor de array_1 será espalhado, e como no caso a variável array_2 está recebendo [...array_1], significa que o valor de array_1 será espalhado dentro de array_2.
const users = ['Albert', 'Nikola', 'Leonardo']
users.length //3
const users = ['Albert', 'Nikola']
//Inserir no final
users.push('Leonardo')
users // ['Albert', 'Nikola', 'Leonardo']
//Inserir no começo
users.unshift('Thomas')
users // ['Thomas', 'Albert', 'Nikola', 'Leonardo']
const users = ['Albert', 'Nikola', 'Leonardo']
//Remover do final
// pop retorna o valor removido
users.pop()
users // ['Albert', 'Nikola']
//Remover do começo
//shift retorna o valore removido
users.shift()
users // ['Nikola']
//Remover item deixando espaço vazio
delete users[0]
users // [<emptyitem>]
Quando o array é fatiado pelo metodo slice, ele não tem o seu valor realmente modificado, slice apenas retorna os valores entre o intervalo que você informar.
const users = ['Albert', 'Nikola', 'Leonardo']
users.slice(0,2) // ['Albert' , 'Nikola']
users.slice(0,-1) // ['Albert', 'Nikola', 'Leonardo']
-1 Inidica a última posição do array
const users = ['Albert', 'Nikola']
users instanceof Array // true
Esse método retira os valores do range que você selecionar. Com isso você pode descartar esses valores ou utiliza-los posteriormente.
// array.splice(posicao_inicial, quantidade_elementos_a_deletar, addElement, addElement, addElement)
const array = [1,2,3,4,5]
const elementos_removidos = array.splice(3,2)
array // [1,2,3]
elementos_removidos // [4,5]
//Example utilizando MAX_VALUE
const array = [1,2,3,4,5]
const elementos_removidos = array.splice(2, Number.MAX_VALUE)
elementos_removidos // [3,4,5]
//Adicionando valores com splice
const array = [1,2,3,4,5]
array.splice(3,0,'value')
array // [ 1, 2, 3, 'value', 4, 5 ]
//Removendo e adicionando ao mesmo tempo
const array = [1,2,3,4,5]
array.splice(3,2,'Albert', 'Nikola')
array // [1,2,3,'Albert', 'Nikola']
const array1 = [1,2,3,4]
const array2 = [5,6,7,8]
array1.concat(array2) // [1,2,3,4,5,6,7,8 ]
Sempre retorna um array
//forma classica
const array = [1,2,3,4,5]
function callBackFilter(value, index, array){
return value > 2;
}
const newArray = array.filter(callBackFilter)
newArray // [3,4,5]
//Forma mais elegante
const array = [1,2,3,4,5]
const newArray = array.filter(value => value > 2)
newArray // [3,4,5]
//Da para fazer assim também
const array = [1,2,3,4,5]
const newArray = array.filter((value, index, array) => {
// use value index array logic
//return
})
Esse método permite passar por todas as posições do array. É bem parecido com um for, você também pode colocar sua lógica para ser executada em cada posição.
Sempre retorna um array
const array = [1,2,3]
array.map((value,index,array) => {
return value
})
// Exemplo - retonar um novo array que valores dobrados
const array = [1,2,3]
const newArray = array.map(value => value * 2)
newArray // [2,4,6]
// Exemplo - Retornar apernas o nome dos objetos
const peoples = [
{name: 'Albert', surname: 'Einstein'},
{name: 'Nikola', surname: 'Tesla'}
]
const arrayWithNames = peoples.map(value => value.name)
arrayWithNames // ['Albert', 'Nikola']
Permite você passar por todas as posições, e também ter um único retorno. Por exemplo fazer a soma de todos os valores dentro do array, aqui teremos um unico retorno que será o valor total.
Reduzir array a um elemento
// Exemplo de soma
const array = [1,2,3]
const total = array.reduce(function(acumulador, valor, indice, array){
acumulador += valor
return acumulador
})
total // 6
// Exemplo de retorno de array
const array = [1,2,3]
const anotherArray = array.reduce(function(acumulator, value ){
acumulador.push(value)
return acumulador
}, [] )// Valor inicial do acumulador)
anotherArray // [1,2,3]
// Exemplo - Retornar o mais velho
const pessoas = [
{name: 'Albert', age: 76},
{name: 'Nikola', age: 86},
{name: 'Isaac', age: 84}
]
const pessoaMaisVelha = pessoas.reduce(function(acumulador, valor){
// O acumulador sempre inicia pegando o valor da primeira posição
// O 'Valor' sempre inicia pegando o valor da segunda posição
if (acumulador.age > valor.age) return acumulador
return valor
})
pessoaMaisVelha // {name: Nikola, age: 86}
Apenas passa sobre o array, assim como um for clássico
const array = [1,2,3]
array.forEach((value, index, array) => {
//logic
})
Funções podem ter retornos ou não, assim como parametros
//Quando se declar uma função da maneira abaixo, a função poderá ser chamada em qualquer lugar do código - Efeito Hosting
//Escopo básico de função
function name (parameters) {
//logic
}
// Função com retorno
function teste(){
return alert('teste')
}
É a mesma coisa que a função normal, porém ela veio para deixar o código mais elegante
//Escopo básico
(parameters) => {logic}
//example
//Aqui como é uma linha não precisa de return, o return é automatico
(num) => num ** 0.5
//or
num => num ** 0.5
//or
const raiz = num => num ** 0.5
//Pegar parametro via desestruturação de objeto
const obj = { name: 'Albert', surname: 'Einstein'}
//Pegando somente o nome
function getName({name}) {
console.log(name)
}
getName(obj) // Albert
//Pegar valores via desestruturação de um array
const array = [1,2,3,4]
const getThreeFirstNumbers = ([num1,num2,num3]) => {
console.log(num1,num2,num3)
}
getThreeFirstNumbers(array) // [1,2,3]
// Função com valores padrões. Funciona também para desestruturação
function soma(x=10, y=20){
return x + y
}
O parametro de resto deve ser o ultimo parametro da funcão
//Rest operator
const a = 1
const b = 2
const c = 3
const d = 4
const e = 5
function example(a,b,...rest){
console.log(a,b,rest)// 1 2 [3,4,5]
}
example(a,b,c,d,e)
const sayHello = function () {
console.log('Hello')
}
// or
const sayHello = () => console.log('Hello')
const sayHello = () => console.log('Hello')
sayHello()
Funciona apenas em function e não em arrow function. Para fazer funcionar de forma semelhante em arrow function, utilize o rest operator
function soma (){
let total = 0
//dentro de arguments, se encontra todos os valores
for (let argument of arguments){
total += Number(argument)
}
return total
}
//Vai somar todos esses valores
soma(1,2,3,4,5,123,123,4,56,7,23,8)
Habilidade da função acessar seu escopo léxico (Onde foi definida)
function multiplica(multiplicador){
return function(n){
return n * multiplicador
}
}
const duplica = multiplica(2) // Recebe a função dentro da função, por conta do return
duplica(4) // 8
Passar funções para ser executadas após outras funções. É bem semelhante ao exemplo mais acima
const first = (callback) => {
console.log('first')
if (callback)
callback()
}
const second = (callback) => {
console.log('second')
if (callback)
callback()
}
const third = (callback) => {
console.log('third')
if (callback)
callback()
}
first(() => second(() => third())) // first second third
A função é executada assim que é invocada
// Escopo classico
(function (parameters){
// logic
})(parameters);
// Escopo com arrow function
(() => {
//logic
})()
//exemplo
(() => console.log('teste'))()
Entrega um valor por chamada. Quando se utilizar [return] a função geradora será parada
A funcão geradora podem usar *
function* geradora1() {
// ... Lógica
yield 'valor1'
// ... Lógica
yield 'valor2'
// ... Lógica
yield 'valor3'
}
const valorGerado = geradora1()
valorGerado.next() // valor 1
valorGerado.next() // valor 2
valorGerado.next() // valor 3
//Exemplo de delegação
function geradora2(){
//Delega a primeira chamada a geradora 1
yield* geradora1()
yield 4
yield 5
yield 6
}
//Consultar os valores da função geradora
const valores = geradora2()
for (value of valores){
console.log(valores)
}
//Utilizando chamadas de funções em sequencia com funções geradoras
const function_1 = () => console.log('function 1')
const function_2 = () => console.log('function 2')
function functionsSequence(){
yield function_1()
yield function_2()
}
const callInSequence = functionsSequence()
callInSequence.next() //function_1
callInSequence.next() //function_2
Função que chama ela mesma
//Fará o laço de repetição 5 vezes
const recursive = (max) => {
if (max >= 5)
return
max++;
recursive(max)
}
recursive(0)
Lembrete - Quando for criar um metodo que se repete em cada objeto, é bem mais performatico utilizar o prototype. Para que o metodo seja criado em apenas um lugar ;)
// Criação literal - Dicionario
const pessoa = {
nome: 'Albert',
sobrenome: 'Einstein'
}
// or
const pessoa = new Object()
pessoa.nome = "Albert"
pessoa.sobrenome = "Einstein"
const people = {
name: 'Albert',
surname: 'Einstein'
}
people.name // Albert
people['name'] // Albert
const awesomePeople = {
name: 'Albert',
surname: 'Einstein',
}
const {name, surname} = awesomePeople
// com valores padrões, para caso os valores não existam no objeto
const {name='Albert', surname='Einstein'} = awesomePeople
//mudar o nome das variaveis para não seguir os nomes dos atributos dos objetos
const {name: sayYourName, surname: sayYourName} = awesomePeople
sayYourName // 'Albert'
sayYourSurname // 'Einstein'
//another example
const people = {
name: 'name',
address: {
street: 'california',
number: 124
},
age: 10
}
const {name, address:{street}, ...rest} = people
name // 'name'
street // 'california'
rest // age: 10
// forma padrão
function criaPessoa (name, surname){
return {
name,
surname,
getAllName: () => `${this.name} ${this.surname}`
}
}
//Se os parametros tiverem os mesmos nomes dos atributos, ficara dessa forma.
//Equivalente a forma de cima
function criaPessoa (nome, sobrenome){
return {
nome,
sobrenome
}
}
Funções fabricas
const createPeople = (name, surname) => {
return {
name,
surname,
sayHello: () => {
//This sempre se refere ao objeto chamado
return `Hello! I'm ${this.name}.`
}
}
}
const people = createPeople()
people.sayHello()
createPeople = (name, surname, age) => {
name,
surname,
age,
get completeName(){
return `${this.name} ${this.surname}`;
}
}
const people = createPeople('Albert', 'Einstein', 76 )
people.compleName // Albert Einstein
createPeople = (name) => {
return {
name,
surname: '',
set setSurname(surname){
this.surname = surname
}
}
}
const people = createPeople('Albert')
people.setSurname = 'Einstein'
people.surname // Einstein
É interessante iniciar com letra maiuscula por convenção.
function Pessoa(nome, sobrenome) {
//Atributos privados
const id = 1;
//metodos privados
const metodo_privado = () => {}
//Atributos publicos
this.nome = nome;
this.sobrenome = sobrenome;
this.metodo = function (){
};
}
const pessoa1 = new Pessoa('Albert', 'Einstein')
const pessoa2 = new Pessoa('Nikola', 'Tesla')
Não permitir alteração no objeto.
//Congelar na criação
function People(name, surname) {
this.name = name
this.surname = surname
Object.freeze(this)
}
//Congelar depois da criação
function People(name, surname) {
this.name = name
this.surname = surname
}
const people = new People('Albert', 'Einstein')
Object.freeze(people)
const pessoa = {
nome,
sobrenome,
falar(){
console.log('Hello World!')
console.log(`i'm ${this.nome}!`)
},
pular(){
console.log(`${this.nome} pulou!`)
}
}
function People (name, surname){
this.name = name
this.surname = surname
Object.defineProperty(this, 'surname', {
enumerable: true, // show key
value: surname, // show value
writable: false, // update
configurable: true, // reset configurations
})
}
const people = new People('Albert', 'Einstein')
function People (name, surname){
this.name = name
this.surname = surname
Object.defineProperties(this, {
name : {
enumerable: true, // show key
value: name, // show value
writable: false, // update
configurable: true, // reset configurations
},
surname: {
enumerable: true, // show key
value: surname, // show value
writable: false, // update
configurable: true, // reset configurations
}
})
}
const people = new People('Albert', 'Einstein')
Object.keys(people) // name, surname
function People (name, surname){
this.name = name
// let surname = surname
Object.defineProperty(this, 'surname', {
enumrable: true,
configurable: true,
get: function() {
return surname
},
set: function(value) {
if(typeof value !== 'string')
throw new TypeError('message')
surname = value
}
})
}
const people = new People('Albert', 'Einstein')
people.surname // 'Einstein'
people.surname = 1 // Error :)
const people = {name: 'Albert', surname: 'Einstein'}
//example 1
const copyPeople = {...people, age: 76}
//example 2
const copyPeople = Object.assign({}, people, {age : 76})
people // {name: 'Albert', surname: 'Einstein'}
copyPeople // {name: 'Albert', surname: 'Einstein', age: 76}
const people = {name: 'Albert', surname: 'Einstein'}
Object.getOwnPropertyDescriptor(people, 'name') /*
{value: 'name',
writable: true,
enumerable: true,
configurable: true}
*/
const people = {name: 'Albert', surname: 'Einstein'}
Object.values(people) // ['Albert', 'Einstein']
Retorna um array com os valores do objeto
const people = {name: 'Albert', surname: 'Einstein'}
console.log(Object.entries(people)) // ['name', 'Albert'], ['surname', 'Einstein']
Cara é muito bom! Cria uma função apenas para todos os objetos. Mantendo assim uma melhor performance.
function People(name, surname){
this.name = name
this.surname = surname
}
People.prototype.completeName = function(){
return `${this.name} ${this.surname}`
}
const object_A = { keyExample_A: 'ExampleA'}
const object_B = { keyExample_B: 'ExampleB'}
// O object_A vai ser o protótipo do object_B
Object.setPrototypeOf(object_B, object_A)
object_B.keyExample_A // 'ExampleA'
function People(name) {
this.name = name
People.prototype.getName = function (){
return `Here return name`
}
}
const example = Object.create(People.prototype, {
newKey: {
writable : true,
configurable: true,
enumerable : true,
value: 'example'
}
})
example // People {newKey: 'Example'}
example.getName() // Here return name
function Produto(nome, preco){
this.nome = nome
this.preco = preco
}
Produto.prototype.aumento = function(quantia){
return this.preco += quantia
}
function Camiseta(nome, preco, cor){
//Onde a herança acontece
Produto.call(this, nome, preco)
this.cor = cor
}
//Setar o mesmo prototype do produto
Camiseta.prototype = Object.create(Produto.prototype)
// Para setar o objeto como uma Camiseta, senão vai ficar como produto
Camiseta.prototype.constructor = Camiseta
// Camiseta se torna uma especialização de produto
const camiseta = new Camiseta('Camiseta', 100, 'Azul')
camiseta.aumento(10)
camiseta.preco // 110
//Para reescrever um metodo do pai
Camiseta.prototype.aumento = function(parameters){
//logic
//Quando aumento for chamado, ele fará oque essa função pedir, em vez de fazer oque o pai está passando
}
Fazer uma classe filha se comportar de forma diferente do pai (Sobreescrita de métodos)
function createGenius(name, surname) {
const pessoaPrototype = {
sayHello (){
console.log('Hello')
}
}
return Object.create(pessoaPrototype, {
name: {value: name},
surname: {value :surname}
})
}
const people = createGenius('Albert', 'Einstein')
const sayHello = {
sayHello () {
console.log(`Hello i'm ${this.name}!`)
}
}
const peoplePrototype = {...sayHello}
// const peoplePrototype = Object.assign({}, sayHello)
function createGenius(name, surname) {
return Object.create(peoplePrototype, {
name: {value: name},
surname: {value: surname}
})
}
const people = createGenius('Albert', 'Einstein')
const genius = [
{name: 'Albert', surname:'Einstein'},
{name: 'Nikola', surname: 'Tesla'},
{name: 'Charles', surname: 'Darwin'}
]
const newGenius = new Map()
for (const people of genius) {
const {name} = people
newGenius.set(name, {...people})
}
console.log(newGenius)
console.log(newGenius.get('Albert'))
Cara que maravilha linkar os prototypes aqui
class People {
constructor(name, surname){
this.name = name,
this.surname = surname
}
sayHello(){
console.log(`Hello i'm ${this.name}!`)
}
}
const people = new People()
const _velocity = Symbol('Velocity')
class Car {
constructor(name){
this.name = name
this[_velocity] = 0
}
get velocity(){
return this[_velocity]
}
set velocity(value){
if (typeof value !== 'number') return
if (value >= 100 || value <= 0) return
this[_velocity] = value
}
}
const car = new Car('Fusca')
car.velocity = 50
car.velocity // 50
class Genius{
constructor(name){
this.name = name
}
sayHello(){
console.log('Hello')
}
}
class People extends Genius{
constructor(name, age){
super(name) //Construtor pai
this.age = 76
}
//Sobre escrever o metodo da classe pai
sayHello(){
console.log("I'm another hello")
}
}
Acessa a classe sem instanciar a classe
class Genius{
constructor(name){
this.name = name
}
//metodo de instancia
sayHello(){
console.log('Hello')
}
//metodo estatico
static sayHelloToEverybody(){
console.log('Hello world!')
}
}
Genius.sayHelloToEverybody() // Hello world
Esses valores criam uma nova cópia quando são copiados
- string
- number
- boolean
- undefined
- null
- bigint
- symbol
// Não da para mudar fazendo isso
let a = 10
a[0] = 20 //Isso não muda o valor
a // 10
Esses valores apontam para o mesmo lugar da memória quando são copiados
- Array
- Object
- Function
//Da para mudar seus valores
const teste = [1,2,3]
teste[0] = 50
teste // [50,2,3]
- > Maior que
- < Menor que
- > Maior ou igual que
- <= Menor ou igual que
- == Igualdade
- === Igualdade estrita - Checa valor e tipo (Recomendado)
- != Diferença
- !== Diferença estrita - Checa valor e tipo (Recomendado)
- && (and - e)
- || (or - ou)
- ! (not - negação)
And - Para a comparação lógica ser verdadeira, todas as outras comprações devem ser verdadeiras
Or - Para a comparação lógica ser verdadeira, pelo menos uma das comparações devem ser verdadeiras
! - Nega a operação lógica
Exemplo
//&& - And - Todas devem ser verdadeiras
0 === 0 && 1 === 1 //true
0 === 0 && 1 === 2 //false
//|| - Or - Pelo menos uma dever ser verdadeira
0 === 0 && 1 === 1 //true
0 === 0 && 1 === 2 //true
0 === 1 && 1 === 2 //false
//! - Negação
true //true
!true //false
false //false
!false //true
!!false //false
!!!false //true
Retorno de valores e operações lógicas
- false
- 0
- ''
- null
- undefined
- NaN
false - Retorna o valor falso quando for encontrado
true - Sempre retornará o ultimo valor avaliado
//false
'Luiz Otavio' && 0 && 'Maria' // 0 pois 0 avalia em falso
//true
'Luiz' && 'Albert' && 'Maria' // Maria - Retorna o ultimo valor avaliado
Retorna o primeiro valore verdadeiro encontrado
Caso não haja valor verdadeiro, retorna o ultimo valor falso encontrado
false || false || 'Albert' || true // 'Albert' - Pois Albert é o primeiro resultado verdadeiro encontrado
Exemplos de validação
const cor = ''
const corPadrao = cor || '#fcfcfc'
corPadrão // '#fcfcfc' - Pois '' é avaliado como false
- If pode ser utilizado sozinho
- Para se usar else, é necessário ter um if antes
- Pode haver vários if else
- Só pode haver um else na checagem
- Não é necessário ter else/else if
//estrutura simples
if (true)
return 'verdadeiro'
else
return 'falso'
//estrutua composta
if (true)
return 'verdadeiro'
else if (false)
return 'falso'
//exemplo
const num = 10
if (num > 9){
console.log(num)
console.log('Numero maior que 9')
} else if (num === 10) {
console.log(num)
console.log('Numero igual a 10')
} else if (num < 5) {
console.log(num)
console.log('Numero menor que 5')
} else {
console.log(num)
console.log('Numero entre 9 e 5')
}
É utilizada para tomar uma ação somente quando a condição for verdadeira. Esse método de avaliação não aceita else.
condition && trueLogic
//Exemplo
1 === 1 && console.log('True') // true
Esse é delinha!
Pode substituir parte do código com condicionais mais simples
condition ? true : false
//example
5 > 10 ? 'Maior' : 'Menor'
const data = new Date() // Data atual por padrão
new Date(0) // 01/01/1970 - Timestamp unix ou época unix
new Date(2019, 3, 20, 15, 14, 27, 500) // 2019/4/20 - 15:14:27:500
new Date('2019-04-20 20:20:59')
Date.now() //Data atual em milesimos de segundos
new Date(Date.now()) // Data atual
//data.toString()
const data = new Date()
data.getFullYear() //ano
data.getMonth() //mes - Começa do zero
data.getDate() //dia
data.getHours() //horas
data.getMinutes() //minutos
data.seconds() //segundos
data.getMilliseconds() //milesimos
data.getDay() //dia da semana - 0 Domingo - Sábado
const data = new Date()
data.toLocaleTimeString('pt-BR', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}) // 00/00/00 00:00:00
switch (variable){
case condition:
//logic
break
case condition:
//logic
break
default:
//logic
break //Não tem necessidade
}
- For clássico - Geralmente com iteráveis (Array ou string)
- For in - Retorna o indice ou chave (string, array, objetos)
- For of - Retorna o valor (iteráveis, arrays ou string)
for (let i = 0; i > length; i++){
//logic
}
const names = ['Albert', 'Nikola', 'Thomas']
for (let index in names){
// first enter
index //1
// Second enter
index // 2
}
const people {
name: 'Albert',
surname: 'Einstein'
}
for (let key in people){
//first enter
console.log(people[key]) // Albert
//second enter
console.log(people[key]) //Einstein
}
for (let value of list){
//logic
}
//example
const peoples = [
{name: 'Albert'},
{name: 'Nikola'},
{name: 'Thomas'},
]
for (let people of peoples){
//first
people // {name: Albert}
//Second
people // {name: Nikoa}
//third
people // {name: Thomas}
}
Checa a condição e depois entra no laço de repetição
while (i <= 10){
//logic
i++;
}
Entra pelo menos uma vez no laço e depois checa a condição
do {
//logic
} while (condition)
Controle do laço. Funciona em todos os laços
- Break - Parar o laço
- Continue - Passar o laço para a próxima entrada
const nums = [1,2,3]
for (let num of nums){
//pulando o console.log do número dois
if (num === 2)
continue
console.log(num)
}
const nums = [1,2,3]
for (let num of nums){
//Parando o laço quando encontrar o número dois
if (num === 2)
break
}
Estrutura básica do DOM
Window > Document > Html > Head | Body
O Dom possui uma api que nos permite interagir com ele. Podemos criar e modificar os dados que estão dentro dele
document.getElementById('id')
document.querySelector('#id') //mais moderno
document.querySelector('.class') //mais moderno
documet.querySelectorAll('element')
// Exemplo
const elements = document.querySelectorAll('p')
elements // NodeArray p's
// Outro exemplo
const container = document.querySelector('.container')
container.querySelectorAll('p') // Get all p's inside in container
// Selecionar com contains
container.classList.contains('class')
const element = document.querySelector('p')
element.parentElement // elemento pai
const element = document.querySelector('element')
element.remove()
const element = document.querySelector('element')
element.parentElement.remove()
const element = document.querySelector('element')
element.innerText //Return text
const input = document.querySelector('.input')
input.addEventListener('event', function(event){
//logic
})
// Exemplo
const input = document.querySelector('.input')
input.addEventListener('click', () => console.log('teste'))
document.addEventLister('click', (event) => {
const element = event.target
})
document.createElement('element')
//example
const p = document.createElement('p')
p.classList.add('class-name')
p.innerHTML += 'text'
//Exemplo de criação de nó de texto
const textNode = document.createTextNode('text')
p.appedChild(textNode) // inserir o texto na tag p
const example = document.querySelector('#id')
example.innerHTML = 'html'
axample.innerText = 'text'
- appendChild(element)
const example = document.querySelector('#id')
//criar p
const p = document.createElement('p')
//Adicionar class a p
p.classList.add('class-name')
//Adicionar p dentro de example
example.appendChild(p)
const styleBody = getComputedStyle(document.body) // pegar estilo do body
// Pegar o background
styleBody.backgroundColor // 'ffffff'
//Exemplo de mudança de cor
const element = document.querySelector('.class')
element.style.backgroundColor = 'red' // mudar a cor
try{
// Execuçãoq uando não há erros
} catch (err){
// Execução caso haja erro
} finally{
// Sempre executado
}
throw new Error('message')
// Example
const number = 'text'
if (typeof number !== 'number')
throw new Error('Precisa ser número')
Executa função em um periodo de tempo definido
setInterval(function, milliseconds)
//example
setInterval(() => console.log('teste'), 1000)
Define um tempo de expiração para um intervalo
//Criando uma função para executar em um intervalo
const interval = setInterval(() => console.log('teste'), 1000)
//Definindo o intervalo de 5 segundos para a função
setTimeout(() => {
clearInterval(interval)
}, 5000)
const tasks = [1,2,3,4]
const tasksJson = JSON.stringify(tasks)
tasksJson = [] // '[1,2,3,4]'
const tasks = [1,2,3,4]
const tasksJson = JSON.stringify(tasks)
tasksJson = [] // '[1,2,3,4]'
const realTasks = JSON.parse(tasksJson)
realTasks // [1,2,3,4]
Base de dados do navegdor
localstorage.setItem('name', string)
//Exemplo
const array = [1,2,3]
const arrayJson = JSON.stringify(array)
localStorage.setItem('array', arrayJson)
localStorage.getItem('name-item')
localStorage.removeItem('keyName')
- Pending
- fullfilled - Resolvida
- Rejected
Execução em pararélo, assincrono
Muito utilizado em conexões com banco de dados e chamadas em API. Esse método é utilizado quando não sabemos a hora correta que vamos receber um retorno da requisição feita. Então é retornado uma promessa de resultado, e podemos usar métodos para esperar essa promessa ser cumprida.
//Example - Modelo classico
function esperaAi(msg, tempo) {
return new Promise((resolve, reject) => {
if (typeof msg !== 'string') {
reject('Valor incorreto')
return
}
setTimeout(() => {
resolve(msg)
}, tempo)
})
}
esperaAi('Frase 1', 1000)
.then(resposta => {
console.log(resposta)
return esperaAi('Frase 2', 1000)
})
.then(resposta => {
console.log(resposta)
})
.catch(e => {
console.log('Erro: ',e)
})
Resolve promessas em sequencia e retorna um array com os resultados
function esperaAi(msg, tempo) {
return new Promise((resolve, reject) => {
if (typeof msg !== 'string') {
reject('Valor incorreto')
return
}
setTimeout(() => {
resolve(msg)
}, tempo)
})
}
promisses = [
esperaAi('Frase 1', 1000),
esperaAi('Frase 2', 1000),
esperaAi('Frase 3', 1000),
]
Promise.all(promisses)
.then(valor => console.log(valor))
.catch(error => console.log(error))
// ['Frase 1', 'Frase 2', 'Frase 3']
Retorna o primeiro valor que for resolvido
function esperaAi(msg, tempo) {
return new Promise((resolve, reject) => {
if (typeof msg !== 'string') {
reject('Valor incorreto')
return
}
setTimeout(() => {
resolve(msg)
}, tempo)
})
}
promisses = [
esperaAi('Frase 1', 1000),
esperaAi('Frase 2', 5000),
esperaAi('Frase 3', 500),
]
Promise.race(promisses)
.then(valor => console.log(valor))
.catch(error => console.log(error))
Retorna uma promise resolvida ou a rejeição dela
- Resolve = Quando da tudo certo
- Reject = Quando da ruim
function emCache(){
const cache = true
if (cache){
return Promise.resolve('Em cache!')
} else {
return Promise.reject('Página sem cache')
}
}
emCache()
.then(mensagem => console.log(mensagem))
.catch(mensagem => console.log(mensagem))
Método para facilitar resolver promessas de modo sincrono
O await é tudo de bom!
function esperaAi(msg, tempo) {
return new Promise((resolve, reject) => {
if (typeof msg !== 'string') {
reject('Valor incorreto')
return
}
setTimeout(() => {
resolve(msg)
}, tempo)
})
}
// É necessário utilizar com funções
async function executa(){
// Para capturar as rejeições é necessário utilizar try catch
try{
const frase1 = await esperaAi('Frase 1', 1000)
console.log(frase1)
const frase2 = await esperaAi('Frase 2', 2000)
console.log(frase2)
const frase3 = await esperaAi('Frase 3', 500)
console.log(frase3)
} catch(e) {
console.log(e)
}
}
executa()
Utilização de requisições AJAX
Quase não se usa mais, pois o Axios está dominando geral
//Exemplo de requisição para o Google (Funciona dentro do site do Google)
const xhr = new XMLHttpRequest()
// xhr.open(method, url, async)
xhr.open('GET', 'https://www.google.com', true)
xhr.send()
xhr.status // 200
Maneira simples de fazer requisições
- Retorna um Promise
//Exampo - Requisição para o Google (Funciona dentro do site do Google)
fetch('https://www.google.com')
.then(result => result.text())
// result.text() - Retorna outra promise
.then(html => console.log(html))
Ele não é nativo do JS então precisa entrar na Doc dele no Github e baixar por lá
Mas em algums frameworks ele já vem no pacote :3
axios('target').then().catch()
Cara, existem várias formas. Irei listar as mais usada abaixo, mas é bom ver a doc :3
const name = 'Albert'
const surname = 'Einstein'
export name
export default name
export name as genius
export const name = 'Albert'
export {name as genius, surname as default}
import { name } from './path/file_name'
// If have export default
import anyName from './path/file_name'
import { name, surname as surnameOfGenius} from './path/file_name'
import defaultModule { surnameOfGenius } from './path/file_name'
npm install --save-dev @babel/cli @babel/preset-env @babel/core
npx babel main.js -o bundle.js --presets=@babel/env
Dentro do arquivo package.json, na linha de scripts
"babel": "babel ./main.js -o ./bundle.js --presets=@babel/env -w"
npm i --save-dev @babel/preset-env @babel/cli @babel/core babel-loader webpack webpack-cli
npm i core-js regenerator-
// loader para css
npm i style-loader css-loader
Dentro do arquivo webpack.config.js
//configuração padrão
const path = require('path')
module.exports = {
mode: 'development',
//Arquivo de entrada
entry: './src/main.js',
//Arquivo de saida
output: {
path: path.resolve(__dirname, 'public', 'assets','js'),
filename: 'bundle.js'
},
module: {
rules: [{
exclude: /node_modules/,
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/env']
}
}
},
{
//loader do CSS
test: /\.css$/,
use: ['style-loader','css-loader']
}]
},
devtool: 'source-map'
}