Baixe o app para aproveitar ainda mais
Prévia do material em texto
PADRÕES WEB Pós-graduação em Desenvolvimento de Aplicações Web Notas de aula da Unidade III Prof. Marcos Kutova © PUC Minas Virtual. Este documento é de autoria e de propriedade da Pontifícia Universidade Católica de Minas Gerais (PUC Minas) e não pode ser reproduzido ou utilizado para qualquer fim, total ou parcialmente, sem a devida autorização dessa instituição. Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 2 1. JAVASCRIPT • JavaScript é uma linguagem desenvolvida por Brendan Eich (https://brendaneich.com/) na Netscape Communications em 1995. • JavaScript foi criada com o nome Mocha e, logo depois, foi renomeada para LiveScript. O nome JavaScript veio mais tarde como foi uma tentativa de tirar proveito do sucesso da Java para atrair novos programadores. • Em 1996, a JavaScript foi submetida como um padrão à ECMA (www.ecma-international.org/) e passou a ser conhecida como ECMAScript (Padrão ECMA-262) (http://www.ecma-international.org/news/Publication%20of%20ECMA-262%206th%20edition.htm) • O ECMAScript é um padrão e JavaScript pode ser considera uma implementação desse padrão. No entanto, os termos geralmente são usados como sinônimos. • A versão largamente adotada na Web é a 5 (ES5). A versão 6 (ES6) foi publicada em 2015, mas ainda carece de pleno suporte pelos navegadores. • Ainda vai demorar um pouco até que a ES6 tenha suporte pleno nos navegadores. Atualmente, precisamos usar um transcompilador para converter o código ES6 em um código ES5. • Apesar de ser possível se construir aplicações completas (do lado do servidor) usando JavaScript, o uso mais comum da linguagem é no suporte às páginas web. Nesses casos, a trechos em JavaScript são usados para controlar a interação com o usuário, permitindo o acesso aos conteúdos e às formatações dos elementos do documento. • Os códigos JavaScript podem ficar no próprio documento HTML, dentro de elementos do tipo <script> ou podem ficar em arquivos externos e serem incorporados por meio do atributo src desse mesmo elemento. <script> // código JavaScript </script> <script src="arquivo.js"></script> • O elemento <script> pode ficar em qualquer lugar do documento. É comum colocá-lo no cabeçalho do documento (<head>) para efeitos de organização da página. Porém, é também comum vê-lo no fim da página, para que só seja carregado depois que as demais informações (HTML e CSS) tiverem sido carregadas. <html> <head> <title> Olá Mundo </title> <script> function ola() { alert( "Olá mundo!" ); } </script> </head> <body onload="ola();"> <p>Olá mundo em JavaScript</p> </body> </html> Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 3 2. CONSOLE WEB • O console web mostra informações sobre a página atualmente carregada e também oferece uma linha de comando em que é possível executar algumas expressões JavaScript. • Chrome: Cmd+Opt+I (Mac) ou Ctrl+Shift+I (Windows) • Firefox: Cmd+Opt+I (Mac) ou Ctrl+Shitf+I (Windows) • Todo documento é um objeto. O objeto que representa o documento como um todo é o objeto document, que pode ser acessado por meio do console. • Uma forma mais fácil de acessar diretamente um elemento é por meio dos seguintes métodos: • document.getElementById() seleciona um elemento por seu id • document.getElementsByTagName() seleciona vários elementos por seu nome • document.getElementsByClassName() seleciona elementos pelo atributo class • document.querySelector() seleciona um elemento usando um seletor CSS • document.querySelectorAll() seleciona vários elementos usando um seletor CSS • Exemplos: document.getElementById('p1') document.querySelector('#p1') document.querySelectorAll('p') • Existem diversos outros objetos e propriedades do documento (e dos elementos) que são acessíveis por meio do console: document.querySelector('#stats').id document.querySelector('#stats').getAttributeNode('id').value • O comando console.log() é usado para depuração de código: console.log(document.getElementById('stats'); • O modo estrito (colocado no início do código) nos ajuda a escrever códigos JavaScript seguros, isto é, que não aceitem uma sintaxe ruim como o uso de variáveis não declaradas ou a atribuição de valores a propriedades apenas de leitura. use strict; Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 4 3. DECLARAÇÃO DE VARIÁVEIS • JavaScript possui uma sintaxe parecida com Java, apesar da relação entre elas não passar disso. • O código é case-sensitive, isto é, maiúsculas e minúsculas são diferentes. • O sistema de codificação de caracteres é o Unicode. • As instruções são terminadas com ponto e vírgula (;). • Espaços em branco, quebras de linha e tabulações são transformadas em um espaço. • Os comentários podem ser de uma linha ou de várias linhas // comentário de uma linha /* comentários de várias linhas */ • Os nomes das constantes, variáveis e objetos, isto é, os identificadores, devem começar com uma letra, subtraço (_) ou cifrão ($) e consideram a diferença entre maiúsculas e minúsculas • Por convenção, deve-se usar camel-case ou snake-case, identificadores iniciados com um ou dois subtraços (_) são internos às bibliotecas e identificadores iniciados por cifrão ($) são de bibliotecas e frameworks como jQuery, constantes devem usar apenas maiúsculas. nomeDaMinhaVariável camel-case nome_da_minha_variável snake-case • A declaração de variáveis pode ser feita de três formas • Com o termo var (escopo local ou global): var a = 10; • Com o termo let (escopo de bloco; ES6) (ver compatibilidade em http://kangax.github.io/compat-table/es6/) let a = 10; • Por atribuição direta (sempre escopo global; não é uma boa prática): a = 10; • A declaração de constantes é feita com o termo const const MÁXIMO = 99; • Variáveis declaradas, mas sem valor atribuído recebem o valor undefined, que pode ser usado em uma expressão var a; if(a != undefined) console.log('variável a possui valor'); else console.log('variável a não possui valor'); Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 5 • O valor undefined equivale a falso (false), apesar de a expressão undefined==false ser falsa. Assim, o exemplo acima poderia ser apenas: var a; if(a) funcao1(); else funcao2(); • Em expressões matemáticas, undefined equivale a NaN (not a number). NaN é sempre retornado quando uma expressão matemática não pode ser executada porque algum termo não é um número. var a; console.log(a*3); // NaN console.log('puc'*3); // NaN • O uso de variáveis não declaradas dispara a exceção ReferenceError. • O valor nulo (null) também pode ser atribuído a uma variável, equivalendo a zero em expressões numéricas e falso em expressões lógicas. var b=null; console.log(b*3); // 0 if(b) console.log('b equivale a true'); else console.log('b equivale a false'); • Até a ES5, o escopo de uma variável podia ser apenas local ou global. • O escopo local é adotado quando a variável é declarada dentro de uma função, isto é, a variável só é vista por aquela função. function f() { var a = 3; console.log(a); } f(); // 3 console.log(a) // ReferenceError • Quando declarada fora da função, o escopo da variável é global e ela pode ser vista por todo o código. var a; function f() { a = 3; console.log(a); } f(); // 3 console.log(a) // 3 Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 6 • A ES6 introduziu o escopo de bloco por meio da declaração com let. Nesse caso, a variável existe apenas dentro do bloco declarado.if(true) { var a = 3; let b = 4; } console.log(a); // 3 console.log(b); // ReferenceError • JavaScript possui uma característica que é chamada de variable hoisting. Isso significa que todas as variáveis declaradas com o termo var serão elevadas ao nível do topo do escopo (ex.: função) e não dependem do local onde foram declaradas. console.log(a); // undefined console.log(b); // ReferenceError var a = 3; • O hoisting usa apenas a declaração da variável e não o seu valor. • Isso não acontece quando a variável é declarada com let. • Da mesma forma como existe um objeto global document para representar todo o documento, existe um objeto window para representar todo o escopo global. var a = 3; console.log(window.a); // 3 Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 7 4. TIPOS DE DADOS • JavaScript oferece seis tipos primitivos e objetos. • Os tipos primitivos são: • boolean true; false • number 20; 30.5; -17.2 • string "carro"; "mundo" • Nulo null • Não definido undefined • Símbolo símbolo único e constante (ES6) • JavaScript é uma linguagem fracamente tipada. Assim, o tipo de uma variável é determinado automaticamente a partir do valor atribuído a ela; e pode ser alterado; var a = 3; console.log(typeof a); // "number" a = "mundo"; console.log(typeof a); // "string" • JavaScript também faz uma conversão automática de tipo (coerção) var r = "A nota final é "; console.log(r+100); // "A nota final é 100" • É importante tomar cuidado com a conversão automática console.log(”12”+3); // ”123” console.log(”12”-3); // 9 • A conversão de strings em números pode ser feita por meio dos métodos parseInt() e parseFloat() do objeto global (window). • Alternativamente, pode ser feita por meio do operador unário, preferencialmente com o termo entre parênteses para assegurar a legibilidade. console.log("12"+3+"4"); // "1234" console.log((+"12")+3+"4"); // "154" console.log((+"12")+3+(+"4")); // 19 • As strings podem ser criadas com aspas simples ou aspas duplas. A propriedade length oferece o tamanho da string. var nome = 'Ana Maria'; var cargo = "Gerente"; console.log(cargo.length); // 7 Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 8 • Alguns caracteres especiais usados nas strings: • \0 Null • \n Nova linha • \t Tabulação • \' Aspas simples • \" Aspas duplas • \\ Barra invertida • \XXX Caráter com a codificação latin-1 (ex.: '\251' = '©') • \xXX Caráter em hexadecimal com a codificação latin-1 (ex.: '\x41' = 'A') • \uXXXX Caráter Unicode de 4 hexadecimais (ex.: '\u2713' = '✓') • É possível usar mais de uma linha para uma string, por meio da barra invertida var nome = "José Maria \ Ribeiro \ da Silva"; console.log(nome); // "José Maria Ribeiro da Silva" • A ES6 oferece a possibilidade de máscaras para strings (template literals) var nome = "José Maria"; console.log(`Olá ${nome}!`); // "Olá José Maria!" • Alguns dos métodos disponíveis para strings são: • indexOf(), lastIndexOf() retorna a primeira ou a última posição de uma substring. • split() cria um vetor de substrings a partir de um separador • toLowerCase(), toUpperCase() converte a caixa das letras da string. • trim() remove espaços em branco no início e fim da string. • Os vetores são grupos de elementos que podem ser do mesmo tipo ou de tipos diferentes. var nomes=["Ana", "Maria", "Pedro"]; var dados=["Ana Maria", 35, , 730.50, false]; // string, number, undefined, //number, boolean • O acesso a um elemento do vetor é feito por meio do seu índice, baseado em 0. console.log(nomes[2]); // "Pedro" Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 9 • Objetos em JavaScript são pares de nomes e valores (não há a necessidade de se criar classes). O acesso a um valor pode ser feito pelo operador ponto ou por colchetes. var cliente = { nome: 'José', sobrenome: 'Silva', idade: 35 }; console.log(cliente.nome+" "+cliente.sobrenome); // "José Silva" console.log(cliente.idade); // 35 console.log(cliente["nome"]); // "José" var campo = "sobrenome"; console.log(cliente[campo]); // "Silva" • Os valores podem ser outros objetos, vetores ou mesmo funções var cliente = { nome: "José", sobrenome: "Silva", endereço: { rua: "Av. Rio Branco", número: 15, cidade: "Belo Horizonte", estado: "MG" }, contatos: [ "(31)3232-1515", "jsilva@gmail.com" ], nomeCompleto: function() { return this.nome+" "+this.sobrenome; } }; console.log(cliente.nomeCompleto()); // "José Silva" Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 10 5. OPERADORES • Os operadores em JavaScript são também semelhantes aos operadores em Java. • Operadores de atribuição • x += y Equivale a x = x + y • x -= y Equivale a x = x – y • x *= y Equivale a x = x * y • x /= y Equivale a x = x / y • x %= y Equivale a x = x % y • x <<= y Equivale a x = x << y • x >>= y Equivale a x = x >> y • x >>>= y Equivale a x = x >>> y • x &= y Equivale a x = x & y • x ^= y Equivale a x = x ^ y • x |= y Equivale a x = x | y • Operadores de comparação • x == y Igual • x != y Diferente • x === y Estritamente igual (mesmo valor e mesmo tipo) • x !== y Estritamente diferente (valor ou tipo diferentes) • x > y Maior que • x >= y Maior ou igual que • x < y Menor que • x <= y Menor ou igual que • Operadores aritméticos • x + y Adição • x - y Subtração • x * y Multiplicação • x / y Divisão • x % y Módulo (resto da divisão) • --x ou x-- Decremento (prefixado ou posfixado) • ++x ou x++ Incremento (prefixado ou posfixado) • -x Negação unária • +x Adição unária (também converte um operando em número) • x ** y Potenciação (ES7) Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 11 • Operadores bit a bit • x & y AND bit a bit • x | y OR bit a bit • x ^ y XOR (exclusive or) bit a bit • ~x NOT bit a bit • x << y Deslocamento à esquerda (preenchimento com zeros) • x >> y Deslocamento à direita (preenchimento com bits mais significativos, isto é, com propagação de sinal) • x >>> y Deslocamento à direita (preenchimento com zeros) • Operadores lógicos • x && y AND (conjunção) • x || y OR (disjunção) • !x NOT (negação) • Operadores especiais • "x" + "y" Concatenação de strings • c ? x : y Operador condicional (se c, então x, senão y) • , Operador vírgula para laço for for(i=0,j=9; i<=9; i++, j--) • typeof x Tipo de dado • void(x) Avaliação de expressão sem valor de retorno javascript:void(document.form.submit()) • Precedências dos operadores (Muitos operadores dessa lista são de objetos e não foram tratados nesta seção, mas foram mantidos na lista, pois também seguem a ordem de precedência). • membro . [] • chamada / criação de instância () new • negação / incremento ! ~ - + ++ -- typeof void delete • multiplicação / divisão * / % • adição / subtração + - • deslocamento bit a bit << >> >>> • relacional < <= > >= in instanceof • igualdade == != === !== • E bit a bit & • OU exclusivo bit a bit ^ • OU bit a bit | • E lógico && • OU lógico || • condicional ?: • atribuição = += -= *= /= %= <<= >>= >>>= &= ^= |= • vírgula , Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distânciaem Desenvolvimento de Aplicações Web 12 6. CONTROLE DO FLUXO DE EXECUÇÃO • Um bloco é declarado por meio de um par de chaves. { instruções; ... } • A partir da ES6, um bloco passa a ter um escopo próprio. var a = 1; { let a = 2; console.log(a); // 2 } console.log(a); // 1 • Um bloco condicional é feito por meio da declaração if...else. if(condição) { instruções; ... } else { instruções; ... } • É possível encadear estruturas condicionais. if(condição) { instruções; ... } else if(condição2) { instruções; ... } else { instruções; ... } • A declaração switch permite criar uma estrutura de escolha. switch(expressão) { case valor_1: instruções; [break;] case valor_2: instruções; [break;] ... default: instruções; } Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 13 • A declaração for é usada para laços baseados no incremento de uma variável for([expressãoInicial]; [condição]; [incremento]) { instruções; } • A declaração do...while é usada para laços que devem ser executados pelo menos uma vez do { instruções; } while(condição); • A declaração while avaliação a condição antes de qualquer execução while(condição) { instruções; } • Uma declaração pode ter um rótulo (label) a ser referenciado em outro ponto do programa. Os rótulos são particularmente úteis para identificar as repetições. label: declaração; • A instrução break é usada para terminar um laço ou uma estrutura de escolha (switch). Essa instrução pode identificar um rótulo específico. for(let a=1; a<=100; a++) { let b = a-1; while(b>1) { if(a%b==0) break; b--; } if(b==1) console.log(a+" é primo"); } • A instrução continue é usada para iniciar a próxima iteração de um laço. Essa instrução pode identificar um rótulo específico. primo: for(let a=1;a<=100;a++) { let b = a-1; while(b>1) { if(a%b==0) continue primo; b--; } console.log(a+" é primo"); } • A declaração for...in é usada para percorrer as propriedades de um objeto for(variável in objeto) { instruções; } Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 14 • A declaração for...of (ES6) é usada para percorrer os elementos de um vetor. for(variável of vetor) { instruções; } • Para se evitar a interrupção de um script, é importante colocar as instruções que podem provocar erros dentro do bloco de uma declaração try...catch. try { instruções; ... } catch(e) { console.log(e); instruções; ... } • É possível se disparar exceções do usuário por meio da instrução throw. throw expressão; • Exemplo: function nomeDoMês(m){ m--; // o vetor é de 0 a 11 var meses = "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" ]; if(m>=0 && m<12) return meses[m]; else throw "Mês inválido! "; } var mês = 15; try { console.log(nomeDoMês(mês)); } catch(e) { console.log(e); } • A cláusula finally é executada independentemente de ocorrer ou não algum erro. try { instruções; ... } catch(e) { console.log(e); instruções; ... } finally { instruções; } Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 15 7. FUNÇÕES • Uma declaração de função em JavaScript possui três componentes: o nome da função, a lista de argumentos que a função recebe e as instruções a serem executadas. function soma(x,y) { return x+y; } console.log(soma(5,2)); // 7 ARGUMENTOS • Um argumento de tipo primitivo é passado para a função por cópia do seu valor, isto é, o argumento é uma cópia do valor original e, portanto, qualquer alteração que sofra não afeta o valor original. function troca(x,y) { var aux = x; x = y; y = aux; console.log(x,y); return; } var a=1, b=2; troca(a,b); // 2 1 console.log(a,b); // 1 2 • Quando o argumento é um objeto, ele é passado por referência, isto é, a função recebe apenas uma referência para o objeto original. Assim, qualquer alteração que o objeto sofra na função será mantido após a sua execução. function incrementa(x) { x.num++; console.log(x.num); return; } var x = { num: 0 }; incrementa(x); // 1 console.log(x.num); // 1 • Funções declaradas dessa forma passam a fazer parte do objeto global, isto é, do objeto window. EXPRESSÕES DE FUNÇÕES • Uma expressão, em programação, é uma combinação de valores, operadores e funções que é interpretada e retorna um valor. • O valor de retorno pode ser de qualquer tipo (de acordo com a linguagem de programação) e armazenado em uma variável. São exemplos de expressões: • 3 • 10 + 5*1.5 • a >= 5*b • "João" • [ 3, 2, 5 ] • { nome: "João", idade: 35 } • soma( 3, 5 ) Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 16 • Uma função também pode ser uma expressão e, assim, armazenada em uma variável: var soma = function(x,y) { return x+y; } console.log(soma(5,2)); // 7 • A função acima é chamada de anônima, porque nenhum nome foi dado à ela. É possível (e recomendável) dar nomes às funções var f = function fatorial(n) { if(n<=1) return 1; return n*fatorial(n-1); } console.log(f(5)); // 120 console.log(f.name); // fatorial • O uso dos nomes é útil para as operações de depuração, para clareza do código e também em funções recursivas. • O seguinte código gera um erro de execução: var a = function(n) { if(n<=1) return 1; return(n*a(n-1)); } console.log(a(4)); // 24 b = a; a = null; console.log(b(5)); // TypeError: a is not a function • Mas esse funciona perfeitamente: var a = function fatorial(n) { if(n<=1) return 1; return(n*fatorial(n-1)); } console.log(a(4)); // 24 b = a; a = null; console.log(b(5)); // 120 • Essa expressão é semelhante à anterior e também pode ser var f = function fat(n) { if(n<=1) return 1; return n*fat(n-1); } Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 17 IIFE (Immediately-Invoked Function Expression) • Além de ser armazenada em uma variável, uma expressão de função pode ser passada como parâmetro console.log( function(x) { return x*x; } ); • O resultado apresentado por esse código, porém, não é um valor específico, mas a própria função. Para que a função seja executada e um valor retornado, ela precisa ser invocada. Essa invocação é feita por meio de (). console.log( function(x) { return x*x; }(5) ); • Essa estrutura é chamada de IIFE (Immediately-Invoked Function Expression) ou expressão de função imediatamente invocada. Observe a diferença entre os dois exemplos. O segundo é uma IIFE e apenas o resultado da operação é armazenado. var a = function(x) { return x*x }; var b = function(x) { return x*x }(3); console.log(a); // function ... console.log(b); // 9 • Existe uma situação particularmente interessante de uso de IIFEs que é quando precisamos executar algumas operações iniciais e não queremos deixar “rastros” dessas operações. • Este exemplo executa uma simples operação, mas deixa dados e variáveis acessíveis por meio do escopo global: var nome = "José"; var sobrenome = "Silva"; console.log( "Olá "+nome+" "+sobrenome+"."); console.log(nome); // "José" • Ao colocarmos o código dentro de uma IIFE, as variáveis nela criadas ficam limitadas ao seu escopo e, assim, fora do escopo global: (function() { var nome = "José"; var sobrenome = "Silva"; console.log( "Olá "+nome+" "+sobrenome+".");}()); console.log(nome); // ReferenceError: nome is not defined • É importante observar que a IIFE foi encaixada dentro de ()s, pois o parser do navegador não aceita uma função anônima ser declarada sem ao menos ser atribuída a uma variável. Os ()s tem sido adotados como principal forma de “contornar” esse “problema”, mas várias alternativas poderiam ter sido usadas como, por exemplo: (function() { /*código*/ })(); +function() { /*código*/ }(); !function() { /*código*/ }(); new function() { /*código*/ }; Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 18 CLOSURES • Uma função pode conter variáveis e outras funções (internas), pois uma função em JavaScript é, antes de tudo, um objeto. var contador = function() { var n = 0; function incrementa() { return ++n; } return incrementa; }(); console.log(contador()); // 1 console.log(contador()); // 2 console.log(contador()); // 3 • Nesse exemplo, a função anônima é executa como IIFE e retorna a subfunção incrementa(). Essa subfunção pode ser acessada por meio da invocação de contador() e tem acesso à variável interna n da função anônima. No entanto, não há como se obter acesso direto a essa variável. • O acesso de uma função interna ao escopo da função pai, mesmo quando esse escopo já foi “fechado” é chamado de closure. • O exemplo de closure abaixo, de Ben Alman (http://benalman.com/news/2010/11/immediately- invoked-function-expression/), é um dos mais clássicos. Nesse exemplo, o retorno é um objeto com diversas funções internas. var counter = (function() { var i = 0; return { get: function() { return i; }, set: function(val) { i = val; }, increment: function() { return ++i; } }; }()); console.log(counter.get()); // 0 counter.set(3); console.log(counter.get()); // 3 counter.increment() console.log(counter.get()); // 4 counter.increment(); console.log(counter.get()); // 5 Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 19 8. VETORES • Um vetor é um conjunto ordenado de valores cujo acesso é feito por meio de um índice. Em JavaScript, os elementos do vetor podem ser de tipos diferentes. • Um vetor pode ser declarado e inicializado por meio de uma literal de vetores ou por meio do objeto Array. var frutas1 = new Array( 'laranja', 'maçã', 'pêra', 'banana' ); var frutas2 = [ 'laranja', 'maçã', 'pêra', 'banana' ]; • Uma alternativa à inicialização do vetor é criá-lo vazio e, em seguida, adicionar novos elementos. var frutas = []; // ou: var frutas = new Array(); frutas[0] = 'laranja'; frutas[1] = 'maçã'; frutas[2] = 'pêra'; frutas[3] = 'banana'; console.log(frutas); // ["laranja", "maçã", "pêra", "banana"] • O uso do construtor do objeto Array permite se criar um vetor de tamanho pré-determinado, mas com cada item equivalendo a undefined. var frutas = new Array(4); frutas[0] = 'laranja'; frutas[1] = 'maçã'; frutas[2] = 'pêra'; frutas[3] = 'banana'; • Em qualquer uma das formas, é possível se especificar um valor além do tamanho do arquivo. Nesse caso, os elementos intermediários serão criados com o valor undefined. frutas[10] = 'uva'; console.log(frutas.join(', '); // laranja, maçã, pêra, banana, , , , , , , uva • O método join usa concatena todos os elementos de um vetor em uma string, separando-os por meio do parâmetro passado no método. • A iteração pelo vetor pode ser feita por meio da propriedade length do vetor que indica a quantidade de elementos que possui e de um laço for. var frutas = [ 'laranja', 'maçã', 'pêra', 'banana' ]; for(var i=0; i<frutas.length; i++ ) { console.log(frutas[i]); } • Uma alternativa é o uso do laço especial for...of. var frutas = [ 'laranja', 'maçã', 'pêra', 'banana' ]; for(var fruta of frutas) { console.log(fruta); } Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 20 • A interação por meio do laço for...in é mais adequada para objetos. Como um vetor é um objeto (e assim como as funções), também pode receber propriedades. Usar um laço for...in para iterar por um vetor pode gerar o seguinte erro: var frutas = [ 'laranja', 'maçã', 'pêra', 'banana' ]; frutas.melhor = 'pêra'; for(var k in frutas) { console.log(k+': '+frutas[k]); // “melhor: morango” fará parte da lista } • Outra alternativa é o uso do método forEach, que permite executar uma função para cada item do vetor. var frutas = [ 'laranja', 'maçã', 'pêra', 'banana' ]; frutas.forEach(function(i) { console.log(i); }); MÉTODOS DO OBJETO ARRAY • concat() – une dois vetores. var v1 = [1,2,3]; var v2 = [4,5,6]; v1 = v1.concat(v2); console.log(v1); // [1, 2, 3, 4, 5, 6] • join(separador) – junta todos os elementos em uma string. var v1 = [1,2,3]; console.log(v1.join(',')); // 1,2,3 • sort() – ordena os elementos no vetor. var v1 = [3,1,4,2]; v1.sort(); console.log(v1.join(',')); // 1,2,3,4 • sort(fn) – ordena os elementos no vetor, a partir de uma ordem definida por uma função de comparação. var v1 = [ 'laranja', 'maçã', 'uva', 'banana' ]; v1.sort(function(a,b){ return a.length-b.length; // ordena por tamanho da string }); console.log(v1.join(',')); // uva,maçã,banana,laranja • reverse() – inverte a ordem dos elementos no vetor. var v1 = [1,2,3]; v1.reverse(); console.log(v1.join(',')); // 3,2,1 • slice(i,j) – retorna uma faixa de elementos do vetor. var v1 = [1,2,3,4,5,6]; console.log(v1.slice(3,5)); // 4, 5 (de i a j-1) Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 21 • splice(i,n,e1,e2,...) – remove uma faixa de elementos do vetor e, opcionalmente, acrescenta novos elementos. var v1 = [1,2,3,4,5,6]; v1.splice(2,2,7); console.log(v1.join(',')); // 1,2,7,5,6 • indexOf(e,fe) – procura pelo elemento e a partir de fe e retorna a sua primeira ocorrência. var v1 = [1,2,3,2]; console.log(v1.indexOf(2)); // 1 console.log(v1.indexOf(2,2)); // 3 • lastIndexOf(e,fe) – procura o elemento e, do fim para o início, a partir de fe. var v1 = [1,2,3,2]; console.log(v1.lastIndexOf(2)); // 3 console.log(v1.lastIndexOf(2,2)); // 1 • push() – adiciona um ou mais elementos ao fim do vetor e retorna o seu novo tamanho. var v1 = [1,2,3]; v1.push(4); console.log(v1.join(',')); // 1,2,3,4 • pop() – remove o último elemento do vetor e o retorna. var v1 = [1,2,3]; console.log(v1.pop()); // 3 console.log(v1.join(',')); // 1,2 • unshift() – adiciona um ou mais elementos ao início do vetor e retorna o seu novo tamanho. var v1 = [1,2,3]; v1.unshift(4,5); console.log(v1.join(',')); // 4,5,1,2,3 • shift() – remove o primeiro elemento do vetor e o retorna var v1 = [1,2,3]; console.log(v1.shift()); // 1 console.log(v1.join(',')); // 2,3 • forEach(fn) – executa uma função para cada elemento do vetor. var v1 = [1,2,3,4]; v1.forEach(function(e){ console.log(e); }); • map(fn) – cria um novo vetor a partir do valor de retorno de uma função para cada elemento. var v1 = [1,2,3,4]; var v2 = v1.map(function(e){ return e*e; }); console.log(v2); • filter(fn) – cria um novo vetor com os elementos que atendam ao filtro. var v1 = [1,2,3,4]; var v2 = v1.filter(function(e){ return e%2==0; }); console.log(v2); Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 22 • every(fn) – retorna verdadeiro se todos os elementos atenderem ao filtro. var v1 = [1,2,3,4]; if( v1.every(function(e){ return typeof e==='number'; }) ) console.log('só números'); • some(fn) – retorna verdadeiro se pelo menos um elemento atender ao filtro. var v1 = [1,2,3,4]; if( v1.some(function(e){return typeof e==='number'; }) ) console.log('pelo menos 1 número'); • reduce(fn) – aplica recursivamente uma função a dois valores do vetor e os substitui pelo resultado, até que sobre apenas um único valor. var v1 = [1,2,3,4]; var soma = v1.reduce(function(a,b){return a+b;}); console.log(soma); // 10 • reduceRight(fn) – mesmo operação de reduce(), mas começando pelo último elemento. var v1 = [1,2,3,4]; var pot = v1.reduceRight(function(a,b){return Math.pow(a,b);}); console.log(pot); // 4096 Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 23 9. OBJETOS • Apesar de JavaScript ser uma linguagem orientada a objetos, ela é ligeiramente diferente da orientação a objetos clássica. A orientação a objetos em JavaScript é baseada em protótipos de objetos e não nas classes tradicionais. • Um objeto em JavaScript é um conjunto de associações entre nomes (ou propriedades) e valores. var pessoa = { nome: 'João', sobrenome: 'Silva' } • Os valores assumidos em cada propriedade podem ser de qualquer tipo em JavaScript, inclusive funções. var pessoa = { nome: 'João', sobrenome: 'Silva', casado: false, contatos: [ '(31)3232-1515', 'jsilva@gmail.com' ], nomeCompleto: function() { return this.nome+' '+this.sobrenome; } } • O acesso a uma propriedade de um objeto pode ser feito de duas formas: por meio do operador ponto (.) ou por meio dos colchetes ([]). Essa segunda forma é interessante quando a escolha do campo é dinâmica, isto é, baseada em uma variável. console.log( pessoa.nome ); // João console.log( pessoa['nome'] ); // João var campo = 'nome'; console.log( pessoa[campo] ); // João • O objeto criado pode também ser alterado por meio da adição de novas propriedades. Para isso, basta atribuir um valor a uma nova propriedade. pessoa.endereco = 'Av. Brasil, 1100'; • De forma análoga, uma propriedade pode ser excluída por meio da instrução delete delete pessoa.endereco; • A forma mais simples de percorrer as propriedades de um objeto é por meio de um laço for...in for(prop in pessoa) console.log(prop+': '+pessoa[prop]); • Também é possível obter a lista de propriedades de um objeto, usando-o como parâmetro do método Object.keys() var props = Object.keys(pessoa); Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 24 LITERAL DE OBJETO E FUNÇÃO CONSTRUTORA • A declaração abaixo cria um objeto por meio de uma literal de objeto. O termo literal, em computação, significa um valor fixo no código fonte que pode ser atribuído a uma variável ou constante. var pessoa = { nome: 'João', sobrenome: 'Silva' } • Internamente, cada objeto pode fazer uma referência própria por meio do termo this. Se feita fora do objeto, essa referência será ao objeto ancestral ou ao objeto global window. var pessoa = { nome: 'João', sobrenome: 'Silva', nomeCompleto: function() { return this.nome+' '+this.sobrenome; } } • Uma literal de objeto pode ser passada como parâmetro para funções ou retornada por elas. • Um objeto vazio pode tanto ser criado por meio de uma literal de objeto vazia. var pessoa = { }; // ou: var pessoa = new Object(); pessoa.nome = 'João'; pessoa.sobrenome = 'Silva'; • Outra forma de criação de objetos é a função construtora, que funciona de forma parecida aos construtores em classes tradicionais. • Por convenção, as funções construtoras começam com letra maiúscula, para se diferenciarem das outras funções. • Uma função construtora é usada junto com o termo new que cria uma nova instância do objeto e associa o termo this a ela. function Pessoa(n,s) { this.nome = n; this.sobrenome = s; this.nomeCompleto = function() { return this.nome+' '+this.sobrenome; } } var joao = new Pessoa('João', 'Silva'); console.log(joao.nomeCompleto()); // João Silva var maria = new Pessoa('Maria', 'Oliveira'); console.log(maria.nomeCompleto()); // Maria Oliveira Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 25 • Não é raro encontrarmos situações em que o termo this passa a referenciar outro objeto e isso gerar erros difíceis de serem localizados. No exemplo abaixo, o termo this dentro da função da propriedade maiorDeIdade faz uma referência ao objeto joao.características e não ao objeto joao. function Pessoa(nome,sobrenome,idade) { this.nome = nome; this.sobrenome = sobrenome; this.idade = idade; this.características = { maiorDeIdade: function() { if(this.idade >= 18) return true; else return false; } } } var joao = new Pessoa('João', 'Silva', 21); console.log(joao.características.maiorDeIdade()); // false • Uma prática recomendada para evitar esse tipo de problema é o uso de uma referência explícita (self) ao objeto desejado. Como ela não existirá no sub-objeto, então o objeto ancestral será consultado. function Pessoa(nome,sobrenome,idade) { var self = this; self.nome = nome; self.sobrenome = sobrenome; self.idade = idade; self.características = { maiorDeIdade: function() { if(self.idade >= 18) return true; else return false; } } } var joao = new Pessoa('João', 'Silva', 21); console.log(joao.características.maiorDeIdade()); // true • É possível ver qual é a função construtora de um objeto por meio da propriedade constructor. console.log(joao.constructor); • A invocação dessa propriedade (já que é uma função) executa novamente o construtor. Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 26 PROTÓTIPO DE OBJETO • A principal diferença entre a orientação a objetos em JavaScript e em outras linguagens é o fato de um objeto em JavaScript ser construído a partir de um protótipo de objeto e não de uma especificação como a classe. • Um objeto em JavaScript, portanto, é criado a partir de outro objeto (o protótipo). Essa clonagem é feita por meio do método Object.create(). var pessoa = { nome: 'Fulano', sobrenome: 'de Tal' } var joao = Object.create(pessoa); joao.nome = 'João'; joao.sobrenome = 'Silva'; var maria = Object.create(pessoa); maria.nome = 'Maria'; maria.sobrenome = 'Oliveira'; • O vínculo entre o protótipo e os objetos é mantido. Assim, alterações feitas ao protótipo refletem sobre todas as instâncias criadas a partir dele. pessoa.nomeCompleto = function() { return this.nome + ' ' + this.sobrenome; } console.log(joao.nomeCompleto()); // João Silva console.log(maria.nomeCompleto()); // Maria Oliveira • Apesar de não ser recomendável, é possível acessar o protótipo de um objeto por meio da propriedade __proto__. console.log(joao.__proto__ === pessoa); // true • Como o objeto Pessoa também tem o seu próprio protótipo (Object), cria-se uma cadeia de protótipos. • Quando um objeto é criado por meio de uma função construtora, a alteração do protótipo gerado por ela deve ser feita por meio da propriedade prototype: function Pessoa(n,s) { this.nome = n; this.sobrenome = s; } var joao = new Pessoa('João', 'Silva'); var maria = new Pessoa('Maria', 'Oliveira'); Pessoa.prototype.nomeCompleto = function() { return this.nome+' '+this.sobrenome; } console.log(joao.nomeCompleto()); // João Silva console.log(maria.nomeCompleto()); // Maria Oliveira Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 27 GETTERS E SETTERS • JavaScript oferece uma alternativa para criação de métodos get e set que permitem um tratamento um pouco mais sofisticado do que a simples atribuição de variáveis. • Com esses métodos,funções específicas assumem a responsabilidade por apresentar o valor de uma propriedade, bem como de tratar o valor antes de armazená-lo (por exemplo, para testar a validade do valor). var ranking = { pos: 1, get getPos() { return ('0'+this.pos).substr(-2); }, set setPos(n) { if(n>0&&n<=100) this.pos=n; else console.log('erro'); } }; ranking.setPos = 3; // O formato do set é de uma atribuição simples console.log(ranking.getPos) // O get também adota a forma de uma propriedade • Os nomes dos métodos get e set não podem ser os mesmos da propriedade original, porque isso poderia criar um laço infinito na tentativa de acessar o seu valor. Mas os métodos podem tratar mais de uma propriedade. var Data = { dia: 1, mes: 1, ano: 2000, get data() { return ('0'+this.dia).substr(-2)+'/'+('0'+this.mes).substr(-2)+'/'+this.ano; }, set data(d) { var valores = d.split('/'); if(valores.length==3) { var dd = parseInt(valores[0]); var mm = parseInt(valores[1]); var aa = parseInt(valores[2]); if(dd>=1 && dd<=31 && mm>=1 && mm<=12) { this.dia = dd; this.mes = mm; this.ano=aa; return; } } console.log("Data inválida"); } }; var hoje = Object.create(Data); hoje.data = '31/12/2010'; console.log(hoje.data); Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 28 10. JSON • Existem diversas formas por meio das quais uma aplicação pode trocar dados com outra como, por exemplo: • Campos textuais de tamanho fixo: CódigoNome Preço 000001Torradeira 0134,50 000002Sanduicheira 0120,30 000003Refrigerador 1240,00 • CSV (comma separated values): Código;Nome;Preço 1;Torradeira;134,50 2;Sanduicheira;120,30 3;Refrigerador;1240,00 • XML: <lista-de-produtos> <produto id="1"> <nome>Torradeira</nome> <preço moeda="R$">134,50</preço> </produto> <produto id="1"> <nome>Sanduicheira</nome> <preço moeda="R$">120,30</preço> </produto> <produto id="1"> <nome> Refrigerador </nome> <preço moeda="R$">1240,00</preço> </produto> </lista-de-produtos> • JSON (JavaScript Object Notation) é mais uma alternativa, mas adequada para uso na Web por usar JavaScript. • Algumas diferenças entre JSON e as literais de objetos em JavaScript são: • Os nomes das propriedades em JSON devem ser escritos entre aspas. • Os valores que podem ser serializados, isto é, representados, são: objetos, vetores, números, strings, booleans e null. • Existe um objeto JSON em JavaScript com apenas dois métodos estáticos: • JSON.parse(s) Transforma uma string em um objeto JSON. • JSON.stringify() Cria uma string que representa um objeto JSON. • Esses métodos são usados para converter um objeto em uma string e uma string em um objeto. Em JavaScript, objetos JSON podem ser usados diretamente como quaisquer outros objetos JavaScript, inclusive como parâmetros entre funções. No entanto, para armazenamento em arquivos ou bancos de dados, para troca com outros sistemas por meio de mensagens e outras situações semelhantes pode ser necessário converter esses objetos em strings. Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 29 • Exemplo: var produtos = { "lista de produtos": [ { "código": 1, "nome": "Torradeira", "preço": 134.5 }, { "código": 2, "nome": "Sanduicheira", "preço": 120.3 }, { "código": 3, "nome": "Refrigerador", "preço": 1240 } ] } console.log(produtos); console.log(JSON.stringify(produtos)); Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 30 11. CLASSES • A ECMAScript 6 criou uma forma de criação de objetos semelhante às linguagens tradicionais, isto é, baseada em classes. No entanto, isso não é representou uma mudança no modelo de objetos da linguagem, apenas criou o que, em inglês, é chamado de syntatical sugar, isto é, um agrado sintático. • Uma classe nada mais é do que uma função especial que tem um método especial: o construtor. class Poligono { constructor(largura, altura) { this.largura = largura; this.altura = altura; } get area() { return this.altura * this.largura; } } const quadrado = new Poligono(10,10); console.log(quadrado.area); • Com ECMAScript 6, também é possível se definir métodos estáticos, isto é, métodos que não dependem da criação de instâncias (e não podem ser chamados a partir de instâncias. class Ponto { constructor(x, y) { this.x = x; this.y = y; } static distancia(a, b) { const dx = a.x - b.x; const dy = a.y - b.y; return Math.sqrt(dx*dx + dy*dy); } toString() { return '(' + this.x + ', ' + this.y + ')'; } } const p1 = new Ponto(5, 5); const p2 = new Ponto (10, 10); console.log(Ponto.distancia(p1, p2)); • Finalmente, é possível criar subclasses da mesma forma que nas linguagens tradicionais. A classe pai pode ser referenciada por meio do termo super. class PontoColorido extends Ponto { constructor(x, y, cor) { super(x, y); this.cor = cor; } toString() { return super.toString() + ' em ' + this.cor; } } var cp = new PontoColorido(10,10,'verde'); console.log(cp.toString()); Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 31 12. OBJETOS INTERNOS • JavaScript oferece uma série de objetos internos que facilitam o processamento de números, strings, datas e outros tipos de dados. Esses objetos possuem constantes e métodos que podem ser invocados a partir do nome do objeto (ex.: Number.parseInt(n), Math.PI, ...) ou a partir de objetos criados com essas classes (var d = new Date()). NUMBER • O objeto interno Number contém constantes e métodos para processamento de números. • JavaScript possui algumas constantes especiais, que não estão vinculadas à classe Number, mas ao objeto global (window): • NaN Not-a-number. Valor retornado quando uma operação matemática falha ou quando tenta transformar uma string em inteiro. Equivale a Number.NaN. • Infinity Valor maior que qualquer outro número. Pode ser positivo ou negativo, correspondendo a Number.POSITIVE_INFINITY ou Number.NEGATIVE_INFINITY respectivamente. • Constantes da classe Number: • MAX_VALUE O maior número representável. • MIN_VALUE O menor número representável. • NaN Not-a-number. • NEGATIVE_INFINITY Infinito negativo (também retornado quando há overflow). • POSITIVE_INFINITY Infinito positivo (também retornado quando há overflow). • EPSILON Menor diferença entre dois números, isto é, a diferença. entre 1 e o menor valor imediatamente maior que 1. • MIN_SAFE_INTEGER Menor número inteiro representável (considerando que os números são do tipo double). Equivale a -9.007.199.254.740.991 ou -(253-1). • MAX_SAFE_INTEGER Maior número inteiro representável. Equivale a +9.007.199.254.740.991 ou +(253-1). • Métodos estáticos da classe Number: • parseFloat() Transforma uma string em float (equivale ao método global). • parseInt() Transforma uma string em inteiro (equivale ao método global). • isFinite() Determina se o valor não é infinito. • isNaN() Determina se o valor não é NaN. • isSafeInteger() Determina se o valor o valor é um inteiro seguro (número inteiro entre –(253-1) e +(253+1). • toExponential() Retona uma string com o número em notação exponencial. • toFixed() Retorna uma string com o número com uma quantidade fixa de casas decimais. • toPrecision() Retorna uma string com o número em uma precisão específica (quantidadede dígitos). Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 32 MATH • O objeto interno Math contém constantes e funções matemáticas especiais. • Constantes da classe Math: • PI Valor de Pi (3,14159...) • Métodos estáticos da classe Math: • abs() Valor absoluto (sem sinal). • sin(), cos(), tan() Funções trigonométricas (argumentos em radianos). • asin(), acos(), atan(), Funções trigonométricas inversas (retorno em radianos). atan2() • sinh(), cosh(), tanh() Funções trigonométricas hiperbólicas (retorno em radianos). • asinh(), acosh(), atanh() Funções trigonométricas hiperbólicas inversas (retorno em radianos). • pow() Potenciação. • exp(), expm1(), Exponenciação. • log10(), log1p(), log2() Logaritmos. • floor() Inteiro imediatamente menor que o argumento. • ceil() Inteiro imediatamente superior ao argumento. • min(), max() Menor e maior elementos de uma lista de argumentos. • random() Número aleatório entre 0 e 1. • round(), fround(), trunc() Arredondamento e truncagem. • sqrt(), cbrt(), hypot() Raiz quadrada, raiz cúbica e raiz da soma dos quadrados dos argumentos. • sign() Sinal do argumento, indicando se é positivo, negativo ou zero. DATE • O objeto interno Date contém métodos para manipulação de datas e horas. • Cada data/hora é armazenada como o número de milissegundos passados desde 01/01/1970, às 00:00:00. • As datas/horas estão limitadas a uma faixa entre -100.000.000 dias e +100.000.000 desde 01/01/1970. • Uma data é criada por meio do construtor Date(). var agora = new Date(); // data e hora atuais var natal = new Date(2016,12,25); // data específica var reuniao1 = new Date(2016,03,15,14,30,00,0); // data e hora específicas var reuniao2 = new Date("2016-03-15T14:30:00-03:00); // formato ISO (com fuso) • Atenção, o formato das strings de datas é o americano. var d = new Date("03/10/2015"); // 10 de março e não 3 de outubro de 2015 var t = new Date("December 25, 2010"); // 25 de dezembro de 2010 Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 33 • Há uma quantidade muito grande de métodos para manipulação de datas e horas. Os que começam com set são usados para definir o valor de datas e horas e os que começam com get para obter o valor. Os métodos que começam com to são usados para criar representações textuais das datas. • getDate(), setDate() Dia do mês. • getDay(), setDay() Dia da semana. • getMonth(), setMonth() Mês (0 a 11). • getFullYear(), setFullYear() Ano com 4 dígitos. • getHours(), setHours() Horas. • getMinutes(), setMinutes() Minutos. • getSeconds(), setSeconds() Segundos. • getMiliseconds(), Milissegundos. setMiliseconds() • getTime(), setTime() Milissegundos desde 01/01/1970. • valueOf() Milissegundos desde 01/01/1970 (da mesma forma que em outros tipos, mas é o mesmo valor de getTime()). • getTimeZoneOffset() Minutos entre a hora local e a hora universal (UTC). • toLocaleString() String com data e hora no formato local. • toLocaleDateString() String com data no formato local. • toLocaleTimeString() String com hora no formato local. • O método Date.now() é um método estático que retorna o número de milissegundos passados desde 01/01/1970. • Existem vários outros métodos baseados na hora universal (UTC) mas que não são comumente usados no Brasil. • Apesar da quantidade de métodos, as operações com datas são limitadas aos cálculos de milissegundos. Aplicações mais sofisticadas podem usar uma biblioteca com mais recursos para manipulação de datas e horas como a Moment.js (http://momentjs.com/). STRING • O objeto interno String contém métodos para manipulação de cadeias de caracteres. • Uma string pode ser criada de duas formas: var s1 = "Olá mundo!"; var s2 = new String("Olá mundo!"); • No primeiro caso, a string s1 criada por uma literal é um tipo primitivo. Já a string s2 é um objeto do tipo String. console.log(typeof s1); // string console.log(typeof s2); // object console.log(s1==s2); // false console.log(s1===s2.toString()); // true • Os métodos do objeto String, no entanto, podem ser usados em uma literal de string, pois ocorre uma coerção automática de tipo. console.log( "Olá mundo!".length ); // 10 Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 34 • Os métodos do objeto String são: • charAt(), charCodeAt(), codePointAt() retorna o caráter em uma posição. • indexOf(), lastIndexOf() retorna a primeira ou a última posição de uma substring. • startsWith(), endsWith(), includes() retorna se a string começa, termina ou contém uma substring. • concat() concatena duas strings. • split() cria um vetor de substrings a partir de um separador. • slice() extrai uma parte da string. • substring(), substr() retorna uma substring entre dois índices ou a partir de um índice e um tamanho. • match(), replace(), search() aplica expressões regulares. • toLowerCase(), toUpperCase() converte a caixa das letras da string. • repeat() cria uma string a partir de uma repetição. • trim() remove espaços em branco no início e fim. REGEXP • O objeto interno RegExp contém métodos para construção de expressões regulares, que são usadas para testar, avaliar, buscar e comparar strings. • A sintaxe geral da literal de uma expressão regular é: /padrão/modificador, mas uma expressão regular também pode ser criada por meio do objeto RegExp. var reTelefone = /\([0-9]{2}\)[0-9]{4,5}-[0-9]{4}/g; var reTelefone = new RegExp( "\\([0-9]{2}\\)[0-9]{4,5}-[0-9]{4}", "g" ); • Uma expressão regular pode ser testada por meio do método test(). var fone1 = "(31)99123-1234"; console.log(reTelefone.test(fone1)); // true var fone2 = "(02131)99123-1234"; console.log(reTelefone.test(fone2)); // false • Expressões regulares estão fora do escopo destas aulas. Algumas referências online sobre o assunto são: • http://regexone.com/ • https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Guide/Regular_Expressions • https://en.wikipedia.org/wiki/Regular_expression Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 35 MAP • O objeto Map é um objeto novo da ECMAScript 6 que permite o armazenamento de uma coleção de pares chave/valor, percorridos de acordo com a sua ordem de inserção. • Os principais métodos de um objeto Map são: • set(k,v) Armazena um valor v usando uma chave k. • get(k) Recupera o valor armazenado com uma chave k. • has(k) Testa se há um valor armazenado com uma chave k. • delete(k) Apagar um valor armazenado com uma chave k. • size Indica a quantidade de elementos armazenada no mapeamento. • O percurso por um mapeamento é feito por meio do laço for...of. var veiculos = new Map(); veiculos.set("HMG0248", "Honda Civic"); veiculos.set("JSQ7436", "Hyundai ix35"); veiculos.set("FOR1904", "Toyota Corolla"); console.log(veiculos.size); // 3 console.log(veiculos.get("JSQ7436")); // Hyundai ix35 console.log(veiculos.has("FOR1904")); // true console.log(veiculos.has("LPT4625")); // false veiculos.delete("HMG0248"); for(var [placa,carro] of veiculos) { console.log(`A placa do ${carro} é ${placa}`); } • Um mapeamento se parece um pouco com um objeto. No entanto, possui as seguintes vantagens: • A chave de um objeto é apenas uma string. Em um mapeamento, pode ser de qualquer tipo. • É possível obter o tamanho de um mapeamento rapidamente (size). • A iteração pelos elementos do mapeamento é feita de acordo com a ordem de inserção. SET • O objeto Set é usado para armazenar um conjunto de valores. A iteração por seus elementos ocorre na ordemda inserção. • Os principais métodos de um objeto Set são: • add(v) Armazena um valor v. • has(v) Testa se há um valor v armazenado. • delete(v) Remove o valor v. • size Indica a quantidade de elementos armazenada no conjunto. • Algumas diferenças entre um objeto Set e um objeto Array (vetor) são: • Em um conjunto, é possível excluir um elemento a partir do seu valor. • Um valor NaN não pode ser encontrado em um Array por meio do método indexOf(). • Os conjuntos não possuem valores duplicados. • Em objetos WeakSet e WeakMap, os valores só são mantidos na coleção se houver referências externas a eles. As chaves do WeakMap e os valores do WeakSet devem ser objetos. Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 36 13. DOM – DOCUMENT OBJECT MODEL • O modelo de objeto de documento (DOM) é uma interface de programação que oferece acesso a todos elementos do documento, bem como a seus atributos e seus conteúdos. Por meio desse acesso, é possível alterar a estrutura do documento, sua formatação e seu conteúdo. • Todo documento é representado por uma árvore hierárquica de elementos. É possível navegar na árvore por meio das seguintes propriedades: • children vetor de elementos filhos • firstElementChild primeiro elemento filho • lastElementChild último elemento filho • nextElementSibling próximo elemento irmão • textContent conteúdo textual do elemento • childNodes vetor de nodos filho. • firstChild primeiro nodo filho. • lastChild último nodo filho. • nextSibling próximo nodo irmão. • Na árvore do documento, os espaços em branco entre elementos acabam virando nodos texto (#text). • O conteúdo de um elemento pode ser um nodo texto, um vetor de elementos ou a combinação dos dois. • Cada nodo possui as seguintes propriedades: • nodeType tipo de nodo (1=elemento, 2=atributo, 3=texto, 8=comentário, ...) • nodeName nome do nodo (elemento ou atributo) • nodeValue valor do nodo (elemento à null, atributo à valor do atributo, texto à string) • O acesso a um ou mais elementos do documento pode ser feito por um conjunto de métodos do objeto document. • getElementById(id) Retorna uma referência para um elemento por meio de seu id. • getElementsByTagName(name) Retorna uma lista de referências para elementos desse tipo (tag). • getElementsByClassName(name) Retorna uma lista de referências para elementos que tenham esse nome de classe. • querySelector(selector) Retorna uma referência para o primeiro elemento que atenda ao seletor (CSS). • querySelectorAll(selector) Retorna uma lista de referências para todos os elementos que atendam ao seletor. • As listas de referência (nodeList) retornadas possuem duas propriedades: • length Quantidade de elementos retornados. • item(n) Elemento de índice n (mas o elemento também pode ser acessado como um vetor, isto é, por meio do operador []). Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 37 • Exemplo: var paragrafos = document.querySelectorAll('p'); for(let i=0; i<paragrafos.length; i++ ) console.log(paragrafos.item(i)); • Também é possível acessar a lista de atributos de um determinado elemento, por meio dos seguintes métodos: • attributes Retorna um vetor dos atributos do elemento. • hasAttribute(a) Testa se o elemento tem um atributo a. • getAttribute(a) Retorna o valor de um atributo a. • setAttribute(a,v) Cria (ou atualiza) um atributo a com o valor v. • removeAttribute(a) Remove um atributo a. • Além dos atributos, os elementos possuem as seguintes propriedades: • innerHTML Conteúdo HTML do elemento. • outerHTML Tag e conteúdo HTML do elemento. • id Valor do atributo id. • className String com as classes do elemento. • classList Vetor com cada uma das classes do elemento. • style Objeto com as propriedades CSS do elemento. • textContent Conteúdo textual do elemento. • A propriedade style, em particular, representa uma coleção de outras propriedades: aquelas usadas na CSS. A única diferença é que, aqui, são escritas em camel case. var titulo = document.querySelector('h1'); titulo.style.border = 'thin solid black'; titulo.style.backgroundColor = 'lightgray'; titulo.style.padding = '5px 10px'; titulo.style.fontFamily = 'Calibri, sans-serif'; titulo.style.fontSize = '24pt'; • É possível criar novos elementos ou excluir elementos por meio dos seguintes métodos. • createElement(t) Cria um novo elemento com a tag t. Em seguida, pode-se definir conteúdo, atributos e formatação por meio das propriedades da lista anterior. Esse método é do objeto document. • appendChild(e) Adiciona um filho e ao elemento selecionado. • remove() Remove o elemento que chamar o método. Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 38 14. EVENTOS • Apesar de ser possível iniciar uma rotina em JavaScript tão logo o documento seja carregado, a aplicação mais interessante da JavaScript em páginas web é na interação com o usuário, isto é, na criação de um comportamento para cada uma das possíveis ações do usuário sobre as páginas. • As ações dos usuários nas páginas disparam eventos que, por sua vez, iniciam funções JavaScript: <button onclick="alert('Botão clicado!');">Clique aqui</button> • Os eventos que cada elemento da HTML possui dependem do tipo próprio tipo do elemento, isto é, há eventos que fazem parte do modelo de um elemento e eventos que fazem parte do modelo de outros elementos (https://www.w3.org/TR/html5/webappapis.html#event-handlers-on-elements,- document-objects,-and-window-objects). • Os eventos do objeto window, aplicados ao elemento <body>, são: • onload Página totalmente carregada • onunload Página foi descarregada (usuário mudou de página ou fechou a janela) • onafterprint Impressão concluída • onbeforeprint Impressão pronta para ser iniciada • onbeforeunload Página prestes a ser descarregada (mas é possível cancelar isso) • onerror Ocorrência de erros • onhashchange Mudança de fragmento (#) da URL da página • onmessage Novos dados chegaram do servidor • onoffline Navegador ficou offline • ononline Navegador ficou online • onpagehide Usuário abandonou a página (inclusive saindo dela) • onpageshow Usuário abriu a página (mesmo que esteja no cache) • onpopstate Mudança no histórico do navegador • onresize Janela foi redimensionada • onstorage Área de dados (web storage) foi alterada • Os eventos onload e onpageshow podem ser usados para assegurar que um script só será executado após a carga completa do documento. <body onload="iniciaScript()"> ... </body> • Os eventos de campos de formulário são: • onblur Elemento perdeu o foco • onchange Valor do campo <select> alterado • oncontextmenu Menu de contexto ativado • onfocus Elemento recebeu o foco • oninput Campo recebeu dados do usuário • oninvalid Conteúdo do campo inválido • onreset Botão reset acionado (<input type="reset">) • onsearch Campo de busca recebeu dados do usuário (<input type="search">) • onselect Algum texto foi selecionado no campo • onsubmit Formulário enviado (<input type="submit">) Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 39 <!DOCTYPE html> <html lang="pt-br"> <head> <title>Formulário</title> <meta charset="utf-8" /> <script> function caracteres() { document.querySelector('#caract').innerHTML = document.querySelector('#email').value.length; } function valida() { var email = document.querySelector('#email'); if(!email.checkValidity()) alert('Email inválido'); return false; } </script> <style> label { width: 100px; display:inline-block; } input:invalid { box-shadow: 0px 0px 10px lightcoral; border-color: lightcoral; } input:focus:invalid { box-shadow: none; } </style> </head> <body> <form onsubmit="valida()"> <fielset id="campos"> <legend>Contato</legend> <p> <label for="email">Email</label> <input type="email" id="email" oninput="caracteres()" oninvalid="alert('email inválido')" /> <span id="caract">0</span> caracteres </p> <p><input type="submit" /> </fieldset> </form> </body> </html> • Os eventos de teclado são: • onkeydown Usuário pressionou a tecla • onkeypress Usuário pressionou e soltou a tecla • onkeyup Usuário soltou a tecla Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 40 • Os eventos de mouse são: • onclick O usuário clicou sobre o elemento • ondblclick O usuário deu um clique duplo sobre o elemento • ondragstart O usuário começou a arrastar o elemento • ondrag O usuário está arrastando o elemento • ondragend O usuário terminou de arrastar o elemento • ondragenter Algo arrastado entrou na área do elemento • ondragover Algo está sendo arrastado sobre o elemento • ondragleave Algo arrastado saiu da área do elemento • ondrop Algo foi largado sobre o elemento • onmousedown O usuário pressionou o botão do mouse • onmouseup O usuário soltou o botão do mouse • onwheel O usuário usou o botão de rolagem do mouse • onmouseover O ponteiro do mouse entrou na área do elemento • onmousemove O ponteiro do mouse está sendo movido sobre o elemento • onmouseout O ponteiro do mouse saiu da área do elemento ... <script> function fsCinza() { document.querySelector('#campos').style.backgroundColor = 'azure'; } function fsBranco() { document.querySelector('#campos').style.backgroundColor = 'white'; } </script> ... <fieldset id="campos" onmouseover="fsCinza()" onmouseout="fsBranco()"> ... </fieldset> ... • O tratamento de eventos também pode ser definido e cancelado por meio da JavaScript. Para isso, basta usarmos os métodos addEventListener() e removeEventListener(): var fs=document.querySelector('#campos'); // para definir o tratamento do evento fs.addEventListener('mouseover', fsCinza); fs.addEventListener('mouseout', fsBranco); ... // para remover o tratamento do evento fs.removeEventListener('mouseover', fsCinza); fs.removeEventListener('mouseout', fsBranco); Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 41 15. AJAX • AJAX é uma forma de solicitação de novos dados ao servidor sem necessidade de recarregar a página, isto é, os dados da página podem ser atualizados dinamicamente (ou enviados ao servidor) • Por exemplo, o Google Docs atualiza as páginas automaticamente usando AJAX. • AJAX = Asynchronous JavaScript and XML (é uma combinação de diversas tecnologias), especialmente: • Objeto XMLHttpRequest, usado para fazer uma conexão assíncrona ao servidor • JavaScript para processar os dados recebidos • XML (ou texto) para a resposta. var xhr = new XMLHttpRequest(); • A requisição pode usar os métodos GET ou POST e ser assíncrona ou síncrona. • Em uma requisição POST, o método send() deve conter os dados a serem enviados. xhr.open("GET", "minhaPagina.php", true); xhr.send(); • A resposta pode ser recuperada por meio de duas propriedades do objeto XMLHttpRequest: • responseText Se o formato for texto ou JSON • responseXML Se o formato for XML • O evento onreadystatechange é disparado quando uma resposta chega. Há vários possíveis estados para a solicitação, que podem ser consultados por meio da propriedade readyState: • readyState 0 – requisição não inicializada 1 – conexão com o servidor estabelecida 2 – requisição recebida pelo servidor 3 – requisição sendo processada 4 – requisição concluída e resposta recebida • status 200 – ok 404 – página não encontrada xhr.onreadystatechange = function() { if(xhr.readyState==4 && xhr.status==200) { var resposta = xhr.responseText; ... } } • Exemplo: HTML <table> <thead><tr><th>Código</th><th>Nome</th><th>Preço</th></tr></thead> <tbody id="dados"></tbody> </table> <p><button onclick="carregarDados()">Carregar</button></p> CSS Padrões Web - Unidade III Prof. Marcos Kutova Curso de especialização a distância em Desenvolvimento de Aplicações Web 42 table { border-collapse: collapse; } td, th { border: thin solid black; padding: 5px; } td:first-child, td:last-child { text-align: right; } JS { "lista de produtos": [ { "código": 1, "nome": "Torradeira", "preço": 134.5 }, { "código": 2, "nome": "Sanduicheira", "preço": 120.3 }, { "código": 3, "nome": "Refrigerador", "preço": 1240 } ] } JS function carregarDados() { var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState == 4 && xhr.status == 200) { document.getElementById('dados').innerHTML = formata(xhr.responseText); } }; xhr.open('GET', 'produtos.json', true); xhr.send(); } function formata(strDados) { var objDados = JSON.parse(strDados); var linhasTabela=''; for(lp of objDados['lista de produtos']) { var preco = (new Number(lp['preço'])).toFixed(2).replace('.',','); linhasTabela += '<tr><td>'+lp['código']+'</td><td>'+lp['nome']+ '</td><td>'+preco+'</td></tr>'; } return linhasTabela; }
Compartilhar