Arrow functions - JavaScript

Arrow functions
===============

Uma **expressão *arrow function*** possui uma sintaxe mais curta quando comparada a uma expressão de função (*function expression*) e não tem seu próprio *this*, *arguments*, *super* ou *new.target*. Estas expressões de funções são melhor aplicadas para funções que não sejam métodos, e elas não podem ser usadas como construtoras (*constructors*).

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

Sintaxe
-------

### Sintaxe básica
```

(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// equivalente a: => { return expression; }

// Parênteses são opcionais quando só há um nome de parâmetro:
(singleParam) => { statements }
singleParam => { statements }

// A lista de parâmetros para uma função sem parâmetros deve ser escrita com um par de parênteses.
() => { statements }
```

### Sintaxe avançada
```

// Envolva o corpo da função em parênteses para retornar uma expressão literal de objeto:
params => ({foo: bar})

// Parâmetros rest (rest parameters) e parâmetros padrões (default parameters) são suportados
(param1, param2, ...rest) => { statements }
(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }

// Desestruturação (destructuring) dentro da lista de parâmetros também é suportado
var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
f(); // 6
```

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

Veja também "ES6 In Depth: Arrow functions" on hacks.mozilla.org.

Dois fatores influenciaram a introdução das *arrow functions*: funções mais curtas e a inexistência da palavra chave `this`.

### Funções mais curtas
```

var elements = [
  'Hydrogen',
  'Helium',
  'Lithium',
  'Beryllium'
];

elements.map(function(element) {
  return element.length;
}); // esta sentença retorna o array: [8, 6, 7, 9]

// A função regular acima pode ser escrita como a arrow function abaixo
elements.map((element) => {
  return element.length;
}); // [8, 6, 7, 9]

// Quando só existe um parâmetro, podemos remover os parênteses envolvendo os parâmetros:
elements.map(element => {
  return element.length;
}); // [8, 6, 7, 9]

// Quando a única sentença em uma arrow function é `return`, podemos remover `return` e remover
// as chaves envolvendo a sentença
elements.map(element => element.length); // [8, 6, 7, 9]

// Neste caso, porque só precisamos da propriedade length, podemos usar o parâmetro de destruição (destructing parameter):
// Note que a string `"length"` corresponde a propriedade que queremos obter enquanto que a
// obviamente propriedade não especial `lengthFooBArX` é só o nome de uma variável que pode ser mudado
// para qualquer nome válido de variável que você quiser
elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]

// Esta atribuição de parâmetro de destruição (destructing parameter) pode ser escrita como visto abaixo. Entretanto, note que
// não há um específico `"length"` para selecionar qual propriedade nós queremos obter. Ao invés disso, o nome literal
// da própria variável `length` é usado como a propriedade que queremos recuperar do objeto.
elements.map(({ length }) => length); // [8, 6, 7, 9]
```

### Sem `this` separado

Antes das *arrow functions*, toda nova função definia seu próprio valor de this (baseado em como a função era chamada, um novo objeto no caso de um construtor, *undefined* em chamadas de funções com modo estrito (*strict mode)*, o objeto base se a função é chamada como um "método de objeto", etc.). Este comportamento é importuno com um estilo de programação orientado a objeto.

```js
function Person() {
  // O contrutor Person() define `this` como uma instância dele mesmo.
  this.age = 0;

  setInterval(function growUp() {
    // Em modo não estrito, a função growUp() define `this`
    // como o objeto global (porque é onde growUp() é executado.),
    // que é diferente ao `this`
    // definido pelo construtor Person().
    this.age++;
  }, 1000);
}

var p = new Person();
```

No ECMAScript 3/5, este comportamento era corrigido definindo o valor em `this` à uma variável que pudesse ser encapsulada.

```js
function Person() {
  var that = this;
  that.age = 0;

  setInterval(function growUp() {
    // A chamada a função refere à variáevel `that` da qual
    // o valor é o objeto esperado.
    that.age++;
  }, 1000);
}
```

Alternativamente, uma função de ligação (bound function) pode ser criada para que o valor pré-atribuido à `this` seja passado para a função alvo de ligação (a função `growUp()` no exemplo acima.

Uma *arrow function* não tem seu próprio `this;` o valor `this` do contexto léxico encapsulado é usado. Ex: *Arrow functions* seguem as regras normais de pesquisa de variáveis. Então, ao procurar por `this`, que não está no escopo atual elas acabam encontrando `this` no escopo encapsulado. Assim, no código a seguir, o `this` dentro da função que é passado para `setInterval` tem o mesmo valor do `this` na função lexicamente encapsulada:

```js
function Person() {
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| corretamente se refere ao objeto Person
  }, 1000);
}

var p = new Person();
```

#### Relação com *strict mode*

Considerando que `this` vem do contexto léxico envolvente, as regras do modo estrito (*strict mode*) em relação ao `this` são ignoradas.

```js
var f = () => {
  "use strict";
  return this;
};
f() === window; // ou o objeto global
```

O restante das regras do modo estrito (*strict mode)* são aplicadas normalmente.

#### Invocação por call ou apply

Já que as *arrow functions* não têm o próprio `this`, os métodos `call()` ou `apply()` só podem passar parâmetros. `thisArg` é ignorado.
```

var adder = {
  base: 1,

  add: function(a) {
    var f = v => v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    var f = v => v + this.base;
    var b = {
      base: 2
    };

    return f.call(b, a);
  }
};

console.log(adder.add(1));         // Deve logar 2
console.log(adder.addThruCall(1)); // Deve logar 2 ainda
```

### Sem ligação (*binding*) de argumentos (`arguments`)

*Arrow functions* não tem o próprio objeto argumentos (arguments object). Assim, neste exemplo, `arguments` é simplesmente uma referência aos argumentos do escopo encapsulado:
```

var arguments = [1, 2, 3];
var arr = () => arguments[0];

arr(); // 1

function foo(n) {
  var f = () => arguments[0] + n; // ligação implícita dos argumentos de foo. arguments[0] é n
  return f();
}

foo(3); // 6
```

Na maioria dos casos, usar parâmetros rest (*rest parameters*) é uma boa alternativa a usar um objeto `arguments`.

```js
function foo(n) {
  var f = (...args) => args[0] + n;
  return f(10);
}

foo(1); // 11
```

### *Arrow functions* usadas como métodos

Como afirmado anteriormente, expressões *arrow function* são melhores para funções que não sejam métods. Vamos ver o que acontece quando tentamos usá-las como métodos.
```

'use strict';

var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log(this.i, this);
  }
}

obj.b(); // imprime undefined, Window {...} (ou o objeto global)
obj.c(); // imprime 10, Object {...}
```

*Arrow functions* não tem o próprio `this`. Outro exemplo envolvendo `Object.defineProperty()`:
```

'use strict';

var obj = {
  a: 10
};

Object.defineProperty(obj, 'b', {
  get: () => {
    console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...} (ou o objeto global)
    return this.a + 10; // representa o objeto global 'Window', portanto 'this.a' retorna 'undefined'
  }
});
```

### Uso do operador `new`

Arrow functions não podem ser usadas como construtores e lançarão um erro quando usadas com o `new`.

### Uso da propriedade `prototype`

*Arrow functions* não têm a propriedade `prototype`.
```

var Foo = () => {};
console.log(Foo.prototype); // undefined
```

### Uso da palavra chave `yield`

A palavra chave `yield` não pode ser usada no corpo de uma *arrow function* (exceto quando permitido dentro de funções aninhadas dentro delas). como consequência, *arrow functions* não podem ser usadas como geradoras (*generators*).

Corpo de função
---------------

*Arrow functions* podem ter um corpo conciso (*"concise body")* ou o usual corpo em bloco (*"block body")*.

Em um *concise body*, apenas uma expressão é especificada, a qual se torna o valor de retorno implícito. Em um *block body*, você precisa explicitamente usar a declaração de retorno, ou seja, o `return`.
```

var func = x => x * x;
// sintaxe de concise body. O "return" é implícito

var func = (x, y) => { return x + y; };
// Em um função com block body, é necessário um "return" explícito
```

Retornando objetos literais
---------------------------

Tenha em mente que retornar objetos literais usando a sintaxe de corpo conciso (*concise body*) `params => {object:literal}` não funcionará como esperado.
```

var func = () => { foo: 1 };
// Chamar func() retornará undefined!

var func = () => { foo: function() {} };
// SyntaxError (Erro de sintaxe): a declaração da função requer um nome
```

Isto acontece porque o código dentro das chaves ({}) é convertido como uma sequência de sentenças (ex: `foo` é tratado como um título, não como uma chave num objeto literal).

Se lembre de envolver o objeto literal em parênteses.
```

var func = () => ({foo: 1});
```

Quebras de linha
----------------

Uma *arrow function* não pode conter uma quebra de linha entre seus parâmetros e sua flecha.
```

var func = (a, b, c)
           => 1;
// SyntaxError (Erro de sintaxe): esperada expressão, mas obteve '=>'
```

Entretanto, isto pode ser corrigido ao usar parênteses ou colocar a quebra de linha dentro dos argumentos como visto abaixo para garantir que o código permaneça bonito e leve.

```js
var func = (a, b, c) => 1;
// SyntaxError (erro de sintaxe) não é lançado
```

Ordem de análise
----------------

Apesar de a flecha numa *arrow function* não ser um operador, *arrow functions* possuem regras especiais de análise que interagem diferentemente com precedência de operador (operator precedence) comparadas à funções comuns.
```

let callback;

callback = callback || function() {}; // ok

callback = callback || () => {};
// SyntaxError (Erro de sintaxe): argumentos inválidos de arrow-function

callback = callback || (() => {});    // ok
```

Mais exemplos
-------------
```

// Uma arrow function vazia retorna undefined
let empty = () => {};

(() => 'foobar')();
// Retorna "foobar"
// (esta é uma Expressão de Função Invocada Imediatamente (Immediately Invoked Function Expression)
// veja 'IIFE' no glossário)

var simple = a => a > 15 ? 15 : a;
simple(16); // 15
simple(10); // 10

let max = (a, b) => a > b ? a : b;

// Mapeamento, filtragem, ... simples de array

var arr = [5, 6, 13, 0, 1, 18, 23];

var sum = arr.reduce((a, b) => a + b);
// 66

var even = arr.filter(v => v % 2 == 0);
// [6, 0, 18]

var double = arr.map(v => v * 2);
// [10, 12, 26, 0, 2, 36, 46]

// Cadeias de promessa (promisse chains) mais concisas
promise.then(a => {
  // ...
}).then(b => {
  // ...
});

// Arrow functions sem parâmetros que são visualmente mais fáceis de analisar
setTimeout( () => {
  console.log('E aconteço antes');
  setTimeout( () => {
    // deeper code
    console.log('Eu aconteço depois');
  }, 1);
}, 1);
```

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

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

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

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


Definições de Método - JavaScript

Definições de Método
====================

No ECMAScript 2015 foi introduzida uma sintaxe reduzida para definição de métodos em inicializadores de objetos. É uma abreviação para uma função atribuída ao nome do método.

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

Sintaxe
-------
```

var obj = {
  propriedade( parametros… ) {},
  *generator( parametros… ) {},
// também com chaves computadas:
  [propriedade]( parameters… ) {},
  *[generator]( parametros… ) {},
// compare ES5 sintaxe para getter/setter:
  get propriedade() {},
  set propriedade(valor) {}
};
```

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

A sintaxe reduzida é similar à da getter e setter introduzida no ECMAScript 5.

Dado o seguinte código:

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

Agora você pode reduzi-lo para isto:

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

### Generator methods

Os generator methods também podem ser definidos utilizando a sintaxe reduzida.

* Observe que o asterisco (\*) na sintaxe reduzida deve estar antes do nome da propriedade generator. Assim, `* g(){}` funcionará, porém `g *(){}` não.
* Se o método não for generator, sua definição não pode conter a palavra-chave `yield`. Dessa forma, generator functions legadas também não funcionarão, lançando um `SyntaxError` (en-US). Sempre utilize `yield` em conjunto com o asterisco (\*)

```js
// Utilizando a propriedade com nome (pre-ES6)
var obj2 = {
  g: function\* () {
    var indice = 0;
    while (true) yield indice++;
  },
};

// O mesmo objeto utilizando a sintaxe reduzida
var obj2 = {
  \*g() {
    var indice = 0;
    while (true) yield indice++;
  },
};

var coisa = obj2.g();
console.log(coisa.next().value); // 0
console.log(coisa.next().value); // 1
```

### Métodos assíncronos

Funções assíncronas também podem ser definidas usando a sintaxe reduzida.

```js
// Utilizando a propriedade com nome (pre-ES6)
var obj3 = {
  f: async function () {
    await alguma_promise;
  },
};

// O mesmo objeto com a sintaxe reduzida
var obj3 = {
  async f() {
    await alguma_promise;
  },
};
```

### Generator methods assíncronos

Os generator methods também podem ser assíncronos

```js
var obj4 = {
  f: async function\* () {
    yield 1;
    yield 2;
    yield 3;
  },
};

// O mesmo objeto com a sintaxe reduzida
var obj4 = {
  async \*f() {
    yield 1;
    yield 2;
    yield 3;
  },
};
```

### Métodos reduzidos não são construíveis

Métodos assim definidos não são construtores e lançarão um `TypeError` se você tentar instanciá-los.

```js
var obj = {
  metodo() {},
};
new obj.metodo(); // TypeError: obj.method is not a constructor

var obj = {
  \*g() {},
};
new obj.g(); // TypeError: obj.g is not a constructor (modificado no ES2016)
```

Exemplos
--------

### Caso de teste simples

```js
var obj = {
  a: "foo",
  b() {
    return this.a;
  },
};
console.log(obj.b()); // "foo"
```

### Nome de propriedades computados

A sintaxe reduzida também suporta nome de propriedades computados.

```js
var bar = {
  foo0: function () {
    return 0;
  },
  foo1() {
    return 1;
  },
  ["foo" + 2]() {
    return 2;
  },
};

console.log(bar.foo0()); // 0
console.log(bar.foo1()); // 1
console.log(bar.foo2()); // 2
```

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

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

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

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

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

* `get`
* `set`
* Gramática léxica


setter - JavaScript

setter
======

A sintaxe **`set`** liga a propriedade da função para ser chamada quando existe uma tentativa de definir valor para essa propriedade.

Sintaxe
-------
```

{set prop(val) { . . . }}
{set [expression](val) { . . . }}
```

### Parâmetros

`prop`

Nome da propriedade ligada a função.

`val`

`Um apelido para variável que será atribuidada a prop.`

expression

Iniciando com ECMAScript 6, você pode usar também expressões para computar o nome da propriedade a ser definida na função.

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

Em JavaScript, um *setter* pode ser usado para executar uma função sempre que se tenta mudar uma propriedade específica. *Setters* são geralmente usados em conjunto com *getters*, para criar um tipo de pseudo-propriedade. No entanto é impossível ter-se um setter para uma propriedade que contenha um valor real.

Observe os seguintes itens ao trabalhar com a sintaxe *set*:

* Ele pode ter um identificador que é um número ou uma string;
* Deve ter exatamente um parâmetro (para mais informações, acesse: Mudança do ES5 incompatível: funções getter e setter literais tem exatamemente zero ou um parâmetros);
* Não deve ter a mesma nomenclatura seja ela para propriedades ou função.
 (`{ set x(v) { }, set x(v) { } }` e `{ x: ..., set x(v) { } }` é proibido.)

Um *setter* pode ser deletado usando o operator `delete` (en-US).

Exemplos
--------

### Definindo um setter em new Objects no inicializador

Vai definir um pseudo-property *current* para este objeto, quando atribuido um valor, vai mudar `log` com o valor passado:

```js
var o = {
  set current(str) {
    this.log[this.log.length] = str;
  },
  log: [],
};
```

Observe que *current* não está definido e qualquer tentativa de acesso irá resultar em *undefined*.

### Removendo um setter com o operador `delete`

Se você deseja remover o *setter*, poderá usar somente o `delete` (en-US):

```js
delete o.current;
```

### Definindo um setter para um Object existente usando o `defineProperty`

Para adicionar um *setter* para um Object existentem mais tarde, use `Object.defineProperty()`.

```js
var o = { a: 0 };

Object.defineProperty(o, "b", {
  set: function (x) {
    this.a = x / 2;
  },
});

o.b = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
console.log(o.a); // 5
```

### Usando um nome de propriedade computada

**Nota:** **Atenção:** Propriedades computadas são uma tecnologia experimental, parte da proposta ECMAScript 6, e não é amplamente suportada por todos os browsers ainda. Ele vai retornar um syntax error en ambientes que não tem suporte.

```js
var expr = "foo";

var obj = {
  baz: "bar",
  set [expr](v) {
    this.baz = v;
  },
};

console.log(obj.baz); // "bar"
obj.foo = "baz"; // run the setter
console.log(obj.baz); // "baz"
```

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

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

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

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

SpiderMonkey-specific notes
---------------------------

* Starting with JavaScript 1.8.1, setters are no longer called when setting properties in object and array initializers.
* From SpiderMonkey 38 on, a setter with a rest parameter is a `SyntaxError` (en-US) as per the ES6 specification.
See also
--------

* getter
* `delete` (en-US)
* `Object.defineProperty()`
* `Object.prototype.__defineGetter__()`
* `Object.prototype.__defineSetter__()`
* Defining Getters and Setters in JavaScript Guide


Arguments object - JavaScript

Arguments object
================

O objeto **`arguments`** é como um objeto Array correspondendo aos argumentos passados para uma função.

Sintaxe
-------
```

arguments
```

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

O objeto `arguments` é uma variável local disponível dentro de todas as funções. Você pode referenciar os argumentos de uma função dentro da função usando o objeto `arguments`. Esse objeto contém um registro para cada argumento fornecido para a função, com o índice do primeiro registro começando em 0. Por exemplo, se são passados três argumentos para uma função, você pode referenciá-los como a seguir:

```js
arguments[0];
arguments[1];
arguments[2];
```

Os argumentos também podem ser definidos:

```js
arguments[1] = "novo valor";
```

O objeto `argumentos` não é um `Array`. É similar a um Array, mas não possui as propriedades de `Array`, exceto `length` (en-US). Por exemplo, ele não possui o método `pop`. Entretanto, ele pode ser convertido em um `Array` real:

```java
var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);

// ES2015
var args = Array.from(arguments);
```

**Aviso:** Usar slice nos argumentos impedem otimizações em alguns motores JavaScript (V8 por exemplo - mais informações). Se você precisar, tente construir um novo array iterando através dos argumentos do objeto. Uma alternativa seria usar o construtor do `Array` como uma função:

```js
var args =
  arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments);
```

Você pode usar o objeto `arguments` se você chamar uma função com mais argumentos do que ele é formalmente declarado para aceitar. Esta técnica é útil para funções que podem ser passada em um número de variáveis de argumentos. Você pode usar `arguments.length` (en-US) para determinar o número de argumentos passado para a função, e então processar cada argumento usando o objeto `arguments`. Para determinar o número de parâmetros declarados na assinatura (en-US) da função, use a propriedade `Function.length` (en-US).

### Usando typeof com Arguments

O comando `typeof arguments` retorna 'object'.

```js
console.log(typeof arguments); // 'object'
```

O `typeof` de argumentos individuais pode ser determinado com o uso do índice.

```js
console.log(typeof arguments[0]); //this will return the typeof individual arguments.
```

### Usando a Sintaxe Spread com Arguments

Você também pode usar o método `Array.from()` ou o operador spread (en-US) para converter argumentos em um Array real:

```js
var args = Array.from(arguments);
var args = [...arguments];
```

Propriedades
------------

`arguments.callee` (en-US)

Referência para a função atualmente em execução.

`arguments.caller`

Referência para a função que invocou a função atualmente em execução.

`arguments.length` (en-US)

Referência para o número de argumentos passados para a função.

`arguments[@@iterator]` (en-US)

Retorna um novo objeto Array Iterator que contém os valores para cada índice dos argumentos.

Exemplos
--------

### Definindo uma função que concatena várias strings

Este exemplo define uma função que concatena várias strings. O único argumento formal para a função é uma string que especifica os caracteres que separam os itens a concatenar. A função é definida como se segue:

```js
function myConcat(separator) {
  var args = Array.prototype.slice.call(arguments, 1);
  return args.join(separator);
}
```

Você pode passar qualquer número de argumentos para essa função e ela cria uma lista usando cada argumento como um item na lista.

```js
// returns "red, orange, blue"
myConcat(", ", "red", "orange", "blue");

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

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

### Definindo uma função que cria listas HTML

Este exemplo define uma função que cria uma string contatenado HTML para uma lista. O único argumento formal para a função é uma string que é "u" se a lista for desordenada (marcadores), ou "o" se a lista for ordenada (numerada). A função é definida como se segue:

```js
function list(type) {
  var result = "<" + type + "l><li>";
  var args = Array.prototype.slice.call(arguments, 1);
  result += args.join("</li><li>");
  result += "</li></" + type + "l>"; // end list

  return result;
}
```

Você pode passar qualquer número de argumentos para essa função, e ela adiciona cada argumento como um item para uma lista do tipo indicado. Por exemplo:

```js
var listHTML = list("u", "One", "Two", "Three");

/\* listHTML is:

"<ul><li>One</li><li>Two</li><li>Three</li></ul>"

\*/
```

### Rest, default e parâmetros desestruturados

O objeto `arguments` pode ser usado em conjunto com os parâmetros rest, default e destruturados.

```js
function foo(...args) {
  return args;
}
foo(1, 2, 3); // [1,2,3]
```

Enquanto a presença dos parâmetros rest, default, ou desestruturados não alteram o comportamento do objeto `arguments` no código em strict mode, existe uma sutil diferença para o código non-strict.

Quando uma função não-strict **não** contém parâmetros rest, default, ou desestruturados, os valores no objeto `arguments` **modificam** os valores dos argumentos (e vice-versa). Veja o código:

```js
function func(a) {
  arguments[0] = 99; // updating arguments[0] also updates a
  console.log(a);
}
func(10); // 99
```

e

```js
function func(a) {
  a = 99; // updating a also updates arguments[0]
  console.log(arguments[0]);
}
func(10); // 99
```

Quando uma função não-strict **contém** parâmetros rest, default, ou desestruturados, os valores no objeto `arguments` **não modificam** os valores dos argumentos (e vice-versa). Ao invés disso, eles refletem os argumentos fornecidos no momento da chamada:

```js
function func(a = 55) {
  arguments[0] = 99; // updating arguments[0] does not also update a
  console.log(a);
}
func(10); // 10
```

e

```js
function func(a = 55) {
  a = 99; // updating a does not also update arguments[0]
  console.log(arguments[0]);
}
func(10); // 10
```

e

```js
function func(a = 55) {
  console.log(arguments[0]);
}
func(); // undefined
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-arguments-exotic-objects |

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

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

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

* `Function`


getter - JavaScript

getter
======

A sintaxe de **get** associa uma propriedade de um objeto a uma função que será chamada quando tal propriedade é acessada.Sintaxe
-------
```

{get prop() { ... } }
{get [expression]() { ... } }
```

### Parâmetros

`prop`

O nome da propriedade à qual a função dada será associada.

expression

A partir do ECMAScript 6, você pode também utilizar expressões para um nome computado de uma propriedade para associar à função dada.

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

Às vezes é desejável que se permita acesso a uma propriedade que retorna um valor computado dinamicamente, ou você pode querer refletir o status de uma variável interna sem requerer o uso de chamadas de método explícitas. Em Javascript, isso pode ser feito com o uso de um *getter*. Não é possível simultaneamente ter um getter associado a uma propriedade e a mesma possuir um valor, embora seja possível usar um getter e um setter em conjunto para criar algo como uma pseudo-propriedade.

Note o seguinte quando for trabalhar com a sintaxe *get*:

* Pode haver um identificador que seja um número ou uma string;
* Deve haver exatamente zero parâmetros (veja Incompatible ES5 change: literal getter and setter functions must now have exactly zero or one arguments para mais informações)
* Não deve haver mais de um getter para a mesma propriedade nem uma propriedade comum como o mesmo nome do getter (`{ get x() { }, get x() { } }` and `{ x: ..., get x() { } }` são proibidos).

Um getter pode ser removido usando o operador `delete.`

Exemplos
--------

### Definindo um getter em novos objetos em inicializadores de objetos

O exemplo abaixo irá criar a pseudo-propriedade `latest` para o objeto `obj`, que irá retornar o último item do array em `log`.

```js
var log = ["test"];
var obj = {
  get latest() {
    if (log.length == 0) return undefined;
    return log[log.length - 1];
  },
};
console.log(obj.latest); // Retornará "test".
```

Note que a tentativa de atribuir um valor a `latest não irá alterá-la.`

### Removendo um getter usando o operador `delete`

Se você quer remover um getter, você pode apenas utilizar `delete.`

```js
delete obj.latest;
```

### Definindo um getter em objetos existentes usando `defineProperty`

Para adicionar um getter a um objeto existente a qualquer momento, use `Object.defineProperty()`.

```js
var o = { a: 0 };

Object.defineProperty(o, "b", {
  get: function () {
    return this.a + 1;
  },
});

console.log(o.b); // Executa o getter, que retornará a + 1 (que é 1)
```

### Usando uma propriedade com nome computado

**Nota:** Propriedades com nome computado são uma tecnologia experimenta, parte da proposta do ECMAScript 6 e não é amplamente suportada pelos navegadores ainda. O exemplo abaixo irá disparar um `SyntaxError em ambientes sem suporte.`

```js
var expr = "foo";

var obj = {
  get [expr]() {
    return "bar";
  },
};

console.log(obj.foo); // "bar"
```

### Smart / self-overwriting / lazy getters

Getters lhe dão uma maneira de definir uma propriedade de um objeto, mas eles não calculam o valor da propriedade até que sejam acessados. Um getter adia o custo de cálculo do valor até que o valor seja necessário e, se nunca o for, você não precisa pagar esse custo.

Uma técnica de otimização adicional para atrasar o cálculo do valor de uma propriedade e cacheá-lo para acesso futuro são os **smart ou memoized getters**. O valor é calculado na primeira vez que o getter é invocado, sendo então cacheado para que acessos subsequentes retornem o valor em cache sem recalculá-lo. Isso é util nas seguintes situações:

* Se o cálculo da propriedade é caro (usa muita RAM ou CPU, cria um worker, retorna um arquivo remoto, etc).
* Se o valor não é necessário agora. Ele será utilizado depois ou, em alguns casos, nem mesmo o será.
* Se for utilizado, ele será acessado diversas vezes e não há necessidade de recalcular um valor que nunca será alterado, ou não deveria ser recalculado.

Isso significa que você não deveria utilizar um lazy getter para uma propriedade cujo valor você espera mudar, porque o getter nunca irá recalcular o valor.

No exemplo a seguir, o objeto tem um getter como uma propriedade própria (own property). Ao tentar obter essa propriedade que foi removida, ela será readicionada, mas implicitamente como uma propriedade comum desta vez. Finalmente, o valor será retornado.

```js
get notifier() {
  delete this.notifier;
  return this.notifier = document.getElementById("bookmarked-notification-anchor");
},
```

Para o Firefox, veja também o código do módulo XPCOMUtils.jsm, que define a função defineLazyGetter().

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

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

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

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

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

* setter
* `delete` (en-US)
* `Object.defineProperty()`
* `Object.prototype.__defineGetter__()`
* `Object.prototype.__defineSetter__()`
* Defining Getters and Setters in JavaScript Guide


Parâmetros Predefinidos - JavaScript

Parâmetros Predefinidos
=======================

**Os parâmetros predefinidos de uma função** permitem que parâmetros regulares sejam inicializados com com valores iniciais caso `undefined` ou nenhum valor seja passado.

Sintaxe
-------
```

function [nome]([param1[ = valorPredefinido1 ][, ..., paramN[ = valorPredefinidoN ]]]) {
   instruções
}
```

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

Em JavaScript, os parâmetros de funções tem ``undefined`` como valor predefinido. Contudo, em alguns casos pode ser útil utilizar algum outro valor. É nesta situação em que os parâmetros predefinidos podem ser úteis.

No passado, a estratégia de definir valores padrão para parâmetros era testar os valores do parâmetros no corpo da função e atribuir um valor se este for **`undefined`.** No exemplo a seguir, se nenhum valor for fornecido para **b** na chamada, este valor será **`undefined`**, quando `a*b` for calculado resultaria em `NaN`. No entanto, isto é capturado na segunda linha definindo um valor padrão para b:

```js
function multiply(a, b) {
  b = typeof b !== "undefined" ? b : 1;

  return a \* b;
}

multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5); // 5
```

Com o parâmetros predefinidos a checagem no corpo da função nao é mais necessária. Agora você pode simplesmente colocar 1 como valor padrão para `b` na declaração da função:

```js
function multiply(a, b = 1) {
  return a \* b;
}

multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5); // 5
```

Exemplos
--------

### Passando `undefined` vs. outros valores "falsy"

Na segunda chamada aqui, mesmo se o segundo argumento é definido explicitamente como `undefined` (com exceção de `null`) quando chamado, o valor para o argumento `num` será o padrão.
```

function test(num = 1) {
  console.log(typeof num);
}

test();          // 'number' (num é definido para 1)
test(undefined); // 'number' (num é definido para 1 também)

// teste com outros values "falsy":
test('');        // 'string' (num é definido para '')
test(null);      // 'object' (num é definido para null)
```

### Avaliado em tempo de chamada

Os parâmetros predefinidos são avaliados no momento da chamada da função, então diferente de ex.: Python, um novo objeto é criado cada vez que a funçao é chamada.

```js
function append(value, array = []) {
  array.push(value);
  return array;
}

append(1); //[1]
append(2); //[2], not [1, 2]
```

Este mesmo comportamento é aplicado para funções e variáveis:

```js
function callSomething(thing = something()) {
  return thing;
}

function something() {
  return "sth";
}

callSomething(); //sth
```

### Parâmetros predefinidos estão disponíveis para os parâmetros seguintes à sua definição

Parâmetros que já foram avaliados ficam disponíveis para uso para os parâmetros seguintes:

```js
function singularAutoPlural(singular, plural = singular+"s",
                            rallyingCry = plural + " ATTACK!!!") {
  return [singular, plural, rallyingCry ];
}

//["Gecko","Geckos", "Geckos ATTACK!!!"]
singularAutoPlural("Gecko");

//["Fox","Foxes", "Foxes ATTACK!!!"]
singularAutoPlural("Fox","Foxes");

//["Deer", "Deer", "Deer ... change."]
singularAutoPlural("Deer", "Deer", "Deer peaceably and respectfully
   petition the government for positive change.")
```

Esta funcionalidade torna-se uma maneira direta e demonstra quantos casos extremos são manipulados.

```js
function go() {
  return ":P";
}

function withDefaults(
  a,
 b = 5,
 c = b,
 d = go(),
 e = this,
 f = arguments,
 g = this.value,
) {
  return [a, b, c, d, e, f, g];
}
function withoutDefaults(a, b, c, d, e, f, g) {
  switch (arguments.length) {
    case 0:
      a;
    case 1:
      b = 5;
    case 2:
      c = b;
    case 3:
      d = go();
    case 4:
      e = this;
    case 5:
      f = arguments;
    case 6:
      g = this.value;
    default:
  }
  return [a, b, c, d, e, f, g];
}

withDefaults.call({ value: "=^\_^=" });
// [undefined, 5, 5, ":P", window, arguments, "=^\_^="]

withoutDefaults.call({ value: "=^\_^=" });
// [undefined, 5, 5, ":P", window, arguments, "=^\_^="]
```

### Funções definidadas dentro do corpo da função

Introduzido no Gecko 33. Funções declaradas no corpo da função não podem ser referenciada dentro de parâmetos padrão e lançará um `ReferenceError` (atualmente um `TypeError` no SpiderMonkey, veja Erro do Firefox 1022967). Parâmetros padrão são sempre executados primeiro, declarações de funções dentro do corpo de outra função são avaliadas depois.

```js
// Não funciona! Throws ReferenceError.
function f(a = go()) {
  function go() {
    return ":P";
  }
}
```

### Parâmetros sem valor padrão depois de parâmetros com valores padrão

Antes do Gecko 26, o seguinte código resultaria em um `SyntaxError` (en-US). Isto foi corrigido no Erro do Firefox 777060 e funciona como esperado em versões posteriores:

```js
function f(x = 1, y) {
  return [x, y];
}

f(); // [1, undefined]
```

### Parâmetro desestruturado com valores padrões

É possível definir valores padrões com a notação destructuring assignment:

```js
function f([x, y] = [1, 2], { z: z } = { z: 3 }) {
  return x + y + z;
}

f(); // 6
```

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

* Original proposal at ecmascript.org


yield* - JavaScript

yield\*
=======

A **expressão `yield*`** é usada para delegar para outro objeto `generator` ou iterable.

Sintaxe
-------
```

 yield* [[expressão]];
```

`expressão`

A expressão que retorna um objeto iterable.

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

A expressão `yield*` itera sobre a operação e yields cada valor retornado por ele.

O valor da expressão `yield*` sozinha é o valor retornado pelo iterator quando ele for fechado (i.e., quando `done` é `true`).

Exemplos
--------

### Delegando para outro generator

No código seguinte, valores "yeldados" por `g1()` são retornados por `next()` chamam apenas os que foram "yeldados" por `g2()`.

```js
function\* g1() {
  yield 2;
  yield 3;
  yield 4;
}

function\* g2() {
  yield 1;
  yield\* g1();
  yield 5;
}

var iterator = g2();

console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: 4, done: false}
console.log(iterator.next()); // {value: 5, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
```

### Outros objetos Iterables

Além de objetos generator, `yield*` também podem `yield` outros tipos de objetos iterables, e.g. arrays, strings ou objetos de argumentos.

```js
function\* g3() {
  yield\* [1, 2];
  yield\* "34";
  yield\* Array.from(arguments);
}

var iterator = g3(5, 6);

console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: "3", done: false}
console.log(iterator.next()); // {value: "4", done: false}
console.log(iterator.next()); // {value: 5, done: false}
console.log(iterator.next()); // {value: 6, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
```

### O valor da expressão `yield*` sozinha

`yield*` é uma expressão, não uma declaração, então ele espera um valor.

```js
function\* g4() {
  yield\* [1, 2, 3];
  return "foo";
}

var result;

function\* g5() {
  result = yield\* g4();
}

var iterator = g5();

console.log(iterator.next()); // {value: 1, done: false}
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: undefined, done: true},
// g4() returned {value: 'foo', done: true} nesse ponto

console.log(result); // "foo"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-generator-function-definitions-runtime-semantics-evaluation |

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

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

Notas específicas do Firefox
----------------------------

* A partir do Gecko 33, o tratamento da expressão yield foi atualizado para se conformar com a espeficação do ES2015 (Erro do Firefox 981599):
    + A restrição de linha finalizadora agora está implementada. Nenhuma linha finalizadora entre "yield" e "\*" é permitida. Código como o a seguir irá invocar uma exception `SyntaxError` (en-US):
     js
    ```js
    function\* foo() {
      yield
      \*[];
    }

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

* O protocolo Iterator (en-US)
* `function*`
* `function* expression`
* `yield`


AND lógico (&&) - JavaScript

AND lógico (&&)
===============

O operador lógico **AND (`&&`)** (conjunção lógica) para um conjunto de operandos booleanos será `true` se e somente se todos os operandos forem `true`. Caso contrário, será `false`.

Geralmente, o operador retorna o valor do primeiro operando falsy encontrado ao avaliar da esquerda para a direita ou retorna o valor do último operando se todos forem truthy.

Exemplo
-------

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

Sintaxe
-------

```js
expr1 && expr2
```

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

O AND lógico (`&&`) avalia operandos da esquerda para a direita, retornando imediatamente com o valor do primeiro operando falsy que encontrar; se todos os valores forem truthy, o valor do último operando é retornado.

Se um valor puder ser convertido em `true`, o valor é denominado como truthy. Se um valor puder ser convertido em `false`, então valor será denominado falsy.

Exemplos de expressões que podem ser convertidas em `false` são:

* `false`;
* `null`;
* `NaN`;
* `0`;
* string vazia (`""` ou `''` ou ````);
* `undefined`.

O operador AND lógico (`&&`) preserva valores não booleanos e os retorna como estão:

```js
result = "" && "foo"; // result retorna "" (string vazia)
result = 2 && 0; // result retorna 0
result = "foo" && 4; // result retorna 4
```

 Mesmo que o operador `&&` possa ser usado com operandos não booleanos, ele ainda é considerado um operador booleano, pois seu valor de retorno sempre pode ser convertido em um boolean primitive.
 Para converter explicitamente seu valor de retorno (ou qualquer expressão em geral) para o valor booleano correspondente, use um double `operador NOT` (en-US) ou o construtor `Boolean` (en-US).

### Avaliação de curto-circuito

A expressão AND lógica é um operador de curto-circuito. Ou seja, à medida que cada operando é convertido em um booleano, se o resultado de uma conversão for `false`, o operador AND para e retorna o valor original desse operando falso; ele **não** avalia nenhum dos operandos restantes.

Considere o pseudocódigo abaixo.
```

(alguma expressao falsa aqui) && expr
```

A `expr` **nunca é avaliada** porque o primeiro operando `(alguma expressao falsa aqui)` é avaliado como falsy. Se `expr` for uma função, a função nunca será chamada. Veja o exemplo abaixo:

```js
function A() {
  console.log("chamou A");
  return false;
}
function B() {
  console.log("chamou B");
  return true;
}

console.log(A() && B());
// registra "chamou A" no console devido à chamada da função A,
// && é avaliado como false (porque a função A retorna false), então false é registrado no console;
// o operador AND entra em curto-circuito aqui e ignora a função B
```

### Operador precedente

O operador AND tem uma precedência maior que o operador OR, o que significa que o operador `&&` é executado antes do operador `||` (consulte precedência de operadores).

```js
true || (false && false); // true
true && (false || false); // false
2 === 3 || (4 < 0 && 1 === 1); // false
```

Exemplos
--------

### Usando AND

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

```js
a1 = true && true; // t && t retorna true
a2 = true && false; // t && f retorna false
a3 = false && true; // f && t retorna false
a4 = false && 3 === 4; // f && f retorna false
a5 = "Cat" && "Dog"; // t && t retorna "Dog"
a6 = false && "Cat"; // f && t retorna false
a7 = "Cat" && false; // t && f retorna false
a8 = "" && false; // f && f retorna ""
a9 = false && ""; // f && f retorna false
```

### Regras de conversão para booleanos

#### Convertendo AND para OR

A seguinte operação envolvendo **booleanos**:

```js
bCondition1 && bCondition2
```

é sempre igual a:

```js
!(!bCondition1 || !bCondition2)
```

#### Convertendo OR para AND

A seguinte operação envolvendo **booleanos**:

```js
bCondition1 || bCondition2
```

é sempre igual a:

```js
!(!bCondition1 && !bCondition2)
```

### Removendo parênteses aninhados

Como as expressões lógicas são avaliadas da esquerda para a direita, sempre é possível remover os parênteses de uma expressão complexa desde que certas regras sejam seguidas.

A seguinte operação composta envolvendo **booleanos**:

```js
bCondition1 || (bCondition2 && bCondition3)
```

é sempre igual a:

```js
bCondition1 || bCondition2 && bCondition3
```

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-LogicalANDExpression |

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

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

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

* `Boolean`
* Truthy
* Falsy


typeof - JavaScript

typeof
======

Sumário
-------

O operador `typeof` retorna uma string indicando o tipo de um operando.

Sintaxe
-------

O operador `typeof` pode ser utilizado das seguintes maneiras:
```

typeof operando
```

### Parâmetros

`operand`o é a string, variável, keyword, ou objeto para que o tipo do mesmo seja retornado. O uso de parênteses é opcional.

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

Esta tabela resume os possíveis valores que são retornados pelo `typeof`:

| Tipo | Resultado |
| --- | --- |
| Undefined | `"undefined"` |
| Null | `"object"` |
| Boolean | `"boolean"` |
| Number | `"number"` |
| String | `"string"` |
| Host object (provided by the JS environment) | *Implementation-dependent* |
| Function object (implements [[Call]] in ECMA-262 terms) | `"function"` |
| E4X XML object | "xml" |
| E4X XMLList object | "xml" |
| Qualquer outro objeto | `"object"` |

Exemplos
--------

### Casos comuns

```js
// Números - Numéricos
typeof 37 === "number";
typeof 3.14 === "number";
typeof Math.LN2 === "number";
typeof Infinity === "number";
typeof NaN === "number"; // Apesar de ser "Não-Numérico"
typeof Number(1) === "number"; // mas nunca utilize desta forma!

// Strings - Seqüências de caracteres
typeof "" === "string";
typeof "bla" === "string";
typeof typeof 1 === "string"; // typeof sempre retorna uma string
typeof String("abc") === "string"; // mas nunca utilize desta forma!

// Booleans - Lógicos booleanos
typeof true === "boolean";
typeof false === "boolean";
typeof Boolean(true) === "boolean"; // mas nunca utilize desta forma!

// Undefined - Indefinidos
typeof undefined === "undefined";
typeof blabla === "undefined"; // uma variável indefinida

// Objetos
typeof { a: 1 } === "object";
typeof [1, 2, 4] === "object"; // use Array.isArray ou Object.prototype.toString.call para diferenciar os objetos das arrays
typeof new Date() === "object";

typeof new Boolean(true) === "object"; // isto é confuso, portanto não use desta forma!
typeof new Number(1) === "object"; // isto é confuso, portanto não use desta forma!
typeof new String("abc") === "object"; // isso também é confuso, assim evite usar esta construção!

// Funções
typeof function () {} === "function";
typeof Math.sin === "function";
```

### `null`

```js
// Desde os primóridos do JavaScript
typeof null === "object";
```

Na primeira implementação do JavaScript, valores em JavaScript foram representados com uma tag (etiqueta) de tipo e um valor. A tag de tipo para objetos foi 0. `null` foi representada com o ponteiro NULL (0x00 na maioria das plataformas). Consequentemente, null teve 0 como sua tag de tipo, portanto o `typeof` retorna esse valor. (necessário referência)

Está previsto para ser corrigido na próxima versão do ECMAScript (que estará disponível através de um opt-in). Isso resultará em um `typeof null === 'null'`.

### Expressões regulares

Expressões regulares que podem ser chamadas foram uma adição não-padrão em alguns browsers (necessidade de referência para dizer qual).

```js
typeof /s/ === "function"; // Chrome 1-12 ... // Não-conforme no ECMAScript 5.1
typeof /s/ === "object"; // Firefox 5+ ... // Conforme no ECMAScript 5.1
```

### Outras peculiaridades

#### `alert` versões antigas do Internet Explorer

No IE 6, 7 e 8, `typeof alert === 'object'`

Especificação
-------------

ECMA-262 section 11.4.3

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

* instanceof (en-US)


super - JavaScript

super
=====

A palavra-chave **super** é usada para acessar o objeto pai de um objeto, em outros casos, é usada para acessar a classe pai de uma classe.

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

// chama o objeto (ou construtor) pai
super(...[arguments]);
// chama um método da classe/objeto pai
super.metodo([arguments]);
```

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

Quando usada no construtor de uma classe, a palavra-chave `super` deve ser usada apenas uma vez, e precisa ser usada antes que a palavra-chave `this` possa ser usada. Essa palavra-chave também pode ser usada para chamar uma função ou objeto pai.

Exemplo
-------

### Usando `super` em classes

Esse trecho de código foi obtido através de classes sample (demonstração). Aqui `super()` é chamado para evitar duplicar a parte do construtor que é comum entre `Polygon` e `Square`.

```js
class Polygon {
  constructor(height, width) {
    this.name = "Polygon";
    this.height = height;
    this.width = width;
  }
  sayName() {
    console.log("Hi, I am a ", this.name + ".");
  }
}

class Square extends Polygon {
  constructor(length) {
    this.height; // ReferenceError, precisa chamar o super primeiro!

    // Aqui, ele chama a classe construtora pai com o tamanho
    // provido pelo Polygon -> width e height
    super(length, length);

    // Nota: Em classes derivadas, super() deve ser chamado antes de
    // usar this. Deixar isso de fora vai causar um ReferenceError.
    this.name = "Square";
  }

  get area() {
    return this.height \* this.width;
  }

  set area(value) {
    this.area = value;
  }
}
```

### Super chamando métodos estáticos

Você também pode chamar o super em métodos estáticos.

```js
class Human {
  constructor() {}
  static ping() {
    return "ping";
  }
}

class Computer extends Human {
  constructor() {}
  static pingpong() {
    return super.ping() + " pong";
  }
}
Computer.pingpong(); // 'ping pong'
```

### Ao deletar propriedades do super, será emitido um erro

Você não pode utilizar o delete operator (en-US) e `super.prop` ou `super[expr]` para deletar uma propriedade da classe pai. Isto emitirá um `ReferenceError`.

```js
class Base {
  constructor() {}
  foo() {}
}
class Derived extends Base {
  constructor() {}
  delete() {
    delete super.foo;
  }
}

new Derived().delete(); // ReferenceError: invalid delete involving 'super'.
```

### `Super.prop` não pode sobrescrever propriedades não editáveis

`super`não pode sobrescrever o valor de uma propriedade quando esta houver sido definida como não editável ('writable: false') com, e.g., `Object.defineProperty`.

```js
class X {
  constructor() {
    Object.defineProperty(this, "prop", {
      configurable: true,
      writable: false,
      value: 1,
    });
  }
  f() {
    super.prop = 2;
  }
}

var x = new X();
x.f();
console.log(x.prop); // 1
```

### Usando `super.prop` em objetos literais

`super` também pode ser usado na inicialização da notação literal de objetos. No exemplo abaixo, cada objeto define um método. No segundo objeto, `super` chama o método do primeiro objeto. Isso funciona graças ao `Object.setPrototypeOf()`, com o qual é possível configurar o prototype do `obj2` para o `obj1`, tornando o `super` capaz de encontrar o `method1()` por meio do `obj2`.

```js
var obj1 = {
  method1() {
    console.log("method 1");
  },
};

var obj2 = {
  method2() {
    super.method1();
  },
};

Object.setPrototypeOf(obj2, obj1);
obj2.method2(); // retorna "method 1"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-super-keyword |

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

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

Notas Gecko específicas
-----------------------

* `super()` ainda não funciona como esperado para prototypes nativos.
Veja mais
---------

* Classes


Sintaxe de Espalhamento - JavaScript

Sintaxe de Espalhamento
=======================

**Sintaxe de Espalhamento (Spread syntax)** permite que um objeto iterável, como uma expressão de array ou uma string seja expandido para ser usado onde zero ou mais argumentos (para chamadas de funções) ou elementos (para arrays *literais*) são esperados, ou que um objeto seja expandido onde zero ou mais pares *propriedade:valor* (para objetos *literais*) são esperados.Experimente
-----------

Sintaxe
-------

Para chamada de funções:
```

myFunction(...iterableObj);
```

Para arrays literais ou strings:
```

[...iterableObj, '4', 'five', 6];
```

Para objetos literais (novo em ECMAScript 2018; stage 3 draft):
```

let objClone = { ...obj };
```

Exemplos
--------

### Espalhamento e chamadas de funções

#### Substituindo apply

É comum usar `Function.prototype.apply` em casos onde você quer usar os elementos de um array como argumentos para uma função.

```js
function myFunction(x, y, z) {}
var args = [0, 1, 2];
myFunction.apply(null, args);
```

Com a sintaxe de espalhamento, o código acima pode ser escrito assim:

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

Qualquer argumento numa lista de argumentos pode usar a sintaxe de espalhamento e pode ser usado mais de uma vez.

```js
function myFunction(v, w, x, y, z) {}
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);
```

#### Apply para new

Quando um construtor é chamado com `new`, não é possivel usar diretamente um array e `apply` (`apply` executa o `[[Call]]` e não o `[[Construct]]`). No entanto, um array pode facilmente ser usado com `new` graças ao operador de espalhamento:

```js
var dateFields = [1970, 0, 1]; // 1 Jan 1970
var d = new Date(...dateFields);
```

Para usar o `new` com array de parâmetros sem a sintaxa de espalhamento, você teria que fazer isso **indiretamente** por meio da aplicação parcial:

```js
function applyAndNew(constructor, args) {
  function partial() {
    return constructor.apply(this, args);
  }
  if (typeof constructor.prototype === "object") {
    partial.prototype = Object.create(constructor.prototype);
  }
  return partial;
}

function myConstructor() {
  console.log("arguments.length: " + arguments.length);
  console.log(arguments);
  this.prop1 = "val1";
  this.prop2 = "val2";
}

var myArguments = ["hi", "how", "are", "you", "mr", null];
var myConstructorWithArguments = applyAndNew(myConstructor, myArguments);

console.log(new myConstructorWithArguments());
// (internal log of myConstructor): arguments.length: 6
// (internal log of myConstructor): ["hi", "how", "are", "you", "mr", null]
// (log of "new myConstructorWithArguments"): {prop1: "val1", prop2: "val2"}
```

### Espalhamento em arrays literais

#### Um array literal mais poderoso

Criar um novo array usando um array existente como parte dele, não é possível utilizando apenas a sintaxe de array literal. O código imperativo deve ser usado ao invés da combinação de `push`, `splice`, `concat`, etc. Com a sintaxe de espalhamento isso se torna muito mais sucinto:

```js
var parts = ["shoulders", "knees"];
var lyrics = ["head", ...parts, "and", "toes"];
// ["head", "shoulders", "knees", "and", "toes"]
```

Assim como espalhar a lista de argumentos, `...` pode ser usado em qualquer lugar em um array literal e pode ser usado multiplas vezes.

#### Copiando um array

```js
var arr = [1, 2, 3];
var arr2 = [...arr]; // like arr.slice()
arr2.push(4);

// arr2 becomes [1, 2, 3, 4]
// arr remains unaffected
```

**Nota:** A sintaxe de espalhamento efetivamente vai um nível mais profundo quando se copia um array. Assim sendo, pode ser inadequado para copiar arrays multidimensionais como o exemplo a seguir mostra (é o mesmo com `Object.assign()` e a sintaxe de espalhamento).

```js
var a = [[1], [2], [3]];
var b = [...a];
b.shift().shift(); // 1
// Now array a is affected as well: [[], [2], [3]]
```

#### Uma maneira melhor de concatenar arrays

`Array.concat` é frequentemente usado para concatenar um array no final de um array existente. Sem a sintaxe de espalhamento é feito assim:

```js
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Append all items from arr2 onto arr1
arr1 = arr1.concat(arr2);
```

Com a sintaxe de espalhamento se torna isso:

```js
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2];
```

`Array.unshift` é frequentemente usado para inserir um array de valores no inicio de um array existente. Sem a sintaxe de espalhamento é feito assim:

```js
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// Prepend all items from arr2 onto arr1
Array.prototype.unshift.apply(arr1, arr2); // arr1 is now [3, 4, 5, 0, 1, 2]
```

Com a *sintaxe de espalhamento* isso se torna *[Note, no entanto, que isso cria um novo `arr1` array. Ao contrário de `Array.unshift`, isso não modifica o array original `arr1` array]*:

```js
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr2, ...arr1]; // arr1 is now [3, 4, 5, 0, 1, 2]
```

### Espalhamento em objetos literais

A proposta Rest/Spread Properties for ECMAScript (stage 3) adiciona espalhamento de propriedades para objetos literais. Este copia as propriedades enumeráveis de um objeto informado em um novo objeto.

**Cópia-rasa (Shallow-cloning)** (excluindo o protótipo) ou fusão (**merge**) de objetos agora é possivel usando uma sintaxe mais curta que `Object.assign()`.

```js
var obj1 = { foo: "bar", x: 42 };
var obj2 = { foo: "baz", y: 13 };

var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }
```

Note que `Object.assign()` chamada os setters e a *sintaxe de espalhamento* não.

### Apenas para iteráveis

A sintaxe de espalhamento (diferente de propriedades espalhadas) só pode ser utilizada com objetos iteráveis.

```js
var obj = { key1: "value1" };
var array = [...obj]; // TypeError: obj is not iterable
```

### Espalhamento com muitos valores

Quando usar a sintaxe de espalhamento para chamada de funções, esteja ciente da possibilidade de exceder tamanho máximo de argumentos do motor do Javascript. Veja `apply()` para mais detalhes.

Sintaxe Rest (parâmetros)
-------------------------

A *sintaxe rest* se parece exatamente como a *sintaxe de espalhamento*, mas esta é usada para desestruturar arrays e objetos. De certa forma, a *sintaxe rest* é o oposto da *sintaxe de espalhamento*: A *sintaxe de espalhamento (spread)* 'expande' um array em vários elementos, enquanto a *sintaxe rest* coleta multiplos elementos e 'condensa' eles em um único elemento. Veja parâmetros rest. (en-US)

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-SpreadElement |
| ECMAScript Language Specification # prod-ArgumentList |
| ECMAScript Language Specification # prod-PropertyDefinition |

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

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

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

* Parâmetros Rest (en-US) (also '`...`')


Operador de Agrupamento - JavaScript

Operador de Agrupamento
=======================

Sumário
-------

O operador de agrupamento `()` controla a precedência e a precedência de avaliação em expressões.

Sintaxe
-------
```

 ( )
```

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

O operador de agrupamento consiste em um par de parênteses em volta de uma expressão, ou sub-expressão, para ignorar a precedência normal de operadores de modo que expressões com menor precedência possam ser avaliadas antes de uma expressão com maior prioridade.

Exemplos
--------

Ignorando multiplicação e divisão primeiro, então adição e substração para avarliar adição primeiramente.

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

// default precedence
a + b \* c; // 7
// evaluated by default like this
a + (b \* c); // 7

// now overriding precedence
// addition before multiplication
(a + b) \* c; // 9

// which is equivalent to
a \* c + b \* c; // 9
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-grouping-operator |

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

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

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

* Operator precedence
* `delete` (en-US)
* `typeof`


Atribuição via desestruturação (destructuring assignment) - JavaScript

Atribuição via desestruturação (destructuring assignment)
=========================================================

A sintaxe de **atribuição via desestruturação (destructuring assignment)** é uma expressão JavaScript que possibilita extrair dados de arrays ou objetos em variáveis distintas.

Sintaxe
-------

```js
var a, b, rest;
[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2

[a, b, ...rest] = [1, 2, 3, 4, 5];
console.log(a); // 1
console.log(b); // 2
console.log(rest); // [3, 4, 5]

({ a, b } = { a: 1, b: 2 });
console.log(a); // 1
console.log(b); // 2

// ES2016 - não implementado em Firefox 47a01
({ a, b, ...rest } = { a: 1, b: 2, c: 3, d: 4 });
```

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

As expressões de objeto e matriz literais fornecem uma maneira fácil de criar pacotes *ad hoc* de dados .

```js
var x = [1, 2, 3, 4, 5];
```

A atribuição via desestruturação usa sintaxe similar, mas no lado esquerdo da atribuição são definidos quais elementos devem ser extraídos da variável de origem.

```js
var x = [1, 2, 3, 4, 5];
var [y, z] = x;
console.log(y); // 1
console.log(z); // 2
```

Esse recurso é semelhante aos recursos presentes em linguagens como Perl e Python.

Desestruturação de array
------------------------

### Atribuição básica de variável

```js
var foo = ["one", "two", "three"];

var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"
```

### Atribuição separada da declaração

Uma variável pode ter seu valor atribuído via desestruturação separadamente da declaração dela.

```js
var a, b;

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
```

### Valores padrão

Uma variável pode ser atribuída de um padrão, no caso em que o valor retirado do array é undefined.

```js
var a, b;

[a = 5, b = 7] = [1];
console.log(a); // 1
console.log(b); // 7
```

### Trocando variáveis

Os valores de duas variáveis podem ser trocados em uma expressão de desestruturação.

Sem atribuição via desestruturação, trocar dois valores requer uma variável temporária (ou, em algumas linguagens de baixo nível, o Algoritmo XOR Swap).

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

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
```

### Analisando um array retornado de uma função

Sempre foi possível retornar uma matriz de uma função. A desestruturação pode tornar mais conciso o trabalho com um valor de retorno do tipo array.

Neste exemplo, `f()` retorna os valores `[1, 2]` como saída, que podem ser analisados em uma única linha com desestruturação.

```js
function f() {
  return [1, 2];
}

var a, b;
[a, b] = f();
console.log(a); // 1
console.log(b); // 2
```

### Ignorando alguns valores retornados

Você pode ignorar valores retornados que você não tem interesse:

```js
function f() {
  return [1, 2, 3];
}

var [a, , b] = f();
console.log(a); // 1
console.log(b); // 3
```

Você também pode ignorar todos os valores retornados:

```js
[, ,] = f();
```

### Atribuindo o resto de um array para uma variável

Ao desestruturar um array, você pode atribuir a parte restante deste em uma viáriável usando o padrão rest:

```js
var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
```

### Extraindo valores do resultado de uma expressão regular

Quando o método de expressão regular `exec()` encontra um resultado, ele retorna um array que contém primeiro toda a porção resultante da string e depois cada uma das porções da string resultante envolvidas por parênteses na expressão regular. A atribuição via desestruturação lhe permite extrair as partes desses array facilmente, ignorando a porção resultante completa se não precisar.

```js
var url = "https://developer.mozilla.org/pt-BR/Web/JavaScript";

var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.\*)$/.exec(url);
console.log(parsedURL); // ["https://developer.mozilla.org/pt-BR/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]

var [, protocol, fullhost, fullpath] = parsedURL;

console.log(protocol); // "https"
```

Desestruturação de objeto
-------------------------

### Atribuição básica

```js
var o = { p: 42, q: true };
var { p, q } = o;

console.log(p); // 42
console.log(q); // true
```

### Atribuição sem declaração

Uma variável pode ter seu valor atribuído via desestruturação separadamente da sua declaração.

```js
var a, b;

({ a, b } = { a: 1, b: 2 });
```

**Nota:** Os parênteses `( ... )` ao redor da declaração de atribuição é uma sintaxe necessária quando se utiliza a atribuição via desestruturação de objeto literal sem uma declaração.

`{a, b} = {a:1, b:2}` não é uma sintaxe stand-alone válida, pois `{a, b}` no lado esquerdo é considarada um bloco, não um objeto literal.

No entanto, `({a, b} = {a:1, b:2})` é valida, assim como `var {a, b} = {a:1, b:2}`

### Atribuição para variáveis com novos nomes

Uma variável pode ser extraída de um objeto e atribuída a uma variável com um nome diferente da propriedade do objeto.

```js
var o = { p: 42, q: true };
var { p: foo, q: bar } = o;

console.log(foo); // 42
console.log(bar); // true
```

### Valores padrão

Uma variável pode ser atribuída de um padrão, no caso em que o valor retirado do objeto é undefined.

```js
var { a = 10, b = 5 } = { a: 3 };

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

### Definindo um valor padrão de parâmetro de função

#### Versão ES5

```js
function drawES5Chart(options) {
  options = options === undefined ? {} : options;
  var size = options.size === undefined ? "big" : options.size;
  var cords = options.cords === undefined ? { x: 0, y: 0 } : options.cords;
  var radius = options.radius === undefined ? 25 : options.radius;
  console.log(size, cords, radius);
  // now finally do some chart drawing
}

drawES5Chart({
  cords: { x: 18, y: 30 },
  radius: 30,
});
```

#### Versão ES2015

```js
function drawES2015Chart({
  size = "big",
  cords = { x: 0, y: 0 },
  radius = 25,
} = {}) {
  console.log(size, cords, radius);
  // do some chart drawing
}

drawES2015Chart({
  cords: { x: 18, y: 30 },
  radius: 30,
});
```

### Objeto aninhado e desestruturação de array

```js
var metadata = {
  title: "Scratchpad",
  translations: [
    {
      locale: "de",
      localization\_tags: [],
      last\_edit: "2014-04-14T08:43:37",
      url: "/de/docs/Tools/Scratchpad",
      title: "JavaScript-Umgebung",
    },
  ],
  url: "/pt-BR/docs/Tools/Scratchpad",
};

var {
  title: englishTitle,
  translations: [{ title: localeTitle }],
} = metadata;

console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"
```

### For de iteração e desestruturação

```js
var people = [
  {
    name: "Mike Smith",
    family: {
      mother: "Jane Smith",
      father: "Harry Smith",
      sister: "Samantha Smith",
    },
    age: 35,
  },
  {
    name: "Tom Jones",
    family: {
      mother: "Norah Jones",
      father: "Richard Jones",
      brother: "Howard Jones",
    },
    age: 25,
  },
];

for (var {
  name: n,
  family: { father: f },
} of people) {
  console.log("Name: " + n + ", Father: " + f);
}

// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"
```

### Extraindo campos de objetos passados como parâmetro de função

```js
function userId({ id }) {
  return id;
}

function whois({ displayName: displayName, fullName: { firstName: name } }) {
  console.log(displayName + " is " + name);
}

var user = {
  id: 42,
  displayName: "jdoe",
  fullName: {
    firstName: "John",
    lastName: "Doe",
  },
};

console.log("userId: " + userId(user)); // "userId: 42"
whois(user); // "jdoe is John"
```

Isso extrai o `id`, `displayName` e `firstName` do objeto `user` e os imprime na tela.

### Nomes computados de propriedade de objeto e desestruturação

Nomes computados de propriedades, como em objetos literais, podem ser usados com desestruturação.

```js
let key = "z";
let { [key]: foo } = { z: "bar" };

console.log(foo); // "bar"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-destructuring-assignment |
| ECMAScript Language Specification # sec-destructuring-binding-patterns |

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

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

Notas específicas do Firefox
----------------------------

* O Firefox forneceu uma extensão não-padronizada de linguagem em JS1.7 para desestruturação. Esta extensão foi removida no Gecko 40. Consulte Erro do Firefox 1083498.
* A partir do Gecko 41 e para cumprir com a especificação ES2015, padrões de desestruturação com parênteses, como `([a, b]) = [1, 2]` or `({a, b}) = { a: 1, b: 2 }`, agora são considerados inválidos e lançarão um `SyntaxError` (en-US). Veja a postagem no blog de Jeff Walden e Erro do Firefox 1146136 para mais detalhes.
Veja também
-----------

* Operadores de Atribuição (en-US)
* "ES6 in Depth: Destructuring" on hacks.mozilla.org (em inglês)


Inicializador de Objeto - JavaScript

Inicializador de Objeto
=======================

Objetos podem ser inicializados utilizando `new Object()`, `Object.create()`, ou a notação *literal*. Um inicializador de objetos é uma lista de zero ou mais pares de *propriedade: valor*, separados por vírgula e fechado por um par de chaves (`{}`).

Sintaxe
-------

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

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

var o = {
  propriedade: function ([parâmetros]) {},
  get propriedade() {},
  set propriedade(valor) {},
};
```

### Novas notações em ECMAScript 2015

Por favor, verifique o suporte das anotações na tabela de compatibilidade. Em ambientes que não dão suporte às anotações, ocorrerá erros de sintaxe.

```js
// // Abreviação em nomes de propriedades (ES2015)
var a = "foo",
  b = 42,
  c = {};
var o = { a, b, c };

// // Abreviação em nomes de métodos (ES2015)
var o = {
  property([parameters]) {},
  get property() {},
  set property(value) {},
};

// Nomes de propriedades computados (ES2015)
var prop = "foo";
var o = {
  [prop]: "hey",
  ["b" + "ar"]: "there",
};
```

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

Um inicializador de objetos é uma expressão que descreve a inicialização de um `Object`. Objects consiste de *propriedades*, as quais descrevem um objeto. Os valores das propriedades de um objeto podem ser tipos de dados primitivos ou outros objetos .

### Criando objetos

Um objeto vazio, sem propriedades, pode ser criado como:

```js
var object = {};
```

Contudo, a vantagem em utilizar a notação *literal* ou o *inicializador* é a possibilidade de rapidamente criar objetos com propriedades dentro de chaves (`{}`). Você simplesmente cria uma lista de pares *chave: valor*, separados por vírgula. O código abaixo cria um objeto com três propriedades, sendo as chaves "foo", "age" e "baz", com seus respectivos valores, tipo string de valor "bar", tipo number de valor 42 e, por último, um outro objeto com seus respectivos pares de *chave: valor*.

```js
var object = {
  foo: "bar",
  age: 42,
  baz: { myProp: 12 },
};
```

### Acessando propriedades

Uma vez que você criou um objeto, é interessante que possa ler ou alterá-lo. As propriedades de um objeto podem ser acessadas utilizando a notação de ponto ou colchetes. Veja assessores de propriedade para mais informações.

```js
object.foo; // "bar"
object["age"]; // 42

object.foo = "baz";
```

### Definições de propriedade

Nós temos aprendido como descrever propriedades utilizando a sintaxe *inicializador*. No entanto, às vezes, há variáveis que queremos inserir em nosso objeto. Então teremos um código parecido como abaixo:

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

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

Com ECMAScript 2015, há uma notação mais curta que possibilita atingir o mesmo resultado:

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

// Abreviação em nomes de propriedades (ES2015)
var o = { a, b, c };

// Em outras palavras,
console.log(o.a === { a }.a); // true
```

#### Duplicação em nomes de propriedades

Quando se está utilizando o mesmo nome para suas propriedades, a última sobrescreverá as anteriores.

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

Em códigos ECMAScript 5 no modo estrito, duplicação em nomes de propriedades serão consideradas `SyntaxError` (en-US). Porém, com a introdução de "nomes de propriedades computadas", tornou-se possível a duplicação das propriedades em tempo de execução. Assim, ECMAScript 2015 removeu a restrição.

```js
function haveES2015DuplicatePropertySemantics() {
  "use strict";
  try {
    ({ prop: 1, prop: 2 });

    // No error thrown, duplicate property names allowed in strict mode
    return true;
  } catch (e) {
    // Error thrown, duplicates prohibited in strict mode
    return false;
  }
}
```

### Definição de métodos

Uma propriedade de um objeto pode se referir à function, ou aos métodos getter ou setter.

```js
var o = {
  propriedade: function ([parâmetros]) {},
  get propriedade() {},
  set propriedade(valor) {},
};
```

No ECMAScript 2015, uma notação abreviada está disponível, dispensando o uso da palavra reservada "function".

```js
// Abreviações em nomes de métodos (ES2015)
var o = {
  propriedade([parâmetros]) {},
  get propriedade() {},
  set propriedade(valor) {},
  \*gerador() {},
};
```

Com ECMAScript 2015, há uma forma concisa em criar propriedades cujo valor é uma função gerador.

```js
var o = {
  \* gerador() {
    ...........
  }
};
```

Mas em ECMAScript 5, você escreveria (lembrar que em ES5 não há geradores):

```js
var o = {
  generator: function \*() {
    ...........
  }
};
```

Para mais informações e exemplos, veja definições de método.

### Nomes de propriedades computados

Começando com ECMAScript 2015, a sintaxe *inicializador* de objeto também suporta "nomes de propriedades computados". Isso permite que você possa inserir uma expressão dentro de colchetes `[]`, que será computada como o nome de uma propriedade. Isto é semelhante à notação de chaves utilizado em acessor de propriedade, utilizado para ler a alterar as propriedades existentes em um objeto. Segue um exemplo utilizando a mesma sintaxe em objetos literais:

```js
// Nomes de propriedades computados (ES2015)
var i = 0;
var a = {
  ["foo" + ++i]: i,
  ["foo" + ++i]: i,
  ["foo" + ++i]: i,
};

console.log(a.foo1); // 1
console.log(a.foo2); // 2
console.log(a.foo3); // 3

var param = "size";
var config = {
  [param]: 12,
  ["mobile" + param.charAt(0).toUpperCase() + param.slice(1)]: 4,
};

console.log(config); // { size: 12, mobileSize: 4 }
```

### Mutação Prototype

Uma definição de propriedade na forma de `__proto__: valor` or `"__proto__": valor` não cria uma propriedade com o nome `__proto__`. Inclusive, se o valor fornecido for um objeto ou `null`, muda o `[[Prototype]]` do objeto criado para o valor informado. (Se o valor fornecido não é um objeto ou null, o valor não será alterado.)

```js
var obj1 = {};
assert(Object.getPrototypeOf(obj1) === Object.prototype);

var obj2 = { \_\_proto\_\_: null };
assert(Object.getPrototypeOf(obj2) === null);

var protoObj = {};
var obj3 = { \_\_proto\_\_: protoObj };
assert(Object.getPrototypeOf(obj3) === protoObj);

var obj4 = { \_\_proto\_\_: "not an object or null" };
assert(Object.getPrototypeOf(obj4) === Object.prototype);
assert(!obj4.hasOwnProperty("\_\_proto\_\_"));
```

Apenas uma única mudança em prototype é permitida em um objeto: múltiplas mudanças gera erro de sintaxe.

Definições de propriedade que não utilizam da notação de ":", não são consideradas mudanças de prototype: são definições de propriedades que se comportam de forma semelhante às definições utilizando qualquer outro nome.

```js
var __proto__ = "variable";

var obj1 = { __proto__ };
assert(Object.getPrototypeOf(obj1) === Object.prototype);
assert(obj1.hasOwnProperty("\_\_proto\_\_"));
assert(obj1.__proto__ === "variable");

var obj2 = {
  \_\_proto\_\_() {
    return "hello";
  },
};
assert(obj2.\_\_proto\_\_() === "hello");

var obj3 = { ["\_\_prot" + "o\_\_"]: 17 };
assert(obj3.__proto__ === 17);
```

Notação de objeto literal vs JSON
---------------------------------

A notação de objeto literal não é a mesma de **J**ava**S**cript **O**bject **N**otation (JSON). Mesmo que possuam semelhanças, há as seguintes diferenças:

* JSON permite definições de propriedades utilizando apenas aspas duplas, como `"propriedade": valor`. E a definição não pode ser abreviada.
* Os valores JSON podem ser apenas strings, numbers, arrays, `true`, `false`, `null`, ou outro objeto JSON.
* Uma função como valor (veja "Métodos" acima) não pode ser atribuido em JSON.
* Objetos como `Date` serão do tipo string após `JSON.parse()`.
* `JSON.parse()` rejeitará "nomes de propriedades computados" e um erro será lançado.
Especificações
--------------

| Specification |
| --- |
| ECMAScript Language Specification # sec-object-initializer |

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

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

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

* Assesores de propriedade
* `get` / `set`
* Definições de métodos
* Lexical grammar


Bitwise XOR (^) - JavaScript

Bitwise XOR (^)
===============

O operador bitwise XOR (`^`) retorna o numero 1 em cada posição de bit para a qual os bits correspondentes de ambos, mas não de ambos os operandos, são `1`s.

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

Sintaxe
-------
```

a ^ b
```

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

Os operandos são convertidos em números inteiros de 32 bits e expressados por uma série de bits (zeros e uns). Numeros com mais de 32 bits descartam seus bits mais significativos. Por exemplo, o número inteiro a seguir com mais de 32 bits será convertido em um número inteiro de 32 bits:
```

Antes: 11100110111110100000000000000110000000000001
Depois:            10100000000000000110000000000001
```

Cada bit no primeiro operando é emparelhado com o bit correspondente no segundo operando: primeiro bit para o primeiro bit, segundo bit para o segundo bit e assim por diante.

O operador é aplicado para cada par de bits e o resultado é construído em bitwise.

A tabela verdade para a operação XOR é:

| a | b | a XOR b |
| --- | --- | --- |
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |

```js
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
    14 (base 10) = 00000000000000000000000000001110 (base 2)
                   --------------------------------
14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
```

Bitwise XORing any number `x` with `0` yields `x`.

Exemplos
--------

### Usando bitwise XOR

```js
// 9 (00000000000000000000000000001001)
// 14 (00000000000000000000000000001110)

14 ^ 9;
// 7 (00000000000000000000000000000111)
```

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-BitwiseXORExpression |

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

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

Leia também
-----------

* Bitwise operators in the JS guide
* Bitwise XOR assignment operator (en-US)


new operator - JavaScript

new operator
============

O **operador `new`** cria uma instancia de um tipo de objeto definido pelo usuário ou de um dos tipos nativos (*built-in*) que possuem uma função construtora.

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

 A fonte deste exemplo interativo é armazenada em um repositório do GitHub. Se você gostaria de contribuir para o projeto de exemplos interativos, clone https://github.com/mdn/interactive-examples e nos envie uma requisição de comando pull.Sintaxe
-------
```

new construtor[([argumentos])]
```

### Parametros

`construtor`

Uma função que especifica o tipo da instância do objeto.

`argumentos`

Uma lista de valores com os quais o construtor será chamado.

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

Criar um objeto definido pelo usuário requer dois passos:

1. Definir o tipo de objeto através da escrita de uma função.
2. Criar uma instancia do objeto utilizando `new`.

Para definir um tipo de objeto, crie uma função para o tipo de objetivo que especifica seu nome e propriedades. Um objeto pode ter uma propriedade que é um outro objeto. Veja os exemplos abaixo:

Quando o código `new Foo(...)` é executado, acontece o seguinte::

1. Um novo objeto é criado, herdando de `Foo.prototype`.
2. A função construtora *F`oo`* é chamado com os argumentos especificados, e com `this` vinculado ao novo objeto criado. `new Foo` é equivalente a `new Foo()`, ou seja, se nenhuma lista de argumentos for especificada, *Foo* é chamado sem argumentos.
3. O objeto retornado pela função construtora é o resultado de toda expressão `new`. Se a função construtora não retornar um objeto explicitamente, o objeto criado no passo 1 é então usado. (Normalmente construtores não retornam um valor, mas eles podem escolher fazê-lo se eles quiserem sobrescrever o processo normal de criação de objeto.)

Você sempre pode adicionar uma propriedade à um objeto definido previamente. Por exemplo, `carro1.cor = "preta"` adiciona a propriedade `cor` em `carro1`, e atribui a ela o valor de "`preta`". Entretanto, isso não afeta os outros objetos. Para adicionar a nova propriedade a todos objetos do mesmo tipo, você deve adicionar a propriedade à definição do tipo de objeto `Carro`.

Você pode adicionar uma propriedade compartilhada à um tipo de objeto definido anteriormente através do uso da propriedade `Function.prototype` (en-US). Isso define uma propriedade que é compartilhada por todos os objetos criados com essa função, ao invés de apenas uma instancia do tipo de objeto. O código a seguir adiciona uma propriedade cor com valor `null` à todos objetos do tipo `carro`, e então sobrescreve aquele valor com a string "`preta`" somente no objeto de instancia `carro1`. Para mais informações veja prototype (en-US).

```js
function Carro() {}
carro1 = new Carro();

console.log(carro1.cor); // undefined

Carro.prototype.cor = null;
console.log(carro1.cor); // null

carro1.cor = "preta";
console.log(carro1.cor); // preta
```

Exemplos
--------

### Tipo de objeto e instância de objeto

Suponha que você quer criar um tipo de objeto para carros. Você quer que esse tipo de objeto se chame `carro`, e quer que ele tenha propriedade para fabricante, modelo e ano. Para fazer isso, você escreveria a função a seguir:

```js
function Carro(fabricante, modelo, ano) {
  this.fabricante = fabricante;
  this.modelo = modelo;
  this.ano = ano;
}
```

Agora você pode criar um objeto chamado `meucarro` como a seguir:

```js
var meucarro = new Carro("Eagle", "Talon TSi", 1993);
```

Essa declaração cria `meucarro` e atribui a ele os valores especificados as suas propriedades. Então o valor de `meucarro.fabricante` é a string "Eagle", `meucarro.ano` é o inteiro 1993, e assim sucessivamente.

Você pode criar qualquer numero de objetos `carro` através de chamadas a `new`. Por exemplo:

```js
var carrodoken = new Carro("Nissan", "300ZX", 1992);
```

### Propriedade do objeto que é outro objeto

Suponha que você defina um objeto chamado `pessoa` como a seguir:

```js
function Pessoa(nome, idade, sexo) {
  this.nome = nome;
  this.idade = idade;
  this.sexo = sexo;
}
```

E então instancia dois novos objetos `pessoa` como a seguir:

```js
var rand = new Pessoa("Rand McNally", 33, "M");
var ken = new Pessoa("Ken Jones", 39, "M");
```

Então você pode reescrever a definição de `carro` para incluir uma propriedade dono que aceita um objeto pessoa, como a seguir:

```js
function Carro(fabricante, modelo, ano, dono) {
  this.fabricante = fabricante;
  this.modelo = modelo;
  this.ano = ano;
  this.dono = dono;
}
```

Para instanciar os novos objetos, você então usa o seguinte:

```js
var carro1 = new Carro("Eagle", "Talon TSi", 1993, rand);
var carro2 = new Carro("Nissan", "300ZX", 1992, ken);
```

Ao invés de passar uma string ou valor inteiro quando criar os novos objetos, as definições acima passam objetos `rand` e `ken` como os parâmetros para os donos. Para descobrir o nome do dono do `carro2`, você pode acessar a seguinte propriedade:

```js
carro2.dono.nome;
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-new-operator |

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

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

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

* `Function`
* `Reflect.construct()`


Operador Condicional Ternário - JavaScript

Operador Condicional Ternário
=============================

Sumário
-------

O **operador condicional (ternário)** é o único operador JavaScript que possui três operandos. Este operador é frequentemente usado como um atalho para a instrução `if`.

Sintaxe
-------
```

condition ? expr1 : expr2
```

Parâmetros
----------

`condition`

Uma expressão que é avaliada como `true` ou `false`.

`expr1`, `expr2`

Expressões com valores de qualquer tipo.

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

Se `condition` é `true`, o operador retornará o valor de `expr1`; se não, ele retorna o valor de `exp2`. Por exemplo, para exibir uma mensagem diferente baseada no valor da variável `isMember`, você poderá utilizar o código (statement) seguinte:

```js
"The fee is " + (isMember ? "$2.00" : "$10.00");
```

Conforme o resultado da operação, você também poderá atribuir a variáveis:

```js
var elvisLives = Math.PI > 4 ? "Yep" : "Nope";
```

Também são possíveis múltiplas avaliaçãoes ternárias (nota: o operador condicional é associativo a direita):

```js
var firstCheck = false,
  secondCheck = false,
  access = firstCheck
    ? "Access denied"
    : secondCheck
      ? "Access denied"
      : "Access granted";

console.log(access); // logs "Access granted"
```

Você também pode usar avaliações ternárias no espaço livre de modo a fazer diferentes operações:

```js
var stop = false,
  age = 16;

age > 18 ? location.assign("continue.html") : (stop = true);
```

Você também pode fazer mais do que uma única operação em cada caso, separando-os por vírgula:

```js
var stop = false,
  age = 23;

age > 18
  ? (alert("OK, you can go."), location.assign("continue.html"))
  : ((stop = true), alert("Sorry, you are much too young!"));
```

Você também pode fazer mais de uma operação durante a atribuição de um valor. Neste caso, **o último valor separado por vírgula dentro** dos parênteses **será o valor a ser atribuído**.

```js
var age = 16;

var url =
  age > 18
    ? (alert("OK, you can go."),
      // alert returns "undefined", but it will be ignored because
      // isn't the last comma-separated value of the parenthesis
      "continue.html") // the value to be assigned if age > 18
    : (alert("You are much too young!"),
      alert("Sorry :-("),
      // etc. etc.
      "stop.html"); // the value to be assigned if !(age > 18)

location.assign(url); // "stop.html"
```

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-conditional-operator |

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

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

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

* Operador condicional if


import.meta - JavaScript

import.meta
===========

O objeto **`import.meta`** mostra os metadados específicos do contexto de um módulo JavaScript. Ele contém informações sobre o módulo, como a sua URL.

Sintaxe
-------
```

import.meta
```

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

A sintaxe consiste na palavra chave `import`, um ponto, e o identificador `meta`. Normalmente no lado esquerdo do ponto é o objeto na qual a propriedade de acesso é realizada is, mas aqui `import` não é exatamente um objeto.

O objeto`import.meta` foi criado no implementação ECMAScript,com um protótipo `null`. O objeto é extensível, e suas propriedades são grávaveis, configuráveis, e enumeráveis.

Exemplos
--------

### Usando import.meta

Dado o modulo `my-module.js`

```html
<script type="module" src="my-module.js"></script>
```

Você pode acessar essa meta informação sobre o modulo usando o objeto `import.meta.`

```js
console.log(import.meta); // { url: "file:///home/user/my-module.js" }
```

Irá retornar um objeto com propriedade URL indicando a base URL do módulo. Isso vai ser o URL da qual o script obteve, por scripts external, ou a base do documento URL contendo documento, para scripts inline.

Note que isso irá incluir parâmetros query e/ou cerquilha (i.e., seguindo o `?` ou `#`).

Por exemplo, seguindo esse HTML:

```html
<script type="module">
 import "./index.mjs?someURLInfo=5";
</script>
```

O arquivo JavaScript a seguir vai registrar o parâmetro `someURLInfo`:

```js
// index.mjs
new URL(import.meta.url).searchParams.get("someURLInfo"); // 5
```

O mesmo se aplica quando um arquivo importa outro:

```js
// index.mjs
import "./index2.mjs?someURLInfo=5";

// index2.mjs
new URL(import.meta.url).searchParams.get("someURLInfo"); // 5
```

Note que enquanto o Node.js vai passar nos parâmetros query (ou na cerquilha) como no exemplo passsado, a partir do Node 14.1.0, a URL com parâmetro query vai dar erro quando carregar no formulário `node --experimental-modules index.mjs?someURLInfo=5` (é tratado como um arquivo ao invés de uma URL nesse contexto).

Nesse arquivo específico, o argumento passado pode ser complementar para ser usado na ampla aplicação `location.href` (com strings query ou cerquilha adicionada depois do caminho de arquivo HTML) (ou por Node.js, através do `process.argv`).

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

| Specification |
| --- |
| ECMAScript Language Specification # prod-ImportMeta |
| HTML Standard # hostgetimportmetaproperties |

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

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

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

* `import`
* `export`


Operador de coalescência nula - JavaScript

Operador de coalescência nula
=============================

O **operador de coalescência nula (`??`)** é um operador lógico que retorna o seu operando do lado direito quando o seu operador do lado esquerdo é `null` ou `undefined`. Caso contrário, ele retorna o seu operando do lado esquerdo.

Ao contrário do operador lógico OR (`||`), o operando esquerdo é retornado se houver um valor *falsy* (falso) que não seja `null` ou `undefined`. Em outras palavras, se você usar `||` para obter algum valor padrão para outra variável `foo`, você pode enfrentar comportamentos inesperados se você considerar algum valor falseável como utilizável (eg. `''` ou `0`). Veja abaixo alguns exemplos:

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

Sintaxe
-------
```

exprEsq ?? exprDir
```

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

O operador de coalescência nula retorna os resultados da expressão de seu lado direito se a expressão de seu lado esquerdo for `null` ou `undefined`.

### Endereçando um valor padrão à variável

Inicialmente, quando se deseja endereçar um valor padrão à variável, um padrão comum é utilizar o operador lógico OR (`||`):

```js
let foo;

// foo nunca é endereçado a nenhum valor, portanto, ainda está indefinido
let someDummyText = foo || "Hello!";
```

Entretanto, devido ao `||` ser um operador lógico booleano, o operando do lado esquerdo é coagido para um valor booleano para sua avaliação e qualquer valor *falseável* (`0`, `''`, `NaN`, `null`, `undefined`) não é retornado. Este comportamento pode causar consequencias inesperadas se você considerar `0`, `''`, ou `NaN` como valores válidos.

```js
let count = 0;
let text = "";

let qty = count || 42;
let message = text || "Olá!";
console.log(qty); // 42 e não 0
console.log(message); // "Olá!" e não ""
```

O operador de coalescência nula evita esta cilada pois retorna o segundo operando apenas quando o primeiro é avaliado entre os valores `null` ou `undefined` (mas nehum outro valor falseável):

```js
let myText = ""; // Uma string vazia (que também é um valor falseável)

let notFalsyText = myText || "Olá mundo";
console.log(notFalsyText); // Olá mundo

let preservingFalsy = myText ?? "Olá vizinhança";
console.log(preservingFalsy); // '' (Pois myText não é undefined e nem null)
```

### Curto-circuito

Assim como os operadores lógicos OR e AND, a expressão do lado direito não é avaliada se o lado esquerdo não for avaliado entre `null` e nem `undefined`.

```js
function A() {
  console.log("A foi chamado");
  return undefined;
}
function B() {
  console.log("B foi chamado");
  return false;
}
function C() {
  console.log("C foi chamado");
  return "foo";
}

console.log(A() ?? C());
// Imprime "A foi chamado" então "C foi chamado" e por fim "foo"
// Como A() retornou undefined então ambas expressões foram avaliadas

console.log(B() ?? C());
// Imprime "B foi chamado" então "false"
// Como B() retornou false (e não null ou undefined), a expressão
// do lado direito não foi avaliada.
```

### Sem encadeamento com os operadores AND e OR

Não é possível encadear ambos operadores AND (`&&`) e OR (`||`) diretamente com o `??`. Um `SyntaxError` (en-US) será disparado nesse tipo de caso.

```js
null || undefined ?? "foo"; // Dispara um SyntaxError
true || undefined ?? "foo"; // Dispara um SyntaxError
```

Entretanto, explicitar diretamente a precedência por meio de parênteses resulta no comportamento correto:

```js
(null || undefined) ?? "foo"; // retorna "foo"
```

### Relacionamento com o operador de encadeamento opcional (`?.`)

O operador de coalescêcia nula trata `undefined` e `null` como valores específicos e então executa o operador de encadeamento opcional (`?.`) o qual é útil para acessar uma propriedade de um objeto, o qual pode ser `null` ou `undefined`.

```js
let foo = { someFooProp: "oi" };

console.log(foo.someFooProp?.toUpperCase()); // "OI"
console.log(foo.someBarProp?.toUpperCase()); // undefined
```

Exemplo
-------

Neste exemplo, nós iremos prover valores padrão, mas manter valores que não sejam (advinha???) `null` ou `undefined`.

```js
const nullValue = null;
const emptyText = ""; // falseável (falsy)
const someNumber = 42;

const valA = nullValue ?? "padrão para A";
const valB = emptyText ?? "padrão para B";
const valC = someNumber ?? 0;

console.log(valA); // "padrão para A"
console.log(valB); // "" (pois a string vazia não é null ou undefined)
console.log(valC); // 42
```

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

| Especificação | Status | comentário |
| --- | --- | --- |
| Proposal for the "nullish coalescing" operator | Stage 4 |  |

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

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

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

* The optional chaining operator
* The logical OR (`||`) operator
* Default parameters in functions


class expression - JavaScript

class expression
================

A **expressão class** é uma das formas de definir uma classe no ECMAScript 2015. Parecido com as expressões function, expressões class poder ser nomeadas ou não. Se nomeada, o nome da classe é local para apenas o corpo da classe. Classes no JavaScript usam herança com base no prototype

Sintaxe
-------
```

var MinhaClasse = class [nomeDaClass] [extends] {
  // corpo da classe
};
```

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

Uma expressão de classe tem uma sintaxe similar a uma declaração de classe. No entanto, com expressões de classe, você poderá omitir o nome da classe ("ligação de identificadores"), que você não pode se usar declarações. Adicionalmente, expressões de classe permitem que você redefina/redeclare classes e **não invocar** nenhum tipo de erros como declaração de classe. A propriedade construtora é opcional. E o *typeof* de classes geradas usando essa palavra-chave sempre será "function".

Assim como declarações de classes, o corpo das expressões de classe são executados em strict mode.

```js
"use strict";
var Foo = class {}; // propriedade de construtor é opcional
var Foo = class {}; // Re-declaração é permitida

typeof Foo; //retorna "function"
typeof class {}; //retorna "function"

Foo instanceof Object; // true
Foo instanceof Function; // true
class Foo {} // Throws TypeError, não permite re-declaração
```

Exemplos
--------

### Uma simples expressão de classe

Isso é apenas uma simples classe anônima que você pode referir usando a variável "Foo".

```js
var Foo = class {
  constructor() {}
  bar() {
    return "Olá mundo!";
  }
};

var instance = new Foo();
instance.bar(); // "Olá mundo!"
Foo.name; // "Foo"
```

### Expressões de classes nomeadas

Se você quiser referir a classe atual dentro do corpo da classe, você pode criar uma expressão de classe nomeada. Esse nome é visível apenas no escopo da expressão classe sozinha.

```js
var Foo = class NamedFoo {
  constructor() {}
  whoIsThere() {
    return NamedFoo.name;
  }
};
var bar = new Foo();
bar.whoIsThere(); // "NamedFoo"
NamedFoo.name; // ReferenceError: NamedFoo is not defined
Foo.name; // "NamedFoo"
```

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

* Expressão `function`
* Declaração `class`
* Classes


void operator - JavaScript

void operator
=============

O **`operador void`** avalia a expressão dada e, em seguida, retorna `undefined`.

Sintaxe
-------
```

void expressão
```

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

Este operador permite a inserção de expressões que produzem efeitos secundários em lugares onde uma expressão que avalia a ação `undefined` é desejada.

O operador `void` é muitas vezes utilizado apenas para obter o valor primitivo `undefined`, geralmente usando "`void(0)`" (o que equivale a "`void 0`"). Nestes casos, a variável global `undefined` pode ser utilizado em vez (supondo que ele não tenha sido atribuído a um valor não-padrão).

Chamada imediata das expressões da função
-----------------------------------------

Quando usamos uma Chamada imediata das expressões da função, valores nulos podem ser usado para forçar a palavra-chave da função a ser tratada como uma expressão em vez de uma declaração.

```js
void (function iife() {
  var bar = function () {};
  var baz = function () {};
  var foo = function () {
    bar();
    baz();
  };
  var biz = function () {};

  foo();
  biz();
})();
```

JavaScript URIs
---------------

Quando o navegador segue uma URI `javascript`, ele avalia o código na URI e então troca o conteúdo da página pelo valor retornado por este, a não ser que o valor retornado seja `undefined`. O operador `void` pode ser usado para retornar `undefined`. Por exemplo:

```html
<a href="javascript:void(0);">Clique aqui para não fazer nada</a>

<a href="javascript:void(document.body.style.backgroundColor='green');">
  Clique aqui para o papel de parede ser verde
</a>
```

Note que no entanto o pseudo protocolo `javascript:` tem seu uso desencorajado perante outras alternativas como *unobtrusive event handlers*.

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-void-operator |

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

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

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

* `undefined`