diff options
Diffstat (limited to 'files/pt-br/web/javascript/guide')
23 files changed, 8961 insertions, 0 deletions
diff --git a/files/pt-br/web/javascript/guide/closures/index.html b/files/pt-br/web/javascript/guide/closures/index.html new file mode 100644 index 0000000000..efc7578d7d --- /dev/null +++ b/files/pt-br/web/javascript/guide/closures/index.html @@ -0,0 +1,336 @@ +--- +title: Closures +slug: Web/JavaScript/Guide/Closures +tags: + - Closure + - ES5 + - Intermediário + - JavaScript + - Referencia +translation_of: Web/JavaScript/Closures +--- +<div>{{jsSidebar("Intermediate")}}</div> + +<p class="summary">Um <em>closure </em>(fechamento) é uma função que se "lembra" do ambiente — ou escopo léxico — em que ela foi criada.</p> + +<h2 id="Escopo_léxico">Escopo léxico</h2> + +<p>Considere a função abaixo:</p> + +<div style="width: auto; overflow: hidden;"> +<pre class="brush: js">function init() { + var name = "Mozilla"; + function displayName() { + alert(name); + } + displayName(); +} +init(); +</pre> +</div> + +<p>A função <code>init()</code> cria uma variável local chamada <code>name</code>, e depois define uma função chamada <code>displayName()</code>. <code>displayName()</code> é uma função aninhada (um <em>closure</em>) — ela é definida dentro da função <code>init()</code>, e está disponivel apenas dentro do corpo daquela função. Diferente de <span style="font-family: courier new,andale mono,monospace; line-height: 1.5;">init()</span><span style="line-height: 1.5;">,</span><span style="line-height: 1.5;"> </span><code style="font-style: normal; line-height: 1.5;">displayName()</code><span style="line-height: 1.5;"> não tem variáveis locais próprias, e ao invés disso reusa a variável </span><code style="font-style: normal; line-height: 1.5;">name</code><span style="line-height: 1.5;"> declarada na função pai.</span></p> + +<p><a href="http://jsfiddle.net/xAFs9/3/">Rode</a> o código e veja que isso funciona. Este é um exemplo de <em>escopo léxico:</em> em JavaScript, o escopo de uma variável é definido por sua localização dentro do código fonte (isto é aparentemente <em>léxico</em>) e funções aninhadas têm acesso às variáveis declaradas em seu escopo externo.</p> + +<h2 id="Closure">Closure</h2> + +<p>Agora considere o seguinte exemplo:</p> + +<pre class="brush: js">function makeFunc() { + var name = "Mozilla"; + function displayName() { + alert(name); + } + return displayName; +} + +var myFunc = makeFunc(); +myFunc(); +</pre> + +<p>Se você rodar este código o mesmo terá exatamente o mesmo efeito que o <code>init()</code> do exemplo anterior: a palavra "Mozilla" será mostrada na caixa de alerta. O que é diferente - e interessante - é o fato de que a função interna do <code>displayName()</code> foi retornada da função externa antes de ser executada.</p> + +<p>Pode parecer não muito intuitivo de que o código de fato funciona. Normalmente variáveis locais a uma função apenas existem pela duração da execução da mesma. Uma vez que <code>makeFunc()</code> terminou de executar, é razoável esperar que a variável <code>name</code> não será mais necessária. Dado que o código ainda funciona como o esperado, este não é o caso.</p> + +<p>A solução para tal problema é que a função <code>myFunc</code> tornou-se uma <code>closure</code>. Uma closure (fechamento) trata-se de um tipo especial de objeto que combina duas coisas: a função e o ambiente onde a função foi criada. Este ambiente consiste de quaisquer variáveis que estavam no escopo naquele momento em que a função foi criada. Neste caso, <code>myFunc</code> é a closure que incorpora tanto a função <code>displayName</code> quanto a palavra <em>Mozilla</em> que existia quando a closure foi criada.</p> + +<p>Aqui temos um exemplo um pouco mais interessante, a função <code>makeAdder</code>:</p> + +<pre class="brush: js">function makeAdder(x) { + return function(y) { + return x + y; + }; +} + +var add5 = makeAdder(5); +var add10 = makeAdder(10); + +print(add5(2)); // 7 +print(add10(2)); // 12 +</pre> + +<p>Neste exemplo definimos a função <code>makeAdder(x)</code> que toma um único argumento <code>x</code> e retorna uma nova função. A função retornada toma então um único argumento, <code>y</code>, e retorna então a soma de <code>x</code> e de <code>y</code>.</p> + +<p>Na essência o <code>makeAdder</code> trata-se de uma <em>função fábrica - </em>irá construir outras funções que podem adicionar um determinado valor específico a seu argumento. No exemplo acima usamos a fábrica de funções para criar duas novas funções - uma que adiciona 5 ao argumento, e outra que adiciona 10.</p> + +<p>Ambas as funções <code>add5</code> e <code>add10</code><em> </em><code> </code>são closures. Compartilham o mesmo corpo de definição de função mas armazenam diferentes ambientes. No ambiente da <code>add5</code>, por exemplo, <code>x</code> equivale a 5, enquanto na <code>add10</code> o valor de x é 10.</p> + +<h2 id="Closures_na_prática">Closures na prática</h2> + +<p>Esta é a teoria — mas closures são realmente úteis? Vamos considerar suas aplicações práticas. Uma closure deixa você associar dados (do ambiente) com uma função que trabalha estes dados. Isto está diretamente ligado com programação orientada a objetos, onde objetos nos permitem associar dados (as propriedades do objeto) utilizando um ou mais métodos.</p> + +<p>Consequentemente, você pode utilizar uma closure em qualquer lugar onde você normalmente utilizaria um objeto de único método.</p> + +<p>Situações onde você poderia utilizar isto são comuns em ambientes web. Muitos códigos escritos em JavaScript para web são baseados em eventos - nós definimos algum comportamento e então, o atribuimos a um evento que será disparado pelo usuário (quando uma tecla for pressionada, por exemplo). Nosso código normalmente é utilizado como callback: uma função que será executada como resposta ao evento.</p> + +<p>Aqui temos um exemplo prático: suponha que queremos adicionar alguns botões para ajustar o tamanho do texto de uma página. Um jeito de fazer seria especificar o tamanho da fonte no elemento body e então definir o tamanho dos outros elementos da página (os cabeçalhos, por exemplo) utilizando a unidade relativa em:</p> + +<pre class="brush: css">body { + font-family: Helvetica, Arial, sans-serif; + font-size: 12px; +} + +h1 { + font-size: 1.5em; +} +h2 { + font-size: 1.2em; +} +</pre> + +<p>Nossos botões interativos de tamanho de texto podem alterar a propriedade font-size do elemento body, e os ajustes serão refletidos em outros elementos graças à unidade relativa.</p> + +<p>O código JavaScript:</p> + +<pre class="brush: js">function makeSizer(size) { + return function() { + document.body.style.fontSize = size + 'px'; + }; +} + +var size12 = makeSizer(12); +var size14 = makeSizer(14); +var size16 = makeSizer(16); +</pre> + +<p><code>size12</code>, <code>size14</code> e <code>size16</code> agora são funções que devem redimensionar o texto do elemento body para 12, 14 e 16 pixels respectivamente. Nós podemos designá-las a botões (neste caso, links) como feito a seguir:</p> + +<pre class="brush: js">document.getElementById('size-12').onclick = size12; +document.getElementById('size-14').onclick = size14; +document.getElementById('size-16').onclick = size16; +</pre> + +<pre class="brush: html"><a href="#" id="size-12">12</a> +<a href="#" id="size-14">14</a> +<a href="#" id="size-16">16</a> +</pre> + +<p><a href="https://jsfiddle.net/vnkuZ">View on JSFiddle</a></p> + +<h2 id="Emulando_métodos_privados_com_closures">Emulando métodos privados com closures</h2> + +<p>Linguagens como Java oferecem a habilidade de declarar métodos privados, o que significa que eles só poderão ser chamados por outros métodos na mesma classe.</p> + +<p>O JavaScript não oferece uma maneira nativa de fazer isso, mas é possível emular métodos privados usando closures. Métodos privados não são somente úteis para restringir acesso ao código: eles também oferecem uma maneira eficaz de gerenciar seu namespace global, evitando que métodos não essenciais baguncem a interface pública do seu código.</p> + +<p>Veja como definir algumas funções públicas que acessam funções e variáveis privadas, usando closures que também é conhecido como <a class="external" href="http://www.google.com/search?q=javascript+module+pattern" title="http://www.google.com/search?q=javascript+module+pattern">module pattern</a>:</p> + +<pre class="brush: js">var Counter = (function() { + var privateCounter = 0; + function changeBy(val) { + privateCounter += val; + } + return { + increment: function() { + changeBy(1); + }, + decrement: function() { + changeBy(-1); + }, + value: function() { + return privateCounter; + } + } +})(); + +alert(Counter.value()); /* Alerts 0 */ +Counter.increment(); +Counter.increment(); +alert(Counter.value()); /* Alerts 2 */ +Counter.decrement(); +alert(Counter.value()); /* Alerts 1 */ +</pre> + +<p>Tem muita coisa acontecendo aqui. Nos exemplos anteriores cada closure teve o seu próprio ambiente; aqui nós criamos um ambiente único que é compartilhado por três funções: <code>Counter.increment</code>, <code>Counter.decrement</code> e <code>Counter.value</code>.</p> + +<p>O ambiente compartilhado é criado no corpo de uma função anônima, da qual é executada assim que é definida. O ambiente contém dois itens privados: uma variável chamada <code>privateCounter</code> e uma função chamada <code>changeBy</code>. Nenhum desses itens privados podem ser acessados diretamente de fora da função anônima. Ao invés disso, eles devem ser acessados pelas três funções públicas que são retornadas.</p> + +<p>Aquelas três funções públicas são closures que compartilham o mesmo ambiente. Graças ao escopo léxico do JavaScript, cada uma delas tem acesso a variável <code>privateCounter</code> e à função <code>changeBy</code>.</p> + +<div class="blockIndicator note"> +<p>Você perceberá que estamos definindo uma função anônima que cria um contador , e então o executamos imediatamente e atribuímos o resultado à variável <code>Counter</code>. Poderíamos armazenar essa função em uma variável separada e usá-la para criar diversos contadores.</p> +</div> + +<pre class="brush: js">var makeCounter = function() { + var privateCounter = 0; + function changeBy(val) { + privateCounter += val; + } + return { + increment: function() { + changeBy(1); + }, + decrement: function() { + changeBy(-1); + }, + value: function() { + return privateCounter; + } + } +}; + +var Counter1 = makeCounter(); +var Counter2 = makeCounter(); +alert(Counter1.value()); /* Alerts 0 */ +Counter1.increment(); +Counter1.increment(); +alert(Counter1.value()); /* Alerts 2 */ +Counter1.decrement(); +alert(Counter1.value()); /* Alerts 1 */ +alert(Counter2.value()); /* Alerts 0 */ +</pre> + +<p>Observe como cada um dos contadores mantém a sua independência em relação ao outro. Seu ambiente durante a execução da função <code>makeCounter()</code> é diferente a cada vez que ocorre. A variável <code>privateCounter</code> contém uma instância diferente a cada vez.</p> + +<div class="blockIndicator note"> +<p>Usar closures desta maneira oferece uma série de benefícios que estão normalmente associados a programação orientada a objetos, em particular encapsulamento e ocultação de dados.</p> +</div> + +<dl> +</dl> + +<h2 id="Criando_closures_dentro_de_loops_Um_erro_comum">Criando closures dentro de loops: Um erro comum</h2> + +<p>Antes da introdução da palavra chave <a href="/en-US/docs/JavaScript/Reference/Statements/let" title="let"><code>let</code></a> no JavaScript 1.7, um problema comum ocorria com closures quando eram criadas dentro de um loop. Considere o exemplo:</p> + +<pre class="brush: html"><p id="help">Helpful notes will appear here</p> +<p>E-mail: <input type="text" id="email" name="email"></p> +<p>Name: <input type="text" id="name" name="name"></p> +<p>Age: <input type="text" id="age" name="age"></p> +</pre> + +<pre class="brush: js">function showHelp(help) { + document.getElementById('help').innerHTML = help; +} + +function setupHelp() { + var helpText = [ + {'id': 'email', 'help': 'Your e-mail address'}, + {'id': 'name', 'help': 'Your full name'}, + {'id': 'age', 'help': 'Your age (you must be over 16)'} + ]; + + for (var i = 0; i < helpText.length; i++) { + var item = helpText[i]; + document.getElementById(item.id).onfocus = function() { + showHelp(item.help); + } + } +} + +setupHelp(); +</pre> + +<p><a href="https://jsfiddle.net/v7gjv">View on JSFiddle</a></p> + +<p>O array <code>helpText</code> define três dicas úteis, cada uma associada ao ID de um input no documento. O loop percorre essas definições, atrelando um evento onfocus para cada um que mostra o método de ajuda associado.</p> + +<p>Se você tentar executar esse código, Você verá que não vai funcionar como esperado. Não importa em qual campo ocorre o focus, a mensagem sobre a sua idade será mostrada.</p> + +<p>O motivo disto é que as funções atreladas ao onfocus são closures; elas consistem na definição da função e do ambiente capturado do escopo da função <code>setupHelp</code>. Três closures foram criados, mas todos eles compartilham o mesmo ambiente. No momento em que os callbacks do onfocus são executados, o loop segue seu curso e então a variável item (compartilhada por todos os três closures) fica apontando para a última entrada na lista <code>helpText</code>.</p> + +<p>Uma solução seria neste caso usar mais closures: em particular, usar uma fábrica de funções como descrito anteriormente:</p> + +<pre class="brush: js">function showHelp(help) { + document.getElementById('help').innerHTML = help; +} + +function makeHelpCallback(help) { + return function() { + showHelp(help); + }; +} + +function setupHelp() { + var helpText = [ + {'id': 'email', 'help': 'Your e-mail address'}, + {'id': 'name', 'help': 'Your full name'}, + {'id': 'age', 'help': 'Your age (you must be over 16)'} + ]; + + for (var i = 0; i < helpText.length; i++) { + var item = helpText[i]; + document.getElementById(item.id).onfocus = makeHelpCallback(item.help); + } +} + +setupHelp(); +</pre> + +<p><a href="https://jsfiddle.net/v7gjv/1">View on JSFiddle</a></p> + +<p>Isto funciona conforme o esperado. Ao invés dos callbacks compartilharem o mesmo ambiente, a função <code>makeHelpCallback</code> cria um novo ambiente para cada um no qual <code>help</code> se refere à string correspondente do array <code>helpText</code>.</p> + +<h2 id="Considerações_de_performance">Considerações de performance</h2> + +<p>Não é sábio criar funções dentro de outras funções se o closure não for necessário para uma tarefa em particular, pois ele afetará a performance do script de forma bem negativa tanto em velocidade de processamento quanto em consumo de memória.</p> + +<p>Por exemplo, ao criar uma nova classe/objeto, os métodos devem normalmente estar associados ao protótipo do objeto do que definido no construtor. O motivo disso é que sempre que o construtor for chamado os métodos serão reatribuídos (isto é, para cada criação de objeto).</p> + +<p>Considere o seguinte exemplo pouco prático porém demonstrativo:</p> + +<pre class="brush: js">function MyObject(name, message) { + this.name = name.toString(); + this.message = message.toString(); + this.getName = function() { + return this.name; + }; + + this.getMessage = function() { + return this.message; + }; +} +</pre> + +<p>O código anterior não aproveita os benefícios dos closures e portanto poderia ser reformulado assim:</p> + +<pre class="brush: js">function MyObject(name, message) { + this.name = name.toString(); + this.message = message.toString(); +} +MyObject.prototype = { + getName: function() { + return this.name; + }, + getMessage: function() { + return this.message; + } +}; +</pre> + +<p>Ou assim:</p> + +<pre class="brush: js">function MyObject(name, message) { + this.name = name.toString(); + this.message = message.toString(); +} +MyObject.prototype.getName = function() { + return this.name; +}; +MyObject.prototype.getMessage = function() { + return this.message; +}; +</pre> + +<p>Nos dois exemplos anteriores, o protótipo herdado pode ser compartilhado por todos os objetos, e as definições de métodos não precisam ocorrer sempre que o objeto for criado. Veja <a href="/en-US/docs/JavaScript/Guide/Details_of_the_Object_Model" title="Detalhes do modelo de objeto">Detalhes do modelo de objeto</a> para mais detalhes.</p> diff --git a/files/pt-br/web/javascript/guide/coleções_chaveadas/index.html b/files/pt-br/web/javascript/guide/coleções_chaveadas/index.html new file mode 100644 index 0000000000..cb626865f8 --- /dev/null +++ b/files/pt-br/web/javascript/guide/coleções_chaveadas/index.html @@ -0,0 +1,149 @@ +--- +title: Coleções chaveadas +slug: Web/JavaScript/Guide/Coleções_chaveadas +tags: + - Coleções + - Guía + - JavaScript + - Mapas +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}</div> + +<p class="summary">This chapter introduces collections of data which are ordered by a key; Map and Set objects contain elements which are iterable in the order of insertion.</p> + +<h2 id="Maps">Maps</h2> + +<h3 id="Map_object"><code>Map</code> object</h3> + +<p>ECMAScript 6 introduces a new data structure to map values to values. A {{jsxref("Map")}} object is a simple key/value map and can iterate its elements in insertion order</p> + +<p>The following code shows some basic operations with a <code>Map</code>. See also the {{jsxref("Map")}} reference page for more examples and the complete API. You can use a {{jsxref("Statements/for...of","for...of")}} loop to return an array of <code>[key, value]</code> for each iteration.</p> + +<pre class="brush: js">var sayings = new Map(); +sayings.set("dog", "woof"); +sayings.set("cat", "meow"); +sayings.set("elephant", "toot"); +sayings.size; // 3 +sayings.get("fox"); // undefined +sayings.has("bird"); // false +sayings.delete("dog"); + +for (var [key, value] of sayings) { + console.log(key + " goes " + value); +} +// "cat goes meow" +// "elephant goes toot" +</pre> + +<h3 id="Object_and_Map_compared"><code>Object</code> and <code>Map</code> compared</h3> + +<p>Traditionally, {{jsxref("Object", "objects", "", 1)}} have been used to map strings to values. Objects allow you to set keys to values, retrieve those values, delete keys, and detect whether something is stored at a key. <code>Map</code> objects, however, have a few more advantages that make them better maps.</p> + +<ul> + <li>The keys of an <code>Object</code> are {{jsxref("Global_Objects/String","Strings")}}, where they can be of any value for a <code>Map</code>.</li> + <li>You can get the size of a <code>Map</code> easily while you have to manually keep track of size for an <code>Object</code>.</li> + <li>The iteration of maps is in insertion order of the elements.</li> + <li>An <code>Object</code> has a prototype, so there are default keys in the map. (this can be bypassed using <code>map = Object.create(null)</code>).</li> +</ul> + +<p>These two tips can help you to decide whether to use a <code>Map</code> or an <code>Object</code>:</p> + +<ul> + <li>Use maps over objects when keys are unknown until run time, and when all keys are the same type and all values are the same type.</li> + <li>Use objects when there is logic that operates on individual elements.</li> +</ul> + +<h3 id="WeakMap_object"><code>WeakMap</code> object</h3> + +<p>The {{jsxref("WeakMap")}} object is a collection of key/value pairs in which the <strong>keys are objects only</strong> and the values can be arbitrary values. The object references in the keys are held <em>weakly</em> meaning that they are target of garbage collection (GC) if there is no other reference to the object anymore. The <code>WeakMap</code> API is the same as the <code>Map</code> API.</p> + +<p>One difference to <code>Map</code> objects is that <code>WeakMap</code> keys are not enumerable (i.e. there is no method giving you a list of the keys). If they were, the list would depend on the state of garbage collection, introducing non-determinism.</p> + +<p>For more information and example code, see also "Why <em>Weak</em>Map?" on the {{jsxref("WeakMap")}} reference page.</p> + +<p>One use case of <code>WeakMap</code> objects is to store private data for an object or to hide implementation details. The following example is from Nick Fitzgerald blog post <a href="http://fitzgeraldnick.com/weblog/53/">"Hiding Implementation Details with ECMAScript 6 WeakMaps"</a>. The private data and methods belong inside the object and are stored in the <code>privates</code> WeakMap object. Everything exposed on the instance and prototype is public; everything else is inaccessible from the outside world because <code>privates</code> is not exported from the module</p> + +<pre class="brush: js">const privates = new WeakMap(); + +function Public() { + const me = { + // Private data goes here + }; + privates.set(this, me); +} + +Public.prototype.method = function () { + const me = privates.get(this); + // Do stuff with private data in `me`... +}; + +module.exports = Public; +</pre> + +<h2 id="Sets">Sets</h2> + +<h3 id="Set_object"><code>Set</code> object</h3> + +<p>{{jsxref("Set")}} objects are collections of values. You can iterate its elements in insertion order. A value in a <code>Set</code> may only occur once; it is unique in the <code>Set</code>'s collection.</p> + +<p>The following code shows some basic operations with a <code>Set</code>. See also the {{jsxref("Set")}} reference page for more examples and the complete API.</p> + +<pre class="brush: js">var mySet = new Set(); +mySet.add(1); +mySet.add("some text"); +mySet.add("foo"); + +mySet.has(1); // true +mySet.delete("foo"); +mySet.size; // 2 + +for (let item of mySet) console.log(item); +// 1 +// "some text" +</pre> + +<h3 id="Converting_between_Array_and_Set">Converting between Array and Set</h3> + +<p>You can create an {{jsxref("Array")}} from a Set using {{jsxref("Array.from")}} or the <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator">spread operator</a>. Also, the <code>Set</code> constructor accepts an <code>Array</code> to convert in the other direction. Note again that <code>Set</code> objects store unique values, so any duplicate elements from an Array are deleted when converting.</p> + +<pre class="brush: js">Array.from(mySet); +[...mySet2]; + +mySet2 = new Set([1,2,3,4]); +</pre> + +<h3 id="Array_and_Set_compared"><code>Array</code> and <code>Set</code> compared</h3> + +<p>Traditionally, a set of elements has been stored in arrays in JavaScript in a lot of situations. The new <code>Set</code> object, however, has some advantages:</p> + +<ul> + <li>Checking whether an element exists in an collection using {{jsxref("Array.indexOf", "indexOf")}} for arrays is slow.</li> + <li><code>Set</code> objects let you delete elements by their value. With an array you would have to splice based on a element's index.</li> + <li>The value {{jsxref("NaN")}} can not be found with <code>indexOf</code> in array.</li> + <li><code>Set</code> objects store unique values, you don't have to keep track of duplicates by yourself.</li> +</ul> + +<h3 id="WeakSet_object"><code>WeakSet</code> object</h3> + +<p>{{jsxref("WeakSet")}} objects are collections of objects. An object in the <code>WeakSet</code> may only occur once; it is unique in the <code>WeakSet</code>'s collection and objects are not enumerable.</p> + +<p>The main differences to the {{jsxref("Set")}} object are:</p> + +<ul> + <li>In contrast to <code>Sets</code>, <code>WeakSets</code> are <strong>collections of objects only</strong> and not of arbitrary values of any type.</li> + <li>The <code>WeakSet</code> is <em>weak</em>: References to objects in the collection are held weakly. If there is no other reference to an object stored in the <code>WeakSet</code>, they can be garbage collected. That also means that there is no list of current objects stored in the collection. <code>WeakSets</code> are not enumerable.</li> +</ul> + +<p>The use cases of <code>WeakSet</code> objects are limited. They will not leak memory so it can be safe to use DOM elements as a key and mark them for tracking purposes, for example.</p> + +<h2 id="Key_and_value_equality_of_Map_and_Set">Key and value equality of <code>Map</code> and <code>Set</code></h2> + +<p>Both, the key equality of <code>Map</code> objects and the value equality of <code>Set</code> objects, are based on the "<a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero">same-value-zero algorithm</a>":</p> + +<ul> + <li>Equality works like the identity comparison operator <code>===</code>.</li> + <li><code>-0</code> and <code>+0</code> are considered equal.</li> + <li>{{jsxref("NaN")}} is considered equal to itself (contrary to <code>===</code>).</li> +</ul> + +<p>{{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}</p> diff --git a/files/pt-br/web/javascript/guide/declarações/index.html b/files/pt-br/web/javascript/guide/declarações/index.html new file mode 100644 index 0000000000..e352b58f6d --- /dev/null +++ b/files/pt-br/web/javascript/guide/declarações/index.html @@ -0,0 +1,429 @@ +--- +title: Controle de Fluxo e Manipulação de Erro +slug: Web/JavaScript/Guide/Declarações +tags: + - Guia(2) + - Iniciante + - JavaScript + - declarações + - declarações de controle +translation_of: Web/JavaScript/Guide/Control_flow_and_error_handling +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}</div> + +<p class="summary">O JavaScript suporta um conjunto compacto de<strong> </strong>declarações, especificamente de fluxo de controle, que você pode utilizar para atribuir uma grande interatividade a páginas web. Este capítulo fornece uma visão geral destas declarações.</p> + +<p>Veja a <a href="/pt-BR/docs/Web/JavaScript/Reference/Statements">Referência do JavaScript</a> para detalhes sobre as declarações mostradas neste capítulo. No código em JavaScript, o caractere ponto e vírgula (<code>;</code>) é utilizado para separar declarações.</p> + +<p>Toda expressão também é uma declaração. Veja <a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators">Expressões e Operadores</a> para informações completas sobre expressões.</p> + +<h2 id="Declaração_em_bloco">Declaração em bloco</h2> + +<p>Uma declaração em bloco é utilizada para agrupar declarações. O bloco é delimitado por um par de chaves:</p> + +<pre class="syntaxbox">{ + declaracao_1; + declaracao_2; + . + . + . + declaracao_n; +} +</pre> + +<h3 id="Exemplo"><strong>Exemplo</strong></h3> + +<p>Declarações em bloco são utilizadas geralmente com declarações de fluxo de controle (ex. <code>if</code>, <code>for</code>, <code>while</code>).</p> + +<pre class="brush: js">while (x < 10) { + x++; +} +</pre> + +<p>Aqui, <code>{ x++; }</code> é a declaração de bloco.</p> + +<p><strong>Importante</strong>: <span class="short_text" id="result_box" lang="pt"><span class="hps">Antes de</span> <span class="hps">ECMAScript</span> <span class="hps">6 o </span></span><span style="line-height: 1.5;">JavaScript <strong>não</strong> possuía escopo de bloco. Variáveis introduzidas dentro de um bloco possuem como escopo a função ou o script em que o bloco está contido, e, definir tais variáveis tem efeito muito além do bloco em si. Em outras palavras, declarações de bloco não introduzem um escopo. Embora blocos "padrão" sejam uma sintaxe válida não utilize-os, em JavaScript, pensando que funcionam como em C ou Java porque eles não funcionam da maneira que você acredita. Por exemplo:</span></p> + +<pre class="brush: js">var x = 1; +{ + var x = 2; +} +console.log(x); // exibe 2 +</pre> + +<p>Este código exibe 2 porque a declaração <code>var x</code> dentro do bloco possui o mesmo escopo que a declaração <code>var x</code> antes do bloco. Em C ou Java, o código equivalente exibiria 1.</p> + +<h2 id="Declarações_condicionais">Declarações condicionais</h2> + +<p>Uma declaração condicional é um conjunto de comandos que são executados caso uma condição especificada seja verdadeira. O JavaScript suporta duas declarações condicionais: <code>if...else</code> e <code>switch</code>.</p> + +<h3 id="if...else_statement" name="if...else_statement">Declaração if...else</h3> + +<p>Use a declaração <code>if</code> para executar alguma declaração caso a condição lógica for verdadeira. Use a cláusula opcional <code>else</code> para executar alguma declaração caso a condição lógica for falsa. Uma declaração <code>if</code> é declarada da seguinte maneira:</p> + +<pre class="syntaxbox">if (condicao) { + declaracao_1; +} else { + declaracao_2; +}</pre> + +<p>onde <code>condicao</code> pode ser qualquer expressão que seja avaliada como verdadeira ou falsa. Veja <a href="/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Boolean#Description">Boolean</a> para uma explicação sobre o que é avaliado como <code>true</code> e <code>false</code>. <span style="line-height: 1.5;">Se <code>condicao</code> for avaliada como verdadeira, declaracao<code>_1</code> é executada; caso contrário, <code>declaracao_2</code> é executada. <code>declaracao_1</code> e <code>declaracao_2</code> podem ser qualquer declaração, incluindo declarações <code>if</code> aninhadas.</span></p> + +<p>Você pode também combinar declarações utilizando <code>else if</code> para obter várias condições testadas em sequência, como o seguinte:</p> + +<pre class="syntaxbox">if (condicao) { + declaracao_1; +} else if (condicao_2) { + declaracao_2; +} else if (condicao_n) { + declaracao_n; +} else { + declaracao_final; +}</pre> + +<p>Para executar várias declarações, agrupe-as em uma declaração em bloco (<code>{ ... }</code>). Em geral, é uma boa prática sempre utilizar declarações em bloco, especialmente ao aninhar declarações <code>if</code>:</p> + +<pre class="syntaxbox">if (condicao) { + declaracao_1_executada_se_condicao_for_verdadeira; + declaracao_2_executada_se_condicao_for_verdadeira; +} else { + declaracao_3_executada_se_condicao_for_falsa; + <span style="font-size: 1rem;">declaracao_4_executada_se_condicao_for_falsa</span>; +} +</pre> + +<div>Recomenda-se não utilizar atribuições simples em uma expressão condicional porque o símbolo de atribuição poderia ser confundido com o de igualdade ao dar uma olhada no código. Por exemplo, não utilize o seguinte código:</div> + +<pre class="example-bad brush: js">if (x = y) { + /* faça a coisa certa */ +} +</pre> + +<p>Caso tenha que utilizar uma atribuição em uma expressão condicional, uma prática comum é colocar parênteses adicionais em volta da atribuição. Por exemplo:</p> + +<pre class="brush: js">if ((x = y)) { + /* faça a coisa certa */ +} +</pre> + +<h4 id="Valores_avaliados_como_falsos">Valores avaliados como falsos</h4> + +<p>Os seguintes valores são avaliados como falsos:</p> + +<ul> + <li><code>false</code></li> + <li><code>undefined</code></li> + <li><code>null</code></li> + <li><code>0</code></li> + <li><code>NaN</code></li> + <li>string vazia (<code>""</code>)</li> +</ul> + +<p>Todos os outros valores, incluindo todos os objetos, são avaliados como verdadeiros quando passados para uma declaração condicional.</p> + +<p>Não confunda os valores booleanos primitivos <code>true</code> e <code>false</code> com os valores de <code>true</code> e <code>false</code> do objeto <a href="/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Boolean#Description">Boolean</a>. Por exemplo:</p> + +<pre>var b = new Boolean(false); +if (b) // esta condição é avaliada como verdadeira +if (b == true) // esta condição é avaliada como falsa </pre> + +<p> </p> + +<h4 id="Exemplo_2"><strong>Exemplo</strong></h4> + +<p>No exemplo a seguir, a função <code>verifiqueDados</code> retorna verdadeiro se o número de caracteres em um objeto <code>Text</code> for três; caso contrário, exibe um alerta e retorna <code>falso</code>.</p> + +<pre class="brush: js">function verifiqueDados() { + if (document.form1.tresCaracteres.value.length == 3) { + return true; + } else { + alert("Informe exatamente três caracteres. " + + document.form1.tresCaracteres.value + " não é válido."); + return false; + } +} +</pre> + +<h3 id="switch_statement" name="switch_statement">Declaração switch</h3> + +<p>Uma declaração <code>switch</code> permite que um programa avalie uma expressão e tente associar o valor da expressão ao rótulo de um <code>case</code>. Se uma correspondência é encontrada, o programa executa a declaração associada. Uma declaração <code>switch</code> se parece com o seguinte:</p> + +<pre class="syntaxbox">switch (expressao) { + case rotulo_1: + declaracoes_1 + [break;] + case rotulo_2: + declaracoes_2 + [break;] + ... + default: + declaracoes_padrao + [break;] +} +</pre> + +<p>O programa primeiramente procura por uma cláusula <code>case</code> com um rótulo que corresponda ao valor da expressão e então transfere o controle para aquela cláusula, executando as declaracoes associadas. Se nenhum rótulo correspondente é encontrado, o programa procura pela cláusula opcional <code>default</code> e, se encontrada, transfere o controle àquela cláusula, executando as declarações associadas. Se nenhuma cláusula <code>default</code> é encontrada, o programa continua a execução a partir da declaracao seguinte ao <code>switch</code>. Por convenção, a cláusula <code>default</code> é a última, mas não é necessário que seja assim.</p> + +<p>A instrução <code>break</code> associada a cada cláusula <code>case,</code> garante que o programa sairá do <code>switch</code> assim que a declaração correspondente for executada e que continuará a execução a partir da declaração seguinte ao <code>switch</code>. Se a declaração <code>break</code> for omitida, o programa continua a execução a partir da próxima declaração dentro do <code>switch</code>.</p> + +<h4 id="Exemplo_3"><strong>Exemplo</strong></h4> + +<p>No exemplo a seguir, se <code>tipofruta</code> for avaliada como "<code>Banana</code>", o programa faz a correspondência do valor com <code>case </code>"<code>Banana</code>" e executa a declaração associada. Quando o <code>break</code> é encontrado, o programa termina o <code>switch</code> e executa a declaração seguinte ao condicional. Se o <code>break</code> fosse omitido, a declaração de <code>case </code>"<code>Cereja</code>" também seria executada.</p> + +<pre class="brush: js">switch (tipofruta) { + case "Laranja": + console.log("O quilo da laranja está R$0,59.<br>"); + break; + case "Maçã": + console.log("O quilo da maçã está R$0,32.<br>"); + break; + case "Banana": + console.log("O quilo da banana está R$0,48.<br>"); + break; + case "Cereja": + console.log("O quilo da cereja está R$3,00.<br>"); + break; + case "Manga": + console.log("O quilo da manga está R$0,56.<br>"); + break; + case "Mamão": + console.log("O quilo do mamão está R$2,23.<br>"); + break; + default: + console.log("Desculpe, não temos " + tipofruta + ".<br>"); +} +console.log("Gostaria de mais alguma coisa?<br>");</pre> + +<h2 id="Declarações_de_Manipulação_de_Error">Declarações de Manipulação de Error</h2> + +<p>Você pode chamar uma exceção usando a declaração <code>throw</code> e manipulá-la usando a declaração <code>try...catch</code>.</p> + +<ul> + <li><a href="#">Declaração throw</a></li> + <li><a href="#try_catch_statement">Declaração <code>try...catch</code> </a></li> +</ul> + +<h3 id="Tipos_de_exceções">Tipos de exceções</h3> + +<p>Praticamente pode-se utilizar <code>throw</code> em qualquer objeto de JavaScript. Todavia, nem todos os objetos ativados por <code>throw</code> são igualmente criados. Embora seja bastante comum tratar números ou strings como erros usando <code>throw</code>, é frequentemente mais eficiente usar alguns tipos de exceções especificamente criadas para esses propósitos:</p> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects#Fundamental_objects">ECMAScript exceptions</a></li> + <li>{{domxref("DOMException")}} and {{domxref("DOMError")}}</li> +</ul> + +<h3 id="Declaração_throw"><code>Declaração throw</code></h3> + +<p>Use a declaração <code>throw</code> para lançar uma exceção. Quando você lança uma exceção, você especifica a expressão contendo o valor a ser lançado:</p> + +<pre class="syntaxbox">throw expressão; +</pre> + +<p>Você pode lançar qualquer expressão, não apenas expressões de um tipo específico. O código a seguir lança várias exceções de diferentes tipos:</p> + +<pre class="brush: js">throw "Error2"; // tipo string +throw 42; // tipo numérico +throw true; // tipo booleano +throw {toString: function() { return "Eu sou um objeto!"; } }; +</pre> + +<div class="note"><strong>Nota: </strong> Você pode especificar um objeto quando você lança uma exceção. Você pode então, referenciar as propriedades de um objeto no bloco catch. O exemplo a seguir cria um objeto myUserException do tipo userException e o usa em uma declaração throw.</div> + +<pre class="brush: js">// Cria um objeto do tipo UserException +function UserException(mensagem) { + this.mensagem = mensagem; + this.nome = "UserException"; +} + +// Realiza a conversão da exceção para uma string adequada quando usada como uma string. +// (ex. pelo console de erro) +UserException.prototype.toString = function() { + return this.name + ': "' + this.message + '"'; +} + +// Cria uma instância de um tipo de objeto e lança ela +throw new UserException("Valor muito alto");</pre> + +<h3 id="Exception_handling_statements" name="Exception_handling_statements"><code>Declaração try...catch</code></h3> + +<p>A declaração <code>try...catch</code> coloca um bloco de declarações em try, e especifica uma ou mais respostas para uma exceção lançada. Se uma exceção é lançada, a declaração <code>try...catch</code> pegá-a.</p> + +<p>A declaração <code>try...catch</code> é composta por um bloco <code>try</code>, que contém uma ou mais declarações, e zero ou mais blocos <code>catch</code>, contendo declarações que especificam o que fazer se uma exceção é lançada no bloco <code>try</code>. Ou seja, você deseja que o bloco <code>try</code> tenha sucesso, e se ele não tiver êxito, você quer o controle passado para o bloco <code>catch</code>. Se qualquer declaração do bloco <code>try</code> (ou em uma função chamada dentro do bloco <code>try</code>) lança uma exceção, o controle é imediatamente mudado para o bloco <code>catch</code>. Se nenhuma exceção é lançada no bloco <code>try</code>, o bloco <code>catch</code> é ignorado. O bloco <code>finally</code> executa após os blocos <code>try</code> e <code>catch</code> executarem, mas antes das declarações seguinte ao bloco<code> try...catch.</code></p> + +<p>O exemplo a seguir usa a declaração <code>try...catch</code>. O exemplo chama uma função que recupera o nome de um mês no array com base no valor passado para a função. Se o valor não corresponde ao número de um mês (1-12), uma exceção é lançada com o valor "<code>InvalidMonthNo</code>" e as declarações no bloco <code>catch</code> define a váriavel <code>monthName</code> para <code>unknown</code>.</p> + +<pre class="brush: js">function getMonthName(mo) { + mo = mo - 1; // Ajusta o número do mês para o índice do array (1 = Jan, 12 = Dec) + var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul", + "Aug","Sep","Oct","Nov","Dec"]; + if (months[mo]) { + return months[mo]; + } else { + throw "InvalidMonthNo"; //lança uma palavra-chave aqui usada. + } +} + +try { // statements to try + monthName = getMonthName(myMonth); // função poderia lançar uma exceção +} +catch (e) { + monthName = "unknown"; + logMyErrors(e); // passa a exceção para o manipulador de erro -> sua função local. +} +</pre> + +<h4 id="The_catch_Block" name="The_catch_Block">O bloco <code>catch</code></h4> + +<p>Você pode usar um bloco <code>catch</code> para lidar com todas as exceções que podem ser geradas no bloco <code>try</code>.</p> + +<pre class="syntaxbox">catch (catchID) { + declaracoes +} +</pre> + +<p>O bloco <code>catch</code> específica um identificador (<code>catchID</code> na sintaxe anterior), que contém o valor especificado pela declaração <code>throw</code>; você pode usar esse identificador para obter informações sobre a exceção que foi lançada. JavaScript cria este identificador quando o bloco <code>catch</code> é inserido; o identificador dura enquanto o bloco <code>catch</code> está em execução, depois que termina a execução do bloco <code>catch</code>, o identificador não estará mais disponível.</p> + +<p>Por exemplo, o seguinte código lança uma exceção. Quando a exceção ocorre, o controle é transferido para o bloco <code>catch</code>.</p> + +<pre class="brush: js">try { + throw "myException"; // lança uma exceção +} +catch (e) { + // declarações de lidar com as exceções + logMyErrors(e); // passar a exceção para o manipulador de erro +} +</pre> + +<h4 id="O_bloco_finally">O bloco <code>finally</code></h4> + +<p>O bloco <code>finally</code> contém instruções para executar após os blocos <code>try</code> e <code>catch</code>, mas antes das declarações seguinte a declaração <code>try...catch</code>. O bloco <code>finally</code> é executado com ou sem o lançamento de uma exceção. Se uma exceção é lançada, a declaração no bloco <code>finally</code> executa, mesmo que nenhum bloco <code>catch</code> processe a exceção.</p> + +<p>Você pode usar bloco <code>finally</code> para deixar a falha de seu script agradável quando uma exceção ocorre; por exemplo, você pode precisar liberar um recurso que seu script tem amarrado. O exemplo a seguir abre um arquivo e então executa instruções que usam o arquivo (JavaScript do lado do servidor permite que você acesse arquivos). Se um exceção é lançada enquanto o arquivo é aberto, o bloco <code>finally</code> fecha o arquivo antes do script falhar.</p> + +<pre class="brush: js">openMyFile(); +try { + writeMyFile(theData); //Isso pode lançar um erro +} catch(e) { + handleError(e); // Se temos um erro temos que lidar com ele +} finally { + closeMyFile(); // Sempre feche o recurso +} +</pre> + +<p>Se o bloco <code>finally</code> retornar um valor, este valor se torna o valor de toda a entrada <code>try-catch-finally</code>, independente de quaisquer declarações de retorno nos blocos <code>try</code> e <code>catch</code>:</p> + +<pre class="brush: js">function f() { + try { + console.log(0); + throw "bogus"; + } catch(e) { + console.log(1); + return true; // essa declaração de retorno é suspensa + // até que o bloco finally seja concluído + console.log(2); // não executa + } finally { + console.log(3); + return false; // substitui o "return" anterior + console.log(4); // não executa + } + // "return false" é executado agora + console.log(5); // não executa +} +f(); // exibe 0, 1, 3; retorna false +</pre> + +<p>Substituições de valores de retorno pelo bloco <code>finally</code> também se aplica a exceções lançadas ou re-lançadas dentro do bloco <code>catch</code>:</p> + +<pre class="brush: js">function f() { + try { + throw "bogus"; + } catch(e) { + console.log('captura interior "falso"'); + throw e; // essa instrução throw é suspensa até + // que o bloco finally seja concluído + } finally { + return false; // substitui "throw" anterior + } + // "return false" é executado agora +} + +try { + f(); +} catch(e) { + // isto nunca é executado porque o throw dentro + // do catch é substituído + // pelo return no finally + console.log('captura exterior "falso"'); +} + +// SAIDA +// captura interior "falso"</pre> + +<h4 id="Nesting_try...catch_Statements" name="Nesting_try...catch_Statements">Aninhando declarações try...catch</h4> + +<p>Você pode aninhar uma ou mais declarações <code>try...catch</code>. Se uma declaração <code>try...catch</code> interior não tem um bloco <code>catch</code>, o delimitador do bloco <code>try...catch</code> da declaração <code>catch</code> é verificado por uma correspondência.</p> + +<h3 id="Utilizing_Error_objects" name="Utilizing_Error_objects">Utilizando objetos de e<code>rro</code></h3> + +<p>Dependendo do tipo de erro, você pode ser capaz de usar as propriedade 'name' e 'message' para pegar uma mensagem mais refinada. A propriedade 'name' fornece a classe geral de erro (ex., 'DOMException' ou 'Error'), enquanto 'message' geralmente oferece uma mensagem mais sucinta do que se poderia obter através da conversão do objeto de erro para uma string.</p> + +<p>Se você está lançando suas próprias exceções, a fim de tirar proveito dessas propriedades (como o seu bloco catch não discrimina entre suas próprias exceções e as exceções próprias da linguagem), você pode usar o construtor Error. Por exemplo:</p> + +<pre class="brush: js">function doSomethingErrorProne () { + if (ourCodeMakesAMistake()) { + throw (new Error('A mensagem')); + } else { + doSomethingToGetAJavascriptError(); + } +} +.... +try { + doSomethingErrorProne(); +} +catch (e) { + console.log(e.name); // exibe 'Error' + console.log(e.message); // exibe 'A mensagem' ou uma mensagem de erro em JavaScript +}</pre> + +<h2 id="Promises">Promises</h2> + +<p>Começando com ECMAScript 6, JavaScript ganha suporte para objetos {{jsxref("Promise")}} que lhe permite controlar o fluxo de operações diferídas e assíncronas.</p> + +<p>Uma Promise assume um destes estados:</p> + +<ul> + <li><em>pending</em>: estado inicial, não <code>fulfilled</code>, ou <code>rejected</code>.</li> + <li><em>fulfilled</em>: operação bem sucedida.</li> + <li><em>rejected</em>: operação falha.</li> + <li><em>settled</em>: A Promise é fulfilled ou rejected, mas não pending.</li> +</ul> + +<p><img alt="" src="https://mdn.mozillademos.org/files/8633/promises.png" style="height: 297px; width: 801px;"></p> + +<h3 id="Carregando_uma_imagem_com_XHR">Carregando uma imagem com XHR</h3> + +<p>Um exemplo simples usando Promise e <code><a href="/pt-BR/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a> para carregar uma imagem disponível no repositório MDN GitHub </code><a href="https://github.com/mdn/promises-test/blob/gh-pages/index.html">promise-test</a>. Você também pode <a href="http://mdn.github.io/promises-test/">vê-lo executando</a>. Cada etapa está comentada o que lhe permite seguir de perto a arquitetura Promise e arquitetura XHR. Aqui está a versão não comentada, mostrando o fluxo <code>Promise</code> para que você possa ter uma ideia:</p> + +<pre class="brush: js">function imgLoad(url) { + return new Promise(function(resolve, reject) { + var request = new XMLHttpRequest(); + request.open('GET', url); + request.responseType = 'blob'; + request.onload = function() { + if (request.status === 200) { + resolve(request.response); + } else { + reject(Error('Image didn\'t load successfully; error code:' + + request.statusText)); + } + }; + request.onerror = function() { + reject(Error('There was a network error.')); + }; + request.send(); + }); +}</pre> + +<p>Para uma informação mais detalhada, consulte a página de referência {{jsxref("Promise")}}.</p> + +<div>{{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}</div> diff --git a/files/pt-br/web/javascript/guide/detalhes_do_modelo_do_objeto/index.html b/files/pt-br/web/javascript/guide/detalhes_do_modelo_do_objeto/index.html new file mode 100644 index 0000000000..55a4c928a5 --- /dev/null +++ b/files/pt-br/web/javascript/guide/detalhes_do_modelo_do_objeto/index.html @@ -0,0 +1,705 @@ +--- +title: Detalhes do modelo de objeto +slug: Web/JavaScript/Guide/Detalhes_do_Modelo_do_Objeto +tags: + - Entidade + - Modelo + - Objeto + - Orientação á Objeto +translation_of: Web/JavaScript/Guide/Details_of_the_Object_Model +--- +<p class="summary"><span id="result_box" lang="pt"><span class="hps">JavaScript</span> <span class="hps">é uma linguagem</span> orientada a <span class="hps">objetos</span> <span class="hps">com base em</span> <span class="hps">protótipos,</span> <span class="hps">em vez de ser</span> <span class="hps">baseada em classes</span><span>.</span> <span class="hps">Devido a essa</span> <span class="hps">base diferente</span><span>, pode ser</span> <span class="hps">menos evidente </span><span class="hps">como</span> o <span class="hps">JavaScript</span> <span class="hps">permite criar</span> <span class="hps">hierarquias de</span> <span class="hps">objetos</span> <span class="hps">e</span> <span class="hps">ter</span> <span class="hps">herança de</span> <span class="hps">propriedades e seus valores</span><span>.</span> <span class="hps">Este capítulo</span> <span class="hps">tenta</span> <span class="hps">esclarecer essa situação.</span></span></p> + +<div class="almost_half_cell" id="gt-res-content"> +<div dir="ltr" style="zoom: 1;"><span id="result_box" lang="pt"><span class="hps">Este capítulo assume que</span> <span class="hps">você já está</span> <span class="hps">um pouco familiarizado com</span> <span class="hps">JavaScript</span> <span class="hps">e</span> <span class="alt-edited hps">que você já tenha usado</span> <span class="hps">funções JavaScript</span> <span class="hps">para criar </span></span><span id="result_box" lang="pt"><span class="hps">simples </span></span><span id="result_box" lang="pt"><span class="hps">objetos</span><span class="hps">.</span></span></div> + +<div dir="ltr" style="zoom: 1;"></div> +</div> + +<h2 id="Linguagens_baseada_em_classe_vs._baseada_em_protótipo">Linguagens baseada em classe vs. baseada em protótipo</h2> + +<p><span id="result_box" lang="pt"><span class="hps">Linguagens orientadas a objetos</span> <span class="hps">baseadas em classe</span><span>, como</span> <span class="hps">Java</span> <span class="hps">e</span> <span class="hps">C</span> <span class="hps">+</span> <span class="hps">+</span><span>,</span> <span class="hps">são fundadas</span> <span class="hps">no conceito de</span> <span class="hps">duas entidades distintas</span><span>: classes</span> <span class="hps">e instâncias.</span></span></p> + +<ul> + <li><span lang="pt"><span class="hps">Uma </span><span class="hps">classe define</span> <span class="hps">todas as propriedades</span> <span class="hps">(considerando-se</span> <span class="hps">os métodos</span> <span class="hps">e campos em</span> <span class="hps">Java</span><span>,</span> <span class="hps">ou membros em</span> <span class="hps">C + +</span><span>, para ser</span> <span class="hps">propriedades)</span> <span class="hps">que caracterizam</span> <span class="hps">um determinado conjunto de</span> <span class="hps">objetos.</span> <span class="hps">Uma classe é</span> algo<span class="hps"> abstrato</span><span>, ao invés de</span> <span class="hps">qualquer membro</span> <span class="hps">particular do</span> <span class="hps">conjunto de objetos</span> <span class="hps">que descreve.</span> <span class="hps">Por exemplo,</span> <span class="hps">a classe <code>Employee</code></span><span class="hps"> poderia representar o</span> <span class="hps">conjunto de</span> <span class="hps">todos os funcionários.</span></span></li> + <li><span id="result_box" lang="pt"><span class="alt-edited hps">Uma</span><em> </em><span class="alt-edited hps"><em>instância</em>,</span> <span class="alt-edited hps">por outro</span> <span class="hps">lado, é a</span> <span class="hps">instanciação de uma classe</span><span>, ou seja,</span> <span class="hps">um dos seus membros</span><span>.</span> <span class="hps">Por exemplo</span><span>, <code>Victoria</code></span> <span class="hps">poderia ser uma</span> <span class="hps">instância da classe</span> </span><code>Employee</code><span id="result_box" lang="pt"><span>, o que representa</span> <span class="hps">um indivíduo em particular</span> <span class="hps">como um empregado.</span> <span class="hps">Uma instância</span> <span class="hps">tem exatamente</span> <span class="hps">as propriedades de</span> <span class="hps">sua classe pai</span> <span class="atn hps">(</span><span>nem mais, nem</span> <span class="hps">menos).</span></span></li> +</ul> + +<p><span id="result_box" lang="pt"><span class="alt-edited hps">Uma</span> <span class="hps">linguagem baseada em</span> <span class="hps">protótipo</span><span>, como</span> <span class="hps">JavaScript,</span> <span class="hps">não faz essa</span> <span class="hps">distinção</span><span>:</span> <span class="hps">ele simplesmente tem</span> <span class="hps">objetos.</span> <span class="hps">Uma</span> <span class="hps">linguagem baseada em</span> <span class="hps">protótipo</span> <span class="hps">tem a idéia </span><span class="alt-edited hps">de um <em>objeto</em></span><em> <span class="alt-edited hps">prototípico</span></em></span><span lang="pt"><span>, um objeto</span> <span class="hps">usado como um modelo</span> <span class="alt-edited hps">do qual</span> <span class="alt-edited hps">obtém as propriedades</span> <span class="hps">iniciais para</span> <span class="hps">um novo objeto.</span> <span class="hps">Qualquer objeto</span> <span class="hps">pode especificar</span> <span class="hps">suas próprias propriedades</span><span class="alt-edited">, quando você</span> <span class="alt-edited hps">o cria</span> <span class="hps">ou</span> <span class="hps">em tempo de execução</span><span>.</span> <span class="hps">Além disso, qualquer</span> <span class="hps">objeto</span> <span class="hps">pode ser associado</span> <span class="hps">como</span> <span class="alt-edited hps">um protótipo de </span><span class="alt-edited hps">outro objeto,</span> <span class="alt-edited hps">permitindo ao</span> <span class="hps">segundo objeto</span> <span class="alt-edited hps">compartilhar</span> <span class="hps">as propriedades</span> <span class="hps">do primeiro</span> <span class="hps">objeto</span><span>.</span></span></p> + +<h3 id="Definindo_uma_classe">Definindo uma classe</h3> + +<p>Em linguagens baseadas em classe, você define uma classe em uma <em>definição de classe</em> separada. Nessa definição, você pode especificar métodos especiais, chamados de <em>construtores</em>, para criar instâncias da classe. Um método <em>construtor</em> pode especificar valores iniciais para as propriedades da instância e executar outros processamentos apropriados no momento da criação. Você pode usar o operador <code>new</code>, em associação com o método construtor para criar instâncias de classe.</p> + +<p>O JavaScript segue um modelo semelhante, mas não têm uma definição da classe separada do construtor. Em vez disso, você define uma função de construtor para criar objetos com um conjunto inicial particular de propriedades e valores. Qualquer função JavaScript pode ser usado como um construtor. Você pode usar o operador <code>new</code> com uma função de construtor para criar um novo objeto.</p> + +<h3 id="Subclasses_e_herança">Subclasses e herança</h3> + +<p>Em uma linguagem baseada em classe, você cria a hierárquia de classes através de sua definição. Em uma definição de classes, você pode especificar que a nova classe é uma <em>subclasse</em> de outra já existente. A subclasse herda todas as propriedades da superclasse e pode adicionar novas propriedades ou modificar propriedades herdadas. Por exemplo, assuma que a classe <code>Employee</code> tem somente duas propriedades <code>name</code> e <code>dept</code> , e <code>Manager</code> é uma subclasse of <code>Employee </code>que adiciona a propriedade <code>reports</code>. Neste caso, uma instância da classe <code>Manager</code> terá todas as três propiedades: <code>name</code>, <code>dept</code>, and <code>reports</code>.</p> + +<p>Em JavaScript, a herança é implementada associando um objeto prototípico a qualquer função de construtor. Então, você pode criar exatamente o mesmo exemplo: <code>Employee</code> — <code>Manager</code>, mas utilizando uma terminologia ligeramente diferente. Primeiro, define-se a função de construtor de <code>Employee</code>, especificando as propriedades <code>name</code> e <code>dept</code>. Depois, define-se a função de construtor de <code>Manager</code>, especificando a propriedade <code>reports</code>. Finalmente, associa-se um objeto new <code>Employee</code> como <code>prototype</code> para a função de construtor <code>Manager</code>. Então, quando vocẽ criar um objeto new <code>Manager</code>, ele herdará as propriedades <code>name</code> e <code>dept</code> do objeto <code>Employee</code>.</p> + +<h3 id="Adicionando_e_removendo_propriedades">Adicionando e removendo propriedades</h3> + +<p>Em uma linguagem baseada em classe, você normalmente cria uma classe em tempo de compilação e então vincula as instâncias da classe em tempo de compilação, ou tempo de execução. Você não pode alterar o número ou o tipo de propriedade de uma classe após definí-la. Em javaScript, no entanto, você pode adicionar ou remover propriedades de qualquer objeto. Se você adiciona uma propriedade a um objeto que é usado como o protótipo para um conjunto de objetos, os objetos no qual ele é protótipo herdarão as novas propriedades.</p> + +<h3 id="Sumário_das_diferenças">Sumário das diferenças</h3> + +<p>A tabela a seguir apresenta um breve resumo de algumas dessas diferenças. O restante deste capítulo descreve os detalhes do uso de construtores e protótipos JavaScript para criar uma hierarquia de objetos e compara isso à maneira como você faria em Java.</p> + +<table class="fullwidth-table"> + <caption>Comparação de objetos do sistema baseados em classes (Java) e baseado em protótipo (JavaScript)</caption> + <thead> + <tr> + <th scope="col"><strong>Baseados em classes (Java)</strong></th> + <th scope="col"><strong>Baseados em protótipos (JavaScript)</strong></th> + </tr> + </thead> + <tbody> + <tr> + <td>Classes e instancias são entidades distintas.</td> + <td>Todos os objetos são instancias.</td> + </tr> + <tr> + <td>Define uma classe com uma definição de classe; cria um objeto - como instância da classe - com o método constructor.</td> + <td>Define e cria um conjunto de objetos com funções construtoras.</td> + </tr> + <tr> + <td>Cria um único objeto com o operador <code>new</code>.</td> + <td>Faz o mesmo.</td> + </tr> + <tr> + <td>Constroi uma hierarquia de objetos usando definição de classe para definir subclasses de classes existentes.</td> + <td>Constrói uma hierarquia de objetos, atribuindo um objeto como o protótipo associado com uma função de construtor.</td> + </tr> + <tr> + <td>Herda propriedade seguindo a cadeia de classe.</td> + <td>Herda propriedade seguindo a cadeia de protótipo.</td> + </tr> + <tr> + <td>Definição de classe especifica todas as propriedades de todas as instâncias de uma classe. Não é possível adicionar propriedades dinamicamente em tempo de execução.</td> + <td>Função construtor ou protótipo especifica um conjunto <em>inicial </em>de propriedades. Pode adicionar ou remover propriedades de forma dinâmica para objetos individuais ou para todo o conjunto de objetos.</td> + </tr> + </tbody> +</table> + +<h2 id="O_exemplo_employee">O exemplo employee</h2> + +<p>O restante deste capítulo usa a hierarquia employee como mostrado na figura abaixo. </p> + +<div class="twocolumns"> +<p>Uma simples hierarquia de objetos:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/3060/figure8.1.png"></p> + +<ul> + <li><code>Employee</code> tem a propriedade <code>name</code> (cujo valor padrão é uma string vazia) e <code>dept</code> (cujo valor padrão e o "general").</li> + <li><code>Manager</code> é baseado no <code>Employee</code>. É adicionada a propriedade <code>reports</code> (cujo valor padrão é um array vazio, planejado para ter um array do objeto <code>Employee como valor</code>).</li> + <li><code>WorkerBee</code> também é baseado no <code>Employee</code>. É adicionada a propriedade <code>projects</code> (cujo valor padrão é um array vazio, pretende-se ter um array de strings como valor).</li> + <li><code>SalesPerson</code> é baseado no <code>WorkerBee</code>. É adicionada a propriedade <code>quota</code> (cujo valor padrão é 100). E também controla a propriedade <code>dept</code> com o valor "sales", indicando que todos os salespersons são o mesmo departamento.</li> + <li><code>Engineer</code> é baseado no <code>WorkerBee</code>. É adicionada a propriedade <code>machine</code> (cujo valor padrão é uma string vazia) e também controla a propriedade <code>dept</code> com o valor "engineering".</li> +</ul> +</div> + +<h2 id="Criando_a_hierarquia">Criando a hierarquia</h2> + +<p>Há muitas formas de definir funções construtoras apropriadas para implementar a hierarquia <code>Employee</code>. Como escolher defini-las depende amplamente do que você quer ser capaz de fazer em sua aplicação.</p> + +<p>Esta seção mostra definições simples de como trabalhar com heranças. Nestas definições, você não pode especificar nenhum valor de propriedade quando criar um objeto. O recém-criado objeto terá os valores padrão, que você poderá alterar mais tarde.</p> + +<p>Na aplicação real, você poderia definir construtores que permitem que você forneça valores de propriedade no momento da criação do objeto (veja <a href="#Construtores_flexíveis">Construtores flexíveis</a> para saber mais). Por enquanto, estas simples definições demonstram como a herança ocorre.</p> + +<p>As seguintes definições Java e JavaScript <code>Employee</code> são similares. A única diferença é que você precisa especificar o tipo de cada propriedade em Java, mas não em JavaScript (devido ao Java ser uma <a href="http://en.wikipedia.org/wiki/Strong_and_weak_typing">linguagem fortemente tipada</a> enquanto o JavaScript é linguagem fracamente tipada).</p> + +<div class="twocolumns"> +<h4 id="JavaScript">JavaScript</h4> + +<pre class="brush: js notranslate">function Employee() { + this.name = ""; + this.dept = "general"; +} +</pre> + +<h4 id="Java">Java</h4> + +<pre class="brush: java notranslate">public class Employee { + public String name = ""; + public String dept = "general"; +} +</pre> +</div> + +<p>As definições <code>Manager</code> e <code>WorkerBee</code> mostram a diferença na forma de especificar o próximo objeto mais alto na cadeia de herança. Em JavaScript, você adiciona uma instância prototípica como o valor da propriedade <code>prototype</code> da função construtora. Você pode fazer isso a qualquer momento depois de definir o construtor. Em Java, você especifica a superclasse dentro da classe definida. Você não pode alterar a superclasse fora da classe definida.</p> + +<div class="twocolumns"> +<h4 id="JavaScript_2">JavaScript</h4> + +<pre class="brush: js notranslate">function Manager() { + Employee.call(this); + this.reports = []; +} +Manager.prototype = Object.create(Employee.prototype); + +function WorkerBee() { + Employee.call(this); + this.projects = []; +} +WorkerBee.prototype = Object.create(Employee.prototype); +</pre> + +<h4 id="Java_2">Java</h4> + +<pre class="brush: java notranslate">public class Manager extends Employee { + public Employee[] reports = new Employee[0]; +} + + + +public class WorkerBee extends Employee { + public String[] projects = new String[0]; +} + + +</pre> +</div> + +<p>As definições <code>Engineer</code> e <code>SalesPerson</code> criam objetos que descendem de <code>WorkerBee</code> e consequentemente de <code>Employee</code>. Objetos destes tipos tem propriedades de todos os objetos acima de sua cadeia. Em adição, estas definições substituem o valor herdado da propriedade <code>dept</code> com novos valores específicos para esses objetos.</p> + +<div class="twocolumns"> +<h4 id="JavaScript_3">JavaScript</h4> + +<pre class="brush: js notranslate">function SalesPerson() { + WorkerBee.call(this); + this.dept = "sales"; + this.quota = 100; +} +SalesPerson.prototype = Object.create(WorkerBee.prototype); + +function Engineer() { + WorkerBee.call(this); + this.dept = "engineering"; + this.machine = ""; +} +Engineer.prototype = Object.create(WorkerBee.prototype); +</pre> + +<h4 id="Java_3">Java</h4> + +<pre class="brush: java notranslate">public class SalesPerson extends WorkerBee { + public double quota; + public dept = "sales"; + public quota = 100.0; +} + + +public class Engineer extends WorkerBee { + public String machine; + public dept = "engineering"; + public machine = ""; +} + +</pre> +</div> + +<p>Usando estas definições, você pode criar instâncias desses objetos que obterão valores padrão para suas propriedades. A próxima imagem mostra o uso destas definições JavaScript para criar novos objetos e mostrar os valores das propriedades dos novos objetos. </p> + +<div class="note"> +<p><strong>Note:</strong> O termo <em>instancia </em>tem significado específicamente técnico em linguagens baseadas em classe. Nessas linguagens, uma instância é uma instanciação individual de uma classe e é fundamentalmente diferente de uma classe. Em JavaScript, "instância" não tem esse significado técnico porque JavaScript não tem essa diferença entre classes e instâncias. No entanto, falando sobre JavaScript, "instância" pode ser usada informalmente para significar um objeto criado usando uma função construtora particular. Então, neste exemplo, você pode informalmente dizer que <code><code>jane</code></code> é uma instância de <code><code>Engineer</code></code>. Similarmente, embora os termos <em><em>parent</em>, <em>child</em>, <em>ancestor</em></em>, e <em><em>descendant</em></em> não tenham significados formais em JavaScript; você pode usá-los informalmente para referir a objetos altos ou baixos na cadeia de protótipos.</p> +</div> + +<h3 id="Criando_objetos_com_definições_simples">Criando objetos com definições simples</h3> + +<div class="twocolumns"> +<h4 id="Hierarquia_do_Objeto">Hierarquia do Objeto</h4> + +<p>A hierarquia abaixo foi criada utilizando o código ao lado.</p> + +<p><img src="https://mdn.mozillademos.org/files/10412/=figure8.3.png"></p> + +<h4 id="Objetos_individuais_Jim_Sally_Mark_Fred_Jane_etc._Instancias_criadas_a_partir_do_construtor.">Objetos individuais = Jim, Sally, Mark, Fred, Jane, etc. "Instancias" criadas a partir do construtor.</h4> + +<pre class="brush: js notranslate">var jim = new Employee; +// jim.name is '' +// jim.dept is 'general' + +var sally = new Manager; +// sally.name is '' +// sally.dept is 'general' +// sally.reports is [] + +var mark = new WorkerBee; +// mark.name is '' +// mark.dept is 'general' +// mark.projects is [] + +var fred = new SalesPerson; +// fred.name is '' +// fred.dept is 'sales' +// fred.projects is [] +// fred.quota is 100 + +var jane = new Engineer; +// jane.name is '' +// jane.dept is 'engineering' +// jane.projects is [] +// jane.machine is '' +</pre> +</div> + +<h2 id="Propriedades_do_Objeto">Propriedades do Objeto</h2> + +<p>Esta seção discute como objetos herdam propriedades de outros objetos na cadeia de protótipos e o que acontece quando você adiciona uma propriedade em tempo de execução.</p> + +<h3 id="Herdando_Propriedades">Herdando Propriedades</h3> + +<p>Suponha que você criou o objeto <code>mark</code> como um <code>WorkerBee</code> com a seguinte declaração:</p> + +<pre class="brush: js notranslate">var mark = new WorkerBee; +</pre> + +<p>Quando o JavaScript vê o operador <code>new</code>, ele cria um novo objeto genérico e implicitamente define o valor da propriedade interna [[Protótipo]] para o valor de <code>WorkerBee.prototype</code> passando este novo objeto como o valor da palavra-chave <code>this</code> para a função construtora de <code>WorkerBee</code>. A propriedade interna [[__proto__]] determina a cadeia de protótipos usada para retornar os valores das propriedades. Uma vez que essas propriedades são definidas, o JavaScript retorna o novo objeto e a declaração de atribuição define a variável <code>mark</code> para este objeto.</p> + +<p>Este processo não põe explicitamente valores no objeto <code>mark</code> (valores <em>locais</em>) para as propriedades que <code>mark</code> herdou da cadeia de protótipo. Quando você solicita o valor de uma propriedade, o JavaScript primeiro verifica se o valor existe nesse objeto. Caso exista, esse valor é retornado. Se o valor não existe localmente, JavaScript verifica a cadeia de protótipos (usando a propriedade interna __proto__). Se um objeto na cadeia de protótipos possui um valor para a propriedade, este valor é retornado. Se nenhuma propriedade é encontrada, o Javascript avisa que o objeto não possui a propriedade. Deste modo, o objeto <code>mark</code> possui as seguintes propriedades e valores: </p> + +<pre class="brush: js notranslate">mark.name = ""; +mark.dept = "general"; +mark.projects = []; +</pre> + +<p>The <code>mark</code> object inherits values for the <code>name</code> and <code>dept</code> properties from the prototypical object in <code>mark.__proto__</code>. It is assigned a local value for the <code>projects</code> property by the <code>WorkerBee</code> constructor. This gives you inheritance of properties and their values in JavaScript. Some subtleties of this process are discussed in <a href="#Property_inheritance_revisited">Property inheritance revisited</a>.</p> + +<p>Because these constructors do not let you supply instance-specific values, this information is generic. The property values are the default ones shared by all new objects created from <code>WorkerBee</code>. You can, of course, change the values of any of these properties. So, you could give specific information for <code>mark</code> as follows:</p> + +<pre class="brush: js notranslate">mark.name = "Doe, Mark"; +mark.dept = "admin"; +mark.projects = ["navigator"];</pre> + +<h3 id="Adding_properties">Adding properties</h3> + +<p>In JavaScript, you can add properties to any object at run time. You are not constrained to use only the properties provided by the constructor function. To add a property that is specific to a single object, you assign a value to the object, as follows:</p> + +<pre class="brush: js notranslate">mark.bonus = 3000; +</pre> + +<p>Now, the <code>mark</code> object has a <code>bonus</code> property, but no other <code>WorkerBee</code> has this property.</p> + +<p>If you add a new property to an object that is being used as the prototype for a constructor function, you add that property to all objects that inherit properties from the prototype. For example, you can add a <code>specialty</code> property to all employees with the following statement:</p> + +<pre class="brush: js notranslate">Employee.prototype.specialty = "none"; +</pre> + +<p>As soon as JavaScript executes this statement, the <code>mark</code> object also has the <code>specialty</code> property with the value of <code>"none"</code>. The following figure shows the effect of adding this property to the <code>Employee</code> prototype and then overriding it for the <code>Engineer</code> prototype.</p> + +<p><img alt="" class="internal" src="/@api/deki/files/4422/=figure8.4.png" style="height: 519px; width: 833px;"><br> + <small><strong>Adding properties</strong></small></p> + +<h2 id="More_flexible_constructors">More flexible constructors</h2> + +<p>The constructor functions shown so far do not let you specify property values when you create an instance. As with Java, you can provide arguments to constructors to initialize property values for instances. The following figure shows one way to do this.</p> + +<p><img alt="" class="internal" id="figure8.5" src="/@api/deki/files/4423/=figure8.5.png" style="height: 481px; width: 1012px;"><br> + <small><strong>Specifying properties in a constructor, take 1</strong></small></p> + +<p>The following table shows the Java and JavaScript definitions for these objects.</p> + +<div class="twocolumns"> +<h4 id="JavaScript_4">JavaScript</h4> + +<h4 id="Java_4">Java</h4> +</div> + +<div class="twocolumns"> +<pre class="brush: js notranslate">function Employee (name, dept) { + this.name = name || ""; + this.dept = dept || "general"; +} +</pre> + +<pre class="brush: java notranslate">public class Employee { + public String name; + public String dept; + public Employee () { + this("", "general"); + } + public Employee (String name) { + this(name, "general"); + } + public Employee (String name, String dept) { + this.name = name; + this.dept = dept; + } +} +</pre> +</div> + +<div class="twocolumns"> +<pre class="brush: js notranslate">function WorkerBee (projs) { + + this.projects = projs || []; +} +WorkerBee.prototype = new Employee; +</pre> + +<pre class="brush: java notranslate">public class WorkerBee extends Employee { + public String[] projects; + public WorkerBee () { + this(new String[0]); + } + public WorkerBee (String[] projs) { + projects = projs; + } +} +</pre> +</div> + +<div class="twocolumns"> +<pre class="brush: js notranslate"> +function Engineer (mach) { + this.dept = "engineering"; + this.machine = mach || ""; +} +Engineer.prototype = new WorkerBee; +</pre> + +<pre class="brush: java notranslate">public class Engineer extends WorkerBee { + public String machine; + public Engineer () { + dept = "engineering"; + machine = ""; + } + public Engineer (String mach) { + dept = "engineering"; + machine = mach; + } +} +</pre> +</div> + +<p>These JavaScript definitions use a special idiom for setting default values:</p> + +<pre class="brush: js notranslate">this.name = name || ""; +</pre> + +<p>The JavaScript logical OR operator (<code>||</code>) evaluates its first argument. If that argument converts to true, the operator returns it. Otherwise, the operator returns the value of the second argument. Therefore, this line of code tests to see if <code>name</code> has a useful value for the <code>name</code> property. If it does, it sets <code>this.name</code> to that value. Otherwise, it sets <code>this.name</code> to the empty string. This chapter uses this idiom for brevity; however, it can be puzzling at first glance.</p> + +<div class="note"> +<p><strong>Note:</strong> This may not work as expected if the constructor function is called with arguments which convert to <code><code>false</code></code> (like <code>0</code> (zero) and empty string (<code><code>""</code></code>). In this case the default value will be chosen.</p> +</div> + +<p>With these definitions, when you create an instance of an object, you can specify values for the locally defined properties. You can use the following statement to create a new <code>Engineer</code>:</p> + +<pre class="brush: js notranslate">var jane = new Engineer("belau"); +</pre> + +<p><code>Jane</code>'s properties are now:</p> + +<pre class="brush: js notranslate">jane.name == ""; +jane.dept == "engineering"; +jane.projects == []; +jane.machine == "belau" +</pre> + +<p>Notice that with these definitions, you cannot specify an initial value for an inherited property such as <code>name</code>. If you want to specify an initial value for inherited properties in JavaScript, you need to add more code to the constructor function.</p> + +<p>So far, the constructor function has created a generic object and then specified local properties and values for the new object. You can have the constructor add more properties by directly calling the constructor function for an object higher in the prototype chain. The following figure shows these new definitions.</p> + +<p><img alt="" class="internal" src="/@api/deki/files/4430/=figure8.6.png" style="height: 534px; width: 1063px;"><br> + <small><strong>Specifying properties in a constructor, take 2</strong></small></p> + +<p>Let's look at one of these definitions in detail. Here's the new definition for the <code>Engineer</code> constructor:</p> + +<pre class="brush: js notranslate">function Engineer (name, projs, mach) { + this.base = WorkerBee; + this.base(name, "engineering", projs); + this.machine = mach || ""; +} +</pre> + +<p>Suppose you create a new <code>Engineer</code> object as follows:</p> + +<pre class="brush: js notranslate">var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau"); +</pre> + +<p>JavaScript follows these steps:</p> + +<ol> + <li>The <code>new</code> operator creates a generic object and sets its <code>__proto__</code> property to <code>Engineer.prototype</code>.</li> + <li>The <code>new</code> operator passes the new object to the <code>Engineer</code> constructor as the value of the <code>this</code> keyword.</li> + <li>The constructor creates a new property called <code>base</code> for that object and assigns the value of the <code>WorkerBee</code> constructor to the <code>base</code> property. This makes the <code>WorkerBee</code> constructor a method of the <code>Engineer</code> object.The name of the<code> base</code> property is not special. You can use any legal property name; <code>base</code> is simply evocative of its purpose.</li> + <li> + <p>The constructor calls the <code>base</code> method, passing as its arguments two of the arguments passed to the constructor (<code>"Doe, Jane"</code> and <code>["navigator", "javascript"]</code>) and also the string <code>"engineering"</code>. Explicitly using <code>"engineering"</code> in the constructor indicates that all <code>Engineer</code> objects have the same value for the inherited <code>dept</code> property, and this value overrides the value inherited from <code>Employee</code>.</p> + </li> + <li>Because <code>base</code> is a method of <code>Engineer</code>, within the call to <code>base</code>, JavaScript binds the <code>this</code> keyword to the object created in Step 1. Thus, the <code>WorkerBee</code> function in turn passes the <code>"Doe, Jane"</code> and <code>"engineering"</code> arguments to the <code>Employee</code> constructor function. Upon return from the <code>Employee</code> constructor function, the <code>WorkerBee</code> function uses the remaining argument to set the <code>projects</code> property.</li> + <li>Upon return from the <code>base</code> method, the <code>Engineer</code> constructor initializes the object's <code>machine</code> property to <code>"belau"</code>.</li> + <li>Upon return from the constructor, JavaScript assigns the new object to the <code>jane</code> variable.</li> +</ol> + +<p>You might think that, having called the <code>WorkerBee</code> constructor from inside the <code>Engineer</code> constructor, you have set up inheritance appropriately for <code>Engineer</code> objects. This is not the case. Calling the <code>WorkerBee</code> constructor ensures that an <code>Engineer</code> object starts out with the properties specified in all constructor functions that are called. However, if you later add properties to the <code>Employee</code> or <code>WorkerBee</code> prototypes, those properties are not inherited by the <code>Engineer</code> object. For example, assume you have the following statements:</p> + +<pre class="brush: js notranslate">function Engineer (name, projs, mach) { + this.base = WorkerBee; + this.base(name, "engineering", projs); + this.machine = mach || ""; +} +var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau"); +Employee.prototype.specialty = "none"; +</pre> + +<p>The <code>jane</code> object does not inherit the <code>specialty</code> property. You still need to explicitly set up the prototype to ensure dynamic inheritance. Assume instead you have these statements:</p> + +<pre class="brush: js notranslate">function Engineer (name, projs, mach) { + this.base = WorkerBee; + this.base(name, "engineering", projs); + this.machine = mach || ""; +} +Engineer.prototype = new WorkerBee; +var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau"); +Employee.prototype.specialty = "none"; +</pre> + +<p>Now the value of the <code>jane</code> object's <code>specialty</code> property is "none".</p> + +<p>Another way of inheriting is by using the <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call" title="en-US/docs/JavaScript/Reference/Global Objects/Function/call">call()</a></code> / <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply" title="en-US/docs/JavaScript/Reference/Global Objects/Function/apply"><code>apply()</code></a> methods. Below are equivalent:</p> + +<div class="twocolumns"> +<pre class="brush: js notranslate">function Engineer (name, projs, mach) { + this.base = WorkerBee; + this.base(name, "engineering", projs); + this.machine = mach || ""; +} +</pre> + +<pre class="brush: js notranslate">function Engineer (name, projs, mach) { + WorkerBee.call(this, name, "engineering", projs); + this.machine = mach || ""; +} +</pre> +</div> + +<p>Using the javascript <code>call()</code> method makes a cleaner implementation because the <code>base</code> is not needed anymore.</p> + +<h2 id="Property_inheritance_revisited">Property inheritance revisited</h2> + +<p>The preceding sections described how JavaScript constructors and prototypes provide hierarchies and inheritance. This section discusses some subtleties that were not necessarily apparent in the earlier discussions.</p> + +<h3 id="Local_versus_inherited_values">Local versus inherited values</h3> + +<p>When you access an object property, JavaScript performs these steps, as described earlier in this chapter:</p> + +<ol> + <li>Check to see if the value exists locally. If it does, return that value.</li> + <li>If there is not a local value, check the prototype chain (using the <code>__proto__</code> property).</li> + <li>If an object in the prototype chain has a value for the specified property, return that value.</li> + <li>If no such property is found, the object does not have the property.</li> +</ol> + +<p>The outcome of these steps depends on how you define things along the way. The original example had these definitions:</p> + +<pre class="brush: js notranslate">function Employee () { + this.name = ""; + this.dept = "general"; +} + +function WorkerBee () { + this.projects = []; +} +WorkerBee.prototype = new Employee; +</pre> + +<p>With these definitions, suppose you create <code>amy</code> as an instance of <code>WorkerBee</code> with the following statement:</p> + +<pre class="brush: js notranslate">var amy = new WorkerBee; +</pre> + +<p>The <code>amy</code> object has one local property, <code>projects</code>. The values for the <code>name</code> and <code>dept</code> properties are not local to <code>amy</code> and so are gotten from the <code>amy</code> object's <code>__proto__</code> property. Thus, <code>amy</code> has these property values:</p> + +<pre class="brush: js notranslate">amy.name == ""; +amy.dept == "general"; +amy.projects == []; +</pre> + +<p>Now suppose you change the value of the <code>name</code> property in the prototype associated with <code>Employee</code>:</p> + +<pre class="brush: js notranslate">Employee.prototype.name = "Unknown" +</pre> + +<p>At first glance, you might expect that new value to propagate down to all the instances of <code>Employee</code>. However, it does not.</p> + +<p>When you create <em>any</em> instance of the <code>Employee</code> object, that instance gets a local value for the <code>name</code> property (the empty string). This means that when you set the <code>WorkerBee</code> prototype by creating a new <code>Employee</code> object, <code>WorkerBee.prototype</code> has a local value for the <code>name</code> property. Therefore, when JavaScript looks up the <code>name</code> property of the <code>amy</code> object (an instance of <code>WorkerBee</code>), JavaScript finds the local value for that property in <code>WorkerBee.prototype</code>. It therefore does not look farther up the chain to <code>Employee.prototype</code>.</p> + +<p>If you want to change the value of an object property at run time and have the new value be inherited by all descendants of the object, you cannot define the property in the object's constructor function. Instead, you add it to the constructor's associated prototype. For example, assume you change the preceding code to the following:</p> + +<pre class="brush: js notranslate">function Employee () { + this.dept = "general"; +} +Employee.prototype.name = ""; + +function WorkerBee () { + this.projects = []; +} +WorkerBee.prototype = new Employee; + +var amy = new WorkerBee; + +Employee.prototype.name = "Unknown"; +</pre> + +<p>In this case, the <code>name</code> property of <code>amy</code> becomes "Unknown".</p> + +<p>As these examples show, if you want to have default values for object properties and you want to be able to change the default values at run time, you should set the properties in the constructor's prototype, not in the constructor function itself.</p> + +<h3 id="Determining_instance_relationships">Determining instance relationships</h3> + +<p>Property lookup in JavaScript looks within an object's own properties and, if the property name is not found, it looks within the special object property <code>__proto__</code>. This continues recursively; the process is called "lookup in the prototype chain".</p> + +<p>The special property <code>__proto__</code> is set when an object is constructed; it is set to the value of the constructor's <code>prototype</code> property. So the expression <code>new Foo()</code> creates an object with <code>__proto__ == <code class="moz-txt-verticalline">Foo.prototype</code></code>. Consequently, changes to the properties of <code class="moz-txt-verticalline">Foo.prototype</code> alters the property lookup for all objects that were created by <code>new Foo()</code>.</p> + +<p>Every object has a <code>__proto__</code> object property (except <code>Object</code>); every function has a <code>prototype</code> object property. So objects can be related by 'prototype inheritance' to other objects. You can test for inheritance by comparing an object's <code>__proto__</code> to a function's <code>prototype</code> object. JavaScript provides a shortcut: the <code>instanceof</code> operator tests an object against a function and returns true if the object inherits from the function prototype. For example,</p> + +<pre class="brush: js notranslate">var f = new Foo(); +var isTrue = (f instanceof Foo);</pre> + +<p>For a more detailed example, suppose you have the same set of definitions shown in <a href="#Inheriting_properties">Inheriting properties</a>. Create an <code>Engineer</code> object as follows:</p> + +<pre class="brush: js notranslate">var chris = new Engineer("Pigman, Chris", ["jsd"], "fiji"); +</pre> + +<p>With this object, the following statements are all true:</p> + +<pre class="brush: js notranslate">chris.__proto__ == Engineer.prototype; +chris.__proto__.__proto__ == WorkerBee.prototype; +chris.__proto__.__proto__.__proto__ == Employee.prototype; +chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype; +chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null; +</pre> + +<p>Given this, you could write an <code>instanceOf</code> function as follows:</p> + +<pre class="brush: js notranslate">function instanceOf(object, constructor) { + object = object.__proto__; + while (object != null) { + if (object == constructor.prototype) + return true; + if (typeof object == 'xml') { + return constructor.prototype == XML.prototype; + } + object = object.__proto__; + } + return false; +} +</pre> + +<div class="note"><strong>Note:</strong> The implementation above checks the type of the object against "xml" in order to work around a quirk of how XML objects are represented in recent versions of JavaScript. See {{ bug(634150) }} if you want the nitty-gritty details.</div> + +<p class="note">Using the <code>instanceOf</code> function defined above, these expressions are true:</p> + +<pre class="brush: js notranslate">instanceOf (chris, Engineer) +instanceOf (chris, WorkerBee) +instanceOf (chris, Employee) +instanceOf (chris, Object) +</pre> + +<p>But the following expression is false:</p> + +<pre class="brush: js notranslate">instanceOf (chris, SalesPerson) +</pre> + +<h3 id="Global_information_in_constructors">Global information in constructors</h3> + +<p>When you create constructors, you need to be careful if you set global information in the constructor. For example, assume that you want a unique ID to be automatically assigned to each new employee. You could use the following definition for <code>Employee</code>:</p> + +<pre class="brush: js notranslate">var idCounter = 1; + +function Employee (name, dept) { + this.name = name || ""; + this.dept = dept || "general"; + this.id = idCounter++; +} +</pre> + +<p>With this definition, when you create a new <code>Employee</code>, the constructor assigns it the next ID in sequence and then increments the global ID counter. So, if your next statement is the following, <code>victoria.id</code> is 1 and <code>harry.id</code> is 2:</p> + +<pre class="brush: js notranslate">var victoria = new Employee("Pigbert, Victoria", "pubs") +var harry = new Employee("Tschopik, Harry", "sales") +</pre> + +<p>At first glance that seems fine. However, <code>idCounter</code> gets incremented every time an <code>Employee</code> object is created, for whatever purpose. If you create the entire <code>Employee</code> hierarchy shown in this chapter, the <code>Employee</code> constructor is called every time you set up a prototype. Suppose you have the following code:</p> + +<pre class="brush: js notranslate">var idCounter = 1; + +function Employee (name, dept) { + this.name = name || ""; + this.dept = dept || "general"; + this.id = idCounter++; +} + +function Manager (name, dept, reports) {...} +Manager.prototype = new Employee; + +function WorkerBee (name, dept, projs) {...} +WorkerBee.prototype = new Employee; + +function Engineer (name, projs, mach) {...} +Engineer.prototype = new WorkerBee; + +function SalesPerson (name, projs, quota) {...} +SalesPerson.prototype = new WorkerBee; + +var mac = new Engineer("Wood, Mac"); +</pre> + +<p>Further assume that the definitions omitted here have the <code>base</code> property and call the constructor above them in the prototype chain. In this case, by the time the <code>mac</code> object is created, <code>mac.id</code> is 5.</p> + +<p>Depending on the application, it may or may not matter that the counter has been incremented these extra times. If you care about the exact value of this counter, one possible solution involves instead using the following constructor:</p> + +<pre class="brush: js notranslate">function Employee (name, dept) { + this.name = name || ""; + this.dept = dept || "general"; + if (name) + this.id = idCounter++; +} +</pre> + +<p>When you create an instance of <code>Employee</code> to use as a prototype, you do not supply arguments to the constructor. Using this definition of the constructor, when you do not supply arguments, the constructor does not assign a value to the id and does not update the counter. Therefore, for an <code>Employee</code> to get an assigned id, you must specify a name for the employee. In this example, <code>mac.id</code> would be 1.</p> + +<h3 id="No_multiple_inheritance">No multiple inheritance</h3> + +<p>Some object-oriented languages allow multiple inheritance. That is, an object can inherit the properties and values from unrelated parent objects. JavaScript does not support multiple inheritance.</p> + +<p>Inheritance of property values occurs at run time by JavaScript searching the prototype chain of an object to find a value. Because an object has a single associated prototype, JavaScript cannot dynamically inherit from more than one prototype chain.</p> + +<p>In JavaScript, you can have a constructor function call more than one other constructor function within it. This gives the illusion of multiple inheritance. For example, consider the following statements:</p> + +<pre class="brush: js notranslate">function Hobbyist (hobby) { + this.hobby = hobby || "scuba"; +} + +function Engineer (name, projs, mach, hobby) { + this.base1 = WorkerBee; + this.base1(name, "engineering", projs); + this.base2 = Hobbyist; + this.base2(hobby); + this.machine = mach || ""; +} +Engineer.prototype = new WorkerBee; + +var dennis = new Engineer("Doe, Dennis", ["collabra"], "hugo") +</pre> + +<p>Further assume that the definition of <code>WorkerBee</code> is as used earlier in this chapter. In this case, the <code>dennis</code> object has these properties:</p> + +<pre class="brush: js notranslate">dennis.name == "Doe, Dennis" +dennis.dept == "engineering" +dennis.projects == ["collabra"] +dennis.machine == "hugo" +dennis.hobby == "scuba" +</pre> + +<p>So <code>dennis</code> does get the <code>hobby</code> property from the <code>Hobbyist</code> constructor. However, assume you then add a property to the <code>Hobbyist</code> constructor's prototype:</p> + +<pre class="brush: js notranslate">Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"] +</pre> + +<p>The <code>dennis</code> object does not inherit this new property.</p> + +<div>{{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}</div> diff --git a/files/pt-br/web/javascript/guide/expressions_and_operators/index.html b/files/pt-br/web/javascript/guide/expressions_and_operators/index.html new file mode 100644 index 0000000000..6b00a18396 --- /dev/null +++ b/files/pt-br/web/javascript/guide/expressions_and_operators/index.html @@ -0,0 +1,944 @@ +--- +title: Expressões e operadores +slug: Web/JavaScript/Guide/Expressions_and_Operators +tags: + - Expressões + - Guia(2) + - Guía + - Iniciante + - JavaScript + - Operadores +translation_of: Web/JavaScript/Guide/Expressions_and_Operators +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Functions", "Web/JavaScript/Guide/Numbers_and_dates")}}</div> + +<p class="summary">Este artigo descreve expressões e operadores de JavaScript, incluindo operadores de atribuição, comparação, aritméticos, bit a bit, lógicos, de strings e especiais.</p> + +<ul> +</ul> + +<h2 id="Operadores">Operadores</h2> + +<p>O JavaScript possui os tipos de operadores a seguir. Esta seção descreve os operadores e contém informações sobre precedência de operadores.</p> + +<ul> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operador_atribuicao">Operadores de atribuição</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operador_comparacao">Operadores de comparação</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operadores_aritmeticos">Operadores aritméticos</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operadores_bit_a_bit">Operadores bit a bit</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operadores_logicos">Operadores lógicos</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operadores_string">Operadores de string</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operador_condicional_ternario">Operador condicional (ternário)</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operador_virgula">Operador vírgula</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operadores_unario">Operadores unário</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operador_virgula">Operadores relacionais</a></li> +</ul> + +<p>O JavaScript possui tanto operadores <em>binários</em> quanto <em>unários</em> e um operador ternário, o operador condicional. Um operador binário exige dois operandos, um antes do operador e outro depois:</p> + +<pre class="notranslate"><em>operando1</em> <em>operador</em> <em>operando2</em> +</pre> + +<p>Por exemplo, <code>3+4</code> ou <code>x*y</code>.</p> + +<p>Um operador unário exige um único operando, seja antes ou depois do operador:</p> + +<pre class="notranslate"><em>operador</em> <em>operando</em> +</pre> + +<p>ou</p> + +<pre class="notranslate"><em>operando</em> <em>operador</em> +</pre> + +<p>Por exemplo, <code>x++</code> ou <code>++x</code>.</p> + +<h3 id="Operadores_de_atribuição"><a id="operador_atribuicao" name="operador_atribuicao">Operadores de atribuição</a></h3> + +<p>Um operador de atribuição atribui um valor ao operando à sua esquerda baseado no valor do operando à direita. O operador de atribuição básico é o igual (=), que atribui o valor do operando à direita ao operando à esquerda. Isto é, x = y atribui o valor de y a x.</p> + +<p>Os outros operadores de atribuição são encurtamentos de operadores padrão, como mostrado na tabela a seguir.</p> + +<table class="standard-table" style="height: 500px; width: 631px;"> + <caption>Operadores de atribuição composto</caption> + <thead> + <tr> + <th scope="col">Nome</th> + <th scope="col" style="width: 30%;">Operador encurtado</th> + <th scope="col">Significado</th> + </tr> + </thead> + <tbody> + <tr> + <td>Atribuição</td> + <td>x = y</td> + <td>x = y</td> + </tr> + <tr> + <td>Atribuição de adição</td> + <td><code>x += y</code></td> + <td><code>x = x + y</code></td> + </tr> + <tr> + <td>Atribuição de subtração</td> + <td><code>x -= y</code></td> + <td><code>x = x - y</code></td> + </tr> + <tr> + <td>Atribuição de multiplicação</td> + <td><code>x *= y</code></td> + <td><code>x = x * y</code></td> + </tr> + <tr> + <td>Atribuição de divisão</td> + <td><code>x /= y</code></td> + <td><code>x = x / y</code></td> + </tr> + <tr> + <td>Atribuição de resto</td> + <td><code>x %= y</code></td> + <td><code>x = x % y</code></td> + </tr> + <tr> + <td>Atribuição exponencial</td> + <td>x **= y</td> + <td>x = x ** y</td> + </tr> + <tr> + <td>Atribuição bit-a-bit por deslocamento á esquerda</td> + <td><code>x <<= y</code></td> + <td><code>x = x << y</code></td> + </tr> + <tr> + <td>Atribuição bit-a-bit por deslocamento á direita</td> + <td><code>x >>= y</code></td> + <td><code>x = x >> y</code></td> + </tr> + <tr> + <td>Atribuiçãode bit-a-bit deslocamento á direita não assinado</td> + <td><code>x >>>= y</code></td> + <td><code>x = x >>> y</code></td> + </tr> + <tr> + <td>Atribuição AND bit-a-bit</td> + <td><code>x &= y</code></td> + <td><code>x = x & y</code></td> + </tr> + <tr> + <td>Atribuição XOR bit-a-bit</td> + <td><code>x ^= y</code></td> + <td><code>x = x ^ y</code></td> + </tr> + <tr> + <td>Atribuição OR bit-a-bit</td> + <td><code>x |= y</code></td> + <td><code>x = x | y</code></td> + </tr> + </tbody> +</table> + +<h3 id="Operadores_de_comparação"><a id="operador_comparacao" name="operador_comparacao">Operadores de comparação</a></h3> + +<p><span class="comment">This seems to me kind of poorly explained, mostly the difference betwen "==" and "==="...</span> Um operador de comparação compara seus operandos e retorna um valor lógico baseado em se a comparação é verdadeira. Os operandos podem ser numéricos, strings, lógicos ou objetos. Strings são comparadas com base em ordenação lexográfica utilizando valores Unicode. Na maioria dos casos, se dois operandos não são do mesmo tipo, o JavaScript tenta convertê-los para um tipo apropriado. Isto geralmente resulta na realização de uma comparação numérica. As únicas exceções a esta regra são os operadores <code>===</code> e o <code>!==</code>, que realizam comparações de igualdade e desigualdade "estritas". Estes operadores não tentam converter os operandos em tipos compatíveis antes de verificar a igualdade. A tabela a seguir descreve os operadores de comparação levando em conta o seguinte código:</p> + +<pre class="brush: js notranslate">var var1 = 3; +var var2 = 4; +</pre> + +<table class="standard-table"> + <caption>Operadores de comparação</caption> + <thead> + <tr> + <th scope="col">Operador</th> + <th scope="col">Descrição</th> + <th scope="col">Exemplos que retornam verdadeiro</th> + </tr> + </thead> + <tbody> + <tr> + <td>Igual (<code>==</code>)</td> + <td>Retorna verdadeiro caso os operandos sejam iguais.</td> + <td><code>3 == var1</code> + <p><code>"3" == var1</code></p> + <code>3 == '3'</code></td> + </tr> + <tr> + <td>Não igual (<code>!=</code>)</td> + <td>Retorna verdadeiro caso os operandos não sejam iguais.</td> + <td><code>var1 != 4<br> + var2 != "3"</code></td> + </tr> + <tr> + <td>Estritamente igual (<code>===</code>)</td> + <td>Retorna verdadeiro caso os operandos sejam iguais e do mesmo tipo. Veja também <a href="/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> e <a href="/pt-BR/docs/Web/JavaScript/Guide/Sameness">igualdade em JS</a>.</td> + <td><code>3 === var1</code></td> + </tr> + <tr> + <td>Estritamente não igual (<code>!==</code>)</td> + <td>Retorna verdadeiro caso os operandos não sejam iguais e/ou não sejam do mesmo tipo.</td> + <td><code>var1 !== "3"<br> + 3 !== '3'</code></td> + </tr> + <tr> + <td>Maior que (<code>></code>)</td> + <td>Retorna verdadeiro caso o operando da esquerda seja maior que o da direita.</td> + <td><code>var2 > var1<br> + "12" > 2</code></td> + </tr> + <tr> + <td>Maior que ou igual (<code>>=</code>)</td> + <td>Retorna verdadeiro caso o operando da esquerda seja maior ou igual ao da direita.</td> + <td><code>var2 >= var1<br> + var1 >= 3</code></td> + </tr> + <tr> + <td>Menor que (<code><</code>)</td> + <td>Retorna verdadeiro caso o operando da esquerda seja menor que o da direita.</td> + <td><code>var1 < var2<br> + "12" < "2"</code></td> + </tr> + <tr> + <td>Menor que ou igual (<code><=</code>)</td> + <td>Retorna verdadeiro caso o operando da esquerda seja menor ou igual ao da direita.</td> + <td><code>var1 <= var2<br> + var2 <= 5</code></td> + </tr> + </tbody> +</table> + +<div class="note"> +<p><strong>Nota:</strong> (<strong>=></strong>) não é um operador, mas a notação para <a href="/pt-BR/docs/Web/JavaScript/Guide/Funções#Arrow_functions">função de seta</a></p> +</div> + +<h3 id="Operadores_aritméticos"><a name="operadores_aritmeticos">Operadores aritméticos</a></h3> + +<p>Operadores aritméticos tomam valores numéricos (sejam literais ou variáveis) como seus operandos e retornam um único valor númerico. Os operadores aritméticos padrão são os de soma (<code>+</code>), subtração (<code>-</code>), multiplicação (<code>*</code>) e divisão (<code>/</code>). Estes operadores trabalham da mesma forma como na maioria das linguagens de programação quando utilizados com números de ponto flutuante (em particular, repare que divisão por zero produz um <a href="/pt-BR/docs/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a>). Por exemplo:</p> + +<pre class="brush: js notranslate">console.log(1 / 2); /* imprime 0.5 */ +console.log(1 / 2 == 1.0 / 2.0); /* isto também é verdadeiro */ +</pre> + +<p>Em complemento às operações aritméticas padrões (+, -, * /), o JavaScript disponibiliza os operadores aritméticos listados na tabela a seguir.</p> + +<table class="fullwidth-table" style="height: 292px; width: 555px;"> + <caption>Operadores aritméticos</caption> + <thead> + <tr> + <th scope="col">Operador</th> + <th scope="col">Descrição</th> + <th scope="col">Exemplo</th> + </tr> + </thead> + <tbody> + <tr> + <td>Módulo (%)</td> + <td>Operador binário. Retorna o inteiro restante da divisão dos dois operandos.</td> + <td>12 % 5 retorna 2.</td> + </tr> + <tr> + <td>Incremento (++)</td> + <td>Operador unário. Adiciona um ao seu operando. Se usado como operador prefixado (<code>++x</code>), retorna o valor de seu operando após a adição. Se usado como operador pósfixado (<code>x++</code>), retorna o valor de seu operando antes da adição.</td> + <td>Se <code>x</code> é 3, então <code>++x</code> define <code>x</code> como 4 e retorna 4, enquanto <code>x++</code> retorna 3 e, somente então, define <code>x</code> como 4.</td> + </tr> + <tr> + <td>Decremento (--)</td> + <td>Operador unário. Subtrai um de seu operando. O valor de retorno é análogo àquele do operador de incremento.</td> + <td>Se <code>x</code> é 3, então <code>--x</code> define <code>x</code> como 2 e retorna 2, enquanto <code>x--</code> retorna 3 e, somente então, define <code>x</code> como 2.</td> + </tr> + <tr> + <td>Negação (-)</td> + <td>Operador unário. Retorna a negação de seu operando.</td> + <td> + <p>Se <code>x</code> é 3, então <code>-x</code> retorna -3.</p> + </td> + </tr> + <tr> + <td>Adição (+)</td> + <td>Operador unário. Tenta converter o operando em um número, sempre que possível.</td> + <td> + <p>+"3" retorna 3.</p> + + <p>+true retorna 1.</p> + </td> + </tr> + <tr> + <td>Operador de exponenciação (**) {{experimental_inline}}</td> + <td>Calcula a base elevada á potência do expoente, que é, base<code><sup>expoente</sup></code></td> + <td> + <p>2 ** 3 retorna 8.</p> + + <p>10 ** -1 retorna 0.1</p> + </td> + </tr> + </tbody> +</table> + +<h3 id="Operadores_bit_a_bit"><a id="operadores_bit_a_bit" name="operadores_bit_a_bit">Operadores bit a bit</a></h3> + +<p>Operadores bit a bit tratam seus operandos como um conjunto de 32 bits (zeros e uns), em vez de tratá-los como números decimais, hexadecimais ou octais. Por exemplo, o número decimal nove possui uma representação binária 1001. Operadores bit a bit realizam suas operações nestas representações, mas retornam valores numéricos padrões do JavaScript.</p> + +<p>A tabela a seguir resume os operadores bit a bit do JavaScript.</p> + +<table class="standard-table"> + <caption>Operadores bit a bit</caption> + <thead> + <tr> + <th scope="col">Operador</th> + <th scope="col">Expressão</th> + <th scope="col">Descrição</th> + </tr> + </thead> + <tbody> + <tr> + <td>AND</td> + <td><code>a & b</code></td> + <td>Retorna um 1 para cada posição em que os bits da posição correspondente de ambos operandos sejam uns.</td> + </tr> + <tr> + <td>OR</td> + <td><code>a | b</code></td> + <td>Retorna um 0 para cada posição em que os bits da posição correspondente de ambos os operandos sejam zeros.</td> + </tr> + <tr> + <td>XOR</td> + <td><code>a ^ b</code></td> + <td> + <p>Retorna um 0 para cada posição em que os bits da posição correspondente são os mesmos.<br> + <br> + [Retorna um 1 para cada posição em que os bits da posição correspondente sejam diferentes.]</p> + </td> + </tr> + <tr> + <td>NOT</td> + <td><code>~ a</code></td> + <td>Inverte os bits do operando.</td> + </tr> + <tr> + <td>Deslocamento à esquerda</td> + <td><code>a << b</code></td> + <td>Desloca <code>a</code> em representação binária <code>b</code> bits à esquerda, preenchendo com zeros à direita.</td> + </tr> + <tr> + <td>Deslocamento à direita com propagação de sinal</td> + <td><code>a >> b</code></td> + <td>Desloca <code>a</code> em representação binária <code>b</code> bits à direita, descartando bits excedentes.</td> + </tr> + <tr> + <td>Deslocamento à direita com preenchimento zero</td> + <td><code>a >>> b</code></td> + <td>Desloca <code>a</code> em representação binária <code>b</code> bits à direita, descartando bits excedentes e preenchendo com zeros à esquerda.</td> + </tr> + </tbody> +</table> + +<h4 id="Bitwise_Logical_Operators" name="Bitwise_Logical_Operators">Operadores bit a bit lógicos</h4> + +<p>Conceitualmente, os operadores bit a bit lógicos funcionam da seguinte maneira:</p> + +<ul> + <li>Os operandos são convertidos em inteiros de 32 bits e expressos como uma série de bits (zeros e uns). Números com representação maior que 32 bits terão seus bits truncados. Por exemplo, o seguinte inteiro tem representação binária maior que 32 bits será convertido em um inteiro de 32 bits.</li> +</ul> + +<pre class="line-numbers language-html notranslate">Antes:<code> </code><code class="language-html">11100110111110100000000000000110000000000001 +Depois: </code><code class="language-html"> 10100000000000000110000000000001</code></pre> + +<ul> + <li>Cada bit do primeiro operando é pareado com o bit correspondente do segundo operando: primeiro bit com primeiro bit, segundo bit com segundo bit e assim por diante.</li> + <li>O operador é aplicado a cada par de bits e o resultado é construído bit a bit.</li> +</ul> + +<p>Por exemplo, a representação binária de nove é 1001 e a representação binária de quinze é 1111. Desta forma, quando operadores bit a bit são aplicados a estes valores, os resultados são como se segue:</p> + +<table class="standard-table"> + <caption>Exemplo de operação bit a bit</caption> + <thead> + <tr> + <th scope="col">Expressão</th> + <th scope="col">Resultado</th> + <th scope="col">Descrição binária</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>15 & 9</code></td> + <td><code>9</code></td> + <td><code>1111 & 1001 = 1001</code></td> + </tr> + <tr> + <td><code>15 | 9</code></td> + <td><code>15</code></td> + <td><code>1111 | 1001 = 1111</code></td> + </tr> + <tr> + <td><code>15 ^ 9</code></td> + <td><code>6</code></td> + <td><code>1111 ^ 1001 = 0110</code></td> + </tr> + <tr> + <td><code>~15</code></td> + <td><code>-16</code></td> + <td><code>~</code><code>00000000...</code><code>00001111 = </code><code>1111</code><code>1111</code><code>...</code><code>11110000</code></td> + </tr> + <tr> + <td><code>~9</code></td> + <td><code>-10</code></td> + <td><code>~</code><code>00000000</code><code>...</code><code>0000</code><code>1001 = </code><code>1111</code><code>1111</code><code>...</code><code>1111</code><code>0110</code></td> + </tr> + </tbody> +</table> + +<div class="note"> +<p><strong>Nota</strong>: No quadro acima perceba que todos os 32 bits são invertidos quando usa-se o operador bit a bit NOT, e que os bits mais significativos (extrema esquerda) são definidos com 1 que representam valores negativos (representação complemento de dois).</p> +</div> + +<h4 id="Bitwise_Shift_Operators" name="Bitwise_Shift_Operators">Operadores de deslocamento bit a bit</h4> + +<p>Os operadores de deslocamento bit a bit possui dois operandos: o primeiro é uma quantidade a ser deslocada e o segundo especifica o número de posições binárias as quais o primeiro operando deverá ser deslocado. A direção da operação de deslocamento é controlada pelo operador utilizado.</p> + +<p>Operadores de deslocamento convertem seus operandos em inteiros de 32 bits e retornam um resultado do tipo do operando à esquerda.</p> + +<p>Os operadores de deslocamento são listados na tabela a seguir.</p> + +<table class="fullwidth-table"> + <caption>Operadores bit a bit de deslocamento</caption> + <thead> + <tr> + <th scope="col">Operador</th> + <th scope="col">Descrição</th> + <th scope="col">Exemplo</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>Deslocamento à esquerda (<<)</code></td> + <td>Este operador desloca o primeiro operando pelo número especificado de bits à esquerda. Bits excedentes deslocados para fora do limite à esquerda são descartados. Bits zero são inseridos à direita.</td> + <td><code>9<<2</code> produz 36 porque 1001 deslocado 2 bits à esquerda se torna 100100, que é 36.</td> + </tr> + <tr> + <td>Deslocamento à direita com propagação de sinal<br> + (<code>>></code>)</td> + <td>Este operador desloca o primeiro operando pelo número especificado de bits à direita. Bits excedentes deslocados para fora do limite à direita são descartados. Cópias dos bits mais à esquerda são deslocadas a partir da esquerda.</td> + <td><code>9>>2</code> produz 2 porque 1001 deslocado 2 bits à direita se torna 10, que é 2. De forma similar, <code>-9>>2</code> produz -3 porque o sinal é preservado.</td> + </tr> + <tr> + <td>Deslocamento à direita com preenchimento zero<br> + (<code>>>></code>)</td> + <td>Este operador desloca o primeiro operando pelo número especificado de bits à direita. Bits excedentes deslocados para fora do limite à direita são descartados. Bits zero são inseridos à esquerda.</td> + <td><code>19>>>2</code> produz 4 porque 10011 deslocado 2 bits à direita se torna 100, que é 4. Para números não negativos o deslocamento à direita com propagação de sinal e o deslocamento à direita com preenchimento zero produzem o mesmo resultado.</td> + </tr> + </tbody> +</table> + +<h3 id="Operadores_lógicos"><a name="operadores_logicos">Operadores lógicos</a></h3> + +<p><a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/Operadores_Logicos">Operadores lógicos</a> são utilizados tipicamente com valores booleanos (lógicos); neste caso, retornam um valor booleano. Entretanto, os operadores && e || na verdade retornam o valor de um dos operandos especificados, de forma que se esses operadores forem utilizados com valores não-booleanos, eles possam retornar um valor não-booleano. Os operadores lógicos são descritos na seguinte tabela.</p> + +<table class="fullwidth-table"> + <caption>Operadores lógico</caption> + <thead> + <tr> + <th scope="col">Operador</th> + <th scope="col">Utilização</th> + <th scope="col">Descrição</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>AND lógico (&&)</code></td> + <td><code>expr1 && expr2</code></td> + <td>(E lógico) - Retorna <code>expr1</code> caso possa ser convertido para falso; senão, retorna <code>expr2</code>. Assim, quando utilizado com valores booleanos, <code>&&</code> retorna verdadeiro caso ambos operandos sejam verdadeiros; caso contrário, retorna falso.</td> + </tr> + <tr> + <td><code>OU lógico (||)</code></td> + <td><code>expr1 || expr2</code></td> + <td>(OU lógico) - Retorna <code>expr1</code> caso possa ser convertido para verdadeiro; senão, retorna <code>expr2</code>. Assim, quando utilizado com valores booleanos, <code>||</code> retorna verdadeiro caso ambos os operandos sejam verdadeiro; se ambos forem falsos, retorna falso.</td> + </tr> + <tr> + <td><code>NOT lógico (!)</code></td> + <td><code>!expr</code></td> + <td>(Negação lógica) Retorna falso caso o único operando possa ser convertido para verdadeiro; senão, retorna verdadeiro.</td> + </tr> + </tbody> +</table> + +<p>Exemplos de expressões que podem ser convertidas para falso são aquelas que são avaliados como nulo, 0, string vazia ("") ou <code>undefined</code>.</p> + +<p>O código a seguir mostra exemplos do operador && (E lógico).</p> + +<pre class="brush: js notranslate">var a1 = true && true; // t && t retorna true +var a2 = true && false; // t && f retorna false +var a3 = false && true; // f && t retorna false +var a4 = false && (3 == 4); // f && f retorna false +var a5 = "Gato" && "Cão"; // t && t retorna Cão +var a6 = false && "Gato"; // f && t retorna false +var a7 = "Gato" && false; // t && f retorna false +</pre> + +<p>O código a seguir mostra exemplos do operador || (OU lógico).</p> + +<pre class="brush: js notranslate">var o1 = true || true; // t || t retorna true +var o2 = false || true; // f || t retorna true +var o3 = true || false; // t || f retorna true +var o4 = false || (3 == 4); // f || f retorna false +var o5 = "Gato" || "Cão"; // t || t retorna Gato +var o6 = false || "Gato"; // f || t retorna Gato +var o7 = "Gato" || false; // t || f retorna Gato +</pre> + +<p>O código a seguir mostra exemplos do operador ! (negação lógica).</p> + +<pre class="brush: js notranslate">var n1 = !true; // !t retorna false +var n2 = !false; // !f retorna true +var n3 = !"Gato"; // !t retorna false +</pre> + +<h4 id="Short-Circuit_Evaluation" name="Short-Circuit_Evaluation">Avaliação de curto-circuito</h4> + +<p>Como expressões lógicas são avaliadas da esquerda para a direita, elas são testadas como possíveis avaliações de "curto-circuito" utilizando as seguintes regras:</p> + +<ul> + <li><code>false</code> && <em>qualquercoisa</em> é avaliado em curto-circuito como falso.</li> + <li><code>true</code> || <em>qualquercoisa</em> é avaliado em curto-circuito como verdadeiro.</li> +</ul> + +<p>As regras de lógica garantem que estas avaliações estejam sempre corretas. Repare que a parte <em>qualquercoisa</em> das expressões acima não é avaliada, de forma que qualquer efeito colateral de fazê-lo não produz efeito algum.</p> + +<h3 id="Operadores_de_string"><a name="operadores_string">Operadores de string</a></h3> + +<p>Além dos operadores de comparação, que podem ser utilizados em valores string, o operador de concatenação (+) concatena dois valores string, retornando outra string que é a união dos dois operandos.</p> + +<p>Por exemplo,</p> + +<pre class="notranslate"> console.log(<code>"minha " + "string"</code>); // exibe a string <code>"minha string"</code>.</pre> + +<p>O operador de atribuição encurtado += também pode ser utilizado para concatenar strings.</p> + +<p>Por exemplo,</p> + +<pre class="notranslate">var minhaString = "alfa"; +minhaString += "beto"; // É avaliada como "alfabeto" e atribui este valor a <code>minhastring</code>.</pre> + +<h3 id="Operador_condicional_ternário"><a name="operador_condicional_ternario">Operador condicional (ternário)</a></h3> + +<p>O operador condicional é o único operador JavaScript que utiliza três operandos. O operador pode ter um de dois valores baseados em uma condição. A sintaxe é:</p> + +<pre class="notranslate"><em>condicao</em> ? <em>valor1</em> : <em>valor2</em> +</pre> + +<p>Se <code>condicao</code> for verdadeira, o operador terá o valor de <code>valor1</code>. Caso contrário, terá o valor de <code>valor2</code>. Você pode utilizar o operador condicional em qualquer lugar onde utilizaria um operador padrão.</p> + +<p>Por exemplo,</p> + +<pre class="brush: js notranslate">var status = (idade >= 18) ? "adulto" : "menor de idade"; +</pre> + +<p>Esta declaração atribui o valor "adulto" à variável <code>status</code> caso <code>idade</code> seja dezoito ou mais. Caso contrário, atribui o valor "menor de idade".</p> + +<h3 id="comma_operator" name="comma_operator"><a id="operador_virgula" name="operador_virgula">Operador vírgula</a></h3> + +<p>O operador vírgula (<code>,</code>) simplesmente avalia ambos de seus operandos e retorna o valor do segundo. Este operador é utilizado primariamente dentro de um laço <code>for</code> para permitir que multiplas variáveis sejam atualizadas cada vez através do laço.</p> + +<p>Por exemplo, se <code>a</code> é uma matriz bidimensional com 10 elementos em um lado, o código a seguir utiliza o operador vírgula para incrementar duas variáveis de uma só vez. O código imprime os valores dos elementos diagonais da matriz:</p> + +<pre class="brush: js notranslate">for (var i = 0, j = 9; i <= 9; i++, j--) + console.log("a[" + i + "][" + j + "]= " + a[i][j]); +</pre> + +<h3 id="delete" name="delete"><a name="operadores_unario">Operadores unário</a></h3> + +<p>Um operador unário é uma operação com apenas um operando.</p> + +<h4 id="delete" name="delete"><code>delete</code></h4> + +<p>O operador <code>delete</code> apaga um objeto, uma propriedade de um objeto ou um elemento no índice especificado de uma matriz. A sintaxe é:</p> + +<pre class="brush: js notranslate">delete nomeObjeto; +delete <span style="font-size: 1rem;">nomeObjeto</span><span style="font-size: 1rem;">.propriedade;</span> +delete nomeObjeto[indice]; +delete propriedade; // válido apenas dentro de uma declaração with +</pre> + +<p>onde <code>nomeObjeto</code> é o nome de um objeto, <code>propriedade</code> é uma propriedade existente e <code>indice</code> é um inteiro que representa a localização de um elemento em uma matriz.</p> + +<p>A quarta forma é permitida somente dentro de uma declaração <code>with</code> para apagar uma propriedade de um objeto.</p> + +<p>Você pode utilizar o operador <code>delete</code> para apagar variáveis declaradas implicitamente mas não aquelas declaradas com <code>var</code>.</p> + +<p>Se o operador <code>delete</code> for bem-sucedido, ele define a propriedade ou elemento para <code>undefined</code>. O operador <code>delete</code> retorna verdadeiro se a operação for possível; ele retorna falso se a operação não for possível.</p> + +<pre class="brush: js notranslate">x = 42; +var y = 43; +meuobj = new Number(); +meuobj.h = 4; // cria a propriedade h +delete x; // retorna true (pode apagar se declarado implicitamente) +delete y; // retorna false (não pode apagar se declarado com var) +delete Math.PI; // retorna false (não pode apagar propriedades predefinidas) +delete meuobj.h; // retorna true (pode apagar propriedades definidas pelo usuário) +delete meuobj; // retorna true (pode apagar se declarado implicitamente) +</pre> + +<h5 id="Apagando_elementos_de_array">Apagando elementos de array</h5> + +<p>Quando você apaga um elemento de um array, o tamanho do array não é afetado. Por exemplo, se você apaga <code>a[3]</code>, o valor de <code>a[4]</code> ainda estará em <code>a[4]</code> e <code>a[3]</code> passa a ser <code>undefined</code>.</p> + +<p>Quando o operador <code>delete</code> remove um elemento do array, aquele elemento não pertence mais ao array. No exemplo a seguir, <code>arvores[3]</code> é removido com <code>delete</code>. Entretanto, <code>arvores[3]</code> ainda é endereçável e retorna <code>undefined</code>.</p> + +<pre class="brush: js notranslate">var arvores = new Array("pau-brasil", "loureiro", "cedro", "carvalho", "sicômoro"); +delete arvores[3]; +if (3 in arvores) { + // isto não é executado +} +</pre> + +<p>Se você quer que um elemento do array exista, mas tenha um valor indefinido, utilize a palavra-chave <code>undefined</code> em vez do operador <code>delete</code>. No exemplo a seguir, o valor <code>undefined</code> é atribuído a <code>arvores[3]</code>, mas o elemento da matriz ainda existe:</p> + +<pre class="brush: js notranslate">var arvores = new Array("pau-brasil", "loureiro", "cedro", "carvalho", "sicômoro"); +arvores[3] = undefined; +if (3 in arvores) { + // isto será executado +} +</pre> + +<h4 id="typeof" name="typeof"><code>typeof</code></h4> + +<p>O operador <code>typeof</code> é utilizado em qualquer uma das seguintes formas:</p> + +<pre class="brush: js notranslate">typeof operando +typeof (operando) +</pre> + +<p>O operador <code>typeof</code> retorna uma string indicando o tipo do operando sem avaliação. <code>operando</code> é uma string, variável, palavra-chave ou objeto cujo tipo deve ser retornado. Os parênteses são opcionais.</p> + +<p>Suponha que você defina as seguintes variáveis:</p> + +<pre class="brush: js notranslate">var meuLazer = new Function("5 + 2"); +var forma = "redondo"; +var tamanho = 1; +var hoje = new Date(); +</pre> + +<p>O operador <code>typeof</code> retornaria o seguinte resultado para aquelas variáveis:</p> + +<pre class="brush: js notranslate">typeof meuLazer; // retorna "function" +typeof forma; // retorna "string" +typeof tamanho; // retorna "number" +typeof hoje; // retorna "object" +typeof naoExiste; // retorna "undefined" +</pre> + +<p>Para as palavras-chave <code>true</code> e <code>null</code>, o <code>typeof</code> retorna os seguintes resultados:</p> + +<pre class="brush: js notranslate">typeof true; // retorna "boolean" +typeof null; // retorna "object" +</pre> + +<p>Para um número ou uma string, o <code>typeof</code> retorna os seguintes resultados:</p> + +<pre class="brush: js notranslate">typeof 62; // retorna "number" +typeof 'Olá mundo'; // retorna "string" +</pre> + +<p>Para valores de propriedades, o <code>typeof</code> retorna o tipo do valor que a propriedade possui:</p> + +<pre class="brush: js notranslate">typeof document.lastModified; // retorna "string" +typeof window.length; // retorna "number" +typeof Math.LN2; // retorna "number" +</pre> + +<p>Para métodos e funções, o <code>typeof</code> retorna os seguintes resultados:</p> + +<pre class="brush: js notranslate">typeof blur; // retorna "function" +typeof eval; // retorna "function" +typeof parseInt; // retorna "function" +typeof forma.split; // retorna "function" +</pre> + +<p>Para objetos predefinidos, o <code>typeof</code> retorna os seguintes resultados:</p> + +<pre class="brush: js notranslate">typeof Date; // retorna "function" +typeof Function; // retorna "function" +typeof Math; // retorna "object" +typeof Option; // retorna "function" +typeof String; // retorna "function" +</pre> + +<h4 id="typeof" name="typeof"><code>void</code></h4> + +<p>O operador <code>void</code> é utilizado de qualquer uma das seguintes formas:</p> + +<pre class="brush: js notranslate">void (expressao) +void expressao +</pre> + +<p>O operador <code>void</code> especifica que uma expressão deve ser avaliada sem retorno de valor. <code>expressao</code> é uma expressão JavaScript que deve ser avaliada. Os parênteses em torno da expressão são opcionais, mas é uma boa prática utilizá-los.</p> + +<p>Você pode utilizar o operador <code>void</code> para especificar uma expressão como um link de hipertexto. A expressão é avaliada mas não é carregada no lugar do documento atual.</p> + +<p>O código a seguir cria um link de hipertexto que não faz coisa alguma quando clicado pelo usuário. Quando o usuário clica no link, <code>void(0)</code> é avaliado como indefinido, que não tem efeito em JavaScript.</p> + +<pre class="brush: html notranslate"><a href="javascript:void(0)">Clique aqui para fazer nada</a> +</pre> + +<p>O código a seguir cria um link de hipertexto que submete um formulário quando clicado pelo usuário.</p> + +<pre class="brush: html notranslate"><a href="javascript:void(document.form.submit())"> +Clique aqui para enviar</a></pre> + +<h3 id="in" name="in"><a name="operadores_relacionais">Operadores relacionais</a></h3> + +<p>Um operador relacional compara seus operando e retorna um valor booleano baseado em se a comparação é verdadeira.</p> + +<h4 id="in" name="in"><code>in</code></h4> + +<p>O operador <code>in</code> retorna verdadeiro se a propriedade especificada estiver no objeto especificado. A sintaxe é:</p> + +<pre class="brush: js notranslate">nomePropriedadeOuNumero in nomeObjeto +</pre> + +<p>onde <code>nomePropriedadeOuNumero</code> é uma string ou uma expressão numérica que representa um nome de propriedade ou um índice de um array, e <code>nomeObjeto</code> é o nome de um objeto.</p> + +<p>Os exemplos a seguir mostram alguns usos do operador <code>in</code>.</p> + +<pre class="brush: js notranslate">// Arrays +var arvores = new Array("pau-brasil", "loureiro", "cedro", "carvalho", "sicômoro"); +0 in arvores; // retorna verdadeiro +3 in arvores; // retorna verdadeiro +6 in arvores; // retorna falso +"cedro" in arvores; // retorna falso (você deve especificar o número do índice, + // não o valor naquele índice) +"length" in arvores; // retorna verdadeiro (length é uma propriedade de Array) + +// Objetos predefinidos +"PI" in Math; // retorna verdadeiro +var minhaString = new String("coral"); +"length" in minhaString; // retorna verdadeiro + +// Objetos personalizados +var meucarro = {marca: "Honda", modelo: "Accord", ano: 1998}; +"marca" in meucarro; // retorna verdadeiro +"modelo" in meucarro; // retorna verdadeiro +</pre> + +<h4 id="instanceof" name="instanceof"><code>instanceof</code></h4> + +<p>O operador <code>instanceof</code> retorna verdadeiro se o objeto especificado for do tipo de objeto especificado. A sintaxe é:</p> + +<pre class="brush: js notranslate">nomeObjeto instanceof tipoObjeto +</pre> + +<p>onde <code>nomeObjeto</code> é o nome do objeto a ser comparado com <code>tipoObjeto</code>, e <code>tipoObjeto</code> é um tipo de objeto como <code>Date</code> ou <code>Array</code>.</p> + +<p>Utilize o <code>instanceof</code> quando você precisar confirmar o tipo de um objeto em tempo de execução. Por exemplo, ao capturar exceções você pode desviar para um código de manipulação de exceção diferente dependendo do tipo de exceção lançada.</p> + +<p>Por exemplo, o código a seguir utiliza o <code>instanceof</code> para determinar se <code>dia</code> é um objeto <code>Date</code>. Como <code>dia</code> é um objeto <code>Date</code>, as declarações do <code>if</code> são executadas.</p> + +<pre class="brush: js notranslate">var dia = new Date(1995, 12, 17); +if (dia instanceof Date) { + // declarações a serem executadas +} +</pre> + +<h3 id="typeof" name="typeof"><a name="precedencia_de_operadores">Precedência de operadores</a></h3> + +<p>A <em>precedência</em> de operadores determina a ordem em que eles são aplicados quando uma expressão é avaliada. Você pode substituir a precedência dos operadores utilizando parênteses.</p> + +<p>A tabela a seguir descreve a precedência de operadores, da mais alta para a mais baixa.</p> + +<table class="standard-table"> + <caption>Precedência de operadores</caption> + <thead> + <tr> + <th scope="col">Tipo de operador</th> + <th scope="col">Operadores individuais</th> + </tr> + </thead> + <tbody> + <tr> + <td>membro</td> + <td><code>. []</code></td> + </tr> + <tr> + <td>chamada / criação de instância</td> + <td><code>() new</code></td> + </tr> + <tr> + <td>negação / incremento</td> + <td><code>! ~ - + ++ -- typeof void delete</code></td> + </tr> + <tr> + <td>multiplicação / divisão / resto ou módulo</td> + <td><code>* / %</code></td> + </tr> + <tr> + <td>adição / subtração</td> + <td><code>+ -</code></td> + </tr> + <tr> + <td>deslocamento bit a bit</td> + <td><code><< >> >>></code></td> + </tr> + <tr> + <td>relacional</td> + <td><code>< <= > >= in instanceof</code></td> + </tr> + <tr> + <td>igualdade</td> + <td><code>== != === !==</code></td> + </tr> + <tr> + <td>E bit a bit</td> + <td><code>&</code></td> + </tr> + <tr> + <td>OU exclusivo bit a bit</td> + <td><code>^</code></td> + </tr> + <tr> + <td>OU bit a bit</td> + <td><code>|</code></td> + </tr> + <tr> + <td>E lógico</td> + <td><code>&&</code></td> + </tr> + <tr> + <td>OU lógico</td> + <td><code>||</code></td> + </tr> + <tr> + <td>condicional</td> + <td><code>?:</code></td> + </tr> + <tr> + <td>atribuição</td> + <td><code>= += -= *= /= %= <<= >>= >>>= &= ^= |=</code></td> + </tr> + <tr> + <td>vírgula</td> + <td><code>,</code></td> + </tr> + </tbody> +</table> + +<p>Uma versão mais detalhada desta tabela, com links adicionais para detalhes de cada operador, pode ser vista em <a href="/pt-BR/docs/JavaScript/Reference/Operators/Operator_Precedence#Table">Referência do JavaScript</a>.</p> + +<h2 id="Expressões">Expressões</h2> + +<p>Uma <em>expressão</em> consiste em qualquer unidade válida de código que é resolvida como um valor.</p> + +<p>Conceitualmente, existem dois tipos de expressões: aquelas que atribuem um valor a uma variável e aquelas que simplesmente possuem um valor.</p> + +<p>A expressão <code>x = 7</code> é um exemplo do primeiro tipo. Esta expressão utiliza o <em>operador</em> = para atribuir o valor sete à variável <code>x</code>. A expressão em si é avaliada como sete.</p> + +<p>O código <code>3 + 4</code> é um exemplo do segundo tipo de expressão. Esta expressão utiliza o operador + para somar três e quatro sem atribuir o resultado, sete, a uma variável.</p> + +<p>O JavaScript possui as seguintes categorias de expressão:</p> + +<ul> + <li>Aritmética: é avaliada como um número, por exemplo 3.14159. (Geralmente utiliza <a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operadores_aritmeticos">operadores aritméticos</a>).</li> + <li>String: é avaliada como uma string de caracteres, por exemplo, "Fred" ou "234". (Geralmente utiliza <a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operadores_string">operadores de string</a>).</li> + <li>Lógica: é avaliada como verdadeira ou falsa. (Costuma envolver<a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#operadores_logicos"> operadores lógicos</a>).</li> + <li>Expressões primárias: Palavras reservadas e expressões gerais do JavaScript.</li> + <li>Expressão lado esquerdo: atribuição à esquerda de valores.</li> +</ul> + +<h3 id="Expressões_primárias">Expressões primárias</h3> + +<p>Palavras reservadas e expressões gerais do JavaScript.</p> + +<h4 id="this" name="this"><code>this</code></h4> + +<p>Utilize a palavra reservada <code>this</code> para se referir ao objeto atual. Em geral, o <code>this</code> se refere ao objeto chamado em um método. Utilize o <code>this</code> das seguintes formas:</p> + +<pre class="brush: js notranslate">this["nomePropriedade"] +this.nomePropriedade +</pre> + +<p>Suponha uma função chamada <code>valide</code> que valida a propriedade <code>valor</code> de um objeto, dado o objeto e os valores máximo e mínimo:</p> + +<pre class="brush: js notranslate">function valide(obj, minimo, maximo){ + if ((obj.valor < minimo) || (obj.valor > maximo)) + alert("Valor inválido!"); +} +</pre> + +<p>Você poderia chamar <code>valide</code> em cada manipulador de evento <code>onChange</code> de um formulário utilizando <code>this</code> para passar o elemento do formulário, como no exemplo a seguir:</p> + +<pre class="brush: html notranslate"><b>Informe um número entre 18 e 99:</b> +<input type="text" name="idade" size=3 + onChange="valide(this, 18, 99);"> +</pre> + +<h4 id="new" name="new">Operador de agrupamento</h4> + +<p>O operador de agrupamento <code>( )</code> controla a precedência de avaliação de expressões. Por exemplo, você pode substituir a precedência da divisão e multiplicação para que a adição e subtração sejam avaliadas primeiro.</p> + +<pre class="brush:js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">var</span> a <span class="operator token">=</span> <span class="number token">1</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> b <span class="operator token">=</span> <span class="number token">2</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> c <span class="operator token">=</span> <span class="number token">3</span><span class="punctuation token">;</span> + +<span class="comment token">// Precedência padrão</span> +a <span class="operator token">+</span> b <span class="operator token">*</span> c <span class="comment token">// 7</span> +<span class="comment token">// a avaliação padrão pode ser assim</span> +a <span class="operator token">+</span> <span class="punctuation token">(</span>b <span class="operator token">*</span> c<span class="punctuation token">)</span> <span class="comment token">// 7</span> + +<span class="comment token">// Agora substitui a precedência</span> +<span class="comment token">// soma antes de multiplicar </span> +<span class="punctuation token">(</span>a <span class="operator token">+</span> b<span class="punctuation token">)</span> <span class="operator token">*</span> c <span class="comment token">// 9</span> + +<span class="comment token">// o que é equivalente a</span> +a <span class="operator token">*</span> c <span class="operator token">+</span> b <span class="operator token">*</span> c <span class="comment token">// 9</span></code></pre> + +<h4 id="new" name="new">Comprehensions</h4> + +<p>Comprehensions são uma característica experimental de JavaScript, marcada para ser inclusa em uma versão futura do ECMAScript. Existem duas versões de Comprehensions:</p> + +<p>{{experimental_inline}}<strong><a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/Array_comprehensions" title="The array comprehension syntax is a JavaScript expression which allows you to quickly assemble a new array based on an existing one. Comprehensions exist in many programming languages."><code>[for (x of y) x]</code></a></strong><br> + Comprehensions de array.</p> + +<p>{{experimental_inline}}<strong><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Generator_comprehensions" title="The generator comprehension syntax is a JavaScript expression which allows you to quickly assemble a new generator function based on an existing iterable object. Comprehensions exist in many programming languages."><code>(for (x of y) y) </code></a><br> + <code> </code></strong><code> gerador de </code>comprehensions</p> + +<p>Comprehensions existem em muitas linguagens de programação e permitem que você rapidamente monte um novo array com base em um existente, por exemplo:</p> + +<pre class="brush:js line-numbers language-js notranslate"><code class="language-js"><span class="punctuation token">[</span><span class="keyword token">for</span> <span class="punctuation token">(</span>i <span class="keyword token">of</span> <span class="punctuation token">[</span> <span class="number token">1</span><span class="punctuation token">,</span> <span class="number token">2</span><span class="punctuation token">,</span> <span class="number token">3</span> <span class="punctuation token">]</span><span class="punctuation token">)</span> i<span class="operator token">*</span>i <span class="punctuation token">]</span><span class="punctuation token">;</span> +<span class="comment token">// [ 1, 4, 9 ]</span> + +<span class="keyword token">var</span> abc <span class="operator token">=</span> <span class="punctuation token">[</span> <span class="string token">"A"</span><span class="punctuation token">,</span> <span class="string token">"B"</span><span class="punctuation token">,</span> <span class="string token">"C"</span> <span class="punctuation token">]</span><span class="punctuation token">;</span> +<span class="punctuation token">[</span><span class="keyword token">for</span> <span class="punctuation token">(</span>letras <span class="keyword token">of</span> abc<span class="punctuation token">)</span> letras<span class="punctuation token">.</span><span class="function token">toLowerCase</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">]</span><span class="punctuation token">;</span> +<span class="comment token">// [ "a", "b", "c" ]</span></code></pre> + +<h3 id="new" name="new">Expressão lado esquerdo</h3> + +<p>Atribuição à esquerda de valores.</p> + +<h4 id="new" name="new"><code>new</code></h4> + +<p>Você pode utilizar o <a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/new">operador new</a> para criar uma instância de um tipo de objeto definido pelo usuário ou de um dos tipos de objeto predefinidos: <code>Array</code>, <code>Boolean</code>, <code>Date</code>, <code>Function</code>, <code>Image</code>, <code>Number</code>, <code>Object</code>, <code>Option</code>, <code>RegExp </code>ou <code>String</code>. No servidor, você pode também utilizar <code>DbPool</code>, <code>Lock</code>, <code>File </code>ou <code>SendMail</code>. Utilize o operador <code>new</code> da seguinte forma:</p> + +<pre class="brush: js notranslate">var nomeObjeto = new tipoObjeto([parametro1, parametro2, ..., parametroN]); +</pre> + +<h4 id="super"><code>super</code></h4> + +<p>A palavra <a href="/pt-BR/docs/Web/JavaScript/Reference/Operators/super">reservada super</a> é utilizada para chamar a função pai de um objeto. É útil para nas classes para a chamada do construtor pai, por exemplo:</p> + +<pre class="syntaxbox notranslate">super([argumentos]); //chama o construtor pai. +super.funcaoDoPai([argumentos]);</pre> + +<h4 id="Operador_spread"><code>Operador spread</code></h4> + +<p>O operador <code>spread</code> permite que uma expressão seja expandido em locais onde são esperados vários argumentos (para chamadas de função) ou vários elementos (para arrays).</p> + +<p>Exemplo: Se você tem um array e deseja criar um novo array com os elementos do array já existente sendo parte do novo array, a sintaxe do array não será suficiente e você terá de usar uma combinação de push, splice, concat, etc. Com a sintaxe <code>spread</code>, isto torna-se muito mais sucinto:</p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">var</span> partes <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">'ombro'</span><span class="punctuation token">,</span> <span class="string token">'joelhos'</span><span class="punctuation token">]</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> musica <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">'cabeca'</span><span class="punctuation token">,</span> <span class="punctuation token">.</span><span class="punctuation token">.</span><span class="punctuation token">.</span>partes<span class="punctuation token">,</span> <span class="string token">'e'</span><span class="punctuation token">,</span> <span class="string token">'pés'</span><span class="punctuation token">]</span><span class="punctuation token">;</span></code></pre> + +<p id="typeof">Da mesma forma, o operador <code>spread</code> funciona com chamadas de função:</p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">f</span><span class="punctuation token">(</span>x<span class="punctuation token">,</span> y<span class="punctuation token">,</span> z<span class="punctuation token">)</span> <span class="punctuation token">{</span> <span class="punctuation token">}</span> +<span class="keyword token">var</span> args <span class="operator token">=</span> <span class="punctuation token">[</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">1</span><span class="punctuation token">,</span> <span class="number token">2</span><span class="punctuation token">]</span><span class="punctuation token">;</span> +<span class="function token">f</span><span class="punctuation token">(</span><span class="punctuation token">.</span><span class="punctuation token">.</span><span class="punctuation token">.</span>args<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<div>{{PreviousNext("Web/JavaScript/Guide/Functions", "Web/JavaScript/Guide/Numbers_and_dates")}}</div> diff --git a/files/pt-br/web/javascript/guide/formatando_texto/index.html b/files/pt-br/web/javascript/guide/formatando_texto/index.html new file mode 100644 index 0000000000..1b4bb50772 --- /dev/null +++ b/files/pt-br/web/javascript/guide/formatando_texto/index.html @@ -0,0 +1,250 @@ +--- +title: Formatando texto +slug: Web/JavaScript/Guide/Formatando_texto +tags: + - Guía + - JavaScript +translation_of: Web/JavaScript/Guide/Text_formatting +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}</div> + +<p class="summary">Esse capítulo introduz como trabalhar com strings e texto em JavaScript.</p> + +<h2 id="Strings">Strings</h2> + +<p>O tipo {{Glossary("String")}} do JavaScript é usado para representar informações de texto. É um conjunto de "elementos" composto por valores inteiros de 16-bits sem sinal. Cada elemento dentro da String ocupa uma posição dentro dessa String. O primeiro elemento está no índice 0, o próximo no índice 1, e assim sucessivamente. O tamanho de uma String é a quantidade de elementos que ela possui. Você pode criar strings usando strings literais ou objetos string.</p> + +<h3 id="Strings_literais">Strings literais</h3> + +<p>Você pode criar strings usando aspas simples ou aspas duplas:</p> + +<pre class="brush: js">'foo' +"bar"</pre> + +<p>Strings mais avançadas podem ser criadas usando <a href="https://pt.wikipedia.org/wiki/Sequ%C3%AAncia_de_escape">sequências de escape</a>:</p> + +<h4 id="Sequências_de_escape_hexadecimais">Sequências de escape hexadecimais</h4> + +<p>O número depois de \x é interpretado como um número <a href="https://en.wikipedia.org/wiki/Hexadecimal">hexadecimal</a>.</p> + +<pre class="brush: js">'\xA9' // "©" +</pre> + +<h4 id="Sequências_de_escape_unicode">Sequências de escape unicode</h4> + +<p>As sequências de escape unicode requerem no mínimo quatro caracteres depois do <code>\u</code>.</p> + +<pre class="brush: js">'\u00A9' // "©"</pre> + +<h4 id="Sequências_de_escape_Unicode_code_point">Sequências de escape Unicode code point</h4> + +<p>É novo no ECMAScript 6. Com essas sequências, cada caractere pode ser "escapado" usando números hexadecimais, sendo possível usar pontos de código Unicode de até 0x10FFFF. Com escapes Unicode simples muitas vezes é necessário escrever as metades substitutas separadamente para obter o mesmo resultado.</p> + +<p>Veja também {{jsxref("String.fromCodePoint()")}} or {{jsxref("String.prototype.codePointAt()")}}.</p> + +<pre class="brush: js">'\u{2F804}' + +// o mesmo com escapes Unicode simples +'\uD87E\uDC04'</pre> + +<h3 id="Objetos_String">Objetos String</h3> + +<p>O objeto {{jsxref("String")}} é como uma "capa" ao redor do tipo primitivo string.</p> + +<pre class="brush: js">var s = new String("foo"); // Cria um objeto String +console.log(s); // Exibe no console: { '0': 'f', '1': 'o', '2': 'o'} +typeof s; // Retorna 'object' +</pre> + +<p>Você pode chamar qualquer um dos métodos do objeto <code>String</code> em cima de uma string literal — JavaScript automaticamente converte a string literal em um objeto <code>String </code>temporário, chama o método, e então descarta o objeto <code>String</code> temporário. Você pode também usar a propriedade <code>String.length</code> com uma string literal.</p> + +<p>Você deve usar strings literais a menos que você realmente precise usar um objeto <code>String</code>, pois objetos <code>String</code> podem ter comportamentos inesperados. Por exemplo:</p> + +<pre class="brush: js">var s1 = "2 + 2"; // Cria uma string literal +var s2 = new String("2 + 2"); // Creates um objeto String +eval(s1); // Retorna o número 4 +eval(s2); // Retorna a string "2 + 2"</pre> + +<p>Um objeto <code>String</code> possui uma propriedade, <code>length</code>, que indica o número de caracteres na string. Por exemplo, o código a seguir atribui o valor 11 à variável <code>x</code>, pois "Olá, mundo!" possui 11 caracteres:</p> + +<pre class="brush: js">var minhaString = "Olá, mundo!"; +var x = minhaString.length; +</pre> + +<p>Um objeto <code>String </code>possui uma variedade de métodos: por exemplo aqueles que retornam uma variação da própria string, como <code>substring</code> e <code>toUpperCase</code>.</p> + +<p>A tabela a seguir lista os métodos de objetos {{jsxref("String")}}.</p> + +<table class="standard-table"> + <caption> + <h4 id="Métodos_de_String">Métodos de <code>String</code></h4> + </caption> + <thead> + <tr> + <th scope="col">Método</th> + <th scope="col">Descrição</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("String.charAt", "charAt")}}, {{jsxref("String.charCodeAt", "charCodeAt")}}, {{jsxref("String.codePointAt", "codePointAt")}}</td> + <td>Retorna o código do caractere ou o caractere em uma posição específica na string.</td> + </tr> + <tr> + <td>{{jsxref("String.indexOf", "indexOf")}}, {{jsxref("String.lastIndexOf", "lastIndexOf")}}</td> + <td>Retorna a posição de uma substring específica na string ou a última posição da substring específica, respectivamente.</td> + </tr> + <tr> + <td>{{jsxref("String.startsWith", "startsWith")}}, {{jsxref("String.endsWith", "endsWith")}}, {{jsxref("String.includes", "includes")}}</td> + <td>Retorna se uma string começa, termina ou contém uma outra string específica.</td> + </tr> + <tr> + <td>{{jsxref("String.concat", "concat")}}</td> + <td>Concatena o texto de duas strings e retorna uma nova string.</td> + </tr> + <tr> + <td>{{jsxref("String.fromCharCode", "fromCharCode")}}, {{jsxref("String.fromCodePoint", "fromCodePoint")}}</td> + <td>Cria uma string a partir de uma sequência específica de valores Unicode. Esse é um método da classe String, não de uma instância do tipo String.</td> + </tr> + <tr> + <td>{{jsxref("String.split", "split")}}</td> + <td>Separa um objeto <code>String </code>em um array de strings, separando a string em substrings.</td> + </tr> + <tr> + <td>{{jsxref("String.slice", "slice")}}</td> + <td>Extrai uma seção de uma string e retorna uma nova string.</td> + </tr> + <tr> + <td>{{jsxref("String.substring", "substring")}}, {{jsxref("String.substr", "substr")}}</td> + <td>Retorna um subconjunto específico de uma string, definindo os índices inicial e final, ou definindo um índice e um tamanho.</td> + </tr> + <tr> + <td>{{jsxref("String.match", "match")}}, {{jsxref("String.replace", "replace")}}, {{jsxref("String.search", "search")}}</td> + <td>Trabalha com expressões regulares.</td> + </tr> + <tr> + <td>{{jsxref("String.toLowerCase", "toLowerCase")}}, {{jsxref("String.toUpperCase", "toUpperCase")}}</td> + <td> + <p>Retorna a string com todos caracteres em minúsculo, ou maiúsculo, respectivamente.</p> + </td> + </tr> + <tr> + <td>{{jsxref("String.normalize", "normalize")}}</td> + <td>Retorna a Forma Normalizada Unicode (Unicode Normalization Form) da string que chama o método.</td> + </tr> + <tr> + <td>{{jsxref("String.repeat", "repeat")}}</td> + <td>Retorna uma string contendo os elementos do objeto repetidos pela quantidade de vezes dada.</td> + </tr> + <tr> + <td>{{jsxref("String.trim", "trim")}}</td> + <td>Retira espaços em branco no começo e no final da string.</td> + </tr> + </tbody> +</table> + +<h3 id="Template_strings_com_várias_linhas">Template strings com várias linhas</h3> + +<p><a href="/en-US/docs/Web/JavaScript/Reference/template_strings">Template strings</a> são strings literais que permitem expressões no seu conteúdo. Você pode usar os recursos de strings com multiplas linhas e interpolações de string com as template strings.</p> + +<p>Template strings são declaradas com o acento grave (``) ao invés de aspas simples ou aspas duplas. Essas strings podem conter place holders. Os place holders são indicados pelo cifrão e com chaves ( <code>${expressao}</code> ).</p> + +<h4 id="Várias_linhas_(Multi-lines)">Várias linhas (Multi-lines)</h4> + +<p>Qualquer caractere de nova linha ( <code>'\n'</code> ) inserido na string também faz parte das template string. Usando strings normais, você teria que usar a sintaxe a seguir para conseguir uma string de várias linhas</p> + +<pre class="brush: js">console.log("linha de texto 1\n\ +linha de texto 2"); +// "linha de texto 1 +// linha de texto 2"</pre> + +<p>Para obter o mesmo efeito com strings multi-lines, você pode agora escrever:</p> + +<pre class="brush: js">console.log(`linha de texto 1 +linha de texto 2`); +// "linha de texto 1 +// linha de texto 2"</pre> + +<h4 id="Expressões_inseridas">Expressões inseridas</h4> + +<p>Para conseguir inserir expressões com strings normais, você teria que usar a seguinte sintaxe:</p> + +<pre class="brush: js">var a = 5; +var b = 10; +console.log("Quinze é " + (a + b) + " e\nnão " + (2 * a + b) + "."); +// "Quinze é 15 e +// não 20."</pre> + +<p>Agora, com template strings, você tem a capacidade de usar uma forma mais simples e legível para fazer essas substituições:</p> + +<pre class="brush: js">var a = 5; +var b = 10; +console.log(`Quinze é ${a + b} e\nnão ${2 * a + b}.`); +// "Quinze é 15 e +// não 20."</pre> + +<p>Para mais informações, leia sobre <a href="/pt-BR/docs/Web/JavaScript/Reference/template_strings">Template strings</a> na <a href="/pt-BR/docs/Web/JavaScript/Reference">referência JavaScript</a>.</p> + +<h2 id="Internacionalização">Internacionalização</h2> + +<p>O objeto {{jsxref("Intl")}} é o <em>namespace</em> para a API de Internacionalização do ECMAScript, que oferece comparação de strings sensíveis à linguagem, formatação de números, e formatação de datas e horas. Os construtores para os objetos {{jsxref("Collator")}}, {{jsxref("NumberFormat")}}, e {{jsxref("DateTimeFormat")}} são propriedades do objeto <code>Intl</code>.</p> + +<h3 id="Formatação_de_data_e_hora">Formatação de data e hora</h3> + +<p>O objeto {{jsxref("DateTimeFormat")}} é útil para a formatação de data e hora. O código a seguir formata uma data em inglês no formato que é utilizado nos Estados Unidos. (O resultado é diferente em outro fuso horário).</p> + +<pre class="brush: js">var msPorDia = 24 * 60 * 60 * 1000; // número de milisegundos em um dia + +// July 17, 2014 00:00:00 UTC. +var july172014 = new Date(msPorDia * (44 * 365 + 11 + 197)); + +var opcoes = { year: "2-digit", month: "2-digit", day: "2-digit", + hour: "2-digit", minute: "2-digit", timeZoneName: "short" }; +var americanDateTime = new Intl.DateTimeFormat("en-US", opcoes).format; + +console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT +</pre> + +<h3 id="Formatação_de_números">Formatação de números</h3> + +<p>O objeto {{jsxref("NumberFormat")}} é útil para formatar números, por exemplo unidade monetária.</p> + +<pre class="brush: js">var precoGasolina = new Intl.NumberFormat("en-US", + { style: "currency", currency: "USD", + minimumFractionDigits: 3 }); + +console.log(precoGasolina.format(5.259)); // $5.259 + +var hanDecimalRMBInChina = new Intl.NumberFormat("zh-CN-u-nu-hanidec", + { style: "currency", currency: "CNY" }); + +console.log(hanDecimalRMBInChina.format(1314.25)); // ¥ 一,三一四.二五 +</pre> + +<h3 id="Collation">Collation</h3> + +<p>O objeto {{jsxref("Collator")}} é usado para comparar e ordenar strings.</p> + +<p>Por exemplo, existem atualmente duas ordens diferentes de classificação no Alemão: <em>listaTelefônica</em> e <em>dicionário</em>. A ordenação da <em>listaTelefônica</em> enfatiza o som, e é como se "ä", "ö", e assim por diante, fossem expandidos para "ae", "oe", e assim sucessivamente, para definir a ordem.</p> + +<pre class="brush: js">var nomes = ["Hochberg", "Hönigswald", "Holzman"]; + +var phonebookAlemao = new Intl.Collator("de-DE-u-co-phonebk"); + +// como se ordenasse ["Hochberg", "Hoenigswald", "Holzman"]: +console.log(names.sort(phonebookAlemao.compare).join(", ")); +// imprime "Hochberg, Hönigswald, Holzman" +</pre> + +<p>Algumas palavras do alemão são conjugadas com tremas extras, mas no <em>dicionário</em> essas palavras são ordenadas ignorando os tremas (exceto quando ordenando palavras que tem <em>apenas </em>o trema como diferença: <em>schon </em>antes de <em>schön</em>).</p> + +<pre class="brush: js">var dicionarioAlemao = new Intl.Collator("de-DE-u-co-dict"); + +// como se ordenasse ["Hochberg", "Honigswald", "Holzman"]: +console.log(names.sort(dicionarioAlemao.compare).join(", ")); +// imprime "Hochberg, Holzman, Hönigswald" +</pre> + +<p>Para mais informação sobre a API {{jsxref("Intl")}}, veja também <a href="https://hacks.mozilla.org/2014/12/introducing-the-javascript-internationalization-api/">Introducing the JavaScript Internationalization API (em inglês)</a>.</p> + +<div>{{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}</div> diff --git a/files/pt-br/web/javascript/guide/funções/index.html b/files/pt-br/web/javascript/guide/funções/index.html new file mode 100644 index 0000000000..7077d1787b --- /dev/null +++ b/files/pt-br/web/javascript/guide/funções/index.html @@ -0,0 +1,640 @@ +--- +title: Funções +slug: Web/JavaScript/Guide/Funções +tags: + - Funções JavaScript + - Guia(2) + - Iniciante + - JavaScript +translation_of: Web/JavaScript/Guide/Functions +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}</div> + +<p class="summary">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.</p> + +<p>Veja também o capítulo de <a href="/pt-BR/docs/Web/JavaScript/Reference/Functions">referência sobre funções JavaScript</a> para conhecer os detalhes.</p> + +<h2 id="Defining_functions" name="Defining_functions">Definindo Funções</h2> + +<h3 id="Declarando_uma_função">Declarando uma função</h3> + +<p>A <strong>definição da função </strong>(também chamada de <strong>declaração de função</strong>) consiste no uso da palavra chave <a href="/pt-BR/docs/JavaScript/Reference/Statements/function" title="function"><code>function</code></a>, seguida por:</p> + +<ul> + <li>Nome da Função.</li> + <li>Lista de argumentos para a função, entre parênteses e separados por vírgulas.</li> + <li>Declarações JavaScript que definem a função, entre chaves <code>{ }</code>.</li> +</ul> + +<p>Por exemplo, o código a seguir define uma função simples chamada <code>square</code>:</p> + +<pre class="brush: js">function square(numero) { + return numero * numero; +} +</pre> + +<p>A função <code>square</code> recebe um argumento chamado <code>numero</code>. A função consiste em uma instrução que indica para retornar o argumento da função (isto é, <code>numero</code>) multiplicado por si mesmo. A declaração <a href="/pt-BR/docs/JavaScript/Reference/Statements/return" title="return"><code>return</code></a> especifica o valor retornado pela função.</p> + +<pre class="brush: js">return numero * numero; +</pre> + +<p>Parâmetros primitivos (como um número) são passados para as funções por <strong>valor</strong>; 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.</p> + +<p>Se você passar um objeto (ou seja, um <a href="/pt-BR/docs/JavaScript/Glossary" title="en-US/docs/JavaScript/Glossary">valor não primitivo</a>, tal como {{jsxref("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:</p> + +<pre class="brush: 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) +</pre> + +<h3 id="Expressão_de_função">Expressão de função</h3> + +<p>Embora a declaração de função acima seja sintaticamente uma declaração, funções também podem ser criadas por uma <strong>expressão de função</strong>. Tal função pode ser <strong>anônima</strong>; ele não tem que ter um nome. Por exemplo, a função <code style="font-size: 14px;">square</code> poderia ter sido definida como:</p> + +<pre class="brush: js">var square = function(numero) {return numero * numero}; +var x = square(4) //x recebe o valor 16</pre> + +<p>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:</p> + +<pre class="brush: js" style="font-size: 14px;">var fatorial = function fac(n) {return n<2 ? 1 : n*fac(n-1)}; + +console.log(fatorial(3)); +</pre> + +<p>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 <code>map </code>sendo definida e, em seguida, chamada com uma função anônima como seu primeiro parâmetro:</p> + +<pre class="brush: js" style="font-size: 14px;">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; +} +</pre> + +<p>O código a seguir:</p> + +<pre class="brush: js" style="font-size: 14px;">map(function(x) {return x * x * x}, [0, 1, 2, 5, 10]); +</pre> + +<p>retorna [0, 1, 8, 125, 1000].</p> + +<p>Em JavaScript, uma função pode ser definida com base numa condição. Por exemplo, a seguinte definição de função define <code>minhaFuncao</code> somente se <code>num</code> é igual a 0:</p> + +<pre class="brush: js">var minhaFuncao; +if (num == 0){ + minhaFuncao = function(objeto) { + objeto.make = "Toyota" + } +}</pre> + +<p><span style="line-height: 1.572;">Além de definir funções, você também pode usar o construtor </span>{{jsxref("Function")}} <span style="line-height: 1.572;">para criar funções a partir de uma string<code> </code>em tempo real, como no método </span>{{jsxref("eval()")}}<span style="line-height: 1.572;">.</span></p> + +<p>Um <strong>método</strong> é uma função invocada por um objeto. Leia mais sobre objetos e métodos em <a href="/pt-BR/docs/JavaScript/Guide/Working_with_Objects" title="en-US/docs/JavaScript/Guide/Working with Objects">Trabalhando com Objetos</a>.</p> + +<h2 id="Calling_functions" name="Calling_functions">Chamando funções</h2> + +<p>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 <code>square</code>, você pode chamá-la do seguinte modo: </p> + +<pre class="brush: js">square(5); +</pre> + +<p>A declaração anterior chama a função com o argumento 5. A função executa as instruções e retorna o valor 25.</p> + +<p>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:</p> + +<pre>console.log(square(5)); +/* ... */ +function square(n){return n*n} +</pre> + +<p>O escopo de uma função é a função na qual ela é declarada, ou todo o programa se ela é declarada no nível superior.</p> + +<div class="note"> +<p>Nota: Isso funciona apenas quando a definição da função usa a sintaxe acima (ex., <code>function funcNome(){ })</code>. O código a seguir não vai funcionar.</p> +</div> + +<pre class="brush: js">console.log(square(5)); +var square = function (n) { + return n * n; +} +</pre> + +<p>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 <code>show_props</code> (definido em <a href="/pt-BR/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_Properties">Trabalhando com Objetos</a>) é um exemplo de uma função que recebe um objeto como um argumento.</p> + +<p>Um função pode chamar a si mesma. Por exemplo, a função que calcula os fatoriais recursivamente:</p> + +<pre class="brush: js">function fatorial(n){ + if ((n == 0) || (n == 1)) + return 1; + else + return (n * fatorial(n - 1)); +} +</pre> + +<p>Você poderia, então, calcular os fatoriais de um a cinco:</p> + +<pre class="brush: 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 +</pre> + +<p>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 {{jsxref("Function")}}). Um desses, o método {{jsxref("Function.apply", "apply()")}}, pode ser usado para atingir esse objetivo.</p> + +<h2 class="deki-transform" id="Function_scope" name="Function_scope">Escopo da função</h2> + +<p>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.</p> + +<pre class="brush: 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" +</pre> + +<h2 id="Scope_and_the_function_stack" name="Scope_and_the_function_stack">Escopo e a pilha de função</h2> + +<h3 id="Recursion" name="Recursion">Recursão</h3> + +<p>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:</p> + +<ol> + <li>o nome da função</li> + <li><code><a href="/pt-BR/docs/JavaScript/Reference/Functions_and_function_scope/arguments/callee">arguments.callee</a></code></li> + <li>uma variável no escopo que se refere a função</li> +</ol> + +<p>Por exemplo, considere a seguinte definição de função:</p> + +<pre class="brush: js">var foo = function bar() { + // declaracoes +}; +</pre> + +<p>Dentro do corpo da função, todos, a seguir, são equivalentes:</p> + +<ol> + <li><code>bar()</code></li> + <li><code>arguments.callee()</code></li> + <li><code>foo()</code></li> +</ol> + +<p>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:</p> + +<pre class="brush: js">var x = 0; +while (x < 10) { // "x < 10" a condição do laço + // faça coisas + x++; +} +</pre> + +<p>pode ser convertido em função recursiva e uma chamada para a função:</p> + +<pre class="brush: 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); +</pre> + +<p>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 <a href="/pt-BR/docs/Web/API/Document_Object_Model">DOM</a>) é mais fácil se feito recursivamente:</p> + +<pre class="brush: 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]); + } +} +</pre> + +<p>Em comparação ao laço da função, cada chamada recursiva realiza outras chamadas recursivas.</p> + +<p>É 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.</p> + +<p>O comportamento da pilha pode ser vista a seguir no exemplo:</p> + +<pre class="brush: js">function foo(i) { + if (i < 0) + return; + document.writeln('begin:' + i); + foo(i - 1); + document.writeln('end:' + i); +} +foo(3); +</pre> + +<p>que produz:</p> + +<pre>begin:3 +begin:2 +begin:1 +begin:0 +end:0 +end:1 +end:2 +end:3 +</pre> + +<h3 id="Nested_functions_and_closures" name="Nested_functions_and_closures">Funções aninhadas e closures</h3> + +<p>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 <em><code>closure</code></em>. 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).</p> + +<p>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.</p> + +<p>Em resumo:</p> + +<ul> + <li>A função interna só pode ser acessada a partir de declarações em função externa.</li> + <li>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.</li> +</ul> + +<p>O exemplo a seguir mostra as funções aninhadas:</p> + +<pre class="brush: 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 +</pre> + +<p>Uma vez que a função interna forma uma <em>closure</em>, você pode chamar a função externa e especificar argumentos para a função externa e interna:</p> + +<pre class="brush: 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 +</pre> + +<h3 id="Efficiency_considerations" name="Efficiency_considerations">Preservação de variáveis</h3> + +<p>Observe como <code>x</code> é preservado quando <code>dentro</code> é retornado. Uma <em>closure</em> 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 <code>fora</code>. A memória só poderá ser liberada quando o <code>dentro</code> retornado já não é mais acessível.</p> + +<p>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.</p> + +<h3 id="Multiply-nested_functions" name="Multiply-nested_functions">Múltiplas funções aninhadas</h3> + +<p>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 <em>closure</em>, 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 <em>closure</em> pode conter vários escopos; eles recursivamente contém o escopo das funções que os contém. Isso é chamado <em><code>encadeamento de escopo</code></em>. (O motivo de ser chamado "encadeamento" será explicado mais tarde).</p> + +<p>Considere o seguinte exemplo:</p> + +<pre class="brush: 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) +</pre> + +<p>Neste exemplo, <code>C</code> acessa <code>y</code> do <code>B</code> e <code>x</code> do <code>A</code>. Isso pode ser feito porque:</p> + +<ol> + <li>B forma uma <em>closure</em> incluindo <code>A</code>, isto é, <code>B</code> pode acessar argumentos e variáveis de <code>A</code>.</li> + <li>C forma uma <em>closure </em>incluindo <code>B</code>.</li> + <li> Devido a closure <code>B</code> inclui <code>A</code>, a <em>closure</em> <code>C</code> inclui <code>A</code>, <code>C</code> pode acessar tanto argumentos e variáveis de <code>B</code> como de <code>A</code>. Em outras palavras, <code>C</code> <em>encadeia </em>o escopo de <code>B</code> e <code>A</code>, nesta ordem.</li> +</ol> + +<p>O inverso, no entanto, não é verdadeiro. <code>A</code> não pode acessar <code>C</code>, porque <code>A</code> não pode acessar qualquer argumento ou variável de <code>B</code>. Assim, <code>C</code> é privado somente a <code>B</code>.</p> + +<h3 id="Name_conflicts" name="Name_conflicts">Conflitos de nome</h3> + +<p>Quando dois argumentos ou variáveis nos escopos da <em>closure</em> tem o mesmo nome, há um <em>conflito de nome</em>. 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:</p> + +<pre class="brush: js">function fora() { + var x = 10; + function dentro(x) { + return x; + } + return dentro; +} +result = fora()(20); // retorna 20 em vez de 10 +</pre> + +<p>O conflito de nome acontece na declaração <code>return x</code> e está entre o parâmetro <code>x</code> de <code>dentro</code> e a variável <code>x</code> de <code>fora</code>. A cadeia de escopo aqui é {<code>dentro</code>, <code>fora</code>, objeto global}. Por isso o <code>x</code> de <code>dentro</code> tem precedência sobre o <code>x</code> de <code>fora</code>, e 20 (<code>x</code> de <code>dentro</code>) é retornado em vez de 10 (<code>x</code> de fora).</p> + +<h2 id="Closures" name="Closures">Closures</h2> + +<p><em>Closures </em>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 <em>closure</em> é criada quando a função interna é de alguma forma disponibilizada para qualquer escopo fora da função externa.</p> + +<pre class="brush: 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" +</pre> + +<p>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.</p> + +<pre class="brush: 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 +</pre> + +<p>Nos códigos acima, a variável <code>nome</code> 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.</p> + +<pre class="brush: 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 +</pre> + +<p>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.</p> + +<pre class="brush: 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 ??? + } + } +} +</pre> + +<p>A palavra reservada <a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/this">this</a> é muito complicada em <em>closures,</em> elas têm de ser usadas com muito cuidado. O objeto ao que <code>this</code> se refere depende completamente de onde a função foi chamada, ao invés de onde ela foi definida.</p> + +<h2 id="Using_the_arguments_object" name="Using_the_arguments_object">Usando objeto de argumentos</h2> + +<p>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: </p> + +<pre class="brush: js">arguments[i] +</pre> + +<p>onde <code>i</code> é um número ordinal do argumento, começando com zero. Então, o primeiro argumento passado para a função seria <code>arguments[0]</code>. O número total de argumentos é indicado por <code>arguments.length</code>.</p> + +<p>Usando o objeto <code>arguments</code>, 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 <code>arguments.length</code> para determinar a quantidade de argumentos passados para a função, e então acessar cada argumento usando o objeto <code>arguments</code>.</p> + +<p>Por exemplo, considere uma função que concatena várias <em>strings</em>. O argumento formal para a função é uma <em>string</em> que especifica os caracteres que separam os itens para concatenar. A função definida como segue:</p> + +<pre class="brush: 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; +} +</pre> + +<p>Você pode passar qualquer quantidade de argumentos para esta função, e ela concatena cada argumento na <em>string</em> "list":</p> + +<pre class="brush: 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"); +</pre> + +<div class="note"> +<p>Nota: A variável <code>arguments</code> é "como um array", mas não é um array. Ela é como um array pois possui um índice numerado e a propriedade <code>length</code>. No entanto, não possui todos os métodos de manipulação de array. </p> +</div> + +<p>Veja objeto {{jsxref("Function")}} na referência do JavaScript para maiores informações.</p> + +<h2 id="Function_parameters" name="Function_parameters">Parâmetros de função</h2> + +<p>Começando com ECMAScript 6, há dois tipos novos de parâmetros: parâmetros padrão e parâmetros rest.</p> + +<h3 id="Parâmetros_padrão">Parâmetros padrão</h3> + +<p>Em JavaScript, parâmetros padrões de funções são <code>undefined</code>. No entanto, em algumas situações pode ser útil definir um valor padrão diferente. Isto é onde os parâmetros padrão podem ajudar.</p> + +<p>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 <code>undefined</code>. Se, no exemplo a seguir, nenhum valor é fornecido para <code>b</code> na chamada, seu valor seria <code>undefined</code> ao avaliar <code>a*b</code> e a chamada para <code>multiplicar</code> retornaria <code>NaN</code>. No entanto, isso é pego com a segunda linha neste exemplo:</p> + +<pre class="brush: js"><code>function multiplicar(a, b) { + b = typeof b !== 'undefined' ? b : 1; + + return a*b; +} + +multiplicar(5); // 5</code></pre> + +<p>Com parâmetros padrão, a verificação no corpo da função não é mais necessária. Agora você pode simplesmente colocar <code>1</code> como valor padrão para <code>b</code> no campo de declaração de parâmetros:</p> + +<pre class="brush: js"><code>function multiplicar(a, b = 1) { + return a*b; +} + +multiplicar(5); // 5</code></pre> + +<p>Mais detalhes, consulte <a href="/pt-BR/docs/Web/JavaScript/Reference/Functions/Default_parameters">parâmetros padrão</a> na referência.</p> + +<h3 id="Parâmetros_rest">Parâmetros rest</h3> + +<p>A sintaxe de <a href="/pt-BR/docs/Web/JavaScript/Reference/Functions/rest_parameters">parâmetro rest</a> permite representar um número indefinido de argumentos como um <em>array</em>. No exemplo, usamos parâmetros <em>rest</em> para coletar argumentos do segundo argumento ao último. Então os multiplicamos pelo primeiro argumento. Neste exemplo é usado uma <em>arrow function</em>, que será introduzida na próxima seção.</p> + +<pre class="brush: js"><code>function multiplicar(multiplicador, ...args) { + return args.map(x => multiplicador * x); +} + +var arr = multiplicar(2, 1, 2, 3); +console.log(arr); // [2, 4, 6]</code></pre> + +<h2 id="Arrow_functions" name="Arrow_functions">Funções de seta</h2> + +<p>Uma <a href="/pt-BR/docs/Web/JavaScript/Reference/Functions/Arrow_functions">expressão função de seta</a> (anteriormente conhecida como <strong>função de seta gorda</strong>) tem uma sintaxe pequena em comparação com a expressão de função e lexicalmente vincula o valor <code>this</code>. Funções de seta são sempre anônimas. Consulte também no blog hacks.mozilla.org no post: "<a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">ES6 In Depth: Arrow functions</a>".</p> + +<p>Dois fatores influenciaram a introdução de funções de seta: funções mais curtas e o léxico <code>this</code>.</p> + +<h3 id="Funções_curtas">Funções curtas</h3> + +<p>Em alguns padrões funcionais, funções curtas são bem-vindas. Compare:</p> + +<pre class="brush: js"><code>var a = [ + "Hydrogen", + "Helium", + "Lithium", + "Beryllium" +]; + +var a2 = a.map(function(s){ return s.length }); + +var a3 = a.map( s => s.length );</code></pre> + +<h3 id="Léxico_this">Léxico this</h3> + +<p>Até as funções de seta, cada nova função definia seu próprio valor <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this">this</a> (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.</p> + +<pre class="brush: 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();</pre> + +<p>No ECMAScript 3/5, este problema foi resolvido atribuindo o valor em <code>this</code> a uma variável que poderia ser fechada.</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">Pessoa</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> self <span class="operator token">=</span> <span class="keyword token">this</span><span class="punctuation token">;</span> <span class="comment token">// Alguns preferem 'that' em vez de 'self'. </span> + <span class="comment token">// Escolha um e seja consistente.</span> + self<span class="punctuation token">.</span></code><code>idade </code><code class="language-js"><span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> + + <span class="function token">setInterval</span><span class="punctuation token">(</span><span class="keyword token">function</span> crescer<span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token">// A chamada de retorno refere-se à variável 'self' na qual</span> + <span class="comment token">// o valor é o objeto esperado.</span> + self<span class="punctuation token">.</span></code><code>idade</code><code class="language-js"><span class="operator token">++</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">,</span> <span class="number token">1000</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p>Como alternativa, uma <a href="/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">função vinculada</a> poderia ser criada para que o valor da propriedade <code>this</code> seja passado para a função <code>crescer()</code>.</p> + +<p>Funções de seta capturam o valor <code>this</code> do contexto delimitado, então o código a seguir funciona conforme o esperado.</p> + +<pre><code>function Pessoa(){ + this.idade = 0; + + setInterval(() => { + this.idade++; // propriedade |this|refere ao objeto pessoa + }, 1000); +} + +var p = new Pessoa();</code></pre> + +<h2 id="Funções_pré-definidas">Funções pré-definidas</h2> + +<p>JavaScript tem várias funções pré-definidas:</p> + +<dl> + <dt>{{jsxref("Global_Objects/eval", "eval()")}}</dt> + <dd> + <p>O método <code><strong>eval()</strong></code> avalia código JavaScript representado como uma <em>string</em>.</p> + </dd> + <dt>{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}</dt> + <dd> + <p>O método <code><strong>uneval()</strong></code> cria uma representação de <em>string</em> do código-fonte de um {{jsxref("Object")}}.</p> + </dd> + <dt>{{jsxref("Global_Objects/isFinite", "isFinite()")}}</dt> + <dd> + <p>A função global <code><strong>isFinite()</strong></code> determina se o valor passado é um número finito. Se necessário, o parâmetro é primeiro convertido para um número.</p> + </dd> + <dt>{{jsxref("Global_Objects/isNaN", "isNaN()")}}</dt> + <dd> + <p>A função <code><strong>isNaN()</strong></code> determina se um valor é {{jsxref("Global_Objects/NaN", "NaN")}} ou não. Nota: coerção dentro da função <code>isNaN</code> tem <a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/isNaN#Description">regras interessantes</a>; você pode, alternativamente, querer usar {{jsxref("Number.isNaN()")}}, como definido no ECMAScript 6, ou você pode usar <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof">typeof</a> </code>para determinar se o valor não é um número.</p> + </dd> + <dt>{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}</dt> + <dd> + <p>A função <code><strong>parseFloat()</strong></code> analisa um argumento do tipo <em>string</em> e retorna um número de ponto flutuante.</p> + </dd> + <dt>{{jsxref("Global_Objects/parseInt", "parseInt()")}}</dt> + <dd> + <p>A função <code><strong>parseInt()</strong></code> analisa um argumento do tipo <em>string</em> e retorna um inteiro da base especificada (base do sistema numérico).</p> + </dd> + <dt>{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}</dt> + <dd> + <p>A função <code><strong>decodeURI()</strong></code> decodifica uma <em>Uniform Resource Identifier</em> (URI) criada anteriormente por {{jsxref("Global_Objects/encodeURI", "encodeURI")}} ou por uma rotina similar.</p> + </dd> + <dt>{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}</dt> + <dd> + <p>O método <code><strong>decodeURIComponent()</strong></code> decodifica um componente <em>Uniform Resource Identifier</em> (URI) criado anteriormente por {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} ou por uma rotina similar.</p> + </dd> + <dt>{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}</dt> + <dd> + <p>O método <code><strong>encodeURI()</strong></code> 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").</p> + </dd> + <dt>{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}</dt> + <dd> + <p>O método <code><strong>encodeURIComponent()</strong></code> codifica um componente <em>Uniform Resource Identifier</em> (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").</p> + </dd> + <dt>{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}</dt> + <dd> + <p>O método obsoleto <code><strong>escape()</strong></code> calcula uma nova <em>string</em> na qual certos caracteres foram substituídos por uma sequência de escape hexadecimal. Use {{jsxref("Global_Objects/encodeURI", "encodeURI")}} ou {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} em vez disso.</p> + </dd> + <dt>{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}</dt> + <dd> + <p>O método obsoleto <code><strong>unescape()</strong></code> calcula uma nova <em>string</em> 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 {{jsxref("Global_Objects/escape", "escape")}}. Por <code>unescape()</code> estar obsoleto, use {{jsxref("Global_Objects/decodeURI", "decodeURI()")}} ou {{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} ao invés dele.</p> + </dd> +</dl> + +<p>{{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}</p> diff --git a/files/pt-br/web/javascript/guide/igualdade/index.html b/files/pt-br/web/javascript/guide/igualdade/index.html new file mode 100644 index 0000000000..786c9c257b --- /dev/null +++ b/files/pt-br/web/javascript/guide/igualdade/index.html @@ -0,0 +1,258 @@ +--- +title: Igualdade em JavaScript +slug: Web/JavaScript/Guide/Igualdade +translation_of: Web/JavaScript/Equality_comparisons_and_sameness +--- +<p>A ES6 possui três facilidades internas para determinar se algum <var>x</var> e algum <var>y</var> são "os mesmos". Elas são: igualdade ou "igual duplo" (<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators"><code>==</code></a>), igualdade rigorosa ou "igual triplo" (<a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators"><code>===</code></a>), e <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a>. (Note que <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> foi adicionado na ES6. Ambos igual duplo e igual triplo existiam antes da ES6, e seu comportamento permanece o mesmo.)</p> +<h2 id="Visão_geral">Visão geral</h2> +<p>Para demonstração, aqui estão as três comparações de igualdade em uso:</p> +<pre class="brush:js">x == y</pre> +<pre class="brush:js">x === y</pre> +<pre class="brush:js">Object.is(x, y)</pre> +<p>De modo breve, o operador igual duplo irá realizar uma conversão de tipo na hora de comparar duas coisas; o operador igual triplo fará a mesma comparação sem conversão de tipo (simplesmente sempre retornando <code>false</code> se os tipos forem diferentes); e <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> se comportará da mesma forma que o operador igual triplo, mas lidando de forma especial com <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a> e <code>-0</code> e <code>+0</code> de modo que os dois últimos não são considerados os mesmos, enquanto que <code>Object.is(NaN, NaN)</code> será <code>true</code>. (Comparar <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a> com <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a> geralmente—i.e., usando-se o operador igual duplo ou o operador igual triplo—resulta em <code>false</code>, de acordo com a IEEE 754.)</p> +<p>Note que a distinção entre todas essas formas de comparação tem a ver com a forma com que lidam com primitivos; nenhuma delas compara se os parâmetros são conceitualmente similares em estrutura. Para quaisquer objetos não-primitivos <var>x</var> e <var>y</var> que têm a mesma estrutura mas que são objetos distintos, todas as formas de comparação acima resultarão no valor <code>false</code>.</p> +<p>Por exemplo:</p> +<pre class="brush:js">let x = { value: 17 }; +let y = { value: 17 }; +console.log(Object.is(x, y)); // false; +console.log(x === y); // false +console.log(x == y); // false</pre> +<h2 id="Igualdade_abstrata_igualdade_rigorosa_e_mesmo_valor">Igualdade abstrata, igualdade rigorosa, e mesmo valor</h2> +<p>Na ES5, a comparação realizada por <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators"><code>==</code></a> é descrita na <a href="http://ecma-international.org/ecma-262/5.1/#sec-11.9.3" title="http://ecma-international.org/ecma-262/5.1/#sec-11.9.3">Seção 11.9.3, O Algoritmo de Igualdade Abstrata</a>. A comparação <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators"><code>===</code></a> é descrita em <a href="http://ecma-international.org/ecma-262/5.1/#sec-11.9.6" title="http://ecma-international.org/ecma-262/5.1/#sec-11.9.6">11.9.6, O Algoritmo de Igualdade Rigorosa</a>. (Dê uma olhada nestes. Eles são rápidos e legíveis. Dica: leia o algoritmo de igualdade rigorosa primeiro.) A ES5 também descreve, na <a href="http://ecma-international.org/ecma-262/5.1/#sec-9.12" title="http://ecma-international.org/ecma-262/5.1/#sec-9.12">Seção 9.12, O Algoritmo de MesmoValor</a> para ser usado internamente pelo engine JS. Ele é em sua maioria similar ao Algoritmo de Igualdade Rigorosa, com exceção de que 11.9.6.4 e 9.12.4 diferem na forma de lidar com <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number"><code>Number</code></a>s (números). A ES6 simplesmente propõe expôr esse algoritmo através de <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a>.</p> +<p>Podemos ver que com os operadores igual duplo e igual triplo, com a exceção de fazer uma checagem de tipo de início em 11.9.6.1, o Algoritmo de Igualdade Rigorosa é um subconjunto do Algoritmo de Igualdade Abstrata, pois 11.9.6.2–7 corresponde a 11.9.3.1.a–f.</p> +<h2 id="Um_modelo_para_entender_comparações_de_igualdade">Um modelo para entender comparações de igualdade?</h2> +<p>Antes da ES6, você pode ter dito, a respeito dos operadores igual duplo e igual triplo, que um é uma versão "melhorada" do outro. Por exemplo, alguém poderia dizer que o operador igual duplo é uma versão extendidad do operador igual triplo, pois o primeiro faz tudo que o último faz, com conversão de tipo em seus operandos (por exemplo, de modo que <code>6 == "6"</code>). Alternativamente, alguém poderia dizer que o operador igual triplo é uma versão melhorada do operador igual duplo, pois requer que os dois operandos sejam do mesmo tipo. Qual é melhor depende de qual é a sua idéia de patamar.</p> +<p>No entanto, essa forma de pensar sobre os operados de igualdade internos não é um modelo que pode ser "esticado" para permitir um lugar para o <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> da ES6 nesse "espectro". O <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> não é simplesmente "menos restrito" do que o operador igual duplo ou "mais restrito" do que o operador igual triplo, nem cabe em algum lugar entre esses níveis (isto é, sendo mais restrito que o operador igual duplo, mas menos restrito que o operador igual triplo). Nós podemos ver da tabela de comparações de igualdade abaixo que isto é devido à forma com que <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> lida com <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a>. Perceba que se <code>Object.is(NaN, NaN)</code> resultasse no valor <code>false</code>, nós <em>poderíamos</em> dizer que ele cabe no espectro pouco restrito/restrito como uma forma ainda mais restrita do operador igual triplo, uma que faz distinção entre <code>-0</code> e <code>+0</code>. A forma de lidar com <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a> significa que isso não é verdade, no entanto. Infelizmente, <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> simplesmente deve ser considerado em termos de duas características específicas, ao invés de sua rigorosidade (ou falta da mesma) com respeito aos operadores de igualdade.</p> +<table class="standard-table"> + <caption> + Comparações de Igualdade</caption> + <thead> + <tr> + <th scope="col" style="text-align: center;">x</th> + <th scope="col" style="text-align: center;">y</th> + <th scope="col" style="width: 10em; text-align: center;"><code>==</code></th> + <th scope="col" style="width: 10em; text-align: center;"><code>===</code></th> + <th scope="col" style="width: 10em; text-align: center;"><code>Object.is</code></th> + </tr> + </thead> + <tbody> + <tr> + <td><code>undefined</code></td> + <td><code>undefined</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + </tr> + <tr> + <td><code>null</code></td> + <td><code>null</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + </tr> + <tr> + <td><code>true</code></td> + <td><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + </tr> + <tr> + <td><code>false</code></td> + <td><code>false</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + </tr> + <tr> + <td><code>"foo"</code></td> + <td><code>"foo"</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + </tr> + <tr> + <td><code>{ foo: "bar" }</code></td> + <td><code>x</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + </tr> + <tr> + <td><code>0</code></td> + <td><code>0</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + </tr> + <tr> + <td><code>+0</code></td> + <td><code>-0</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>0</code></td> + <td><code>false</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>""</code></td> + <td><code>false</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>""</code></td> + <td><code>0</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>"0"</code></td> + <td><code>0</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>"17"</code></td> + <td><code>17</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>new String("foo")</code></td> + <td><code>"foo"</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>null</code></td> + <td><code>undefined</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>null</code></td> + <td><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>undefined</code></td> + <td><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>{ foo: "bar" }</code></td> + <td><code>{ foo: "bar" }</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>new String("foo")</code></td> + <td><code>new String("foo")</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>0</code></td> + <td><code>null</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>0</code></td> + <td><code>NaN</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>"foo"</code></td> + <td><code>NaN</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + </tr> + <tr> + <td><code>NaN</code></td> + <td><code>NaN</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(255, 144, 144); text-align: center;"><code>false</code></td> + <td style="background-color: rgb(144, 255, 144); text-align: center;"><code>true</code></td> + </tr> + </tbody> +</table> +<h2 id="Quando_usar_Object.is_versus_o_operador_igual_triplo">Quando usar <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> versus o operador igual triplo</h2> +<p>Além da forma com que trata o valor it <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a>, de modo geral, o único caso em o comportamento especial de <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> com a relação a zeros é capaz de ser de interesse é na busca de certos esquemas de metaprogramação, especialmente em relação a descritores de propriedade quando é desejável que seu trabalho espelhe algumas das características de <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty"><code>Object.defineProperty</code></a>. Se seu caso de uso não requer isso, sugere-se evitar-se <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> e usar-se o operador <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators"><code>===</code></a> ao invés disso. Mesmo se seus requerimentos envolvem que comparações entre dois valores <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a> resultem em <code>true</code>, de modo geral é mais fácil fazer-se uma checagem especial por <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN"><code>NaN</code></a>s (usando-se o método <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN"><code>isNaN</code></a> disponíveis de versões anteritores da ECMAScript) do que lidar com como computações externas possam afetar o sinal de quaisquer zeros que você possa encontrar em sua comparação.</p> +<p>Aqui está uma lista não-exaustiva de métodos e operadores internos que podem fazer com que uma distinção entre <code>-0</code> e <code>+0</code> se manifeste em seu código:</p> +<dl> + <dt> + <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#-_.28Unary_Negation.29" title="/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators"><code>- (negação unária)</code></a></dt> +</dl> +<dl> + <dd> + <p>É óbvio que negar <code>0</code> produz <code>-0</code>. Mas a abstração de uma expressão pode fazer com o valor <code>-0</code> apareça de modo despercebido. Por exemplo, considere o seguinte:</p> + <pre class="brush:js">let stoppingForce = obj.mass * -obj.velocity</pre> + <p>Se <code>obj.velocity</code> é <code>0</code> (ou resulta no valor <code>0</code>), um <code>-0</code> é introduzido naquele ponto e propaga-se para <code>stoppingForce</code>.</p> + </dd> +</dl> +<dl> + <dt> + <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2"><code>Math.atan2</code></a></dt> + <dt> + <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil"><code>Math.ceil</code></a></dt> + <dt> + <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow"><code>Math.pow</code></a></dt> + <dt> + <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round"><code>Math.round</code></a></dt> +</dl> +<dl> + <dd> + É possível que um <code>-0</code> seja introduzido em uma expressão como um valor de retorno desses métodos em alguns casos, mesmo quando nenhum <code>-0</code> existe como um dos parâmetros. Por exemplo, usando-se <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/pow"><code>Math.pow</code></a> para elevar o valor <code>-<a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity">Infinity</a></code> à potência de qualquer expoente negativo ímpar resulta no valor <code>-0</code>. Veja a documentação para os métodos individuais.</dd> +</dl> +<dl> + <dt> + <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor"><code>Math.floor</code></a></dt> + <dt> + <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max"><code>Math.max</code></a></dt> + <dt> + <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min"><code>Math.min</code></a></dt> + <dt> + <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin"><code>Math.sin</code></a></dt> + <dt> + <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt"><code>Math.sqrt</code></a></dt> + <dt> + <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tan" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tan"><code>Math.tan</code></a></dt> +</dl> +<dl> + <dd> + É possível obter-se um valor de retorno <code>-0</code> desses métodos em alguns casos quando um <code>-0</code> existe como um dos parâmetros. Por exemplo, <code>Math.min(-0, +0)</code> resulta no valor <code>-0</code>. Veja a documentação para os métodos individuais.</dd> +</dl> +<dl> + <dt> + <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators">~</a></code></dt> + <dt> + <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators"><<</a></code></dt> + <dt> + <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators" title="/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators">>></a></code></dt> + <dd> + Cada um desses operadores usa o algoritmo ToInt32 internamente. Uma vez que só há uma representação para o valor 0 no tipo inteiro de 32 bits interno, o valor <code>-0</code> não irá sobreviver a um arredondamento depois de uma operação inversa. Por exemplo, ambos <code>Object.is(~~(-0), -0)</code> e <code>Object.is(-0 << 2 >> 2, -0)</code> resultam no valor <code>false</code>.</dd> +</dl> +<p>Contar com <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is"><code>Object.is</code></a> quando o sinal de zeros não é levado em consideração pode ser problemático. É claro que quando a intenção é distinguir entre <code>-0</code> e <code>+0</code>, ele faz exatamente o que é desejado.gual</p> diff --git a/files/pt-br/web/javascript/guide/index.html b/files/pt-br/web/javascript/guide/index.html new file mode 100644 index 0000000000..c781f61e0d --- /dev/null +++ b/files/pt-br/web/javascript/guide/index.html @@ -0,0 +1,127 @@ +--- +title: Guia JavaScript +slug: Web/JavaScript/Guide +tags: + - Guia Javascript + - JavaScript +translation_of: Web/JavaScript/Guide +--- +<div>{{jsSidebar("JavaScript Guide")}}</div> + +<p class="summary">O Guia JavaScript mostra como usar <a href="/pt-BR/docs/Web/JavaScript">JavaScript</a> e dá uma visão geral da linguagem. Se você quer começar com JavaScript ou programação em geral, consulte os artigos na <a href="/pt-BR/docs/Aprender/JavaScript">área de aprendizagem</a>. Se você precisar de informações mais aprofundadas sobre algum recurso da linguagem, consulte a <a href="/pt-BR/docs/Web/JavaScript/Reference">referência JavaScript</a>.</p> + +<h2 id="Capítulos">Capítulos</h2> + +<p>Este guia está dividido em vários capítulos:</p> + +<ul class="card-grid"> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Introduction">Introdução</a></span> + + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Introduction#Onde_encontrar_informações_sobre_JavaScript">Sobre este guia</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Introduction#O_que_é_JavaScript">Sobre JavaScript</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Introduction#JavaScript_and_Java">JavaScript e Java</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Introduction#JavaScript_and_the_ECMAScript_Specification">ECMAScript</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Introduction#Getting_started_with_JavaScript">Ferramentas</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Introduction#Hello_world">Olá Mundo</a></p> + </li> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Values%2C_variables%2C_and_literals">Sintaxe e tipos</a></span> + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Values%2C_variables%2C_and_literals#Basics">Sintaxe básica e comentários</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Values%2C_variables%2C_and_literals#Declarations">Declarações</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Values%2C_variables%2C_and_literals#Variable_scope">Escopo de variável</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Values%2C_variables%2C_and_literals#Variable_hoisting">Hoisting</a> <br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Values%2C_variables%2C_and_literals#Data_structures_and_types">Estruturas de dados e Tipos</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Values%2C_variables%2C_and_literals#Literals">Literais</a></p> + </li> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Declarações">Controle de fluxo e manipulação de erro</a></span> + <p><code><a href="/pt-BR/docs/Web/JavaScript/Guide/Declarações#if...else_statement">if...else</a></code><br> + <code><a href="/pt-BR/docs/Web/JavaScript/Guide/Declarações#switch_statement">switch</a></code><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Declarações#Exception_handling_statements"><code>try</code>/<code>catch</code>/<code>throw</code></a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Declarações#Utilizing_Error_objects">Objetos de erro</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Declarações#Promises">Promises</a></p> + </li> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Lacos_e_iteracoes">Laços e iteração</a></span> + <p><code><a href="/pt-BR/docs/Web/JavaScript/Guide/Lacos_e_iteracoes#for_statement">for</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Lacos_e_iteracoes#while_statement">while</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Lacos_e_iteracoes#do...while_statement">do...while</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Lacos_e_iteracoes#break_statement">break</a>/<a href="/pt-BR/docs/Web/JavaScript/Guide/Lacos_e_iteracoes#continue_statement">continue</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Lacos_e_iteracoes#for...in_statement">for..in</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Lacos_e_iteracoes#for...of_statement">for..of</a></code></p> + </li> +</ul> + +<ul class="card-grid"> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Funções">Funções</a></span> + + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Funções#Defining_functions">Definição de funções</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Funções#Calling_functions">Chamando funções</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Funções#Function_scope">Escopo da função</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Funções#Closures">Closures</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Funções#Using_the_arguments_object">Argumentos</a> & <a href="/pt-BR/docs/Web/JavaScript/Guide/Funções#Function_parameters">parâmetros</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Funções#Arrow_functions">Funções de seta</a></p> + </li> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators">Expressões e operadores</a></span> + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment_operators">Atribuição</a> & <a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#Comparison_operators">comparações</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#Arithmetic_operators">Operadores aritméticos</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators">Operadores lógicos</a> & <a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#Logical_operators">bit a bit</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators#Conditional_(ternary)_operator">Operador condicional (Ternário)</a></p> + </li> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Numeros_e_datas">Números e datas</a></span><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Numeros_e_datas#Numbers">Números</a> + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Numeros_e_datas#Number_object">Objeto de números</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Numeros_e_datas#Math_object">Objeto Math</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Numeros_e_datas#Date_object">Objeto Data</a></p> + </li> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Formatando_texto">Formatação de texto</a></span> + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Formatando_texto#String_literals">Strings</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Formatando_texto#String_objects">Objetos de strings</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Formatando_texto#Multi-line_template_strings">Modelos de strings</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Formatando_texto#Internationalization">Internacionalização</a></p> + </li> +</ul> + +<ul class="card-grid"> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Regular_Expressions">Expressões Regular</a></span> + + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Regular_Expressions#criando_expressao_regular">Criando uma expressão regular</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Regular_Expressions#escrita_expressao_regular">Padrão de escrita de uma expressão regular</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Regular_Expressions#trabalhando_expressao_regular">Trabalhando com expressões regular</a></p> + </li> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Indexed_collections">Coleções Indexadas</a></span> + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Indexed_collections#Array_object">Arrays</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Indexed_collections#Typed_Arrays">Arrays digitados</a></p> + </li> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Keyed_collections">Coleções Chaveadas</a></span> + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Keyed_collections#Map_object">Maps</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Keyed_collections#WeakMap_object">WeakMaps</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Keyed_collections#Set_object">Set</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Keyed_collections#WeakSet_object">WeakSet</a></p> + </li> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Working_with_Objects">Trabalhando com objetos</a></span> + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties">Objetos e propriedades</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Working_with_Objects#Creating_new_objects">Criando Objetos</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_methods">Definindo Métodos</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters">Getter e setter</a></p> + </li> +</ul> + +<ul class="card-grid"> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Details_of_the_Object_Model">Detalhes do modelo de objetos</a></span> + + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Class-based_vs._prototype-based_languages">POO baseada na prototipagem</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Creating_the_hierarchy">Criando hierarquias de objetos</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Property_inheritance_revisited">Herança</a></p> + </li> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Iterators_and_Generators">Iteradores e geradores</a></span> + <p><a href="/pt-BR/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterators">Iterators</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterables">Iterables</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Iterators_and_Generators#Generators">Generators</a></p> + </li> + <li><span><a href="/pt-BR/docs/Web/JavaScript/Guide/Meta_programming">Meta programação</a></span> + <p><code><a href="/pt-BR/docs/Web/JavaScript/Guide/Meta_programming#Proxies">Proxy</a></code><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Meta_programming#Handlers_and_traps">Handlers e traps</a><br> + <a href="/pt-BR/docs/Web/JavaScript/Guide/Meta_programming#Revocable_Proxy">Proxy revogável</a><br> + <code><a href="/pt-BR/docs/Web/JavaScript/Guide/Meta_programming#Reflection">Refletor</a></code></p> + </li> +</ul> + +<p>{{Next("Web/JavaScript/Guide/Introduction")}}</p> diff --git a/files/pt-br/web/javascript/guide/indexed_collections/index.html b/files/pt-br/web/javascript/guide/indexed_collections/index.html new file mode 100644 index 0000000000..5e9cea67f9 --- /dev/null +++ b/files/pt-br/web/javascript/guide/indexed_collections/index.html @@ -0,0 +1,452 @@ +--- +title: Coleções Indexadas +slug: Web/JavaScript/Guide/Indexed_collections +tags: + - Guia(2) + - JavaScript + - metodo +translation_of: Web/JavaScript/Guide/Indexed_collections +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Keyed_Collections")}}</div> + +<p class="summary">Este capítulo introduz coleções de dados que são ordenados por um valor indexado. Isso inclui construtores de arrays e array-like como objetos {{jsxref("Array")}} e {{jsxref("TypedArray")}}.</p> + +<h2 id="Objeto_Array">Objeto <code>Array</code></h2> + +<p>Um array é um conjunto de valores ordenados que você o referencia com um nome e um índice. Por exemplo, você pode ter um array chamado <code>emp</code> que contém nomes de funcionários indexados por seus números de funcionários. Então <code>emp[1]</code> poderia ser o funcionário número 1, <code>emp[2]</code> o funcionário número 2 e assim por diante.</p> + +<p>JavaScript não possui um tipo de dados array específico. No entanto, você pode usar o objeto predefinido <code>Array</code> e seus métodos para trabalhar com arrays em suas aplicações. O objeto <code>Array</code> tem métodos para manipular arrays de várias maneiras como join, reverse e sort. Ele tem uma propriedade para determinar o tamanho do array e outras propriedades para usar com expressões regulares.</p> + +<h3 id="Criando_um_array">Criando um array</h3> + +<p>As declarações a seguir criam arrays equivalentes:</p> + +<pre class="brush: js notranslate">var arr = new Array(elemento0, elemento1, ..., elementoN); +var arr = Array(elemento0, elemento1, ..., elementoN); +var arr = [elemento0, elemento1, ..., elementoN]; +</pre> + +<p><code>elemento0, elemento1, ..., elementoN</code> é uma lista de valores para os elementos do array. Quando esses valores são especificados, o array é inicializado com eles como elementos deste array. A propriedade do comprimento do array é definida pelo número de argumentos.</p> + +<p>A sintaxe dos colchetes é chamada de "array literal" ou "inicializador de array". É uma abreviação de outras formas de criação de array e é a forma preferida de criação. Veja <a href="/pt-BR/docs/Web/JavaScript/Guide/Grammar_and_types#Array_literal">Array literal</a> para detalhes.</p> + +<p>Para criar um array com tamanho diferente de zero mas sem nenhum item, qualquer esquema abaixo pode ser utilizado:</p> + +<pre class="brush: js notranslate">var arr = new Array(comprimentoDoArray); +var arr = Array(comprimentoDoArray); + +// Estes produzem exatamente o mesmo efeito +var arr = []; +arr.length = comprimentoDoArray; +</pre> + +<div class="note"> +<p><strong>Nota :</strong> No código acima, <code>comprimentoDoArray</code> deve ser um <code>Número</code>. De outra maneira, um array com um único elemento (o valor passado) será criado. Chamar <code>arr.length</code> retornará <code>comprimentoDoArray</code>, mas o array na verdade, contem elementos vazios (undefined). Executar um loop {{jsxref("Statements/for...in","for...in")}} no array, não retornará nenhum dos elementos do array.</p> +</div> + +<p>Além de poderem ser definidos como uma nova variável, como mostrado acima, arrays também podem ser atribuídos como uma propriedade de um novo objeto, ou de um objeto existente:</p> + +<pre class="brush: js notranslate">var obj = {}; +// ... +obj.prop = [elemento0, elemento1, ..., elementoN]; + +// OU +var obj = {prop: [elemento0, elemento1, ...., elementoN]} +</pre> + +<p>Se você deseja inicializar um array com um único elemento, e este elemento é um <code>Número</code>, você precisa usar a sintáxe dos colchetes. Quando um único valor de <code>Número</code> é passado para o construtor do Array(), ou para uma função, ele é interpretado como um <code>comprimentoDoArray</code>, e não como um elemento único.</p> + +<pre class="brush: js notranslate">var arr = [42]; // Cria um array com apenas um elemento: + // o número 42. + +var arr = Array(42); // Cria um array sem elementos + // e arr.length é definido como 42; isso é + // equivalente a: +var arr = []; +arr.length = 42; +</pre> + +<p>Chamar <code>Array(N)</code> resulta em um <code>RangeError</code>, se <code>N</code> é um número não inteiro cuja porção fracionária não é zero. O exemplo a seguir ilustra esse comportamento.</p> + +<pre class="brush: js notranslate">var arr = Array(9.3); // RangeError: Invalid array length +</pre> + +<p>Se o seu código precisa criar arrays com elementos singulares de um tipo de dados arbitrário, é mais seguro usar arrays literais. Ou então, crie um array vazio antes de adicionar um elemento singular nele.</p> + +<h3 id="Povoando_um_array">Povoando um array</h3> + +<p>Você pode povoar (inserir elementos) a um array atribuindo valores aos seus elementos. Por exemplo:</p> + +<pre class="brush: js notranslate">var emp = []; +emp[0] = 'Casey Jones'; +emp[1] = 'Phil Lesh'; +emp[2] = 'August West'; +</pre> + +<div class="note"> +<p><strong>Nota :</strong> se você fornece um valor não inteiro ao operador do array, como no código acima, a propriedade será criada no objeto representando o array, ao invés do elemento do array.</p> +</div> + +<pre class="brush: js notranslate">var arr = []; +arr[3.4] = 'Oranges'; +console.log(arr.length); // 0 +console.log(arr.hasOwnProperty(3.4)); // verdadeiro +</pre> + +<p>Você também pode povoar o array quando o cria:</p> + +<pre class="brush: js notranslate">var myArray = new Array('Olá', myVar, 3.14159); +var myArray = ['Manga', 'Maçã', 'Laranja'] +</pre> + +<h3 id="Referenciando_os_elementos_do_array">Referenciando os elementos do array</h3> + +<p>Você referencia os elementos do array através do uso de elementos numéricos ordinais. Por exemplo, suponha que você definiu o seguinte array:</p> + +<pre class="brush: js notranslate">var myArray = ['Vento', 'Chuva', 'Fogo']; +</pre> + +<p>Você então se refere ao primeiro elemento do array como em <code>myArray[0]</code> e ao segundo elemento do array como em <code>myArray[1]</code>. O índice do elemento começa com zero.</p> + +<div class="note"> +<p><strong>Nota :</strong> o operador do array (colchetes) também é usado para acessar as propriedades do array (arrays também são objetos em JavaScript). Por exemplo,</p> +</div> + +<pre class="brush: js notranslate">var arr = ['um', 'dois', 'três']; +arr[2]; // três +arr['length']; // 3 +</pre> + +<h3 id="Compreendendo_o_comprimento">Compreendendo o comprimento</h3> + +<p>Sobe o ponto de vista da implementação, arrays JavaScript armazenam na realidade elementos como propriedades de objetos padrões, usando o índice do array como o nome da propriedade. O comprimento da propriedade é especial: ele sempre retorna o índice do último mais um (no exemplo seguinte Dusty é indexado no 30, então cats.length retorna 30 + 1). Lembre-se, índices de arrays JavaScript são baseados no zero: eles começam no 0, não no 1. Isso significa que o comprimento da propriedade será um a mais que o maior índice armazenado no array:</p> + +<pre class="brush: js notranslate">var gatos = []; +gatos[30] = ['Dusty']; +console.log(gatos.length); // 31 +</pre> + +<p>Você também pode atribuir um valor à propriedade <code>length</code>. Ao escrever um valor menor que o número de itens armazenados, trunca o array: escrevendo zero limpa-o completamente:</p> + +<pre class="brush: js notranslate">var gatos = ['Dusty', 'Misty', 'Twiggy']; +console.log(gatos.length); // 3 + +gatos.length = 2; +console.log(gatos); // mostra "Dusty, Misty" - Twiggy foi removido + +gatos.length = 0; +console.log(gatos); // nada é apresentado; o array gatos está vazio + +gatos.length = 3; +console.log(gatos); // [undefined, undefined, undefined] +</pre> + +<h3 id="Iteração_em_arrays">Iteração em arrays</h3> + +<p>Uma operação comum é a de iterar sobre os valores de um array, processando cada elemento de alguma maneira. A maneira mais simples para fazer isso é como segue:</p> + +<pre class="brush: js notranslate">var cores = ['vermelho', 'verde', 'azul']; +for (var i = 0; i < cores.length; i++) { + console.log(cores[i]); +} +</pre> + +<p>Se você sabe que nenhum dos elemnetos no seu array é avaliado como <code>false</code> em um contexto booleano — se o seu array consiste apenas de nodos do <a href="/pt-BR/docs/DOM/Referencia_do_DOM" title="en-US/docs/DOM">DOM</a>, como exemplo, você pode usar um idioma mais eficiente:</p> + +<pre class="brush: js notranslate">var divs = document.getElementsByTagName('div'); +for (var i = 0, div; div = divs[i]; i++) { + /* Processa div de alguma forma */ +} +</pre> + +<p>Isso evita a sobrecarga da checagem do comprimento do array, e garante que a variável div seja reatribuida ao item atual cada vez que o loop for adicionado por conveniência.</p> + +<p>O método {{jsxref("Array.forEach", "forEach()")}} disponibiliza um outro jeito de iterar sobre/em um array:</p> + +<pre class="brush: js notranslate">var cores = ['vermelho', 'verde', 'azul']; +cores.forEach(function(cor) { + console.log(cor); +}); +// vermelho +// verde +// azul +</pre> + +<p>Alternativamente, você pode encurtar o código para o parâmetro do <code>forEach</code> com Arrow Functions ES6.</p> + +<pre class="notranslate"><code>var cores = ['vermelho', 'verde', 'azul']; +cores.forEach(cor => console.log(cor)); +// vermelho +// verde +// azul</code></pre> + +<p>A função passada para o <code>forEach</code> é executada uma vez para cada item no array, com o item do array passado como o argumento para a função. Valores não atribuídos não são iterados no loop <code>forEach</code>.</p> + +<p>Note que os elementos de um array que foram omitidos quando o array foi definido, não são listados quando iterados pelo <code>forEach</code>, mas são listados quando <code>undefined</code> foi manualmente atribuído ao elemento:</p> + +<pre class="brush: js notranslate">var array = ['primeiro', 'segundo', , 'quarto']; + +array.forEach(function(elemento) { + console.log(elemento); +}) +// primeiro +// segundo +// quarto + +if (array[2] === undefined) { + console.log('array[2] is undefined'); // verdadeiro +} + +array = ['primeiro', 'segundo', undefined, 'quarto']; + +array.forEach(function(elemento) { + console.log(elemento); +}); +// primeiro +// segundo +// undefined +// quarto</pre> + +<p>Como elementos JavaScript são salvos como propriedades de objetos padronizados, não é aconselhável iterar sobre arrays JavaScript usando loops {{jsxref("Statements/for...in","for...in")}}, porque elementos normais e todas as propriedades numeráveis serão listadas.</p> + +<h3 id="Métodos_dos_arrays">Métodos dos arrays</h3> + +<p>O objeto {{jsxref("Array")}} possui os seguintes métodos:</p> + +<p>{{jsxref("Array.concat", "concat()")}} une dois arrays e retorna um novo array.</p> + +<pre class="brush: js notranslate">var myArray = new Array('1', '2', '3'); +myArray = myArray.concat('a', 'b', 'c'); +// myArray agora é ["1", "2", "3", "a", "b", "c"] +</pre> + +<p>{{jsxref("Array.join", "join(deliminator = ',')")}} une todos os elementos de um array dentro de um string.</p> + +<pre class="brush: js notranslate">var myArray = new Array('Vento', 'Chuva', 'Fogo'); +var lista = myArray.join(' - '); // lista é "Vento - Chuva - Fogo" +</pre> + +<p>{{jsxref("Array.push", "push()")}} adiciona um ou mais elementos no fim de um array e retorna o comprimento resultante do array.</p> + +<pre class="brush: js notranslate">var myArray = new Array('1', '2'); +myArray.push('3'); // myArray é agora ["1", "2", "3"] +</pre> + +<p>{{jsxref("Array.pop", "pop()")}} remove o último elemento de um array e retorna esse elemento.</p> + +<pre class="brush: js notranslate">var myArray = new Array('1', '2', '3'); +var ultimo = myArray.pop(); +// myArray é agora ["1", "2"], ultimo = "3" +</pre> + +<p>{{jsxref("Array.shift", "shift()")}} remove o primeiro elemento de um array e retorna esse elemento.</p> + +<pre class="brush: js notranslate">var myArray = new Array('1', '2', '3'); +var primeiro = myArray.shift(); +// myArray agora é ["2", "3"], primeiro é "1" +</pre> + +<p>{{jsxref("Array.unshift", "unshift()")}} adiciona um ou mais elementos ao início do array e retorna o novo comprimento do array.</p> + +<pre class="brush: js notranslate">var myArray = new Array('1', '2', '3'); +myArray.unshift('4', '5'); +// myArray torna-se ["4", "5", "1", "2", "3"]</pre> + +<p>{{jsxref("Array.slice", "slice(start_index, upto_index)")}} extrai uma seção de um array e retorna um novo array.</p> + +<pre class="brush: js notranslate">var myArray = new Array('a', 'b', 'c', 'd', 'e'); +myArray = myArray.slice(1, 4); // inicia no índice 1 e extrai todos os elementos + // até o índice 3, retornado [ "b", "c", "d"] +</pre> + +<p>{{jsxref("Array.splice", "splice(index, count_to_remove, addElement1, addElement2, ...)")}} remove elementos de um array e (opcionalmente) o substitui, e retorna os itens que foram removidos do array.</p> + +<pre class="brush: js notranslate">var myArray = new Array('1', '2', '3', '4', '5'); +myArray.splice(1, 3, 'a', 'b', 'c', 'd'); +// myArray é agora ["1", "a", "b", "c", "d", "5"] +// Este código iniciou no índice um (ou onde o "2" estava), +// removeu 3 elementos a partir dali, e então inseriu todos os elementos +// consecutivos em seus lugares. +</pre> + +<p>{{jsxref("Array.reverse", "reverse()")}} transpõe (inverte) os elementos de um array, <em>in situ</em>: o primeiro elemento do array se torna o último e o último torna-se o primeiro, e retorna uma referência para o array.</p> + +<pre class="brush: js notranslate">var myArray = new Array('1', '2', '3'); +myArray.reverse(); +// transpõe o array de modo que myArray = [ "3", "2", "1" ] +</pre> + +<p>{{jsxref("Array.sort", "sort()")}} ordena os elementos de um array <em>in situ</em>, e retorna uma referência para o array.</p> + +<pre class="brush: js notranslate">var myArray = new Array('Neve', 'Chuva', 'Fogo'); +myArray.sort(); +// ordena o array de modo que myArray = [ "Chuva", "Fogo", "Neve" ] +</pre> + +<p><code>sort()</code> também pode 'pegar' uma função callback para determinar como os elementos do array são comparados.</p> + +<p>O método sort, assim como outros métodos abaixo que tomam um callback são conhecidos como <em>métodos iterativos</em>, porque eles iteram sobre o array de alguma forma. Cada um pega um segundo argumento opcional chamado <code>thisObject</code>. Se fornecido, <code>thisObject</code> se torna o valor da palavra chave <code>this</code> dentro do corpo da função callback. Se não fornecido, como em outros casos onde uma função é invocada fora do contexto explícito de um objeto, <code>this</code> fará referência ao objeto global ({{domxref("window")}}).</p> + +<p>A função callback é na verdade chamada com três argumentos. O primeiro é o valor do item corrente, o segundo é o índice do array e o terceiro é uma referência ao próprio array. Funções javaScript ignoram qualquer argumento que não são nomeados na lista de parâmetros, portanto é seguro prover uma função callback que toma somente um único argumento, como a função <code>alert</code>.</p> + +<p>A função abaixo compara dois valores e retorna um dos tres valores: -1, 0 ou 1.</p> + +<p>Por exemplo, o seguinte trecho de código vai ordenar pela última letra da string:</p> + +<pre class="brush: js notranslate">var sortFn = function(a, b){ + if (a[a.length - 1] < b[b.length - 1]) return -1; + if (a[a.length - 1] > b[b.length - 1]) return 1; + if (a[a.length - 1] == b[b.length - 1]) return 0; +} +myArray.sort(sortFn); +// ordena o array de modo que myArray = ["Chuva","Neve","Fogo"]</pre> + +<ul> + <li>se <code>a</code> for menor que <code>b</code> pelo sistema de ordenação, retorna -1 (ou qualquer número negativo)</li> + <li>se <code>a</code> for maior que <code>b</code> pelo sistema de ordenação, retorna 1 (ou qualquer número positivo)</li> + <li>se <code>a</code> e <code>b</code> forem considerados equivalentes, returnará 0.</li> +</ul> + +<p>{{jsxref("Array.indexOf", "indexOf(searchElement[, fromIndex])")}} busca <code>searchElement</code> no array e retorna o índice da primeira ocorrência.</p> + +<pre class="brush: js notranslate">var a = ['a', 'b', 'a', 'b', 'a']; +console.log(a.indexOf('b')); // mostra 1 +// Agora tente novamente, iniciando após o último resultado de busca +console.log(a.indexOf('b', 2)); // mostra 3 +console.log(a.indexOf('z')); // mostra -1, porque 'z' não foi encontrado +</pre> + +<p>{{jsxref("Array.lastIndexOf", "lastIndexOf(searchElement[, fromIndex])")}} funciona como <code>indexOf</code>, mas começa no fim e busca de trás para a frente.</p> + +<pre class="brush: js notranslate">var a = ['a', 'b', 'c', 'd', 'a', 'b']; +console.log(a.lastIndexOf('b')); // mostra 5 +// Agora tente novamente, iniciando antes do último resultado de busca +console.log(a.lastIndexOf('b', 4)); // mostra 1 +console.log(a.lastIndexOf('z')); // mostra -1 +</pre> + +<p>{{jsxref("Array.forEach", "forEach(callback[, thisObject])")}} executa um <code>callback</code> em cada item do array e retorna undefined.</p> + +<pre class="brush: js notranslate">var a = ['a', 'b', 'c']; +a.forEach(function(element) { console.log(elemento); }); +// mostra cada item por vez +</pre> + +<p>{{jsxref("Array.map", "map(callback[, thisObject])")}} retorna um novo array do valor retornado da execução do callback em cada item do array.</p> + +<pre class="brush: js notranslate">var a1 = ['a', 'b', 'c']; +var a2 = a1.map(function(item) { return item.toUpperCase(); }); +console.log(a2); // logs ['A', 'B', 'C'] +</pre> + +<p>{{jsxref("Array.filter", "filter(callback[, thisObject])")}} retorna um novo array contendo os items verdadeiros ao executar o callback.</p> + +<pre class="brush: js notranslate">var a1 = ['a', 10, 'b', 20, 'c', 30]; +var a2 = a1.filter(function(item) { return typeof item === 'number'; }); +console.log(a2); // mostra [10, 20, 30] +</pre> + +<p>{{jsxref("Array.every", "every(callback[, thisObject])")}} retorna verdadeiro se o <code>callback</code> retornar verdadeiro para cada item no array.</p> + +<pre class="brush: js notranslate">function isNumber(valor) { + return typeof valor === 'number'; +} +var a1 = [1, 2, 3]; +console.log(a1.every(isNumber)); // mostra true +var a2 = [1, '2', 3]; +console.log(a2.every(isNumber)); // mostra false +</pre> + +<p>{{jsxref("Array.some", "some(callback[, thisObject])")}} retorna verdadeiro se o <code>callback</code> retornar verdadeiro para pelo menos um item no array.</p> + +<pre class="brush: js notranslate">function isNumber(valor) { + return typeof valor === 'number'; +} +var a1 = [1, 2, 3]; +console.log(a1.some(isNumber)); // mostra true +var a2 = [1, '2', 3]; +console.log(a2.some(isNumber)); // mostra true +var a3 = ['1', '2', '3']; +console.log(a3.some(isNumber)); // mostra false +</pre> + +<p>{{jsxref("Array.reduce", "reduce(callback[, initialValue])")}} aplica <code>callback(firstValue, secondValue)</code> para reduzir a lista de itens para um único valor e retorna este valor.</p> + +<pre class="brush: js notranslate">var a = [10, 20, 30]; +var total = a.reduce(function(primeiro, segundo) { return primeiro + segundo; }, 0); +console.log(total) // mostra 60 +</pre> + +<p>{{jsxref("Array.reduceRight", "reduceRight(callback[, initalvalue])")}} funciona como <code>reduce()</code>, mas inicia com o último elemento.</p> + +<p><code>reduce</code> e <code>reduceRight</code> são os métodos iterativos menos óbvios dos arrays. Eles devem ser usados para algorítmos que combinam dois valores de maneira recursiva com a finalidade de reduzir uma sequência para um único valor.</p> + +<h3 id="Arrays_multidimensionais">Arrays multidimensionais</h3> + +<p>Arrays podem ser aninhados, significando que um array pode conter outro array como seu elemento. Usando essa característica dos arrays JavaScript, arrays multidimensionais pode ser criados.</p> + +<p>O código a seguir cria dois arrays multidimensionais:</p> + +<pre class="brush: js notranslate">var a = new Array(4); +for (i = 0; i < 4; i++) { + a[i] = new Array(4); + for (j = 0; j < 4; j++) { + a[i][j] = '[' + i + ',' + j + ']'; + } +} +</pre> + +<p>Esse exemplo cria um array com as seguintes linhas:</p> + +<pre class="notranslate">Linha 0: [0,0] [0,1] [0,2] [0,3] +Linha 1: [1,0] [1,1] [1,2] [1,3] +Linha 2: [2,0] [2,1] [2,2] [2,3] +Linha 3: [3,0] [3,1] [3,2] [3,3] +</pre> + +<h3 id="Arrays_e_expressões_regulares">Arrays e expressões regulares</h3> + +<p>Quando um array é o resultado de uma equivalência entre uma expressão regular e um string, o array retorna propriedades e elementos que disponibilizam a informação sobre a correspondência. Um array é o valor retornado de {{jsxref("Global_Objects/RegExp/exec","RegExp.exec()")}}, {{jsxref("Global_Objects/String/match","String.match()")}}, e {{jsxref("Global_Objects/String/split","String.split()")}}. Para informações sobre o uso de arrays com expressões regulares, veja <a href="/pt-BR/docs/Web/JavaScript/Guide/Regular_Expressions">Expressões Regulares</a>.</p> + +<h3 id="Trabalhando_com_objetos_array-like">Trabalhando com objetos array-like</h3> + +<p>Alguns objetos JavaScript, como a {{domxref("NodeList")}} retornada pelo {{domxref("document.getElementsByTagName()")}} ou o objeto acessível dentro do {{jsxref("Functions/arguments","arguments")}} de uma função, se parecem e se comportam superficialmente como arrays, mas não compartilham de todos os seus métodos. O objeto <code>arguments</code> fornece um atributo {{jsxref("Global_Objects/Function/length","length")}} mas não implementa o método {{jsxref("Array.forEach", "forEach()")}}, por exemplo.</p> + +<p>Métodos Array prototype podem ser chamados contra outros objetos array-like. Por exemplo:</p> + +<pre class="brush: js notranslate">function printArguments() { + Array.prototype.forEach.call(arguments, function(item) { + console.log(item); + }); +} +</pre> + +<p>Métodos Array prototype também podem ser usados em strings, desde que eles forneçam acesso sequencial a seus caracteres de maneira similar às arrays:</p> + +<pre class="brush: js notranslate">Array.prototype.forEach.call('uma string', function(chr) { + console.log(chr); +});</pre> + +<h2 id="Arrays_Tipados">Arrays Tipados</h2> + +<p><a href="/pt-BR/docs/Web/JavaScript/Typed_arrays">Arrays tipados no JavaScript</a> são objetos array-like e provêm um mecanismo para acessar dados binários crus. Como você já sabe, objetos {{jsxref("Array")}} crescem e encolhem dinamicamente e podem ter um valor JavaScript. O motor do JavaScript executa otimizações para que os arrays sejam rápidos. Contudo, à medida que as aplicações web se tornam cada vez mais poderosas, com a adição de funcionalidades como manipulação de áudio e vídeo, acesso a dados crus usando <a href="/pt-BR/docs/WebSockets">WebSockets</a>, etc., ficou claro que existem momentos em que seria útil para o código JavaScript ser capaz de rapida e facilmente manipular dados binários crus em arrays tipados.</p> + +<h3 id="Buffers_e_views_arquitetura_do_array_tipado">Buffers e views: arquitetura do array tipado</h3> + +<p>Para alcançar máxima flexibilidade e eficiência, as views de array tipado do JavaScript dividem a implementação em <strong>buffers</strong> e <strong>views.</strong> Um buffer (implementado pelo objeto {{jsxref("ArrayBuffer")}}) é um objeto que representa um monte de dados; não possui nenhum formato específico e não oferece nenhum mecanismo para acessar seu conteúdo. Para acessar a memória contida em um buffer, você precisa usar uma view. Uma view provê um contexto — ou seja, um tipo de dado, um offset inicial e número de elementos — que transforma o dado em um array tipado real.</p> + +<p><img alt="Typed arrays in an ArrayBuffer" src="https://mdn.mozillademos.org/files/8629/typed_arrays.png" style="height: 278px; width: 666px;"></p> + +<h3 id="ArrayBuffer">ArrayBuffer</h3> + +<p>O {{jsxref("ArrayBuffer")}} é um tipo de dado usado para representar um buffer de dados binários de tamanho fixo genérico. Você não pode manipular diretamente o conteúdo de um <code>ArrayBuffer;</code> ao invés disso, você deve criar uma view de array tipado ou uma {{jsxref("DataView")}} que represente o buffer em um formato específico, e use esta view para ler e modificar o conteúdo do buffer.</p> + +<h3 id="Views_de_arrays_tipados">Views de arrays tipados</h3> + +<p>Views de arrays tipados possuem nomes autodescritivos e provêm views para todos os tipos numéricos usuais como <code>Int8</code>, <code>Uint32</code>, <code>Float64</code> e assim por diante. Existe uma view de array tipado especial, o <code>Uint8ClampedArray</code>. Ela fixa os valores entre 0 e 255. Isto é útil para <a href="/en-US/docs/Web/API/ImageData">Canvas data processing</a>, por exemplo.</p> + +<p>{{page("/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray", "TypedArray_objects")}}</p> + +<p>Para mais informações, veja <a href="/pt-BR/docs/Web/JavaScript/Typed_arrays">Arrays tipados no JavaScript</a> e documentos de referência para os diferentes objetos {{jsxref("TypedArray")}}.</p> + +<p>{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Keyed_Collections")}}</p> diff --git a/files/pt-br/web/javascript/guide/inheritance_and_the_prototype_chain/index.html b/files/pt-br/web/javascript/guide/inheritance_and_the_prototype_chain/index.html new file mode 100644 index 0000000000..d6aad53066 --- /dev/null +++ b/files/pt-br/web/javascript/guide/inheritance_and_the_prototype_chain/index.html @@ -0,0 +1,193 @@ +--- +title: Herança e cadeia de protótipos (prototype chain) +slug: Web/JavaScript/Guide/Inheritance_and_the_prototype_chain +tags: + - herança intermediário JavaScript OOP +translation_of: Web/JavaScript/Inheritance_and_the_prototype_chain +--- +<div>{{jsSidebar("Advanced")}}</div> + +<p>JavaScript é um pouco confuso para desenvolvedores com experiência em linguagens baseadas em classes (como Java ou C++), porque é dinâmico e não dispõe de uma implementação de uma <code>class</code> (a palavra-chave <code>class</code> foi introduzida no ES2015, mas é syntax sugar, o JavaScript permanece baseado em <code>prototype</code>).</p> + +<p>Quando se trata de herança, o JavaScript tem somente um construtor: objetos. Cada objeto tem um link interno para um outro objeto chamado <code>prototype</code>. Esse objeto <code>prototype</code> também tem um atributo <code>prototype</code>, e assim por diante até o que o valor <code>null</code> seja encontrado como sendo o seu <code>prototype</code>. <code>null</code> que, por definição, não tem <code>prototype</code>, e age como um link final nesta <strong>cadeia de protótipos</strong> (prototype chain).</p> + +<p><span id="result_box" lang="pt">Isto<span class="hps"> muitas vezes é</span> <span class="hps">considerado como</span> <span class="hps">um dos</span> <span class="hps">pontos fracos</span> <span class="hps">do JavaScript</span><span>, mas o modelo de</span> <span class="hps">herança prototipal</span> <span class="hps">é de fato</span> <span class="hps">mais potente</span> <span class="hps">do que o modelo</span> <span class="hps">clássico.</span> <span class="hps">É</span><span>,</span> <span class="hps">por exemplo</span><span>,</span> <span class="hps">relativamente</span> <span class="hps">trivial</span> <span class="hps">construir</span> <span class="hps">um</span> "<span class="hps">modelo</span> <span class="hps">clássico" (como na implementaçao de <code>class</code></span>)<span>,</span> <span class="hps">enquanto</span> <span class="hps">o contrário</span> <span class="hps">é</span> <span class="hps">uma</span> <span class="hps">tarefa</span> <span class="hps">muito mais</span> <span class="hps">difícil</span><span>.</span></span></p> + +<p><sup>1 </sup><em>N. da T: Como em uma implementação de fila em C, por exemplo.</em></p> + +<h2 id="Herança_com_o_encadeamento_de_protótipos">Herança com o encadeamento de protótipos</h2> + +<h3 id="Propriedades_de_heranças">Propriedades de heranças</h3> + +<p><span id="result_box" lang="pt"><span class="hps">Objetos em JavaScript</span> <span class="hps">são</span> <span class="hps">"sacos"</span> <span class="hps">dinâmicos de</span> <span class="atn hps">propriedades (</span><span>a que se refere</span> <span class="hps">as próprias propriedades</span><span>)</span> <span class="hps">e cada um tem</span> <span class="hps">um link para um</span> <span class="hps">objeto </span><span><code>prototype</code>.</span> <span class="hps">Eis o que acontece</span> <span class="hps">quando se tenta</span> <span class="hps">acessar uma propriedade</span><span>:</span></span></p> + +<pre><code>// </code>Vamos criar um objeto o da função f com suas próprias propriedades a e b:<code> +let f = function () { + this.a = 1; + this.b = 2; +} +let o = new f(); // {a: 1, b: 2} + +// </code>adicionar propriedades no protótipo da função f<code> +f.prototype.b = 3; +f.prototype.c = 4;</code> + +// não defina o protótipo f.prototype = {b: 3, c: 4}; isso vai quebrar a cadeia de protótipos +// o. [[Prototype]] possui propriedades bec. +// o. [[Prototype]]. [[Prototype]] é Object.prototype. +// Finalmente, o. [[Prototype]]. [[Prototype]]. [[Prototype]] é nulo. +// Este é o fim da cadeia de protótipos, como nulo, +// por definição, não possui [[Prototype]]. +// Assim, a cadeia completa de protótipos se parece com: +// {a: 1, b: 2} ---> {b: 3, c: 4} ---> Object.prototype ---> null dfdf + +<code>console.log(o.a); // 1 +// Existe uma propriedade 'a' no objeto o? Sim, e seu valor é 1. + +console.log(o.b); // 2 +// Existe uma propriedade própria 'b' em o? Sim, e seu valor é 2. +// O protótipo também tem uma propriedade 'b', mas não é visitado. +// Isso é chamado de sombreamento de propriedade(Property Shadowing) + +console.log(o.c); // 4 +// Existe uma propriedade própria 'c' em o? Não, verifique seu protótipo. +// Existe uma propriedade 'c' própria em o. [[Prototype]]? Sim, seu valor é 4. + +console.log(o.d); // undefined +// Existe uma propriedade 'd' própria em o? Não, verifique seu prototype. +// Existe uma propriedade 'd' em o. [[Prototype]]? Não, verifique seu prototype. +// o. [[Prototype]]. [[Prototype]] é Object.prototype e não há propriedade 'd' por padrão, verifique seu prototype. +// o. [[Prototype]]. [[Prototype]]. [[Prototype]] é nulo, pare de pesquisar, +// nenhuma propriedade encontrada, retorne indefinido.</code> +</pre> + +<p><a href="https://repl.it/@khaled_hossain_code/prototype" style="background-color: rgb(255, 255, 255); font-family: Arial, x-locale-body, sans-serif; font-size: 1rem; letter-spacing: -0.00278rem;">Code Link</a></p> + +<p><span id="result_box" lang="pt"><span class="hps">Atribuir uma propriedade</span> <span class="hps">a um objeto</span> <span class="hps">cria uma</span> <span class="hps">propriedade nele.</span> <span class="hps">A única</span> <span class="hps">exceção às regras</span> <span class="hps">de obtenção e definição</span> <span class="hps">de comportamento</span> <span class="hps">é quando há</span> <span class="hps">uma propriedade herdada</span> <span class="hps">com </span></span>um <a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters" title="Defining Getters and Setters">getter or a setter</a>.</p> + +<h3 id="Herença_de_métodos">Herença de "métodos"</h3> + +<p>JavaScript não tem "métodos" como os que conhecemos em linguagens baseadas em classes. Em JavaScript, qualquer função pode ser adicionada em um objeto em forma de propriedade. Uma herança de funções age como a herança de quaisquers outras propriedades que não sejam funções, e podemos inclusive realizar sobre-escrita de função(<em>method overriding</em>)!</p> + +<p>Quando uma herança de função é executada, o valor de <a href="/en/JavaScript/Reference/Operators/this" title="this"><code>this</code></a> aponta para o objeto que herdou as propriedades, não para o objeto prototype onde as propriedades foram escritas originalmente.</p> + +<pre class="brush: js">var o = { + a: 2, + m: function(b){ + return this.a + 1; + } +}; + +console.log(o.m()); // 3 +// <span class="short_text" id="result_box" lang="pt"><span class="hps">Ao chamar</span> <span class="atn hps">'</span><span>o.m</span><span>'</span> <span class="hps">neste caso,</span> <span class="hps">"this" </span><span class="hps">refere-se a</span> <span class="hps">'o'</span></span> + +var p = Object.create(o); +// 'p' é um objeto que foi herdado de 'o' + +p.a = 12; // cria uma propriedade 'a' no objeto 'p' +console.log(p.m()); // 13 +// Ao chamar 'p.m', 'this' refere-se a 'p' +// <span id="result_box" lang="pt"><span class="hps">Então,</span> <span class="atn hps">quando '</span><span>p'</span> <span class="hps">herda</span> <span class="hps">a função de</span> <span class="hps">'m'</span> <span class="hps">de</span> <span class="hps">'o'</span><span>,</span> <span class="atn hps">'</span><span>this.a</span><span>'</span> representa <span class="atn hps">'p</span><span>.a</span><span>'</span> que é <span class="hps">a</span> <span class="hps">própria propriedade</span> <span class="hps">'a'</span> <span class="hps">de</span> <span class="hps">'p'</span></span> + +</pre> + +<h2 id="Maneiras_de_criar_objetos_e_resultados_dos_protótipos_encadeados">Maneiras de criar objetos e resultados dos protótipos encadeados</h2> + +<h3 id="Objetos_criados_com_sintaxe_de_construtores">Objetos criados com sintaxe de construtores</h3> + +<pre class="brush: js">var o = {a: 1}; + +// <span id="result_box" lang="pt"><span class="hps">O recém-criado</span> <span class="hps">objecto 'o'</span> <span class="hps">tem</span> <span class="hps">Object.prototype</span> <span class="hps">como o seu</span> <span class="atn hps">[[</span><span>Prototype</span><span>]]</span></span> +// <span id="result_box" lang="pt"><span class="hps">'o'</span> <span class="hps">não tem</span> <span class="hps">não tem uma propriedade chamada </span><span class="atn hps">'</span><span>hasOwnProperty</span><span>'</span></span> +// <span id="result_box" lang="pt"><span class="hps">hasOwnProperty</span> <span class="hps">é uma propriedade</span> <span class="hps">própria</span> <span class="hps">de</span> <span class="hps">Object.prototype</span><span>.</span> <span class="hps">Então</span> <span class="hps">'o'</span> <span class="hps">herda</span> <span class="hps">hasOwnProperty</span> <span class="hps">de</span> <span class="hps">Object.prototype</span></span> + +// Object.prototype tem null como seu protótipo. +// o ---> Object.prototype ---> null + +var a = ["yo", "whadup", "?"]; + +// <span id="result_box" lang="pt"><span class="hps">Arrays</span> <span class="hps">herdam de</span> <span class="hps">Array.prototype</span> <span class="hps">(que tem</span> <span class="hps">métodos como</span> <span class="hps">indexOf</span><span>,</span> <span class="hps">forEach</span><span>, etc.)</span></span> +// A cadeia de protótipos se parece com isso: +// a ---> Array.prototype ---> Object.prototype ---> null + +function f(){ + return 2; +} + +// <span id="result_box" lang="pt"><span class="hps">Funções</span> <span class="hps">herdam de</span> <span class="hps">Function.prototype</span> <span class="hps">(que tem</span> <span class="hps">métodos como</span> <span class="hps">call, </span><span class="hps">bind,</span> <span class="hps">etc.)</span></span> +// f ---> Function.prototype ---> Object.prototype ---> null +</pre> + +<h3 id="Com_um_construtor">Com um construtor</h3> + +<p>Um "construtor" em JavaScript é "somente" uma função que passa a ser chamada com o operador <a href="/en/JavaScript/Reference/Operators/new" title="new">new</a>.</p> + +<pre class="brush: js">function Graph() { + this.vertexes = []; + this.edges = []; +} + +Graph.prototype = { + addVertex: function(v){ + this.vertexes.push(v); + } +}; + +var g = new Graph(); +// 'g' é um objeto com as propriedades 'vertexes' e 'edges'. +// g.[[Prototype]] é o valor de Graph.prototype quando new Graph() é executada. +</pre> + +<h3 id="Com_Object.create">Com Object.create</h3> + +<p>ECMAScript 5 introduziu o novo método: <a href="/en/JavaScript/Reference/Global_Objects/Object/create" title="create">Object.create</a>. Invocando este método podemos criar novos objetos. O prototype destes novos objetos é o primeiro argumento do método:</p> + +<pre class="brush: js">var a = {a: 1}; +// a ---> Object.prototype ---> null + +var b = Object.create(a); +// b ---> a ---> Object.prototype ---> null +console.log(b.a); // 1 (inherited) + +var c = Object.create(b); +// c ---> b ---> a ---> Object.prototype ---> null + +var d = Object.create(null); +// d ---> null +console.log(d.hasOwnProperty); // undefined, <span class="short_text" id="result_box" lang="pt"><span class="hps">porque</span> <span class="hps">não herda de</span> <span class="hps">Object.prototype</span></span> +</pre> + +<div> +<h3 id="Performace">Performace</h3> + +<p>O tempo de pesquisa para as propriedades que estão no alto da cadeia de protótipos pode ter um impacto negativo no desempenho, e isso pode ser significativo no código em que o desempenho é crítico. Além disso, tentando acessar propriedades inexistentes vai sempre atravessar a cadeia cheia do protótipo (full prototype chain).</p> + +<p>Porém, quando estamos interagindo com as propriedades de um objeto, <strong>toda</strong> propriedade que está na cadeia do prototype (prototype chain) vai ser enumerada.</p> + +<p>Para verificar se um objeto tem uma propriedade definida em si mesmo e não em algum lugar na sua cadeia de protótipo, é necessário usar o método <a href="/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty" title="/ru/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty"><code>hasOwnProperty</code></a> que todos os objetos herdam do Object.prototype.</p> + +<p><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty" title="/ru/docs/JavaScript/Reference/Global_Objects/Object/hasOwnProperty"><code>hasOwnProperty</code></a> é a única alternativa em JavaScript que lida com propriedades sem atravessar a cadeia de protótipos.</p> + + +<div class="note">Observação: <strong>Não</strong> é suficiente apenas verificar se o valor da propriedade é <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined">undefined</a></code> para saber se ela existe. A propriedade pode muito bem existir e não ter sido inicializada, sendo assim o seu valor undefined.</div> + +<div> +<h3 id="Má_Pratica_Estender_protótipos_nativos">Má Pratica: Estender protótipos nativos</h3> + +<p>Um erro frequentemente cometido por programadores é estender um Object.prototype.</p> + +<p>Esta técnica é chamada de "monkey patching" e quebra o encapsulamento. Não existe uma boa razão para desorganizar tipos nativos do JavaScript para adicionar uma nova funcionalidade ao mesmo. </p> + +<p>O único bom motivo para estender um protótipo nativo do JavaScript é para dar suporte a novas "features" do JavaScript; por exemplo: Array.forEach, etc.</p> +</div> + +<div> +<h3 id="Conclusão">Conclusão</h3> + +<p>É essencial entender bem "prototypal inheritance" antes de escrever códigos complexos. Tome cuidado com o tamanho da sua cadeia de protótipos, quebre a cadeia caso necessário para evitar problemas de performace. Nunca estenda protótipos nativos a menos que seja para conseguir compatibilidade com novas "features" do JavaScript.</p> + + +</div> +</div> + +<p>{{ languages( {"zh-cn": "zh-cn/JavaScript/Guide/Inheritance_and_the_prototype_chain" } ) }}</p> diff --git a/files/pt-br/web/javascript/guide/introduction/index.html b/files/pt-br/web/javascript/guide/introduction/index.html new file mode 100644 index 0000000000..3cb0082600 --- /dev/null +++ b/files/pt-br/web/javascript/guide/introduction/index.html @@ -0,0 +1,153 @@ +--- +title: Introdução +slug: Web/JavaScript/Guide/Introduction +tags: + - Guia(2) + - Introdução + - JavaScript + - básico +translation_of: Web/JavaScript/Guide/Introduction +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}</div> + +<div class="summary"> +<p>Este capítulo apresenta o JavaScript e discute alguns de seus conceitos fundamentais.</p> +</div> + +<h2 id="O_que_você_realmente_já_deveria_saber">O que você realmente já deveria saber?</h2> + +<p>Este guia assume que você tem os seguintes conhecimentos básicos:</p> + +<ul> + <li>Um entendimento geral da internet e da <em>World Wide Web</em> ({{Glossary("WWW")}}).</li> + <li>Um bom conhecimento de <em>HyperText Markup Language</em> ({{Glossary("HTML")}}).</li> + <li>Alguma experiência em programação. Se você é novo em programação, veja alguns tutorias na página inicial sobre <a href="/pt-BR/docs/Web/JavaScript" title="/en-US/docs/">JavaScript</a>.</li> +</ul> + +<h2 id="Onde_encontrar_informações_sobre_JavaScript">Onde encontrar informações sobre JavaScript</h2> + +<p>A documentação de JavaScript na MDN inclui o seguinte:</p> + +<ul> + <li><a href="/en-US/Learn">Aprendendo sobre a internet</a> fornece informações aos iniciantes e introduz os conceitos básicos de programação e da internet.</li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide" title="en/Core_JavaScript_1.5_Guide">Guia JavaScript</a> (este guia) dá uma visão geral sobre a linguagem de programação JavaScript e seus objetos.</li> + <li><a href="/pt-BR/docs/Web/JavaScript/Reference" title="en/JavaScript/Reference">Referência JavaScript</a> provê um material de referência detalhado da linguagem JavaScript.</li> +</ul> + +<p>Se você é novo com JavaScript, comece com os artigos na <a href="/en-US/Learn">área de aprendizado</a> e com o <a href="/pt-BR/docs/Web/JavaScript/Guide" title="en/Core_JavaScript_1.5_Guide">Guia JavaScript</a>. Quando você já possuir uma compreensão dos princípios básicos, você pode usar a <a href="/pt-BR/docs/Web/JavaScript/Reference" title="en/JavaScript/Reference">Referência JavaScript</a> para ter mais detalhes sobre objetos e declarações.</p> + +<h2 id="O_que_é_JavaScript">O que é JavaScript?</h2> + +<p>JavaScript é uma linguagem de script orientada a objetos, multiplataforma. É uma linguagem pequena e leve. Dentro de um ambiente de host (por exemplo, um navegador web) o JavaScript pode ser ligado aos objetos deste ambiente para prover um controle programático sobre eles.</p> + +<p>JavaScript tem uma biblioteca padrão de objetos, como: <code>Array</code>, <code>Date</code>, e <code>Math</code>, 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:</p> + +<ul> + <li><em>O lado cliente do JavaScript</em> estende-se do núcleo linguagem, fornecendo objetos para controlar um navegador web e seu <em>Document Object Model</em> (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.</li> + <li><em>O lado do servidor do JavaScript</em> 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.</li> +</ul> + +<h2 id="JavaScript_and_Java" name="JavaScript_and_Java">JavaScript e Java</h2> + +<p>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. <span id="result_box" lang="pt"><span title="In contrast to Java's compile-time system of classes built by declarations, JavaScript supports a runtime system based on a small number of data types representing numeric, Boolean, and string values.">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.</span></span></p> + +<p><span lang="pt"><span title="In contrast to Java's compile-time system of classes built by declarations, JavaScript supports a runtime system based on a small number of data types representing numeric, Boolean, and string values.">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</span></span>. <span id="result_box" lang="pt"><span title="JavaScript has a prototype-based object model instead of the more common class-based object model.">JavaScript tem um modelo de objeto baseado em protótipo em vez do modelo, mais comum, de objeto baseado em classes. </span><span title="The prototype-based model provides dynamic inheritance;">O modelo baseado em protótipo fornece herança dinâmica; </span><span title="that is, what is inherited can vary for individual objects.">isto é, o que é herdado pode variar para objetos individuais. </span><span title="JavaScript also supports functions without any special declarative requirements.">JavaScript também suporta funções sem quaisquer requisitos especiais declarativos. </span><span title="Functions can be properties of objects, executing as loosely typed methods. + +">As funções podem ser propriedades de objetos, executando como métodos.</span></span></p> + +<p><span id="result_box" lang="pt"><span title="JavaScript is a very free-form language compared to Java.">JavaScript é uma linguagem mais livre em comparação a Java. </span><span title="You do not have to declare all variables, classes, and methods.">Você não tem de declarar todas as variáveis, classes e métodos. </span><span title="You do not have to be concerned with whether methods are public, private, or protected, and you do not have to implement interfaces.">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. </span><span title="Variables, parameters, and function return types are not explicitly typed. + +">Variáveis, parâmetros e tipo de retorno da função não são explicitamente tipados.</span></span></p> + +<p><span id="result_box" lang="pt"><span class="hps">Java</span> <span class="hps">é</span> <span class="hps">uma linguagem de programação</span> <span class="hps">baseada em classes</span>, <span class="hps">projetada para</span> <span class="hps">execução rápida</span> <span class="hps">e segurança de tipos</span><span class="hps">.</span> <span class="hps">Segurança de tipo significa que</span><span>,</span> <span class="hps">por exemplo, </span><span class="hps">você não pode converter</span> <span class="hps">um</span> <span class="hps">número inteiro</span> <span class="hps">em</span> <span class="hps">Java</span> <span class="hps">para uma referência de objeto</span> <span class="hps">ou</span><span class="hps"> acessar a memória</span> <span class="hps">privada</span> <span class="hps">corrompendo</span> <span class="hps">bytecodes</span> <span class="hps">Java.</span> O m<span class="hps">odelo</span> <span class="hps">baseado em classes</span> <span class="hps">do</span> <span class="hps">Java</span> <span class="hps">significa que os programas são</span> <span class="hps">exclusivamente constituídos por</span> <span class="hps">classes e seus</span> <span class="hps">métodos.</span> <span class="hps">Herança de classe</span> <span class="hps">do</span> <span class="hps">Java</span> <span class="hps">e</span> <span class="hps">tipagem forte</span> <span class="hps">geralmente</span> <span class="hps">requerem</span> hierarquias de objetos fortemente acoplados<span>.</span> <span class="hps">Esses</span> <span class="hps">requisitos tornam</span> a <span class="hps">programação em</span> <span class="hps">Java</span> <span class="hps">mais complexa</span> <span class="hps">do que a programação em</span> <span class="hps">JavaScript.</span></span></p> + +<p><span id="result_box" lang="pt"><span class="hps">Em contraste, </span> <span class="hps">JavaScript</span> <span class="alt-edited hps">descende</span> <span class="hps">em espírito</span> <span class="hps">de uma linhagem de linguagens menores com tipagem dinâmica, como </span><span class="hps">HyperTalk</span> <span class="hps">e</span> <span class="hps">dBASE</span><span>.</span> <span class="hps">Essas</span> <span class="hps">linguagens de script</span> <span class="hps">oferecem</span> <span class="hps">ferramentas de programação</span> <span class="hps">para um público muito</span> <span class="hps">mais amplo</span> <span class="hps">por causa de sua</span> <span class="hps">sintaxe</span> <span class="hps">mais fácil</span><span>, funções especializadas embutidas</span><span class="hps"> e</span> <span class="hps">requisitos mínimos para</span> <span class="hps">a criação de objetos</span><span>.</span></span></p> + +<table class="standard-table"> + <caption>JavaScript vs Java</caption> + <thead> + <tr> + <th scope="col">JavaScript</th> + <th scope="col">Java</th> + </tr> + </thead> + <tbody> + <tr> + <td>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.</td> + <td>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.</td> + </tr> + <tr> + <td> + <p>Os tipos de dados das variáveis não precisam ser declarados (tipagem dinâmica)</p> + </td> + <td> + <p>Os tipos de dados das variáveis devem ser declarados (tipagem estática).</p> + </td> + </tr> + <tr> + <td>Não pode escrever automaticamente no disco rigído.</td> + <td>Pode escrever automaticamente no disco rigído.</td> + </tr> + <tr> + <td>Linguagem não compilada</td> + <td>Linguagem compilada</td> + </tr> + </tbody> +</table> + +<p>Para mais informações sobre as diferenças entre JavaScript e Java, veja a seção <a href="/pt-BR/docs/Web/JavaScript/Guide/Detalhes_do_Modelo_do_Objeto" title="JavaScript/Guide/Details of the Object Model">Detalhes do modelo de objetos</a>.</p> + +<h2 id="JavaScript_and_the_ECMAScript_Specification" name="JavaScript_and_the_ECMAScript_Specification">JavaScript e a especificação ECMAScript</h2> + +<p>O JavaScript é padronizado pela <a class="external" href="http://www.ecma-international.org/">Ecma International</a> — 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) <span id="result_box" lang="pt"><span class="hps">para entregar</span> <span class="hps">uma linguagem de programação</span> <span class="hps">padronizada,</span> <span class="hps">internacional</span> <span class="hps">baseada em</span> <span class="hps">JavaScript.</span> <span class="hps">Esta versão</span> <span class="hps">padronizada de</span> <span class="hps">JavaScript,</span> <span class="hps">chamada</span> <span class="hps">ECMAScript</span><span>, comporta-se</span> <span class="hps">da mesma forma</span> <span class="hps">em todas as aplicações</span> <span class="hps">que suportam o padrão</span><span>.</span> <span class="hps">As empresas podem usar</span> <span class="hps">a linguagem de</span> <span class="hps">padrão aberto</span> <span class="hps">para desenvolver a sua</span> <span class="hps">implementação de</span> <span class="hps">JavaScript.</span> <span class="hps">O padrão</span> <span class="hps">ECMAScript</span> <span class="hps">é documentado </span><span class="hps">na especificação</span> <span class="hps">ECMA</span><span>-262</span><span>.</span> <span class="hps">Veja</span> <a href="/pt-BR/docs/Web/JavaScript/New_in_JavaScript">Novidades em JavaScript</a> <span class="hps">para aprender mais sobre</span> <span class="hps">diferentes versões de</span> <span class="hps">JavaScript e</span> edições da especificação <span class="hps">ECMAScript</span><span class="hps">.</span></span></p> + +<p>O padrão ECMA-262 também é aprovado pela <a class="external" href="http://www.iso.ch/">ISO</a> (International Organization for Standardization) como ISO-16262. Você também pode encontrar a especificação no site da <a class="external" href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">Ecma International</a>. A especificação ECMAScript não descreve o Document Object Model (DOM), que é padronizado pelo <a class="external" href="http://www.w3.org/">World Wide Web Consortium (W3C)</a>. 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 <a href="/pt-BR/docs/Web/JavaScript/JavaScript_technologies_overview">Visão Geral do JavaScript</a>.</p> + +<h3 id="JavaScript_Documentation_versus_the_ECMAScript_Specification" name="JavaScript_Documentation_versus_the_ECMAScript_Specification">Documentação JavaScript versus Especificação ECMAScript</h3> + +<p>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 <em>engine</em> (como SpiderMonkey no Firefox, ou v8 no Chrome).</p> + +<p>O documento ECMAScript não se destina a ajudar programadores de script; utilize a documentação JavaScript para informações sobre como escrever scripts.</p> + +<p>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.</p> + +<p>A documentação JavaScript descreve aspectos da linguagem que são apropriadas para um programador JavaScript.</p> + +<h2 id="Getting_started_with_JavaScript" name="Getting_started_with_JavaScript">Começando com JavaScript</h2> + +<p>Começar a aprender JavaScript é fácil: Tudo o que você precisa é de um navegador web moderno. Esse guia inclui algumas características do JavaScript que só estão disponíveis nas últimas versões do Firefox, então, é recomendável o uso de uma versão mais recente do Firefox.</p> + +<p>Há duas ferramentas no Firefox que são muito úteis para aprender JavaScript: O console web e o Scratchpad.</p> + +<h3 id="O_console_web">O console web</h3> + +<p>O <a href="/en-US/docs/Tools/Web_Console">console web</a> mostra informações sobre a página web que está sendo carregada atualmente e também inclui a <a href="/en-US/docs/Tools/Web_Console#The_command_line_interpreter">linha de comando</a> que você pode utilizar para executar códigos JavaScript na página atual.</p> + +<p>Para abrir o console (Ctrl+Shift+K), selecione "Web Console" do menu "Web Developer", que está sob o menu "Tools" no Firefox. Ele aparece na parte inferior da janela do navegador. Na parte inferior do console está a linha de comando que você pode usar para colocar o JavaScript, e a saída é exibida no painel acima:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/7363/web-console-commandline.png" style="display: block; margin-left: auto; margin-right: auto;"></p> + +<h3 id="Scratchpad">Scratchpad</h3> + +<p>O Web Console é excelente para executar linhas únicas de JavaScript, mas embora você possa executar várias linhas, não é muito conveniente para isso, e você não pode salvar as amostras de código usando o Web Console. Assim, para exemplos mais complexos a ferramenta <a href="/en-US/docs/Tools/Scratchpad">Scratchpad</a> é melhor.</p> + +<p>Para abrir o Scratchpad (Shift+F4), selecione "Scratchpad" do menu "Web Developer", que está sob o menu "Tools/Ferramentas" do Firefox. Ele abre em uma janela separada e é um editor que você pode usar para escrever e executar JavaScript no navegador. Você também pode salvar os scripts para o disco e carregá-los a partir do disco. </p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/7365/scratchpad.png" style="display: block; margin-left: auto; margin-right: auto;"></p> + +<h3 id="Hello_world">Hello world</h3> + +<p>Para começar a escrever JavaScript, abra o Console Web ou o Scratchpad e escreva seu primeiro código JavaScript "Olá, mundo". </p> + +<pre class="brush: js">function greetMe(nome) { + alert("Olá, " + nome); +} + +greetMe("mundo"); // "Olá, mundo" +</pre> + +<p>Logo após, pressione Ctrl+R para executar o código em seu navegador.</p> + +<p>Nas páginas seguintes, este guia irá apresentar-lhe a sintaxe e as características da linguagem JavaScript, de modo que você possa escrever aplicações mais complexas.</p> + +<p>{{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}</p> diff --git a/files/pt-br/web/javascript/guide/iteratores_e_geradores/index.html b/files/pt-br/web/javascript/guide/iteratores_e_geradores/index.html new file mode 100644 index 0000000000..13a9b87f11 --- /dev/null +++ b/files/pt-br/web/javascript/guide/iteratores_e_geradores/index.html @@ -0,0 +1,161 @@ +--- +title: Iteratores e geradores +slug: Web/JavaScript/Guide/Iteratores_e_geradores +tags: + - Generators + - Guia(2) + - Intermediario(2) + - Iteradores + - JavaScript +translation_of: Web/JavaScript/Guide/Iterators_and_Generators +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}</div> + +<p class="summary">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 {{jsxref("Statements/for","for")}}, até um {{jsxref("Global_Objects/Array/map","map()")}} e também com o {{jsxref("Global_Objects/Array/filter","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 {{jsxref("Statements/for...of","for...of")}}.</p> + +<p>Para detalhes, também veja:</p> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Iteration_protocols">Protocolos de iteração</a></li> + <li>{{jsxref("Statements/for...of","for...of")}}</li> + <li>{{jsxref("Statements/function*","function*")}} e {{jsxref("Generator")}}</li> + <li>{{jsxref("Operators/yield","yield")}} e {{jsxref("Operators/yield*","yield*")}}</li> +</ul> + +<h2 id="Iterators_Iteradores">Iterators (Iteradores)</h2> + +<p>Um objeto é um <strong>iterator (iterador)</strong> 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 <code>next(),</code> o qual retorna o próximo item da sequência. Este método retorna um objeto com duas propriedades: <code>done</code> e <code>value</code>.</p> + +<p>Uma vez criado, um objeto iterator pode ser usado explicitamente ao chamar repetidas vezes o método <code>next()</code>.</p> + +<pre class="brush: js notranslate">const makeIterator = (array) => { + +let nextIndex = 0; + +return { + next : () => { + return nextIndex < array.length ? + {value: array[nextIndex ++], done: false} : + {done: true}; + } + } +};</pre> + +<p>Uma vez inicializado, o método <code>next()</code> pode ser chamado para acessar os pares chave/valor do objeto da vez.</p> + +<pre class="brush: js notranslate">let it = makeIterator(['yo', 'ya']); +console.log(it.next().value); // 'yo' +console.log(it.next().value); // 'ya' +console.log(it.next().done); // true</pre> + +<h2 id="Iterables_Iteráveis">Iterables (Iteráveis)</h2> + +<p>Um objeto é iterável <strong>(iterable),</strong> se ele define seu comportamento de iteração, como no caso de quais valores percorridos em um laço do tipo {{jsxref("Statements/for...of", "for..of")}}. Alguns tipos embutidos, como o {{jsxref("Array")}}, ou o {{jsxref("Map")}}, têm um comportamento iterável padrão, enquanto outros tipos (como o{{jsxref("Object")}}) não possuem.</p> + +<p>Para que um objeto seja <strong>iterable</strong>, o objeto precisa implemntar o método <strong>@@iterator</strong>, significando que o objeto (ou um dos objetos na cadeia de prototipagem - <a href="/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain">prototype chain</a>) precisa ter uma propriedade com uma chave {{jsxref("Symbol.iterator")}}:</p> + +<h3 id="Iterables_definidos_pelo_usuário">Iterables definidos pelo usuário</h3> + +<p>Nós podemos fazer, criar, os nossos próprios iteráveis como aqui:</p> + +<pre class="brush: js notranslate">var myIterable = {} +myIterable[Symbol.iterator] = function* () { + yield 1; + yield 2; + yield 3; +}; +[...myIterable] // [1, 2, 3] +</pre> + +<h3 id="Iterables_Built-in_Iteráveis_Embutidos">Iterables Built-in (Iteráveis Embutidos)</h3> + +<p>{{jsxref("String")}}, {{jsxref("Array")}}, {{jsxref("TypedArray")}}, {{jsxref("Map")}} e {{jsxref("Set")}} são iteráveis embutidos, pois o protótipo dos objetos de todos eles têm o método {{jsxref("Symbol.iterator")}}.</p> + +<h3 id="Syntaxes_expecting_iterables">Syntaxes expecting iterables</h3> + +<p>Algumas declarações e expressões esperam por iteradores, por exemplo o {{jsxref("Statements/for...of","for-of")}} loops, {{jsxref("Operators/Spread_operator","spread operator","","true")}}, {{jsxref("Operators/yield*","yield*")}}, e {{jsxref("Operators/Destructuring_assignment","destructuring assignment","","true")}}.</p> + +<pre class="brush: js notranslate">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" + +</pre> + +<h2 id="Generators">Generators</h2> + +<p>Enquanto os iteradores são ferramentas muito úteis, sua criação requer um cuidado devido a necessidade de manter explicito seu estado interno. <strong>{{jsxref("Global_Objects/Generator","Generators","","true")}}</strong> provê uma alternativa poderosa: eles te permitem definir um algorítimo iterativo escrevendo uma função simples que pode manter seu estado próprio.</p> + +<p>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 {{jsxref("Operators/yield","yield")}} e se ela usa a sintaxe {{jsxref("Statements/function*","function*")}}.</p> + +<pre class="brush: js notranslate">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 +// ...</pre> + +<h2 id="Generators_avançados">Generators avançados</h2> + +<p>Generators computam seus valores "yielded" por demanda, que os permitem representar sequencias de forma eficiente que costumam ser trabalhosas ao serem computadas, ou até sequencias infinitas como demonstradas acima.</p> + +<p>O método {{jsxref("Global_Objects/Generator/next","next()")}} também aceita um valor que pode ser usado para modificar o estado interno de um generator. O valor passado pro <code>next()</code> será tratado como o resultado da última expressão yield que pausou o generator.</p> + +<p>Aqui um gerador de sequencia fibonacci usando <code>next(x)</code> pra restartar a sequencia:</p> + +<pre class="brush: js notranslate">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</pre> + +<div class="note"><strong>Nota:</strong> Como um ponto de interesse, chamando <code>next(undefined)</code> é o mesmo que chamar <code>next()</code>. Entretanto, estartar um novo generator com qualquer valor que não seja undefined na chamada next() terá <code>TypeError</code> exception.</div> + +<p>Você pode forçar um generator a lançar uma exceção chamando o seu método {{jsxref("Global_Objects/Generator/throw","throw()")}} 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 <code>yield</code> atualmente suspenso fosse um <code>throw</code>.</p> + +<p>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 <code>throw()</code>, e pra subsequente chamada do <code>next()</code> que terá a propriedade done resultando em <code>true</code>.</p> + +<p>Generators tem o método {{jsxref("Global_Objects/Generator/return","return(value)")}} que retorna o valor pego e finaliza o generator.</p> + +<p>{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}</p> diff --git a/files/pt-br/web/javascript/guide/keyed_collections/index.html b/files/pt-br/web/javascript/guide/keyed_collections/index.html new file mode 100644 index 0000000000..a760c1d916 --- /dev/null +++ b/files/pt-br/web/javascript/guide/keyed_collections/index.html @@ -0,0 +1,156 @@ +--- +title: Coleções chaveadas +slug: Web/JavaScript/Guide/Keyed_collections +tags: + - Coleções + - Guía + - JavaScript + - Map + - configuração +translation_of: Web/JavaScript/Guide/Keyed_collections +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}</div> + +<p class="summary">Este capítulo apresenta coleções de dados que são ordenados por uma chave; Objetos Map e Set contêm elementos que são iteráveis em ordem de inserção.</p> + +<h2 id="Mapas">Mapas</h2> + +<h3 id="Objeto_Map"><code>Objeto Map</code></h3> + +<p>ECMAScript 6 apresenta uma nova estrutura de dados para mapear valores para valores. Um objeto {{jsxref("Map")}} é um simples mapa de chave/valor que pode ter seus elementos iterados por ordem de inserção.</p> + +<p>O código a seguir mostra algumas operações básicas com um <code>Map</code>. Veja também a página de referência do {{jsxref("Map")}} para mais exemplos e a API completa. Você pode usar um laço {{jsxref("Statements/for...of","for...of")}} para retornar um array de<code> [chave, valor]</code> para cada iteração.</p> + +<pre class="brush: js">var sayings = new Map(); +sayings.set("dog", "woof"); +sayings.set("cat", "meow"); +sayings.set("elephant", "toot"); +sayings.size; // 3 +sayings.get("fox"); // undefined +sayings.has("bird"); // false +sayings.delete("dog"); +sayings.has("dog"); // false + +for (var [key, value] of sayings) { + console.log(key + " goes " + value); +} +// "cat goes meow" +// "elephant goes toot" + +sayings.clear(); +sayings.size; // 0 +</pre> + +<h3 id="Object_e_Map_comparados"><code>Object</code> e <code>Map</code> comparados</h3> + +<p>Tradicionalmente, {{jsxref("Object", "objetos", "", 1)}} tem sido usado para mapear strings para valores. Objetos permitem que você defina chaves para valores, recupere esses valores, exclua chaves e detecte se algo está armazenado em uma chave. Objetos <code>Map</code>, contudo, possuem algumas vantagens que os tornam mapas melhores.</p> + +<ul> + <li>As chaves de um <code>Objeto</code> são {{jsxref("Global_Objects/String","Strings")}}, onde elas podem ser de qualquer valor para um <code>Map</code>.</li> + <li>Você pode obter o tamanho de um <code>Map</code> facilmente enquanto que para um <code>Object, </code>você tem que obter manualmente o seu tamanho.</li> + <li>A iteração de mapas é por ordem de inserção dos elementos.</li> + <li>Um <code>Object</code> tem um protótipo, então existem chaves padrão no mapa. (este pode ser ignorado usando <code>map = Object.create(null)</code>).</li> +</ul> + +<p>Estes dois tipos podem ajudar você a decidir se usa um <code>Map</code> ou um <code>Object</code>:</p> + +<ul> + <li>Use mapas sobre objetos quando as chaves forem desconhecidas até a execução, e quando todas as chaves são do mesmo tipo e todos valores são do mesmo tipo.</li> + <li>Use mapas caso haja a necessidade de armazenar valores primitivos como chaves, porque objetos tratam cada chave como uma string ou um valor numérico, valor booleano ou qualquer outro valor primitivo.</li> + <li>Use objetos quando há uma lógica que opera em elementos individuais.</li> +</ul> + +<h3 id="Objeto_WeakMap"><code>Objeto WeakMap</code></h3> + +<p>O objeto {{jsxref("WeakMap")}} é uma coleção de pares de chave/valor em que as <strong>chaves são somente objetos</strong> e seus valores podem ser valores arbitrários. As referências do objeto nas chaves são <em>fracamente</em> mantidas, isso significa que eles são alvo da garbage collection (coleta de lixo) se não houver nenhuma outra referência para o objeto. A API <code>WeakMap</code> é a mesma API do <code>Map</code>.</p> + +<p>Uma diferença para objetos <code>Map</code> é que chaves <code>WeakMap</code> não são enumeráveis (isto é, não há um método que dê a você uma lista de chaves). Se eles fossem, a lista dependeria do estado da coleta de lixo, introduzindo um não-determinismo.</p> + +<p>Para mais informações e código de exemplo, veja também "Por quê <em>Weak</em>Map?" na página de referência {{jsxref("WeakMap")}}.</p> + +<p>Um caso de uso de objetos <code>WeakMap</code> é armazenar dados privados para um objeto ou ocultar detalhes de implementação. O exemplo a seguir é Nick Fitzgerald a partir de um post <a href="http://fitzgeraldnick.com/weblog/53/">"Ocultando detalhes de implementação com WeakMaps ECMAScript 6" </a>em seu blog. Os dados privados e métodos pertencem ao objeto e são armazenados nos objetos WeakMap <code>privados</code>. Tudo exposto na instância e o protótipo é público, todo o restante é inacessível a partir do mundo externo por que <code>privado </code>não é exportado pelo módulo.</p> + +<pre class="brush: js">const privates = new WeakMap(); + +function Public() { + const me = { + // Dados privados vem aqui + }; + privates.set(this, me); +} + +Public.prototype.method = function () { + const me = privates.get(this); + // Faça coisas com dado privado em `me`... +}; + +module.exports = Public; +</pre> + +<h2 id="Conjuntos">Conjuntos</h2> + +<h3 id="Objeto_Set"><code>Objeto Set</code></h3> + +<p>Objetos {{jsxref("Set")}} são coleções de valores. Você pode iterar seus elementos em ordem de inserção. Um valor em um <code>Set</code> só pode ocorrer uma vez; ele é único em uma coleção <code>Set</code>.</p> + +<p>O código a seguir mostra algumas operações básicas com um <code>Set</code>. Veja também a página de referência {{jsxref("Set")}} para mais exemplos e a API completa.</p> + +<pre class="brush: js">var mySet = new Set(); +mySet.add(1); +mySet.add("some text"); +mySet.add("foo"); + +mySet.has(1); // true +mySet.delete("foo"); +mySet.size; // 2 + +for (let item of mySet) console.log(item); +// 1 +// "some text" +</pre> + +<h3 id="Conversão_entre_Array_e_Set">Conversão entre Array e Set</h3> + +<p>Você pode criar um {{jsxref("Array")}} a partir de um Set usando {{jsxref("Array.from")}} ou o <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator">operador de propagação</a>. Além disso, o construtor <code>Set</code> aceita um <code>Array</code> para converter em outra direção. Observe novamente que objetos <code>Set</code> armazenam valores únicos, então quaisquer elementos duplicados de um Array são excluídos quando convertidos.</p> + +<pre class="brush: js">Array.from(mySet); +[...mySet2]; + +mySet2 = new Set([1,2,3,4]); +</pre> + +<h3 id="Array_e_Set_comparados"><code>Array</code> e <code>Set</code> comparados</h3> + +<p>Tradicionalmente, um conjunto de elementos tem sido armazenados em arrays JavaScript em muitas situações. O novo objeto <code>Set</code>, contudo, tem algumas vantagens:</p> + +<ul> + <li>Checar se um elemento existe em uma coleção usando {{jsxref("Array.indexOf", "indexOf")}} para arrays é lento.</li> + <li>Objetos <code>Set</code> permitem que você exclua elementos por seu valor. Com um array você teria que unir baseado no índice do elemento.</li> + <li>O valor {{jsxref("NaN")}} não pode ser encontrado com <code>indexOf</code> no array.</li> + <li>Objetos <code>Set</code> armazenam valores únicos, você não tem que manter o controle de duplicidades manualmente por você mesmo.</li> +</ul> + +<h3 id="Objeto_WeakSet"><code>Objeto WeakSet</code></h3> + +<p>Objetos {{jsxref("WeakSet")}} são coleções de objetos. Um objeto no <code>WeakSet</code> só pode ocorrer uma vez; Isto é único em coleções <code>WeakSet</code> e objetos não são enumeráveis.</p> + +<p>As principais diferenças para objetos {{jsxref("Set")}} são:</p> + +<ul> + <li>Em contraste com <code>Sets</code>, <code>WeakSets</code> são <strong>apenas coleções de objetos</strong> e não de valores arbritários de qualquer tipo.</li> + <li>O <code>WeakSet</code> é <em>fraco</em>: Referências para objetos são fracamente realizadas na coleção. Se não há outra referência para um objeto armazenado no <code>WeakSet</code>, eles podem ser coletados pelo coletor de lixo. Isso significa também que não há uma lista de objetos correntes armazenados na coleção. <code>WeakSets</code> não são enumeráveis.</li> +</ul> + +<p>Os casos de uso do objeto <code>WeakSet</code> são limitados. Eles não vão desperdiçar memória para ser seguro o uso de elementos DOM como chaves e marcá-los para propósitos de controle, por exemplo.</p> + +<h2 id="Igualdade_de_chave_e_valor_do_Map_and_Set">Igualdade de chave e valor do <code>Map</code> and <code>Set</code></h2> + +<p>Ambos, a igualdade de chaves de objetos <code>Map</code> e a igualdade de valor de objetos <code>Set</code>, são baseados no "<a href="https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero">algoritmo mesmo valor de zero</a>":</p> + +<ul> + <li>Igualdade funciona como o operador de comparação de identidade <code>===</code>.</li> + <li><code>-0</code> e <code>+0</code> são considerados iguais.</li> + <li>{{jsxref("NaN")}} é considerado igual a ela mesmo (contrário de <code>===</code>).</li> +</ul> + +<p>{{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}</p> diff --git a/files/pt-br/web/javascript/guide/lacos_e_iteracoes/index.html b/files/pt-br/web/javascript/guide/lacos_e_iteracoes/index.html new file mode 100644 index 0000000000..fcf7437612 --- /dev/null +++ b/files/pt-br/web/javascript/guide/lacos_e_iteracoes/index.html @@ -0,0 +1,333 @@ +--- +title: Laços e iterações +slug: Web/JavaScript/Guide/Lacos_e_iteracoes +translation_of: Web/JavaScript/Guide/Loops_and_iteration +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}</div> + +<div class="summary"> +<p>Laços oferecem um jeito fácil e rápido de executar uma ação repetidas vezes. Este capítulo do <a href="/en-US/docs/Web/JavaScript/Guide">guia do JavaScript</a> abordará diferentes formas de iterações existentes no JavaScript.</p> +</div> + +<p>Você pode pensar em um laço de repetição como um jogo onde você manda o seu personagem andar X passos em uma direção e Y passos em outra; por exemplo, a ideia "vá 5 passos para leste" pode ser expressa em um laço desta forma:</p> + +<pre class="brush: js">var passo; +for (passo = 0; passo < 5; passo++) { + // Executa 5 vezes, com os valores de passos de 0 a 4. + console.log('Ande um passo para o leste'); +} +</pre> + +<p>Existem várias formas diferentes de laços, mas eles essencialmente fazem a mesma coisa: repetir uma ação múltiplas vezes ( inclusive você poderá repetir 0 vezes). Os vários mecanismos diferentes de laços oferecem diferentes formas de determinar quando este irá começar ou terminar. Há várias situações em que é mais fácil resolver um problema utilizando um determinado tipo de laço do que outros.</p> + +<p>Os possíveis laços de repetição em JavaScript:</p> + +<ul> + <li>{{anch("for_statement")}}</li> + <li>{{anch("do...while_statement")}}</li> + <li>{{anch("while_statement")}}</li> + <li>{{anch("label_statement")}}</li> + <li>{{anch("break_statement")}}</li> + <li>{{anch("continue_statement")}}</li> + <li>{{anch("for...in_statement")}}</li> + <li>{{anch("for...of_statement")}}</li> +</ul> + +<h2 id="for_statement" name="for_statement"><code>Declaração for</code></h2> + +<p>Um laço <a href="/en-US/docs/Web/JavaScript/Reference/Statements/for">for</a> é repetido até que a condição especificada seja falsa. O laço for no JavaScript é similar ao Java e C. Uma declaração for é feita da seguinte maneira:</p> + +<pre class="syntaxbox">for ([expressaoInicial]; [condicao]; [incremento]) + declaracao +</pre> + +<p>Quando um for é executado, ocorre o seguinte:</p> + +<ol> + <li>A expressão <code>expressao Inicial</code> é inicializada e, caso possível, é executada. Normalmente essa expressão inicializa um ou mais contadores, mas a sintaxe permite expressões de qualquer grau de complexidade. Podendo conter também declaração de variáveis.</li> + <li>A expressão <code>condicao</code> é avaliada. caso o resultado de <code>condicao</code> seja verdadeiro, o laço é executado. Se o valor de <code>condicao</code> é falso, então o laço terminará. Se a expressão <code>condicao</code> é omitida, a <code>condicao</code> é assumida como verdadeira.</li> + <li> A instrução é executada. Para executar múltiplas declarações, use uma declaração em bloco ({ ... }) para agrupá-las.</li> + <li>A atualização da expressão <code>incremento</code>, se houver, executa, e retorna o controle para o passo 2.</li> +</ol> + +<h3 id="Exemplo"><strong>Exemplo</strong></h3> + +<p>A função a seguir contém uma declaração <code>for</code> que contará o número de opções selecionadas em uma lista (um elemento {{HTMLElement("select")}} permite várias seleções). Dentro do <code>for</code> é declarado uma váriavel <code>i</code> inicializada com zero. A declaração <code>for</code> verifica se <code>i</code> é menor que o número de opções no elemento <code><select></code>, executa sucessivas declaração <code>if</code>, e incrementa <code>i</code> de um em um a cada passagem pelo laço.</p> + +<pre class="brush: html"><form name="selectForm"> + <p> + <label for="tipoMusica">Escolha alguns tipos de música, em seguida, clique no botão abaixo:</label> + <select id="tipoMusica" name="tipoMusica" multiple="multiple"> + <option selected="selected">R&B</option> + <option>Jazz</option> + <option>Blues</option> + <option>New Age</option> + <option>Classico</option> + <option>Ópera</option> + </select> + </p> + <p><input id="btn" type="button" value="Quantos foram selecionados?" /></p> +</form> + +<script> +function howMany(selectObject) { + var numeroSelecionadas = 0; + for (var i = 0; i < selectObject.options.length; i++) { + if (selectObject.options[i].selected) { + numeroSelecionadas++; + } + } + return numeroSelecionadas; +} + +var btn = document.getElementById("btn"); +btn.addEventListener("click", function(){ + alert('Total de opções selecionadas: ' + howMany(document.selectForm.tipoMusica)) +}); +</script> + +</pre> + +<h2 id="do...while_statement" name="do...while_statement"><code>Declaração do...while</code></h2> + +<p>A instrução <a href="/en-US/docs/Web/JavaScript/Reference/Statements/do...while">do...while</a> repetirá até que a condição especificada seja falsa.</p> + +<pre class="syntaxbox">do + declaracao +while (condicao); +</pre> + +<p>A instrução será executada uma vez antes da condição ser verificada. Para executar multiplas instruções utilize uma declaração de bloco ({ ... }) para agrupá-las. Caso a <code>condicao</code> seja verdadeira, então o laço será executado novamente. Ao final de cada execução, a <code>condicao</code> é verificada. Quando a condição contida no while for falsa a execução do laço é terminada e o controle é passado para a instrução seguinte a <code>do...while</code>.</p> + +<h3 id="Exemplo_2"><strong>Exemplo</strong></h3> + +<p>No exemplo a seguir, o laço é executado pelo menos uma vez e irá executar até que <code>i</code> seja menor que 5.</p> + +<pre class="brush: js">do { + i += 1; + console.log(i); +} while (i < 5);</pre> + +<h2 id="while_statement" name="while_statement"><code>Declaração while</code></h2> + +<p>Uma declaração <a href="/pt-BR/docs/Web/JavaScript/Reference/Statements/while">while</a> executa suas instruções, desde que uma condição especificada seja avaliada como verdadeira. Segue uma declaração <code>while</code>: </p> + +<pre class="syntaxbox">while (condicao) + declaracao +</pre> + +<p>Se a condição se tornar falsa, a declaração dentro do laço para a execução e o controle é passado para a instrução após o laço.</p> + +<p>O teste da condição ocorre antes que o laço seja executado. Desta forma se a condição for verdadeira o laço executará e testará a condição novamente. Se a condição for falsa o laço termina e passa o controle para as instruções após o laço.</p> + +<p>Para executar múltiplas declarações, use uma declaração em bloco ({ ... }) para agrupar essas declarações.</p> + +<h3 id="Exemplo_1"><strong>Exemplo 1</strong></h3> + +<p>O <code>while</code> a seguir executará enquanto <code>n</code> for menor que três:</p> + +<pre class="brush: js">n = 0; +x = 0; +while (n < 3) { + n++; + x += n; +} +</pre> + +<p>A cada iteração, o laço incrementa <code>n</code> e adiciona este valor para <code>x</code>. Portanto, <code>x</code> e <code>n</code> recebem os seguintes valores:</p> + +<ul> + <li>Depois de executar pela primeira vez: <code>n</code> = 1 e <code>x</code> = 1</li> + <li>Depois da segunda vez: <code>n</code> = 2 e <code>x</code> = 3</li> + <li>Depois da terceira vez: <code>n</code> = 3 e <code>x</code> = 6</li> +</ul> + +<p>Depois de executar pela terceira vez, a condição <code>n < 3</code> não será mais verdadeira, então o laço encerrará.</p> + +<h3 id="Exemplo_2_2"><strong>Exemplo 2</strong></h3> + +<p>Evite laços infinitos. Tenha certeza que a condição do laço eventualmente será falsa; caso contrário, o laço nunca terminará. O while a seguir executará para sempre pois sua condição nunca será falsa:</p> + +<pre class="brush: js">while (true) { + console.log("Olá, mundo"); +}</pre> + +<h2 id="Declaração_label"><code>Declaração label</code></h2> + +<p>Um <a href="/pt-BR/docs/Web/JavaScript/Reference/Statements/label">label</a> provê um identificador que permite que este seja referenciado em outro lugar no seu programa. Por exemplo, você pode usar uma label para identificar um laço, e então usar <code>break</code> ou <code>continue</code> para indicar quando o programa deverá interromper o laço ou continuar sua execução.</p> + +<p>Segue a sintaxe da instrução label:</p> + +<pre class="syntaxbox">label : declaracao +</pre> + +<p>Um label pode usar qualquer idenficador que não seja uma palavra reservada do JavaScript. Você pode identificar qualquer instrução com um label.</p> + +<h3 id="Exemplo_3"><strong>Exemplo</strong></h3> + +<p>Neste exemplo, o label <code>markLoop</code> idenfica um laço <code>while</code>.</p> + +<pre class="brush: js">markLoop: +while (theMark == true) { + facaAlgo(); +}</pre> + +<h2 id="break_statement" name="break_statement"><code>Declaração break</code></h2> + +<p>Use <a href="/en-US/docs/Web/JavaScript/Reference/Statements/break">break</a> para terminar laços, <code>switch</code>, ou um conjunto que utiliza label.</p> + +<ul> + <li>Quando você utiliza <code>break</code> sem um label, ele encerrará imediatamente o laço mais interno <code>while</code>, <code>do-while</code>, <code>for</code>, ou <code>switch</code> e transferirá o controle para a próxima instrução.</li> + <li>Quando você utiliza <code>break</code> com um label, ele encerrará o label específico.</li> +</ul> + +<p>Segue a sintaxe do break:</p> + +<ol> + <li><code>break;</code></li> + <li><code>break <em>label</em>;</code></li> +</ol> + +<p>Na primeira opção será encerrado o laço de repetição mais interno ou <code>switch</code>. Já na segunda opção será encerrada o bloco de código referente a label.</p> + +<h3 id="Exemplo_1_2"><strong>Exemplo</strong> <strong>1</strong></h3> + +<p>O exemplo a seguir percorre os elementos de um array até que ele encontre o índice do elemento que possui o valor contido em <code>theValue</code>:</p> + +<pre class="brush: js">for (i = 0; i < a.length; i++) { + if (a[i] == theValue) { + break; + } +}</pre> + +<h3 id="Exemplo_2_Utilizando_break_em_label"><strong>Exemplo 2: </strong>Utilizando break em label</h3> + +<pre class="brush: js">var x = 0; +var z = 0 +labelCancelaLaco: while (true) { + console.log("Laço exterior: " + x); + x += 1; + z = 1; + while (true) { + console.log("Laço interior: " + z); + z += 1; + if (z === 10 && x === 10) { + break labelCancelaLaco; + } else if (z === 10) { + break; + } + } +} +</pre> + +<h2 id="continue_statement" name="continue_statement"><code>Declaração continue</code></h2> + +<p>A declaração <a href="/pt-BR/docs/Web/JavaScript/Reference/Statements/continue">continue</a> pode ser usada para reiniciar uma instrução <code>while</code>, <code>do-while</code>, <code>for</code>, ou <code>label</code>.</p> + +<ul> + <li>Quando você utiliza <code>continue</code> sem uma label, ele encerrará a iteração atual mais interna de uma instrução <code>while</code>, <code>do-while</code>, ou <code>for</code> e continuará a execução do laço a partir da próxima iteração. Ao contrário da instrução <code>break</code>, <code>continue</code> não encerra a execução completa do laço. Em um laço <code>while</code>, ele voltará para a condição. Em um laço <code>for</code>, ele pulará para a expressão de incrementação.</li> + <li>Quando você utiliza <code>continue</code> com uma label, o <code>continue</code> será aplicado ao laço identificado por esta label. </li> +</ul> + +<p>Segue a sintaxe do <code>continue</code>:</p> + +<ol> + <li><code>continue;</code></li> + <li><code>continue </code><em><code>label;</code></em></li> +</ol> + +<h3 id="Exemplo_1_3"><strong>Exemplo 1</strong></h3> + +<p>O exemplo a seguir mostra um laço <code>while</code> utlizando <code>continue</code> que executará quando o valor de <code>i</code> for igual a 3. Desta forma, <code>n</code> recebe os valores um, três, sete, e doze.</p> + +<pre class="brush: js">i = 0; +n = 0; +while (i < 5) { + i++; + if (i == 3) { + continue; + } + n += i; +} +</pre> + +<h3 id="Exemplo_2_3"><strong>Exemplo 2</strong></h3> + +<p>Uma instrução label <code>checkiandj</code> contém uma instrução label c<code>heckj</code>. Se o <code>continue</code> for executado, o programa terminará a iteração atual de <code>checkj</code> e começará a próxima iteração. Toda vez que o <code>continue</code> for executado, <code>checkj</code> recomeçará até que a condição do <code>while</code> for falsa. Quando isto ocorrer <code>checkiandj</code> executará até que sua condição seja falsa.</p> + +<p>Se o <code>continue</code> estivesse referenciando <code>checkiandj</code>, o programa deveria continuar do topo de <code>checkiandj</code>.</p> + +<pre class="brush: js">checkiandj: + while (i < 4) { + console.log(i); + i += 1; + checkj: + while (j > 4) { + console.log(j); + j -= 1; + if ((j % 2) == 0) { + continue checkj; + } + console.log(j + " é estranho."); + } + console.log("i = " + i); + console.log("j = " + j); + }</pre> + +<h2 id="for...in_statement" name="for...in_statement"><code>Declaração for...in</code></h2> + +<p>A declaração <a href="/pt-BR/docs/Web/JavaScript/Reference/Statements/for...in">for...in</a> executa iterações a partir de uma variável específica, percorrendo todas as propriedades de um objeto.<br> + Para cada propriedade distinta, o JavaScript executará uma iteração. Segue a sintaxe:</p> + +<pre class="syntaxbox">for (variavel in objeto) { + declaracoes +} +</pre> + +<h3 id="Exemplo_4"><strong>Exemplo</strong></h3> + +<p>A função a seguir recebe em seu argumento um objeto e o nome deste objeto. Então executará uma iteração para cada elemento e retornará uma lista de string, que irá conter o nome da propriedade e seu valor.</p> + +<pre class="brush: js">function dump_props(obj, obj_name) { + var result = ""; + for (var i in obj) { + result += obj_name + "." + i + " = " + obj[i] + "<br>"; + } + result += "<hr>"; + return result; +} +</pre> + +<p>Para um objeto chamado <code>car</code> com propriedades <code>make</code> e <code>model</code>, o resultado será:</p> + +<pre class="brush: js">car.make = Ford +car.model = Mustang +</pre> + +<h3 id="Arrays"><strong>Arrays</strong></h3> + +<p>Embora seja tentador usar esta forma para interagir com os elementos de um Array, a declaração <strong>for...in</strong> irá retornar o nome pré-definido da propriedade ao invés do seu index numérico. Assim é melhor usar o tradicional <a href="/pt-BR/docs/Web/JavaScript/Reference/Statements/for">for</a> com index numérico quando interagir com arrays, pois o <strong>for...in</strong> interage com as propriedades definidas pelo programador ao invés dos elementos do array.</p> + +<h2 id="for...of_statement" name="for...of_statement">Declaração <code>for...of</code></h2> + +<p> A declaração for...of cria uma laço com objetos interativos ((incluindo, {{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, assim por conseguinte ), executando uma iteração para o valor de cada propriedade distinta.</p> + +<pre class="syntaxbox">for (<em>variavel</em> of <em>objeto</em>) { + <em>declaracoes +</em>}</pre> + +<p>O exemplo a seguir mostra a diferença entre o <code>for...of</code> e o <code><a href="/pt-BR/docs/Web/JavaScript/Reference/Statements/for...in">for...in</a></code>. Enquanto o <code>for...in</code> interage com o nome das propriedades, o <code>for...of</code> interage com o valor das propriedades.</p> + +<pre class="brush:js">let arr = [3, 5, 7]; +arr.foo = "hello"; + +for (let i in arr) { + console.log(i); // logs "0", "1", "2", "foo" +} + +for (let i of arr) { + console.log(i); // logs "3", "5", "7" +} +</pre> + +<p>{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}</p> diff --git a/files/pt-br/web/javascript/guide/meta_programming/index.html b/files/pt-br/web/javascript/guide/meta_programming/index.html new file mode 100644 index 0000000000..e1264f7bcc --- /dev/null +++ b/files/pt-br/web/javascript/guide/meta_programming/index.html @@ -0,0 +1,263 @@ +--- +title: Meta programação +slug: Web/JavaScript/Guide/Meta_programming +translation_of: Web/JavaScript/Guide/Meta_programming +--- +<div>{{jsSidebar("JavaScript Guide")}} {{Previous("Web/JavaScript/Guide/Iterators_and_Generators")}}</div> + +<p>Começando com ECMAScript 6, o JavaScript ganha suporte para os objetos {{jsxref("Proxy")}} e {{jsxref("Reflect")}}, permitindo você interceptar e definir o comportamento personalizado para operações fundamentais da linguagem (por exemplo, pesquisa de propriedade, atribuição, enumeração, invocação de função, etc). Com a ajuda destes dois objetos você será capaz de programar a nível <a href="https://pt.wikipedia.org/wiki/Metaprograma%C3%A7%C3%A3o">meta</a> em JavaScript.</p> + +<h2 id="Proxies">Proxies</h2> + +<p>Introduzido em ECMAScript 6, objetos {{jsxref("Proxy")}} permitem que você intercepte determinadas operações e implementar comportamentos personalizados. Por exemplo, receber uma propriedade em um objeto:</p> + +<pre class="brush: js notranslate">var handler = { + get: function(target, name){ + return name in target ? target[name] : 42; +}}; +var p = new Proxy({}, handler); +p.a = 1; +console.log(p.a, p.b); // 1, 42 +</pre> + +<p>O objeto Proxy define um <em>target</em> (um objeto vazio aqui) e um objeto <em>handler</em> em que um <code>get</code> <em>trap</em> é implementado. Aqui, um objeto que está em proxy não retornará indefinido quando receber propriedades indefinidas, mas, ao contrário, retornar o número 42.</p> + +<p>Exemplos adicionais estão disponíveis na página de referência de {{jsxref("Proxy")}} .</p> + +<h3 id="Terminologia">Terminologia</h3> + +<p>Os seguintes termos são usados quando se fala sobre a funcionalidade de proxies.</p> + +<dl> + <dt>{{jsxref("Global_Objects/Proxy/handler","handler","","true")}}</dt> + <dd>Espaço reservado de objeto que contenha traps.</dd> + <dt>traps</dt> + <dd>Os métodos que fornecem acesso de propriedade. Isto é análogo ao conceito de traps em sistemas operacionais.</dd> + <dt>target</dt> + <dd>Objeto que o proxy está virtualizando. Ele é frequentemente usado como backend de armazenamento para o proxy. Invariantes (semânticas que permanecem inalteradas) relativas a objetos que não podem ser extendidos ou propriedades que não podem ser configuradas são comparadas com o target. </dd> + <dt>invariantes</dt> + <dd>Semânticas que permanecem inalteradas na execução de operações personalizadas são chamados de <em>invariantes</em>. Se você violar as invariantes de um manipulador, um {{jsxref("TypeError")}} será lançado.</dd> +</dl> + +<h2 id="Handlers_e_traps">Handlers e traps</h2> + +<p>A tabela a seguir resume as traps disponíveis aos objetos do tipo Proxy. Veja as <a href="/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler">páginas de referência</a> para explicações detalhadas e exemplos.</p> + +<table class="standard-table"> + <thead> + <tr> + <th>Handler / trap</th> + <th>Interceptions</th> + <th>Invariants</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}</td> + <td>{{jsxref("Object.getPrototypeOf()")}}<br> + {{jsxref("Reflect.getPrototypeOf()")}}<br> + {{jsxref("Object/proto", "__proto__")}}<br> + {{jsxref("Object.prototype.isPrototypeOf()")}}<br> + {{jsxref("Operators/instanceof", "instanceof")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li>O método <code>getPrototypeOf</code> deve retornar um object ou <code>null</code>.</li> + <li><font face="Open Sans, arial, sans-serif">Se </font><code>target</code> não puder ser extendido, o método <code>Object.getPrototypeOf(proxy)</code> deve retornar o mesmo valor que <code>Object.getPrototypeOf(target)</code>.</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}</td> + <td>{{jsxref("Object.setPrototypeOf()")}}<br> + {{jsxref("Reflect.setPrototypeOf()")}}</td> + <td> + <p>Se <code>target </code>não puder ser extendido, o parâmetro <code>prototype </code>dever ter o mesmo valor que <code>Object.getPrototypeOf(target)</code>.</p> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}</td> + <td>{{jsxref("Object.isExtensible()")}}<br> + {{jsxref("Reflect.isExtensible()")}}</td> + <td><code>Object.isExtensible(proxy)</code> deve retornar o mesmo valor que <code>Object.isExtensible(target)</code>.</td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}</td> + <td>{{jsxref("Object.preventExtensions()")}}<br> + {{jsxref("Reflect.preventExtensions()")}}</td> + <td><code>Object.preventExtensions(proxy)</code> retorna <code>true</code> somente se <code>Object.isExtensible(proxy)</code> retornar <code>false</code>.</td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}</td> + <td>{{jsxref("Object.getOwnPropertyDescriptor()")}}<br> + {{jsxref("Reflect.getOwnPropertyDescriptor()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li><code>getOwnPropertyDescriptor</code> deve retornar um object ou <code>undefined</code>.</li> + <li>Uma propriedade não pode ser descrita como não existente se ela existir como uma propriedade própria e não configurável do objeto alvo.</li> + <li>Uma propriedade não pode ser relatada como inexistente, se existir como uma propriedade própria do objeto de destino e o objeto de destino não for extensível.</li> + <li>Uma propriedade não pode ser relatada como existente, se não existir como uma propriedade própria do objeto de destino e o objeto de destino não for extensível.</li> + <li>Uma propriedade não pode ser relatada como não configurável, se não existir como uma propriedade própria do objeto de destino ou se existir como uma propriedade própria configurável do objeto de destino.</li> + <li>O resultado de <code>Object.getOwnPropertyDescriptor(target)</code> pode ser aplicado ao objeto de destino usando <code>Object.defineProperty</code> e não emitirá uma exceção.</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}</td> + <td>{{jsxref("Object.defineProperty()")}}<br> + {{jsxref("Reflect.defineProperty()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li>Uma propriedade não pode ser adicionada se o objeto de destino não for extensível.</li> + <li>Uma propriedade não pode ser adicionada como ou modificada para não ser configurável, se não existir como uma propriedade própria não configurável do objeto de destino.</li> + <li>Uma propriedade pode não ser não configurável, se existir uma propriedade configurável correspondente do objeto de destino.</li> + <li>Se uma propriedade tiver uma propriedade de objeto de destino correspondente <code>Object.defineProperty(target, prop, descriptor)</code> não lançará uma exceção.</li> + <li>No modo estrito, um valor de retorno <code>false</code> do manipulador <code>defineProperty</code> manipulador lançará um {{jsxref("TypeError")}} exceção.</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}</td> + <td>Property query: <code>foo in proxy</code><br> + Inherited property query: <code>foo in Object.create(proxy)</code><br> + {{jsxref("Reflect.has()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li>Uma propriedade não pode ser relatada como inexistente, se existir como uma propriedade própria não configurável do objeto de destino.</li> + <li>Uma propriedade não pode ser relatada como inexistente, se existir como uma propriedade própria do objeto de destino e o objeto de destino não for extensível.</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}</td> + <td>Property access: <code>proxy[foo]</code>and <code>proxy.bar</code><br> + Inherited property access: <code>Object.create(proxy)[foo]</code><br> + {{jsxref("Reflect.get()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li>O valor relatado para uma propriedade deve ser igual ao valor da propriedade do objeto de destino correspondente se a propriedade do objeto de destino for uma propriedade de dados não gravável e não configurável.</li> + <li>O valor relatado para uma propriedade deve ser indefinido se a propriedade do objeto de destino correspondente for uma propriedade acessora não configurável que tenha sido indefinida como seu atributo [[Get]].</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}</td> + <td>Property assignment: <code>proxy[foo] = bar</code> and <code>proxy.foo = bar</code><br> + Inherited property assignment: <code>Object.create(proxy)[foo] = bar</code><br> + {{jsxref("Reflect.set()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li>Não é possível alterar o valor de uma propriedade para ser diferente do valor da propriedade do objeto de destino correspondente se a propriedade do objeto de destino correspondente for uma propriedade de dados não gravável e não configurável.</li> + <li>Não é possível definir o valor de uma propriedade se a propriedade do objeto de destino correspondente for uma propriedade acessadora não configurável que tenha <code>undefined</code> como seu atributo [[Set]].</li> + <li>No modo estrito, um valor de retorno <code>false</code> do manipulador <code>set</code> lançará uma exceção {{jsxref ("TypeError")}}}.</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}</td> + <td>Property deletion: <code>delete proxy[foo]</code> and <code>delete proxy.foo</code><br> + {{jsxref("Reflect.deleteProperty()")}}</td> + <td>Uma propriedade não pode ser excluída, se existir como uma propriedade própria não configurável do objeto de destino.</td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/enumerate", "handler.enumerate()")}}</td> + <td>Property enumeration / for...in: <code>for (var name in proxy) {...}</code><br> + {{jsxref("Reflect.enumerate()")}}</td> + <td> + <p><span>O método </span><code>enumerate</code><span> deve retornar um objeto.</span></p> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}</td> + <td>{{jsxref("Object.getOwnPropertyNames()")}}<br> + {{jsxref("Object.getOwnPropertySymbols()")}}<br> + {{jsxref("Object.keys()")}}<br> + {{jsxref("Reflect.ownKeys()")}}</td> + <td> + <ul style="padding-left: 20px; margin: 5px;"> + <li>O resultado de <code>ownKeys</code> é uma lista.</li> + <li>O tipo de cada elemento da lista de resultados é {{jsxref ("String")}} ou {{jsxref ("Symbol")}}.</li> + <li>A lista de resultados deve conter as chaves de todas as propriedades próprias não configuráveis do objeto de destino.</li> + <li>Se o objeto de destino não for extensível, a Lista de resultados deverá conter todas as chaves das próprias propriedades do objeto de destino e nenhum outro valor.</li> + </ul> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}</td> + <td><code>proxy(..args)</code><br> + {{jsxref("Function.prototype.apply()")}} and {{jsxref("Function.prototype.call()")}}<br> + {{jsxref("Reflect.apply()")}}</td> + <td> + <p>Não há invariantes para o método <code>handler.apply</code></p> + </td> + </tr> + <tr> + <td>{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}</td> + <td><code>new proxy(...args)</code><br> + {{jsxref("Reflect.construct()")}}</td> + <td>O resultado deve ser um <code>Object</code>.</td> + </tr> + </tbody> +</table> + +<h2 id="Proxy_Revogável">Proxy Revogável</h2> + +<p>O método {{jsxref("Proxy.revocable()")}} é utilizado para criar um objeto Proxy revogável. Isso significa que o proxy pode ser revogado através da função <code>revoke</code>, desligando-o. Depois disso, qualquer operação com o proxy lançará um {{jsxref("TypeError")}}.</p> + +<pre class="brush: js notranslate">var revocable = Proxy.revocable({}, { + get: function(target, name) { + return "[[" + name + "]]"; + } +}); +var proxy = revocable.proxy; +console.log(proxy.foo); // "[[foo]]" + +revocable.revoke(); + +console.log(proxy.foo); // TypeError é lançado +proxy.foo = 1 // TypeError novamente +delete proxy.foo; // ainda um TypeError +typeof proxy // "object", typeof não desencadeia nenhuma trap</pre> + +<h2 id="Reflexão">Reflexão</h2> + +<p>{{jsxref("Reflect")}} é um objeto embutido que contém métodos que permitem a criação de operações interceptáveis em JavaScript. Os métodos são iguais àqueles de {{jsxref("Global_Objects/Proxy/handler","proxy handlers","","true")}}. <code>Reflect </code>não é um objeto do tipo function.</p> + +<p><code>Reflect </code>auxilia no encaminhamento de operações padrão do handler para o target.</p> + +<p>{{jsxref("Reflect.has()")}}, por exemplo, tem o mesmo efeito prático que o operador in, com a facilidade de ser utilizado como uma função:</p> + +<pre class="brush: js notranslate">Reflect.has(Object, "assign"); // true +</pre> + +<h3 id="Uma_função_apply_melhorada">Uma função <code>apply </code>melhorada</h3> + +<p>Em ES5, você normalmente utiliza o método {{jsxref("Function.prototype.apply()")}} para invocar uma função com um dado valor para <code>this</code> e <code>arguments</code> fornecido como um array (ou um <a href="/pt-BR/docs/Web/JavaScript/Guide/Indexed_collections#Working_with_array-like_objects">objeto parecido com um array</a>).</p> + +<pre class="brush: js notranslate">Function.prototype.apply.call(Math.floor, undefined, [1.75]);</pre> + +<p>Com {{jsxref("Reflect.apply")}} essa operação se torna menos verbosa e mais fácil de compreender:</p> + +<pre class="brush: js notranslate">Reflect.apply(Math.floor, undefined, [1.75]); +// 1; + +Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]); +// "hello" + +Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index; +// 4 + +Reflect.apply("".charAt, "ponies", [3]); +// "i" +</pre> + +<h3 id="Verificando_se_a_definição_da_propriedade_obteve_sucesso">Verificando se a definição da propriedade obteve sucesso</h3> + +<p>Com {{jsxref("Object.defineProperty")}}, a qual returna um <code>object</code> em caso de sucesso ou lança um {{jsxref("TypeError")}} em caso contrário, você utilizaria um bloco {{jsxref("Statements/try...catch","try...catch")}} para capturar qualquer erro que tenha ocorrido ao definir uma propriedade. Devido ao fato de {{jsxref("Reflect.defineProperty")}} retornar um status do tipo <code>Boolean</code>, você pode simplesmente utilizar aqui um bloco {{jsxref("Statements/if...else","if...else")}}:</p> + +<pre class="brush: js notranslate">if (Reflect.defineProperty(target, property, attributes)) { + // success +} else { + // failure +}</pre> + +<p>{{Previous("Web/JavaScript/Guide/Iterators_and_Generators")}}</p> diff --git a/files/pt-br/web/javascript/guide/módulos/index.html b/files/pt-br/web/javascript/guide/módulos/index.html new file mode 100644 index 0000000000..6a2cb73687 --- /dev/null +++ b/files/pt-br/web/javascript/guide/módulos/index.html @@ -0,0 +1,454 @@ +--- +title: Módulos JavaScript +slug: Web/JavaScript/Guide/Módulos +translation_of: Web/JavaScript/Guide/Modules +--- +<div>{{JSSidebar("JavaScript Guide")}}{{Previous("Web/JavaScript/Guide/Meta_programming")}}</div> + +<p>Este guia fornece tudo o que você precisa para começar com a sintaxe de módulo do JavaScript.</p> + +<h2 id="Um_background_em_módulos">Um background em módulos</h2> + +<p>Os programas JavaScript começaram muito pequenos - a maior parte do seu uso nos primeiros dias era para executar tarefas isoladas de script, fornecendo um pouco de interatividade às suas páginas da Web sempre que necessário, de modo que scripts grandes geralmente não eram necessários. Com o avanço rápido da tecnologia agora temos aplicativos completos sendo executados em navegadores com muito JavaScript, além de JavaScript ser usado em outros contextos (<a href="/en-US/docs/Glossary/Node.js">Node.js</a>, por exemplo).</p> + +<p>Portanto, fez sentido nos últimos anos começar a pensar em fornecer mecanismos para dividir programas JavaScript em módulos separados que podem ser importados quando necessário. O Node.js possui essa capacidade há muito tempo e existem várias bibliotecas e estruturas JavaScript que permitem o uso do módulo (por exemplo, outros <a href="https://en.wikipedia.org/wiki/CommonJS">CommonJS</a> e <a href="https://github.com/amdjs/amdjs-api/blob/master/AMD.md">AMD</a>-sistemas de módulos baseados em <a href="https://requirejs.org/">RequireJS</a>, e mais recentemente <a href="https://webpack.github.io/">Webpack</a> e <a href="https://babeljs.io/">Babel</a>).</p> + +<p>A boa notícia é que os navegadores modernos começaram a dar suporte nativamente à funcionalidade do módulo, e é sobre isso que este artigo trata. Isso só pode ser uma coisa boa - os navegadores podem otimizar o carregamento de módulos, tornando-o mais eficiente do que ter que usar uma biblioteca e fazer todo esse processamento extra no lado do cliente e viagens de ida e volta extras.</p> + +<h2 id="Suporte_do_navegador">Suporte do navegador</h2> + +<p>O uso de módulos JavaScript nativos depende do{{JSxRef("Statements/import", "import")}} e {{JSxRef("Statements/export", "export")}} afirmações; estes são suportados nos navegadores da seguinte maneira:</p> + +<h3 id="importa">importa</h3> + +<p>{{Compat("javascript.statements.import")}}</p> + +<h3 id="exporta">exporta</h3> + +<p>{{Compat("javascript.statements.export")}}</p> + +<h2 id="Apresentando_um_exemplo">Apresentando um exemplo</h2> + +<p>Para demonstrar o uso dos módulos, criamos um <a href="https://github.com/mdn/js-examples/tree/master/modules">conjunto simples de exemplos</a> que você pode encontrar no GitHub. Estes exemplos demonstram um conjunto simples de módulos que criam um<a href="/en-US/docs/Web/HTML/Element/canvas" title="Use the HTML <canvas> element with either the canvas scripting API or the WebGL API to draw graphics and animations."><code><canvas></code></a> em uma página da Web e desenhe (e relate informações sobre) formas diferentes na tela.</p> + +<p>Estes são bastante triviais, mas foram mantidos deliberadamente simples para demonstrar claramente os módulos.</p> + +<div class="blockIndicator note"> +<p><strong>Nota: Se você deseja fazer o download dos exemplos e executá-los localmente, precisará executá-los por meio de um servidor da web local.</strong></p> +</div> + +<h2 id="Exemplo_de_uma_estrutura_básica">Exemplo de uma estrutura básica</h2> + +<p>No nosso primeiro exemplo (consulte <a href="https://github.com/mdn/js-examples/tree/master/modules/basic-modules">basic-modules</a>) nós temos uma estrutura de arquivos da seguinte maneira:</p> + +<pre class="notranslate">index.html +main.js +modules/ + canvas.js + square.js</pre> + +<div class="blockIndicator note"> +<p><strong>Nota: Todos os exemplos neste guia têm basicamente a mesma estrutura; o exposto acima deve começar a ficar bem familiar.</strong></p> +</div> + +<p>Os dois módulos do diretório modules são descritos abaixo:</p> + +<ul> + <li><code>canvas.js</code> — contém funções relacionadas à configuração da tela: + + <ul> + <li><code>create()</code> — cria uma tela com uma largura e altura especificadas dentro de um invólucro <a href="/en-US/docs/Web/HTML/Element/div" title="The HTML Content Division element (<div>) is the generic container for flow content. It has no effect on the content or layout until styled using CSS."><code><div></code></a> com um ID especificado, que é anexado dentro de um elemento pai especificado. Retorna um objeto que contém o contexto 2D da tela e o ID do <a href="https://developer.mozilla.org/pt-BR/docs/Glossario/Wrapper">wrapper</a>.</li> + <li><code>createReportList()</code> — cria uma lista não ordenada anexada dentro de um elemento de wrapper especificado, que pode ser usado para gerar dados de relatório. Retorna o ID da lista.</li> + </ul> + </li> + <li><code>square.js</code> — contém: + <ul> + <li><code>name</code> — uma constante contendo a string 'square'.</li> + <li><code>draw()</code> — desenha um quadrado em uma tela especificada, com um tamanho, posição e cor especificados. Retorna um objeto que contém o tamanho, a posição e a cor do quadrado.</li> + <li><code>reportArea()</code> — grava a área de um quadrado em uma lista de relatórios específica, considerando seu tamanho.</li> + <li><code>reportPerimeter()</code> — grava o perímetro de um quadrado em uma lista de relatórios específica, considerando seu comprimento.</li> + </ul> + </li> +</ul> + +<h2 id="Aside_—_.mjs_versus_.js">Aside — <code>.mjs</code> versus <code>.js</code></h2> + +<p>Neste artigo, usamos extensões .js para nossos arquivos de módulo, mas em outros recursos você pode ver a extensão .mjs usada. <a href="https://v8.dev/features/modules#mjs">A documentação da V8 recomenda isso</a>, por exemplo. Os motivos apresentados são:</p> + +<ul> + <li>É bom para maior clareza, ou seja, deixa claro quais arquivos são módulos e quais são JavaScript regulares.</li> + <li>Ele garante que seus arquivos de módulo sejam analisados como um módulo por tempos de execução, como <a href="https://nodejs.org/api/esm.html#esm_enabling">Node.js</a>, e construir ferramentas como <a href="https://babeljs.io/docs/en/options#sourcetype">Babel</a>.</li> +</ul> + +<p>No entanto, decidimos continuar usando .js, pelo menos por enquanto. Para que os módulos funcionem corretamente em um navegador, você precisa garantir que seu servidor os esteja servindo com um cabeçalho Content-Type que contenha um tipo MIME JavaScript, como text / javascript. Caso contrário, você receberá um erro estrito de verificação do tipo MIME, de acordo com as linhas "O servidor respondeu com um tipo MIME não JavaScript" e o navegador não executará seu JavaScript. A maioria dos servidores já define o tipo correto para arquivos .js, mas ainda não para arquivos .mjs. Servidores que já veiculam arquivos .mjs incluem corretamente <a href="https://pages.github.com/">GitHub Pages</a> e <code><a href="https://github.com/http-party/http-server#readme">http-server</a></code> para Node.js.</p> + +<p>Tudo bem se você já estiver usando esse ambiente ou se não estiver, mas souber o que está fazendo e tiver acesso (ou seja, você pode configurar o servidor para definir a configuração correta <code><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type">Content-Type</a></code> para arquivos <code>.mjs</code>). No entanto, isso pode causar confusão se você não controlar o servidor do qual está servindo arquivos ou publicar arquivos para uso público, como estamos aqui.</p> + +<p>Para fins de aprendizado e portabilidade, decidimos manter o<code>.js</code>.</p> + +<p>Se você realmente valoriza a clareza de usar .mjs para módulos versus usar .js para arquivos JavaScript "normais", mas não deseja se deparar com o problema descrito acima, sempre poderá usar .mjs durante o desenvolvimento e convertê-los em .js durante sua etapa de construção.</p> + +<p>Também é importante notar que:</p> + +<ul> + <li>Algumas ferramentas podem nunca suportar .mjs, como<a href="https://www.typescriptlang.org/">TypeScript</a>.</li> + <li>O atributo <code><script type="module"></code>é usado para indicar quando um módulo está sendo apontado, como você verá abaixo.</li> +</ul> + +<h2 id="Exportando_recursos_do_módulo">Exportando recursos do módulo</h2> + +<p>A primeira coisa que você faz para obter acesso aos recursos do módulo é exportá-los. Isso é feito usando o {{JSxRef("Statements/export", "export")}} declaração.</p> + +<p>A maneira mais fácil de usá-lo é colocá-lo na frente de qualquer item que você queira exportar para fora do módulo, por exemplo:</p> + +<pre class="brush: js; notranslate">export const name = 'square'; + +export function draw(ctx, length, x, y, color) { + ctx.fillStyle = color; + ctx.fillRect(x, y, length, length); + + return { + length: length, + x: x, + y: y, + color: color + }; +}</pre> + +<p>Você pode exportar funções, <code>var</code>, <code>let</code>, <code>const</code>, e — como veremos mais tarde - classes. Eles precisam ser itens de nível superior; você não pode usar a exportação dentro de uma função, por exemplo.</p> + +<p>Uma maneira mais conveniente de exportar todos os itens que você deseja exportar é usar uma única instrução de exportação no final do arquivo do módulo, seguida por uma lista separada por vírgula dos recursos que você deseja exportar envoltos em chaves. Por exemplo:</p> + +<pre class="brush: js; notranslate">export { name, draw, reportArea, reportPerimeter };</pre> + +<h2 id="Importando_recursos_para_o_seu_script">Importando recursos para o seu script</h2> + +<p>Depois de exportar alguns recursos do seu módulo, é necessário importá-los para o script para poder usá-los. A maneira mais simples de fazer isso é a seguinte:</p> + +<pre class="brush: js notranslate">import { name, draw, reportArea, reportPerimeter } from './modules/square.js';</pre> + +<p>Você usa o {{JSxRef("Statements/import", "import")}} , seguida por uma lista separada por vírgula dos recursos que você deseja importar agrupados em chaves, seguidos pela palavra-chave de, seguida pelo caminho para o arquivo do módulo - um caminho relativo à raiz do site, que para nossa <code>basic-modules</code> exemplo seria<code>/js-examples/modules/basic-modules</code>.</p> + +<p>No entanto, escrevemos o caminho de maneira um pouco diferente - estamos usando a sintaxe de ponto (.) Para significar "o local atual", seguido pelo caminho além do arquivo que estamos tentando encontrar. Isso é muito melhor do que escrever todo o caminho relativo a cada vez, pois é mais curto e torna o URL portátil - o exemplo ainda funcionará se você o mover para um local diferente na hierarquia do site.</p> + +<p>Então, por exemplo:</p> + +<pre class="notranslate">/js-examples/modules/basic-modules/modules/square.js</pre> + +<p>torna-se</p> + +<pre class="notranslate">./modules/square.js</pre> + +<p>Você pode ver essas linhas em ação em <code><a href="https://github.com/mdn/js-examples/blob/master/modules/basic-modules/main.js">main.js</a></code>.</p> + +<div class="blockIndicator note"> +<p><strong>Nota: Em alguns sistemas de módulos, você pode omitir a extensão do arquivo e o ponto</strong>(e.g. <code>'/modules/square'</code>). Isso não funciona nos módulos JavaScript nativos.</p> +</div> + +<p>Depois de importar os recursos para o seu script, você pode usá-los exatamente como eles foram definidos no mesmo arquivo. O seguinte é encontrado em<br> + <code>main.js</code>, abaixo das linhas de importação:</p> + +<pre class="brush: js; notranslate">let myCanvas = create('myCanvas', document.body, 480, 320); +let reportList = createReportList(myCanvas.id); + +let square1 = draw(myCanvas.ctx, 50, 50, 100, 'blue'); +reportArea(square1.length, reportList); +reportPerimeter(square1.length, reportList); +</pre> + +<div class="blockIndicator note"> +<p><strong>Nota: Embora os recursos importados estejam disponíveis no arquivo, eles são visualizações somente leitura do recurso que foi exportado. Você não pode alterar a variável importada, mas ainda pode modificar propriedades semelhantes à const. Além disso, esses recursos são importados como ligações ativas, o que significa que eles podem mudar de valor mesmo que você não possa modificar a ligação ao contrário de const.</strong></p> +</div> + +<h2 id="Aplicando_o_módulo_ao_seu_HTML">Aplicando o módulo ao seu HTML</h2> + +<p>Agora, apenas precisamos aplicar o módulo main.js. à nossa página HTML. Isso é muito semelhante ao modo como aplicamos um script regular a uma página, com algumas diferenças notáveis.</p> + +<p>Primeiro de tudo, você precisa incluir <code>type="module"</code> no <a href="/en-US/docs/Web/HTML/Element/script" title="The HTML <script> element is used to embed or reference executable code; this is typically used to embed or refer to JavaScript code."><code><script></code></a> elemento, para declarar esse script como um módulo. Para importar o <code>main.js</code> script, usamos este:</p> + +<pre class="brush: html; no-line-numbers notranslate"><script type="module" src="main.js"></script></pre> + +<p>Você também pode incorporar o script do módulo diretamente no arquivo HTML, colocando o código JavaScript no corpo do elemento <script>:</p> + +<pre class="brush: js notranslate"><script type="module"> + /* JavaScript module code here */ +</script></pre> + +<p>O script para o qual você importa os recursos do módulo atua basicamente como o módulo de nível superior. Se você o omitir, o Firefox, por exemplo, exibirá um erro "SyntaxError: as declarações de importação podem aparecer apenas no nível superior de um módulo".</p> + +<p>Você só pode usar <code>import</code> e <code>export</code> instruções dentro de módulos, não scripts regulares.</p> + +<h2 id="Outras_diferenças_entre_módulos_e_scripts_padrão">Outras diferenças entre módulos e scripts padrão</h2> + +<ul> + <li>Você precisa prestar atenção nos testes locais - se você tentar carregar o arquivo HTML localmente (i.e. com um arquivo<code>://</code> URL), você encontrará erros do CORS devido a requisitos de segurança do módulo JavaScript. Você precisa fazer seus testes através de um servidor.</li> + <li>Além disso, observe que você pode obter um comportamento diferente das seções de script definidas dentro dos módulos e não nos scripts padrão. Isso ocorre porque os módulos usam {{JSxRef("Strict_mode", "strict mode", "", 1)}} automaticamente.</li> + <li>Não há necessidade de usar o atributo deferir (consulte <a href="/en-US/docs/Web/HTML/Element/script#Attributes" title="The HTML <script> element is used to embed or reference executable code; this is typically used to embed or refer to JavaScript code."><code><script></code> attributes</a>) ao carregar um script de módulo; módulos são adiados automaticamente.</li> + <li>Os módulos são executados apenas uma vez, mesmo que tenham sido referenciados em várias tags <script>.</li> + <li>Por último, mas não menos importante, vamos esclarecer: os recursos do módulo são importados para o escopo de um único script - eles não estão disponíveis no escopo global. Portanto, você poderá acessar apenas os recursos importados no script para o qual eles foram importados e não poderá acessá-los no console JavaScript, por exemplo. Você ainda receberá erros de sintaxe mostrados no DevTools, mas não poderá usar algumas das técnicas de depuração que você esperava usar.</li> +</ul> + +<h2 id="Exportações_padrão_versus_exportações_nomeadas">Exportações padrão versus exportações nomeadas</h2> + +<p>A funcionalidade que exportamos até agora foi composta por <strong>named exports</strong> — cada item (seja uma função, const, etc.) foi referido por seu nome na exportação e esse nome também foi usado para se referir a ele na importação.</p> + +<p>Há também um tipo de exportação chamado <strong>default export</strong> — isso foi projetado para facilitar a função padrão fornecida por um módulo e também ajuda os módulos JavaScript a interoperar com os sistemas de módulos CommonJS e AMD existentes (conforme explicado em <a href="https://hacks.mozilla.org/2015/08/es6-in-depth-modules/">ES6 In Depth: Modules</a> por Jason Orendorff; procure por "Exportações padrão").</p> + +<p>Vejamos um exemplo ao explicar como ele funciona. Nos nossos módulos básicos <code>square.js</code> você pode encontrar uma função chamada <code>randomSquare()</code> que cria um quadrado com cor, tamanho e posição aleatórios. Queremos exportar isso como padrão, portanto, na parte inferior do arquivo, escrevemos isso:</p> + +<pre class="brush: js; notranslate">export default randomSquare;</pre> + +<p>Note a falta dos colchetes.</p> + +<p>Em vez disso, poderíamos acrescentar <code>export default</code> na função e defina-a como uma função anônima, assim:</p> + +<pre class="brush: js; notranslate">export default function(ctx) { + ... +}</pre> + +<p>No nosso arquivo main.js., importamos a função padrão usando esta linha:</p> + +<pre class="brush: js; notranslate">import randomSquare from './modules/square.js';</pre> + +<p>Isso ocorre porque há apenas uma exportação padrão permitida por módulo e sabemos que <em>randomSquare</em> é isso.</p> + +<pre class="brush: js; notranslate">import {default as randomSquare} from './modules/square.js';</pre> + +<div class="blockIndicator note"> +<p><strong>Nota: A sintaxe as para renomear itens exportados é explicada abaixo no </strong><a href="#Renaming_imports_and_exports">Renaming imports and exports</a> seção.</p> +</div> + +<h2 id="Evitando_conflitos_de_nomenclatura">Evitando conflitos de nomenclatura</h2> + +<p>Até agora, nossos módulos de desenho de forma de tela parecem estar funcionando bem. Mas o que acontece se tentarmos adicionar um módulo que lide com o desenho de outra forma, como um círculo ou triângulo? Essas formas provavelmente teriam funções associadas, como <code>draw()</code>, <code>reportArea()</code>, etc. também; se tentássemos importar diferentes funções com o mesmo nome para o mesmo arquivo de módulo de nível superior, acabaríamos com conflitos e erros.</p> + +<p>Felizmente, existem várias maneiras de contornar isso. Veremos isso nas próximas seções.</p> + +<h2 id="Renomeando_importações_e_exportações">Renomeando importações e exportações</h2> + +<p>Dentro dos colchetes da instrução de importação e exportação, você pode usar a palavra-chave junto com um novo nome de recurso, para alterar o nome de identificação que será usado para um recurso dentro do módulo de nível superior.</p> + +<p>Por exemplo, os dois itens a seguir executariam o mesmo trabalho, embora de uma maneira ligeiramente diferente:</p> + +<pre class="brush: js; notranslate">// inside module.js +export { + function1 as newFunctionName, + function2 as anotherNewFunctionName +}; + +// inside main.js +import { newFunctionName, anotherNewFunctionName } from './modules/module.js';</pre> + +<pre class="brush: js; notranslate">// inside module.js +export { function1, function2 }; + +// inside main.js +import { function1 as newFunctionName, + function2 as anotherNewFunctionName } from './modules/module.js';</pre> + +<p>Vejamos um exemplo real. Na nossa <a href="https://github.com/mdn/js-examples/tree/master/modules/renaming">renaming</a> diretório, você verá o mesmo sistema de módulos do exemplo anterior, exceto que adicionamos <code>circle.js</code> e <code>triangle.js</code> módulos para desenhar e relatar círculos e triângulos.</p> + +<p>Dentro de cada um desses módulos, temos recursos com os mesmos nomes sendo exportados e, portanto, cada um tem o mesmo <code>export</code> declaração na parte inferior:</p> + +<pre class="brush: js; notranslate">export { name, draw, reportArea, reportPerimeter };</pre> + +<p>Ao importá-los para o main.js, se tentarmos usar</p> + +<pre class="brush: js; notranslate">import { name, draw, reportArea, reportPerimeter } from './modules/square.js'; +import { name, draw, reportArea, reportPerimeter } from './modules/circle.js'; +import { name, draw, reportArea, reportPerimeter } from './modules/triangle.js';</pre> + +<p>O navegador geraria um erro como "SyntaxError: redeclaration of import name" (Firefox).</p> + +<p>Em vez disso, precisamos renomear as importações para que sejam únicas:</p> + +<pre class="brush: js; notranslate">import { name as squareName, + draw as drawSquare, + reportArea as reportSquareArea, + reportPerimeter as reportSquarePerimeter } from './modules/square.js'; + +import { name as circleName, + draw as drawCircle, + reportArea as reportCircleArea, + reportPerimeter as reportCirclePerimeter } from './modules/circle.js'; + +import { name as triangleName, + draw as drawTriangle, + reportArea as reportTriangleArea, + reportPerimeter as reportTrianglePerimeter } from './modules/triangle.js';</pre> + +<p>Observe que você pode resolver o problema nos arquivos do módulo, e.g.</p> + +<pre class="brush: js; notranslate">// in square.js +export { name as squareName, + draw as drawSquare, + reportArea as reportSquareArea, + reportPerimeter as reportSquarePerimeter };</pre> + +<pre class="brush: js; notranslate">// in main.js +import { squareName, drawSquare, reportSquareArea, reportSquarePerimeter } from './modules/square.js';</pre> + +<p>E funcionaria da mesma forma. Qual o estilo que você usa depende de você, no entanto, sem dúvida faz mais sentido deixar o código do módulo em paz e fazer as alterações nas importações. Isso faz especialmente sentido quando você está importando de módulos de terceiros sobre os quais você não tem controle.</p> + +<p>24/5000</p> + +<p>Criando um objeto de módulo</p> + +<p>O método acima funciona bem, mas é um pouco confuso e longo. Uma solução ainda melhor é importar os recursos de cada módulo dentro de um objeto de módulo. O seguinte formulário de sintaxe faz isso:</p> + +<pre class="brush: js; notranslate">import * as Module from './modules/module.js';</pre> + +<p>Isso captura todas as exportações disponíveis no module.js e as torna disponíveis como membros de um objeto <code>Module</code>, efetivamente dando o seu próprio namespace. Então, por exemplo:</p> + +<pre class="brush: js; notranslate">Module.function1() +Module.function2() +etc.</pre> + +<p>Novamente, vejamos um exemplo real. Se você for ao nosso <a href="https://github.com/mdn/js-examples/tree/master/modules/module-objects">module-objects</a> diretório, você verá o mesmo exemplo novamente, mas reescrito para aproveitar essa nova sintaxe. Nos módulos, as exportações são todas da seguinte forma simples:</p> + +<pre class="brush: js; notranslate">export { name, draw, reportArea, reportPerimeter };</pre> + +<p>As importações, por outro lado, são assim:</p> + +<pre class="brush: js; notranslate">import * as Canvas from './modules/canvas.js'; + +import * as Square from './modules/square.js'; +import * as Circle from './modules/circle.js'; +import * as Triangle from './modules/triangle.js';</pre> + +<p>Em cada caso, agora você pode acessar as importações do módulo abaixo do nome do objeto especificado, por exemplo:</p> + +<pre class="brush: js; notranslate">let square1 = Square.draw(myCanvas.ctx, 50, 50, 100, 'blue'); +Square.reportArea(square1.length, reportList); +Square.reportPerimeter(square1.length, reportList);</pre> + +<p>Agora você pode escrever o código da mesma forma que antes (contanto que inclua os nomes dos objetos quando necessário) e as importações sejam muito mais limpas.</p> + +<h2 id="Módulos_e_classes">Módulos e classes</h2> + +<p>Como sugerimos anteriormente, você também pode exportar e importar classes; essa é outra opção para evitar conflitos no seu código e é especialmente útil se você já tiver o código do módulo gravado em um estilo orientado a objetos.</p> + +<p>Você pode ver um exemplo do nosso módulo de desenho de forma reescrito com as classes ES em nosso <a href="https://github.com/mdn/js-examples/tree/master/modules/classes">classes</a> diretório. Como exemplo, o <code><a href="https://github.com/mdn/js-examples/blob/master/modules/classes/modules/square.js">square.js</a></code> O arquivo agora contém todas as suas funcionalidades em uma única classe:</p> + +<pre class="brush: js; notranslate">class Square { + constructor(ctx, listId, length, x, y, color) { + ... + } + + draw() { + ... + } + + ... +}</pre> + +<p>que exportamos então:</p> + +<pre class="brush: js; notranslate">export { Square };</pre> + +<p>No main.js, nós o importamos assim:</p> + +<pre class="brush: js; notranslate">import { Square } from './modules/square.js';</pre> + +<p>E então use a classe para desenhar nosso quadrado:</p> + +<pre class="brush: js; notranslate">let square1 = new Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue'); +square1.draw(); +square1.reportArea(); +square1.reportPerimeter();</pre> + +<h2 id="Módulos_de_agregação">Módulos de agregação</h2> + +<p>Haverá momentos em que você desejará agregar módulos. Você pode ter vários níveis de dependências, nos quais deseja simplificar as coisas, combinando vários submódulos em um módulo pai. Isso é possível usando a sintaxe de exportação dos seguintes formulários no módulo pai:</p> + +<pre class="brush: js; notranslate">export * from 'x.js' +export { name } from 'x.js'</pre> + +<p>Por exemplo, veja nosso <a href="https://github.com/mdn/js-examples/tree/master/modules/module-aggregation">module-aggregation</a> diretório. Neste exemplo (com base no exemplo de classes anteriores), temos um módulo extra chamado shapes.js, que agrega toda a funcionalidade de circle.js, square.js e triangle.js juntos. Também movemos nossos submódulos para dentro de um subdiretório dentro do diretório modules chamado shapes. Portanto, a estrutura do módulo neste exemplo é:</p> + +<pre class="notranslate">modules/ + canvas.js + shapes.js + shapes/ + circle.js + square.js + triangle.js</pre> + +<p>Em cada um dos submódulos, a exportação é da mesma forma, e.g.</p> + +<pre class="brush: js; notranslate">export { Square };</pre> + +<p>Em seguida, vem a parte de agregação. Dentro de shapes.js, incluímos as seguintes linhas:</p> + +<pre class="brush: js; notranslate">export { Square } from './shapes/square.js'; +export { Triangle } from './shapes/triangle.js'; +export { Circle } from './shapes/circle.js';</pre> + +<p>Eles capturam as exportações dos submódulos individuais e os disponibilizam efetivamente no módulo shapes.js.</p> + +<div class="blockIndicator note"> +<p><strong>Nota: As exportações mencionadas no shapes.js são basicamente redirecionadas pelo arquivo e realmente não existem nele, portanto, você não poderá escrever nenhum código relacionado útil dentro do mesmo arquivo.</strong></p> +</div> + +<p>Portanto, agora no arquivo main.js., podemos obter acesso às três classes de módulos substituindo</p> + +<pre class="brush: js; notranslate">import { Square } from './modules/square.js'; +import { Circle } from './modules/circle.js'; +import { Triangle } from './modules/triangle.js';</pre> + +<p>com a seguinte linha única:</p> + +<pre class="brush: js; notranslate">import { Square, Circle, Triangle } from './modules/shapes.js';</pre> + +<h2 id="Carregamento_dinâmico_do_módulo">Carregamento dinâmico do módulo</h2> + +<p>A parte mais recente da funcionalidade dos módulos JavaScript a estar disponível nos navegadores é o carregamento dinâmico de módulos. Isso permite que você carregue módulos dinamicamente somente quando eles forem necessários, em vez de precisar carregar tudo antecipadamente. Isso tem algumas vantagens óbvias de desempenho; vamos ler e ver como isso funciona.</p> + +<p>Essa nova funcionalidade permite que você ligue {{JSxRef("Statements/import", "import()", "#Dynamic_Imports")}} como uma função, passando o caminho para o módulo como um parâmetro. Retorna um{{JSxRef("Promise")}}, que cumpre com um objeto de módulo (consulte <a href="#Creating_a_module_object">Creating a module object</a>) dando acesso às exportações desse objeto, e.g.</p> + +<pre class="brush: js; notranslate">import('./modules/myModule.js') + .then((module) => { + // Do something with the module. + });</pre> + +<p>Vejamos um exemplo. No <a href="https://github.com/mdn/js-examples/tree/master/modules/dynamic-module-imports">dynamic-module-imports</a> diretório, temos outro exemplo baseado em nosso exemplo de classes. Desta vez, no entanto, não estamos desenhando nada na tela quando o exemplo é carregado. Em vez disso, incluímos trêsbuttons — "Circle", "Square", e "Triangle" — que, quando pressionado, carrega dinamicamente o módulo necessário e, em seguida, usa-o para desenhar os shape.</p> + +<p>Neste exemplo, fizemos apenas alterações em nossa <code><a href="https://github.com/mdn/js-examples/blob/master/modules/dynamic-module-imports/index.html">index.html</a></code> e <code><a href="https://github.com/mdn/js-examples/blob/master/modules/dynamic-module-imports/main.mjs">main.js</a></code> arquivos - as exportações do módulo permanecem as mesmas de antes.</p> + +<p>No main.js, pegamos uma referência a cada botão usando um<a href="/en-US/docs/Web/API/Document/querySelector"><code>Document.querySelector()</code></a> chamada, por exemplo:</p> + +<pre class="brush: js; notranslate">let squareBtn = document.querySelector('.square');</pre> + +<p>Em seguida, anexamos um ouvinte de evento a cada botão para que, quando pressionado, o módulo relevante seja carregado dinamicamente e usado para desenhar a forma(shape):</p> + +<pre class="brush: js; notranslate">squareBtn.addEventListener('click', () => { + import('./modules/square.js').then((Module) => { + let square1 = new Module.Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue'); + square1.draw(); + square1.reportArea(); + square1.reportPerimeter(); + }) +});</pre> + +<p>Observe que, como o cumprimento da promessa retorna um objeto de módulo, a classe é então transformada em uma sub-característica do objeto, portanto, agora precisamos acessar o construtor com <code>Module.</code> anexado a ele, e.g. <code>Module.Square( ... )</code>.</p> + +<h2 id="Solução_de_problemas">Solução de problemas</h2> + +<p>Aqui estão algumas dicas que podem ajudá-lo se você estiver com problemas para fazer seus módulos funcionarem. Sinta-se livre para adicionar à lista se descobrir mais!</p> + +<ul> + <li>Mencionamos isso antes, mas para reiterar: arquivos<code>.js</code> precisa ser carregado com um tipo MIME de <code>text/javascript</code> (ou outro tipo MIME compatível com JavaScript, mas <code>text/javascript</code> é recomendável), caso contrário, você receberá um erro estrito de verificação do tipo MIME como "O servidor respondeu com um tipo MIME não JavaScript".</li> + <li>Se você tentar carregar o arquivo HTML localmente (i.e. com um arquivo<code>://</code> URL), você encontrará erros do CORS devido a requisitos de segurança do módulo JavaScript. Você precisa fazer seus testes através de um servidor. As páginas do GitHub são ideais, pois também servem arquivos .js com o tipo MIME correto.</li> + <li>Como .mjs é uma extensão de arquivo não padrão, alguns sistemas operacionais podem não reconhecê-lo ou tentar substituí-lo por outra. Por exemplo, descobrimos que o macOS estava adicionando silenciosamente .js ao final dos arquivos .mjs e ocultando automaticamente a extensão do arquivo. Então, todos os nossos arquivos foram lançados como x.mjs.js. Depois de desativarmos ocultar automaticamente as extensões de arquivo e treiná-lo para aceitar .mjs, tudo bem.</li> +</ul> + +<h2 id="Veja_também">Veja também</h2> + +<ul> + <li><a href="https://developers.google.com/web/fundamentals/primers/modules#mjs">Using JavaScript modules on the web</a>, por Addy Osmani e Mathias Bynens</li> + <li><a href="https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/">ES modules: A cartoon deep-dive</a>, Postagem no blog Hacks por Lin Clark</li> + <li><a href="https://hacks.mozilla.org/2015/08/es6-in-depth-modules/">ES6 in Depth: Modules</a>, Publicação de blog de Hacks por Jason Orendorff</li> + <li>Livro de Axel Rauschmayer <a href="http://exploringjs.com/es6/ch_modules.html">Exploring JS: Modules</a></li> +</ul> + +<p>{{Previous("Web/JavaScript/Guide/Meta_programming")}}</p> diff --git a/files/pt-br/web/javascript/guide/numeros_e_datas/index.html b/files/pt-br/web/javascript/guide/numeros_e_datas/index.html new file mode 100644 index 0000000000..8f08cb3619 --- /dev/null +++ b/files/pt-br/web/javascript/guide/numeros_e_datas/index.html @@ -0,0 +1,374 @@ +--- +title: Números e datas +slug: Web/JavaScript/Guide/Numeros_e_datas +translation_of: Web/JavaScript/Guide/Numbers_and_dates +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}</div> + +<p class="summary">Este capítulo apresenta como utilizar números e datas em JavaScript.</p> + +<h2 id="Números">Números</h2> + +<p>Em Javascript, todos os números são implementados em <a class="external external-icon" href="https://en.wikipedia.org/wiki/Double-precision_floating-point_format">double-precision 64-bit binary format IEEE 754</a> (Por exemplo, um número entre -(2<sup>53</sup> -1) e 2<sup>53</sup> -1). <strong>Não havendo especificação de tipo Integer</strong>. Além de ser capaz de representar números de ponto flutuante, o tipo de número tem três valores simbólicos: <code>+</code>{{jsxref("Infinity")}}, <code>-</code>{{jsxref("Infinity")}}, and {{jsxref("NaN")}} (not-a-number). Veja também <a href="/en-US/docs/Web/JavaScript/Data_structures">Estruturas e Tipos de Dados em Javascript</a> em contexto com outros tipos primitivos em JavaScript.</p> + +<p>Você pode usar quatro tipos de números literais: decimal, binário, octal, e hexadecimal.</p> + +<h3 id="Números_Decimais">Números Decimais</h3> + +<pre class="brush: js notranslate">1234567890 +42 + +// Cuidado quando usar zeros à esquerda: + +0888 // 888 interpretado como decimal +0777 // interpretado como octal em modo no-strict (511 em decimal) +</pre> + +<p>Note que literais decimais podem começar com zero (<code>0</code>) seguido por outro digito decimal, porém se o próximo dígito depois do primeiro zero for menor do que 8, o número será analisado como um número octal.</p> + +<h3 id="Números_Binários">Números Binários</h3> + +<p>A sintaxe para números Binários, usa um zero à esquerda seguido de uma letra minúscula ou maiúscula "B" (<code>0b</code> or <code>0B</code>). Se os dígitos depois de 0b não forem 0 ou 1, a seguinte exceção <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError">SyntaxError</a></code> é lançada: "Missing binary digits after 0b".</p> + +<pre class="brush: js notranslate">var FLT_SIGNBIT = 0b10000000000000000000000000000000; // 2147483648 +var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040 +var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607</pre> + +<h3 id="Números_octais">Números octais</h3> + +<p>A sintaxe dos números octais usa um zero na frente. Se os dígitos depois do 0 estiverem fora do alcance 0 a 7, o número será interpretado como um número decimal.</p> + +<pre class="brush: js notranslate">var n = 0755; // 493 +var m = 0644; // 420 +</pre> + +<p>Modo estrito no ECMAScript 5 proíbe a sintaxe octal. A sintaxe Octal não é parte do ECMAScript 5, mas é suportada por todos os navegadores prefixando o número octal com zero: <code>0644 === 420</code> e <code>"\045" === "%"</code>. Em ECMAScript 6 números Octais são suportados prefixando o número com "<code>0</code>o" isto é.</p> + +<pre class="brush: js notranslate">var a = 0o10; // ES6: Octal +</pre> + +<h3 id="Numeros_hexadecimais">Numeros hexadecimais</h3> + +<p>A sintaxe numérica Hexadecimal usa um 0 na frente seguido por uma letra "X" maiúscula ou minúscula (<code>0x</code> ou <code>0X)</code>. Se os dígidos depois do 0x estiverem fora do alcance (0123456789ABCDF), o seguinte erro de sintaxe (<code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError">SyntaxError</a></code>) ocorrerá: "Identifier starts immediately after numeric literal" (O identificador começa imediatamente depois do literal numérico).</p> + +<pre class="brush: js notranslate">0xFFFFFFFFFFFFFFFFF // 295147905179352830000 +0x123456789ABCDEF // 81985529216486900 +0XA // 10 +</pre> + +<h3 id="Exponenciação">Exponenciação</h3> + +<pre class="brush: js notranslate">1E3 // 1000 +2e6 // 2000000 +0.1e2 // 10</pre> + +<h2 id="Objeto_Number"><code>Objeto Number</code></h2> + +<p>Um objeto built-in {{jsxref("Number")}} tem propriedades para constantes numéricas, tais como valor máximo, não número e infinito. Você não pode alterar os valores dessas propriedades e elas são usadas assim:</p> + +<pre class="brush: js notranslate">var maiorNum = Number.MAX_VALUE; //Valor máximo +var menorNum = Number.MIN_VALUE; //Valor mínimo +var infiniteNum = Number.POSITIVE_INFINITY; //Infinito positivo +var negInfiniteNum = Number.NEGATIVE_INFINITY; //Infinito negativo +var notANum = Number.NaN; //Não é numeral +</pre> + +<p>Você sempre se refere a uma propriedade do objeto predefinido <code>Number</code> como mostrado acima, e não como uma propriedade de um objeto <code>Number que você mesmo criou.</code></p> + +<p>A tabela à seguir sumariza as propriedades do objeto <code>Number.</code></p> + +<table class="standard-table"> + <caption>Propriedades de <code>Number</code></caption> + <thead> + <tr> + <th scope="col">Propriedade</th> + <th scope="col">Descrição</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("Number.MAX_VALUE")}}</td> + <td>O maior número representável.</td> + </tr> + <tr> + <td>{{jsxref("Number.MIN_VALUE")}}</td> + <td>O menor número representável.</td> + </tr> + <tr> + <td>{{jsxref("Number.NaN")}}</td> + <td>Valor "not a number" especial</td> + </tr> + <tr> + <td>{{jsxref("Number.NEGATIVE_INFINITY")}}</td> + <td>Valor especial infinito negativo; retornado em overflow</td> + </tr> + <tr> + <td>{{jsxref("Number.POSITIVE_INFINITY")}}</td> + <td>Valor especial infinito positivo; retornado em overflow</td> + </tr> + <tr> + <td>{{jsxref("Number.EPSILON")}}</td> + <td>Diferença entre um e o menor valor maior do que um que pode ser representado como um {{jsxref("Number")}}.</td> + </tr> + <tr> + <td>{{jsxref("Number.MIN_SAFE_INTEGER")}}</td> + <td>Mínimo safe integer em JavaScript.</td> + </tr> + <tr> + <td>{{jsxref("Number.MAX_SAFE_INTEGER")}}</td> + <td>Máximo safe integer em JavaScript.</td> + </tr> + </tbody> +</table> + +<table class="standard-table"> + <caption>Métodos de <code>Number</code></caption> + <thead> + <tr> + <th>Método</th> + <th>Descrição</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("Number.parseFloat()")}}</td> + <td>Analisa um argumento string e retorna um número float.<br> + O mesmo que a função global {{jsxref("parseFloat", "parseFloat()")}}.</td> + </tr> + <tr> + <td>{{jsxref("Number.parseInt()")}}</td> + <td>Analisa um argumento string e retorna um inteiro da raiz ou base especificada.<br> + O mesmo que a função global{{jsxref("parseInt", "parseInt()")}}.</td> + </tr> + <tr> + <td>{{jsxref("Number.isFinite()")}}</td> + <td>Determina se o valor passado é um número finito.</td> + </tr> + <tr> + <td>{{jsxref("Number.isInteger()")}}</td> + <td>Determina se o valor passado é um inteiro.</td> + </tr> + <tr> + <td>{{jsxref("Number.isNaN()")}}</td> + <td>Determina se o valor passado é {{jsxref("Global_Objects/NaN", "NaN")}}. A versão mais robusta da original {{jsxref("Global_Objects/isNaN", "isNaN()")}}.</td> + </tr> + <tr> + <td>{{jsxref("Number.isSafeInteger()")}}</td> + <td>Determina se o valor passado é um safe integer.</td> + </tr> + </tbody> +</table> + +<p>O protótipo <code>Number</code> provê métodos para resgatar informações de objetos <code>Number </code>em vários formatos. A tabela a seguir sumariza os métodos de<code> Number.prototype</code>.</p> + +<table class="standard-table"> + <caption>Métodos de <code>Number.prototype</code></caption> + <thead> + <tr> + <th scope="col">Método</th> + <th scope="col">Descrição</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("Number.toExponential", "toExponential()")}}</td> + <td>Retorna uma string representando o número em uma notação exponencial.</td> + </tr> + <tr> + <td>{{jsxref("Number.toFixed", "toFixed()")}}</td> + <td>Retorna uma string representando o número em notação com ponto-fíxo.</td> + </tr> + <tr> + <td>{{jsxref("Number.toPrecision", "toPrecision()")}}</td> + <td>Retorna uma string representando o número em uma precisão especificada na notação de ponto-fíxo.</td> + </tr> + </tbody> +</table> + +<h2 id="Objeto_Math"><code>Objeto Math</code></h2> + +<p>O objeto {{jsxref("Math")}} tem propriedades e métodos para constantes matemáticas e funções. Por exemplo, o <code>PI do objeto</code> Math tem o valor de pi (3,141...), que você usaria em uma aplicação como</p> + +<pre class="brush: js notranslate">Math.PI +</pre> + +<p>Similarmente, funções matemáticas padrão são métodos do Math. Isto inclui funções trigonométricas, logarítmicas, exponenciais, e outras funções. Por exemplo, se você quiser usar a função trigonométrica seno, basta escrever</p> + +<pre class="brush: js notranslate">Math.sin(1.56) +</pre> + +<p>Note que todos os métodos trigonométricos pegam argumentos em radianos.</p> + +<p>A tabela a seguir sumariza os métodos do objeto Math.</p> + +<table class="standard-table"> + <caption><code>Métodos de Math</code></caption> + <thead> + <tr> + <th scope="col">Método</th> + <th scope="col">Descrição</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("Math.abs", "abs()")}}</td> + <td>Valor absoluto</td> + </tr> + <tr> + <td>{{jsxref("Math.sin", "sin()")}}, {{jsxref("Math.cos", "cos()")}}, {{jsxref("Math.tan", "tan()")}}</td> + <td>Funções trigonométricas padrão; Argumentos em radianos</td> + </tr> + <tr> + <td>{{jsxref("Math.asin", "asin()")}}, {{jsxref("Math.acos", "acos()")}}, {{jsxref("Math.atan", "atan()")}}, {{jsxref("Math.atan2", "atan2()")}}</td> + <td>Funções trigonométricas inversas; retorna valores em radianos</td> + </tr> + <tr> + <td>{{jsxref("Math.sinh", "sinh()")}}, {{jsxref("Math.cosh", "cosh()")}}, {{jsxref("Math.tanh", "tanh()")}}</td> + <td>Funções trigonométricas hiperbólicas; retorna valores em radianos.</td> + </tr> + <tr> + <td>{{jsxref("Math.asinh", "asinh()")}}, {{jsxref("Math.acosh", "acosh()")}}, {{jsxref("Math.atanh", "atanh()")}}</td> + <td>Funções trigonométricas hiperbólicas inversas; retorna valores em radianos.</td> + </tr> + <tr> + <td> + <p>{{jsxref("Math.pow", "pow()")}}, {{jsxref("Math.exp", "exp()")}}, {{jsxref("Math.expm1", "expm1()")}}, {{jsxref("Math.log10", "log10()")}}, {{jsxref("Math.log1p", "log1p()")}}, {{jsxref("Math.log2", "log2()")}}</p> + </td> + <td>Funções exponenciais e logarítmicas.</td> + </tr> + <tr> + <td>{{jsxref("Math.floor", "floor()")}}, {{jsxref("Math.ceil", "ceil()")}}</td> + <td>Retorna o maior/menor inteiro que é menor/maior inteiro que ou igual ao argumento.</td> + </tr> + <tr> + <td>{{jsxref("Math.min", "min()")}}, {{jsxref("Math.max", "max()")}}</td> + <td>Retorna menor ou maior (respectivamente) de uma lista separada por vírgula de argumentos numéricos</td> + </tr> + <tr> + <td>{{jsxref("Math.random", "random()")}}</td> + <td>Retorna um número aleatório entre 0 e 1.</td> + </tr> + <tr> + <td>{{jsxref("Math.round", "round()")}}, {{jsxref("Math.fround", "fround()")}}, {{jsxref("Math.trunc", "trunc()")}},</td> + <td>Funções de arredondamento e truncamento.</td> + </tr> + <tr> + <td>{{jsxref("Math.sqrt", "sqrt()")}}, {{jsxref("Math.cbrt", "cbrt()")}}, {{jsxref("Math.hypot", "hypot()")}}</td> + <td>Raiz quadrada, raiz cúbica, raiz quadrada da soma de argumentos ao quadrado.</td> + </tr> + <tr> + <td>{{jsxref("Math.sign", "sign()")}}</td> + <td>O sinal de um número, indicando se o número é positivo, negativo ou zero.</td> + </tr> + <tr> + <td>{{jsxref("Math.clz32", "clz32()")}},<br> + {{jsxref("Math.imul", "imul()")}}</td> + <td>Número de zeros à esquerda na representação binária de 32-bits.<br> + The result of the C-like 32-bit multiplication of the two arguments.</td> + </tr> + </tbody> +</table> + +<p>Diferentemente de muitos outros objetos, você nunca cria um objeto Math por conta própria. Você sempre deve utilizar o objeto Math nativo.</p> + +<h2 id="Objeto_Date"><code>Objeto Date</code></h2> + +<p>JavaScript não possui dados do tipo data. No entanto, você pode usar o objeto {{jsxref("Date")}} e seus métodos para trabalhar com datas e horas nas suas aplicações. O objeto Date tem um grande número de métodos para setar, recuperar e manipular datas. Ele não tem nenhuma propriedade.</p> + +<p>JavaScript manipula datas de maneira semelhante ao Java. As duas linguagens tem muitos dos mesmos métodos para lidar com datas e ambas armazenam datas como números em milisegundos, desde 1 de janeiro de 1970, às 00:00:00 ( January 1, 1970, 00:00:00).</p> + +<p>A abrangência do objeto Date é de -100,000,000 dias até 100,000,000 dias relativos a 01 de janeiro de 1970 UTC.</p> + +<p>Para criar um objeto Date:</p> + +<pre class="brush: js notranslate">var dateObjectName = new Date([parameters]); +</pre> + +<p>onde <code>dateObjectName </code>é o nome do objeto Date que está sendo criado; ele pode ser um novo objeto ou uma propriedade de um objeto existente.</p> + +<p>A chamada de Date sem a palavra reservada <code>new</code>, simplesmente converte a data para uma representação dela como string.</p> + +<p>Os <code>parâmetros </code>do código acima podem ser qualquer um a seguir:</p> + +<ul> + <li>Nada: cria a data e hora de hoje. Por exemplo, <code>today = new Date();.</code></li> + <li>Uma string representando uma data da seguinte forma: "Mês dia, ano, horas:minutos:segundos". Por exemplo, <code>Xmas95 = new Date("25 de dezembro de 1995, 13:30:00")</code>. Se você omitir as horas, minutos ou segundos, o valor será setado para zero.</li> + <li>Um conjunto de valores inteiros para ano, mês e dia. Por exemplo, <code>var Xmas95 = new Date(1995, 11, 25)</code>.</li> + <li>Um conjunto de valores inteiros par ano, mês, dia, hora, minuto e segundos. Por exemplo, <code>var Xmas95 = new Date(1995, 11, 25, 9, 30, 0);</code>.</li> +</ul> + +<h3 id="Métodos_do_objeto_Date">Métodos do objeto Date</h3> + +<p>Os métodos do objeto Date para manipular data e hora pertencem às seguintes categorias:</p> + +<ul> + <li>Métodos "set", para setar valores de data e hora em objetos Date.</li> + <li>Métodos "get", para recuperar valores de data e hora de objetos Date.</li> + <li>Métodos "to", para retornar valores de string de objetos Date.</li> + <li>Métodos parse e UTC, para parsear string de Data.</li> +</ul> + +<p>Com os métods "get" e "set", você pode recuperar e setar segundos, minutos, horas, dia e mês, dia da semana, meses e anos, separadamente. Existe um método <code>getDay </code>que retorna o dia da semana, mas não existe um método <code>setDay </code>correspondente, porque o dia da semana é setado automaticamente. Estes métodos utilizam números inteiros para representar estes valores da seguinte maneira:</p> + +<ul> + <li>Segundos e minutos: de 0 a 59</li> + <li>Horas: de 0 a 23</li> + <li>Dia: 0 (Domingo) a 6 (Sábado)</li> + <li>Data: 1 a 31 (dia do mês)</li> + <li>Meses: 0 (Janeiro) a 11 (Dezembro)</li> + <li>Ano: anos desde 1900</li> +</ul> + +<p>Por exemplo, suponha que você queira definir a seguinite data:</p> + +<pre class="brush: js notranslate">var Xmas95 = new Date("December 25, 1995"); +</pre> + +<p>Então <code>Xmas95.getMonth() </code>retorna 11<code> e Xmas95.getFullYear()</code> retorna 1995.</p> + +<p>Os métodos <code>getTime</code> e <code>setTime </code>são úteis para comparar datas. O método <code>getTime</code> retorna o número dos milisegundos desde 1 de janeiro de 1970, às 00:00:00 para um objeto Date.</p> + +<p>Por exemplo, o código a seguir mostra os números dos dias que ainda faltam do ano vigente:</p> + +<pre class="brush: js notranslate">var hoje = new Date(); +var fimAno = new Date(1995, 11, 31, 23, 59, 59, 999); // Seta dia e mês +fimAno.setFullYear(hoje.getFullYear()); // Seta o ano para esse ano +var msPorDia = 24 * 60 * 60 * 1000; // Quantidade de milisegundos por dia +var diasRestantes = (fimAno.getTime() - hoje.getTime()) / msPorDia; +var diasRestantes = Math.round(diasRestantes); //retorna os dias restantes no ano +</pre> + +<p>Este exemplo cria um objeto Date chamado <code>hoje </code>que contém a data de hoje. Ele, então, cria o objeto Date chamado <code>fimAno </code>e seta o ano para o ano vigente. Então, usando o número de milisegundos por dia, ele computa o número de dias entre hoje e <code>fimAno, </code>usando <code>getTime </code>e arredondando os números de dias.</p> + +<p>O método <code>parse </code>é útil para associar valores de strings de data para objetos Date existentes. Por exemplo, o código a seguir usa <code>parse</code> e <code>setTime</code> para associar um valor de data ao objeto <code>IPOdate:</code></p> + +<pre class="brush: js notranslate">var IPOdate = new Date(); +IPOdate.setTime(Date.parse("Aug 9, 1995")); +</pre> + +<p>No exemplo a seguir, a função <code>JSClock() </code>retorna o tempo no formato de um relógio digital.</p> + +<pre class="brush: js notranslate">function JSClock() { + var tempo = new Date(); + var hora = tempo.getHours(); + var minuto = tempo.getMinutes(); + var segundo = tempo.getSeconds(); + var temp = "" + ((hora > 12) ? hora - 12 : hora); + if (hora == 0) + temp = "12"; + temp += ((minuto < 10) ? ":0" : ":") + minuto; + temp += ((segundo < 10) ? ":0" : ":") + segundo; + temp += (hora >= 12) ? " P.M." : " A.M."; + return temp; +} +</pre> + +<p>A função <code>JSClock </code>primeiro cria um objeto new <code>Date </code>chamado tempo; já que nenhum argumento é passado, <code>tempo</code> é criado com data e hora atuais. Ela então chama os métodos <code>getHours</code>, <code>getMinutes</code> e <code>getSeconds </code>e associa o valor à hora, minuto e segundo atuais à hora, minuto e segundo.</p> + +<p>As próximas quatro declarações constroem uma string baseada em time. A primeira declaração cria uma variável <code>temp</code>, associando um valor utilizando uma expressão condicional; se hora é maior que 12, (hora - 12), senão simplesmente hora, a não ser que hora seja 0 que, nesse caso, será 12.</p> + +<p>A próxima declaração anexa um valor <code>minuto</code> a <code>temp</code>. Se o valor de minuto for menos que 10, a expressão condicional acrescenta uma string com um 0 na frente; senão ela acrescenta uma string com dois pontos. Então a declaração anexa um valor <code>segundo </code>a <code>temp</code> do mesmo jeito.</p> + +<p>Finalmente, a expressão condicional anexa "P.M." a <code>temp</code> se <code>hora</code> for 12 ou maior; senão ela anexa "A.M." a <code>temp</code>.</p> + +<p>{{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}</p> diff --git a/files/pt-br/web/javascript/guide/regular_expressions/index.html b/files/pt-br/web/javascript/guide/regular_expressions/index.html new file mode 100644 index 0000000000..41cc239d94 --- /dev/null +++ b/files/pt-br/web/javascript/guide/regular_expressions/index.html @@ -0,0 +1,637 @@ +--- +title: Expressões Regulares +slug: Web/JavaScript/Guide/Regular_Expressions +tags: + - Expressões Regulares + - Guía + - JavaScript + - Nível Intermediário + - Referencia + - RegExp + - regex +translation_of: Web/JavaScript/Guide/Regular_Expressions +--- +<p>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}</p> + +<div></div> + +<p class="summary">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 <a href="/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec" title="exec"><code>exec</code></a> e <a href="/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/test" title="test"><code>test</code></a> do objeto<a href="/en-US/docs/JavaScript/Reference/Global_Objects/RegExp" title="RegExp"> <code>RegExp</code></a>, e com os métodos <a href="/en-US/docs/JavaScript/Reference/Global_Objects/String/match" title="match"><code>match</code></a>, <a href="/en-US/docs/JavaScript/Reference/Global_Objects/String/replace" title="en-US/docs/JavaScript/Reference/Global_Objects/String/replace"><code>replace</code></a>,<a href="/en-US/docs/JavaScript/Reference/Global_Objects/String/search" title="search"> <code>search</code></a>, e <a href="/en-US/docs/JavaScript/Reference/Global_Objects/String/split" title="split"><code>split</code></a> do objeto <a href="/en-US/docs/JavaScript/Reference/Global_Objects/String" title="String"><code>String</code></a>. Este capítulo descreve o uso de expressões regulares em JavaScript.</p> + +<h2 id="Criando_uma_Expressão_Regular"><a id="criando_expressao_regular" name="criando_expressao_regular">Criando uma Expressão Regular</a></h2> + +<p>Há duas maneiras de construir uma expressão regular:</p> + +<p>Usando uma expressão literal, que consiste em um padrão fechado entre barras, como o exemplo a seguir:</p> + +<div style="margin-right: 270px;"> +<pre class="brush: js notranslate">const re = /ab+c/; +</pre> +</div> + +<p>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.</p> + +<p>Ou chamando o construtor do objeto <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/RegExp" title="en-US/docs/JavaScript/Reference/Global Objects/RegExp">RegExp</a></code>:</p> + +<div style="margin-right: 270px;"> +<pre class="brush: js notranslate">let re = new RegExp("ab+c"); +</pre> +</div> + +<p>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.</p> + +<div class="blockIndicator note"> +<p>Nota: Se você já está familiarizado com as formas de uma expressão regular, também pode ler o <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet">resumo</a> para uma rápida pesquisa de um padrão específico.</p> +</div> + +<h2 id="Escrevendo_um_padrão_de_expressão_regular"><a id="escrita_expressao_regular" name="escrita_expressao_regular">Escrevendo um padrão de expressão regular</a></h2> + +<p>Um padrão de expressão é composto por um conjunto de caracteres simples, como <code>/abc/</code>, ou uma combinação de caracteres simples e especiais, como <code>/ab*c/</code> ou <code>/Capitulo (\d+)\.\d*/</code>. 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: {{ web.link("#Using_Parenthesized_Substring_Matches", "Using Parenthesized Substring Matches") }}.</p> + +<h3 id="Uso_de_Padrões_Simples">Uso de Padrões Simples</h3> + +<p>Padrões simples são construídos utilizando os caracteres que você deseja encontrar correspondências diretas. Por exemplo, o padrão <code>/abc/</code> 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 <u>abc</u>?" e "Os mais recentes aviões evoluíram do sl<u>abc</u>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.</p> + +<h3 id="Uso_dos_Caracteres_Especiais">Uso dos Caracteres Especiais</h3> + +<p>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 <code>/ab*c/.</code> O caractere <code>*</code> seleciona zero ou mais ocorrências do item que o precede. Se aplicada ao texto 'cbb<u>abbbbc</u>debc', essa expressão regular encontraria o subconjunto grifado no texto.</p> + +<p>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 <a href="http://regexr.com/">regExr</a>.</p> + +<table class="fullwidth-table"> + <caption>Caracteres especiais utilizados em expressões regulares.<span style="display: none;"> </span><span style="display: none;"> </span></caption> + <thead> + <tr> + <th scope="col">Caractere</th> + <th scope="col">Descrição</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="#special-backslash" id="special-backslash" name="special-backslash"><code>\</code></a></td> + <td> + <p>Aplicado conforme as seguintes regras:</p> + + <p>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 <code>'\b'</code> ele passará a significar a ocorrência do caractere especial {{web.link('#special-word-boundary', 'fronteira do caractere')}}.</p> + + <p>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 <code>/a*/</code>, que selecionará a ocorrência de zero ou mais caracteres 'a' quando utilizado sem a \ para escape. Por outro lado no padrão <code>/a\*/</code> 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 '*'.</p> + + <p>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.</p> + </td> + </tr> + <tr> + <td><a href="#special-caret" id="special-caret" name="special-caret"><code>^</code></a></td> + <td> + <p>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.</p> + + <p>Por exemplo, <code>/^A/</code> não corresponde ao 'A' em "Um Alvo", mas corresponde ao 'A' em "Alvo Encontrado".</p> + + <p><br> + Este caractere tem um significado diferente quando aparece como o primeiro caractere em um conjunto padrão de caracteres. Veja <a href="/pt-BR/docs/Web/JavaScript/Guide/Regular_Expressions#special-negated-character-set">conjunto de caracteres negados ou complementados</a> para detalhes e mais exemplos.</p> + </td> + </tr> + <tr> + <td><a href="#special-dollar" id="special-dollar" name="special-dollar"><code>$</code></a></td> + <td> + <p>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.</p> + + <p>Por exemplo, <code>/r$/</code> não corresponde ao 'r' em "corre", mas acha correspondência em "correr".</p> + </td> + </tr> + <tr> + <td><a href="#special-asterisk" id="special-asterisk" name="special-asterisk"><code>*</code></a></td> + <td> + <p>Corresponde a expressão que o precede repetida 0 ou mais vezes. Equivalente a {0,}</p> + + <p>Por exemplo, <code>/bo*/</code> acha uma correspondência para 'boooo' em "Scoob doo" e 'b' em "A bird warbled", mas nenhuma em "A goat grunted".</p> + </td> + </tr> + <tr> + <td><a href="#special-plus" id="special-plus" name="special-plus"><code>+</code></a></td> + <td> + <p>Corresponde a expressão que o precede repetido 1 ou mais vezes. Equivalente a {1,}.</p> + + <p>Por exemplo, <code>/a+/</code> acha correspondência para o 'a' em "candy" e todos os "as" em "caaaaaaandy", mas nâo encontra em "cndy".</p> + </td> + </tr> + <tr> + <td><a href="#special-questionmark" id="special-questionmark" name="special-questionmark"><code>?</code></a></td> + <td> + <p>Corresponde a expressão que o precede repetido 0 ou 1 vez. Equivalente à {0,1}.</p> + + <p>Por exemplo, <code>/e?le?/</code> encontra o 'el' em "angel" e o 'le' em "angle" e também o 'l' em "oslo".</p> + + <p>Se usado imediatamente após qualquer um dos quantificadores <code>*</code>, <code>+</code>, <code>? </code>ou <code>{}</code>, 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 <code>/\d+/</code> em "123abc" encontra "123". Mas aplicando <code>/\d+?/</code>, apenas "1" será encontrado.</p> + + <p>Também usado em declarações lookahead, descritas sob <code>x(?=y)</code> e <code>x(?!y)</code>logo abaixo na tabela.</p> + </td> + </tr> + <tr> + <td><a href="#special-dot" id="special-dot" name="special-dot"><code>.</code></a></td> + <td> + <p>(O ponto decimal) corresponde com qualquer caracter, exceto o caracter de nova linha.</p> + + <p>Por exemplo, <code>/.n/</code> acha correspondência para o 'an' e 'on' em "nove dias restantes para onze de agosto.", mas não encontra 'no' em 'nove'.</p> + </td> + </tr> + <tr> + <td><a href="#special-capturing-parentheses" id="special-capturing-parentheses" name="special-capturing-parentheses"><code>(x)</code></a></td> + <td> + <p>Pesquisa correspondência com o caractere 'x' e memoriza-o, como a o exemplo a seguir mostra. Os parênteses são chamados <em>parênteses de captura</em>.</p> + + <p>Por exemplo, o '(foo)' e '(bar)' no padrão <code>/(foo) (bar) \1 \2/</code> 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. </p> + </td> + </tr> + <tr> + <td><a href="#special-non-capturing-parentheses" id="special-non-capturing-parentheses" name="special-non-capturing-parentheses"><code>(?:x)</code></a></td> + <td>Pesquisa correspondência com o caractere 'x' porém não o memoriza. Os parênteses são chamados de<em> parênteses de não-captura</em> e permitem que você defina uma subexpressão para operadores de expressão regular trabalhar com eles. Considere essa expressão de exemplo <code>/(?:foo){1,2}/</code>. Se a expressão era <code>/foo{1,2}/</code>, 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'.</td> + </tr> + <tr> + <td><a href="#special-lookahead" id="special-lookahead" name="special-lookahead"><code>x(?=y)</code></a></td> + <td> + <p>Pesquisa correspondência em 'x' apenas se 'x' é seguido por 'y'. Isso é chamado de <em>lookahead</em>.</p> + + <p>Por exemplo, <code>/Jack(?=Sprat)/</code> busca 'Jack' apenas se é seguido por 'Sprat'. <code>/Jack(?=Sprat|Frost)/</code> busca 'Jack' apenas se ele é seguido por 'Sprat' ou 'Frost'. No entanto, 'Sprat' nem 'Frost' faz parte do resultado retornado.</p> + </td> + </tr> + <tr> + <td><a href="#special-negated-look-ahead" id="special-negated-look-ahead" name="special-negated-look-ahead"><code>x(?!y)</code></a></td> + <td> + <p>Pesquisa correspondência em 'x' apenas se 'x' não é seguido por 'y'. Isso é chamado <em>negação lookahead</em>.</p> + + <p>Por exemplo, <code>/\d+(?!\.)/</code> encontra um número apenas se ele não for seguido por um ponto decimal. A expressão regular <code>/\d+(?!\.)/.exec("3.141")</code> encontra '141' mas não '3.141'.</p> + </td> + </tr> + <tr> + <td><a href="#special-or" id="special-or" name="special-or"><code>x|y</code></a></td> + <td> + <p>Pesquisa correspondência em 'x' ou 'y'.</p> + + <p>Por exemplo, <code>/verde|vermelha/</code> encontra 'verde' em "maçã verde" e 'vermelha' em "maçã vermelha."</p> + </td> + </tr> + <tr> + <td><a href="#special-quantifier" id="special-quantifier" name="special-quantifier"><code>{n}</code></a></td> + <td> + <p>Pesquisa n ocorrências correspondentes ao caracter precedido. Onde, <code>n</code> deve ser um inteiro positivo.</p> + + <p>Por exemplo, <code>/a{2}/</code> 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."</p> + </td> + </tr> + <tr> + <td><a href="#special-quantifier-range" id="special-quantifier-range" name="special-quantifier-range"><code>{n,m}</code></a></td> + <td> + <p>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, <code>n</code> e <code>m</code> devem ser inteiros positivo.</p> + + <p>Por exemplo, <code>/a{1,3}/</code> 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.</p> + </td> + </tr> + <tr> + <td><a href="#special-character-set" id="special-character-set" name="special-character-set"><code>[xyz]</code></a></td> + <td> + <p>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.</p> + + <p>Por exemplo, <code>[abcd]</code> é o mesmo que <code><span style="font-family: monospace;">[</span>a-d]</code>. Com a expressão será encontrado o 'b' em "beijo" e o 'c' em "chop". A expressão <code>/[a-z.]+/</code> e <code>/[\w.]+/</code> ambos encontraram as letras que formam "test.i.ng".</p> + </td> + </tr> + <tr> + <td><a href="#special-negated-character-set" id="special-negated-character-set" name="special-negated-character-set"><code>[^xyz]</code></a></td> + <td> + <p>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.</p> + + <p>Por exemplo, <code>[^abc]</code> é o mesmo que <code>[^a-c]</code>. Com a expressão será encontrado inicialmente 'e' em "beijo" e 'h' em "chop."</p> + </td> + </tr> + <tr> + <td><a href="#special-backspace" id="special-backspace" name="special-backspace"><code>[\b]</code></a></td> + <td>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 <code>\b</code>.)</td> + </tr> + <tr> + <td><a href="#special-word-boundary" id="special-word-boundary" name="special-word-boundary"><code>\b</code></a></td> + <td> + <p>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].)</p> + + <p>Exemplos:<br> + <code>/\bmoo/</code> encontra a substring 'moo' em "moon" ;<br> + <code>/oo\b/</code> não encontra o 'oo' em "moon", devido o 'oo' ser seguido por 'n' que é um caractere;<br> + <code>/oon\b/</code> encontra a substring 'oon' em "moon", devido 'oon' ser o fim da string, ou seja, não é seguido por nenhum caractere;<br> + <code>/\w\b\w/</code> não encontrará nada, pois o caractere nunca será seguido por um não caractere e um caractere.</p> + + <div class="note"> + <p><strong>Nota:</strong> 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.</p> + </div> + </td> + </tr> + <tr> + <td><a href="#special-non-word-boundary" id="special-non-word-boundary" name="special-non-word-boundary"><code>\B</code></a></td> + <td> + <p>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.</p> + + <p>Por exemplo, /\B../ encontra correspondente 'oo' em "boolean", e /y\B./ encontra correspondente 'ye' em "possibly yesterday."</p> + </td> + </tr> + <tr> + <td><a href="#special-control" id="special-control" name="special-control"><code>\c<em>X</em></code></a></td> + <td> + <p>Onde X é um caractere pertencente ao conjunto A-Z. Encontra correspondência de um <a href="https://pt.wikipedia.org/wiki/Caractere_de_controle">caractere de controle</a> em uma string.</p> + + <p>Por exemplo, <code>/\cM/</code> encontra correspondente control-M (U+000D) em uma string.</p> + </td> + </tr> + <tr> + <td><a href="#special-digit" id="special-digit" name="special-digit"><code>\d</code></a></td> + <td> + <p>Encontra correspondência com um número. Equivalente a [0-9].</p> + + <p>Por exemplo, <code>/\d/</code> ou <code>/[0-9]/</code> encontra correspondente '8' em "Dróide BB8".</p> + </td> + </tr> + <tr> + <td><a href="#special-non-digit" id="special-non-digit" name="special-non-digit"><code>\D</code></a></td> + <td> + <p>Encontra correspondência com um caractere que não seja número. Equivalente a [^0-9].</p> + + <p>Por exemplo, <code>/\D/</code> ou <code>/[^0-9]/</code> econtra correspondente 'C' em "C3 está ativada."</p> + </td> + </tr> + <tr> + <td><a href="#special-form-feed" id="special-form-feed" name="special-form-feed"><code>\f</code></a></td> + <td>Encontra correspondência com um caractere de escape <em>avanço de página</em> (U+000C).</td> + </tr> + <tr> + <td><a href="#special-line-feed" id="special-line-feed" name="special-line-feed"><code>\n</code></a></td> + <td>Encontra correspondência com um caractere de escape <em>quebra de linha</em> (U+000A).</td> + </tr> + <tr> + <td><a href="#special-carriage-return" id="special-carriage-return" name="special-carriage-return"><code>\r</code></a></td> + <td>Encontra correspondência com um caractere de escape <em>retorno de carro</em> (U+000D).</td> + </tr> + <tr> + <td><a href="#special-white-space" id="special-white-space" name="special-white-space"><code>\s</code></a></td> + <td> + <p>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 <code>[ \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]</code>.</p> + + <p>Por exemplo, <code>/\s\w*/</code> encontra correspondente ' bar' em "foo bar."</p> + </td> + </tr> + <tr> + <td><a href="#special-non-white-space" id="special-non-white-space" name="special-non-white-space"><code>\S</code></a></td> + <td> + <p>Encontra correspondência em um único caractere que não seja espaço em branco. Equivalente a <code>[^ \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]</code>.</p> + + <p>Por exemplo, <code>/\S\w*/</code> encontra correspondente 'foo' em "foo bar."</p> + </td> + </tr> + <tr> + <td><a href="#special-tab" id="special-tab" name="special-tab"><code>\t</code></a></td> + <td>Encontra correspondência em uma tabulação (U+0009).</td> + </tr> + <tr> + <td><a href="#special-vertical-tab" id="special-vertical-tab" name="special-vertical-tab"><code>\v</code></a></td> + <td>Encontra correspondência em uma tabulação vertical (U+000B).</td> + </tr> + <tr> + <td><a href="#special-word" id="special-word" name="special-word"><code>\w</code></a></td> + <td> + <p>Encontra correspondência de qualquer caractere alfanumérico incluindo underline. Equivalente a <code>[A-Za-z0-9_]</code>.</p> + + <p>Por exemplo, <code>/\w/</code> encontra correspondente 'a' em "apple," '5' em "$5.28," e '3' em "3D."</p> + </td> + </tr> + <tr> + <td><a href="#special-non-word" id="special-non-word" name="special-non-word"><code>\W</code></a></td> + <td> + <p>Encontra correspondência em um não caractere. Equivalente a <code>[^A-Za-z0-9_]</code>.</p> + + <p>Por exemplo, <code>/\W/</code> ou <code>/[^A-Za-z0-9_]/</code> encontra correspondente '%' em "50%."</p> + </td> + </tr> + <tr> + <td><a href="#special-backreference" id="special-backreference" name="special-backreference"><code>\<em>num</em></code></a></td> + <td> + <p>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.</p> + + <p>Por exemplo, /(muito) (cacique) pra \2 \1/ encontra 'muito cacique pra cacique muito' em 'Na aldeia tem muito cacique pra cacique muito.'</p> + </td> + </tr> + <tr> + <td><a href="#special-null" id="special-null" name="special-null"><code>\0</code></a></td> + <td>Encontra correspondência em um caractere NULL (U+0000). Não adicione outro número após o zero, pois <code>\0<digitos> é um escape para número octal</code>.</td> + </tr> + <tr> + <td><a href="#special-hex-escape" id="special-hex-escape" name="special-hex-escape"><code>\xhh</code></a></td> + <td>Encontra correspondência com o código hh (dois valores hexadecimal).</td> + </tr> + <tr> + <td><a href="#special-unicode-escape" id="special-unicode-escape" name="special-unicode-escape"><code>\uhhhh</code></a></td> + <td>Encontra correspondência com o código hhh (três valores hexadecimal).</td> + </tr> + <tr> + <td>\u{hhhh}</td> + <td>(funciona apenas com a flag u) Encontra correspondência com o valor Unicode hhhh (dígitos hexadecimais).</td> + </tr> + </tbody> +</table> + +<h3 id="Usando_Parênteses">Usando Parênteses</h3> + +<p>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 {{ web.link("#Using_Parenthesized_Substring_Matches", "Usando as Substrings entre Parênteses na Expressão Regular") }}.</p> + +<p>Por Exemplo, a expressão <code>/Capitulo (\d+)\.\d*/</code> <span id="result_box" lang="pt"><span>ilustra caracteres adicionais escapados e especiais e indica que parte do padrão deve ser lembrado.</span></span> Corresponde precisamente aos caracteres 'Capitulo ' seguidos por um ou mais caracteres numéricos (<code>\d</code> significa qualquer caracter numérico e <code>+</code> 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 (<code>\d</code> significa caracter numérico, <code>*</code> significa 0 ou mais vezes). Além disso, os parenteses são usados para relembrar os primeiros caracteres numéricos correspondentes.</p> + +<p>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'.</p> + +<p>Para encontrar uma substring sem que a correspondência seja relembrada, dentro dos parênteses inicie o padrão com <code>?:</code>. Por exemplo, <code>(?:\d+)</code> corresponde a um ou mais caracteres numéricos mas não relembra os caracteres correspondentes.</p> + +<h2 id="Trabalhando_com_expressões_regulares">Trabalhando com expressões regulares</h2> + +<p>Expressões Regulares são usadas com os metodos <code>test</code> e <code>exec</code> do objeto <code>RegExp </code>e com os metodos <code>match</code>, <code>replace</code>, <code>search</code>, e <code>split</code> do objeto <code>String</code>. Estes metodos são explicados em detalhe em <a href="/en-US/docs/JavaScript/Reference" title="en-US/docs/JavaScript/Reference">JavaScript Reference</a>.</p> + +<table class="standard-table"> + <caption>Tabela 4.2 Metodos que usam Expressões regulares</caption> + <thead> + <tr> + <th scope="col">Metodo</th> + <th scope="col">Descrição</th> + </tr> + </thead> + <tbody> + <tr> + <td><code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec" title="en-US/docs/JavaScript/Reference/Global_Objects/RegExp/exec">exec</a></code></td> + <td>Um método <code>RegExp</code> que execute uma pesquisa por uma correspondência em uma string. Retorna um array de informações.</td> + </tr> + <tr> + <td><code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/RegExp/test" title="en-US/docs/JavaScript/Reference/Global_Objects/RegExp/test">test</a></code></td> + <td>Um método <code>RegExp</code> que testa uma correspondência em uma string. Retorna true ou false.</td> + </tr> + <tr> + <td><code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/String/match" title="en-US/docs/JavaScript/Reference/Global_Objects/String/match">match</a></code></td> + <td>Um método <code>String</code> 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.</td> + </tr> + <tr> + <td><code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/String/search" title="en-US/docs/JavaScript/Reference/Global_Objects/String/search">search</a></code></td> + <td>Um método <code>String</code> que testa uma correspondência em uma string. Retorna o indice da correspondência ou -1 se o teste falhar.</td> + </tr> + <tr> + <td><code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/String/replace" title="en-US/docs/JavaScript/Reference/Global_Objects/String/replace">replace</a></code></td> + <td>Um método <code>String</code> que executa uma pesquisa por uma correspondência em uma string, e substitui a substring correspondênte por uma substring de substituição.</td> + </tr> + <tr> + <td><code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/String/split" title="en-US/docs/JavaScript/Reference/Global_Objects/String/split">split</a></code></td> + <td>Um método <code>String</code> que usa uma expressão regular ou uma string fixa para quebrar uma string dentro de um array de substrings.</td> + </tr> + </tbody> +</table> + +<p>Quando você quer saber se um padrão é encontrado em uma string, use o método <code>test</code> ou <code>search</code>; para mais informações (mas execução mais lenta) use o método <code>exec</code> ou <code>match</code>. Se você usar <code>exec</code> ou <code>match</code> 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 <code>RegExp</code>. Se não houver corespondência, o método <code>exec</code> retorna <code>null</code> (convertido para <code>false</code>).</p> + +<p>No seguinte exemplo, o script usa o método <code>exec</code> para encontrar uma correspondência em uma string.</p> + +<pre class="brush: js notranslate">var myRe = /d(b+)d/g; +var myArray = myRe.exec("cdbbdbsbz"); +</pre> + +<p>Se você não precisa acessar as propriedades da expressão regular, uma alternativa de criar <code>myArray</code> é com esse script:</p> + +<pre class="brush: js notranslate">var myArray = /d(b+)d/g.exec("cdbbdbsbz"); +</pre> + +<p>Se você quiser construir a expressão regular a partir de uma string, outra alternativa é esse script:</p> + +<pre class="brush: js notranslate">var myRe = new RegExp("d(b+)d", "g"); +var myArray = myRe.exec("cdbbdbsbz"); +</pre> + +<p>Com esses scripts, a correspondência é encontrada o array é retornado e são atualizadas as propriedades mostradas na tabela a seguir.</p> + +<table class="fullwidth-table"> + <caption>Table 4.3 Resultados da execução de expressões regulares.</caption> + <thead> + <tr> + <th scope="col">Objeto</th> + <th scope="col">Propriedade or indice</th> + <th scope="col">Descrição</th> + <th scope="col">Nesse exemplo</th> + </tr> + </thead> + <tbody> + <tr> + <td rowspan="4"><code>myArray</code></td> + <td></td> + <td>A string correspondente e todas as substrings relembradas.</td> + <td><code>["dbbd", "bb"]</code></td> + </tr> + <tr> + <td><code>index</code></td> + <td>O índice do encontro em relação à string original.</td> + <td><code>1</code></td> + </tr> + <tr> + <td><code>input</code></td> + <td>A string original.</td> + <td><code>"cdbbdbsbz"</code></td> + </tr> + <tr> + <td><code>[0]</code></td> + <td>Os últimos caracteres encontrados.</td> + <td><code>"dbbd"</code></td> + </tr> + <tr> + <td rowspan="2"><code>myRe</code></td> + <td><code>lastIndex</code></td> + <td>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 {{web.link ("# Advanced_Searching_With_Flags", "Advanced Searching With Flags")}}.)</td> + <td><code>5</code></td> + </tr> + <tr> + <td><code>source</code></td> + <td>O texto da expressão regular. Atualizado quando a expressão é criada, não executada.</td> + <td><code>"d(b+)d"</code></td> + </tr> + </tbody> +</table> + +<p>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:</p> + +<pre class="brush: js notranslate">var myRe = /d(b+)d/g; +var myArray = myRe.exec("cdbbdbsbz"); +console.log("O útltimo índice é " + myRe.lastIndex); +</pre> + +<p>Este script mostra:</p> + +<pre class="notranslate">O último índice é 5</pre> + +<p>Contudo, se tem este script:</p> + +<pre class="brush: js notranslate">var myArray = /d(b+)d/g.exec("cdbbdbsbz"); +console.log("O último índice é " + /d(b+)d/g.lastIndex); +</pre> + +<p>Ele mostra:</p> + +<pre class="notranslate">O último índice é 0 +</pre> + +<p>As ocorrências de <code>/d(b+)d/g</code> nas duas declarações são objetos expressões regulares diferentes e consequentemente têm diferentes valores para suas propriedades <code>lastIndex</code>. Se precisa acessar as propriedades de uma expressão regular criada com um inicializaor de objeto, você deve primeiro atribuí-la à uma variável.</p> + +<h3 id="Usando_as_Substrings_entre_Parênteses_na_Expressão_Regular">Usando as Substrings entre Parênteses na Expressão Regular</h3> + +<p>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, <code>/a(b)c/</code> corresponde aos caracteres 'abc' e lembra 'b'. Para recuperar essas correspondências de substring entre parênteses, use o <code>Arra</code><code>[1]</code>, ..., <code>[n]</code>.</p> + +<p>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.</p> + +<h4 id="Exemplo_1">Exemplo 1</h4> + +<p>O script a seguir usa o método <a href="/en-US/docs/JavaScript/Reference/Global_Objects/String/replace" title="en-US/docs/JavaScript/Reference/Global Objects/String/replace"><code>replace()</code></a> para alternar as palavras na string. Para o texto de substituição, o script usa o <code>$1</code> e <code>$2</code> na substituição para indicar a primeira e a segunda correspondências de substring entre parênteses.</p> + +<pre class="brush: js notranslate">var re = /(\w+)\s(\w+)/; +var str = "John Smith"; +var newstr = str.replace(re, "$2, $1"); +console.log(newstr); +</pre> + +<p>Isto imprime "Smith, John".</p> + +<h3 id="Pesquisa_avançada_com_Flags">Pesquisa avançada com Flags</h3> + +<p>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.</p> + +<p>{{Fx_minversion_note (3, "Suporte para o sinalizador <code>y </code>foi adicionado no Firefox 3. <br> + O sinalizador <code>y </code>falha se a correspondência não for bem-sucedida na posição atual na cadeia de destino.")}}</p> + +<p>Para incluir um sinalizador com a expressão regular, use esta sintaxe:</p> + +<pre class="brush: js notranslate">var re = /pattern/flags; +</pre> + +<p>ou</p> + +<pre class="brush: js notranslate">var re = new RegExp("pattern", "flags"); +</pre> + +<p>Observe que os sinalizadores são parte integrante de uma expressão regular. Eles não podem ser adicionados ou removidos posteriormente.</p> + +<p>Por exemplo, <code>re = /\w+\s/g</code> 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.</p> + +<pre class="brush: js notranslate">var re = /\w+\s/g; +var str = "fee fi fo fum"; +var myArray = str.match(re); +console.log(myArray); +</pre> + +<p>Isso exibe ["fee ", "fi ", "fo "]. Neste exemplo, você pode substituir a linha</p> + +<pre class="brush: js notranslate">var re = /\w+\s/g; +</pre> + +<p>por:</p> + +<pre class="brush: js notranslate">var re = new RegExp("\\w+\\s", "g"); +</pre> + +<p>e obtenha o mesmo resultado.</p> + +<p>O sinalizador <code>m</code> é usado para especificar que uma sequência de entrada de múltiplas linhas deve ser tratada como várias linhas. Se o sinalizador <code>m</code> for usado, <code>^</code> e <code>$</code> 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.</p> + +<h2 id="Exemplos">Exemplos</h2> + +<p>Os exemplos que se seguem mostram mais usos expressões regulares.</p> + +<h3 id="Alterando_o_pedido_em_uma_string_de_entrada">Alterando o pedido em uma string de entrada</h3> + +<p>O exemplo a seguir ilustra a formação de expressões regulares e o uso de <code>string.split()</code> e <code>string.replace()</code>. 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</p> + +<pre class="brush: js notranslate">// 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 = ["---------- Original String\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 <code>string</code> 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("---------- After Split by Regular Expression"); + +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("---------- Names Reversed"); +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("---------- Sorted"); +for (i = 0, len = bySurnameList.length; i < len; i++){ + output.push(bySurnameList[i]); +} + +output.push("---------- End"); + +console.log(output.join("\n")); +</pre> + +<h3 id="Usando_caracteres_especiais_para_verificar_entradas">Usando caracteres especiais para verificar entradas</h3> + +<p>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.</p> + +<p>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}.</p> + +<p>Com o evento Change ativo, quando o usuário pressionar Enter, o valor será capturado por RegExp.input.</p> + +<pre class="brush: html notranslate"><!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> +</pre> + +<div>{{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}</div> diff --git a/files/pt-br/web/javascript/guide/sintaxe_e_tipos/index.html b/files/pt-br/web/javascript/guide/sintaxe_e_tipos/index.html new file mode 100644 index 0000000000..953a9543de --- /dev/null +++ b/files/pt-br/web/javascript/guide/sintaxe_e_tipos/index.html @@ -0,0 +1,583 @@ +--- +title: Sintaxe e tipos +slug: Web/JavaScript/Guide/Sintaxe_e_tipos +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}</div> + +<p class="summary">Este capítulo trata sobre a sintaxe básica do JavaScript, declarações de variáveis, tipos de dados e literais.</p> + +<h2 id="Basics" name="Basics">Sintaxe básica</h2> + +<p>JavaScript pega emprestado a maior parte de sua sintaxe do Java, mas também é influenciado por Awk, Perl e Python.</p> + +<p>JavaScript é <strong>case-sensitive</strong> e usa o conjunto de caracteres <strong>Unicode.</strong></p> + +<p>No JavaScript, instruções são chamadas de {{Glossary("Statement", "declarações")}} e são separadas por um ponto e vírgula (;). Espaços, tabulação e uma nova linha são chamados de espaços em branco. O código fonte dos scripts em JavaScript são lidos da esquerda para a direita e são convertidos em uma sequência de elementos de entrada como simbolos, caracteres de controle, terminadores de linha, comentários ou espaço em branco. ECMAScript também define determinadas palavras-chave e literais, e tem regras para inserção automática de ponto e vírgula (<a href="/pt-BR/docs/Web/JavaScript/Reference/Lexical_grammar#Automatic_semicolon_insertion">ASI</a>) para terminar as declarações. No entanto, recomenda-se sempre adicionar ponto e vírgula no final de suas declarações; isso evitará alguns imprevistos. Para obter mais informações, consulte a referência detalhada sobre a <a href="/pt-BR/docs/Web/JavaScript/Reference/Lexical_grammar">gramática léxica</a> do JavaScript.</p> + +<h2 id="Comentários">Comentários</h2> + +<p>A sintaxe dos comentários em JavaScript é semelhante como em C++ e em muitas outras linguagens:</p> + +<pre class="brush: js">// comentário de uma linha + +/* isto é um comentário longo + de múltiplas linhas. + */ + +/* Você não pode, porém, /* aninhar comentários */ SyntaxError */</pre> + +<h2 id="Declarations" name="Declarations">Declarações</h2> + +<p>Existem três tipos de declarações em JavaScript.</p> + +<dl> + <dt>{{jsxref("Statements/var", "var")}}</dt> + <dd>Declara uma variável, opcionalmente, inicializando-a com um valor.</dd> + <dt>{{experimental_inline}} {{jsxref("Statements/let", "let")}}</dt> + <dd>Declara uma variável local de escopo do bloco, opcionalmente, inicializando-a com um valor.</dd> + <dt>{{experimental_inline}} {{jsxref("Statements/const", "const")}}</dt> + <dd>Declara uma constante apenas de leitura.</dd> +</dl> + +<h3 id="Variáveis">Variáveis</h3> + +<p>Você usa variáveis como nomes simbólicos para os valores em sua aplicação. O nome das variáveis, chamados de {{Glossary("Identifier", "identificadores")}}, obedecem determinadas regras.</p> + +<p>Um identificador JavaScript deve começar com uma letra, underline (<code>_</code>), ou cifrão (<code>$</code>); os caracteres subsequentes podem também ser números (0-9). Devido JavaScript ser case-sensitive, letras incluem caracteres de "A" a "Z" (maiúsculos) e caracteres de "a" a "z" (minúsculos).</p> + +<p>Você pode usar a ISO 8859-1 ou caracteres Unicode tal como os identificadores å e ü. Você pode também usar as <a href="/pt-BR/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals">sequências de escape Unicode</a> como caracteres e identificadores.</p> + +<p>Alguns exemplos de nomes legais são <code>Numeros_visitas</code>, <code>temp99</code>, e<code> _nome</code>.</p> + +<h3 id="Declarando_variáveis">Declarando variáveis</h3> + +<p>Você pode declarar uma variável de três formas:</p> + +<ul> + <li>Com a palavra chave {{jsxref("Statements/var", "var")}}. Por exemplo, var <code>x = 42</code>. Esta sintaxe pode ser usada para declarar tanto variáveis locais como variáveis global.</li> + <li>Por simples adição de valor. Por exemplo, <code>x = 42</code>. Isso declara uma variável global. Essa declaração gera um aviso de advertência no JavaScript. Você não deve usar essa variante.</li> + <li>Com a palavra chave {{jsxref("Statements/let", "let")}}. Por exemplo, <code>let y = 13</code>. Essa sintaxe pode ser usada para declarar uma variável local de escopo de bloco. Veja <a href="/pt-BR/docs/Web/JavaScript/Guide/Grammar_and_Types#Variable_scope">escopo de variável</a> abaixo.</li> +</ul> + +<h3 id="Classificando_variáveis">Classificando variáveis</h3> + +<p>Uma variável declarada usando a declaração <code>var</code> ou <code>let</code> sem especificar o valor inicial tem o valor {{jsxref("undefined")}}.</p> + +<p>Uma tentativa de acessar uma variável não declarada resultará no lançamento de uma exceção {{jsxref("ReferenceError")}}:</p> + +<pre class="brush: js">var a; +console.log("O valor de a é " + a); // saída "O valor de a é undefined" +console.log("O valor de b é " + b); // throws ReferenceError exception +</pre> + +<p>Você pode usar <code>undefined</code> para determinar se uma variável tem um valor. No código a seguir, não é atribuído um valor de entrada na variável e a declaração <code><a href="/pt-BR/docs/Web/JavaScript/Reference/Statements/if...else">if</a></code> será avaliada como verdadeira (<code>true</code>).</p> + +<pre class="brush: js">var input; +if(input === undefined){ + facaIsto(); +} else { + facaAquilo(); +} +</pre> + +<p>O valor <code>undefined</code> se comporta como falso (<code>false</code>), quando usado em um contexto booleano. Por exemplo, o código a seguir executa a função <code>myFunction</code> devido o elemento <code>myArray</code> ser undefined:</p> + +<pre class="brush: js">var myArray = []; +if (!myArray[0]) myFunction(); +</pre> + +<p>O valor <code>undefined</code> converte-se para <code>NaN</code> quando usado no contexto numérico.</p> + +<pre class="brush: js">var a; +a + 2; // Avaliado como NaN +</pre> + +<p>Quando você avalia uma variável nula, o valor nulo se comporta como 0 em contextos numéricos e como falso em contextos booleanos. Por exemplo:</p> + +<pre class="brush: js">var n = null; +console.log(n * 32); // a saída para o console será 0. +</pre> + +<h3 id="Variable_scope" name="Variable_scope">Escopo de variável</h3> + +<p>Quando você declara uma váriavel fora de qualquer função, ela é chamada de variável <em>global</em>, porque está disponível para qualquer outro código no documento atual. Quando você declara uma variável dentro de uma função, é chamada de variável <em>local</em>, pois ela está disponível somente dentro dessa função.</p> + +<p>JavaScript antes do ECMAScript 6 não possuía escopo de <a href="/pt-BR/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Block_statement">declaração de bloco</a>; pelo contrário, uma variável declarada dentro de um bloco de uma <em>função </em>é uma variável local (ou contexto <em>global</em>) do bloco que está inserido a função. Por exemplo o código a seguir exibirá 5, porque o escopo de <code>x</code> está na função (ou contexto global) no qual <code>x</code> é declarado, não o bloco, que neste caso é a declaração <code>if</code>. </p> + +<pre class="brush: js">if (true) { + var x = 5; +} +console.log(x); // 5 +</pre> + +<p>Esse comportamento é alterado, quando usado a declaração <code>let</code> introduzida pelo ECMAScript 6.</p> + +<pre class="brush: js">if (true) { + let y = 5; +} +console.log(y); // ReferenceError: y não está definido +</pre> + +<h3 id="Variable_hoisting" name="Variable_hoisting">Hoisting</h3> + +<p>Outra coisa incomum sobre variáveis em JavaScript é que você pode utilizar a variável e declará-la depois, sem obter uma exceção. Este conceito é conhecido como <strong>hoisting</strong>; variáveis em JavaScript são num sentido "hoisted" ou lançada para o topo da função ou declaração. No entanto, as variáveis que são "hoisted" retornarão um valor <code>undefined</code>. Então, mesmo se você usar ou referir a variável e depois declará-la e inicializá-la, ela ainda retornará undefined.</p> + +<pre class="brush: js">/** + * Exemplo 1 + */ +console.log(x === undefined); // exibe "true" +var x = 3; + +/** + * Exemplo 2 + */ +// returnará um valor undefined +var myvar = "my value"; + +(function() { + console.log(myvar); // undefined + var myvar = "local value"; +})(); +</pre> + +<p>Os exemplos acima serão interpretados como:</p> + +<pre class="brush: js">/** + * Exemplo 1 + */ +var x; +console.log(x === undefined); // exibe "true" +x = 3; + +/** + * Exemplo 2 + */ +var myvar = "um valor"; + +(function() { + var myvar; + console.log(myvar); // undefined + myvar = "valor local"; +})(); +</pre> + +<p>Devido o hoisting, todas as declarações <code>var</code> em uma função devem ser colocadas no início da função. Essa recomendação de prática deixa o código mais legível.</p> + +<h3 id="Variáveis_Globais">Variáveis Globais</h3> + +<p>Variáveis globais são propriedades do <em>objeto global</em>. Em páginas web o objeto global é a {{domxref("window")}}, assim você pode configurar e acessar variáveis globais utilizando a sintaxe <code>window.variavel.</code> </p> + +<p>Consequentemente, você pode acessar variáveis globais declaradas em uma janela ou frame ou frame de outra janela. Por exemplo, se uma variável chamada phoneNumber é declarada em um documento, você pode consultar esta variável de um frame como <code>parent.phoneNumber</code>.</p> + +<h3 id="Constantes">Constantes</h3> + +<p>Você pode criar uma constante apenas de leitura por meio da palavra-chave {{jsxref("Statements/const", "const")}}. A sintaxe de um identificador de uma constante é semelhante ao identificador de uma variável: deve começar com uma letra, underline ou cifrão e pode conter caracteres alfabético, numérico ou underline.</p> + +<pre class="brush: js">const prefix = '212'; +</pre> + +<p>Uma constante não pode alterar seu valor por meio de uma atribuição ou ao ser declarada novamente enquanto o script é executado. Deve ser inicializada com um valor.</p> + +<p>As regras de escopo para as constantes são as mesmas para as váriaveis <code>let</code> de escopo de bloco. Se a palavra-chave <code>const</code> for omitida, o identificado é adotado para representar uma variável.</p> + +<p>Você não pode declarar uma constante com o mesmo nome de uma função ou variável que estão no mesmo escopo. Por exemplo: </p> + +<pre class="example-bad brush: js">// Isto irá causar um erro +function f() {}; +const f = 5; + +// Isto também irá causar um erro. +function f() { + const g = 5; + var g; + + //declarações +} +</pre> + +<h2 id="Data_structures_and_types" name="Data_structures_and_types">Estrutura de dados e tipos</h2> + +<h3 id="Tipos_de_dados">Tipos de dados</h3> + +<p>O mais recente padrão ECMAScript define sete tipos de dados:</p> + +<ul> + <li>Seis tipos de dados são os chamados {{Glossary("Primitive", "primitivos")}}: + <ul> + <li>{{Glossary("Boolean")}}. <code>true</code> e <code>false</code>.</li> + <li>{{Glossary("null")}}. Uma palavra-chave que indica valor nulo. Devido JavaScript ser case-sensitive, <code>null</code> não é o mesmo que <code>Null</code>, <code>NULL</code>, ou ainda outra variação.</li> + <li>{{Glossary("undefined")}}. Uma propriedade superior cujo valor é indefinido.</li> + <li>{{Glossary("Number")}}. <code>42</code> ou <code>3.14159</code>.</li> + <li>{{Glossary("String")}}. "Howdy"</li> + <li>{{Glossary("Symbol")}} (novo em ECMAScript 6). Um tipo de dado cuja as instâncias são únicas e imutáveis.</li> + </ul> + </li> + <li>e {{Glossary("Object")}}</li> +</ul> + +<p>Embora esses tipos de dados sejam uma quantidade relativamente pequena, eles permitem realizar funções úteis em suas aplicações. <span style="line-height: 1.5;">{{jsxref("Object", "Objetos")}} e {{jsxref("Function", "funçõess")}} são outros elementos fundamentais na linguagem. Você pode pensar em objetos como recipientes para os valores, e funções como métodos que suas aplicações podem executar.</span></p> + +<h3 id="Conversão_de_tipos_de_dados">Conversão de tipos de dados</h3> + +<p>JavaScript é uma linguagem dinamicamente tipada. Isso significa que você não precisa especificar o tipo de dado de uma variável quando declará-la, e tipos de dados são convertidos automaticamente conforme a necessidade durante a execução do script. Então, por exemplo, você pode definir uma variável da seguinte forma:</p> + +<pre class="brush: js">var answer = 42; +</pre> + +<p>E depois, você pode atribuir uma string para a mesma variável, por exemplo:</p> + +<pre class="brush: js">answer = "Obrigado pelos peixes..."; +</pre> + +<p>Devido JavaScript ser dinamicamente tipado, essa declaração não gera uma mensagem de erro.</p> + +<p>Em expressões envolvendo valores numérico e string com o operador +, JavaScript converte valores numérico para strings. Por exemplo, considere a seguinte declaração:</p> + +<pre class="brush: js">x = "A resposta é " + 42 // "A resposta é 42" +y = 42 + " é a resposta" // "42 é a resposta" +</pre> + +<p>Nas declarações envolvendo outros operadores, JavaScript não converte valores numérico para strings. Por exemplo:</p> + +<pre class="brush: js">"37" - 7 // 30 +"37" + 7 // "377" +</pre> + +<h3 id="Convertendo_strings_para_números">Convertendo strings para números</h3> + +<p>No caso de um valor que representa um número está armazenado na memória como uma string, existem métodos para a conversão.</p> + +<ul> + <li id="parseInt()_and_parseFloat()">{{jsxref("parseInt", "parseInt()")}}</li> + <li>{{jsxref("parseFloat", "parseFloat()")}}</li> +</ul> + +<p>parseInt irá retornar apenas números inteiros, então seu uso é restrito para a casa dos decimais. Além disso, é uma boa prática ao usar parseInt incluir o parâmetro da base. O parâmetro da base é usado para especificar qual sistema númerico deve ser usado.</p> + +<p><font face="Consolas, Liberation Mono, Courier, monospace">Uma método alternativo de conversão de um número em forma de string é com o operador <code>+</code> (operador soma):</font></p> + +<pre class="brush: js">"1.1" + "1.1" = "1.11.1" +(+"1.1") + (+"1.1") = 2.2 +// Nota: Os parênteses foram usados para deixar mais legível o código, ele não é requirido.</pre> + +<h2 id="Literals" name="Literals">Literais</h2> + +<p>Você usa literais para representar valores em JavaScript. Estes são valores fixados, não variáveis, que você <code>literalmente</code> insere em seu script. Esta seção descreve os seguintes tipos literais:</p> + +<ul> + <li>{{anch("Array literal")}}</li> + <li>{{anch("Literais boolean")}}</li> + <li>{{anch("Literais de ponto flutuante")}}</li> + <li>{{anch("Inteiros")}}</li> + <li>{{anch("Objeto literal")}}</li> + <li>{{anch("String literal")}}</li> +</ul> + +<h3 id="Array_literal">Array literal</h3> + +<p>Um literal de array é uma lista de zero ou mais expressões, onde cada uma delas representam um elemento do array, inseridas entre colchetes (<code>[]</code>). Quando você cria um array usando um array literal, ele é inicializado com os valores especificados como seus elementos, e seu comprimento é definido com o número de elementos especificados.</p> + +<p>O exemplo a seguir cria um array <code>coffees</code> com três elementos e um comprimento de três:</p> + +<pre class="brush: js">var coffees = ["French Roast", "Colombian", "Kona"]; +</pre> + +<div class="note"> +<p><strong>Nota :</strong> Um array literal é um tipo de inicializador de objetos. Veja <a href="/pt-BR/docs/Web/JavaScript/Guide/Working_with_Objects#Using_object_initializers" title="en-US/docs/JavaScript/Guide/Working with Objects#Using Object Initializers">Usando inicializadores de Objetos</a>.</p> +</div> + +<p>Se um array é criado usando um literal no topo do script, JavaScript interpreta o array cada vez que avalia a expressão que contêm o array literal. Além disso, um literal usado em uma função é criado cada vez que a função é chamada.</p> + +<p>Array literal são também um array de objetos. Veja {{jsxref("Array")}} e <a href="/pt-BR/docs/Web/JavaScript/Guide/Indexed_collections">Coleções indexadas</a> para detalhes sobre array de objetos.</p> + +<h4 id="Vírgulas_extras_em_array_literal">Vírgulas extras em array literal</h4> + +<p>Você não precisa especificar todos os elementos em um array literal. Se você colocar duas vírgulas em uma linha, o array é criado com <code>undefined</code> para os elementos não especificados. O exemplo a seguir cria um array chamado <code>fish</code>:</p> + +<pre class="brush: js">var fish = ["Lion", , "Angel"]; +</pre> + +<p>Esse array tem dois elementos com valores e um elemento vazio (<code>fish[0]</code> é "Lion", <code>fish[1]</code> é <code>undefined</code>, e <code>fish[2]</code> é "Angel" ).</p> + +<p>Se você incluir uma vírgula à direita no final da lista dos elementos, a vírgula é ignorada. No exemplo a seguir, o comprimento do array é três. Não há nenhum <code>myList[3]</code>. Todas as outras vírgulas na lista indicam um novo elemento.</p> + +<div class="note"> +<p><strong>Nota :</strong> Vírgulas à direita podem criar erros em algumas versões de navegadores web antigos, é recomendável removê-las.</p> +</div> + +<pre class="brush: js">var myList = ['home', , 'school', ]; +</pre> + +<p>No exemplo a seguir, o comprimento do array é quatro, e <code>myList[0]</code> e <code>myList[2]</code> são <code>undefined</code>.</p> + +<pre class="brush: js">var myList = [ , 'home', , 'school']; +</pre> + +<p>No exemplo a seguir, o comprimento do array é quatro, e <code>myList[1]</code> e <code>myList[3]</code> são <code>undefined</code>. Apenas a última vírgula é ignorada.</p> + +<pre class="brush: js">var myList = ['home', , 'school', , ]; +</pre> + +<p>Entender o comportamento de vírgulas extras é importante para a compreensão da linguagem JavaScript, no entanto, quando você escrever seu próprio código: declarar explicitamente os elementos em falta como <code>undefined</code> vai aumentar a clareza do código, e consequentemente na sua manutenção.</p> + +<h3 id="Literais_Boolean">Literais Boolean</h3> + +<p>O tipo Boolean tem dois valores literal: <code>true</code> e <code>false</code>.</p> + +<p>Não confunda os valores primitivos Boolean <code>true</code> e <code>false</code> com os valores <code>true</code> e <code>false</code> do objeto Boolean. O objeto Boolean é um invólucro em torno do tipo de dado primitivo. Veja {{jsxref("Boolean")}} para mais informação.</p> + +<h3 id="Inteiros">Inteiros</h3> + +<p>Inteiros podem sem expressos em decimal (base 10), hexadecimal (base 16), octal (base 8) e binário (base 2).</p> + +<ul> + <li>Decimal inteiro literal consiste em uma sequência de dígitos sem um 0 (zero).</li> + <li>0 (zero) em um inteiro literal indica que ele está em octal. Octal pode incluir somente os dígitos 0-7.</li> + <li>0x (ou 0X) indica um hexadecimal. Inteiros hexadecimais podem incluir dígitos (0-9) e as letras a-f e A-F.</li> + <li>0b (ou 0B) indica um binário. Inteiros binário podem incluir apenas os dígitos 0 e 1.</li> +</ul> + +<p>Alguns exemplos de inteiros literal são:</p> + +<pre class="eval">0, 117 and -345 (decimal, base 10) +015, 0001 and -077 (octal, base 8) +0x1123, 0x00111 and -0xF1A7 (hexadecimal, "hex" or base 16) +0b11, 0b0011 and -0b11 (binário, base 2) +</pre> + +<p>Para maiores informações, veja <a href="/pt-BR/docs/Web/JavaScript/Reference/Lexical_grammar#Numeric_literals">Literais numérico na referência Léxica</a>.</p> + +<h3 id="Literais_de_ponto_flutuante">Literais de ponto flutuante</h3> + +<p>Um literal de ponto flutuante pode ter as seguintes partes:</p> + +<ul> + <li>Um inteiro decimal que pode ter sinal (precedido por "<code>+</code>" ou "<code>-</code>"),</li> + <li>Um ponto decimal ("<code>.</code>"),</li> + <li>Uma fração (outro número decimal),</li> + <li>Um expoente.</li> +</ul> + +<p>O expoente é um "e" ou "E" seguido por um inteiro, que pode ter sinal (precedido por "+" ou "-"). Um literal de ponto flutuante deve ter no mínimo um dígito e um ponto decimal ou "e" (ou "E").</p> + +<p>Mais sucintamente, a sintaxe é:</p> + +<pre class="eval">[(+|-)][digitos][.digitos][(E|e)[(+|-)]digitos] +</pre> + +<p>Por exemplo:</p> + +<pre class="eval">3.1415926 +-.123456789 +-3.1E+12 +.1e-23 +</pre> + +<h3 id="Objeto_literal">Objeto literal</h3> + +<p>Um objeto literal é uma lista de zero ou mais pares de nomes de propriedades e valores associados de de um objeto, colocado entre chaves (<code>{}</code>). Você não deve usar um objeto literal no início de uma declaração. Isso levará a um erro ou não se comportará conforme o esperado, porque o <code>{</code> será interpretado como início de um bloco.</p> + +<p>Segue um exemplo de um objeto literal. O primeiro elemento do objeto <code>car </code>define uma propriedade, <code>myCar</code>, e atribui para ele uma nova string, "Saturn"; o segundo elemento, a propriedade <code>getCar</code>, é imediatamente atribuído o resultado de chamar uma função (<code>carTypes("Honda")</code>); o terceiro elemento, a propriedade especial, usa uma variável existente (<code>sales)</code>.</p> + +<pre class="brush: js">var sales = "Toyota"; + +function carTypes(name) { + if (name == "Honda") { + return name; + } else { + return "Sorry, we don't sell " + name + "."; + } +} + +var car = { myCar: "Saturn", getCar: carTypes("Honda"), special: sales }; + +console.log(car.myCar); // Saturn +console.log(car.getCar); // Honda +console.log(car.special); // Toyota +</pre> + +<p>Além disso, você pode usar um literal numérico ou string para o nome de uma propriedade ou aninhar um objeto dentro do outro. O exemplo a seguir usar essas opções.</p> + +<pre class="brush: js">var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" }; + +console.log(car.manyCars.b); // Jeep +console.log(car[7]); // Mazda +</pre> + +<p>Nomes de propriedades de objeto podem ser qualquer string, incluindo uma string vazia. Caso o nome da propriedade não seja um {{Glossary("Identifier","identificador")}} JavaScript ou número, ele deve ser colocado entre aspas. Nomes de propriedades que não possuem identificadores válido, também não podem ser acessadas pela propriedade de ponto (<code>.</code>), mas podem ser acessadas e definidas com a notação do tipo array ("<code>[]</code>").</p> + +<pre class="brush: js">var unusualPropertyNames = { + "": "Uma string vazia", + "!": "Bang!" +} +console.log(unusualPropertyNames.""); // SyntaxError: string inesperada +console.log(unusualPropertyNames[""]); // Um string vazia +console.log(unusualPropertyNames.!); // SyntaxError: símbolo ! inesperado +console.log(unusualPropertyNames["!"]); // Bang!</pre> + +<p>Observe:</p> + +<pre class="brush: js">var foo = {a: "alpha", 2: "two"}; +console.log(foo.a); // alpha +console.log(foo[2]); // two +//console.log(foo.2); // Error: missing ) after argument list +//console.log(foo[a]); // Error: a não está definido +console.log(foo["a"]); // alpha +console.log(foo["2"]); // two +</pre> + +<h3 id="String_Literal">String Literal</h3> + +<p>Uma string literal são zero ou mais caracteres dispostos em aspas duplas (<code>"</code>) ou aspas simples (<code>'</code>). Uma sequência de caracteres deve ser delimitada por aspas do mesmo tipo; ou seja, as duas aspas simples ou ambas aspas duplas. A seguir um exemplo de strings literais.</p> + +<pre class="eval">"foo" +'bar' +"1234" +"um linha \n outra linha" +"John's cat" +</pre> + +<p>Você pode chamar qualquer um dos métodos do objeto string em uma string literal - JavaScript automaticamente converte a string literal para um objeto string temporário, chama o método, em seguida, descarta o objeto string temporário. Você também pode usar a propriedade <code>String.length</code> com uma string literal:</p> + +<pre class="brush: js">console.log("John's cat".length) +// Irá exibir a quantidade de caracteres na string incluindo o espaço em branco. +// Nesse caso, 10 caracteres. +</pre> + +<p>Você deve usar string literal, a não ser que você precise usar um objeto string. Veja {{jsxref("String")}} para detalhes sobre objetos de strings.</p> + +<h4 id="Uso_de_caracteres_especiais_em_string">Uso de caracteres especiais em string</h4> + +<p>Além dos caracteres comuns, você também pode incluir caracteres especiais em strings, como mostrado no exemplo a seguir.</p> + +<pre class="brush: js">"uma linha \n outra linha" +</pre> + +<p>A tabela a seguir lista os caracteres especiais que podem ser usados em strings no JavaScript.</p> + +<table class="standard-table"> + <caption>Tabela: Caracteres especiais no JavaScript</caption> + <thead> + <tr> + <th scope="col">Caracter</th> + <th scope="col">Descrição</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>\0</code></td> + <td>Byte nulo</td> + </tr> + <tr> + <td><code>\b</code></td> + <td>Backspace</td> + </tr> + <tr> + <td><code>\f</code></td> + <td>Alimentador de formulário</td> + </tr> + <tr> + <td><code>\n</code></td> + <td>Nova linha</td> + </tr> + <tr> + <td><code>\r</code></td> + <td>Retorno do carro</td> + </tr> + <tr> + <td><code>\t</code></td> + <td>Tabulação</td> + </tr> + <tr> + <td><code>\v</code></td> + <td>Tabulação vertical</td> + </tr> + <tr> + <td><code>\'</code></td> + <td>Apóstrofo ou aspas simples</td> + </tr> + <tr> + <td><code>\"</code></td> + <td>Aspas dupla</td> + </tr> + <tr> + <td><code>\\</code></td> + <td>Caractere de barra invertida</td> + </tr> + <tr> + <td><code>\<em>XXX</em></code></td> + <td> + <p>Caractere com a codificação Latin-1 especificada por três dígitos octal <em>XXX </em>entre 0 e 377. Por exemplo, \251 é sequência octal para o símbolo de direitos autorais.</p> + </td> + </tr> + <tr> + </tr> + <tr> + <td><code>\x<em>XX</em></code></td> + <td> + <p>Caractere com a codificação Latin-1 especificada por dois dígitos hexadecimal <em>XX</em> entre 00 e FF. Por exemplo, \xA9 é a sequência hexadecimal para o símbolo de direitos autorais.</p> + </td> + </tr> + <tr> + </tr> + <tr> + <td><code>\u<em>XXXX</em></code></td> + <td> + <p>Caractere Unicode especificado por quatro dígitos hexadecimal <em>XXXX</em>. Por exemplo, \u00A9 é a sequência Unicode para o símbolo de direitos autorais. Veja <a href="/pt-BR/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals">sequências de escape Unicode</a>.</p> + </td> + </tr> + </tbody> +</table> + +<h4 id="Caracteres_de_escape">Caracteres de escape</h4> + +<p>Para caracteres não listados na tabela, se precedidos de barra invertida ela é ignorada, seu uso está absoleto e deve ser ignorado.</p> + +<p>Você pode inserir uma aspa dentro de uma string precendendo-a com uma barra invertida. Isso é conhecido como <em>escaping</em> das aspas. Por exemplo:</p> + +<pre class="brush: js">var quote = "Ele lê \"The Cremation of Sam McGee\" de R.W. Service."; +console.log(quote); +</pre> + +<p>O resultado disso seria:</p> + +<pre class="eval">Ele lê "The Cremation of Sam McGee" de R.W. Service. +</pre> + +<p>Para incluir uma barra invertida dentro de uma string, você deve escapar o caractere de barra invertida. Por exemplo, para atribuir o caminho do arquivo <code>c:\temp </code>para uma string, utilize o seguinte:</p> + +<pre class="brush: js">var home = "c:\\temp"; +</pre> + +<p>Você também pode escapar quebras de linhas, precedendo-as com barra invertida. A barra invertida e a quebra de linha são ambas removidas da string.</p> + +<pre class="brush: js">var str = "esta string \ +está quebrada \ +em várias\ +linhas." +console.log(str); // esta string está quebrada em várias linhas. +</pre> + +<p>Embora JavaScript não tenha sintaxe "heredoc", você pode adicionar uma quebra de linha e um escape de quebra de linha no final de cada linha:</p> + +<pre class="brush: js">var poem = +"Rosas são vermelhas,\n\ +Violetas são azul.\n\ +Eu sou esquizofrênico,\n\ +e é isso que sou." +</pre> + +<h2 id="Mais_informação">Mais informação</h2> + +<p>Este capítulo focou na sintaxe básica das declarações e tipos. Para saber mais sobre a linguagem JavaScript, veja também os seguintes capítulos deste guia:</p> + +<ul> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Control_flow_and_error_handling">Controle de fluxo e manipulação de erro</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Loops_and_iteration">Laços e iteração</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Functions">Funções</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators">Expressões e operadores</a></li> +</ul> + +<p>No próximo capítulo, veremos a construção de controle de fluxos e manipulação de erro.</p> + +<p>{{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}</p> diff --git a/files/pt-br/web/javascript/guide/trabalhando_com_objetos/index.html b/files/pt-br/web/javascript/guide/trabalhando_com_objetos/index.html new file mode 100644 index 0000000000..1dccaeef2e --- /dev/null +++ b/files/pt-br/web/javascript/guide/trabalhando_com_objetos/index.html @@ -0,0 +1,494 @@ +--- +title: Trabalhando com objetos +slug: Web/JavaScript/Guide/Trabalhando_com_Objetos +tags: + - Comparando Objetos + - Contrutor + - Documento + - ECMAScript6 + - Guia(2) + - Iniciante + - JavaScript +translation_of: Web/JavaScript/Guide/Working_with_Objects +--- +<p><strong>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 <em>chave</em>) e um valor. Um valor de propriedade pode ser uma função, que é então considerada um <em>método</em> do objeto. Além dos objetos que são pré-definidos no browser, você pode definir seus próprios objetos.</strong></p> + +<p><strong>Este capítulo descreve como usar objetos, propriedades, funções, e métodos, e como criar seus próprios objetos.</strong></p> + +<h2 id="Visão_geral_de_objetos">Visão geral de objetos</h2> + +<p>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.</p> + +<p>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.</p> + +<h2 id="Objetos_e_propriedades">Objetos e propriedades</h2> + +<p>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:</p> + +<div style="margin-right: 270px;"> +<pre class="brush: js">nomeDoObjeto.nomeDaPropriedade +</pre> +</div> + +<p>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 <code>meuCarro</code> e dar a ele propriedades chamadas <code>fabricacao</code>, <code>modelo</code>, e <code>ano</code>, conforme mostrado a seguir:</p> + +<pre class="brush: js">var meuCarro = new Object(); +meuCarro.fabricacao = "Ford"; +meuCarro.modelo = "Mustang"; +meuCarro.ano = 1969; +</pre> + +<p>Propriedades não definidas de um objeto são {{jsxref("undefined")}} (e não {{jsxref("null")}}).</p> + +<pre class="brush: js">meuCarro.semPropriedade; //undefined</pre> + +<p>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 <em>arrays associativos</em>, 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 <code>meuCarro</code> como se segue:</p> + +<pre class="brush: js">meuCarro["fabricacao"] = "Ford"; +meuCarro["modelo"] = "Mustang"; +meuCarro["ano"] = 1969; +</pre> + +<p>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:</p> + +<pre class="brush: 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); +</pre> + +<p>Você pode também acessar propriedades usando um valor de string que está armazenado em uma variável:</p> + +<div style="width: auto;"> +<pre class="brush: js">var nomeDaPropriedade = "fabricacao"; +meuCarro[nomeDaPropriedade] = "Ford"; + +nomeDaPropriedade = "modelo"; +meuCarro[nomeDaPropriedade] = "Mustang"; +</pre> +</div> + +<p>Você pode usar a notação de colchetes com o comando <a class="internal" href="/en-US/docs/JavaScript/Guide/Statements#for...in_Statement" title="en-US/docs/JavaScript/Guide/Statements#for...in Statement">for...in</a> 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:</p> + +<pre class="brush: js">function mostrarProps(obj, nomeDoObj) { + var resultado = ""; + for (var i in obj) { + if (obj.hasOwnProperty(i)) { + resultado += nomeDoObj + "." + i + " = " + obj[i] + "\n"; + } + } + return resultado; +} +</pre> + +<p>Então, a chamada de função <code>mostrarProps(meuCarro, "meuCarro")</code> retornaria o seguinte:</p> + +<pre>meuCarro.fabricacao = Ford +meuCarro.modelo = Mustang +meuCarro.ano = 1969</pre> + +<h2 id="Objetos_tudo">Objetos: tudo</h2> + +<p>Em JavaScript, quase tudo é um objeto. Todos os tipos primitivos - com exceção de <code>null</code> e <code>undefined</code> - 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.</p> + +<h2 id="Enumerando_todas_as_propriedades_de_um_objeto">Enumerando todas as propriedades de um objeto</h2> + +<p>Começando com a <a href="/en-US/docs/JavaScript/ECMAScript_5_support_in_Mozilla" title="en-US/docs/JavaScript/ECMAScript 5 support in Mozilla">ECMAScript 5</a>, há três formas nativas de se listar (ou "caminhar por") as propriedades de um objeto:</p> + +<ul> + <li><a href="/en-US/docs/JavaScript/Reference/Statements/for...in" title="en-US/docs/JavaScript/Reference/Statements/for...in">for...in</a> loops<br> + Esse método caminha por todas as propriedades enumeráveis de um objeto e sua cadeia de protótipos</li> + <li><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys" title="en-US/docs/JavaScript/Reference/Global Objects/Object/keys">Object.keys(o)</a><br> + Esse método retorna um array com todos os nomes ("chaves") de propriedades próprios de um objeto <code>o</code> (mas não na cadeia de protótipos).</li> + <li><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames" title="en-US/docs/JavaScript/Reference/Global Objects/Object/getOwnPropertyNames">Object.getOwnPropertyNames(o)</a><br> + Esse método retorna um array contendo todos os nomes de propriedades próprios (enumeráveis ou não) de um objeto <code>o</code>.</li> +</ul> + +<p>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:</p> + +<pre class="brush: 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; +} +</pre> + +<p>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.</p> + +<h2 id="Criando_novos_objetos">Criando novos objetos</h2> + +<p>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 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer">objeto inicializador</a>. Alternativamente, você pode primeiro criar uma função construtora e depois instanciar um objeto usando aquela função e o operador <code>new</code>.</p> + +<h3 id="Usando_inicializadores_de_objeto">Usando inicializadores de objeto</h3> + +<p>Além de criar objetos usando uma função construtora, você pode criar objetos usando um <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer">inicializador de objeto</a>. 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++.</p> + +<p>A sintaxe para um objeto usando-se um inicializador de objeto é:</p> + +<pre class="brush: 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 +</pre> + +<p>onde <code>obj</code> é o nome do novo objeto, cada <code>propriedade_<em>i</em></code> é um identificador (um nome, um número, ou uma string literal), e cada <code>valor_<em>i</em></code> é uma expressão cujo valor é atribuído à <code>propriedade_<em>i</em></code>. O <code>obj</code> 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.)</p> + +<p>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.</p> + +<p>O seguinte comando cria um objeto e o atribui à variável <code>x</code> somente se a expressão <code>cond</code> é verdadeira.</p> + +<pre class="brush: js">if (cond) var x = {hi: "there"}; +</pre> + +<p>O seguinte exemplo cria <code>minhaHonda</code> com três propriedades. Note que a propriedade <code>motor</code> é também um objeto com suas próprias propriedades.</p> + +<pre class="brush: js">var minhaHonda = {cor: "vermelho", rodas: 4, motor: {cilindros: 4, tamanho: 2.2}}; +</pre> + +<p>Você pode também usar inicializadores de objeto para criar arrays. Veja <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Array_literals">arrays literais</a>.</p> + +<h3 id="Usando_uma_função_construtora">Usando uma função construtora</h3> + +<p>Alternativamente, você pode criar um objeto com estes dois passos:</p> + +<ol> + <li>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.</li> + <li>Crie uma instância do objeto com <code>new</code>.</li> +</ol> + +<p>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 <code>carro</code>, e você quer ele tenha propriedades de marca, modelo, e ano. Para fazer isto, você escreveria a seguinte função:</p> + +<pre class="brush: js">function Carro(marca, modelo, ano) { + this.marca = marca; + this.modelo = modelo; + this.ano = ano; +} +</pre> + +<p>Note o uso de <code>this</code> para atribuir valores às propriedades do objeto com base nos valores passados para a função.</p> + +<p>Agora você pode criar um objeto chamado <code>meucarro</code> como se segue:</p> + +<pre class="brush: js">var meucarro = new Carro("Eagle", "Talon TSi", 1993); +</pre> + +<p>Esse comando cria <code>meucarro</code> e atribui a ele valores especificados para suas propriedade. Então o valor de <code>meucarro.marca</code> é a string "Eagle", <code>meucarro.ano</code> é o inteiro 1993, e assim por diante.</p> + +<p>Você pode criar qualquer número de objetos <code>carro</code> com o uso de <code>new</code>. Exemplo,</p> + +<pre class="brush: js">var carroDeKen = new Carro("Nissan", "300ZX", 1992); +var carroDeVPG = new Carro("Mazda", "Miata", 1990); +</pre> + +<p>Um objeto pode ter uma propriedade que por si só também é um objeto. Por exemplo, suponha que você define um objeto chamado <code>pessoa</code> como se segue:</p> + +<pre class="brush: js">function Pessoa(nome, idade, sexo) { + this.nome = nome; + this.idade = idade; + this.sexo = sexo; +} +</pre> + +<p>e então você instancia dois novos objetos<code> pessoa</code> da seguinte forma:</p> + +<pre class="brush: js">var jose = new Pessoa("Jose Silva", 33, "M"); +var paulo = new Pessoa("Paulo Santos", 39, "M"); +</pre> + +<p>Então, você pode reescrever a definição de <code>carro</code> de modo a incluir uma propriedade <code>dono</code> que recebe um objeto <code>pessoa</code>, como se segue:</p> + +<pre class="brush: js">function Carro(marca, modelo, ano, dono) { + this.marca = marca; + this.modelo = modelo; + this.ano = ano; + this.dono = dono; +} +</pre> + +<p>Para instanciar os novos objetos, você então usa o seguinte:</p> + +<pre class="brush: js">var carro1 = new Carro("Eagle", "Talon TSi", 1993, jose); +var carro2 = new Carro("Nissan", "300ZX", 1992, paulo); +</pre> + +<p>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 <code>jose</code> e <code>paulo</code> como os argumentos para os donos. Então se você quiser descobrir o nome do dono de <code>carro2</code>, você pode acessar a seguinte propriedade:</p> + +<pre class="brush: js">carro2.dono +</pre> + +<p>Note que você pode sempre adicionar uma propriedade a um objeto definido anteriormente. Por exemplo, o comando</p> + +<pre class="brush: js">carro1.cor = "preto"; +</pre> + +<p>adiciona uma propriedade <code>cor</code> ao <code>carro1</code>, e dá a ele o valor <code>"preto."</code> 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 <code>carro</code>.</p> + +<h3 id="Usando_o_método_Object.create">Usando o método Object.create</h3> + +<p>Objetos podem também ser criados usando-se o método <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create">Object.create()</a></code>. 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.</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="comment token">// Encapsulamento das propriedades e métodos de Animal</span> +<span class="keyword token">var</span> Animal <span class="operator token">=</span> <span class="punctuation token">{</span> + tipo<span class="punctuation token">:</span> <span class="string token">"Invertebrados"</span><span class="punctuation token">,</span> <span class="comment token">// Propriedades de valores padrão</span> + qualTipo <span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> <span class="comment token">// Método que ira mostrar o tipo de Animal</span> + console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.tipo</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span> + +<span class="comment token">// Cria um novo tipo de animal chamado animal1</span> +<span class="keyword token">var</span> animal1 <span class="operator token">=</span> Object<span class="punctuation token">.</span><span class="function token">create</span><span class="punctuation token">(</span>Animal<span class="punctuation token">)</span><span class="punctuation token">;</span> +animal1<span class="punctuation token">.</span><span class="function token">qualTipo</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// Saída:Invertebrados</span> + +<span class="comment token">// Cria um novo tipo de animal chamado Peixes</span> +<span class="keyword token">var</span> peixe <span class="operator token">=</span> Object<span class="punctuation token">.</span><span class="function token">create</span><span class="punctuation token">(</span>Animal<span class="punctuation token">)</span><span class="punctuation token">;</span> +peixe<span class="punctuation token">.</span>tipo <span class="operator token">=</span> <span class="string token">"Peixes"</span><span class="punctuation token">;</span> +peixe<span class="punctuation token">.</span><span class="function token">qualTipo</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// Saída: Peixes</span></code></pre> + +<h3 id="Herança">Herança</h3> + +<p>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 <code>prototype</code> do construtor.</p> + +<h2 id="Indexando_Propriedades_de_Objetos">Indexando Propriedades de Objetos</h2> + +<p>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.</p> + +<p>Esta restrição se aplica quando você cria um objeto e suas propriedades com uma função construtora (como fizemos anteriormente com o <font face="Consolas, Liberation Mono, Courier, monospace">objeto do tipo carro</font>) e quando você define propriedades individuais explicitamente (por exemplo, <code>meuCarro.cor = "vermelho"</code>). Se você inicialmente definir uma propriedade do objeto com um índice, tal como <code>meuCarro[5] = "25 mpg"</code>, você pode subsequentemente referir-se á propriedade somente como <code>meuCarro[5]</code>.</p> + +<p>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 <code><FORM></code> em um documento tem um atributo <code>NAME</code> de "meuFormulario", você pode se referir ao formulário como <code>document.forms[1]</code> ou <code>document.forms["meuFormulario"] </code>ou <code>document.meuFormulario</code>.</p> + +<h2 id="Definindo_propriedades_para_um_tipo_de_objeto">Definindo propriedades para um tipo de objeto</h2> + +<p>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 <code>cor</code> para todos os objetos do tipo C<code>arro</code>, em seguida adiciona um valor a propriedade <code>cor</code> do objeto <code>carro1</code>.</p> + +<pre class="brush: js">Carro.prototype.cor = null; +carro1.cor = "preto"; +</pre> + +<p>Consulte a <a href="/en-US/docs/JavaScript/Reference/Global_Objects/Function/prototype">propriedade</a> <a href="/en-US/docs/JavaScript/Reference/Global_Objects/Function/prototype" title="en-US/docs/JavaScript/Reference/Global Objects/Function/prototype"><code>prototype</code></a> do objeto <code>Function </code>na <a href="/en-US/docs/JavaScript/Reference">Referência</a> <a href="/en-US/docs/JavaScript/Reference" title="en-US/docs/JavaScript/Reference">JavaScript</a> para mais informações.</p> + +<h2 id="Definindo_métodos">Definindo métodos</h2> + +<p>Um <em>método</em> é 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:</p> + +<pre class="brush: js">nomeDoObjeto.nomedometodo = nome_da_funcao; + +var meuObjeto = { + meuMetodo: function(parametros) { + // ...faça algo + } +}; +</pre> + +<p>Onde <code>nomeDoObjeto</code> é um objeto existente, <code>nomedometodo</code> é o nome que você atribuiu ao método, e <code>nome_da_funcao</code> é o nome da função.</p> + +<p>Em seguida, você pode chamar o método no contexto do objeto da seguinte forma:</p> + +<pre class="brush: js">objeto.<code>nomedometodo</code>(parametros); +</pre> + +<p>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 <code>carro</code> previamente definido; por exemplo,</p> + +<pre class="brush: js">function mostreCarro() { + var resultado = "Um belo " + this.ano + " " + this.fabricacao + + " " + this.modelo; + pretty_print(resultado); +} +</pre> + +<p>onde <code>pretty_print</code> é uma função que mostra uma linha horizontal e uma string. Observe o uso de <code>this</code> para referenciar o objeto ao qual o método pertence.</p> + +<p>Você pode fazer desta função um método de <code>carro,</code> adicionando seu estado à definição do objeto.</p> + +<pre class="brush: js">this.mostreCarro = mostreCarro; +</pre> + +<p>Assim, a definição completa de <code>carro</code> seria agora, parecida com essa:</p> + +<pre class="brush: js">function Carro(fabricacao, modelo, ano, proprietario) { + this.fabricacao = fabricacao; + this.modelo = modelo; + this.ano = ano; + this.proprietario = proprietario; + this.mostreCarro = mostreCarro; +} +</pre> + +<p>Então você pode chamar o método <code>mostreCarro</code> para cada objeto seguinte:</p> + +<pre class="brush: js">carro1.mostreCarro(); +carro2.mostreCarro(); +</pre> + +<h2 id="Usando_this_para_referências_de_objetos">Usando <code>this</code> para referências de objetos</h2> + +<p>JavaScript tem uma palavra-chave especial, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this">this</a>, que você pode usar dentro de um método para referenciar o objeto corrente. Por exemplo, suponha que você tenha uma função chamada <code>validate</code> que valida o <code>valor</code> da propriedade de um objeto, dado o objeto e os valores altos e baixos:</p> + +<pre class="brush: js">function validate(obj, lowval, hival) { + if ((obj.value < lowval) || (obj.value > hival)) + alert("Valor inválido!"); +} +</pre> + +<p>Então, você poderia chamar <code>validate</code> no manipulador de evento <code>onchange</code> em cada elemento do formulário, usando <code>this </code>para passar o elemento, como no exemplo a seguir:</p> + +<pre class="brush: html"><input type="text" name="age" size="3" + onChange="validate(this, 18, 99)"> +</pre> + +<p>No geral, <code>this</code> referencia o objeto chamando um método.</p> + +<p>Quando combinado com a propriedade <code>form</code> , <code>this</code> pode referenciar a forma original do objeto atual. No exemplo seguinte, o formulário <code>myForm</code> contém um objeto <code>Text</code> e um botão. Quando o usuário clica no botão, o valor do objeto <code>Text</code> é definido como nome do formulário. O manipulador de eventos <code>onclick</code> do botão usa <code>this.form</code> para referenciar a forma original, <code>myForm</code>.</p> + +<pre class="brush: html"><form name="myForm"> +<p><label>Nome do form:<input type="text" name="text1" value="Beluga"></label> +<p><input name="button1" type="button" value="Mostre o Nome do Form" + onclick="this.form.text1.value = this.form.name"> +</p> +</form></pre> + +<h2 id="Definindo_getters_e_setters">Definindo getters e setters</h2> + +<p>Um <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get">getter</a> é um método que obtém o valor de uma propriedade específica. Um <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set">setter</a> é 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.</p> + +<p>O código a seguir ilustra como getters e setters podem funcionar para um objeto<code> o </code>definido pelo usuário.</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">var</span> o <span class="operator token">=</span> <span class="punctuation token">{</span> + a<span class="punctuation token">:</span> <span class="number token">7</span><span class="punctuation token">,</span> + <span class="keyword token">get</span> <span class="function token">b</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">return</span> <span class="keyword token">this</span><span class="punctuation token">.</span>a <span class="operator token">+</span> <span class="number token">1</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">,</span> + <span class="keyword token">set</span> <span class="function token">c</span><span class="punctuation token">(</span>x<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">this</span><span class="punctuation token">.</span>a <span class="operator token">=</span> x <span class="operator token">/</span> <span class="number token">2</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">;</span> + +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>o<span class="punctuation token">.</span>a<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// 7</span> +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>o<span class="punctuation token">.</span>b<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// 8</span> +o<span class="punctuation token">.</span>c <span class="operator token">=</span> <span class="number token">50</span><span class="punctuation token">;</span> +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>o<span class="punctuation token">.</span>a<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// 25</span></code></pre> + +<p>As propriedades do objeto <code>o</code> são:</p> + +<ul> + <li><code>o.a</code> — um número</li> + <li><code>o.b</code> — um getter que retorna <code>o.a</code> + 1</li> + <li><code>o.c</code> — um setter que define o valor de <code>o.a</code> pela metade do valor definindo para <code>o.c</code></li> +</ul> + +<p>Observe que nomes de função de getters e setters definidos em um objeto literal usando "[gs]et <em>property</em>()" (ao contrário de <code>__define[GS]etter__</code> ) não são os próprios nomes dos getters, embora a sintaxe <code>[gs]et <em>propertyName</em>(){ }</code> possa induzir ao erro e você pensar de outra forma. Para nomear uma função getter ou setter usando a sintaxe "[gs]et <em>property</em>()", define explicitamente um função nomeada programaticamente usando <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty" title="en-US/docs/Core JavaScript 1.5 Reference/Global +Objects/Object/defineProperty">Object.defineProperty</a></code> (ou o legado fallback <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineGetter" title="en-US/docs/Core JavaScript 1.5 Reference/Global +Objects/Object/defineGetter">Object.prototype.__defineGetter__</a></code>).</p> + +<p>O código a seguir ilustra como getters e setters podem extender o protótipo <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date">Date</a></code> para adicionar a propriedade <code>ano</code> para todas as instâncias de classes <code>Date</code> pré-definidas. Ele usa os métodos <code>getFullYear</code> e <code>setFullYear</code> existentes da classe <code>Date</code> para suportar o getter e setter da propriedade <code>ano</code>.</p> + +<p>Estes estados definem um getter e setter para a propriedade <code>ano</code>:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">var</span> d <span class="operator token">=</span> Date<span class="punctuation token">.</span>prototype<span class="punctuation token">;</span> +Object<span class="punctuation token">.</span><span class="function token">defineProperty</span><span class="punctuation token">(</span>d<span class="punctuation token">,</span> <span class="string token">"year"</span><span class="punctuation token">,</span> <span class="punctuation token">{</span> + <span class="keyword token">get</span><span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> <span class="keyword token">return</span> <span class="keyword token">this</span><span class="punctuation token">.</span><span class="function token">getFullYear</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">}</span><span class="punctuation token">,</span> + <span class="keyword token">set</span><span class="punctuation token">:</span> <span class="keyword token">function</span><span class="punctuation token">(</span>y<span class="punctuation token">)</span> <span class="punctuation token">{</span> <span class="keyword token">this</span><span class="punctuation token">.</span><span class="function token">setFullYear</span><span class="punctuation token">(</span>y<span class="punctuation token">)</span> <span class="punctuation token">}</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>Estes estados usam o getter e setter em um objeto <code>Date</code>:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">var</span> now <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Date</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>now<span class="punctuation token">.</span>year<span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// 2000</span> +now<span class="punctuation token">.</span>year <span class="operator token">=</span> <span class="number token">2001</span><span class="punctuation token">;</span> <span class="comment token">// 987617605170</span> +console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>now<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="comment token">// Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001</span></code></pre> + +<p>A principio, getters e setters podem ser ou</p> + +<ul> + <li>definidos usando <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Using_object_initializers">objetos inicializadores</a>, ou</li> + <li>adicionar posteriormente para qualquer objeto a qualquer tempo usando um método getter ou setter adicionado</li> +</ul> + +<p>Ao definir getters e setters usando <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Using_object_initializers">objetos inicializadores</a> tudo o que você precisa fazer é prefixar um método getter com <code>get</code> e um método setter com <code>set</code>. 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:</p> + +<pre class="brush: js">var o = { + a: 7, + <strong>get</strong> b() { return this.a + 1; }, + <strong>set</strong> c(x) { this.a = x / 2; } +}; +</pre> + +<p>Getters e setters podem também ser adicionado em um objeto a qualquer hora depois da criação usando o método <code>Object.defineProperties</code>. 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:<br> + </p> + +<pre class="brush: 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 +</pre> + +<p>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.</p> + +<h2 id="Removendo_propriedades">Removendo propriedades</h2> + +<p>Você pode remover uma propriedade não herdada usando o operador <code>delete</code>. O código a seguir mostra como remover uma propriedade.</p> + +<pre class="brush: 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" +</pre> + +<p>Você também pode usar <code>delete</code> para remover uma variável global se a <code>var</code> keyword não estiver sendo usada para declarar a variável:</p> + +<pre class="brush: js">g = 17; +delete g; +</pre> + +<h2 id="Comparando_Objetos">Comparando Objetos</h2> + +<p>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.</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="comment token">// Duas variáveis, dois objetos distintos com as mesmas propriedades</span> +<span class="keyword token">var</span> fruit <span class="operator token">=</span> <span class="punctuation token">{</span>name<span class="punctuation token">:</span> <span class="string token">"apple"</span><span class="punctuation token">}</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> fruitbear <span class="operator token">=</span> <span class="punctuation token">{</span>name<span class="punctuation token">:</span> <span class="string token">"apple"</span><span class="punctuation token">}</span><span class="punctuation token">;</span> + +fruit <span class="operator token">==</span> fruitbear <span class="comment token">// return false</span> +fruit <span class="operator token">===</span> fruitbear <span class="comment token">// return false</span></code></pre> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="comment token">// Duas variáveis, um único objeto</span> +<span class="keyword token">var</span> fruit <span class="operator token">=</span> <span class="punctuation token">{</span>name<span class="punctuation token">:</span> <span class="string token">"apple"</span><span class="punctuation token">}</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> fruitbear <span class="operator token">=</span> fruit<span class="punctuation token">;</span> <span class="comment token">// assign fruit object reference to fruitbear</span> + +<span class="comment token">// Here fruit and fruitbear are pointing to same object</span> +fruit <span class="operator token">==</span> fruitbear <span class="comment token">// return true</span> +fruit <span class="operator token">===</span> fruitbear <span class="comment token">// return true</span></code></pre> + +<p>Para mais informações sobre comparaçāo de operadores, veja <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators">Operadores de comparaçāo</a>.</p> + +<h2 id="Veja_também">Veja também</h2> + +<ul> + <li>Para se aprofundar, leia sobre os <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model">detalhes do modelo de objetos javaScript</a>.</li> + <li>Para saber mais sobre classes em ECMAScript6 (uma nova forma de criar objetos), veja o capítulo <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes">JavaScript classes</a>.</li> +</ul> + +<div>{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}</div> diff --git a/files/pt-br/web/javascript/guide/usando_promises/index.html b/files/pt-br/web/javascript/guide/usando_promises/index.html new file mode 100644 index 0000000000..a0dd09c8c2 --- /dev/null +++ b/files/pt-br/web/javascript/guide/usando_promises/index.html @@ -0,0 +1,269 @@ +--- +title: Usando promises +slug: Web/JavaScript/Guide/Usando_promises +tags: + - Guía + - Intermediário + - JavaScript + - Promise + - Promises +translation_of: Web/JavaScript/Guide/Using_promises +--- +<div>{{jsSidebar("JavaScript Guide")}}{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}</div> + +<p class="summary">Uma {{jsxref("Promise")}} é um objeto que representa a eventual conclusão ou falha de uma operação assincrona. Como a maioria das pessoas consomem promisses já criadas, este guia explicará o consumo de promisses devolvidas antes de explicar como criá-las.</p> + +<p>Essencialmente, uma promise é um objeto retornado para o qual você adiciona callbacks, em vez de passar callbacks para uma função.</p> + +<p>Por exemplo, em vez de uma função old-style que espera dois callbacks, e chama um deles em uma eventual conclusão ou falha:</p> + +<pre class="brush: js line-numbers language-html language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">successCallback</span><span class="punctuation token">(</span>result<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">"It succeeded with "</span> <span class="operator token">+</span> result<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="keyword token">function</span> <span class="function token">failureCallback</span><span class="punctuation token">(</span>error<span class="punctuation token">)</span> <span class="punctuation token">{</span> + console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="string token">"It failed with "</span> <span class="operator token">+</span> error<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="function token">doSomething</span><span class="punctuation token">(</span>successCallback<span class="punctuation token">,</span> failureCallback<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>…funções modernas retornam uma promisse e então você pode adicionar seus callbacks:</p> + +<pre class="brush: js line-numbers language-html language-js"><code class="language-js"><span class="keyword token">const</span> promise <span class="operator token">=</span> <span class="function token">doSomething</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +promise<span class="punctuation token">.</span><span class="function token">then</span><span class="punctuation token">(</span>successCallback<span class="punctuation token">,</span> failureCallback<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>…ou simplesmente:</p> + +<pre class="brush: js line-numbers language-html language-js"><code class="language-js"><span class="function token">doSomething</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">then</span><span class="punctuation token">(</span>successCallback<span class="punctuation token">,</span> failureCallback<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>Nós chamamos isso de <em>chamada de função assincrona</em>. Essa convenção tem várias vantagens. Vamos explorar cada uma delas.</p> + +<h2 id="Garantias">Garantias</h2> + +<p>Ao contrário dos callbacks com retornos de funções old-style, uma promisse vem com algumas garantias:</p> + +<ul> + <li>Callbacks nunca serão chamados antes da <a href="/en-US/docs/Web/JavaScript/EventLoop#Run-to-completion">conclusão da execução atual</a> do loop de eventos do JavaScript. </li> + <li>Callbacks adicionadas com .then mesmo <em>depois</em> do sucesso ou falha da operação assincrona, serão chamadas, como acima.</li> + <li>Multiplos callbacks podem ser adicionados chamando-se .then várias vezes, para serem executados independentemente da ordem de inserção.</li> +</ul> + +<p>Mas o benefício mais imediato da promises é o encadeamento.</p> + + + +<h2 id="Encadeamento">Encadeamento</h2> + +<p>Uma necessidade comum é executar duas ou mais operações assincronas consecutivas, onde cada operação subsequente começa quando a operação anterior é bem sucedida, com o resultado do passo anterior. Nós conseguimos isso criando uma <em>cadeia de promises</em>.</p> + +<p>Aqui está a magica: a função <code>then</code> retorna uma nova promise, diferente da original:</p> + +<pre class="brush: js">const promise = doSomething(); +const promise2 = promise.then(successCallback, failureCallback); +</pre> + +<p>ou</p> + +<pre class="brush: js">const promise2 = doSomething().then(successCallback, failureCallback); +</pre> + +<p>Essa segunda promise representa a conclusão não apenas de <code>doSomething()</code>, mas também do <code>successCallback</code> ou <code>failureCallback</code> que você passou, que podem ser outras funções assincronas que retornam uma promise. Quando esse for o caso, quaisquer callbacks adicionados a <code>promise2</code> serão enfileiradas atrás da promise retornada por <code>successCallback</code> ou <code>failureCallback</code>.</p> + +<p>Basicamente, cada promise representa a completude de outro passo assíncrono na cadeia.</p> + +<p>Antigamente, realizar operações assíncronas comuns em uma linha levaria à clássica pirâmide da desgraça :</p> + +<pre class="brush: js">doSomething(function(result) { + doSomethingElse(result, function(newResult) { + doThirdThing(newResult, function(finalResult) { + console.log('Got the final result: ' + finalResult); + }, failureCallback); + }, failureCallback); +}, failureCallback); +</pre> + +<p>Ao invés disso, com funções modernas, nós atribuímos nossas callbacks às promises retornadas, formando uma <em>cadeia de promise</em>:</p> + +<pre class="brush: js">doSomething().then(function(result) { + return doSomethingElse(result); +}) +.then(function(newResult) { + return doThirdThing(newResult); +}) +.then(function(finalResult) { + console.log('Got the final result: ' + finalResult); +}) +.catch(failureCallback); +</pre> + +<p>Os argumentos para <code>then</code> são opcionais, e <code>catch(failureCallback)</code> é uma abreviação para <code>then(null, failureCallback)</code>. Você pode também pode ver isso escrito com <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">arrow functions</a>:</p> + +<pre class="brush: js">doSomething() +.then(result => doSomethingElse(result)) +.then(newResult => doThirdThing(newResult)) +.then(finalResult => { + console.log(`Got the final result: ${finalResult}`); +}) +.catch(failureCallback); +</pre> + +<p><strong>Importante: </strong>Sempre retorne um resultado, de outra forma as callbacks não vão capturar o resultado da promise anterior.</p> + +<h3 id="Encadeando_depois_de_um_catch">Encadeando depois de um catch</h3> + +<p>É possivel encadear <em>depois </em>de uma falha, i.e um <code>catch</code>, isso é muito útil para realizar novas ações mesmo depois de uma falha no encadeamento. Leia o seguinte exemplo: </p> + +<pre class="brush: js">new Promise((resolve, reject) => { + console.log('Initial'); + + resolve(); +}) +.then(() => { + throw new Error('Something failed'); + + console.log('Do this'); +}) +.catch(() => { + console.log('Do that'); +}) +.then(() => { + console.log('Do this whatever happened before'); +}); +</pre> + +<p>Isso vai produzir o seguinte texto:</p> + +<pre>Initial +Do that +Do this whatever happened before +</pre> + +<p>Observe que o texto "Do this" não foi impresso por conta que o erro "Something failed" causou uma rejeição.</p> + +<h2 id="Propagação_de_erros">Propagação de erros</h2> + +<p>Na pirâmide da desgraça vista anteriormente, você pode se lembrar de ter visto <code>failureCallback</code> três vezes, em comparação a uma única vez no fim da corrente de promessas:</p> + +<pre class="brush: js">doSomething() +.then(result => doSomethingElse(result)) +.then(newResult => doThirdThing(newResult)) +.then(finalResult => console.log(`Got the final result: ${finalResult}`)) +.catch(failureCallback); +</pre> + +<p>Basicamente, uma corrente de promessas para se houver uma exceção, procurando por catch handlers no lugar. Essa modelagem de código segue bastante a maneira de como o código síncrono funciona:</p> + +<pre class="brush: js">try { + const result = syncDoSomething(); + const newResult = syncDoSomethingElse(result); + const finalResult = syncDoThirdThing(newResult); + console.log(`Got the final result: ${finalResult}`); +} catch(error) { + failureCallback(error); +} +</pre> + +<p>Essa simetria com código assíncrono resulta no <em>syntactic sugar</em> <a href="/en-US/docs/Web/JavaScript/Reference/Statements/async_function"><code>async</code>/<code>await</code></a> presente no ECMAScript 2017:</p> + +<pre class="brush: js">async function foo() { + try { + const result = await doSomething(); + const newResult = await doSomethingElse(result); + const finalResult = await doThirdThing(newResult); + console.log(`Got the final result: ${finalResult}`); + } catch(error) { + failureCallback(error); + } +} +</pre> + +<p>É construído sobre promesas, por exemplo, <code>doSomething()</code> é a mesma função que antes. Leia mais sobre a sintaxe <a href="https://developers.google.com/web/fundamentals/getting-started/primers/async-functions">aqui</a>.</p> + +<p>Por pegar todos os erros, até mesmo exceções jogadas(<em>thrown exceptions</em>) e erros de programação, as promises acabam por solucionar uma falha fundamental presente na pirâmide da desgraça dos callbacks. Essa característica é essencial para a composição funcional das operações assíncronas.</p> + +<h2 id="Criando_uma_Promise_em_torno_de_uma_callback_API_antiga">Criando uma Promise em torno de uma callback API antiga</h2> + +<p>Uma {{jsxref("Promise")}} pode ser criada do zero utilizando o seu construtor. Isto deve ser necessário apenas para o envolvimento de APIs antigas.</p> + +<p>Em um mundo ideal, todas as funções assincronas já retornariam promises. Infelizmente, algumas APIs ainda esperam que os retornos de suceso e/ou falha sejam passados da maneira antiga. O exemplo por excelência é o {{domxref("WindowTimers.setTimeout", "setTimeout()")}} function:</p> + +<pre class="brush: js">setTimeout(() => saySomething("10 seconds passed"), 10000); +</pre> + +<p>Misturar chamadas de retorno e promeses de <em>old-style</em> é problemático. Se <code>saySomething</code> falhar ou contiver um erro de programação, nada o captura.</p> + +<p>Por sorte nós podemos envolve-la em uma promise. É uma boa prática envolver funções problemáticas no menor nivel possível, e nunca chama-las diretamente de novo:</p> + +<pre class="brush: js">const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); + +wait(10000).then(() => saySomething("10 seconds")).catch(failureCallback); +</pre> + +<p>Basically, the promise constructor takes an executor function that lets us resolve or reject a promise manually. Since <code>setTimeout</code> doesn't really fail, we left out reject in this case.</p> + +<p>Basicamente, um construtor de promises pega uma função executora que nos deixa resolver ou rejeitar uma promise manualmente. Desde que <code>setTimeout</code> não venha a falhar, nos deixamos a rejeição de fora nesse caso</p> + +<h2 id="Composição">Composição</h2> + +<p>{{jsxref("Promise.resolve()")}} e {{jsxref("Promise.reject()")}} são atalhos para se criar manualmente uma promessa que já foi resolvida ou rejeitada, respectivamente. Isso pode ser útil em algumas situações.</p> + +<p>{{jsxref("Promise.all()")}} e {{jsxref("Promise.race()")}} são duas ferramentas de composição para se executar operações assíncronas em paralelo.</p> + +<p>Uma composição sequencial é possível usando JavaScript de uma forma esperta:</p> + +<pre class="brush: js">[func1, func2].reduce((p, f) => p.then(f), Promise.resolve()); +</pre> + +<p>Basicamente reduzimos um vetor de funções assíncronas a uma cadeia de promessas equivalentes a: <code>Promise.resolve().then(func1).then(func2);</code></p> + +<p>Isso também pode ser feito com uma função de composição reutilizável, que é comum em programação funcional:</p> + +<pre class="brush: js">const applyAsync = (acc,val) => acc.then(val); +const composeAsync = (...funcs) => x => funcs.reduce(applyAsync, Promise.resolve(x));</pre> + + + +<p>A função composeAsync aceitará qualquer número de funções como argumentos e retornará uma nova função que aceita um valor incial a ser passado pelo pipeline de composição. Isso é benéfico porque alguma, ou todas as funções, podem ser assíncronas ou síncronas, e é garantido de que serão executadas na ordem correta.</p> + +<pre class="brush: js">const transformData = composeAsync(func1, asyncFunc1, asyncFunc2, func2); +transformData(data); +</pre> + +<p>No ECMAScript 2017, uma composição sequencial pode ser feita sde forma mais simples com async/await:</p> + +<pre class="brush: js">for (const f of [func1, func2]) { + await f(); +} +</pre> + +<h2 id="Cronometragem">Cronometragem</h2> + +<p>Para evitar surpresas, funções passadas para <code>then</code> nunca serão chamadas sincronamente, mesmo com uma função ja resolvida:</p> + +<pre class="brush: js">Promise.resolve().then(() => console.log(2)); +console.log(1); // 1, 2 +</pre> + +<p>Instead of running immediately, the passed-in function is put on a microtask queue, which means it runs later when the queue is emptied at the end of the current run of the JavaScript event loop, i.e. pretty soon:</p> + +<p>Ao invés de rodar imediatamente, a função passada é colocada em uma micro tarefa, o que significa que ela roda depois que a fila estiver vazia no final do atual processo de evento de loop do Javascript, isto é muito em breve</p> + +<pre class="brush: js">const wait = ms => new Promise(resolve => setTimeout(resolve, ms)); + +wait().then(() => console.log(4)); +Promise.resolve().then(() => console.log(2)).then(() => console.log(3)); +console.log(1); // 1, 2, 3, 4 +</pre> + +<h2 id="Ver_também">Ver também</h2> + +<ul> + <li>{{jsxref("Promise.then()")}}</li> + <li><a href="http://promisesaplus.com/">Promises/A+ specification</a></li> + <li><a href="https://medium.com/@ramsunvtech/promises-of-promise-part-1-53f769245a53">Venkatraman.R - JS Promise (Part 1, Basics)</a></li> + <li><a href="https://medium.com/@ramsunvtech/js-promise-part-2-q-js-when-js-and-rsvp-js-af596232525c#.dzlqh6ski">Venkatraman.R - JS Promise (Part 2 - Using Q.js, When.js and RSVP.js)</a></li> + <li><a href="https://tech.io/playgrounds/11107/tools-for-promises-unittesting/introduction">Venkatraman.R - Tools for Promises Unit Testing</a></li> + <li><a href="http://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html">Nolan Lawson: We have a problem with promises — Common mistakes with promises</a></li> +</ul> + +<p>{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}</p> diff --git a/files/pt-br/web/javascript/guide/values,_variables,_and_literals/index.html b/files/pt-br/web/javascript/guide/values,_variables,_and_literals/index.html new file mode 100644 index 0000000000..7920ee6b1a --- /dev/null +++ b/files/pt-br/web/javascript/guide/values,_variables,_and_literals/index.html @@ -0,0 +1,601 @@ +--- +title: Sintaxe e tipos +slug: 'Web/JavaScript/Guide/Values,_variables,_and_literals' +tags: + - Guia(2) + - Guía + - Iniciante + - JavaScript +translation_of: Web/JavaScript/Guide/Grammar_and_types +--- +<p>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}</p> + +<p class="summary">Este capítulo trata sobre a sintaxe básica do JavaScript, declarações de variáveis, tipos de dados e literais.</p> + +<h2 id="Basics" name="Basics">Sintaxe básica</h2> + +<p>JavaScript pega emprestado a maior parte de sua sintaxe do Java, mas também é influenciado por Awk, Perl e Python.</p> + +<p>JavaScript é <strong>case-sensitive</strong> e usa o conjunto de caracteres <strong>Unicode. </strong>Por exemplo, a palavra Früh (que significa "cedo" em Alemão) pode ser usada como nome de variável.</p> + +<pre class="brush: js">var Früh = "foobar";</pre> + +<p>Mas a variável <code>früh</code> não é a mesma que <code>Früh</code> porque JavaScript é case sensitive.</p> + +<p>No JavaScript, instruções são chamadas de {{Glossary("Statement", "declaração")}} e são separadas por um ponto e vírgula (;). Espaços, tabulação e uma nova linha são chamados de espaços em branco. O código fonte dos scripts em JavaScript são lidos da esquerda para a direita e são convertidos em uma sequência de elementos de entrada como simbolos, caracteres de controle, terminadores de linha, comentários ou espaço em branco. ECMAScript também define determinadas palavras-chave e literais, e tem regras para inserção automática de ponto e vírgula (<a href="/pt-BR/docs/Web/JavaScript/Reference/Lexical_grammar#Automatic_semicolon_insertion">ASI</a>) para terminar as declarações. No entanto, recomenda-se sempre adicionar ponto e vírgula no final de suas declarações; isso evitará alguns imprevistos. Para obter mais informações, consulte a referência detalhada sobre a <a href="/pt-BR/docs/Web/JavaScript/Reference/Lexical_grammar">gramática léxica</a> do JavaScript.</p> + +<h2 id="Comentários">Comentários</h2> + +<p>A sintaxe dos comentários em JavaScript é semelhante como em C++ e em muitas outras linguagens:</p> + +<pre class="brush: js">// comentário de uma linha + +/* isto é um comentário longo + de múltiplas linhas. + */ + +/* Você não pode, porém, /* aninhar comentários */ SyntaxError */</pre> + +<h2 id="Declarations" name="Declarations">Declarações</h2> + +<p>Existem três tipos de declarações em JavaScript.</p> + +<dl> + <dt>{{jsxref("Statements/var", "var")}}</dt> + <dd>Declara uma variável, opcionalmente, inicializando-a com um valor.</dd> + <dt>{{experimental_inline}} {{jsxref("Statements/let", "let")}}</dt> + <dd>Declara uma variável local de escopo do bloco, opcionalmente, inicializando-a com um valor.</dd> + <dt>{{experimental_inline}} {{jsxref("Statements/const", "const")}}</dt> + <dd>Declara uma constante de escopo de bloco, apenas de leitura.</dd> +</dl> + +<h3 id="Variáveis">Variáveis</h3> + +<p>Você usa variáveis como nomes simbólicos para os valores em sua aplicação. O nome das variáveis, chamados de {{Glossary("Identifier", "identificadores")}}, obedecem determinadas regras.</p> + +<p>Um identificador JavaScript deve começar com uma letra, underline (<code>_</code>), ou cifrão (<code>$</code>); os caracteres subsequentes podem também ser números (0-9). Devido JavaScript ser case-sensitive, letras incluem caracteres de "A" a "Z" (maiúsculos) e caracteres de "a" a "z" (minúsculos).</p> + +<p>Você pode usar a ISO 8859-1 ou caracteres Unicode tal como os identificadores å e ü. Você pode também usar as <a href="/pt-BR/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals">sequências de escape Unicode</a> como caracteres e identificadores.</p> + +<p>Alguns exemplos de nomes legais são <code>Numeros_visitas</code>, <code>temp99</code>, e<code> _nome</code>.</p> + +<h3 id="Declarando_variáveis">Declarando variáveis</h3> + +<p>Você pode declarar uma variável de três formas:</p> + +<ul> + <li>Com a palavra chave {{jsxref("Statements/var", "var")}}. Por exemplo, var <code>x = 42</code>. Esta sintaxe pode ser usada para declarar tanto variáveis locais como variáveis globais.</li> + <li>Por simples adição de valor. Por exemplo, <code>x = 42</code>. Isso declara uma variável global. Essa declaração gera um aviso de advertência no JavaScript. Você não deve usar essa variante.</li> + <li>Com a palavra chave {{jsxref("Statements/let", "let")}}. Por exemplo, <code>let y = 13</code>. Essa sintaxe pode ser usada para declarar uma variável local de escopo de bloco. Veja <a href="/pt-BR/docs/Web/JavaScript/Guide/Grammar_and_Types#Variable_scope">escopo de variável</a> abaixo.</li> +</ul> + +<h3 id="Classificando_variáveis">Classificando variáveis</h3> + +<p>Uma variável declarada usando a declaração <code>var</code> ou <code>let</code> sem especificar o valor inicial tem o valor {{jsxref("undefined")}}.</p> + +<p>Uma tentativa de acessar uma variável não declarada resultará no lançamento de uma exceção {{jsxref("ReferenceError")}}:</p> + +<pre class="brush: js">var a; +console.log("O valor de a é " + a); // saída "O valor de a é undefined" +console.log("O valor de b é " + b); // executa uma exception de erro de referência (ReferenceError) +</pre> + +<p>Você pode usar <code>undefined</code> para determinar se uma variável tem um valor. No código a seguir, não é atribuído um valor de entrada na variável e a declaração <code><a href="/pt-BR/docs/Web/JavaScript/Reference/Statements/if...else">if</a></code> será avaliada como verdadeira (<code>true</code>).</p> + +<pre class="brush: js">var input; +if(input === undefined){ + facaIsto(); +} else { + facaAquilo(); +} +</pre> + +<p>O valor <code>undefined</code> se comporta como falso (<code>false</code>), quando usado em um contexto booleano. Por exemplo, o código a seguir executa a função <code>myFunction</code> devido o elemento <code>myArray</code> ser undefined:</p> + +<pre class="brush: js">var myArray = []; +if (!myArray[0]) myFunction(); +</pre> + +<p>O valor <code>undefined</code> converte-se para <code>NaN</code> quando usado no contexto numérico.</p> + +<pre class="brush: js">var a; +a + 2; // Avaliado como NaN +</pre> + +<p>Quando você avalia uma variável nula, o valor nulo se comporta como 0 em contextos numéricos e como falso em contextos booleanos. Por exemplo:</p> + +<pre class="brush: js">var n = null; +console.log(n * 32); // a saída para o console será 0. +</pre> + +<h3 id="Variable_scope" name="Variable_scope">Escopo de variável</h3> + +<p>Quando você declara uma váriavel fora de qualquer função, ela é chamada de variável <em>global</em>, porque está disponível para qualquer outro código no documento atual. Quando você declara uma variável dentro de uma função, é chamada de variável <em>local</em>, pois ela está disponível somente dentro dessa função.</p> + +<p>JavaScript antes do ECMAScript 6 não possuía escopo de <a href="/pt-BR/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Block_statement">declaração de bloco</a>; pelo contrário, uma variável declarada dentro de um bloco de uma <em>função </em>é uma variável local (ou contexto <em>global</em>) do bloco que está inserido a função. Por exemplo o código a seguir exibirá 5, porque o escopo de <code>x</code> está na função (ou contexto global) no qual <code>x</code> é declarado, não o bloco, que neste caso é a declaração <code>if</code>. </p> + +<pre class="brush: js">if (true) { + var x = 5; +} +console.log(x); // 5 +</pre> + +<p>Esse comportamento é alterado, quando usado a declaração <code>let</code> introduzida pelo ECMAScript 6.</p> + +<pre class="brush: js">if (true) { + let y = 5; +} +console.log(y); // ReferenceError: y não está definido +</pre> + +<h3 id="Variable_hoisting" name="Variable_hoisting">Variável de elevação</h3> + +<p>Outra coisa incomum sobre variáveis em JavaScript é que você pode utilizar a variável e declará-la depois, sem obter uma exceção. Este conceito é conhecido como <strong>hoisting</strong>; variáveis em JavaScript são num sentido "hoisted" ou lançada para o topo da função ou declaração. No entanto, as variáveis que são "hoisted" retornarão um valor <code>undefined</code>. Então, mesmo se você usar ou referir a variável e depois declará-la e inicializá-la, ela ainda retornará undefined.</p> + +<pre class="brush: js">/** + * Exemplo 1 + */ +console.log(x === undefined); // exibe "true" +var x = 3; + +/** + * Exemplo 2 + */ +// retornará um valor undefined +var myvar = "my value"; + +(function() { + console.log(myvar); // undefined + var myvar = "local value"; +})(); +</pre> + +<p>Os exemplos acima serão interpretados como:</p> + +<pre class="brush: js">/** + * Exemplo 1 + */ +var x; +console.log(x === undefined); // exibe "true" +x = 3; + +/** + * Exemplo 2 + */ +var myvar = "um valor"; + +(function() { + var myvar; + console.log(myvar); // undefined + myvar = "valor local"; +})(); +</pre> + +<p>Devido o hoisting, todas as declarações <code>var</code> em uma função devem ser colocadas no início da função. Essa recomendação de prática deixa o código mais legível.</p> + +<h3 id="Variáveis_Globais">Variáveis Globais</h3> + +<p>Variáveis globais são propriedades do <em>objeto global</em>. Em páginas web o objeto global é a {{domxref("window")}}, assim você pode configurar e acessar variáveis globais utilizando a sintaxe <code>window.variavel.</code> </p> + +<p>Consequentemente, você pode acessar variáveis globais declaradas em uma janela ou frame ou frame de outra janela. Por exemplo, se uma variável chamada phoneNumber é declarada em um documento, você pode consultar esta variável de um frame como <code>parent.phoneNumber</code>.</p> + +<h3 id="Constantes">Constantes</h3> + +<p>Você pode criar uma constante apenas de leitura por meio da palavra-chave {{jsxref("Statements/const", "const")}}. A sintaxe de um identificador de uma constante é semelhante ao identificador de uma variável: deve começar com uma letra, sublinhado ou cifrão e pode conter caractere alfabético, numérico ou sublinhado.</p> + +<pre class="brush: js">const PI = 3.14; +</pre> + +<p>Uma constante não pode alterar seu valor por meio de uma atribuição ou ser declarada novamente enquanto o script está em execução. Deve ser inicializada com um valor.</p> + +<p>As regras de escopo para as constantes são as mesmas para as váriaveis <code>let</code> de escopo de bloco. Se a palavra-chave <code>const</code> for omitida, presume-se que o identificador represente uma variável.</p> + +<p>Você não pode declarar uma constante com o mesmo nome de uma função ou variável que estão no mesmo escopo. Por exemplo: </p> + +<pre class="example-bad brush: js">// Isto irá causar um erro +function f() {}; +const f = 5; + +// Isto também irá causar um erro. +function f() { + const g = 5; + var g; + + //declarações +} +</pre> + +<h2 id="Data_structures_and_types" name="Data_structures_and_types">Estrutura de dados e tipos</h2> + +<h3 id="Tipos_de_dados">Tipos de dados</h3> + +<p>O mais recente padrão ECMAScript define sete tipos de dados:</p> + +<ul> + <li>Seis tipos de dados são os chamados {{Glossary("Primitive", "primitivos")}}: + <ul> + <li>{{Glossary("Boolean")}}. <code>true</code> e <code>false</code>.</li> + <li>{{Glossary("null")}}. Uma palavra-chave que indica valor nulo. Devido JavaScript ser case-sensitive, <code>null</code> não é o mesmo que <code>Null</code>, <code>NULL</code>, ou ainda outra variação.</li> + <li>{{Glossary("undefined")}}. Uma propriedade superior cujo valor é indefinido.</li> + <li>{{Glossary("Number")}}. <code>42</code> ou <code>3.14159</code>.</li> + <li>{{Glossary("String")}}. "Howdy"</li> + <li>{{Glossary("Symbol")}} (novo em ECMAScript 6). Um tipo de dado cuja as instâncias são únicas e imutáveis.</li> + </ul> + </li> + <li>e {{Glossary("Object")}}</li> +</ul> + +<p>Embora esses tipos de dados sejam uma quantidade relativamente pequena, eles permitem realizar funções úteis em suas aplicações. <span style="line-height: 1.5;">{{jsxref("Object", "Objetos")}} e {{jsxref("Function", "funções")}} são outros elementos fundamentais na linguagem. Você pode pensar em objetos como recipientes para os valores, e funções como métodos que suas aplicações podem executar.</span></p> + +<h3 id="Conversão_de_tipos_de_dados">Conversão de tipos de dados</h3> + +<p>JavaScript é uma linguagem dinamicamente tipada. Isso significa que você não precisa especificar o tipo de dado de uma variável quando declará-la, e tipos de dados são convertidos automaticamente conforme a necessidade durante a execução do script. Então, por exemplo, você pode definir uma variável da seguinte forma:</p> + +<pre class="brush: js">var answer = 42; +</pre> + +<p>E depois, você pode atribuir uma string para a mesma variável, por exemplo:</p> + +<pre class="brush: js">answer = "Obrigado pelos peixes..."; +</pre> + +<p>Devido JavaScript ser dinamicamente tipado, essa declaração não gera uma mensagem de erro.</p> + +<p>Em expressões envolvendo valores numérico e string com o operador +, JavaScript converte valores numérico para strings. Por exemplo, considere a seguinte declaração:</p> + +<pre class="brush: js">x = "A resposta é " + 42 // "A resposta é 42" +y = 42 + " é a resposta" // "42 é a resposta" +</pre> + +<p>Nas declarações envolvendo outros operadores, JavaScript não converte valores numérico para strings. Por exemplo:</p> + +<pre class="brush: js">"37" - 7 // 30 +"37" + 7 // "377" +</pre> + +<h3 id="Convertendo_strings_para_números">Convertendo strings para números</h3> + +<p>No caso de um valor que representa um número está armazenado na memória como uma string, existem métodos para a conversão.</p> + +<ul> + <li id="parseInt()_and_parseFloat()">{{jsxref("parseInt", "parseInt()")}}</li> + <li>{{jsxref("parseFloat", "parseFloat()")}}</li> +</ul> + +<p>parseInt irá retornar apenas números inteiros, então seu uso é restrito para a casa dos decimais. Além disso, é uma boa prática ao usar parseInt incluir o parâmetro da base. O parâmetro da base é usado para especificar qual sistema númerico deve ser usado.</p> + +<p><font face="Consolas, Liberation Mono, Courier, monospace">Uma método alternativo de conversão de um número em forma de string é com o operador <code>+</code> (operador soma):</font></p> + +<pre class="brush: js">"1.1" + "1.1" = "1.11.1" +(+"1.1") + (+"1.1") = 2.2 +// Nota: Os parênteses foram usados para deixar mais legível o código, ele não é requirido.</pre> + +<h2 id="Literals" name="Literals">Literais</h2> + +<p>Você usa literais para representar valores em JavaScript. Estes são valores fixados, não variáveis, que você <code>literalmente</code> insere em seu script. Esta seção descreve os seguintes tipos literais:</p> + +<ul> + <li>{{anch("Array literal")}}</li> + <li>{{anch("Literais boolean")}}</li> + <li>{{anch("Literais de ponto flutuante")}}</li> + <li>{{anch("Inteiros")}}</li> + <li>{{anch("Objeto literal")}}</li> + <li>{{anch("String literal")}}</li> +</ul> + +<h3 id="Array_literal">Array literal</h3> + +<p>Um array literal é uma lista de zero ou mais expressões, onde cada uma delas representam um elemento do array, inseridas entre colchetes (<code>[]</code>). Quando você cria um array usando um array literal, ele é inicializado com os valores especificados como seus elementos, e seu comprimento é definido com o número de elementos especificados.</p> + +<p>O exemplo a seguir cria um array <code>coffees</code> com três elementos e um comprimento de três:</p> + +<pre class="brush: js">var coffees = ["French Roast", "Colombian", "Kona"]; +</pre> + +<div class="note"> +<p><strong>Nota :</strong> Um array literal é um tipo de inicializador de objetos. Veja <a href="/pt-BR/docs/Web/JavaScript/Guide/Working_with_Objects#Using_object_initializers" title="en-US/docs/JavaScript/Guide/Working with Objects#Using Object Initializers">Usando inicializadores de Objetos</a>.</p> +</div> + +<p>Se um array é criado usando um literal no topo do script, JavaScript interpreta o array cada vez que avalia a expressão que contêm o array literal. Além disso, um literal usado em uma função é criado cada vez que a função é chamada.</p> + +<p>Array literal são também um array de objetos. Veja {{jsxref("Array")}} e <a href="/pt-BR/docs/Web/JavaScript/Guide/Indexed_collections">Coleções indexadas</a> para detalhes sobre array de objetos.</p> + +<h4 id="Vírgulas_extras_em_array_literal">Vírgulas extras em array literal</h4> + +<p>Você não precisa especificar todos os elementos em um array literal. Se você colocar duas vírgulas em uma linha, o array é criado com <code>undefined</code> para os elementos não especificados. O exemplo a seguir cria um array chamado <code>fish</code>:</p> + +<pre class="brush: js">var fish = ["Lion", , "Angel"]; +</pre> + +<p>Esse array tem dois elementos com valores e um elemento vazio (<code>fish[0]</code> é "Lion", <code>fish[1]</code> é <code>undefined</code>, e <code>fish[2]</code> é "Angel" ).</p> + +<p>Se você incluir uma vírgula à direita no final da lista dos elementos, a vírgula é ignorada. No exemplo a seguir, o comprimento do array é três. Não há nenhum <code>myList[3]</code>. Todas as outras vírgulas na lista indicam um novo elemento.</p> + +<div class="note"> +<p><strong>Nota :</strong> Vírgulas à direita podem criar erros em algumas versões de navegadores web antigos, é recomendável removê-las.</p> +</div> + +<pre class="brush: js">var myList = ['home', , 'school', ]; +</pre> + +<p>No exemplo a seguir, o comprimento do array é quatro, e <code>myList[0]</code> e <code>myList[2]</code> são <code>undefined</code>.</p> + +<pre class="brush: js">var myList = [ , 'home', , 'school']; +</pre> + +<p>No exemplo a seguir, o comprimento do array é quatro, e <code>myList[1]</code> e <code>myList[3]</code> são <code>undefined</code>. Apenas a última vírgula é ignorada.</p> + +<pre class="brush: js">var myList = ['home', , 'school', , ]; +</pre> + +<p>Entender o comportamento de vírgulas extras é importante para a compreensão da linguagem JavaScript, no entanto, quando você escrever seu próprio código: declarar explicitamente os elementos em falta como <code>undefined</code> vai aumentar a clareza do código, e consequentemente na sua manutenção.</p> + +<h3 id="Literais_Boolean">Literais Boolean</h3> + +<p>O tipo Boolean tem dois valores literal: <code>true</code> e <code>false</code>.</p> + +<p>Não confunda os valores primitivos Boolean <code>true</code> e <code>false</code> com os valores <code>true</code> e <code>false</code> do objeto Boolean. O objeto Boolean é um invólucro em torno do tipo de dado primitivo. Veja {{jsxref("Boolean")}} para mais informação.</p> + +<h3 id="Inteiros">Inteiros</h3> + +<p>Inteiros podem ser expressos em decimal (base 10), hexadecimal (base 16), octal (base 8) e binário (base 2).</p> + +<ul> + <li>Decimal inteiro literal consiste em uma sequência de dígitos sem um 0 (zero).</li> + <li>0 (zero) em um inteiro literal indica que ele está em octal. Octal pode incluir somente os dígitos 0-7.</li> + <li>0x (ou 0X) indica um hexadecimal. Inteiros hexadecimais podem incluir dígitos (0-9) e as letras a-f e A-F.</li> + <li>0b (ou 0B) indica um binário. Inteiros binário podem incluir apenas os dígitos 0 e 1.</li> +</ul> + +<p>Alguns exemplos de inteiros literal são:</p> + +<pre class="eval">0, 117 and -345 (decimal, base 10) +015, 0001 and -077 (octal, base 8) +0x1123, 0x00111 and -0xF1A7 (hexadecimal, "hex" or base 16) +0b11, 0b0011 and -0b11 (binário, base 2) +</pre> + +<p>Para maiores informações, veja <a href="/pt-BR/docs/Web/JavaScript/Reference/Lexical_grammar#Numeric_literals">Literais numérico na referência Léxica</a>.</p> + +<h3 id="Literais_de_ponto_flutuante">Literais de ponto flutuante</h3> + +<p>Um literal de ponto flutuante pode ter as seguintes partes:</p> + +<ul> + <li>Um inteiro decimal que pode ter sinal (precedido por "<code>+</code>" ou "<code>-</code>"),</li> + <li>Um ponto decimal ("<code>.</code>"),</li> + <li>Uma fração (outro número decimal),</li> + <li>Um expoente.</li> +</ul> + +<p>O expoente é um "e" ou "E" seguido por um inteiro, que pode ter sinal (precedido por "+" ou "-"). Um literal de ponto flutuante deve ter no mínimo um dígito e um ponto decimal ou "e" (ou "E").</p> + +<p>Mais sucintamente, a sintaxe é:</p> + +<pre class="eval">[(+|-)][digitos][.digitos][(E|e)[(+|-)]digitos] +</pre> + +<p>Por exemplo:</p> + +<pre class="eval">3.1415926 +-.123456789 +-3.1E+12 +.1e-23 +</pre> + +<h3 id="Objeto_literal">Objeto literal</h3> + +<p>Um objeto literal é uma lista de zero ou mais pares de nomes de propriedades e valores associados de um objeto, colocado entre chaves (<code>{}</code>). Você não deve usar um objeto literal no início de uma declaração. Isso levará a um erro ou não se comportará conforme o esperado, porque o <code>{</code> será interpretado como início de um bloco.</p> + +<p>Segue um exemplo de um objeto literal. O primeiro elemento do objeto <code>carro </code>define uma propriedade, <code>meuCarro</code>, e atribui para ele uma nova string, "Punto"; o segundo elemento, a propriedade <code>getCarro</code>, é imediatamente atribuído o resultado de chamar uma função (<code>tipoCarro("Fiat")</code>); o terceiro elemento, a propriedade <code>especial</code>, usa uma variável existente (<code>vendas)</code>.</p> + +<pre class="brush: js">var vendas = "Toyota"; + +function tipoCarro(nome) { + if (nome == "Fiat") { + return nome; + } else { + return "Desculpa, não vendemos carros " + nome + "."; + } +} + +var carro = { meuCarro: "Punto", getCarro: tipoCarro("Fiat"), especial: vendas }; + +console.log(carro.meuCarro); // Punto +console.log(carro.getCarro); // Fiat +console.log(carro.especial); // Toyota +</pre> + +<p>Além disso, você pode usar um literal numérico ou string para o nome de uma propriedade ou aninhar um objeto dentro do outro. O exemplo a seguir usar essas opções.</p> + +<pre class="brush: js">var carro = { carros: {a: "Saab", "b": "Jeep"}, 7: "Mazda" }; + +console.log(carro.carros.b); // Jeep +console.log(carro[7]); // Mazda +</pre> + +<p>Nomes de propriedades de objeto podem ser qualquer string, incluindo uma string vazia. Caso o nome da propriedade não seja um {{Glossary("Identifier","identificador")}} JavaScript ou número, ele deve ser colocado entre aspas. Nomes de propriedades que não possuem identificadores válido, também não podem ser acessadas pela propriedade de ponto (<code>.</code>), mas podem ser acessadas e definidas com a notação do tipo array ("<code>[]</code>").</p> + +<pre class="brush: js">var unusualPropertyNames = { + "": "Uma string vazia", + "!": "Bang!" +} +console.log(unusualPropertyNames.""); // SyntaxError: string inesperada +console.log(unusualPropertyNames[""]); // Um string vazia +console.log(unusualPropertyNames.!); // SyntaxError: símbolo ! inesperado +console.log(unusualPropertyNames["!"]); // Bang!</pre> + +<p>Observe:</p> + +<pre class="brush: js">var foo = {a: "alpha", 2: "two"}; +console.log(foo.a); // alpha +console.log(foo[2]); // two +//console.log(foo.2); // Error: missing ) after argument list +//console.log(foo[a]); // Error: a não está definido +console.log(foo["a"]); // alpha +console.log(foo["2"]); // two +</pre> + +<h3 id="sect1"> </h3> + +<h3 id="Expressão_Regex_Literal">Expressão Regex Literal</h3> + +<p>Um regex literal é um padrão entre barras. A seguir um exemplo de regex literal.</p> + +<pre>var re = /ab+c/;</pre> + +<h3 id="String_Literal">String Literal</h3> + +<p>Uma string literal são zero ou mais caracteres dispostos em aspas duplas (<code>"</code>) ou aspas simples (<code>'</code>). Uma sequência de caracteres deve ser delimitada por aspas do mesmo tipo; ou seja, as duas aspas simples ou ambas aspas duplas. A seguir um exemplo de strings literais.</p> + +<pre class="eval">"foo" +'bar' +"1234" +"um linha \n outra linha" +"John's cat" +</pre> + +<p>Você pode chamar qualquer um dos métodos do objeto string em uma string literal - JavaScript automaticamente converte a string literal para um objeto string temporário, chama o método, em seguida, descarta o objeto string temporário. Você também pode usar a propriedade <code>String.length</code> com uma string literal:</p> + +<pre class="brush: js">console.log("John's cat".length) +// Irá exibir a quantidade de caracteres na string incluindo o espaço em branco. +// Nesse caso, 10 caracteres. +</pre> + +<p>Você deve usar string literal, a não ser que você precise usar um objeto string. Veja {{jsxref("String")}} para detalhes sobre objetos de strings.</p> + +<h4 id="Uso_de_caracteres_especiais_em_string">Uso de caracteres especiais em string</h4> + +<p>Além dos caracteres comuns, você também pode incluir caracteres especiais em strings, como mostrado no exemplo a seguir.</p> + +<pre class="brush: js">"uma linha \n outra linha" +</pre> + +<p>A tabela a seguir lista os caracteres especiais que podem ser usados em strings no JavaScript.</p> + +<table class="standard-table"> + <caption>Tabela: Caracteres especiais no JavaScript</caption> + <thead> + <tr> + <th scope="col">Caracter</th> + <th scope="col">Descrição</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>\0</code></td> + <td>Byte nulo</td> + </tr> + <tr> + <td><code>\b</code></td> + <td>Backspace</td> + </tr> + <tr> + <td><code>\f</code></td> + <td>Alimentador de formulário</td> + </tr> + <tr> + <td><code>\n</code></td> + <td>Nova linha</td> + </tr> + <tr> + <td><code>\r</code></td> + <td>Retorno do carro</td> + </tr> + <tr> + <td><code>\t</code></td> + <td>Tabulação</td> + </tr> + <tr> + <td><code>\v</code></td> + <td>Tabulação vertical</td> + </tr> + <tr> + <td><code>\'</code></td> + <td>Apóstrofo ou aspas simples</td> + </tr> + <tr> + <td><code>\"</code></td> + <td>Aspas dupla</td> + </tr> + <tr> + <td><code>\\</code></td> + <td>Caractere de barra invertida</td> + </tr> + <tr> + <td><code>\<em>XXX</em></code></td> + <td> + <p>Caractere com a codificação Latin-1 especificada por três dígitos octal <em>XXX </em>entre 0 e 377. Por exemplo, \251 é sequência octal para o símbolo de direitos autorais.</p> + </td> + </tr> + <tr> + </tr> + <tr> + <td><code>\x<em>XX</em></code></td> + <td> + <p>Caractere com a codificação Latin-1 especificada por dois dígitos hexadecimal <em>XX</em> entre 00 e FF. Por exemplo, \xA9 é a sequência hexadecimal para o símbolo de direitos autorais.</p> + </td> + </tr> + <tr> + </tr> + <tr> + <td><code>\u<em>XXXX</em></code></td> + <td> + <p>Caractere Unicode especificado por quatro dígitos hexadecimal <em>XXXX</em>. Por exemplo, \u00A9 é a sequência Unicode para o símbolo de direitos autorais. Veja <a href="/pt-BR/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals">sequências de escape Unicode</a>.</p> + </td> + </tr> + </tbody> +</table> + +<h4 id="Caracteres_de_escape">Caracteres de escape</h4> + +<p>Para caracteres não listados na tabela, se precedidos de barra invertida ela é ignorada, seu uso está absoleto e deve ser ignorado.</p> + +<p>Você pode inserir uma aspa dentro de uma string precendendo-a com uma barra invertida. Isso é conhecido como <em>escaping</em> das aspas. Por exemplo:</p> + +<pre class="brush: js">var quote = "Ele lê \"The Cremation of Sam McGee\" de R.W. Service."; +console.log(quote); +</pre> + +<p>O resultado disso seria:</p> + +<pre class="eval">Ele lê "The Cremation of Sam McGee" de R.W. Service. +</pre> + +<p>Para incluir uma barra invertida dentro de uma string, você deve escapar o caractere de barra invertida. Por exemplo, para atribuir o caminho do arquivo <code>c:\temp </code>para uma string, utilize o seguinte:</p> + +<pre class="brush: js">var home = "c:\\temp"; +</pre> + +<p>Você também pode escapar quebras de linhas, precedendo-as com barra invertida. A barra invertida e a quebra de linha são ambas removidas da string.</p> + +<pre class="brush: js">var str = "esta string \ +está quebrada \ +em várias\ +linhas." +console.log(str); // esta string está quebrada em várias linhas. +</pre> + +<p>Embora JavaScript não tenha sintaxe "heredoc", você pode adicionar uma quebra de linha e um escape de quebra de linha no final de cada linha:</p> + +<pre class="brush: js">var poema = +"Rosas são vermelhas\n\ +Violetas são azuis,\n\ +Esse seu sorriso\n\ +é o que me seduz. (Lucas Pedrosa)" +</pre> + +<h2 id="Mais_informação">Mais informação</h2> + +<p>Este capítulo focou na sintaxe básica das declarações e tipos. Para saber mais sobre a linguagem JavaScript, veja também os seguintes capítulos deste guia:</p> + +<ul> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Control_flow_and_error_handling">Controle de fluxo e manipulação de erro</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Loops_and_iteration">Laços e iteração</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Functions">Funções</a></li> + <li><a href="/pt-BR/docs/Web/JavaScript/Guide/Expressions_and_Operators">Expressões e operadores</a></li> +</ul> + +<p>No próximo capítulo, veremos a construção de controle de fluxos e manipulação de erro.</p> + +<p>{{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}</p> |