Javascript é uma linguagem de auto nível que segue o padrão ECMAScript. Ela é fracamente tipada e possui tipagem dinâmica, Orientação Objetos baseada em Protótipos e funções como cidadão de primeira classe. Suporta os paradigmas de programação imperativo, funcional e orientada a eventos.
Características
Fracamente Tipada
Uma linguagem fracamente tipada aceita que valores de tipos diferentes sejam atribuídos a uma mesma variável.
Em linguagens fortemente tipadas (como C, C++ e Java), ocorreria um erro no codigo acima. Pois um variável que foi declarada com string, seria permitido receber apenas valores do tipo string.
Tipagem Dinâmica
Uma linguagem pode possuir tipagem Estática ou Dinâmica.
Na Tipagem Estática, quando o tipo da valores que a variável irá receber é determinado na declaração da variável (como ocorre no C, C++ e Java).
Na Tipagem Dinâmica, o tipo de valor da variável é determinado somente no momento que um valor é atribuído a ela.
Podemos usar o comando typeof para determinar o tipo do valor contido na variável.
typeof value
Exemplo:
Number 1
Em Javascript, o tipo Number é uma função e representa tanto números inteiros (Integer) como números de ponto flutuante (Float). Ele apresenta várias operações muito úteis, como no exemplo a seguir.
Exemplo:
Números especiais
Javascript possui alguns valores de números especiais que normalmente não encontramos em outra linguagem: NaN
e Infinity
.
NaN
O valor Nan
(do inglês, Not a Number) é produzido quando o resultado de uma operação retorna um valor que não é um Number.
Exemplo:
Importante:
NaN
é o único valor que não ígual a si mesmo.
Essa peculiaridade vem da regra IEEE utilizada para operações com ponto flutuante. Isso ocorre devido a natureza dos valores que o NaN
pode representar.
Para realizar a verificação se um determinado valor é NaN
, ddevemos utilizar a função isNaN
:
Infinity
É considerado o maior “número” da linguagem, assim como -Infinty
é considerado o menor, com exceção do NaN
. De modo a verificar se um Number assume um dos valores Infinity
, utilizamos a função isFinite
.
Operações aritméticas
O Javascript apresenta alguma excentricidades em relação ao Number que devem ser observadas.
Divisão por zero
Diferente de outras linguagens, o Javascript não irá acusar erro ou disparar uma exceção quando ocorrer uma divisão por zero. Ao invés disso, a linguagem possui o tipo Infinity, um tipo especial para representar valores infinitos.
Operações com tipos diferentes
Por ser fracamente tipada, o Javascript permite alguns tipos de operações envolvendo valores de tipos diferentes.
Chamando funções diretamente
Quando desejado podemos chamar as funções diretamente pelo Number, sem precisar guardar o valor em uma variável primeiro.
Operações com números de ponto flutuante
Em operações com números de ponto flutuante, o Javascript sempre irá retornar o número máximo de casas decimais, seguindo o padrão IEEE 2.
Math 3
O objeto Math nos permite executar tarefas matemáticas, como raiz quadrada, elevar um número a determinada potência, seno e cosseno de um determinado angulo e determinar o máximo e mínimo de um determinado conjunto de valores, entre outras funções.
Math não é um construtor, então todos os metodos do objeto podem ser chamados sem criá-lo (semelhante a funções estática de outras linguagens).
String 4
Em Javascript, uma string pode ser representada tanto por aspas duplas quanto por aspas simples. A string é tratada como uma lista, isso nos permite realizar buscas e cortes na mesma, conforme a necessidade.
Exemplos:
Interpolação e Concatenação de strings
O Javascript, assim como outras linguagens, também apresenta recursos para interpolação e concatenação de strings. Interpolação de Strings seria utilizar uma string como template, onde essa string possui variaveis nas partes de texto que valores reais durante o processo de interpolação.
Exemplo concatenação:
Exemplo interpolação:
O Javascript tentará executar tudo o que esta dentro da chave ${}
. Desde a execução de funções até operações aritméticas.
Boolean 5
Em Javascript, os valores booleanos são representados por true e false. Como ocorre em algumas linguagens, alguns valores também podem representar true ou false quando utilizados em determinados contextos.
Os valores a seguir são considerados true:
true
,1
: ou qualquer inteiro diferente de zero,' '
: string com pelo menos um caracter (mesmo que seja espaço) ,Infinity
: palavra reservada,[]
: array vazio,{}
: objeto literal.
Os valores a seguir são considerados false:
-
false
, -
0
: valor inteiro, -
null
: palavra reservada, -
undefined
: palavra reservada, -
NaN
: palavra reservada (Not a Number).Declaração de variáveis
let e const são substitutos para var, introduzidos no ECMAScript6 e proveem escopo de block para o Javascript. Antes do ES6 (2015), o JavaScript possuia apernas escopo global e escopo de função.
var6
As variáveis definidas com var possuem as seguintes propriedades:
- Devem ser declaradas antes do uso
- Podem ser redeclaradas
- Possuem escopo global ou de função
ECMAScript6 (ES6 / JavaScript 2015) encoraja a declaração de varáveis com let, de modo a evitar alguns possíveis problemas. O primeiro diz respeito ao escopo.
Exemplo:
No exemplo acima, vericamos que o valor impresso nas duas situações foi 10
. Isso ocorre porque var permite a redeclaração de variáveis e redeclar uma variável dentro de um block iŕa redeclará-la fora do bloco. Sendo assim, o Javascript intepretou que as duas variáveis n
eram na verdade, a mesma variável. Por isso o valor impresso foi o valor da última atribuição.
Outro inconveniente de var
é o fato dele permitir o acesso externo de variáveis declaras dentro do bloco {}
.
Exemplo:
Essa liberdade de acesso independente do escopo pode atrapalhar a legibilidade de código e causar erros de inconsistência no estado das variáveis (valor armazenado pela mesma), algo muito importante em linguagens de paradigma funcional.
let 7
As variáveis definidas com let possuem as seguintes propriedades:
- Devem ser declaradas antes do uso
- Não podem ser redeclaradas
- Possuem escopo de bloco
{}
O uso de let resolve os incoveniêntes apresentado pelo uso do var.
Exemplo:
O let não permite a redeclaração de variáveis em um mesmo escopo de bloco {}
. Sendo assim, o Javascript entende que, salvo terem o mesmo nome, as varáveis n
são variáveis diferentes.
O let também não permite o acesso fora do escopo de bloco onde ele foi declarado.
Exemplo:
A tentativa de acesso resultará em um ReferenceError
indicando que a variável nome
não foi definida.
const 8
As variáveis definidas com const possuem as seguintes propriedades:
- Devem ser declaradas e inicializas com um valor antes do uso
- Não podem ser redeclaradas
- Não podem sofrer reatribuição
- Possuem escopo de bloco
{}
Exemplo:
Sempre declaramos uma variável com const quando sabemos que a referência ao qual ela aponta não deve mudar. Recomenda-se o uso de const quando declaramos:
- Um novo array
- Um novo object
- Uma nova Function
O const não define um uma valor constante. Ela define um referência constante a uma valor. Sendo assim, não podemos reatribuir outro object a uma constante, mas podemos alterar os valores do mesmo.
Exemplo:
Hoisting 9
Hoisting é um comportamento padrão do Javascript de mover todas as declaração para o topo do escopo atual (para o topo do script ou da função). Isso permite que variáveis possam ser utilizadas antes de serem declaradas.
É a mesma coisa que:
O Javascript somente executa o hoisting para declarações, não inicializações:
É diferente de:
O Javascript irá indicar que b
esta undefined
. Isso ocorre porque somente a declaração var b
, e não atribuição = 2
, sofreu hoisting para o topo do script. Em outras palavras, ocorre o comportamento semelhante ao seguinte código:
Comportamento para o let e const
Variáveis declaradas com let e const sofrem hoisting para o topo do bloco, mas não são inicializadas. Isso significa que o bloco sabe da existência das variáveis, mas não pode usá-las até que as mesmas sejam declaradas.
Exemplo:
Boas práticas
O funcionamento do hoisting pode causar erros dificeis de depurar caso não saibamos do seu funcionamento e resultar em estados inesperados nas variáveis. De modo a evitar o surgimento de bugs e melhorar a legibilidade do código, é uma boa prática sempre declarar as variáveis no inicio de cada escopo e evitar usar variaveis que ainda não foram declaradas (o uso de let e const evita isso).
Null e Undefined
São valores denominados nullish.
Undefined é utilizado pelo Javascript quando temos uma variável que não foi inicializada com nenhum valor.
Null é utilizado quando queremos evitar que uma variável fique como undefined mas não desejamos atribui nenhum valor a ela.
O Javascript utiliza cópia por referência para atribuição de valores. O mesmo não ocorre para tipos primitivos, onde é utilizada a cópia por valor.
O null também é util quando desejamos reinicializar o valor de um objeto.
Operadores 10
Existem diferentes tipos de operadores em Javascripts e esses são separados nas seguintes categorias:
- Operadores Aritméticos
- Operadores de Atribuição
- Operadores de Comparação
- Operadores Lógicos
- Operadores Condicionais
- Operadores de Tipo
Operadores Aritméticos
São utilizados para executar operações aritméticas de números.
Operador | Descrição |
---|---|
+ | Adição |
- | Subtração |
* | Multiplicação |
** | Exponenciação (ES2016) |
/ | Divisão |
% | Modulo (resto da divisão) |
++ | incremento |
— | Decremento |
Operadores de Atribuição
São utilizados para atribuir valores as variáveis.
Exemplo:
Atribuição Via Desestruturação
No Javascript, uma atribuição via desestruturação (do inglês, destructuring assignment), é uma expressão que permite extrair dados de arrays ou objects em variáveis distintas.
Exemplo com object:
Operadores de Tipo
Operador | Descrição |
---|---|
typeof | Retorna o tipo da variável |
instanceof | Retorma true se um objeto é uma instância de um tipo objeto |
Exemplo:
Operadores de Manipulação de Bits
São operadores de bits utilizados para trabalhar com numeros de 32 bits. Qualquer valor númerico na operação é convertido em um número de 32 bits. O resultado é reconvertido para um Number
.
Operador | Descrição |
---|---|
& | AND |
| | OR |
~ | NOT |
^ | XOR |
<< | left shift |
>> | right shift |
>>> | unsigned right shift |
Estruturas de Controle
As estruturas de controle no Javascript são semelhantes ao encontrado em outras linguagens.
Estrutura IF/ELSE 11
Possui estrutura semelhante ao de outras linguagens com C e Java.
Exemplo:
Se o bloco de código do IF
possuir apenas uma linha, podemos omitir as chaves {}
.
No exemplo acima, como não utilizamos chaves {}
para o IF
, o Javascript interpreta que o bloco de código do IF
contem apenas a linha com o comando console.log('A')
. Sendo assim, a string 'A'
será impressa apenas se condicao
for verdadeira. Por outro lado, a string 'B'
sempre será impressa, independente do valor.
Estrutura Switch 12
Funciona também de modo semelhate ao de outras linguagens.
Exemplo:
É uma boa prática sempre utilizar o default
, de modo a garantir o tratamento para todos os possíveis resultados de expressao
.
Estrutura While e Do While 13
Segue o mesmo funcionamento do while e do do while presente em outras linguagens.
Exemplo:
Exemplo:
Estrutura FOR e FOR/IN
O Javascript nos fornece dois tipos de estrutura de repetição for.
for
: percorre um bloco de código, um determinado número de vezes.for/in
: percorre as propriedades de um objeto.for/of
: percorre os valores das propriedades um objeto .
A seguir, temos alguns exemplos do uso da estrutura for , for/in e for/of e suas descrições.
FOR
O for comum, encontrado em outras linguagens com C
e Java
. É utilizado para percorrer arrays.
Exemplo:
FOR/IN
É utilizado para percorrer as propriedades enumeradas de um objeto. No caso de arrays, temos o seguinte comportamento.
Exemplo:
A variável a
recebeu em cada interação, não o valor contido no array, mas o seu indice. O laço for/in interage sobre propriedades enumeradas de um objeto, na ordem original de inserção.
Para objects, o for/in funciona retornando as propriedades dos objetos, e não seus valores.
Exemplo:
FOR/OF
O for/of foi introduzido no ECMAScript 6 (2015) e é utilizado para interar através dos valores de objetos interaveis. Ele nos permite iterar através de estruturas de dados como Arrays, Sets, Maps e Strings.
Exemplo:
Se tentarmos utilizar o for/of com um object, como no código a seguir:
Isso ocorre porque o objeto Pessoa
não implementa a propriedade que permite a iteração.
Break e Continue
Ainda cobrindo a área de loops, temos dois comandos muito úteis:
break
: comando que “pula fora” do loop.continue
: comando que “pula” uma iteração do loop.
Exemplo break:
No exemplo acima, percorremos o array de nomes, imprimindo cada um deles até encontrarmos um nome que começa com a leta P
. Nesse caso, utilizamos o break
para encerrar o loop for.
Exemplo continue:
No exemplo acima, também percorremos o array de nomes, imprimindo cada um deles até encontrarmos um nome que começa com a leta P
. Nesse caso, utilizamos o continue
para pular para o próximo valor presente no array.
Tratamento de Erros 14
O tratamento de erros em Javascript possui as seguintes palavras chaves:
try
: define o bloco de código a ser executado (obrigatório)catch
: define o bloco de código que irá tratar o erro (obrigatório)finally
: define um bloco de código que será executado indeferente do resultado (opcional)throw
: utilizado para disparar um erro criado pelo usuário.
Exemplo:
Array 15
O array é utilizado para armazenar multiplos valores em uma unica variável. Funciona como uma lista e apresenta os métodos mais conhecidos desse tipo de estrutura de dados.
Exemplo:
Quando atribuimos um valor a um indice que não existe no array, o Javascript irá estender o array, o preenchendo com undefined até o indice desejado, que receberá o valor que foi fornecido.
Exemplo:
Array Destructuring
É um modo prático de extrair valores de um array e atribui-los a variáveis distintas.
Exemplo:
Rest e Spread
O Javascript possui o operador ...
, que facilita trabalhar com lista que não conhecemos a quantidade de elementos. Dependendo do contexto de uso (lado esquerdo ou direito da atribuição), é chamado de operador rest
ou operador spread
.
Rest Elements
Quando o operador ...
aparece do lado esquerdo da atribuição, é denominado como operador rest
. Este operador coleta zero ou mais valores, armazenando-os em um array.
O array resto
que aparece acompanhada do operador é denominado rest elements
.
O elemento
rest
deve ser o último elemento do operação de destructurig.
O exemplo acima irá apresentar um SyntaxError
, porque o rest element não esta no final da operação de destructuring.
Rest Properties
Também podemos aplicar o mesmo conceito do operador rest
para propriedades de objetos.
Exemplo:
Rest Parameters
O operador rest
também pode ser utilizado como parâmento de uma função, possibilitando que passemso um número variável de parametros durante a chamada da função.
Spread
Spread Elements
Quando o operador ...
aparece do lado direto do operador de atribuição, ele é denominado operador spread
. Esse operador expande um array em uma lista de elementos e, diferente do operador rest
, pode ser usado mais de uma vez e em qualquer lugar da expressão.
Spread Properties
Assim como o operador rest
, também podemos utilizar o spread
sobre propriedades de objetos.
Array Analysis
São método nativos para analisar o conteúdo de um array. A maioria desses métodos recebe uma function como parâmetro (denominada predicate) e devolve true ou false como parâmetro. Normalmente são utilizadas no lugar de laços for.
include
Verifica se um array contem um determinado valor.
Exemplo:
every
Verifica se todos os elementos do array cumprem o requisito analisado pela function, retornando true ou false.
Exemplo:
Funcionamento semelhante ao all() em Python.
some
Verifica se pelo menos um dos elementros do array cumpre o requisito analisado pela função, retornando true ou false.
Exemplo:
Funcionamento semelhante ao any() em Python.
find
Retorna o valor do primeiro elemento que satisfaça a condição analisada pela função.
Exemplo:
findIndex
Funciona de forma semelhante ao find(), porém retorna o indice do elemento ao invés do elemento em si.
Exemplo:
Array Transformations
A classe Array possui muitos metodos para manipulação de valores. Esses métodos são denominados puros quando não alteram o array original. Quando os valores do array original são alterados, a função é denominada impura.
Exemplo função pura:
Exemplo função impura:
Object 16
Object é uma function do Javascript. É utilizado para armazenar coleços de chave: valor.
Não confundir object com o formato JSON(Javascript Object Notation). Apesar de serem parecidos, o JSON é um formato textual e aceita apenas aspas duplas como delimitador de texto, enquanto Object é uma notação literal para objetos e aceita tanto aspas simples como aspas duplas para delimitar textos
O exemplo a seguir cria um object com 2 propriedades chave: valor.
O object funciona de modo semelhante ao dict do Python.
Exemplo:
Podemos também utilizar um object como base para a criaçãoi de outro objeto.
Exemplo:
Funções 17
No Javascript, funções são consideradas Objetos de Primeira Classe (do inglês, First Class Object). Isso significa que as funções tem papel central na linguagem e que podemos tratá-la com um dado. Como consequência disso, tanto object como class também sao do tipo function e cada função instânciada é portanto um objeto da classe Function.
Podemos armazenar uma function em uma variável e invocá-la posteriormente.
Passagem de parâmetros
Assim como em outras linguagens, uma function pode aceitar um conjunto de parâmetros de qualquer tipo de modo a executar seu código. Entretanto, em Javascript, passar mais ou menos argumentos do que a quantidade de parâmetros que a function recebe não dispara nenhum erro.
Parâmetros e retornos em Javascript são opcionais.
Exemplo:
Podemos atribuir um valor default para os parâmetros, de modo a evitar que os mesmo fiquem como undefined se nenhum argumento correspondente não forem passados para a function.
Exemplo:
O Javascript também nos permite passar functions como parâmetro.
Exemplo:
Retorno de função
Uma function pode retornar valores de quaiquer tipos, porém pode retornar apenas um valor por vez. Uma function que não retorna valor ou que possui o return ausente, retorna undefined. No Javascript não existem return implicitos.
Exemplo:
Função Anônima
Como funções são membros de primeira classe*, também podemos atribuí-las a variáveis. Esse recurso é muito util em diversas funções do Javascript que muitas das vezes, devido a sua natureza funcional, recebem outras funções como parâmetro.
Exemplo:
Também podemos atribuir uma função como uma property de um objeto.
Exemplo:
Arrow Functions
As funções anônimas também podem ser escritas usando arrow functions. Essa função foi introduzida no ES6 e possibilita uma notação mais exuta da função.
Exemplo:
Função Callback 18
São funções passadas como argumento para outras funções e é executada dentro dessa função para completar algum tipo de rotina. Função de callback são normalmente utilizadas em de assincrono.
Exemplo:
No exemplo acima, quando o botão button
for pressionado, a função printHello
será invocada e mensagem Hello World!
será impresso.
Função Nested (nested function) [^nested-functio]
Uma função é denominada nested (ou aninhada), quando é declara dentro de outra função. Normalmente é utilizada de modo a centralizar um código que ocorre repetidas vezes dentro do escopo da função ao qual ela foi inserida.
Prototypes & Classes
Javascript permite programação orientada a objetos utilizando herança baseada em prototipos.
Prototype Syntax
Constructor Function
Quando uma function é utilizada como template (class), ela é chamada contructor function (o nome da função deve seguir o padrão CamelCase para esse caso). As instâcias (objetos) derivados do template utilizam new para invocar o contrutor do template.
Os objetos criados possuem uma property interna denominada prototype. Essa property é uma relação com a contructor functon. Ela armazena uma referência para a chave prototype da contructor function.
Campos e métodos
Os campos de uma contructor function podem ser acessadas utilizando o this.
Os métodos podém ser acessados usando a property prototype da constructor function.
Class Syntax
Nas versões mais recentes, Javascript trouxe a palavra chave class, utilizada para criação de templates como o mesmo funcionamento de outras linguagens Orientadas a Objetos.
Mesmo com a utilização de classes, Javascript ainda continua sendo uma linguagem baseadas em protótipos.
Os get e set de outras linguagens OO também estão presentes.
Herança de classes
Podemos também utilizar herança entre as classes utilizando a palavra chave extends.