Introdução - JavaScript

Introdução
==========

* « Previous
* Next »

Este capítulo apresenta o JavaScript e discute alguns de seus conceitos fundamentais.

O que você realmente já deveria saber?
--------------------------------------

Este guia assume que você tem os seguintes conhecimentos básicos:

* Um entendimento geral da internet e da World Wide Web (WWW (en-US)).
* Um bom conhecimento de HyperText Markup Language (HTML)
* Alguma experiência em programação. Se você é novo em programação, veja alguns tutorias na página inicial sobre JavaScript.
Onde encontrar informações sobre JavaScript
-------------------------------------------

A documentação de JavaScript na MDN inclui o seguinte:

* Aprendendo sobre a internet fornece informações aos iniciantes e introduz os conceitos básicos de programação e da internet.
* Guia JavaScript (este guia) dá uma visão geral sobre a linguagem de programação JavaScript e seus objetos.
* Referência JavaScript provê um material de referência detalhado da linguagem JavaScript.

Se você é novo em JavaScript, comece com os artigos na área de aprendizado e com o Guia JavaScript. Quando você já possuir uma compreensão dos princípios básicos, você pode usar a Referência JavaScript para ter mais detalhes sobre objetos e declarações.

O que é JavaScript?
-------------------

JavaScript é uma linguagem de script orientada a objetos e plataforma cruzada usada para tornar as páginas da Web interativas (por exemplo, com animações complexas, botões clicáveis, menus pop-up etc.). Há também versões mais avançadas do lado do servidor do JavaScript, como Node.js, que permitem adicionar mais funcionalidades a um site do que baixar arquivos (como colaboração em tempo real entre vários computadores). Dentro de um ambiente de host (por exemplo, um navegador da Web), o JavaScript pode ser conectado aos objetos de seu ambiente para fornecer controle programático sobre eles.

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

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

Isso significa que, no navegador, o JavaScript pode alterar a aparência da página da Web (DOM). E, da mesma forma, o JavaScript Node.js no servidor pode responder a solicitações personalizadas enviadas por código executado no navegador.

JavaScript e Java
-----------------

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

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

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

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

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

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

JavaScript e a especificação ECMAScript
---------------------------------------

O JavaScript é padronizado pela Ecma International — a associação Europeia para a padronização de sistemas de comunicação e informação (antigamente ECMA era um acrônimo para European Computer Manufacturers Association) para entregar uma linguagem de programação padronizada, internacional baseada em JavaScript. Esta versão padronizada de JavaScript, chamada ECMAScript, comporta-se da mesma forma em todas as aplicações que suportam o padrão. As empresas podem usar a linguagem de padrão aberto para desenvolver a sua implementação de JavaScript. O padrão ECMAScript é documentado na especificação ECMA-262.

O padrão ECMA-262 também é aprovado pela ISO (International Organization for Standardization) como ISO-16262. Você também pode encontrar a especificação no site da Ecma International. A especificação ECMAScript não descreve o Document Object Model (DOM), que é padronizado pelo World Wide Web Consortium (W3C) e/ou WHATWG (Web Hypertext Application Technology Working Group). O DOM define a maneira na qual os objetos do documento HTML estão expostos no seu script. Para ter uma ideia melhor sobre as diferentes tecnologias que são usadas durante a programação com JavaScript, consultar o artigo Visão Geral das tecnologias JavaScript.

### Documentação JavaScript versus especificação ECMAScript

A especificação ECMAScript é um conjunto de requisitos para a implementação ECMAScript. É útil se você desejar implementar recursos compatíveis com os padrões da linguagem em sua implementação ECMAScript ou *engine* (como SpiderMonkey no Firefox, ou v8 no Chrome).

O documento ECMAScript *não* se destina a ajudar programadores de script. Utilize a documentação JavaScript para obter informações ao escrever scripts.

A especificação ECMAScript utiliza terminologia e sintaxe que podem ser desconhecidos para um programador JavaScript. Embora a descrição da linguagem possa ser diferente no ECMAScript, a linguagem em si continua sendo a mesma. JavaScript suporta todas as funcionalidades descritas na especificação ECMAScript.

A documentação JavaScript descreve aspectos da linguagem que são apropriadas para um programador JavaScript.

Começando com JavaScript
------------------------

Para começar a aprender JavaScript é fácil: Tudo o que você precisa é de um navegador web moderno. Versões recentes do Firefox, Chrome, Microsoft Edge, e Safari todas suportam os recursos discutidos neste guia.

Uma ferramenta muito útil para explorar o JavaScript é o JavaScript Console (às vezes chamado de Web Console, ou apenas o console): é uma ferramenta que permite inserir JavaScript e executá-lo na página atual.

A captura de tela aqui mostra o Firefox Web Console, mas todos os navegadores modernos vêm com um console que funciona de maneira semelhante.

### Abrindo o console

As instruções exatas para abrir o console variam de um navegador para outro:

* Abrindo o console no Firefox
* Abrindo o console no Chrome
* Abrindo o console no Microsoft Edge
### Inserindo e executando JavaScript

O console aparece na parte inferior da janela do navegador. Na parte inferior do console há uma linha de entrada que você pode usar para inserir JavaScript, e a saída aparece no painel acima:

![Uma janela do navegador com o console da web aberto na parte inferior, contendo duas linhas de entrada e saída. O texto pode ser inserido abaixo disso.](/pt-BR/docs/Web/JavaScript/Guide/Introduction/2019-04-04_00-15-29.png)

O console funciona exatamente da mesma forma que `eval`: a última expressão digitada é retornada. Por uma questão de simplicidade, pode-se imaginar que toda vez que algo é inserido no console, ele é realmente cercado por `console.log` em torno de `eval`, assim:

```js
console.log(eval("3 + 5"));
```

### Entrada de várias linhas no console

Por padrão, se você pressionar `Enter` após inserir uma linha de código, a string digitada será executada. Para inserir entrada multilinha:

* Se a string digitada estiver incompleta (por exemplo, você digitou `function foo() {`), o console tratará `Enter` como uma quebra de linha e permitirá que você digite outra linha.
* Se você segurar `Shift` enquanto pressiona `Enter`, o console tratará isso como uma quebra de linha e permitirá que você digite outra linha.
* Somente no Firefox, você pode ativar modo de entrada multi-linha, em onde você pode inserir várias linhas em um mini-editor e, em seguida, executar tudo quando estiver pronto.

Para começar a escrever JavaScript, abra o console, copie o seguinte código e cole na linha de comando:

```js
(function () {
  "use strict";
  /\* Ínicio do seu código \*/
  function greetMe(seuNome) {
    alert(`Olá ${seuNome}`);
  }

  greetMe("Mundo");
  /\* Fim do seu código \*/
})();
```

Pressione `Enter` para vê-lo abrir em seu navegador!

O que vem em seguida?
---------------------

Nas páginas seguintes, este guia apresentará a sintaxe e os recursos da linguagem JavaScript, para que você possa escrever aplicativos mais complexos.

Mas, por enquanto, lembre-se de sempre incluir `(function(){"use strict";` antes de seu código e adicionar `})();` ao final de seu código. Os artigos modo estrito e IIFE explicam o que eles fazem, mas por enquanto eles podem ser considerados em fazer o seguinte:

1. Evitam a semântica em JavaScript que engana os iniciantes.
2. Impedem que trechos de código executados no console interajam entre si (por exemplo, ter algo criado em uma execução de console sendo usado para uma execução de console diferente).
* « Previous
* Next »


Iteratores e geradores - JavaScript

Iteratores e geradores
======================

* « Previous
* Next »

Processar cada item em uma coleção é uma operação muito comum. O JavaScript disponibiliza uma série de maneiras de iterar sobre uma coleção, desde um simples laço `for`, até um `map()` e também com o `filter()`. Iteradores e Geradores trazem o conceito da interação ocorrer diretamente no núcleo da linguagem e prover um mecanismo para a customização do comportamento dos laços `for...of`.

Para detalhes, também veja:

* Protocolos de iteração
* `for...of`
* `function*` e `Generator`
* `yield` e `yield*`
Iterators (Iteradores)
----------------------

Um objeto é um **iterator (iterador)** quando sabe como acessar itens numa coleção, um por vez, enquanto mantém rastreada a posição atual em uma dada sequência. Em JavaScript um iterator é um objeto que oferece o método `next()`, o qual retorna o próximo item da sequência. Este método retorna um objeto com duas propriedades: `done` e `value`.

Uma vez criado, um objeto iterator pode ser usado explicitamente ao chamar repetidas vezes o método `next()`.

```js
const makeIterator = (array) => {
  let nextIndex = 0;

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

Uma vez inicializado, o método `next()` pode ser chamado para acessar os pares chave/valor do objeto da vez.

```js
let it = makeIterator(["yo", "ya"]);
console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done); // true
```

Iterables (Iteráveis)
---------------------

Um objeto é iterável **(iterable),** se ele define seu comportamento de iteração, como no caso de quais valores percorridos em um laço do tipo `for..of`. Alguns tipos embutidos, como o `Array`, ou o `Map`, têm um comportamento iterável padrão, enquanto outros tipos (como o`Object`) não possuem.

Para que um objeto seja **iterable**, o objeto precisa implementar o método **@@iterator**, significando que o objeto (ou um dos objetos na cadeia de prototipagem - prototype chain) precisa ter uma propriedade com uma chave `Symbol.iterator`:

### Iterables definidos pelo usuário

Você pode fazer seus próprios iteráveis da seguinte maneira:

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

### Iterables Built-in (Iteráveis Embutidos)

`String`, `Array`, `TypedArray` (en-US), `Map` e `Set` são iteráveis embutidos, pois o protótipo dos objetos de todos eles têm o método `Symbol.iterator`.

### Syntaxes expecting iterables

Algumas declarações e expressões esperam por iteradores, por exemplo o `for-of` loops, spread operator (en-US), `yield*`, e destructuring assignment.

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

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

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

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

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

Generators
----------

Enquanto os iteradores são ferramentas muito úteis, sua criação requer um cuidado devido à necessidade de manter explícito seu estado interno. **Generators** provêm uma alternativa poderosa: eles te permitem definir um algoritmo iterativo escrevendo uma função simples que pode manter seu estado próprio.

Generator é um tipo especial de função que trabalha como uma factory para iteradores. A função vira um generator se ela contém uma ou mais expressões `yield` e se ela usa a sintaxe `function*`.

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

var gen = idMaker();

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

Generators avançados
--------------------

Generators computam seus valores "yielded" por demanda, que os permitem representar sequências de forma eficiente que costumam ser trabalhosas ao serem computadas, ou até sequências infinitas como demonstradas acima.

O método `next()` (en-US) também aceita um valor que pode ser usado para modificar o estado interno de um generator. O valor passado pro `next()` será tratado como o resultado da última expressão yield que pausou o generator.

Aqui um gerador de sequência Fibonacci usando `next(x)` pra restartar a sequência:

```js
function\* fibonacci() {
  var fn1 = 1;
  var fn2 = 1;
  while (true) {
    var current = fn2;
    fn2 = fn1;
    fn1 = fn1 + current;
    var reset = yield current;
    if (reset) {
      fn1 = 1;
      fn2 = 1;
    }
  }
}

var sequence = fibonacci();
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
console.log(sequence.next().value); // 5
console.log(sequence.next().value); // 8
console.log(sequence.next().value); // 13
console.log(sequence.next(true).value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
```

**Nota:** Como um ponto de interesse, chamando `next(undefined)` é o mesmo que chamar `next()`. Entretanto, estartar um novo generator com qualquer valor que não seja undefined na chamada next() terá `TypeError` exception.

Você pode forçar um generator a lançar uma exceção chamando o seu método `throw()` (en-US) e passando o valor da exceção que ele deve lançar. Essa exceção será lançada do contexto suspenso atual do generator, como se o `yield` atualmente suspenso fosse um `throw`.

Se um yield não for encontrado durante o processo de lançamento de um thrown exception, então o exception será propagado através da chamada do `throw()`, e pra subsequente chamada do `next()` que terá a propriedade done resultando em `true`.

Generators têm o método `return(value)` (en-US) que retorna o valor pego e finaliza o generator.

* « Previous
* Next »


Expressões Regulares - JavaScript

Expressões Regulares
====================

* « Previous
* Next »

Expressões regulares são padrões utilizados para selecionar combinações de caracteres em uma string. Em JavaScript, expressões regulares também são objetos. Elas podem ser utilizadas com os métodos `exec` (en-US) e `test` (en-US) do objeto `RegExp` (en-US), e com os métodos `match` (en-US), `replace` (en-US),`search` (en-US), e `split` (en-US) do objeto `String`. Este capítulo descreve o uso de expressões regulares em JavaScript.

Criando uma Expressão Regular
-----------------------------

Há duas maneiras de construir uma expressão regular:

Usando uma expressão literal, que consiste em um padrão fechado entre barras, como o exemplo a seguir:

```js
const re = /ab+c/;
```

As expressões regulares na forma literal são compiladas quando o script é carregado. Esta forma de construção possui melhor performace quando a expressão regular utilizada é uma constante, ou seja, não muda durante a execução.

Ou chamando o construtor do objeto `RegExp` (en-US):

```js
let re = new RegExp("ab+c");
```

Usando o construtor, a compilação da expressão regular é realizada em tempo de execução. Use o construtor quando souber que o padrão da expressão regular irá mudar ou quando o padrão for desconhecido, oriundo de outra fonte, uma entrada de usuário por exemplo.

**Nota:** Nota: Se você já está familiarizado com as formas de uma expressão regular, também pode ler o resumo (en-US) para uma rápida pesquisa de um padrão específico.

Escrevendo um padrão de expressão regular
-----------------------------------------

Um padrão de expressão é composto por um conjunto de caracteres simples, como `/abc/`, ou uma combinação de caracteres simples e especiais, como `/ab*c/` ou `/Capitulo (\d+)\.\d*/`. O último exemplo contém parênteses, que são usados como um mecanismo de armazenamento. A correspondência feita por essa parte da expressão é armazenada para uso posterior, como descrito em: Using Parenthesized Substring Matches.

### Uso de Padrões Simples

Padrões simples são construídos utilizando os caracteres que você deseja encontrar correspondências diretas. Por exemplo, o padrão `/abc/` encontra combinações de caracteres em strings apenas quando os caracteres 'abc' forem encontrados juntos e na ordem especificada. Esse padrão será encontrado com sucesso nas strings "Olá, você conhece o **abc**?" e "Os mais recentes aviões evoluíram do sl**abc**raft.". Em ambos os casos, a correspondência estará no subconjunto 'abc'. Porém, o padrão não será encontrado no texto "Grab crab" pois apesar de conter os mesmos caractes do padrão 'ab c', estes não aparecem na ordem especificada.

### Uso dos Caracteres Especiais

Quando for necessário buscar algo além de uma correspondência direta, como encontrar uma ou mais ocorrências da letra 'b', ou encontrar espaços em branco, será necessário adicionar caracteres especiais ao padrão. Por exemplo, para encontrar uma única correspondência de 'a' seguido de nenhum ou mais 'b's seguido de 'c', o padrão a utilizar seria `/ab*c/`. O caractere `*` seleciona zero ou mais ocorrências do item que o precede. Se aplicada ao texto 'cbb**abbbbc**debc', essa expressão regular encontraria o subconjunto grifado no texto.

A tabela abaixo fornece uma lista completa dos caracteres especiais que podem ser utilizados nas expressões regulares, com sua respectiva descrição. Para testar os exemplos de expressão regular você pode usar o regExr.

Caracteres especiais utilizados em expressões regulares.| Caractere | Descrição |
| --- | --- |
| `\` | Aplicado conforme as seguintes regras:

 Uma barra invertida que preceda um caractere não especial significa
 que o caractere seguinte é especial e não deve ser interpretado de
 forma literal. Por exemplo, o caractere 'b' quando não precedido de
 uma barra invertida significará uma ocorrência do próprio caractere
 'b' minúsculo, porém se precedido da barra invertida
 `'\b'` ele passará a significar a ocorrência do caractere
 especial
 [fronteira do caractere](#special-word-boundary).

 Quando a barra invertida preceder um caractere especial isso
 significará que o próximo caractere deve ser interpretado de forma
 literal. Por exemplo o padrão `/a*/`, que selecionará a
 ocorrência de zero ou mais caracteres 'a' quando utilizado sem a \
 para escape. Por outro lado no padrão `/a\*/` o asterisco
 deixa de ter seu significado especial, pois a '\' de escape fará com
 que o '\*' seja interpretado de forma literal, passando o padrão a
 selecionar o caractere 'a' seguido do caractere '\*'.

 Quando utilizar o construtor RegExp("padrao"), não se esqueça de fazer
 o escape do caractere \, já que esse caractere é também utilizado como
 caractere de escape em strings.
  |
| `^` |
 Corresponde ao início do texto. Se a flag multilinhas é setada para
 true, também se aplica imediatamente após um caractere de quebra de
 linha.

 Por exemplo, `/^A/` não corresponde ao 'A' em "Um Alvo",
 mas corresponde ao 'A' em "Alvo Encontrado".

Este caractere tem um significado diferente quando aparece como
 o primeiro caractere em um conjunto padrão de caracteres. Veja
 conjunto de caracteres negados ou complementados
 para detalhes e mais exemplos.
  |
| `$` |
 Corresponde ao final do texto. Se a flag multilinhas é setada para
 true, também se aplica imediatamente antes de um caractere de quebra
 de linha.

 Por exemplo, `/r$/` não corresponde ao 'r' em "corre", mas
 acha correspondência em "correr".
  |
| `*` |
 Corresponde a expressão que o precede repetida 0 ou mais vezes.
 Equivalente a {0,}

 Por exemplo, `/bo*/` acha uma correspondência para 'boo'
 em "boolean" e 'b' em "A bird warbled", mas nenhuma em "A goat
 grunted".
  |
| `+` |
 Corresponde a expressão que o precede repetido 1 ou mais vezes.
 Equivalente a {1,}.

 Por exemplo, `/a+/` acha correspondência para o 'a' em
 "candy" e todos os "as" em "caaaaaaandy", mas nâo encontra em "cndy".
  |
| `?` |
 Corresponde a expressão que o precede repetido 0 ou 1 vez. Equivalente
 à {0,1}.

 Por exemplo, `/e?le?/` encontra o 'el' em "angel" e o 'le'
 em "angle" e também o 'l' em "oslo".

 Se usado imediatamente após qualquer um dos quantificadores
 `*`, `+`, `?` ou `{}`, faz
 o quantificador não guloso (combinando o número mínimo de vezes), como
 um oposto para o padrão que é guloso (combinar o número máximo
 possível). Por exemplo, aplicando `/\d+/` em "123abc"
 encontra "123". Mas aplicando `/\d+?/`, apenas "1" será
 encontrado.

 Também usado em declarações lookahead, descritas sob
 `x(?=y)` e `x(?!y)`logo abaixo na tabela.
  |
| `.` |
 (O ponto decimal) corresponde com qualquer caracter, exceto o caracter
 de nova linha.

 Por exemplo, `/.n/` acha correspondência para o 'an' e 'on'
 em "nove dias restantes para onze de agosto.", mas não encontra 'no'
 em 'nove'.
  |
| `(x)` |
 Pesquisa correspondência com o caractere 'x' e memoriza-o, como a o
 exemplo a seguir mostra. Os parênteses são chamados
 *parênteses de captura*.

 Por exemplo, o '(foo)' e '(bar)' no padrão
 `/(foo) (bar) \1 \2/` encontra e memoriza a primeira das
 duas palavras na string "foo bar foo bar". O \1 e \2 no padrão combina
 as duas últimas palavras da string. Note que \1, \2, \n são utilizados
 na parte correspondente do regex.
  |
| `(?:x)` |
 Pesquisa correspondência com o caractere 'x' porém não o memoriza. Os
 parênteses são chamados de *parênteses de não-captura* e permitem
 que você defina uma subexpressão para operadores de expressão regular
 trabalhar com eles. Considere essa expressão de exemplo
 `/(?:foo){1,2}/`. Se a expressão era `/foo{1,2}/`,
 o {1,2} poderia ser aplicado apenas para o último 'o' em 'foo'. Com os
 parênteses de não-captura, o {1,2} é aplicado para toda a palavra 'foo'.
  |
| `x(?=y)` |
 Pesquisa correspondência em 'x' apenas se 'x' é seguido por 'y'. Isso
 é chamado de *lookahead*.

 Por exemplo, `/Jack(?=Sprat)/` busca 'Jack' apenas se é
 seguido por 'Sprat'. `/Jack(?=Sprat|Frost)/` busca 'Jack'
 apenas se ele é seguido por 'Sprat' ou 'Frost'. No entanto, 'Sprat'
 nem 'Frost' faz parte do resultado retornado.
  |
| `x(?!y)` |
 Pesquisa correspondência em 'x' apenas se 'x' não é seguido por 'y'.
 Isso é chamado *negação lookahead*.

 Por exemplo, `/\d+(?!\.)/` encontra um número apenas se ele
 não for seguido por um ponto decimal. A expressão regular
 `/\d+(?!\.)/.exec("3.141")` encontra '141' mas não '3.141'.
  |
| `x|y` | Pesquisa correspondência em 'x' ou 'y'.

 Por exemplo, `/verde|vermelha/` encontra 'verde' em "maçã
 verde" e 'vermelha' em "maçã vermelha."
  |
| `{n}` |
 Pesquisa n ocorrências correspondentes ao caracter precedido. Onde,
 `n` deve ser um inteiro positivo.

 Por exemplo, `/a{2}/` não encontra o 'a' em "candy," mas
 encontra-o se houver a quantidade de a's informarda em "caandy," e os
 dois primeiros a's em "caaandy."
  |
| `{n,m}` |
 Pesquisa a n menor correspondência e a m maior correspondência do
 caractere precedido. Quando n ou m é zero, ele poderá ser omitido.
 Onde, `n` e `m` devem ser inteiros positivo.

 Por exemplo, `/a{1,3}/` não encontra nada em "cndy", mas
 encontra o 'a' em "candy", encontra os dois primeiros a's em "caandy,"
 e encontra os três primeiros a's em "caaaaaaandy". Observe que, ao
 fazer a correspondência de "caaaaaaandy", serão encontrados apenas os
 "aaa", mesmo que a string tenha mais a's.
  |
| `[xyz]` |
 Um conjunto de caracteres. Pesquisa correspondência para qualquer um
 dos caracteres entre colchetes. Você pode especificar um intervalo de
 caracteres usando hífen. Caracteres especiais (como o ponto (.) e o
 asterisco(\*)) não tem significado algum quando está dentro de um
 conjunto de caracteres. Não necessita utilizar escape neles. Mas, se
 utilizar escape também irá funcionar.

 Por exemplo, `[abcd]` é o mesmo que `[a-d]`. Com
 a expressão será encontrado o 'b' em "beijo" e o 'c' em "chop". A
 expressão `/[a-z.]+/` e `/[\w.]+/` ambos
 encontraram as letras que formam "test.i.ng".
  |
| `[^xyz]` |
 Um conjunto de caracteres negados ou complementados. Isto é, combina
 com qualquer coisa que não esteja listado entre os colchetes. Você
 pode especificar um intervalo de caracteres usando hífen. Tudo que
 funciona no conjunto de caracteres (apresentado acima) também funciona
 aqui.

 Por exemplo, `[^abc]` é o mesmo que `[^a-c]`.
 Com a expressão será encontrado inicialmente 'e' em "beijo" e 'h' em
 "chop."
  |
| `[\b]` |
 Pesquisa correspondência com espaço em branco (U+0008). É preciso
 utilizar os colchetes se você quer encontrar um espaço em branco. (Não
 confunda-o com `\b`.)
  |
| `\b` |
 Pesquisa correspondência em uma fronteira de caractere. Uma fronteira
 de caractere corresponde a posição onde um caractere/palavra não é
 seguido ou antecedido por outro caractere/palavra. Isto é, em
 fronteira de caractere não pode haver nenhum caractere ou espaço, seu
 tamanho deve ser vazio. (não confunda-o com [\b].)

 Exemplos:`/\bmoo/` encontra a substring 'moo' em
 "moon" ;`/oo\b/` não encontra o 'oo' em "moon",
 devido o 'oo' ser seguido por 'n' que é um caractere;`/oon\b/`
 encontra a substring 'oon' em "moon", devido 'oon' ser o fim da
 string, ou seja, não é seguido por nenhum caractere;`/\w\b\w/`
 não encontrará nada, pois o caractere nunca será seguido por um não
 caractere e um caractere.

**Nota:** O mecanismo de expressão regular no
 JavaScript define um conjunto específico de caracteres para serem
 caracteres "palavras". Qualquer caractere que não esteja neste
 conjunto é considerado uma quebra de palavra. Este conjunto de
 caractere é bastante limitado: consiste apenas no alfabeto romano
 tanto maiúsculo como minúsculo, digítos decimais, e o caractere
 sublinhado. Caracteres acentuados, tal como "é" ou "ã" são,
 infelizmente, tratados como palavras quebradas.

 |
| `\B` |
 Pesquisa correspondência que não seja em uma fronteira de caractere.
 Para a correspondência é associada uma posição onde o caractere
 anterior e o próximo tem as mesmas características: ambos são
 caractere/palavra, ou ambos não sejam caractere/palavra. O início e o
 fim de uma string não considerados como não caractere/palavra.

 Por exemplo, /\B../ encontra correspondente 'oo' em "boolean", e
 /y\B./ encontra correspondente 'ye' em "possibly yesterday."
  |
| `\c*X*` |
 Onde X é um caractere pertencente ao conjunto A-Z. Encontra
 correspondência de um
 caractere de controle
 em uma string.

 Por exemplo, `/\cM/` encontra correspondente control-M
 (U+000D) em uma string.
  |
| `\d` | Encontra correspondência com um número. Equivalente a [0-9].

 Por exemplo, `/\d/` ou `/[0-9]/` encontra
 correspondente '8' em "Dróide BB8".
  |
| `\D` |
 Encontra correspondência com um caractere que não seja número.
 Equivalente a [^0-9].

 Por exemplo, `/\D/` ou `/[^0-9]/` econtra
 correspondente 'C' em "C3 está ativada."
  |
| `\f` |
 Encontra correspondência com um caractere de escape
 *avanço de página* (U+000C).
  |
| `\n` |
 Encontra correspondência com um caractere de escape
 *quebra de linha* (U+000A).
  |
| `\r` |
 Encontra correspondência com um caractere de escape
 *retorno de carro* (U+000D).
  |
| `\s` |
 Encontra correspondência com um único caractere de espaço em branco,
 espaço, tabulação, avanço de página, quebra de linha. Equivalente a
 `[
\f\n\r\t\v\u00A0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u2028\u2029\u202f\u205f\u3000]`.

 Por exemplo, `/\s\w*/` encontra correspondente ' bar' em
 "foo bar."
  |
| `\S` |
 Encontra correspondência em um único caractere que não seja espaço em
 branco. Equivalente a
 `[^
\f\n\r\t\v\u00A0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u2028\u2029\u202f\u205f\u3000]`.

 Por exemplo, `/\S\w*/` encontra correspondente 'foo' em
 "foo bar."
  |
| `\t` | Encontra correspondência em uma tabulação (U+0009). |
| `\v` | Encontra correspondência em uma tabulação vertical (U+000B). |
| `\w` |
 Encontra correspondência de qualquer caractere alfanumérico incluindo
 underline. Equivalente a `[A-Za-z0-9_]`.

 Por exemplo, `/\w/` encontra correspondente 'a' em "apple,"
 '5' em "$5.28," e '3' em "3D."
  |
| `\W` |
 Encontra correspondência em um não caractere. Equivalente a
 `[^A-Za-z0-9_]`.

 Por exemplo, `/\W/` ou
 `/[^A-Za-z0-9_]/` encontra correspondente '%' em "50%."
  |
| `\*num*` |
 Onde num é um inteiro positivo. Faz referência a substring pertencente
 à um grupo, um grupo é definido entre parênteses. Grupos são numerados
 de 1 até 9.

 Por exemplo, /(muito) (cacique) pra \2 \1/ encontra 'muito cacique pra
 cacique muito' em 'Na aldeia tem muito cacique pra cacique muito.'
  |
| `\0` |
 Encontra correspondência em um caractere NULL (U+0000). Não adicione
 outro número após o zero, pois
 `\0<digitos> é um escape para número octal`.
  |
| `\xhh` | Encontra correspondência com o código hh (dois valores hexadecimal). |
| `\uhhhh` | Encontra correspondência com o código hhh (três valores hexadecimal). |
| \u{hhhh} |
 (funciona apenas com a flag u) Encontra correspondência com o valor
 Unicode hhhh (dígitos hexadecimais).
  |

### Usando Parênteses

Usar parênteses em volta de qualquer parte de uma expressão regular faz com que essa parte seja lembrada para ser usada depois, como descrito em Usando as Substrings entre Parênteses na Expressão Regular.

Por Exemplo, a expressão `/Capitulo (\d+)\.\d*/` ilustra caracteres adicionais escapados e especiais e indica que parte do padrão deve ser lembrado. Corresponde precisamente aos caracteres 'Capitulo ' seguidos por um ou mais caracteres numéricos (`\d` significa qualquer caracter numérico e `+` significa 1 ou mais vezes), seguidos por um ponto decimal (que é um caracter especial; preceder com um \ significa que a expressão regular deve buscar pelo caracter literal '.'), seguido por qualquer caracter numérico 0 ou mais vezes (`\d` significa caracter numérico, `*` significa 0 ou mais vezes). Além disso, os parenteses são usados para relembrar os primeiros caracteres numéricos correspondentes.

Esse padrão é encontrado em "Abra o capitulo 4.3, parágrafo 6" o '4' é relembrado. O padrão não é encontrado em "Capitulo 3 e 4", porque essa string não tem um período após o '3'.

Para encontrar uma substring sem que a correspondência seja relembrada, dentro dos parênteses inicie o padrão com `?:`. Por exemplo, `(?:\d+)` corresponde a um ou mais caracteres numéricos mas não relembra os caracteres correspondentes.

Trabalhando com expressões regulares
------------------------------------

Expressões Regulares são usadas com os metodos `test` e `exec` do objeto `RegExp`e com os metodos `match`, `replace`, `search`, e `split` do objeto `String`. Estes metodos são explicados em detalhe em JavaScript Reference.

| Metodo | Descrição |
| --- | --- |
| `exec` (en-US) | Um método `RegExp` que execute uma pesquisa por uma correspondência em uma string. Retorna um array de informações. |
| `test` (en-US) | Um método `RegExp` que testa uma correspondência em uma string. Retorna true ou false. |
| `match` (en-US) | Um método `String` que executa uma pesquisa por uma correspondência em uma string. Retorna uma array de informações ou null caso não haja uma correspondência. |
| `search` (en-US) | Um método `String` que testa uma correspondência em uma string. Retorna o indice da correspondência ou -1 se o teste falhar. |
| `replace` (en-US) | Um método `String` que executa uma pesquisa por uma correspondência em uma string, e substitui a substring correspondênte por uma substring de substituição. |
| `split` (en-US) | Um método `String` que usa uma expressão regular ou uma string fixa para quebrar uma string dentro de um array de substrings. |

Quando você quer saber se um padrão é encontrado em uma string, use o método `test` ou `search`; para mais informações (mas execução mais lenta) use o método `exec` ou `match`. Se você usar `exec` ou `match` e se houver correspondência, estes métodos retornam um array e atualizam as propriedades do objeto da expressão regular associada e também do objeto da expressão regular predfinada `RegExp`. Se não houver corespondência, o método `exec` retorna `null` (convertido para `false`).

No seguinte exemplo, o script usa o método `exec` para encontrar uma correspondência em uma string.

```js
var myRe = /d(b+)d/g;
var myArray = myRe.exec("cdbbdbsbz");
```

Se você não precisa acessar as propriedades da expressão regular, uma alternativa de criar `myArray` é com esse script:

```js
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
```

Se você quiser construir a expressão regular a partir de uma string, outra alternativa é esse script:

```js
var myRe = new RegExp("d(b+)d", "g");
var myArray = myRe.exec("cdbbdbsbz");
```

Com esses scripts, a correspondência é encontrada o array é retornado e são atualizadas as propriedades mostradas na tabela a seguir.

Table 4.3 Resultados da execução de expressões regulares.| Objeto | Propriedade or indice | Descrição | Nesse exemplo |
| --- | --- | --- | --- |
| `myArray` |  | A string correspondente e todas as substrings relembradas. | `["dbbd", "bb"]` |
| `index` | O índice do encontro em relação à string original. | `1` |
| `input` | A string original. | `"cdbbdbsbz"` |
| `[0]` | Os últimos caracteres encontrados. | `"dbbd"` |
| `myRe` | `lastIndex` |
 O índice no qual iniciar a próxima partida. (Esta propriedade é
 configurada apenas se a expressão regular usar a opção g, descrita em
 [Advanced Searching With Flags](#Advanced\_Searching\_With\_Flags).)
  | `5` |
| `source` |
 O texto da expressão regular. Atualizado quando a expressão é criada,
 não executada.
  | `"d(b+)d"` |

Como mostrado na segunda forma deste exemplo, você pode usar uma expressão regular criada com um inicializador de objeto sem atribuí-la à uma variável. Contudo, se você o fizer, toda ocorrência é uma nova expressão regular. Assim sendo, se você usar esta forma sem atribuí-la à uma variável, você não pode subsequentemente acessar as propriedades da expressão regular. Assumamos que tenha este script, por exemplo:

```js
var myRe = /d(b+)d/g;
var myArray = myRe.exec("cdbbdbsbz");
console.log("O útltimo índice é " + myRe.lastIndex);
```

Este script mostra:
```

O último índice é 5
```

Contudo, se tem este script:

```js
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
console.log("O último índice é " + /d(b+)d/g.lastIndex);
```

Ele mostra:
```

O último índice é 0
```

As ocorrências de `/d(b+)d/g` nas duas declarações são objetos expressões regulares diferentes e consequentemente têm diferentes valores para suas propriedades `lastIndex`. Se precisa acessar as propriedades de uma expressão regular criada com um inicializaor de objeto, você deve primeiro atribuí-la à uma variável.

### Usando as Substrings entre Parênteses na Expressão Regular

A inclusão de parênteses em um padrão de expressão regular faz com que a sub-correspondência correspondente seja lembrada. Por exemplo, `/a(b)c/` corresponde aos caracteres 'abc' e lembra 'b'. Para recuperar essas correspondências de substring entre parênteses, use o `Arra[1]`, ..., `[n]`.

O número de substring entre parênteses possíveis é ilimitado. A matriz retornada contém tudo o que foi encontrado. Os exemplos a seguir ilustram como usar parênteses entre parênteses.

#### Exemplo 1

O script a seguir usa o método `replace()` (en-US) para alternar as palavras na string. Para o texto de substituição, o script usa o `$1` e `$2` na substituição para indicar a primeira e a segunda correspondências de substring entre parênteses.

```js
var re = /(\w+)\s(\w+)/;
var str = "John Smith";
var newstr = str.replace(re, "$2, $1");
console.log(newstr);
```

Isto imprime "Smith, John".

### Pesquisa avançada com Flags

As expressões regulares possuem quatro flags opcionais as quais se incluem a pesquisa global e case insensitive. Para realizar uma pesquisa global, utilize a flag g. Para realizar uma pesquisa sem diferenciar letras maiúsculas de minúsculas, utilize a flag i. Para realizar uma pesquisa multi-linhas, utilize a flag m. Ao realizar uma pesquisa "sticky", o ponto de partida será a posição corrente da string alvo, use com a flag y.Estas flags podem ser usadas separadamente ou juntas, em qualquer ordem, e serão inclusas como parte da expressão regular.

Para incluir um sinalizador com a expressão regular, use esta sintaxe:

```js
var re = /pattern/flags;
```

ou

```js
var re = new RegExp("pattern", "flags");
```

Observe que os sinalizadores são parte integrante de uma expressão regular. Eles não podem ser adicionados ou removidos posteriormente.

Por exemplo, `re = /\w+\s/g` cria uma expressão regular que procura um ou mais caracteres seguidos por um espaço e procura essa combinação em toda a cadeia.

```js
var re = /\w+\s/g;
var str = "fee fi fo fum";
var myArray = str.match(re);
console.log(myArray);
```

Isso exibe ["fee ", "fi ", "fo "]. Neste exemplo, você pode substituir a linha

```js
var re = /\w+\s/g;
```

por:

```js
var re = new RegExp("\\w+\\s", "g");
```

e obtenha o mesmo resultado.

O sinalizador `m` é usado para especificar que uma sequência de entrada de múltiplas linhas deve ser tratada como várias linhas. Se o sinalizador `m` for usado, `^` e `$` combinam no início ou no final de qualquer linha na sequência de entrada, em vez do início ou no final de toda a sequência.

Exemplos
--------

Os exemplos que se seguem mostram mais usos expressões regulares.

### Alterando o pedido em uma string de entrada

O exemplo a seguir ilustra a formação de expressões regulares e o uso de `string.split()` e `string.replace()`. Ela limpa uma string de entrada formatada com nomes (primeiro nome sobrenome) separados por espaço em branco, tabulações e exatamente um ponto e virgula. Por fim, inverte a ordem do nome (sobrenome e primeiro nome) e ordena a lista

```js
// A cadeia de nomes contém vários espaços e guias,
// e pode ter vários espaços entre o nome e o sobrenome.
var names = "Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ";

var output = ["---------- String original\n", names + "\n"];

// Prepare dois padrões de expressão regular e armazenamento em array.
// Divide a string em elementos da matriz.

// pattern: possível espaço em branco, em seguida, ponto e vírgula, em seguida, possível espaço em branco
var pattern = /\s\*;\s\*/;

// Quebra string em pedaços separados pelo padrão acima e
// armazene as partes em uma matriz chamada nameList
var nameList = names.split(pattern);

// new pattern: um ou mais caracteres, espaços e caracteres.
// Use parênteses para "memorizar" partes do padrão.
// As partes memorizadas são referenciadas mais tarde.
pattern = /(\w+)\s+(\w+)/;

// Nova matriz para armazenar nomes sendo processados.
var bySurnameList = [];

// Exibe a matriz de nomes e preenche a nova matriz
// com nomes separados por vírgula, último primeiro.
//
// O método replace remove qualquer coisa que corresponda ao padrão
// e substitui-o pela sequência memorizada - segunda parte memorizada
// seguido por espaço de vírgula seguido pela primeira parte memorizada.
//
// As variáveis $ 1 e $ 2 se referem às partes
// memorizado enquanto corresponde ao padrão.

output.push("---------- Após Separar pela Expressão Regular");

var i, len;
for (i = 0, len = nameList.length; i < len; i++) {
  output.push(nameList[i]);
  bySurnameList[i] = nameList[i].replace(pattern, "$2, $1");
}

// Exibe a nova matriz.
output.push("---------- Nomes Invertidos");
for (i = 0, len = bySurnameList.length; i < len; i++) {
  output.push(bySurnameList[i]);
}

// Classifica pelo sobrenome e exibe a matriz classificada.
bySurnameList.sort();
output.push("---------- Ordenado");
for (i = 0, len = bySurnameList.length; i < len; i++) {
  output.push(bySurnameList[i]);
}

output.push("---------- Fim");

console.log(output.join("\n"));
```

### Usando caracteres especiais para verificar entradas

No exemplo a seguir, é esperado que o usuário informe um número de telefone. Quando o usuário pressionar o botão "Check", o script verificará a validade do número. Se o número for válido (a sequência de caracteres especificada corresponderá a expressão regular), então, o script exibe uma mensagem agradecendo o usuário e confirmando o seu número. Se o número for inválido, o script informa ao usuário que o número de telefone não é válido.

A expressão regular procura por zero ou uma ocorrência de parênteses de abertura \(?, seguido de três dígitos \d{3}, seguido de zero ou uma ocorrência de parênteses de fechamento \)?, seguido de um hífen, barra ou ponto decimal e, quando encontrado, guarda o caractere ([-\/\.]), seguido de três dígitos \d{3}, seguido por um caractere de hífen, barra ou ponto decimal que fora guardado \1, seguido por quatro dígitos \d{4}.

Com o evento Change ativo, quando o usuário pressionar Enter, o valor será capturado por RegExp.input.

```html
<!doctype html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />
    <script type="text/javascript">
 var re = /\(?\d{3}\)?([-\/\.])\d{3}\1\d{4}/;
 function testInfo(phoneInput) {
 var OK = re.exec(phoneInput.value);
 if (!OK)
 window.alert(
 RegExp.input + " Não é um número de telefone com código de área!",
 );
 else window.alert("Obrigado, o seu número de telefone é " + OK[0]);
 }
 </script>
  </head>
  <body>
    <p>
      Informe o seu número de telefone (com código de área) e então clique em
      "Check". <br />O formato esperado é ###-###-####.
    </p>
    <form action="#">
      <input id="phone" /><button
 onclick="testInfo(document.getElementById('phone'));">
        Check
      </button>
    </form>
  </body>
</html>
```

* « Previous
* Next »


Trabalhando com objetos - JavaScript

Trabalhando com objetos
=======================

**A linguagem JavaScript é projetada com base em um simples paradigma orientado a objeto. Um objeto é uma coleção de propriedades, e uma propriedade é uma associação entre um nome (ou *chave*) e um valor. Um valor de propriedade pode ser uma função, que é então considerada um *método* do objeto. Além dos objetos que são pré-definidos no browser, você pode definir seus próprios objetos.**

**Este capítulo descreve como usar objetos, propriedades, funções, e métodos, e como criar seus próprios objetos.**

Visão geral de objetos
----------------------

Objetos em JavaScript, assim como em muitas outras linguagens de programação, podem ser comparados com objetos na vida real. O conceito de objetos em JavaScript pode ser entendido com objetos tangíveis da vida real.

Em JavaScript, um objeto é uma entidade independente, com propriedades e tipos. Compare-o com uma xícara, por exemplo. Uma xícara é um objeto, com propriedades. Uma xícara tem uma cor, uma forma, peso, um material de composição, etc. Da mesma forma, objetos em JavaScript podem ter propriedades, que definem suas características.

Objetos e propriedades
----------------------

Um objeto em JavaScript tem propriedades associadas a ele. Uma propriedade de um objeto pode ser explicada como uma variável que é ligada ao objeto. Propriedades de objetos são basicamente as mesmas que variáveis normais em JavaScript, exceto pelo fato de estarem ligadas a objetos. As propriedades de um objeto definem as características do objeto. Você acessa as propriedades de um objeto com uma simples notação de ponto:

```js
nomeDoObjeto.nomeDaPropriedade;
```

Como as variáveis em JavaScript, o nome do objeto (que poderia ser uma variável normal) e um nome de propriedade diferem em maiúsculas/minúsculas (por exemplo, cor e Cor são propriedades diferentes). Você pode definir uma propriedade atribuindo um valor a ela. Por exemplo, vamos criar um objeto chamado `meuCarro` e dar a ele propriedades chamadas `fabricacao`, `modelo`, e `ano`, conforme mostrado a seguir:

```js
var meuCarro = new Object();
meuCarro.fabricacao = "Ford";
meuCarro.modelo = "Mustang";
meuCarro.ano = 1969;
```

Propriedades não definidas de um objeto são `undefined` (e não `null`).

```js
meuCarro.semPropriedade; //undefined
```

Propriedades de objetos em JavaScript podem também ser acessadas ou alteradas usando-se notação de colchetes. Objetos são às vezes chamados de *arrays associativos*, uma vez que cada propriedade é associada com um valor de string que pode ser usado para acessá-la. Então, por exemplo, você poderia acessar as propriedades do objeto `meuCarro` como se segue:

```js
meuCarro["fabricacao"] = "Ford";
meuCarro["modelo"] = "Mustang";
meuCarro["ano"] = 1969;
```

Um nome de propriedade de um objeto pode ser qualquer string JavaScript válida, ou qualquer coisa que possa ser convertida em uma string, incluindo uma string vazia. No entanto, qualquer nome e propriedade que não é um identificador JavaScript válido (por exemplo, um nome de propriedade que tem um espaço ou um hífen, ou que começa com um número) só pode ser acessado(a) usando-se a notação de colchetes. Essa notação é também muito útil quando nomes de propriedades devem ser determinados dinamicamente (quando o nome da propriedade não é determinado até o momento de execução). Exemplos são mostrados a seguir:

```js
var meuObj = new Object(),
  str = "minhaString",
  aleat = Math.random(),
  obj = new Object();

meuObj.tipo = "Sintaxe de ponto";
meuObj["data de criacao"] = "String com espaco";
meuObj[str] = "valor de String";
meuObj[aleat] = "Numero Aleatorio";
meuObj[obj] = "Objeto";
meuObj[""] = "Mesmo uma string vazia";

console.log(meuObj);
```

Você pode também acessar propriedades usando um valor de string que está armazenado em uma variável:

```js
var nomeDaPropriedade = "fabricacao";
meuCarro[nomeDaPropriedade] = "Ford";

nomeDaPropriedade = "modelo";
meuCarro[nomeDaPropriedade] = "Mustang";
```

Você pode usar a notação de colchetes com o comando for...in para iterar por todas as propriedades enumeráveis de um objeto. Para ilustrar como isso funciona, a seguinte função mostra as propriedades de um objeto quando você passa o objeto e o nome do objeto como argumentos para a função:

```js
function mostrarProps(obj, nomeDoObj) {
  var resultado = "";
  for (var i in obj) {
    if (obj.hasOwnProperty(i)) {
      resultado += nomeDoObj + "." + i + " = " + obj[i] + "\n";
    }
  }
  return resultado;
}
```

Então, a chamada de função `mostrarProps(meuCarro, "meuCarro")` retornaria o seguinte:
```

meuCarro.fabricacao = Ford
meuCarro.modelo = Mustang
meuCarro.ano = 1969
```

Objetos: tudo
-------------

Em JavaScript, quase tudo é um objeto. Todos os tipos primitivos - com exceção de `null` e `undefined` - são tratados como objetos. Eles podem receber propriedades (propriedades atribuídas de alguns tipos não são persistentes), e possuem todas as características de objetos.

Enumerando todas as propriedades de um objeto
---------------------------------------------

Começando com a ECMAScript 5, há três formas nativas de se listar (ou "caminhar por") as propriedades de um objeto:

* for...in (en-US) loops
 Esse método caminha por todas as propriedades enumeráveis de um objeto e sua cadeia de protótipos
* Object.keys(o) (en-US)
 Esse método retorna um array com todos os nomes ("chaves") de propriedades próprios de um objeto `o` (mas não na cadeia de protótipos).
* Object.getOwnPropertyNames(o) (en-US)
 Esse método retorna um array contendo todos os nomes de propriedades próprios (enumeráveis ou não) de um objeto `o`.

Antes, na ECMAScript 5, não existia uma forma nativa de se listar todas as propriedades de um objeto. No entanto, isso pode ser feito com a seguinte função:

```js
function listarTodasAsPropriedades(o) {
  var objectoASerInspecionado;
  var resultado = [];

  for (
    objectoASerInspecionado = o;
    objectoASerInspecionado !== null;
    objectoASerInspecionado = Object.getPrototypeOf(objectoASerInspecionado)
  ) {
    resultado = resultado.concat(
      Object.getOwnPropertyNames(objectoASerInspecionado),
    );
  }

  return resultado;
}
```

Isso pode ser útil para revelar propriedades "escondidadas" (propriedades na cadeia de protótipos que não são acessíveis através do objeto, porque outra propriedade possui o mesmo nome anteriormente na cadeia de protótipos). A listagem de propriedades acessíveis só pode ser facilmente feita através da remoção de valores duplicados no array.

Criando novos objetos
---------------------

JavaScript possui um número de objetos pré-definidos. Além disso, você pode criar seus próprios objetos. Você pode criar um objeto usando um objeto inicializador. Alternativamente, você pode primeiro criar uma função construtora e depois instanciar um objeto usando aquela função e o operador `new`.

### Usando inicializadores de objeto

Além de criar objetos usando uma função construtora, você pode criar objetos usando um inicializador de objeto. O uso de inicializadores de objeto é às vezes conhecido como criar objetos com notação literal. O termo "inicializador de objeto" é consistente com a terminologia usada por C++.

A sintaxe para um objeto usando-se um inicializador de objeto é:

```js
var obj = {
  propriedade\_1: valor_1, // propriedade\_# pode ser um identificador...
  2: valor_2, // ou um numero...
  // ...,
  "propriedade n": valor_n,
}; // ou uma string
```

onde `obj` é o nome do novo objeto, cada `propriedade_i` é um identificador (um nome, um número, ou uma string literal), e cada `valor_i` é uma expressão cujo valor é atribuído à `propriedade_i`. O `obj` e a atribuição são opcionais; se você não precisa fazer referência a esse objeto em nenhum outro local, você não precisa atribuí-lo a uma variável. (Note que você pode precisar colocar o objeto literal entre parentêses se o objeto aparece onde um comando é esperado, de modo a não confundir o literal com uma declaração de bloco.)

Se um objeto é criado com um inicializador de objeto em um script de alto nível, JavaScript interpreta o objeto a cada vez que avalia uma expressão contendo o objeto literal. Além disso, um inicializador usado em uma função é criado toda vez que a função é chamada.

O seguinte comando cria um objeto e o atribui à variável `x` somente se a expressão `cond` é verdadeira.

```js
if (cond) var x = { hi: "there" };
```

O seguinte exemplo cria `minhaHonda` com três propriedades. Note que a propriedade `motor` é também um objeto com suas próprias propriedades.

```js
var minhaHonda = {
  cor: "vermelho",
  rodas: 4,
  motor: { cilindros: 4, tamanho: 2.2 },
};
```

Você pode também usar inicializadores de objeto para criar arrays. Veja arrays literais.

### Usando uma função construtora

Alternativamente, você pode criar um objeto com estes dois passos:

1. Defina o tipo de objeto escrevendo uma função construtora. Há uma forte convenção, e com boa razão, de se usar uma letra inicial maiúscula.
2. Crie uma instância do objeto com `new`.

Para definir um tipo de objeto, crie uma função para o tipo de objeto que especifique seu nome, suas propriedades e seus métodos. Por exemplo, suponha que você queira criar um tipo objeto para carros. Você quer que esse tipo de objeto seja chamado `carro`, e você quer ele tenha propriedades de marca, modelo, e ano. Para fazer isto, você escreveria a seguinte função:

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

Note o uso de `this` para atribuir valores às propriedades do objeto com base nos valores passados para a função.

Agora você pode criar um objeto chamado `meucarro` como se segue:

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

Esse comando cria `meucarro` e atribui a ele valores especificados para suas propriedade. Então o valor de `meucarro.marca` é a string "Eagle", `meucarro.ano` é o inteiro 1993, e assim por diante.

Você pode criar qualquer número de objetos `carro` com o uso de `new`. Exemplo,

```js
var carroDeKen = new Carro("Nissan", "300ZX", 1992);
var carroDeVPG = new Carro("Mazda", "Miata", 1990);
```

Um objeto pode ter uma propriedade que por si só também é um objeto. Por exemplo, suponha que você define um objeto chamado `pessoa` como se segue:

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

e então você instancia dois novos objetos `pessoa` da seguinte forma:

```js
var jose = new Pessoa("Jose Silva", 33, "M");
var paulo = new Pessoa("Paulo Santos", 39, "M");
```

Então, você pode reescrever a definição de `carro` de modo a incluir uma propriedade `dono` que recebe um objeto `pessoa`, como se segue:

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

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

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

Perceba que ao invés de passar uma string literal ou um valor inteiro na hora de criar os novos objetos, os comandos acima passam os objetos `jose` e `paulo` como os argumentos para os donos. Então se você quiser descobrir o nome do dono de `carro2`, você pode acessar a seguinte propriedade:

```js
carro2.dono;
```

Note que você pode sempre adicionar uma propriedade a um objeto definido anteriormente. Por exemplo, o comando

```js
carro1.cor = "preto";
```

adiciona uma propriedade `cor` ao `carro1`, e dá a ele o valor `"preto."` No entanto, isso não afeta nenhum outro objeto. Para adicionar a nova propriedade a todos os objetos do mesmo tipo, você deve adicionar a propriedade na definição do tipo de objeto `carro`.

### Usando o método Object.create

Objetos podem também ser criados usando-se o método `Object.create()`. Esse método pode ser muito útil, pois permite que você escolha o objeto protótipo para o objeto que você quer criar, sem a necessidade de se definir uma função construtora.

```js
// Encapsulamento das propriedades e métodos de Animal
var Animal = {
  tipo: "Invertebrados", // Propriedades de valores padrão
  qualTipo: function () {
    // Método que ira mostrar o tipo de Animal
    console.log(this.tipo);
  },
};

// Cria um novo tipo de animal chamado animal1
var animal1 = Object.create(Animal);
animal1.qualTipo(); // Saída:Invertebrados

// Cria um novo tipo de animal chamado Peixes
var peixe = Object.create(Animal);
peixe.tipo = "Peixes";
peixe.qualTipo(); // Saída: Peixes
```

### Herança

Todos os objetos em JavaScript herdam de pelo menos um outro objeto. O objeto "pai" é conhecido como o protótipo, e as propriedades herdadas podem ser encontradas no objeto `prototype` do construtor.

Indexando Propriedades de Objetos
---------------------------------

Você pode se referir a uma propriedade de um objeto pelo seu nome de propriedade ou pelo seu índice ordinal. Se você inicialmente definiu uma propriedade pelo nome, você deve sempre se referir a ela pelo nome, e se você inicialmente definir uma propriedade por um índice, você deve sempre se referir a ela pelo índice.

Esta restrição se aplica quando você cria um objeto e suas propriedades com uma função construtora (como fizemos anteriormente com o objeto do tipo carro) e quando você define propriedades individuais explicitamente (por exemplo, `meuCarro.cor = "vermelho"`). Se você inicialmente definir uma propriedade do objeto com um índice, tal como `meuCarro[5] = "25 mpg"`, você pode subsequentemente referir-se á propriedade somente como `meuCarro[5]`.

A exceção a esta regra é a objetos refletidos a partir do HTML, como o conjunto de formulários. Você pode sempre se referir a objetos nessas matrizes por seu número de ordem (com base em onde eles aparecem no documento) ou seu nome (se definido). Por exemplo, se a segunda tag `<FORM>` em um documento tem um atributo `NAME` de "meuFormulario", você pode se referir ao formulário como `document.forms[1]` ou `document.forms["meuFormulario"]` ou `document.meuFormulario`.

Definindo propriedades para um tipo de objeto
---------------------------------------------

Você pode adicionar uma propriedade a um tipo de objeto definido anteriormente, utilizando a propriedade prototype. Esta define uma propriedade que é partilhada por todos os objetos do tipo especificado, em vez de apenas uma instância do objeto. O código a seguir adiciona uma propriedade `cor` para todos os objetos do tipo C`arro`, em seguida adiciona um valor a propriedade `cor` do objeto `carro1`.

```js
Carro.prototype.cor = null;
carro1.cor = "preto";
```

Consulte a propriedade (en-US) `prototype` (en-US) do objeto `Function` na Referência JavaScript para mais informações.

Definindo métodos
-----------------

Um *método* é uma função associada a um objeto, ou, simplesmente, um método é uma propriedade de um objeto que é uma função. Métodos são definidos da forma que as funções normais são definidas, exceto que eles tenham que ser atribuídos como propriedade de um objeto. São exemplos:

```js
nomeDoObjeto.nomedometodo = nome_da_funcao;

var meuObjeto = {
  meuMetodo: function (parametros) {
    // ...faça algo
  },
};
```

Onde `nomeDoObjeto` é um objeto existente, `nomedometodo` é o nome que você atribuiu ao método, e `nome_da_funcao` é o nome da função.

Em seguida, você pode chamar o método no contexto do objeto da seguinte forma:

```js
objeto.nomedometodo(parametros);
```

Você pode definir métodos para um tipo de objeto incluindo uma definição de metodo na função construtora do objeto. Por exemplo, você poderia definir uma função que iria formatar e mostrar as propriedades do objeto `carro` previamente definido; por exemplo,

```js
function mostreCarro() {
  var resultado =
    "Um belo " + this.ano + " " + this.fabricacao + " " + this.modelo;
  pretty\_print(resultado);
}
```

onde `pretty_print` é uma função que mostra uma linha horizontal e uma string. Observe o uso de `this` para referenciar o objeto ao qual o método pertence.

Você pode fazer desta função um método de `carro`, adicionando seu estado à definição do objeto.

```js
this.mostreCarro = mostreCarro;
```

Assim, a definição completa de `carro` seria agora, parecida com essa:

```js
function Carro(fabricacao, modelo, ano, proprietario) {
  this.fabricacao = fabricacao;
  this.modelo = modelo;
  this.ano = ano;
  this.proprietario = proprietario;
  this.mostreCarro = mostreCarro;
}
```

Então você pode chamar o método `mostreCarro` para cada objeto seguinte:

```js
carro1.mostreCarro();
carro2.mostreCarro();
```

Usando `this` para referências de objetos
-----------------------------------------

JavaScript tem uma palavra-chave especial, this, que você pode usar dentro de um método para referenciar o objeto corrente. Por exemplo, suponha que você tenha uma função chamada `validate` que valida o `valor` da propriedade de um objeto, dado o objeto e os valores altos e baixos:

```js
function validate(obj, lowval, hival) {
  if (obj.value < lowval || obj.value > hival) alert("Valor inválido!");
}
```

Então, você poderia chamar `validate` no manipulador de evento `onchange` em cada elemento do formulário, usando `this` para passar o elemento, como no exemplo a seguir:

```html
<input type="text" name="age" size="3" onChange="validate(this, 18, 99)" />
```

No geral, `this` referencia o objeto chamando um método.

Quando combinado com a propriedade `form` , `this` pode referenciar a forma original do objeto atual. No exemplo seguinte, o formulário `myForm` contém um objeto `Text` e um botão. Quando o usuário clica no botão, o valor do objeto `Text` é definido como nome do formulário. O manipulador de eventos `onclick` do botão usa `this.form` para referenciar a forma original, `myForm`.

```html
<form name="myForm">
  <p>
    <label
 >Nome do form:<input type="text" name="text1" value="Beluga"
 /></label>
  </p>
  <p>
    <input
 name="button1"
 type="button"
 value="Mostre o Nome do Form"
 onclick="this.form.text1.value = this.form.name" />
  </p>
</form>
```

Definindo getters e setters
---------------------------

Um getter é um método que obtém o valor de uma propriedade específica. Um setter é um método que define o valor de uma propriedade específica. Você pode definir getters e setters em qualquer objeto de núcleo pré-definido ou objeto definido pelo usuário que suporta a adição de novas propriedades. A sintaxe para definir getters e setters usa a sintaxe literal do objeto.

O código a seguir ilustra como getters e setters podem funcionar para um objeto`o`definido pelo usuário.

```js
var o = {
  a: 7,
  get b() {
    return this.a + 1;
  },
  set c(x) {
    this.a = x / 2;
  },
};

console.log(o.a); // 7
console.log(o.b); // 8
o.c = 50;
console.log(o.a); // 25
```

As propriedades do objeto `o` são:

* `o.a` — um número
* `o.b` — um getter que retorna `o.a` + 1
* `o.c` — um setter que define o valor de `o.a` pela metade do valor definindo para `o.c`

Observe que nomes de função de getters e setters definidos em um objeto literal usando "[gs]et *property*()" (ao contrário de `__define[GS]etter__` ) não são os próprios nomes dos getters, embora a sintaxe `[gs]et propertyName(){ }` possa induzir ao erro e você pensar de outra forma. Para nomear uma função getter ou setter usando a sintaxe "[gs]et *property*()", define explicitamente um função nomeada programaticamente usando `Object.defineProperty` (en-US) (ou o legado fallback `Object.prototype.__defineGetter__` (en-US)).

O código a seguir ilustra como getters e setters podem extender o protótipo `Date` para adicionar a propriedade `ano` para todas as instâncias de classes `Date` pré-definidas. Ele usa os métodos `getFullYear` e `setFullYear` existentes da classe `Date` para suportar o getter e setter da propriedade `ano`.

Estes estados definem um getter e setter para a propriedade `ano`:

```js
var d = Date.prototype;
Object.defineProperty(d, "year", {
  get: function () {
    return this.getFullYear();
  },
  set: function (y) {
    this.setFullYear(y);
  },
});
```

Estes estados usam o getter e setter em um objeto `Date`:

```js
var now = new Date();
console.log(now.year); // 2000
now.year = 2001; // 987617605170
console.log(now);
// Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
```

A principio, getters e setters podem ser ou

* definidos usando objetos inicializadores, ou
* adicionar posteriormente para qualquer objeto a qualquer tempo usando um método getter ou setter adicionado

Ao definir getters e setters usando objetos inicializadores tudo o que você precisa fazer é prefixar um método getter com `get` e um método setter com `set`. Claro, o método getter não deve esperar um parâmetro, enquanto o método setter espera exatamente um parâmetro (novo valor para definir). Por exemplo:

```js
var o = {
  a: 7,
  get b() {
    return this.a + 1;
  },
  set c(x) {
    this.a = x / 2;
  },
};
```

Getters e setters podem também ser adicionado em um objeto a qualquer hora depois da criação usando o método `Object.defineProperties`. O primeiro parâmetro deste método é o objeto no qual você quer definir o getter ou setter. O segundo parâmetro é um objeto cujos nomes das propriedades são os nomes getter ou setter, e cujo valores das propriedades são objetos para definição de funções getter ou setter. Aqui está um exemplo que define o mesmo getter e setter usado no exemplo anterior:

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

Object.defineProperties(o, {
  b: {
    get: function () {
      return this.a + 1;
    },
  },
  c: {
    set: function (x) {
      this.a = x / 2;
    },
  },
});

o.c = 10; // Roda o setter, que associa 10 / 2 (5) para a propriedade 'a'
console.log(o.b); // Roda o getter, que yields a + 1 ou 6
```

Escolher qual das duas formas depende do seu estilo de programação e tarefa na mão. Se você já vai para o inicializador de objeto ao definir um protótipo, provavelmente a maior parte do tempo escolherá a primeira forma. Esta forma é mais compacta e natural. No entanto, se você precisar adicionar getters e setters mais tarde - porque você não escreveu o protótipo ou objeto particular - então a segunda forma é a única possível. A segunda forma provavelmente melhor representa a natureza dinâmica do JavaScript - mas pode tornar o código difícil de ler e entender.

Removendo propriedades
----------------------

Você pode remover uma propriedade não herdada usando o operador `delete`. O código a seguir mostra como remover uma propriedade.

```js
//Criando um novo objeto, myobj, com duas propriedades, a e b.
var myobj = new Object();
myobj.a = 5;
myobj.b = 12;

//Removendo a propriedade a, deixando myobj com apenas a propriedade b.
delete myobj.a;
console.log("a" in myobj); // yields "false"
```

Você também pode usar `delete` para remover uma variável global se a `var` keyword não estiver sendo usada para declarar a variável:

```js
g = 17;
delete g;
```

Comparando Objetos
------------------

Em JavaScript, objetos são um tipo de referência. Dois objetos distintos nunca são iguais, mesmo que tenham as mesmas propriedades. Apenas comparando o mesmo objeto de referência com ele mesmo produz verdadeiro.

```js
// Duas variáveis, dois objetos distintos com as mesmas propriedades
var fruit = { name: "apple" };
var fruitbear = { name: "apple" };

fruit == fruitbear; // return false
fruit === fruitbear; // return false
```

```js
// Duas variáveis, um único objeto
var fruit = { name: "apple" };
var fruitbear = fruit; // assign fruit object reference to fruitbear

// Here fruit and fruitbear are pointing to same object
fruit == fruitbear; // return true
fruit === fruitbear; // return true
```

Para mais informações sobre comparaçāo de operadores, veja Operadores de comparaçāo (en-US).

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

* Para se aprofundar, leia sobre os detalhes do modelo de objetos javaScript.
* Para saber mais sobre classes em ECMAScript6 (uma nova forma de criar objetos), veja o capítulo JavaScript classes.
* « Previous
* Next »


Funções - JavaScript

Funções
=======

* « Previous
* Next »

Funções são blocos de construção fundamentais em JavaScript. Uma função é um procedimento de JavaScript - um conjunto de instruções que executa uma tarefa ou calcula um valor. Para usar uma função, você deve defini-la em algum lugar no escopo do qual você quiser chamá-la.

Veja também o capítulo de referência sobre funções JavaScript para conhecer os detalhes.

Definindo Funções
-----------------

### Declarando uma função

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

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

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

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

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

```js
return numero \* numero;
```

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

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

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

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

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

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

### Expressão de função

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

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

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

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

console.log(fatorial(3));
```

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

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

O código a seguir:

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

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

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

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

Além de definir funções, você também pode usar o construtor `Function` para criar funções a partir de uma string em tempo real, como no método `eval()` (en-US).

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

Chamando funções
----------------

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

```js
square(5);
```

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

Funções devem estar no escopo quando são chamadas, mas a declaração de uma função pode ser puxada para o topo (aparecem abaixo da chamada no código), como neste exemplo:
```

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

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

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

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

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

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

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

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

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

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

Escopo da função
----------------

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

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

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

multiplica(); // Retorna 60

// Um exemplo de função aninhada
function getScore() {
  var num1 = 2,
    num2 = 3;

  function add() {
    return nome + " scored " + (num1 + num2);
  }

  return add();
}

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

Escopo e a pilha de função
--------------------------

### Recursão

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

1. o nome da função
2. `arguments.callee` (en-US)
3. uma variável no escopo que se refere a função

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

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

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

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

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

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

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

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

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

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

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

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

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

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

que produz:
```

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

### Funções aninhadas e closures

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

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

Em resumo:

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

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

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

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

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

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

### Preservação de variáveis

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

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

### Múltiplas funções aninhadas

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

Considere o seguinte exemplo:

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

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

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

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

### Conflitos de nome

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

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

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

Closures
--------

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

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

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

myPet(); // Retorna "Vivie"
```

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

```js
var criarPet = function (nome) {
  var sex;

  return {
    setNome: function (newNome) {
      nome = newNome;
    },

    getNome: function () {
      return nome;
    },

    getSex: function () {
      return sex;
    },

    setSex: function (newSex) {
      if (
        typeof newSex == "string" &&
        (newSex.toLowerCase() == "macho" || newSex.toLowerCase() == "fêmea")
      ) {
        sex = newSex;
      }
    },
  };
};

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

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

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

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

  return function () {
    return secureCode;
  };
})();

getCode(); // Retorna o secureCode
```

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

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

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

Usando objeto de argumentos
---------------------------

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

```js
arguments[i];
```

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

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

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

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

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

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

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

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

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

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

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

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

### Parâmetros padrão

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

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

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

  return a \* b;
}

multiplicar(5); // 5
```

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

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

multiplicar(5); // 5
```

Mais detalhes, consulte parâmetros padrão na referência.

### Parâmetros rest

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

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

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

Funções de seta
---------------

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

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

### Funções curtas

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

```js
var a = ["Hydrogen", "Helium", "Lithium", "Beryllium"];

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

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

### Léxico this

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

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

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

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

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

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

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

function Pessoa(){
  this.idade = 0;

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

var p = new Pessoa();
```

Funções pré-definidas
---------------------

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

`eval()`

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

`uneval()`
Non-standard

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

`isFinite()`

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

`isNaN()`

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

`parseFloat()`

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

`parseInt()`

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

`decodeURI()`

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

`decodeURIComponent()`

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

`encodeURI()`

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

`encodeURIComponent()`

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

`escape()`
Deprecated

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

`unescape()`
Deprecated

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

* « Previous
* Next »