JAVASCRIPT

Parte 1 - Conhecendo o JavaScript

Henrique Rotava

A linguagem da Web

Quem é Henrique Rotava?

Bacharel em Ciência da Computação em 2016 pela URI
Compasso Tecnologia desde 2011
Pulpo desde 2015
Experiência:

     Java: Oracle Commerce ATG, JSF, JSP
       JavaScript: Ionic, Cordova, AngularJS, Meteor, React, jQuery, CouchDB, PouchDB, MongoDB

Contato:

       henrique@pulpo.work

       (54) 9902-4999

O que é JavaScript?

Uma linguagem de script
Orientada a objeto por meio de prototipagem
Multiplataforma
Uma linguagem leve e simples
Objetivo inicial era executar no navegador sem passar pelo servidor e criar animações
Tipagem fraca e dinâmica
Hoje é usada no lado do servidor, programação de hardware, bancos de dados, programas desktops, jogos e em aplicações móveis

Popularidade do JavaScript

Hoje é a linguagem de programação essencial da web além de ser uma das mais populares

História do JavaScript

Criada por um engenheiro da Nestscape Brendan Eich em 1995 sob o nome Mocha
Lançada em 1995 na versão beta do Netscape 2.0 sob o nome LiveScript
Em um anúncio em conjunto com a Sun Microsystems em dezembro o nome muda para JavaScript e a confusão começa...
Com a popularidade a Microsoft lança a JScript no IE 3.0 na metade de 1996, uma versão "melhor" do JavaScript

 

História do JavaScript

No final de 1996 a Netscape submete a linguagem para ECMA Internacional, resultando no padrão da linguagem chamado ECMAScript
A versão 3 em 1999 foi bastante significante, a 4 foi abandonada e a 5 foi lançada em 2009
Em junho de 2015 foi lançada a versão 6 que ainda está em implementação
O objetivo do curso é estudar a versão 5 utilizando a implementação JavaScript do ECMAScript

 

Engine JavaScript

O código JavaScript ou ECMAScript é executado em uma engine ou interpretador JavaScript
A guerra dos navegadores hoje tem por objetivo desenvolver um interpretador cada vez mais rápido

 

Engine JavaScript

Algumas da principais engines ativas:
    Rhino, mantida pela Mozilla Foundation, open source, desenvolvida totalmente em Java
    SpiderMonkey, a primeira engine, primeiramente presente no Netscape e hoje no Firefox
    V8, open source, desenvolvida pela Google, faz parte do Google Chrome
    JavaScriptCore, open source, conhecida como Nitro e desenvolvida para a Apple para o Safari
    KJS - KDE's ECMAScript/JavaScript, originalmente desenvolvidaa por Harri Porten para o navegador Konqueror
    Chakra (JScript9), desenvolvida para o Internet Explorer
    Chakra (JavaScript) desenvolvida para o Microsoft Edge

Porque usar JavaScript?

JavaScript é fácil de aprender
É fácil de escrever código JavaScript
Prototipagem possibilita desenvolvimento  e design flexível
A comunidade, a quantidade de bibliotecas e ferramentas é gigante
É fácil de debugar
É a linguagem da web
Hoje entende-se que a linguagem não é apenas um brinquedo para fazer animações nas páginas e o objetivo da comunidade é melhorar cada vez mais o uso da linguagem em todos os sentidos

 

Salvando exercícios

Sugestão - criar uma estrutura de arquivos:
C:/Projetos/JavaScript/Aula1/Exercicio1/index.html
C:/Projetos/JavaScript/Aula1/Exercicio1/script.js

Material base: https://goo.gl/Y7oNRx
Baixar base.html


Editores de texto

Dicas para debug

Acessando o console do navegador:
Pressione F12

Digite o código que desejar
Use seta para cima para reexecutar códigos anteriores
Exibindo valores:

alert('Pop up!');
var message = 'Mensagem teste';
alert(message);

console.log('Teste console');
console.log(message);

Operadores

Os operadores do JavaScript são bem parecidos com Java e C
Operadores aritméticos: +, -, /, *, %, +=, -=, --, ++
Os operadores de comparação: ==, <=, >= , !=, >, <
Comparações de tipo usam mais um = no final, veremos a seguir
Operadores lógicos: && e ||
Para negação é utilizado o operador !
A atribuição de valor é dada pelo operador =
O final da linha é indicado por ; não é obrigatório seu uso,  mas mesmo assim é aconselhável sempre utilizá-lo para tornar o código mais organizado e evitar confusões

Exemplos de operadores

Execute os seguintes comandos no console do navegador e veja os resultados

// Comparação de igualdade
123 == '123';
1 == true;
// Comparação considerando tipagem
123 === '123';
1 === true;
// Soma/concatenação:
4.2 + 9;
45 + 'str';
'3' + 4 + 5;
3 + 4 + '5';
// Subtração:
4 - 6.2;
45 - 'str';
// Divisão:
5 / 2;
4 / 0;
// Multiplicação:
5 * 4;

Variáveis

Variáveis são definidas pela palavra reservada var
Possuem tipagem fraca e dinâmica​

var tipo = 12; // number
tipo = 'agora sou uma string'; // string
tipo = ['string', 34, 45.76]; // array com vários tipos
tipo = { nome: 'propriedade nome' }; // object

// Utilize typeof para saber o tipo de dado da variável
typeof tipo; // 'object'

Variáveis - Escopo

Variáveis criadas sem a palavra var, são globais e pertencem ao objeto window

Estruturas de controle não possuem escopo próprio

var variable = 'initial';

function testGlobal(){
    console.log(global); // "global value"
}

function aFunction(){

    if(true){
	var variable = 'value'; // Será visível para toda a função
	global = 'global value';  // Variável global, pertence ao escopo do window
    }

    console.log(variable); // "value"
}

aFunction();
testGlobal();
console.log(variable); // "initial"
console.log(global); // "global value"

Objetos globais

O JavaScript possui alguns objetos nativos prontos para serem utilizados, aprenderemos melhor sobre cada um ao longo do curso

 

Number

String

Boolean

Object

   Function

   Array

   Date

   RegExp

Number

Representa valores numéricos

Um double com precisão de 64 bits

var answer = 42; 
typeof answer; // “number”
Math.pow(4, 2); // 16
Math.sqrt(16); // 4
Math.PI; // 3.141592653589793
parseInt('0134', 10); // 134
parseInt('010', 8); // 8
parseInt('0x10', 16); // 16
parseInt('110', 2); // 6
parseInt('50 linhas', 10) // 50
parseInt('str', 10); // NaN
isNaN('teste'); // true
parseFloat('23.45'); // 23.45

String

Strings são sequências de caracteres unicode. Mais especificamente, cada caractere é representado por uma ou duas unidades de código UTF-16, cada unidade de código é representada por um número de 16 bits

var str = 'string com aspas simples';
str = "string com aspas duplas";
// String com caracteres especiais
"中文 español English हिन्दी العربية português বাংলা русский 日本語 ਪੰਜਾਬੀ 한국어 தமிழ்";
'ac' > 'ab'; // true 
'hello'.length; // 5
'hello'.charAt(0); // "h"
'hello'[1]; // "e"
'hello'.indexOf('l'); // 2 primeira ocorrência do l
'hello, world'.replace("hello", "goodbye"); // "goodbye, world"
'hello'.toUpperCase(); // "HELLO"

String - Métodos

Método Descrição
charAt(1) Retorna o caractere no índice específico
charCodeAt(1) Retorna o número indicando o valor Unicode do caractere na posição específica.
concat('string') Junta duas strings e retorna uma nova string.
indexOf('teste') Retorna a posição da primeira ocorrência da string informada ou retorna -1 caso não tenha sido encontrada
lastIndexOf('te') Retorna a posição da última ocorrência da string informada ou retorna -1 caso não tenha sido encontrada
replace('x','y') Procura uma string ou expressão regular e substitui por outra string
slice(2,4) Extrai uma parte de uma string e retorna uma nova string
split(',') Separa os caracteres em um array baseado no parâmetro delimitador
substr(1,3) Retorna uma parte da  string começando pelo índice informado e terminando na quantidade de caracteres informada
substring(2,4) Retorna uma parte da  string entre os dois índices informados

String - Métodos

Método Descrição
toLowerCase() Retorna a string em letras minúsculas
toUpperCase() Retorna a string em letras maiúsculas
trim() Remove os espaços no início e final da string

null

Uma variável será do tipo null caso não possua nenhum valor

var nula = null; // null

undefined

Uma variável não inicializada será do tipo undefined

Você verá bastante a palavra undefined quando trabalhar com JS

var indefinida; // undefined

Boolean

Uma variável booleana pode assumir dois valores, verdadeiro (true) ou falso (false) e é utilizada para operações lógicas

O JavaScript também é dinâmico nesse sentido

false, 0, strings vazias (""), NaN, null, e undefined são considerados valores falsos

Todos os outros valores são verdadeiros

Boolean - Exemplos

var verdade = true; // true
var mentira = false; // false
Boolean(''); // false
Boolean(12); // true
var undefinedVar; // undefined
if(undefinedVar) // Não entrará no if
var zero = 0;
!!zero; // false
zero = 'zero';
!!zero; // true

var str = 'value';
if(str != null && str != undefined && str.length > 0)
// ou simplesmente
if(str)

Date

Uma instância JavaScript de Date representa um único momento no tempo

Objetos Date são baseados no valor de tempo que é o número de milisegundos desde 1 de Janeiro de 1970 (UTC)

// Construtores:
new Date();
new Date(valor);
new Date(dataString);
new Date(ano, mês, dia, hora, minuto, segundo, milissegundo);

Date - Exemplos

var today = new Date();
var birthday = new Date("December 17, 1995 03:24:00");
var birthday = new Date("1995-12-17T03:24:00");
var birthday = new Date(1995,11,17);
var birthday = new Date(1995,11,17,3,24,0);

Estruturas de controle - If, else

var name = 'gatos';
if (name == 'cães') {
    name += '!';
} else if (name == 'gatos') {
    name += '!!';
} else {
    name = '!' + name;
}
name == 'gatos!!'; // true

Estruturas de controle - While, do while

while (true) {
    // loop infinito
}

var input;
do {
    input = nextInput();
} while (!input)

Estruturas de controle - For

for (var index = 0; index < 5; index++) {
    // Executará 5 vezes
}

Estruturas de controle - Circuito

Lógica de circuito curto (muito prático)

// Se object estiver definido e tiver a propriedade name, 
// a variável name terá o valor do atributo name
var name = object && object.name;

// Valida nome completo de usuário
if(user && user.firstName && user.lastName);

// Em Java
if(user != null && user.getName() != null && user.getName().size() > 0) 

Estruturas de controle - Circuito

Lógica de circuito curto para valor padrão

var name = nameParam || 'default';

Estruturas de controle - Teste ternário

Exemplo de operador ternário

var age = 25;
var allowed = (age > 18) ? 'yes' : 'no';
console.log(allowed); // 'yes'

Estruturas de controle - Switch

Exemplo de uso de switch

var stuff = 'beer';
switch(stuff) {
    case 'beer':
        drinkIt();
        break; // caso não existir, o próximo caso também será testado
    case 'bacon':
        eatIt();
        break;
    default: // opcional
        callBartender();
}

try, catch, finally e throw

try: contém linhas de código a serem executadas

catch: especifica o que fazer se ocorrer alguma exceção

finally: sempre executará

throw: lança uma exceção

var obj;
try {
    console.log(obj.property); // Irá lançar uma exceção
    throw('Erro ao executar comando'); // Irá lançar uma exceção
} catch(e) { // opcional
    console.log(e);
} finally { // opcional
    console.log('finally');
}

Exercício

1. Dada uma variável teste, onde 0 < teste < 100:

    Se ela for par, utilize o loop while para decrementá-la até seu valor ser zero

    Se ela for ímpar utilize o loop for para incrementá-la até 100

2. Dada uma variável tipo onde seu valor pode ser do tipo string, number ou boolean:

    Use a estrutura switch para imprimir uma mensagem diferente para cada uma informando seu tipo. Ex.: "Esta variável contém uma string"

 

Exercício

3. Dadas 3 variáveis do tipo string, use a lógica de circuito para pegar o valor da primeira que contiver um valor. Ao final verifique se a string contém a palavra 'JS', se contiver, substitua 'JS' por 'JavaScript'.

var string1 = '';
var string2 = 'Programando com JS!';
var string3 = '';

4. Baseado no exercício anterior, considere que nenhuma variável foi inicializada. Use try e catch para impedir a propagação de erros ao acessar os métodos da string. Além disso, no bloco finally use a lógica de circuito para atribuir um valor padrão para a string.

Funções

Uma função é um procedimento que executa uma tarefa ou calcula um valor 

Funções em JavaScript podem receber uma quantidade indefinida de argumentos, pode também retornar ou não um valor

Funções são objetos de primeira classe, ou seja, podem possuir atributos e funções internas, podem ser passados como argumentos, serem atribuídos a variáveis ou retornados como qualquer outro objeto

 

Funções - Exemplos

function add(x, y){
    var total = x + y;
    return total;
}

// Quando você chama a função você pode passar quantos parâmetros quiser
add(3, 6); // 9
add(); // NaN
add(2, 3, 8); // 5

Funções - arguments

// Atribuindo função para uma variável
var avg = function() {
    var sum = 0;
    for (var i = 0; i < arguments.length; i++) {
        sum += arguments[i];
    }
    return sum / arguments.length;
}
avg(2, 3, 4, 5); // 3.5

Funções também possuem uma variável interna chamada arguments que é um array dos argumentos passados para a função

Funções imediatas

var a = 1;
var b = 2;

(function() {
    var b = 3;
    a += b;
})();

a; // 4
b; // 2

É possível criar funções que são executadas imediatamente, isso serve para isolar partes do código, ou impedir a chamada de uma função externamente ou mais de uma vez

Funções internas

function parentFunction(){
    var arg = 55;
    function childFunction(){
        return ++arg;
    }
    return childFunction();
}
parentFunction(); // 56

É possível criar funções dentro de funções, isso será importante quando começarmos a trabalhar com Objetos

Exercício

5. Crie uma função chamada soma que recebe duas strings como parâmetro, o valor das strings devem ser números decimais, podendo ser inteiros ou com ponto flutuante. Retorne a soma dos dois números. Caso um dos dois números for inválido (undefined, null, NaN) ou não informado, assuma que seu valor é 0

// Casos de teste
soma('12','43.9'); // 55.9
soma('34'); // 34
soma(); // 0
soma(undefined, NaN); // 0
soma(12); // 12
soma(15, 40); // 55
soma(null, ''); // 0
soma(null, '4'); // 4

Objetos

Um objeto em JavaScript é uma coleção de pares nome-valor, como mapas ou ponteiros

Objetos podem possuir instância, propriedades e métodos
O nome do atributo de um objeto sempre é uma string que pode possuir qualquer caractere, seu valor pode ser qualquer objeto
É possível criar, alterar ou remover qualquer atributo de um objeto em tempo de execução, possibilitando criar qualquer estrutura de objeto

var obj = new Object();
var obj = {};

Objetos - Exemplos

var user = {
    firstName: 'Neilor',
    lastName: 'Tonin',
    workInfo: [
        { local: 'URI', job: 'Coordenador do curso'},
        { local: 'Compasso', job: 'Coordenador administrativo'}	
    ],
    address: {
	street: 'Pedro Alvares Cabral',
	number: '32',
	complement: 'Apartamento 802'
    },
    '@tribut# b3m l*k0': ':)'
};

user.address.street; // 'Pedro Alvares Cabral'
user.address.street = 'Avenida Sete de Setembro'; // 'Avenida Sete de Setembro'
user['firstName']; // Neilor
user['@tribut# b3m l*k0']; // ':)'

Objetos - Instanciáveis

function Person(firstName, lastName, birthDate){
    this.firstName = firstName,
    this.lastName = lastName,
    this.birthDate = new Date(birthDate)
};

var Paulo = new Person('Paulo', 'Rodegheri', '07/30/1960');

Objetos - prototype

Usando o objeto prototype é possível adicionar atributos dinamicamente para todas as instancias de um objeto. Este objeto pode ser alterado nos objetos nativos do JavaScript também

Person.prototype.initials = function(){
    return this.firstName[0] + this.lastName.charAt[0];
}

// Retorna a primeira hora de uma data
Date.prototype.getMinimumDayTime = function(){
    var date = new Date(this);
    date.setHours(0);
    date.setMinutes(0);
    date.setSeconds(0);
    return date;
}

Exercício

6. Criar um método no objeto Person que retorne o nome completo da pessoa

7. Utilizando o objeto prototype, crie um método no objeto Person que retorne a idade da pessoa

function Person(firstName, lastName, birthDate){
    this.firstName = firstName,
    this.lastName = lastName,
    this.birthDate = new Date(birthDate)
};

Closures

Closure é uma das coisas mais poderosas em relação a abstração que o JavaScript possui. Mas também é a mais confusa.

Permite acessar a referência de variáveis do escopo local, global e de outro determinado escopo

function somador(a) {
    var c = 2;
    return function(b) {
        return a + b + c;
    };
}
var x = somador(5);
var y = somador(20);
x(6); // ?
y(7); // ?

Arrays

São objetos especiais com propriedades acessadas por [] e seus atributos são referenciados por um índice

var a = new Array();
a[0] = 'dog';
a[1] = 'cat';
a[2] = 'hen';
a.length; // 3

// ou:

var a = ["dog", "cat", "hen"];
a.length; // 3

Arrays - Posição dinâmica

// É possível utilizar qualquer posição, sem definir o tamanho do array:

var a = ["dog", "cat", "crow"];
a[100] = "fox";

// O valor do length será um valor acima do índice mais alto
a.length; // 101


// Acessando um indíce não existente:
a[20]; // undefined


Arrays - Iteração

var refrigerantes = ['Coca-cola', 'Fanta', 'Sprite', 'Pepsi'];
for (var i = 0; i < refrigerantes.length; i++) {
    // Utilize refrigerantes[i]
}

// ou:

refrigerantes.forEach(function(refrigerante, index, array) {
    // Utilize refrigerantes ou array[index]
    console.log(refrigerante);
});

Arrays - Métodos

Método Descrição
toString() Retorna os elementos separados por vírgula
concat([]) Junta o array com o parâmetro passado
join(separator) Converte o array em string separando os valores com o valor do parâmetro
pop() Remove e retorna o último índice
​push(item1, ..., itemN) Adiciona 1 ou mais itens no final do array
​reverse() Inverte o  a
shift() Remove e retorna o primeiro valor
slice(start[, end]) Retorna um subarray
sort([cmpfn]) Ordena, pode-se passar uma função de ordenação
splice(start, delcount[, item1[, ...[, itemN]]]) Modifica o array, deletando uma seção e substituindo por outros elementos
unshift(item1[, item2[, ...[, itemN]]]) Adiciona items no início do array

Callbacks

Pelo fato de funções serem objetos de primeira classe elas podem ser passadas como parâmetros de outras funções. Essa função passada como parâmetro será chamada de callback.
Dentro desta outra função é possível executar a callback ou até mesmo retornar o callback para ser executado posteriormente.
Esta técnica ajuda muito em códigos assíncronos e listeners de eventos

Callbacks - função anônima

function getProfiles(){
    return [
        {name: 'Matias', gender: 'M'},
        {name: 'Maria', gender: 'F'},
        {name: 'Camila', gender: 'F'},
        {name: 'Marcos', gender: 'M'}
    ];
}

function addProfiles(newProfiles, callback){
    // Poderia ser uma inserção ou query em banco
    var profiles = getProfiles();
    var result = profiles.concat(newProfiles);
    callback(result);
}

var newProfiles = [{name: 'Asdrubal', gender: 'F'}];

addProfiles(newProfiles, function(profilesToLog){
    profilesToLog.forEach(function(profile){
	console.log(profile.name);
    });
});

Callbacks - função nomeada

function logProfiles(profilesToLog){
    profilesToLog.forEach(function(profile){
    	console.log(profile.name);
    });
}

Para melhorarar o uso de callbacks, é aconselhado o uso de funções nomeadas, isso melhora a testabilidade do código e evita o famoso problema de callback hell em programas assíncronos

Callbacks - Callback hell

Callbacks - Callback hell

Parecido com o código Hadouken

Callbacks - Parâmetro de erro

profiles = null;

function addProfiles(newProfiles, callback){
    if(profiles){
        profiles.concat(newProfiles);
        callback(false, profiles);
        // Atenção! Sem return teremos um problema
    }
    callback(true, 'Profiles array is not defined');
}

addProfiles(newProfiles, function(error, profilesToLog){
    if(!error){
        profilesToLog.forEach(function(profile){
    	    console.log(profile.name);
        });
    }
});

Uma boa prática é passar um parâmetro indicando sucesso ou erro para a callback

Timers - setTimeout

function showAlert(){
    alert(‘Time out!’);
}

var timeout = setTimeout(showAlert, 5000);

// Cancelando o timer
function cancelAlert(){
    clearTimeout(timeout);
}

Uma forma de adicionar um delay na execução de algumas funções.
Executa uma parte de código depois de um tempo específico uma única vez.

Timers - setInterval

function showLog(){
    console.log('Time out!');
}

var interval = setInterval(showLog, 2000);

// Cancelar o timer
function cancelLog(){
    clearInterval(interval);
}

A diferença entre setTimeout é que o setInterval repete o código indefinidas vezes entre o intervalo definido.

Exercício

8. Crie uma função que recebe dois parâmetros, uma string e uma callback, você deve:

    a. Caso a string não possuir valor, chame a callback indicando que houve um erro

    b. Caso contrário, espere um segundo, inverta a string e chame a callback indicando que houve sucesso, além de retornar a string invertida como segundo parâmetro

 

JavaScript - Parte 1

By Henrique Rotava

JavaScript - Parte 1

  • 1,350