Usando promises - JavaScript

Usando promises
===============

* « Previous
* Next »

Uma `Promise` é um objeto que representa a eventual conclusão ou falha de uma operação assíncrona. Como a maioria das pessoas consomem promises já criadas, este guia explicará o consumo de promises devolvidas antes de explicar como criá-las.

Essencialmente, uma promise é um objeto retornado para o qual você adiciona callbacks, em vez de passar callbacks para uma função.

Por exemplo, em vez de uma função old-style que espera dois callbacks, e chama um deles em uma eventual conclusão ou falha:

```js
function successCallback(result) {
  console.log("It succeeded with " + result);
}

function failureCallback(error) {
  console.log("It failed with " + error);
}

doSomething(successCallback, failureCallback);
```

…funções modernas retornam uma promise e então você pode adicionar seus callbacks:

```js
const promise = doSomething();
promise.then(successCallback, failureCallback);
```

…ou simplesmente:

```js
doSomething().then(successCallback, failureCallback);
```

Nós chamamos isso de *chamada de função assíncrona*. Essa convenção tem várias vantagens. Vamos explorar cada uma delas.

Garantias
---------

Ao contrário dos callbacks com retornos de funções old-style, uma promise vem com algumas garantias:

* Callbacks nunca serão chamados antes da conclusão da execução atual do loop de eventos do JavaScript.
* Callbacks adicionadas com .then mesmo *depois* do sucesso ou falha da operação assíncrona, serão chamadas, como acima.
* Multiplos callbacks podem ser adicionados chamando-se .then várias vezes, para serem executados independentemente da ordem de inserção.

Mas o benefício mais imediato das promises é o encadeamento.

Encadeamento
------------

Uma necessidade comum é executar duas ou mais operações assíncronas consecutivas, onde cada operação subsequente começa quando a operação anterior é bem sucedida, com o resultado do passo anterior. Nós conseguimos isso criando uma *cadeia de promises*.

Aqui está a mágica: a função `then` retorna uma nova promise, diferente da original:

```js
const promise = doSomething();
const promise2 = promise.then(successCallback, failureCallback);
```

ou

```js
const promise2 = doSomething().then(successCallback, failureCallback);
```

Essa segunda promise representa a conclusão não apenas de `doSomething()`, mas também do `successCallback` ou `failureCallback` que você passou, que podem ser outras funções assíncronas que retornam uma promise. Quando esse for o caso, quaisquer callbacks adicionados a `promise2` serão enfileiradas atrás da promise retornada por `successCallback` ou `failureCallback`.

Basicamente, cada promise representa a completude de outro passo assíncrono na cadeia.

Antigamente, realizar operações assíncronas comuns em uma linha levaria à clássica pirâmide da desgraça:

```js
doSomething(function (result) {
  doSomethingElse(
    result,
    function (newResult) {
      doThirdThing(
        newResult,
        function (finalResult) {
          console.log("Got the final result: " + finalResult);
        },
        failureCallback,
      );
    },
    failureCallback,
  );
}, failureCallback);
```

Ao invés disso, com funções modernas, nós atribuímos nossas callbacks às promises retornadas, formando uma *cadeia de promise*:

```js
doSomething()
  .then(function (result) {
    return doSomethingElse(result);
  })
  .then(function (newResult) {
    return doThirdThing(newResult);
  })
  .then(function (finalResult) {
    console.log("Got the final result: " + finalResult);
  })
  .catch(failureCallback);
```

Os argumentos para `then` são opcionais, e `catch(failureCallback)` é uma abreviação para `then(null, failureCallback)`. Você pode também pode ver isso escrito com arrow functions:

```js
doSomething()
  .then((result) => doSomethingElse(result))
  .then((newResult) => doThirdThing(newResult))
  .then((finalResult) => {
    console.log(`Got the final result: ${finalResult}`);
  })
  .catch(failureCallback);
```

**Importante:** Sempre retorne um resultado, de outra forma as callbacks não vão capturar o resultado da promise anterior.

### Encadeando depois de um catch

É possivel encadear *depois* de uma falha, i.e um `catch`. Isso é muito útil para realizar novas ações mesmo depois de uma falha no encadeamento. Leia o seguinte exemplo:

```js
new Promise((resolve, reject) => {
  console.log("Initial");

  resolve();
})
  .then(() => {
    throw new Error("Something failed");

    console.log("Do this");
  })
  .catch(() => {
    console.log("Do that");
  })
  .then(() => {
    console.log("Do this whatever happened before");
  });
```

Isso vai produzir o seguinte texto:
```

Initial
Do that
Do this whatever happened before
```

Observe que o texto "Do this" não foi impresso por conta que o erro "Something failed" causou uma rejeição.

Propagação de erros
-------------------

Na pirâmide da desgraça vista anteriormente, você pode se lembrar de ter visto `failureCallback` três vezes, em comparação a uma única vez no fim da corrente de promises:

```js
doSomething()
  .then((result) => doSomethingElse(result))
  .then((newResult) => doThirdThing(newResult))
  .then((finalResult) => console.log(`Got the final result: ${finalResult}`))
  .catch(failureCallback);
```

Basicamente, uma corrente de promises para se houver uma exceção, procurando por catch handlers no lugar. Essa modelagem de código segue bastante a maneira de como o código síncrono funciona:

```js
try {
  const result = syncDoSomething();
  const newResult = syncDoSomethingElse(result);
  const finalResult = syncDoThirdThing(newResult);
  console.log(`Got the final result: ${finalResult}`);
} catch (error) {
  failureCallback(error);
}
```

Essa simetria com código assíncrono resulta no *syntactic sugar* `async`/`await` presente no ECMAScript 2017:

```js
async function foo() {
  try {
    const result = await doSomething();
    const newResult = await doSomethingElse(result);
    const finalResult = await doThirdThing(newResult);
    console.log(`Got the final result: ${finalResult}`);
  } catch (error) {
    failureCallback(error);
  }
}
```

É construído sobre promises, por exemplo, `doSomething()` é a mesma função que antes. Leia mais sobre a sintaxe aqui.

Por pegar todos os erros, até mesmo exceções jogadas(*thrown exceptions*) e erros de programação, as promises acabam por solucionar uma falha fundamental presente na pirâmide da desgraça dos callbacks. Essa característica é essencial para a composição funcional das operações assíncronas.

Criando uma Promise em torno de uma callback API antiga
-------------------------------------------------------

Uma `Promise` pode ser criada do zero utilizando o seu construtor. Isto deve ser necessário apenas para o envolvimento de APIs antigas.

Em um mundo ideal, todas as funções assíncronas já retornariam promises. Infelizmente, algumas APIs ainda esperam que os retornos de sucesso e/ou falha sejam passados da maneira antiga. O exemplo por excelência é o `setTimeout()` (en-US) function:

```js
setTimeout(() => saySomething("10 seconds passed"), 10000);
```

Misturar chamadas de retorno e promises de *old-style* é problemático. Se `saySomething` falhar ou contiver um erro de programação, nada o captura.

Por sorte nós podemos envolvê-la em uma promise. É uma boa prática envolver funções problemáticas no menor nivel possível, e nunca chamá-las diretamente de novo:

```js
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

wait(10000)
  .then(() => saySomething("10 seconds"))
  .catch(failureCallback);
```

Basicamente, um construtor de promises pega uma função executora que nos deixa resolver ou rejeitar uma promise manualmente. Desde que `setTimeout` não falhe, nós deixamos a rejeição de fora neste caso.

Composição
----------

`Promise.resolve()` e `Promise.reject()` são atalhos para se criar manualmente uma promise que já foi resolvida ou rejeitada, respectivamente. Isso pode ser útil em algumas situações.

`Promise.all()` e `Promise.race()` são duas ferramentas de composição para se executar operações assíncronas em paralelo.

Uma composição sequencial é possível usando JavaScript de uma forma esperta:

```js
[func1, func2].reduce((p, f) => p.then(f), Promise.resolve());
```

Basicamente reduzimos um vetor de funções assíncronas a uma cadeia de promises equivalentes a: `Promise.resolve().then(func1).then(func2);`

Isso também pode ser feito com uma função de composição reutilizável, que é comum em programação funcional:

```js
const applyAsync = (acc, val) => acc.then(val);
const composeAsync =
  (...funcs) =>
  (x) =>
    funcs.reduce(applyAsync, Promise.resolve(x));
```

A função composeAsync aceitará qualquer número de funções como argumentos e retornará uma nova função que aceita um valor inicial a ser passado pelo pipeline de composição. Isso é benéfico porque alguma, ou todas as funções, podem ser assíncronas ou síncronas, e é garantido de que serão executadas na ordem correta.

```js
const transformData = composeAsync(func1, asyncFunc1, asyncFunc2, func2);
transformData(data);
```

No ECMAScript 2017, uma composição sequencial pode ser feita de forma mais simples com async/await:

```js
for (const f of [func1, func2]) {
  await f();
}
```

Cronometragem
-------------

Para evitar surpresas, funções passadas para `then` nunca serão chamadas sincronamente, mesmo com uma função já resolvida:

```js
Promise.resolve().then(() => console.log(2));
console.log(1); // 1, 2
```

Ao invés de rodar imediatamente, a função passada é colocada em uma micro tarefa, o que significa que ela roda depois que a fila estiver vazia no final do atual processo de evento de loop do Javascript, ou seja: muito em breve:

```js
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

wait().then(() => console.log(4));
Promise.resolve()
  .then(() => console.log(2))
  .then(() => console.log(3));
console.log(1); // 1, 2, 3, 4
```

Ver também
----------

* `Promise.then()`
* Promises/A+ specification
* Venkatraman.R - JS Promise (Part 1, Basics)
* Venkatraman.R - JS Promise (Part 2 - Using Q.js, When.js and RSVP.js)
* Venkatraman.R - Tools for Promises Unit Testing
* Nolan Lawson: We have a problem with promises — Common mistakes with promises
* « Previous
* Next »


Controle de Fluxo e Manipulação de Erro - JavaScript

Controle de Fluxo e Manipulação de Erro
=======================================

* « Previous
* Next »

O JavaScript suporta um conjunto compacto de declarações, especificamente de fluxo de controle, que você pode utilizar para atribuir uma grande interatividade a páginas web. Este capítulo fornece uma visão geral destas declarações.

Veja a Referência do JavaScript para detalhes sobre as declarações mostradas neste capítulo. No código em JavaScript, o caractere ponto e vírgula (`;`) é utilizado para separar declarações.

Toda expressão também é uma declaração. Veja Expressões e Operadores para informações completas sobre expressões.

Declaração em bloco
-------------------

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

{
   declaracao_1;
   declaracao_2;
   .
   .
   .
   declaracao_n;
}
```

### Exemplo

Declarações em bloco são utilizadas geralmente com declarações de fluxo de controle (ex. `if`, `for`, `while`).

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

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

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

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

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

Declarações condicionais
------------------------

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

### Declaração if...else

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

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

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

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

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

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

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

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

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

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

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

#### Valores avaliados como falsos

Os seguintes valores são avaliados como falsos:

* `false`
* `undefined`
* `null`
* `0`
* `NaN`
* string vazia (`""`)

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

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

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

#### Exemplo

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

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

### Declaração switch

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

switch (expressao) {
   case rotulo_1:
      declaracoes_1
      [break;]
   case rotulo_2:
      declaracoes_2
      [break;]
   ...
   default:
      declaracoes_padrao
      [break;]
}
```

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

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

#### Exemplo

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

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

Declarações de Manipulação de Error
-----------------------------------

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

* Declaração throw
* Declaração `try...catch`
### Tipos de exceções

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

* ECMAScript exceptions
* `DOMException` (en-US) and `DOMError` (en-US)
### `Declaração throw`

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

throw expressão;
```

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

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

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

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

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

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

### `Declaração try...catch`

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

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

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

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

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

#### O bloco `catch`

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

catch (catchID) {
  declaracoes
}
```

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

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

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

#### O bloco `finally`

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

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

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

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

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

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

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

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

// SAIDA
// captura interior "falso"
```

#### Aninhando declarações try...catch

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

### Utilizando objetos de `erro`

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

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

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

Promises
--------

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

Uma Promise assume um destes estados:

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

![](/pt-BR/docs/Web/JavaScript/Guide/Control_flow_and_error_handling/promises.png)

### Carregando uma imagem com XHR

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

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

Para uma informação mais detalhada, consulte a página de referência `Promise`.

* « Previous
* Next »


Arrays tipados no JavaScript - JavaScript

Arrays tipados no JavaScript
============================

Os arrays tipados do Javascript são objetos parecidos com arrays convencionais, e fornecem um mecanismo para lidar com dados binários em sua forma "bruta". Como você já deve saber, objetos do tipo `Array` aumentam e encolhem dinamicamente, e podem conter qualquer tipo de valor possível no Javascript. Os interpretadores Javascript realizam otimizações para que estes arrays sejam rápidos de se manipular. Todavia, à medida em que as aplicações web tornam-se mais e mais poderosas, adicionando recursos como manipulação de áudio e vídeo, acesso a dados brutos utilizando WebSockets, e assim por diante, tornou-se claro que há momentos em que seria útil ao código Javascript ser capaz de manipular dados binários "brutos" em arrays tipados, de forma rápida e fácil.Entretanto, os arrays tipados não devem ser confundidos com arrays convencionais, já que invocar o método `Array.isArray()` em um array tipado retornará `false`. Além disso, nem todos os métodos disponíveis para arrays normais são suportados pelos arrays tipados (ex. push e pop).Buffers e views: a arquitetura dos arrays tipados
-------------------------------------------------

Para alcançar a máxima flexibilidade e eficiência, os arrays tipados do Javascript dividem sua implementação entre **buffers** e **views**. Um buffer (implementado pelo objeto `ArrayBuffer`) é um objeto que representa um fragmento (chunk) de dados; Não possui formato para ser discutido, e não oferece mecanismos para acessar seu conteúdo. Para acessar os dados contidos em um buffer, você precisa utilizar uma view. Uma view fornece um contexto — isto é, um tipo de dado, o deslocamento inicial, e o número de elementos — que transforma estes dados em um array tipado.

![Typed arrays in an ArrayBuffer](/pt-BR/docs/Web/JavaScript/Guide/Typed_arrays/typed_arrays.png)

### ArrayBuffer

O `ArrayBuffer` é um tipo de dado que é utilizado para representar um buffer genérico de dados binários, com comprimento fixo. Você não pode manipular diretamente o conteúdo de um `ArrayBuffer`; ao invés, você cria uma view de array tipado ou um objeto do tipo `DataView`, que representa o buffer em um formato específico, e os utiliza para ler e escrever no conteúdo do buffer.

### Views de arrays tipados

As views de arrays tipados possuem nomes auto descritivos e fornecem exibições para todos os tipos numéricos habituais, como `Int8`, `Uint32`, `Float64` e assim por diante. Há uma view de array tipado especial, a view `Uint8ClampedArray`. Ela comporta os valores entre `0` e `255`. Isto é útil no processamento de dados do Canvas (en-US), por exemplo.

{{page("/pt-BR/docs/Web/JavaScript/Reference/Global\_Objects/TypedArray", "TypedArray\_objects")}}### DataView

O objeto do tipo `DataView` é uma interface de baixo nível que fornece uma API no estilo *getter*/*setter* para ler e escrever dados arbitrários ao buffer. Isto é útil quando se está lidando com diferentes tipos de dados, por exemplo. As views de arrays tipados estão em ordem de bytes nativa (veja Endianness) da sua plataforma. Com uma `DataView` você é capaz de controlar a ordem dos bytes. Esta ordem é *big-endian* por padrão e pode ser alterada para *little-endian* através dos métodos *getters* e *setters* citados anteriormente.

Web APIs que utilizam arrays tipados
------------------------------------

`FileReader.prototype.readAsArrayBuffer()`

O método `FileReader.prototype.readAsArrayBuffer()` inicia a leitura do conteúdo de um objeto do tipo Blob ou FIle especificado.

`XMLHttpRequest.prototype.send()`

O método `send()` das instâncias de `XMLHttpRequest` agora suportam arrays tipados e objetos do tipo `ArrayBuffer` como argumento.

`ImageData.data` (en-US)

É objeto do tipo `Uint8ClampedArray` (en-US) que representa uma matriz unidimensional que contém dados na ordem RGBA, com valores numéricos entre `0` e `255` inclusive.

Exemplos
--------

### Utilizando views com buffers

Primeiramente, nós precisamos criar um buffer, com um tamanho fixo de 16 bytes neste caso:

```js
var buffer = new ArrayBuffer(16);
```

Neste ponto, nós temos um fragmento de memória cujos bytes estão todos pré-inicializados em `0`. Não há muito que possamos fazer com isto, no entanto. Nós podemos confirmar que possuem de fato 16 bytes de comprimento, e isso é tudo sobre ele:

```js
if (buffer.byteLength === 16) {
  console.log("Sim, são 16 bytes.");
} else {
  console.log("Ah não, o tamanho não está certo!");
}
```

Antes de realmente começarmos a trabalhar com este buffer, precisamos criar uma view. Vamos criar uma view que trata os dados neste buffer como um array de inteiros assinados de 32 bits:

```js
var int32View = new Int32Array(buffer);
```

Agora nós podemos acessar os campos neste array assim como em um array convencional:

```js
for (var i = 0; i < int32View.length; i++) {
  int32View[i] = i \* 2;
}
```

Isto preenche as 4 posições do array (4 posições com 4 bytes cada uma, produzindo um total de 16 bytes) com os valores `0`, `2`, `4` e `6`.

### Multiplas views dos mesmos dados

As coisas começar a ficar realmente interessantes quando você considera que é possível criar múltiplas views para os mesmos dados. Por exemplo, dado o código acima, nós podemos continuar desta forma:

```js
var int16View = new Int16Array(buffer);

for (var i = 0; i < int16View.length; i++) {
  console.log("Posição " + i + ": " + int16View[i]);
}
```

Aqui nós criamos uma view de inteiros de 16 bits que compartilha o mesmo buffer que a view de 32 bits existente, e emitimos todos os valores no buffer como inteiros de 16 bits. Agora nós obtemos a saída `0`, `0`, `2`, `0`, `4`, `0`, `6`, `0`.

Você pode ir um pouco mais longe, no entanto. Considere isto:

```js
int16View[0] = 32;
console.log("Entra 0 na matriz de 32 bits agora é " + int32View[0]);
```

A saída disso é "Entrada 0 na matriz de 32 bits agora é 32". Em outras palavras, as duas matrizes são, na verdade, apenas vistas no mesmo buffer de dados, tratando-as como formatos diferentes. Você pode fazer isso com qualquer tipo de visualização (en-US).

### Trabalhando com Estruturas de Dados Complexas

Ao combinar um único buffer com várias exibições de diferentes tipos, iniciando em diferentes deslocamentos no buffer, você pode interagir com objetos de dados contendo vários tipos de dados. Isso permite, por exemplo, interagir com estruturas de dados complexas de WebGL, arquivos de dados ou estruturas C que você precisa usar ao usar js-ctypes.

Considere esta estrutura em C:

```cpp
struct someStruct {
  unsigned long id;
  char username[16];
  float amountDue;
};
```

Você pode acessar um buffer contendo dados neste formato assim:

```js
var buffer = new ArrayBuffer(24);

// ... leia os dados no buffer ...

var idView = new Uint32Array(buffer, 0, 1);
var usernameView = new Uint8Array(buffer, 4, 16);
var amountDueView = new Float32Array(buffer, 20, 1);
```

Então você pode acessar, por exemplo, o devido valor com `amountDueView[0]`.

**Nota:** O alinhamento da estrutura de dados em uma estrutura em C depende da plataforma. Tome precauções e considerações para essas diferenças de preenchumento.

### Conversão para arrays normais

Depois de processar uma array tipada, às vezes é útil convertê-la de volta em uma array normal para se beneficiar do `Array` prototype. Isso pode ser feito usando `Array.from`, ou usando o seguinte código onde `Array.from` não é suportado.

```js
var typedArray = new Uint8Array([1, 2, 3, 4]),
  normalArray = Array.prototype.slice.call(typedArray);
normalArray.length === 4;
normalArray.constructor === Array;
```

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

* Getting `ArrayBuffer`s or typed arrays from *Base64*-encoded strings (en-US)
* `StringView` – a C-like representation of strings based on typed arrays
* Faster Canvas Pixel Manipulation with Typed Arrays
* Typed Arrays: Binary Data in the Browser
* Endianness


Formatando texto - JavaScript

Formatando texto
================

* « Previous
* Next »

Esse capítulo introduz como trabalhar com strings e texto em JavaScript.

Strings
-------

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

### Strings literais

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

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

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

#### Sequências de escape hexadecimais

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

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

#### Sequências de escape unicode

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

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

#### Sequências de escape Unicode code point

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

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

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

// o mesmo com escapes Unicode simples
"\uD87E\uDC04";
```

### Objetos String

O objeto `String` é como uma "capa" ao redor do tipo primitivo string.

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

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

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

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

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

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

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

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

| Método | Descrição |
| --- | --- |
| `charAt`, `charCodeAt`, `codePointAt` | Retorna o código do caractere ou o caractere em uma posição específica na string. |
| `indexOf`, `lastIndexOf` | Retorna a posição de uma substring específica na string ou a última posição da substring específica, respectivamente. |
| `startsWith`, `endsWith`, `includes` | Retorna se uma string começa, termina ou contém uma outra string específica. |
| `concat` | Concatena o texto de duas strings e retorna uma nova string. |
| `fromCharCode`, `fromCodePoint` | Cria uma string a partir de uma sequência específica de valores Unicode. Esse é um método da classe String, não de uma instância do tipo String. |
| `split` | Separa um objeto `String` em um array de strings, separando a string em substrings. |
| `slice` | Extrai uma seção de uma string e retorna uma nova string. |
| `substring`, `substr` | Retorna um subconjunto específico de uma string, definindo os índices inicial e final, ou definindo um índice e um tamanho. |
| `match`, `replace`, `search` | Trabalha com expressões regulares. |
| `toLowerCase`, `toUpperCase` | Retorna a string com todos caracteres em minúsculo, ou maiúsculo, respectivamente. |
| `normalize` | Retorna a Forma Normalizada Unicode (Unicode Normalization Form) da string que chama o método. |
| `repeat` | Retorna uma string contendo os elementos do objeto repetidos pela quantidade de vezes dada. |
| `trim` | Retira espaços em branco no começo e no final da string. |

### Template strings com várias linhas

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

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

#### Várias linhas (Multi-lines)

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

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

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

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

#### Expressões inseridas

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

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

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

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

Para mais informações, leia sobre Template strings na referência JavaScript.

Internacionalização
-------------------

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

### Formatação de data e hora

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

```js
var msPorDia = 24 \* 60 \* 60 \* 1000; // número de milisegundos em um dia

// July 17, 2014 00:00:00 UTC.
var july172014 = new Date(msPorDia \* (44 \* 365 + 11 + 197));

var opcoes = {
  year: "2-digit",
  month: "2-digit",
  day: "2-digit",
  hour: "2-digit",
  minute: "2-digit",
  timeZoneName: "short",
};
var americanDateTime = new Intl.DateTimeFormat("en-US", opcoes).format;

console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT
```

### Formatação de números

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

```js
var precoGasolina = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  minimumFractionDigits: 3,
});

console.log(precoGasolina.format(5.259)); // $5.259

var hanDecimalRMBInChina = new Intl.NumberFormat("zh-CN-u-nu-hanidec", {
  style: "currency",
  currency: "CNY",
});

console.log(hanDecimalRMBInChina.format(1314.25)); // ￥ 一,三一四.二五
```

### Collation

O objeto `Collator` (en-US) é usado para comparar e ordenar strings.

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

```js
var nomes = ["Hochberg", "Hönigswald", "Holzman"];

var phonebookAlemao = new Intl.Collator("de-DE-u-co-phonebk");

// como se ordenasse ["Hochberg", "Hoenigswald", "Holzman"]:
console.log(names.sort(phonebookAlemao.compare).join(", "));
// imprime "Hochberg, Hönigswald, Holzman"
```

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

```js
var dicionarioAlemao = new Intl.Collator("de-DE-u-co-dict");

// como se ordenasse ["Hochberg", "Honigswald", "Holzman"]:
console.log(names.sort(dicionarioAlemao.compare).join(", "));
// imprime "Hochberg, Holzman, Hönigswald"
```

Para mais informação sobre a API `Intl`, veja também Introducing the JavaScript Internationalization API (em inglês).

* « Previous
* Next »


Meta programação - JavaScript

Meta programação
================

* « Previous

Começando com ECMAScript 6, o JavaScript ganha suporte para os objetos `Proxy` e `Reflect`, permitindo você interceptar e definir o comportamento personalizado para operações fundamentais da linguagem (por exemplo, pesquisa de propriedade, atribuição, enumeração, invocação de função, etc). Com a ajuda destes dois objetos você será capaz de programar a nível meta em JavaScript.

Proxies
-------

Introduzido em ECMAScript 6, objetos `Proxy` permitem que você intercepte determinadas operações e implementar comportamentos personalizados. Por exemplo, receber uma propriedade em um objeto:

```js
var handler = {
  get: function (target, name) {
    return name in target ? target[name] : 42;
  },
};
var p = new Proxy({}, handler);
p.a = 1;
console.log(p.a, p.b); // 1, 42
```

O objeto Proxy define um `target` (um objeto vazio aqui) e um objeto `handler` em que um `get` *trap* é implementado. Aqui, um objeto que está em proxy não retornará indefinido quando receber propriedades indefinidas, mas, ao contrário, retornar o número 42.

Exemplos adicionais estão disponíveis na página de referência de `Proxy` .

### Terminologia

Os seguintes termos são usados quando se fala sobre a funcionalidade de proxies.

handler (en-US)

Espaço reservado de objeto que contenha traps.

traps

Os métodos que fornecem acesso de propriedade. Isto é análogo ao conceito de traps em sistemas operacionais.

target

Objeto que o proxy está virtualizando. Ele é frequentemente usado como backend de armazenamento para o proxy. Invariantes (semânticas que permanecem inalteradas) relativas a objetos que não podem ser extendidos ou propriedades que não podem ser configuradas são comparadas com o target.

invariantes

Semânticas que permanecem inalteradas na execução de operações personalizadas são chamados de *invariantes*. Se você violar as invariantes de um manipulador, um `TypeError` será lançado.

Handlers e traps
----------------

A tabela a seguir resume as traps disponíveis aos objetos do tipo Proxy. Veja as páginas de referência (en-US) para explicações detalhadas e exemplos.

| Handler / trap | Interceptions | Invariants |
| --- | --- | --- |
| `handler.getPrototypeOf()` (en-US) | `Object.getPrototypeOf()``Reflect.getPrototypeOf()` (en-US)`__proto__``Object.prototype.isPrototypeOf()``instanceof` | * O método `getPrototypeOf` deve retornar um object ou
 `null`.
* Se `target` não puder ser extendido, o método
 `Object.getPrototypeOf(proxy)` deve retornar o mesmo
 valor que `Object.getPrototypeOf(target)`.
 |
| `handler.setPrototypeOf()` (en-US) | `Object.setPrototypeOf()``Reflect.setPrototypeOf()` (en-US) |
 Se `target` não puder ser extendido, o parâmetro
 `prototype` dever ter o mesmo valor que
 `Object.getPrototypeOf(target)`.
  |
| `handler.isExtensible()` (en-US) | `Object.isExtensible()``Reflect.isExtensible()` (en-US) | `Object.isExtensible(proxy)` deve retornar o mesmo valor que
 `Object.isExtensible(target)`.
  |
| `handler.preventExtensions()` (en-US) | `Object.preventExtensions()``Reflect.preventExtensions()` (en-US) | `Object.preventExtensions(proxy)` retorna
 `true` somente se
 `Object.isExtensible(proxy)` retornar `false`.
  |
| `handler.getOwnPropertyDescriptor()` (en-US) | `Object.getOwnPropertyDescriptor()``Reflect.getOwnPropertyDescriptor()` (en-US) | * `getOwnPropertyDescriptor` deve retornar um object ou
 `undefined`.
* Uma propriedade não pode ser descrita como não existente se ela
 existir como uma propriedade própria e não configurável do objeto
 alvo.
* Uma propriedade não pode ser relatada como inexistente, se existir
 como uma propriedade própria do objeto de destino e o objeto de
 destino não for extensível.
* Uma propriedade não pode ser relatada como existente, se não existir
 como uma propriedade própria do objeto de destino e o objeto de
 destino não for extensível.
* Uma propriedade não pode ser relatada como não configurável, se não
 existir como uma propriedade própria do objeto de destino ou se
 existir como uma propriedade própria configurável do objeto de
 destino.
* O resultado de
 `Object.getOwnPropertyDescriptor(target)` pode ser
 aplicado ao objeto de destino usando
 `Object.defineProperty` e não emitirá uma exceção.
 |
| `handler.defineProperty()` (en-US) | `Object.defineProperty()``Reflect.defineProperty()` | * Uma propriedade não pode ser adicionada se o objeto de destino não
 for extensível.
* Uma propriedade não pode ser adicionada como ou modificada para não
 ser configurável, se não existir como uma propriedade própria não
 configurável do objeto de destino.
* Uma propriedade pode não ser não configurável, se existir uma
 propriedade configurável correspondente do objeto de destino.
* Se uma propriedade tiver uma propriedade de objeto de destino
 correspondente
 `Object.defineProperty(target, prop, descriptor)` não
 lançará uma exceção.
* No modo estrito, um valor de retorno `false` do
 manipulador `defineProperty` manipulador lançará um
 `TypeError` exceção.
 |
| `handler.has()` (en-US) |
 Property query: `foo in proxy`Inherited property query:
 `foo in Object.create(proxy)``Reflect.has()` (en-US) | * Uma propriedade não pode ser relatada como inexistente, se existir
 como uma propriedade própria não configurável do objeto de destino.
* Uma propriedade não pode ser relatada como inexistente, se existir
 como uma propriedade própria do objeto de destino e o objeto de
 destino não for extensível.
 |
| `handler.get()` (en-US) | 1
 Property access: `proxy[foo]`and `proxy.bar`Inherited property access: `Object.create(proxy)[foo]``Reflect.get()` (en-US) | * O valor relatado para uma propriedade deve ser igual ao valor da
 propriedade do objeto de destino correspondente se a propriedade do
 objeto de destino for uma propriedade de dados não gravável e não
 configurável.
* O valor relatado para uma propriedade deve ser indefinido se a
 propriedade do objeto de destino correspondente for uma propriedade
 acessora não configurável que tenha sido indefinida como seu
 atributo [[Get]].
 |
| `handler.set()` (en-US) |
 Property assignment: `proxy[foo] = bar` and
 `proxy.foo = bar`Inherited property assignment:
 `Object.create(proxy)[foo] = bar``Reflect.set()` | * Não é possível alterar o valor de uma propriedade para ser diferente
 do valor da propriedade do objeto de destino correspondente se a
 propriedade do objeto de destino correspondente for uma propriedade
 de dados não gravável e não configurável.
* Não é possível definir o valor de uma propriedade se a propriedade
 do objeto de destino correspondente for uma propriedade acessadora
 não configurável que tenha `undefined` como seu atributo
 [[Set]].
* No modo estrito, um valor de retorno `false` do
 manipulador `set` lançará uma exceção
 `TypeError`.
 |
| `handler.deleteProperty()` (en-US) |
 Property deletion: `delete proxy[foo]` and
 `delete proxy.foo``Reflect.deleteProperty()` (en-US) |
 Uma propriedade não pode ser excluída, se existir como uma propriedade
 própria não configurável do objeto de destino.
  |
| `handler.enumerate()` |
 Property enumeration / for...in:
 `for (var name in proxy) {...}``Reflect.enumerate()` | O método `enumerate` deve retornar um objeto. |
| `handler.ownKeys()` (en-US) | `Object.getOwnPropertyNames()``Object.getOwnPropertySymbols()``Object.keys()``Reflect.ownKeys()` (en-US) | * O resultado de `ownKeys` é uma lista.
* O tipo de cada elemento da lista de resultados é
 `String` ou `Symbol`.
* A lista de resultados deve conter as chaves de todas as propriedades
 próprias não configuráveis do objeto de destino.
* Se o objeto de destino não for extensível, a Lista de resultados
 deverá conter todas as chaves das próprias propriedades do objeto de
 destino e nenhum outro valor.
 |
| `handler.apply()` (en-US) | `proxy(..args)``Function.prototype.apply()` and
 `Function.prototype.call()``Reflect.apply()` | Não há invariantes para o método `handler.apply` |
| `handler.construct()` (en-US) | `new proxy(...args)``Reflect.construct()` | O resultado deve ser um `Object`. |

Proxy Revogável
---------------

O método `Proxy.revocable()` (en-US) é utilizado para criar um objeto Proxy revogável. Isso significa que o proxy pode ser revogado através da função `revoke`, desligando-o. Depois disso, qualquer operação com o proxy lançará um `TypeError`.

```js
var revocable = Proxy.revocable(
  {},
  {
    get: function (target, name) {
      return "[[" + name + "]]";
    },
  },
);
var proxy = revocable.proxy;
console.log(proxy.foo); // "[[foo]]"

revocable.revoke();

console.log(proxy.foo); // TypeError é lançado
proxy.foo = 1; // TypeError novamente
delete proxy.foo; // ainda um TypeError
typeof proxy; // "object", typeof não desencadeia nenhuma trap
```

Reflexão
--------

`Reflect` é um objeto embutido que contém métodos que permitem a criação de operações interceptáveis em JavaScript. Os métodos são iguais àqueles de proxy handlers (en-US). `Reflect` não é um objeto do tipo function.

`Reflect` auxilia no encaminhamento de operações padrão do handler para o target.

`Reflect.has()` (en-US), por exemplo, tem o mesmo efeito prático que o operador in, com a facilidade de ser utilizado como uma função:

```js
Reflect.has(Object, "assign"); // true
```

### Uma função `apply` melhorada

Em ES5, você normalmente utiliza o método `Function.prototype.apply()` para invocar uma função com um dado valor para `this` e `arguments` fornecido como um array (ou um objeto parecido com um array).

```js
Function.prototype.apply.call(Math.floor, undefined, [1.75]);
```

Com `Reflect.apply` essa operação se torna menos verbosa e mais fácil de compreender:

```js
Reflect.apply(Math.floor, undefined, [1.75]);
// 1;

Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
// "hello"

Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index;
// 4

Reflect.apply("".charAt, "ponies", [3]);
// "i"
```

### Verificando se a definição da propriedade obteve sucesso

Com `Object.defineProperty`, a qual retorna um `object` em caso de sucesso ou lança um `TypeError` em caso contrário, você utilizaria um bloco `try...catch` para capturar qualquer erro que tenha ocorrido ao definir uma propriedade. Devido ao fato de `Reflect.defineProperty` retornar um status do tipo `Boolean`, você pode simplesmente utilizar aqui um bloco `if...else`:

```js
if (Reflect.defineProperty(target, property, attributes)) {
  // success
} else {
  // failure
}
```

* « Previous


:nth-of-type() - CSS

:nth-of-type()
==============

A pseudo-classe CSS **`:nth-of-type()`** corresponde a um ou mais elementos de um dado tipo, baseado em sua posição entre um grupo de irmãos.

```css
/\* Seleciona cada quarto elemento <p>
 entre qualquer grupo de irmãos \*/
p:nth-of-type(4n) {
  color: lime;
}
```

Sintaxe
-------

A pseudo-classe `nth-of-type` é especificada com um único argumento, o qual representa o padrão para a correspondência dos elementos.

Veja `:nth-child` para uma explicação mais detalhada de sua sintaxe.

### Sintaxe formal

Error: could not find syntax for this itemExemplos
--------

### Exemplo básico

#### HTML

```html
<div>
  <div>Este elemento não é contado.</div>
  <p>1º parágrafo.</p>
  <p>2º parágrafo.</p>
  <div>Este elemento não é contado.</div>
  <p>3º parágrafo.</p>
  <p>4º parágrafo.</p>
</div>
```

#### CSS

```css
/\* Parágrafos ímpares \*/
p:nth-of-type(2n + 1) {
  color: red;
}

/\* Parágrafos pares \*/
p:nth-of-type(2n) {
  color: blue;
}

/\* Primeiro parágrafo \*/
p:nth-of-type(1) {
  font-weight: bold;
}
```

#### Resultado

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

| Specification |
| --- |
| Selectors Level 4 # nth-of-type-pseudo |

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

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

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

* `:nth-child`, `:nth-last-of-type` (en-US)


Valor usado - CSS

Valor usado
===========

O **valor usado** de uma propriedade CSS é o valor final dessa propriedade depois de todos os cálculos terem sido executados.

After the user agent has finished its calculations, every CSS property has a used value. The used values of dimensions (e.g., `width`, `line-height`) are in pixels. The used values of shorthand properties (e.g., background) are consistent with those of their component properties (e.g., `background-color`, `display)` and with `position` and `float`.

For some properties, JavaScript can retrieve the used value through the window.getComputedStyle (en-US) method.

Detalhes
--------

There are four steps to calculating any CSS property's final value. First, the specified value (en-US) is the result of cascading (choosing the most specific stylesheet rule that changes the property), inheritance (en-US) (using the same computed value as a parent if the property is inheritable), or using the default. Then, the computed value (en-US) is calculated according to the specification (for example, a `span` with `position: absolute` will have its computed `display` changed to `block`). Then, layout is calculated (dimensions that are `auto` or percentages relative to a parent are replaced with pixel values), and the result is the **used value**.

Finally, transformed according to the limitations of the local environment, the result is actual value. The actual value is the used value after any approximations have been applied. For example, a user agent may only be able to render borders with integer pixel widths, and therefore have to approximate the computed width, or the user agent may be forced to use only black and white shades, instead of full color. These steps are calculated internally.

JavaScript can read only the final used values with window.getComputedStyle (en-US). This method may instead return computed values, depending on the property. The values it returns are generically called `resolved values` (en-US)).

Exemplo
-------

Compute and show the used width of three elements (updates on resize):

### HTML

```html
<div id="no-width">
  <p>No explicit width.</p>
  <p class="show-used-width">..</p>

  <div id="width-50">
    <p>Explicit width: 50%.</p>
    <p class="show-used-width">..</p>

    <div id="width-inherit">
      <p>Explicit width: inherit.</p>
      <p class="show-used-width">..</p>
    </div>
  </div>
</div>
```

### CSS

```css
#no-width {
  width: auto;
}

#width-50 {
  width: 50%;
}

#width-inherit {
  width: inherit;
}

/\* Make results easier to see: \*/
div {
  border: 1px solid red;
  padding: 8px;
}
```

### JavaScript

```js
function updateUsedWidth(id) {
  var div = document.getElementById(id);
  var par = document.querySelector(`#${id} .show-used-width`);
  var wid = window.getComputedStyle(div)["width"];
  par.textContent = `Used width: ${wid}.`;
}

function updateAllUsedWidths() {
  updateUsedWidth("no-width");
  updateUsedWidth("width-50");
  updateUsedWidth("width-inherit");
}

updateAllUsedWidths();
window.addEventListener("resize", updateAllUsedWidths);
```

### Resultado

Diferentes valores computados
-----------------------------

CSS 2.0 defined only computed value (en-US) as the last step in a property's calculation. Then, CSS 2.1 introduced the distinct definition of used value. An element could then explicitly inherit a width/height of a parent, whose computed value is a percentage. For CSS properties that don't depend on layout (e.g., display, font-size, line-height), the computed values and used values are the same. These are the CSS 2.1 properties that do depend on layout, so they have a different computed value and used value: (taken from CSS 2.1 Changes: Specified, computed, and actual values):

* background-position
* bottom, left, right, top
* height, width
* margin-bottom, margin-left, margin-right, margin-top,
* min-height, min-width
* padding-bottom, padding-left, padding-right, padding-top
* text-indent
Especificações
--------------

CSS Level 2: Used Values

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

* CSS Reference (en-US)
* window.getComputedStyle (en-US)


align-items - CSS

align-items
===========

A propriedade CSS **`align-items`** estabelece o valor `align-self` em todos filhos diretos como um grupo. A propriedade align-self estabelece o alinhamento de um certo item dentro do bloco que o contém. Em Flexbox ele controla o alinhamento dos itens em Cross Axis (en-US), enquanto que no Grid Layout, controla o alinhamento dos itens no Eixo de Bloco dentro de sua grid area.

O exemplo interativo abaixo demonstra alguns dos valores para `align-items` usando grid layout.

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

Sintaxe
-------

```css
/\* Palavras-chave básicas \*/
align-items: normal;
align-items: stretch;

/\* Posicionamento do alinhamento \*/
/\* align-items não recebe valores left e right \*/
align-items: center; /\* Itens posicionados ao redor do centro \*/
align-items: start; /\* Posiciona itens a partir do início \*/
align-items: end; /\* Posiciona itens a partir do fim \*/
align-items: flex-start; /\* Posiciona itens-flex a partir do início \*/
align-items: flex-end; /\* Posiciona itens-flex a partir do fim \*/
align-items: self-start;
align-items: self-end;

/\* Alinhamento da baseline \*/
align-items: baseline;
align-items: first baseline;
align-items: last baseline; /\* Overflow alinhamento (apenas para alinhamento de posição) \*/
align-items: safe center;
align-items: unsafe center;

/\* Valores globais \*/
align-items: inherit;
align-items: initial;
align-items: unset;
```

### Valores

`normal`

O efeito desta palavra-chave depende do modo de layout em que nos encontramos:

* Em layouts absolutamente posicionados, a palavra-chave se comporta como `start` em *replaced* de caixas absolutamente posicionadas, e como `stretch` em *all others* de caixas absolutamente posicionadas.
* Em posição estática de layouts absolutamente posicionados, a palavra-chave se comporta como `stretch`.
* Para itens-flex, a palavra chave se comporto como `stretch`.
* Para itens-grid, esta palavra-chave leva a um comportamento similiar ao `stretch`, exceto para caixas com um aspect ratio ou tamanhos intrínsecos, onde se comporta como `start`.
* A propriedade não se aplica para caixas block-level, e para células de tabela.

`flex-start`

As bordas da margem superior dos itens-flex são juntados com a borda superior da linha.

`flex-end`

As bordas da margem inferior dos itens flex são juntados com a borda inferior da linha.

`center`

As caixas de margem dos itens flex são centralizados ao longo da linha do eixo. Caso o tamanho de um item seja superior ao container flex, irá transbordar de maneira igual em ambas direções.

`start`

Os itens são posicionados, para cada um, em direção a borda início do container de alinhamento no eixo apropriado.

`end`

Os itens são posicionados, para cada um, em direção a borda fim do container de alinhamento no eixo apropriado.

`self-start`

Os itens são posicionados para a borda do container de alinhamento do lado inicial do item, no eixo apropriado.

`self-end`

Os itens são posicionados para a borda do container de alinhamento do lado final do item, no eixo apropriado.

`baseline`

`first baseline`

`last baseline`

Todos itens-flex são alinhados de tal forma que suas baselines de container flex estejam alinhados. O item com a maior distância entre o eixo de início de sua margem e sua baseline é juntado com eixo de início da linha.

`stretch`

Itens-flex são esticados de tal maneira que o tamanho da caixa de margem do item seja o mesmo da linha, respeitando as restrições de comprimento e altura.

`safe`

Usado em conjunto com uma palavra-chave de alinhamento. Se a palavra-chave escolhida signifique que o item transborde o alinhamento do container, causando assim perda de dados, o item é alinhado como estivesse no modo `start`.

`unsafe`

Usado em conjunto com uma palavra-chave de alinhamento. Independente dos tamanhos relativos do item, do alinhamento do container e caso overflow possa causar perda de dados, o valor de alinhamento estabelecido é mantido.

### Sintaxe formal
```

align-items =
  normal                                    | (en-US)
  stretch                                   | (en-US)
  <baseline-position>                       | (en-US)
  [ (en-US) <overflow-position>? (en-US) <self-position> ] (en-US)  | (en-US)
  anchor-center

<baseline-position> =
  [ (en-US) first | (en-US) last ] (en-US)? (en-US)  && (en-US)
  baseline

<overflow-position> =
  unsafe  | (en-US)
  safe

<self-position> =
  center      | (en-US)
  start       | (en-US)
  end         | (en-US)
  self-start  | (en-US)
  self-end    | (en-US)
  flex-start  | (en-US)
  flex-end

```

Exemplo
-------

### CSS

```css
#container {
  height: 200px;
  width: 240px;
  align-items: center; /\* Pode ser mudado na amostra ao vivo \*/
  background-color: #8c8c8c;
}

.flex {
  display: flex;
  flex-wrap: wrap;
}

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, 50px);
}

div > div {
  box-sizing: border-box;
  border: 2px solid #8c8c8c;
  width: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
}

#item1 {
  background-color: #8cffa0;
  min-height: 30px;
}

#item2 {
  background-color: #a0c8ff;
  min-height: 50px;
}

#item3 {
  background-color: #ffa08c;
  min-height: 40px;
}

#item4 {
  background-color: #ffff8c;
  min-height: 60px;
}

#item5 {
  background-color: #ff8cff;
  min-height: 70px;
}

#item6 {
  background-color: #8cffff;
  min-height: 50px;
  font-size: 30px;
}

select {
  font-size: 16px;
}

.row {
  margin-top: 10px;
}
```

### HTML

```html
<div id="container" class="flex">
  <div id="item1">1</div>
  <div id="item2">2</div>
  <div id="item3">3</div>
  <div id="item4">4</div>
  <div id="item5">5</div>
  <div id="item6">6</div>
</div>

<div class="row">
  <label for="display">display: </label>
  <select id="display">
    <option value="flex">flex</option>
    <option value="grid">grid</option>
  </select>
</div>

<div class="row">
  <label for="values">align-items: </label>
  <select id="values">
    <option value="normal">normal</option>
    <option value="flex-start">flex-start</option>
    <option value="flex-end">flex-end</option>
    <option value="center" selected>center</option>
    <option value="baseline">baseline</option>
    <option value="stretch">stretch</option>

    <option value="start">start</option>
    <option value="end">end</option>
    <option value="self-start">self-start</option>
    <option value="self-end">self-end</option>
    <option value="left">left</option>
    <option value="right">right</option>

    <option value="first baseline">first baseline</option>
    <option value="last baseline">last baseline</option>

    <option value="safe center">safe center</option>
    <option value="unsafe center">unsafe center</option>
    <option value="safe right">safe right</option>
    <option value="unsafe right">unsafe right</option>
    <option value="safe end">safe end</option>
    <option value="unsafe end">unsafe end</option>
    <option value="safe self-end">safe self-end</option>
    <option value="unsafe self-end">unsafe self-end</option>
    <option value="safe flex-end">safe flex-end</option>
    <option value="unsafe flex-end">unsafe flex-end</option>
  </select>
</div>
```

```
var values = document.getElementById("values");
var display = document.getElementById("display");
var container = document.getElementById("container");

values.addEventListener("change", function (evt) {
  container.style.alignItems = evt.target.value;
});

display.addEventListener("change", function (evt) {
  container.className = evt.target.value;
});
```

### Resultado

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

| Specification |
| --- |
| CSS Box Alignment Module Level 3 # align-items-property |
| CSS Flexible Box Layout Module Level 1 # align-items-property |

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

### Support in Flex layout

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

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

* CSS Flexbox Guide: *Basic Concepts of Flexbox*
* CSS Flexbox Guide: *Aligning items in a flex container*
* CSS Grid Guide: *Box alignment in CSS Grid layouts (en-US)*
* CSS Box Alignment (en-US)
* The `align-self` property


transition-timing-function - CSS

transition-timing-function
==========================

A propriedade CSS **`transition-timing-function`** é usada para descrever como os valores intermediários das propriedades CSS sendo afetados por um efeito de transição são calculados. Em essência isso permite você estabelecer uma curva de aceleração, para que então a velocidade da transição possa variar durante sua duração.

Essa curva de aceleração é definida usando `<timing-function>` (en-US) para cada propriedade a ser transicionada.

```css
/\* Keyword values \*/
transition-timing-function: ease;
transition-timing-function: ease-in;
transition-timing-function: ease-out;
transition-timing-function: ease-in-out;
transition-timing-function: linear;
transition-timing-function: step-start;
transition-timing-function: step-end;

/\* Function values \*/
transition-timing-function: steps(4, end);
transition-timing-function: cubic-bezier(0.1, 0.7, 1, 0.1);
transition-timing-function: frames(10);

/\* Multiple timing functions \*/
transition-timing-function: ease, step-start, cubic-bezier(0.1, 0.7, 1, 0.1);

/\* Global values \*/
transition-timing-function: inherit;
transition-timing-function: initial;
transition-timing-function: unset;
```

You may specify multiple timing functions; each one will be applied to the corresponding property as specified by the `transition-property` (en-US) property, which acts as a master list. If there are fewer functions specified than in the master list, missing values are set to the initial value (`ease`). If there are more timing functions, the list is simply truncated to the right size. In both case the CSS declaration stays valid.

|  |  |
| --- | --- |
| Initial value | `ease` |
| Aplica-se a | all elements, `::before` and `::after` pseudo-elements |
| Inherited | não |
| Computed value | as specified |
| Animation type | Not animatable |

Syntax
------

### Values

`<timing-function>`

Each `<timing-function>` (en-US) represents the timing function to link to the corresponding property to transition, as defined in `transition-property` (en-US).

### Formal syntax
```

transition-timing-function =
  <easing-function># (en-US)

<easing-function> =
  linear                          | (en-US)
  <linear-easing-function>        | (en-US)
  <cubic-bezier-easing-function>  | (en-US)
  <step-easing-function>

<linear-easing-function> =
  linear( <linear-stop-list> )

<cubic-bezier-easing-function> =
  ease                                                | (en-US)
  ease-in                                             | (en-US)
  ease-out                                            | (en-US)
  ease-in-out                                         | (en-US)
  cubic-bezier( <number [0,1]> , <number> , <number [0,1]> , <number> )

<step-easing-function> =
  step-start                             | (en-US)
  step-end                               | (en-US)
  steps( <integer> (en-US) , <step-position>? (en-US) )

<linear-stop-list> =
  [ (en-US) <linear-stop> ] (en-US)# (en-US)

<step-position> =
  jump-start  | (en-US)
  jump-end    | (en-US)
  jump-none   | (en-US)
  jump-both   | (en-US)
  start       | (en-US)
  end

<linear-stop> =
  <number>               && (en-US)
  <linear-stop-length>? (en-US)

<linear-stop-length> =
  <percentage> (en-US){1,2} (en-US)

```

Examples
--------

`transition-timing-function: ease`
```

<div class="parent">
  <div class="box">Lorem</div>
</div>
```

```
.parent {
  width: 250px;
  height: 125px;
}
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  font-size: 20px;
  left: 0px;
  top: 0px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: ease;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: ease;
}
.box1 {
  width: 50px;
  height: 50px;
  background-color: blue;
  color: yellow;
  font-size: 18px;
  left: 150px;
  top: 25px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: ease;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: ease;
}
```

```
function updateTransition() {
  var el = document.querySelector("div.box");

  if (el) {
    el.className = "box1";
  } else {
    el = document.querySelector("div.box1");
    el.className = "box";
  }

  return el;
}

var intervalID = window.setInterval(updateTransition, 7000);
```

`transition-timing-function: ease-in`
```

<div class="parent">
  <div class="box">Lorem</div>
</div>
```

```
.parent {
  width: 250px;
  height: 125px;
}
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  font-size: 20px;
  left: 0px;
  top: 0px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: ease-in;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: ease-in;
}
.box1 {
  width: 50px;
  height: 50px;
  background-color: blue;
  color: yellow;
  font-size: 18px;
  left: 150px;
  top: 25px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: ease-in;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: ease-in;
}
```

```
function updateTransition() {
  var el = document.querySelector("div.box");

  if (el) {
    el.className = "box1";
  } else {
    el = document.querySelector("div.box1");
    el.className = "box";
  }

  return el;
}

var intervalID = window.setInterval(updateTransition, 7000);
```

`transition-timing-function: ease-out`
```

<div class="parent">
  <div class="box">Lorem</div>
</div>
```

```
.parent {
  width: 250px;
  height: 125px;
}
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  font-size: 20px;
  left: 0px;
  top: 0px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: ease-out;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: ease-out;
}
.box1 {
  width: 50px;
  height: 50px;
  background-color: blue;
  color: yellow;
  font-size: 18px;
  left: 150px;
  top: 25px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: ease-out;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: ease-out;
}
```

```
function updateTransition() {
  var el = document.querySelector("div.box");

  if (el) {
    el.className = "box1";
  } else {
    el = document.querySelector("div.box1");
    el.className = "box";
  }

  return el;
}

var intervalID = window.setInterval(updateTransition, 7000);
```

`transition-timing-function: ease-in-out`
```

<div class="parent">
  <div class="box">Lorem</div>
</div>
```

```
.parent {
  width: 250px;
  height: 125px;
}
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  font-size: 20px;
  left: 0px;
  top: 0px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: ease-in-out;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: ease-in-out;
}
.box1 {
  width: 50px;
  height: 50px;
  background-color: blue;
  color: yellow;
  font-size: 18px;
  left: 150px;
  top: 25px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: ease-in-out;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: ease-in-out;
}
```

```
function updateTransition() {
  var el = document.querySelector("div.box");

  if (el) {
    el.className = "box1";
  } else {
    el = document.querySelector("div.box1");
    el.className = "box";
  }

  return el;
}

var intervalID = window.setInterval(updateTransition, 7000);
```

`transition-timing-function: linear`
```

<div class="parent">
  <div class="box">Lorem</div>
</div>
```

```
.parent {
  width: 250px;
  height: 125px;
}
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  font-size: 20px;
  left: 0px;
  top: 0px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: linear;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: linear;
}
.box1 {
  width: 50px;
  height: 50px;
  background-color: blue;
  color: yellow;
  font-size: 18px;
  left: 150px;
  top: 25px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: linear;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: linear;
}
```

```
function updateTransition() {
  var el = document.querySelector("div.box");

  if (el) {
    el.className = "box1";
  } else {
    el = document.querySelector("div.box1");
    el.className = "box";
  }

  return el;
}

var intervalID = window.setInterval(updateTransition, 7000);
```

`transition-timing-function: step-start`
```

<div class="parent">
  <div class="box">Lorem</div>
</div>
```

```
.parent {
  width: 250px;
  height: 125px;
}
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  font-size: 20px;
  left: 0px;
  top: 0px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: step-start;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: step-start;
}
.box1 {
  width: 50px;
  height: 50px;
  background-color: blue;
  color: yellow;
  font-size: 18px;
  left: 150px;
  top: 25px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: step-start;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: step-start;
}
```

```
function updateTransition() {
  var el = document.querySelector("div.box");

  if (el) {
    el.className = "box1";
  } else {
    el = document.querySelector("div.box1");
    el.className = "box";
  }

  return el;
}

var intervalID = window.setInterval(updateTransition, 7000);
```

`transition-timing-function: step-end`
```

<div class="parent">
  <div class="box">Lorem</div>
</div>
```

```
.parent {
  width: 250px;
  height: 125px;
}
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  font-size: 20px;
  left: 0px;
  top: 0px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: step-end;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: step-end;
}
.box1 {
  width: 50px;
  height: 50px;
  background-color: blue;
  color: yellow;
  font-size: 18px;
  left: 150px;
  top: 25px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: step-end;
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: step-end;
}
```

```
function updateTransition() {
  var el = document.querySelector("div.box");

  if (el) {
    el.className = "box1";
  } else {
    el = document.querySelector("div.box1");
    el.className = "box";
  }

  return el;
}

var intervalID = window.setInterval(updateTransition, 7000);
```

`transition-timing-function: steps(4, end)`
```

<div class="parent">
  <div class="box">Lorem</div>
</div>
```

```
.parent {
  width: 250px;
  height: 125px;
}
.box {
  width: 100px;
  height: 100px;
  background-color: red;
  font-size: 20px;
  left: 0px;
  top: 0px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: steps(4, end);
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: steps(4, end);
}
.box1 {
  width: 50px;
  height: 50px;
  background-color: blue;
  color: yellow;
  font-size: 18px;
  left: 150px;
  top: 25px;
  position: absolute;
  -webkit-transition-property: width height background-color font-size left top
    color;
  -webkit-transition-duration: 2s;
  -webkit-transition-timing-function: steps(4, end);
  transition-property: width height background-color font-size left top color;
  transition-duration: 2s;
  transition-timing-function: steps(4, end);
}
```

```
function updateTransition() {
  var el = document.querySelector("div.box");

  if (el) {
    el.className = "box1";
  } else {
    el = document.querySelector("div.box1");
    el.className = "box";
  }

  return el;
}

var intervalID = window.setInterval(updateTransition, 7000);
```

Specifications
--------------

| Specification |
| --- |
| CSS Transitions # transition-timing-function-property |

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

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

See also
--------

* Using CSS transitions (en-US)
* `TransitionEvent` (en-US)


<display-box> - CSS

<display-box>
=============

Essas palavras-chave definem se um elemento gera caixas de exibição.

Sintaxe
-------

`contents`
Experimental

Esses elementos não produzem uma caixa específica por si mesmos. Eles são substituídos por sua pseudo-caixa e suas caixas filho. Observe que a especificação CSS Display Level 3 define como o `contents`

o valor deve afetar "elementos incomuns" - elementos que não são renderizados apenas pelos conceitos da caixa CSS, como elementos substituídos. Consulte o Apêndice B: Efeitos da exibição: conteúdo em Elementos incomuns para obter mais detalhes.

Devido a um erro nos navegadores, atualmente isso remove o elemento da árvore de acessibilidade - os leitores de tela não analisam o que está dentro. Consulte a seção Preocupações com acessibilidade abaixo para obter mais detalhes.

`none`

 Desativa a exibição de um elemento para que não tenha efeito no layout (o documento é renderizado como se o elemento não existisse). Todos os elementos descendentes também têm a exibição desativada.
 Para que um elemento ocupe o espaço que normalmente ocuparia, mas sem renderizar nada, use o `visibility` propriedade em vez disso.

### Sintaxe formal
```

<display-box> =
  contents  | (en-US)
  none

```

Exemplos
--------

Neste primeiro exemplo, o parágrafo com uma classe de segredo é definido como `display: none`; a caixa e qualquer conteúdo agora não são renderizados.

### display: none

#### HTML

```html
<p>Visible text</p>
<p class="secret">Invisible text</p>
```

#### CSS

```css
p.secret {
  display: none;
}
```

#### Resultado

### display: contents

Neste exemplo, o externo `<div>` possui uma borda vermelha de 2 pixels e uma largura de 300 px. No entanto, também tem`display: contents` especificado, portanto, este `<div>` não será renderizado, a borda e a largura não serão mais aplicadas e o elemento filho será exibido como se o pai nunca tivesse existido.

#### HTML

```html
<div class="outer">
  <div>Inner div.</div>
</div>
```

#### CSS

```css
.outer {
  border: 2px solid red;
  width: 300px;
  display: contents;
}

.outer > div {
  border: 1px solid green;
}
```

#### Resultado

Preocupações com acessibilidade
-------------------------------

As implementações atuais na maioria dos navegadores removerão da árvore de acessibilidade qualquer elemento com um `display` valor de `contents`. Isso fará com que o elemento - e em algumas versões do navegador, seus elementos descendentes - não sejam mais anunciados pela tecnologia de leitura de tela. Esse é um comportamento incorreto de acordo com a especificação CSSWG.

* Marcação mais acessível com display: conteúdo | Hidde de Vries
* Exibição: conteúdo não é uma redefinição de CSS | Adrian Roselli
Compatibilidade com navegadores
-------------------------------

### Support of contents

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

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

* `display`
    + `<display-outside>`
    + `<display-inside>`
    + `<display-listitem>`
    + `<display-internal>`
    + `<display-legacy>`
* Exibição: conteúdo não é uma redefinição de CSS | Adrian Roselli
* Marcação mais acessível com display: contents - hiddedevries.nl


::first-letter (:first-letter) - CSS

::first-letter (:first-letter)
==============================

Sumário
-------

O pseudo-elemento CSS `::first-letter` seleciona a primeira letra da primeira linha de um bloco, desde que não seja precedida por outro conteúdo (como imagens ou tabelas embutidas/inline) na mesma linha.

A primeira letra de um elemento não é necessariamente uma identificação trivial:

* Pontuação, que é qualquer caractere definido em Unicode de abertura (Ps), de fechamento (Pe), aspa inicial (Pi), aspa final (Pf) e outras pontuações (Po), precedendo ou imediatamente após a primeira letra também é correspondida por esse pseudo-elemento.
* Da mesma forma, alguns idiomas têm dígitos que são sempre escritos em maiúsculas, como o IJ em holandês. Nesses casos raros, as duas letras do dígrafo devem corresponder ao pseudo-elemento `::first-letter`. (Isso é pouco suportado pelos navegadores, verifique a tabela de compatibilidade).
* Finalmente, uma combinação do pseudoelemento `::before` e a propriedade `content` podem injetar algum texto no início do elemento. Nesse caso, `::first-letter` corresponderá à primeira letra deste conteúdo gerado.

Uma primeira linha tem apenas significado em uma caixa de contêiner de bloco; portanto, o pseudo-elemento `::first-letter` apenas afeta os elementos com um valor de `display` de `block`, `inline-block`, `table-cell`, `list-item` ou `table-caption`. Em todos os outros casos, `::first-letter` não tem efeito.

Somente um pequeno subconjunto de todas as propriedades CSS pode ser usado dentro de um bloco de declaração de um conjunto de regras CSS que contém um seletor usando o pseudoelemento `::first-letter`:

* Todas as propriedades de fonts : `font` (en-US), `font-style` (en-US), `font-feature-settings`, `font-kerning`, `font-language-override` (en-US), `font-stretch` (en-US), `font-synthesis` (en-US), `font-variant` (en-US), `font-variant-alternates` (en-US), `font-variant-caps` (en-US), `font-variant-east-asian` (en-US), `font-variant-ligatures` (en-US), `font-variant-numeric` (en-US), `font-variant-position` (en-US), `font-weight`, `font-size`, `font-size-adjust` (en-US), `line-height` (en-US) and `font-family`.
* Todas as propriededas de background : `background-color`, `background-image` (en-US), `background-clip`, `background-origin`, `background-position` (en-US), `background-repeat` (en-US), `background-size`, `background-attachment`, and `background-blend-mode`.
* Todas as propriedades de margem: `margin`, `margin-top`, `margin-right` (en-US), `margin-bottom`, `margin-left` (en-US).
* Todas as propriedades de "padding" (preenchimento): `padding`, `padding-top` (en-US), `padding-right` (en-US), `padding-bottom` (en-US), `padding-left`.
* Todas as bordas: the taquigraficas `border` (en-US), `border-style` (en-US), `border-color` (en-US), `border-width` (en-US), `border-radius` (en-US), `border-image` (en-US), e as propriedades manuscritas.
* A propriedade `color`.
* As propriedades CSS: `text-decoration`, `text-shadow`, `text-transform`, `letter-spacing`, `word-spacing` (en-US) (when appropriate), `line-height` (en-US), `text-decoration-color` (en-US), `text-decoration-line` (en-US), `text-decoration-style`, `box-shadow`, `float`, `vertical-align` (somente se `float` for `none`).

Como toda essa lista será estendida no futuro, é recomendado que você não use qualquer propriedade dentro da declaração do bloco, afim de manter o CSS a qualquer prova.

**Nota:** No CSS 2, os pseudoelementos eram prefixados com um caractere de dois pontos (`:`). Como as pseudo-classes também estavam seguindo a mesma convenção, elas eram indistinguíveis. Para resolver isso, o CSS 2.1 mudou a convenção para pseudoelementos. Agora, um pseudoelemento é prefixado com dois caracteres de dois pontos (`::`) e uma pseudo-classe ainda é prefixado com um único dois pontos (`:`).

 Exemplo de **pseudoclasse**:
 `.classedoelemento:hover { ... }`

Exemplo de **pesudoelemento:** > `.classedoelemento::first-letter { ... }`

Como vários navegadores já implementaram a versão CSS 2 em uma versão de lançamento, todos os navegadores que suportam a sintaxe de dois pontos também suportam a antiga sintaxe de dois pontos.

**Aviso:** Mas isso pode mudar, portanto use SEMPRE `::` para pseudolementos

...a não se que você **precise muito** que seu código seja compatível com Internet Explore 8, então use um carectere de dois pontos.

Exemplo
-------

```css
/\* Fazendo odas as letras dos paragrados maior e vermelha \*/

p::first-letter {
  /\* Use :first-letter if você precise muito de compatibilidade com IE 8 \*/
  color: red;
  font-size: 130%;
}
```

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

| Specification |
| --- |
| CSS Pseudo-Elements Module Level 4 # first-letter-pseudo |

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

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

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

* O peseudo-elemento `::first-line` .


animation-delay - CSS

animation-delay
===============

A propriedade CSS **`animation-delay`** especifíca quando uma animação deve começar. Você pode começar a animação no futuro, imediatamente ou desde o início, ou imediatamente e parcialmente através do ciclo de animação.

```css
/\* Uma animação \*/
animation-delay: 3s;
animation-delay: 0s;
animation-delay: -1500ms;

/\* Várias animações \*/
animation-delay: 2.1s, 480ms;
```

Muitas vezes é conveniente usar a propriedade abreviada `animation` para definir todas as propriedades de animação de uma só vez.

|  |  |
| --- | --- |
| Initial value | `0s` |
| Aplica-se a | all elements, `::before` and `::after` pseudo-elements |
| Inherited | não |
| Computed value | as specified |
| Animation type | Not animatable |

Sintaxe
-------

### Valores

``<time>``

O deslocamento do tempo, a partir do momento em que a animação é aplicada ao elemento, no qual a animação deve começar. Isso pode ser especificado em segundos (`s`) ou milesegundos or milliseconds (`ms`). A unidade é necessaria.

Um valor positivo indica que a animação deve começar após o período de especificação ter decorrido. O valor de `0s`, que é o padrão, incida que a animação deve começar desde que foi aplicada.

Um valor negativo faz com que a animação comece imediatamente, mas parcialmente através do seu ciclo. Por exemplo, se você específicar `-1s` como tempo da animation-delay , a animação vai começar imediatamente, mas começará 1 segundo na sequência de animação. Se você específicar um valor negativo para a animation-delay, mas o valor inicial é implícito, o valor inicial é retirado do momento em que a animação é aplicada ao elemento.

**Nota:** Quando você especifica vários valores separados por vírgula em uma propriedade `animation-*` , eles serão atribuídos às animações especificadas na propriedade `animation-name` (en-US) em diferentes modos, dependendo de quantos existam. Para mais informações veja Setting multiple animation property values.

### Sintaxe formal
```

animation-delay =
  <time># (en-US)

```

Exemplos
--------

Veja CSS animations (en-US) para exemplos.

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

| Specification |
| --- |
| CSS Animations Level 1 # animation-delay |

Compatibilidade com os browsers
-------------------------------

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

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

* Using CSS animations (en-US)
* JavaScript `AnimationEvent` API


env() - CSS

env()
=====

A função CSS **`env()`** pode ser usada para inserir o valor de uma variável de ambiente definida pelo agente do usuário em seu CSS, de uma maneira semelhante à função `var()` e propriedades personalizadas. A diferença é que, além de serem definidas pelo agente do usuário em vez de serem definidas pelo usuário, as variáveis de ambiente têm escopo global para um documento, enquanto as propriedades personalizadas têm um escopo para o(s) elemento(s) no(s) qual(is) é/são declarado(s).

```css
body {
  padding: env(safe-area-inset-top, 20px) env(safe-area-inset-right, 20px) env(
      safe-area-inset-bottom,
      20px
    ) env(safe-area-inset-left, 20px);
}
```

Além disso, ao contrário das propriedades personalizadas, que não podem ser usadas fora do escopo das declarações, a função `env()` pode ser usada em qualquer parte do valor de uma propriedade ou em qualquer parte de um *descriptor* (por exemplo, regras Media (en-US)). À medida que a especificação evolui, essa também pode ser usada em outros lugares, como em seletores.

Originalmente fornecido pelo navegador iOS para permitir que os desenvolvedores coloquem seu conteúdo em uma *safe area* (área segura) na janela de visualização, os valores de `safe-area-inset-*` definidos na especificação podem ser usados para ajudar a garantir que o conteúdo seja visível até mesmo para usuários que usam uma tela não retangular.

Sintaxe
-------

```css
/\* Usando os quatro valores de inserção safe area sem valores de fallback \*/
env(safe-area-inset-top);
env(safe-area-inset-right);
env(safe-area-inset-bottom);
env(safe-area-inset-left);

/\* Usando-os com valores de fallback \*/
env(safe-area-inset-top, 20px);
env(safe-area-inset-right, 1em);
env(safe-area-inset-bottom, 0.5vh);
env(safe-area-inset-left, 1.4rem);
```

### Valores

`safe-area-inset-top`, `safe-area-inset-right`, `safe-area-inset-bottom`, `safe-area-inset-left`

As variáveis `safe-area-inset-*` são quatro variáveis de ambiente que definem um retângulo por seus valores de inserção: *top, right, bottom* e *left* a partir da borda da janela de visualização, no qual é seguro colocar o conteúdo sem o risco de ser cortado pela forma de um visor não retangular. Para janelas de visualização retangulares, como o monitor de um laptop comum, seu valor é igual a zero. Para telas não retangulares - como um visor de um relógio redondo - os quatro valores definidos pelo agente do usuário formam um retângulo de modo que todo o conteúdo dentro do retângulo seja visível.

**Nota:** Ao contrário de outras propriedades CSS, os nomes de propriedades definidos pelo agente do usuário fazem distinção entre maiúsculas e minúsculas.

### Sintaxe formal
```

<env()> =
  env( <custom-ident> (en-US) <integer [0,∞]> (en-US)\* (en-US) , <declaration-value>? (en-US) )

```

Exemplos
--------

O exemplo abaixo faz uso do segundo parâmetro opcional de `env()`, que permite fornecer um valor de *fallback* caso a variável de ambiente não esteja disponível.

```html
<p>
  Se a função <code>env()</code> é suportada em seu navegador, o texto deste
  parágrafo deverá estar na borda <i>top</i>, <i>right</i> e <i>bottom</i>, ter
  50px de preenchimento entre a borda e o texto. O CSS é equivalente ao
  preenchimento: <code>padding: 0 0 0 50px</code>, porque, ao contrário de
  outras propriedades CSS, os nomes de propriedades do agente do usuário
  diferenciam letras maiúsculas de minúsculas.
</p>
```

```css
p {
  width: 300px;
  border: 2px solid red;
  padding: env(safe-area-inset-top, 50px) env(safe-area-inset-right, 50px) env(
      safe-area-inset-bottom,
      50px
    ) env(SAFE-AREA-INSET-LEFT, 50px);
}
```

### Exemplo com valores

```css
padding: env(
  safe-area-inset-bottom,
  50px
); /\* zero para todos agentes do usuário que são retangulares\*/
padding: env(
  Safe-area-inset-bottom,
  50px
); /\* 50px porque as propriedades do agente do usuário diferenciam maiúsculas de minúsculas \*/
padding: env(
  x,
  50px 20px
); /\* como se estivesse preenchendo: '50px 20px' que foram definidos, porque x não é uma variável de ambiente válida \*/
padding: env(
  x,
  50px,
  20px
); /\* ignorado '50px, 20px' porque não é um valor de preenchimento válido e x não é uma variável de ambiente válida \*/
```

A sintaxe *fallback*, como de propriedades customizadas, permite vírgulas. Mas se o valor da propriedade não suportar vírgulas, o valor não é válido.

**Nota:** As propriedades do agente do usuário não são redefinidas pela propriedade all (en-US).

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

| Specification |
| --- |
| CSS Environment Variables Module Level 1 # env-function |

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

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

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

* `var(…)`
* CSS Custom Properties for Cascading Variables (en-US)
* Custom Properties (--\*)
* Using CSS custom properties (variables)