Strict mode - JavaScript

Strict mode
===========

O **strict mode** do ECMAScript 5 é uma forma de *optar* por uma variante restrita do JavaScript. O strict mode não é apenas um subconjunto: ele *intencionalmente* tem semânticas diferentes do código normal. Navegadores que não suportam strict mode executarão código strict mode com um comportamento diferente dos navegadores que suportam, então não confie no strict mode sem testar o suporte a funcionalidades dos aspectos relevantes do strict mode. Código strict mode e código não-strict mode podem coexistir, então scripts podem optar pelo strict mode incrementalmente.

O strict mode faz várias mudanças nas semânticas normais do JavaScript. Primeiro, o strict mode elimina alguns erros silenciosos do JavaScript fazendo-os lançar exceções. Segundo, o strict mode evita equívocos que dificultam que motores JavaScript realizem otimizações: código strict mode pode às vezes ser feito para executar mais rápido que código idêntico não-strict mode. Terceiro, strict mode proíbe algumas sintaxes que provavelmente serão definidas em versões futuras do ECMAScript.

Veja transitioning to strict mode (en-US) se você quer mudar seu código para funcionar na variante restrita do JavaScript.

Invocando strict mode
---------------------

Strict mode se aplica a *scripts* inteiros ou *funções individuais*. Ele não se aplica a declarações de bloco fechadas em chaves `{}`; tentar aplicá-lo a tais contextos não faz nada. Código `eval`, código `Function`, atributos *event handlers*, strings passadas para `setTimeout` (en-US) e coisas do tipo são scripts inteiros, e invocar strict mode neles funciona como esperado.

### Strict mode para scripts

Para invocar strict mode para um script inteiro, coloque *exatamente* a declaração `"use strict";` (ou `'use strict';`) antes de qualquer outra declaração.

```js
// Sintaxe strict mode para todo o script
"use strict";
var v = "Oi! Eu sou um script strict mode!";
```

Essa sintaxe tem uma armadilha que já pegou um site grande: não é possível concatenar cegamente scripts não-conflitantes. Considere concatenar um script strict mode com um script não-strict mode: a concatenação inteira parece strict! O inverso também é verdade: não-strict mais strict parece não-strict. Concatenar scripts strict mode com outros é bom, e concatenar scripts não-strict mode é bom. Simplesmente concatenar scripts strict e não-strict é problemático. Portanto é recomendado que você ative strict mode função-por-função (pelo menos durante o período de transição).

Você também pode usar a abordagem de embrulhar o conteúdo inteiro de um script em uma função e fazer a função externa usar strict mode. Isto elimina o problema da concatenação, mas significa que você tem que exportar explicitamente quaisquer variáveis globais fora do escopo da função.

### Strict mode para funções

Da mesma forma, para invocar strict mode para uma função, coloque *exatamente* a declaração `"use strict";` (ou `'use strict';`) no corpo da função antes de qualquer outra declaração.

```js
function strict() {
  // Sintaxe strict mode a nível de função
  "use strict";
  function nested() {
    return "E eu também!";
  }
  return "Oi! Eu sou uma função strict mode! " + nested();
}
function notStrict() {
  return "Eu não sou strict.";
}
```

Mudanças no strict mode
-----------------------

Strict mode muda tanto a sintaxe quando o comportamento em tempo de execução. Mudanças geralmente se encaixam em uma destas categorias: mudanças que convertem equívocos em erros (como erros de sintaxe ou em tempo de execução), mudanças que simplificam como uma variável particular para um dado uso de um nome é computada, mudanças que simplificam `eval` e `arguments`, mudanças que facilitam JavaScript "seguro", e mudanças que antecipam a evolução futura do ECMAScript.

### Convertendo equívocos em erros

Strict mode transforma em erros alguns equívocos anteriormente aceitos. O JavaScript foi projetado para ser fácil para novos desenvolvedores, e algumas vezes ele dá semânticas de não-erros a operações que deveriam ser erros. Algumas vezes isso resolve o problema pontual, mas outras vezes cria problemas piores no futuro. Strict mode trata esses equívocos como erros para que sejam descobertos e consertados prontamente.

Primeiro, o strict mode impossibilita criar variáveis globais acidentalmente. Em JavaScript normal, cometer um erro de digitação ao digitar uma variável em uma atribuição cria uma nova propriedade no objeto global e continua a "funcionar" (embora falhas futuras sejam possíveis: provavelmente, em JavaScript moderno). Atribuições que acidentalmente criariam variáveis globais lançam exceções em vez disso no strict mode:

```js
"use strict";
// Assumindo que uma variável global variavelErrada existe
variavellErrada = 17; // esta linha lança ReferenceError por conta do
// erro de digitação da variável
```

Segundo, strict mode faz com que atribuições que outrora falhariam silenciosamente lançar uma exceção. Por exemplo, `NaN` é uma variável global não-atribuível. Em código normal, atribuir a `NaN` não faz nada; o desenvolvedor não recebe qualquer resposta de falha. No strict mode, atribuir a `NaN` lança uma exceção. Qualquer atribuição que falha silenciosamente em código normal (atribuir a uma propriedade não-atribuível, atribuir a uma propriedade getter-only, atribuir a uma propriedade de um objeto não-extensível) lançarão exceções em strict mode:

```js
"use strict";

// Atribuir a uma propriedade não-atribuível
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // lança TypeError

// Atribuir a uma propriedade getter-only
var obj2 = {
  get x() {
    return 17;
  },
};
obj2.x = 5; // lança TypeError

// Atribuir a uma nova propriedade de um objeto não-extensível
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // lança TypeError
```

Terceiro, strict mode faz com que tentativas de deletar propriedades não-deletáveis lancem exceções (onde anteriormente a tentativa simplesmente não faria efeito):

```js
"use strict";
delete Object.prototype; // lança TypeError
```

Quarto, strict mode anterior ao Gecko 34 requer que todas as propriedades nomeadas em um objeto literal sejam únicas. Código normal pode duplicar nomes de propriedades, sendo que a última ocorrência determina o valor da propriedade. Mas como apenas o último faz algo, a duplicação é meramente um vetor de bugs, se o código for modificado para mudar o valor da propriedade por outro meio que não modificando a última instância. Nomes de propriedades duplicados são erro de sintaxe em strict mode:

**Nota:** Não é mais o caso no ECMAScript 6 (Erro do Firefox 1041128).

```js
"use strict";
var o = { p: 1, p: 2 }; // !!! erro de sintaxe
```

Quinto, strict mode exige que nomes de parâmetros de função sejam únicos. Em código normal, o último argumento duplicado esconde argumentos anteriores com nome semelhante. Estes argumentos anteriores continuam disponíveis através de `arguments[i]`**,** portanto não são completamente inacessíveis. Entretanto, esta ocultação faz pouco sentido e provavelmente é indesejável (pode esconder um erro de digitação, por exemplo), então em strict mode nomes de argumentos duplicados são erro de sintaxe:

```js
function sum(a, a, c) {
  // !!! erro de sintaxe
  "use strict";
  return a + b + c; // errado se este código executasse
}
```

Sexto, strict mode em ECMAScript 5 proíbe sintaxe octal. Sintaxe ocatal não é parte do ECMAScript 5, mas é suportado em todos os navegadores prefixando o número octal com um zero: `0644 === 420` e `"\045" === "%"`. No ECMAScript 6, número octal é suportado prefixando um número com "`0o`":

```js
var a = 0o10; // ES6: Octal
```

Novos desenvolvedores algumas vezes acham que um prefixo zero não tem significado semântico, então eles o utilizam como mecanismo de alinhamento — mas isso muda o significado do número! Sintaxe octal é raramente útil e pode ser usada equivocadamente, então o strict mode torna octal erro de sintaxe:

```js
"use strict";
var sum =
  015 + // !!! erro de sintaxe
  197 +
  142;
```

Sétimo, strict mode em ECMAScript 6 proíbe definir propriedades em valores primitivos. Sem strict mode, definir uma propriedade é simplesmente ignorado; com strict mode, no entanto, um `TypeError` é lançado.

```js
(function () {
  "use strict";

  false.true = ""; // TypeError
  (14).navegandoPara = "casa"; // TypeError
  "com".voce = "distante"; // TypeError
})();
```

### Simplificando usos de variáveis

Strict mode simplifica como nomes de variáveis se mapeiam a definições de variáveis particulares no código. Muitas otimizações de compiladores dependem da habilidade de dizer que variável *X* está guardada *naquele* local; isto é crítico para otimizar completamente o código JavaScript. JavaScript às vezes torna este mapeamento básico de nome para definição de variável no código impossível de executar até o tempo de execução. Strict mode remove a maioria dos casos onde isso acontece, então o compilador pode otimizar melhor código strict mode.

Primeiro, strict mode proíbe `with`. O problema com `with` é que qualquer nome dentro do block pode mapear tanto para uma propriedade do objeto passado quanto para uma variável no escopo envolvente (ou até global), em tempo de execução: é impossível saber qual de antemão. Strict mode torna `with` um erro de sintaxe, então não há chance de um nome em um `with` referir-re a uma localização deconhecida em tempo de execução:

```js
"use strict";
var x = 17;
with (obj) {
  // !!! erro de sintaxe
  // Se isto não fosse strict mode, isso seria var x ou obj.x?
  // No geral, é impossível saber sem executar o código, então
  // o nome não pode ser otimizado.
  x;
}
```

A alternativa simples de atribuir o objeto a uma variável de nome curto, e então acessar a propriedade correspondente naquela variável, está pronta para substituir `with`.

Segundo, eval de código strict mode não introduz novas variáves no escopo envolvente. Em código normal, `eval("var x;")` introduz uma variável `x` na função envolvente ou no escopo global. Isto significa que, no geral, em uma função que contém uma chamada para `eval`, todo nome que não se refere a um argumento ou variável local deve ser mapeado para uma definição particular em tempo de execução (porque aquele `eval` pode ter introduzido uma nova variável que esconderia a variável externa). No strict mode, `eval` cria variáveis apenas para o código sendo avaliado, portanto `eval` não pode afetar se um nome se refere a uma variável externa ou alguma variável local:

```js
var x = 17;
var evalX = eval("'use strict'; var x = 42; x");
console.assert(x === 17);
console.assert(evalX === 42);
```

Relacionadamente, se a função `eval` for invocada por uma expressão da forma `eval(...)` em código strict mode, o código será avaliado como código strict mode. O código pode invocar strict code explicitamente, mas não é necessário.

```js
function strict1(str) {
  "use strict";
  return eval(str); // str será tratado como código strict mode
}
function strict2(f, str) {
  "use strict";
  return f(str); // não é eval(...): str é strict se e
  // somente se invocar strict mode
}
function nonstrict(str) {
  return eval(str); // str é strict se e somente se
  // invocar strict mode
}

strict1("'Código strict mode!'");
strict1("'use strict'; 'Código strict mode!'");
strict2(eval, "'Código não-strict.'");
strict2(eval, "'use strict'; 'Código strict mode!'");
nonstrict("'Código não-strict.'");
nonstrict("'use strict'; 'Código strict mode!'");
```

Portanto nomes em código `eval` de strict mode se comportam da mesma forma que nomes em código strict mode que não estão sendo avaliados como resultado de `eval`.

Terceiro, strict mode proíbe deletar nomes simples. `delete name` em strict mode é erro de sintaxe:

```js
"use strict";

var x;
delete x; // !!! erro de sintaxe

eval("var y; delete y;"); // !!! erro de sintaxe
```

### Tornando `eval` e `arguments` mais simples

Strict mode torna `arguments` e `eval` menos estranhamente mágicos. Ambos envolvem uma quantidade considerável de comportamento mágico em código normal: `eval` para adicionar ou remover *bindings* e para mudar valores de *bindings*, e `arguments` com suas propriedades indexadas como *alias* de argumentos nomeados. Strict mode dá grandes passos na direção de tratar `eval` e `arguments` como palavras-chave, embora reparos completos não venham até uma futura edição do ECMAScript.

Primeiro, os nomes `eval` e `arguments` não podem ser vinculados ou atribuídos na sintaxe da linguagem. Todas as tentativas são erros de sintaxe:

```js
"use strict";
eval = 17;
arguments++;
++eval;
var obj = { set p(arguments) {} };
var eval;
try {
} catch (arguments) {}
function x(eval) {}
function arguments() {}
var y = function eval() {};
var f = new Function("arguments", "'use strict'; return 17;");
```

Segundo, código strict mode não faz *alias* para propriedades de objetos `arguments` criados dentro de si. Em código normal dentro de uma função cujo primeiro argumento é `arg`, definir `arg` também define `arguments[0]`, e vice-versa (a menos que nenhum argumento seja fornecido ou `arguments[0]` seja deletado). Objetos `arguments` para funções strict mode armazenam os argumentos originais quando a função é invocada. `arguments[i]` não rastreia o valor do argumento nomeado correspondente, nem um argumento nomeado rastreia o valor do `arguments[i]` correspondente.

```js
function f(a) {
  "use strict";
  a = 42;
  return [a, arguments[0]];
}
var pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);
```

Terceiro, `arguments.callee` não é mais suportado. Em código normal, `arguments.callee` se refere à função envolvente. Esse caso de uso é frágil: apenas nomeie a função envolvente! Além disso, `arguments.callee` prejudica substancialmente otimizações como tornar funções *inline* porque deve ser possível fornecer uma referência à função não-*inline* se `arguments.callee` for acessado. `arguments.callee` para funções strict mode é uma propriedade não-deletável que lança exceção quando atribuída ou recuperada:

```js
"use strict";
var f = function () {
  return arguments.callee;
};
f(); // lança TypeError
```

### Tornando JavaScript "seguro"

Strict mode torna mais fácil escrever JavaScript "seguro". Alguns websites agora oferecem formas de escrever JavaScript que será executado pelo website *em nome de outros usuários*. JavaScript nos navegadores pode acessar informações privadas do usuário, então tal JavaScript deve ser parcialmente transformado antes de executado, para barrar acesso a funcionalidades proibidas. A flexibilidade do JavaScript torna isso efetivamente impossível sem várias verificações em tempo de execução. Algumas funções da linguagem são tão pervasivas que fazer verificações em tempo de execução tem um custo de desempenho considerável. Alguns ajustes do strict mode, mais a exigência de que o JavaScript submetido por usuários seja código strict mode e invocá-lo de uma certa maneira, reduz substancialmente a necessidade de realizar verificações em tempo de execução.

Primeiro, o valor passado como `this` para uma função em strict mode não é forçado a ser um objeto (entenda-se "encaixotamento"). Para uma função normal, `this` é sempre um objeto: seja o objeto fornecido se chamado com um `this` cujo valor é um objeto; o valor, encaixotado, se chamado com um `this` Boolean, string ou número; ou o objeto global se chamado com um `this` `undefined` ou `null`. Use `call`, `apply`, ou `bind` para especificar um determinado `this`. O encaixotamento automático não apenas é um custo de desempenho, como também expor o objeto global em navegadores é um risco de segurança, porque o objeto global oferece acesso a funcionalidades que ambientes JavaScript "seguros" devem restringir. Assim, para uma função strict mode, o `this` especificado não é encaixotado em um objeto, e se não especificado, `this` será `undefined`:

```js
"use strict";
function fun() {
  return this;
}
console.assert(fun() === undefined);
console.assert(fun.call(2) === 2);
console.assert(fun.apply(null) === null);
console.assert(fun.call(undefined) === undefined);
console.assert(fun.bind(true)() === true);
```

Isso significa, além de outras coisas, que em navegadores não é mais possíveis referenciar o objeto `window` através de `this` dentro de uma função strict mode.

Segundo, em strict mode não é mais possível "caminhar" a pilha JavaScript via extensões do ECMAScript comumente implementadas. Em código normal com essas extensões, quando uma funçao `fun` está no meio de ser chamada, `fun.caller` é a função que chamou `fun` mais recentemente, e `fun.arguments` é o `arguments` para aquela invocação de `fun`. Ambas as extensões são problemáticas para JavaScript "seguro" porque permitem que código "seguro" acesse funções "privilegiadas" e seus argumentos (potencialmente inseguros). Se `fun` estiver em strict mode, tanto `fun.caller` quando `fun.arguments` são propriedades não-deletáveis que lançam exceção quando definidas ou recuperadas:

```js
function restrita() {
  "use strict";
  restrita.caller; // lança TypeError
  restrita.arguments; // lança TypeError
}
function invocadorPrivilegiado() {
  return restrita();
}
invocadorPrivilegiado();
```

Terceiro, `arguments` para funções strict mode não oferecem mais acesso às variáveis da chamada de função correspondente. Em algumas implementações antigas do ECMAScript, `arguments.caller` era um objeto cujas propriedades faziam *alias* de variáveis naquela função. Isso é um risco de segurança porque quebra a habilidade de esconder valores privilegiados via abstração de função; isso também exclui a maioria das otimizações. Por essas razões, nenhum navegador moderno implementa isso. Ainda assim, por causa de sua funcionalidade histórica, `arguments.caller` para uma função strict mode também é uma propriedade não-deletável que lança exceção quando definida ou recuperada:

```js
"use strict";
function fun(a, b) {
  "use strict";
  var v = 12;
  return arguments.caller; // lança TypeError
}
fun(1, 2); // não expõe v (or a or b)
```

### Pavimentando o caminho para versões futuras do ECMAScript

Versões futuras do ECMAScript provavelmente introduzirão nova sintaxe, e o strict mode no ECMAScript 5 aplica algumas restrições para facilitar essa transição. Será mais fácil fazer algumas mudanças se as fundações dessas mudanças forem proibidas no strict mode.

Primeiro, no strict mode, uma pequena lista de identificadores tornam-se palavras-chave reservadas. Estas palavras são `implements`, `interface`, `let`, `package`, `private`, `protected`, `public`, `static` e `yield`. Em strict mode, portanto, você não pode nomear ou usar variáveis ou argumentos com esses nomes.

```js
function package(protected) {
  // !!!
  "use strict";
  var implements; // !!!

  // !!!
  interface: while (true) {
    break interface; // !!!
  }

  function private() {} // !!!
}
function fun(static) {
  "use strict";
} // !!!
```

Duas ressalvas específicas à Mozilla: primeiro, se seu código for JavaScript 1.7 ou superior (por exemplo em código chrome ou usando o `<script type="">` correto) e for strict mode, `let` e `yield` têm a funcionaldade que eles tiveram desde que essas palavras-chave foram introduzidas pela primeira vez. Mas código strict mode na web, carregado com `<script src="">` ou `<script>...</script>`, não serão capazes de usar `let`/`yield` como identificadores. Segundo, enquanto o ES5 reserva incondicionalmente as palavras `class`, `enum`, `export`, `extends`, `import` e `super`, a Mozilla reservava-as apenas em strict mode antes do Firefox 5.

Segundo, strict mode proíbe declaração de funções fora do nível superior de um script ou função. Em código normal em navegadores, declarações de funções são permitidas "em todo lugar". *Isso não é parte do ES5 (nem do ES3)!* É uma extensão com semânticas incompatíveis em diferentes navegadores. Edições futuras do ECMAScript promissoramente especificarão novas semânticas para declarações de funções fora do nível superior de um script ou função. Proibir tais declarações de funções em strict mode "limpa a mesa" para especificação em uma *release* futura do ECMAScript:

```js
"use strict";
if (true) {
  function f() {} // !!! erro de sintaxe
  f();
}

for (var i = 0; i < 5; i++) {
  function f2() {} // !!! erro de sintaxe
  f2();
}

function baz() {
  // correto
  function eit() {} // erro de sintaxe
}
```

Essa proibição não é adequada ao strict mode porque tais declarações de função são uma extensão de ES5 básico. Mas é a recomendação do comitê do ECMAScript e os navegadores a implementarão.

Strict mode em navegadores
--------------------------

Os principais navegadores agora implementam strict mode. Entretanto, não dependa deles cegamente já que ainda há várias versões de navegadores utilizadas por aí que têm apenas suporte parcial ao strict mode ou que não suportam de forma alguma (ex.: Internet Explorer abaixo da versão 10!). *Strict mode muda semântica*. Depender dessas mudanças causará equívocos e erros em navegadores que não implementam strict mode. Tenha cautela ao usar strict mode e gere confiança no strict mode com testes de funcionalidades que verificam se partes relevantes do strict mode estão implementadas. Finalmente, certifique-se de *testar seu código em navegadores que suportam e não suportam strict mode.* Se você testar apenas em navegadores que não suportam strict mode, você provavelmente terá problemas em navegadores que suportam e vice-versa.

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

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

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

* Where's Walden? » New ES5 strict mode support: now with poison pills!
* Where's Walden? » New ES5 strict mode requirement: function statements not at top level of a program or function are prohibited
* Where's Walden? » New ES5 strict mode support: new vars created by strict mode eval code are local to that code only
* JavaScript "use strict" tutorial for beginners.
* John Resig - ECMAScript 5 Strict Mode, JSON, and More
* ECMA-262-5 in detail. Chapter 2. Strict Mode.
* Strict mode compatibility table
* Transitioning to strict mode (en-US)


Operadores - JavaScript

Operadores
==========

Este capítulo documenta todos os operadores, expressões e keywords da linguagem JavaScript .

Expressões e operadores por categoria
-------------------------------------

Para uma lista alfabética ver a barra lateral à esquerda.

### Expressões primárias

Palavras-chave e expressões básicas em JavaScript.

`this`

A palavra-chave `this` refere-se ao contexto de execução da função.

`function`

A palavra-chave `function` define uma função.

Experimental `class`

A palavra-chave `class` define uma classe.

Experimental `function*`

A palavra-chave `function*` define um gerador de função.

Experimental `yield`

Pausa e retorma uma função de gerador

Experimental `yield*`

Delegar a outra função gerador ou objeto iterável.

`[]`

Array initializer/literal syntax.

`{}`

Object initializer/literal syntax.

`/ab+c/i`

Regular expression literal syntax.

Experimental `[for (x of y) x]` (en-US)

Array comprehensions.

Experimental `(for (x of y) y)` (en-US)

Generator comprehensions.

`( )`

Grouping operator.

### Left-hand-side expressions

Left values are the destination of an assignment.

Property accessors

 Member operators provide access to a property or method of an object
 (`object.property` and `object["property"]`).

`new`

The `new` operator creates an instance of a constructor.

Experimental `super`

The `super` keyword calls the parent constructor.

Experimental `...obj` (en-US)

The spread operator allows an expression to be expanded in places where multiple arguments (for function calls) or multiple elements (for array literals) are expected.

### Incremento e decremento

Operadores sufixo/prefixo para incremento e sufixo/prefixo para decremento.

`A++` (en-US)

Operador sufixo para incremento.

`A--` (en-US)

Operador sufixo para decremento.

`++A` (en-US)

Operador prefixo para incremento.

`--A` (en-US)

Operador prefixo para decremento.

### Unary operators

A unary operation is operation with only one operand.

`delete` (en-US)

The `delete` operator deletes a property from an object.

`void`

The `void` operator discards an expression's return value.

`typeof`

The `typeof` operator determines the type of a given object.

`+` (en-US)

The unary plus operator converts its operand to Number type.

`-` (en-US)

The unary negation operator converts its operand to Number type and then negates it.

`~` (en-US)

Bitwise NOT operator.

`!` (en-US)

Logical NOT operator.

### Operadores aritméticos

Arithmetic operators take numerical values (either literals or variables) as their operands and return a single numerical value.

`+` (en-US)

Operador de soma.

`-` (en-US)

Operador de subtração.

`/` (en-US)

Operador de divisão.

`*` (en-US)

Operador de multiplicação.

`%` (en-US)

Remainder operator.

### Operadores relacionais

A comparison operator compares its operands and returns a `Boolean` value based on whether the comparison is true.

`in`

The `in` operator determines whether an object has a given property.

`instanceof`

The `instanceof` operator determines whether an object is an instance of another object.

`<` (en-US)

Operador "menor que".

`>` (en-US)

Operador "maior que".

`<=` (en-US)

Operador "menor ou igual que".

`>=` (en-US)

Operador "maior ou igual que".

### Operadores de igualdade

O resultador de um operador de igualdade é do tipo `Booleano` baseado que a comparação seja verdadeira.

`==` (en-US)

Operadores de igualdade.

`!=` (en-US)

Inequality operator.

`===` (en-US)

Identity operator.

`!==` (en-US)

Nonidentity operator.

### Bitwise shift operators

Operations to shift all bits of the operand.

`<<` (en-US)

Bitwise left shift operator.

`>>` (en-US)

Bitwise right shift operator.

`>>>` (en-US)

Bitwise unsigned right shift operator.

### Binary bitwise operators

Bitwise operators treat their operands as a set of 32 bits (zeros and ones) and return standard JavaScript numerical values.

`&` (en-US)

Bitwise AND.

`|` (en-US)

Bitwise OR.

`^` (en-US)

Bitwise XOR.

### Operadores Lógicos Binários

Operadores lógicos são normalmente usados com boolean (logical) valores, e quando eles são, eles retornam um valor Boolean.

`&&` (en-US)

AND.

`||` (en-US)

OR.

### Operador de Condicional (ternário)

`(condition ? ifTrue : ifFalse)`

O operador condicional retorna um dos dois valores baseado no valor lógico da condição.

### Assignment operators

An assignment operator assigns a value to its left operand based on the value of its right operand.

`=` (en-US)

Assignment operator.

`*=` (en-US)

Multiplication assignment.

`/=` (en-US)

Division assignment.

`%=` (en-US)

Remainder assignment.

`+=` (en-US)

Addition assignment.

`-=` (en-US)

Subtraction assignment

`<<=` (en-US)

Left shift assignment.

`>>=` (en-US)

Right shift assignment.

`>>>=` (en-US)

Unsigned right shift assignment.

`&=` (en-US)

Bitwise AND assignment.

`^=` (en-US)

Bitwise XOR assignment.

`|=` (en-US)

Bitwise OR assignment.

Experimental
 `[a, b] = [1, 2]`

Experimental
 `{a, b} = {a:1, b:2}`

Destructuring assignment allows you to assign the properties of an array or object to variables using syntax that looks similar to array or object literals.

### Comma operator

`,`

The comma operator allows multiple expressions to be evaluated in a single statement and returns the result of the last expression.

### Non-standard features

Non-standard Legacy generator function (en-US)

The `function` keyword can be used to define a legacy generator function inside an expression. To make the function a legacy generator, the function body should contains at least one `yield` expression.

Non-standard Expression closures

The expression closure syntax is a shorthand for writing simple function.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-addition-operator-plus |
| ECMAScript Language Specification # sec-assignment-operators |
| ECMAScript Language Specification # sec-async-function-definitions |
| ECMAScript Language Specification # sec-async-generator-function-definitions |
| ECMAScript Language Specification # prod-BitwiseANDExpression |
| ECMAScript Language Specification # sec-bitwise-not-operator |
| ECMAScript Language Specification # prod-BitwiseORExpression |
| ECMAScript Language Specification # prod-BitwiseXORExpression |
| ECMAScript Language Specification # sec-class-definitions |
| ECMAScript Language Specification # sec-comma-operator |
| ECMAScript Language Specification # sec-conditional-operator |
| ECMAScript Language Specification # sec-postfix-decrement-operator |
| ECMAScript Language Specification # sec-delete-operator |
| ECMAScript Language Specification # sec-destructuring-assignment |
| ECMAScript Language Specification # sec-destructuring-binding-patterns |
| ECMAScript Language Specification # sec-multiplicative-operators |
| ECMAScript Language Specification # sec-equality-operators |
| ECMAScript Language Specification # sec-exp-operator |
| ECMAScript Language Specification # sec-function-definitions |
| ECMAScript Language Specification # sec-generator-function-definitions |
| ECMAScript Language Specification # sec-relational-operators |
| ECMAScript Language Specification # sec-grouping-operator |
| ECMAScript Language Specification # sec-import-calls |
| ECMAScript Language Specification # prod-ImportMeta |
| HTML Standard # hostgetimportmetaproperties |
| ECMAScript Language Specification # sec-postfix-increment-operator |
| ECMAScript Language Specification # sec-left-shift-operator |
| ECMAScript Language Specification # prod-LogicalANDExpression |
| ECMAScript Language Specification # sec-logical-not-operator |
| ECMAScript Language Specification # prod-LogicalORExpression |
| ECMAScript Language Specification # sec-new-operator |
| ECMAScript Language Specification # sec-built-in-function-objects |
| ECMAScript Language Specification # sec-null-value |
| ECMAScript Language Specification # prod-CoalesceExpression |
| ECMAScript Language Specification # sec-object-initializer |
| ECMAScript Language Specification # prod-OptionalExpression |
| ECMAScript Language Specification # sec-property-accessors |
| ECMAScript Language Specification # sec-signed-right-shift-operator |
| ECMAScript Language Specification # prod-SpreadElement |
| ECMAScript Language Specification # prod-ArgumentList |
| ECMAScript Language Specification # prod-PropertyDefinition |
| ECMAScript Language Specification # sec-subtraction-operator-minus |
| ECMAScript Language Specification # sec-super-keyword |
| ECMAScript Language Specification # sec-this-keyword |
| ECMAScript Language Specification # sec-typeof-operator |
| ECMAScript Language Specification # sec-unary-minus-operator |
| ECMAScript Language Specification # sec-unary-plus-operator |
| ECMAScript Language Specification # sec-unsigned-right-shift-operator |
| ECMAScript Language Specification # sec-void-operator |
| ECMAScript Language Specification # prod-YieldExpression |
| ECMAScript Language Specification # sec-generator-function-definitions-runtime-semantics-evaluation |

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

* Operator precedence


Objetos Globais - JavaScript

Objetos Globais
===============

Resumo
------

Este capítulo documenta todos os objetos nativos do JavaScript padrão, assim como seus métodos e propriedades.

O termo "objetos globais" (ou objetos nativos por padrão) aqui não deve ser confundido com o de **objeto global**. Aqui, objetos globais se referem aos **objetos no escopo global** (somente se o modo estrito/*strict mode* do ECMAScript 5 não for usado; Nesse caso retorna `undefined`). O **objeto global** pode ser acessado usando o operador `this` no escopo global. De fato, o escopo global **consiste em** propriedades do objeto global, incluindo propriedades herdadas, se houver.

Outros objetos no escopo global também são criados pelo desenvolvedor ou fornecido pela aplicação *host*. Os objetos disponíveis no *host* no contexto do browser são documentados na API reference (en-US). Para maiores informações sobre as distinções entre DOM (en-US) e core JavaScript, veja visão geral das tecnologias JavaScript.

Objetos padrão (por categoria)
------------------------------

### Propriedades de valor

Propriedades globais retornam um valor simples; eles não tem propriedades ou métodos.

* `Infinity`
* `NaN`
* `undefined`
* `null` literal
### Propriedades de função

Estas funções globais —funções que são chamadas globalmente ao invés de em um objeto—retornam diretamente seus resultados a quem chama.

* `eval()`
* `uneval()`
Non-standard
* `isFinite()`
* `isNaN()`
* `parseFloat()`
* `parseInt()`
* `decodeURI()`
* `decodeURIComponent()`
* `encodeURI()`
* `encodeURIComponent()`
* `escape()`
Deprecated
* `unescape()`
Deprecated
### Objetos fundamentais

Estes são objetos básicos e fundamentais nos quais todos os outros objetos são baseados. Isso inclui objetos que representam objetos genéricos, funções e erros.

* `Object`
* `Function`
* `Boolean`
* `Symbol`
Experimental
* `Error`
* `EvalError`
* `InternalError`
* `RangeError` (en-US)
* `ReferenceError`
* `StopIteration`
* `SyntaxError` (en-US)
* `TypeError`
* `URIError` (en-US)
### Números e datas

Estes são objetos base para a representação de números, datas e cálculos matemáticos.

* `Number`
* `Math`
* `Date`
### Processamento de texto

Estes objetos representam strings e manipulam as mesmas.

* `String`
* `RegExp`
### Coleções indexadas

Estes objetos representam coleções de dados que são ordenados pelo valor de um índice. Isso inclui arrays (tipados) e arrays baseados em outros construtores, como `[]`.

* `Array`
* `Float32Array` (en-US)
* `Float64Array` (en-US)
* `Int16Array` (en-US)
* `Int32Array` (en-US)
* `Int8Array` (en-US)
* `Uint16Array` (en-US)
* `Uint32Array` (en-US)
* `Uint8Array` (en-US)
* `Uint8ClampedArray` (en-US)
* `ParallelArray`
Non-standard
### Coleções chaveadas

Estes objetos representam coleções que usam chaves; estas contém elementos que são iteráveis na ordem de inserção.

* `Map`
Experimental
* `Set`
Experimental
* `WeakMap`
Experimental
* `WeakSet`
Experimental
### Dados estruturados

Estes objetos representam e interagem com buffers de dados estruturados e dados codificados usando JavaScript Object Notation (JSON).

* `ArrayBuffer`
* `DataView`
* `JSON`
### Controle de abstrações de objetos

* `Promise`
Experimental
* `Generator`
Experimental
* `GeneratorFunction` (en-US)
Experimental
### Reflexão (reflection)

* `Reflect`
Experimental
* `Proxy`
Experimental
### Internacionalização

Adições ao core do ECMAScript para funcionalidades sensíveis à linguagem.

* `Intl`
* `Intl.Collator` (en-US)
* `Intl.DateTimeFormat` (en-US)
* `Intl.NumberFormat`
### Objetos não-padrão

* `Iterator` (en-US)
Non-standard
* `ParallelArray`
Non-standard
* `StopIteration`
Non-standard
### Outros

* `arguments` (en-US)


Classes - JavaScript

Classes
=======

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
Classes em JavaScript são introduzidas no ECMAScript 2015 e são simplificações da linguagem para as heranças baseadas nos protótipos. A sintaxe para classes **não** introduz um novo modelo de herança de orientação a objetos em JavaScript. Classes em JavaScript provêm uma maneira mais simples e clara de criar objetos e lidar com herança.

Definindo classes
-----------------

As Classes são, de fato, "funções especiais", e, assim como você pode definir "function expressions" e "function declarations", a sintaxe de uma classe possui dois componentes: "class expressions" e "class declarations".

### Declarando classes

Uma maneira de definir uma classe é usando uma declaração de classe. Para declarar uma classe, você deve usar a palavra-chave `class` seguida pelo nome da classe (aqui "Retangulo").

```js
class Retangulo {
  constructor(altura, largura) {
    this.altura = altura;
    this.largura = largura;
  }
}
```

#### Uso antes da declaração (Hoisting - Tradução Literal: Lançamento)

Uma diferença importante entre **declarações de funções** das **declarações de classes**, é que declararações de funções são hoisted e declarações de classes não são. Primeiramente deve declarar sua classe para só então acessá-la, pois do contrário o código a seguir irá lançar uma exceção: `ReferenceError`:

```js
const p = new Retangulo(); // Erro de referência (ReferenceError)

class Retangulo {}
```

### Expressões de Classes

Uma **Expressão de Classe** (class expression) é outra forma para definir classes. Expressões de Classes podem possuir nomes ou não (anônimas). O nome dado para uma expressão de classe é local ao corpo da classe.

```js
// sem nome
let Retangulo = class {
  constructor(altura, largura) {
    this.altura = altura;
    this.largura = largura;
  }
};

// nomeada
let Retangulo = class Retangulo {
  constructor(altura, largura) {
    this.altura = altura;
    this.largura = largura;
  }
};
```

**Nota:** As **expressões de classe** também sofrem com o mesmo problema de hoisted mencionados em **declarações** de classe.

Corpo de uma classe e definições de métodos
-------------------------------------------

O corpo de uma classe é a parte que está entre chaves `{}`. É aí onde você define os membros da classe, como os métodos, ou os construtores.

### Modo Estrito (strict mode)

Os corpos das Declarações de Classes e das Expressões de Classes são executados em modo estrito.

### Construtor

O método `constructor` é um tipo especial de método para criar e iniciar um objeto criado pela classe. Só pode existir um método especial com o nome "constructor" dentro da classe. Um erro de sintaxe `SyntaxError` (en-US) será lançado se a classe possui mais do que uma ocorrência do método `constructor`.

Um construtor pode usar a palavra-chave `super` para chamar o construtor de uma classe pai.

### Métodos Protótipos

Veja também definições de métodos (method definitions).

```js
class Retangulo {
  constructor(altura, largura) {
    this.altura = altura;
    this.largura = largura;
  }
  //Getter
  get area() {
    return this.calculaArea();
  }

  calculaArea() {
    return this.altura \* this.largura;
  }
}

const quadrado = new Retangulo(10, 10);

console.log(quadrado.area);
```

### Métodos estáticos

A palavra-chave `static` define um método estático de uma classe. Métodos estáticos são chamados sem a instanciação da sua classe e não podem ser chamados quando a classe é instanciada. Métodos estáticos são geralmente usados para criar funções de utilidades por uma aplicação.

```js
class Ponto {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  static distancia(a, b) {
    const dx = a.x - b.x;
    const dy = a.y - b.y;

    return Math.hypot(dx, dy);
  }
}

const p1 = new Ponto(5, 5);
const p2 = new Ponto(10, 10);

p1.distancia; //undefined
p2.distancia; //undefined

console.log(Ponto.distancia(p1, p2));
```

### Empacotando com protótipos e métodos estáticos

Quando um método estático ou protótipo é chamado sem um objeto "this" configurado (ou com "this" como boolean, string, number, undefined ou null), então o valor "this" será **`undefined`** dentro da função chamada. Autoboxing não vai acontecer. O comportamento será o mesmo se escrevemos o código no modo não-estrito.

```js
class Animal {
  falar() {
    return this;
  }
  static comer() {
    return this;
  }
}

let obj = new Animal();
obj.falar(); // Animal {}
let falar = obj.falar;
falar(); // undefined

Animal.comer(); // class Animal
let comer = Animal.comer;
comer(); // undefined
```

Se escrevemos o código acima usando classes baseadas em função tradicional, então o autoboxing acontecerá com base no valor de "this" para o qual a função foi chamada.

```js
function Animal() {}

Animal.prototype.falar = function () {
  return this;
};

Animal.comer = function () {
  return this;
};

let obj = new Animal();
let falar = obj.falar;
falar(); // objeto global

let comer = Animal.comer;
comer(); // objeto global
```

### Propriedades de instância

Propriedades de instâncias devem ser definidas dentro dos métodos da classe:
```

class Retangulo {
  constructor(altura, largura) {
    this.altura = altura;
    this.largura = largura;
  }
}
```

Propriedades de dados estáticos e propriedades de dados prototipados (prototype) devem ser definidos fora da declaração do corpo da classe.
```

Retangulo.larguraEstatico = 20;
Retangulo.prototype.larguraPrototipagem = 25;
```

Sub classes com o `extends`
---------------------------

A palavra-chave `extends` é usada em uma *declaração de classe*, ou em uma *expressão de classe* para criar uma classe como filha de uma outra classe.

```js
class Animal {
  constructor(nome) {
    this.nome = nome;
  }

  falar() {
    console.log(this.nome + " emite um barulho.");
  }
}

class Cachorro extends Animal {
  falar() {
    console.log(this.nome + " latidos.");
  }
}

let cachorro = new Cachorro("Mat");
cachorro.falar();
```

Se existir um contrutor nas subclasses, é necessário primeiro chamar super() antes de usar a keyword "this".

Também é possivel ampliar (extends) "classes" baseadas em funções tradicionais.

```js
function Animal(nome) {
  this.nome = nome;
}

Animal.prototype.falar = function () {
  console.log(this.nome + " faça barulho.");
};

class Cachorro extends Animal {
  falar() {
    console.log(this.nome + " lati.");
  }
}

let cachorro = new Cachorro("Mitzie");
cachorro.falar(); // Mitzie lati.
```

Note que classes não extendem objetos normais (não construíveis). Se você quer herdar de um objeto, é necessário utilizar `Object.setPrototypeOf()`:

```js
let Animal = {
  falar() {
    console.log(this.nome + " faça barulho.");
  },
};

class Cachorro {
  constructor(nome) {
    this.nome = nome;
  }
}

Object.setPrototypeOf(Cachorro.prototype, Animal);

let cachorro = new Cachorro("Mitzie");
cachorro.falar(); //Mitzie faça barulho.
```

Species
-------

Você pode querer retornar um objeto `Array` na sua classe `MinhaArray` derivada de array. O padrão Species permite a sobrescrita do construtor padrão.

Por exemplo, quando utilizando um método como `map()` que retorna o construtor padrão, você pode querer que esse método retorne um objeto `Array` ao invés do objeto `MinhaArray`. O `Symbol.species` te permite fazer isso:

```js
class MinhaArray extends Array {
  // Sobrescreve species para o construtor da classe pai Array
  static get [Symbol.species]() {
    return Array;
  }
}

let a = new MinhaArray(1, 2, 3);
let mapped = a.map((x) => x \* x);

console.log(mapped instanceof MyArray); // false
console.log(mapped instanceof Array); // true
```

Chamada da classe pai com `super`
---------------------------------

A palavra-chave (keyword) `super` é utilizada para chamar funções que pertencem ao pai do objeto.

```js
class Gato {
  constructor(nome) {
    this.nome = nome;
  }

  falar() {
    console.log(this.nome + " faça barulho.");
  }
}

class Leao extends Gato {
  falar() {
    super.falar();
    console.log(this.nome + " roars.");
  }
}

let leao = new Leao("Fuzzy");
leao.falar();

// Fuzzy faça barulho.
// Fuzzy roars.
```

Mix-ins
-------

Subclasses abstratas ou *mix-ins* são templates para classes. Uma classe do ECMAScript pode apenas ter uma classe pai, assim sendo, não é possível a classe ter herança múltipla.

Para se ter um comportamento similar ao de herança múltipla no ECMAScript usa-se mix-ins, uma forma de implementar mix-ins é usar um template de subclasse que é uma função que instancia uma classe base e retorna uma subclasse extendida desta classe base:

```js
class Humano {
  constructor(nome) {
    this.nome = nome;
  }
  andar() {
    return this.nome + " andou um passo";
  }
}

const HumanoFalante = (Base) =>
  class extends Base {
    falar() {
      return this.nome + " diz: olá mundo!";
    }
  };

const HumanoFalanteMixado = (Base) => class extends Base {};

const HumanoFinal = HumanoFalanteMixado(HumanoFalante(Humano));

const humano = new HumanoFinal("Bill Gates");

console.log(humano.andar());
console.log(humano.falar());
```

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.

Rodando com Scratchpad
----------------------

Uma classe não pode ser redefinida. Se você estiver rodando código com Scratchpad (Menu do Firefox Ferramentas > Web Developer > Scratchpad) e você acionar 'Run' a uma definição de uma classe com o mesmo nome duas vezes, você verá um confuso SyntaxError: redeclaration of let <class-name> (Erro de Sintaxe: redeclaração de let <nome-da-classe>).

 Para reacionar (re-run) uma definição, use o menu do Scratchpad em Execute > Reload and Run (Executar > Atualizar e Rodar).
 Por favor, vote no bug #1428672.

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

* Funções
* Declaração de `classes` (class declaration)
* Expressão de `classes` (class expression)
* `super`
* Blog post: "ES6 In Depth: Classes"


Funções - JavaScript

Funções
=======

De modo geral, função é um "subprograma" que pode ser *chamado* por código externo (ou interno no caso de recursão) à função. Assim como o programa em si, uma função é composta por uma sequência de instruções chamada *corpo da função*. Valores podem ser *passados* para uma função e ela vai *retornar* um valor.

Em JavaScript, funções são objetos de primeira classe, pois elas podem ter propriedades e métodos como qualquer outro objeto. O que as difere de outros objetos é que as funções podem ser chamados. Em resumo, elas são objetos `Function`.

Para mais exemplos e explicações, veja também o Guia de JavaScript sobre funções.

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

Toda função em JavaScript é um objeto `Function`. Veja `Function` para informação das propriedades e métodos dos objetos `Function`.

Funções não são como procedimentos (*procedure*). Uma função sempre retorna um valor, mas um procedimento pode ou não retornar um valor.

Para retornar um valor diferente do padrão, uma função deve ter uma instrução return que específica o valor a ser retornado. Uma função sem um `return` retornará um valor padrão. No caso de um método construtor chamado com a palavra reservada `new`, o valor padrão é o valor do parâmetro `this`. Para todas as outras funções, o valor padrão de retorno é `undefined`.

Os parâmetros de uma função são chamados de argumentos da função. Argumentos são passados para a função *por valor*. Se uma função muda o valor de um argumento, esta mudança não é refletida globalmente ou na chamada da função. Contudo, referência de objetos são valores também, e eles são especiais: se a função muda as propriedades do objeto referenciado, estas mudanças são visíveis fora da função, como é mostrado no exemplo a seguir:

```js
/\* Declare a função 'minhaFunção' \*/
function minhaFuncao(objeto) {
  objeto.marca = "Toyota";
}

/\*
 \* Declare a variável 'meucarro';
 \* crie e inicialize um novo Objeto;
 \* atribua referência para 'meucarro'
 \*/
var meucarro = {
  marca: "Honda",
  modelo: "Accord",
  ano: 1998,
};

/\* Exibe 'Honda' \*/
console.log(meucarro.marca);

/\* Passe a referência do objeto para a função \*/
minhaFuncao(meucarro);

/\*
 \* Exibe 'Toyota' como valor para a propriedade 'marca'
 \* do objeto, mudado pela função.
 \*/
console.log(meucarro.marca);
```

A palavra reservada `this` não se refere a função sendo executada no momento, então você deve referenciar um objeto `Function` pelo nome, mesmo dentro do corpo da função.

Definindo funções
-----------------

Há várias maneiras de definir funções:

### Declaração de função (Instrução `function`)

Há um sintaxe especial para declarar funções (veja Instrução function para detalhes):
```

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

`nome`

O nome da função.

`param`

O nome de um argumento a ser passado para a função.

`instruções`

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

### A expressão function (Operador `function`)

Uma expressão function é parecida com uma declaração function e tem até a mesma sintaxe (veja Operador function para detalhes):
```

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

`nome`

O nome da função. Pode ser omitido, e neste caso a função é conhecida como função anônima.

`param`

O nome de um argumento a ser passado para a função.

`instruções`

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

### O gerador de declaração de função (instrução `function*`)

**Nota:** Expressão Arrow function é uma tecnologia experimental, parte da proposta do ECMAScript 6, e ainda não é amplamente suportada pelos navegadores.

Uma expressão arrow function tem uma sintaxe curta e conecta seu valor lexicamente (veja arrow functions para mais detalhes):
```

([param] [, param]) => {
   instruções
}

param => expressão
```

`param`

O nome de um argumento. Quando não há argumentos deve ser indicado com o uso dos parênteses ( ). Para apenas um argumento os parênteses não são obrigatórios. (por exemplo `foo => 1`)

`instruções ou expressão`

Múltiplas instruções precisam ser envolvidas por chaves. Uma única expressão não requer chaves. A expressão também é implicitamente o valor de retorno dessa função.

### O construtor `Function`

**Nota:** O uso do construtor Function para criar funções não é recomendado uma vez que é requerido o corpo da função como string, o que pode impedir algumas otimizações por parte do motor JS e pode também causar outros problemas.

Como todos os outros objetos, objetos `Function` podem ser criados usando o operador new:
```

new Function (arg1, arg2, ... argN, corpoDaFuncao)
```

`arg1, arg2, ... argN`

Nenhum ou mais nomes para serem usados pela função como nomes formais de argumentos. Cada um deve ser uma string em conformidade com as regras para um identificador JavaScript válido ou uma lista com tais strings separadas por vírgula; por exemplo "x", "oValor", ou "a, b".

*corpoDaFuncao*

Uma string contento as instruções JavaScript correspondendo a definição da função.

Invocar o construtor Function como uma função (sem usar o operador new) the o mesmo efeito de invocá-lo como um construtor comum.

Parâmetros de Função
--------------------

**Nota:** Parâmetros Default e Rest são tecnologias experimentais, parte da proposta do ECMAScript 6, e ainda não são amplamente suportados pelos navegadores.

### Parâmetros Default

Parâmetro Default de função permite que parâmetros formais sejam inicializados com valores padrão se nenhum valor ou valor undefined é passado. Para mais detalhes, veja parâmetros default.

### Parâmetros Rest

A sintaxe do parâmetro rest permite representar um número indefinido de argumentos em forma de array. Para mais detalhes, veja parâmetros rest.

O objeto `arguments`
--------------------

Você pode referenciar aos argumentos da função dentro da função utilizando o objeto arguments. Veja arguments.

* `arguments` (en-US): Um objeto array-like contendo os argumentos passados para a função atualmente em execução.
* `arguments.callee` (en-US)
Deprecated
: A função atualmente em execução.
* `arguments.caller`: A função que invocou a função atualmente em execução.
* `arguments.length` (en-US): O número de argumentos passados para a função.
Definindo Métodos de Funções
----------------------------

### Funções Getter e setter

Você pode definir getters (métodos de acesso) and setters (métodos de alteração) em qualquer objeto interno padrão ou objeto definido pelo usuário que ofereça suporte à adição de novas propriedades. A sintaxe para definir getters e setters usa a sintaxe literal do objeto.

get

Vincula uma propriedade de objeto a uma função que será chamada quando essa propriedade é requisitada.

set

Vincula uma propriedade de objeto a uma função a ser chamada quando há uma tentativa de definir essa propriedade.

### Sintaxe dos métodos de funções

**Nota:** Definições de métodos são tecnologias experimentais, parte da proposta do ECMAScript 6, e ainda não são amplamente suportados pelos navegadores.

Começando com ECMAScript 6, você é capaz de definir métodos próprios em uma sintaxe mais curta, semelhante aos getters e setters. Veja method definitions para mais informações.

```js
var obj = {
  foo() {},
  bar() {},
};
```

`Function` constructor vs. function declaration vs. function expression
-----------------------------------------------------------------------

Compare o seguinte:

Uma função definida com `Function` *constructor* atribuída à variável `multiply`

```js
var multiply = new Function("x", "y", "return x \* y");
```

Uma *function expression* de uma função anônima atribuída à variável `multiply`

```js
var multiply = function (x, y) {
  return x \* y;
};
```

Uma *function expression* de uma função chamada `func_name` atribuída à variável `multiply`

```js
var multiply = function func\_name(x, y) {
  return x \* y;
};
```

### Diferenças

Todas fazem aproximadamente a mesma coisa, com algumas diferenças sutis:

Há uma distinção entre o nome da função e a variável à qual a função é atribuída. O nome da função não pode ser alterado, enquanto a variável à qual a função está atribuída pode ser reatribuída. O nome da função pode ser usado somente dentro do corpo da função. A tentativa de usá-lo fora do corpo da função resulta em um *error* (ou *undefined* se o nome da função foi declarado anteriormente por meio de uma declaração de variável). Por exemplo:

```js
var y = function x() {};
alert(x); // throws an error
```

O nome da função também aparece quando a função é serializada através do `método toString de Function()`.

Por outro lado, a variável à qual a função é atribuída é limitada somente pelo seu escopo, garantindo-se que ele inclui o escopo onde a função é declarada.

Como o quarto exemplo mostra, o nome da função pode ser diferente da variável à qual a função é atribuída. Eles não têm relação um com o outro. Uma declaração de função também cria uma variável com o mesmo nome da função. Assim, ao contrário daquelas definidas por expressões de função, funções definidas por declarações de função podem ser acessadas pelo seu nome no escopo onde elas foram definidas:

Uma função definida por '`new Function'` não possui um nome. Entretanto, na máquina de JavaScript SpiderMonkey, a forma serializada da função aparece como se ela tivesse o nome "anonymous". Por exemplo, `alert(new Function())` gera como saída:

```js
function anonymous() {}
```

Já que a função na realidade não possui um nome, `anonymous` não é uma variável que possa ser acessada dentro da função. Por exemplo, o código seguinte iria resultar em um erro:

```js
var foo = new Function("alert(anonymous);");
foo();
```

Ao contrário das funções definidas por expressões de função ou pelo construtor `Function`, uma função definida por uma declaração de função pode ser usada antes da declaração da função em si. Por exemplo:

```js
foo(); // alerts FOO!
function foo() {
  alert("FOO!");
}
```

Uma função definida por uma expressão de função herda o escopo atual. Isto é, a função forma um closure. Por outro lado, uma função definida por um construtor `Function` não herda qualquer escopo a não ser o escopo global (que todas as funções herdam).

Funções definidas por expressões de função e declarações de função são analisadas somente uma vez, enquanto aquelas definidas pelo construtor `Function` não são. Isto é, a string que forma o corpo da função, passada para o construtor `Function` precisa ser analisada toda vez que o construtor é chamado. Embora uma expressão de função crie um closure a cada vez, o corpo da função não é reanalisado, assim expressões de função ainda são mais rápidas do que "`new Function(...)`". Assim, o construtor `Function` deve geralmente ser evitado sempre que possível.

Deve ser notado, entretanto, que expressões de função e declarações de função aninhadas dentro de uma função gerada pela análise da string de um construtor `Function` não são analisadas repetidamente. Por exemplo:

```js
var foo = new Function(
  "var bar = 'FOO!';\nreturn(function() {\n\talert(bar);\n});",
)();
foo(); // O segmento "function() {\n\talert(bar);\n}" do corpo da função não é reanalisado.
```

Uma declaração de função é muito facilmente (e às vezes de forma não intencional) transformada em uma expressão de função. Uma declaração de função deixa de ser o que ela é nos casos em que:

* se torna parte de uma expressão; ou
* não é mais um "elemento fonte" de uma função ou do script em si. Um "elemento fonte" é uma instrução não aninhada no script ou no corpo de uma função:

```js
var x = 0; // elemento fonte
if (x == 0) {
  // elemento fonte
  x = 10; // não é um elemento fonte
  function boo() {} // não é um elemento fonte
}
function foo() {
  // elemento fonte
  var y = 20; // elemento fonte
  function bar() {} // elemento fonte
  while (y == 10) {
    // elemento fonte
    function blah() {} // não é um elemento fonte
    y++; // não é um elemento fonte
  }
}
```

### Examples

```js
// declaração de função
function foo() {}

// expressão de função
(function bar() {});

// expressão de função
x = function hello() {};

if (x) {
  // expressão de função
  function world() {}
}

// declaração de função
function a() {
  // declaração de função
  function b() {}
  if (0) {
    // expressão de função
    function c() {}
  }
}
```

Definindo uma função condicionalmente
-------------------------------------

As funções podem ser definidas condicionalmente usando instruções de função (uma extensão permitida para o padrão ECMA-262 Edição 3) ou o construtor 'Function'. Observe que essas instruções de funções não são mais permitidas no ES5 strinct. Além disso, esse recurso não funciona de forma consistente em navegadores, portanto, você não deve confiar nele.

No script a seguir, a função 'zero' nunca é definida e não pode ser chamada, porque 'if (0)' avalia sua condição como falso:

```js
if (0) {
  function zero() {
    document.writeln("Isso é zero.");
  }
}
```

If the script is changed so that the condition becomes '`if (1)`', function `zero` is defined.

Nota: Although this kind of function looks like a function declaration, it is actually an expression (or statement), since it is nested within another statement. See differences between function declarations and function expressions.

Nota: Some JavaScript engines, not including SpiderMonkey, incorrectly treat any function expression with a name as a function definition. This would lead to `zero` being defined, even with the always-false `if` condition. A safer way to define functions conditionally is to define the function anonymously and assign it to a variable:

```js
if (0) {
  var zero = function () {
    document.writeln("Aqui tem zero.");
  };
}
```

Exemplo
-------

### Exemplo: Retornando um número formatado

A função a seguir retorna uma sequência contendo a representação formatada de um número preenchido com zeros à esquerda.

```js
// Esta função retorna uma string preenchida com zeros à esquerda
function padZeros(num, totalLen) {
  var numStr = num.toString(); // Inicializar valor de retorno como string
  var numZeros = totalLen - numStr.length; // Calcular números de zeros
  for (var i = 1; i <= numZeros; i++) {
    // Preencher a quantidade de zeros
    numStr = "0" + numStr;
  }
  return numStr; // Retorna a string já preenchida
}
```

The following statements call the padZeros function.

```js
var resultado;
resultado = padZeros(42, 4); // retorno "0042"
resultado = padZeros(42, 2); // retorno "42"
resultado = padZeros(5, 4); // retorno "0005"
```

### Example: Determining whether a function exists

You can determine whether a function exists by using the `typeof` operator. In the following example, a test is peformed to determine if the `window` object has a property called `noFunc` that is a function. If so, it is used; otherwise some other action is taken.

```js
if ("function" == typeof window.noFunc) {
  // use noFunc()
} else {
  // do something else
}
```

Note that in the `if` test, a reference to `noFunc` is used—there are no brackets "()" after the function name so the actual function is not called.

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
-----------

* `Function` (en-US)
* `function` statement (en-US)
* `function` operator (en-US)


Deprecated and obsolete features - JavaScript

Deprecated and obsolete features
================================

Esta página lista funcionalidades do JavaScript que foram descontinuadas (ou seja, continuam disponíveis mas têm remoção planejada) e obsoletas (ou seja, não estão mais disponíveis).

*Funcionalidades* descontinuadas
--------------------------------

Estas *features* descontinuadas ainda podem ser usadas, mas com cautela, porque espera-se que sejam removidas por completo no futuro. Aconselha-se que remova-as do seu código.

### Propriedades RegExp

As propriedades a seguir foram descontinuadas. Isto não afeta o uso delas em replacement strings:

| Propriedade | Descrição |
| --- | --- |
| `$1-$9` (en-US) | Encontra *substrings* dentro de parênteses. **Atenção:** Usar estas propriedades pode resultar em problemas, porque extensões do navegador podem modifica-las. Evite-as! |
| `$_` (en-US) | Ver `input`. |
| `$*` (en-US) | Ver `multiline`. |
| `$&` (en-US) | Ver `lastMatch`. |
| `$+` (en-US) | Ver `lastParen`. |
| `$`` (en-US) | Ver `leftContext`. |
| `$'` (en-US) | Ver `rightContext`. |
| `input` (en-US) | A string encontrada por uma expressão regular. |
| `lastMatch` (en-US) | Os últimos caracteres encontrados. |
| `lastParen` (en-US) | A última *substring* entre parênteses que foi encontrada. |
| `leftContext` (en-US) | A penúltima *substring* encontrada. |
| `rightContext` (en-US) | A *substring* que segue a que foi encontrada por último. |

As propriedades a seguir pertencem a instâncias de um `RegExp`, não mais ao objeto `RegExp`:

| Propriedades | Descrição |
| --- | --- |
| `global` (en-US) | Determina se deve ou não testar a expressão regular com todas as combinações possíveis em uma *string* ou só com a primeira. |
| `ignoreCase` | Determina se deve ou não ignorar a capitalização ao tentar encontrar uma combinação em uma *string*. |
| `lastIndex` (en-US) | O índince que aponta o começo da próxima combinação. |
| `multiline` (en-US) | Determina se deve ou não procurar por *strings* em várias linhas diferentes. |
| `source` (en-US) | O texto do padrão. |

### Métodos RegExp

* O método `compile()` foi descontinuado.
* O método `valueOf` não é mais especializado para `RegExp`. Use `Object.valueOf()`.
### Propriedades de Função

* As propriedades `caller` e `arguments` foram descontinuadas, porque elas estouram o chamador de funções. Ao invés da propriedade *arguments*, deve-se usar o objeto `arguments` dentro dos fechamentos da função.
### Legacy generator

* `Legacy generator function statement` (en-US) e `Legacy generator function expression` (en-US) foram descontinuados. No lugar deles, use `function* statement` e `function* expression`.
* O `JS1.7/JS1.8 Array comprehension` (en-US) e o `JS1.7/JS1.8 Generator comprehension` (en-US) foram descontinuados.
### Iterador

* `StopIteration` foi descontinuado.
* `Iterator` (en-US) foi descontinuado.
### Métodos de objeto

* `watch` e `unwatch` foram descontinuados. No lugar deles, use `Proxy` .
* `__iterator__` foi descontinuado.
* `Object.prototype.__noSuchMethod__` foi descontinuado. Use `Proxy` em seu lugar.
### Métodos de data

* `getYear` e `setYear` foram afetados pelo Bug do Milênio e foram reagrupados em `getFullYear` e `setFullYear`.
* Deve-se usar `toISOString` ao invés do método descontinuado `toGMTString` em códigos novos.
* `toLocaleFormat` foi descontinuado.
### Funções

* Expression closures foram descontinuadas. Use `functions` normais ou arrow functions no lugar delas.
### Proxy

* Proxy.create e Proxy.createFunction foram descontinuadas. Use `Proxy` no lugar delas.
* As armadilhas a seguir ficaram obsoletas:
    + `hasOwn` (Erro do Firefox 980565, Firefox 33).
    + `getEnumerablePropertyKeys` (Erro do Firefox 783829, Firefox 37)
    + `getOwnPropertyNames` (Erro do Firefox 1007334, Firefox 33)
    + `keys` (Erro do Firefox 1007334, Firefox 33)
### let

* `let blocks` e `let expressions` foram descontinuados.
### Sequências de escape

* Sequências de escape octais (\ seguido por um, dois ou três dígitos octais) foram descontinuadas em literais *string* e expressões regulares.
* As funções `escape` e `unescape` foram descontinuadas. Use `encodeURI`, `encodeURIComponent`, `decodeURI` ou `decodeURIComponent` para codificar e decodificar sequências de escape para caracteres especiais.
### Métodos de *string*

* HTML wrapper methods como `String.prototype.fontsize` e `String.prototype.big`.
* `String.prototype.quote` foi removido do Firefox 37.
* parâmetros flag não padrões em `String.prototype.search`, `String.prototype.match`, e `String.prototype.replace` foram depreciados.
*Features* obsoletas
--------------------

Estas *features* obsoletas foram totamente removidas do JavaScript e não podem ser usadas a partir da versão indicada do JavaScript.

### Object

* The `Object.prototype.__proto__` accessors are deprecated. Use `Object.getPrototypeOf` and `Object.setPrototypeOf` instead. This does not apply to the `__proto__` literal key in object literals.
* The `Object.prototype.__defineGetter__`, `Object.prototype.__defineSetter__`, `Object.prototype.__lookupGetter__`, and `Object.prototype.__lookupSetter__` methods are deprecated. Use `Object.getOwnPropertyDescriptor` and `Object.defineProperty` instead.
### Function

| Property | Description |
| --- | --- |
| `arity` | Number of formal arguments. |

### Array

| Property | Description |
| --- | --- |
| `Array.observe()` | Asynchronously observing changes to Arrays. |
| `Array.unobserve()` | Remove observers. |

### Number

* `Number.toInteger()`
### ParallelArray

* `ParallelArray`
### Statements

* `for each...in` is deprecated. Use `for...of` instead.
* Destructuring `for...in` is deprecated. Use `for...of` instead.
### E4X

See E4X for more information.

### Sharp variables

See Sharp variables in JavaScript for more information.


Instruções e declarações - JavaScript

Instruções e declarações
========================

Aplicações em JavaScript são realizadas através de instruções com uma sintaxe apropriada. Uma única instrução pode abranger multiplas linhas. Multiplas instruções podem estar contidas em uma única linha se cada instrução estiver separada por ponto e vírgula ( ; ).

Instruções e declarações por categoria
--------------------------------------

Para visualizar em ordem alfabética use a barra de rolagem à esquerda.

### Control flow

`Block`

Uma instrução de bloqueio é usada para um grupo de zero ou mais instruções. O bloqueio é delimitado por um par de chaves.

`break`

Termina o atual loop, troca, ou nomeia instruções e transfere o controle do programa para a próxima instrução após a que foi terminada agora.

`continue`

Termina a execução das instruções na atual iteração do atual loop, e continua a execução do loop com a seguinte iteração.

`Empty`

Uma instrução vazia é usada para gerar uma "não-instrução", ainda que o JavaScrpit espere uma.

`if...else`

Executa uma instrução se a condição especificada é verdadeira. Se a condição é falsa, outra instrução pode ser executada.

`switch`

Retorna uma expressão, combinando o valor da expressão a condição do caso, e executa a condição associada a este caso.

`throw`

Aplica uma exceção definida pelo usuário.

`try...catch`

Marca um bloco de instruções para tentar, e especifica a resposta, uma exceção deve ser retornada.

### Declarações

`var`

Declara uma variável, opcionalmente inicializando com um valor.

Experimental `let`

Declara acesso ao local da variável, opcionalmente inicializando com um valor.

Experimental `const`

Declara uma constante de apenas leitura.

### Funções e classes

`function`

Declara uma função com os parâmetros especificos.

Experimental `function*`

Gera funções habilitando iteradores de escrita mais facilmente.

`return`

Especifica o valor a ser retornado por uma função.

Experimental `class`

Declara uma classe.

### Iterações

`do...while`

Cria um loop que executa uma especifica instrução até que a condição de teste seja falsa. A condição é retornada depois da execução da instrução, resultando na instrução especificada executando ao menos uma vez.

`for`

Cria um loop que consiste em três opções de expressões, entre parenteses e separado por ponto e vírgula, seguido pela instrução executada no loop.

Deprecated
Non-standard
 `for each...in`

Itera uma variável especificada sobre todos os valores das propriedades do objeto. Para cada propriedade distinta, uma instrução especificada é executada.

`for...in`

Itera através de enumeráveis propriedades de um objeto, em ordem arbitrária. Para cada propriedade distinta, instruções podem ser executadas.

Experimental `for...of`

Itera através de objetos iteráveis (incluindo arrays, array-like objects, iterators and generators (en-US)), invocando uma iteração personalizada com instruções para serem executadas pelo valor de cada propriedade.

`while`

Cria um loop que executa uma especifica instrução enquanto o teste da condição for positivo. A condição é retornada antes de executar a instrução.

### Outros

`debugger`

Invoca qualquer funcionalidade de depuração disponível. Se não há funcionabilidade disponível, a instrução não tem efeito.

Experimental `export`

Usado para exportar funções que os deixa disponível para importação em módulos externos, outros scripts.

Experimental `import`

Usado para importar funções exportadas de um módulo externo, outro script.

`label`

Fornece uma instrução com um identificador que pode ser referido usando `break` ou `continue` instruções.

Deprecated `with`

Extende o alcance de uma instrução.

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

* Operators


Iteration protocols - JavaScript

Iteration protocols
===================

Algumas adições do ECMAScript 2015 não são novos *built-ins* ou uma nova sintaxe, mas protocolos. Estes protocolos podem ser implementados por qualquer objeto desde que respeitando algumas convenções.Existem dois protocolos: O *protocolo iterável* (iterable protocol) e o *protocolo iterador* (iterator protocol).O protocolo iterável (iterable protocol)
----------------------------------------

O protocolo **iterável** permite que objetos JavaScript definam ou personalizem seu comportamento de iteração, como valores em um loop do construtor `for..of`. Alguns tipos *built-in* são *built-in iterables* com um comportamento de iteração padrão, tal como `Array` ou `Map`, enquanto outros tipos (como `Object`) não são assim.

Para ser **iterável**, um objeto deve implementar o método **@@iterator**, o que significa que o objeto (ou um dos objetos acima de sua cadeia de protótipos) deve ter uma propriedade com uma chave **@@iterator** que está disponível via constante ``Symbol.iterator``:

| Property | Value |
| --- | --- |
| `[Symbol.iterator]` | Uma função de zero argumentos que retorna um objeto, em conformidade com o protocolo iterador. |

Sempre que um objeto precisa ser iterado (como no início de um loop `for..of`), o método `@@iterator` é chamado sem argumentos e o retorno do **iterador** é usado para obter os valores a serem iterados.

O protocolo iterador (iterator protocol)
----------------------------------------

O protocolo **iterador** define uma maneira padrão de produzir uma sequência de valores (finito ou infinito).

Um objeto é um iterador quando implementa um método **`next()`** com a semântica adiante:

| Propriedade | Valor |
| --- | --- |
| `next` | Uma função sem argumentos que retorna um objeto com duas propriedades:* `done` (boolean)
    + Tem o valor `true` se o iterador ultrapassar o final
     da sequência iterada. Nesse caso
     `value` opcionalmente especifica o valor de retorno
     do iterador.
    + Tem o valor `false` se o iterador foi capaz de
     produzir o próximo valor na sequência. Isso é equivalente a não
     especificar a propriedade `done`.
* `value` - qualquer valor JavaScript retornado pelo
 iterador. Pode ser omitido quando `done` é
 `true`.

 O método `next` sempre retorna um objeto com propriedades
 apropriadas, incluindo `done` e `value`. Se um
 valor não-objeto é retornado (tal como `false` ou
 `undefined`), será lançado um
 `TypeError` ("iterator.next() retorna o valor de
 um não-objeto").
  |

**Nota:** Não é possível saber de forma reflexiva se um determinado objeto implementa o protocolo do iterador, no entanto, é fácil criar um objeto que satisfaça tanto o iterador quanto os protocolos iteráveis (como mostrado no exemplo abaixo). Fazer isso permite que um iterador seja consumido pelas várias sintaxes que iteráveis esperam. Assim, raramente é desejável implementar o protocolo do iterador sem também implementar iteráveis.

```js
var myIterator = {
  next: function () {
    // ...
  },
  [Symbol.iterator]: function () {
    return this;
  },
};
```

Exemplos de uso do protocolo de iteração
----------------------------------------

Uma `String` é um exemplo de um objeto iterable built-in:

```js
var someString = "hi";
typeof someString[Symbol.iterator]; // "function"
```

O iterador padrão de uma string retorna as posições dos caracteres de uma string um por um:

```js
var iterator = someString[Symbol.iterator]();
iterator + ""; // "[object String Iterator]"

iterator.next(); // { value: "h", done: false }
iterator.next(); // { value: "i", done: false }
iterator.next(); // { value: undefined, done: true }
```

Alguns construtores built-in, como *spread syntax*, usam o mesmo protocolo de iteração interiormente:

```js
[...someString]; // ["h", "i"]
```

Podemos redefinir o comportamento de iteração fornecendo nosso próprio `@@iterator`:
```

var someString = new String('hi');           // need to construct a String object explicitly to avoid auto-boxing

someString[Symbol.iterator] = function() {
  return { // this is the iterator object, returning a single element, the string "bye"
    next: function() {
      if (this._first) {
        this._first = false;
        return { value: 'bye', done: false };
      } else {
        return { done: true };
      }
    },
    _first: true
  };
};
```

Observe como redefinir `@@iterator` afeta o comportamento built-in que faz uso do protocolo de iteração:

```js
[...someString]; // ["bye"]
someString + ""; // "hi"
```

Exemplos de Iteráveis
---------------------

### Iteráveis Built-in

`String`, `Array`, `TypedArray` (en-US), `Map` and `Set` são todos iteráveis internos, porque cada um dos seus objetos protótipos implementa um método `@@iterator`.

### Iteráveis definidos pelo usuário

Nós podemos fazer nossos próprios iterables assim:
```

var myIterable = {};
myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};
[...myIterable]; // [1, 2, 3]
```

### Built-in APIs que aceitam iteráveis

Existem muitas APIs que aceitam iteráveis, por exemplo: `Map([iterable])`, `WeakMap([iterable])`, `Set([iterable])` e `WeakSet([iterable])`:
```

var myObj = {};
new Map([[1, 'a'], [2, 'b'], [3, 'c']]).get(2);               // "b"
new WeakMap([[{}, 'a'], [myObj, 'b'], [{}, 'c']]).get(myObj); // "b"
new Set([1, 2, 3]).has(3);                               // true
new Set('123').has('2');                                 // true
new WeakSet(function* () {
    yield {};
    yield myObj;
    yield {};
}()).has(myObj);                                         // true
```

Veja também `Promise.all(iterable)`, `Promise.race(iterable)` e `Array.from()`.

### Sintaxe que espera iteráveis

Some statements and expressions expect iterables, for example the `for-of` loops, spread operator (en-US), `yield*`, and destructuring assignment:
```

for(let value of ['a', 'b', 'c']){
    console.log(value);
}
// "a"
// "b"
// "c"

[...'abc']; // ["a", "b", "c"]

function* gen() {
  yield* ['a', 'b', 'c'];
}

gen().next(); // { value:"a", done:false }

[a, b, c] = new Set(['a', 'b', 'c']);
a // "a"
```

### Iteráveis não bem formados

If an iterable's `@@iterator` method doesn't return an iterator object, then it's a non-well-formed iterable. Using it as such is likely to result in runtime exceptions or buggy behavior:
```

var nonWellFormedIterable = {}
nonWellFormedIterable[Symbol.iterator] = () => 1
[...nonWellFormedIterable] // TypeError: [] is not a function
```

Iterator examples
-----------------

### Simple iterator
```

function makeIterator(array) {
    var nextIndex = 0;

    return {
       next: function() {
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
}

var it = makeIterator(['yo', 'ya']);

console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done);  // true
```

### Infinite iterator
```

function idMaker() {
    var index = 0;

    return {
       next: function(){
           return {value: index++, done: false};
       }
    };
}

var it = idMaker();

console.log(it.next().value); // '0'
console.log(it.next().value); // '1'
console.log(it.next().value); // '2'
// ...
```

### Com um gerador
```

function* makeSimpleGenerator(array) {
    var nextIndex = 0;

    while (nextIndex < array.length) {
        yield array[nextIndex++];
    }
}

var gen = makeSimpleGenerator(['yo', 'ya']);

console.log(gen.next().value); // 'yo'
console.log(gen.next().value); // 'ya'
console.log(gen.next().done);  // true

function* idMaker() {
    var index = 0;
    while (true)
        yield index++;
}

var gen = idMaker();

console.log(gen.next().value); // '0'
console.log(gen.next().value); // '1'
console.log(gen.next().value); // '2'
// ...
```

### Com uma classe ES2015
```

class SimpleClass {
  constructor(data) {
    this.index = 0;
    this.data = data;
  }

  [Symbol.iterator]() {
    return {
      next: () => {
        if (this.index < this.data.length) {
          return {value: this.data[this.index++], done: false};
        } else {
          this.index = 0; //If we would like to iterate over this again without forcing manual update of the index
          return {done: true};
        }
      }
    };
  }
}

const simple = new SimpleClass([1,2,3,4,5]);

for (const val of simple) {
  console.log(val);  //'0' '1' '2' '3' '4' '5'
}
```

Um objeto gerador um iterador ou iterável?
------------------------------------------

Um objeto gerador é tanto iterador quanto iterável:
```

var aGeneratorObject = function* () {
    yield 1;
    yield 2;
    yield 3;
}();
typeof aGeneratorObject.next;
// "function", because it has a next method, so it's an iterator
typeof aGeneratorObject[Symbol.iterator];
// "function", because it has an @@iterator method, so it's an iterable
aGeneratorObject[Symbol.iterator]() === aGeneratorObject;
// true, because its @@iterator method returns itself (an iterator), so it's an well-formed iterable
[...aGeneratorObject];
// [1, 2, 3]
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-iteration |

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

* Para mais informações sobre *generators* ES2015, consulte a documentação de function\*.


Template strings - JavaScript

Template strings
================

*Template* Strings são *string*s que permitem expressões embutidas. Você pode *utilizar string* multi-linhas e interpolação de *string* com elas.

Basicamente é uma nova forma de criar strings e tornar o seu código um pouco mais legível.

Sintaxe
-------

```js
`corpo de texto`

`texto linha 1
 texto linha 2`

`texto string ${expression} texto string`

tag `texto string ${expression} texto string`
```

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

*Template strings* são envolvidas por (acentos graves) (` `) em vez de aspas simples ou duplas. *Template strings* podem possuir *placeholders*. Estes são indicados por um cifrão seguido de chaves (`${expression}`). As expressões nos *placeholders*, bem como o texto em volta delas são passados a uma função. A função padrão apenas concatena as partes em uma *string* única. Se existir uma expressão precedendo a *template string* (função `tag` exemplo), a *template string* é definida como "*tagged template string*". No caso, a expressão *tag* (geralmente uma função) é chamada pela *template string* processada, que você pode manipular antes de produzir o resultado.

```js
`\`` === "`"; // --> true
```

### Strings multi-linhas

Qualquer caracter de nova linha inserido no código é parte da *template string*. Utilizando *strings* normais, você teria de usar a síntaxe a seguir para obter strings multi-linhas:

```js
console.log("texto string linha 1\n" + "texto string linha 2");
// "texto string linha 1
// texto string linha 2"
```

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

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

### Interpolação de Expressões

Para encapsular expressões dentro de strings, você precisava utilizar a seguinte sintaxe:

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

Agora, com template strings, você pode utilizar as substituições sintáticas tornando o código mais legível:

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

### Tagged template strings

Uma forma mais avançada dos *template string* são os *template strings* com marcações ou tags, ou *tagged template strings*. Com eles, você tem a possibilidade de modificar a saída dos *template strings* usando uma função. O primeiro argumento contém um array de literais ("Hello" e "World" neste exemplo). Do segundo em diante e cada argumento subsequente contém valores previamente processados (algumas vezes chamados *cooked*) pelas expressões de substituição ("15" e "50" no caso do exemplo). No final, a função retorna a string ja manipulada:

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

function tag(strings, ...values) {
  console.log(strings[0]); // "Hello "
  console.log(strings[1]); // " world "
  console.log(values[0]); // 15
  console.log(values[1]); // 50

  return "Bazinga!";
}

tag`Hello ${a + b} world ${a \* b}`;
// "Bazinga!"
```

### Strings *Raw*

A propriedade especial `raw`, disponível no primeiro argumento da função da *tagged template string* acima, permite o acesso as strings de maneira pura (*raw*) exatamente como elas foram especificadas:

```js
function tag(strings, ...values) {
  return strings.raw[0];
}

tag`string text line 1 \n string text line 2`;
// "string text line 1 \\n string text line 2"
```

Adicionalmente, o método `String.raw()` permite a criação de strings cruas, exatamente como as *template functions* e as concatenações deveram criar.

```js
String.raw`Hi\n${2 + 3}!`; // "Hi\\n5!"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-template-literals |

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

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

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

* `String`
* `String.raw()`
* Gramática léxica
* Template-like strings in ES3 compatible syntax
* "ES6 in Depth: Template strings" on hacks.mozilla.org
* https://styled-components.com/


Trailing commas - JavaScript

Trailing commas
===============

**Trailing commas** (por vezes chamadas "final commas") podem ser úteis quando
 adicionar novos elementos, parâmetros, ou propriedades ao código JavaScript. Se desejar adicionar um
 nova propriedade, pode adicionar uma nova linha sem modificar a última linha anterior, se isso
 A linha já usa uma vírgula de trailing. Isto torna as diffs de controle de versão mais limpas e editadas, assim o
 controle de versão do código pode ser menos problemático.

 O JavaScript tem permitido o uso de trailing commas em arrays literais desde o início, e posteriormente adicionou-as aos objetos literais, e mais recentemente, a
 parâmetros da função e a importações nomeadas e exportações nomeadas.

JSON, no entanto, não permitem o uso de trailing comma.

Syntax
------

```js
,
```

Exemplos
--------

### Trailing commas em literais

#### Arrays

JavaScript ignora trailing commas em arrays:

```js
const arr = [1, 2, 3];
arr; // [1, 2, 3]
arr.length; // 3
```

 Se for utilizada mais do que uma trailing comma, é produzida uma elisão (ou buraco). Uma elisão
 com buracos é chamado de *sparse* (uma matriz *densa* não tem sparse). Quando
 arrays iteráveis por exemplo com `Array.prototype.forEach()` ou
 `Array.prototype.map()`, os buracos da matriz são saltados.

```js
const arr = [1, 2, 3, , ,];
arr.length; // 5
```

#### Objetos

Trailing commas em objetos literais também são úteis:

```js
const objeto = {
  foo: "bar",
  teclado: "qwerty",
  idade: 42,
};
```

### Trailing commas em funções

Trailing commas também são permitidas nas listas de parâmetros de funções

#### Definição de parâmetros

 Os seguintes pares de definição de funções são válidos e equivalentes um ao outro.
 As trailing commas não afetam a propriedade `length` das declarações de função
 ou o objeto `arguments`

```js
function f(p) {}
function f(p) {}
(p) => {};
(p) => {};
```

As trailing commas também funcionam como definições de métodos para classes ou objetos:

```js
class C {
  um(a) {}
  dois(a, b) {}
}
const objeto = {
  um(a) {},
  dois(a, b) {},
};
```

#### Chamadas de função

Os seguintes pares de invocação de funções são válidos e equivalentes um ao outro.

```js
f(p);
f(p);
Math.max(10, 20);
Math.max(10, 20);
```

#### Trailing commas inválidas

 Definições de parâmetros de funções ou invocações de funções que contenham apenas uma vírgula
 lançam um `SyntaxError` (en-US). Além disso, ao utilizar um parâmetros rest, não são permitidas trailling commas:

```js
function f(,) {} // SyntaxError: parâmetro formal em falta
(,) => {};       // SyntaxError: expressão esperada, contém ','
f(,)             // SyntaxError: expressão esperada, contém ','
function f(...p,) {} // SyntaxError: parâmetro após parâmetro de repouso
(...p,) => {}        // SyntaxError: parênteses de fecho esperados, contém ','
```

### Trailing commas em desestruturação

 Também é permitida uma vírgula no lado esquerdo quando se usa
 atribuição de desestruturação:

```js
// desestruturação de array com trailing comma
[a, b] = [1, 2];
// desestruturação de objeto com trailing comma
const o = {
  p: 42,
  q: true,
};
const { p, q } = o;
```

Mais uma vez, ao utilizar um elemento de rest, um `SyntaxError` (en-US) será lançado:

```js
const [a, ...b] = [1, 2, 3];
// SyntaxError: elemento rest pode nao ter um trailing comma
```

### Trailing commas em JSON

Como o JSON se baseia num subconjunto muito restrito de sintaxe JavaScript, **não são permitidas trailing commas no JSON\***.

Ambas as linhas irão lançar um `SyntaxError`:

```js
JSON.parse("[1, 2, 3, 4, ]");
JSON.parse('{"foo" : 1, }');
// SyntaxError JSON.parse: carácter inesperado
// na linha 1 coluna 14 dos dados do JSON
```

Omitir trailing commas para analisar correctamente o JSON:

```js
JSON.parse("[1, 2, 3, 4 ]");
JSON.parse('{"foo" : 1 }');
```

### Trailling commas em importações nomeadas e exportações nomeadas

Trailing commas são válidas em importações nomeadas e exportações nomeadas.

#### importações nomeadas

```js
import { A, B, C } from "D";
import { X, Y, Z } from "W";
import { A as B, C as D, E as F } from "Z"; //Renomeando as importações
```

#### exportações nomeadas

```js
export { A, B, C };
export { A, B, C };
export { A as B, C as D, E as F }; // Renomeando as importações
```

### Prefixo do quantificador

```js
  //{ DecimalDigits[~Sep], DecimalDigits[~Sep] }
  x{n,}
  x{n,m}
  x{n,m}?
```

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-Elision |
| ECMAScript Language Specification # prod-ObjectLiteral |
| ECMAScript Language Specification # prod-ArrayLiteral |
| ECMAScript Language Specification # prod-Arguments |
| ECMAScript Language Specification # prod-FormalParameters |
| ECMAScript Language Specification # prod-CoverParenthesizedExpressionAndArrowParameterList |
| ECMAScript Language Specification # prod-NamedImports |
| ECMAScript Language Specification # prod-NamedExports |
| ECMAScript Language Specification # prod-QuantifierPrefix |
| ECMAScript Language Specification # prod-annexB-InvalidBracedQuantifier |

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

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

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

* Proposta inicial do ECMAScript: trailing function commas por Jeff Morrison


JavaScript error reference - JavaScript

JavaScript error reference
==========================

Lista de erros "globais".

* Erro de Sintaxe: faltando : depois da propriedade id
* Erro de sintaxe falta ) depois da lista de argumentos
* Erro de sintaxe: declaração de função requer um nome
* Error: Permission denied to access property "x"
* InternalError: too much recursion
* RangeError: argument is not a valid code point
* RangeError: invalid array length
* RangeError: invalid date
* RangeError: precision is out of range
* RangeError: repeat count must be non-negative
* ReferenceError: "x" não está definido
* ReferenceError: Atribuição à variável não declarada "x"
* ReferenceError: can't access lexical declaration`X' before initialization
* ReferenceError: invalid assignment left-hand side
* ReferenceError: reference to undefined property "x"
* SyntaxError: JSON.parse: bad parsing
* SyntaxError: Unexpected token
* SyntaxError: as declarações da cabeça do laço for-in podem não ter inicializadores
* SyntaxError: flag de expressão regular inválida "x"
* SyntaxError: illegal character
* SyntaxError: missing formal parameter
* SyntaxError: missing variable name
* SyntaxError: missing } after property list
* SyntaxError: redeclaration of formal parameter "x"
* SyntaxError: uma declaração na cabeça de um laço for-of não pode ter um inicializador
* SyntaxError: unterminated string literal
* TypeError: "x" is (not) "y"
* TypeError: "x" is not a function
* TypeError: "x" is read-only
* TypeError: atribuição inválida para const "x"
* TypeError: can't assign to property "x" on "y": not an object
* TypeError: can't define property "x": "obj" is not extensible
* TypeError: can't redefine non-configurable property "x"
* TypeError: invalid Array.prototype.sort argument
* TypeError: property "x" is non-configurable and can't be deleted
* TypeError: setting getter-only property "x"
* Warning: -file- is being assigned a //# sourceMappingURL, but already has one
* Warning: unreachable code after return statement