Gramática léxica - JavaScript

Gramática léxica
================

Esta página descreve a gramática léxica da linguagem JavaScript. O código fonte de um script ECMAScript é lido da esquerda para direita e traduzido em uma sequência de elementos de entrada, como símbolos, caracteres de controle, finalizadores de linha, comentários ou espaços em branco. ECMAScript também define certas palavras-chave e literais e possui regras para inserção automática de ponto e vírgula ao final de declarações.

Caracteres de controle
----------------------

Caracteres de controle não possuem representação visual, mas são usados para controlar a interpretação do código.

| Código | Nome | Abreviação | Descrição |
| --- | --- | --- | --- |
| `U+200C` | Zero width non-joiner | <ZWNJ> | Colocado entre caracteres para evitar que sejam visualmente ligados (fundidos) em algumas linguagens (Wikipedia). |
| `U+200D` | Zero width joiner | <ZWJ> | Colocado entre caracteres que podem não estar normalmente conectados, para que estes caracteres sejam renderizados com suas devidas ligações em certas linguagens (Wikipedia). |
| `U+FEFF` | Byte order mark | <BOM> | Usado no início do script para marcá-lo como Unicode e especificar a ordem de bytes do código (Wikipedia). |

Espaço em branco
----------------

Espaços em branco ajudam na legibilidade do código e separam os símbolos um do outro. Estes caracteres normalmente não são funcionais no código. Ferramentas de minificação podem ser usadas para remover espaços em branco do código reduzindo, assim, a quantidade de dados que precisam ser transferidos.

| Código | Nome | Abreviação | Descrição | Sequência de escape |
| --- | --- | --- | --- | --- |
| U+0009 | Character tabulation | <HT> | Tabulação horizontal | \t |
| U+000B | Line tabulation | <VT> | Tabulação vertical | \v |
| U+000C | Form feed | <FF> | Pular para próxima página (Wikipedia). | \f |
| U+0020 | Space | <SP> | Espaço normal |  |
| U+00A0 | No-break space | <NBSP> | Espaço normal, sem marcar quebra de linha |  |
| Others | Other Unicode space characters | <USP> | Outros tipos de espaço. Veja na Wikipedia |  |

Finalizadores de linha
----------------------

Além dos caracteres de espaço em branco, caracteres finalizadores de linha são usados para melhorar a legibilidade do código. Contudo, em alguns casos, finalizadores de linha podem influenciar a execução do código JavaScript, por isso você não poderá usá-los em alguns casos. Eles também afetam o processo automático de inserção de ponto e vírgula. Em expressões regulares os finalizadores de linha podem ser indicados com a classe **\s**.

Apenas os seguintes códigos Unicode são tratados como finalizadores de linha no ECMAScript, outros caracteres de quebra de linha são tratados apenas como espaço em branco (por exemplo, Next Line, NEL, U+0085 são considerados espaço em branco).

| Código | Nome | Abreviação | Descrião | Sequência de escape |
| --- | --- | --- | --- | --- |
| U+000A | Line Feed | <LF> | Caractere de nova linha em sistemas UNIX. | \n |
| U+000D | Carriage Return | <CR> | Caractere de nova linha nos sistemas Commodore e nos primeiros Mac's. | \r |
| U+2028 | Line Separator | <LS> | Wikipedia |  |
| U+2029 | Paragraph Separator | <PS> | Wikipedia |  |

Comentários
-----------

Comentários são usados para inserir dicas, notas, sugestões ou alertas no código JavaScript. Isto pode tornar mais fácil ler ou entender o que o código faz. Também pode ser usado para desabilitar código, evitando sua execução; isto pode ser uma valiosa ferramenta na hora de debugar seu código.

JavaScript possui duas formas de inserir comentário no código.

O primeiro é com o uso de duas barras `//`; isso faz com que qualquer coisa escrita a seguir, e na mesma linha, se torne comentário. Por exemplo:

```js
function comment() {
  // Isto é um comentário de uma linha em JavaScript
  console.log("Hello world!");
}
comment();
```

A segunda forma é com o uso de `/* */`, que é muito mais flexível.

Por exemplo, você pode usá-lo em uma única linha:

```js
function comment() {
  /\* Isto é um comentário de uma linha em JavaScript \*/
  console.log("Hello world!");
}
comment();
```

Ou pode fazer um comentário de várias linhas, desta forma:

```js
function comment() {
  /\* Este é um comentário de várias linhas. Observe que
 não precisamos encerrar o comentário até terminar. \*/
  console.log("Hello world!");
}
comment();
```

Você também pode usá-lo no meio de uma linha, se quiser, porém isto pode tornar seu código mais difícil de ler, portanto use com cautela:

```js
function comment(x) {
  console.log("Hello " + x /\* insira o valor de x \*/ + " !");
}
comment("world");
```

Além disso, você pode usá-lo para desativar algum código para evitar que seja executado, envolvendo o código em um comentário, assim:

```js
function comment() {
  /\* console.log('Hello world!'); \*/
}
comment();
```

Neste caso, a função `console.log()` nunca será invocada, pois está comentada. Qualquer quantidade de linhas de código podem ser desabilitadas desta forma.

Palavras-chave
--------------

### Palavras-chave reservadas do ECMAScript 2015

* `break`
* `case`
* `catch`
* `class`
* `const`
* `continue`
* `debugger`
* `default` (en-US)
* `delete` (en-US)
* `do`
* `else`
* `export`
* `extends`
* `finally`
* `for`
* `function`
* `if`
* `import`
* `in`
* `instanceof`
* `new`
* `return`
* `super`
* `switch`
* `this`
* `throw`
* `try`
* `typeof`
* `var`
* `void`
* `while`
* `with`
* `yield`
### Palavras-chave reservadas para uso futuro

As seguintes palavras-chave estão reservadas para uso futuro na especificação ECMAScript. Atualmente elas não tem funcionalidade, mas poderão ter no futuro, portanto elas também não podem ser usadas como identificadores.

Estes sempre são reservados:

* `enum`

Os seguintes são reservados apenas quando o código está em modo estrito (*strict mode*):

* `implements`
* `interface`
* `let`
* `package`
* `private`
* `protected`
* `public`
* `static`

Os seguintes são reservados apenas quando são encontrados no código do módulo:

* `await`

#### Palavras-chave reservadas para uso futuro em versões antigas

As seguintes palavras-chave foram reservadas para uso futuro em especificações antigas do ECMAScript (ECMAScript 1 até 3).

* `abstract`
* `boolean`
* `byte`
* `char`
* `double`
* `final`
* `float`
* `goto`
* `int`
* `long`
* `native`
* `short`
* `synchronized`
* `throws`
* `transient`
* `volatile`

Além disso, os literais `null`, `true`, e `false` não podem ser usados como identificadores em ECMAScript.

### Uso de palavras-chave reservadas

Palavras reservadas atualmente só não podem ser usadas como identificadores . Como descrito em es5.github.com/#A.1, não há problema em usar palavras reservadas desta forma.

```js
a.import
a['import']
a = { import: 'test' }.
```

Por outro lado, o seguinte é ilegal por quê a palavra reservada "*import*" está sendo usada como identificador. Identificadores podem ser usados em declaração de expressões e funções.

```js
function import() {} // Proibido.
```

Literais
--------

### Null

Veja também `null` para mais informações.

```js
null;
```

### Booleanos

Veja também `Boolean` para mais informações.

```js
true;
false;
```

### Números

#### Decimal

```js
1234567890;
42;

// Cuidado com o uso precedido de zero:
0888; // 888 convertido como decimal
0777; // Convertido como octal, 511 em decimal
```

Veja que números decimais podem começar com zero (`0`) seguido de outro dígito decimal, porém se todos dígitos após o zero inicial forem menores que 8, o número é interpretado como um número octal. Isso não vai disparar um erro em JavaScript, veja Erro do Firefox 957513. Veja também esta página sobre conversão de tipo `parseInt()`.

#### Binário

Números binários em JavaScript são iniciados em zero seguido da letra "B" em maiúsculo ou minúsculo (`0b` ou `0B`). Esta sintaxe é nova no ECMAScript 2015, por isso verifique a compatibilidade do navegador. Se o dígito seguinte ao `0b` não for 0 ou 1, o seguinte erro de sintaxe (en-US) é disparado: "Missing binary digits after 0b".

```js
var FLT\_SIGNBIT = 0b10000000000000000000000000000000; // 2147483648
var FLT\_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
var FLT\_MANTISSA = 0b00000000011111111111111111111111; // 8388607
```

#### Octal

Números octais em JavaScript são escritos com zero inicial seguido da letra "O" em maiúsculo ou minúsculo (`0o` ou `0O)`. Esta sintaxe é nova no ECMAScript 2015, por isso verifique a compatibilidade do navegador. Se os dígitos após o `0o não forem octais válidos` (01234567), o seguinte erro de sintaxe (en-US) será disparado: "Missing octal digits after 0o".

```js
var n = 0o755; // 493
var m = 0o644; // 420

// Também é possível com apenas um zero no início (veja sobre decimais acima)
0755;
0644;
```

#### Hexadecimal

Números hexadecimais em JavaScript são iniciados com zero seguido da letra "X" em maiúsculo ou minúsculo (`0x` ou `0X)`. Se os dígitos após o 0x não forem hexadecimais válidos (0123456789ABCDEF), o seguinte erro de sintaxe (en-US) será disparado: "Identifier starts immediately after numeric literal".

```js
0xfffffffffffffffff; // 295147905179352830000
0x123456789abcdef; // 81985529216486900
0xa; // 10
```

### Objetos

Veja também `Object` e Object initializer para mais informações.

```js
var o = { a: "foo", b: "bar", c: 42 };

// Notação curta. Novidade no ES2015
var a = "foo",
  b = "bar",
  c = 42;
var o = { a, b, c };

// instead of
var o = { a: a, b: b, c: c };
```

### Arrays

Veja também `Array` para mais informações.

```js
[1954, 1974, 1990, 2014];
```

### Strings

```js
'foo';
"bar";
```

#### Caracteres de escape em hexadecimal

```js
"\xA9"; // "©"
```

#### Caracteres de escape em Unicode

A representação de caracteres de escape em Unicode requer ao menos quatro caracteres após o `\u`.

```js
"\u00A9"; // "©"
```

#### Codificação de caracteres Unicode

Novidade no ECMAScript 2015. Com a codificação de caracteres Unicode qualquer caractere pode ser representado usando sequência hexadecimal, desta forma podemos representar caracteres Unicode com sequência hexadecimal até `0x10FFFF`. Usando apenas Unicode, muitas vezes pode ser necessário utilizar mais de uma sequência para conseguir o mesmo resultado.

Veja também `String.fromCodePoint()` ou `String.prototype.codePointAt()`.

```js
"\u{2F804}";

// O mesmo usando apenas Unicode
"\uD87E\uDC04";
```

### Expressões regulares

Veja também `RegExp` para mais informações.

```js
/ab+c/g

// Um "espaço vazio" em expressão regular
// Para evitar confusão com comentário de linha única
// faça o seguinte:
/(?:)/
```

### Templates

Veja também template strings para mais informações .

```js
`texto`;

`linha de texto 1
 linha de texto 2`;

`texto ${expressão} texto`;

tag`texto ${expressão} texto`;
```

Inserção automática de ponto e vírgula
--------------------------------------

Algumas declarações JavaScript precisam ser finalizadas com ponto e vírgula e, por isso, são afetadas pelo mecanismo automático de inserção de ponto evírgula (na silga ASI, em inglês):

* Declaração vazia
* `let`, `const`, declaração de variável
* `import`, `export`, declaração module
* Expressões
* `debugger`
* `continue`, `break`, `throw`
* `return`

A especificação ECMAScript menciona três regras para inserção de ponto e vírgula.

1. Um ponto e vírgula é inserido antes, quando um finalizador de linha ou um "}" é encontrado em local não permitido pela sintaxe.

```js
{ 1 2 } 3

// É transformado pelo ASI em

{ 1 2 ;} 3;
```

2. Um ponto e vírgula é inserido ao final, quando o sinal de final de linha é detectado e o conversor não é capaz de unir a linha seguinte em um único comando.

Aqui o `++ não é interpretado como operador de incremento aplicado à variável b por que há um finalizador de linha entre o b e ++` .

```js
a = b
++c

// É transformado pelo ASI em

a = b;
++c;
```

3. Um ponto e vírgula é inserido ao final quando uma declaração com regra léxica restrita é encontrada seguida de um finalizador de linha. As declaraçõs sem regra específica de finalizador de linha são:

* Operadores de incremento ou decremento (`++` and `--`)
* `continue`
* `break`
* `return`
* `yield`, `yield*`
* `module`

```js
return
a + b

// É transformado pelo ASI em

return;
a + b;
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification  |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Firefox-notas específicas
-------------------------

* Em versões anteriores ao Firefox 5 (JavaScript 1.8.6) palavras reservadas para uso futuro não pdem ser usadas em strict mode. Essa falha de ECMAScript foi corrigida no Firefox 5.
Veja também
-----------

* Jeff Walden: Binary and octal numbers
* Mathias Bynens: JavaScript character escape sequences
* `Boolean`
* `Number`
* `RegExp`
* `String`


let - JavaScript

let
===

Declara uma variável local no escopo do bloco atual, opcionalmente iniciando-a com um valor.

Sintaxe
-------

Definição `let`:
```

let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];
```

Expressão `let`:
```

let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) expression;
```

Instrução `let`:
```

let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) statement;
```

### Parâmetros

| Parameter | Description |
| --- | --- |
| `var1`, `var2`, …, `varN` | Nome da variável. Pode ser qualquer identificador válido. |
| `value1`, `value2`, …, `valueN` | Valor inicial da variável. Pode ser qualquer expressão válida. |
| `expression` | Qualquer expressão válida. |
| `statement` | Qualquer instrução válida. |

Descrição
---------

`let` permite que você declare variáveis limitando seu escopo no bloco, instrução, ou em uma expressão na qual ela é usada. Isso é inverso da keyword `var` (en-US), que define uma variável globalmente ou no escopo inteiro de uma função, independentemente do escopo de bloco.

**Nota:** **Nota do tradutor:** o trecho acima: "independentemente do escopo de bloco", na verdade, significa dizer que variáveis declaradas dentro de blocos internos da função, por exemplo, são vinculadas no escopo da função, não no bloco no qual elas são declaradas. Se isso parece confuso - e realmente é -, apenas entenda que, ao contrário do que se poderia supor, em Javascript blocos não possuem escopo como em outras linguagens, somente funções têm! Isso quer dizer que mesmo uma váriavel definida com a keyword `var` dentro de um bloco de instrução `if`, será visível no resto inteiro da função.

Escopo de bloco
---------------

Variáveis declaradas com `let` são "içadas" para começo do bloco em que elas são definidas (isso é conhecido também pelo termo, hoisting).

Redeclaração de uma mesma variável num mesmo escopo de bloco causa um `TypeError` (en-US).

```js
if (x) {
  let foo;
  let foo; // Emite um TypeError.
}
```

No entanto, corpos de funções não possuem essa limitação!

```js
function do\_something() {
  let foo;
  let foo; // Isso funciona.
}
```

**Aviso:** **Atenção:** Os rascunhos do ECMAScript 6 (desde abril de 2012) tornam este comportamento ilegal. Isso significa, provavelmente, que as futuras versões do JavaScript levantarão um `TypeError` (en-US). Então, se você faz isso, deveria evitar essa prática!

Você pode encontrar erros em instruções `switch` (en-US) porque existe apenas um bloco subjacente.

```js
switch (x) {
  case 0:
    let foo;
    break;

  case 1:
    let foo; // TypeError para a redeclaração.
    break;
}
```

Exemplos
--------

Uma *expressão let* limita o escopo de uma variável declarada somente para aquela expressão.

```js
var a = 5;
let(a = 6) alert(a); // 6
alert(a); // 5
```

Usada dentro de um bloco, *let* limita os escopo das variáveis para aquele bloco. Observe a diferença entre *var* em que o escopo é definido dentro da função onde é declarada

```js
var a = 5;
var b = 10;

if (a === 5) {
  let a = 4; // O escopo é dentro do bloco if
  var b = 1; // O escopo é dentro da função

  console.log(a); // 4
  console.log(b); // 1
}

console.log(a); // 5
console.log(b); // 1
```

É possível usar a keyword *let* para vincular variáveis localmente no escopo de loops em vez de usar uma variável global (definida usando *var*) para isso.

```js
for (let i = 0; i < 10; i++) {
  alert(i); // 1, 2, 3, 4 ... 9
}

alert(i); // i não está definida
```

Veja também
-----------

* `var` (en-US)
* `const` (en-US)
* Novidades do JavaScript 1.7


block - JavaScript

block
=====

Uma **declaração em bloco** (ou **declaração composta (compound)** em outras linguagens) é usado para agrupar nenhum ou mais declarações. O bloco é delimitado por um par de chaves e pode opcionalmente ser `nomeado`:

Sintaxe
-------

### Declaração de Bloco
```

{
  ListaDeDeclarações
}
```

### Declaração de Bloco Nomeada
```

NomeIdentificador: {
  ListaDeDeclarações
}
```

`ListaDeDeclarações`

Declarações agroupadas com a declaração em bloco.

`NomeIdentificador`

Um `nome (label)` opcional para identificação visual ou um alvo para `break`.

Descrição
---------

A declaração em bloco é frequentemente chamada de **declaração composta (compound)** em outras linguagens. Ela permite que você use multiplas declarações onde o JavaScript espera apenas uma declaração. Combinar declarações em blocos são uma prática comum em JavaScript. O comportamento oposto é possível usando uma declaração vazia, onde você fornece nenhuma declaração, mesmo que uma seja requerida.

### Regras de Bloqueio de Escopo

#### Com `var`

Variáveis declaradas com `var` **não** possuem bloqueio de escopo. Variáveis introduzidas com um bloco são guardadas no escopo da função que elas estão ou script, e os efeitos de configura-las persistem pelo próprio bloco. Em outras palavras, declarações em bloco não introduzem um escopo. Mesmo blocos "standalone" são sintaxes válidas, você não vai querer usar blocos standalone em JavaScript, porque não fazem o que você pensa que eles fazem, se você pensa que eles fazer coisas como blocos em C ou Java. Por exemplo:

```js
var x = 1;
{
  var x = 2;
}
console.log(x); // imprime 2
```

Isso loga 2 porque a declaração `var x` com o bloco está no mesmo escopo que a declaração `var x` antes do bloco. No C ou Java, o código equivalente iria imprimir 1.

#### Com `let` e `const`

Por contraste, variáveis declaradas com `let` e `const` **tem** escopo bloqueado:

```js
let x = 1;
{
  let x = 2;
}
console.log(x); // imprime 1 1
```

`O x = 2` é limitado ao escopo do bloco em que ele foi definido.

O mesmo true de `const`:

```js
const c = 1;
{
  const c = 2;
}
console.log(c); // imprime 1 e não invoca uma throw SyntaxError...
```

Note que o escope bloqueado de `const c = 2` *não invoca uma* `SyntaxError: Identifier 'c' has already been declared` porque ele foi unicamente declarado no bloco.

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-block |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `while`
* `if...else`
* `let`


switch - JavaScript

switch
======

A condicional **switch** avalia uma expressão, combinando o valor da expressão para um cláusula **case**, e executa as instruções associadas ao **case**.Experimente
-----------

Sintaxe
-------
```

switch (expressão) {
  case valor1:
    //Instruções executadas quando o resultado da expressão for igual á valor1
    [break;]
  case valor2:
    //Instruções executadas quando o resultado da expressão for igual á valor2
    [break;]
  ...
  case valueN:
    //Instruções executadas quando o resultado da expressão for igual á valorN
    [break;]
  default:
    //Instruções executadas quando o valor da expressão é diferente de todos os cases
    [break;]
}
```

`expressão`

Uma expressão que será comparada á cada cláusula **case**.

`case expressão`

Uma cláusula **case** que será comparada á expressão.

Descrição
---------

Se a condição for correspondida, o programa executa as instruções asssociadas. Se múltiplos casos corresponderem o valor, o primeiro caso que corresponder é selecionado, mesmo se os casos não forem iguais entre si.

O programa primeiro procura por um caso o qual a expressão avalie como tendo o mesmo valor que o input da expressão (usando a comparação de igualdade estrita (en-US), `===`) transferindo assim o controle para a cláusula encontrada e em seguida executando as instruções associadas. Caso nenhum caso seja correspondido, então o programa procura pela cláusula opcional `default`, que, se encontrado, tem o controle transferido a ele, executando suas instruções associadas. Se não houver uma cláusula `default`, o programa continua a execução da instrução seguindo para o final do `switch`. Por convenção, a cláusula default é a última, mas não é algo obrigatório.

A instrução opcional `break` associada com cada `case` garante que o programa saia da condicional `switch` assim que a instrução correspondente for executada e executa a instrução que segue logo após o switch. Caso `break` seja omitido, o programa continua a execução para a próxima instrução dentro de `switch`.

Exemplos
--------

### Exemplo: Usando `switch`

No exemplo a seguir, if `expr` é avaliado como "Bananas", o programa corresponde o valor com o `case` "Bananas" e executa a instrução associada. Quando `break` for encontrado, o programa para (break), saindo de `switch` e executa a instrução localizada após o `switch`. Se `break` fosse omitido, a instrução para "Cherries" também seria executada.

```js
switch (expr) {
  case "Laranjas":
    console.log("As laranjas custam $0.59 o quilo.");
    break;
  case "Maçãs":
    console.log("Maçãs custam $0.32 o quilo.");
    break;
  case "Bananas":
    console.log("Bananas custam $0.48 o quilo.");
    break;
  case "Cerejas":
    console.log("Cerejas custam $3.00 o quilo.");
    break;
  case "Mangas":
  case "Mamões":
    console.log("Mangas e mamões custam $2.79 o quilo.");
    break;
  default:
    console.log("Desculpe, estamos sem nenhuma " + expr + ".");
}

console.log("Tem algo mais que você gostaria de levar?");
```

### Exemplo: O que acontece se eu esquecer um break?

Se você esquecer um break então o script irá rodar a partir do caso onde o critério foi correspondido e irá rodar também o caso seguinte independentemente do critério ter sido correspondido ou não:

```js
var foo = 0;
switch (foo) {
  case -1:
    console.log("1 negativo");
    break;
  case 0: // foo é 0 então aqui o critério foi correspondido, então esse bloco vai rodar
    console.log(0);
  // NOTA: o break esquecido deveria estar aqui
  case 1: // nenhuma instrução break em 'case 0:' então essa instrução vai rodar também
    console.log(1);
    break; // o programa encontra esse break então não vai continuar para o 'case 2:'
  case 2:
    console.log(2);
    break;
  default:
    console.log("default");
}
```

### Exemplo: Métodos para múltiplos casos

Referência para esta técnica abaixo:

- Switch statement multiple cases in JavaScript (Stack Overflow)

#### Multi-Caso - Operação Simples

Esse método toma vantagem do fato de não existir um break após um case e irá continuara executar o próximo case independentemente se o case corresponde ao critério. Veja o título desta seção "O que acontece se eu esquecer um break?"

Esse é um exemplo de uma operação sequencial simples com a instrução switch, onde quatro valores diferentes fazem a mesma coisa..

```js
var Animal = "Girafa";
switch (Animal) {
  case "Vaca":
  case "Girafa":
  case "Cachorro":
  case "Porco":
    alert("Esse animal irá para Arca de Noé");
    break;
  case "Dinossauro":
  default:
    alert("Esse animal não vai.");
}
```

#### Multi-Caso - Operações encadeadas

Esse é um exemplo de múltiplas operações squenciais usando a instrução `switch`, onde, dependendo do número inteiro, você poderá receber outputs diferentes. Isso mostra que você pode alterar a ordem que você insere as instruções de `case`, e isso não precisa ser uma sequência numérica. Em JavaScript, você pode até mesmo misturar definições de strings dentro desses `cases`.

This is an example of a multiple-operation sequential switch statement, where, depending on the provided integer, you can receive different output. This shows you that it wil traverse in the order that you put the case statements, and it does not have to be numerically sequential. In JavaScript, you can even mix in definitions of strings into these case statements as well.

```js
var foo = 1;
var output = "Output: ";
switch (foo) {
  case 10:
    output += "Então ";
  case 1:
    output += "Qual ";
    output += "É ";
  case 2:
    output += "O Seu ";
  case 3:
    output += "Nome";
  case 4:
    output += "?";
    alert(output);
    break;
  case 5:
    output += "!";
    alert(output);
    break;
  default:
    alert("Favor escolher um número de 0 à 6!");
}
```

Output para esse exemplo:

| Value | Alert Text |
| --- | --- |
| foo é NaN ou não é 1, 2, 3, 4, 5 ou 10 | Favor escolher um número de 0 à 6! |
| 10 | Output: Então Qual É O Seu Nome? |
| 1 | Output: Qual É O Seu Nome? |
| 2 | Output: Seu Nome? |
| 3 | Output: Nome? |
| 4 | Output: ? |
| 5 | Output: ! |

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-switch-statement |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

See also
--------

* `if...else`


break - JavaScript

break
=====

Sumário
-------

O comando **break** encerra o loop atual, `switch`, ou o loop que foi informado no `label` e transfere o controle da execução do programa para o comando seguinte.

Síntaxe
-------
```

break [label];
```

`label`

Opcional. Identificador associado ao label de um comando. Se a estrutura não for um loop ou `switch`, ele será um pré-requisito.

Descrição
---------

O comando `break` inclui um label opcional que permite ao programa encerrar a execução da estrutura que possui o nome informado na label. O comando `break` deve estar dentro dessa estrutura informada no label. A estrutura que possui o nome informada na label pode ser qualquer comando `block`; não é necessário que seja precedida por um loop.

Exemplos
--------

A função a seguir possui um comando `break` que encerra o loop `while` quando a variável i vale 3, e então retorna o valor 3 \* `x`.

```js
function testaBreak(x) {
  var i = 0;

  while (i < 6) {
    if (i == 3) {
      break;
    }
    i += 1;
  }
  return i \* x;
}
```

O código a seguir possui o comando break dentro de uma estrutura nomeada. O comando `break` deverá estar dentro da estrutura na qual o label se refere. Veja que `inner_block` está dentro de `outer_block`.

```js
bloco\_externo: {
  bloco\_interno: {
    console.log("1");
    break bloco_externo; // encerra bloco\_interno e bloco\_externok
    console.log(":-("); // não é executado
  }

  console.log("2"); // não é executado
}
```

O código a seguir também utiliza o comando break com blocos nomeados mas gera um erro de sintaxe pois o comando break está dentro do bloco\_1 mas faz uma referência ao bloco\_2. Um comando break sempre deverá estar dentro da estrutura nomeada na qual fizer referência.

```js
bloco\_1:{
  console.log ('1');
  break bloco_2;            // SyntaxError: label not found
}

bloco\_2:{
  console.log ('2');
}
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-break-statement |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `continue`
* `label`
* `switch`


for...in - JavaScript

for...in
========

O laço **`for...in`** interage sobre propriedades enumeradas de um objeto, na ordem original de inserção. O laço pode ser executado para cada propriedade distinta do objeto.

Syntax
------
```

for (variavel in objeto) {...
}
```

`variavel`

Uma propriedade diferente do objeto é atribuida em cada iteração.

`objeto`

Objeto com as propriedades enumeradas.

Descrição
---------

O laço for...in somente iterage sobre propriedades enumeradas. Objetos criados a partir de construtores built-in (arrays e object) herdam propriedades não enumeradas de object.prototype e String.prototype, assim como método `String`'s `indexOf()` ou `Object`'s `toString()`. O laço irá iterar sobre todas as propriedades enumeráveis do próprio objeto e somente aquelas enumeráveis herdadas de construtores de objetos prototype.

### Propriedades deletadas, adicionadas ou modificadas

O laço `for...in` iterage sobre as propriedades de um objeto em uma ordem arbitrária (veja o `delete` (en-US) ). Se uma propriedade é deletada durante a execução do loop, ela se torna indisponível para ser acessada depois. É recomendável não adicionar, remover ou alterar propriedades novas ao objeto durante a execução do laço (durante o loop)

### Iteração em Arrays e `for...in`

**Nota:** `for...in` não deve ser usado para iteração em uma `Array` onde a ordem é importante, visto que ele iterage em uma ordem arbitrária.

Indices de arrays somente se tornam propriedades enumeradas com inteiros (integer). Não há garantia de que utilizando o laço for...in os indices de um array serão retornados em uma ordem particular ou irá retornar todas as propriedades enumeráveis. É recomendável utilizar o laço `for` com índices numéricos ou `Array.prototype.forEach()` ou ainda `for...of` quando iteragir sobre arrays onde a ordem é importante.

### Iteração apenas sobre suas próprias propriedades

Se você quer considerar somente as propriedades do próprio objeto e não as herdadas via prototype, use `getOwnPropertyNames()` ou execute `hasOwnProperty()` ou (`propertyIsEnumerable`

Exemplos
--------

A função seguinte toma como argumento um objeto. O laço for...in iterage sobre todos as propriedades enumeráveis do objeto e retorna uma string com o nome das propriedades e seus respectivos valores.

```js
//Objeto
var obj = { a: 1, b: 2, c: 3 };

//Para prop (propriedade) in obj (objeto) faça
for (var prop in obj) {
  // ctrl+shift+k (para abrir o console no mozilla firefox)
  console.log("obj." + prop + " = " + obj[prop]);
}

//A saída (output) deverá ser:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"
```

A função seguinte ilustra o uso de `hasOwnProperty()`: as propriedades herdadas não são exibidas.

```js
var triangle = { a: 1, b: 2, c: 3 };

function ColoredTriangle() {
  this.color = "red";
}

ColoredTriangle.prototype = triangle;

var obj = new ColoredTriangle();

for (var prop in obj) {
  if (obj.hasOwnProperty(prop)) {
    console.log("obj." + prop + " = " + obj[prop]);
  }
}

// Output:
// "obj.color = red"
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-for-in-and-for-of-statements |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Compatibilidade: Initializer expressions
----------------------------------------

Anterior ao SpiderMonkey 40, era possível usar uma expressão inicial com o laço for...in, conforme exemplo que se segue:

```js
var obj = {a:1, b:2, c:3};
for(var i=0 in obj) {
  console.log(obj[i]);
}
// 1
// 2
// 3
```

Este não é o comportamento padrão e atualmente é ignorado a partir da versão 40 e posteriores e seu uso irá exibir o error `SyntaxError` (en-US) ("for-in loop head declarations may not have initializers"). Outras engines como a v8 (Chrome), Chakra (IE/Edge) e JSC (Webkit/Safari) estão estudando o que fazer com esse comportamento.

Veja também
-----------

* `for...of` - laço similar que iterage sobre os valores das propriedades.
* `for each in` - (deprecated).
* `for`
* Generator expressions (uses the `for...in` syntax)
* Enumerability and ownership of properties
* `Object.getOwnPropertyNames()`
* `Object.prototype.hasOwnProperty()`
* `Array.prototype.forEach()`


Declaração de função - JavaScript

Declaração de função
====================

A **declaração function** define uma função com os especificados parâmetros.

Você pode também definir funções usando o construtor `Function` e uma `function expression`.

Sintaxe
-------
```

function name([param,[, param,[..., param]]]) {
   [statements]
}
```

`name`

O nome da função.

`param`

O nome de um argumento a ser passado para a função. Uma função pode ter atè 255 argumentos.

`statements`

As instruções que compõem o corpo da função.

Descrição
---------

Uma função criada com uma declaração function é um objeto `Function` e tem todas as propriedades, métodos e comportamentos dos objetos `Function`. Veja `Function` para informações detalhadas sobre as funções.

Uma função pode também ser criada usando uma expressão (veja `function expression`).

Por padrão, funções retornam `undefined`. Para retornar qualquer outro valor, a função precisa ter uma instrução `return` que especifica o valor para retorno.

### Criando funções condicionalmente

Funções podem ser condicionalmente declaradas, isso é, uma instrução de função pode ser aninhada dentro de uma instrução `if`. A maioria dos navegadores que não sejam Mozilla ir tratar essas declarações condicionais como uma incondicional e criará a função se a condição for true ou não, veja esse artigo para uma visão geral. Portanto, ela não pode ser usada para criação de expressões de função condicional.

### Declarações de funções hoisting

Declarações de funções em JavaScript são hoisted à definição da função. Você pode usar uma função antes de tê-la declarado:

```js
hoisted(); // logs "foo"

function hoisted() {
  console.log("foo");
}
```

Note que `function expressions` não são hoisted:

```js
notHoisted(); // TypeError: notHoisted is not a function

var notHoisted = function () {
  console.log("bar");
};
```

Exemplos
--------

### Usando funções

O seguinte código declara uma função que retorna a quantidade total das vendas, quando dados os números de unidades vendidas dos produtos a, b e c.

```js
function calc\_sales(units\_a, units\_b, units\_c) {
  return units_a \* 79 + units_b \* 129 + units_c \* 699;
}
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-function-definitions |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `Functions and function scope` (en-US)
* `Function`
* `function expression`
* `function* statement`
* `function* expression`
* `Arrow functions`
* `GeneratorFunction` (en-US)


return - JavaScript

return
======

A **declaração `return`** finaliza a execução de uma função e especifica os valores que devem ser retonados para onde a função foi chamada.

Sintaxe
-------
```

return [[expression]];
```

`expression`

A expressão cujo valor será retornado. Se omitido, `undefined` é retornado.

Descrição
---------

Quando uma declaração `return` é usada em um corpo de função, a execução dessa função é parada. Se especificado, um dado valor é retornado à quem chamou a função. Se a expressão for omitida, `undefined` será retornado. Todas as declarações return a seguir param a execução da função:

```js
return;
return true;
return false;
return x;
return x + y / 3;
```

### Inserção Automática de Ponto-e-Vírgula

A declaração `return` é afetada pela inserção automática de ponto e vírgula (ASI). Nenhum terminador de linha é permitido entre a palavra-chave `return` e a expressão.

```js
return
a + b;
```

é transformado pelo ASI em:
```

return;
a + b;
```

O console irá alertar "unreachable code after return statement" (código inacessível após a declaração return).

**Nota:** A partir do Gecko 40, um alerta é mostrado no console se um código inacessível é encontrado após uma declaração `return`.

Exemplos
--------

### return

A função a seguir retorna o quadro do seu argumento, `x`, quando `x` é um número.

```js
function square(x) {
  return x \* x;
}
```

### Interrompendo uma função

Uma função para imediatamente no ponto em que `return` é chamado.

```js
function counter() {
  for (var count = 1; ; count++) {
    // loop infinito
    console.log(count + "A"); // até 5
    if (count === 5) {
      return;
    }
    console.log(count + "B"); // até 4
  }
  console.log(count + "C"); // nunca aparece
}

counter();

// Saída:
// 1A
// 1B
// 2A
// 2B
// 3A
// 3B
// 4A
// 4B
// 5A
```

### Retornando uma função

Veja também o artigo sobre Closures.

```js
function magic(x) {
  return function calc(x) {
    return x \* 42;
  };
}

var answer = magic();
answer(1337); // 56154
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-return-statement |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* Funções (en-US)
* Closures


while - JavaScript

while
=====

A **declaração while** cria um laço que executa uma rotina especifica enquanto a condição de teste for avaliada como verdadeira. A condição é avaliada antes da execução da rotina.

Syntax
------
```

while (condição) {
  rotina
}
```

`condição`

Uma expressão avaliada antes de cada passagem através do laço. Se essa condição for avaliada como verdadeira, a rotina é executada. Quando a condição for avaliada como falsa, a execução continua na declaração depois do laço `while`.

rotina

Uma declaração que é executada enquanto a condição é avaliada como verdadeira. Para executar multiplas declarações dentro de um laço, use uma declaração em bloco (en-US) (`{ ... }`) para agrupar essas declarações.

Exemplos
--------

O seguinte laço `while` itera enquanto n é menor que três.

```js
var n = 0;
var x = 0;

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

Cada iteração, o laço incrementa n e soma à x. Portanto, x e n assumem os seguintes valores:

* Depois da primeira passagem: n = 1 e x = 1
* Depois da segunda passagem: n = 2 e x = 3
* Depois da terceira passagem: n = 3 e x = 6

Depois de completar a terceira passagem, a condição n < 3 não é mais verdadeira, então o laço termina.

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-while-statement |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja Também
-----------

* `do...while`
* `for`


debugger - JavaScript

debugger
========

A **declaração debug** invoca qualquer funcionalidade de depuração disponivel, como definir um breakpoint. Se nenhuma funcionalidade de depuração estiver disponivel, essa declaração não tem nenhum efeito.

Sintaxe
-------
```

debugger;
```

Exemplos
--------

O exemplo a seguir mostra o código onde uma declaração debugger foi inserida para invocar um depurador (se um existir) quando a função for chamada.

```js
function codigoPotencialmenteBugado() {
  debugger;
  // faça atividades de depuração como examinar, pular um passo etc.
}
```

Quando o depurador é invocado, a execução é parada na declaração debugger. É como um breakpoint no código-fonte.

![Paused at a debugger statement.](/pt-BR/docs/Web/JavaScript/Reference/Statements/debugger/screen_shot_2014-02-07_at_9.14.35_am.png)

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-debugger-statement |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* Depurando JavaScript
* O Depurador nas Ferramentas de Desenvolvedor do Firefox


var - JavaScript

var
===

Sumário
-------

O **`variable` statement** declara uma variável, opcionalmente é possível atribuir à ela um valor em sua inicialização.

Sintaxe
-------
```

var varname1 [= value1 [, varname2 [, varname3 ... [, varnameN]]]];
```

`varnameN`

Nome da variável. Pode ser utilizado qualquer identificador legal.

`valueN`

Valor inicial da variável. Pode ser qualquer expressão legal.

Descrição
---------

Declarações de variáveis, onde quer que elas ocorram, são processadas antes que qualquer outro código seja executado. O escopo de uma variável declarada com `var` é seu contexto atual em execução, o qual é a função a qual pertence ou, para variáveis declaradas fora de qualquer função, o escopo é o global.

Atribuir um valor a uma variável não declarada anteriormente implica em criar uma variável global (ela se torna uma propriedade do objeto global) quando a atribuição é executada. As diferenças entre uma variável declarada e uma não delcarada são:

1. Variáveis declaradas estão relacionadas com o contexto de execução quando elas são criadas (por exemplo, uma função, objeto). Por outro lado, as variaveis não declaradas sempre são globais.

```js
function x() {
  y = 1; // Lança a exceção ReferenceError em modo restrito (strict mode)
  var z = 2;
}

x();

console.log(y); // logs "1"
console.log(z); // Lança a exceção ReferenceError: z não foi definida fora da função x()
```

2. Variáveis declaradas são criadas antes de qualquer código ser executado. As variáveis não declaradas não existem até quando o código atribuir um valor a ela.

```js
console.log(a); // Lança a exceção ReferenceError.
console.log("still going..."); // Nunca será executado.
```

```js
var a;
console.log(a); // mostra "undefined" ou "" dependendo do naveador.
console.log("still going..."); // mostra "still going...".
```

3. Variáveis declaradas são propriedades não configuráveis no contexto de execução (função ou global). Variaveis não declaradas são configuráveis (por exemplo, podem ser excluídas).

```js
var a = 1;
b = 2;

delete this.a; // Lança a exceção TypeError em modo restrito(strict mode). Caso contrário, Falha silenciosamente.
delete this.b;

console.log(a, b); // Throws a ReferenceError.
// A propriedade 'b' foi deletada e não existe mais.
```

Por conta dessas três diferenças, falha para declarar variáveis, muito provavelmente, levar a resultados inesperados. **Então, é recomendado sempre declarar as variáveis, independentemente se as variáveis estão em escopo de função ou escopo global**. E o modo restrito (strict mode (en-US)) do ECMAScript 5 sempre lançará uma exceçao quando o código atribuir um valor a uma variável não declarada.

### var hoisting

Como as declarações de variáveis (e declarações em geral) são processadas antes de qualquer código seja executado, declarar uma variável em qualquer lugar no código é equivalente a declarar no inicio. Isso também significa que uma variável pode aparecer para ser usada antes dela ser declarada. Esse comportamento é chamado de "hoisting", a variável é movida para o inicio da função ou do código global.

```js
bla = 2;
var bla;
// ...

// é implicitamente entendido como:

var bla;
bla = 2;
```

Por essa razão, recomenda-se sempre declarar variáveis na parte superior do seu escopo de aplicação (o topo do código global e a parte superior do código da função). Por isso, é claro que as variáveis são função de escopo (local) e que são resolvidos na cadeia de escopo.

Exemplos
--------

### Declarando e inicializando duas variáveis

```js
var a = 0,
  b = 0;
```

### Atribuindo duas variáveis com uma única expressão

```js
var a = "A";
var b = a;

// Equivalente a:

var a,
  b = (a = "A");
```

É sempre importante lembrar da ordem da declaração das variáveis:

```js
var x = y,
  y = "A";
console.log(x + y); // undefinedA
```

Então, x e y são declarados antes de qualquer código seja executado, a atribuição ocorre posteriormente. Quando "x = y" for executado, y existe e nenhum exceção ReferenceError é lançada, e o valor de y será considerado como '`undefined`'. Por este motivo, este valor é atribuido a x. Depois disso, o valor 'A' é atribuido a variável y. Consequentemente, depois da primeira linha, x === undefined && y === 'A', então o resultado.

### Iniciando diversas variáveis

```js
var x = 0;

function f() {
  var x = (y = 1); // x é declarado localmente,y não é!
}
f();

console.log(x, y); // 0, 1
// x é uma variável global como experado
// y vazou para fora da função!
```

### Variável global implícita e fora do escopo da função

Variáveis que aparecem como variáveis globais implicitas podem ser referenciadas como variáveis fora do escopo da função:

```js
var x = 0; // x é declarada como global e é igual a 0

console.log(typeof z); // undefined, desde que z não tenha sido criada anteriormente

function a() {
  // quando a for chamada,
  var y = 2; // y é declarada como local desta função, e o valor 2 é atribuido

  console.log(x, y); // 0 2

  function b() {
    // quando b for chamado,
    x = 3; // atribui o valor 3 a variável global existente, ele não cria uma nova variável global
    y = 4; // atribui o valor 4 a uma variável fora, ele não cria uma nova variável
    z = 5; // cria uma nova variável global e atribui o valor 5.
  } // (Lança a exceção ReferenceError em modo restrito.)

  b(); // chamando b, o código irá criar z como variável global
  console.log(x, y, z); // 3 4 5
}

a(); // chamando a, também irá chamar b
console.log(x, z); // 3 5
console.log(typeof y); // indefinido já que y é uma variável local da função a
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-variable-statement |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `let`
* `const`
* How One Missing `var` Ruined our Launch


class - JavaScript

class
=====

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2017.

* Learn more
* See full compatibility
* Report feedback
A **declaração class** cria uma nova classe com dado **nome** usando a herança do protótipo base.
Você também pode definir uma classe usando class expression.

Sintaxe
-------

```js
class name [extends] {
  // class body
}
```

Descrição
---------

Assim como as expressões de classe, o corpo de uma declaração de classe é executado em strict mode.

Declarações de classe não são hoisted (ao contrário de function declarations).

Exemplos
--------

### Declaração simples de classe

No exemplo a seguir, primeiro definimos uma classe chamada *Polygon*, então extendemos essa classe para criar uma classe chamada *Square*. Note que *super()*, usada no construtor, só pode ser usada em construtores e deve ser chamada antes da chave *this* ser usada.

```js
class Poligono {
  constructor(altura, largura) {
    this.nome = "Polígono";
    this.altura = altura;
    this.largura = largura;
  }
}

class Quadrado extends Poligono {
  constructor(altura) {
    super(altura, altura);
    this.nome = "Quadrado";
  }
}
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-class-definitions |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `function` declaration
* `class` expression
* Classes


label (Etiqueta) - JavaScript

label (Etiqueta)
================

Provém uma declaração com um indentificador o qual pode ser referido posteriormente utilizando-se os comandos *break* ou *continue*.

Por exemplo, você pode usar um *label* para identificar um laço e então com um comando de *break* ou *continue* indicar se este deve ser interrompido ou então continuar sua execução.

Sintaxe
-------
```

label :
   declaração
```

### Parâmetros

`label`

Qualquer idenfiticador JavaScript válido que não é uma palavra reservada.

`declaração`

Uma declaração qualquer. *break* pode ser utilizado com qualquer declaração entiquetada (com *label*) , assim como o *continue* também pode.

**Aviso:** ### Evite usar labelsLabels não são comunmente utilizados em JavaScript já que estes fazem com que programas fiquei mais difíceis de ler e entender. Sempre que possível evite utilizar labels e, dependendo dos casos, prefira chamar funções (en-US) ou lançar um erro (en-US).

Exemplos
--------

### `Exemplo com continue`

```js
var i, j;

loop1: for (i = 0; i < 3; i++) {
  //O primeiro 'for' é etiquetado com "loop1"
  loop2: for (j = 0; j < 3; j++) {
    //O segundo é etiquetado com "loop2"
    if (i == 1 && j == 1) {
      continue loop1;
    } else {
      console.log("i = " + i + ", j = " + j);
    }
  }
}

// Sua saída é:
// "i = 0, j = 0"
// "i = 0, j = 1"
// "i = 0, j = 2"
// "i = 1, j = 0"
// "i = 2, j = 0"
// "i = 2, j = 1"
// "i = 2, j = 2"
// Note como pula-se "i = 1, j = 1" e "i = 1, j = 2"
```

### Exemplo 2 `(continue)`

Dado uma lista de itens e outra de testes, este exemplo conta o número de ítens que passam em todos os testes.

```js
var itemsPassed = 0;
var i, j;

top: for (i = 0; i < items.length; i++) {
  for (j = 0; j < tests.length; j++) if (!tests[j].pass(items[i])) continue top;
  itemsPassed++;
}
```

### Exemplo 3 `(break)`

Dado uma lista de ítens e uma lista de testes, neste exemplo determina-se se todos os ítens passam em todos os testes.

```js
var allPass = true;
var i, j;

top: for (i = 0; items.length; i++)
  for (j = 0; j < tests.length; i++)
    if (!tests[j].pass(items[i])) {
      allPass = false;
      break top;
    }
```

Veja também
-----------

* break (en-US)
* continue (en-US)


const - JavaScript

const
=====

Constantes possuem escopo de bloco, semelhantes às variáveis declaradas usando o palavra-chave `let`. O valor de uma constante não pode ser alterado por uma atribuição, e ela não pode ser redeclarada.

Experimente
-----------

Resumo
------

A **declaração `const`** cria uma variável cujo o valor é fixo, ou seja, uma constante somente leitura. Isso não significa que o valor é imutável, apenas que a variável constante não pode ser alterada ou retribuída.

Sintaxe
-------
```

const name1 = value1 [, name2 = value2 [, ... [, nameN = valueN]]]];
```

`nameN`

Nome da constante. Pode ser qualquer identificador válido.

`valueN`

Valor atribuido a constante. Pode ser qualquer expressão válida, incluindo uma função.

Descrição
---------

Esta declaração cria uma constante que pode pertencer tanto ao escopo global (na janela ou objeto) quanto ao local do bloco em que é declarada. Constantes globais não se tornam propriedades do objeto `window`, diferente da criação de variáveis com `var`.

Toda constante requer um inicializador, ou seja, é preciso especificar um valor para a constante no momento em que ela é declarada (o que faz sentido, uma vez que esse valor não pode ser alterado).

A declaração **`const`** cria uma referência somente leitura a um valor. Isso **não** significa que esse valor é imutável, apenas que o identificador da variável constante não pode ser alterado. Se o conteúdo do identificador for um objeto, isso significa que o conteúdo do objeto (ex. seus parâmetros) podem ser alterados.

Todas as considerações de "temporal dead zone" se aplicam tanto a **`let`** quanto a **`const`**.

Uma constante não pode ter o mesmo nome que uma função ou variável que esteja no mesmo escopo.

Exemplos
--------

O exemplo abaixo demonstra o comportamento de uma constante. Experimente executá-lo no console do seu navegador.

```js
// NOTA: constantes podem ser declaradas em caixa alta ou baixa,
// mas uma convenção comum é usar apenas caixa alta

// define MY\_FAV como uma constante e lhe atribui o valor 7
const MY\_FAV = 7;

// isto falha mas não emite erros no Firefox e Chrome (porém não falha no Safari)
MY\_FAV = 20;

// a variável MY\_FAV possui o valor 7
console.log("my favorite number is: " + MY\_FAV);

// tentar redeclarar a constante emite um erro - Uncaught SyntaxError: Identifier 'MY\_FAV' has already been declared
const MY\_FAV = 20;

// o nome MY\_FAV está reservado para a constante acima, logo também irá falhar
var MY\_FAV = 20;

// isso também vai falhar
let MY\_FAV = 20;

// É importante notar a natureza de escopo por bloco
if (MY\_FAV === 7) {
    // não tem problema fazer isso, pois cria uma variável de bloco MY\_FAV
    // com escopo local (o nome MY\_FAV poderia ser usado com let também)
    let MY\_FAV = 20;

    // MY\_FAV agora é 20
    console.log("meu número favorito é " + MY\_FAV);

    // isso retorna um erro, pois tenta registrar a variável no contexto global
    var MY\_FAV = 20;
}

//MY\_FAV ainda é 7
console.log('meu número favorito é ' + MY\_FAV);

// const deve ser inicializada
const FOO; // SyntaxError: missing = in const declaration

// const também funciona com objetos
const MY\_OBJECT = {'key':'value'};

// Sobrescrever o objeto também falha (no Firefox e Chrome mas não no Safari) - Uncaught TypeError: Assignment to constant variable.
MY\_OBJECT = {"OTHER\_KEY": "value"};

// Entretanto, atributos de objetos não estão protegidos,
// logo a seguinte instrução é executada sem problemas
MY\_OBJECT.key = "otherValue"; // Utilize Object.freeze() se quiser tornar um objeto imutável

// o mesmo se aplica para arrays
const MY\_ARRAY = [];
// É possível utilizar push para incluir itens no array
MY\_ARRAY.push('A'); //["A"]
// Todavia, atribuir um novo array para a variável gera um erro
MY\_ARRAY = ['B'];
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-let-and-const-declarations |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### Observações

Em versões anteriores do Firefox & Chrome e a partir de Safari 5.1.7 e Opera 12.00, se você define uma variável com `const`, você ainda consegue alterar o valor depois. Este recurso não é suportado no Internet Explorer 6-10, mas está incluído no Internet Explorer 11.

### Observações específicas para Firefox

A declaração `const` foi implementada no Firefox muito antes de `const` aparecer na especificação ECMAScript 6. For `const` ES6 compliance see Erro do Firefox 950547 and Erro do Firefox 611388.

* Iniciando com o Gecko 36:
    + `{const a=1};a` passa a retornar `ReferenceError` e não retorna `1` devido block-scoping.
    + `const a;` passa a retornar `SyntaxError` (en-US) ("missing = in const declaration`"`): É necessário incializar a constante.
    + `const a = 1; a = 2;` passa a retornar `SyntaxError` (en-US) ("invalid assignment to const a").
Veja também
-----------

* `var`
* `let`
* Guia de constantes em JavaScript


import - JavaScript

import
======

A declaração estática **`import`** é usada para importar vínculos que são exportados por um outro módulo. Os módulos importados estão em `strict mode`, declarado como tal ou não. A declaração `import` não pode ser usada em scripts embutidos, a menos que tal script tenha um `type="module"`.

Há também uma função dinâmica **`import()`**, que não requer scripts de `type="module"`.

A compatibilidade com versões anteriores pode ser garantida usando o atributo `nomodule` na tag de script.

A importação dinâmica é útil em situações em que você deseja carregar um módulo condicionalmente ou sob demanda. A forma estática é preferível para carregar dependências iniciais e pode se beneficiar mais prontamente de ferramentas de análise estática e tree shaking (en-US).

Sintaxe
-------
```

import defaultExport from "module-name";
import * as name from "module-name";
import { export } from "module-name";
import { export as alias } from "module-name";
import { export1 , export2 } from "module-name";
import { foo , bar } from "module-name/path/to/specific/un-exported/file";
import { export1 , export2 as alias2 , [...] } from "module-name";
import defaultExport, { export [ , [...] ] } from "module-name";
import defaultExport, * as name from "module-name";
import "module-name"; var promise = import("module-name"); // This is a stage 3 proposal.
```

`defaultExport`

Nome que de referência para a exportação padrão do módulo.

`module-name`

O módulo para importar. Geralmente, esse é um nome de caminho relativo ou absoluto para o arquivo `.js` contendo esse módulo. Certos empacotadores podem permitir ou exigir o uso da extensão; verifique seu ambiente. Apenas aspas simples e aspas duplas são permitidas.

`name`

Nome do objeto do módulo que será usado como um tipo de espaço de nomes ao se referir às importações.

`export, exportN`

Nome das exportações a serem importadas.

`alias, aliasN`

Nomes que se referem às importações nomeadas.

Descrição
---------

O parâmetro name é o nome do "objeto módulo", que será usado como um tipo de namespace para se referir às exportações. Os parâmetros de exportação especificam exportações nomeadas individuais, enquanto a importação \* como sintaxe de nome importa todos eles. Abaixo estão alguns exemplos para esclarecer a sintaxe.

### Importar o conteúdo de todo um módulo

Isso insere `myModule` no escopo atual, contendo todas as exportações do módulo no arquivo localizado em `/modules/my-module.js`.
```

import * as myModule from '/modules/my-module.js';
```

Aqui, acessar as exportações significa usar o nome do módulo ("myModule" neste caso) como um namespace. Por exemplo, se o módulo importado acima incluir um export `doAllTheAmazingThings()`, você o chamaria assim:
```

myModule.doAllTheAmazingThings();
```

### Importar uma única exportação de um módulo

Dado um objeto ou valor chamado `myExport`que foi exportado do módulo `my-module` implicitamente (porque o módulo inteiro é exportado) ou explicitamente (usando a instrução `export` statement), isso insere `myExport` no escopo atual.
```

import {myExport} from '/modules/my-module.js';
```

### Importar várias exportações do módulo

Isso inclui tanto `foo` como `bar` no escopo atual.

### Importar uma exportação com um alias mais conveniente

Você pode renomear uma exportação ao importá-la. Por exemplo, isso insere `shortName` no escopo atual.
```

import {reallyReallyLongModuleExportName as shortName}
  from '/modules/my-module.js';
```

### Renomear várias exportações durante a importação

Importe várias exportações de um módulo com aliases convenientes.
```

import {
  reallyReallyLongModuleExportName as shortName,
  anotherLongModuleName as short
} from '/modules/my-module.js';
```

### Importar um módulo apenas para seus efeitos colaterais

Importe um módulo inteiro somente para efeitos colaterais, sem importar nada. Isso executa o código global do módulo, mas na verdade não importa nenhum valor.
```

import '/modules/my-module.js';
```

### Importando Padrões

É possível ter um padrão `exportação` (seja um objeto, uma função, uma classe etc.). A declaração de importação pode então ser usada para importar esses padrões.

A versão mais simples importa diretamente o padrão:
```

import myDefault from '/modules/my-module.js';
```

Também é possível usar a sintaxe padrão com as vistas acima (importações de namespace ou importações nomeadas). Em tais casos, a importação padrão terá que ser declarada primeiro. Por exemplo:
```

import myDefault, * as myModule from '/modules/my-module.js';
// myModule used as a namespace
```

Ou
```

import myDefault, {foo, bar} from '/modules/my-module.js';
// specific, named imports
```

### Importações Dinâmicas

A palavra-chave `import` pode ser chamada como uma função para importar dinamicamente um módulo. Quando usado dessa maneira, retorna uma promessa.
```

import('/modules/my-module.js')
  .then((module) => {
    // Do something with the module.
  });
```

Este formulário também suporta a palavra-chave await.
```

let module = await import('/modules/my-module.js');
```

Exemplos
--------

### Padrão Import

O código abaixo mostra como importar um módulo secundário para auxiliar no processamento de uma requisição AJAX que retorna um JSON.

#### O Módulo: file.js
```

function getJSON(url, callback) {
  let xhr = new XMLHttpRequest();
  xhr.onload = function () {
    callback(this.responseText)
  };
  xhr.open('GET', url, true);
  xhr.send();
}

export function getUsefulContents(url, callback) {
  getJSON(url, data => callback(JSON.parse(data)));
}
```

#### O programa principal: main.js

```js
import { getUsefulContents } from "/modules/file.js";

getUsefulContents("http://www.example.com", (data) => {
  doSomethingUseful(data);
});
```

### Dynamic Import

Este exemplo mostra como carregar a funcionalidade em uma página com base em uma ação do usuário, nesse caso, um clique no botão e, em seguida, chamar uma função dentro desse módulo. Esta não é a única maneira de implementar essa funcionalidade. A função `import()` também é compatível com `await`.

```js
const main = document.querySelector("main");
for (const link of document.querySelectorAll("nav > a")) {
  link.addEventListener("click", (e) => {
    e.preventDefault();

    import("/modules/my-module.js")
      .then((module) => {
        module.loadPageInto(main);
      })
      .catch((err) => {
        main.textContent = err.message;
      });
  });
}
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-imports |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `export`
* `import.meta`
* Previewing ES6 Modules and more from ES2015, ES2016 and beyond
* ES6 in Depth: Modules, Hacks blog post by Jason Orendorff
* ES modules: A cartoon deep-dive, Hacks blog post by Lin Clark
* Axel Rauschmayer's book: "Exploring JS: Modules"


empty - JavaScript

empty
=====

Uma **declaração vazia** é usada para fornecer nenhuma declaração, embora a sintaxe do JavaScript esperasse uma.

Experimente
-----------

Sintaxe
-------
```

;
```

Descrição
---------

A instrução vazia é um ponto-e-vírgula (;) indicando que nenhuma instrução será executada, mesmo se a sintaxe do JavaScript exigir uma.

O comportamento oposto, em que você deseja várias instruções, mas o JavaScript permite apenas uma única, é possível usando uma instrução de bloco ; combina várias declarações em uma única.

Exemplos
--------

A instrução vazia às vezes é usada com instruções de loop. Veja o exemplo a seguir com um corpo de loop vazio:

```js
var arr = [1, 2, 3];

// Assign all array values to 0
for (i = 0; i < arr.length; arr[i++] = 0 /\* empty statement \*/);

console.log(arr);
// [0, 0, 0]
```

**Nota:** É uma boa ideia comentar o uso intencional da declaração vazia, pois não é realmente óbvio distinguir entre um ponto e vírgula normal. No exemplo a seguir, o uso provavelmente não é intencional:

```js
if (condition) // Caution, this "if" does nothing!
  killTheUniverse(); // So this gets always executed!!!
```

Outro Exemplo: Uma declaração `if...else` declaração sem chaves ({ }). Se três for verdadeiro, nada acontecerá, quatro não importa e também a função launchRocket ( ) no caso contrário não será executada.

```js
if (one) doOne();
else if (two) doTwo();
else if (three) // nothing here
else if (four) doFour();
else launchRocket();
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-empty-statement |

Browsers compatíveis
--------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `Block statement`


if...else - JavaScript

if...else
=========

A condicional **if** é uma estrutura condicional que executa a afirmação, dentro do bloco, se determinada condição for verdadeira. Se for falsa, executa as afirmações dentro de **else**.

Sintaxe
-------
```

if (condição) afirmação1 [else afirmação2]
```

`condição`

Uma expressão (premissa) que pode ser avaliada como verdadeira (true) ou falsa (false), veja lógica de programação para entender melhor.

`condição1`

Condicional que será executada caso a condição em *if* seja verdadeira (true). Pode ser qualquer instrução, incluindo mais condicionais *if* aninhadas à instrução. Para executar multiplas instruções, faça um agrupamento com uma instrução em bloco ({ ... }). Para não executar nenhuma instrução, utilize uma instrução vazia (empty).

`condição2`

Condicional que será executada caso a condição em *if* seja avaliada como falsa (false) e a condição *else* exista. Pode ser qualquer instrução, incluindo instruões em bloco e mais condicionais *if* aninhadas.

Descrição
---------

Múltiplas condicionais *if ... else* podem ser aninhados quando necessário. Observe que não existe elseif (em uma palavra). O correto é a instrução com espaços (else if), conforme abaixo:
```

if (condição1)
   instrução1
else if (condição2)
   instrução2
else if (condição3)
   instrução3
...
else
   instruçãoN
```

Para ver seu funcionamento, abaixo está a instrução como deveria ser caso identada corretamente.
```

if (condição1)
   instrução1
else
   if (condição2)
      instrução2
   else
      if (condição3)
...
```

Para executar multiplas instruções dentro de uma condição, utilize um bloco (`{ ... }`) . Em geral, é sempre uma boa prática utilizar instruções dentro de blocos, especialmente em códigos que envolvam condicionais *if* aninhadas:
```

if (condição) {
   instrução1
} else {
   instrução2
}
```

Não confunda os valores boolean primitivos `true` e `false` com os valores true e false do objeto Boolean. Qualquer valor que não for `undefined`, `null`, `0`, `NaN`, ou uma string vazia (`""`), e qualquer objeto, incluíndo um objeto Boolean cujo valor é false, é avaliado como true quando passado por uma condicional. Por exemplo:

```js
var b = new Boolean(false);
if (b) // essa condição é avaliada como true
```

Exemplos
--------

### Usando `if...else`

```js
if (cipher_char === from_char) {
  result = result + to_char;
  x++;
} else {
  result = result + clear_char;
}
```

### Usando `else if`

Perceba que não existe sintaxe de `elseif` em JavaScript. Entretanto, você pode escrevê-la com um espaço entre o if e o else.

```js
if (x > 5) {
} else if (x > 50) {
} else {
}
```

### Atribuições junto de expressões condicionais

É recomendado não utilizar atribuições simples junto de uma expressão condicional, visto que atribuições podem ser confundidas com igualdade ao olhar o código. Por exemplo, não use o código abaixo:

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

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

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

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-if-statement |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `block`
* `switch`


for await...of - JavaScript

for await...of
==============

A **declaração `for await...of`** cria um loop que itera sobre objetos iteráveis assíncronos, bem como sobre iteráveis síncronos, incluindo: `String`, `Array`, `Array`-como objetos (e.g., `arguments` or `NodeList`), `TypedArray` (en-US), `Map`, `Set`, e iteráveis async/sync. Invoca um hook de iteração personalizado com instruções a serem executadas para o valor de cada propriedade do objeto.

Sintaxe
-------
```

for await (variável of iterável) {
  // declaração
}
```

`variável`

Em cada iteração, o valor de uma propriedade diferente é atribuído à *variável*. A *variável* pode ser declarada como `const`, `let` ou `var`.

`iterável`

Objeto cujas propriedades iteráveis devem ser iteradas.

### Iterando sobre iteráveis assíncronos

Você também pode iterar sobre um objeto que explicidamente implementa protocolo iterável assíncrono(*async iterable protocol*):

```js
var asyncIterable = {
  [Symbol.asyncIterator]() {
    return {
      i: 0,
      next() {
        if (this.i < 3) {
          return Promise.resolve({ value: this.i++, done: false });
        }

        return Promise.resolve({ done: true });
      },
    };
  },
};

(async function () {
  for await (let num of asyncIterable) {
    console.log(num);
  }
})();

// 0
// 1
// 2
```

### Iterando sobre generators assíncronos

Como os geradores assíncronos implementam o protocolo assíncrono Iterator, eles podem fazer um loop usando `for await... of`

```js
async function\* asyncGenerator() {
  var i = 0;
  while (i < 3) {
    yield i++;
  }
}

(async function () {
  for await (let num of asyncGenerator()) {
    console.log(num);
  }
})();
// 0
// 1
// 2
```

Para termos um exemplo mais concreto de iteração sobre um generator assíncrono usando `for await... of`, considere iterar sobre dados obtidos através de um fecth de uma API. Este exemplo cria primeiro um iterador assíncrono para um stream de dados e depois usa-o para encontrar o tamanho da resposta da API.

```js
async function\* streamAsyncIterator(stream) {
  const reader = stream.getReader();
  try {
    while (true) {
      const { done, value } = await reader.read();
      if (done) {
        return;
      }
      yield value;
    }
  } finally {
    reader.releaseLock();
  }
}
// Obtém dados do URL e calcula o tamanho da resposta usando o generator assíncrono
async function getResponseSize(url) {
  const response = await fetch(url);
  // Guardará o tamanho do response em bytes.
  let responseSize = 0;
  // O for-wait-loop irá iterar de forma assíncrona sobre cada parte do response.
  for await (const chunk of streamAsyncIterator(response.body)) {
    // Incrementa o valor do responseSize
    responseSize += chunk.length;
  }

  console.log(`Response Size: ${responseSize} bytes`);
  // output esperado:"Response Size: 1071472"
  return responseSize;
}
getResponseSize("https://jsonplaceholder.typicode.com/photos");
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-for-in-and-for-of-statements |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `Statements/for...of`


try...catch - JavaScript

try...catch
===========

As declarações **try...catch** marcam um bloco de declarações para testar (**try**), e especifica uma resposta, caso uma exceção seja lançada.

Sintaxe
-------
```

try {
   try_statements
}
[catch (exception_var_1 if condition_1) {
   catch_statements_1
}]
...
[catch (exception_var_2) {
   catch_statements_2
}]
[finally {
   finally_statements
}]
```

`try_statements`

Declarações (statements) a serem executadas.

`catch_statements_1`, `catch_statements_2`

Declarações que são executadas se uma exceção é lançada no bloco `try.`

`exception_var_1`, `exception_var_2`

Um indentificador que leva um objeto exceção para uma cláusula `catch` associada.

`condition_1`

Uma expressão condicional.

`finally_statements`

Declarações que são executadas depois que a declaração `try` é completada. Essas declarações são executadas independetemente se uma exceção foi ou não lançada ou capturada.

Descrição
---------

A declaração `try` consiste em um bloco `try`, que contém uma ou mais declarações, e ao menos uma cláusula `catch` ou uma cláusula `finally`, ou ambas. Ou seja, há 3 formas de declarações `try` :

1. `try...catch`
2. `try...finally`
3. `try...catch...finally`

Uma cláusula `catch` contém declarações que especificam o que fazer caso uma exceção seja lançada no bloco `try`. Ou seja, se você quer que o bloco `try` tenha êxito, e caso não tenha, você quer que o controle passe para o bloco `catch`. Caso qualquer declaração dentro do bloco `try` (ou em uma função chamada no interior do bloco `try`) lançar uma exceção o controle imediatamente muda para a cláusula `catch`. Se nenhuma exceção for lançada no bloco `try` a cláusula `catch` é ignorada.

A cláusula `finally` é executada após a excecução do bloco `try` e da(s) cláusula(s) `catch` porém antes das declarações seguintes ao `try`. Ela sempre é executada, independente se uma exceção for lançada ou capturada.

Você pode aninhar uma ou mais declarações `try`. Caso uma declaração `try` interior não tenha uma cláusula `catch`, a cláusula catch pertencente a declaração `try` que a envolve é introduzida.

Você pode usar a declaração try para manipular exceções em JavaScript. Veja o Guia Javascript para informações sobre exceções em JavaScript.

### Cláusula catch incondicional

Quando uma única, incondicional cláusula `catch` é utilizada, o bloco `catch` é inserido quando qualquer exceção for lançada. Por exemplo, quando a exceção ocorre no código a seguir, o controle é transferido para a cláusula `catch`.

```js
try {
  throw "myException"; // gera uma exceção
} catch (e) {
  // declarações para manipular quaisquer exceções
  logMyErrors(e); // passa o objeto de exceção para o manipulador de erro
}
```

### Cláusulas `catch` condicionais

**Non-standard:** This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

Você pode utilizar uma ou mais cláusulas `catch` condicionals para manipular exceções específicas. Nesse caso a cláusula `catch` apropriada será inserida quando a exceção espeficica for lançada. No exemplo a seguir, o código no bloco `try` pode potencialmente jogar três exceções: `TypeError`, `RangeError` (en-US), e `EvalError`. Quando a exceção ocorre, o controle transfere para a cláusula `catch` apropriada. Caso a exceção não seja uma das especificadas e uma cláusula `catch` incondicional for encontrada, o controle é transferido para essa cláusula `catch`.

Se utilizar uma cláusula `catch` incondicional com uma ou mais cláusulas `catch` condicionais, o catch incondicional deve ser especificado por último. Caso contrário, o catch incondicional interceptará todos os tipos de exceção antes que eles alcancem os condicionais.

Nota: Essa funcionalidade não é parte da especificação ECMAScript.
```

try {
    myroutine(); // pode lançar três tipos de exceções
} catch (e if e instanceof TypeError) {
    // declarações para manipular exceções TypeError
} catch (e if e instanceof RangeError) {
    // declarações para manipular exceções RangeError
} catch (e if e instanceof EvalError) {
    // declarações para manipular exceções EvalError
} catch (e) {
    // declarações para manipular quaisquer exceções não especificadas
    logMyErrors(e); // passa o objeto de exceção para o manipulador de erro
}
```

E aqui temos como implementar as mesmas "cláusulas `catch` condicionais" utilizando apenas JavaScript puro conforme a especificação ECMAScript (obviamente é mais verboso, porém, funciona em qualquer lugar):
```

try {
    myroutine(); // pode lançar três tipos de exceções
} catch (e) {
    if (e instanceof TypeError) {
        // declarações para manipular exceções TypeError
    } else if (e instanceof RangeError) {
        // declarações para manipular exceções RangeError
    } else if (e instanceof EvalError) {
        // declarações para manipular exceções EvalError
    } else {
       // declarações para manipular quaisquer exceções não especificadas
       logMyErrors(e); // passa o objeto de exceção para o manipulador de erro
    }
}
```

### O identificador de exceção

Quando uma exceção é lançada no bloco `try`, `exception_var` (ex. o `e` dentro de `catch (e)`) armazena o valor especificado pela declaração `throw`. Você pode usar esse identificador para conseguir informação sobre a exceção que foi lançanda.

Esse identificador é local para a cláusula `catch`. Ou seja, é criado quando a cláusula `catch` é introduzida e após terminar sua excecução o identificador não se torna mais disponível.

### A cláusula `finally`

A cláusula `finally` é executada após a excecução do bloco `try` e da(s) cláusula(s) `catch` porém antes das declarações seguintes a declaração `try`. Ela sempre é executada, independente se uma exceção for lançada ou capturada.

A cláusula `finally` contém declarações para executarem após a execução do bloco `try` e da(s) cláusula(s) `catch` porém antes das declarações seguintes a declaração `try`. A cláusula `finally` é excutada independente se uma exceção for lançada ou não. Caso uma exceção seja lançada, as declarações no interior da cláusula `finally` são executadas mesmo que nenhum `catch` manipule a exceção.

Você pode utilizar a cláusula `finally` para fazer seu script falhar graciosamente quando uma exceção ocorrer; por exemplo, você pode precisar liberar um recurso que seu script possui vinculado. O exemplo seguinte abre um aquivo e então executa declarações que utilizam o arquivo (server-side JavaScript permite que você acesse arquivos). Se uma exceção for lançada enquanto o arquivo estiver aberto, a cláusula `finally` fecha o arquivo antes que o script falhe.

```js
openMyFile();
try {
  // vincula o recurso
  writeMyFile(theData);
} finally {
  closeMyFile(); // sempre fecha o recurso
}
```

Exemplos
--------

### Blocos try aninhados

Primeiro vamos ver o que acontece com isso:
```

try {
  try {
    throw new Error("oops");
  }
  finally {
    console.log("finally");
  }
}
catch (ex) {
  console.error("outer", ex.message);
}

// Resultado
// "finally"
// "outer" "oops"
```

Agora, caso nós já capturamos a exceção no bloco `try` interno adicionando um bloco `catch`
```

try {
  try {
    throw new Error("oops");
  }
  catch (ex) {
    console.error("inner", ex.message);
  }
  finally {
    console.log("finally");
  }
}
catch (ex) {
  console.error("outer", ex.message);
}

// Resultado:
// "inner" "oops"
// "finally"
```

E agora, vamos relançar o erro.
```

try {
  try {
    throw new Error("oops");
  }
  catch (ex) {
    console.error("inner", ex.message);
    throw ex;
  }
  finally {
    console.log("finally");
  }
}
catch (ex) {
  console.error("outer", ex.message);
}

// Resultado:
// "inner" "oops"
// "finally"
// "outer" "oops"
```

Qualquer exceção lançada será capturada apenas uma vez pelo bloco `catch` envolvente mais próximo, a não ser que seja relançada. Obviamente qualquer nova exceção elevada no bloco "interno" (pois código em um bloco `catch` pode fazer algo que lance), será capturado pelo bloco "externo".

### Retornando de um bloco `finally`

Caso o bloco `finally` retorne um valor, esse valor torna-se o valor de retorno do produto de `try-catch-finally` inteiro, independente de qualquer declaração return nos blocos `try` e `catch`. Isso inclui exceções lançadas dentro do bloco `catch`:
```

try {
  try {
    throw new Error("oops");
  }
  catch (ex) {
    console.error("inner", ex.message);
    throw ex;
  }
  finally {
    console.log("finally");
    return;
  }
}
catch (ex) {
  console.error("outer", ex.message);
}

// Resultado:
// "inner" "oops"
// "finally"
```

O "oops" externo não é lançado devido ao retorno do bloco `finally`. O mesmo se aplicaria a qualquer valor retornado do bloco `catch`.

Vejam também
------------

* throw
* Error


for - JavaScript

for
===

A instrução `for` cria um loop que consiste em três expressões opcionais, dentro de parênteses e separadas por ponto e vírgula, seguidas por uma declaração ou uma sequência de declarações executadas em sequência.

A fonte desse exemplo interativo está armazenada em um repositório do GitHub. Se você gostaria de contribuir com os projetos de exemplos interativos, por favor clone https://github.com/mdn/interactive-examples e nos envie um pull request (requisição para puxar).

Sintaxe
-------
```

for ([inicialização]; [condição]; [expressão final])
   declaração
```

`inicialização`

Uma expressão (incluindo expressões de atribuição) ou declarações variáveis. Geralmente usada para iniciar o contador de variáveis. Esta expressão pode, opcionalmente, declarar novas variáveis com a palavra chave `var`. Essas variáveis não são locais no loop, isto é, elas estão no mesmo escopo que o loop `for` está. Variáveis declaradas com let são locais para a declaração.

O resultado desta expressão é descartado.

`condição`

Uma expressão para ser avaliada antes de cada iteração do loop. Se esta expressão for avaliada para true, `declaração` será executado. Este teste da condição é opcional. Se omitido, a condição sempre será avaliada como verdadeira. Se a expressão for avaliada como falsa, a execução irá para a primeira expressão após a construção loop `for`.

`expressão final`

Uma expressão que será validada no final de cada iteração de loop. Isso ocorre antes da próxima avaliação da condição. Geralmente usado para atualizar ou incrementar a variável do contador.

`declaração`

Uma declaração que é executada enquanto a condição for verdadeira. Para executar múltiplas condições dentro do loop, use uma instrução de bloco `({...})` para agrupar essas condições. Para não executar declarações dentro do loop, use uma instrução vazia `(;)`.

Exemplos de uso
---------------

### Usando `for`

A declaração `for` começa declarando a variável `i` e inicializando-a como `0`. Ela verifica se `i` é menor que nove, executa as duas instruções subsequentes e incrementa 1 a variável `i` após cada passagem pelo loop.

```js
for (var i = 0; i < 9; i++) {
  console.log(i);
  // more statements
}
```

### Expressões `for` opcionais

Todas as três expressões na condição do loop `for` são opcionais.

Por exemplo, no bloco de *inicialização*, não é necessário inicializar variáveis:

```js
var i = 0;
for (; i < 9; i++) {
  console.log(i);
  // more statements
}
```

Assim como ocorre no bloco de *inicialização*, a *condição* também é opcional. Se você está omitindo essa expressão, você deve certificar-se de quebrar o loop no corpo para não criar um loop infinito.

```js
for (var i = 0; ; i++) {
  console.log(i);
  if (i > 3) break;
  // more statements
}
```

Você também pode omitir todos os três blocos. Novamente, certifique-se de usar uma instrução `break` no final do loop e também modificar (incrementar) uma variável, para que a condição do `break` seja verdadeira em algum momento.

```js
var i = 0;

for (;;) {
  if (i > 3) break;
  console.log(i);
  i++;
}
```

### Usando `for` sem uma declaração

O ciclo `for` a seguir calcula a posição de deslocamento de um nó na seção [expressão final] e, portanto, não requer o uso de uma declaração ou de um bloco de declaração, e no seu lugar é usado um ponto-vírgula - `;`.

```js
function showOffsetPos(sId) {
  var nLeft = 0,
    nTop = 0;

  for (
    var oItNode = document.getElementById(sId); // inicialização
    oItNode; // condition
    nLeft += oItNode.offsetLeft,
      nTop += oItNode.offsetTop,
      oItNode = oItNode.offsetParent // expressão final
    /\* empty statement \*/
  );

  console.log(
    'Offset position of "' +
      sId +
      '" element:\n left: ' +
      nLeft +
      "px;\n top: " +
      nTop +
      "px;",
  );
}

// Exemplo de call:

showOffsetPos("content");

// Resultado:
// "Offset position of "content" element:
// left: 0px;
// top: 153px;"
```

**Nota:** Nesse caso, quando você não usa a seção de declaração, **o** **ponto-e-vírgula é colocada imediatamente após a declaração do ciclo**.

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-for-statement |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `break`
* `continue`
* `empty`
* `while`
* `do...while`
* `for...in`
* `for...of`


Funções assíncronas - JavaScript

Funções assíncronas
===================

Baseline Widely available
-------------------------

This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2017.

* Learn more
* See full compatibility
* Report feedback
A declaração **`async function`** define uma *função assíncrona*, que retorna um objeto `AsyncFunction`.

Você também pode definir funções assíncronas usando uma `expressão async function`.

Sintaxe
-------
```

async function nome([param[, param[, ... param]]]) {
   instruções
}
```

`nome`

O nome da função.

`param`

O nome de um parâmetro a ser passado para a função.

`instruções`

As instruções que compõem o corpo da função.

Descrição
---------

Quando uma função assíncrona é chamada, ela retorna uma `Promise`. Quando a função assíncrona retorna um valor, a `Promise` será resolvida com o valor retornado. Quando a função assíncrona lança uma exceção ou algum valor, a `Promise` será rejeitada com o valor lançado.

Uma função assíncrona pode conter uma expressão `await`, que pausa a execução da função assíncrona e espera pela resolução da `Promise` passada, e depois retoma a execução da função assíncrona e retorna o valor resolvido.

**Nota:** A proposta das funções `async/await` é de simplificar o uso de forma síncrona das `Promises` e executar alguns procedimentos em um grupo de `Promises`. Assim como `Promises` são similares a `callbacks` estruturados, funções `async/await` são similares à junção de `generators` com `Promises`.

Exemplos
--------

### Exemplo simples

```js
function resolverDepoisDe2Segundos(x) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(x);
    }, 2000);
  });
}

async function adicionar1(x) {
  var a = resolverDepoisDe2Segundos(20);
  var b = resolverDepoisDe2Segundos(30);
  return x + (await a) + (await b);
}

adicionar1(10).then((v) => {
  console.log(v); // exibe 60 depois de 2 segundos.
});

async function adicionar2(x) {
  var a = await resolverDepoisDe2Segundos(20);
  var b = await resolverDepoisDe2Segundos(30);
  return x + a + b;
}

adicionar2(10).then((v) => {
  console.log(v); // exibe 60 depois de 4 segundos.
});
```

### Reescrevendo uma cadeia de `Promise` com uma função `async`

Uma API que retorna uma `Promise` vai resultar em uma cadeia de `Promises` e separa a função em várias partes. Considere o seguinte código:

```js
function pegarDadosProcessados(url) {
  return baixarDados(url) // retorna uma Promise
    .catch((e) => {
      return baixarDadosReservas(url); // retorna uma Promise
    })
    .then((v) => {
      return processarDadosNoWorker(v); // retorna uma Promise
    });
}
```

pode ser escrita em uma única função `async` desta forma:

```js
async function pegarDadosProcessados(url) {
  let v;
  try {
    v = await baixarDados(url);
  } catch (e) {
    v = await baixarDadosReservas(url);
  }
  return processarDadosNoWorker(v);
}
```

Note que no exemplo acima não tem a instrução `await` na instrução do `return`, porque o valor retornado de uma função `async` é implícitamente passado por um `Promise.resolve`.

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-async-function-definitions |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

### Notas específicas do Firefox

* A função expression closure syntax não é permitida com funções assíncronas e irão lançar a exceção SyntaxError (en-US) a partir do Firefox 55.
Veja também
-----------

* async\_function
* AsyncFunction
* await


export - JavaScript

export
======

O export é utilizado quando criamos módulos JavaScript para exportar ligações em tempo real para suas funções, objetos ou valores primitivos de um módulo sejam utilizados por outros programas através de declarações `import`. Ligações que são exportadas ainda podem ser modificadas localmente; quando importadas, embora elas possam ser lidas somente pelo módulo que as importou, seu valor é atualizado sempre que ela modificada pelo módulo que a exportou.

Módulos exportados ficam em `strict mode`, independentemente se é declarado dessa forma, ou não. Export não pode ser utilizado em scripts embutidos.

Sintaxe
-------

Há dois tipos de exportação:

1. Exportações Explícitas (Named Exports) (Zero ou mais exports por módulo)
2. Exportações Padrão (Default Exports) (Uma por módulo)
```

// Exportando recursos individuais
export let name1, name2, …, nameN; // também var, const
export let name1 = …, name2 = …, …, nameN; // também var, const
export function functionName(){...}
export class ClassName {...}

// Lista de exportações
export { name1, name2, …, nameN };

// Renomeando exports
export { variable1 as name1, variable2 as name2, …, nameN };

// Exportando atribuições desestruturadas renomeando
export const { name1, name2: bar } = o;

// Exportações Padrão (Default exports)
export default expression;
export default function (…) { … } // também class, function*
export default function name1(…) { … } // também class, function*
export { name1 as default, … };

// Agregando módulos
export * from …; // não define a exportação padrão
export * as name1 from …; // Draft ECMAScript® 2O21
export { name1, name2, …, nameN } from …;
export { import1 as name1, import2 as name2, …, nameN } from …;
export { default } from …;
```

`nameN`

Identificador para ser exportado (assim ele pode ser importado via `import` em outro script).

Descrição
---------

Há dois diferentes tipos de export, explícito(named) e padrão(default). Pode-se ter várias exportações explícitas por módulo, mas apenas uma padrão. Cada tipo corresponde à uma da síntaxe acima:

Exportações explícitas:

```js
// exporta recursos declarados anteriomente
export { myFunction, myVariable };

// exporta recursos individuais (pode exportar var, let,
// const, function, class)
export let myVariable = Math.sqrt(2);
export function myFunction() { ... };
```

Exportação padrão (pode ser feita apenas uma por script):

```js
// exporta um recurso declarado anteriormente como padrão
export { myFunction as default };

// exporta recursos individuais como padrão
export default function () { ... }
export default class { .. }
```

Exportações explícitas são úteis para exportar vários valores. Durante a importação, é obrigatório usar o mesmo nome do objeto correspondente.

Mas a exportação padrão pode ser importada com qualquer nome, por exemplo:

```js
// arquivo test.js
let k;
export default k = 12;
```

```js
// algum outro arquivo
import m from "./test"; // note que temos a liberdade de usar import m ao invés de import k, porque k era uma exportaçào padrão
console.log(m); // vai retornar log 12
```

Você também pode renomear exportações explícitas para evitar conflitos e nome:

```js
export { myFunction as function1, myVariable as variable };
```

### Re-exportando / Agregando

É possível também "importar/exportar" de módulos diferentes em um módulo pai, de modo que eles estejam disponíveis para serem importados daquele módulo. Em outras palavras, pode-se criar um módulo único concentrando várias exportações de vários módulos.

Isto pode ser feito com a sintaxe "export from":

```js
export { default as function1, function2 } from "bar.js";
```

O que é comparável com um combinação de import e export:

```js
import { default as function1, function2 } from "bar.js";
export { function1, function2 };
```

Mas onde `function1` e `function2` não ficam disponíveis dentro do módulo atual.

**Nota:** Os exemplos a seguir são sintaticamente inválidos apesar de sua equivalência com o import:

```js
import DefaultExport from "bar.js"; // Válido
```

```js
export DefaultExport from "bar.js"; // Inválido
```

O modo correto de fazer isso e renomeando o export:

```js
export { default as DefaultExport } from "bar.js";
```

Exemplos
--------

### Usando exportações explícitas

Em um módulo `my-module.js` poderiamos usar o seguinte código:

```js
// módulo "my-module.js"
function cube(x) {
  return x \* x \* x;
}

const foo = Math.PI + Math.SQRT2;

var graph = {
  options: {
    color: "white",
    thickness: "2px",
  },
  draw: function () {
    console.log("Da função draw de graph");
  },
};

export { cube, foo, graph };
```

Então, no módulo principal incluído sem sua página HTML, poderíamos ter:

```js
import { cube, foo, graph } from "./my-module.js";

graph.options = {
  color: "blue",
  thickness: "3px",
};

graph.draw();
console.log(cube(3)); // 27
console.log(foo); // 4.555806215962888
```

É importante notar o seguinte:

* Você pode incluir esse script no seu código HTML através do elemento `<script>` do tipo="module", de modo que ele seja reconhecido e tratado apropriadamente.
* Você não pode executar módulos JS através de `file://` URL — você receberá errors CORS. Você deve rodá-los através de um servidor HTTP.
### Usando a exportação padrão

Se queremos exportar um valor sozinho ou obter um valor de reserva para o nosso módulo, nós poderiamos usar `export default`:

```js
// módulo "my-module.js"
export default function cube(x) {
  return x \* x \* x;
}
```

Daí em outro script podemos usar:

```js
import cube from "my-module";
console.log(cube(3)); // 27
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-exports |

Compatibilidade
---------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `import`
* ES6 in Depth: Modules, Hacks blog post by Jason Orendorff
* Axel Rauschmayer's book: "Exploring JS: Modules"


with - JavaScript

with
====

**Aviso:** O uso da declaração `with` não é recomendado, isso porque ele pode ser a fonte de bugs confusos e problemas de compatibilidade. Veja o parágrafo "Contra de ambiguidade" na seção "Descrição" para mais detalhes.

A **declaração with** extende a cadeia de escopo para uma declaração.

Sintaxe
-------
```

with (expressão)
  declaração
```

`expressão`

Adiciona a dada expressão à cadeia de escopo quando estiver avaliando a declaração. O parênteses em volta da expressão é obrigatório.

`declaração`

Qualquer declaração. Para executação multiplas declarações, utilize a declaração em bloco ({ ... }) para agrupar estas declarações.

Descrição
---------

JavaScript procura por um nome não qualificado procurando uma cadeia de escopo associada à execução do contexto do script ou função contendo um nome não qualificado. A declaração 'with' adiciona o dado objeto à frenet dessa cadeia de escopo durante a validação desse corpo de declarações. Se um nome não qualificado usado no corpo for igual ao de uma propriedade na cadeia de escopo, então o nome ficará ligado à propriedade e ao objeto contendo a propriedade. Senão, um `ReferenceError` será invocado.

**Nota:** Usar `with` não é recomendado, e está probido no strict mode (en-US) do ECMAScript 5. A alternativa recomendada é atribuir o objeto cujas propriedades você quer acessar a uma variável temporária.

### Pros & contras de perfomance

**Pro:** A declaração `with` pode ajudar o tamanho do arquivo por reduzir a necessidade de repetir a referência a um objeto longo sem penalidade na perfomance. A cadeia de escopo mudada por um 'with' não é computacionalmente cara. O uso de 'with' irá aliviar o interpretador de tratar repetidamente as referências. Note que, no entando, isso em muitos casos pode ser substituído usando uma variável temporária para armazenar a referência do objeto desejado.

**Contra:** A declaração `with` força que o objeto especifícado a ser procurado primeiro por pesquisas de nome. Assim sendo, todos os indentificadores que não são membros do objeto espeficícado vão ser encontrados mais lentamente em um bloco 'with'. Onde a perfomance é importande, 'with' deve ser usado apenas para englobar blocos de código que acessam membros de um objeto especifíco.

### Contra de ambiguidade

**Contra:** A declaração `with` faz ser difícil para um leitor humano ou compilador JavaScript decidir se um nome não qualificado var se encontrado em uma cadeia de escopo, e também, em qual objeto. Dado o exemplo seguinte:

```js
function f(x, o) {
  with (o) {
    console.log(x);
  }
}
```

Apenas quando `f` é chamado é `x` ou encontrado ou não, e se for encontrado, ou em `o` ou (se nenhuma propriedade existir) no objeto de ativação de `f`, onde o nome de `x` é o primeiro argumento formal. Se você esquecer de definir `x` no objeto que você passou como segundo argumento, ou se há algum bug similar ou confusão, você não vai receber um erro — apenas resultados inesperados.

**Contra:** Código utilizando `with` talvez não seja compatível posteriormente, especialmente quando usado com algo que não seja um objeto simples. Considere esse exemplo:

```js
function f(foo, values) {
  with (foo) {
    console.log(values);
  }
}
```

Se você chamar `f([1,2,3], obj)` em um ambiente ECMAScript 5, então a referência de `values` dentro da declaração `with` irá ser `obj`. No entando, ECMAScript 6 introduz uma propriedade `values` no `Array.prototype` (então isso estará disponível em todas as arrays). Então, em um ambiente JavaScript que suporta ECMAScript 6, a referência de `values` dentro da declaração `with` irá ser `[1,2,3].values`.

Exemplos
--------

### Usando `with`

A seguinte declaração `with` irá especificar que o objeto `Math` é o objeto padrão. As seguintes declarações seguindo a declaração `with` irão referir a propriedade `PI` e aos métodos `cos` e `sin`, sem especificar um objeto. JavaScript assume o objeto `Math` para essas referências.

```js
var a, x, y;
var r = 10;

with (Math) {
  a = PI \* r \* r;
  x = r \* cos(PI);
  y = r \* sin(PI / 2);
}
```

Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-with-statement |

Compatibilidade com navegadores
-------------------------------

BCD tables only load in the browser with JavaScript enabled. Enable JavaScript to view data.

Veja também
-----------

* `block`
* Strict mode (en-US)
* `Symbol.unscopables`
* `Array.prototype[@@unscopables]`