Primeiros passos com JavaScript – part 1

JavaScript é uma linguagem de programação interpretada. Inicialmente foi projectada para rodar em navegadores e dar vida aos websites desenvolvidos na época. JavaScript evoluiu tanto que hoje não é só possível executar-lo no lado do cliente (navegador/browser) como também no lado do servidor, isso graças a plataformas como Node.js. E não fica por aí, com o JavaScript hoje, também é possível criarmos aplicações “nativas” para plataformas móveis usando tecnologias como React Native.

JavaScript sendo uma linguagem interpretada, não há a necessidade de compilar o código para que seja executado. Ou seja, programas escritos em JavaScript podem rodar directamente em qualquer navegador sem a necessidade de processos intermédiarios. Contudo, existem algumas linguagens que foram criadas afim de adicionarem mais recursos à linguagem. Estas linguagens normalmente precisam ser transpilados (traduzidos para código JavaScript) como é o caso do CoffeeScript (que já foi muito utilizado pela comunidade Rails), o TypeScript (que adiciona tipagem forte, criada pela Microsoft), etc.

Apesar do nome JavaScript, vale lembrar que a linguagem não tem nenhuma relação com a linguagem de programação Java.

Para programarmos em JavaScript não precisamos de um ambiente de programação avançando. Basta um navegador e um editor de códigos como o Notepad, Visual Studio Code (o meu favorito), Atom, ou qualquer outro editor de código da sua preferência.

Os navegadores trazem uma ferramenta muito útil na hora de desenvolver com JavaScript. Estou a falar do console que pode ser aberto através das combinações de teclas Opt+Cmd+K (Firefox – meu favorito) ou Cmd+Opt+J (Chrome) ou mesmo através da tecla F12 em outros SOs. No console, podemos testar pequenas instruções em JavaScript assim como ver possíveis erros retornados pelo nosso programa.

Com o nosso ambiente preparado, podemos começar a ver algumas instruções em JavaScript.

JavaScript pode ser incluindo em qualquer parte do nosso documento HTML usando a tag <scritp>. Vamos ver um exemplo,  criando um arquivo index.html com o código abaixo:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <script>
            alert('JavaScript no Cabeçalho do Documento');
        </script>
    </head>
    <body>
        <script>
            alert('JavaScript no inicio do corpo do documento JavaScript');
        </script>

        <p>Conteúdo do nosso documento</p>

        <script>
            alert('JavaScript no final do corpo do nosso documento');
        </script>
    </body>
</html>

Abrindo este o arquivo criando acima no nosso navegador (Firefox é o meu favorito), será apresentado três caixas de alerta seguidas uma da outra.

Há um detalhe aqui que vale prestar atenção e não esquecer, pois é um grande motivo que leva os desenvolvedores web a colocarem o conteúdo JavaScript no final do documento. O detalhe é que o conteúdo apresentável do nosso documento (<p>Conteúdo do nosso documento</p>) só será apresentado depois de clicarmos no botão OK da segunda caixa de alerta. Isso acontece porque o conteúdo do nosso arquivo HTML é lido e interpretado de forma sequencial desde o TOPO até o FINAL do documento. Por isso, recomenda-se colocar o conteúdo JavaScript no final do documento. Isso não só permite que o nosso documento HTML seja carregado mais rápido, como permite que o DOM (Document Object Model) esteja disponível para ser manipulado pelo nosso JavaScript. Sabendo disso, o nosso código JavaScript será sempre colocado no final do documento de agora em diante.

Existe outra forma de incluir JavaScript à nossa página HTML, que é através de arquivos JavaScript (arquivos com extensões  .js) externos ao nosso documento HTML ou mesmo externos ao nosso servidor como veremos no exemplo abaixo:

<!DOCTYPE html>
<html>
    <head>
        <metacharset="utf-8">
    </head>
    <body>
        <p>Conteúdo do nosso documento</p>

        <script
            src="https://code.jquery.com/jquery-3.3.1.min.js"
            integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
            crossorigin="anonymous"></script>
        <script src="scripts.js"></script>
    </body>
</html>

No exemplo acima, adicionamos dois arquivos JavaScript no nosso documento HTML. O primeiro é a biblioteca jQuery localizada num servidor externo e o segundo é o arquivo onde colocaremos o nosso código JavaScript, e o mesmo está localizado no nosso servidor, junto ao nosso arquivo HTML.

O conteúdo do nosso arquivo “scripts.js” poderia ser algo como:
alert("JavaScript no Documento Externo");

* alert é uma função JavaScript que permite criar uma (caixa de) mensagem de alerta.

Sintâxe Básica

A sintaxe de JavaScript é muito parecida com a de outras linguagens de programação como Java e C. As regras/características básicas que definem a sintaxe de JavaScript são:
  • Espaços em branco e mudanças de linhas são ignoradas;
  • O uso de ponto e vírgula no final de cada instrução pode ser opcional quando existe uma quebra de linha.  Minha recomendação é usar sempre o ponto e vérgula no final de cada instrução mesmo quando o seu uso é opcional.
alert('Olá JavaScript');alert('Olá Programador');
alert('Olá JavaScript')
alert('Olá Programador')
  • Tipagem fraca e dinámica – tipagem fraca quer dizer que quando declaramos  uma variável não precisamos especificar o seu tipo de dado. E dinámica porque, a mesma variável pode armazenar diferentes tipos de dados durante a execução de um script. Todas as variáveis são objectos (referência);
  • JavaScript é case-sensitive, ou seja, diferencia maíuscula de mínusculas. O que quer dizer, “let” é diferente de “LET“.
  • Comentários em JavaScript são ignorados durante a execução do Script; nos permitem documentar o código; Comentários podem ser de uma linha “//” ou de múltiplas linhas “/* … */” :
// Este é um comentário de uma linha
alert("Olá Mundo");

alert("Olá Mundo"); // Este é comentário de uma linha

/* Exemplo de um comentário
de múltiplas linhas.
*/
alert("Bem vindo ao JavaScript");

Variáveis

Muitas vezes quando estamos a programar, precisamos guardar dados para uso posterior. Para este fim usamos as variáveis.

Para criarmos (declararmos ou definirmos) uma variável em JavaScript, usamos a palavra-chave “let”. A instrução abaixo cria uma variável com o nome “idade”:

let idade;

A variável acima foi inicializada com o valor “undefined” ou seja, valor não definido. Podemos atribuir valor à nossa variável usando o sinal de igualidade (operador de atribuição):

idade = 25;

A declaração de uma variável e a respectiva atribuição de  valor pode ser feira numa mesma  linha (instrução):

let idade = 30;

Uma vez que atribuímos um valor inteiro à nossa variável “idade”, ela passa ser do tipo INTEIRO (INTEGER). Contudo, como JavaScript é uma linguagem de tipagem dinámica, eu posso reatribuir um outro valor à variável e mudando assim o seu tipo como segue abaixo:

let peso = 92;
peso = "Acima da Média".

Na primeira linha, a nossa variável é do tipo inteiro porque atribuímos um valor INTEIRO a ela. Já na segunda linha, não estamos a redeclarar a variável mas a reatribuir um valor a ela. Sendo o novo valor uma String (cadeia de caracteres), a variável passa a ser do tipo String.

Uma string é uma cadeia de caracteres delimitadas por aspas duplas ou aspas simples. Abaixo estão as declarações válidas de variáveis de tipo String:

let nome = "Patrício dos Santos";
let morada = 'Luanda - Angola';
let texto = `${nome} vive em ${morada}`; // retorna o texto: "Patrício dos Santos vive em Luanda - Angola"

Podemos declarar várias variáveis e atribuir os respectivos valores numa mesma lista. Separamos as variáveis com vírgula como segue abaixo:

let nome = "Firmino Changani", titulo = "Fullstack Node.js Developer";

console.log(nome);
console.log(titulo);
Resultado da execução do código acima

Apesar de deixar mais curto o nosso código, ela pode comprometer a legibilidade do mesmo. Por isso precisa ser evitado.

A declaração de variáveis também por ser feita usando a palavra-chave “var“:

var cidade = "Luanda";

Actualmente já não se usa muito esta forma pelo que seu uso é desaconselhado. Num próximo artigo falarei mais a fundo sobre a diferença entre “var” e “let“.

Existem algumas regras que devem ser seguidas na hora de declarar variáveis:

  • Nome de variáveis devem conter apenas letras, dígitos, caracteres $ e _ (underscore).
  • O primeiro caracter não pode ser um dígito.
let nomeCompleto; // válido
let caso2; // válido
let 2caso; // inválido
  • Quando nomes de variáveis são compostas por duas ou mais palavras, usa-se o camelCase. Ou seja, as seguintes palavras têm a primeira letra em maiuscula, como por exemplo: “minhaVariavelLonga“.
  • Palavras reservadas (palavras-chave) não podem ser usadas como nome de variáveis. “let“, “return“, “const” são exemplos de palavras reservadas que não podem ser usadas como nome de variáveis.

Já dissemos acima que JavaScript é uma linguagem case-sensitive. Neste caso, “nome” e “Nome” são duas variáveis completamente diferentes.

Normalmente, devemos declarar uma varíavel antes de usá-la. Contudo, no passado, era tecnicamente possível usar uma variável atribuindo um valor a ela antes de declara-la. O comportamento padrão dos browsers aceitam isso hoje para manter a compatibilidade com scripts antigos.

idade = 25; // a variável "idade" é criada
console.log("idade"); // mostra o número 25 na consola do navegador

Contudo, está é uma má prática. Podemos forçar a declação de uma variável antes do seu uso usando o “strict mode”:

"use strict";

idade = 25; // esta linha gera um erro na consola e o nosso script não é executado correctamente.
Erro ao tentar usar uma variável não declarada no strict mode.

Nota: O “use strict” deve sempre ser declarada no início do documento JavaScript. Como a primeira linha do nosso arquivo. Caso contrário, não funciona.

Constantes

Quando falamos em constantes, estamos a falar de espaços reservados na memória onde armazenamos valores que não mudam com o tempo. O valor do PI por exemplo, não munda nunca. Logo, é o candidato perfeito para ser uma constante.

Para declararmos uma constante em JavaScript, utilizados a palavra reservada “const” seguido do nome da constante e do respectivo valor atribuído. Ou seja, não podemos declarar uma constante sem atribuir-lhe um valor como se pode fazer com as variáveis.

const PI = 3.14;

const MINHA_CONSTANTE; // retorna um erro. Pois não atribuímos um valor à nossa constante

Diferente das variáveis, uma vez declarada a constante, não podemos mudar o seu valor (reatribuir valor à constante), por isso se chama constante.  O código abaixo irá causar um erro (error, can’t reassign the constant!):

const DATA_DE_NASCIMENTO = '12/03/2018';
DATA_DE_NASCIMENTO = '12/03/1965'; // error, can't reasign the constant!

Regra geral, nomes de constantes devem ser em letras maíusculas, apesar de existir excepções onde de pode declarar constantes em camelCase.

Tipos de Dados

Uma variável em JavaScript pode armazenar qualquer dado. E num dado momento este dado pode ser do tipo String e noutro pode ser um tipo númerico. Isso porque JavaScript é uma linguagem de tipagem dinámica.

let idade = "25";
idade = 38; // funciona sem erro. E a variável passa a ser do tipo numerico e não mais string.

JavaScript suporte 7 tipos de dados básicos, que são:

  • String: Cadeia de caracteres que podem ser delimitados por aspas simples ( ‘ ), aspas duplas ( ” ) ou backticks (acento grave) ( ` ). O resultado sempre será o mesmo
// Todas as declarações abaixo são String válidas
let nomeNodeDev = "Firmino Changani";
let nomeGameDev = 'Keven Chantre';
let sexo = "M";
// backkstick é útil quando queremos embutir o valor de uma variável numa String (interpolação):
let frase = `O nome do dev de games é ${nomeGameDev}`; // o nome do dev de games é Keven Chantre.
  • Number: Usado para representar qualquer tipo de número. Inteiro ou Ponto-flutuante (decimal).
let idade = 68; // tipo inteiro
let altura 1.87; // tipo decimal

Existem ainda para tipos númericos aqueles que podemos chamar de “valores númericos especiais” que são: Infinity (Infinito), –Infinity (menos Infinito) e NaN (lê-se “Not a Number” – Não é um número).

Infinity representa o infinito matemátio ( ∞ ). É um valor especial que é maior do que qualquer número que possamos representar. E o -Infinity é menor do que qualquer número que possamos representar.

Em JavaScript, diferente de outras linguagens, qualquer número que dividirmos por 0 (zero) retornará infinito.

let resultado = 3 / 0; // o valor de "resultado" será Infinity

NaN (not a number) representa um erro computacional. Trata-se de um resultado matemático incorrecto ou indefenido.

let resultado = "string qualquer" / 2;
console.log(resultado);

Se rodarmos o código acima, o resultado será NaN. Pois não podemos dividir uma String por um Número – O resultado nunca será um número :).

 

  • Boolean: variável de tipo booleano suporta apenas dois valores que podem ser true (verdadeiro) ou false (falso). Ou seja, valores lógicos.
let isAdmin = true;
let isManager = false;
  • Undefined: Este tipo possui apenas um valor (undefined). Representa um valor não definido que é atribuído automaticamente a qualquer variável declarada e não inicializada.
let pais;
console.log(pais); // mostra no console do navegador o texto "undefined"
  • null: Assim como o tipo undefined suporta apenas um valor, o mesmo acontece com o tipo “null”, que suporta apenas o valor “null”. Serve para representar um valor vazio ou desconhecido.
let urlPerfilFacebook = null;
  • object: O tipo object é um tipo especial que serve para representar estruturas mais complexas como vectores (arrays – colecção de dados do mesmo ou diferentes tipos). Os outros tipos acima são chamados de primitivos porque podem conter apenas um único valor. Já objectos podem armazenar coleções de dados e entidades mais complexas.
// apesar de ser um array com dados do mesmo tipo,
// podemos usar diferentes tipos da mesma colecção
let programadores = ['Leandro Landin', "Célio Garcia", "Firmino Changani", "Keven Chantre"];

// para acessar o valor de um array, usamos o índice deste valor.
// JavaScrip, assim como outras linguagens começa a contar do 0 (zero)
console.log(programadores[1]); // Célio Garcia

console.log(programadores[3]); // Keven Chantre

Arrays são estrutruras que usam índices (números inteiro) como vimos acima, para acessar os seus valores. contudo, podemos criar objectos com propriedades (chaves nomeadas):

let programador = {
    nome: "Firmino Changani",
    titulo: "Full-stack Node.js Developer"
};

// podemos acessar as propriedades deste objecto usando o . (ponto).
console.log(programador.nome); // Fimirno Changani
  • symbol: Este tipo foi introduzido no ECMAScript 6; é usado para criar identificadores únicos para objectos (objects).

Operadores

Operador typeof

O operador `typeof` retorna o tipo de dado do argumento passado. Muito útil quando queremos dar um tratamento específico para diferentes tipos de dados.

typeof undefined; // "undefined"

typeof("Patrício dos Santos"); // string

typeof [1, 2, "qualquer", Symbol("nome")]; // object

typeof(Symbol("nome")); // "symbol"

Operador de atribuição

Já temos utilizado este operador deste o início do nosso artigo. É o operador que nos permite atribuir um valor específico à uma variável ou constante. O sinal de igualidade , assim como em outras linguagens, é utilizado como operador de atribuição.

let idade = 30; // atribuímos o valor 30 à variável idade

let linguagem = "Ruby"; // atribuímos o texto "Ruby" à variável linguagem

Operadores aritméticos

Nos permitem realizar operações matemáticas sobre os tipos numericos. Os operadores aritméticos são: adição ( + ), subtração  ( – ), multiplicação ( * ) e divisão ( / ). Podemos incluir também nesta lista o operador “módulo” ( % ) que retorna o resto de uma divisão.

let soma = 5 + 15;
console.log(soma); // 20

let num1 = 30; num2 = 15;
let subtracao = num1 - num2;
console.log(`${num1} + ${num2} = ${subtracao}`); // 30 - 15 = 15

// multiplicação
console.log(`${6 * 6}`}; // 36

// divisão
let num = 3;
let resultado = 9 / num;
console.log(resultado); // 3

// Resto da divisão usando o módulos:
let resto1 = 4 % 2;
let resto2 = 5 % 2;
console.log(resto1); // 0
console.log(resto2); // 1

Os operadores aritécticos funcionam apenas com tipos númericos. Contudo, existe uma excepção com o operador da soma ( + ) que funciona com tipo String, não para somar mas para concatenar.

let resultado = "10" + 5;
console.log(resultado); // 105

let palavra1 = "Ruby";
let palavra2 = "Rails";
let frase = palavra1 + " on " + palavra2; // Ruby on Rails

console.log("Java" + "Script"); // JavaScript

Incremento ( ++ ) e Decremento ( — )

Estes operadores servem para incrementar e decrementar por uma unidade o valor de uma variável. Elas funcionam apenas com tipos numericos.

let numero = 100;
let numero_seguinte = numero++;
console.log(numero_seguinte); // 101

let numero2 = 50;
let numero_anterior = numero2--;
console.log(numero_anterior); // 49

Os operadores de incremento e decremento podem ser utilizados como prefixo (++numero/–numero) ou como sufixo (numero++/numero–). A diferença é que quando usamos como sufixo, primeiro é feita a operação sobre a variável ou o valor e só depois o incremento acontece e como préfixo, primeiro é feito o incremento ou decremento e só depois a operação é avaliada como um todo.

let num1 = 10;
let num2 = 20;
let sufixo = num1++ + 10;
console.log(sufixo); // 15
console.log(num1); // 11

let prefixo = ++num2 + 5;
console.log(prefixo); // 26
console.log(num2); // 21

Podemos combinar os operadores aritmeticos com o operador de atribuição para incrementar valores maiores de 1. Normalmente, também são chamados de operadores de atribuição.

// imagina que queremos incrementar 5 unidades à nossa variável peso:
let peso = 10;
peso = peso + 5; // o valor de peso agora seria 5

//O mesmo podemos fazer com outros operadores aritméticos:
let numero = 5;
numero = numero * 5; // 25

//Existe uma forma curta de fazer isso:
let peso1 = 10;
peso1 += 5; // 15
let peso2 = 5;
peso2 *= 5; // 25

Operadores de comparação

Servem para comparar dois ou mais valores. Retornam valores to tipo booleano. Ou seja, true ou false.

// igualidade
10 == 10 // true
"10" == 10 // true
"10" === 10 // false - três sinais de igualidade compara além do valor, o tipo
5 == 20 // false

// maior e menor
let num1 = 10;
let num2 = 20;
num1 > num2; // false
num2 < num2; // true
num1 >= num2 // false
num1 <= num2 // true

// desigualidade / diferente
"10" != 10 // false
"10" !== 10 // true - compara também o tipo
40 != 10 // true

Em combinação com os operadores de comparação, também podemos utilizar o operador ternário. Para entermos o que este operador faz, vamos ver um exemplo:

let idade  = 17;
let resultado = idade >= 18 ? "maior de idade" : "menor de idade"; // o valor de resultado será "menor e idade"

Ou seja, atribui valor à uma variável mediante a avaliação booleana.

Operadores lógicos

São operadores que nos permitem obter o valor lógico (true ou false) entre valores ou variáveis. Elas são o E (&&) – conjunção, OU ( || ) – disjunção inclusiva e o NÃO ( ! ) – negação.

// true && true = true
10 > 5 && 5 < 10 // true

// true && false = false
10 > 5 && 5 == 10 // false

// true || false = true
// false || false = false
10 > 5 || 5 == 10 // true
10 == 20 || 3 > 10 // false

// ! true = false
// ! false = true
!(10 == 20) // true
!(25 === 25) // false

 

O artigo ficou muito logo. Por isso ficaremos por aqui hoje. Na segunda parte falarei estruturas de controlo, funções e estruturas de repetição.

,,