Como desenvolver games para Smart TVs – Parte 02

Continuando nosso mini curso hoje vamos compreender que as Smart TVs são divididas em 3 principais grupos quando o assunto é desenvolvimento de games ou apps.

Logo abaixo dividimos os em 3 principais grupos com seus respectivos fabricantes, sistemas operacionais e tecnologias utilizadas:

1 – Samsung – TIZEN (Html, Css e JavaScript)

2 – LG – WebOS (Html, Css e JavaScript)

3 – SONY – Android TV – (Java Android)

A princípio vamos nos concentrar nos dois primeiros grupos em nosso curso. Observem um detalhe, tanto a Samsung como a LG apresentam em comum as mesmas tecnologias para desenvolvimento, entretanto há diferenças na prática, ou seja, suas implementações são bem distintas.

O ideal seria que o aluno já tenha algum conhecimento em HTML, CSS e JavaScript ou jQUERY, mas vamos fazer uma breve introdução das 3 tecnologias a seguir:

HTML

HTML é uma das linguagens que utilizamos para desenvolver websites. O acrônimo HTML vem do inglês e significa Hypertext Markup Language ou em português Linguagem de Marcação de Hipertexto.

O HTML é a liguagem base da internet. Foi criada para ser de fácil entendimento por seres humanos e também por máquinas, como por exemplo o Google ou outros sistemas que percorrem a internet capturando informação.

Quem criou o HTML?

Tim Berners-Lee. Esse é o nome do homem que criou o HTML. Ele criou o HTML para a comunicação e disseminação de pesquisas entre ele e seu grupo de colegas. O HTML ficou bastante conhecido quando começou a ser utilizada para formar a rede pública daquela época, o que se tornaria mais tarde a internet que conhecemos hoje.

O que são as tags do HTML?

O HTML é uma linguagem baseada em marcação. Nós marcamos os elementos para mostrar quais informações a página exibe. Por exemplo, um título importante. Aquele título do artigo, da manchete do site, nós marcamos com uma tag/elemento chamado H1. Veja um exemplo:

<h1>Aqui vai o texto do título</h1>

Perceba que o texto está entre duas marcações. Essas marcações são chamadas de TAGS. As tags são abertas e depois fechadas. No exemplo acima abrimos a tag com

e fechamos com

. O que está dentro é o conteúdo mostrado para o usuário.

O parágrafos são marcados com a tag P. Assim:

<p>Aqui vai o texto do parágrafo. 
Geralmente parágrafos tem muitas palavras, 
letras menores que as do título</p>

Utilizando as tags, nós dizemos para o navegador o que é cada informação. O que é um título, o que é um parágrafo, o que é um botão, um formulário etc. Dizemos também o que é cada coisa para os sistemas de busca, como o Google. O Google, nesse caso, para exibir os resultados de busca, ele precisa saber o que é um parágrafo e o que é um título. Ele sabe disso através das tags.

A estrutura básica

Todo HTML começa do mesmo jeito. Não há segredos aqui. Você pode simplesmente copiar em algum lugar para usar esse código toda vez iniciar um novo HTML.

<!DOCTYPE html>

<html lang="pt-br">
<head>
    <meta charset="utf-8">
    <title>Título da página</title>
</head>
<body>
 ... aqui vai todo o codigo HTML que faz seu site...
</body>
</html>

A primeira linha se chamada DOCTYPE. O Doctype avisa aos browsers, robôs de busca, leitores de tela e outras coisas que tipo de documento e aquele que eles estao prestes a carregar. Existem outros códigos que podemos carregar, por exemplo XML. Por isso o Doctype avisa o browser para que ele saiba como se comportar ao ler o código.

Depois começamos com a Tag HTML. Isso quer dizer que todo o que estiver entre as tags é escrito em HTML. Ao lado da palavra HTML tem um atributo (explico o que são atributos mais pra frente) chamado lang, onde indicamos qual o idioma do texto que escreveremos.

Logo após a tag html temos a tag . Na tag Head nós indicamos o título do documento e indicamos a tabela de caractéres que o browser deve usar para renderizar seu texto. Também não se preocupe com isso agora.

A tag <tittle> é muito importante. É com ela que você indica o título do documento. O Google e outros sistemas de busca utilizam essa tag para indicar em suas buscas o título da págin. Isso é muito importante para que você apareça bem nas buscas.

Logo depois da tag de fechamento começamos a tag . Dentro deste elemento é que vamos escrever todo o código HTML do resto do site.

<!DOCTYPE html>

<html lang="pt-br">
<head>
    <meta charset="utf-8">
    <title>Título da página</title>
</head>
<body>
   <h1>Aqui vai o texto do título</h1>
   <p>Aqui vai o texto do parágrafo. 
   Geralmente parágrafos tem muitas palavras, letras menores que as do título</p>
</body>
</html>

Criando seu primeiro HTML

Para criar seu HTML é muito simples. Primeiro, abra e crie um arquivo vazio, sem texto, com o nome index.html. Utilize o Notepad (se estiver no windows) ou o TextEdit (se estiver no Mac).

Perceba que a extensão do seu arquivo é .html e não .txt

Feito isso, copie o código utilizado no exemplo acima e cole neste documento. Salve e abra no seu navegador. Voilá! Você fez seu primeiro arquivo HTML

Um pouco avançado: Desenvolvimento em Camadas

Um dos principais problemas no desenvolvimento para internet é a mistura dos diversos códigos. Nós não usamos apenas o HTML para fazer sites. Além do HTML, utilizamos ainda o CSS, que é uma linguagem para configurarmos o visual das páginas e o Javascript, que vai cuidar do comportamento da página, por exemplo, o que acontece quando o usuário clica em um botão.

Há também as linguagens chamadas Linguagens Server-Side, que são linguagens como PHP, Python, Ruby, ASP e etc. Essas linguagens fazem tudo funcionar. Elas fazem os cálculos nos servidores e dão a resposta para o navegador do usuário.

Para que os códigos não se misturem, nós os separamos em diversas camadas. Para ficar mais fácil de entender, imagine que o HTML é sempre o esqueleto do site. É com ele que vamos fazer toda a estrutura de código, onde iremos dizer o que é um título, o que é um parágrafo, uma imagem e etc. 

O CSS será a parte externa do corpo. É o que deixará o esqueleto bonito. É com o CSS que iremos dar cor para o título, configurar o tamanho do texto, largura das colunas e etc.

Dessa forma nós não misturamos o código HTML e o código CSS. Utilizamos a mesma ideia para separar os outros códigos citados acima.

O que é CSS?

CSS é chamado de linguagem Cascading Style Sheet e é usado para estilizar elementos escritos em uma linguagem de marcação como HTML. O CSS separa o conteúdo da representação visual do site. Pense  na decoração da sua página. Utilizando o CSS é possível alterar a cor do texto e do fundo, fonte e espaçamento entre parágrafos. Também pode criar tabelas, usar variações de layouts, ajustar imagens para suas respectivas telas e assim por diante.

CSS foi desenvolvido pelo W3C (World Wide Web Consortium) em 1996, por uma razão bem simples. O HTML não foi projetado para ter tags que ajudariam a formatar a página. Você deveria apenas escrever a marcação para o site.

Tags como <font> foram introduzidas na versão 3.2 do HTML e causaram muitos problemas para os desenvolvedores. Como os sites tinham diferentes fontes, cores e estilos, era um processo longo, doloroso e caro para reescrever o código. Assim, o CSS foi criado pelo W3C para resolver este problema.

A relação entre HTML e CSS é bem forte. Como o HTML é uma linguagem de marcação (o alicerce de um site) e o CSS é focado no estilo (toda a estética de um site), eles andam juntos.

CSS não é tecnicamente uma necessidade, mas provavelmente você não gostaria de olhar para um site que usa apenas HTML, pois isso pareceria completamente abandonado.

Vantagens do CSS

A diferença entre um site que implementa CSS e outro que não o usa é gigantesca e notável.

Você já deve ter visto um site que não carrega completamente ou tem um plano de fundo branco com texto azul e preto. Isso significa que a parte CSS do site não foi carregada corretamente ou não existe.

E é assim que um site somente com HTML se parece. Acredito que você vai concordar comigo de que isso não é muito bonito, certo?

Antes de usar CSS, toda a estilização tinha que ser incluída na marcação HTML. Isso significa que você deveria descrever separadamente todo o plano de fundo, as cores das fontes, os alinhamentos, etc.

Mas o CSS permite que você estilize tudo em um arquivo diferente, criando assim o estilo separadamente. E, mais tarde, faça integração do arquivo CSS na parte superior da marcação HTML. Isso mantém a marcação HTML limpa e fácil de manter.

Resumindo, com o CSS você não precisa mais escrever repetidamente como os elementos individuais se parecem. Isso economiza tempo, encurta o código e diminui a chance de erros.

O CSS permite que você tenha vários estilos em uma página HTML, tornando as possibilidades de personalização quase infinitas. Hoje em dia, isso está se tornando mais uma necessidade do que um simples recurso.

Como CSS Funciona

O CSS é uma ferramenta muito potente que possibilita criar diversas funcionalidades ao invés de usar JavaScript ou outra linguagem mais pesada. Se usado com moderação, CSS pode viabilizar uma ótima experiência ao desenvolvedor e usuários das páginas web.

Com o Cascading Style Sheets é possível criar animações complexas, criar efeitos com uso de parallax, que faz parecer que a imagem de fundo tem uma profundidade diferente um dos outros, criar sites interativos e também jogos com HTML5 e CSS3.

O CSS usa uma sintaxe simples baseada em inglês com um conjunto de regras que o governam. Como mencionamos anteriormente, o HTML nunca teve a intenção de usar elementos de estilo, apenas a marcação da página. Foi criado para descrever apenas o conteúdo. Por exemplo: <p>Este é um parágrafo.</p>.

Mas como você estiliza o parágrafo? A estrutura da sintaxe CSS é bem simples. Tem um seletor e um bloco de declaração. Você seleciona um elemento e depois declara o que deseja fazer com ele. Bastante simples, certo?

Mas tem algumas regras que você precisa saber. Isso também é simples, não se preocupe.

O seletor aponta para o elemento HTML que você deseja estilizar. O bloco de declaração contém uma ou mais declarações separadas por ponto e vírgula.

Cada declaração inclui um nome de propriedade CSS e um valor, separados por dois pontos. Uma declaração CSS sempre termina com um ponto-e-vírgula e os blocos de declaração são cercados por chaves.

Vamos ver um exemplo:

Todos os elementos <p> serão estilizados e serão coloridos de azul e negrito.

  1. <style>
  2. p {
  3. color: blue;
  4. text-weight: bold;
  5. }
  6. <style>

Em outro exemplo, todos os elementos <p> serão centralizados, com tamanho 16x e de cor pink.

  1. <style>
  2. p {
  3. text-align: center;
  4. font-size: 16px;
  5. color: pink;
  6. }
  7. </style>

Anatomia de um comando CSS

O CSS estipula regras para o arquivo em html. Com cada regra é possível estilizar o conteúdo todo ou somente determinados elementos. Por isso entenda, um comando básico é composto por seletor e declarações, que contém propriedade e valor.

SELETOR {PROPRIEDADE: VALOR}

A sintaxe do CSS é muito simples de aprender. O seletor seleciona quais elementos em html receberão a propriedade. Pode ser p (parágrafo) ou o body (corpo da sua página). Já a propriedade pode ser a cor ou algo mais específico como cor do fundo (background). E por último o valor, que determina o valor da propriedade.

Vamos simular um exemplo. Digamos que o objetivo é mudar a fonte de uma tag h1. Para isso podemos usar h1 {font-size: 20px;}

  • h1 – é o seletor. Neste caso selecionamos o h1.
  • font-size – é a declaração que contém  a propriedade (font-size) e o valor é (20px).

Lista de comandos básicos CSS

São tantas opções entre seletores, propriedades e valores que pode ser muito difícil para um desenvolvedor lembrar de todos eles apenas confiando na memória. Por isso decidimos criar uma Lista de Comandos Básicos CSS (CSS3 Incluso) que servirá de ajuda para você que está aprendendo sobre o que é CSS.

 Este documento foi estrategicamente estruturado e dividido em seções para facilitar sua leitura. Faça download da Lista de Comandos CSS em PDF clicando aqui e aprofunde seus conhecimentos sobre o que é CSS.

Estilos CSS Interno, Externo e Inline

Analisaremos cada estilo de forma rápida! Para uma explicação detalhada, acesse o link que vamos disponibilizar logo abaixo.

Vamos começar com o estilo interno. Estilos CSS feitos desta forma são carregados cada vez que um site é atualizado, o que pode aumentar o tempo de carregamento. Além disso, você não poderá usar o mesmo estilo CSS em várias páginas, pois está contido em uma única página. Mas a vantagem disso é que ter tudo em uma página facilita o compartilhamento do modelo para uma visualização.

O método externo pode ser o mais conveniente. Tudo é feito externamente em um arquivo .css. Isso significa que você pode fazer todo o estilo em um arquivo separado e aplicar o CSS a qualquer página desejada. O estilo externo também pode melhorar o tempo de carregamento.

Por fim, tem também o estilo Inline do CSS. Inline trabalha com elementos específicos que possuem a tag <style>. Cada componente deve ser estilizado, por isso talvez não seja o melhor ou o mais rápido para lidar com CSS. Mas pode ser útil, por exemplo, para alterar um único elemento, visualizar rapidamente as alterações ou se não tiver acesso aos arquivos CSS.

Como Criar uma Folha de Estilo

Para criar uma folha de estilos é bem simples. Basta abrir seu editor de códigos, como o Sublime, e criar um documento novo.

Depois de criado, salve como estilo.css, mesmo sem ainda ter escrito nada (este .css é o que define um arquivo ser reconhecido pelo navegador como a folha de estilo).

Como criar um folha de estilo CSS

Assim que for salvo, o editor de texto vai conseguir ler o arquivo com mais facilidade, até mesmo com sugestões de auto complete enquanto digita os códigos da folha de estilo, como mostra o print abaixo:

Como integrar o CSS no HTML?

Após salvar como estilo.css precisamos colocar o arquivo em nosso arquivo HTML, porque é ele quem vai carregar o CSS, o CSS sozinho não faz site! E é com tags de referência que você avisa ao HTML que existe um arquivo de estilo para ele, veja:

<link rel=”stylesheet” type=”text/css” href=”estilo.css”>

Esta tag vai indicar ao HTML que tem um arquivo CSS para ser adicionado à  página. Isto deve ser adicionado dentro da tag <head> </head> do seu HTML, como pode ver nesse print abaixo.

Como incorporar CSS no Html

Agora abra o documento estilo .css com o Sublime, que provavelmente está na mesma pasta do nosso HTML.

Incorporando CSS no HTML

A partir desta última imagem, vamos entender como o CSS funciona com três parâmetros básicos:

Elementos Básicos do CSS

Os elementos são tags do HTML, #id e .classe.

1. Tags HTML

  1. body
  2. h1
  3. h2
  4. h3
  5. h4
  6. h5
  7. h6
  8. span
  9. p

2. Classes CSS

Criar e usar uma classe CSS é simples. No documento CSS basta colocar .nome-da-classe-que-deseja . Abaixo criamos a classe título:

Criando classes no CSS

Note que existe um ponto (.) antes do nome da classe. Isso faz com que o CSS entenda que se está criando uma classe para ser usada no HTML.

Para se adicionar essa classe que criamos dentro do CSS, basta que na tag HTML tenha o parâmetro class=””.

Observação: dentro das aspas, não precisa usar o ponto (.) antes da classe pois o nome class no HTML já avisa para o CSS que é para ele buscar pelo nome da classe com “.”

Criando classe título no CSS

Lembrando que uma tag HTML, como h1 ou qualquer outra, pode ter mais de uma classe, basta separá-las com espaço como mostra no exemplo abaixo:

<h1 class=”titulo fonte-grande sublinhado”>Melhor site</h1>

Nesta tag foram usadas três classes: “titulo”, “fonte-grande” e “sublinhado”.

Mas para que todas estas classes tenham efeito épreciso criá-las no CSS. Veja como criamos estas classes:

Criando diversas classes no html
Exemplo de uso de CSS

Quando abrirmos nosso HTML o título deverá ficar assim:

3- Criando ID’s CSS:

O uso dos ID’s em CSS é parecido com as classes, mas as principais diferenças são que os id’s são identificados com # e só podem ser usados um id por tag html. Para adicionar um ID ao HTML, adicione como parâmetro id=””.

Veja que a quando usamos no HTML, também excluímos o #  do id da mesma forma que excluímos o . da classe.

Criando ID no CSS

Dessa forma, o botão deverá ficar assim:

criando botão com CSS

DICA: Este parâmetro de ID’s não é o mais apropriado para se usar em uma página para muitos botões pois pode causar conflitos com a linguagem de programação JavaScript, que utiliza normalmente dos ID’s no HTML para realizar ações mais complexas.

Como adicionar CSS no HTML sem a tag <link>?

Existem duas outras maneiras de se adicionar CSS no HTML, apesar de não serem recomendadas devido a um padrão adotado mundialmente, é nosso dever te mostrar como faz.

1- Adicionar CSS no HTML sem uso do arquivo externo

Você pode adicionar o CSS colocando o estilo dentro do próprio HTML, sem usar um arquivo CSS externo como mostra o exemplo abaixo:

Como adicionar CSS no HTML sem a tag link

Neste exemplo, o estilo fica dentro do HTML mesmo com o uso da tag <style> dentro da tag <head>. Isso faz com que tudo fique centralizado em um único documento.

E por que não é recomendado? Quando há muitas linhas de estilo isso pode causar uma demora ao abrir a página uma vez que o navegador lê o seu documento de cima para baixo, linha por linha. Então se tiver muitas linhas de estilo para ler, vai demorar mais para o conteúdo da página ser mostrado.

Por isso, o ideal é usar a tag <link> para que, ao invés de ler muitas linhas de estilo, o navegador leia somente uma referência para outro arquivo e assim fazer com que seu conteúdo seja carregado mais rapidamente.

2- Adicionar CSS no HTML utilizando o parâmetro style

Você pode adicionar CSS no HTML utilizando o parâmetro style em uma tag html específica. Mas isso afetará somente aquela tag e não todas as demais tags com o mesmo nome. Então, ao invés de usarmos os parâmetros id=”” ou class=””, utilizaremos o parâmetro style=””:

<h1 style=”font-size: 3rem;color: #333;text-align: center;”>

Veja como fica:

Adicionando css no html com parâmetro Style

E por que não é recomendado? Este tipo de uso de estilos se torna um problema caso outros elementos tenham as mesmas características do seu título, por exemplo. Com isso, você teria que copiar todo o parâmetro style da tag h1.

Diante de disso, concluímos também que o mais recomendado é o uso de classes através de um arquivo de estilo externo ao CSS. Assim, conseguimos usar os estilos de forma mais limpa e rápida e é possível reutilizar essas classes em outras tags sempre que desejar, sem afetar o tempo de carregamento da página.

CSS3

Apesar de lançada em 2010, CSS3 é a última versão da Folha de Estilo em Cascata e veio para acrescentar de forma melhorada das versões anteriores.

A melhor novidade é em relação a flexibilidade na criação de layouts, trazendo mais autonomia para os webdesigners e também desenvolvedores, que de certa forma estão ligados ao visual do site.

Com o CSS3, é possível elaborar cantos arredondados, sombras, efeitos gradientes, animações e efeitos de transição, dentre outras opções.

Alguns exemplos:

@keyframes exemplo {
    0% {background-color: red;}/*a animação começa vermelho*/
    50% {background-color: yellow;}/*a animação chega na metade em amarela*/
  100% {background-color: red;}/*a animação termina vermelha novamente*/

}
div {
    width: 100px;/*largura do elemento*/
    height: 100px;/*altura do elemento*/
    background-color: red;/*cor do inicial do elemento*/
    animation-name: exemplo;/*aqui vem o nome da animação*/
    animation-duration: 4s;/*tempo da duração do inicio ao fim*/
  animation-iteration-count:infinite;
}

E no html basta colocar a tag <div></div> e a animação começará assim que o estilo conteúdo do site for carregado.

O que é JavaScript?

JavaScript é uma linguagem de script orientada a objetos, multiplataforma. É uma linguagem pequena e leve. Dentro de um ambiente de host (por exemplo, um navegador web) o JavaScript pode ser ligado aos objetos deste ambiente para prover um controle programático sobre eles.

JavaScript  tem uma biblioteca padrão de objetos, como: ArrayDate, e Math, e um conjunto de elementos que formam o núcleo da linguagem, tais como: operadores, estruturas de controle e declarações. O núcleo do JavaScript pode ser estendido para uma variedade de propósitos, complementando assim a linguagem:

  • O lado cliente do JavaScript estende-se do núcleo linguagem, fornecendo objetos para controlar um navegador web e seu Document Object Model (DOM). Por exemplo, as extensões do lado do cliente permitem que uma aplicação coloque elementos em um formulário HTML e responda a eventos do usuário, como cliques do mouse, entrada de formulário e de navegação da página.
  • O lado do servidor do JavaScript estende-se do núcleo  da linguagem, fornecendo objetos relevantes à execução do JavaScript em um servidor. Por exemplo, as extensões do lado do servidor permitem que uma aplicação comunique-se com um banco de dados, garantindo a continuidade de informações de uma chamada para a outra da aplicação, ou executar manipulações de arquivos em um servidor.

JavaScript não é Java

JavaScript e Java são similares em algumas coisas, mas são diferentes em outras. O JavaScript assemelha-se ao Java, porém não possui tipagem estática e checagem rigída de tipos como o Java. JavaScript segue a sintaxe básica do Java, convenções de nomenclatura e construções de controle de fluxo, razões pelas quais esta linguagem foi renomeada de LiveScript para JavaScript.

Em contraste com o sistema em tempo de compilação das classes construídas por declarações no Java, JavaScript suporta um sistema em tempo de execução com base em um pequeno número de tipos de dados representando valores numéricos, booleanos, e strings. JavaScript tem um modelo de objeto baseado em protótipo em vez do modelo, mais comum, de objeto baseado em classes. O modelo baseado em protótipo fornece herança dinâmica; isto é, o que é herdado pode variar para objetos individuais. JavaScript também suporta funções sem quaisquer requisitos especiais declarativos. As funções podem ser propriedades de objetos, executando como métodos.

JavaScript é uma linguagem mais livre em comparação a Java. Você não tem de declarar todas as variáveis, classes e métodos. Você não tem que se preocupar com o fato dos métodos serem públicos, privados ou protegidos, e você não tem que implementar interfaces. Variáveis, parâmetros e tipo de retorno da função não são explicitamente tipados.

Java é uma linguagem de programação baseada em classes, projetada para execução rápida e segurança de tipos. Segurança de tipo significa que, por exemplo, você não pode converter um número inteiro em Java para uma referência de objeto ou acessar a memória privada corrompendo bytecodes Java. O modelo baseado em classes do Java significa que os programas são exclusivamente constituídos por classes e seus métodos. Herança de classe do Java e tipagem forte geralmente requerem hierarquias de objetos fortemente acoplados. Esses requisitos tornam a programação em Java mais complexa do que a programação em JavaScript.

Em contraste,  JavaScript descende em espírito de uma linhagem de linguagens menores com tipagem dinâmica, como HyperTalk e dBASE. Essas linguagens de script oferecem ferramentas de programação para um público muito mais amplo por causa de sua sintaxe mais fácil, funções especializadas embutidas e requisitos mínimos para a criação de objetos.

JavaScriptJava
Orientada a objeto. Sem distinção entre tipos e objetos. A herança é feita através do protótipo e as propriedades e métodos podem ser adicionadas a qualquer objeto dinamicamente.Baseada em classes. Objetos são divididos em classes e instâncias com toda a herança através da hierarquia da classe. Classes e instâncias não podem ter propriedades ou métodos adicionados dinamicamente.
Os tipos de dados das variáveis não precisam ser declarados (tipagem dinâmica)Os tipos de dados das variáveis devem ser declarados (tipagem estática).
Não pode escrever automaticamente no disco rigído.Pode escrever automaticamente no disco rigído.
Linguagem não compiladaLinguagem compilada

Começando com JavaScript

Começar a aprender JavaScript é fácil: Tudo o que você precisa é de um navegador web moderno. Esse guia inclui algumas características do JavaScript que só estão disponíveis nas últimas versões do Firefox, então, é recomendável o uso de uma versão mais recente do Firefox.

Há duas ferramentas no Firefox que são muito úteis para aprender JavaScript: O console web e o Scratchpad.

O console web mostra informações sobre a página web que está sendo carregada atualmente e também inclui a linha de comando que você pode utilizar para executar códigos JavaScript na página atual.

Para abrir o console (Ctrl+Shift+K), selecione “Web Console” do menu “Web Developer”, que está sob o menu “Tools” no Firefox. Ele aparece na parte inferior da janela do navegador. Na parte inferior do console está a linha de comando que você pode usar para colocar o JavaScript, e a saída é exibida no painel acima:

O Web Console é excelente para executar linhas únicas de JavaScript, mas embora você possa executar várias linhas, não é muito conveniente para isso, e você não pode salvar as amostras de código usando o Web Console. Assim, para exemplos mais complexos a ferramenta Scratchpad é melhor.

Para abrir o Scratchpad (Shift+F4), selecione “Scratchpad” do menu “Web Developer”, que está sob o menu “Tools/Ferramentas” do Firefox. Ele abre em uma janela separada e é um editor que você pode usar para escrever e executar JavaScript no navegador. Você também pode salvar os scripts para o disco e carregá-los a partir do disco.  

Para começar a escrever JavaScript, abra o Console Web ou o Scratchpad e escreva seu primeiro código JavaScript “Olá, mundo”. 

function greetMe(nome) {
  alert("Olá, " + nome);
}

greetMe("mundo"); // "Olá, mundo"

Logo após, pressione Ctrl+R para executar o código em seu navegador.

Nas páginas seguintes, este guia irá apresentar-lhe a sintaxe e as características da linguagem JavaScript, de modo que você possa escrever aplicações mais complexas.

Sintaxe básica

JavaScript pega emprestado a maior parte de sua sintaxe do Java, mas também é influenciado por Awk, Perl e Python.

JavaScript é case-sensitive e usa o conjunto de caracteres Unicode. Por exemplo, a palavra Früh (que significa “cedo” em Alemão) pode ser usada como nome de variável.

var Früh = "foobar";

Mas a variável früh não é a mesma que Früh porque JavaScript é case sensitive.

No JavaScript, instruções são chamadas de declaração e são separadas por um ponto e vírgula (;). Espaços, tabulação e uma nova linha são chamados de espaços em branco. O código fonte dos scripts em JavaScript são lidos da esquerda para a direita e são convertidos em uma sequência de elementos de entrada como simbolos, caracteres de controle, terminadores de linha, comentários ou espaço em branco. ECMAScript também define determinadas palavras-chave e literais, e tem regras para inserção automática de ponto e vírgula (ASI) para terminar as declarações. No entanto, recomenda-se sempre adicionar ponto e vírgula no final de suas declarações; isso evitará alguns imprevistos. Para obter mais informações, consulte a referência detalhada sobre a gramática léxica do JavaScript.

Comentários

A sintaxe dos comentários em JavaScript é semelhante como em C++ e em muitas outras linguagens:

// comentário de uma linha
 
/* isto é um comentário longo
   de múltiplas linhas.
 */
 
/* Você não pode, porém, /* aninhar comentários */ SyntaxError */

Declarações

Existem três tipos de declarações em JavaScript.varDeclara uma variável, opcionalmente, inicializando-a com um valor. letDeclara uma variável local de escopo do bloco, opcionalmente, inicializando-a com um valor. constDeclara uma constante de escopo de bloco, apenas de leitura.

Variáveis

Você usa variáveis como nomes simbólicos para os valores em sua aplicação. O nome das variáveis, chamados de identificadores, obedecem determinadas regras.

Um identificador JavaScript deve começar com uma letra, underline (_), ou cifrão ($); os caracteres subsequentes podem também ser números (0-9). Devido JavaScript ser case-sensitive, letras incluem caracteres de “A” a “Z” (maiúsculos) e caracteres de “a” a “z” (minúsculos).

Você pode usar a ISO 8859-1 ou caracteres Unicode tal como os identificadores å e ü. Você pode também usar as sequências de escape Unicode como caracteres e identificadores.

Alguns exemplos de nomes legais são Numeros_visitastemp99, e _nome.

Declarando variáveisS

Você pode declarar uma variável de três formas:

  • Com a palavra chave var. Por exemplo, var x = 42. Esta sintaxe pode ser usada para declarar tanto variáveis locais como variáveis globais.
  • Por simples adição de valor. Por exemplo, x = 42. Isso declara uma variável global. Essa declaração gera um aviso de advertência no JavaScript. Você não deve usar essa variante.
  • Com a palavra chave let. Por exemplo, let y = 13. Essa sintaxe pode ser usada para declarar uma variável local de escopo de bloco. Veja escopo de variável abaixo.

Classificando variáveis

Uma variável declarada usando a declaração var ou let sem especificar o valor inicial tem o valor  undefined.

Uma tentativa de acessar uma variável não declarada resultará no lançamento de uma exceção ReferenceError:

var a;
console.log("O valor de a é " + a); // saída "O valor de a é undefined"
console.log("O valor de b é " + b); // executa uma exception de erro de referência (ReferenceError)

Você pode usar undefined para determinar se uma variável tem um valor. No código a seguir, não é atribuído um valor de entrada na variável e a declaração if será avaliada como verdadeira (true).

var input;
if(input === undefined){
  facaIsto();
} else {
  facaAquilo();
}

O valor undefined se comporta como falso (false), quando usado em um contexto booleano. Por exemplo, o código a seguir executa a função myFunction devido o elemento myArray ser undefined:

var myArray = [];
if (!myArray[0]) myFunction();

O valor undefined converte-se para NaN quando usado no contexto numérico.

var a;
a + 2;  // Avaliado como NaN

Quando você avalia uma variável nula, o valor nulo se comporta como 0 em contextos numéricos e como falso em contextos booleanos. Por exemplo:

var n = null;
console.log(n * 32); // a saída para o console será 0.

Escopo de variável

Quando você declara uma váriavel fora de qualquer função, ela é chamada de variável global, porque está disponível para qualquer outro código no documento atual. Quando você declara uma variável dentro de uma função, é chamada de variável local,  pois ela está disponível somente dentro dessa função.

JavaScript antes do ECMAScript 6 não possuía escopo de declaração de bloco; pelo contrário, uma variável declarada dentro de um bloco de uma função é uma variável local (ou contexto global) do bloco que está inserido a função. Por exemplo o código a seguir exibirá 5, porque o escopo de x está na função (ou contexto global) no qual x é declarado, não o bloco, que neste caso é a declaração if

if (true) {
  var x = 5;
}
console.log(x);  // 5

Esse comportamento é alterado, quando usado a declaração let introduzida pelo ECMAScript 6.

if (true) {
  let y = 5;
}
console.log(y);  // ReferenceError: y não está definido

Variável de elevação

Outra coisa incomum sobre variáveis em JavaScript é que você pode utilizar a variável e declará-la depois, sem obter uma exceção. Este conceito é conhecido como hoisting; variáveis em JavaScript são num sentido “hoisted” ou lançada para o topo da função ou declaração. No entanto, as variáveis que são “hoisted” retornarão um valor undefined. Então, mesmo se você usar ou referir a variável e depois declará-la e inicializá-la, ela ainda retornará undefined.

/**
 * Exemplo 1
 */
console.log(x === undefined); // exibe "true"
var x = 3;

/**
 * Exemplo 2
 */
// retornará um valor undefined
var myvar = "my value";
 
(function() {
  console.log(myvar); // undefined
  var myvar = "local value";
})();

Os exemplos acima serão interpretados como:

/**
 * Exemplo 1
 */
var x;
console.log(x === undefined); // exibe "true"
x = 3;
 
/**
 * Exemplo 2
 */
var myvar = "um valor";
 
(function() {
  var myvar;
  console.log(myvar); // undefined
  myvar = "valor local";
})();

Devido o hoisting, todas as declarações var em uma função devem ser colocadas no início da função. Essa recomendação de prática deixa o código mais legível.

Variáveis Globais

Variáveis globais são propriedades do objeto global. Em páginas web o objeto global é a window, assim você pode configurar e acessar variáveis globais utilizando a sintaxe window.variavel. 

Consequentemente, você pode acessar variáveis globais declaradas em uma janela ou frame ou frame de outra janela. Por exemplo, se uma variável chamada phoneNumber é declarada em um documento, você pode consultar esta variável de um frame como parent.phoneNumber.

Constantes

Você pode criar uma constante apenas de leitura por meio da palavra-chave const. A sintaxe de um identificador de uma constante é semelhante ao identificador de uma variável: deve começar com uma letra, sublinhado ou cifrão e pode conter caractere alfabético, numérico ou sublinhado.

const PI = 3.14;

Uma constante não pode alterar seu valor por meio de uma atribuição ou ser declarada novamente enquanto o script está em execução. Deve ser inicializada com um valor.

As regras de escopo para as constantes são as mesmas para as váriaveis let de escopo de bloco. Se a palavra-chave const for omitida, presume-se que o identificador represente uma variável.

Você não pode declarar uma constante com o mesmo nome de uma função ou variável que estão no mesmo escopo. Por exemplo: 

// Isto irá causar um  erro
function f() {};
const f = 5;

// Isto também irá causar um erro.
function f() {
  const g = 5;
  var g;

  //declarações
}

Estrutura de dados e tipos

Tipos de dados

O mais recente padrão ECMAScript define sete tipos de dados:

  • Seis tipos de dados são os chamados primitivos:
    • Boolean. true e false.
    • null. Uma palavra-chave que indica valor nulo. Devido JavaScript ser case-sensitive, null não é o mesmo que NullNULL, ou ainda outra variação.
    • undefined. Uma propriedade superior cujo valor é indefinido.
    • Number. 42 ou 3.14159.
    • String. “Howdy”
    • Symbol (novo em ECMAScript 6). Um tipo de dado cuja as instâncias são únicas e imutáveis.
  • e Object

Embora esses tipos de dados sejam uma quantidade relativamente pequena, eles permitem realizar funções úteis em suas aplicações.  Objetos e funções são outros elementos fundamentais na linguagem. Você pode pensar em objetos como recipientes para os valores, e funções como métodos que suas aplicações podem executar.

Conversão de tipos de dados

JavaScript é uma linguagem dinamicamente tipada. Isso significa que você não precisa especificar o tipo de dado de uma variável quando declará-la, e tipos de dados são convertidos automaticamente conforme a necessidade durante a execução do script. Então, por exemplo, você pode definir uma variável da seguinte forma:

var answer = 42;

E depois, você pode atribuir uma string para a mesma variável, por exemplo:

answer = "Obrigado pelos peixes...";

Devido JavaScript ser dinamicamente tipado, essa declaração não gera uma mensagem de erro.

Em expressões envolvendo valores numérico e string com o operador +, JavaScript converte valores numérico para strings. Por exemplo, considere a seguinte declaração:

x = "A resposta é " + 42 // "A resposta é 42"
y = 42 + " é a resposta" // "42 é a resposta"

Nas declarações envolvendo outros operadores,  JavaScript não converte valores numérico para strings. Por exemplo:

"37" - 7 // 30
"37" + 7 // "377"

Convertendo strings para números

No caso de um valor que representa um número está armazenado na memória como uma string, existem métodos para a conversão.

parseInt irá retornar apenas números inteiros, então seu uso é restrito para a casa dos decimais. Além disso, é uma boa prática ao usar parseInt incluir o parâmetro da base. O parâmetro da base é usado para especificar qual sistema númerico deve ser usado.

Uma método alternativo de conversão de um número em forma de string é com o operador + (operador soma):

"1.1" + "1.1" = "1.11.1"
(+"1.1") + (+"1.1") = 2.2   
// Nota: Os parênteses foram usados para deixar mais legível o código, ele não é requirido.

Literais

Você usa literais para representar valores em JavaScript. Estes são valores fixados, não variáveis, que você literalmente insere em seu script. Esta seção descreve os seguintes tipos literais:

  • Array literal
  • Literais boolean
  • Literais de ponto flutuante
  • Inteiros
  • Objeto literal
  • String literal

Array literal

Um array literal é uma lista de zero ou mais expressões, onde cada uma delas representam um elemento do array, inseridas entre colchetes ([]). Quando você cria um array usando um array literal, ele é inicializado  com os valores especificados como seus elementos, e seu comprimento é definido com o  número de elementos especificados.

O exemplo a seguir cria um array coffees com três elementos e um comprimento de três:

var coffees = ["French Roast", "Colombian", "Kona"];

Nota : Um array literal é um tipo de inicializador de objetos. Veja Usando inicializadores de Objetos.

Se um array é criado usando um literal no topo do script, JavaScript interpreta o array cada vez que avalia a expressão que contêm o array literal. Além disso, um literal usado em uma função é criado cada vez que a função é chamada.

Array literal são também um array de objetos. Veja  Array e Coleções indexadas para detalhes sobre array de objetos.

Vírgulas extras em array literal

Você não precisa especificar todos os elementos em um array literal. Se você colocar duas vírgulas em uma linha, o array é criado com undefined para os elementos não especificados. O exemplo a seguir cria um array chamado fish:

var fish = ["Lion", , "Angel"];

Esse array tem dois elementos com valores e um elemento vazio (fish[0] é “Lion”, fish[1] é undefined, e fish[2] é “Angel” ).

Se você incluir uma vírgula à direita no final da lista dos elementos, a vírgula é ignorada. No exemplo a seguir, o comprimento do array é três. Não há nenhum myList[3]. Todas as outras vírgulas na lista indicam um novo elemento.

Nota : Vírgulas à direita podem criar erros em algumas versões de navegadores web antigos, é recomendável removê-las.

var myList = ['home', , 'school', ];

No exemplo a seguir, o comprimento do array é quatro, e myList[0] e myList[2] são undefined.

var myList = [ , 'home', , 'school'];

No exemplo a seguir, o comprimento do array é quatro, e myList[1] e myList[3] são undefined. Apenas a última vírgula é ignorada.

var myList = ['home', , 'school', , ];

Entender o comportamento de vírgulas extras é importante para a compreensão da linguagem JavaScript, no entanto, quando você escrever seu próprio código: declarar explicitamente os elementos em falta como undefined vai aumentar a clareza do código, e consequentemente na sua manutenção.

Literais Boolean

O tipo Boolean tem dois valores literal: true e false.

Não confunda os valores primitivos Boolean true e false com os valores true e false do objeto Boolean. O objeto Boolean é um invólucro em torno do tipo de dado primitivo. Veja Boolean para mais informação.

Inteiros

Inteiros podem ser expressos em decimal (base 10), hexadecimal (base 16), octal (base 8) e binário (base 2).

  • Decimal inteiro literal consiste em uma sequência de dígitos sem um 0 (zero).
  • 0 (zero) em um inteiro literal indica que ele está em octal. Octal pode incluir somente os dígitos 0-7.
  • 0x (ou 0X) indica um hexadecimal. Inteiros hexadecimais podem incluir dígitos (0-9) e as letras a-f e A-F.
  • 0b (ou 0B) indica um binário. Inteiros binário podem incluir apenas os dígitos 0 e 1.

Alguns exemplos de inteiros literal são:

0, 117 and -345 (decimal, base 10)
015, 0001 and -077 (octal, base 8) 
0x1123, 0x00111 and -0xF1A7 (hexadecimal, "hex" or base 16)
0b11, 0b0011 and -0b11 (binário, base 2)

Literais de ponto flutuante

Um literal de ponto flutuante pode ter as seguintes partes:

  • Um inteiro decimal que pode ter sinal (precedido por “+” ou “-“),
  • Um ponto decimal (“.“),
  • Uma fração (outro número decimal),
  • Um expoente.

O expoente é um “e” ou “E” seguido por um inteiro, que pode ter sinal (precedido por “+” ou “-“). Um literal de ponto flutuante  deve ter no mínimo um dígito e um ponto decimal ou “e” (ou “E”).

Mais sucintamente, a sintaxe é:

[(+|-)][digitos][.digitos][(E|e)[(+|-)]digitos]

Por exemplo:

3.1415926
-.123456789
-3.1E+12
.1e-23

Objeto literal

Um objeto literal é uma lista de zero ou mais pares de nomes de propriedades e valores associados de um objeto, colocado entre chaves ({}). Você não deve usar um objeto literal no início de uma declaração. Isso levará a um erro ou não se comportará conforme o esperado, porque o { será interpretado como início de um bloco.

Segue um exemplo de um objeto literal. O primeiro elemento do objeto carro define uma propriedade, meuCarro, e atribui para ele uma nova string, “Punto”; o segundo elemento, a propriedade getCarro, é imediatamente atribuído o resultado de chamar uma função (tipoCarro("Fiat")); o terceiro elemento, a propriedade especial, usa uma variável existente (vendas).

var vendas = "Toyota";

function tipoCarro(nome) {
  if (nome == "Fiat") {
    return nome;
  } else {
    return "Desculpa, não vendemos carros " + nome + ".";
  }
}

var carro = { meuCarro: "Punto", getCarro: tipoCarro("Fiat"), especial: vendas };

console.log(carro.meuCarro);   // Punto
console.log(carro.getCarro);  // Fiat
console.log(carro.especial); // Toyota

Além disso, você pode usar um literal numérico ou string para o nome de uma propriedade ou aninhar um objeto dentro do outro. O exemplo a seguir usar essas opções.

var carro = { carros: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };

console.log(carro.carros.b); // Jeep
console.log(carro[7]); // Mazda

Nomes de propriedades de objeto podem ser qualquer string, incluindo uma string vazia. Caso o nome da propriedade não seja um identificador JavaScript ou número, ele deve ser colocado entre aspas. Nomes de propriedades que não possuem identificadores válido, também não podem ser acessadas pela propriedade de ponto (.), mas podem ser acessadas e definidas com a notação do tipo array (“[]“).

var unusualPropertyNames = {
  "": "Uma string vazia",
  "!": "Bang!"
}
console.log(unusualPropertyNames."");   // SyntaxError: string inesperada
console.log(unusualPropertyNames[""]);  // Um string vazia
console.log(unusualPropertyNames.!);    // SyntaxError: símbolo ! inesperado
console.log(unusualPropertyNames["!"]); // Bang!

Observe:

var foo = {a: "alpha", 2: "two"};
console.log(foo.a);    // alpha
console.log(foo[2]);   // two
//console.log(foo.2);  // Error: missing ) after argument list
//console.log(foo[a]); // Error: a não está definido
console.log(foo["a"]); // alpha
console.log(foo["2"]); // two

Expressão Regex Literal

Um regex literal é um padrão entre barras. A seguir um exemplo de regex literal.

var re = /ab+c/;

String Literal

Uma string literal são zero ou mais caracteres dispostos em aspas duplas (") ou aspas simples ('). Uma sequência de caracteres deve ser delimitada por aspas do mesmo tipo; ou seja,  as duas aspas simples ou ambas aspas duplas. A seguir um exemplo de strings literais.

"foo"
'bar'
"1234"
"um linha \n outra linha"
"John's cat"

Você pode chamar qualquer um dos métodos do objeto string em uma string literal – JavaScript automaticamente converte a string literal para um objeto string temporário, chama o método, em seguida, descarta o objeto string temporário. Você também pode usar a propriedade String.length com uma string literal:

console.log("John's cat".length) 
// Irá exibir a quantidade de caracteres na string incluindo o espaço em branco. 
// Nesse caso, 10 caracteres.

Você deve usar string literal, a não ser que você precise usar um objeto string. Veja String para detalhes sobre objetos de strings.

Uso de caracteres especiais em string

Além dos caracteres comuns, você também pode incluir caracteres especiais em strings, como mostrado no exemplo a seguir.

"uma linha \n outra linha"

A tabela a seguir lista os caracteres especiais que podem ser usados em strings no JavaScript.

CaracterDescrição
\0Byte nulo
\bBackspace
\fAlimentador de formulário
\nNova linha
\rRetorno do carro
\tTabulação
\vTabulação vertical
\'Apóstrofo ou aspas simples
\"Aspas dupla
\\Caractere de barra invertida
\XXXCaractere com a codificação Latin-1 especificada por três dígitos octal XXX entre 0 e 377. Por exemplo, \251 é sequência octal para o símbolo de direitos autorais.
\xXXCaractere com a codificação Latin-1 especificada por dois dígitos hexadecimal XX entre 00 e FF. Por exemplo, \xA9 é a sequência hexadecimal para o símbolo de direitos autorais.
\uXXXXCaractere Unicode especificado por quatro dígitos hexadecimal XXXX. Por exemplo, \u00A9 é a sequência Unicode para o símbolo de direitos autorais.

Caracteres de escape

Para caracteres não listados na tabela, se precedidos de barra invertida ela é ignorada, seu uso está absoleto e deve ser ignorado.

Você pode inserir uma aspa dentro de uma string precendendo-a com uma barra invertida. Isso  é conhecido como escaping das aspas. Por exemplo:

var quote = "Ele lê \"The Cremation of Sam McGee\" de R.W. Service.";
console.log(quote);

O resultado disso seria:

Ele lê "The Cremation of Sam McGee" de R.W. Service.

Para incluir uma barra invertida dentro de uma string, você deve escapar o caractere de barra invertida. Por exemplo, para atribuir o caminho do arquivo c:\temp para uma string, utilize o seguinte:

var home = "c:\\temp";

Você também pode escapar quebras de linhas, precedendo-as com barra invertida. A barra invertida e a quebra de linha são ambas removidas da string.

var str = "esta string \
está quebrada \
em várias\
linhas."
console.log(str);   // esta string está quebrada em várias linhas.

Embora JavaScript não tenha sintaxe “heredoc”, você pode adicionar uma quebra de linha e um escape de quebra de linha no final de cada linha:

var poema = 
"Rosas são vermelhas\n\
Violetas são azuis,\n\
Esse seu sorriso\n\
é o que me seduz. (Lucas Pedrosa)"

Declaração em bloco

Uma declaração em bloco é utilizada para agrupar declarações. O bloco é delimitado por um par de chaves:

{
   declaracao_1;
   declaracao_2;
   .
   .
   .
   declaracao_n;
}

Exemplo

Declarações em bloco são utilizadas geralmente com declarações de fluxo de controle (ex. ifforwhile).

while (x < 10) {
  x++;
}

Aqui, { x++; } é a declaração de bloco.

Importante: Antes de ECMAScript 6 o JavaScript não possuía escopo de bloco. Variáveis introduzidas dentro de um bloco possuem como escopo a função ou o script em que o bloco está contido, e, definir tais variáveis tem efeito muito além do bloco em si. Em outras palavras, declarações de bloco não introduzem um escopo. Embora blocos “padrão” sejam uma sintaxe válida não utilize-os, em JavaScript, pensando que funcionam como em C ou Java porque eles não funcionam da maneira que você acredita. Por exemplo:

var x = 1;
{
  var x = 2;
}
console.log(x); // exibe 2

Este código exibe 2 porque a declaração var x dentro do bloco possui o mesmo escopo que a declaração var x antes do bloco. Em C ou Java, o código equivalente exibiria 1.

Declarações condicionais

Uma declaração condicional é um conjunto de comandos que são executados caso uma condição especificada seja verdadeira. O JavaScript suporta duas declarações condicionais: if...else e switch.

Declaração if…else

Use a declaração if para executar alguma declaração caso a condição lógica for verdadeira. Use a cláusula opcional else para executar alguma declaração caso a condição lógica for falsa. Uma declaração if é declarada da seguinte maneira:

if (condicao) {
  declaracao_1;
} else {
  declaracao_2;
}

onde condicao pode ser qualquer expressão que seja avaliada como verdadeira ou falsa. Veja Boolean para uma explicação sobre o que é avaliado como true e false. Se condicao for avaliada como verdadeira, declaracao_1 é executada; caso contrário, declaracao_2 é executada. declaracao_1 e declaracao_2 podem ser qualquer declaração, incluindo declarações if aninhadas.

Você pode também combinar declarações utilizando else if para obter várias condições testadas em sequência, como o seguinte:

if (condicao) {
  declaracao_1;
} else if (condicao_2) {
  declaracao_2;
} else if (condicao_n) {
  declaracao_n;
} else {
  declaracao_final;
}

Para executar várias declarações, agrupe-as em uma declaração em bloco ({ ... }). Em geral, é uma boa prática sempre utilizar declarações em bloco, especialmente ao aninhar declarações if:

if (condicao) {
    declaracao_1_executada_se_condicao_for_verdadeira;
    declaracao_2_executada_se_condicao_for_verdadeira;
} else {
    declaracao_3_executada_se_condicao_for_falsa;
    declaracao_4_executada_se_condicao_for_falsa;
}

Recomenda-se não utilizar atribuições simples em uma expressão condicional porque o símbolo de atribuição poderia ser confundido com o de igualdade ao dar uma olhada no código. Por exemplo, não utilize o seguinte código:

if (x = y) {
  /* faça a coisa certa */
}

Caso tenha que utilizar uma atribuição em uma expressão condicional, uma prática comum é colocar parênteses adicionais em volta da atribuição. Por exemplo:

if ((x = y)) {
  /* faça a coisa certa */
}

Valores avaliados como falsos

Os seguintes valores são avaliados como falsos:

  • false
  • undefined
  • null
  • 0
  • NaN
  • string vazia ("")

Todos os outros valores, incluindo todos os objetos, são avaliados como verdadeiros quando passados para uma declaração condicional.

Não confunda os valores booleanos primitivos true e false com os valores de true e false do objeto Boolean. Por exemplo:

var b = new Boolean(false);
if (b) // esta condição é avaliada como verdadeira
if (b == true) // esta condição é avaliada como falsa

Exemplo

No exemplo a seguir, a função verifiqueDados retorna verdadeiro se o número de caracteres em um objeto Text for três; caso contrário, exibe um alerta e retorna falso.

function verifiqueDados() {
  if (document.form1.tresCaracteres.value.length == 3) {
    return true;
  } else {
    alert("Informe exatamente três caracteres. " +
      document.form1.tresCaracteres.value + " não é válido.");
    return false;
  }
}

Declaração switch

Uma declaração switch permite que um programa avalie uma expressão e tente associar o valor da expressão ao rótulo de um case. Se uma correspondência é encontrada, o programa executa a declaração associada. Uma declaração switch se parece com o seguinte:

switch (expressao) {
   case rotulo_1:
      declaracoes_1
      

[break;]

case rotulo_2: declaracoes_2

[break;]

… default: declaracoes_padrao

[break;]

}

O programa primeiramente procura por uma cláusula case com um rótulo que corresponda ao valor da expressão e então transfere o controle para aquela cláusula, executando as declaracoes associadas. Se nenhum rótulo correspondente é encontrado, o programa procura pela cláusula opcional default e, se encontrada, transfere o controle àquela cláusula, executando as declarações associadas. Se nenhuma cláusula default é encontrada, o programa continua a execução a partir da declaracao seguinte ao switch. Por convenção, a cláusula default é a última, mas não é necessário que seja assim.

A instrução break associada a cada cláusula case, garante que o programa sairá do switch assim que a declaração correspondente for executada e que continuará a execução a partir da declaração seguinte ao switch. Se a declaração break for omitida, o programa continua a execução a partir da próxima declaração dentro do switch.

Exemplo

No exemplo a seguir, se tipofruta for avaliada como “Banana“, o programa faz a correspondência do valor com case Banana” e executa a declaração associada. Quando o break é encontrado, o programa termina o switch e executa a declaração seguinte ao condicional. Se o break fosse omitido, a declaração de case Cereja” também seria executada.

switch (tipofruta) {
   case "Laranja":
      console.log("O quilo da laranja está R$0,59.<br>");
      break;
   case "Maçã":
      console.log("O quilo da maçã está R$0,32.<br>");
      break;
   case "Banana":
      console.log("O quilo da banana está R$0,48.<br>");
      break;
   case "Cereja":
      console.log("O quilo da cereja está R$3,00.<br>");
      break;
   case "Manga":
      console.log("O quilo da manga está R$0,56.<br>");
       break;
   case "Mamão":
      console.log("O quilo do mamão está R$2,23.<br>");
      break;
   default:
      console.log("Desculpe, não temos " + tipofruta + ".<br>");
}
console.log("Gostaria de mais alguma coisa?<br>");

Declarações de Manipulação de Error

Você pode chamar uma exceção usando a declaração throw e manipulá-la usando a declaração try...catch.

  • Declaração throw
  • Declaração try...catch

Tipos de exceções

Praticamente pode-se utilizar throw em qualquer objeto de JavaScript. Todavia, nem todos os objetos ativados por throw são igualmente criados. Embora seja bastante comum tratar números ou strings como erros usando throw, é frequentemente mais eficiente usar alguns tipos de exceções especificamente criadas para esses propósitos:

Declaração throw

Use a declaração throw para lançar uma exceção. Quando você lança uma exceção, você especifica a expressão contendo o valor a ser lançado:

throw expressão;

Você pode lançar qualquer expressão, não apenas expressões de um tipo específico. O código a seguir lança várias exceções de diferentes tipos:

throw "Error2";   // tipo string
throw 42;         // tipo numérico
throw true;       // tipo booleano
throw {toString: function() { return "Eu sou um objeto!"; } };

Nota:  Você pode especificar um objeto quando você lança uma exceção. Você pode então, referenciar as propriedades de um objeto no bloco catch.  O exemplo a seguir cria um objeto myUserException do tipo userException e o usa em uma declaração throw.

// Cria um objeto do tipo UserException
function UserException(mensagem) {
  this.mensagem = mensagem;
  this.nome = "UserException";
}

// Realiza a conversão da exceção para uma string adequada quando usada como uma string.
// (ex. pelo console de erro)
UserException.prototype.toString = function() {
  return this.name + ': "' + this.message + '"';
}

// Cria uma instância de um tipo de objeto e lança ela
throw new UserException("Valor muito alto");

Declaração try...catchSeção

A declaração try...catch coloca um bloco de declarações em try, e especifica uma ou mais respostas para uma exceção lançada. Se uma exceção é lançada, a declaração try...catch pegá-a.

A declaração try...catch é composta por um bloco try, que contém uma ou mais declarações, e zero ou mais blocos catch, contendo declarações que especificam o que fazer se uma exceção é lançada no bloco try. Ou seja, você deseja que o bloco try  tenha sucesso, e se ele não tiver êxito, você quer o controle passado para o bloco catch. Se qualquer declaração do bloco try (ou em uma função chamada dentro do bloco try) lança uma exceção, o controle é imediatamente mudado para o bloco catch. Se nenhuma exceção é lançada no bloco try, o bloco catch é ignorado. O bloco finally executa após os blocos try e catch executarem, mas antes das declarações seguinte ao bloco try...catch.

O exemplo a seguir usa a declaração try...catch. O exemplo chama uma função que recupera o nome de um mês no array com base no valor passado para a função. Se o valor não corresponde ao número de um mês (1-12), uma exceção é lançada com o valor “InvalidMonthNo” e as declarações no bloco catch define a váriavel monthName para unknown.

function getMonthName(mo) {
  mo = mo - 1; // Ajusta o número do mês para o índice do array (1 = Jan, 12 = Dec)
  var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul",
                "Aug","Sep","Oct","Nov","Dec"];
  if (months[mo]) {
    return months[mo];
  } else {
    throw "InvalidMonthNo"; //lança uma palavra-chave aqui usada.
  }
}

try { // statements to try
  monthName = getMonthName(myMonth); // função poderia lançar uma exceção
}
catch (e) {
  monthName = "unknown";
  logMyErrors(e); // passa a exceção para o manipulador de erro -> sua função local.
}

O bloco catch

Você pode usar um bloco catch para lidar com todas as exceções que podem ser geradas no bloco try.

catch (catchID) {
  declaracoes
}

O bloco catch específica um identificador (catchID na sintaxe anterior), que contém o valor especificado pela declaração throw; você pode usar esse identificador para obter informações sobre a exceção que foi lançada. JavaScript cria este identificador quando o bloco catch é inserido; o identificador dura enquanto o bloco catch está em execução, depois que termina a execução do bloco catch, o identificador não estará mais disponível.

Por exemplo, o seguinte código lança uma exceção. Quando a exceção ocorre, o controle é transferido para o bloco catch.

try {
  throw "myException"; // lança  uma exceção
}
catch (e) {
  // declarações de lidar com as exceções
  logMyErrors(e); // passar a exceção para o manipulador de erro
}

O bloco finally

O bloco finally contém instruções para executar após os blocos try e catch, mas antes das declarações seguinte a declaração try...catch. O bloco finally é executado com ou sem o lançamento de uma exceção. Se uma exceção é lançada, a declaração no bloco finally executa, mesmo que nenhum bloco catch processe a exceção.

Você pode usar bloco finally para deixar a falha de seu script agradável quando uma exceção ocorre; por exemplo, você pode precisar liberar um recurso que seu script tem amarrado. O exemplo a seguir abre um arquivo e então executa instruções que usam o arquivo (JavaScript do lado do servidor permite que você acesse arquivos). Se um exceção é lançada enquanto o arquivo é aberto, o bloco finally fecha o arquivo antes do script falhar.

openMyFile();
try {
  writeMyFile(theData); //Isso pode lançar um erro
} catch(e) {  
  handleError(e); // Se temos um erro temos que lidar com ele
} finally {
  closeMyFile(); // Sempre feche o recurso
}

Se o bloco finally retornar um valor, este valor se torna o valor de toda a entrada try-catch-finally, independente de quaisquer declarações de retorno nos blocos try e catch:

function f() {
  try {
    console.log(0);
    throw "bogus";
  } catch(e) {
    console.log(1);
    return true; // essa declaração de retorno é suspensa
                 // até que o bloco finally seja concluído
    console.log(2); // não executa
  } finally {
    console.log(3);
    return false; // substitui o "return" anterior
    console.log(4); // não executa
  }
  // "return false" é executado agora 
  console.log(5); // não executa
}
f(); // exibe 0, 1, 3; retorna false

Substituições de valores de retorno pelo bloco finally também se aplica a exceções lançadas ou re-lançadas dentro do bloco catch:

function f() {
  try {
    throw "bogus";
  } catch(e) {
    console.log('captura interior "falso"');
    throw e; // essa instrução throw é suspensa até 
             // que o bloco finally seja concluído
  } finally {
    return false; // substitui "throw" anterior
  }
  // "return false" é executado agora
}

try {
  f();
} catch(e) {
  // isto nunca é executado porque o throw dentro
  // do catch é substituído
  // pelo return no finally
  console.log('captura exterior "falso"');
}

// SAIDA
// captura interior "falso"

Aninhando declarações try…catch

Você pode aninhar uma ou mais declarações try...catch. Se uma declaração try...catch interior não tem um bloco catch, o delimitador do bloco try...catch da declaração catch é verificado por uma correspondência.

Utilizando objetos de erro

Dependendo do tipo de erro, você pode ser capaz de usar as propriedade ‘name’ e ‘message’ para pegar uma mensagem mais refinada. A propriedade ‘name’ fornece a classe geral de erro (ex., ‘DOMException’ ou ‘Error’), enquanto ‘message’ geralmente oferece uma mensagem mais sucinta do que se poderia obter através da conversão do objeto de erro para uma string.

Se você está lançando suas próprias exceções, a fim de tirar proveito dessas propriedades (como o seu bloco catch não discrimina entre suas próprias exceções e as exceções próprias da linguagem), você pode usar o construtor Error. Por exemplo:

function doSomethingErrorProne () {
  if (ourCodeMakesAMistake()) {
    throw (new Error('A mensagem'));
  } else {
    doSomethingToGetAJavascriptError();
  }
}
....
try {
  doSomethingErrorProne();
}
catch (e) {
  console.log(e.name); // exibe 'Error'
  console.log(e.message); // exibe 'A mensagem' ou uma mensagem de erro em JavaScript
}

Promises

Começando com ECMAScript 6, JavaScript ganha suporte para objetos Promise que lhe permite controlar o fluxo de operações diferídas e assíncronas.

Uma Promise assume um destes estados:

  • pending: estado inicial, não fulfilled, ou rejected.
  • fulfilled: operação bem sucedida.
  • rejected: operação falha.
  • settled: A Promise é fulfilled ou rejected, mas não pending.

Carregando uma imagem com XHRSeção

Um exemplo simples usando Promise e XMLHttpRequest para carregar uma imagem disponível no repositório MDN GitHub promise-test. Você também pode vê-lo executando. Cada etapa está comentada o que lhe permite seguir de perto a arquitetura Promise e arquitetura XHR. Aqui está a versão não comentada, mostrando o fluxo Promise para que você possa ter uma ideia:

function imgLoad(url) {
  return new Promise(function(resolve, reject) {
    var request = new XMLHttpRequest();
    request.open('GET', url);
    request.responseType = 'blob';
    request.onload = function() {
      if (request.status === 200) {
        resolve(request.response);
      } else {
        reject(Error('Image didn\'t load successfully; error code:' 
                     + request.statusText));
      }
    };
    request.onerror = function() {
      reject(Error('There was a network error.'));
    };
    request.send();
  });
}

.

Laços oferecem um jeito fácil e rápido de executar uma ação repetidas vezes. Este capítulo abordará diferentes formas de iterações existentes no JavaScript.

Você pode pensar em um laço de repetição como um jogo onde você manda o seu personagem andar X passos em uma direção e Y passos em outra; por exemplo, a ideia “vá 5 passos para leste” pode ser expressa em um laço desta forma:

var passo;
for (passo = 0; passo < 5; passo++) {
  // Executa 5 vezes, com os valores de passos de 0 a 4.
  console.log('Ande um passo para o leste');
}

Existem várias formas diferentes de laços, mas eles essencialmente fazem a mesma coisa: repetir uma ação múltiplas vezes ( inclusive você poderá repetir 0 vezes). Os vários mecanismos diferentes de laços oferecem diferentes formas de determinar quando este irá começar ou terminar. Há várias situações em que é mais fácil resolver um problema utilizando um determinado tipo de laço do que outros.

Os possíveis laços de repetição  em JavaScript:

  • for_statement
  • do…while_statement
  • while_statement
  • label_statement
  • break_statement
  • continue_statement
  • for…in_statement
  • for…of_statement

Declaração for

Um laço for é repetido até que a condição especificada seja falsa. O laço for no JavaScript é similar ao Java e C. Uma declaração for é feita da seguinte maneira:

for ([expressaoInicial]; [condicao]; [incremento])
  declaracao

Quando um for é executado, ocorre o seguinte:

  1. A expressão expressao Inicial é inicializada e, caso possível, é executada. Normalmente essa expressão inicializa um ou mais contadores, mas a sintaxe permite expressões de qualquer grau de complexidade. Podendo conter também declaração de variáveis.
  2. A expressão condicao é avaliada. caso o resultado de condicao seja verdadeiro, o laço é executado. Se o valor de condicao é falso, então o laço terminará. Se a expressão condicao é omitida, a condicao é assumida como verdadeira.
  3.  A instrução é executada. Para executar múltiplas declarações, use uma declaração em bloco ({ … }) para agrupá-las.
  4. A atualização da expressão incremento, se houver, executa, e retorna o controle para o passo 2.

Exemplo

A função a seguir contém uma declaração for que contará o número de opções selecionadas em uma lista (um elemento <select> permite várias seleções). Dentro do for é declarado uma váriavel i inicializada com zero. A declaração for verifica se i é menor que o número de opções no elemento <select>, executa sucessivas declaração  if, e incrementa i de um em um a cada passagem pelo laço.

<form name="selectForm">
  <p>
    <label for="tipoMusica">Escolha alguns tipos de música, em seguida, clique no botão abaixo:</label>
    <select id="tipoMusica" name="tipoMusica" multiple="multiple">
      <option selected="selected">R&B</option>
      <option>Jazz</option>
      <option>Blues</option>
      <option>New Age</option>
      <option>Classico</option>
      <option>Ópera</option>
    </select>
  </p>
  <p><input id="btn" type="button" value="Quantos foram selecionados?" /></p>
</form>

<script>
function howMany(selectObject) {
  var numeroSelecionadas = 0;
  for (var i = 0; i < selectObject.options.length; i++) {
    if (selectObject.options[i].selected) {
      numeroSelecionadas++;
    }
  }
  return numeroSelecionadas;
}

var btn = document.getElementById("btn");
btn.addEventListener("click", function(){
  alert('Total de opções selecionadas: ' + howMany(document.selectForm.tipoMusica))
});
</script>

Declaração do...while

A instrução do…while repetirá até que a condição especificada seja falsa.

do
  declaracao
while (condicao);

A instrução será executada uma vez antes da condição ser verificada. Para executar multiplas instruções utilize uma declaração de bloco ({ … }) para agrupá-las. Caso a condicao seja verdadeira, então o laço será executado novamente. Ao final de cada execução, a condicao é verificada. Quando a condição contida no while for falsa a execução do laço é terminada e o controle é passado para a instrução seguinte a do...while.

Exemplo

No exemplo a seguir, o laço é executado pelo menos uma vez e irá executar até que i seja menor que 5.

do {
  i += 1;
  console.log(i);
} while (i < 5);

Declaração while

Uma declaração while executa suas instruções, desde que uma condição especificada seja avaliada como verdadeira. Segue uma declaração while

while (condicao)
  declaracao

Se a condição se tornar falsa,  a declaração dentro do laço para a execução e o controle é passado para a instrução após o laço.

O teste da condição ocorre antes que o laço seja executado. Desta forma se a condição for verdadeira o laço executará e testará a condição novamente. Se a condição for falsa o laço termina e passa o controle para as instruções após o laço.

Para executar múltiplas declarações, use uma declaração em bloco ({ … }) para agrupar essas declarações.

Exemplo 1

while a seguir executará enquanto n for menor que três:

n = 0;
x = 0;
while (n < 3) {
  n++;
  x += n;
}

A cada iteração, o laço incrementa n e adiciona este valor para x. Portanto, x e n recebem os seguintes valores:

  • Depois de executar pela primeira vez: n = 1 e x = 1
  • Depois da segunda vez: n = 2 e x = 3
  • Depois da terceira vez: n = 3 e x = 6

Depois de executar pela terceira vez, a condição n < 3 não será mais verdadeira, então o laço encerrará.

Exemplo 2

Evite laços infinitos. Tenha certeza que a condição do laço eventualmente será falsa; caso contrário, o laço nunca terminará. O while a seguir executará para sempre pois sua condição nunca será falsa:

while (true) {
  console.log("Olá, mundo");
}

Declaração label

Um label provê um identificador que permite que este seja referenciado em outro lugar no seu programa. Por exemplo, você pode usar uma label para identificar um laço, e então usar break ou continue para indicar quando o programa deverá interromper o laço ou continuar sua execução.

Segue a sintaxe da instrução label:

label : declaracao

Um label pode usar qualquer idenficador que não seja uma palavra reservada do JavaScript. Você pode identificar qualquer instrução com um label.

Exemplo

Neste exemplo, o label markLoop idenfica um laço while.

markLoop:
while (theMark == true) {
   facaAlgo();
}

Declaração break

Use break para terminar laços, switch, ou um conjunto que utiliza label.

  • Quando você utiliza break sem um label, ele encerrará imediatamente o laço mais interno whiledo-whilefor, ou switch e transferirá o controle para a próxima instrução.
  • Quando você utiliza break com um label, ele encerrará o label específico.

Segue a sintaxe do break:

  1. break;
  2. break label;

Na primeira opção será encerrado o laço de repetição mais interno ou switch. Já na segunda opção será encerrada o bloco de código referente a label.

Exemplo 1

O exemplo a seguir percorre os elementos de um array até que ele encontre o índice do elemento que possui o valor contido em theValue:

for (i = 0; i < a.length; i++) {
  if (a[i] == theValue) {
    break;
  }
}

Exemplo 2: Utilizando break em label

var x = 0;
var z = 0
labelCancelaLaco: while (true) {
  console.log("Laço exterior: " + x);
  x += 1;
  z = 1;
  while (true) {
    console.log("Laço interior: " + z);
    z += 1;
    if (z === 10 && x === 10) {
      break labelCancelaLaco;
    } else if (z === 10) {
      break;
    }
  }
}

Declaração continue

A declaração continue pode ser usada para reiniciar uma instrução whiledo-whilefor, ou label.

  • Quando você utiliza continue sem uma label, ele encerrará a iteração atual mais interna de uma instrução whiledo-while, ou for e continuará a execução do laço a partir da próxima iteração. Ao contrário da instrução breakcontinue não encerra a execução completa do laço. Em um laço while, ele voltará para a condição. Em um laço for, ele pulará para a expressão de incrementação.
  • Quando você utiliza continue com uma label, o continue será aplicado ao laço identificado por esta label. 

Segue a sintaxe do continue:

  1. continue;
  2. continue label;

Exemplo 1

O exemplo a seguir mostra um laço while utlizando continue que executará quando o valor de i for igual a 3. Desta forma, n recebe os valores um, três, sete, e doze.

i = 0;
n = 0;
while (i < 5) {
  i++;
  if (i == 3) {
    continue;
  }
  n += i;
}

Exemplo 2

Uma instrução label checkiandj contém uma instrução label checkj. Se o continue for executado, o programa terminará a iteração atual de checkj e começará a próxima iteração. Toda vez que o continue for executado, checkj recomeçará até que a condição do while for falsa. Quando isto ocorrer checkiandj executará até que sua condição seja falsa.

Se o continue estivesse referenciando checkiandj, o programa deveria continuar do topo de checkiandj.

checkiandj:
  while (i < 4) {
    console.log(i);
    i += 1;
    checkj:
      while (j > 4) {
        console.log(j);
        j -= 1;
        if ((j % 2) == 0) {
          continue checkj;
        }
        console.log(j + " é estranho.");
      }
      console.log("i = " + i);
      console.log("j = " + j);
  }

Declaração for...in

A declaração for…in executa iterações a partir de uma variável específica, percorrendo todas as propriedades de um objeto.
Para cada propriedade distinta, o JavaScript executará uma iteração. Segue a sintaxe:

for (variavel in objeto) {
  declaracoes
}

Exemplo

A função a seguir recebe em seu argumento um objeto e o nome deste objeto. Então executará uma iteração para cada elemento e retornará uma lista de string, que irá conter o nome da propriedade e seu valor.

function dump_props(obj, obj_name) {
  var result = "";
  for (var i in obj) {
    result += obj_name + "." + i + " = " + obj[i] + "<br>";
  }
  result += "<hr>";
  return result;
}

Para um objeto chamado car com propriedades make e model, o resultado será:

car.make = Ford
car.model = Mustang

Arrays

Embora seja tentador usar esta forma para interagir com os elementos de um Array, a declaração for…in irá retornar o nome pré-definido da propriedade ao invés do seu index numérico. Assim é melhor usar o tradicional for com index numérico quando interagir com arrays, pois o for…in interage com as propriedades definidas pelo programador ao invés dos elementos do array.

Declaração for...of

 A declaração for…of cria uma laço com objetos interativos ((incluindo, ArrayMapSet, assim por conseguinte ), executando uma iteração para o valor de cada propriedade distinta.

for (variavel of objeto) {
  declaracoes
}

O exemplo a seguir mostra a diferença entre o for...of e o for...in. Enquanto o for...in interage com o nome das propriedades, o for...of interage com o valor das propriedades.

let arr = [3, 5, 7];
arr.foo = "hello";

for (let i in arr) {
   console.log(i); // logs "0", "1", "2", "foo"
}

for (let i of arr) {
   console.log(i); // logs "3", "5", "7"
}

Definindo Funções

definição da função (também chamada de declaração de função) consiste no uso da palavra chave function, seguida por:

  • Nome da Função.
  • Lista de argumentos para a função, entre parênteses e separados por vírgulas.
  • Declarações JavaScript que definem a função, entre chaves { }.

Por exemplo, o código a seguir define uma função simples chamada square:

function square(numero) { 
  return numero * numero; 
}

A função square recebe um argumento, chamado numero. A função consiste em uma instrução que indica para retornar o argumento da função (isto é, numero) multiplicado por si mesmo. A declaração return especifica o valor retornado pela função.

return numero * numero;

Parâmetros primitivos (como um número) são passados para as funções por valor; o valor é passado para a função, mas se a função altera o valor do parâmetro, esta mudança não reflete globalmente ou na função chamada.

Se você passar um objeto (ou seja, um  valor não primitivo, tal como Array ou um objeto definido por você) como um parâmetro e a função alterar as propriedades do objeto, essa mudança é visível fora da função, conforme mostrado no exemplo a seguir:

function minhaFuncao(objeto) {
  objeto.make = "Toyota";
}

var meucarro = {make: "Honda", model: "Accord", year: 1998};
var x, y;

x = meucarro.make;     // x recebe o valor "Honda"

minhaFuncao(meucarro);
y = meucarro.make;     // y recebe o valor "Toyota"
                    // (a propriedade make foi alterada pela função)

Expressão de função

Embora a declaração de função acima seja sintaticamente uma declaração, funções também podem ser criadas por uma expressão de função. Tal função pode ser anônima; ele não tem que ter um nome. Por exemplo, a função square poderia ter sido definida como:

var square = function(numero) {return numero * numero}; 
var x = square(4) //x recebe o valor 16

No entanto, um nome pode ser fornecido com uma expressão de função e pode ser utilizado no interior da função para se referir a si mesma, ou em um debugger para identificar a função em stack traces:

var fatorial = function fac(n) {return n<2 ? 1 : n*fac(n-1)};

console.log(fatorial(3));

As expressões de função são convenientes ao passar uma função como um argumento para outra função. O exemplo a seguir mostra uma função map sendo definida e, em seguida, chamada com uma função anônima como seu primeiro parâmetro:

function map(f,a) {
  var result = []; // Cria um novo Array
  var i;
  for (i = 0; i != a.length; i++)
    result[i] = f(a[i]);
  return result;
}

O código a seguir:

map(function(x) {return x * x * x}, [0, 1, 2, 5, 10]);

retorna [0, 1, 8, 125, 1000].

Em JavaScript, uma função pode ser definida com base numa condição. Por exemplo, a seguinte definição de função define minhaFuncao somente se num  é igual a 0:

var minhaFuncao;
if (num == 0){
  minhaFuncao = function(objeto) {
    objeto.make = "Toyota"
  }
}

Além de definir funções, você também pode usar o contrutor Function para criar funções a partir de uma stringem tempo real, como no método eval().

Um método é uma função invocada por um objeto. Leia mais sobre objetos e métodos em Trabalhando com Objetos.

Chamando funções

A definição de uma função não a executa. Definir a função é simplesmente nomear a função e especificar o que fazer quando a função é chamada. Chamar a função executa, realmente, as ações especificadas com os parâmetros indicados. Por exemplo, se você definir a função square, você pode chamá-la do seguinte modo: 

square(5);

A declaração anterior chama a função com o argumento 5. A função executa as instruções e retorna o valor 25.

Funções devem estar no escopo quando são chamadas, mas a declaração de uma função pode ser alçada para o topo (“hoisted”), como neste exemplo:

console.log(square(5));
/* ... */
function square(n){return n*n}

O escopo de uma função é a função na qual ela é declarada, ou todo o programa se ela é declarada no nível superior.

Nota: Isso funciona apenas quando a definição da função usa a sintaxe acima (ex., function funcNome(){ }). O código a seguir não vai funcionar.

console.log(square(5));
var square = function (n) {
  return n * n;
}

Os argumentos de uma função não estão limitados a strings e números. Você pode passar objetos para uma função. A função show_props (definido em Trabalhando com Objetos) é um exemplo de uma função que recebe um objeto como um argumento.

Um função pode chamar a si mesma. Por exemplo, a função que calcula os fatoriais recursivamente:

function fatorial(n){
  if ((n == 0) || (n == 1))
    return 1;
  else
    return (n * fatorial(n - 1));
}

Você poderia, então, calcular os fatoriais de um a cinco:

var a, b, c, d, e;
a = fatorial(1); // a recebe o valor 1
b = fatorial(2); // b recebe o valor 2
c = fatorial(3); // c recebe o valor 6
d = fatorial(4); // d recebe o valor 24
e = fatorial(5); // e recebe o valor 120

Há outras maneiras de chamar funções. Muitas vezes há casos em que uma função precisa ser chamada dinamicamente, ou o número de argumentos de uma função varia, ou em que o contexto da chamada de função precisa ser definido para um objeto específico determinado em tempo de execução. Acontece que as funções são, por si mesmas, objetos, e esses objetos por sua vez têm métodos (veja objeto Function). Um desses, o método apply(), pode ser usado para atingir esse objetivo.

Escopo da função

As variáveis definidas no interior de uma função não podem ser acessadas de nenhum lugar fora da função, porque a variável está definida apenas no escopo da função. No entanto, uma função pode acessar todas variáveis e funções definida fora do escopo onde ela está definida. Em outras palavras, a função definida no escopo global pode acessar todas as variáveis definidas no escopo global. A função definida dentro de outra função também pode acessar todas as variáveis definidas na função hospedeira e outras variáveis ao qual a função hospedeira tem acesso.

// As seguintes variáveis são definidas no escopo global
var num1 = 20,
    num2 = 3,
    nome = "Chamahk";

// Esta função é definida no escopo global
function multiplica() {
  return num1 * num2;
}

multiplica(); // Retorna 60

// Um exemplo de função aninhada
function getScore () {
  var num1 = 2,
      num2 = 3;
  
  function add() {
    return nome + " scored " + (num1 + num2);
  }
  
  return add();
}

getScore(); // Retorna "Chamahk scored 5"

Escopo e a pilha de função

Recursão

Uma função pode referir-se e chamar a si própria. Há três maneiras de uma função referir-se a si mesma:

  1. o nome da função
  2. arguments.callee
  3. uma variável no escopo que se refere a função

Por exemplo, considere a seguinte definição de função:

var foo = function bar() {
   // declaracoes
};

Dentro do corpo da função, todos, a seguir, são equivalentes:

  1. bar()
  2. arguments.callee()
  3. foo()

Uma função que chama a si mesma é chamada de função recursiva. Em alguns casos, a recursividade é análoga a um laço. Ambos executam o código várias vezes, e ambos necessitam de uma condição (para evitar um laço infinito, ou melhor, recursão infinita, neste caso). Por exemplo,  o seguinte laço:

var x = 0;
while (x < 10) { // "x < 10" a condição do laço
   // faça coisas
   x++;
}

pode ser convertido em função recursiva e uma chamada para a função:

function loop(x) {
   if (x >= 10) // "x >= 10" a condição de parada (equivalente a "!(x < 10)")
      return;
   // faça coisas
   loop(x + 1); // chamada recursiva
}
loop(0);

No entanto, alguns algoritmos não podem ser simples laços iterativos. Por exemplo, conseguir todos os nós da estrutura de uma árvore (por exemplo, o DOM) é mais fácil se feito recursivamente:

function walkTree(node) {
   if (node == null) // 
      return;
   // faça algo com o nó
   for (var i = 0; i < node.childNodes.length; i++) {
      walkTree(node.childNodes[i]);
   }
}

Em comparação ao laço da função, cada chamada recursiva realiza outras chamadas recursivas.

É possível converter qualquer algoritmo recursivo para um não recursivo, mas muitas vezes a lógica é muito mais complexa e exige o uso de pilhas. Na verdade a própria recursão usa pilha: a pilha de função.

O comportamento da pilha pode ser vista a seguir no exemplo:

function foo(i) {
   if (i < 0)
      return;
   document.writeln('begin:' + i);
   foo(i - 1);
   document.writeln('end:' + i);
}
foo(3);

que produz:

begin:3
begin:2
begin:1
begin:0
end:0
end:1
end:2
end:3

Funções aninhadas e closures

Você pode aninhar uma função dentro de outra. A função aninhada (interna) é acessível apenas para a função que a contém (exterior). Isso constitui também uma closure. Uma closure é uma expressão (tipicamente uma função) que pode ter variáveis livres em conjunto com um ambiente que conecta estas variáveis (que “fecha” a expressão).

Uma vez que uma função aninhada é uma closure, isto significa que uma função aninhada pode “herdar” os argumentos e variáveis de sua função de contenção. Em outras palavras, a função interior contém o escopo da função exterior.

Em resumo:

  • A função interna só pode ser acessada a partir de declarações em função externa.
  • A função interna forma uma closure: a função  interna pode usar os argumentos e variáveis da função externa, enquanto a função externa não pode usar os argumentos e variáveis da função interna.

O exemplo a seguir mostra as funções aninhadas:

function addSquares(a,b) {
   function square(x) {
      return x * x;
   }
   return square(a) + square(b);
}
a = addSquares(2,3); // retorna 13
b = addSquares(3,4); // retorna 25
c = addSquares(4,5); // retorna 41

Uma vez que a função interna forma uma closure, você pode chamar a função externa e especificar argumentos para a função externa e interna:

function fora(x) {
   function dentro(y) {
      return x + y;
   }
   return dentro;
}
fn_inside = fora(3); // Pense nisso como: Receba uma função que adicionará 3 ao que quer que você repasse para ela
result = fn_inside(5); // retorna 8

result1 = fora(3)(5); // retorna 8

Preservação  de variáveis

Observe como x é preservado quando dentro é retornado. Uma closure deve preservar os argumentos e variáveis em todos os escopos que ela referencia. Uma vez que cada chamada fornece potencialmente argumentos diferentes, uma nova closure é criada para cada chamada de fora. A memória só poderá ser liberada quando o dentro retornado já não é mais acessível.

Isso não é diferente de armazenar referências em outros objetos, mas muitas vezes é menos óbvio, porque um não define diretamente as referências e não pode inspecioná-las.

Múltiplas funções aninhadas

Funções podem ter múltiplo aninhamento, por exemplo, a função (A) contém a função (B) que contém a função (C). Tanto as funções B e C formam uma closure, então B pode acessar A, e C pode acessar B. Além disso, uma vez que C pode acessar B que pode acessar A, C também pode acessar A. Assim, a closure pode conter vários escopos; eles recursivamente contém o escopo das funções que os contém. Isso é chamado encadeamento de escopo. (Porque isso é chamado de “encadeamento”, será explicado mais tarde).

Considere o seguinte exemplo:

function A(x) {
   function B(y) {
      function C(z) {
         alert(x + y + z);
      }
      C(3);
   }
   B(2);
}
A(1); // Exibe um alerta com o valor 6 (1 + 2 + 3)

Neste exemplo, C acessa y do B e x do A. Isso pode ser feito porque:

  1. B forma uma closure incluindo A, isto é, B pode acessar argumentos e variáveis de A.
  2. C forma uma closure incluindo B.
  3.  Devido a closure B inclui A, a closure C inclui AC pode acessar tanto argumentos e variáveis de B como de A. Em outras palavras, C encadeia o escopo de B e A, nesta ordem.

O inverso, no entanto, não é verdadeiro. A não pode acessar C, porque A não pode acessar qualquer argumento ou variável de B. Assim, C é privado somente a B.

Conflitos de nome

Quando dois argumentos ou variáveis nos escopos da closure tem o mesmo nome, há um conflito de nome. Mas escopos internos tem prioridade, por isso o escopo mais interno tem a maior prioridade, enquanto que o escopo mais externo tem a menor. Esta é a cadeia de escopo. O primeiro da cadeia é o escopo mais interno, e o último é o escopo mais externo. Considere o seguinte:

function fora() {
   var x = 10;
   function dentro(x) {
      return x;
   }
   return dentro;
}
result = fora()(20); // retorna 20 em vez de 10

O  conflito de nome acontece na declaração return x e está entre o parâmetro x de dentro e a variável x de fora. A cadeia de escopo aqui é {dentrofora, objeto global}. Por isso o x de dentro tem precedência sobre o x de fora, e 20 (x de dentro) é retornado em vez de 10 (x de fora).

Closures

Closures são um dos recursos mais poderosos de JavaScript. JavaScript permite o aninhamento de funções e garante acesso completo à função interna a todas as variáveis e funções definidas dentro da função externa (e todas as outras variáveis e funções que a função externa tem acesso). No entanto, a função externa não tem acesso às variáveis e funções definidas dentro da função interna. Isto proporciona uma espécie de segurança para as variáveis da função interna. Além disso, uma vez  que a função interna tem acesso ao escopo da função externa, as variáveis e funções definidas na função externa vão durar na memória mais do que a própria função externa, isto se a função interna permanecer na memória mais tempo do que a função externa. Uma closure é criada quando a função interna é de alguma forma disponibilizada para qualquer escopo fora da função externa.

var pet = function(nome) {          // A função externa define uma variável "nome"
      var getNome = function() {
        return nome;                // A função interna tem acesso à variável "nome"  da função externa
      }

      return getNome;               // Retorna a função interna, expondo-a assim para escopos externos
    },
    myPet = pet("Vivie");
    
myPet();                            // Retorna "Vivie"

Ela pode ser  mais complexa que o código acima. Um objeto contendo métodos para manipular as variáveis da função externa pode ser devolvida.

var criarPet = function(nome) {
  var sex;
  
  return {
    setNome: function(newNome) {
      nome = newNome;
    },
    
    getNome: function() {
      return nome;
    },
    
    getSex: function() {
      return sex;
    },
    
    setSex: function(newSex) {
      if(typeof newSex == "string" && (newSex.toLowerCase() == "macho" || newSex.toLowerCase() == "fêmea")) {
        sex = newSex;
      }
    }
  }
}

var pet = criarPet("Vivie");
pet.getNome();                  // Vivie

pet.setNome("Oliver");
pet.setSex("macho");
pet.getSex();                   // macho
pet.getNome();                  // Oliver

Nos códigos acima, a variável nome da função externa é acessível para as funções internas, e não há nenhuma outra maneira para acessar as variáveis internas, exceto pelas funções internas. As variáveis internas da função interna atuam como armazenamento seguro para as funções internas. Elas armazenam “persistentes”, mas seguros, os dados com os quais as funções internas irão trabalhar. As funções não tem  que ser atribuídas a uma variável, ou ter um nome.

var getCode = (function(){
  var secureCode = "0]Eal(eh&2";    // Um código que não queremos que pessoas de fora sejam capazes de modificar
  
  return function () {
    return secureCode;
  };
})();

getCode();    // Retorna o secureCode

Há, no entanto, uma série de armadilhas que se deve ter cuidado ao usar closures. Se uma função fechada define uma variável com o mesmo nome de uma variável em um escopo externo, não há nenhuma maneira de se referir para a variável em um escopo externo novamente.

var createPet = function(nome) {  // Função externa define uma variável chamada "nome"
  return {
    setNome: function(nome) {    // Função fechada define uma variável chamada "nome"
      nome = nome;               // ??? Como podemos acessar o "nome" definido pela função externa ???
    }
  }
}

A palavra reservada this é muito complicada em closures.  Elas têm de ser usadas com muito cuidado, como ao que this se refere depende completamente de onde a função foi chamada, ao invés de onde ela foi definida.

Usando objeto de argumentos

Os argumentos de uma função são mantidos em um objeto do tipo array. Dentro de uma função, você pode endereçar os argumentos passados para ele conforme: 

arguments[i]

onde i é um número ordinal do argumento, começando com zero. Então, o primeiro argumento passado para a função seria arguments[0]. O número total de argumentos é indicado por arguments.length.

Usando o objeto arguments, você pode chamar a função com mais argumentos do que o formalmente declarado. Isso muitas vezes é útil se você não sabe de antemão quantos argumentos serão passados para a função. Você pode usar arguments.length para determinar a quantidade de argumentos passados para a função, e então acessar cada argumento usando o objeto arguments.

Por exemplo, considere uma função que concatena várias strings. O argumento formal para a função é uma string que especifica os caracteres que separam os itens para concatenar.  A função definida como segue:

function myConcat(separador) {
   var result = "", // inicializa a lista
       i;
   // itera por meio de argumentos
   for (i = 1; i < arguments.length; i++) {
      result += arguments[i] + separador;
   }
   return result;
}

Você pode passar qualquer quantidade de argumentos para esta função, e ela concatena cada argumento na string “list”:

// retorna "red, orange, blue, "
myConcat(", ", "red", "orange", "blue");

// retorna "elephant; giraffe; lion; cheetah; "
myConcat("; ", "elephant", "giraffe", "lion", "cheetah");

// retorna "sage. basil. oregano. pepper. parsley. "
myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");

Nota: A variável arguments é “como um array”, mas não é um array. Ela é como um array pois possui um índice numerado e a propriedade length. No entanto, não possui todos os métodos de manipulação de array. 

Veja objeto Function na referência do JavaScript para maiores informações.

Parâmetros de função

Começando com ECMAScript 6, há dois tipos novos de parâmetros: parâmetros padrão e parâmetros rest.

Parâmetros padrão

Em JavaScript, parâmetros padrões de funções são undefined. No entanto, em algumas situações pode ser útil definir um valor padrão diferente. Isto é onde os parâmetros padrão podem ajudar.

No passado, a estratégia geral para definir padrões era testar os valores de parâmetro no corpo da função e atribuir um valor se eles fossem undefined. Se, no exemplo a seguir, nenhum valor é fornecido para b na chamada, seu valor seria undefined ao avaliar a*b e a chamada para multiplicar retornaria NaN. No entanto, isso é pego com a segunda linha neste exemplo:

function multiplicar(a, b) {
  b = typeof b !== 'undefined' ?  b : 1;

  return a*b;
}

multiplicar(5); // 5

Com parâmetros padrão, a verificação no corpo da função não é mais necessária. Agora você pode simplesmente colocar 1 como valor padrão para b no campo de declaração de parâmetros:

function multiplicar(a, b = 1) {
  return a*b;
}

multiplicar(5); // 5

Parâmetros rest

A sintaxe de parâmetro rest permite representar um número indefinido de argumentos como um array. No exemplo, usamos parâmetros rest para coletar argumentos do segundo argumento ao último. Então os multiplicamos pelo primeiro argumento. Neste exemplo é usado uma função seta, que será introduzida na próxima seção.

function multiplicar(multiplicador, ...args) {
  return args.map(x => multiplicador * x);
}

var arr = multiplicar(2, 1, 2, 3);
console.log(arr); // [2, 4, 6]

Funções de seta

Uma expressão função de seta (anteriormente conhecida como função de seta gorda) tem uma sintaxe pequena em comparação com a expressão de função e lexicalmente vincula o valor this. Funções de seta são sempre anônimas. Consulte também no blog hacks.mozilla.org no post: “ES6 In Depth: Arrow functions”.

Dois fatores influenciaram a introdução de funções de seta: funções mais curtas e o léxico this.

Funções curtas

Em alguns padrões funcionais, funções curtas são bem-vindas. Compare:

var a = [
  "Hydrogen",
  "Helium",
  "Lithium",
  "Beryl­lium"
];

var a2 = a.map(function(s){ return s.length });

var a3 = a.map( s => s.length );

Léxico this

Até as funções de seta, cada nova função definia seu próprio valor this (um novo objeto no caso de um construtor, indefinido em chamadas de função no modo estrito, o objeto de contexto se a função é chamada como um “método de objeto”, etc.). Isso pode ser irritante com um estilo de programação orientada a objetos.

function Pessoa() {      // O construtor Pessoa() define 'this' como sendo ele.   
    this.idade = 0; 
    setInterval(function crescer() {    // No modo não estrito, a função crescer define 'this'
            // como o objeto global, o que é diferente do 'this'
            // definido pelo construtor Pessoa().
            this.idade++; 
     }, 1000); 
} 
var p = new Pessoa();

No ECMAScript 3/5, este problema foi resolvido atribuindo o valor em this a uma variável que poderia ser fechada.

function Pessoa() {
  var self = this; // Alguns preferem 'that' em vez de 'self'. 
                   // Escolha um e seja consistente.
  self.idade = 0;

  setInterval(function crescer() {
    // A chamada de retorno refere-se à variável 'self' na qual
    // o valor é o objeto esperado.
    self.idade++;
  }, 1000);
}

Como alternativa, uma função vinculada poderia ser criada para que o valor da propriedade this seja passado para a função crescer().

Funções de seta capturam o valor this do contexto delimitado, então o código a seguir funciona conforme o esperado.

function Pessoa(){
  this.idade = 0;

  setInterval(() => {
    this.idade++; // propriedade |this|refere ao objeto pessoa
  }, 1000);
}

var p = new Pessoa();

Funções pré-definidas

JavaScript tem várias funções pré-definidas:eval()

O método eval() avalia código JavaScript representado como uma string.uneval()

O método uneval() cria uma representação de string do código-fonte de um  Object.isFinite()

A função global isFinite() determina se o valor passado é um número finito. Se necessário, o parâmetro é primeiro convertido para um número.isNaN()

A função isNaN() determina se um valor é NaN ou não. Nota: coerção dentro da função isNaN tem regras interessantes; você pode, alternativamente, querer usar Number.isNaN(), como definido no ECMAScript 6,  ou você pode usar typeof para determinar se o valor não é um número.parseFloat()

A função parseFloat() analisa um argumento do tipo string e retorna um número de ponto flutuante.parseInt()

A função parseInt() analisa um argumento do tipo string e retorna um inteiro da base especificada (base do sistema numérico).decodeURI()

A função decodeURI() decodifica uma Uniform Resource Identifier (URI) criada anteriormente por encodeURI ou por uma rotina similar.decodeURIComponent()

O método decodeURIComponent() decodifica um componente Uniform Resource Identifier (URI) criado anteriormente por encodeURIComponent ou por uma rotina similar.encodeURI()

O método encodeURI() codifica um Uniform Resource Identifier (URI), substituindo cada ocorrência de determinados caracteres por um, dois, três, ou quatro sequências de escape que representa a codificação UTF-8 do caracter (só serão quatro sequências de escape para caracteres compostos de dois caracteres “substitutos”).encodeURIComponent()

O método encodeURIComponent() codifica um componente Uniform Resource Identifier (URI), substituindo cada ocorrência de determinados caracteres por um, dois, três, ou quatro sequências de escape que representa a codificação UTF-8 do caracter (só serão quatro sequências de escape para caracteres compostos de dois caracteres “substitutos”).escape()

O método obsoleto escape() calcula uma nova string na qual certos caracteres foram substituídos por uma sequência de escape hexadecimal. Use encodeURI ou encodeURIComponent em vez disso.unescape()

O método obsoleto unescape() calcula uma nova string na qual sequências de escape hexadecimais são substituídas pelo caractere que ela representa. As sequências de escape podem ser introduzidas por uma função como escape. Por unescape() estar obsoleto, use decodeURI() ou decodeURIComponent ao invés dele.

Operadores

O JavaScript possui os tipos de operadores a seguir. Esta seção descreve os operadores e contém informações sobre precedência de operadores.

  • Operadores de atribuição
  • Operadores de comparação
  • Operadores aritméticos
  • Operadores bit a bit
  • Operadores lógicos
  • Operadores de string
  • Operador condicional (ternário)
  • Operador vírgula
  • Operadores unário
  • Operadores relacionais

O JavaScript possui tanto operadores binários quanto unários e um operador ternário, o operador condicional. Um operador binário exige dois operandos, um antes do operador e outro depois:

operando1 operador operando2

Por exemplo, 3+4 ou x*y.

Um operador unário exige um único operando, seja antes ou depois do operador:

operador operando

ou

operando operador

Por exemplo, x++ ou ++x.

Operadores de atribuição

Um operador de atribuição atribui um valor ao operando à sua esquerda baseado no valor do operando à direita. O operador de atribuição básico é o igual (=), que atribui o valor do operando à direita ao operando à esquerda. Isto é, x = y atribui o valor de y a x.

Os outros operadores de atribuição são encurtamentos de operadores padrão, como mostrado na tabela a seguir.

NomeOperador encurtadoSignificado
Atribuiçãox = yx = y
Atribuição de adiçãox += yx = x + y
Atribuição de subtraçãox -= yx = x - y
Atribuição de multiplicaçãox *= yx = x * y
Atribuição de divisãox /= yx = x / y
Atribuição de restox %= yx = x % y
Atribuição exponencialx **= yx = x ** y
Atribuição bit-a-bit por deslocamento á esquerdax <<= yx = x << y
Atribuição bit-a-bit por deslocamento á direitax >>= yx = x >> y
Atribuiçãode bit-a-bit deslocamento á direita não assinadox >>>= yx = x >>> y
Atribuição AND bit-a-bitx &= yx = x & y
Atribuição XOR bit-a-bitx ^= yx = x ^ y
Atribuição OR bit-a-bitx |= yx = x | y

Operadores de comparação

Um operador de comparação compara seus operandos e retorna um valor lógico baseado em se a comparação é verdadeira. Os operandos podem ser numéricos, strings, lógicos ou objetos. Strings são comparadas com base em ordenação lexográfica utilizando valores Unicode. Na maioria dos casos, se dois operandos não são do mesmo tipo, o JavaScript tenta convertê-los para um tipo apropriado. Isto geralmente resulta na realização de uma comparação numérica. As únicas exceções a esta regra são os operadores === e o !==, que realizam comparações de igualdade e desigualdade “estritas”. Estes operadores não tentam converter os operandos em tipos compatíveis antes de verificar a igualdade. A tabela a seguir descreve os operadores de comparação levando em conta o seguinte código:

var var1 = 3;
var var2 = 4;
OperadorDescriçãoExemplos que retornam verdadeiro
Igual (==)Retorna verdadeiro caso os operandos sejam iguais.3 == var1"3" == var13 == '3'
Não igual (!=)Retorna verdadeiro caso os operandos não sejam iguais.var1 != 4
var2 != "3"
Estritamente igual (===)Retorna verdadeiro caso os operandos sejam iguais e do mesmo tipo. Veja também Object.is e igualdade em JS.3 === var1
Estritamente não igual (!==)Retorna verdadeiro caso os operandos não sejam iguais e/ou não sejam do mesmo tipo.var1 !== "3"
3 !== '3'
Maior que (>)Retorna verdadeiro caso o operando da esquerda seja maior que o da direita.var2 > var1
"12" > 2
Maior que ou igual (>=)Retorna verdadeiro caso o operando da esquerda seja maior ou igual ao da direita.var2 >= var1
var1 >= 3
Menor que (<)Retorna verdadeiro caso o operando da esquerda seja menor que o da direita.var1 < var2
"12" < "2"
Menor que ou igual (<=)Retorna verdadeiro caso o operando da esquerda seja menor ou igual ao da direita.var1 <= var2
var2 <= 5

Nota: (=>) não é um operador, mas a notação para função de seta

Operadores aritméticos

Operadores aritméticos tomam valores numéricos (sejam literais ou variáveis) como seus operandos e retornam um único valor númerico. Os operadores aritméticos padrão são os de soma (+), subtração (-), multiplicação (*) e divisão (/). Estes operadores trabalham da mesma forma como na maioria das linguagens de programação quando utilizados com números de ponto flutuante (em particular, repare que divisão por zero produz um NaN). Por exemplo:

console.log(1 / 2); /* imprime 0.5 */
console.log(1 / 2 == 1.0 / 2.0); /* isto também é verdadeiro */

Em complemento às operações aritméticas padrões (+, -, * /), o JavaScript disponibiliza os operadores aritméticos listados na tabela a seguir.

OperadorDescriçãoExemplo
Módulo (%)Operador binário. Retorna o inteiro restante da divisão dos dois operandos.12 % 5 retorna 2.
Incremento (++)Operador unário. Adiciona um ao seu operando. Se usado como operador prefixado (++x), retorna o valor de seu operando após a adição. Se usado como operador pósfixado (x++), retorna o valor de seu operando antes da adição.Se x é 3, então ++x define x como 4 e retorna 4, enquanto x++ retorna 3 e, somente então, define x como 4.
Decremento (–)Operador unário. Subtrai um de seu operando. O valor de retorno é análogo àquele do operador de incremento.Se x é 3, então --x define x como 2 e retorna 2, enquanto x-- retorna 3 e, somente então, define x como 2.
Negação (-)Operador unário. Retorna a negação de seu operando.Se x é 3, então -x retorna -3.
Adição (+)Operador unário. Tenta converter o operando em um número, sempre que possível.+”3″ retorna 3.+true retorna 1.
Operador de exponenciação (**) Calcula a base elevada á potência do expoente, que é, baseexpoente2 ** 3 retorna 8.10 ** -1 retorna 0.1

Operadores bit a bit

Operadores bit a bit tratam seus operandos como um conjunto de 32 bits (zeros e uns), em vez de tratá-los como números decimais, hexadecimais ou octais. Por exemplo, o número decimal nove possui uma representação binária 1001. Operadores bit a bit realizam suas operações nestas representações, mas retornam valores numéricos padrões do JavaScript.

A tabela a seguir resume os operadores bit a bit do JavaScript.

OperadorExpressãoDescrição
ANDa & bRetorna um 1 para cada posição em que os bits da posição correspondente de ambos operandos sejam uns.
ORa | bRetorna um 0 para cada posição em que os bits da posição correspondente de  ambos os operandos sejam zeros.
XORa ^ bRetorna um 0 para cada posição em que os bits da posição correspondente são os mesmos.

[Retorna um 1 para cada posição em que os bits da posição correspondente sejam diferentes.]
NOT~ aInverte os bits do operando.
Deslocamento à esquerdaa << bDesloca a em representação binária b bits à esquerda, preenchendo com zeros à direita.
Deslocamento à direita com propagação de sinala >> bDesloca a em representação binária b bits à direita, descartando bits excedentes.
Deslocamento à direita com preenchimento zeroa >>> bDesloca a em representação binária b bits à direita, descartando bits excedentes e preenchendo com zeros à esquerda.

Operadores bit a bit lógicos

Conceitualmente, os operadores bit a bit lógicos funcionam da seguinte maneira:

  • Os operandos são convertidos em inteiros de 32 bits e expressos como uma série de bits (zeros e uns). Números com representação maior que 32 bits terão seus bits truncados. Por exemplo, o seguinte inteiro tem representação binária maior que 32 bits será convertido em um inteiro de 32 bits.
Antes: 11100110111110100000000000000110000000000001
Depois:            10100000000000000110000000000001
  • Cada bit do primeiro operando é pareado com o bit correspondente do segundo operando: primeiro bit com primeiro bit, segundo bit com segundo bit e assim por diante.
  • O operador é aplicado a cada par de bits e o resultado é construído bit a bit.

Por exemplo, a representação binária de nove é 1001 e a representação binária de quinze é 1111. Desta forma, quando operadores bit a bit são aplicados a estes valores, os resultados são como se segue:

ExpressãoResultadoDescrição binária
15 & 991111 & 1001 = 1001
15 | 9151111 | 1001 = 1111
15 ^ 961111 ^ 1001 = 0110
~15-16~00000000...00001111 = 11111111...11110000
~9-10~00000000...00001001 = 11111111...11110110

Nota: No quadro acima perceba que todos os 32 bits são invertidos quando usa-se o operador bit a bit NOT, e que os bits mais significativos (extrema esquerda) são definidos com 1 que representam valores negativos (representação complemento de dois).

Operadores de deslocamento bit a bit

Os operadores de deslocamento bit a bit possui dois operandos: o primeiro é uma quantidade a ser deslocada e o segundo especifica o número de posições binárias as quais o primeiro operando deverá ser deslocado. A direção da operação de deslocamento é contralada pelo operador utilizado.

Operadores de deslocamento convertem seus operandos em inteiros de 32 bits e retornam um resultado do tipo do operando à esquerda.

Os operadores de deslocamento são listados na tabela a seguir.

OperadorDescriçãoExemplo
Deslocamento à esquerda (<<)Este operador desloca o primeiro operando pelo número especificado de bits à esquerda. Bits excedentes deslocados para fora do limite à esquerda são descartados. Bits zero são inseridos à direita.9<<2 produz 36 porque 1001 deslocado 2 bits à esquerda se torna 100100, que é 36.
Deslocamento à direita com propagação de sinal
(>>)
Este operador desloca o primeiro operando pelo número especificado de bits à direita. Bits excedentes deslocados para fora do limite à direita são descartados. Cópias dos bits mais à esquerda são deslocadas a partir da esquerda.9>>2 produz 2 porque 1001 deslocado 2 bits à direita se torna 10, que é 2. De forma similar, -9>>2 produz -3 porque o sinal é preservado.
Deslocamento à direita com preenchimento zero
(>>>)
Este operador desloca o primeiro operando pelo número especificado de bits à direita. Bits excedentes deslocados para fora do limite à direita são descartados. Bits zero são inseridos à esquerda.19>>>2 produz 4 porque 10011 deslocado 2 bits à direita se torna 100, que é 4. Para números não negativos o deslocamento à direita com propagação de sinal e o deslocamento à direita com preenchimento zero produzem o mesmo resultado.

Operadores lógicos

Operadores lógicos são utilizados tipicamente com valores booleanos (lógicos); neste caso, retornam um valor booleano. Entretanto, os operadores && e || na verdade retornam o valor de um dos operandos especificados, de forma que se esses operadores forem utilizados com valores não-booleanos, eles possam retornar um valor não-booleano. Os operadores lógicos são descritos na seguinte tabela.

OperadorUtilizaçãoDescrição
AND lógico (&&)expr1 && expr2(E lógico) – Retorna expr1 caso possa ser convertido para falso; senão, retorna expr2. Assim, quando utilizado com valores booleanos, && retorna verdadeiro caso ambos operandos sejam verdadeiros; caso contrário, retorna falso.
OU lógico (||)expr1 || expr2(OU lógico) –  Retorna expr1 caso possa ser convertido para verdadeiro; senão, retorna expr2. Assim, quando utilizado com valores booleanos, || retorna verdadeiro caso ambos os operandos sejam verdadeiro; se ambos forem falsos, retorna falso.
NOT lógico (!)!expr(Negação lógica) Retorna falso caso o único operando possa ser convertido para verdadeiro; senão, retorna verdadeiro.

Exemplos de expressões que podem ser convertidas para falso são aquelas que são avaliados como nulo, 0, string vazia (“”) ou undefined.

O código a seguir mostra exemplos do operador && (E lógico).

var a1 =  true && true;     // t && t retorna true
var a2 =  true && false;    // t && f retorna false
var a3 = false && true;     // f && t retorna false
var a4 = false && (3 == 4); // f && f retorna false
var a5 = "Gato" && "Cão";   // t && t retorna Cão
var a6 = false && "Gato";   // f && t retorna false
var a7 = "Gato" && false;   // t && f retorna false

O código a seguir mostra exemplos do operador || (OU lógico).

var o1 =  true || true;     // t || t retorna true
var o2 = false || true;     // f || t retorna true
var o3 =  true || false;    // t || f retorna true
var o4 = false || (3 == 4); // f || f retorna false
var o5 = "Gato" || "Cão";   // t || t retorna Gato
var o6 = false || "Gato";   // f || t retorna Gato
var o7 = "Gato" || false;   // t || f retorna Gato

O código a seguir mostra exemplos do operador ! (negação lógica).

var n1 = !true;   // !t retorna false
var n2 = !false;  // !f retorna true
var n3 = !"Gato"; // !t retorna false

Avaliação de curto-circuito

Como expressões lógicas são avaliadas da esquerda para a direita, elas são testadas como possíveis avaliações de “curto-circuito” utilizando as seguintes regras:

  • false && qualquercoisa é avaliado em curto-circuito como falso.
  • true || qualquercoisa é avaliado em curto-circuito como verdadeiro.

As regras de lógica garantem que estas avaliações estejam sempre corretas. Repare que a parte qualquercoisa das expressões acima não é avaliada, de forma que qualquer efeito colateral de fazê-lo não produz efeito algum.

Operadores de string

Além dos operadores de comparação, que podem ser utilizados em valores string, o operador de concatenação (+) concatena dois valores string, retornando outra string que é a união dos dois operandos.

Por exemplo,

 console.log("minha " + "string"); // exibe a string "minha string".

O operador de atribuição encurtado += também pode ser utilizado para concatenar strings.

Por exemplo,

var minhaString = "alfa";
minhaString += "beto"; // É avaliada como "alfabeto" e atribui este valor a minhastring.

Operador condicional (ternário)

O operador condicional é o único operador JavaScript que utiliza três operandos. O operador pode ter um de dois valores baseados em uma condição. A sintaxe é:

condicao ? valor1 : valor2

Se condicao for verdadeira, o operador terá o valor de valor1. Caso contrário, terá o valor de valor2. Você pode utilizar o operador condicional em qualquer lugar onde utilizaria um operador padrão.

Por exemplo,

var status = (idade >= 18) ? "adulto" : "menor de idade";

Esta declaração atribui o valor “adulto” à variável status caso idade seja dezoito ou mais. Caso contrário, atribui o valor “menor de idade”.

Operador vírgula

O operador vírgula (,) simplesmente avalia ambos de seus operandos e retorna o valor do segundo. Este operador é utilizado primariamente dentro de um laço for para permitir que multiplas variáveis sejam atualizadas cada vez através do laço.

Por exemplo, se a é uma matriz bidimensional com 10 elementos em um lado, o código a seguir utiliza o operador vírgula para incrementar duas variáveis de uma só vez. O código imprime os valores dos elementos diagonais da matriz:

for (var i = 0, j = 9; i <= 9; i++, j--)
  console.log("a[" + i + "][" + j + "]= " + a[i][j]);

Operadores unário

Um operador unário é uma operação com apenas um operando.

delete

O operador delete apaga um objeto, uma propriedade de um objeto ou um elemento no índice especificado de uma matriz. A sintaxe é:

delete nomeObjeto;
delete nomeObjeto.propriedade;
delete nomeObjeto[indice];
delete propriedade; // válido apenas dentro de uma declaração with

onde nomeObjeto é o nome de um objeto, propriedade é uma propriedade existente e indice é um inteiro que representa a localização de um elemento em uma matriz.

A quarta forma é permitida somente dentro de uma declaração with para apagar uma propriedade de um objeto.

Você pode utilizar o operador delete para apagar variáveis declaradas implicitamente mas não aquelas declaradas com var.

Se o operador delete for bem-sucedido, ele define a propriedade ou elemento para undefined. O operador delete retorna verdadeiro se a operação for possível; ele retorna falso se a operação não for possível.

x = 42;
var y = 43;
meuobj = new Number();
meuobj.h = 4;    // cria a propriedade h
delete x;        // retorna true (pode apagar se declarado implicitamente)
delete y;        // retorna false (não pode apagar se declarado com var)
delete Math.PI;  // retorna false (não pode apagar propriedades predefinidas)
delete meuobj.h; // retorna true (pode apagar propriedades definidas pelo usuário)
delete meuobj;   // retorna true (pode apagar se declarado implicitamente)
Apagando elementos de array

Quando você apaga um elemento de um array, o tamanho do array não é afetado. Por exemplo, se você apaga a[3], o valor de a[4] ainda estará em a[4] e a[3] passa a ser undefined.

Quando o operador delete remove um elemento do array, aquele elemento não pertence mais ao array. No exemplo a seguir, arvores[3] é removido com delete. Entretanto, arvores[3] ainda é endereçável e retorna undefined.

var arvores = new Array("pau-brasil", "loureiro", "cedro", "carvalho", "sicômoro");
delete arvores[3];
if (3 in arvores) {
  // isto não é executado
}

Se você quer que um elemento do array exista, mas tenha um valor indefinido, utilize a palavra-chave undefined em vez do operador delete. No exemplo a seguir, o valor undefined é atribuído a arvores[3], mas o elemento da matriz ainda existe:

var arvores = new Array("pau-brasil", "loureiro", "cedro", "carvalho", "sicômoro");
arvores[3] = undefined;
if (3 in arvores) {
  // isto será executado
}

typeof

O operador typeof é utilizado em qualquer uma das seguintes formas:

typeof operando
typeof (operando)

O operador typeof retorna uma string indicando o tipo do operando sem avaliação. operando é uma string, variável, palavra-chave ou objeto cujo tipo deve ser retornado. Os parênteses são opcionais.

Suponha que você defina as seguintes variáveis:

var meuLazer = new Function("5 + 2");
var forma = "redondo";
var tamanho = 1;
var hoje = new Date();

O operador typeof retornaria o seguinte resultado para aquelas variáveis:

typeof meuLazer;  // retorna "function"
typeof forma;     // retorna "string"
typeof tamanho;   // retorna "number"
typeof hoje;      // retorna "object"
typeof naoExiste; // retorna "undefined"

Para as palavras-chave true e null, o typeof retorna os seguintes resultados:

typeof true; // retorna "boolean"
typeof null; // retorna "object"

Para um número ou uma string, o typeof retorna os seguintes resultados:

typeof 62;          // retorna "number"
typeof 'Olá mundo'; // retorna "string"

Para valores de propriedades, o typeof retorna o tipo do valor que a propriedade possui:

typeof document.lastModified; // retorna "string"
typeof window.length;         // retorna "number"
typeof Math.LN2;              // retorna "number"

Para métodos e funções, o typeof retorna os seguintes resultados:

typeof blur;        // retorna "function"
typeof eval;        // retorna "function"
typeof parseInt;    // retorna "function"
typeof forma.split; // retorna "function"

Para objetos predefinidos, o typeof retorna os seguintes resultados:

typeof Date;     // retorna "function"
typeof Function; // retorna "function"
typeof Math;     // retorna "object"
typeof Option;   // retorna "function"
typeof String;   // retorna "function"

void

O operador void é utilizado de qualquer uma das seguintes formas:

void (expressao)
void expressao

O operador void especifica que uma expressão deve ser avaliada sem retorno de valor. expressao é uma expressão JavaScript que deve ser avaliada. Os parênteses em torno da expressão são opcionais, mas é uma boa prática utilizá-los.

Você pode utilizar o operador void para especificar uma expressão como um link de hipertexto. A expressão é avaliada mas não é carregada no lugar do documento atual.

O código a seguir cria um link de hipertexto que não faz coisa alguma quando clicado pelo usuário. Quando o usuário clica no link, void(0) é avaliado como indefinido, que não tem efeito em JavaScript.

<a href="javascript:void(0)">Clique aqui para fazer nada</a>

O código a seguir cria um link de hipertexto que submete um formulário quando clicado pelo usuário.

<a href="javascript:void(document.form.submit())">
Clique aqui para enviar</a>

Operadores relacionais

Um operador relacional compara seus operando e retorna um valor booleano baseado em se a comparação é verdadeira.

in

O operador in retorna verdadeiro se a propriedade especificada estiver no objeto especificado. A sintaxe é:

nomePropriedadeOuNumero in nomeObjeto

onde nomePropriedadeOuNumero é uma string ou uma expressão numérica que representa um nome de propriedade ou um índice de um array, e nomeObjeto é o nome de um objeto.

Os exemplos a seguir mostram alguns usos do operador in.

// Arrays
var arvores = new Array("pau-brasil", "loureiro", "cedro", "carvalho", "sicômoro");
0 in arvores;        // retorna verdadeiro
3 in arvores;        // retorna verdadeiro
6 in arvores;        // retorna falso
"cedro" in arvores;  // retorna falso (você deve especificar o número do índice,
                     // não o valor naquele índice)
"length" in arvores; // retorna verdadeiro (length é uma propriedade de Array)

// Objetos predefinidos
"PI" in Math;            // retorna verdadeiro
var minhaString = new String("coral");
"length" in minhaString; // retorna verdadeiro

// Objetos personalizados
var meucarro = {marca: "Honda", modelo: "Accord", ano: 1998};
"marca" in meucarro;  // retorna verdadeiro
"modelo" in meucarro; // retorna verdadeiro

instanceof

O operador instanceof retorna verdadeiro se o objeto especificado for do tipo de objeto especificado. A sintaxe é:

nomeObjeto instanceof tipoObjeto

onde nomeObjeto é o nome do objeto a ser comparado com tipoObjeto, e tipoObjeto é um tipo de objeto como Date ou Array.

Utilize o instanceof quando você precisar confirmar o tipo de um objeto em tempo de execução. Por exemplo, ao capturar exceções você pode desviar para um código de manipulação de exceção diferente dependendo do tipo de exceção lançada.

Por exemplo, o código a seguir utiliza o instanceof para determinar se dia é um objeto Date. Como dia é um objeto Date, as declarações do if são executadas.

var dia = new Date(1995, 12, 17);
if (dia instanceof Date) {
  // declarações a serem executadas
}

Precedência de operadores

precedência de operadores determina a ordem em que eles são aplicados quando uma expressão é avaliada. Você pode substituir a precedência dos operadores utilizando parênteses.

A tabela a seguir descreve a precedência de operadores, da mais alta para a mais baixa.

Tipo de operadorOperadores individuais
membro. []
chamada / criação de instância() new
negação / incremento! ~ - + ++ -- typeof void delete
multiplicação / divisão / resto ou módulo* / %
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,

Expressões

Uma expressão consiste em qualquer unidade válida de código que é resolvida como um valor.

Conceitualmente, existem dois tipos de expressões: aquelas que atribuem um valor a uma variável e aquelas que simplesmente possuem um valor.

A expressão x = 7 é um exemplo do primeiro tipo. Esta expressão utiliza o operador = para atribuir o valor sete à variável x. A expressão em si é avaliada como sete.

O código 3 + 4 é um exemplo do segundo tipo de expressão. Esta expressão utiliza o operador + para somar três e quatro sem atribuir o resultado, sete, a uma variável.

O JavaScript possui as seguintes categorias de expressão:

  • Aritmética: é avaliada como um número, por exemplo 3.14159. (Geralmente utiliza operadores aritméticos).
  • String: é avaliada como uma string de caracteres, por exemplo, “Fred” ou “234”. (Geralmente utiliza operadores de string).
  • Lógica: é avaliada como verdadeira ou falsa. (Costuma envolver operadores lógicos).
  • Expressões primárias: Palavras reservadas e expressões gerais do JavaScript.
  • Expressão lado esquerdo: atribuição à esquerda de valores.

Expressões primárias

Palavras reservadas e expressões gerais do JavaScript.

this

Utilize a palavra reservada this para se referir ao objeto atual. Em geral, o this se refere ao objeto chamado em um método. Utilize o this das seguintes formas:

this["nomePropriedade"]
this.nomePropriedade

Suponha uma função chamada valide que valida a propriedade valor de um objeto, dado o objeto e os valores máximo e mínimo:

function valide(obj, minimo, maximo){
  if ((obj.valor < minimo) || (obj.valor > maximo))
    alert("Valor inválido!");
}

Você poderia chamar valide em cada manipulador de evento onChange de um formulário utilizando this para passar o elemento do formulário, como no exemplo a seguir:

<b>Informe um número entre 18 e 99:</b>
<input type="text" name="idade" size=3
   onChange="valide(this, 18, 99);">

Operador de agrupamento

O operador de agrupamento ( ) controla a precedência de avaliação de expressões. Por exemplo, você pode substituir a precedência da divisão e multiplicação para que a adição e subtração sejam avaliadas primeiro.

var a = 1;
var b = 2;
var c = 3;

// Precedência padrão
a + b * c     // 7
// a avaliação padrão pode ser assim
a + (b * c)   // 7

// Agora substitui a precedência
// soma antes de multiplicar   
(a + b) * c   // 9

// o que é equivalente a
a * c + b * c // 9

Comprehensions

Comprehensions são uma característica experimental de JavaScript, marcada para ser inclusa em uma versão futura do ECMAScript. Existem duas versões de Comprehensions:

[for (x of y) x]
       Comprehensions de array.

(for (x of y) y)
 gerador de comprehensions

Comprehensions existem em muitas linguagens de programação e permitem que você rapidamente monte um novo array com base em um existente, por exemplo:

[for (i of [ 1, 2, 3 ]) i*i ]; 
// [ 1, 4, 9 ]

var abc = [ "A", "B", "C" ];
[for (letras of abc) letras.toLowerCase()];
// [ "a", "b", "c" ]

Expressão lado esquerdo

Atribuição à esquerda de valores.

new

Você pode utilizar o operador new para criar uma instância de um tipo de objeto definido pelo usuário ou de um dos tipos de objeto predefinidos: ArrayBooleanDateFunctionImageNumberObjectOptionRegExp ou String. No servidor, você pode também utilizar DbPoolLockFile ou SendMail. Utilize o operador new da seguinte forma:

var nomeObjeto = new tipoObjeto([parametro1, parametro2, ..., parametroN]);

super

A palavra reservada super é utilizada para chamar a função pai de um objeto. É útil para nas classes para a chamada do construtor pai, por exemplo:

super([argumentos]); //chama o construtor pai.
super.funcaoDoPai([argumentos]);

Operador spread

O operador spread permite que uma expressão seja expandido em locais onde são esperados vários argumentos (para chamadas de função) ou vários elementos (para arrays).

Exemplo: Se você tem um array e deseja criar um novo array com os elementos do array já existente sendo parte do novo array, a sintaxe do array não será suficiente e você terá de usar uma combinação de push, splice, concat, etc. Com a sintaxe spread, isto torna-se muito mais sucinto:

var partes = ['ombro', 'joelhos'];
var musica = ['cabeca', ...partes, 'e', 'pés'];

Da mesma forma, o operador spread funciona com chamadas de função:

function f(x, y, z) { }
var args = [0, 1, 2];
f(...args);

Strings

O tipo String do JavaScript é usado para representar informações de texto. É um conjunto de “elementos” composto por valores inteiros de 16-bits sem sinal. Cada elemento dentro da String ocupa uma posição dentro dessa String. O primeiro elemento está no índice 0, o próximo no índice 1, e assim sucessivamente. O tamanho de uma String é a quantidade de elementos que ela possui. Você pode criar strings usando strings literais ou objetos string.

Strings literais

Você pode criar strings usando aspas simples ou aspas duplas:

'foo'
"bar"

Strings mais avançadas podem ser criadas usando sequências de escape:

Sequências de escape hexadecimais

O número depois de \x é interpretado como um número hexadecimal.

'\xA9' // "©"

Sequências de escape unicode

As sequências de escape unicode requerem no mínimo quatro caracteres depois do \u.

'\u00A9' // "©"

Sequências de escape Unicode code point

É novo no ECMAScript 6. Com essas sequências, cada caractere pode ser “escapado” usando números hexadecimais, sendo possível usar pontos de código Unicode de até 0x10FFFF. Com escapes Unicode simples muitas vezes é necessário escrever as metades substitutas separadamente para obter o mesmo resultado.

Veja também String.fromCodePoint() or String.prototype.codePointAt().

'\u{2F804}'

// o mesmo com escapes Unicode simples
'\uD87E\uDC04'

Objetos String

O objeto String é como uma “capa” ao redor do tipo primitivo string.

var s = new String("foo"); // Cria um objeto String
console.log(s); // Exibe no console: { '0': 'f', '1': 'o', '2': 'o'}
typeof s; // Retorna 'object'

Você pode chamar qualquer um dos métodos do objeto String em cima de uma string literal — JavaScript automaticamente converte a string literal em um objeto String temporário, chama o método, e então descarta o objeto String temporário. Você pode também usar a propriedade String.length com uma string literal.

Você deve usar strings literais a menos que você realmente precise usar um objeto String, pois objetos String podem ter comportamentos inesperados. Por exemplo:

var s1 = "2 + 2"; // Cria uma string literal
var s2 = new String("2 + 2"); // Creates um objeto String
eval(s1); // Retorna o número 4
eval(s2); // Retorna a string "2 + 2"

Um objeto String possui uma propriedade, length, que indica o número de caracteres na string. Por exemplo, o código a seguir atribui o valor 11 à variável x, pois “Olá, mundo!” possui 11 caracteres:

var minhaString = "Olá, mundo!";
var x = minhaString.length;

Um objeto String possui uma variedade de métodos: por exemplo aqueles que retornam uma variação da própria string, como substring e toUpperCase.

A tabela a seguir lista os métodos de objetos String.

MétodoDescrição
charAtcharCodeAtcodePointAtRetorna o código do caractere ou o caractere em uma posição específica na string.
indexOflastIndexOfRetorna a posição de uma substring específica na string ou a última posição da substring específica, respectivamente.
startsWithendsWithincludesRetorna se uma string começa, termina ou contém uma outra string específica.
concatConcatena o texto de duas strings e retorna uma nova string.
fromCharCodefromCodePointCria uma string a partir de uma sequência específica de valores Unicode. Esse é um método da classe String, não de uma instância do tipo String.
splitSepara um objeto String em um array de strings, separando a string em substrings.
sliceExtrai uma seção de uma string e retorna uma nova string.
substringsubstrRetorna um subconjunto específico de uma string, definindo os índices inicial e final, ou definindo um índice e um tamanho.
matchreplacesearchTrabalha com expressões regulares.
toLowerCasetoUpperCaseRetorna a string com todos caracteres em minúsculo, ou maiúsculo, respectivamente.
normalizeRetorna a Forma Normalizada Unicode (Unicode Normalization Form) da string que chama o método.
repeatRetorna uma string contendo os elementos do objeto repetidos pela quantidade de vezes dada.
trimRetira espaços em branco no começo e no final da string.

Template strings com várias linhas

Template strings são strings literais que permitem expressões no seu conteúdo. Você pode usar os recursos de strings com multiplas linhas e interpolações de string com as template strings.

Template strings são declaradas com o acento grave (“) ao invés de aspas simples ou aspas duplas. Essas strings podem conter place holders. Os place holders são indicados pelo cifrão e com chaves ( ${expressao} ).

Várias linhas (Multi-lines)

Qualquer caractere de nova linha ( '\n' ) inserido na string também faz parte das template string. Usando strings normais, você teria que usar a sintaxe a seguir para conseguir uma string de várias linhas

console.log("linha de texto 1\n\
linha de texto 2");
// "linha de texto 1
// linha de texto 2"

Para obter o mesmo efeito com strings multi-lines, você pode agora escrever:

console.log(`linha de texto 1
linha de texto 2`);
// "linha de texto 1
// linha de texto 2"

Expressões inseridas

Para conseguir inserir expressões com strings normais, você teria que usar a seguinte sintaxe:

var a = 5;
var b = 10;
console.log("Quinze é " + (a + b) + " e\nnão " + (2 * a + b) + ".");
// "Quinze é 15 e
// não 20."

Agora, com template strings, você tem a capacidade de usar uma forma mais simples e legível para fazer essas substituições:

var a = 5;
var b = 10;
console.log(`Quinze é ${a + b} e\nnão ${2 * a + b}.`);
// "Quinze é 15 e 
// não 20."

Internacionalização

O objeto Intl é o namespace para a API de Internacionalização do ECMAScript, que oferece comparação de strings sensíveis à linguagem, formatação de números, e formatação de datas e horas. Os construtores para os objetos CollatorNumberFormat, e DateTimeFormat são propriedades do objeto Intl.

Formatação de data e hora

O objeto DateTimeFormat é útil para a formatação de data e hora. O código a seguir formata uma data em inglês no formato que é utilizado nos Estados Unidos. (O resultado é diferente em outro fuso horário).

var msPorDia = 24 * 60 * 60 * 1000; // número de milisegundos em um dia
 
// July 17, 2014 00:00:00 UTC.
var july172014 = new Date(msPorDia * (44 * 365 + 11 + 197));

var opcoes = { year: "2-digit", month: "2-digit", day: "2-digit",
                hour: "2-digit", minute: "2-digit", timeZoneName: "short" };
var americanDateTime = new Intl.DateTimeFormat("en-US", opcoes).format;
 
console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT

Formatação de números

O objeto NumberFormat é útil para formatar números, por exemplo unidade monetária.

var precoGasolina = new Intl.NumberFormat("en-US",
                        { style: "currency", currency: "USD",
                          minimumFractionDigits: 3 });
 
console.log(precoGasolina.format(5.259)); // $5.259

var hanDecimalRMBInChina = new Intl.NumberFormat("zh-CN-u-nu-hanidec",
                        { style: "currency", currency: "CNY" });
 
console.log(hanDecimalRMBInChina.format(1314.25)); // ¥ 一,三一四.二五

Collation

O objeto Collator é usado para comparar e ordenar strings.

Por exemplo, existem atualmente duas ordens diferentes de classificação no Alemão: listaTelefônica e dicionário. A ordenação da listaTelefônica enfatiza o som, e é como se “ä”, “ö”, e assim por diante, fossem expandidos para “ae”, “oe”, e assim sucessivamente, para definir a ordem.

var nomes = ["Hochberg", "Hönigswald", "Holzman"];
 
var phonebookAlemao = new Intl.Collator("de-DE-u-co-phonebk");
 
// como se ordenasse ["Hochberg", "Hoenigswald", "Holzman"]:
console.log(names.sort(phonebookAlemao.compare).join(", "));
// imprime "Hochberg, Hönigswald, Holzman"

Algumas palavras do alemão são conjugadas com tremas extras, mas no dicionário essas palavras são ordenadas ignorando os tremas (exceto quando ordenando palavras que tem apenas o trema como diferença: schon antes de schön).

var dicionarioAlemao = new Intl.Collator("de-DE-u-co-dict");
 
// como se ordenasse ["Hochberg", "Honigswald", "Holzman"]:
console.log(names.sort(dicionarioAlemao.compare).join(", "));
// imprime "Hochberg, Holzman, Hönigswald"

.

Objeto Array

Um array é um conjunto de valores ordenados que você o referencia com um nome e um índice. Por exemplo, você pode ter um array chamado emp que contém nomes de funcionários indexados por seus números de funcionários. Então emp[1] poderia ser o funcionário número 1, emp[2] o funcionário número 2 e assim por diante.

JavaScript não possui um tipo de dados array específico. No entanto, você pode usar  o objeto predefinido Array e seus métodos para trabalhar com arrays em suas aplicações. O objeto Array tem métodos para manipular arrays de várias maneiras como join, reverse e sort. Ele tem uma propriedade para determinar o tamanho do array e outras propriedades para usar com expressões regulares.

Criando um array

As declarações a seguir criam arrays equivalentes:

var arr = new Array(elemento0, elemento1, ..., elementoN);
var arr = Array(elemento0, elemento1, ..., elementoN);
var arr = [elemento0, elemento1, ..., elementoN];

elemento0, elemento1, ..., elementoN é uma lista de valores para os elementos do array. Quando esses valores são especificados, o array é inicializado com eles como elementos deste array. A propriedade do comprimento do array é definida pelo número de argumentos.

A sintaxe dos colchetes é chamada de “array literal” ou “inicializador de array”. É uma abreviação de outras formas de criação de array e é a forma preferida de criação. Veja  Array literal para detalhes.

Para criar um array com tamanho diferente de zero mas sem nenhum item, qualquer esquema abaixo pode ser utilizado:

var arr = new Array(comprimentoDoArray);
var arr = Array(comprimentoDoArray);

// Estes produzem exatamente o mesmo efeito
var arr = [];
arr.length = comprimentoDoArray;

Nota : No código acima, comprimentoDoArray deve ser um Número. De outra maneira, um array com um único elemento (o valor passado) será criado. Chamar arr.length retornará comprimentoDoArray, mas o array na verdade, contem elementos vazios (undefined). Executar um loop for...in no array, não retornará nenhum dos elementos do array.

Além de poderem ser definidos como uma nova variável, como mostrado acima, arrays também podem ser atribuídos como uma propriedade de um novo objeto, ou de um objeto existente:

var obj = {};
// ...
obj.prop = [elemento0, elemento1, ..., elementoN];

// OU
var obj = {prop: [elemento0, elemento1, ...., elementoN]}

Se você deseja inicializar um array com um único elemento, e este elemento é um Número, você precisa usar a sintáxe dos colchetes. Quando um único valor de Número é passado para o construtor do Array(), ou para uma função, ele é interpretado como um comprimentoDoArray, e não como um elemento único.

var arr = [42];      // Cria um array com apenas um elemento:
                     // o número 42.

var arr = Array(42); // Cria um array sem elementos
                     // e arr.length é definido como 42; isso é
                     // equivalente a:
var arr = [];
arr.length = 42;

Chamar Array(N) resulta  em um RangeError, se N é um número não inteiro cuja porção fracionária não é zero. O exemplo a seguir ilustra esse comportamento.

var arr = Array(9.3);  // RangeError: Invalid array length

Se o seu código precisa criar arrays com elementos singulares de um tipo de dados arbitrário, é mais seguro usar arrays literais. Ou então, crie um array vazio antes de adicionar um elemento singular nele.

Povoando um array

Você pode povoar (inserir elementos) a um array atribuindo valores aos seus elementos. Por exemplo,

var emp = [];
emp[0] = 'Casey Jones';
emp[1] = 'Phil Lesh';
emp[2] = 'August West';

Nota : se você fornece um valor não inteiro ao operador do array, como no código acima, a propriedade será criada no objeto representando o array, ao invés do elemento do array.

var arr = [];
arr[3.4] = 'Oranges';
console.log(arr.length);                // 0
console.log(arr.hasOwnProperty(3.4));   // verdadeiro

Você também pode povoar o array quando o cria:

var myArray = new Array('Olá', myVar, 3.14159);
var myArray = ['Manga', 'Maçã', 'Laranja']

Referenciando os elementos do array

Você referencia os elementos do array através do uso de elementos numéricos ordinais. Por exemplo, suponha que você definiu o seguinte array:

var myArray = ['Vento', 'Chuva', 'Fogo'];

Você então se refere ao primeiro elemento do array como em myArray[0] e ao segundo elemento do array como em myArray[1]. O índice do elemento começa com zero.

Nota : o operador do array (colchetes) também é usado para acessar as propriedades do array (arrays também são objetos em JavaScript). Por exemplo,

var arr = ['um', 'dois', 'três'];
arr[2];         // três
arr['length'];  // 3

Compreendendo o comprimento

Sobe o ponto de vista da implementação, arrays JavaScript armazenam na realidade elementos como propriedades de objetos padrões, usando o índice do array como o nome da propriedade. O comprimento da propriedade é especial: ele sempre retorna o índice do último mais um (no exemplo seguinte Dusty é indexado no 30, então  cats.length retorna 30 + 1). Lembre-se, índices de arrays JavaScript são baseados no zero: eles começam no 0, não no 1. Isso significa que  o comprimento da propriedade será um a mais que o maior índice armazenado no array:

var gatos = [];
gatos[30] = ['Dusty'];
console.log(gatos.length); // 31

Você também pode atribuir um valor à propriedade length. Ao escrever um valor menor que o número de itens armazenados, trunca o array: escrevendo zero limpa-o completamente:

var gatos = ['Dusty', 'Misty', 'Twiggy'];
console.log(gatos.length); // 3

gatos.length = 2;
console.log(gatos); // mostra "Dusty, Misty" - Twiggy foi removido

gatos.length = 0;
console.log(gatos); // nada é apresentado; o array gatos está vazio

gatos.length = 3;
console.log(gatos); // [undefined, undefined, undefined]

Iteração em arrays

Uma operação comum é a de iterar sobre os valores de um array, processando cada elemento de alguma maneira. A maneira mais simples para fazer isso é como segue:

var cores = ['vermelho', 'verde', 'azul'];
for (var i = 0; i < cores.length; i++) {
  console.log(cores[i]);
}

Se você sabe que nenhum dos elemnetos no seu array é avaliado como false em um contexto booleano  — se o seu array consiste apenas de nodos do DOM, como exemplo, você pode usar um idioma mais eficiente:

var divs = document.getElementsByTagName('div');
for (var i = 0, div; div = divs[i]; i++) {
  /* Processa div de alguma forma */
}

Isso evita a sobrecarga da checagem do comprimento do array, e garante que a variável div seja reatribuida ao item atual cada vez que o loop for adicionado por conveniência.

O método forEach() disponibiliza um outro jeito de iterar sobre/em um array:

var cores = ['vermelho', 'verde', 'azul'];
cores.forEach(function(cor) {
  console.log(cor);
});
// vermelho
// verde
// azul

Alternativamente, você pode encurtar o código para o parâmetro do forEach com Arrow Functions ES6.

var cores = ['vermelho', 'verde', 'azul'];
cores.forEach(cor => console.log(cor)); 
// vermelho
// verde
// azul

A função passada para o forEach é executada uma vez para cada item no array, com o item do array passado como o argumento para a função. Valores não atribuídos não são iterados no loop forEach.

Note que os elementos de um array que foram omitidos quando o array foi definido, não são listados quando iterados pelo forEach, mas são listados quando undefined foi manualmente atribuído ao elemento:

var array = ['primeiro', 'segundo', , 'quarto'];

array.forEach(function(elemento) {
  console.log(elemento);
})
// primeiro
// segundo
// quarto

if (array[2] === undefined) {
  console.log('array[2] is undefined'); // verdadeiro
}

array = ['primeiro', 'segundo', undefined, 'quarto'];

array.forEach(function(elemento) {
  console.log(elemento);
});
// primeiro
// segundo
// undefined
// quarto

Como elementos JavaScript são salvos como propriedades de objetos padronizados, não é aconselhável iterar sobre arrays JavaScript usando loops for...in, porque elementos normais e todas as propriedades numeráveis serão listadas.

Métodos dos arrays

O objeto Array possui os seguintes métodos:

concat() une dois arrays e retorna um novo array.

var myArray = new Array('1', '2', '3');
myArray = myArray.concat('a', 'b', 'c'); 
// myArray agora é ["1", "2", "3", "a", "b", "c"]

join(deliminator = ',') une todos os elementos de um array dentro de um string.

var myArray = new Array('Vento', 'Chuva', 'Fogo');
var lista = myArray.join(' - '); // lista é "Vento - Chuva - Fogo"

push() adiciona um ou mais elementos no fim de um array e retorna o comprimento resultante do array.

var myArray = new Array('1', '2');
myArray.push('3'); // myArray é agora ["1", "2", "3"]

pop() remove o último elemento de um array e retorna esse elemento.

var myArray = new Array('1', '2', '3');
var ultimo = myArray.pop(); 
// myArray é agora ["1", "2"], ultimo = "3"

shift() remove o primeiro elemento de um array e retorna esse elemento.

var myArray = new Array('1', '2', '3');
var primeiro = myArray.shift(); 
// myArray agora é ["2", "3"], primeiro é "1"

unshift() adiciona um ou mais elementos ao início do array e retorna o novo comprimento do array.

var myArray = new Array('1', '2', '3');
myArray.unshift('4', '5'); 
// myArray torna-se ["4", "5", "1", "2", "3"]

slice(start_index, upto_index) extrai uma seção de um array e retorna um novo array.

var myArray = new Array('a', 'b', 'c', 'd', 'e');
myArray = myArray.slice(1, 4); // inicia no índice 1 e extrai todos os elementos
                               // até o índice 3, retornado [ "b", "c", "d"]

splice(index, count_to_remove, addElement1, addElement2, ...) remove elementos de um array e (opcionalmente) o substitui, e retorna os itens que foram removidos do array.

var myArray = new Array('1', '2', '3', '4', '5');
myArray.splice(1, 3, 'a', 'b', 'c', 'd'); 
// myArray é agora ["1", "a", "b", "c", "d", "5"]
// Este código iniciou no índice um (ou onde o "2" estava),
// removeu 3 elementos a partir dali, e então inseriu todos os elementos
// consecutivos em seus lugares.

reverse() transpõe (inverte) os elementos de um array, in situ: o primeiro elemento do array se torna o último e o último torna-se o primeiro, e retorna uma referência para o array.

var myArray = new Array('1', '2', '3');
myArray.reverse(); 
// transpõe o array de modo que myArray = [ "3", "2", "1" ]

sort() ordena os elementos de um array in situ, e retorna uma referência para o array.

var myArray = new Array('Neve', 'Chuva', 'Fogo');
myArray.sort(); 
// ordena o array de modo que myArray = [ "Chuva", "Fogo", "Neve" ]

sort() também pode ‘pegar’ uma função callback para determinar como os elementos do array são comparados.

O método sort, assim como outros métodos abaixo que tomam um callback são conhecidos como métodos iterativos, porque eles iteram sobre o array de alguma forma. Cada um pega um segundo argumento opcional chamado thisObject. Se fornecido, thisObject se torna o valor da palavra chave this dentro do corpo da função callback. Se não fornecido, como em outros casos onde uma função é invocada fora do contexto explícito de um objeto, this fará referência ao objeto global (window).

A função callback é na verdade chamada com três argumentos. O primeiro é o valor do item corrente, o segundo é o índice do array e o terceiro é uma referência ao próprio array. Funções javaScript ignoram qualquer argumento que não são nomeados na lista de parâmetros, portanto é seguro prover uma função callback que toma somente um único argumento, como a função alert.

A função abaixo compara dois valores e retorna um dos tres valores: -1, 0 ou 1.

Por exemplo, o seguinte trecho de código vai ordenar pela última letra da string:

var sortFn = function(a, b){
  if (a[a.length - 1] < b[b.length - 1]) return -1;
  if (a[a.length - 1] > b[b.length - 1]) return 1;
  if (a[a.length - 1] == b[b.length - 1]) return 0;
}
myArray.sort(sortFn); 
// ordena o array de modo que myArray = ["Chuva","Neve","Fogo"]
  • se a for menor que b pelo sistema de ordenação, retorna -1 (ou qualquer número negativo)
  • se a for maior que b pelo sistema de ordenação, retorna 1 (ou qualquer número positivo)
  • se a e b forem considerados equivalentes, returnará 0.

indexOf(searchElement[, fromIndex]) busca searchElement no array e retorna o índice da primeira ocorrência.

var a = ['a', 'b', 'a', 'b', 'a'];
console.log(a.indexOf('b'));    // mostra 1
// Agora tente novamente, iniciando após o último resultado de busca
console.log(a.indexOf('b', 2)); // mostra 3
console.log(a.indexOf('z'));    // mostra -1, porque 'z' não foi encontrado

lastIndexOf(searchElement[, fromIndex]) funciona como indexOf, mas começa no fim e busca de trás para a frente.

var a = ['a', 'b', 'c', 'd', 'a', 'b'];
console.log(a.lastIndexOf('b'));    // mostra 5
// Agora tente novamente, iniciando antes do último resultado de busca
console.log(a.lastIndexOf('b', 4)); // mostra 1
console.log(a.lastIndexOf('z'));    // mostra -1

forEach(callback[, thisObject]) executa um callback em cada item do array e retorna undefined.

var a = ['a', 'b', 'c'];
a.forEach(function(element) { console.log(elemento); });
// mostra cada item por vez

map(callback[, thisObject]) retorna um novo array do valor retornado da execução do callback em cada item do array.

var a1 = ['a', 'b', 'c'];
var a2 = a1.map(function(item) { return item.toUpperCase(); });
console.log(a2); // logs ['A', 'B', 'C']

filter(callback[, thisObject]) retorna um novo array contendo os items verdadeiros ao executar o callback.

var a1 = ['a', 10, 'b', 20, 'c', 30];
var a2 = a1.filter(function(item) { return typeof item === 'number'; });
console.log(a2); // mostra [10, 20, 30]

every(callback[, thisObject]) retorna verdadeiro se o callback retornar verdadeiro para cada item no array.

function isNumber(valor) {
  return typeof valor === 'number';
}
var a1 = [1, 2, 3];
console.log(a1.every(isNumber)); // mostra true
var a2 = [1, '2', 3];
console.log(a2.every(isNumber)); // mostra false

some(callback[, thisObject]) retorna verdadeiro se o callback retornar verdadeiro para pelo menos um item no array.

function isNumber(valor) {
  return typeof valor === 'number';
}
var a1 = [1, 2, 3];
console.log(a1.some(isNumber)); // mostra true
var a2 = [1, '2', 3];
console.log(a2.some(isNumber)); // mostra true
var a3 = ['1', '2', '3'];
console.log(a3.some(isNumber)); // mostra false

reduce(callback[, initialValue]) aplica callback(firstValue, secondValue) para reduzir a lista de itens para um único valor e retorna este valor.

var a = [10, 20, 30];
var total = a.reduce(function(primeiro, segundo) { return primeiro + segundo; }, 0);
console.log(total) // mostra 60

reduceRight(callback[, initalvalue]) funciona como reduce(), mas inicia com o último elemento.

reduce e reduceRight são os métodos iterativos menos óbvios dos arrays. Eles devem ser usados para algorítmos que combinam dois valores de maneira recursiva com a finalidade de reduzir uma sequência para um único valor.

Arrays multidimensionais

Arrays podem ser aninhados, significando que um array pode conter outro array como seu elemento. Usando essa característica dos arrays JavaScript, arrays multidimensionais pode ser criados.

O código a seguir cria dois arrays multidimensionais:

var a = new Array(4);
for (i = 0; i < 4; i++) {
  a[i] = new Array(4);
  for (j = 0; j < 4; j++) {
    a[i][j] = '[' + i + ',' + j + ']';
  }
}

Esse exemplo cria um array com as seguintes linhas:

Linha 0: [0,0] [0,1] [0,2] [0,3]
Linha 1: [1,0] [1,1] [1,2] [1,3]
Linha 2: [2,0] [2,1] [2,2] [2,3]
Linha 3: [3,0] [3,1] [3,2] [3,3]

Arrays e expressões regulares

Quando um array é o resultado de uma equivalência entre uma expressão regular e um string, o array retorna propriedades e elementos que disponibilizam a informação sobre a correspondência. Um array é o valor retornado de RegExp.exec()String.match(), e String.split(). Para informações sobre o uso de arrays com expressões regulares, veja Expressões Regulares.

Trabalhando com objetos array-like

Alguns objetos JavaScript, como a NodeList retornada pelo document.getElementsByTagName() ou o objeto acessível dentro do arguments de uma função, se parecem e se comportam superficialmente como arrays, mas não compartilham de todos os seus métodos. O objeto arguments fornece um atributo length mas não implementa o método forEach(), por exemplo.

Métodos Array prototype podem ser chamados contra outros objetos array-like. Por exemplo:

function printArguments() {
  Array.prototype.forEach.call(arguments, function(item) {
    console.log(item);
  });
}

Métodos Array prototype também podem ser usados em strings, desde que eles forneçam acesso sequencial a seus caracteres de maneira similar às arrays:

Array.prototype.forEach.call('uma string', function(chr) {
  console.log(chr);
});

Arrays Tipados

Arrays tipados no JavaScript são objetos array-like e provêm um mecanismo para acessar dados binários crus. Como você já sabe, objetos Array crescem e encolhem dinamicamente e podem ter um valor JavaScript. O motor do JavaScript executa otimizações para que os arrays sejam rápidos. Contudo, à medida que as aplicações web se tornam cada vez mais poderosas, com a adição de funcionalidades como manipulação de áudio e vídeo, acesso a dados crus usando WebSockets, etc., ficou claro que existem momentos em que seria útil para o código JavaScript ser capaz de rapida e facilmente manipular dados binários crus em arrays tipados.

Buffers e views: arquitetura do array tipado

Para alcançar máxima flexibilidade e eficiência, as views de array tipado do JavaScript dividem a implementação em buffers e views. Um buffer (implementado pelo objeto ArrayBuffer) é um objeto que representa um monte de dados; não possui nenhum formato específico e não oferece nenhum mecanismo para acessar seu conteúdo. Para acessar a memória contida em um buffer, você precisa usar uma view. Uma view provê um contexto — ou seja, um tipo de dado, um offset inicial e número de elementos — que transforma o dado em um array tipado real.

Typed arrays in an ArrayBuffer

ArrayBuffer

ArrayBuffer é um tipo de dado usado para representar um buffer de dados binários de tamanho fixo genérico. Você não pode manipular diretamente o conteúdo de um ArrayBuffer; ao invés disso, você deve criar uma view de array tipado ou uma DataView que represente o buffer em um formato específico, e use esta view para ler e modificar o conteúdo do buffer.

Views de arrays tipados

Views de arrays tipados possuem nomes autodescritivos e provêm views para todos os tipos numéricos usuais como Int8Uint32Float64 e assim por diante. Existe uma view de array tipado especial, o Uint8ClampedArray. Ela fixa os valores entre 0 e 255. Isto é útil para Canvas data processing, por exemplo.

TypeValue RangeSize in bytesDescriptionWeb IDL typeEquivalent C type
Int8Array-128 to 12718-bit two’s complement signed integerbyteint8_t
Uint8Array0 to 25518-bit unsigned integeroctetuint8_t
Uint8ClampedArray0 to 25518-bit unsigned integer (clamped)octetuint8_t
Int16Array-32768 to 32767216-bit two’s complement signed integershortint16_t
Uint16Array0 to 65535216-bit unsigned integerunsigned shortuint16_t
Int32Array-2147483648 to 2147483647432-bit two’s complement signed integerlongint32_t
Uint32Array0 to 4294967295432-bit unsigned integerunsigned longuint32_t
Float32Array1.2×10-38 to 3.4×1038432-bit IEEE floating point number ( 7 significant digits e.g. 1.1234567)unrestricted floatfloat
Float64Array5.0×10-324 to 1.8×10308864-bit IEEE floating point number (16 significant digits e.g. 1.123…15)unrestricted doubledouble