- HTML, CSS e Javascript (Módulo 1 ao 14) - Identificador de autenticidade: DVWBVSH17HT307110
- Firebase, jQuery, Bootstrap (Módulo 17 ao 20)
- Node, Mongo (Módulo 21 ao 30)
Para verificar a autentencidade de um certificado, acesse: https://programadorbr.com/autenticidade e insira o identificador.
- Curso de Desenvolvimento Web - Programador BR
- Tag
- Estrutura Básica
- Títulos e Parágrafos
- Comentários
- Formatação
- Links
- Imagens
- Quebra de Linha
- Listas
- Tabelas
- CSS inline
- CSS interno
- CSS externo
- Classes e Ids
- Cores
- Background
- Div
- Ferramentas do Google Chrome
- Unidades de medida (fixas)
- Unidades de Medida (referência)
- Margin e Padding
- Border
- Box Model
- Ajustes de texto
- Fontes
- Usando fontes customizadas
- Estilo de link
- Listas
Controla como cada elemento é mostrado na tela.
selector {
display: none;
/* Retira o elemento do layout da página (como se nunca tivesse sido colocado)*/
display: block;
/* Quebra de linha no final, possível especificar tamanho (width, height) */
display: inline;
/* Não tem quebra de linha, tamanho fixo */
display: inline-block;
/* Não tem quebra de linha, mas permite especificar tamanho */
}IMPORTANTE: quando aplicado inline-block, uma margem de 4px é aplicada automaticamente devido a quebra de linha existente no HTML. Mais informações e ideias de solução aqui.
Propriedade display padrão dos elementos:
<div>: block
<span>: inline
<p>: block
<img>: inline especial, age como inline-block
IMPORTANTE: Nunca colocar um elemento com display: block dentro de um parágrafo <p>, pois irá quebrar o fluxo do parágrafo (ex: background-color).
Controla como um conteúdo se comporta em relação ao seu container.
selector {
overflow: visible;
/* Mostra todo o conteúdo, independente do elemento pai */
overflow: hidden;
/* Cropa o conteúdo usando o elemento pai */
overflow: scroll;
/* Cria uma barra de rolagem no elemento pai (vertical e horizontal) */
overflow: auto;
/* Cria uma barra de rolagem automaticamente quando necessário, ou altera o tamanho da div */
overflow-x: scroll;
/* Overflow HORIZONTAL, nesse caso adiciona somente barra de rolagem horizontal*/
overflow-y: scroll;
/* Overflow VERTICAL, nesse caso adiciona somente barra de rolagem vertical*/
}Usar a propriedade margin.
Para <div>:
selector {
margin: auto;
/* Centraliza horizontalmente, adicionando margens de ambos os lados preenchendo toda a largura da tela */
margin-left: auto;
/* Alinha a direita */
}Para <img>:
Opção 1:
Mudar paradisplay: blocke usarmarginna imagem.
Opção 2:
Colocar a imagem dentro de uma<div>e usartext-aligncomcenter,leftourightna div.
Usar a propriedade position.
selector {
position: static;
/* Position padrão, posiciona conforme descrito em 'display' */
position: relative;
/* Posicionamento relativo ao padrão, pode ser usado com 'left', 'top'... */
left: 20px;
top: 20px;
/* Muda a posição e sobrepõe outros elementos, só altera a posição do elemento afetado, diferente de 'margin' */
/* O elemento é posicionado em relação a sua própria posição natural, se fosse 'static' */
/* Posicionamentos usando relative são muito frágeis */
/* Os outros elementos não ocupam o espaço deste elemento, mesmo que movimentado */
}selector {
position: absolute;
/* Ancora o elemento com relação ao elemento pai, mas outros elementos passam a ocupar o mesmo espaço, como se este elemento não estivesse ali */
/* A posição inicial do elemento é sua posição natural, porém em frente a outros elementos que também tomaram essa posição */
/* Este elemento não é usado por outros como referência para seus posicionamentos */
/* O elemento pai é usado somente se ele NÃO FOR ESTÁTICO, se for, o avô é usado como referência, e assim sucessivamente até o body ser usado como ref */
right: 0px;
bottom: 0px;
/* Se o elemento pai não for static: cola este elemento ao canto inferior direito do pai*/
}selector {
position: fixed;
/* Assim como em 'absolute', deixa outros elementos ocuparem seu lugar */
/* Ancora o elemento com relação ao viewport, não ao pai ou ascendentes */
/* O viewport é a parte da janela que está aparecendo na tela */
/* Para efeitos de dimensionamento, não leva em conta o pai */
}selector {
position: sticky;
/* Não deixa outros elementos ocuparem seu lugar */
/* Continua sendo referência para outros elementos */
/* Rola junto com o elemento pai/página */
top: 0px;
/* Rola com a página mas fica grudado no topo e não sai do viewport, neste momento o restante desliza por baixo para continuar rolando */
}selector {
float: left;
/* Elemento fica flutuando a esquerda do próximo */
/* Ex: Uma imagem é envelopada por um texto */
}
selector2 {
/* É possível impedir que algum elemento flutue ao redor deste usando 'clear'*/
clear: left;
/* Afeta somente o lado esquerdo, pode ser: both, left, right */
clear: none;
/* Valor padrão, não impede nada */
}Para textos dentro de um <div>:
selector {
line-height: 100px;
/* Linha de 100px, se o elemento pai tem 100px, o texto centralizado */
/* DESVANTAGEM: TEM QUE SABER O TAMANHO DO ELEMENTO PAI */
}
selector {
position: absolute;
top: 50%;
/* Lembrando que o pai não pode ter position: static */
/* O topo da linha é alinhado com o centro do pai */
transform: translateY(-50%);
/* Translada o elemento -50% de seu tamanho, nesse caso a altura da linha, dessa forma o centro da linha fica alinhado com o centro do elemento pai */
}Para centralizar um elemento:
selector {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}Adicionar uma tag <meta> no <head> do HTML para que o navegador entenda como processar o site.
<meta name="viewport" content="width=device-width, initial-scale=1.0" />Utilizar unidades de medida relativas ao tamanho da tela ou de elementos ascendentes, por exemplo %, vw ...
Aplica as regras de CSS somente se a tela corresponder a um tamanho máximo (max-width) ou mínimo (min-width).
@media screen and (max-width: 400px) {
/* Executa somente em telas de no máximo 400px */
selector {
/* Regras */
}
}É possível adicionar diversos Media Queries, eles vão sendo aplicados consecutivamente:
selector {
background-color: white;
color: blue;
}
@media screen and (max-width: 500px) {
selector {
background-color: black;
}
}
@media screen and (max-width: 250px) {
selector {
color: red;
}
}
/* No caso acima, temos:
Telas com mais de 500px: fundo branco e fonte azul
Telas com 250 a 500px: fundo preto e fonte azul
Telas com menos de 250px: fundo preto e fonte vermelha */IMPORTANTE: A ordem dos media queries IMPORTA, deve ser do MAIOR para o MENOR se usando max-width.
IMPORTANTE: Os media queries devem ser colocados no FINAL do arquivo de CSS.
method: método de envio de dados, GET ou POST
action: endpoint, se estiver no domínio da página pode ser apenas /nomeDoEndpoint
<!-- Exemplo de formulário para busca no youtube -->
<form method="GET" action="https://www.youtube.com/results">
<input type="text" name="search_query" placeholder="Busca" />
<input type="submit" />
</form>text: Texto comum em uma linha.
password: Esconde o que está sendo digitado.
checkbox: Passa on se não tiver value, senão passa o value. Permite várias seleções.
radio: Semelhante ao checkbox, mas só permite uma seleção entre tags com o mesmo name. checked indica o estado default como marcado.
reset: Limpa todos os campos.
submit: Envia os dados. value indica o texto escrito no botão. (Para enviar é melhor usar a tag button).
<
<form method="POST" action="/">
<input type="text" name="text" />
<input type="password" name="password" />
<input type="checkbox" name="checkbox" value="manterLogado" />
<input type="radio" name="radio" value="M" checked />
<!-- Botão -->
<input type="submit" />
<!-- Usar a tag button em vez de input para enviar -->
<button>Submit</button>
</form>
>O name do select é enviado junto com o value do option.
selected em option indica a posição padrão exibida no dropdown.
size em select indica o número de opções exibidas, se houver mais uma barra de rolagem aparece. Não dá o efeito de dropdown.
multiple em select permite a seleção de várias opções.
<!-- Envia: estado=SP, por exemplo -->
<select name="estado" size="2">
<option value="RJ">Rio de Janeiro</option>
<option value="SP" selected>São Paulo</option>
<option value="MG">Minas Gerais</option>
</select>Adiciona uma caixa para entrada de texto. É necessário conter um name, senão não é enviado.
<form method="POST" action="">
<textarea name="texto"></textarea>
<button>Enviar</button>
</form>caniuse.com
Buscar quais funcionalidades os navegadores suportam.
color: abre um seletor de cores e envia o HEX.
date: calendário para selecionar data. Usar max="{{data}}" para definir uma data limite.
datetime-local: permite a seleção de data e hora.
file: envio de arquivos. O método deve ser POST.
number: envio de números. Usar min e max para limitar os valores.
range: cria um slider entre min e max. Usar value para setar o default. step define o passo
tel: em mobile abre somente o teclado numérico.
email: verifica se o input contém elementos de email, como ponto e arroba.
<
<form method="POST" action="/">
<input type="color" name="cor" />
<input type="date" name="data" max="1995-01-24" />
<input type="datetime-local" name="data" max="1995-01-24" />
<input type="file" name="arquivo" />
<input type="number" name="numero" min="0" max="10" />
<input type="range" name="intervalo" min="0" max="10" value="6" step="1" />
<input type="tel" name="telefone" />
<input type="email" name="email" />
</form>Tags semânticas informam os buscadores sobre o conteúdo da página, dessa forma eles podem ser melhor interpretadas e ranqueadas por eles.
header: cabeçalho da página. Mesmo comportamento da tag <div>.
nav: barra de navegação. Aparece dentro do header.
footer: rodapé.
main: principal conteúdo do site, só pode haver 1 por página.
section: seção do site, para melhor organização.
article: artigo do site, seu conteúdo deve fazer sentido independente da página.\
<header>
<h2>Logo</h2>
<nav>
<!-- Itens -->
</nav>
</header>
<main>
<!-- Conteúdo principal -->
<section></section>
<article></article>
</main>
<footer>
<!-- Conteúdo -->
</footer>Um script javascript pode ser adicionado ao HTML com a tag <script>, internamente ou em arquivos separados.
<script>
alert("Hello, World");
</script>
<!-- ou -->
<script src="script.js"></script>Com script.js:
alert("Hello, World");Print no console:
console.log("Hello, World");var a = "Hello, World");
console.log(a);Boolean : True ou False
Null : variável vazia
Undefined : retorno de variáveis não inicializadas
Number : número, console mostra em azul
"String" : sequência de caracteres, console mostra em preto
{Object} : dado estruturado, tem propriedades (atributos) e funcionalidades (métodos)
[Array] : lista, agrupamento de dados
+: Adição
-: Subtração
*: Multiplicação
/: Divisão
%: Módulo (resto de divisão)
**: Exponencial
++: Incremento
--: Decremento
Incremento e decremento podem aparecer antes ou depois da variável, isso muda como é feita uma atribuição, por exemplo:
var a = 30;
var b = --a;
console.log("a = " + a); // a = 29
console.log("b = " + b); // b = 29 <<<var a = 30;
var b = a--;
console.log("a = " + a); // a = 29
console.log("b = " + b); // b = 30 <<<| Operator | Usage | Meaning |
|---|---|---|
= |
x = y | x = y |
+= |
x += y | x = x + y |
-= |
x -= y | x = x - y |
*= |
x *= y | x = x * y |
/= |
x /= y | x = x / y |
%= |
x %= y | x = x % y |
| Operator | Usage |
|---|---|
== |
igual |
=== |
idêntico / estritamente igual (valor e tipo) |
!= |
diferente |
!== |
estritamente diferente (valor e tipo diferentes) |
> |
maior |
< |
menor |
>= |
maior ou igual |
<= |
menor ou igual |
Exemplo de uso:
var a = 3;
var b = "3";
console.log(a == 3); // True
console.log(a === 3); // False| Operator | Usage |
|---|---|
&& |
E |
|| |
OU |
! |
Negação |
str
Pode-se usar aspas "duplas" ou 'simples'.
var str = "Texto";
var str = "Texto";O operador + concatena strings.
Se a string for somente numérica, pode-se usar operadores matemáticos, mas o tipo passar a ser number:
var numero = "5";
typeof numero; // string
numero *= 2; // numero = 10
typeof numero; // number
var str = "abc" * 2; // str = NaNPara forçar uma mudança de tipo:
parseInt(var) converte para inteiro por truncamento, tipo number
var a = "5.5"; // "5.5"
typeof a; // string
a = parseInt(a); // 5
typeof a; // numberparseFloat(var) converte para float, tipo number
var a = "5.5"; // "5.5"
typeof a; // string
a = parseFloat(a); // 5.5
typeof a; // numberNumber(var) converte para tipo number
alert("mensagem")
Cria um popup com a "mensagem" e um botão "ok".
prompt("mensagem")
Cria um popup com um campo para receber input.
var nome = prompt("Qual o seu nome?");
alert("Bom dia, " + nome + " :)");Os dados recebidos por prompt são do tipo string.
Sintaxe:
if (/*teste lógico*/) {
// executa se o true
}
else if {
// executa se o anterior é false
}
else {
// executa se o anterior é false
}Exemplo:
var idade = 20;
if (idade >= 35) {
console.log("Pode comprar");
console.log("Qual o seu pedido?");
} else if (idade >= 18) {
console.log("Pode comprar");
console.log("Mostre seu documento de identidade");
} else {
console.log("Não pode comprar");
console.log("Volte futuramente");
}Recomendado para testes simples em uma única linha.
Sintaxe:
var a = /*(teste lógico)*/ ? /*(executa se true)*/ : /*(executa se false)*/Exemplo: verificar se maior de idade
var idade = 15;
idade >= 18 ? console.log("Sim") : console.log("Não");
// Equivalente a:
var resposta = idade >= 18 ? "Sim" : "Não";
console.log(resposta);
// Equivalente a:
if (idade >= 18) {
console.log("Sim");
} else {
console.log("Não");
}Exemplo: multiplicar por 2 se menor que 5, senão multiplicar por 10
var numero = 1;
var resultado = numero < 5 ? numero * 2 : numero * 10;
// Equivalente a:
if (numero < 5) {
resultado = numero * 2;
} else {
resultado = numero * 10;
}Usado para comparar um valor com diversas referências.
Sintaxe:
switch (valor) {
case referencia1:
// executa se valor == referencia1
break;
case referencia2:
// executa se valor == referencia2
break;
case referencia2:
// executa se valor == referencia2
break;
default:
// executa se não entrar em nenhum caso anterior
break;
}Exemplo: organização de fila de embarque
var tipoPassagem = "VIP";
switch (tipoPassagem) {
case "VIP":
console.log("Vá para a fila prioritária");
break;
case "Comum":
console.log("Vá para a fila comum");
break;
default:
console.log("Você não pode embarcar");
break;
}Sintaxe for:
for (var i = 0; i < 5; i++) {
console.log(i); // imprime 0, 1, 2, 3, 4
}
console.log("i = " + i); // i = 5Pode-se limitar o escopo do contador i declarando com let:
for (let i = 0; i < 5; i++) {
console.log(i); // imprime 0, 1, 2, 3, 4
}
console.log("i = " + i); // Erro "Uncaught ReferenceError: i is not defined"Sintaxe while:
var i = 0;
while (i < 5) {
console.log(i); // imprime 0, 1, 2, 3, 4
i++;
}
console.log("i = " + i); // i = 5Lista de elementos separados por vírgula.
var letras = new Array("A", "B", "C", "D", "E");
var letras = ["A", "B", "C", "D", "E"];
console.log(letras[0]); // "A"
console.log(letras[1]); // "B"
console.log(letras[2]); // "C"Acessando valores com for (3 formas):
var letras = ["A", "B", "C", "D", "E"];
for (let i = 0; i < letras.length; i++) {
console.log(letras[i]); // imprime todos os itens
}
// Ou (pegando os índices)
for (let i in letras) {
console.log(letras[i]); // imprime todos os itens, i recebe os índices
}
// Ou (pegando os itens)
for (let letra of letras) {
console.log(letra); // imprime todos os itens, letra recebe o item
}Funções nomeadas estão sujeitas a hoisting.
Sintaxe:
function nomeDaFuncao(parâmetros) {
//Comandos
return; //valor
}
// receber parâmetros e retornar valores é opcional
nomeDaFuncao(argumentos);
// os argumentos correspondem aos parâmetros da função quando ela está sendo invocadaExemplo: cálculo de média
function media(nota1, nota2) {
let media = (nota1 + nota2) / 2;
return media;
}
var resultado = media(10, 5);
console.log(resultado); // 7.5É possível atribuir a própria função, passando seu nome, a uma outra variável, que passará a ser utilizável como função:
function media(nota1, nota2) {
return (nota1 + nota2) / 2;
}
console.log(media(10, 5)); // 7.5
m = media; // 'm' recebe a função 'media'
console.log(m(10, 2)); // 6ATENÇÃO: Variáveis em Funções
Se uma variável for declarada em uma função SEM utilizar palavras reservadas (var, let, const), ela passar a ter ESCOPO GLOBAL:
function soma(n1, n2) {
total = n1 + n2;
}
soma(1, 5);
console.log(total); // 6, notar que 'total' foi declarada dentro da função e está sendo utilizada foraSe uma variável é declarada dentro da função com QUALQUER palavra reservada, seu escopo é limitado ao escopo da função!
function soma(n1, n2) {
var total = n1 + n2; // poderia ser let ou const
}
soma(1, 5);
console.log(total); // ReferenceError: total is not defined
// Notar que 'total', mesmo declarada com 'var', não sai do escopo da funçãoFunção anônima
Funções anônimas não estão sujeitas a hoisting.
Sintaxe:
var nomeDaFuncao = function (parâmetros) {
//Comandos
return; //valor
};Exemplo:
var media = function (nota1, nota2) {
return (nota1 + nota2) / 2;
};Função de seta / arrow function
Sintaxe:
var nomeDaFuncao = (parâmetros) => {
//Comandos
return; //valor
};Exemplo:
var media = (nota1, nota2) => {
return (nota1 + nota2) / 2;
};Função de callback / callback function
Quando uma função é passada como parâmetro de outra função, ela pode ser executada como uma callback function.
function foo(callbackFunction) {
console.log("Before callback function");
callbackFunction();
console.log("After callback function");
}
foo(() => {
console.log("I'm inside a callback function! :)");
});
// Before callback function
// I'm inside a callback function! :)
// After callback functionSão conjuntos de propriedades separadas por vírgula.
As propriedades podem ser variáveis de qualquer tipo, com uma chave e um valor separados por dois pontos (:).
Um objeto também pode ser uma propriedade de outro objeto.
São parecidos com dicionários de python.
Sintaxe:
// Declaração:
var nomeObjeto = new Object()
// ou
var nomeObjeto = new Object({
chave1: valor1
chave2: valor2
})
// ou
var nomeObjeto = {
chave1: valor1
chave2: valor2
}
// Acessar valores:
nomeObjeto.chave1 // retorna 'valor1'
nomeObjeto["chave1"] // retorna 'valor1'
// Adicionar propriedades:
nomeObjeto.chave3 = valor3
nomeObjeto["chave4"] = valor4Deletar uma propriedade de um objeto:
delete nomeObjeto.chave;Exemplo:
var aluno = {
nome: "Igor",
nota1: 7.5,
};
console.log(aluno.nome + " tirou " + aluno.nota1 + " na prova");
// Igor tirou 7.5 na prova
console.log(aluno["nome"] + " tirou " + aluno["nota1"] + " na prova");
// Igor tirou 7.5 na prova
delete aluno.nota1;
console.log(aluno);
// aluno = {
// nome: "Igor"
// }Objetos como argumentos:
var aluno1 = {
nome: "Igor",
nota: 7.5,
};
var aluno2 = {
nome: "Pedro",
nota: 5.5,
};
var aluno3 = {
nome: "Maria",
nota: 9.5,
};
var alunos = { aluno1, aluno2, aluno3 };
console.log(alunos);
/*
{
{
nome: "Igor",
nota: 7.5
},
{
nome: "Pedro",
nota: 5.5
},
{
nome: "Maria",
nota: 9.5
}
}
*/Um objeto também pode conter funções, que são chamadas de métodos.
Os métodos podem ser funções definidas dentro ou fora do objeto.
var aluno = {
nome: "Igor",
notas: [6, 7],
media: function (n1, n2) {
return (n1 + n2) / 2;
},
};
// 'media' é um método de 'aluno'
console.log(aluno.media(aluno.notas[0], aluno.notas[1])); // 6.5function calcMedia(n1, n2) {
return (n1 + n2) / 2;
}
var aluno = {
nome: "Igor",
notas: [6, 7],
media: calcMedia,
};
// 'media' é um método de 'aluno'
console.log(aluno.media(aluno.notas[0], aluno.notas[1])); // 6.5this
Referencia o objeto internamente:
var aluno = {
nome: "Igor",
notas: [6, 7],
media: function () {
return (this.notas[0] + this.notas[1]) / 2;
},
};
// 'media' é um método de 'aluno'
console.log(aluno.media()); // 6.5O método também pode ser definido externamente:
function calcMedia() {
return (this.notas[0] + this.notas[1]) / 2;
}
var aluno = {
nome: "Igor",
notas: [6, 7],
media: calcMedia,
};
// 'media' é um método de 'aluno'
console.log(aluno.media()); // 6.5Funções para criar objetos de maneira mais fácil e estruturada, além de evitar erros de digitação.
function criarAluno(nomeAluno, nota1, nota2) {
let aluno = {
nome: nomeAluno,
notas: [nota1, nota2],
media: function () {
return (this.notas[0] + this.notas[1]) / 2;
},
};
return aluno;
}
var turma = [
criarAluno("Igor", 9, 6),
criarAluno("João", 6, 7),
criarAluno("Maria", 5, 10),
];
console.log(turma[1].media()); // 6.5 (média do João)Funções também são objetos. Elas são usadas como Construtores para criar outros objetos com uma certa estrutura:
// Objeto tipo 'aluno'
function aluno(nome, nota1, nota2) {
this.nome = nome;
this.nota = new Array();
this.nota[0] = nota1;
this.nota[1] = nota2;
this.media = function () {
return (this.nota[0] + this.nota[1]) / 2;
};
}
// Criando objetos (instanciar)
var aluno1 = new aluno("Igor", 8, 7);
var aluno2 = new aluno("João", 6, 7);
// 'aluno1' e 'aluno2' são instâncias de 'aluno'
console.log(aluno1);
console.log(aluno2);forEach()
Método do objeto Array, recebe uma função cujo parâmetro será cada elemento do array. Semelhante a um loop for.
Sintaxe:
objeto.forEach((elemento, index, array) => {
// função
}, thisArg);
// 'thisArg' será o valor usado por 'this' na função, é opcional, assim como receber o index e o arrayExemplo:
var alunos = ["Igor", "João", "Maria"];
alunos.forEach(function (elemento) {
console.log(elemento); // Imprime Igor, João, Maria
});
// Usando função de seta:
alunos.forEach((elemento) => {
console.log(elemento); // Imprime Igor, João, Maria
});
// Usando mais argumentos:
alunos.forEach((elemento, index, array) => {
console.log(elemento, index, array);
});
/* Imprime:
Igor 0 ["Igor", "João", "Maria"]
João 1 ["Igor", "João", "Maria"]
Maria 2 ["Igor", "João", "Maria"]
*/
// A função que forEach recebe pode ser qualquer função, ela é aplicada a todos os elementos da array
var numeros = [1, 2, 3];
function dobro(num, i, arr) {
arr[i] = num * 2;
}
console.log(numeros); // [1, 2, 3]
numeros.forEach(dobro);
console.log(numeros); // [2, 4, 6]Datas são objetos em JS.
var d = new Date(); // Data atual
console.log(d);
// Sat Oct 23 2021 18:26:11 GMT-0300 (Brasilia Standard Time)É possível declarar manualmente. Atenção: valor passado para o mês é um índice numa array que vai de 0 (Jan) a 11 (Dez)!!
Sintaxe:
// Data atual
new Date();
// String de data
new Date("dateString");
// Argumentos
new Date(year, monthIndex, day, hours, minutes, seconds, milliseconds);
// Se apenas um parâmetro for passado, será considerado milissegundos
new Date(milliseconds);
// Timestamp
const d = new Date();
let timestamp = d.getTime();Exemplos:
var d = new Date(2021, 09, 23);
console.log(d);
// Sat Oct 23 2021 00:00:00 GMT-0300 (Brasilia Standard Time)
var d = new Date(0);
// Wed Dec 31 1969 21:00:00 GMT-0300 (Brasilia Standard Time) [epoch]
var d = new Date("12 24 2021 14:00");
// Fri Dec 24 2021 14:00:00 GMT-0300 (Brasilia Standard Time)Datas têm métodos específicos, mais informações:
Palavras reservadas para declarar variáveis.
var: tem escopo global, dentro e fora de blocos (como ifs, por ex), hoisting (declara a variável, mas não atribui valor).
let: tem escopo local, só existe dentro do bloco onde foi declarada (como um if, por ex).
var a = 1;
let b = 2;
console.log(a); // 1
console.log(b); // 2
{
var c = 3;
let d = 4;
}
console.log(c); // 3
console.log(d); // Erro: Uncaught ReferenceError: d is not definedconst: tem escopo local e valor constante.
Não pode ter seu valor reatribuído:
const a = 1;
a = 2; // Erro: Uncaught TypeError: Assignment to constant variable.Não pode ser redeclarada:
const a = 1;
const a = 2; // Erro: Uncaught SyntaxError: Identifier 'a' has already been declaredContudo, pode ser modificada.
- Se for uma array, por exemplo, seu conteúdo pode mudar, mas não pode deixar de ser uma array nem ser atribuída outra array.
const a = [1];
a[0] = 2;
console.log(a); // [2]
const b = [3];
b[1] = 4;
console.log(b); // [3, 4]
const c = [5];
c = [6]; // Erro: Uncaught TypeError: Assignment to constant variable.ATENÇÃO: Funções têm escopo restrito, uma variável declarada com var dentro de uma função não estará disponível fora da função.
Objeto padrão de páginas da web, contém muitas propriedades, como o console.
Por ser o objeto padrão, não é necessário mencioná-lo:
window.console.log("hello, js"); // hello, js
console.log("hello, js"); // hello, jsdocument é uma propriedade do objeto window, com ele é possível acessar o DOM.
As tags head e body, filhas de html, são objetos que podem ser acessados como uma propriedade de document:
document.head e document.body
- Usando um id: document.getElementById
- Usando uma class: document.getElementsByClassName
- Usando a tag html: document.getElementsByTagName
Também é possível usar os seletores CSS:
- .querySelector("#id")
- .querySelector(".class")
- .querySelector("name")
- ...
Obter e modificar o conteúdo de um elemento:
- .innerHTML: recebe html e interpreta, retorna o conteúdo total, incluindo as tags.
- .innerText: recebe texto simples, retorna somente o texto visível que a tag contém.
- .textContent: recebe texto simples, retorna todo o texto que a tag contém, mesmo que algo esteja sendo escondido da visualização por meio de CSS, porém sem as tags.
span {
display: none;
}<p class="paragrafoTeste">paragrafo teste <span>texto oculto com css</span></p>let p = document.querySelector(".paragrafoTeste");
console.log(p.innerHTML); // retorna: "paragrafo teste <span>texto oculto com css</span>"
console.log(p.textContent); // retorna: "paragrafo teste texto oculto com css"
console.log(p.innerText); // retorna: "paragrafo teste"Modificando atributos clássicos (ex: classes, style, etc):
- Classes: .className
let p = document.querySelector(".paragrafoTeste");
p.className = "newClassName";- Style: .style
let p = document.querySelector(".paragrafoTeste");
p.style = "color: blue";Modificando atributos personalizados:
<p meuAtt="nomeDoMeuAtributo">Texto</p>let p = document.querySelector(".paragrafoTeste");
p.getAttribute("meuAtt"); // retorna: "nomeDoMeuAtributo"
p.setAttribute("meuAtt", "novoNome");.setAttribute também serve para criar um novo atributo personalizado.
Eventos podem ser adicionado a tags como atributos. Eles podem modificar elementos,
chamar funções, aplicar estilos, etc.
Exemplos de eventos:
- onclick="funcao" : Executa uma função quando clicado.
- onchange="funcao" : Colocado em uma tag input, executa quando o campo de texto perde o foco.
- oninput="funcao" : Colocado em uma tag input, executa conforme o texto é digitado.
- onload="funcao" : Colocado na tag body, executa depois que toda a página for carregada.
- onmouseover="funcao" : Executa quando o cursor passar sobre o elemento
- onmouseout="funcao" : Executa quando o cursor deixar o elemento.
Também é possível alterar os efeitos dos eventos no próprio JS, basta acessar o evento por meio de notação de ponto:
let div = document.querySelector(".divTeste");
div.onclick = novaFuncao; // em que 'novaFuncao' é o nome de outra função a ser executada
function novaFuncao() { ... }Além disso, é possível adicionar um evento utilizando um Event Listener, com .addEventListener:
Sintaxe:
element.addEventListener("<event>", "<function>"); // nome dos eventos sem 'on', ex: 'onclick' -> 'click', 'onmouseover' -> 'mouseover'...Por exemplo:
let div = document.querySelector(".divTeste");
div.addEventListener("click", novaFuncao);
function novaFuncao() { ... }- Criando na tag html:
A propriedade this retorna o objeto window, não a tag.
<p onclick="f1()">Clique Aqui 1</p>function f1() {
console.log("teste1");
console.log(this); // Imprime o objeto window
}Nenhum argumento é enviado para a função, se não for explicitamente colocado.
function f1(e) {
console.log("teste1");
console.log(e); // undefined
}Para acessar a tag no js, é possível passar this como um argumento da função na tag, porém o parâmetro recebido pela função não pode se chamar this.
<p onclick="f1(this)">Clique Aqui 1</p>function f1(tag) {
console.log("teste1");
console.log(this); // Imprime o objeto window
console.log(tag); // Imprime a tag html
}- Criando com .addEventListener:
A propriedade this retorna a tag que teve um evento adicionado.
<p id="ref">Clique Aqui 2</p>function f2() {
console.log("teste2");
console.log(this); // Imprime a tag p com id ref
}
window.onload = () => {
let p = document.querySelector("#ref");
p.addEventListener("click", f2);
};O método .addEventListener envia como argumento o evento de clique PointerEvent, que é um objeto com inúmeras informações sobre o evento, como a tag que foi clicada:
function f2(e) {
console.log("teste2");
console.log(e); // PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
console.log(e.target); // Imprime a tag que foi clicada
}Para acessar os elementos pai ou filhos a partir de um elemento:
- .parentElement : acessa o elemento pai
- .children : acessa os elementos filhos
Biblioteca de funções matemáticas.
- Math.PI : retorna o número pi
- Math.E : retorna o número e
- Math.sqrt(<value>) : retorna a raiz quadrada de <value>
- Math.pow(<val1>,<val2>) : retorna a potência <val1>^<val2>
- Math.random : retorna um número aleatório entre 0 e 0.99...
- Math.round(<value>) : retorna <value> arredondado para o maior ou menor inteiro mais próximo
- Math.floor(<value>) : retorna <value> arredondado para o maior inteiro mais próximo
- Math.ceil(<value>) : retorna <value> arredondado para o menor inteiro mais próximo
- Math.trunc(<value>) : retorna <value> arredondando para o inteiro mais próximo na direção do zero
Math.trunc() arredonda na direção do zero, ou seja, se o número for positivo, ele arredonda para menos, se for negativo, ele arredonda para mais. Enquanto Math.floor() sempre arredonda para menos e Math.ceil() sempre arredonda para mais. Ou seja, Math.trunc() funciona como Math.floor() para números positivos e como Math.ceil() para números negativos. Além disso, nenhuma dessas funções leva em conta o valor não inteiro do número.
Exemplos:
-> 1.2
Math.trunc(1.2) retorna 1
Math.floor(1.2) retorna 1
Math.ceil(1.2) retorna 2
-> -1.2
Math.trunc(1.2) retorna -1
Math.floor(1.2) retorna -2
Math.ceil(1.2) retorna -1
É a representação de um objeto: JavaScript Object Notation.
JSON possui dois métodos:
- JSON.parse : pega uma string e transforma em um objeto JSON.
- JSON.stringfy : pega um objeto JSON e transforma em uma string.
let person = {
name: "Vitor",
age: "26",
};
console.log(JSON.stringify(person)); // string: {"name":"Vitor","age":"26"}
let cat = '{"name": "Tom", "sound": "meow"}';
console.log(JSON.parse(cat)); // objeto: {name: 'Tom', sound: 'meow'}localStorage é uma propriedade de window, ele permite a persistência de dados por meio dos métodos:
- .setItem() : salva um dado na memória -> localStorage.setItem("name", "Vitor")
- .getItem() : recupera um dado da memória -> localStorage.getItem("name")
- .removeItem() : deleta um dado da memória -> localStorage.removeItem("name")
Os dados são armazenados conforme o domínio da página, ou seja, não podem ser acessados em páginas diferentes. Por exemplo, dados de um aluno salvos em escola.com não podem ser acessados em faculdade.com.
- Timer: executa uma função uma vez depois de um intervalo de tempo
<name> = setTimeout(<function>, <time>), o tempo deve ser especificado em ms
- Intervalo: executa uma função repetidamente a cada intervalo de tempo
<name> = setInterval(<function>, <time>)
- Parar execução: clearTimeout(<name>) e clearInterval(<name>)
É possível criar atributos personalizado utilizando o método .setAttribute(<attrName>,<attrValue>).
Para atributos com o nome precedido de "data-", é possivel acessar os atributos utilizando el.dataset.<attrName>:
<ul id="list" data-num="5"></ul>const lista = document.querySelector("#list");
console.log(lista.dataset.num); // "5"Por padrão, os controles de vídeo ficam ocultos. Utilizar o atributo controls para mostrá-los.
<video controls src="video.mp4"></video>Atributos:
-> autoplay e muted: reproduzir automaticamente, alguns navegadores só reproduzem automaticamente se o som estiver mutado.
-> loop: reprodução em loop.
-> poster="thumb.png": thumb do vídeo.
-> preload=<auto | metadata | none>: configura como o vídeo deve ser carregado.
É possível criar players com controles personalizados para videos. Ver referência com a lista de métodos e propriedades.
Utilizar a tag iframe para adicionar outras páginas html dentro de uma página html. É útil para adicionar vídeos do YouTube.
Tag audio. É possivel adicionar audios em fallback, caso um formato principal não seja reconhecido (assim como se faz com fontes):
<audio controls>
<source src="./audio1.ogg" type="audio/ogg" />
<source src="./audio2.mp3" type="audio/mpeg" />
</audio>Assim como vídeos, há diversas propriedades e métodos para controle e personalização.
Utilizar canvas para desenhar. A tela de desenho é definida pela tag canvas, que deve possuir um id, width e height. É importante definir a largura e altura no html, para não ter problemas com o posicionamento dos desenhos depois.
Antes de começar a desenhar, é preciso acessar o contexto.
-> Linhas:
<canvas id="canvas" width="500px" height="500px"> </canvas>const canvas = document.querySelector("#canvas");
const context = canvas.getContext("2d");
context.moveTo(2.5, 0);
context.lineTo(250, 250);
context.lineTo(497.5, 0);
context.lineTo(497.5, 497.5);
context.lineTo(2.5, 497.5);
context.lineTo(2.5, 0);
context.lineWidth = 5;
context.strokeStyle = "darkblue";
context.stroke();-> Retângulos:
Os argumentos estão na ordem: (x, y, width, height).
context.fillStyle = "lightskyblue";
context.fillRect(20, 380, 150, 100);
context.strokeRect(330, 380, 150, 100);
context.rect(200, 330, 100, 150);
context.fill();
context.stroke();
context.clearRect(40, 420, 400, 20);-> Path
Para separar as curvas, utilizar context.beginPath().
Após passar uma sequência de pontos, para fechar a curva: context.closePath().
context.beginPath();
context.strokeStyle = "gray";
context.fillStyle = "lightgray";
context.moveTo(25, 75);
context.lineTo(200, 250);
context.lineTo(25, 250);
context.closePath();
context.fill();
context.stroke();-> Circles
Os argumentos estão na ordem: T
context.beginPath();
context.strokeStyle = "black";
context.fillStyle = "lightgray";
const { x_center, y_center, radius, start, end } = {
x_center: 250 + 250 * (2 / 3),
y_center: 250 * (2 / 3),
radius: 25,
start: Math.PI * 0,
end: Math.PI * 2,
};
context.arc(x_center, y_center, radius, start, end);
context.fill();
context.stroke();-> Animação
É possível criar animações utilizando setInterval e as funções de desenho.
-> Imagens
É possível inserir imagens dentro de um canvas, para isso, criar um elemento usando const img = new Image(), definir a fonte da imagem img.src = "./image.png", e adicionar ao canvas com context.drawImg(img, <x>, <y>, <width>, <height>). Para acessar o tamanho da image, pode-se usar img.naturalWidth e img.naturalHeight.
Pode se necessário esperar a página carregar, nesse caso, utilizar o método onload e passar um função que contenha o código que desenha a imagem (nessa função, o elemento de imagem pode ser referenciado com this).
Indicados por :: após um seletor. Permitem funções adicionais no CSS. Mais informações aqui. E aqui.
-> ::first-letter
-> ::first-line
-> ::before
-> ::after
-> ::selection
Selecionam elementos para aplicação de estilos. Mais informações aqui. E aqui.
Indicadas por : após um seletor. Permitem funções adicionais no CSS. Mais informações aqui. E aqui.
Permite a realização de cálculos para serem usados como valores de propriedades. Mais informações aqui.
É possível aplicar transformações aos elementos selecionados utilizando transform. Essa propriedade tem como valor uma função, que vai determinar o tipo de transformação. Exemplos:
-> transform: rotate(45deg)
-> transform: scale(0.25)
-> transform: skew(-15deg, -15deg)
-> transform: translate(-50%, -50%)
Também é possível combinar transformações: transform: rotate(45deg) scale(0.25).
Mais opções consultar aqui.
Nem todos os navegadores são compatíveis com algumas propriedades CSS. Verificar compatibilidade em:
É possível criar variáveis em CSS.
:root {
--size: 200px;
--azul: cornflowerblue;
--margin: 100px;
}
div.square {
width: var(--size);
height: var(--size);
background-color: var(--azul);
margin: var(--margin);
}
div.circle {
width: var(--size);
height: var(--size);
background-color: var(--azul);
margin: var(--margin);
border-radius: 50%;
}Mais informações aqui.
E aqui.
E aqui.
E testes interativos aqui.
Treinar flexbox no Flexbox Froggy.
-> Flex Direction: Determina a direção do eixo principal.
-> Wrap: Determina se os elementos devem ter seu tamanho modificado para caber em uma linha ou se deve ser aplicada uma quebra de linha (preserva o tamanho dos elementos).
-> Flex Flow: Shorthand para o flex direction e wrap.
-> Justify Content: Alinha os itens com relação ao EIXO PRINCIPAL (as linhas).
-> Align Items: Alinha os itens com relação ao EIXO TRANSVERSAL (as linhas).
-> Align Content: Alinha as linhas com relação ao container, nesse caso elas passam a ter apenas o tamanho necessário para conter os itens, em vez de preencher todo o espaço do elemento pai (padrão stretch).
-> Grow/Shrink: Determina como o elemento pode expandir para preencher o espaço restante. Ou encolher para caber no espaço disponível.
-> Ordem: Determina a ordem em que os elementos aparecem. Por padrão vale 0.
-> Align Self: Propriedade aplicada no elemento. Cria uma regra específica para aquele elemento e sobrescreve a regra geral definida no elemento pai. Com isso, é possível, por exemplo, alinhar todos os elementos ao centro (regra geral) e um elemento específico ao topo (regra específica).
-> Template:
- grid-template-rows: 1fr 1fr: duas linhas de mesmo tamanho, que preenchem todo o espaço disponível.
- grid-template-columns: 1fr 2fr 1fr: três colunas, sendo a do meio com o dobro do tamanho das adjacentes. Preenchem todo o espaço disponível.
- grid-template: 1fr fr / 1fr 2fr 1fr: shorthand, com valores para as linhas primeiro, separados por uma barra dos valores para colunas.
É possível alterar o posicionamento dos elementos individualmente utilizando grid-row e grid-colum.
-> Gap:
Define o espaçamento entre os elementos do grid.
- row-gap: 10px: espaçamento entre linhas.
- colum-gap: 20px: espaçamento entre colunas.
- gap: 15px shorthand, aplica o valor para linhas e colunas. Se forem passados dois valores, o primeiro corresponde ao gap das linhas e o segundo, ao das colunas.
-> Justify e Align Items:
justify-items e align-items posicionam os elementos dentro de sua célula do grid.
-> Justify e Align Content:
justify-content e align-content posicionam as linhas e colunas (células) do grid com relação ao elemento pai. Ao alterar uma dessas propriedades, as células deixam de crescer para ocupar todo o espaço disponível e passam a ter apenas o tamanho necessário para conter os elementos que estão em seu interior (perdem o valor padrão stretch).
-> Template Area:
-> Column e Row Start e End:
Para fazer um elemento ocupar mais de uma coluna, utilizar grid-column-start e grid-colum-end passando as referências das células do grid. Essa referência indica o início da célula, então para um elemento cobrir as três primeiras colunas, por exemplo, ele deve receber 1 e 4.
Para linhas, utilizar grid-row-start e grid-row-end.
Quando um elemento já começa em uma posição desejada, pode-se passar apenas onde ele deve terminar. Assim, para indicar apenas a quantidade de células que um elemento deve ocupar, pode-se passar span antes do número de espaços a ocupar. Por exemplo, para ocupar 3 colunas: grid-column-end: span 3 (sem o span ele ocuparia apenas 1 espaço na última coluna).
Para criar uma animação, criar um @keyframe com o nome da animação e definir o estado inicial, com from e o estado final, com to. Em seguida, aplicar a animação a um elemento utilizando a propriedade animation-name e definir a duração com animation-duration.
@keyframes changeColor {
from {
background-color: lightcyan;
color: black;
}
to {
background-color: darkblue;
color: white;
}
}
.animation .square {
animation-name: changeColor;
animation-duration: 5s;
}Além do estado inicial e final, é possível definir estados intermediários utilizando porcentagens:
@keyframes changeColorAndWidth {
0% {
background-color: lightcyan;
color: black;
}
50% {
background-color: purple;
width: 200px;
}
100% {
background-color: darkblue;
color: white;
}
}
.animation .square {
animation-name: changeColorAndWidth;
animation-duration: 5s;
}É possível determinar um delay antes da animação começar, para isso, setar no elemento a propriedade animation-delay passando um valor de tempo.
.animation .square {
animation-name: changeColorAndWidth;
animation-duration: 5s;
animation-delay: 2s;
}Para repetir uma animação, setar no elemento a propriedade animation-iteration-count passando um número de repetições ou infinite.
.animation .square {
animation-name: changeColorAndWidth;
animation-duration: 5s;
animation-iteration-count: infinite;
}É possível determinar a direção da animação utilizando a propriedade animation-direction. Passando o valor reverse por exemplo, a animação começará do estado final e irá para o estado inicial. Já o valor alternate inicia pelo estado inicial, vai para o estado final, porém reinicia a partir do estado final.
.animation .square {
animation-name: changeColorAndWidth;
animation-duration: 3s;
animation-iteration-count: infinite;
animation-direction: alternate;
}Para determinar o estado de uma animação ao carregar a página ou ao terminar a animação, utilizar a propriedade animation-fill-mode.
-> animation-fill-mode: forwards congela no último frame após o término da animação.
.animation .square {
animation-name: changeColorAndWidth;
animation-duration: 3s;
animation-fill-mode: forwards;
}-> animation-fill-mode: backwards mostra o elemento no estado inicial da animação assim que a página é carregada. Só funciona se a propriedade animation-delay estiver determinada.
.animation .square {
animation-name: changeColorAndWidth;
animation-duration: 3s;
animation-delay: 500ms;
animation-fill-mode: backwards;
}-> animation-fill-mode: both combina as duas funções anteriores: inicia o elemento após o carregamento da página com o estado inicial da animação e congela o ultimo frame após o término.
A propriedade animation-timing-function define a velocidade do movimento.
.animation .square:nth-child(1) {
animation-timing-function: linear; /* Velocidade Linear */
}
.animation .square:nth-child(2) {
animation-timing-function: ease; /* Médio no início, muito rápido no meio e lento no final */
}
.animation .square:nth-child(3) {
animation-timing-function: ease-in; /* Lento no início */
}
.animation .square:nth-child(4) {
animation-timing-function: ease-out; /* Lento no final */
}
.animation .square:nth-child(5) {
animation-timing-function: ease-in-out; /* Lento no início e no final */
}É possível passar todos os valores em uma única propriedade: animation.
animation: <name> <duration> <timing-function> <delay> <iteration-count> <direction> <fill-mode>;Sem a definição de uma transição, a aplicação de uma pseudo-classe (:hover, por exemplo) é instantânea. Para alterar esse comportamento, escolher a/as propriedades com transition-property e determinar a duração com transition-duration. Deve-se aplicar as definições de transição no elemento que já está sendo exibido na página (sem a pseudo-classe).
.transition div {
margin: 20px;
transition-property: background-color color border-radius;
transition-duration: 500ms;
}
.transition .square:hover {
background-color: darkblue;
color: white;
border-radius: 50%;
}Quando nenhuma propriedade é escolhida, mas uma duração é determinada, ela é aplicada a todas as propriedades do elemento no momento que a página é carregada.
Para tornar obrigatória a declaração de todas as variáveis dentro do escopo que estão sendo utilizadas, adicionar "use strict" no início do script. Assim, problemas de escopo são evitados. Exemplo: uma variável utilizada dentro de uma função porém não declarada com uma palavra reservada (var, let, const) tem escopo global, pois é declarada no momento do hoisting da função. Ao utilizar o strict mode isso não é mais possível. Da mesma forma que declarar uma variável fora de uma função e depois tentar usá-la dentro da função não funcionará.
this faz referência ao objeto em contexto. Por exemplo, um método dentro de um objeto pode acessar informações do próprio objeto utilizando this e notação de ponto. Com isso, também é possível criar funções genéricas para determinadas classes de objetos que possuam atributos com mesma key. Ex:
function speakGeneric() {
print(this.sound);
console.log(this.sound);
}
const Dog = {
sound: "Woof woof",
speak: speakGeneric,
};
const Cat = {
sound: "Meow meow",
speak: speakGeneric,
};
Dog.speak(); // Woof woof
Cat.speak(); // Meow meowSe a função não tiver um contexto (fora de um objeto, por exemplo), o this será indefinido. Para dar contexto a função, utilizar bind para passar um objeto como argumento que a função irá considerar para o valor de this.
speakGeneric(); // undefined
let function_bind = speakGeneric.bind(Dog);
function_bind(); // Woof woofÉ uma função anônima, porém não pode ser usada com a palavra chave this, arrow functions perdem o contexto mesmo se estiverem dentro do objeto. bind também não funciona. A arrow function entende o this como o objeto global window. Sintaxe:
(parâmetro) => {
//código a ser executado
}Quando uma função é passada como parâmetro para outra função ela é chamada de callback. No exemplo abaixo, as funções hi e bye são callbacks.
function hi() {
console.log("Hi");
}
function bye() {
console.log("Bye");
}
function greetUser(greeting, name) {
greeting();
console.log(name);
}
greetUser(hi, "Vitor"); // Hi Vitor
greetUser(bye, "Vitor"); // Bye VitorFunções callback são úteis quando é preciso se comunicar com um servidor, por exemplo, e esperar uma resposta (execução assíncrona). Esse delay entre requisitar e receber uma informação é simulado no exemplo abaixo com um timeout de 1s:
// (1) Com callback:
let users = ["John", "James", "Joe", "Joseph"];
function addUser(name, callback) {
setTimeout(() => {
users.push(name);
callback();
}, 1000);
}
function listUsers() {
console.log(users);
}
addUser("Vitor", listUsers);
// ['John', 'James', 'Joe', 'Joseph', 'Vitor']Se fosse realizado um fluxo de execução tradicional (síncrono), como no exemplo abaixo, a listagem de usuários não mostraria o usuário recém inserido (Vitor):
// (2) Sem callback:
let users2 = ["John", "James", "Joe", "Joseph"];
function addUser2(name) {
setTimeout(() => {
users2.push(name);
}, 1000);
}
function listUsers2() {
console.log(users2);
}
addUser2("Vitor");
listUsers2();
// ['John', 'James', 'Joe', 'Joseph']São uma maneira mais nova de se usar callback. Uma promise é um objeto que recebe como parâmetro uma função com dois argumentos: resolve e reject, que são funções que devem ser executadas em caso de sucesso ou falha da operação. Ao final da função, a promise deve ser retornada. No momento do uso, para se utilizar o retorno da função (a promise), utilizar .then, que será executada caso a promise tenha terminado executando resolve(). Para capturar erros, utilizar .catch e uma função a ser executada caso a promise tenha terminado executando reject(). Mesmo exemplo anterior, utilizando promises:
// (3) Com promise
let users3 = ["John", "James", "Joe", "Joseph"];
function addUser3(name) {
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
users3.push(name);
let error = false;
if (!error) {
resolve();
} else {
reject({
msg: "(3) Com promise ==> Alguma mensagem de erro! :(",
});
}
}, 1000);
});
return promise;
}
function listUsers3() {
console.log("(3) Com promise");
console.log(users3);
}
addUser3("Vitor")
.then(listUsers3)
.catch((error) => {
console.log(error.msg);
});
// ['John', 'James', 'Joe', 'Joseph', 'Vitor']Uma outra maneira de usar promises.
async precede a definição de uma função e indica que, dentro dessa função, em algum momento será necessário esperar o retorno de uma promise. Isso será indicado pela palavra reservada await. O mesmo exemplo anterior:
let users4 = ["John", "James", "Joe", "Joseph"];
function addUser4(name) {
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
users4.push(name);
let error = false;
if (!error) {
resolve();
} else {
reject({
msg: "(4) Com async await ==> Alguma mensagem de erro! :(",
});
}
}, 1000);
});
return promise;
}
function listUsers4() {
console.log("(4) Com async await");
console.log(users4);
}
async function run() {
try {
await addUser4("Vitor");
listUsers4();
} catch (error) {
console.log(error.msg);
}
}
run();
// ['John', 'James', 'Joe', 'Joseph', 'Vitor']Higher-Order Functions (HOF) são funções que aceitam um função como parâmetro e/ou retornam uma função.
O método filter() recebe uma função callback que deve retornar true/false e cria um novo array com todos os elementos que passaram no teste implementado pela função fornecida (retornaram true). Essa função recebe automaticamente como parâmetros os elementos da array à qual o método está sendo aplicado (e também o índice do elemento e o array inteiro, opcionalmente - mesmo esquema dos parâmetros de forEach).
Por exemplo, dada uma lista de objetos que contém nomes e idades de alunos, filtrar os alunos maiores e menores de 30 anos:
// Criação da lista de objetos
function newStudent(name, age) {
return { name, age };
}
let students = [
newStudent("Mario", 23),
newStudent("José", 45),
newStudent("Marcia", 29),
newStudent("João", 35),
];
// Filtrar alunos menores de 30 anos
let studentsUnder30 = students.filter((student) => {
return student.age < 30;
});
// Filtrar alunos maiores de 30 anos
let studentsOver30 = students.filter((student) => {
return student.age > 30;
});
console.log("Students under 30: ", studentsUnder30);
console.log("Students over 30: ", studentsOver30);O método map() retorna um array porém é mais generalista que filter(). Pode-se criar uma nova array utilizando os dados da array original. Por exemplo, criar uma array com frases descrevendo a idade de cada aluno (mesma lista do exemplo anterior):
let studentsDescription = students.map((student) => {
return `${student.name} is ${student.age} years old`;
});
console.log(studentsDescription);
// ['Mario is 23 years old', 'José is 45 years old', 'Marcia is 29 years old', 'João is 35 years old']Tomar cuidado para não modificar a array original. O parâmetro passado para a função callback é uma referência ao array original, não uma cópia/valor.
O método reduce() executa uma função reducer agregadora (definida pelo usuário) para cada membro do array, resultando num único valor de retorno. Pode ser usado para fazer uma soma, encontrar o maior ou menor valor numa lista, etc. O reducer sempre percorrerá toda a lista e retornará apenas um resultado.
O primeiro argumento passado para o método deve ser a função reducer, que possui dois parâmetros: um acumulador e o item da iteração, o valor retornado a cada iteração é atribuído ao acumulador. O segundo argumento deve ser o valor inicial do acumulador.
let order = [
{ item: "Hamburger", price: 20 },
{ item: "Fries", price: 12 },
{ item: "Coke", price: 9 },
{ item: "Chocolate Cake", price: 16 },
];
let orderTotal = order.reduce((total, item) => {
return total + item.price;
}, 0);
console.log("orderTotal =", orderTotal); // orderTotal = 57Também é possível utilizar reduce() para criar strings:
let orderItems = order.reduce((items, item) => {
return items + " " + item.item;
}, "Order Items:");
console.log(orderItems); // Order Items: Hamburger Fries Coke Chocolate CakeEm JS, quando um objeto (ou array) é atribuído a outra variável, há apenas uma passagem de referência (como se fosse um ponteiro), não é criada uma cópia e atribuída a outra variável. Assim, se alguma propriedade for modificada, haverá alteração no original. Por exemplo:
let objA = { name: "John", age: 5 };
let objB = objA;
objB.age = 10;
console.log(objA.age); // 10
console.log(objB.age); // 10
let arrA = [1, 2, 3];
let arrB = arrA;
arrB[0] = 100;
console.log(arrA[0]); // 100
console.log(arrB[0]); // 100Isso não ocorre com tipos primitivos (strings, numbers, booleans), em que há passagem por valor:
let a = 5;
let b = a;
b = 10;
console.log(a); // 5
console.log(b); // 10Contudo, se um novo objeto/array for atribuído a nova variável (B) não há alteração no original:
let obj_A = { name: "John", age: 5 };
let obj_B = obj_A;
obj_B = { name: "Mary", age: 10 };
console.log(obj_A.age); // 5
console.log(obj_B.age); // 10
let arr_A = [1, 2, 3];
let arr_B = arr_A;
arr_B = [100, 200, 300];
console.log(arr_A); // [1, 2, 3]
console.log(arr_B); // [100, 200, 300]Para contornar a passagem por referência e criar uma cópia:
-> Método slice(): geralmente usado para separar uma parte de um array, quando não é passado nenhum valor, cria uma cópia do array inteiro.
let arrA_2 = [1, 2, 3];
let arrB_2 = arrA_2.slice();
arrB_2[0] = 100;
console.log(arrA_2); // [1, 2, 3]
console.log(arrB_2); // [100, 2, 3]-> [...<arrName>]: spread operator. Copia todos os valores de um array para um novo array, pode-se adicionar novas informações ou não (quando não, apenas uma cópia é criada).
let arrA_3 = [1, 2, 3];
let arrB_3 = [...arrA_3, 4, 5, 6];
arrB_3[0] = 100;
console.log(arrA_3); // [1, 2, 3]
console.log(arrB_3); // [100, 2, 3, 4, 5, 6]-> Objet.assign(<obj1>, <obj2>): adiciona as propriedades do objeto 2 ao objeto 1 e retorna o um objeto combinado. Se o objeto 1 for vario, retorna apenas uma cópia do objeto 2.
let objA_2 = { name: "John", age: 5 };
let objB_2 = Object.assign({ hair: "black" }, objA_2);
objB_2.age = 10;
console.log(objA_2); // {name: 'John', age: 5}
console.log(objB_2); // {hair: 'black', name: 'John', age: 10}-> {...<objName>}: spread operator. Mesmo uso mostrado acima para arrays.
let objA_3 = { name: "John", age: 5 };
let objB_3 = { ...objA_3, hair: "black" };
objB_3.age = 10;
console.log(objA_3); // {name: 'John', age: 5}
console.log(objB_3); // {name: 'John', age: 10, hair: 'black'}Permite unir objetos ou arrays. Atenção com os nomes das keys (devem ser únicos), se houver repetição, prevalecerá apenas o último.
let person = {
name: "John",
age: 25,
};
let contact = {
phoneNumber: "123456789",
email: "john.doe@gmail.com",
};
let personContact = { ...person, ...contact };
console.log(personContact);
// {name: 'John', age: 25, phoneNumber: '123456789', email: 'john.doe@gmail.com'}Utilizado para extrair propriedades de um objeto salvando-as em variáveis com o mesmo nome das keys. A variável que receberá o valor deve ter o mesmo nome da key, caso contrário seu valor será indefinido. É possível utilizar o spread operator em uma desestruturação.
let personInfo = {
name: "John",
age: 25,
phoneNumber: "123456789",
email: "john.doe@gmail.com",
};
let { name, email, number, ...otherInfo } = personInfo;
console.log(name); // John
console.log(email); // john.doe@gmail.com
console.log(number); // undefined
console.log(otherInfo); // {age: 25, phoneNumber: '123456789'}Para arrays o funcionamento é semelhante, porém as variáveis podem ter qualquer nome. O importante é seu posicionamento.
let array = [1, 2, 3];
let [pos0, pos1, pos2] = array;
console.log(pos0); // 1Com fetch() é possível fazer requisições passando endpoints. O retorno é uma Promise. Por exemplo, para obter a conversão de EUR para BRL:
Usando .then() para receber resposta:
let currencyCode = "EUR";
let APIurl = `https://v6.exchangerate-api.com/v6/4d40d8e180e79b77a58e09fc/pair/${currencyCode}/BRL`;
fetch(APIurl)
.then((response) => {
return response.json();
})
.then((responseJSON) => {
let conversion_rate = responseJSON.conversion_rate;
console.log(conversion_rate);
});Usando async await:
let currencyCode = "EUR";
async function getExchangeRate(currencyCode) {
let APIurl = `https://v6.exchangerate-api.com/v6/4d40d8e180e79b77a58e09fc/pair/${currencyCode}/BRL`;
let response = await fetch(APIurl);
let responseJSON = await response.json();
let conversion_rate = responseJSON.conversion_rate;
console.log(conversion_rate);
}
getExchangeRate(currencyCode);Utilizado para tratamento de erros. Quando um erro ocorre, a execução do script é interrompida. Para evitar que isso aconteça, utiliza-se try {} catch {} finally {} para capturar os erros e poder continuar a execução.
Para levantar um erro, utilizar throw new Error(<msg>).
let userName = "";
try {
if (userName === "") {
throw new Error("O nome não pode ser vazio");
}
console.log(userName);
} catch (error) {
console.log(error.message);
} finally {
console.log("Boa noite");
}
// O nome não pode ser vazio
// Boa noite- Behance
- freepik
- streamline icons
- steamline hq
- envato
- unsplash
- flaticon
- pexels
- Material Design Icons
- PNG Egg