From 68fc8e96a9629e73469ed457abd955e548ec670c Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 14:49:58 +0100 Subject: unslug pt-br: move --- files/pt-br/web/javascript/closures/index.html | 336 ++++++++++ .../index.html | 280 -------- .../index.html | 280 ++++++++ .../pt-br/web/javascript/guide/closures/index.html | 336 ---------- .../cole\303\247\303\265es_chaveadas/index.html" | 149 ----- .../control_flow_and_error_handling/index.html | 429 +++++++++++++ .../guide/declara\303\247\303\265es/index.html" | 429 ------------- .../guide/details_of_the_object_model/index.html | 705 +++++++++++++++++++++ .../guide/detalhes_do_modelo_do_objeto/index.html | 705 --------------------- .../javascript/guide/formatando_texto/index.html | 250 -------- .../web/javascript/guide/functions/index.html | 640 +++++++++++++++++++ .../guide/fun\303\247\303\265es/index.html" | 640 ------------------- .../javascript/guide/grammar_and_types/index.html | 601 ++++++++++++++++++ .../web/javascript/guide/igualdade/index.html | 259 -------- .../inheritance_and_the_prototype_chain/index.html | 193 ------ .../guide/iteratores_e_geradores/index.html | 161 ----- .../guide/iterators_and_generators/index.html | 161 +++++ .../javascript/guide/lacos_e_iteracoes/index.html | 333 ---------- .../guide/loops_and_iteration/index.html | 333 ++++++++++ .../pt-br/web/javascript/guide/modules/index.html | 454 +++++++++++++ .../javascript/guide/m\303\263dulos/index.html" | 454 ------------- .../javascript/guide/numbers_and_dates/index.html | 374 +++++++++++ .../javascript/guide/numeros_e_datas/index.html | 374 ----------- .../javascript/guide/sintaxe_e_tipos/index.html | 583 ----------------- .../javascript/guide/text_formatting/index.html | 250 ++++++++ .../guide/trabalhando_com_objetos/index.html | 494 --------------- .../javascript/guide/usando_promises/index.html | 269 -------- .../web/javascript/guide/using_promises/index.html | 269 ++++++++ .../values,_variables,_and_literals/index.html | 601 ------------------ .../guide/working_with_objects/index.html | 494 +++++++++++++++ .../inheritance_and_the_prototype_chain/index.html | 193 ++++++ .../index.html | 352 ---------- .../index.html" | 38 -- .../index.html | 52 -- .../missing_curly_after_property_list/index.html | 52 ++ .../index.html | 38 ++ .../reference/errors/not_defined/index.html | 66 ++ .../errors/n\303\243o_definido/index.html" | 66 -- .../index.html" | 116 ---- .../errors/unnamed_function_statement/index.html | 116 ++++ .../functions/default_parameters/index.html | 210 ++++++ .../functions/definicoes_metodos/index.html | 200 ------ .../functions/method_definitions/index.html | 200 ++++++ .../functions/parametros_predefinidos/index.html | 210 ------ .../global_objects/array/contains/index.html | 106 ---- .../global_objects/array/filter/index.html | 227 +++++++ .../global_objects/array/filtro/index.html | 227 ------- .../global_objects/array/includes/index.html | 106 ++++ .../global_objects/array/prototype/index.html | 206 ------ .../global_objects/bigint/prototype/index.html | 61 -- .../global_objects/boolean/prototype/index.html | 112 ---- .../global_objects/function/prototype/index.html | 95 --- .../intl/numberformat/prototype/index.html | 126 ---- .../global_objects/map/prototype/index.html | 136 ---- .../global_objects/number/prototype/index.html | 140 ---- .../global_objects/object/prototype/index.html | 227 ------- .../global_objects/promise/prototype/index.html | 114 ---- .../global_objects/set/prototype/index.html | 85 --- .../global_objects/string/prototype/index.html | 177 ------ .../global_objects/weakmap/prototype/index.html | 118 ---- .../operators/arithmetic_operators/index.html | 329 ---------- .../atribuicao_via_desestruturacao/index.html | 445 ------------- .../operators/bitwise_operators/index.html | 559 ---------------- .../reference/operators/comma_operator/index.html | 102 +++ .../operators/conditional_operator/index.html | 171 +++++ .../operators/destructuring_assignment/index.html | 445 +++++++++++++ .../operators/inicializador_objeto/index.html | 392 ------------ .../nullish_coalescing_operator/index.html | 159 +++++ .../operators/object_initializer/index.html | 392 ++++++++++++ .../operators/operador_condicional/index.html | 171 ----- .../operador_de_coalescencia_nula/index.html | 159 ----- .../operators/operador_virgula/index.html | 102 --- .../index.html" | 251 -------- .../operators/operadores_logicos/index.html | 343 ---------- .../reference/operators/spread_operator/index.html | 201 ------ .../reference/statements/async_function/index.html | 149 +++++ .../reference/statements/default/index.html | 187 ------ .../statements/funcoes_assincronas/index.html | 149 ----- .../reference/template_literals/index.html | 140 ++++ .../reference/template_strings/index.html | 140 ---- 80 files changed, 8092 insertions(+), 12902 deletions(-) create mode 100644 files/pt-br/web/javascript/closures/index.html delete mode 100644 files/pt-br/web/javascript/enumerabilidade_e_posse_de_propriedades/index.html create mode 100644 files/pt-br/web/javascript/enumerability_and_ownership_of_properties/index.html delete mode 100644 files/pt-br/web/javascript/guide/closures/index.html delete mode 100644 "files/pt-br/web/javascript/guide/cole\303\247\303\265es_chaveadas/index.html" create mode 100644 files/pt-br/web/javascript/guide/control_flow_and_error_handling/index.html delete mode 100644 "files/pt-br/web/javascript/guide/declara\303\247\303\265es/index.html" create mode 100644 files/pt-br/web/javascript/guide/details_of_the_object_model/index.html delete mode 100644 files/pt-br/web/javascript/guide/detalhes_do_modelo_do_objeto/index.html delete mode 100644 files/pt-br/web/javascript/guide/formatando_texto/index.html create mode 100644 files/pt-br/web/javascript/guide/functions/index.html delete mode 100644 "files/pt-br/web/javascript/guide/fun\303\247\303\265es/index.html" create mode 100644 files/pt-br/web/javascript/guide/grammar_and_types/index.html delete mode 100644 files/pt-br/web/javascript/guide/igualdade/index.html delete mode 100644 files/pt-br/web/javascript/guide/inheritance_and_the_prototype_chain/index.html delete mode 100644 files/pt-br/web/javascript/guide/iteratores_e_geradores/index.html create mode 100644 files/pt-br/web/javascript/guide/iterators_and_generators/index.html delete mode 100644 files/pt-br/web/javascript/guide/lacos_e_iteracoes/index.html create mode 100644 files/pt-br/web/javascript/guide/loops_and_iteration/index.html create mode 100644 files/pt-br/web/javascript/guide/modules/index.html delete mode 100644 "files/pt-br/web/javascript/guide/m\303\263dulos/index.html" create mode 100644 files/pt-br/web/javascript/guide/numbers_and_dates/index.html delete mode 100644 files/pt-br/web/javascript/guide/numeros_e_datas/index.html delete mode 100644 files/pt-br/web/javascript/guide/sintaxe_e_tipos/index.html create mode 100644 files/pt-br/web/javascript/guide/text_formatting/index.html delete mode 100644 files/pt-br/web/javascript/guide/trabalhando_com_objetos/index.html delete mode 100644 files/pt-br/web/javascript/guide/usando_promises/index.html create mode 100644 files/pt-br/web/javascript/guide/using_promises/index.html delete mode 100644 files/pt-br/web/javascript/guide/values,_variables,_and_literals/index.html create mode 100644 files/pt-br/web/javascript/guide/working_with_objects/index.html create mode 100644 files/pt-br/web/javascript/inheritance_and_the_prototype_chain/index.html delete mode 100644 files/pt-br/web/javascript/introduction_to_object-oriented_javascript/index.html delete mode 100644 "files/pt-br/web/javascript/reference/errors/fata_par\303\252nteses_ap\303\263s_lista_argumento/index.html" delete mode 100644 files/pt-br/web/javascript/reference/errors/fecha_chaves_esquecida_apos_lista_propriedades/index.html create mode 100644 files/pt-br/web/javascript/reference/errors/missing_curly_after_property_list/index.html create mode 100644 files/pt-br/web/javascript/reference/errors/missing_parenthesis_after_argument_list/index.html create mode 100644 files/pt-br/web/javascript/reference/errors/not_defined/index.html delete mode 100644 "files/pt-br/web/javascript/reference/errors/n\303\243o_definido/index.html" delete mode 100644 "files/pt-br/web/javascript/reference/errors/n\303\243onomeado_func\303\243o_declara\303\247\303\243o/index.html" create mode 100644 files/pt-br/web/javascript/reference/errors/unnamed_function_statement/index.html create mode 100644 files/pt-br/web/javascript/reference/functions/default_parameters/index.html delete mode 100644 files/pt-br/web/javascript/reference/functions/definicoes_metodos/index.html create mode 100644 files/pt-br/web/javascript/reference/functions/method_definitions/index.html delete mode 100644 files/pt-br/web/javascript/reference/functions/parametros_predefinidos/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/array/contains/index.html create mode 100644 files/pt-br/web/javascript/reference/global_objects/array/filter/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/array/filtro/index.html create mode 100644 files/pt-br/web/javascript/reference/global_objects/array/includes/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/array/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/bigint/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/boolean/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/function/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/intl/numberformat/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/map/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/number/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/object/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/promise/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/set/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/string/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/global_objects/weakmap/prototype/index.html delete mode 100644 files/pt-br/web/javascript/reference/operators/arithmetic_operators/index.html delete mode 100644 files/pt-br/web/javascript/reference/operators/atribuicao_via_desestruturacao/index.html delete mode 100644 files/pt-br/web/javascript/reference/operators/bitwise_operators/index.html create mode 100644 files/pt-br/web/javascript/reference/operators/comma_operator/index.html create mode 100644 files/pt-br/web/javascript/reference/operators/conditional_operator/index.html create mode 100644 files/pt-br/web/javascript/reference/operators/destructuring_assignment/index.html delete mode 100644 files/pt-br/web/javascript/reference/operators/inicializador_objeto/index.html create mode 100644 files/pt-br/web/javascript/reference/operators/nullish_coalescing_operator/index.html create mode 100644 files/pt-br/web/javascript/reference/operators/object_initializer/index.html delete mode 100644 files/pt-br/web/javascript/reference/operators/operador_condicional/index.html delete mode 100644 files/pt-br/web/javascript/reference/operators/operador_de_coalescencia_nula/index.html delete mode 100644 files/pt-br/web/javascript/reference/operators/operador_virgula/index.html delete mode 100644 "files/pt-br/web/javascript/reference/operators/operadores_de_compara\303\247\303\243o/index.html" delete mode 100644 files/pt-br/web/javascript/reference/operators/operadores_logicos/index.html delete mode 100644 files/pt-br/web/javascript/reference/operators/spread_operator/index.html create mode 100644 files/pt-br/web/javascript/reference/statements/async_function/index.html delete mode 100644 files/pt-br/web/javascript/reference/statements/default/index.html delete mode 100644 files/pt-br/web/javascript/reference/statements/funcoes_assincronas/index.html create mode 100644 files/pt-br/web/javascript/reference/template_literals/index.html delete mode 100644 files/pt-br/web/javascript/reference/template_strings/index.html (limited to 'files/pt-br/web/javascript') diff --git a/files/pt-br/web/javascript/closures/index.html b/files/pt-br/web/javascript/closures/index.html new file mode 100644 index 0000000000..efc7578d7d --- /dev/null +++ b/files/pt-br/web/javascript/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 +--- +
{{jsSidebar("Intermediate")}}
+ +

Um closure (fechamento) é uma função que se "lembra" do ambiente — ou escopo léxico — em que ela foi criada.

+ +

Escopo léxico

+ +

Considere a função abaixo:

+ +
+
function init() {
+  var name = "Mozilla";
+  function displayName() {
+    alert(name);
+  }
+  displayName();
+}
+init();
+
+
+ +

A função init() cria uma variável local chamada name, e depois define uma função chamada displayName(). displayName() é uma função aninhada (um closure) — ela é definida dentro da função init(), e está disponivel apenas dentro do corpo daquela função. Diferente de init(), displayName() não tem variáveis locais próprias, e ao invés disso reusa a variável name declarada na função pai.

+ +

Rode o código e veja que isso funciona. Este é um exemplo de escopo léxico: em JavaScript, o escopo de uma variável é definido por sua localização dentro do código fonte (isto é aparentemente léxico) e funções aninhadas têm acesso às variáveis declaradas em seu escopo externo.

+ +

Closure

+ +

Agora considere o seguinte exemplo:

+ +
function makeFunc() {
+  var name = "Mozilla";
+  function displayName() {
+    alert(name);
+  }
+  return displayName;
+}
+
+var myFunc = makeFunc();
+myFunc();
+
+ +

Se você rodar este código o mesmo terá exatamente o mesmo efeito que o init() 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 displayName() foi retornada da função externa antes de ser executada.

+ +

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 makeFunc() terminou de executar, é razoável esperar que a variável name não será mais necessária. Dado que o código ainda funciona como o esperado, este não é o caso.

+ +

A solução para tal problema é que a função myFunc tornou-se uma closure. 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, myFunc é a closure que incorpora tanto a função displayName quanto a palavra Mozilla que existia quando a closure foi criada.

+ +

Aqui temos um exemplo um pouco mais interessante, a função makeAdder:

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

Neste exemplo definimos a função makeAdder(x) que toma um único argumento x e retorna uma nova função. A função retornada toma então um único argumento, y, e retorna então a soma de x e de y.

+ +

Na essência o makeAdder trata-se de uma função fábrica - 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.

+ +

Ambas as funções add5 e add10 são closures. Compartilham o mesmo corpo de definição de função mas armazenam diferentes ambientes. No ambiente da add5, por exemplo, x equivale a 5, enquanto na add10 o valor de x é 10.

+ +

Closures na prática

+ +

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.

+ +

Consequentemente, você pode utilizar uma closure em qualquer lugar onde você normalmente utilizaria um objeto de único método.

+ +

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.

+ +

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:

+ +
body {
+  font-family: Helvetica, Arial, sans-serif;
+  font-size: 12px;
+}
+
+h1 {
+  font-size: 1.5em;
+}
+h2 {
+  font-size: 1.2em;
+}
+
+ +

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.

+ +

O código JavaScript:

+ +
function makeSizer(size) {
+  return function() {
+    document.body.style.fontSize = size + 'px';
+  };
+}
+
+var size12 = makeSizer(12);
+var size14 = makeSizer(14);
+var size16 = makeSizer(16);
+
+ +

size12, size14 e size16 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:

+ +
document.getElementById('size-12').onclick = size12;
+document.getElementById('size-14').onclick = size14;
+document.getElementById('size-16').onclick = size16;
+
+ +
<a href="#" id="size-12">12</a>
+<a href="#" id="size-14">14</a>
+<a href="#" id="size-16">16</a>
+
+ +

View on JSFiddle

+ +

Emulando métodos privados com closures

+ +

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.

+ +

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.

+ +

Veja como definir algumas funções públicas que acessam funções e variáveis privadas, usando closures que também é conhecido como module pattern:

+ +
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 */
+
+ +

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: Counter.increment, Counter.decrement e Counter.value.

+ +

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 privateCounter e uma função chamada changeBy. 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.

+ +

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 privateCounter e à função changeBy.

+ +
+

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 Counter. Poderíamos armazenar essa função em uma variável separada e usá-la para criar diversos contadores.

+
+ +
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 */
+
+ +

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 makeCounter() é diferente a cada vez que ocorre. A variável privateCounter contém uma instância diferente a cada vez.

+ +
+

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.

+
+ +
+
+ +

Criando closures dentro de loops: Um erro comum

+ +

Antes da introdução da palavra chave let no JavaScript 1.7, um problema comum ocorria com closures quando eram criadas dentro de um loop. Considere o exemplo:

+ +
<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>
+
+ +
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();
+
+ +

View on JSFiddle

+ +

O array helpText 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.

+ +

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.

+ +

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 setupHelp. 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 helpText.

+ +

Uma solução seria neste caso usar mais closures: em particular, usar uma fábrica de funções como descrito anteriormente:

+ +
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();
+
+ +

View on JSFiddle

+ +

Isto funciona conforme o esperado. Ao invés dos callbacks compartilharem o mesmo ambiente, a função makeHelpCallback cria um novo ambiente para cada um no qual help se refere à string correspondente do array helpText.

+ +

Considerações de performance

+ +

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.

+ +

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

+ +

Considere o seguinte exemplo pouco prático porém demonstrativo:

+ +
function MyObject(name, message) {
+  this.name = name.toString();
+  this.message = message.toString();
+  this.getName = function() {
+    return this.name;
+  };
+
+  this.getMessage = function() {
+    return this.message;
+  };
+}
+
+ +

O código anterior não aproveita os benefícios dos closures e portanto poderia ser reformulado assim:

+ +
function MyObject(name, message) {
+  this.name = name.toString();
+  this.message = message.toString();
+}
+MyObject.prototype = {
+  getName: function() {
+    return this.name;
+  },
+  getMessage: function() {
+    return this.message;
+  }
+};
+
+ +

Ou assim:

+ +
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;
+};
+
+ +

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 Detalhes do modelo de objeto para mais detalhes.

diff --git a/files/pt-br/web/javascript/enumerabilidade_e_posse_de_propriedades/index.html b/files/pt-br/web/javascript/enumerabilidade_e_posse_de_propriedades/index.html deleted file mode 100644 index 3d7feb0bd4..0000000000 --- a/files/pt-br/web/javascript/enumerabilidade_e_posse_de_propriedades/index.html +++ /dev/null @@ -1,280 +0,0 @@ ---- -title: Enumerabilidade e posse de propriedades -slug: Web/JavaScript/Enumerabilidade_e_posse_de_propriedades -tags: - - JavaScript -translation_of: Web/JavaScript/Enumerability_and_ownership_of_properties ---- -
{{JsSidebar("Mais")}}
- -

-Propriedades enumeráveis são aquelas propriedades cuja flag interna [[Enumerable]] é verdadeira (true), que é o padrão para propriedades criadas via assinatura simples ou através de um inicializador (propriedades definidas através de  Object.defineProperty e tipo padrão [[Enumerable]] falso (false)).
- -
 
- -
Propriedades enumeráveis aparecem em for...in loops exceto se o nome da propriedade for um objeto Symbol. Posse de propriedades é determinada pelo fato da propriedade pertencer ao objeto diretamente e não a uma cadeira de protótipos. Propriedades de um objeto pode também ser recuperadas diretamente. Há um número de built-in de detecção, iteração/enumeração e recuperação de propriedades,  com o gráfico mostrando que estão disponíveis. 
- -
 
- -
O código de exemplo a seguir demostra como obter as categorias que faltam.
- -
 
- -
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Propriedade de enumerabilidade e posse - métodos internos de detecção, recuperação, e iteração
FuncionalidadePróprio objeto -

Próprio objeto e sua cadeia de caracteres

-
Somente cadeia de protótipos
Detecção - - - - - - - - - - - - - - - -
EnumerávelNão enumerávelEnumerável e Não enumerável
propertyIsEnumerablehasOwnProperty e não propertyIsEnumerablehasOwnProperty
-
Não disponível sem código extraNão disponível sem código extra
Recuperação - - - - - - - - - - - - - - - -
EnumerávelNão enumerávelEnumerável e Não enumerável
Object.keysgetOwnPropertyNames filtrou-se para incluir as propriedades quando não passado propertyIsEnumerablegetOwnPropertyNames
-
Não disponível sem código extraNão disponível sem código extra
Iteração - - - - - - - - - - - - - - - -
EnumerávelNão enumerávelEnumerável e Não enumerável
Iterar Object.keys -

itera getOwnPropertyNames filtrou-se para incluir as propriedades quando não passado propertyIsEnumerable

-
iterar getOwnPropertyNames
-
- - - - - - - - - - - - - - - -
EnumerávelNão enumerávelEnumerável e Não enumerável
for..inNão disponível sem código extraNão disponível sem código extra
-
Não disponível sem código extra
- -

Obtendo propriedades por enumerabilidade/posse

- -

 

- -

Note que não é o algoritmo mais eficiente para todos os casos, mas útil para uma demonstração rápida.

- - - -
var SimplePropertyRetriever = {
-    getOwnEnumerables: function (obj) {
-        return this._getPropertyNames(obj, true, false, this._enumerable);
-         // Ou poderia usar for..in filtrado com hasOwnProperty ou apenas isto: return Object.keys(obj);
-    },
-    getOwnNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, true, false, this._notEnumerable);
-    },
-    getOwnEnumerablesAndNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, true, false, this._enumerableAndNotEnumerable);
-        // Ou apenas use: return Object.getOwnPropertyNames(obj);
-    },
-    getPrototypeEnumerables: function (obj) {
-        return this._getPropertyNames(obj, false, true, this._enumerable);
-    },
-    getPrototypeNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, false, true, this._notEnumerable);
-    },
-    getPrototypeEnumerablesAndNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, false, true, this._enumerableAndNotEnumerable);
-    },
-    getOwnAndPrototypeEnumerables: function (obj) {
-        return this._getPropertyNames(obj, true, true, this._enumerable);
-        // Ou poderia usar filtrado for..in
-    },
-    getOwnAndPrototypeNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, true, true, this._notEnumerable);
-    },
-    getOwnAndPrototypeEnumerablesAndNonenumerables: function (obj) {
-        return this._getPropertyNames(obj, true, true, this._enumerableAndNotEnumerable);
-    },
-    // Private static property checker callbacks
-    _enumerable : function (obj, prop) {
-        return obj.propertyIsEnumerable(prop);
-    },
-    _notEnumerable : function (obj, prop) {
-        return !obj.propertyIsEnumerable(prop);
-    },
-    _enumerableAndNotEnumerable : function (obj, prop) {
-        return true;
-    },
-    // Inspirado por http://stackoverflow.com/a/8024294/271577
-    _getPropertyNames : function getAllPropertyNames(obj, iterateSelfBool, iteratePrototypeBool, includePropCb) {
-        var props = [];
-
-        do {
-            if (iterateSelfBool) {
-                Object.getOwnPropertyNames(obj).forEach(function (prop) {
-                    if (props.indexOf(prop) === -1 && includePropCb(obj, prop)) {
-                        props.push(prop);
-                    }
-                });
-            }
-            if (!iteratePrototypeBool) {
-                break;
-            }
-            iterateSelfBool = true;
-        } while (obj = Object.getPrototypeOf(obj));
-
-        return props;
-    }
-};
- -

Tabela de Detecção

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 infor..inhasOwnPropertypropertyIsEnumerablein Object.keysin Object.getOwnPropertyNamesin Object.getOwnPropertyDescriptors
Enumeráveltruetruetruetruetruetruetrue
Não enumeráveltruefalsetruefalsefalsetruetrue
Inherited Enumerabletruetruefalsefalsefalsefalsefalse
Inherited Nonenumerabletruefalsefalsefalsefalsefalsefalse
Account for Symbols keystruefalsetruetruefalsefalsetrue
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/enumerability_and_ownership_of_properties/index.html b/files/pt-br/web/javascript/enumerability_and_ownership_of_properties/index.html new file mode 100644 index 0000000000..3d7feb0bd4 --- /dev/null +++ b/files/pt-br/web/javascript/enumerability_and_ownership_of_properties/index.html @@ -0,0 +1,280 @@ +--- +title: Enumerabilidade e posse de propriedades +slug: Web/JavaScript/Enumerabilidade_e_posse_de_propriedades +tags: + - JavaScript +translation_of: Web/JavaScript/Enumerability_and_ownership_of_properties +--- +
{{JsSidebar("Mais")}}
+ +

+Propriedades enumeráveis são aquelas propriedades cuja flag interna [[Enumerable]] é verdadeira (true), que é o padrão para propriedades criadas via assinatura simples ou através de um inicializador (propriedades definidas através de  Object.defineProperty e tipo padrão [[Enumerable]] falso (false)).
+ +
 
+ +
Propriedades enumeráveis aparecem em for...in loops exceto se o nome da propriedade for um objeto Symbol. Posse de propriedades é determinada pelo fato da propriedade pertencer ao objeto diretamente e não a uma cadeira de protótipos. Propriedades de um objeto pode também ser recuperadas diretamente. Há um número de built-in de detecção, iteração/enumeração e recuperação de propriedades,  com o gráfico mostrando que estão disponíveis. 
+ +
 
+ +
O código de exemplo a seguir demostra como obter as categorias que faltam.
+ +
 
+ +
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Propriedade de enumerabilidade e posse - métodos internos de detecção, recuperação, e iteração
FuncionalidadePróprio objeto +

Próprio objeto e sua cadeia de caracteres

+
Somente cadeia de protótipos
Detecção + + + + + + + + + + + + + + + +
EnumerávelNão enumerávelEnumerável e Não enumerável
propertyIsEnumerablehasOwnProperty e não propertyIsEnumerablehasOwnProperty
+
Não disponível sem código extraNão disponível sem código extra
Recuperação + + + + + + + + + + + + + + + +
EnumerávelNão enumerávelEnumerável e Não enumerável
Object.keysgetOwnPropertyNames filtrou-se para incluir as propriedades quando não passado propertyIsEnumerablegetOwnPropertyNames
+
Não disponível sem código extraNão disponível sem código extra
Iteração + + + + + + + + + + + + + + + +
EnumerávelNão enumerávelEnumerável e Não enumerável
Iterar Object.keys +

itera getOwnPropertyNames filtrou-se para incluir as propriedades quando não passado propertyIsEnumerable

+
iterar getOwnPropertyNames
+
+ + + + + + + + + + + + + + + +
EnumerávelNão enumerávelEnumerável e Não enumerável
for..inNão disponível sem código extraNão disponível sem código extra
+
Não disponível sem código extra
+ +

Obtendo propriedades por enumerabilidade/posse

+ +

 

+ +

Note que não é o algoritmo mais eficiente para todos os casos, mas útil para uma demonstração rápida.

+ + + +
var SimplePropertyRetriever = {
+    getOwnEnumerables: function (obj) {
+        return this._getPropertyNames(obj, true, false, this._enumerable);
+         // Ou poderia usar for..in filtrado com hasOwnProperty ou apenas isto: return Object.keys(obj);
+    },
+    getOwnNonenumerables: function (obj) {
+        return this._getPropertyNames(obj, true, false, this._notEnumerable);
+    },
+    getOwnEnumerablesAndNonenumerables: function (obj) {
+        return this._getPropertyNames(obj, true, false, this._enumerableAndNotEnumerable);
+        // Ou apenas use: return Object.getOwnPropertyNames(obj);
+    },
+    getPrototypeEnumerables: function (obj) {
+        return this._getPropertyNames(obj, false, true, this._enumerable);
+    },
+    getPrototypeNonenumerables: function (obj) {
+        return this._getPropertyNames(obj, false, true, this._notEnumerable);
+    },
+    getPrototypeEnumerablesAndNonenumerables: function (obj) {
+        return this._getPropertyNames(obj, false, true, this._enumerableAndNotEnumerable);
+    },
+    getOwnAndPrototypeEnumerables: function (obj) {
+        return this._getPropertyNames(obj, true, true, this._enumerable);
+        // Ou poderia usar filtrado for..in
+    },
+    getOwnAndPrototypeNonenumerables: function (obj) {
+        return this._getPropertyNames(obj, true, true, this._notEnumerable);
+    },
+    getOwnAndPrototypeEnumerablesAndNonenumerables: function (obj) {
+        return this._getPropertyNames(obj, true, true, this._enumerableAndNotEnumerable);
+    },
+    // Private static property checker callbacks
+    _enumerable : function (obj, prop) {
+        return obj.propertyIsEnumerable(prop);
+    },
+    _notEnumerable : function (obj, prop) {
+        return !obj.propertyIsEnumerable(prop);
+    },
+    _enumerableAndNotEnumerable : function (obj, prop) {
+        return true;
+    },
+    // Inspirado por http://stackoverflow.com/a/8024294/271577
+    _getPropertyNames : function getAllPropertyNames(obj, iterateSelfBool, iteratePrototypeBool, includePropCb) {
+        var props = [];
+
+        do {
+            if (iterateSelfBool) {
+                Object.getOwnPropertyNames(obj).forEach(function (prop) {
+                    if (props.indexOf(prop) === -1 && includePropCb(obj, prop)) {
+                        props.push(prop);
+                    }
+                });
+            }
+            if (!iteratePrototypeBool) {
+                break;
+            }
+            iterateSelfBool = true;
+        } while (obj = Object.getPrototypeOf(obj));
+
+        return props;
+    }
+};
+ +

Tabela de Detecção

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 infor..inhasOwnPropertypropertyIsEnumerablein Object.keysin Object.getOwnPropertyNamesin Object.getOwnPropertyDescriptors
Enumeráveltruetruetruetruetruetruetrue
Não enumeráveltruefalsetruefalsefalsetruetrue
Inherited Enumerabletruetruefalsefalsefalsefalsefalse
Inherited Nonenumerabletruefalsefalsefalsefalsefalsefalse
Account for Symbols keystruefalsetruetruefalsefalsetrue
+ +

Veja também

+ + diff --git a/files/pt-br/web/javascript/guide/closures/index.html b/files/pt-br/web/javascript/guide/closures/index.html deleted file mode 100644 index efc7578d7d..0000000000 --- a/files/pt-br/web/javascript/guide/closures/index.html +++ /dev/null @@ -1,336 +0,0 @@ ---- -title: Closures -slug: Web/JavaScript/Guide/Closures -tags: - - Closure - - ES5 - - Intermediário - - JavaScript - - Referencia -translation_of: Web/JavaScript/Closures ---- -
{{jsSidebar("Intermediate")}}
- -

Um closure (fechamento) é uma função que se "lembra" do ambiente — ou escopo léxico — em que ela foi criada.

- -

Escopo léxico

- -

Considere a função abaixo:

- -
-
function init() {
-  var name = "Mozilla";
-  function displayName() {
-    alert(name);
-  }
-  displayName();
-}
-init();
-
-
- -

A função init() cria uma variável local chamada name, e depois define uma função chamada displayName(). displayName() é uma função aninhada (um closure) — ela é definida dentro da função init(), e está disponivel apenas dentro do corpo daquela função. Diferente de init(), displayName() não tem variáveis locais próprias, e ao invés disso reusa a variável name declarada na função pai.

- -

Rode o código e veja que isso funciona. Este é um exemplo de escopo léxico: em JavaScript, o escopo de uma variável é definido por sua localização dentro do código fonte (isto é aparentemente léxico) e funções aninhadas têm acesso às variáveis declaradas em seu escopo externo.

- -

Closure

- -

Agora considere o seguinte exemplo:

- -
function makeFunc() {
-  var name = "Mozilla";
-  function displayName() {
-    alert(name);
-  }
-  return displayName;
-}
-
-var myFunc = makeFunc();
-myFunc();
-
- -

Se você rodar este código o mesmo terá exatamente o mesmo efeito que o init() 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 displayName() foi retornada da função externa antes de ser executada.

- -

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 makeFunc() terminou de executar, é razoável esperar que a variável name não será mais necessária. Dado que o código ainda funciona como o esperado, este não é o caso.

- -

A solução para tal problema é que a função myFunc tornou-se uma closure. 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, myFunc é a closure que incorpora tanto a função displayName quanto a palavra Mozilla que existia quando a closure foi criada.

- -

Aqui temos um exemplo um pouco mais interessante, a função makeAdder:

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

Neste exemplo definimos a função makeAdder(x) que toma um único argumento x e retorna uma nova função. A função retornada toma então um único argumento, y, e retorna então a soma de x e de y.

- -

Na essência o makeAdder trata-se de uma função fábrica - 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.

- -

Ambas as funções add5 e add10 são closures. Compartilham o mesmo corpo de definição de função mas armazenam diferentes ambientes. No ambiente da add5, por exemplo, x equivale a 5, enquanto na add10 o valor de x é 10.

- -

Closures na prática

- -

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.

- -

Consequentemente, você pode utilizar uma closure em qualquer lugar onde você normalmente utilizaria um objeto de único método.

- -

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.

- -

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:

- -
body {
-  font-family: Helvetica, Arial, sans-serif;
-  font-size: 12px;
-}
-
-h1 {
-  font-size: 1.5em;
-}
-h2 {
-  font-size: 1.2em;
-}
-
- -

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.

- -

O código JavaScript:

- -
function makeSizer(size) {
-  return function() {
-    document.body.style.fontSize = size + 'px';
-  };
-}
-
-var size12 = makeSizer(12);
-var size14 = makeSizer(14);
-var size16 = makeSizer(16);
-
- -

size12, size14 e size16 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:

- -
document.getElementById('size-12').onclick = size12;
-document.getElementById('size-14').onclick = size14;
-document.getElementById('size-16').onclick = size16;
-
- -
<a href="#" id="size-12">12</a>
-<a href="#" id="size-14">14</a>
-<a href="#" id="size-16">16</a>
-
- -

View on JSFiddle

- -

Emulando métodos privados com closures

- -

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.

- -

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.

- -

Veja como definir algumas funções públicas que acessam funções e variáveis privadas, usando closures que também é conhecido como module pattern:

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

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: Counter.increment, Counter.decrement e Counter.value.

- -

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 privateCounter e uma função chamada changeBy. 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.

- -

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 privateCounter e à função changeBy.

- -
-

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 Counter. Poderíamos armazenar essa função em uma variável separada e usá-la para criar diversos contadores.

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

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 makeCounter() é diferente a cada vez que ocorre. A variável privateCounter contém uma instância diferente a cada vez.

- -
-

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.

-
- -
-
- -

Criando closures dentro de loops: Um erro comum

- -

Antes da introdução da palavra chave let no JavaScript 1.7, um problema comum ocorria com closures quando eram criadas dentro de um loop. Considere o exemplo:

- -
<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>
-
- -
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();
-
- -

View on JSFiddle

- -

O array helpText 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.

- -

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.

- -

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 setupHelp. 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 helpText.

- -

Uma solução seria neste caso usar mais closures: em particular, usar uma fábrica de funções como descrito anteriormente:

- -
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();
-
- -

View on JSFiddle

- -

Isto funciona conforme o esperado. Ao invés dos callbacks compartilharem o mesmo ambiente, a função makeHelpCallback cria um novo ambiente para cada um no qual help se refere à string correspondente do array helpText.

- -

Considerações de performance

- -

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.

- -

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

- -

Considere o seguinte exemplo pouco prático porém demonstrativo:

- -
function MyObject(name, message) {
-  this.name = name.toString();
-  this.message = message.toString();
-  this.getName = function() {
-    return this.name;
-  };
-
-  this.getMessage = function() {
-    return this.message;
-  };
-}
-
- -

O código anterior não aproveita os benefícios dos closures e portanto poderia ser reformulado assim:

- -
function MyObject(name, message) {
-  this.name = name.toString();
-  this.message = message.toString();
-}
-MyObject.prototype = {
-  getName: function() {
-    return this.name;
-  },
-  getMessage: function() {
-    return this.message;
-  }
-};
-
- -

Ou assim:

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

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 Detalhes do modelo de objeto para mais detalhes.

diff --git "a/files/pt-br/web/javascript/guide/cole\303\247\303\265es_chaveadas/index.html" "b/files/pt-br/web/javascript/guide/cole\303\247\303\265es_chaveadas/index.html" deleted file mode 100644 index cb626865f8..0000000000 --- "a/files/pt-br/web/javascript/guide/cole\303\247\303\265es_chaveadas/index.html" +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: Coleções chaveadas -slug: Web/JavaScript/Guide/Coleções_chaveadas -tags: - - Coleções - - Guía - - JavaScript - - Mapas ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}
- -

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.

- -

Maps

- -

Map object

- -

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

- -

The following code shows some basic operations with a Map. 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 [key, value] for each iteration.

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

Object and Map compared

- -

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. Map objects, however, have a few more advantages that make them better maps.

- - - -

These two tips can help you to decide whether to use a Map or an Object:

- - - -

WeakMap object

- -

The {{jsxref("WeakMap")}} object is a collection of key/value pairs in which the keys are objects only and the values can be arbitrary values. The object references in the keys are held weakly meaning that they are target of garbage collection (GC) if there is no other reference to the object anymore. The WeakMap API is the same as the Map API.

- -

One difference to Map objects is that WeakMap 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.

- -

For more information and example code, see also "Why WeakMap?" on the {{jsxref("WeakMap")}} reference page.

- -

One use case of WeakMap objects is to store private data for an object or to hide implementation details. The following example is from Nick Fitzgerald blog post "Hiding Implementation Details with ECMAScript 6 WeakMaps". The private data and methods belong inside the object and are stored in the privates WeakMap object. Everything exposed on the instance and prototype is public; everything else is inaccessible from the outside world because privates is not exported from the module

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

Sets

- -

Set object

- -

{{jsxref("Set")}} objects are collections of values. You can iterate its elements in insertion order. A value in a Set may only occur once; it is unique in the Set's collection.

- -

The following code shows some basic operations with a Set. See also the {{jsxref("Set")}} reference page for more examples and the complete API.

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

Converting between Array and Set

- -

You can create an {{jsxref("Array")}} from a Set using {{jsxref("Array.from")}} or the spread operator. Also, the Set constructor accepts an Array to convert in the other direction. Note again that Set objects store unique values, so any duplicate elements from an Array are deleted when converting.

- -
Array.from(mySet);
-[...mySet2];
-
-mySet2 = new Set([1,2,3,4]);
-
- -

Array and Set compared

- -

Traditionally, a set of elements has been stored in arrays in JavaScript in a lot of situations. The new Set object, however, has some advantages:

- - - -

WeakSet object

- -

{{jsxref("WeakSet")}} objects are collections of objects. An object in the WeakSet may only occur once; it is unique in the WeakSet's collection and objects are not enumerable.

- -

The main differences to the {{jsxref("Set")}} object are:

- - - -

The use cases of WeakSet 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.

- -

Key and value equality of Map and Set

- -

Both, the key equality of Map objects and the value equality of Set objects, are based on the "same-value-zero algorithm":

- - - -

{{PreviousNext("Web/JavaScript/Guide/Indexed_Collections", "Web/JavaScript/Guide/Working_with_Objects")}}

diff --git a/files/pt-br/web/javascript/guide/control_flow_and_error_handling/index.html b/files/pt-br/web/javascript/guide/control_flow_and_error_handling/index.html new file mode 100644 index 0000000000..e352b58f6d --- /dev/null +++ b/files/pt-br/web/javascript/guide/control_flow_and_error_handling/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 +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}
+ +

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

+ +

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

+ +

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

+ +

Declaração em bloco

+ +

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

+ +
{
+   declaracao_1;
+   declaracao_2;
+   .
+   .
+   .
+   declaracao_n;
+}
+
+ +

Exemplo

+ +

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

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

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

+ +

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

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

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

+ +

Declarações condicionais

+ +

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

+ +

Declaração if...else

+ +

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

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

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

+ +

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

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

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

+ +
if (condicao) {
+    declaracao_1_executada_se_condicao_for_verdadeira;
+    declaracao_2_executada_se_condicao_for_verdadeira;
+} else {
+    declaracao_3_executada_se_condicao_for_falsa;
+    declaracao_4_executada_se_condicao_for_falsa;
+}
+
+ +
Recomenda-se não utilizar atribuições simples em uma expressão condicional porque o símbolo de atribuição poderia ser confundido com o de igualdade ao dar uma olhada no código. Por exemplo, não utilize o seguinte código:
+ +
if (x = y) {
+  /* faça a coisa certa */
+}
+
+ +

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

+ +
if ((x = y)) {
+  /* faça a coisa certa */
+}
+
+ +

Valores avaliados como falsos

+ +

Os seguintes valores são avaliados como falsos:

+ + + +

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

+ +

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

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

 

+ +

Exemplo

+ +

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

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

Declaração switch

+ +

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

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

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

+ +

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

+ +

Exemplo

+ +

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

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

Declarações de Manipulação de Error

+ +

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

+ + + +

Tipos de exceções

+ +

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

+ + + +

Declaração throw

+ +

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

+ +
throw expressão;
+
+ +

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

+ +
throw "Error2";   // tipo string
+throw 42;         // tipo numérico
+throw true;       // tipo booleano
+throw {toString: function() { return "Eu sou um objeto!"; } };
+
+ +
Nota:  Você pode especificar um objeto quando você lança uma exceção. Você pode então, referenciar as propriedades de um objeto no bloco catch.  O exemplo a seguir cria um objeto myUserException do tipo userException e o usa em uma declaração throw.
+ +
// Cria um objeto do tipo UserException
+function UserException(mensagem) {
+  this.mensagem = mensagem;
+  this.nome = "UserException";
+}
+
+// Realiza a conversão da exceção para uma string adequada quando usada como uma string.
+// (ex. pelo console de erro)
+UserException.prototype.toString = function() {
+  return this.name + ': "' + this.message + '"';
+}
+
+// Cria uma instância de um tipo de objeto e lança ela
+throw new UserException("Valor muito alto");
+ +

Declaração try...catch

+ +

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

+ +

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

+ +

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

+ +
function getMonthName(mo) {
+  mo = mo - 1; // Ajusta o número do mês para o índice do array (1 = Jan, 12 = Dec)
+  var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul",
+                "Aug","Sep","Oct","Nov","Dec"];
+  if (months[mo]) {
+    return months[mo];
+  } else {
+    throw "InvalidMonthNo"; //lança uma palavra-chave aqui usada.
+  }
+}
+
+try { // statements to try
+  monthName = getMonthName(myMonth); // função poderia lançar uma exceção
+}
+catch (e) {
+  monthName = "unknown";
+  logMyErrors(e); // passa a exceção para o manipulador de erro -> sua função local.
+}
+
+ +

O bloco catch

+ +

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

+ +
catch (catchID) {
+  declaracoes
+}
+
+ +

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

+ +

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

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

O bloco finally

+ +

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

+ +

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

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

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

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

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

+ +
function f() {
+  try {
+    throw "bogus";
+  } catch(e) {
+    console.log('captura interior "falso"');
+    throw e; // essa instrução throw é suspensa até
+             // que o bloco finally seja concluído
+  } finally {
+    return false; // substitui "throw" anterior
+  }
+  // "return false" é executado agora
+}
+
+try {
+  f();
+} catch(e) {
+  // isto nunca é executado porque o throw dentro
+  // do catch é substituído
+  // pelo return no finally
+  console.log('captura exterior "falso"');
+}
+
+// SAIDA
+// captura interior "falso"
+ +

Aninhando declarações try...catch

+ +

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

+ +

Utilizando objetos de erro

+ +

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

+ +

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

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

Promises

+ +

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

+ +

Uma Promise assume um destes estados:

+ + + +

+ +

Carregando uma imagem com XHR

+ +

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

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

Para uma informação mais detalhada, consulte a página de referência {{jsxref("Promise")}}.

+ +
{{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}
diff --git "a/files/pt-br/web/javascript/guide/declara\303\247\303\265es/index.html" "b/files/pt-br/web/javascript/guide/declara\303\247\303\265es/index.html" deleted file mode 100644 index e352b58f6d..0000000000 --- "a/files/pt-br/web/javascript/guide/declara\303\247\303\265es/index.html" +++ /dev/null @@ -1,429 +0,0 @@ ---- -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 ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}
- -

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

- -

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

- -

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

- -

Declaração em bloco

- -

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

- -
{
-   declaracao_1;
-   declaracao_2;
-   .
-   .
-   .
-   declaracao_n;
-}
-
- -

Exemplo

- -

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

- -
while (x < 10) {
-  x++;
-}
-
- -

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

- -

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

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

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

- -

Declarações condicionais

- -

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

- -

Declaração if...else

- -

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

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

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

- -

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

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

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

- -
if (condicao) {
-    declaracao_1_executada_se_condicao_for_verdadeira;
-    declaracao_2_executada_se_condicao_for_verdadeira;
-} else {
-    declaracao_3_executada_se_condicao_for_falsa;
-    declaracao_4_executada_se_condicao_for_falsa;
-}
-
- -
Recomenda-se não utilizar atribuições simples em uma expressão condicional porque o símbolo de atribuição poderia ser confundido com o de igualdade ao dar uma olhada no código. Por exemplo, não utilize o seguinte código:
- -
if (x = y) {
-  /* faça a coisa certa */
-}
-
- -

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

- -
if ((x = y)) {
-  /* faça a coisa certa */
-}
-
- -

Valores avaliados como falsos

- -

Os seguintes valores são avaliados como falsos:

- - - -

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

- -

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

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

 

- -

Exemplo

- -

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

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

Declaração switch

- -

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

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

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

- -

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

- -

Exemplo

- -

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

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

Declarações de Manipulação de Error

- -

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

- - - -

Tipos de exceções

- -

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

- - - -

Declaração throw

- -

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

- -
throw expressão;
-
- -

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

- -
throw "Error2";   // tipo string
-throw 42;         // tipo numérico
-throw true;       // tipo booleano
-throw {toString: function() { return "Eu sou um objeto!"; } };
-
- -
Nota:  Você pode especificar um objeto quando você lança uma exceção. Você pode então, referenciar as propriedades de um objeto no bloco catch.  O exemplo a seguir cria um objeto myUserException do tipo userException e o usa em uma declaração throw.
- -
// Cria um objeto do tipo UserException
-function UserException(mensagem) {
-  this.mensagem = mensagem;
-  this.nome = "UserException";
-}
-
-// Realiza a conversão da exceção para uma string adequada quando usada como uma string.
-// (ex. pelo console de erro)
-UserException.prototype.toString = function() {
-  return this.name + ': "' + this.message + '"';
-}
-
-// Cria uma instância de um tipo de objeto e lança ela
-throw new UserException("Valor muito alto");
- -

Declaração try...catch

- -

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

- -

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

- -

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

- -
function getMonthName(mo) {
-  mo = mo - 1; // Ajusta o número do mês para o índice do array (1 = Jan, 12 = Dec)
-  var months = ["Jan","Feb","Mar","Apr","May","Jun","Jul",
-                "Aug","Sep","Oct","Nov","Dec"];
-  if (months[mo]) {
-    return months[mo];
-  } else {
-    throw "InvalidMonthNo"; //lança uma palavra-chave aqui usada.
-  }
-}
-
-try { // statements to try
-  monthName = getMonthName(myMonth); // função poderia lançar uma exceção
-}
-catch (e) {
-  monthName = "unknown";
-  logMyErrors(e); // passa a exceção para o manipulador de erro -> sua função local.
-}
-
- -

O bloco catch

- -

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

- -
catch (catchID) {
-  declaracoes
-}
-
- -

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

- -

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

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

O bloco finally

- -

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

- -

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

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

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

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

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

- -
function f() {
-  try {
-    throw "bogus";
-  } catch(e) {
-    console.log('captura interior "falso"');
-    throw e; // essa instrução throw é suspensa até
-             // que o bloco finally seja concluído
-  } finally {
-    return false; // substitui "throw" anterior
-  }
-  // "return false" é executado agora
-}
-
-try {
-  f();
-} catch(e) {
-  // isto nunca é executado porque o throw dentro
-  // do catch é substituído
-  // pelo return no finally
-  console.log('captura exterior "falso"');
-}
-
-// SAIDA
-// captura interior "falso"
- -

Aninhando declarações try...catch

- -

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

- -

Utilizando objetos de erro

- -

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

- -

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

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

Promises

- -

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

- -

Uma Promise assume um destes estados:

- - - -

- -

Carregando uma imagem com XHR

- -

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

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

Para uma informação mais detalhada, consulte a página de referência {{jsxref("Promise")}}.

- -
{{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}
diff --git a/files/pt-br/web/javascript/guide/details_of_the_object_model/index.html b/files/pt-br/web/javascript/guide/details_of_the_object_model/index.html new file mode 100644 index 0000000000..55a4c928a5 --- /dev/null +++ b/files/pt-br/web/javascript/guide/details_of_the_object_model/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 +--- +

JavaScript é uma linguagem orientada a objetos com base em protótipos, em vez de ser baseada em classes. Devido a essa base diferente, pode ser menos evidente como o JavaScript permite criar hierarquias de objetos e ter herança de propriedades e seus valores. Este capítulo tenta esclarecer essa situação.

+ +
+
Este capítulo assume que você já está um pouco familiarizado com JavaScript e que você já tenha usado funções JavaScript para criar simples objetos.
+ +
+
+ +

Linguagens baseada em classe vs. baseada em protótipo

+ +

Linguagens orientadas a objetos baseadas em classe, como Java e C + +, são fundadas no conceito de duas entidades distintas: classes e instâncias.

+ + + +

Uma linguagem baseada em protótipo, como JavaScript, não faz essa distinção: ele simplesmente tem objetos. Uma linguagem baseada em protótipo tem a idéia de um objeto prototípico, um objeto usado como um modelo do qual obtém as propriedades iniciais para um novo objeto. Qualquer objeto pode especificar suas próprias propriedades, quando você o cria ou em tempo de execução. Além disso, qualquer objeto pode ser associado como um protótipo de outro objeto, permitindo ao segundo objeto compartilhar as propriedades do primeiro objeto.

+ +

Definindo uma classe

+ +

Em linguagens baseadas em classe, você define uma classe em uma definição de classe separada. Nessa definição, você pode especificar métodos especiais, chamados de construtores, para criar instâncias da classe. Um método construtor 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 new, em associação com o método construtor para criar instâncias de classe.

+ +

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 new com uma função de construtor para criar um novo objeto.

+ +

Subclasses e herança

+ +

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 subclasse 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 Employee tem somente duas propriedades name e dept , e Manager é uma subclasse of Employee que adiciona a propriedade reports. Neste caso, uma instância da classe Manager  terá todas as três propiedades: name, dept, and reports.

+ +

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: EmployeeManager, mas utilizando uma terminologia ligeramente diferente. Primeiro, define-se a função de construtor de  Employee, especificando as propriedades name e dept. Depois,  define-se a função de construtor de  Manager, especificando a propriedade reports. Finalmente, associa-se um objeto new Employee  como  prototype para a função de construtor Manager. Então, quando vocẽ criar um objeto new Manager, ele herdará as propriedades  name e dept do objeto Employee.

+ +

Adicionando e removendo propriedades

+ +

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.

+ +

Sumário das diferenças

+ +

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.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Comparação de objetos do sistema baseados em classes (Java) e baseado em protótipo (JavaScript)
Baseados em classes (Java)Baseados em protótipos (JavaScript)
Classes e instancias são entidades distintas.Todos os objetos são instancias.
Define uma classe com uma definição de classe; cria um objeto - como instância da classe - com o método constructor.Define e cria um conjunto de objetos com funções construtoras.
Cria um único objeto com o operador new.Faz o mesmo.
Constroi uma hierarquia de objetos usando definição de classe para definir subclasses de classes existentes.Constrói uma hierarquia de objetos, atribuindo um objeto como o protótipo associado com uma função de construtor.
Herda propriedade seguindo a cadeia de classe.Herda propriedade seguindo a cadeia de protótipo.
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.Função construtor ou protótipo especifica um conjunto inicial de propriedades. Pode adicionar ou remover propriedades de forma dinâmica para objetos individuais ou para todo o conjunto de objetos.
+ +

O exemplo employee

+ +

O restante deste capítulo usa a hierarquia employee como mostrado na figura abaixo. 

+ +
+

Uma simples hierarquia de objetos:

+ +

+ + +
+ +

Criando a hierarquia

+ +

Há muitas formas de definir funções construtoras apropriadas para implementar a hierarquia Employee. Como escolher defini-las depende amplamente do que você quer ser capaz de fazer em sua aplicação.

+ +

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.

+ +

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 Construtores flexíveis para saber mais). Por enquanto, estas simples definições demonstram como a herança ocorre.

+ +

As seguintes definições Java e JavaScript Employee 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 linguagem fortemente tipada enquanto o JavaScript é linguagem fracamente tipada).

+ +
+

JavaScript

+ +
function Employee() {
+  this.name = "";
+  this.dept = "general";
+}
+
+ +

Java

+ +
public class Employee {
+   public String name = "";
+   public String dept = "general";
+}
+
+
+ +

As definições Manager e WorkerBee 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 prototype 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.

+ +
+

JavaScript

+ +
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);
+
+ +

Java

+ +
public class Manager extends Employee {
+   public Employee[] reports = new Employee[0];
+}
+
+
+
+public class WorkerBee extends Employee {
+   public String[] projects = new String[0];
+}
+
+
+
+
+ +

As definições Engineer e SalesPerson criam objetos que descendem de WorkerBee e consequentemente de Employee. 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 dept com novos valores específicos para esses objetos.

+ +
+

JavaScript

+ +
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);
+
+ +

Java

+ +
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 = "";
+}
+
+
+
+ +

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. 

+ +
+

Note: O termo instancia   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 jane é uma instância de Engineer. Similarmente, embora os termos parent, child, ancestor, e descendant não tenham significados formais em JavaScript; você pode usá-los informalmente para referir a objetos altos ou baixos na cadeia de protótipos.

+
+ +

Criando objetos com definições simples

+ +
+

Hierarquia do Objeto

+ +

A hierarquia abaixo foi criada utilizando o código ao lado.

+ +

+ +

Objetos individuais = Jim, Sally, Mark, Fred, Jane, etc. "Instancias" criadas a partir do construtor.

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

Propriedades do Objeto

+ +

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.

+ +

Herdando Propriedades

+ +

Suponha que você criou o objeto mark como um WorkerBee com a seguinte declaração:

+ +
var mark = new WorkerBee;
+
+ +

Quando o JavaScript vê o operador new, ele cria um novo objeto genérico e implicitamente define o valor da propriedade interna [[Protótipo]] para o valor de WorkerBee.prototype passando este novo objeto como o valor da palavra-chave this para a função construtora de WorkerBee. 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 mark para este objeto.

+ +

Este processo não põe explicitamente valores no objeto mark (valores locais) para as propriedades que mark 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 mark possui as seguintes propriedades e valores: 

+ +
mark.name = "";
+mark.dept = "general";
+mark.projects = [];
+
+ +

The mark object inherits values for the name and dept properties from the prototypical object in mark.__proto__. It is assigned a local value for the projects property by the WorkerBee constructor. This gives you inheritance of properties and their values in JavaScript. Some subtleties of this process are discussed in Property inheritance revisited.

+ +

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 WorkerBee. You can, of course, change the values of any of these properties. So, you could give specific information for mark as follows:

+ +
mark.name = "Doe, Mark";
+mark.dept = "admin";
+mark.projects = ["navigator"];
+ +

Adding properties

+ +

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:

+ +
mark.bonus = 3000;
+
+ +

Now, the mark object has a bonus property, but no other WorkerBee has this property.

+ +

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 specialty property to all employees with the following statement:

+ +
Employee.prototype.specialty = "none";
+
+ +

As soon as JavaScript executes this statement, the mark object also has the specialty property with the value of "none". The following figure shows the effect of adding this property to the Employee prototype and then overriding it for the Engineer prototype.

+ +


+ Adding properties

+ +

More flexible constructors

+ +

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.

+ +


+ Specifying properties in a constructor, take 1

+ +

The following table shows the Java and JavaScript definitions for these objects.

+ +
+

JavaScript

+ +

Java

+
+ +
+
function Employee (name, dept) {
+  this.name = name || "";
+  this.dept = dept || "general";
+}
+
+ +
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;
+   }
+}
+
+
+ +
+
function WorkerBee (projs) {
+
+ this.projects = projs || [];
+}
+WorkerBee.prototype = new Employee;
+
+ +
public class WorkerBee extends Employee {
+   public String[] projects;
+   public WorkerBee () {
+      this(new String[0]);
+   }
+   public WorkerBee (String[] projs) {
+      projects = projs;
+   }
+}
+
+
+ +
+
+function Engineer (mach) {
+   this.dept = "engineering";
+   this.machine = mach || "";
+}
+Engineer.prototype = new WorkerBee;
+
+ +
public class Engineer extends WorkerBee {
+   public String machine;
+   public Engineer () {
+      dept = "engineering";
+      machine = "";
+   }
+   public Engineer (String mach) {
+      dept = "engineering";
+      machine = mach;
+   }
+}
+
+
+ +

These JavaScript definitions use a special idiom for setting default values:

+ +
this.name = name || "";
+
+ +

The JavaScript logical OR operator (||) 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 name has a useful value for the name property. If it does, it sets this.name to that value. Otherwise, it sets this.name to the empty string. This chapter uses this idiom for brevity; however, it can be puzzling at first glance.

+ +
+

Note: This may not work as expected if the constructor function is called with arguments which convert to false (like 0 (zero) and empty string (""). In this case the default value will be chosen.

+
+ +

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

+ +
var jane = new Engineer("belau");
+
+ +

Jane's properties are now:

+ +
jane.name == "";
+jane.dept == "engineering";
+jane.projects == [];
+jane.machine == "belau"
+
+ +

Notice that with these definitions, you cannot specify an initial value for an inherited property such as name. If you want to specify an initial value for inherited properties in JavaScript, you need to add more code to the constructor function.

+ +

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.

+ +


+ Specifying properties in a constructor, take 2

+ +

Let's look at one of these definitions in detail. Here's the new definition for the Engineer constructor:

+ +
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+ +

Suppose you create a new Engineer object as follows:

+ +
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
+
+ +

JavaScript follows these steps:

+ +
    +
  1. The new operator creates a generic object and sets its __proto__ property to Engineer.prototype.
  2. +
  3. The new operator passes the new object to the Engineer constructor as the value of the this keyword.
  4. +
  5. The constructor creates a new property called base for that object and assigns the value of the WorkerBee constructor to the base property. This makes the WorkerBee constructor a method of the Engineer object.The name of the base property is not special. You can use any legal property name; base is simply evocative of its purpose.
  6. +
  7. +

    The constructor calls the base method, passing as its arguments two of the arguments passed to the constructor ("Doe, Jane" and ["navigator", "javascript"]) and also the string "engineering". Explicitly using "engineering" in the constructor indicates that all Engineer objects have the same value for the inherited dept property, and this value overrides the value inherited from Employee.

    +
  8. +
  9. Because base is a method of Engineer, within the call to base, JavaScript binds the this keyword to the object created in Step 1. Thus, the WorkerBee function in turn passes the "Doe, Jane" and "engineering" arguments to the Employee constructor function. Upon return from the Employee constructor function, the WorkerBee function uses the remaining argument to set the projects property.
  10. +
  11. Upon return from the base method, the Engineer constructor initializes the object's machine property to "belau".
  12. +
  13. Upon return from the constructor, JavaScript assigns the new object to the jane variable.
  14. +
+ +

You might think that, having called the WorkerBee constructor from inside the Engineer constructor, you have set up inheritance appropriately for Engineer objects. This is not the case. Calling the WorkerBee constructor ensures that an Engineer object starts out with the properties specified in all constructor functions that are called. However, if you later add properties to the Employee or WorkerBee prototypes, those properties are not inherited by the Engineer object. For example, assume you have the following statements:

+ +
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";
+
+ +

The jane object does not inherit the specialty property. You still need to explicitly set up the prototype to ensure dynamic inheritance. Assume instead you have these statements:

+ +
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";
+
+ +

Now the value of the jane object's specialty property is "none".

+ +

Another way of inheriting is by using the call() / apply() methods. Below are equivalent:

+ +
+
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+ +
function Engineer (name, projs, mach) {
+  WorkerBee.call(this, name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+
+ +

Using the javascript call() method makes a cleaner implementation because the base is not needed anymore.

+ +

Property inheritance revisited

+ +

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.

+ +

Local versus inherited values

+ +

When you access an object property, JavaScript performs these steps, as described earlier in this chapter:

+ +
    +
  1. Check to see if the value exists locally. If it does, return that value.
  2. +
  3. If there is not a local value, check the prototype chain (using the __proto__ property).
  4. +
  5. If an object in the prototype chain has a value for the specified property, return that value.
  6. +
  7. If no such property is found, the object does not have the property.
  8. +
+ +

The outcome of these steps depends on how you define things along the way. The original example had these definitions:

+ +
function Employee () {
+  this.name = "";
+  this.dept = "general";
+}
+
+function WorkerBee () {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+ +

With these definitions, suppose you create amy as an instance of WorkerBee with the following statement:

+ +
var amy = new WorkerBee;
+
+ +

The amy object has one local property, projects. The values for the name and dept properties are not local to amy and so are gotten from the amy object's __proto__ property. Thus, amy has these property values:

+ +
amy.name == "";
+amy.dept == "general";
+amy.projects == [];
+
+ +

Now suppose you change the value of the name property in the prototype associated with Employee:

+ +
Employee.prototype.name = "Unknown"
+
+ +

At first glance, you might expect that new value to propagate down to all the instances of Employee. However, it does not.

+ +

When you create any instance of the Employee object, that instance gets a local value for the name property (the empty string). This means that when you set the WorkerBee prototype by creating a new Employee object, WorkerBee.prototype has a local value for the name property. Therefore, when JavaScript looks up the name property of the amy object (an instance of WorkerBee), JavaScript finds the local value for that property in WorkerBee.prototype. It therefore does not look farther up the chain to Employee.prototype.

+ +

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:

+ +
function Employee () {
+  this.dept = "general";
+}
+Employee.prototype.name = "";
+
+function WorkerBee () {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+var amy = new WorkerBee;
+
+Employee.prototype.name = "Unknown";
+
+ +

In this case, the name property of amy becomes "Unknown".

+ +

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.

+ +

Determining instance relationships

+ +

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 __proto__. This continues recursively; the process is called "lookup in the prototype chain".

+ +

The special property __proto__ is set when an object is constructed; it is set to the value of the constructor's prototype property. So the expression new Foo() creates an object with __proto__ == Foo.prototype. Consequently, changes to the properties of Foo.prototype alters the property lookup for all objects that were created by new Foo().

+ +

Every object has a __proto__ object property (except Object); every function has a prototype object property. So objects can be related by 'prototype inheritance' to other objects. You can test for inheritance by comparing an object's __proto__ to a function's prototype object. JavaScript provides a shortcut: the instanceof operator tests an object against a function and returns true if the object inherits from the function prototype. For example,

+ +
var f = new Foo();
+var isTrue = (f instanceof Foo);
+ +

For a more detailed example, suppose you have the same set of definitions shown in Inheriting properties. Create an Engineer object as follows:

+ +
var chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");
+
+ +

With this object, the following statements are all true:

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

Given this, you could write an instanceOf function as follows:

+ +
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;
+}
+
+ +
Note: 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.
+ +

Using the instanceOf function defined above, these expressions are true:

+ +
instanceOf (chris, Engineer)
+instanceOf (chris, WorkerBee)
+instanceOf (chris, Employee)
+instanceOf (chris, Object)
+
+ +

But the following expression is false:

+ +
instanceOf (chris, SalesPerson)
+
+ +

Global information in constructors

+ +

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

+ +
var idCounter = 1;
+
+function Employee (name, dept) {
+   this.name = name || "";
+   this.dept = dept || "general";
+   this.id = idCounter++;
+}
+
+ +

With this definition, when you create a new Employee, the constructor assigns it the next ID in sequence and then increments the global ID counter. So, if your next statement is the following, victoria.id is 1 and harry.id is 2:

+ +
var victoria = new Employee("Pigbert, Victoria", "pubs")
+var harry = new Employee("Tschopik, Harry", "sales")
+
+ +

At first glance that seems fine. However, idCounter gets incremented every time an Employee object is created, for whatever purpose. If you create the entire Employee hierarchy shown in this chapter, the Employee constructor is called every time you set up a prototype. Suppose you have the following code:

+ +
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");
+
+ +

Further assume that the definitions omitted here have the base property and call the constructor above them in the prototype chain. In this case, by the time the mac object is created, mac.id is 5.

+ +

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:

+ +
function Employee (name, dept) {
+   this.name = name || "";
+   this.dept = dept || "general";
+   if (name)
+      this.id = idCounter++;
+}
+
+ +

When you create an instance of Employee 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 Employee to get an assigned id, you must specify a name for the employee. In this example, mac.id would be 1.

+ +

No multiple inheritance

+ +

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.

+ +

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.

+ +

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:

+ +
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")
+
+ +

Further assume that the definition of WorkerBee is as used earlier in this chapter. In this case, the dennis object has these properties:

+ +
dennis.name == "Doe, Dennis"
+dennis.dept == "engineering"
+dennis.projects == ["collabra"]
+dennis.machine == "hugo"
+dennis.hobby == "scuba"
+
+ +

So dennis does get the hobby property from the Hobbyist constructor. However, assume you then add a property to the Hobbyist constructor's prototype:

+ +
Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"]
+
+ +

The dennis object does not inherit this new property.

+ +
{{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}
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 deleted file mode 100644 index 55a4c928a5..0000000000 --- a/files/pt-br/web/javascript/guide/detalhes_do_modelo_do_objeto/index.html +++ /dev/null @@ -1,705 +0,0 @@ ---- -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 ---- -

JavaScript é uma linguagem orientada a objetos com base em protótipos, em vez de ser baseada em classes. Devido a essa base diferente, pode ser menos evidente como o JavaScript permite criar hierarquias de objetos e ter herança de propriedades e seus valores. Este capítulo tenta esclarecer essa situação.

- -
-
Este capítulo assume que você já está um pouco familiarizado com JavaScript e que você já tenha usado funções JavaScript para criar simples objetos.
- -
-
- -

Linguagens baseada em classe vs. baseada em protótipo

- -

Linguagens orientadas a objetos baseadas em classe, como Java e C + +, são fundadas no conceito de duas entidades distintas: classes e instâncias.

- - - -

Uma linguagem baseada em protótipo, como JavaScript, não faz essa distinção: ele simplesmente tem objetos. Uma linguagem baseada em protótipo tem a idéia de um objeto prototípico, um objeto usado como um modelo do qual obtém as propriedades iniciais para um novo objeto. Qualquer objeto pode especificar suas próprias propriedades, quando você o cria ou em tempo de execução. Além disso, qualquer objeto pode ser associado como um protótipo de outro objeto, permitindo ao segundo objeto compartilhar as propriedades do primeiro objeto.

- -

Definindo uma classe

- -

Em linguagens baseadas em classe, você define uma classe em uma definição de classe separada. Nessa definição, você pode especificar métodos especiais, chamados de construtores, para criar instâncias da classe. Um método construtor 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 new, em associação com o método construtor para criar instâncias de classe.

- -

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 new com uma função de construtor para criar um novo objeto.

- -

Subclasses e herança

- -

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 subclasse 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 Employee tem somente duas propriedades name e dept , e Manager é uma subclasse of Employee que adiciona a propriedade reports. Neste caso, uma instância da classe Manager  terá todas as três propiedades: name, dept, and reports.

- -

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: EmployeeManager, mas utilizando uma terminologia ligeramente diferente. Primeiro, define-se a função de construtor de  Employee, especificando as propriedades name e dept. Depois,  define-se a função de construtor de  Manager, especificando a propriedade reports. Finalmente, associa-se um objeto new Employee  como  prototype para a função de construtor Manager. Então, quando vocẽ criar um objeto new Manager, ele herdará as propriedades  name e dept do objeto Employee.

- -

Adicionando e removendo propriedades

- -

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.

- -

Sumário das diferenças

- -

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.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Comparação de objetos do sistema baseados em classes (Java) e baseado em protótipo (JavaScript)
Baseados em classes (Java)Baseados em protótipos (JavaScript)
Classes e instancias são entidades distintas.Todos os objetos são instancias.
Define uma classe com uma definição de classe; cria um objeto - como instância da classe - com o método constructor.Define e cria um conjunto de objetos com funções construtoras.
Cria um único objeto com o operador new.Faz o mesmo.
Constroi uma hierarquia de objetos usando definição de classe para definir subclasses de classes existentes.Constrói uma hierarquia de objetos, atribuindo um objeto como o protótipo associado com uma função de construtor.
Herda propriedade seguindo a cadeia de classe.Herda propriedade seguindo a cadeia de protótipo.
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.Função construtor ou protótipo especifica um conjunto inicial de propriedades. Pode adicionar ou remover propriedades de forma dinâmica para objetos individuais ou para todo o conjunto de objetos.
- -

O exemplo employee

- -

O restante deste capítulo usa a hierarquia employee como mostrado na figura abaixo. 

- -
-

Uma simples hierarquia de objetos:

- -

- - -
- -

Criando a hierarquia

- -

Há muitas formas de definir funções construtoras apropriadas para implementar a hierarquia Employee. Como escolher defini-las depende amplamente do que você quer ser capaz de fazer em sua aplicação.

- -

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.

- -

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 Construtores flexíveis para saber mais). Por enquanto, estas simples definições demonstram como a herança ocorre.

- -

As seguintes definições Java e JavaScript Employee 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 linguagem fortemente tipada enquanto o JavaScript é linguagem fracamente tipada).

- -
-

JavaScript

- -
function Employee() {
-  this.name = "";
-  this.dept = "general";
-}
-
- -

Java

- -
public class Employee {
-   public String name = "";
-   public String dept = "general";
-}
-
-
- -

As definições Manager e WorkerBee 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 prototype 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.

- -
-

JavaScript

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

Java

- -
public class Manager extends Employee {
-   public Employee[] reports = new Employee[0];
-}
-
-
-
-public class WorkerBee extends Employee {
-   public String[] projects = new String[0];
-}
-
-
-
-
- -

As definições Engineer e SalesPerson criam objetos que descendem de WorkerBee e consequentemente de Employee. 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 dept com novos valores específicos para esses objetos.

- -
-

JavaScript

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

Java

- -
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 = "";
-}
-
-
-
- -

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. 

- -
-

Note: O termo instancia   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 jane é uma instância de Engineer. Similarmente, embora os termos parent, child, ancestor, e descendant não tenham significados formais em JavaScript; você pode usá-los informalmente para referir a objetos altos ou baixos na cadeia de protótipos.

-
- -

Criando objetos com definições simples

- -
-

Hierarquia do Objeto

- -

A hierarquia abaixo foi criada utilizando o código ao lado.

- -

- -

Objetos individuais = Jim, Sally, Mark, Fred, Jane, etc. "Instancias" criadas a partir do construtor.

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

Propriedades do Objeto

- -

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.

- -

Herdando Propriedades

- -

Suponha que você criou o objeto mark como um WorkerBee com a seguinte declaração:

- -
var mark = new WorkerBee;
-
- -

Quando o JavaScript vê o operador new, ele cria um novo objeto genérico e implicitamente define o valor da propriedade interna [[Protótipo]] para o valor de WorkerBee.prototype passando este novo objeto como o valor da palavra-chave this para a função construtora de WorkerBee. 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 mark para este objeto.

- -

Este processo não põe explicitamente valores no objeto mark (valores locais) para as propriedades que mark 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 mark possui as seguintes propriedades e valores: 

- -
mark.name = "";
-mark.dept = "general";
-mark.projects = [];
-
- -

The mark object inherits values for the name and dept properties from the prototypical object in mark.__proto__. It is assigned a local value for the projects property by the WorkerBee constructor. This gives you inheritance of properties and their values in JavaScript. Some subtleties of this process are discussed in Property inheritance revisited.

- -

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 WorkerBee. You can, of course, change the values of any of these properties. So, you could give specific information for mark as follows:

- -
mark.name = "Doe, Mark";
-mark.dept = "admin";
-mark.projects = ["navigator"];
- -

Adding properties

- -

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:

- -
mark.bonus = 3000;
-
- -

Now, the mark object has a bonus property, but no other WorkerBee has this property.

- -

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 specialty property to all employees with the following statement:

- -
Employee.prototype.specialty = "none";
-
- -

As soon as JavaScript executes this statement, the mark object also has the specialty property with the value of "none". The following figure shows the effect of adding this property to the Employee prototype and then overriding it for the Engineer prototype.

- -


- Adding properties

- -

More flexible constructors

- -

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.

- -


- Specifying properties in a constructor, take 1

- -

The following table shows the Java and JavaScript definitions for these objects.

- -
-

JavaScript

- -

Java

-
- -
-
function Employee (name, dept) {
-  this.name = name || "";
-  this.dept = dept || "general";
-}
-
- -
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;
-   }
-}
-
-
- -
-
function WorkerBee (projs) {
-
- this.projects = projs || [];
-}
-WorkerBee.prototype = new Employee;
-
- -
public class WorkerBee extends Employee {
-   public String[] projects;
-   public WorkerBee () {
-      this(new String[0]);
-   }
-   public WorkerBee (String[] projs) {
-      projects = projs;
-   }
-}
-
-
- -
-
-function Engineer (mach) {
-   this.dept = "engineering";
-   this.machine = mach || "";
-}
-Engineer.prototype = new WorkerBee;
-
- -
public class Engineer extends WorkerBee {
-   public String machine;
-   public Engineer () {
-      dept = "engineering";
-      machine = "";
-   }
-   public Engineer (String mach) {
-      dept = "engineering";
-      machine = mach;
-   }
-}
-
-
- -

These JavaScript definitions use a special idiom for setting default values:

- -
this.name = name || "";
-
- -

The JavaScript logical OR operator (||) 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 name has a useful value for the name property. If it does, it sets this.name to that value. Otherwise, it sets this.name to the empty string. This chapter uses this idiom for brevity; however, it can be puzzling at first glance.

- -
-

Note: This may not work as expected if the constructor function is called with arguments which convert to false (like 0 (zero) and empty string (""). In this case the default value will be chosen.

-
- -

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

- -
var jane = new Engineer("belau");
-
- -

Jane's properties are now:

- -
jane.name == "";
-jane.dept == "engineering";
-jane.projects == [];
-jane.machine == "belau"
-
- -

Notice that with these definitions, you cannot specify an initial value for an inherited property such as name. If you want to specify an initial value for inherited properties in JavaScript, you need to add more code to the constructor function.

- -

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.

- -


- Specifying properties in a constructor, take 2

- -

Let's look at one of these definitions in detail. Here's the new definition for the Engineer constructor:

- -
function Engineer (name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, "engineering", projs);
-  this.machine = mach || "";
-}
-
- -

Suppose you create a new Engineer object as follows:

- -
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
-
- -

JavaScript follows these steps:

- -
    -
  1. The new operator creates a generic object and sets its __proto__ property to Engineer.prototype.
  2. -
  3. The new operator passes the new object to the Engineer constructor as the value of the this keyword.
  4. -
  5. The constructor creates a new property called base for that object and assigns the value of the WorkerBee constructor to the base property. This makes the WorkerBee constructor a method of the Engineer object.The name of the base property is not special. You can use any legal property name; base is simply evocative of its purpose.
  6. -
  7. -

    The constructor calls the base method, passing as its arguments two of the arguments passed to the constructor ("Doe, Jane" and ["navigator", "javascript"]) and also the string "engineering". Explicitly using "engineering" in the constructor indicates that all Engineer objects have the same value for the inherited dept property, and this value overrides the value inherited from Employee.

    -
  8. -
  9. Because base is a method of Engineer, within the call to base, JavaScript binds the this keyword to the object created in Step 1. Thus, the WorkerBee function in turn passes the "Doe, Jane" and "engineering" arguments to the Employee constructor function. Upon return from the Employee constructor function, the WorkerBee function uses the remaining argument to set the projects property.
  10. -
  11. Upon return from the base method, the Engineer constructor initializes the object's machine property to "belau".
  12. -
  13. Upon return from the constructor, JavaScript assigns the new object to the jane variable.
  14. -
- -

You might think that, having called the WorkerBee constructor from inside the Engineer constructor, you have set up inheritance appropriately for Engineer objects. This is not the case. Calling the WorkerBee constructor ensures that an Engineer object starts out with the properties specified in all constructor functions that are called. However, if you later add properties to the Employee or WorkerBee prototypes, those properties are not inherited by the Engineer object. For example, assume you have the following statements:

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

The jane object does not inherit the specialty property. You still need to explicitly set up the prototype to ensure dynamic inheritance. Assume instead you have these statements:

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

Now the value of the jane object's specialty property is "none".

- -

Another way of inheriting is by using the call() / apply() methods. Below are equivalent:

- -
-
function Engineer (name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, "engineering", projs);
-  this.machine = mach || "";
-}
-
- -
function Engineer (name, projs, mach) {
-  WorkerBee.call(this, name, "engineering", projs);
-  this.machine = mach || "";
-}
-
-
- -

Using the javascript call() method makes a cleaner implementation because the base is not needed anymore.

- -

Property inheritance revisited

- -

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.

- -

Local versus inherited values

- -

When you access an object property, JavaScript performs these steps, as described earlier in this chapter:

- -
    -
  1. Check to see if the value exists locally. If it does, return that value.
  2. -
  3. If there is not a local value, check the prototype chain (using the __proto__ property).
  4. -
  5. If an object in the prototype chain has a value for the specified property, return that value.
  6. -
  7. If no such property is found, the object does not have the property.
  8. -
- -

The outcome of these steps depends on how you define things along the way. The original example had these definitions:

- -
function Employee () {
-  this.name = "";
-  this.dept = "general";
-}
-
-function WorkerBee () {
-  this.projects = [];
-}
-WorkerBee.prototype = new Employee;
-
- -

With these definitions, suppose you create amy as an instance of WorkerBee with the following statement:

- -
var amy = new WorkerBee;
-
- -

The amy object has one local property, projects. The values for the name and dept properties are not local to amy and so are gotten from the amy object's __proto__ property. Thus, amy has these property values:

- -
amy.name == "";
-amy.dept == "general";
-amy.projects == [];
-
- -

Now suppose you change the value of the name property in the prototype associated with Employee:

- -
Employee.prototype.name = "Unknown"
-
- -

At first glance, you might expect that new value to propagate down to all the instances of Employee. However, it does not.

- -

When you create any instance of the Employee object, that instance gets a local value for the name property (the empty string). This means that when you set the WorkerBee prototype by creating a new Employee object, WorkerBee.prototype has a local value for the name property. Therefore, when JavaScript looks up the name property of the amy object (an instance of WorkerBee), JavaScript finds the local value for that property in WorkerBee.prototype. It therefore does not look farther up the chain to Employee.prototype.

- -

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:

- -
function Employee () {
-  this.dept = "general";
-}
-Employee.prototype.name = "";
-
-function WorkerBee () {
-  this.projects = [];
-}
-WorkerBee.prototype = new Employee;
-
-var amy = new WorkerBee;
-
-Employee.prototype.name = "Unknown";
-
- -

In this case, the name property of amy becomes "Unknown".

- -

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.

- -

Determining instance relationships

- -

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 __proto__. This continues recursively; the process is called "lookup in the prototype chain".

- -

The special property __proto__ is set when an object is constructed; it is set to the value of the constructor's prototype property. So the expression new Foo() creates an object with __proto__ == Foo.prototype. Consequently, changes to the properties of Foo.prototype alters the property lookup for all objects that were created by new Foo().

- -

Every object has a __proto__ object property (except Object); every function has a prototype object property. So objects can be related by 'prototype inheritance' to other objects. You can test for inheritance by comparing an object's __proto__ to a function's prototype object. JavaScript provides a shortcut: the instanceof operator tests an object against a function and returns true if the object inherits from the function prototype. For example,

- -
var f = new Foo();
-var isTrue = (f instanceof Foo);
- -

For a more detailed example, suppose you have the same set of definitions shown in Inheriting properties. Create an Engineer object as follows:

- -
var chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");
-
- -

With this object, the following statements are all true:

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

Given this, you could write an instanceOf function as follows:

- -
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;
-}
-
- -
Note: 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.
- -

Using the instanceOf function defined above, these expressions are true:

- -
instanceOf (chris, Engineer)
-instanceOf (chris, WorkerBee)
-instanceOf (chris, Employee)
-instanceOf (chris, Object)
-
- -

But the following expression is false:

- -
instanceOf (chris, SalesPerson)
-
- -

Global information in constructors

- -

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

- -
var idCounter = 1;
-
-function Employee (name, dept) {
-   this.name = name || "";
-   this.dept = dept || "general";
-   this.id = idCounter++;
-}
-
- -

With this definition, when you create a new Employee, the constructor assigns it the next ID in sequence and then increments the global ID counter. So, if your next statement is the following, victoria.id is 1 and harry.id is 2:

- -
var victoria = new Employee("Pigbert, Victoria", "pubs")
-var harry = new Employee("Tschopik, Harry", "sales")
-
- -

At first glance that seems fine. However, idCounter gets incremented every time an Employee object is created, for whatever purpose. If you create the entire Employee hierarchy shown in this chapter, the Employee constructor is called every time you set up a prototype. Suppose you have the following code:

- -
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");
-
- -

Further assume that the definitions omitted here have the base property and call the constructor above them in the prototype chain. In this case, by the time the mac object is created, mac.id is 5.

- -

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:

- -
function Employee (name, dept) {
-   this.name = name || "";
-   this.dept = dept || "general";
-   if (name)
-      this.id = idCounter++;
-}
-
- -

When you create an instance of Employee 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 Employee to get an assigned id, you must specify a name for the employee. In this example, mac.id would be 1.

- -

No multiple inheritance

- -

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.

- -

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.

- -

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:

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

Further assume that the definition of WorkerBee is as used earlier in this chapter. In this case, the dennis object has these properties:

- -
dennis.name == "Doe, Dennis"
-dennis.dept == "engineering"
-dennis.projects == ["collabra"]
-dennis.machine == "hugo"
-dennis.hobby == "scuba"
-
- -

So dennis does get the hobby property from the Hobbyist constructor. However, assume you then add a property to the Hobbyist constructor's prototype:

- -
Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"]
-
- -

The dennis object does not inherit this new property.

- -
{{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}
diff --git a/files/pt-br/web/javascript/guide/formatando_texto/index.html b/files/pt-br/web/javascript/guide/formatando_texto/index.html deleted file mode 100644 index 1b4bb50772..0000000000 --- a/files/pt-br/web/javascript/guide/formatando_texto/index.html +++ /dev/null @@ -1,250 +0,0 @@ ---- -title: Formatando texto -slug: Web/JavaScript/Guide/Formatando_texto -tags: - - Guía - - JavaScript -translation_of: Web/JavaScript/Guide/Text_formatting ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}
- -

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

- -

Strings

- -

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.

- -

Strings literais

- -

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

- -
'foo'
-"bar"
- -

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

- -

Sequências de escape hexadecimais

- -

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

- -
'\xA9' // "©"
-
- -

Sequências de escape unicode

- -

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

- -
'\u00A9' // "©"
- -

Sequências de escape Unicode code point

- -

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

- -

Veja também {{jsxref("String.fromCodePoint()")}} or {{jsxref("String.prototype.codePointAt()")}}.

- -
'\u{2F804}'
-
-// o mesmo com escapes Unicode simples
-'\uD87E\uDC04'
- -

Objetos String

- -

O objeto {{jsxref("String")}} é como uma "capa" ao redor do tipo primitivo string.

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

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

- -

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

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

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

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

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

- -

A tabela a seguir lista os métodos de objetos {{jsxref("String")}}.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

Métodos de String

-
MétodoDescrição
{{jsxref("String.charAt", "charAt")}}, {{jsxref("String.charCodeAt", "charCodeAt")}}, {{jsxref("String.codePointAt", "codePointAt")}}Retorna o código do caractere ou o caractere em uma posição específica na string.
{{jsxref("String.indexOf", "indexOf")}}, {{jsxref("String.lastIndexOf", "lastIndexOf")}}Retorna a posição de uma substring específica na string ou a última posição da substring específica, respectivamente.
{{jsxref("String.startsWith", "startsWith")}}, {{jsxref("String.endsWith", "endsWith")}}, {{jsxref("String.includes", "includes")}}Retorna se uma string começa, termina ou contém uma outra string específica.
{{jsxref("String.concat", "concat")}}Concatena o texto de duas strings e retorna uma nova string.
{{jsxref("String.fromCharCode", "fromCharCode")}}, {{jsxref("String.fromCodePoint", "fromCodePoint")}}Cria uma string a partir de uma sequência específica de valores Unicode. Esse é um método da classe String, não de uma instância do tipo String.
{{jsxref("String.split", "split")}}Separa um objeto String em um array de strings, separando a string em substrings.
{{jsxref("String.slice", "slice")}}Extrai uma seção de uma string e retorna uma nova string.
{{jsxref("String.substring", "substring")}}, {{jsxref("String.substr", "substr")}}Retorna um subconjunto específico de uma string, definindo os índices inicial e final, ou definindo um índice e um tamanho.
{{jsxref("String.match", "match")}}, {{jsxref("String.replace", "replace")}}, {{jsxref("String.search", "search")}}Trabalha com expressões regulares.
{{jsxref("String.toLowerCase", "toLowerCase")}}, {{jsxref("String.toUpperCase", "toUpperCase")}} -

Retorna a string com todos caracteres em minúsculo, ou maiúsculo, respectivamente.

-
{{jsxref("String.normalize", "normalize")}}Retorna a Forma Normalizada Unicode (Unicode Normalization Form) da string que chama o método.
{{jsxref("String.repeat", "repeat")}}Retorna uma string contendo os elementos do objeto repetidos pela quantidade de vezes dada.
{{jsxref("String.trim", "trim")}}Retira espaços em branco no começo e no final da string.
- -

Template strings com várias linhas

- -

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

- -

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

- -

Várias linhas (Multi-lines)

- -

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

- -
console.log("linha de texto 1\n\
-linha de texto 2");
-// "linha de texto 1
-// linha de texto 2"
- -

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

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

Expressões inseridas

- -

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

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

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

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

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

- -

Internacionalização

- -

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

- -

Formatação de data e hora

- -

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

- -
var msPorDia = 24 * 60 * 60 * 1000; // número de milisegundos em um dia
-
-// July 17, 2014 00:00:00 UTC.
-var july172014 = new Date(msPorDia * (44 * 365 + 11 + 197));
-
-var opcoes = { year: "2-digit", month: "2-digit", day: "2-digit",
-                hour: "2-digit", minute: "2-digit", timeZoneName: "short" };
-var americanDateTime = new Intl.DateTimeFormat("en-US", opcoes).format;
-
-console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT
-
- -

Formatação de números

- -

O objeto {{jsxref("NumberFormat")}} é útil para formatar números, por exemplo unidade monetária.

- -
var precoGasolina = new Intl.NumberFormat("en-US",
-                        { style: "currency", currency: "USD",
-                          minimumFractionDigits: 3 });
-
-console.log(precoGasolina.format(5.259)); // $5.259
-
-var hanDecimalRMBInChina = new Intl.NumberFormat("zh-CN-u-nu-hanidec",
-                        { style: "currency", currency: "CNY" });
-
-console.log(hanDecimalRMBInChina.format(1314.25)); // ¥ 一,三一四.二五
-
- -

Collation

- -

O objeto {{jsxref("Collator")}} é usado para comparar e ordenar strings.

- -

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

- -
var nomes = ["Hochberg", "Hönigswald", "Holzman"];
-
-var phonebookAlemao = new Intl.Collator("de-DE-u-co-phonebk");
-
-// como se ordenasse ["Hochberg", "Hoenigswald", "Holzman"]:
-console.log(names.sort(phonebookAlemao.compare).join(", "));
-// imprime "Hochberg, Hönigswald, Holzman"
-
- -

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

- -
var dicionarioAlemao = new Intl.Collator("de-DE-u-co-dict");
-
-// como se ordenasse ["Hochberg", "Honigswald", "Holzman"]:
-console.log(names.sort(dicionarioAlemao.compare).join(", "));
-// imprime "Hochberg, Holzman, Hönigswald"
-
- -

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

- -
{{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}
diff --git a/files/pt-br/web/javascript/guide/functions/index.html b/files/pt-br/web/javascript/guide/functions/index.html new file mode 100644 index 0000000000..7077d1787b --- /dev/null +++ b/files/pt-br/web/javascript/guide/functions/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 +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}
+ +

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

+ +

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

+ +

Definindo Funções

+ +

Declarando uma função

+ +

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

+ + + +

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

+ +
function square(numero) {
+  return numero * numero;
+}
+
+ +

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

+ +
return numero * numero;
+
+ +

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

+ +

Se você passar um objeto (ou seja, um  valor não primitivo, 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:

+ +
function minhaFuncao(objeto) {
+  objeto.make = "Toyota";
+}
+
+var meucarro = {make: "Honda", model: "Accord", year: 1998};
+var x, y;
+
+x = meucarro.make;     // x recebe o valor "Honda"
+
+minhaFuncao(meucarro);
+y = meucarro.make;     // y recebe o valor "Toyota"
+                    // (a propriedade make foi alterada pela função)
+
+ +

Expressão de função

+ +

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

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

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

+ +
var fatorial = function fac(n) {return n<2 ? 1 : n*fac(n-1)};
+
+console.log(fatorial(3));
+
+ +

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

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

O código a seguir:

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

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

+ +

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

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

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

+ +

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

+ +

Chamando funções

+ +

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

+ +
square(5);
+
+ +

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

+ +

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

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

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

+ +
+

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

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

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

+ +

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

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

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

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

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

+ +

Escopo da função

+ +

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

+ +
// As seguintes variáveis são definidas no escopo global
+var num1 = 20,
+    num2 = 3,
+    nome = "Chamahk";
+
+// Esta função é definida no escopo global
+function multiplica() {
+  return num1 * num2;
+}
+
+multiplica(); // Retorna 60
+
+// Um exemplo de função aninhada
+function getScore () {
+  var num1 = 2,
+      num2 = 3;
+
+  function add() {
+    return nome + " scored " + (num1 + num2);
+  }
+
+  return add();
+}
+
+getScore(); // Retorna "Chamahk scored 5"
+
+ +

Escopo e a pilha de função

+ +

Recursão

+ +

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

+ +
    +
  1. o nome da função
  2. +
  3. arguments.callee
  4. +
  5. uma variável no escopo que se refere a função
  6. +
+ +

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

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

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

+ +
    +
  1. bar()
  2. +
  3. arguments.callee()
  4. +
  5. foo()
  6. +
+ +

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:

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

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

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

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

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

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

+ +

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

+ +

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

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

que produz:

+ +
begin:3
+begin:2
+begin:1
+begin:0
+end:0
+end:1
+end:2
+end:3
+
+ +

Funções aninhadas e closures

+ +

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

+ +

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

+ +

Em resumo:

+ + + +

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

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

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

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

Preservação  de variáveis

+ +

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

+ +

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

+ +

Múltiplas funções aninhadas

+ +

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

+ +

Considere o seguinte exemplo:

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

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

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

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

+ +

Conflitos de nome

+ +

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

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

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

+ +

Closures

+ +

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

+ +
var pet = function(nome) {          // A função externa define uma variável "nome"
+      var getNome = function() {
+        return nome;                // A função interna tem acesso à variável "nome"  da função externa
+      }
+
+      return getNome;               // Retorna a função interna, expondo-a assim para escopos externos
+    },
+    myPet = pet("Vivie");
+
+myPet();                            // Retorna "Vivie"
+
+ +

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

+ +
var criarPet = function(nome) {
+  var sex;
+
+  return {
+    setNome: function(newNome) {
+      nome = newNome;
+    },
+
+    getNome: function() {
+      return nome;
+    },
+
+    getSex: function() {
+      return sex;
+    },
+
+    setSex: function(newSex) {
+      if(typeof newSex == "string" && (newSex.toLowerCase() == "macho" || newSex.toLowerCase() == "fêmea")) {
+        sex = newSex;
+      }
+    }
+  }
+}
+
+var pet = criarPet("Vivie");
+pet.getNome();                  // Vivie
+
+pet.setNome("Oliver");
+pet.setSex("macho");
+pet.getSex();                   // macho
+pet.getNome();                  // Oliver
+
+ +

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

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

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

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

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

+ +

Usando objeto de argumentos

+ +

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

+ +
arguments[i]
+
+ +

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

+ +

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

+ +

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

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

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

+ +
// retorna "red, orange, blue, "
+myConcat(", ", "red", "orange", "blue");
+
+// retorna "elephant; giraffe; lion; cheetah; "
+myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
+
+// retorna "sage. basil. oregano. pepper. parsley. "
+myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
+
+ +
+

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

+
+ +

Veja objeto {{jsxref("Function")}} na referência do JavaScript para maiores informações.

+ +

Parâmetros de função

+ +

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

+ +

Parâmetros padrão

+ +

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

+ +

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

+ +
function multiplicar(a, b) {
+  b = typeof b !== 'undefined' ?  b : 1;
+
+  return a*b;
+}
+
+multiplicar(5); // 5
+ +

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

+ +
function multiplicar(a, b = 1) {
+  return a*b;
+}
+
+multiplicar(5); // 5
+ +

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

+ +

Parâmetros rest

+ +

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

+ +
function multiplicar(multiplicador, ...args) {
+  return args.map(x => multiplicador * x);
+}
+
+var arr = multiplicar(2, 1, 2, 3);
+console.log(arr); // [2, 4, 6]
+ +

Funções de seta

+ +

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

+ +

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

+ +

Funções curtas

+ +

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

+ +
var a = [
+  "Hydrogen",
+  "Helium",
+  "Lithium",
+  "Beryl­lium"
+];
+
+var a2 = a.map(function(s){ return s.length });
+
+var a3 = a.map( s => s.length );
+ +

Léxico this

+ +

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

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

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

+ +
function Pessoa() {
+  var self = this; // Alguns preferem 'that' em vez de 'self'. 
+                   // Escolha um e seja consistente.
+  self.idade = 0;
+
+  setInterval(function crescer() {
+    // A chamada de retorno refere-se à variável 'self' na qual
+    // o valor é o objeto esperado.
+    self.idade++;
+  }, 1000);
+}
+ +

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

+ +

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

+ +
function Pessoa(){
+  this.idade = 0;
+
+  setInterval(() => {
+    this.idade++; // propriedade |this|refere ao objeto pessoa
+  }, 1000);
+}
+
+var p = new Pessoa();
+ +

Funções pré-definidas

+ +

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

+ +
+
{{jsxref("Global_Objects/eval", "eval()")}}
+
+

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

+
+
{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}
+
+

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

+
+
{{jsxref("Global_Objects/isFinite", "isFinite()")}}
+
+

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

+
+
{{jsxref("Global_Objects/isNaN", "isNaN()")}}
+
+

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

+
+
{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}
+
+

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

+
+
{{jsxref("Global_Objects/parseInt", "parseInt()")}}
+
+

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

+
+
{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}
+
+

A função decodeURI() decodifica uma Uniform Resource Identifier (URI) criada anteriormente por {{jsxref("Global_Objects/encodeURI", "encodeURI")}} ou por uma rotina similar.

+
+
{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}
+
+

O método decodeURIComponent() decodifica um componente Uniform Resource Identifier (URI) criado anteriormente por {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} ou por uma rotina similar.

+
+
{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}
+
+

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

+
+
{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}
+
+

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

+
+
{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}
+
+

O método obsoleto escape() calcula uma nova string 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.

+
+
{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}
+
+

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

+
+
+ +

{{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}

diff --git "a/files/pt-br/web/javascript/guide/fun\303\247\303\265es/index.html" "b/files/pt-br/web/javascript/guide/fun\303\247\303\265es/index.html" deleted file mode 100644 index 7077d1787b..0000000000 --- "a/files/pt-br/web/javascript/guide/fun\303\247\303\265es/index.html" +++ /dev/null @@ -1,640 +0,0 @@ ---- -title: Funções -slug: Web/JavaScript/Guide/Funções -tags: - - Funções JavaScript - - Guia(2) - - Iniciante - - JavaScript -translation_of: Web/JavaScript/Guide/Functions ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}
- -

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

- -

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

- -

Definindo Funções

- -

Declarando uma função

- -

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

- - - -

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

- -
function square(numero) {
-  return numero * numero;
-}
-
- -

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

- -
return numero * numero;
-
- -

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

- -

Se você passar um objeto (ou seja, um  valor não primitivo, 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:

- -
function minhaFuncao(objeto) {
-  objeto.make = "Toyota";
-}
-
-var meucarro = {make: "Honda", model: "Accord", year: 1998};
-var x, y;
-
-x = meucarro.make;     // x recebe o valor "Honda"
-
-minhaFuncao(meucarro);
-y = meucarro.make;     // y recebe o valor "Toyota"
-                    // (a propriedade make foi alterada pela função)
-
- -

Expressão de função

- -

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

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

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

- -
var fatorial = function fac(n) {return n<2 ? 1 : n*fac(n-1)};
-
-console.log(fatorial(3));
-
- -

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

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

O código a seguir:

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

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

- -

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

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

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

- -

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

- -

Chamando funções

- -

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

- -
square(5);
-
- -

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

- -

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

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

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

- -
-

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

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

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

- -

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

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

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

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

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

- -

Escopo da função

- -

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

- -
// As seguintes variáveis são definidas no escopo global
-var num1 = 20,
-    num2 = 3,
-    nome = "Chamahk";
-
-// Esta função é definida no escopo global
-function multiplica() {
-  return num1 * num2;
-}
-
-multiplica(); // Retorna 60
-
-// Um exemplo de função aninhada
-function getScore () {
-  var num1 = 2,
-      num2 = 3;
-
-  function add() {
-    return nome + " scored " + (num1 + num2);
-  }
-
-  return add();
-}
-
-getScore(); // Retorna "Chamahk scored 5"
-
- -

Escopo e a pilha de função

- -

Recursão

- -

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

- -
    -
  1. o nome da função
  2. -
  3. arguments.callee
  4. -
  5. uma variável no escopo que se refere a função
  6. -
- -

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

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

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

- -
    -
  1. bar()
  2. -
  3. arguments.callee()
  4. -
  5. foo()
  6. -
- -

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:

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

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

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

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

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

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

- -

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

- -

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

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

que produz:

- -
begin:3
-begin:2
-begin:1
-begin:0
-end:0
-end:1
-end:2
-end:3
-
- -

Funções aninhadas e closures

- -

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

- -

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

- -

Em resumo:

- - - -

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

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

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

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

Preservação  de variáveis

- -

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

- -

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

- -

Múltiplas funções aninhadas

- -

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

- -

Considere o seguinte exemplo:

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

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

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

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

- -

Conflitos de nome

- -

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

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

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

- -

Closures

- -

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

- -
var pet = function(nome) {          // A função externa define uma variável "nome"
-      var getNome = function() {
-        return nome;                // A função interna tem acesso à variável "nome"  da função externa
-      }
-
-      return getNome;               // Retorna a função interna, expondo-a assim para escopos externos
-    },
-    myPet = pet("Vivie");
-
-myPet();                            // Retorna "Vivie"
-
- -

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

- -
var criarPet = function(nome) {
-  var sex;
-
-  return {
-    setNome: function(newNome) {
-      nome = newNome;
-    },
-
-    getNome: function() {
-      return nome;
-    },
-
-    getSex: function() {
-      return sex;
-    },
-
-    setSex: function(newSex) {
-      if(typeof newSex == "string" && (newSex.toLowerCase() == "macho" || newSex.toLowerCase() == "fêmea")) {
-        sex = newSex;
-      }
-    }
-  }
-}
-
-var pet = criarPet("Vivie");
-pet.getNome();                  // Vivie
-
-pet.setNome("Oliver");
-pet.setSex("macho");
-pet.getSex();                   // macho
-pet.getNome();                  // Oliver
-
- -

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

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

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

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

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

- -

Usando objeto de argumentos

- -

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

- -
arguments[i]
-
- -

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

- -

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

- -

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

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

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

- -
// retorna "red, orange, blue, "
-myConcat(", ", "red", "orange", "blue");
-
-// retorna "elephant; giraffe; lion; cheetah; "
-myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
-
-// retorna "sage. basil. oregano. pepper. parsley. "
-myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
-
- -
-

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

-
- -

Veja objeto {{jsxref("Function")}} na referência do JavaScript para maiores informações.

- -

Parâmetros de função

- -

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

- -

Parâmetros padrão

- -

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

- -

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

- -
function multiplicar(a, b) {
-  b = typeof b !== 'undefined' ?  b : 1;
-
-  return a*b;
-}
-
-multiplicar(5); // 5
- -

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

- -
function multiplicar(a, b = 1) {
-  return a*b;
-}
-
-multiplicar(5); // 5
- -

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

- -

Parâmetros rest

- -

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

- -
function multiplicar(multiplicador, ...args) {
-  return args.map(x => multiplicador * x);
-}
-
-var arr = multiplicar(2, 1, 2, 3);
-console.log(arr); // [2, 4, 6]
- -

Funções de seta

- -

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

- -

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

- -

Funções curtas

- -

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

- -
var a = [
-  "Hydrogen",
-  "Helium",
-  "Lithium",
-  "Beryl­lium"
-];
-
-var a2 = a.map(function(s){ return s.length });
-
-var a3 = a.map( s => s.length );
- -

Léxico this

- -

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

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

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

- -
function Pessoa() {
-  var self = this; // Alguns preferem 'that' em vez de 'self'. 
-                   // Escolha um e seja consistente.
-  self.idade = 0;
-
-  setInterval(function crescer() {
-    // A chamada de retorno refere-se à variável 'self' na qual
-    // o valor é o objeto esperado.
-    self.idade++;
-  }, 1000);
-}
- -

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

- -

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

- -
function Pessoa(){
-  this.idade = 0;
-
-  setInterval(() => {
-    this.idade++; // propriedade |this|refere ao objeto pessoa
-  }, 1000);
-}
-
-var p = new Pessoa();
- -

Funções pré-definidas

- -

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

- -
-
{{jsxref("Global_Objects/eval", "eval()")}}
-
-

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

-
-
{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}
-
-

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

-
-
{{jsxref("Global_Objects/isFinite", "isFinite()")}}
-
-

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

-
-
{{jsxref("Global_Objects/isNaN", "isNaN()")}}
-
-

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

-
-
{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}
-
-

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

-
-
{{jsxref("Global_Objects/parseInt", "parseInt()")}}
-
-

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

-
-
{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}
-
-

A função decodeURI() decodifica uma Uniform Resource Identifier (URI) criada anteriormente por {{jsxref("Global_Objects/encodeURI", "encodeURI")}} ou por uma rotina similar.

-
-
{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}
-
-

O método decodeURIComponent() decodifica um componente Uniform Resource Identifier (URI) criado anteriormente por {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} ou por uma rotina similar.

-
-
{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}
-
-

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

-
-
{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}
-
-

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

-
-
{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}
-
-

O método obsoleto escape() calcula uma nova string 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.

-
-
{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}
-
-

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

-
-
- -

{{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}

diff --git a/files/pt-br/web/javascript/guide/grammar_and_types/index.html b/files/pt-br/web/javascript/guide/grammar_and_types/index.html new file mode 100644 index 0000000000..7920ee6b1a --- /dev/null +++ b/files/pt-br/web/javascript/guide/grammar_and_types/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 +--- +

{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

+ +

Este capítulo trata sobre a sintaxe básica do JavaScript, declarações de variáveis, tipos de dados e literais.

+ +

Sintaxe básica

+ +

JavaScript pega emprestado a maior parte de sua sintaxe do Java, mas também é influenciado por Awk, Perl e Python.

+ +

JavaScript é case-sensitive e usa o conjunto de caracteres Unicode. Por exemplo, a palavra Früh (que significa "cedo" em Alemão) pode ser usada como nome de variável.

+ +
var Früh = "foobar";
+ +

Mas a variável früh não é a mesma que Früh porque JavaScript é case sensitive.

+ +

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 (ASI) 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 gramática léxica do JavaScript.

+ +

Comentários

+ +

A sintaxe dos comentários em JavaScript é semelhante como em C++ e em muitas outras linguagens:

+ +
// comentário de uma linha
+
+/* isto é um comentário longo
+   de múltiplas linhas.
+ */
+
+/* Você não pode, porém, /* aninhar comentários */ SyntaxError */
+ +

Declarações

+ +

Existem três tipos de declarações em JavaScript.

+ +
+
{{jsxref("Statements/var", "var")}}
+
Declara uma variável, opcionalmente, inicializando-a com um valor.
+
{{experimental_inline}} {{jsxref("Statements/let", "let")}}
+
Declara uma variável local de escopo do bloco, opcionalmente, inicializando-a com um valor.
+
{{experimental_inline}} {{jsxref("Statements/const", "const")}}
+
Declara uma constante de escopo de bloco, apenas de leitura.
+
+ +

Variáveis

+ +

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.

+ +

Um identificador JavaScript deve começar com uma letra, underline (_), ou cifrão ($); 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).

+ +

Você pode usar a ISO 8859-1 ou caracteres Unicode tal como os identificadores å e ü. Você pode também usar as sequências de escape Unicode como caracteres e identificadores.

+ +

Alguns exemplos de nomes legais são Numeros_visitas, temp99, e _nome.

+ +

Declarando variáveis

+ +

Você pode declarar uma variável de três formas:

+ + + +

Classificando variáveis

+ +

Uma variável declarada usando a declaração var ou let sem especificar o valor inicial tem o valor  {{jsxref("undefined")}}.

+ +

Uma tentativa de acessar uma variável não declarada resultará no lançamento de uma exceção {{jsxref("ReferenceError")}}:

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

Você pode usar undefined 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 if será avaliada como verdadeira (true).

+ +
var input;
+if(input === undefined){
+  facaIsto();
+} else {
+  facaAquilo();
+}
+
+ +

O valor undefined se comporta como falso (false), quando usado em um contexto booleano. Por exemplo, o código a seguir executa a função myFunction devido o elemento myArray ser undefined:

+ +
var myArray = [];
+if (!myArray[0]) myFunction();
+
+ +

O valor undefined converte-se para NaN quando usado no contexto numérico.

+ +
var a;
+a + 2;  // Avaliado como NaN
+
+ +

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:

+ +
var n = null;
+console.log(n * 32); // a saída para o console será 0.
+
+ +

Escopo de variável

+ +

Quando você declara uma váriavel fora de qualquer função, ela é chamada de variável global, 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 local,  pois ela está disponível somente dentro dessa função.

+ +

JavaScript antes do ECMAScript 6 não possuía escopo de declaração de bloco; pelo contrário, uma variável declarada dentro de um bloco de uma função é uma variável local (ou contexto global) do bloco que está inserido a função. Por exemplo o código a seguir exibirá 5, porque o escopo de x está na função (ou contexto global) no qual x é declarado, não o bloco, que neste caso é a declaração if

+ +
if (true) {
+  var x = 5;
+}
+console.log(x);  // 5
+
+ +

Esse comportamento é alterado, quando usado a declaração let introduzida pelo ECMAScript 6.

+ +
if (true) {
+  let y = 5;
+}
+console.log(y);  // ReferenceError: y não está definido
+
+ +

Variável de elevação

+ +

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 hoisting; 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 undefined. Então, mesmo se você usar ou referir a variável e depois declará-la e inicializá-la, ela ainda retornará undefined.

+ +
/**
+ * 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";
+})();
+
+ +

Os exemplos acima serão interpretados como:

+ +
/**
+ * 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";
+})();
+
+ +

Devido o hoisting, todas as declarações var 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.

+ +

Variáveis Globais

+ +

Variáveis globais são propriedades do objeto global. Em páginas web o objeto global é a {{domxref("window")}}, assim você pode configurar e acessar variáveis globais utilizando a sintaxe window.variavel. 

+ +

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 parent.phoneNumber.

+ +

Constantes

+ +

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.

+ +
const PI = 3.14;
+
+ +

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.

+ +

As regras de escopo para as constantes são as mesmas para as váriaveis let de escopo de bloco. Se a palavra-chave const for omitida, presume-se que o identificador represente uma variável.

+ +

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: 

+ +
// 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
+}
+
+ +

Estrutura de dados e tipos

+ +

Tipos de dados

+ +

O mais recente padrão ECMAScript define sete tipos de dados:

+ + + +

Embora esses tipos de dados sejam uma quantidade relativamente pequena, eles permitem realizar funções úteis em suas aplicações.  {{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.

+ +

Conversão de tipos de dados

+ +

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:

+ +
var answer = 42;
+
+ +

E depois, você pode atribuir uma string para a mesma variável, por exemplo:

+ +
answer = "Obrigado pelos peixes...";
+
+ +

Devido JavaScript ser dinamicamente tipado, essa declaração não gera uma mensagem de erro.

+ +

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:

+ +
x = "A resposta é " + 42 // "A resposta é 42"
+y = 42 + " é a resposta" // "42 é a resposta"
+
+ +

Nas declarações envolvendo outros operadores,  JavaScript não converte valores numérico para strings. Por exemplo:

+ +
"37" - 7 // 30
+"37" + 7 // "377"
+
+ +

Convertendo strings para números

+ +

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.

+ + + +

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.

+ +

Uma método alternativo de conversão de um número em forma de string é com o operador + (operador soma):

+ +
"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.
+ +

Literais

+ +

Você usa literais para representar valores em JavaScript. Estes são valores fixados, não variáveis, que você literalmente insere em seu script. Esta seção descreve os seguintes tipos literais:

+ + + +

Array literal

+ +

Um array literal é uma lista de zero ou mais expressões, onde cada uma delas representam um elemento do array, inseridas entre colchetes ([]). 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.

+ +

O exemplo a seguir cria um array coffees com três elementos e um comprimento de três:

+ +
var coffees = ["French Roast", "Colombian", "Kona"];
+
+ +
+

Nota : Um array literal é um tipo de inicializador de objetos. Veja Usando inicializadores de Objetos.

+
+ +

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.

+ +

Array literal são também um array de objetos. Veja  {{jsxref("Array")}} e Coleções indexadas para detalhes sobre array de objetos.

+ +

Vírgulas extras em array literal

+ +

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 undefined para os elementos não especificados. O exemplo a seguir cria um array chamado fish:

+ +
var fish = ["Lion", , "Angel"];
+
+ +

Esse array tem dois elementos com valores e um elemento vazio (fish[0] é "Lion", fish[1] é undefined, e fish[2] é "Angel" ).

+ +

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 myList[3]. Todas as outras vírgulas na lista indicam um novo elemento.

+ +
+

Nota : Vírgulas à direita podem criar erros em algumas versões de navegadores web antigos, é recomendável removê-las.

+
+ +
var myList = ['home', , 'school', ];
+
+ +

No exemplo a seguir, o comprimento do array é quatro, e myList[0] e myList[2] são undefined.

+ +
var myList = [ , 'home', , 'school'];
+
+ +

No exemplo a seguir, o comprimento do array é quatro, e myList[1] e myList[3] são undefined. Apenas a última vírgula é ignorada.

+ +
var myList = ['home', , 'school', , ];
+
+ +

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 undefined vai aumentar a clareza do código, e consequentemente na sua manutenção.

+ +

Literais Boolean

+ +

O tipo Boolean tem dois valores literal: true e false.

+ +

Não confunda os valores primitivos Boolean true e false com os valores true e false do objeto Boolean. O objeto Boolean é um invólucro em torno do tipo de dado primitivo. Veja {{jsxref("Boolean")}} para mais informação.

+ +

Inteiros

+ +

Inteiros podem ser expressos em decimal (base 10), hexadecimal (base 16), octal (base 8) e binário (base 2).

+ + + +

Alguns exemplos de inteiros literal são:

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

Para maiores informações, veja Literais numérico na referência Léxica.

+ +

Literais de ponto flutuante

+ +

Um literal de ponto flutuante pode ter as seguintes partes:

+ + + +

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").

+ +

Mais sucintamente, a sintaxe é:

+ +
[(+|-)][digitos][.digitos][(E|e)[(+|-)]digitos]
+
+ +

Por exemplo:

+ +
3.1415926
+-.123456789
+-3.1E+12
+.1e-23
+
+ +

Objeto literal

+ +

Um objeto literal é uma lista de zero ou mais pares de nomes de propriedades e valores associados de um objeto, colocado entre chaves ({}). 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 { será interpretado como início de um bloco.

+ +

Segue um exemplo de um objeto literal. O primeiro elemento do objeto carro define uma propriedade, meuCarro, e atribui para ele uma nova string, "Punto"; o segundo elemento, a propriedade getCarro, é imediatamente atribuído o resultado de chamar uma função (tipoCarro("Fiat")); o terceiro elemento, a propriedade especial, usa uma variável existente (vendas).

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

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.

+ +
var carro = { carros: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
+
+console.log(carro.carros.b); // Jeep
+console.log(carro[7]); // Mazda
+
+ +

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 (.), mas podem ser acessadas e definidas com a notação do tipo array ("[]").

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

Observe:

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

 

+ +

Expressão Regex Literal

+ +

Um regex literal é um padrão entre barras. A seguir um exemplo de regex literal.

+ +
var re = /ab+c/;
+ +

String Literal

+ +

Uma string literal são zero ou mais caracteres dispostos em aspas duplas (") ou aspas simples ('). 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.

+ +
"foo"
+'bar'
+"1234"
+"um linha \n outra linha"
+"John's cat"
+
+ +

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 String.length com uma string literal:

+ +
console.log("John's cat".length)
+// Irá exibir a quantidade de caracteres na string incluindo o espaço em branco.
+// Nesse caso, 10 caracteres.
+
+ +

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.

+ +

Uso de caracteres especiais em string

+ +

Além dos caracteres comuns, você também pode incluir caracteres especiais em strings, como mostrado no exemplo a seguir.

+ +
"uma linha \n outra linha"
+
+ +

A tabela a seguir lista os caracteres especiais que podem ser usados em strings no JavaScript.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Tabela: Caracteres especiais no JavaScript
CaracterDescrição
\0Byte nulo
\bBackspace
\fAlimentador de formulário
\nNova linha
\rRetorno do carro
\tTabulação
\vTabulação vertical
\'Apóstrofo ou aspas simples
\"Aspas dupla
\\Caractere de barra invertida
\XXX +

Caractere com a codificação Latin-1 especificada por três dígitos octal XXX entre 0 e 377. Por exemplo, \251 é sequência octal para o símbolo de direitos autorais.

+
\xXX +

Caractere com a codificação Latin-1 especificada por dois dígitos hexadecimal XX entre 00 e FF. Por exemplo, \xA9 é a sequência hexadecimal para o símbolo de direitos autorais.

+
\uXXXX +

Caractere Unicode especificado por quatro dígitos hexadecimal XXXX. Por exemplo, \u00A9 é a sequência Unicode para o símbolo de direitos autorais. Veja sequências de escape Unicode.

+
+ +

Caracteres de escape

+ +

Para caracteres não listados na tabela, se precedidos de barra invertida ela é ignorada, seu uso está absoleto e deve ser ignorado.

+ +

Você pode inserir uma aspa dentro de uma string precendendo-a com uma barra invertida. Isso  é conhecido como escaping das aspas. Por exemplo:

+ +
var quote = "Ele lê \"The Cremation of Sam McGee\" de R.W. Service.";
+console.log(quote);
+
+ +

O resultado disso seria:

+ +
Ele lê "The Cremation of Sam McGee" de R.W. Service.
+
+ +

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 c:\temp para uma string, utilize o seguinte:

+ +
var home = "c:\\temp";
+
+ +

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.

+ +
var str = "esta string \
+está quebrada \
+em várias\
+linhas."
+console.log(str);   // esta string está quebrada em várias linhas.
+
+ +

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:

+ +
var poema =
+"Rosas são vermelhas\n\
+Violetas são azuis,\n\
+Esse seu sorriso\n\
+é o que me seduz. (Lucas Pedrosa)"
+
+ +

Mais informação

+ +

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:

+ + + +

No próximo capítulo, veremos a construção de controle de fluxos e manipulação de erro.

+ +

{{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

diff --git a/files/pt-br/web/javascript/guide/igualdade/index.html b/files/pt-br/web/javascript/guide/igualdade/index.html deleted file mode 100644 index 57f1c2fdcc..0000000000 --- a/files/pt-br/web/javascript/guide/igualdade/index.html +++ /dev/null @@ -1,259 +0,0 @@ ---- -title: Igualdade em JavaScript -slug: Web/JavaScript/Guide/Igualdade -translation_of: Web/JavaScript/Equality_comparisons_and_sameness -translation_of_original: Web/JavaScript/Guide/Sameness ---- -

A ES6 possui três facilidades internas para determinar se algum x e algum y são "os mesmos". Elas são: igualdade ou "igual duplo" (==), igualdade rigorosa ou "igual triplo" (===), e Object.is. (Note que Object.is foi adicionado na ES6. Ambos igual duplo e igual triplo existiam antes da ES6, e seu comportamento permanece o mesmo.)

-

Visão geral

-

Para demonstração, aqui estão as três comparações de igualdade em uso:

-
x == y
-
x === y
-
Object.is(x, y)
-

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 false se os tipos forem diferentes); e Object.is se comportará da mesma forma que o operador igual triplo, mas lidando de forma especial com NaN e -0 e +0 de modo que os dois últimos não são considerados os mesmos, enquanto que Object.is(NaN, NaN) será true. (Comparar NaN com NaN geralmente—i.e., usando-se o operador igual duplo ou o operador igual triplo—resulta em false, de acordo com a IEEE 754.)

-

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 x e y que têm a mesma estrutura mas que são objetos distintos, todas as formas de comparação acima resultarão no valor false.

-

Por exemplo:

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

Igualdade abstrata, igualdade rigorosa, e mesmo valor

-

Na ES5, a comparação realizada por == é descrita na Seção 11.9.3, O Algoritmo de Igualdade Abstrata. A comparação === é descrita em 11.9.6, O Algoritmo de Igualdade Rigorosa. (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 Seção 9.12, O Algoritmo de MesmoValor 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 Numbers (números). A ES6 simplesmente propõe expôr esse algoritmo através de Object.is.

-

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.

-

Um modelo para entender comparações de igualdade?

-

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 6 == "6"). 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.

-

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 Object.is da ES6 nesse "espectro". O Object.is 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 Object.is lida com NaN. Perceba que se Object.is(NaN, NaN) resultasse no valor false, nós poderíamos 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 -0 e +0. A forma de lidar com NaN significa que isso não é verdade, no entanto. Infelizmente, Object.is 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.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Comparações de Igualdade
xy=====Object.is
undefinedundefinedtruetruetrue
nullnulltruetruetrue
truetruetruetruetrue
falsefalsetruetruetrue
"foo""foo"truetruetrue
{ foo: "bar" }xtruetruetrue
00truetruetrue
+0-0truetruefalse
0falsetruefalsefalse
""falsetruefalsefalse
""0truefalsefalse
"0"0truefalsefalse
"17"17truefalsefalse
new String("foo")"foo"truefalsefalse
nullundefinedtruefalsefalse
nullfalsefalsefalsefalse
undefinedfalsefalsefalsefalse
{ foo: "bar" }{ foo: "bar" }falsefalsefalse
new String("foo")new String("foo")falsefalsefalse
0nullfalsefalsefalse
0NaNfalsefalsefalse
"foo"NaNfalsefalsefalse
NaNNaNfalsefalsetrue
-

Quando usar Object.is versus o operador igual triplo

-

Além da forma com que trata o valor it NaN, de modo geral, o único caso em o comportamento especial de Object.is 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 Object.defineProperty. Se seu caso de uso não requer isso, sugere-se evitar-se Object.is e usar-se o operador === ao invés disso. Mesmo se seus requerimentos envolvem que comparações entre dois valores NaN resultem em true, de modo geral é mais fácil fazer-se uma checagem especial por NaNs (usando-se o método isNaN 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.

-

Aqui está uma lista não-exaustiva de métodos e operadores internos que podem fazer com que uma distinção entre -0 e +0 se manifeste em seu código:

-
-
- - (negação unária)
-
-
-
-

É óbvio que negar 0 produz -0. Mas a abstração de uma expressão pode fazer com o valor -0 apareça de modo despercebido. Por exemplo, considere o seguinte:

-
let stoppingForce = obj.mass * -obj.velocity
-

Se obj.velocity é 0 (ou resulta no valor 0), um -0 é introduzido naquele ponto e propaga-se para stoppingForce.

-
-
-
-
- Math.atan2
-
- Math.ceil
-
- Math.pow
-
- Math.round
-
-
-
- É possível que um -0 seja introduzido em uma expressão como um valor de retorno desses métodos em alguns casos, mesmo quando nenhum -0 existe como um dos parâmetros. Por exemplo, usando-se Math.pow para elevar o valor -Infinity à potência de qualquer expoente negativo ímpar resulta no valor -0. Veja a documentação para os métodos individuais.
-
-
-
- Math.floor
-
- Math.max
-
- Math.min
-
- Math.sin
-
- Math.sqrt
-
- Math.tan
-
-
-
- É possível obter-se um valor de retorno -0 desses métodos em alguns casos quando um -0 existe como um dos parâmetros. Por exemplo, Math.min(-0, +0) resulta no valor -0. Veja a documentação para os métodos individuais.
-
-
-
- ~
-
- <<
-
- >>
-
- 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 -0 não irá sobreviver a um arredondamento depois de uma operação inversa. Por exemplo, ambos Object.is(~~(-0), -0) e Object.is(-0 << 2 >> 2, -0) resultam no valor false.
-
-

Contar com Object.is quando o sinal de zeros não é levado em consideração pode ser problemático. É claro que quando a intenção é distinguir entre -0 e +0, ele faz exatamente o que é desejado.gual

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 deleted file mode 100644 index d6aad53066..0000000000 --- a/files/pt-br/web/javascript/guide/inheritance_and_the_prototype_chain/index.html +++ /dev/null @@ -1,193 +0,0 @@ ---- -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 ---- -
{{jsSidebar("Advanced")}}
- -

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 class (a palavra-chave class foi introduzida no ES2015, mas é syntax sugar, o JavaScript permanece baseado em prototype).

- -

Quando se trata de herança, o JavaScript tem somente um construtor: objetos. Cada objeto tem um link interno para um outro objeto chamado prototype. Esse objeto prototype também tem um atributo prototype, e assim por diante até o que o valor null seja encontrado como sendo o seu prototype. null que, por definição, não tem prototype, e age como um link final nesta cadeia de protótipos (prototype chain).

- -

Isto muitas vezes é considerado como um dos pontos fracos do JavaScript, mas o modelo de herança prototipal é de fato mais potente do que o modelo clássico. É, por exemplo, relativamente trivial construir um "modelo clássico" (como na implementaçao de class), enquanto o contrário é uma tarefa muito mais difícil.

- -

N. da T: Como em uma implementação de fila em C, por exemplo.

- -

Herança com o encadeamento de protótipos

- -

Propriedades de heranças

- -

Objetos em JavaScript são "sacos" dinâmicos de propriedades (a que se refere as próprias propriedades) e cada um tem um link para um objeto prototype. Eis o que acontece quando se tenta acessar uma propriedade:

- -
// Vamos criar um objeto o da função f com suas próprias propriedades a e b:
-let f = function () {
-   this.a = 1;
-   this.b = 2;
-}
-let o = new f(); // {a: 1, b: 2}
-
-// adicionar propriedades no protótipo da função f
-f.prototype.b = 3;
-f.prototype.c = 4;
-
-// 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
-
-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 Link

- -

Atribuir uma propriedade a um objeto cria uma propriedade nele. A única exceção às regras de obtenção e definição de comportamento é quando há uma propriedade herdada com um getter or a setter.

- -

Herença de "métodos"

- -

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(method overriding)!

- -

Quando uma herança de função é executada, o valor de this aponta para o objeto que herdou as propriedades, não para o objeto prototype onde as propriedades foram escritas originalmente.

- -
var o = {
-  a: 2,
-  m: function(b){
-    return this.a + 1;
-  }
-};
-
-console.log(o.m()); // 3
-// Ao chamar 'o.m' neste caso, "this" refere-se a 'o'
-
-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'
-// Então, quando 'p' herda a função de 'm' de 'o', 'this.a' representa 'p.a' que é a própria propriedade 'a' de 'p'
-
-
- -

Maneiras de criar objetos e resultados dos protótipos encadeados

- -

Objetos criados com sintaxe de construtores

- -
var o = {a: 1};
-
-// O recém-criado objecto 'o' tem Object.prototype como o seu [[Prototype]]
-// 'o' não tem não tem uma propriedade chamada 'hasOwnProperty'
-// hasOwnProperty é uma propriedade própria de Object.prototype. Então 'o' herda hasOwnProperty de Object.prototype
-
-// Object.prototype tem null como seu protótipo.
-// o ---> Object.prototype ---> null
-
-var a = ["yo", "whadup", "?"];
-
-// Arrays herdam de Array.prototype (que tem métodos como indexOf, forEach, etc.)
-// A cadeia de protótipos se parece com isso:
-// a ---> Array.prototype ---> Object.prototype ---> null
-
-function f(){
-  return 2;
-}
-
-// Funções herdam de Function.prototype (que tem métodos como call, bind, etc.)
-// f ---> Function.prototype ---> Object.prototype ---> null
-
- -

Com um construtor

- -

Um "construtor" em JavaScript é "somente" uma função que passa a ser chamada com o operador new.

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

Com Object.create

- -

ECMAScript 5 introduziu o novo método: Object.create. Invocando este método podemos criar novos objetos. O prototype destes novos objetos é o primeiro argumento do método:

- -
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, porque não herda de Object.prototype
-
- -
-

Performace

- -

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

- -

Porém, quando estamos interagindo com as propriedades de um objeto, toda propriedade que está na cadeia do prototype (prototype chain) vai ser enumerada.

- -

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 hasOwnProperty que todos os objetos herdam do Object.prototype.

- -

hasOwnProperty é a única alternativa em JavaScript que lida com propriedades sem atravessar a cadeia de protótipos.

- - -
Observação: Não é suficiente apenas verificar se o valor da propriedade é undefined para saber se ela existe. A propriedade pode muito bem existir e não ter sido inicializada, sendo assim o seu valor undefined.
- -
-

Má Pratica: Estender protótipos nativos

- -

Um erro frequentemente cometido por programadores é estender um Object.prototype.

- -

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. 

- -

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.

-
- -
-

Conclusão

- -

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

- - -
-
- -

{{ languages( {"zh-cn": "zh-cn/JavaScript/Guide/Inheritance_and_the_prototype_chain" } ) }}

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 deleted file mode 100644 index 13a9b87f11..0000000000 --- a/files/pt-br/web/javascript/guide/iteratores_e_geradores/index.html +++ /dev/null @@ -1,161 +0,0 @@ ---- -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 ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}
- -

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")}}.

- -

Para detalhes, também veja:

- - - -

Iterators (Iteradores)

- -

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

- -

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

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

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

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

Iterables (Iteráveis)

- -

Um objeto é iterável (iterable), se ele define seu comportamento de iteração, como no caso de quais valores percorridos em um laço do tipo {{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.

- -

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

- -

Iterables definidos pelo usuário

- -

Nós podemos fazer, criar, os nossos próprios iteráveis como aqui:

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

Iterables Built-in (Iteráveis Embutidos)

- -

{{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")}}.

- -

Syntaxes expecting iterables

- -

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")}}.

- -
for(let value of ["a", "b", "c"]){
-    console.log(value)
-}
-// "a"
-// "b"
-// "c"
-
-[..."abc"] // ["a", "b", "c"]
-
-function* gen(){
-  yield* ["a", "b", "c"]
-}
-
-gen().next() // { value:"a", done:false }
-
-[a, b, c] = new Set(["a", "b", "c"])
-a // "a"
-
-
- -

Generators

- -

Enquanto os iteradores são ferramentas muito úteis, sua criação requer um cuidado devido a necessidade de manter explicito seu estado interno. {{jsxref("Global_Objects/Generator","Generators","","true")}} provê uma alternativa poderosa: eles te permitem definir um algorítimo iterativo escrevendo uma função simples que pode manter seu estado próprio.

- -

Generator é um tipo especial de função que trabalha como uma factory para iteradores. A função vira um generator se ela contém uma ou mais expressões {{jsxref("Operators/yield","yield")}} e se ela usa a sintaxe {{jsxref("Statements/function*","function*")}}.

- -
function* idMaker(){
-  var index = 0;
-  while(true)
-    yield index++;
-}
-
-var gen = idMaker();
-
-console.log(gen.next().value); // 0
-console.log(gen.next().value); // 1
-console.log(gen.next().value); // 2
-// ...
- -

Generators avançados

- -

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

- -

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 next() será tratado como o resultado da última expressão yield que pausou o generator.

- -

Aqui um gerador de sequencia fibonacci usando next(x) pra restartar a sequencia:

- -
function* fibonacci(){
-  var fn1 = 1;
-  var fn2 = 1;
-  while (true){
-    var current = fn2;
-    fn2 = fn1;
-    fn1 = fn1 + current;
-    var reset = yield current;
-    if (reset){
-        fn1 = 1;
-        fn2 = 1;
-    }
-  }
-}
-
-var sequence = fibonacci();
-console.log(sequence.next().value);     // 1
-console.log(sequence.next().value);     // 1
-console.log(sequence.next().value);     // 2
-console.log(sequence.next().value);     // 3
-console.log(sequence.next().value);     // 5
-console.log(sequence.next().value);     // 8
-console.log(sequence.next().value);     // 13
-console.log(sequence.next(true).value); // 1
-console.log(sequence.next().value);     // 1
-console.log(sequence.next().value);     // 2
-console.log(sequence.next().value);     // 3
- -
Nota: Como um ponto de interesse, chamando next(undefined) é o mesmo que chamar next(). Entretanto, estartar um novo generator com qualquer valor que não seja undefined na chamada next() terá TypeError exception.
- -

Você pode forçar um generator a lançar uma exceção chamando o seu método {{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 yield atualmente suspenso fosse um throw.

- -

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

- -

Generators tem o método {{jsxref("Global_Objects/Generator/return","return(value)")}} que retorna o valor pego e finaliza o generator.

- -

{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}

diff --git a/files/pt-br/web/javascript/guide/iterators_and_generators/index.html b/files/pt-br/web/javascript/guide/iterators_and_generators/index.html new file mode 100644 index 0000000000..13a9b87f11 --- /dev/null +++ b/files/pt-br/web/javascript/guide/iterators_and_generators/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 +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}
+ +

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")}}.

+ +

Para detalhes, também veja:

+ + + +

Iterators (Iteradores)

+ +

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

+ +

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

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

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

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

Iterables (Iteráveis)

+ +

Um objeto é iterável (iterable), se ele define seu comportamento de iteração, como no caso de quais valores percorridos em um laço do tipo {{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.

+ +

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

+ +

Iterables definidos pelo usuário

+ +

Nós podemos fazer, criar, os nossos próprios iteráveis como aqui:

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

Iterables Built-in (Iteráveis Embutidos)

+ +

{{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")}}.

+ +

Syntaxes expecting iterables

+ +

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")}}.

+ +
for(let value of ["a", "b", "c"]){
+    console.log(value)
+}
+// "a"
+// "b"
+// "c"
+
+[..."abc"] // ["a", "b", "c"]
+
+function* gen(){
+  yield* ["a", "b", "c"]
+}
+
+gen().next() // { value:"a", done:false }
+
+[a, b, c] = new Set(["a", "b", "c"])
+a // "a"
+
+
+ +

Generators

+ +

Enquanto os iteradores são ferramentas muito úteis, sua criação requer um cuidado devido a necessidade de manter explicito seu estado interno. {{jsxref("Global_Objects/Generator","Generators","","true")}} provê uma alternativa poderosa: eles te permitem definir um algorítimo iterativo escrevendo uma função simples que pode manter seu estado próprio.

+ +

Generator é um tipo especial de função que trabalha como uma factory para iteradores. A função vira um generator se ela contém uma ou mais expressões {{jsxref("Operators/yield","yield")}} e se ela usa a sintaxe {{jsxref("Statements/function*","function*")}}.

+ +
function* idMaker(){
+  var index = 0;
+  while(true)
+    yield index++;
+}
+
+var gen = idMaker();
+
+console.log(gen.next().value); // 0
+console.log(gen.next().value); // 1
+console.log(gen.next().value); // 2
+// ...
+ +

Generators avançados

+ +

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

+ +

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 next() será tratado como o resultado da última expressão yield que pausou o generator.

+ +

Aqui um gerador de sequencia fibonacci usando next(x) pra restartar a sequencia:

+ +
function* fibonacci(){
+  var fn1 = 1;
+  var fn2 = 1;
+  while (true){
+    var current = fn2;
+    fn2 = fn1;
+    fn1 = fn1 + current;
+    var reset = yield current;
+    if (reset){
+        fn1 = 1;
+        fn2 = 1;
+    }
+  }
+}
+
+var sequence = fibonacci();
+console.log(sequence.next().value);     // 1
+console.log(sequence.next().value);     // 1
+console.log(sequence.next().value);     // 2
+console.log(sequence.next().value);     // 3
+console.log(sequence.next().value);     // 5
+console.log(sequence.next().value);     // 8
+console.log(sequence.next().value);     // 13
+console.log(sequence.next(true).value); // 1
+console.log(sequence.next().value);     // 1
+console.log(sequence.next().value);     // 2
+console.log(sequence.next().value);     // 3
+ +
Nota: Como um ponto de interesse, chamando next(undefined) é o mesmo que chamar next(). Entretanto, estartar um novo generator com qualquer valor que não seja undefined na chamada next() terá TypeError exception.
+ +

Você pode forçar um generator a lançar uma exceção chamando o seu método {{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 yield atualmente suspenso fosse um throw.

+ +

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

+ +

Generators tem o método {{jsxref("Global_Objects/Generator/return","return(value)")}} que retorna o valor pego e finaliza o generator.

+ +

{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}

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 deleted file mode 100644 index fcf7437612..0000000000 --- a/files/pt-br/web/javascript/guide/lacos_e_iteracoes/index.html +++ /dev/null @@ -1,333 +0,0 @@ ---- -title: Laços e iterações -slug: Web/JavaScript/Guide/Lacos_e_iteracoes -translation_of: Web/JavaScript/Guide/Loops_and_iteration ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}
- -
-

Laços oferecem um jeito fácil e rápido de executar uma ação repetidas vezes. Este capítulo do guia do JavaScript abordará diferentes formas de iterações existentes no JavaScript.

-
- -

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:

- -
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');
-}
-
- -

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.

- -

Os possíveis laços de repetição  em JavaScript:

- - - -

Declaração for

- -

Um laço for é 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:

- -
for ([expressaoInicial]; [condicao]; [incremento])
-  declaracao
-
- -

Quando um for é executado, ocorre o seguinte:

- -
    -
  1. A expressão expressao Inicial é 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.
  2. -
  3. A expressão condicao é avaliada. caso o resultado de condicao seja verdadeiro, o laço é executado. Se o valor de condicao é falso, então o laço terminará. Se a expressão condicao é omitida, a condicao é assumida como verdadeira.
  4. -
  5.  A instrução é executada. Para executar múltiplas declarações, use uma declaração em bloco ({ ... }) para agrupá-las.
  6. -
  7. A atualização da expressão incremento, se houver, executa, e retorna o controle para o passo 2.
  8. -
- -

Exemplo

- -

A função a seguir contém uma declaração for que contará o número de opções selecionadas em uma lista (um elemento {{HTMLElement("select")}} permite várias seleções). Dentro do for é declarado uma váriavel i inicializada com zero. A declaração for verifica se i é menor que o número de opções no elemento <select>, executa sucessivas declaração  if, e incrementa i de um em um a cada passagem pelo laço.

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

Declaração do...while

- -

A instrução do...while repetirá até que a condição especificada seja falsa.

- -
do
-  declaracao
-while (condicao);
-
- -

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 condicao seja verdadeira, então o laço será executado novamente. Ao final de cada execução, a condicao é 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 do...while.

- -

Exemplo

- -

No exemplo a seguir, o laço é executado pelo menos uma vez e irá executar até que i seja menor que 5.

- -
do {
-  i += 1;
-  console.log(i);
-} while (i < 5);
- -

Declaração while

- -

Uma declaração while executa suas instruções, desde que uma condição especificada seja avaliada como verdadeira. Segue uma declaração while

- -
while (condicao)
-  declaracao
-
- -

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.

- -

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.

- -

Para executar múltiplas declarações, use uma declaração em bloco ({ ... }) para agrupar essas declarações.

- -

Exemplo 1

- -

O while a seguir executará enquanto n for menor que três:

- -
n = 0;
-x = 0;
-while (n < 3) {
-  n++;
-  x += n;
-}
-
- -

A cada iteração, o laço incrementa n e adiciona este valor para x. Portanto, x e n recebem os seguintes valores:

- - - -

Depois de executar pela terceira vez, a condição n < 3 não será mais verdadeira, então o laço encerrará.

- -

Exemplo 2

- -

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:

- -
while (true) {
-  console.log("Olá, mundo");
-}
- -

Declaração label

- -

Um label 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 break ou continue para indicar quando o programa deverá interromper o laço ou continuar sua execução.

- -

Segue a sintaxe da instrução label:

- -
label : declaracao
-
- -

Um label pode usar qualquer idenficador que não seja uma palavra reservada do JavaScript. Você pode identificar qualquer instrução com um label.

- -

Exemplo

- -

Neste exemplo, o label markLoop idenfica um laço while.

- -
markLoop:
-while (theMark == true) {
-   facaAlgo();
-}
- -

Declaração break

- -

Use break para terminar laços, switch, ou um conjunto que utiliza label.

- - - -

Segue a sintaxe do break:

- -
    -
  1. break;
  2. -
  3. break label;
  4. -
- -

Na primeira opção será encerrado o laço de repetição mais interno ou switch. Já na segunda opção será encerrada o bloco de código referente a label.

- -

Exemplo 1

- -

O exemplo a seguir percorre os elementos de um array até que ele encontre o índice do elemento que possui o valor contido em theValue:

- -
for (i = 0; i < a.length; i++) {
-  if (a[i] == theValue) {
-    break;
-  }
-}
- -

Exemplo 2: Utilizando break em label

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

Declaração continue

- -

A declaração continue pode ser usada para reiniciar uma instrução while, do-while, for, ou label.

- - - -

Segue a sintaxe do continue:

- -
    -
  1. continue;
  2. -
  3. continue label;
  4. -
- -

Exemplo 1

- -

O exemplo a seguir mostra um laço while utlizando continue que executará quando o valor de i for igual a 3. Desta forma, n recebe os valores um, três, sete, e doze.

- -
i = 0;
-n = 0;
-while (i < 5) {
-  i++;
-  if (i == 3) {
-    continue;
-  }
-  n += i;
-}
-
- -

Exemplo 2

- -

Uma instrução label checkiandj contém uma instrução label checkj. Se o continue for executado, o programa terminará a iteração atual de checkj e começará a próxima iteração. Toda vez que o continue for executado, checkj recomeçará até que a condição do while for falsa. Quando isto ocorrer checkiandj executará até que sua condição seja falsa.

- -

Se o continue estivesse referenciando checkiandj, o programa deveria continuar do topo de checkiandj.

- -
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);
-  }
- -

Declaração for...in

- -

A declaração for...in executa iterações a partir de uma variável específica, percorrendo todas as propriedades de um objeto.
- Para cada propriedade distinta, o JavaScript executará uma iteração. Segue a sintaxe:

- -
for (variavel in objeto) {
-  declaracoes
-}
-
- -

Exemplo

- -

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.

- -
function dump_props(obj, obj_name) {
-  var result = "";
-  for (var i in obj) {
-    result += obj_name + "." + i + " = " + obj[i] + "<br>";
-  }
-  result += "<hr>";
-  return result;
-}
-
- -

Para um objeto chamado car com propriedades make e model, o resultado será:

- -
car.make = Ford
-car.model = Mustang
-
- -

Arrays

- -

Embora seja tentador usar esta forma para interagir com os elementos de um Array, a declaração for...in irá retornar o nome pré-definido da propriedade ao invés do seu index numérico. Assim é melhor usar o tradicional for com index numérico quando interagir com arrays, pois o for...in interage com as propriedades definidas pelo programador ao invés dos elementos do array.

- -

Declaração for...of

- -

 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.

- -
for (variavel of objeto) {
-  declaracoes
-}
- -

O exemplo a seguir mostra a diferença entre o for...of e o for...in. Enquanto o for...in interage com o nome das propriedades, o for...of interage com o valor das propriedades.

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

{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}

diff --git a/files/pt-br/web/javascript/guide/loops_and_iteration/index.html b/files/pt-br/web/javascript/guide/loops_and_iteration/index.html new file mode 100644 index 0000000000..fcf7437612 --- /dev/null +++ b/files/pt-br/web/javascript/guide/loops_and_iteration/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 +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}
+ +
+

Laços oferecem um jeito fácil e rápido de executar uma ação repetidas vezes. Este capítulo do guia do JavaScript abordará diferentes formas de iterações existentes no JavaScript.

+
+ +

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:

+ +
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');
+}
+
+ +

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.

+ +

Os possíveis laços de repetição  em JavaScript:

+ + + +

Declaração for

+ +

Um laço for é 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:

+ +
for ([expressaoInicial]; [condicao]; [incremento])
+  declaracao
+
+ +

Quando um for é executado, ocorre o seguinte:

+ +
    +
  1. A expressão expressao Inicial é 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.
  2. +
  3. A expressão condicao é avaliada. caso o resultado de condicao seja verdadeiro, o laço é executado. Se o valor de condicao é falso, então o laço terminará. Se a expressão condicao é omitida, a condicao é assumida como verdadeira.
  4. +
  5.  A instrução é executada. Para executar múltiplas declarações, use uma declaração em bloco ({ ... }) para agrupá-las.
  6. +
  7. A atualização da expressão incremento, se houver, executa, e retorna o controle para o passo 2.
  8. +
+ +

Exemplo

+ +

A função a seguir contém uma declaração for que contará o número de opções selecionadas em uma lista (um elemento {{HTMLElement("select")}} permite várias seleções). Dentro do for é declarado uma váriavel i inicializada com zero. A declaração for verifica se i é menor que o número de opções no elemento <select>, executa sucessivas declaração  if, e incrementa i de um em um a cada passagem pelo laço.

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

Declaração do...while

+ +

A instrução do...while repetirá até que a condição especificada seja falsa.

+ +
do
+  declaracao
+while (condicao);
+
+ +

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 condicao seja verdadeira, então o laço será executado novamente. Ao final de cada execução, a condicao é 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 do...while.

+ +

Exemplo

+ +

No exemplo a seguir, o laço é executado pelo menos uma vez e irá executar até que i seja menor que 5.

+ +
do {
+  i += 1;
+  console.log(i);
+} while (i < 5);
+ +

Declaração while

+ +

Uma declaração while executa suas instruções, desde que uma condição especificada seja avaliada como verdadeira. Segue uma declaração while

+ +
while (condicao)
+  declaracao
+
+ +

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.

+ +

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.

+ +

Para executar múltiplas declarações, use uma declaração em bloco ({ ... }) para agrupar essas declarações.

+ +

Exemplo 1

+ +

O while a seguir executará enquanto n for menor que três:

+ +
n = 0;
+x = 0;
+while (n < 3) {
+  n++;
+  x += n;
+}
+
+ +

A cada iteração, o laço incrementa n e adiciona este valor para x. Portanto, x e n recebem os seguintes valores:

+ + + +

Depois de executar pela terceira vez, a condição n < 3 não será mais verdadeira, então o laço encerrará.

+ +

Exemplo 2

+ +

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:

+ +
while (true) {
+  console.log("Olá, mundo");
+}
+ +

Declaração label

+ +

Um label 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 break ou continue para indicar quando o programa deverá interromper o laço ou continuar sua execução.

+ +

Segue a sintaxe da instrução label:

+ +
label : declaracao
+
+ +

Um label pode usar qualquer idenficador que não seja uma palavra reservada do JavaScript. Você pode identificar qualquer instrução com um label.

+ +

Exemplo

+ +

Neste exemplo, o label markLoop idenfica um laço while.

+ +
markLoop:
+while (theMark == true) {
+   facaAlgo();
+}
+ +

Declaração break

+ +

Use break para terminar laços, switch, ou um conjunto que utiliza label.

+ + + +

Segue a sintaxe do break:

+ +
    +
  1. break;
  2. +
  3. break label;
  4. +
+ +

Na primeira opção será encerrado o laço de repetição mais interno ou switch. Já na segunda opção será encerrada o bloco de código referente a label.

+ +

Exemplo 1

+ +

O exemplo a seguir percorre os elementos de um array até que ele encontre o índice do elemento que possui o valor contido em theValue:

+ +
for (i = 0; i < a.length; i++) {
+  if (a[i] == theValue) {
+    break;
+  }
+}
+ +

Exemplo 2: Utilizando break em label

+ +
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;
+    }
+  }
+}
+
+ +

Declaração continue

+ +

A declaração continue pode ser usada para reiniciar uma instrução while, do-while, for, ou label.

+ + + +

Segue a sintaxe do continue:

+ +
    +
  1. continue;
  2. +
  3. continue label;
  4. +
+ +

Exemplo 1

+ +

O exemplo a seguir mostra um laço while utlizando continue que executará quando o valor de i for igual a 3. Desta forma, n recebe os valores um, três, sete, e doze.

+ +
i = 0;
+n = 0;
+while (i < 5) {
+  i++;
+  if (i == 3) {
+    continue;
+  }
+  n += i;
+}
+
+ +

Exemplo 2

+ +

Uma instrução label checkiandj contém uma instrução label checkj. Se o continue for executado, o programa terminará a iteração atual de checkj e começará a próxima iteração. Toda vez que o continue for executado, checkj recomeçará até que a condição do while for falsa. Quando isto ocorrer checkiandj executará até que sua condição seja falsa.

+ +

Se o continue estivesse referenciando checkiandj, o programa deveria continuar do topo de checkiandj.

+ +
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);
+  }
+ +

Declaração for...in

+ +

A declaração for...in executa iterações a partir de uma variável específica, percorrendo todas as propriedades de um objeto.
+ Para cada propriedade distinta, o JavaScript executará uma iteração. Segue a sintaxe:

+ +
for (variavel in objeto) {
+  declaracoes
+}
+
+ +

Exemplo

+ +

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.

+ +
function dump_props(obj, obj_name) {
+  var result = "";
+  for (var i in obj) {
+    result += obj_name + "." + i + " = " + obj[i] + "<br>";
+  }
+  result += "<hr>";
+  return result;
+}
+
+ +

Para um objeto chamado car com propriedades make e model, o resultado será:

+ +
car.make = Ford
+car.model = Mustang
+
+ +

Arrays

+ +

Embora seja tentador usar esta forma para interagir com os elementos de um Array, a declaração for...in irá retornar o nome pré-definido da propriedade ao invés do seu index numérico. Assim é melhor usar o tradicional for com index numérico quando interagir com arrays, pois o for...in interage com as propriedades definidas pelo programador ao invés dos elementos do array.

+ +

Declaração for...of

+ +

 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.

+ +
for (variavel of objeto) {
+  declaracoes
+}
+ +

O exemplo a seguir mostra a diferença entre o for...of e o for...in. Enquanto o for...in interage com o nome das propriedades, o for...of interage com o valor das propriedades.

+ +
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"
+}
+
+ +

{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}

diff --git a/files/pt-br/web/javascript/guide/modules/index.html b/files/pt-br/web/javascript/guide/modules/index.html new file mode 100644 index 0000000000..6a2cb73687 --- /dev/null +++ b/files/pt-br/web/javascript/guide/modules/index.html @@ -0,0 +1,454 @@ +--- +title: Módulos JavaScript +slug: Web/JavaScript/Guide/Módulos +translation_of: Web/JavaScript/Guide/Modules +--- +
{{JSSidebar("JavaScript Guide")}}{{Previous("Web/JavaScript/Guide/Meta_programming")}}
+ +

Este guia fornece tudo o que você precisa para começar com a sintaxe de módulo do JavaScript.

+ +

Um background em módulos

+ +

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 (Node.js, por exemplo).

+ +

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 CommonJS e AMD-sistemas de módulos baseados em RequireJS, e mais recentemente Webpack e Babel).

+ +

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.

+ +

Suporte do navegador

+ +

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:

+ +

importa

+ +

{{Compat("javascript.statements.import")}}

+ +

exporta

+ +

{{Compat("javascript.statements.export")}}

+ +

Apresentando um exemplo

+ +

Para demonstrar o uso dos módulos, criamos um conjunto simples de exemplos que você pode encontrar no GitHub. Estes exemplos demonstram um conjunto simples de módulos que criam um<canvas> em uma página da Web e desenhe (e relate informações sobre) formas diferentes na tela.

+ +

Estes são bastante triviais, mas foram mantidos deliberadamente simples para demonstrar claramente os módulos.

+ +
+

Nota: Se você deseja fazer o download dos exemplos e executá-los localmente, precisará executá-los por meio de um servidor da web local.

+
+ +

Exemplo de uma estrutura básica

+ +

No nosso primeiro exemplo (consulte basic-modules) nós temos uma estrutura de arquivos da seguinte maneira:

+ +
index.html
+main.js
+modules/
+    canvas.js
+    square.js
+ +
+

Nota: Todos os exemplos neste guia têm basicamente a mesma estrutura; o exposto acima deve começar a ficar bem familiar.

+
+ +

Os dois módulos do diretório modules são descritos abaixo:

+ + + +

Aside — .mjs versus .js

+ +

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 documentação da V8 recomenda isso, por exemplo. Os motivos apresentados são:

+ + + +

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 GitHub Pages e http-server para Node.js.

+ +

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 Content-Type para arquivos .mjs). 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.

+ +

Para fins de aprendizado e portabilidade, decidimos manter o.js.

+ +

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.

+ +

Também é importante notar que:

+ + + +

Exportando recursos do módulo

+ +

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.

+ +

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:

+ +
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
+  };
+}
+ +

Você pode exportar funções, var, let, const, 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.

+ +

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:

+ +
export { name, draw, reportArea, reportPerimeter };
+ +

Importando recursos para o seu script

+ +

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:

+ +
import { name, draw, reportArea, reportPerimeter } from './modules/square.js';
+ +

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 basic-modules exemplo seria/js-examples/modules/basic-modules.

+ +

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.

+ +

Então, por exemplo:

+ +
/js-examples/modules/basic-modules/modules/square.js
+ +

torna-se

+ +
./modules/square.js
+ +

Você pode ver essas linhas em ação em main.js.

+ +
+

Nota: Em alguns sistemas de módulos, você pode omitir a extensão do arquivo e o ponto(e.g. '/modules/square'). Isso não funciona nos módulos JavaScript nativos.

+
+ +

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
+ main.js, abaixo das linhas de importação:

+ +
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);
+
+ +
+

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.

+
+ +

Aplicando o módulo ao seu HTML

+ +

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.

+ +

Primeiro de tudo, você precisa incluir type="module" no <script> elemento, para declarar esse script como um módulo. Para importar o main.js script, usamos este:

+ +
<script type="module" src="main.js"></script>
+ +

Você também pode incorporar o script do módulo diretamente no arquivo HTML, colocando o código JavaScript no corpo do elemento <script>:

+ +
<script type="module">
+  /* JavaScript module code here */
+</script>
+ +

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

+ +

Você só pode usar import e export instruções dentro de módulos, não scripts regulares.

+ +

Outras diferenças entre módulos e scripts padrão

+ + + +

Exportações padrão versus exportações nomeadas

+ +

A funcionalidade que exportamos até agora foi composta por named exports — 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.

+ +

Há também um tipo de exportação chamado default export — 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 ES6 In Depth: Modules por Jason Orendorff; procure por "Exportações padrão").

+ +

Vejamos um exemplo ao explicar como ele funciona. Nos nossos módulos básicos square.js você pode encontrar uma função chamada randomSquare() 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:

+ +
export default randomSquare;
+ +

Note a falta dos colchetes.

+ +

Em vez disso, poderíamos acrescentar export default na função e defina-a como uma função anônima, assim:

+ +
export default function(ctx) {
+  ...
+}
+ +

No nosso arquivo main.js., importamos a função padrão usando esta linha:

+ +
import randomSquare from './modules/square.js';
+ +

Isso ocorre porque há apenas uma exportação padrão permitida por módulo e sabemos que randomSquare é isso.

+ +
import {default as randomSquare} from './modules/square.js';
+ +
+

Nota: A sintaxe as para renomear itens exportados é explicada abaixo no Renaming imports and exports seção.

+
+ +

Evitando conflitos de nomenclatura

+ +

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 draw(), reportArea(), 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.

+ +

Felizmente, existem várias maneiras de contornar isso. Veremos isso nas próximas seções.

+ +

Renomeando importações e exportações

+ +

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.

+ +

Por exemplo, os dois itens a seguir executariam o mesmo trabalho, embora de uma maneira ligeiramente diferente:

+ +
// inside module.js
+export {
+  function1 as newFunctionName,
+  function2 as anotherNewFunctionName
+};
+
+// inside main.js
+import { newFunctionName, anotherNewFunctionName } from './modules/module.js';
+ +
// inside module.js
+export { function1, function2 };
+
+// inside main.js
+import { function1 as newFunctionName,
+         function2 as anotherNewFunctionName } from './modules/module.js';
+ +

Vejamos um exemplo real. Na nossa renaming diretório, você verá o mesmo sistema de módulos do exemplo anterior, exceto que adicionamos circle.js e triangle.js módulos para desenhar e relatar círculos e triângulos.

+ +

Dentro de cada um desses módulos, temos recursos com os mesmos nomes sendo exportados e, portanto, cada um tem o mesmo export declaração na parte inferior:

+ +
export { name, draw, reportArea, reportPerimeter };
+ +

Ao importá-los para o main.js, se tentarmos usar

+ +
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';
+ +

O navegador geraria um erro como "SyntaxError: redeclaration of import name" (Firefox).

+ +

Em vez disso, precisamos renomear as importações para que sejam únicas:

+ +
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';
+ +

Observe que você pode resolver o problema nos arquivos do módulo, e.g.

+ +
// in square.js
+export { name as squareName,
+         draw as drawSquare,
+         reportArea as reportSquareArea,
+         reportPerimeter as reportSquarePerimeter };
+ +
// in main.js
+import { squareName, drawSquare, reportSquareArea, reportSquarePerimeter } from './modules/square.js';
+ +

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.

+ +

24/5000

+ +

Criando um objeto de módulo

+ +

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:

+ +
import * as Module from './modules/module.js';
+ +

Isso captura todas as exportações disponíveis no module.js e as torna disponíveis como membros de um objeto Module, efetivamente dando o seu próprio namespace. Então, por exemplo:

+ +
Module.function1()
+Module.function2()
+etc.
+ +

Novamente, vejamos um exemplo real. Se você for ao nosso module-objects 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:

+ +
export { name, draw, reportArea, reportPerimeter };
+ +

As importações, por outro lado, são assim:

+ +
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';
+ +

Em cada caso, agora você pode acessar as importações do módulo abaixo do nome do objeto especificado, por exemplo:

+ +
let square1 = Square.draw(myCanvas.ctx, 50, 50, 100, 'blue');
+Square.reportArea(square1.length, reportList);
+Square.reportPerimeter(square1.length, reportList);
+ +

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.

+ +

Módulos e classes

+ +

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.

+ +

Você pode ver um exemplo do nosso módulo de desenho de forma reescrito com as classes ES em nosso classes diretório. Como exemplo, o square.js O arquivo agora contém todas as suas funcionalidades em uma única classe:

+ +
class Square {
+  constructor(ctx, listId, length, x, y, color) {
+    ...
+  }
+
+  draw() {
+    ...
+  }
+
+  ...
+}
+ +

que exportamos então:

+ +
export { Square };
+ +

No main.js, nós o importamos assim:

+ +
import { Square } from './modules/square.js';
+ +

E então use a classe para desenhar nosso quadrado:

+ +
let square1 = new Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue');
+square1.draw();
+square1.reportArea();
+square1.reportPerimeter();
+ +

Módulos de agregação

+ +

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:

+ +
export * from 'x.js'
+export { name } from 'x.js'
+ +

Por exemplo, veja nosso module-aggregation 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 é:

+ +
modules/
+  canvas.js
+  shapes.js
+  shapes/
+    circle.js
+    square.js
+    triangle.js
+ +

Em cada um dos submódulos, a exportação é da mesma forma, e.g.

+ +
export { Square };
+ +

Em seguida, vem a parte de agregação. Dentro de shapes.js, incluímos as seguintes linhas:

+ +
export { Square } from './shapes/square.js';
+export { Triangle } from './shapes/triangle.js';
+export { Circle } from './shapes/circle.js';
+ +

Eles capturam as exportações dos submódulos individuais e os disponibilizam efetivamente no módulo shapes.js.

+ +
+

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.

+
+ +

Portanto, agora no arquivo main.js., podemos obter acesso às três classes de módulos substituindo

+ +
import { Square } from './modules/square.js';
+import { Circle } from './modules/circle.js';
+import { Triangle } from './modules/triangle.js';
+ +

com a seguinte linha única:

+ +
import { Square, Circle, Triangle } from './modules/shapes.js';
+ +

Carregamento dinâmico do módulo

+ +

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.

+ +

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 Creating a module object) dando acesso às exportações desse objeto, e.g.

+ +
import('./modules/myModule.js')
+  .then((module) => {
+    // Do something with the module.
+  });
+ +

Vejamos um exemplo. No dynamic-module-imports 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.

+ +

Neste exemplo, fizemos apenas alterações em nossa index.html e main.js arquivos - as exportações do módulo permanecem as mesmas de antes.

+ +

No main.js, pegamos uma referência a cada botão usando umDocument.querySelector() chamada, por exemplo:

+ +
let squareBtn = document.querySelector('.square');
+ +

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

+ +
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();
+  })
+});
+ +

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 Module. anexado a ele, e.g. Module.Square( ... ).

+ +

Solução de problemas

+ +

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!

+ + + +

Veja também

+ + + +

{{Previous("Web/JavaScript/Guide/Meta_programming")}}

diff --git "a/files/pt-br/web/javascript/guide/m\303\263dulos/index.html" "b/files/pt-br/web/javascript/guide/m\303\263dulos/index.html" deleted file mode 100644 index 6a2cb73687..0000000000 --- "a/files/pt-br/web/javascript/guide/m\303\263dulos/index.html" +++ /dev/null @@ -1,454 +0,0 @@ ---- -title: Módulos JavaScript -slug: Web/JavaScript/Guide/Módulos -translation_of: Web/JavaScript/Guide/Modules ---- -
{{JSSidebar("JavaScript Guide")}}{{Previous("Web/JavaScript/Guide/Meta_programming")}}
- -

Este guia fornece tudo o que você precisa para começar com a sintaxe de módulo do JavaScript.

- -

Um background em módulos

- -

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 (Node.js, por exemplo).

- -

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 CommonJS e AMD-sistemas de módulos baseados em RequireJS, e mais recentemente Webpack e Babel).

- -

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.

- -

Suporte do navegador

- -

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:

- -

importa

- -

{{Compat("javascript.statements.import")}}

- -

exporta

- -

{{Compat("javascript.statements.export")}}

- -

Apresentando um exemplo

- -

Para demonstrar o uso dos módulos, criamos um conjunto simples de exemplos que você pode encontrar no GitHub. Estes exemplos demonstram um conjunto simples de módulos que criam um<canvas> em uma página da Web e desenhe (e relate informações sobre) formas diferentes na tela.

- -

Estes são bastante triviais, mas foram mantidos deliberadamente simples para demonstrar claramente os módulos.

- -
-

Nota: Se você deseja fazer o download dos exemplos e executá-los localmente, precisará executá-los por meio de um servidor da web local.

-
- -

Exemplo de uma estrutura básica

- -

No nosso primeiro exemplo (consulte basic-modules) nós temos uma estrutura de arquivos da seguinte maneira:

- -
index.html
-main.js
-modules/
-    canvas.js
-    square.js
- -
-

Nota: Todos os exemplos neste guia têm basicamente a mesma estrutura; o exposto acima deve começar a ficar bem familiar.

-
- -

Os dois módulos do diretório modules são descritos abaixo:

- - - -

Aside — .mjs versus .js

- -

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 documentação da V8 recomenda isso, por exemplo. Os motivos apresentados são:

- - - -

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 GitHub Pages e http-server para Node.js.

- -

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 Content-Type para arquivos .mjs). 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.

- -

Para fins de aprendizado e portabilidade, decidimos manter o.js.

- -

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.

- -

Também é importante notar que:

- - - -

Exportando recursos do módulo

- -

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.

- -

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:

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

Você pode exportar funções, var, let, const, 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.

- -

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:

- -
export { name, draw, reportArea, reportPerimeter };
- -

Importando recursos para o seu script

- -

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:

- -
import { name, draw, reportArea, reportPerimeter } from './modules/square.js';
- -

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 basic-modules exemplo seria/js-examples/modules/basic-modules.

- -

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.

- -

Então, por exemplo:

- -
/js-examples/modules/basic-modules/modules/square.js
- -

torna-se

- -
./modules/square.js
- -

Você pode ver essas linhas em ação em main.js.

- -
-

Nota: Em alguns sistemas de módulos, você pode omitir a extensão do arquivo e o ponto(e.g. '/modules/square'). Isso não funciona nos módulos JavaScript nativos.

-
- -

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
- main.js, abaixo das linhas de importação:

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

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.

-
- -

Aplicando o módulo ao seu HTML

- -

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.

- -

Primeiro de tudo, você precisa incluir type="module" no <script> elemento, para declarar esse script como um módulo. Para importar o main.js script, usamos este:

- -
<script type="module" src="main.js"></script>
- -

Você também pode incorporar o script do módulo diretamente no arquivo HTML, colocando o código JavaScript no corpo do elemento <script>:

- -
<script type="module">
-  /* JavaScript module code here */
-</script>
- -

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

- -

Você só pode usar import e export instruções dentro de módulos, não scripts regulares.

- -

Outras diferenças entre módulos e scripts padrão

- - - -

Exportações padrão versus exportações nomeadas

- -

A funcionalidade que exportamos até agora foi composta por named exports — 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.

- -

Há também um tipo de exportação chamado default export — 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 ES6 In Depth: Modules por Jason Orendorff; procure por "Exportações padrão").

- -

Vejamos um exemplo ao explicar como ele funciona. Nos nossos módulos básicos square.js você pode encontrar uma função chamada randomSquare() 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:

- -
export default randomSquare;
- -

Note a falta dos colchetes.

- -

Em vez disso, poderíamos acrescentar export default na função e defina-a como uma função anônima, assim:

- -
export default function(ctx) {
-  ...
-}
- -

No nosso arquivo main.js., importamos a função padrão usando esta linha:

- -
import randomSquare from './modules/square.js';
- -

Isso ocorre porque há apenas uma exportação padrão permitida por módulo e sabemos que randomSquare é isso.

- -
import {default as randomSquare} from './modules/square.js';
- -
-

Nota: A sintaxe as para renomear itens exportados é explicada abaixo no Renaming imports and exports seção.

-
- -

Evitando conflitos de nomenclatura

- -

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 draw(), reportArea(), 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.

- -

Felizmente, existem várias maneiras de contornar isso. Veremos isso nas próximas seções.

- -

Renomeando importações e exportações

- -

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.

- -

Por exemplo, os dois itens a seguir executariam o mesmo trabalho, embora de uma maneira ligeiramente diferente:

- -
// inside module.js
-export {
-  function1 as newFunctionName,
-  function2 as anotherNewFunctionName
-};
-
-// inside main.js
-import { newFunctionName, anotherNewFunctionName } from './modules/module.js';
- -
// inside module.js
-export { function1, function2 };
-
-// inside main.js
-import { function1 as newFunctionName,
-         function2 as anotherNewFunctionName } from './modules/module.js';
- -

Vejamos um exemplo real. Na nossa renaming diretório, você verá o mesmo sistema de módulos do exemplo anterior, exceto que adicionamos circle.js e triangle.js módulos para desenhar e relatar círculos e triângulos.

- -

Dentro de cada um desses módulos, temos recursos com os mesmos nomes sendo exportados e, portanto, cada um tem o mesmo export declaração na parte inferior:

- -
export { name, draw, reportArea, reportPerimeter };
- -

Ao importá-los para o main.js, se tentarmos usar

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

O navegador geraria um erro como "SyntaxError: redeclaration of import name" (Firefox).

- -

Em vez disso, precisamos renomear as importações para que sejam únicas:

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

Observe que você pode resolver o problema nos arquivos do módulo, e.g.

- -
// in square.js
-export { name as squareName,
-         draw as drawSquare,
-         reportArea as reportSquareArea,
-         reportPerimeter as reportSquarePerimeter };
- -
// in main.js
-import { squareName, drawSquare, reportSquareArea, reportSquarePerimeter } from './modules/square.js';
- -

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.

- -

24/5000

- -

Criando um objeto de módulo

- -

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:

- -
import * as Module from './modules/module.js';
- -

Isso captura todas as exportações disponíveis no module.js e as torna disponíveis como membros de um objeto Module, efetivamente dando o seu próprio namespace. Então, por exemplo:

- -
Module.function1()
-Module.function2()
-etc.
- -

Novamente, vejamos um exemplo real. Se você for ao nosso module-objects 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:

- -
export { name, draw, reportArea, reportPerimeter };
- -

As importações, por outro lado, são assim:

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

Em cada caso, agora você pode acessar as importações do módulo abaixo do nome do objeto especificado, por exemplo:

- -
let square1 = Square.draw(myCanvas.ctx, 50, 50, 100, 'blue');
-Square.reportArea(square1.length, reportList);
-Square.reportPerimeter(square1.length, reportList);
- -

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.

- -

Módulos e classes

- -

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.

- -

Você pode ver um exemplo do nosso módulo de desenho de forma reescrito com as classes ES em nosso classes diretório. Como exemplo, o square.js O arquivo agora contém todas as suas funcionalidades em uma única classe:

- -
class Square {
-  constructor(ctx, listId, length, x, y, color) {
-    ...
-  }
-
-  draw() {
-    ...
-  }
-
-  ...
-}
- -

que exportamos então:

- -
export { Square };
- -

No main.js, nós o importamos assim:

- -
import { Square } from './modules/square.js';
- -

E então use a classe para desenhar nosso quadrado:

- -
let square1 = new Square(myCanvas.ctx, myCanvas.listId, 50, 50, 100, 'blue');
-square1.draw();
-square1.reportArea();
-square1.reportPerimeter();
- -

Módulos de agregação

- -

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:

- -
export * from 'x.js'
-export { name } from 'x.js'
- -

Por exemplo, veja nosso module-aggregation 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 é:

- -
modules/
-  canvas.js
-  shapes.js
-  shapes/
-    circle.js
-    square.js
-    triangle.js
- -

Em cada um dos submódulos, a exportação é da mesma forma, e.g.

- -
export { Square };
- -

Em seguida, vem a parte de agregação. Dentro de shapes.js, incluímos as seguintes linhas:

- -
export { Square } from './shapes/square.js';
-export { Triangle } from './shapes/triangle.js';
-export { Circle } from './shapes/circle.js';
- -

Eles capturam as exportações dos submódulos individuais e os disponibilizam efetivamente no módulo shapes.js.

- -
-

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.

-
- -

Portanto, agora no arquivo main.js., podemos obter acesso às três classes de módulos substituindo

- -
import { Square } from './modules/square.js';
-import { Circle } from './modules/circle.js';
-import { Triangle } from './modules/triangle.js';
- -

com a seguinte linha única:

- -
import { Square, Circle, Triangle } from './modules/shapes.js';
- -

Carregamento dinâmico do módulo

- -

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.

- -

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 Creating a module object) dando acesso às exportações desse objeto, e.g.

- -
import('./modules/myModule.js')
-  .then((module) => {
-    // Do something with the module.
-  });
- -

Vejamos um exemplo. No dynamic-module-imports 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.

- -

Neste exemplo, fizemos apenas alterações em nossa index.html e main.js arquivos - as exportações do módulo permanecem as mesmas de antes.

- -

No main.js, pegamos uma referência a cada botão usando umDocument.querySelector() chamada, por exemplo:

- -
let squareBtn = document.querySelector('.square');
- -

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

- -
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();
-  })
-});
- -

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 Module. anexado a ele, e.g. Module.Square( ... ).

- -

Solução de problemas

- -

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!

- - - -

Veja também

- - - -

{{Previous("Web/JavaScript/Guide/Meta_programming")}}

diff --git a/files/pt-br/web/javascript/guide/numbers_and_dates/index.html b/files/pt-br/web/javascript/guide/numbers_and_dates/index.html new file mode 100644 index 0000000000..8f08cb3619 --- /dev/null +++ b/files/pt-br/web/javascript/guide/numbers_and_dates/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 +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}
+ +

Este capítulo apresenta como utilizar números e datas em JavaScript.

+ +

Números

+ +

Em Javascript, todos os números são implementados em double-precision 64-bit binary format IEEE 754 (Por exemplo, um número entre -(253 -1) e 253 -1). Não havendo especificação de tipo Integer. Além de ser capaz de representar números de ponto flutuante, o tipo de número tem três valores simbólicos: +{{jsxref("Infinity")}}, -{{jsxref("Infinity")}}, and {{jsxref("NaN")}} (not-a-number).  Veja também Estruturas e Tipos de Dados em Javascript em contexto com outros tipos primitivos em JavaScript.

+ +

Você pode usar quatro tipos de números literais: decimal, binário, octal, e hexadecimal.

+ +

Números Decimais

+ +
1234567890
+42
+
+// Cuidado quando usar zeros à esquerda:
+
+0888 // 888 interpretado como decimal
+0777 // interpretado como octal  em modo no-strict (511 em decimal)
+
+ +

Note que literais decimais podem começar com zero (0)  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.

+ +

Números Binários

+ +

A sintaxe para números Binários, usa um zero à esquerda seguido de uma letra minúscula ou maiúscula "B" (0b or 0B). Se os dígitos depois de 0b não forem 0 ou 1, a seguinte exceção SyntaxError é lançada: "Missing binary digits after 0b".

+ +
var FLT_SIGNBIT  = 0b10000000000000000000000000000000; // 2147483648
+var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
+var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607
+ +

Números octais

+ +

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.

+ +
var n = 0755; // 493
+var m = 0644; // 420
+
+ +

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: 0644 === 420 e "\045" === "%". Em ECMAScript 6 números Octais são suportados prefixando o número com "0o" isto é.

+ +
var a = 0o10; // ES6: Octal
+
+ +

Numeros hexadecimais

+ +

A sintaxe numérica Hexadecimal usa um 0 na frente seguido por uma letra "X" maiúscula ou minúscula (0x ou 0X). Se os dígidos depois do 0x estiverem fora do alcance (0123456789ABCDF), o seguinte erro de sintaxe (SyntaxError) ocorrerá: "Identifier starts immediately after numeric literal" (O identificador começa imediatamente depois do literal numérico).

+ +
0xFFFFFFFFFFFFFFFFF // 295147905179352830000
+0x123456789ABCDEF   // 81985529216486900
+0XA                 // 10
+
+ +

Exponenciação

+ +
1E3   // 1000
+2e6   // 2000000
+0.1e2 // 10
+ +

Objeto Number

+ +

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:

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

Você sempre se refere a uma propriedade do objeto predefinido Number como mostrado acima, e não como uma propriedade de um objeto Number que você mesmo criou.

+ +

A tabela à seguir sumariza as propriedades do objeto Number.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Propriedades de Number
PropriedadeDescrição
{{jsxref("Number.MAX_VALUE")}}O maior número representável.
{{jsxref("Number.MIN_VALUE")}}O menor número representável.
{{jsxref("Number.NaN")}}Valor "not a number" especial
{{jsxref("Number.NEGATIVE_INFINITY")}}Valor especial infinito negativo; retornado em overflow
{{jsxref("Number.POSITIVE_INFINITY")}}Valor especial infinito positivo; retornado em overflow
{{jsxref("Number.EPSILON")}}Diferença entre um e o menor valor maior do que um que pode ser representado como um {{jsxref("Number")}}.
{{jsxref("Number.MIN_SAFE_INTEGER")}}Mínimo safe integer em JavaScript.
{{jsxref("Number.MAX_SAFE_INTEGER")}}Máximo safe integer em JavaScript.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Métodos de Number
MétodoDescrição
{{jsxref("Number.parseFloat()")}}Analisa um argumento string e retorna um número float.
+ O mesmo que a função global {{jsxref("parseFloat", "parseFloat()")}}.
{{jsxref("Number.parseInt()")}}Analisa um argumento string e retorna um inteiro da raiz ou base especificada.
+ O mesmo que a função global{{jsxref("parseInt", "parseInt()")}}.
{{jsxref("Number.isFinite()")}}Determina se o valor passado é um número finito.
{{jsxref("Number.isInteger()")}}Determina se o valor passado é um inteiro.
{{jsxref("Number.isNaN()")}}Determina se o valor passado é {{jsxref("Global_Objects/NaN", "NaN")}}. A versão mais robusta da original {{jsxref("Global_Objects/isNaN", "isNaN()")}}.
{{jsxref("Number.isSafeInteger()")}}Determina se o valor passado é um safe integer.
+ +

O protótipo Number provê métodos para resgatar informações de objetos Number em vários formatos. A tabela a seguir sumariza os métodos de Number.prototype.

+ + + + + + + + + + + + + + + + + + + + + + + +
Métodos de Number.prototype
MétodoDescrição
{{jsxref("Number.toExponential", "toExponential()")}}Retorna uma string representando o número em uma notação exponencial.
{{jsxref("Number.toFixed", "toFixed()")}}Retorna uma string representando o número em notação com ponto-fíxo.
{{jsxref("Number.toPrecision", "toPrecision()")}}Retorna uma string representando o número em uma precisão especificada na notação de ponto-fíxo.
+ +

Objeto Math

+ +

O objeto {{jsxref("Math")}} tem propriedades e métodos para constantes matemáticas e funções. Por exemplo, o PI do objeto Math tem o valor de pi (3,141...), que você usaria em uma aplicação como

+ +
Math.PI
+
+ +

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

+ +
Math.sin(1.56)
+
+ +

Note que todos os métodos trigonométricos pegam argumentos em radianos.

+ +

A tabela a seguir sumariza os métodos do objeto Math.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Métodos de Math
MétodoDescrição
{{jsxref("Math.abs", "abs()")}}Valor absoluto
{{jsxref("Math.sin", "sin()")}}, {{jsxref("Math.cos", "cos()")}}, {{jsxref("Math.tan", "tan()")}}Funções trigonométricas padrão; Argumentos em radianos
{{jsxref("Math.asin", "asin()")}}, {{jsxref("Math.acos", "acos()")}}, {{jsxref("Math.atan", "atan()")}}, {{jsxref("Math.atan2", "atan2()")}}Funções trigonométricas inversas; retorna valores em radianos
{{jsxref("Math.sinh", "sinh()")}}, {{jsxref("Math.cosh", "cosh()")}}, {{jsxref("Math.tanh", "tanh()")}}Funções trigonométricas hiperbólicas; retorna valores em radianos.
{{jsxref("Math.asinh", "asinh()")}}, {{jsxref("Math.acosh", "acosh()")}}, {{jsxref("Math.atanh", "atanh()")}}Funções trigonométricas hiperbólicas inversas; retorna valores em radianos.
+

{{jsxref("Math.pow", "pow()")}}, {{jsxref("Math.exp", "exp()")}}, {{jsxref("Math.expm1", "expm1()")}}, {{jsxref("Math.log10", "log10()")}}, {{jsxref("Math.log1p", "log1p()")}}, {{jsxref("Math.log2", "log2()")}}

+
Funções exponenciais e logarítmicas.
{{jsxref("Math.floor", "floor()")}}, {{jsxref("Math.ceil", "ceil()")}}Retorna o maior/menor inteiro que é menor/maior inteiro que ou igual ao argumento.
{{jsxref("Math.min", "min()")}}, {{jsxref("Math.max", "max()")}}Retorna menor ou maior (respectivamente) de uma lista separada por vírgula de argumentos numéricos
{{jsxref("Math.random", "random()")}}Retorna um número aleatório entre 0 e 1.
{{jsxref("Math.round", "round()")}}, {{jsxref("Math.fround", "fround()")}}, {{jsxref("Math.trunc", "trunc()")}},Funções de arredondamento e truncamento.
{{jsxref("Math.sqrt", "sqrt()")}}, {{jsxref("Math.cbrt", "cbrt()")}}, {{jsxref("Math.hypot", "hypot()")}}Raiz quadrada, raiz cúbica, raiz quadrada da soma de argumentos ao quadrado.
{{jsxref("Math.sign", "sign()")}}O sinal de um número, indicando se o número é positivo, negativo ou zero.
{{jsxref("Math.clz32", "clz32()")}},
+ {{jsxref("Math.imul", "imul()")}}
Número de zeros à esquerda na representação binária de 32-bits.
+ The result of the C-like 32-bit multiplication of the two arguments.
+ +

Diferentemente de muitos outros objetos, você nunca cria um objeto Math por conta própria. Você sempre deve utilizar o objeto Math nativo.

+ +

Objeto Date

+ +

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.

+ +

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

+ +

A abrangência do objeto Date é de -100,000,000 dias até 100,000,000 dias relativos a 01 de janeiro de 1970 UTC.

+ +

Para criar um objeto Date:

+ +
var dateObjectName = new Date([parameters]);
+
+ +

onde dateObjectName é o nome do objeto Date que está sendo criado; ele pode ser um novo objeto ou uma propriedade de um objeto existente.

+ +

A chamada de Date sem a palavra reservada new, simplesmente converte a data para uma representação dela como string.

+ +

Os parâmetros do código acima podem ser qualquer um a seguir:

+ + + +

Métodos do objeto Date

+ +

Os métodos do objeto Date para manipular data e hora pertencem às seguintes categorias:

+ + + +

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 getDay que retorna o dia da semana, mas não existe um método setDay correspondente, porque o dia da semana é setado automaticamente. Estes métodos utilizam números inteiros para representar estes valores da seguinte maneira:

+ + + +

Por exemplo, suponha que você queira definir a seguinite data:

+ +
var Xmas95 = new Date("December 25, 1995");
+
+ +

Então Xmas95.getMonth() retorna 11 e Xmas95.getFullYear() retorna 1995.

+ +

Os métodos getTime e setTime são úteis para comparar datas. O método getTime retorna o número dos milisegundos desde 1 de janeiro de 1970, às 00:00:00 para um objeto Date.

+ +

Por exemplo, o código a seguir mostra os números dos dias que ainda faltam do ano vigente:

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

Este exemplo cria um objeto Date chamado hoje que contém a data de hoje. Ele, então, cria o objeto Date chamado fimAno 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 fimAno, usando getTime e arredondando os números de dias.

+ +

O método parse é útil para associar valores de strings de data para objetos Date existentes. Por exemplo, o código a seguir usa parse e setTime para associar um valor de data ao objeto IPOdate:

+ +
var IPOdate = new Date();
+IPOdate.setTime(Date.parse("Aug 9, 1995"));
+
+ +

No exemplo a seguir, a função  JSClock() retorna o tempo no formato de um relógio digital.

+ +
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;
+}
+
+ +

A função JSClock primeiro cria um objeto new Date chamado tempo; já que nenhum argumento é passado, tempo é criado com data e hora atuais. Ela então chama os métodos getHours, getMinutes e getSeconds e associa o valor à hora, minuto e segundo atuais à hora, minuto e segundo.

+ +

As próximas quatro declarações constroem uma string baseada em time. A primeira declaração cria uma variável temp, 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.

+ +

A próxima declaração anexa um valor minuto a temp. 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 segundo a temp do mesmo jeito.

+ +

Finalmente, a expressão condicional anexa "P.M." a temp se hora for 12 ou maior; senão ela anexa "A.M." a temp.

+ +

{{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}

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 deleted file mode 100644 index 8f08cb3619..0000000000 --- a/files/pt-br/web/javascript/guide/numeros_e_datas/index.html +++ /dev/null @@ -1,374 +0,0 @@ ---- -title: Números e datas -slug: Web/JavaScript/Guide/Numeros_e_datas -translation_of: Web/JavaScript/Guide/Numbers_and_dates ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}
- -

Este capítulo apresenta como utilizar números e datas em JavaScript.

- -

Números

- -

Em Javascript, todos os números são implementados em double-precision 64-bit binary format IEEE 754 (Por exemplo, um número entre -(253 -1) e 253 -1). Não havendo especificação de tipo Integer. Além de ser capaz de representar números de ponto flutuante, o tipo de número tem três valores simbólicos: +{{jsxref("Infinity")}}, -{{jsxref("Infinity")}}, and {{jsxref("NaN")}} (not-a-number).  Veja também Estruturas e Tipos de Dados em Javascript em contexto com outros tipos primitivos em JavaScript.

- -

Você pode usar quatro tipos de números literais: decimal, binário, octal, e hexadecimal.

- -

Números Decimais

- -
1234567890
-42
-
-// Cuidado quando usar zeros à esquerda:
-
-0888 // 888 interpretado como decimal
-0777 // interpretado como octal  em modo no-strict (511 em decimal)
-
- -

Note que literais decimais podem começar com zero (0)  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.

- -

Números Binários

- -

A sintaxe para números Binários, usa um zero à esquerda seguido de uma letra minúscula ou maiúscula "B" (0b or 0B). Se os dígitos depois de 0b não forem 0 ou 1, a seguinte exceção SyntaxError é lançada: "Missing binary digits after 0b".

- -
var FLT_SIGNBIT  = 0b10000000000000000000000000000000; // 2147483648
-var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
-var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607
- -

Números octais

- -

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.

- -
var n = 0755; // 493
-var m = 0644; // 420
-
- -

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: 0644 === 420 e "\045" === "%". Em ECMAScript 6 números Octais são suportados prefixando o número com "0o" isto é.

- -
var a = 0o10; // ES6: Octal
-
- -

Numeros hexadecimais

- -

A sintaxe numérica Hexadecimal usa um 0 na frente seguido por uma letra "X" maiúscula ou minúscula (0x ou 0X). Se os dígidos depois do 0x estiverem fora do alcance (0123456789ABCDF), o seguinte erro de sintaxe (SyntaxError) ocorrerá: "Identifier starts immediately after numeric literal" (O identificador começa imediatamente depois do literal numérico).

- -
0xFFFFFFFFFFFFFFFFF // 295147905179352830000
-0x123456789ABCDEF   // 81985529216486900
-0XA                 // 10
-
- -

Exponenciação

- -
1E3   // 1000
-2e6   // 2000000
-0.1e2 // 10
- -

Objeto Number

- -

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:

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

Você sempre se refere a uma propriedade do objeto predefinido Number como mostrado acima, e não como uma propriedade de um objeto Number que você mesmo criou.

- -

A tabela à seguir sumariza as propriedades do objeto Number.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Propriedades de Number
PropriedadeDescrição
{{jsxref("Number.MAX_VALUE")}}O maior número representável.
{{jsxref("Number.MIN_VALUE")}}O menor número representável.
{{jsxref("Number.NaN")}}Valor "not a number" especial
{{jsxref("Number.NEGATIVE_INFINITY")}}Valor especial infinito negativo; retornado em overflow
{{jsxref("Number.POSITIVE_INFINITY")}}Valor especial infinito positivo; retornado em overflow
{{jsxref("Number.EPSILON")}}Diferença entre um e o menor valor maior do que um que pode ser representado como um {{jsxref("Number")}}.
{{jsxref("Number.MIN_SAFE_INTEGER")}}Mínimo safe integer em JavaScript.
{{jsxref("Number.MAX_SAFE_INTEGER")}}Máximo safe integer em JavaScript.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Métodos de Number
MétodoDescrição
{{jsxref("Number.parseFloat()")}}Analisa um argumento string e retorna um número float.
- O mesmo que a função global {{jsxref("parseFloat", "parseFloat()")}}.
{{jsxref("Number.parseInt()")}}Analisa um argumento string e retorna um inteiro da raiz ou base especificada.
- O mesmo que a função global{{jsxref("parseInt", "parseInt()")}}.
{{jsxref("Number.isFinite()")}}Determina se o valor passado é um número finito.
{{jsxref("Number.isInteger()")}}Determina se o valor passado é um inteiro.
{{jsxref("Number.isNaN()")}}Determina se o valor passado é {{jsxref("Global_Objects/NaN", "NaN")}}. A versão mais robusta da original {{jsxref("Global_Objects/isNaN", "isNaN()")}}.
{{jsxref("Number.isSafeInteger()")}}Determina se o valor passado é um safe integer.
- -

O protótipo Number provê métodos para resgatar informações de objetos Number em vários formatos. A tabela a seguir sumariza os métodos de Number.prototype.

- - - - - - - - - - - - - - - - - - - - - - - -
Métodos de Number.prototype
MétodoDescrição
{{jsxref("Number.toExponential", "toExponential()")}}Retorna uma string representando o número em uma notação exponencial.
{{jsxref("Number.toFixed", "toFixed()")}}Retorna uma string representando o número em notação com ponto-fíxo.
{{jsxref("Number.toPrecision", "toPrecision()")}}Retorna uma string representando o número em uma precisão especificada na notação de ponto-fíxo.
- -

Objeto Math

- -

O objeto {{jsxref("Math")}} tem propriedades e métodos para constantes matemáticas e funções. Por exemplo, o PI do objeto Math tem o valor de pi (3,141...), que você usaria em uma aplicação como

- -
Math.PI
-
- -

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

- -
Math.sin(1.56)
-
- -

Note que todos os métodos trigonométricos pegam argumentos em radianos.

- -

A tabela a seguir sumariza os métodos do objeto Math.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Métodos de Math
MétodoDescrição
{{jsxref("Math.abs", "abs()")}}Valor absoluto
{{jsxref("Math.sin", "sin()")}}, {{jsxref("Math.cos", "cos()")}}, {{jsxref("Math.tan", "tan()")}}Funções trigonométricas padrão; Argumentos em radianos
{{jsxref("Math.asin", "asin()")}}, {{jsxref("Math.acos", "acos()")}}, {{jsxref("Math.atan", "atan()")}}, {{jsxref("Math.atan2", "atan2()")}}Funções trigonométricas inversas; retorna valores em radianos
{{jsxref("Math.sinh", "sinh()")}}, {{jsxref("Math.cosh", "cosh()")}}, {{jsxref("Math.tanh", "tanh()")}}Funções trigonométricas hiperbólicas; retorna valores em radianos.
{{jsxref("Math.asinh", "asinh()")}}, {{jsxref("Math.acosh", "acosh()")}}, {{jsxref("Math.atanh", "atanh()")}}Funções trigonométricas hiperbólicas inversas; retorna valores em radianos.
-

{{jsxref("Math.pow", "pow()")}}, {{jsxref("Math.exp", "exp()")}}, {{jsxref("Math.expm1", "expm1()")}}, {{jsxref("Math.log10", "log10()")}}, {{jsxref("Math.log1p", "log1p()")}}, {{jsxref("Math.log2", "log2()")}}

-
Funções exponenciais e logarítmicas.
{{jsxref("Math.floor", "floor()")}}, {{jsxref("Math.ceil", "ceil()")}}Retorna o maior/menor inteiro que é menor/maior inteiro que ou igual ao argumento.
{{jsxref("Math.min", "min()")}}, {{jsxref("Math.max", "max()")}}Retorna menor ou maior (respectivamente) de uma lista separada por vírgula de argumentos numéricos
{{jsxref("Math.random", "random()")}}Retorna um número aleatório entre 0 e 1.
{{jsxref("Math.round", "round()")}}, {{jsxref("Math.fround", "fround()")}}, {{jsxref("Math.trunc", "trunc()")}},Funções de arredondamento e truncamento.
{{jsxref("Math.sqrt", "sqrt()")}}, {{jsxref("Math.cbrt", "cbrt()")}}, {{jsxref("Math.hypot", "hypot()")}}Raiz quadrada, raiz cúbica, raiz quadrada da soma de argumentos ao quadrado.
{{jsxref("Math.sign", "sign()")}}O sinal de um número, indicando se o número é positivo, negativo ou zero.
{{jsxref("Math.clz32", "clz32()")}},
- {{jsxref("Math.imul", "imul()")}}
Número de zeros à esquerda na representação binária de 32-bits.
- The result of the C-like 32-bit multiplication of the two arguments.
- -

Diferentemente de muitos outros objetos, você nunca cria um objeto Math por conta própria. Você sempre deve utilizar o objeto Math nativo.

- -

Objeto Date

- -

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.

- -

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

- -

A abrangência do objeto Date é de -100,000,000 dias até 100,000,000 dias relativos a 01 de janeiro de 1970 UTC.

- -

Para criar um objeto Date:

- -
var dateObjectName = new Date([parameters]);
-
- -

onde dateObjectName é o nome do objeto Date que está sendo criado; ele pode ser um novo objeto ou uma propriedade de um objeto existente.

- -

A chamada de Date sem a palavra reservada new, simplesmente converte a data para uma representação dela como string.

- -

Os parâmetros do código acima podem ser qualquer um a seguir:

- - - -

Métodos do objeto Date

- -

Os métodos do objeto Date para manipular data e hora pertencem às seguintes categorias:

- - - -

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 getDay que retorna o dia da semana, mas não existe um método setDay correspondente, porque o dia da semana é setado automaticamente. Estes métodos utilizam números inteiros para representar estes valores da seguinte maneira:

- - - -

Por exemplo, suponha que você queira definir a seguinite data:

- -
var Xmas95 = new Date("December 25, 1995");
-
- -

Então Xmas95.getMonth() retorna 11 e Xmas95.getFullYear() retorna 1995.

- -

Os métodos getTime e setTime são úteis para comparar datas. O método getTime retorna o número dos milisegundos desde 1 de janeiro de 1970, às 00:00:00 para um objeto Date.

- -

Por exemplo, o código a seguir mostra os números dos dias que ainda faltam do ano vigente:

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

Este exemplo cria um objeto Date chamado hoje que contém a data de hoje. Ele, então, cria o objeto Date chamado fimAno 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 fimAno, usando getTime e arredondando os números de dias.

- -

O método parse é útil para associar valores de strings de data para objetos Date existentes. Por exemplo, o código a seguir usa parse e setTime para associar um valor de data ao objeto IPOdate:

- -
var IPOdate = new Date();
-IPOdate.setTime(Date.parse("Aug 9, 1995"));
-
- -

No exemplo a seguir, a função  JSClock() retorna o tempo no formato de um relógio digital.

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

A função JSClock primeiro cria um objeto new Date chamado tempo; já que nenhum argumento é passado, tempo é criado com data e hora atuais. Ela então chama os métodos getHours, getMinutes e getSeconds e associa o valor à hora, minuto e segundo atuais à hora, minuto e segundo.

- -

As próximas quatro declarações constroem uma string baseada em time. A primeira declaração cria uma variável temp, 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.

- -

A próxima declaração anexa um valor minuto a temp. 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 segundo a temp do mesmo jeito.

- -

Finalmente, a expressão condicional anexa "P.M." a temp se hora for 12 ou maior; senão ela anexa "A.M." a temp.

- -

{{PreviousNext("Web/JavaScript/Guide/Expressions_and_Operators", "Web/JavaScript/Guide/Text_formatting")}}

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 deleted file mode 100644 index 953a9543de..0000000000 --- a/files/pt-br/web/javascript/guide/sintaxe_e_tipos/index.html +++ /dev/null @@ -1,583 +0,0 @@ ---- -title: Sintaxe e tipos -slug: Web/JavaScript/Guide/Sintaxe_e_tipos ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}
- -

Este capítulo trata sobre a sintaxe básica do JavaScript, declarações de variáveis, tipos de dados e literais.

- -

Sintaxe básica

- -

JavaScript pega emprestado a maior parte de sua sintaxe do Java, mas também é influenciado por Awk, Perl e Python.

- -

JavaScript é case-sensitive e usa o conjunto de caracteres Unicode.

- -

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 (ASI) 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 gramática léxica do JavaScript.

- -

Comentários

- -

A sintaxe dos comentários em JavaScript é semelhante como em C++ e em muitas outras linguagens:

- -
// comentário de uma linha
-
-/* isto é um comentário longo
-   de múltiplas linhas.
- */
-
-/* Você não pode, porém, /* aninhar comentários */ SyntaxError */
- -

Declarações

- -

Existem três tipos de declarações em JavaScript.

- -
-
{{jsxref("Statements/var", "var")}}
-
Declara uma variável, opcionalmente, inicializando-a com um valor.
-
{{experimental_inline}} {{jsxref("Statements/let", "let")}}
-
Declara uma variável local de escopo do bloco, opcionalmente, inicializando-a com um valor.
-
{{experimental_inline}} {{jsxref("Statements/const", "const")}}
-
Declara uma constante apenas de leitura.
-
- -

Variáveis

- -

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.

- -

Um identificador JavaScript deve começar com uma letra, underline (_), ou cifrão ($); 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).

- -

Você pode usar a ISO 8859-1 ou caracteres Unicode tal como os identificadores å e ü. Você pode também usar as sequências de escape Unicode como caracteres e identificadores.

- -

Alguns exemplos de nomes legais são Numeros_visitas, temp99, e _nome.

- -

Declarando variáveis

- -

Você pode declarar uma variável de três formas:

- - - -

Classificando variáveis

- -

Uma variável declarada usando a declaração var ou let sem especificar o valor inicial tem o valor  {{jsxref("undefined")}}.

- -

Uma tentativa de acessar uma variável não declarada resultará no lançamento de uma exceção {{jsxref("ReferenceError")}}:

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

Você pode usar undefined 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 if será avaliada como verdadeira (true).

- -
var input;
-if(input === undefined){
-  facaIsto();
-} else {
-  facaAquilo();
-}
-
- -

O valor undefined se comporta como falso (false), quando usado em um contexto booleano. Por exemplo, o código a seguir executa a função myFunction devido o elemento myArray ser undefined:

- -
var myArray = [];
-if (!myArray[0]) myFunction();
-
- -

O valor undefined converte-se para NaN quando usado no contexto numérico.

- -
var a;
-a + 2;  // Avaliado como NaN
-
- -

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:

- -
var n = null;
-console.log(n * 32); // a saída para o console será 0.
-
- -

Escopo de variável

- -

Quando você declara uma váriavel fora de qualquer função, ela é chamada de variável global, 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 local,  pois ela está disponível somente dentro dessa função.

- -

JavaScript antes do ECMAScript 6 não possuía escopo de declaração de bloco; pelo contrário, uma variável declarada dentro de um bloco de uma função é uma variável local (ou contexto global) do bloco que está inserido a função. Por exemplo o código a seguir exibirá 5, porque o escopo de x está na função (ou contexto global) no qual x é declarado, não o bloco, que neste caso é a declaração if

- -
if (true) {
-  var x = 5;
-}
-console.log(x);  // 5
-
- -

Esse comportamento é alterado, quando usado a declaração let introduzida pelo ECMAScript 6.

- -
if (true) {
-  let y = 5;
-}
-console.log(y);  // ReferenceError: y não está definido
-
- -

Hoisting

- -

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 hoisting; 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 undefined. Então, mesmo se você usar ou referir a variável e depois declará-la e inicializá-la, ela ainda retornará undefined.

- -
/**
- * 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";
-})();
-
- -

Os exemplos acima serão interpretados como:

- -
/**
- * 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";
-})();
-
- -

Devido o hoisting, todas as declarações var 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.

- -

Variáveis Globais

- -

Variáveis globais são propriedades do objeto global. Em páginas web o objeto global é a {{domxref("window")}}, assim você pode configurar e acessar variáveis globais utilizando a sintaxe window.variavel. 

- -

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 parent.phoneNumber.

- -

Constantes

- -

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.

- -
const prefix = '212';
-
- -

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.

- -

As regras de escopo para as constantes são as mesmas para as váriaveis let de escopo de bloco. Se a palavra-chave const for omitida, o identificado é adotado para representar uma variável.

- -

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: 

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

Estrutura de dados e tipos

- -

Tipos de dados

- -

O mais recente padrão ECMAScript define sete tipos de dados:

- - - -

Embora esses tipos de dados sejam uma quantidade relativamente pequena, eles permitem realizar funções úteis em suas aplicações.  {{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.

- -

Conversão de tipos de dados

- -

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:

- -
var answer = 42;
-
- -

E depois, você pode atribuir uma string para a mesma variável, por exemplo:

- -
answer = "Obrigado pelos peixes...";
-
- -

Devido JavaScript ser dinamicamente tipado, essa declaração não gera uma mensagem de erro.

- -

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:

- -
x = "A resposta é " + 42 // "A resposta é 42"
-y = 42 + " é a resposta" // "42 é a resposta"
-
- -

Nas declarações envolvendo outros operadores,  JavaScript não converte valores numérico para strings. Por exemplo:

- -
"37" - 7 // 30
-"37" + 7 // "377"
-
- -

Convertendo strings para números

- -

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.

- - - -

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.

- -

Uma método alternativo de conversão de um número em forma de string é com o operador + (operador soma):

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

Literais

- -

Você usa literais para representar valores em JavaScript. Estes são valores fixados, não variáveis, que você literalmente insere em seu script. Esta seção descreve os seguintes tipos literais:

- - - -

Array literal

- -

Um literal de array é uma lista de zero ou mais expressões, onde cada uma delas representam um elemento do array, inseridas entre colchetes ([]). 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.

- -

O exemplo a seguir cria um array coffees com três elementos e um comprimento de três:

- -
var coffees = ["French Roast", "Colombian", "Kona"];
-
- -
-

Nota : Um array literal é um tipo de inicializador de objetos. Veja Usando inicializadores de Objetos.

-
- -

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.

- -

Array literal são também um array de objetos. Veja  {{jsxref("Array")}} e Coleções indexadas para detalhes sobre array de objetos.

- -

Vírgulas extras em array literal

- -

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 undefined para os elementos não especificados. O exemplo a seguir cria um array chamado fish:

- -
var fish = ["Lion", , "Angel"];
-
- -

Esse array tem dois elementos com valores e um elemento vazio (fish[0] é "Lion", fish[1] é undefined, e fish[2] é "Angel" ).

- -

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 myList[3]. Todas as outras vírgulas na lista indicam um novo elemento.

- -
-

Nota : Vírgulas à direita podem criar erros em algumas versões de navegadores web antigos, é recomendável removê-las.

-
- -
var myList = ['home', , 'school', ];
-
- -

No exemplo a seguir, o comprimento do array é quatro, e myList[0] e myList[2] são undefined.

- -
var myList = [ , 'home', , 'school'];
-
- -

No exemplo a seguir, o comprimento do array é quatro, e myList[1] e myList[3] são undefined. Apenas a última vírgula é ignorada.

- -
var myList = ['home', , 'school', , ];
-
- -

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 undefined vai aumentar a clareza do código, e consequentemente na sua manutenção.

- -

Literais Boolean

- -

O tipo Boolean tem dois valores literal: true e false.

- -

Não confunda os valores primitivos Boolean true e false com os valores true e false do objeto Boolean. O objeto Boolean é um invólucro em torno do tipo de dado primitivo. Veja {{jsxref("Boolean")}} para mais informação.

- -

Inteiros

- -

Inteiros podem sem expressos em decimal (base 10), hexadecimal (base 16), octal (base 8) e binário (base 2).

- - - -

Alguns exemplos de inteiros literal são:

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

Para maiores informações, veja Literais numérico na referência Léxica.

- -

Literais de ponto flutuante

- -

Um literal de ponto flutuante pode ter as seguintes partes:

- - - -

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").

- -

Mais sucintamente, a sintaxe é:

- -
[(+|-)][digitos][.digitos][(E|e)[(+|-)]digitos]
-
- -

Por exemplo:

- -
3.1415926
--.123456789
--3.1E+12
-.1e-23
-
- -

Objeto literal

- -

Um objeto literal é uma lista de zero ou mais pares de nomes de propriedades e valores associados de de um objeto, colocado entre chaves ({}). 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 { será interpretado como início de um bloco.

- -

Segue um exemplo de um objeto literal. O primeiro elemento do objeto car define uma propriedade, myCar, e atribui para ele uma nova string, "Saturn"; o segundo elemento, a propriedade getCar, é imediatamente atribuído o resultado de chamar uma função (carTypes("Honda")); o terceiro elemento, a propriedade especial, usa uma variável existente (sales).

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

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.

- -
var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
-
-console.log(car.manyCars.b); // Jeep
-console.log(car[7]); // Mazda
-
- -

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 (.), mas podem ser acessadas e definidas com a notação do tipo array ("[]").

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

Observe:

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

String Literal

- -

Uma string literal são zero ou mais caracteres dispostos em aspas duplas (") ou aspas simples ('). 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.

- -
"foo"
-'bar'
-"1234"
-"um linha \n outra linha"
-"John's cat"
-
- -

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 String.length com uma string literal:

- -
console.log("John's cat".length)
-// Irá exibir a quantidade de caracteres na string incluindo o espaço em branco.
-// Nesse caso, 10 caracteres.
-
- -

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.

- -

Uso de caracteres especiais em string

- -

Além dos caracteres comuns, você também pode incluir caracteres especiais em strings, como mostrado no exemplo a seguir.

- -
"uma linha \n outra linha"
-
- -

A tabela a seguir lista os caracteres especiais que podem ser usados em strings no JavaScript.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Tabela: Caracteres especiais no JavaScript
CaracterDescrição
\0Byte nulo
\bBackspace
\fAlimentador de formulário
\nNova linha
\rRetorno do carro
\tTabulação
\vTabulação vertical
\'Apóstrofo ou aspas simples
\"Aspas dupla
\\Caractere de barra invertida
\XXX -

Caractere com a codificação Latin-1 especificada por três dígitos octal XXX entre 0 e 377. Por exemplo, \251 é sequência octal para o símbolo de direitos autorais.

-
\xXX -

Caractere com a codificação Latin-1 especificada por dois dígitos hexadecimal XX entre 00 e FF. Por exemplo, \xA9 é a sequência hexadecimal para o símbolo de direitos autorais.

-
\uXXXX -

Caractere Unicode especificado por quatro dígitos hexadecimal XXXX. Por exemplo, \u00A9 é a sequência Unicode para o símbolo de direitos autorais. Veja sequências de escape Unicode.

-
- -

Caracteres de escape

- -

Para caracteres não listados na tabela, se precedidos de barra invertida ela é ignorada, seu uso está absoleto e deve ser ignorado.

- -

Você pode inserir uma aspa dentro de uma string precendendo-a com uma barra invertida. Isso  é conhecido como escaping das aspas. Por exemplo:

- -
var quote = "Ele lê \"The Cremation of Sam McGee\" de R.W. Service.";
-console.log(quote);
-
- -

O resultado disso seria:

- -
Ele lê "The Cremation of Sam McGee" de R.W. Service.
-
- -

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 c:\temp para uma string, utilize o seguinte:

- -
var home = "c:\\temp";
-
- -

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.

- -
var str = "esta string \
-está quebrada \
-em várias\
-linhas."
-console.log(str);   // esta string está quebrada em várias linhas.
-
- -

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:

- -
var poem =
-"Rosas são vermelhas,\n\
-Violetas são azul.\n\
-Eu sou esquizofrênico,\n\
-e é isso que sou."
-
- -

Mais informação

- -

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:

- - - -

No próximo capítulo, veremos a construção de controle de fluxos e manipulação de erro.

- -

{{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

diff --git a/files/pt-br/web/javascript/guide/text_formatting/index.html b/files/pt-br/web/javascript/guide/text_formatting/index.html new file mode 100644 index 0000000000..1b4bb50772 --- /dev/null +++ b/files/pt-br/web/javascript/guide/text_formatting/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 +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}
+ +

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

+ +

Strings

+ +

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.

+ +

Strings literais

+ +

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

+ +
'foo'
+"bar"
+ +

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

+ +

Sequências de escape hexadecimais

+ +

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

+ +
'\xA9' // "©"
+
+ +

Sequências de escape unicode

+ +

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

+ +
'\u00A9' // "©"
+ +

Sequências de escape Unicode code point

+ +

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

+ +

Veja também {{jsxref("String.fromCodePoint()")}} or {{jsxref("String.prototype.codePointAt()")}}.

+ +
'\u{2F804}'
+
+// o mesmo com escapes Unicode simples
+'\uD87E\uDC04'
+ +

Objetos String

+ +

O objeto {{jsxref("String")}} é como uma "capa" ao redor do tipo primitivo string.

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

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

+ +

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

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

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

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

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

+ +

A tabela a seguir lista os métodos de objetos {{jsxref("String")}}.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

Métodos de String

+
MétodoDescrição
{{jsxref("String.charAt", "charAt")}}, {{jsxref("String.charCodeAt", "charCodeAt")}}, {{jsxref("String.codePointAt", "codePointAt")}}Retorna o código do caractere ou o caractere em uma posição específica na string.
{{jsxref("String.indexOf", "indexOf")}}, {{jsxref("String.lastIndexOf", "lastIndexOf")}}Retorna a posição de uma substring específica na string ou a última posição da substring específica, respectivamente.
{{jsxref("String.startsWith", "startsWith")}}, {{jsxref("String.endsWith", "endsWith")}}, {{jsxref("String.includes", "includes")}}Retorna se uma string começa, termina ou contém uma outra string específica.
{{jsxref("String.concat", "concat")}}Concatena o texto de duas strings e retorna uma nova string.
{{jsxref("String.fromCharCode", "fromCharCode")}}, {{jsxref("String.fromCodePoint", "fromCodePoint")}}Cria uma string a partir de uma sequência específica de valores Unicode. Esse é um método da classe String, não de uma instância do tipo String.
{{jsxref("String.split", "split")}}Separa um objeto String em um array de strings, separando a string em substrings.
{{jsxref("String.slice", "slice")}}Extrai uma seção de uma string e retorna uma nova string.
{{jsxref("String.substring", "substring")}}, {{jsxref("String.substr", "substr")}}Retorna um subconjunto específico de uma string, definindo os índices inicial e final, ou definindo um índice e um tamanho.
{{jsxref("String.match", "match")}}, {{jsxref("String.replace", "replace")}}, {{jsxref("String.search", "search")}}Trabalha com expressões regulares.
{{jsxref("String.toLowerCase", "toLowerCase")}}, {{jsxref("String.toUpperCase", "toUpperCase")}} +

Retorna a string com todos caracteres em minúsculo, ou maiúsculo, respectivamente.

+
{{jsxref("String.normalize", "normalize")}}Retorna a Forma Normalizada Unicode (Unicode Normalization Form) da string que chama o método.
{{jsxref("String.repeat", "repeat")}}Retorna uma string contendo os elementos do objeto repetidos pela quantidade de vezes dada.
{{jsxref("String.trim", "trim")}}Retira espaços em branco no começo e no final da string.
+ +

Template strings com várias linhas

+ +

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

+ +

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

+ +

Várias linhas (Multi-lines)

+ +

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

+ +
console.log("linha de texto 1\n\
+linha de texto 2");
+// "linha de texto 1
+// linha de texto 2"
+ +

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

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

Expressões inseridas

+ +

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

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

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

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

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

+ +

Internacionalização

+ +

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

+ +

Formatação de data e hora

+ +

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

+ +
var msPorDia = 24 * 60 * 60 * 1000; // número de milisegundos em um dia
+
+// July 17, 2014 00:00:00 UTC.
+var july172014 = new Date(msPorDia * (44 * 365 + 11 + 197));
+
+var opcoes = { year: "2-digit", month: "2-digit", day: "2-digit",
+                hour: "2-digit", minute: "2-digit", timeZoneName: "short" };
+var americanDateTime = new Intl.DateTimeFormat("en-US", opcoes).format;
+
+console.log(americanDateTime(july172014)); // 07/16/14, 5:00 PM PDT
+
+ +

Formatação de números

+ +

O objeto {{jsxref("NumberFormat")}} é útil para formatar números, por exemplo unidade monetária.

+ +
var precoGasolina = new Intl.NumberFormat("en-US",
+                        { style: "currency", currency: "USD",
+                          minimumFractionDigits: 3 });
+
+console.log(precoGasolina.format(5.259)); // $5.259
+
+var hanDecimalRMBInChina = new Intl.NumberFormat("zh-CN-u-nu-hanidec",
+                        { style: "currency", currency: "CNY" });
+
+console.log(hanDecimalRMBInChina.format(1314.25)); // ¥ 一,三一四.二五
+
+ +

Collation

+ +

O objeto {{jsxref("Collator")}} é usado para comparar e ordenar strings.

+ +

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

+ +
var nomes = ["Hochberg", "Hönigswald", "Holzman"];
+
+var phonebookAlemao = new Intl.Collator("de-DE-u-co-phonebk");
+
+// como se ordenasse ["Hochberg", "Hoenigswald", "Holzman"]:
+console.log(names.sort(phonebookAlemao.compare).join(", "));
+// imprime "Hochberg, Hönigswald, Holzman"
+
+ +

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

+ +
var dicionarioAlemao = new Intl.Collator("de-DE-u-co-dict");
+
+// como se ordenasse ["Hochberg", "Honigswald", "Holzman"]:
+console.log(names.sort(dicionarioAlemao.compare).join(", "));
+// imprime "Hochberg, Holzman, Hönigswald"
+
+ +

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

+ +
{{PreviousNext("Web/JavaScript/Guide/Numbers_and_dates", "Web/JavaScript/Guide/Regular_Expressions")}}
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 deleted file mode 100644 index 1dccaeef2e..0000000000 --- a/files/pt-br/web/javascript/guide/trabalhando_com_objetos/index.html +++ /dev/null @@ -1,494 +0,0 @@ ---- -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 ---- -

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

- -

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

- -

Visão geral de objetos

- -

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

- -

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

- -

Objetos e propriedades

- -

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

- -
-
nomeDoObjeto.nomeDaPropriedade
-
-
- -

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

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

Propriedades não definidas de um objeto são {{jsxref("undefined")}} (e não {{jsxref("null")}}).

- -
meuCarro.semPropriedade; //undefined
- -

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

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

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

- -
var meuObj = new Object(),
-    str = "minhaString",
-    aleat = Math.random(),
-    obj = new Object();
-
-meuObj.tipo               = "Sintaxe de ponto";
-meuObj["data de criacao"] = "String com espaco";
-meuObj[str]               = "valor de String";
-meuObj[aleat]             = "Numero Aleatorio";
-meuObj[obj]               = "Objeto";
-meuObj[""]                = "Mesmo uma string vazia";
-
-console.log(meuObj);
-
- -

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

- -
-
var nomeDaPropriedade = "fabricacao";
-meuCarro[nomeDaPropriedade] = "Ford";
-
-nomeDaPropriedade = "modelo";
-meuCarro[nomeDaPropriedade] = "Mustang";
-
-
- -

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

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

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

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

Objetos: tudo

- -

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

- -

Enumerando todas as propriedades de um objeto

- -

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

- - - -

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:

- -
function listarTodasAsPropriedades(o){
-	var objectoASerInspecionado;
-	var resultado = [];
-
-	for(objectoASerInspecionado = o; objectoASerInspecionado !== null; objectoASerInspecionado = Object.getPrototypeOf(objectoASerInspecionado)){
-		resultado = resultado.concat(Object.getOwnPropertyNames(objectoASerInspecionado));
-	}
-
-	return resultado;
-}
-
- -

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

- -

Criando novos objetos

- -

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

- -

Usando inicializadores de objeto

- -

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

- -

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

- -
var obj = { propriedade_1:   valor_1,   // propriedade_# pode ser um identificador...
-            2:            valor_2,   // ou um numero...
-            // ...,
-            "propriedade n": valor_n }; // ou uma string
-
- -

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

- -

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

- -

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

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

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

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

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

- -

Usando uma função construtora

- -

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

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

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

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

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

- -

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

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

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

- -

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

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

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

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

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

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

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

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

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

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

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

- -
carro2.dono
-
- -

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

- -
carro1.cor = "preto";
-
- -

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

- -

Usando o método Object.create

- -

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

- -
// Encapsulamento das propriedades e métodos de Animal
-var Animal = {
-  tipo: "Invertebrados", // Propriedades de valores padrão
-  qualTipo : function() {  // Método que ira mostrar o tipo de Animal
-    console.log(this.tipo);
-  }
-}
-
-// Cria um novo tipo de animal chamado animal1
-var animal1 = Object.create(Animal);
-animal1.qualTipo(); // Saída:Invertebrados
-
-// Cria um novo tipo de animal chamado Peixes
-var peixe = Object.create(Animal);
-peixe.tipo = "Peixes";
-peixe.qualTipo(); // Saída: Peixes
- -

Herança

- -

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

- -

Indexando Propriedades de Objetos

- -

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

- -

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

- -

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

- -

Definindo propriedades para um tipo de objeto

- -

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

- -
Carro.prototype.cor = null;
-carro1.cor = "preto";
-
- -

Consulte a propriedade prototype do objeto Function na Referência JavaScript  para mais informações.

- -

Definindo métodos

- -

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

- -
nomeDoObjeto.nomedometodo = nome_da_funcao;
-
-var meuObjeto = {
-  meuMetodo: function(parametros) {
-    // ...faça algo
-  }
-};
-
- -

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

- -

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

- -
objeto.nomedometodo(parametros);
-
- -

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

- -
function mostreCarro() {
-  var resultado = "Um belo " + this.ano + " " + this.fabricacao
-    + " " + this.modelo;
-  pretty_print(resultado);
-}
-
- -

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

- -

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

- -
this.mostreCarro = mostreCarro;
-
- -

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

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

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

- -
carro1.mostreCarro();
-carro2.mostreCarro();
-
- -

Usando this para referências de objetos

- -

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

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

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

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

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

- -

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

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

Definindo getters e setters

- -

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

- -

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

- -
var o = {
-  a: 7,
-  get b() {
-    return this.a + 1;
-  },
-  set c(x) {
-    this.a = x / 2
-  }
-};
-
-console.log(o.a); // 7
-console.log(o.b); // 8
-o.c = 50;
-console.log(o.a); // 25
- -

As propriedades do objeto o são:

- - - -

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

- -

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

- -

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

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

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

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

A principio, getters e setters podem ser ou

- - - -

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

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

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

- -
var o = { a:0 }
-
-Object.defineProperties(o, {
-    "b": { get: function () { return this.a + 1; } },
-    "c": { set: function (x) { this.a = x / 2; } }
-});
-
-o.c = 10 // Roda o setter, que associa 10 / 2 (5) para a propriedade 'a'
-console.log(o.b) // Roda o getter, que yields a + 1 ou 6
-
- -

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

- -

Removendo propriedades

- -

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

- -
//Criando um novo objeto, myobj, com duas propriedades, a e b.
-var myobj = new Object;
-myobj.a = 5;
-myobj.b = 12;
-
-//Removendo a propriedade a, deixando myobj com apenas a propriedade b.
-delete myobj.a;
-console.log ("a" in myobj) // yields "false"
-
- -

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

- -
g = 17;
-delete g;
-
- -

Comparando Objetos

- -

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

- -
// Duas variáveis, dois objetos distintos com as mesmas propriedades
-var fruit = {name: "apple"};
-var fruitbear = {name: "apple"};
-
-fruit == fruitbear // return false
-fruit === fruitbear // return false
- -
// Duas variáveis, um único objeto
-var fruit = {name: "apple"};
-var fruitbear = fruit;  // assign fruit object reference to fruitbear
-
-// Here fruit and fruitbear are pointing to same object
-fruit == fruitbear // return true
-fruit === fruitbear // return true
- -

Para mais informações sobre comparaçāo de operadores, veja Operadores de comparaçāo.

- -

Veja também

- - - -
{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}
diff --git a/files/pt-br/web/javascript/guide/usando_promises/index.html b/files/pt-br/web/javascript/guide/usando_promises/index.html deleted file mode 100644 index a0dd09c8c2..0000000000 --- a/files/pt-br/web/javascript/guide/usando_promises/index.html +++ /dev/null @@ -1,269 +0,0 @@ ---- -title: Usando promises -slug: Web/JavaScript/Guide/Usando_promises -tags: - - Guía - - Intermediário - - JavaScript - - Promise - - Promises -translation_of: Web/JavaScript/Guide/Using_promises ---- -
{{jsSidebar("JavaScript Guide")}}{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}
- -

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.

- -

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

- -

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

- -
function successCallback(result) {
-  console.log("It succeeded with " + result);
-}
-
-function failureCallback(error) {
-  console.log("It failed with " + error);
-}
-
-doSomething(successCallback, failureCallback);
- -

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

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

…ou simplesmente:

- -
doSomething().then(successCallback, failureCallback);
- -

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

- -

Garantias

- -

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

- - - -

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

- - - -

Encadeamento

- -

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 cadeia de promises.

- -

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

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

ou

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

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

- -

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

- -

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

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

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

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

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

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

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

- -

Encadeando depois de um catch

- -

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

- -
new Promise((resolve, reject) => {
-    console.log('Initial');
-
-    resolve();
-})
-.then(() => {
-    throw new Error('Something failed');
-
-    console.log('Do this');
-})
-.catch(() => {
-    console.log('Do that');
-})
-.then(() => {
-    console.log('Do this whatever happened before');
-});
-
- -

Isso vai produzir o seguinte texto:

- -
Initial
-Do that
-Do this whatever happened before
-
- -

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

- -

Propagação de erros

- -

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

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

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:

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

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

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

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

- -

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

- -

Criando uma Promise em torno de uma callback API antiga

- -

Uma {{jsxref("Promise")}} pode ser criada do zero utilizando o seu construtor. Isto deve ser necessário apenas para o envolvimento de APIs antigas.

- -

Em um mundo ideal, todas as funções 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:

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

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

- -

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:

- -
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
-
-wait(10000).then(() => saySomething("10 seconds")).catch(failureCallback);
-
- -

Basically, the promise constructor takes an executor function that lets us resolve or reject a promise manually. Since setTimeout doesn't really fail, we left out reject in this case.

- -

Basicamente, um construtor de promises pega uma função executora que nos deixa resolver ou rejeitar uma promise manualmente. Desde que setTimeout não venha a falhar, nos deixamos a rejeição de fora nesse caso

- -

Composição

- -

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

- -

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

- -

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

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

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

- -

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

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

A função composeAsync aceitará qualquer número de funções como argumentos e retornará uma nova função que aceita um valor 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.

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

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

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

Cronometragem

- -

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

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

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:

- -

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

- -
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
-
-wait().then(() => console.log(4));
-Promise.resolve().then(() => console.log(2)).then(() => console.log(3));
-console.log(1); // 1, 2, 3, 4
-
- -

Ver também

- - - -

{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}

diff --git a/files/pt-br/web/javascript/guide/using_promises/index.html b/files/pt-br/web/javascript/guide/using_promises/index.html new file mode 100644 index 0000000000..a0dd09c8c2 --- /dev/null +++ b/files/pt-br/web/javascript/guide/using_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 +--- +
{{jsSidebar("JavaScript Guide")}}{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}
+ +

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.

+ +

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

+ +

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

+ +
function successCallback(result) {
+  console.log("It succeeded with " + result);
+}
+
+function failureCallback(error) {
+  console.log("It failed with " + error);
+}
+
+doSomething(successCallback, failureCallback);
+ +

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

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

…ou simplesmente:

+ +
doSomething().then(successCallback, failureCallback);
+ +

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

+ +

Garantias

+ +

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

+ + + +

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

+ + + +

Encadeamento

+ +

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 cadeia de promises.

+ +

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

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

ou

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

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

+ +

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

+ +

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

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

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

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

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

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

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

+ +

Encadeando depois de um catch

+ +

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

+ +
new Promise((resolve, reject) => {
+    console.log('Initial');
+
+    resolve();
+})
+.then(() => {
+    throw new Error('Something failed');
+
+    console.log('Do this');
+})
+.catch(() => {
+    console.log('Do that');
+})
+.then(() => {
+    console.log('Do this whatever happened before');
+});
+
+ +

Isso vai produzir o seguinte texto:

+ +
Initial
+Do that
+Do this whatever happened before
+
+ +

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

+ +

Propagação de erros

+ +

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

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

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:

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

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

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

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

+ +

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

+ +

Criando uma Promise em torno de uma callback API antiga

+ +

Uma {{jsxref("Promise")}} pode ser criada do zero utilizando o seu construtor. Isto deve ser necessário apenas para o envolvimento de APIs antigas.

+ +

Em um mundo ideal, todas as funções 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:

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

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

+ +

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:

+ +
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
+
+wait(10000).then(() => saySomething("10 seconds")).catch(failureCallback);
+
+ +

Basically, the promise constructor takes an executor function that lets us resolve or reject a promise manually. Since setTimeout doesn't really fail, we left out reject in this case.

+ +

Basicamente, um construtor de promises pega uma função executora que nos deixa resolver ou rejeitar uma promise manualmente. Desde que setTimeout não venha a falhar, nos deixamos a rejeição de fora nesse caso

+ +

Composição

+ +

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

+ +

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

+ +

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

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

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

+ +

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

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

A função composeAsync aceitará qualquer número de funções como argumentos e retornará uma nova função que aceita um valor 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.

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

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

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

Cronometragem

+ +

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

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

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:

+ +

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

+ +
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
+
+wait().then(() => console.log(4));
+Promise.resolve().then(() => console.log(2)).then(() => console.log(3));
+console.log(1); // 1, 2, 3, 4
+
+ +

Ver também

+ + + +

{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Iterators_and_Generators")}}

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 deleted file mode 100644 index 7920ee6b1a..0000000000 --- a/files/pt-br/web/javascript/guide/values,_variables,_and_literals/index.html +++ /dev/null @@ -1,601 +0,0 @@ ---- -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 ---- -

{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

- -

Este capítulo trata sobre a sintaxe básica do JavaScript, declarações de variáveis, tipos de dados e literais.

- -

Sintaxe básica

- -

JavaScript pega emprestado a maior parte de sua sintaxe do Java, mas também é influenciado por Awk, Perl e Python.

- -

JavaScript é case-sensitive e usa o conjunto de caracteres Unicode. Por exemplo, a palavra Früh (que significa "cedo" em Alemão) pode ser usada como nome de variável.

- -
var Früh = "foobar";
- -

Mas a variável früh não é a mesma que Früh porque JavaScript é case sensitive.

- -

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 (ASI) 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 gramática léxica do JavaScript.

- -

Comentários

- -

A sintaxe dos comentários em JavaScript é semelhante como em C++ e em muitas outras linguagens:

- -
// comentário de uma linha
-
-/* isto é um comentário longo
-   de múltiplas linhas.
- */
-
-/* Você não pode, porém, /* aninhar comentários */ SyntaxError */
- -

Declarações

- -

Existem três tipos de declarações em JavaScript.

- -
-
{{jsxref("Statements/var", "var")}}
-
Declara uma variável, opcionalmente, inicializando-a com um valor.
-
{{experimental_inline}} {{jsxref("Statements/let", "let")}}
-
Declara uma variável local de escopo do bloco, opcionalmente, inicializando-a com um valor.
-
{{experimental_inline}} {{jsxref("Statements/const", "const")}}
-
Declara uma constante de escopo de bloco, apenas de leitura.
-
- -

Variáveis

- -

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.

- -

Um identificador JavaScript deve começar com uma letra, underline (_), ou cifrão ($); 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).

- -

Você pode usar a ISO 8859-1 ou caracteres Unicode tal como os identificadores å e ü. Você pode também usar as sequências de escape Unicode como caracteres e identificadores.

- -

Alguns exemplos de nomes legais são Numeros_visitas, temp99, e _nome.

- -

Declarando variáveis

- -

Você pode declarar uma variável de três formas:

- - - -

Classificando variáveis

- -

Uma variável declarada usando a declaração var ou let sem especificar o valor inicial tem o valor  {{jsxref("undefined")}}.

- -

Uma tentativa de acessar uma variável não declarada resultará no lançamento de uma exceção {{jsxref("ReferenceError")}}:

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

Você pode usar undefined 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 if será avaliada como verdadeira (true).

- -
var input;
-if(input === undefined){
-  facaIsto();
-} else {
-  facaAquilo();
-}
-
- -

O valor undefined se comporta como falso (false), quando usado em um contexto booleano. Por exemplo, o código a seguir executa a função myFunction devido o elemento myArray ser undefined:

- -
var myArray = [];
-if (!myArray[0]) myFunction();
-
- -

O valor undefined converte-se para NaN quando usado no contexto numérico.

- -
var a;
-a + 2;  // Avaliado como NaN
-
- -

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:

- -
var n = null;
-console.log(n * 32); // a saída para o console será 0.
-
- -

Escopo de variável

- -

Quando você declara uma váriavel fora de qualquer função, ela é chamada de variável global, 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 local,  pois ela está disponível somente dentro dessa função.

- -

JavaScript antes do ECMAScript 6 não possuía escopo de declaração de bloco; pelo contrário, uma variável declarada dentro de um bloco de uma função é uma variável local (ou contexto global) do bloco que está inserido a função. Por exemplo o código a seguir exibirá 5, porque o escopo de x está na função (ou contexto global) no qual x é declarado, não o bloco, que neste caso é a declaração if

- -
if (true) {
-  var x = 5;
-}
-console.log(x);  // 5
-
- -

Esse comportamento é alterado, quando usado a declaração let introduzida pelo ECMAScript 6.

- -
if (true) {
-  let y = 5;
-}
-console.log(y);  // ReferenceError: y não está definido
-
- -

Variável de elevação

- -

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 hoisting; 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 undefined. Então, mesmo se você usar ou referir a variável e depois declará-la e inicializá-la, ela ainda retornará undefined.

- -
/**
- * 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";
-})();
-
- -

Os exemplos acima serão interpretados como:

- -
/**
- * 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";
-})();
-
- -

Devido o hoisting, todas as declarações var 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.

- -

Variáveis Globais

- -

Variáveis globais são propriedades do objeto global. Em páginas web o objeto global é a {{domxref("window")}}, assim você pode configurar e acessar variáveis globais utilizando a sintaxe window.variavel. 

- -

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 parent.phoneNumber.

- -

Constantes

- -

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.

- -
const PI = 3.14;
-
- -

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.

- -

As regras de escopo para as constantes são as mesmas para as váriaveis let de escopo de bloco. Se a palavra-chave const for omitida, presume-se que o identificador represente uma variável.

- -

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: 

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

Estrutura de dados e tipos

- -

Tipos de dados

- -

O mais recente padrão ECMAScript define sete tipos de dados:

- - - -

Embora esses tipos de dados sejam uma quantidade relativamente pequena, eles permitem realizar funções úteis em suas aplicações.  {{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.

- -

Conversão de tipos de dados

- -

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:

- -
var answer = 42;
-
- -

E depois, você pode atribuir uma string para a mesma variável, por exemplo:

- -
answer = "Obrigado pelos peixes...";
-
- -

Devido JavaScript ser dinamicamente tipado, essa declaração não gera uma mensagem de erro.

- -

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:

- -
x = "A resposta é " + 42 // "A resposta é 42"
-y = 42 + " é a resposta" // "42 é a resposta"
-
- -

Nas declarações envolvendo outros operadores,  JavaScript não converte valores numérico para strings. Por exemplo:

- -
"37" - 7 // 30
-"37" + 7 // "377"
-
- -

Convertendo strings para números

- -

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.

- - - -

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.

- -

Uma método alternativo de conversão de um número em forma de string é com o operador + (operador soma):

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

Literais

- -

Você usa literais para representar valores em JavaScript. Estes são valores fixados, não variáveis, que você literalmente insere em seu script. Esta seção descreve os seguintes tipos literais:

- - - -

Array literal

- -

Um array literal é uma lista de zero ou mais expressões, onde cada uma delas representam um elemento do array, inseridas entre colchetes ([]). 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.

- -

O exemplo a seguir cria um array coffees com três elementos e um comprimento de três:

- -
var coffees = ["French Roast", "Colombian", "Kona"];
-
- -
-

Nota : Um array literal é um tipo de inicializador de objetos. Veja Usando inicializadores de Objetos.

-
- -

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.

- -

Array literal são também um array de objetos. Veja  {{jsxref("Array")}} e Coleções indexadas para detalhes sobre array de objetos.

- -

Vírgulas extras em array literal

- -

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 undefined para os elementos não especificados. O exemplo a seguir cria um array chamado fish:

- -
var fish = ["Lion", , "Angel"];
-
- -

Esse array tem dois elementos com valores e um elemento vazio (fish[0] é "Lion", fish[1] é undefined, e fish[2] é "Angel" ).

- -

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 myList[3]. Todas as outras vírgulas na lista indicam um novo elemento.

- -
-

Nota : Vírgulas à direita podem criar erros em algumas versões de navegadores web antigos, é recomendável removê-las.

-
- -
var myList = ['home', , 'school', ];
-
- -

No exemplo a seguir, o comprimento do array é quatro, e myList[0] e myList[2] são undefined.

- -
var myList = [ , 'home', , 'school'];
-
- -

No exemplo a seguir, o comprimento do array é quatro, e myList[1] e myList[3] são undefined. Apenas a última vírgula é ignorada.

- -
var myList = ['home', , 'school', , ];
-
- -

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 undefined vai aumentar a clareza do código, e consequentemente na sua manutenção.

- -

Literais Boolean

- -

O tipo Boolean tem dois valores literal: true e false.

- -

Não confunda os valores primitivos Boolean true e false com os valores true e false do objeto Boolean. O objeto Boolean é um invólucro em torno do tipo de dado primitivo. Veja {{jsxref("Boolean")}} para mais informação.

- -

Inteiros

- -

Inteiros podem ser expressos em decimal (base 10), hexadecimal (base 16), octal (base 8) e binário (base 2).

- - - -

Alguns exemplos de inteiros literal são:

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

Para maiores informações, veja Literais numérico na referência Léxica.

- -

Literais de ponto flutuante

- -

Um literal de ponto flutuante pode ter as seguintes partes:

- - - -

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").

- -

Mais sucintamente, a sintaxe é:

- -
[(+|-)][digitos][.digitos][(E|e)[(+|-)]digitos]
-
- -

Por exemplo:

- -
3.1415926
--.123456789
--3.1E+12
-.1e-23
-
- -

Objeto literal

- -

Um objeto literal é uma lista de zero ou mais pares de nomes de propriedades e valores associados de um objeto, colocado entre chaves ({}). 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 { será interpretado como início de um bloco.

- -

Segue um exemplo de um objeto literal. O primeiro elemento do objeto carro define uma propriedade, meuCarro, e atribui para ele uma nova string, "Punto"; o segundo elemento, a propriedade getCarro, é imediatamente atribuído o resultado de chamar uma função (tipoCarro("Fiat")); o terceiro elemento, a propriedade especial, usa uma variável existente (vendas).

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

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.

- -
var carro = { carros: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
-
-console.log(carro.carros.b); // Jeep
-console.log(carro[7]); // Mazda
-
- -

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 (.), mas podem ser acessadas e definidas com a notação do tipo array ("[]").

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

Observe:

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

 

- -

Expressão Regex Literal

- -

Um regex literal é um padrão entre barras. A seguir um exemplo de regex literal.

- -
var re = /ab+c/;
- -

String Literal

- -

Uma string literal são zero ou mais caracteres dispostos em aspas duplas (") ou aspas simples ('). 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.

- -
"foo"
-'bar'
-"1234"
-"um linha \n outra linha"
-"John's cat"
-
- -

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 String.length com uma string literal:

- -
console.log("John's cat".length)
-// Irá exibir a quantidade de caracteres na string incluindo o espaço em branco.
-// Nesse caso, 10 caracteres.
-
- -

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.

- -

Uso de caracteres especiais em string

- -

Além dos caracteres comuns, você também pode incluir caracteres especiais em strings, como mostrado no exemplo a seguir.

- -
"uma linha \n outra linha"
-
- -

A tabela a seguir lista os caracteres especiais que podem ser usados em strings no JavaScript.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Tabela: Caracteres especiais no JavaScript
CaracterDescrição
\0Byte nulo
\bBackspace
\fAlimentador de formulário
\nNova linha
\rRetorno do carro
\tTabulação
\vTabulação vertical
\'Apóstrofo ou aspas simples
\"Aspas dupla
\\Caractere de barra invertida
\XXX -

Caractere com a codificação Latin-1 especificada por três dígitos octal XXX entre 0 e 377. Por exemplo, \251 é sequência octal para o símbolo de direitos autorais.

-
\xXX -

Caractere com a codificação Latin-1 especificada por dois dígitos hexadecimal XX entre 00 e FF. Por exemplo, \xA9 é a sequência hexadecimal para o símbolo de direitos autorais.

-
\uXXXX -

Caractere Unicode especificado por quatro dígitos hexadecimal XXXX. Por exemplo, \u00A9 é a sequência Unicode para o símbolo de direitos autorais. Veja sequências de escape Unicode.

-
- -

Caracteres de escape

- -

Para caracteres não listados na tabela, se precedidos de barra invertida ela é ignorada, seu uso está absoleto e deve ser ignorado.

- -

Você pode inserir uma aspa dentro de uma string precendendo-a com uma barra invertida. Isso  é conhecido como escaping das aspas. Por exemplo:

- -
var quote = "Ele lê \"The Cremation of Sam McGee\" de R.W. Service.";
-console.log(quote);
-
- -

O resultado disso seria:

- -
Ele lê "The Cremation of Sam McGee" de R.W. Service.
-
- -

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 c:\temp para uma string, utilize o seguinte:

- -
var home = "c:\\temp";
-
- -

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.

- -
var str = "esta string \
-está quebrada \
-em várias\
-linhas."
-console.log(str);   // esta string está quebrada em várias linhas.
-
- -

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:

- -
var poema =
-"Rosas são vermelhas\n\
-Violetas são azuis,\n\
-Esse seu sorriso\n\
-é o que me seduz. (Lucas Pedrosa)"
-
- -

Mais informação

- -

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:

- - - -

No próximo capítulo, veremos a construção de controle de fluxos e manipulação de erro.

- -

{{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

diff --git a/files/pt-br/web/javascript/guide/working_with_objects/index.html b/files/pt-br/web/javascript/guide/working_with_objects/index.html new file mode 100644 index 0000000000..1dccaeef2e --- /dev/null +++ b/files/pt-br/web/javascript/guide/working_with_objects/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 +--- +

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

+ +

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

+ +

Visão geral de objetos

+ +

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

+ +

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

+ +

Objetos e propriedades

+ +

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

+ +
+
nomeDoObjeto.nomeDaPropriedade
+
+
+ +

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

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

Propriedades não definidas de um objeto são {{jsxref("undefined")}} (e não {{jsxref("null")}}).

+ +
meuCarro.semPropriedade; //undefined
+ +

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

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

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

+ +
var meuObj = new Object(),
+    str = "minhaString",
+    aleat = Math.random(),
+    obj = new Object();
+
+meuObj.tipo               = "Sintaxe de ponto";
+meuObj["data de criacao"] = "String com espaco";
+meuObj[str]               = "valor de String";
+meuObj[aleat]             = "Numero Aleatorio";
+meuObj[obj]               = "Objeto";
+meuObj[""]                = "Mesmo uma string vazia";
+
+console.log(meuObj);
+
+ +

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

+ +
+
var nomeDaPropriedade = "fabricacao";
+meuCarro[nomeDaPropriedade] = "Ford";
+
+nomeDaPropriedade = "modelo";
+meuCarro[nomeDaPropriedade] = "Mustang";
+
+
+ +

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

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

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

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

Objetos: tudo

+ +

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

+ +

Enumerando todas as propriedades de um objeto

+ +

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

+ + + +

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:

+ +
function listarTodasAsPropriedades(o){
+	var objectoASerInspecionado;
+	var resultado = [];
+
+	for(objectoASerInspecionado = o; objectoASerInspecionado !== null; objectoASerInspecionado = Object.getPrototypeOf(objectoASerInspecionado)){
+		resultado = resultado.concat(Object.getOwnPropertyNames(objectoASerInspecionado));
+	}
+
+	return resultado;
+}
+
+ +

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

+ +

Criando novos objetos

+ +

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

+ +

Usando inicializadores de objeto

+ +

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

+ +

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

+ +
var obj = { propriedade_1:   valor_1,   // propriedade_# pode ser um identificador...
+            2:            valor_2,   // ou um numero...
+            // ...,
+            "propriedade n": valor_n }; // ou uma string
+
+ +

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

+ +

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

+ +

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

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

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

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

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

+ +

Usando uma função construtora

+ +

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

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

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

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

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

+ +

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

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

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

+ +

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

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

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

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

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

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

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

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

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

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

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

+ +
carro2.dono
+
+ +

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

+ +
carro1.cor = "preto";
+
+ +

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

+ +

Usando o método Object.create

+ +

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

+ +
// Encapsulamento das propriedades e métodos de Animal
+var Animal = {
+  tipo: "Invertebrados", // Propriedades de valores padrão
+  qualTipo : function() {  // Método que ira mostrar o tipo de Animal
+    console.log(this.tipo);
+  }
+}
+
+// Cria um novo tipo de animal chamado animal1
+var animal1 = Object.create(Animal);
+animal1.qualTipo(); // Saída:Invertebrados
+
+// Cria um novo tipo de animal chamado Peixes
+var peixe = Object.create(Animal);
+peixe.tipo = "Peixes";
+peixe.qualTipo(); // Saída: Peixes
+ +

Herança

+ +

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

+ +

Indexando Propriedades de Objetos

+ +

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

+ +

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

+ +

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

+ +

Definindo propriedades para um tipo de objeto

+ +

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

+ +
Carro.prototype.cor = null;
+carro1.cor = "preto";
+
+ +

Consulte a propriedade prototype do objeto Function na Referência JavaScript  para mais informações.

+ +

Definindo métodos

+ +

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

+ +
nomeDoObjeto.nomedometodo = nome_da_funcao;
+
+var meuObjeto = {
+  meuMetodo: function(parametros) {
+    // ...faça algo
+  }
+};
+
+ +

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

+ +

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

+ +
objeto.nomedometodo(parametros);
+
+ +

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

+ +
function mostreCarro() {
+  var resultado = "Um belo " + this.ano + " " + this.fabricacao
+    + " " + this.modelo;
+  pretty_print(resultado);
+}
+
+ +

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

+ +

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

+ +
this.mostreCarro = mostreCarro;
+
+ +

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

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

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

+ +
carro1.mostreCarro();
+carro2.mostreCarro();
+
+ +

Usando this para referências de objetos

+ +

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

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

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

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

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

+ +

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

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

Definindo getters e setters

+ +

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

+ +

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

+ +
var o = {
+  a: 7,
+  get b() {
+    return this.a + 1;
+  },
+  set c(x) {
+    this.a = x / 2
+  }
+};
+
+console.log(o.a); // 7
+console.log(o.b); // 8
+o.c = 50;
+console.log(o.a); // 25
+ +

As propriedades do objeto o são:

+ + + +

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

+ +

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

+ +

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

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

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

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

A principio, getters e setters podem ser ou

+ + + +

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

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

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

+ +
var o = { a:0 }
+
+Object.defineProperties(o, {
+    "b": { get: function () { return this.a + 1; } },
+    "c": { set: function (x) { this.a = x / 2; } }
+});
+
+o.c = 10 // Roda o setter, que associa 10 / 2 (5) para a propriedade 'a'
+console.log(o.b) // Roda o getter, que yields a + 1 ou 6
+
+ +

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

+ +

Removendo propriedades

+ +

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

+ +
//Criando um novo objeto, myobj, com duas propriedades, a e b.
+var myobj = new Object;
+myobj.a = 5;
+myobj.b = 12;
+
+//Removendo a propriedade a, deixando myobj com apenas a propriedade b.
+delete myobj.a;
+console.log ("a" in myobj) // yields "false"
+
+ +

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

+ +
g = 17;
+delete g;
+
+ +

Comparando Objetos

+ +

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

+ +
// Duas variáveis, dois objetos distintos com as mesmas propriedades
+var fruit = {name: "apple"};
+var fruitbear = {name: "apple"};
+
+fruit == fruitbear // return false
+fruit === fruitbear // return false
+ +
// Duas variáveis, um único objeto
+var fruit = {name: "apple"};
+var fruitbear = fruit;  // assign fruit object reference to fruitbear
+
+// Here fruit and fruitbear are pointing to same object
+fruit == fruitbear // return true
+fruit === fruitbear // return true
+ +

Para mais informações sobre comparaçāo de operadores, veja Operadores de comparaçāo.

+ +

Veja também

+ + + +
{{PreviousNext("Web/JavaScript/Guide/Regular_Expressions", "Web/JavaScript/Guide/Details_of_the_Object_Model")}}
diff --git a/files/pt-br/web/javascript/inheritance_and_the_prototype_chain/index.html b/files/pt-br/web/javascript/inheritance_and_the_prototype_chain/index.html new file mode 100644 index 0000000000..d6aad53066 --- /dev/null +++ b/files/pt-br/web/javascript/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 +--- +
{{jsSidebar("Advanced")}}
+ +

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 class (a palavra-chave class foi introduzida no ES2015, mas é syntax sugar, o JavaScript permanece baseado em prototype).

+ +

Quando se trata de herança, o JavaScript tem somente um construtor: objetos. Cada objeto tem um link interno para um outro objeto chamado prototype. Esse objeto prototype também tem um atributo prototype, e assim por diante até o que o valor null seja encontrado como sendo o seu prototype. null que, por definição, não tem prototype, e age como um link final nesta cadeia de protótipos (prototype chain).

+ +

Isto muitas vezes é considerado como um dos pontos fracos do JavaScript, mas o modelo de herança prototipal é de fato mais potente do que o modelo clássico. É, por exemplo, relativamente trivial construir um "modelo clássico" (como na implementaçao de class), enquanto o contrário é uma tarefa muito mais difícil.

+ +

N. da T: Como em uma implementação de fila em C, por exemplo.

+ +

Herança com o encadeamento de protótipos

+ +

Propriedades de heranças

+ +

Objetos em JavaScript são "sacos" dinâmicos de propriedades (a que se refere as próprias propriedades) e cada um tem um link para um objeto prototype. Eis o que acontece quando se tenta acessar uma propriedade:

+ +
// Vamos criar um objeto o da função f com suas próprias propriedades a e b:
+let f = function () {
+   this.a = 1;
+   this.b = 2;
+}
+let o = new f(); // {a: 1, b: 2}
+
+// adicionar propriedades no protótipo da função f
+f.prototype.b = 3;
+f.prototype.c = 4;
+
+// 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
+
+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 Link

+ +

Atribuir uma propriedade a um objeto cria uma propriedade nele. A única exceção às regras de obtenção e definição de comportamento é quando há uma propriedade herdada com um getter or a setter.

+ +

Herença de "métodos"

+ +

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(method overriding)!

+ +

Quando uma herança de função é executada, o valor de this aponta para o objeto que herdou as propriedades, não para o objeto prototype onde as propriedades foram escritas originalmente.

+ +
var o = {
+  a: 2,
+  m: function(b){
+    return this.a + 1;
+  }
+};
+
+console.log(o.m()); // 3
+// Ao chamar 'o.m' neste caso, "this" refere-se a 'o'
+
+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'
+// Então, quando 'p' herda a função de 'm' de 'o', 'this.a' representa 'p.a' que é a própria propriedade 'a' de 'p'
+
+
+ +

Maneiras de criar objetos e resultados dos protótipos encadeados

+ +

Objetos criados com sintaxe de construtores

+ +
var o = {a: 1};
+
+// O recém-criado objecto 'o' tem Object.prototype como o seu [[Prototype]]
+// 'o' não tem não tem uma propriedade chamada 'hasOwnProperty'
+// hasOwnProperty é uma propriedade própria de Object.prototype. Então 'o' herda hasOwnProperty de Object.prototype
+
+// Object.prototype tem null como seu protótipo.
+// o ---> Object.prototype ---> null
+
+var a = ["yo", "whadup", "?"];
+
+// Arrays herdam de Array.prototype (que tem métodos como indexOf, forEach, etc.)
+// A cadeia de protótipos se parece com isso:
+// a ---> Array.prototype ---> Object.prototype ---> null
+
+function f(){
+  return 2;
+}
+
+// Funções herdam de Function.prototype (que tem métodos como call, bind, etc.)
+// f ---> Function.prototype ---> Object.prototype ---> null
+
+ +

Com um construtor

+ +

Um "construtor" em JavaScript é "somente" uma função que passa a ser chamada com o operador new.

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

Com Object.create

+ +

ECMAScript 5 introduziu o novo método: Object.create. Invocando este método podemos criar novos objetos. O prototype destes novos objetos é o primeiro argumento do método:

+ +
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, porque não herda de Object.prototype
+
+ +
+

Performace

+ +

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

+ +

Porém, quando estamos interagindo com as propriedades de um objeto, toda propriedade que está na cadeia do prototype (prototype chain) vai ser enumerada.

+ +

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 hasOwnProperty que todos os objetos herdam do Object.prototype.

+ +

hasOwnProperty é a única alternativa em JavaScript que lida com propriedades sem atravessar a cadeia de protótipos.

+ + +
Observação: Não é suficiente apenas verificar se o valor da propriedade é undefined para saber se ela existe. A propriedade pode muito bem existir e não ter sido inicializada, sendo assim o seu valor undefined.
+ +
+

Má Pratica: Estender protótipos nativos

+ +

Um erro frequentemente cometido por programadores é estender um Object.prototype.

+ +

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. 

+ +

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.

+
+ +
+

Conclusão

+ +

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

+ + +
+
+ +

{{ languages( {"zh-cn": "zh-cn/JavaScript/Guide/Inheritance_and_the_prototype_chain" } ) }}

diff --git a/files/pt-br/web/javascript/introduction_to_object-oriented_javascript/index.html b/files/pt-br/web/javascript/introduction_to_object-oriented_javascript/index.html deleted file mode 100644 index aaab9150b3..0000000000 --- a/files/pt-br/web/javascript/introduction_to_object-oriented_javascript/index.html +++ /dev/null @@ -1,352 +0,0 @@ ---- -title: Introdução ao JavaScript Orientado a Objeto -slug: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript -tags: - - Construtor - - Encapsular - - Herança - - Intermediário - - Membros - - Objeto - - Orientado a Objeto - - POO -translation_of: Learn/JavaScript/Objects -translation_of_original: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript ---- -

JavaScript tem fortes capacidades de programação orientada a objetos, apesar de ocorrerem algumas discussões devido às diferenças da orientação a objetos no JavaScript em comparação com outras linguagens.

- -

Esse artigo começa com uma introdução à programação orientada a objetos, em seguida, revisa o modelo de objetos em JavaScript e, por fim, demonstra conceitos de programação orientada a objetos no JavaScript.

- -

Revisão do Javascript

- -

Se você não se sente confiante com conceitos de JavaScript como variáveis, tipos, funções e escopo, você pode ler sobre estes tópicos em Uma reintrodução ao JavaScript. Você também pode consultar o Core JavaScript 1.5 Guide.

- -

Programação Orientada a Objetos

- -

Programação Orientada a Objetos é um paradigma de programação que usa abstração para criar modelos baseados no mundo real. POO usa várias técnicas vindas de paradigmas previamente estabelecidos, incluindo modularidade, polimorfismo e encapsulamento. Atualmente, muitas linguagens de programação populares (como Java, JavaScript, C #, C ++, Python, PHP, Ruby e Objective-C) permitem a programação orientada a objetos (POO).

- -

A POO pode ser vista como o projeto de software utilizando uma coleção de objetos em cooperação, em oposição a uma vista tradicional, em que um programa pode ser visto como uma série de funções, ou simplesmente como uma lista de instruções para o computador. Em OOP, cada objeto é capaz de receber mensagens, processar dados e envio de mensagens para outros objetos. Cada objeto pode ser visto como uma pequena máquina independente, com um papel ou responsabilidade distinta.

- -

A POO se destina a promover uma maior flexibilidade e facilidade de manutenção na aplicação, e é muito popular em engenharia de softwares de grande escala. Em virtude de sua forte ênfase na modularidade, código orientado a objetos destina-se a ser mais simples de desenvolver e mais fácil de entender mais tarde, prestando-se a uma análise mais direta, codificação e compreensão de situações e procedimentos mais complexos do que nos métodos de programação menos modulares.

- -

Terminologia

- -
-
Namespaces
-
Um recipiente que permite empacotar todas as funcionalidades em um nome único e específico da aplicação.
-
- -
-
Classe
-
Define as características do objeto. Uma classe é uma definição modelo das propriedades e métodos de um objeto.
-
Objeto
-
Um exemplar de uma classe.
-
Atributo
-
Uma característica do objeto, como cor, modelo, fabricante se estivemos representando um veículo, por exemplo.
-
Método
-
Uma ação do objeto, como ligar, desligar, frear se estivemos representando um veículo, por exemplo. É uma subrotina ou função associada a uma classe.
-
Construtor
-
Um método chamado assim que um novo exemplar do objeto for criado. Ele geralmente tem o mesmo nome da classe que o contém.
-
Herança
-
Uma classe pode herdar características de outra classe.
-
Encapsulamento
-
Uma maneira de agrupar os dados e os métodos que usam os dados.
-
Abstração
-
A conjunção de herança complexa, métodos, propriedades de um objeto devem refletir adequadamente um modelo da realidade.
-
Polimorfismo
-
Diferentes classes podem definir o mesmo método ou propriedade.
-
- -

Para uma descrição mais extensiva sobre programação orientada a objetos, veja Orientação a objetos na Wikipédia.

- -

Programação Baseada em Protótipos

- -

Programação baseada em protótipos é um estilo de programação orientada a objetos na qual não temos presença de classes. Em vez disso, a reutilização de comportamento (equivalente à herança das linguagens baseadas em classes) é realizada através de um processo de decorar (ou expandir) objetos existentes que servem como protótipos. Este modelo também é conhecido como sem classes, orientado a protótipo, ou programação baseada em exemplares.

- -

O exemplo original (e o mais canônico ) de uma linguagem baseada em protótipo é a linguagem de programação Self desenvolvida por David Ungar e Randall Smith.  No entanto, o estilo de programação sem classes tem se tornado mais popular recentemente, e foi adotado por linguagens de programação como JavaScript, Cecil, NewtonScript, lo, MOO, REBOL, Kevo, Squeak (quando se utiliza o framework Viewer para manipular componentes do Morphic) e várias outras.

- -

Programação Orientada a Objetos em Javascript

- -

Namespaces

- -

Um namespace é um recipiente que permite aos desenvolvedores agrupar funcionalidades em um único nome específico para uma aplicação. Em JavaScript, um namespace é simplesmente outro objeto contendo métodos, propriedades e objetos.

- -
-

Nota: É importante notar que, em Javascript, não existe diferença a nível da linguagem entre objetos normais e namespaces. Isso é diferente do que ocorre em muitas outras linguagens orientadas a objetos, e pode ser causa de confusão entre programadores(as) JavaScript novatos(as).

-
- -

A ideia por trás de criar um namespace em JavaScript é simples: cria-se um objeto global e todas as variáveis, métodos e chamadas de função tornam-se propriedades daquele objeto. O uso de namespaces também reduz a chance de conflitos de nomes em uma aplicação, já que os objetos de cada aplicação são propriedades de um objeto global definido pela aplicação.

- -

Vamos criar um objeto global chamado MEUAPP:

- -
// namespaces global
-var MEUAPP = MEUAPP || {};
- -

No código acima, primeiro verificamos se MEUAPP já está definido (no mesmo arquivo ou em outro). Se estiver, usamos o objeto MEUAPP global existente. Caso contrário, criamos um objeto vazio chamado MEUAPP, que encapsula métodos, variáveis e objetos

- -

Podemos também criar sub-espaços de nomes.

- -
// sub namespaces
-MEUAPP.eventos = {};
- -

A seguir, temos a sintaxe para criar um namespace e adicionar variáveis, funções e um método:

- -
// Criando um recipiente chamado MEUAPP.metodosEmComum
-// para métodos e propriedades em comum
-
-MEUAPP.metodosEmComum = {
-
-  regexParaNome: "", // definindo uma expressao regular
-                     // para validação de nomes
-
-  regexParaTelefone: "",  // define uma expressao regular para
-                          //validacao de numeros de telefone
-}
-
-// Objeto junto a declaracoes de método
-
-MEUAPP.eventos = {
-
-    adicionarTratador: function(elemento, tipo, funcao) {
-
-    // codigos
-
-    },
-
-    removerTratador: function(elemento, tipo, funcao) {
-
-    // codigos
-
-    },
-
-    obterEvento: function(e) {
-
-    // codigos
-
-    }
-
-    // é possível adicionar outros métodos e propriedades
-
-}
-
-// Sintaxe para usar o método adicionarTratador:
-
-MEUAPP.eventos.adicionarTratador("youre1", "tipo", tratador);
- -

Objetos inclusos por padrão

- -

JavaScript tem vários objetos incluídos em seu núcleo; por exemplo, objetos como Math, Object, Array, e String. O exemplo abaixo mostra como usar o objeto Math para obter um número aleatório usando seu método random().

- -
console.log(Math.random());
-
- -
Nota: Este e todos os exemplos a seguir presumem que uma função console.log() está definida globalmente. A função console.log() não faz parte do JavaScript em si, mas muitos navegadores a implementam para ajudar no processo de depuração.
- -

Veja Core JavaScript 1.5 Reference:Global Objects para a lista dos objetos inclusos por padrão em JavaScript.

- -

Cada objeto em JavaScript é um exemplar do objeto Object e, portanto, herda todas as suas propriedades e métodos.

- -

Objetos Personalizados

- -

A Classe

- -

JavaScript é uma linguagem baseada em protótipos e não contém a declaração class, como vemos em C++ ou Java. Isso, às vezes, causa confusão em programadores(as) acostumados(as) a linguagens com uma declaração para classes. Em vez disto, JavaScript usa funções como classes. Definir uma classe-função é tão fácil quanto definir uma função. No exemplo abaixo, nós definimos uma nova classe chamada Pessoa.

- -
var Pessoa = function () {};
- -

O objeto (exemplar de uma classe)

- -

Para criar um novo exemplar de um objeto obj, usamos a declaração new obj, atribuindo o resultado (que é do tipo obj) a uma variável que será acessada depois.

- -

No exemplo acima, definimos uma classe chamada Pessoa. No exemplo abaixo, criamos dois exemplares (pessoa1 e pessoa2).

- -
var pessoa1 = new Pessoa();
-var pessoa2 = new Pessoa();
-
- -
Nota: Por favor, veja também Object.create para um novo e alternativo método que cria um exemplar não-inicializado.
- -

O Construtor

- -

O construtor é chamado no momento que o exemplar do objeto é criado. O construtor é um método da classe. Em JavaScript, a função serve como o construtor do objeto. Portanto, não há a necessidade de definir explicitamente um método construtor. Toda ação declarada na classe é executada no momento da criação.

- -

O construtor é usado para definir as propriedades do objeto ou para chamar metodos que preparem o objeto para o uso. O acréscimo de métodos e suas definições à classe funciona através do uso uma sintaxe diferente, descrita mais adiante, nesse artigo.

- -

No exemplo abaixo, o construtor da classe Pessoa envia uma mensagem ao log quando um exemplar de Pessoa é criado.

- -
var Pessoa = function () {
-  console.log("exemplar criado");
-}
-
-var pessoa1 = new Pessoa();
-var pessoa2 = new Pessoa();
-
- -

Propriedades (atributos de objetos)

- -

Propriedades são variáveis contidas em uma classe; cada exemplar do objeto tem essas propriedades. Propriedades devem ser definidas no construtor (ou função) da classe, de modo que sejam criados em cada exemplar.

- -

A palavra-chave this, que se refere ao objeto atual, te permite trabalhar com propriedades do lado de dentro da classe. Acessos (leitura ou escrita) uma propriedade do lado de fora da classe são feitos com a sintaxe NomeDoExemplar.Propriedade, assim como em C++, Java e várias outras linguagens. (Dentro da classe, a sintaxe this.Propriedade é usada para obter ou atribuir um valor ao objeto.)

- -
var Pessoa = function(nome) {
-  this.nome = nome;
-  console.log('Exemplar de Pessoa criado');
-};
-
-var pessoa1 = new Pessoa('Alice');
-var pessoa2 = new Pessoa('Bob');
-
-// mostrando as propriedades nome dos objetos
-console.log('pessoa1 é ' + pessoa1.nome); // envia "pessoa1 é Alice" ao log
-console.log('pessoa2 é ' + pessoa2.nome); // envia "pessoa2 é Bob" ao log
- -

Métodos

- -

Métodos são funções (e definidos como funções), mas seguem a mesma lógica das propriedades. Chamar um método é parecido com acessar uma propriedade, mas você coloca () no final do nome do método, possivelmente com argumentos. Para definir um método, atribua uma função a uma propriedade com nome do prototype da classe. Depois disso, você pode chamar o método do objeto usando o mesmo nome ao qual você atribuiu a função.

- -

No exemplo abaixo, definimos e usarmos o método dizerOla() na classe Pessoa .

- -
var Pessoa = function (genero) {
-  this.genero = genero;
-  alert('Pessoa instanciada');
-}
-
-Pessoa.prototype.dizerOla = function()
-{
-  alert ('hello');
-};
-
-var pessoa1 = new Pessoa('Masculino');
-var pessoa2 = new Pessoa('Feminino');
-
-// Chamando o método dizerOla em Pessoa .
-pessoa1.dizerOla(); // hello
-
- -

Em JavaScript métodos são funções normais de objetos que são vinculados a uma classe/objeto como uma propriedade, o que significa que eles podem ser invocados "fora de contexto" . Considere o seguinte exemplo de código: 

- -
function Pessoa(genero) {
-  this.genero = genero;
-}
-
-Pessoa.prototype.dizGenero = function()
-{
-  alert(this.genero);
-};
-
-var pessoa1 = new Pessoa('Masculino');
-var informaGenero = pessoa1.dizGenero;
-
-pessoa1.dizGenero(); // 'Masculino'
-informaGenero(); // undefined
-alert(informaGenero === pessoa1.dizGenero); //true
-alert(informaGenero === Pessoa.prototype.dizGenero); //true
-
- -

Este exemplo demonstra vários conceitos de uma vez. Mostrando que não existem "métodos por objetos " em Javascript as referências ao método apontam para a mesma função, aquela que definimos primeiro usando prototype. JavaScript "liga" o "contexto de objeto" atual à variável especial "this", quando uma função é invocada como um método (ou propriedade para ser exato) de um objeto. Isso equivale a chamar o método "call" do objeto Function, da seguinte maneira:

- -
informaGenero.call(pessoa1); //alerts 'Masculino'
-
- -
Veja mais sobre em Function.call e Function.apply
- -

Herança

- -

Herança é uma maneira de criar uma classe como uma versão especializados de uma ou mais classes (JavaScript suporta apenas herança de classe única). A classe especializada é comumente chamada de filha, e a outra classe é comumente chamada de pai. Em JavaScript você faz isso nomeando uma instância da classe pai para a classe filha, e então especializa-a. Em navegadores modernos você também pode usar Object.create para implementar herança.

- -
-

JavaScript não detecta o  prototype.constructor da classe filha, veja a propriedade Core JavaScript 1.5 Reference:Global Objects:Object:prototype, então devemos declará-la manualmente.

-
- -

No exemplo abaixo, nós definimos a classe Estudante como filha da classe Pessoa. Então redefinimos o método dizOi() e cria o método dizTchau().

- -
// define a classe Pessoa
-function Pessoa() {}
-
-Pessoa.prototype.caminhar = function(){
-  alert ('Estou Caminhando!');
-};
-Pessoa.prototype.dizOi = function(){
-  alert ('Oi!');
-};
-
-// define a classe  Estudante
-function Estudante() {
-  // Chama o método pai
-  Pessoa.call(this);
-}
-
-// herda de Pessoa
-Estudante.prototype = new Pessoa();
-
-// corrige o ponteiro construtor, que aponta para Pessoa
-Estudante.prototype.constructor = Estudante;
-
-// adiciona o método dizOi
-Estudante.prototype.dizOi = function(){
-  alert('Oi, eu sou estudante');
-}
-
-// adiciona o método dizTchau
-Estudante.prototype.dizTchau = function(){
-  alert('tchau');
-}
-
-var estudante1 = new Estudante();
-estudante1.dizOi();
-estudante1.caminhar();
-estudante1.dizTchau();
-
-// checa a herança
-alert(estudante1 instanceof Pessoa); // true
-alert(estudante1 instanceof Estudante); // true
-
- -

Utilizando Object.create a linha de herança deveria ser:

- -
Estudante.prototype = Object.create(Pessoa.prototype);
- -

Encapsulamento

- -

Em exemplo anterior, Estudante não precisava saber como o método caminhar() da classe Pessoa seria implementada, mas ainda pode utilizar esté método; a classe Estudante não possui necessidade explícita de definir o método desde que não queremos alterar-lo. Isso se chama encapsulamento, pelo qual cada classe herda os métodos de seu pai e só precisa definir as coisas que deseja mudar.

- -

Abstração

- -

A Abstração é uma mecânica que permite modelar a parte atual do problema no trabalho.  Isso pode ser alcançado com herança (especialização), ou composição. JavaScript alcança especialização por herança, e composição por deixando instâncias de classes ser os valores de atributos de outros objetos.

- -

A Função de classe do JavaScript é hedar da classe Object (isso demonstra a especialização do modelo). e a propriedade Function.prototype é uma instância de Object (isso demonstra composição)

- -
var foo = function(){};
-alert( 'foo é um Function: ' + (foo instanceof Function) );
-alert( 'foo.prototype é um Object: ' + (foo.prototype instanceof Object) );
-
- -

Polimorfismo

- -

Assim como todos os métodos e propriedades são definidos dentro da propriedade prototype, classes diferentes podem definir métodos com o mesmo nome; os métodos tem como escopo a classe a qual foram definidos, a menos que duas classes possuam uma relação pai-filho. (ex.: uma herda da outra numa cadeia de herança).

- -

Notas

- -

As técnicas apresentadas nesse artigo para implementar programação orientada objetos em JavaScript não são as únicas que podem ser usadas.

- -

As técnicas utilizadas nesse artigo não usam nenhum tipo de hacks, nem tenta implantar teorias de outras linguagens em JavaScript. 

- -

Existem outras técnicas que fazem um uso ainda mais avançado de programação orientada a  objetos em JavaScript, mas estão além desse artigo introdutório.

- -

Referências

- -
    -
  1. Mozilla. "Core JavaScript 1.5 Guide", https://developer.mozilla.org/docs/Web/JavaScript/Guide
  2. -
  3. Wikipedia. "Object-oriented programming", http://en.wikipedia.org/wiki/Object-...ed_programming
  4. -
- -
-

Original Document Information

- - -
- -

Es: https://developer.mozilla.org/es/docs/Introducción_a_JavaScript_orientado_a_objetos 

diff --git "a/files/pt-br/web/javascript/reference/errors/fata_par\303\252nteses_ap\303\263s_lista_argumento/index.html" "b/files/pt-br/web/javascript/reference/errors/fata_par\303\252nteses_ap\303\263s_lista_argumento/index.html" deleted file mode 100644 index 83844d17b5..0000000000 --- "a/files/pt-br/web/javascript/reference/errors/fata_par\303\252nteses_ap\303\263s_lista_argumento/index.html" +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Erro de sintaxe falta ) depois da lista de argumentos -slug: Web/JavaScript/Reference/Errors/Fata_parênteses_após_lista_argumento -translation_of: Web/JavaScript/Reference/Errors/Missing_parenthesis_after_argument_list ---- -
{{jsSidebar("Errors")}}
- -

Mensagem

- -
Erro de sintaxe: Falta ) depois da lista de argumento
-
- -

Tipo de Erro

- -

{{jsxref("Erro de sintaxe")}}.

- -

O que houve de errado?

- -

Ocorreu um erro quando a função foi chamada. Pode ter sido um erro de escrita, falta de operador, ou uma string fora das aspas, por exemplo.

- -

Exemplos

- -

Pela falta do operador "+" para fazer a concatenação da string, o JavaScript esperou um argumento para a função log ser "PI: ". Nesse caso, deveria ser finalizado com parênteses de fechamento ')'.

- -
console.log("PI: " Math.PI);
-// SyntaxError: missing ) after argument list
-
- -

Você pode corrigir a chamada do log adicionand o operador "+":

- -
console.log("PI: " + Math.PI);
-// "PI: 3.141592653589793"
- -

Veja também:

- - diff --git a/files/pt-br/web/javascript/reference/errors/fecha_chaves_esquecida_apos_lista_propriedades/index.html b/files/pt-br/web/javascript/reference/errors/fecha_chaves_esquecida_apos_lista_propriedades/index.html deleted file mode 100644 index b10562516e..0000000000 --- a/files/pt-br/web/javascript/reference/errors/fecha_chaves_esquecida_apos_lista_propriedades/index.html +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: 'SyntaxError: missing } after property list' -slug: Web/JavaScript/Reference/Errors/Fecha_chaves_esquecida_apos_lista_propriedades -tags: - - Erro de Sintaxe - - Erros - - JavaScript - - SyntaxError -translation_of: Web/JavaScript/Reference/Errors/Missing_curly_after_property_list ---- -
{{jsSidebar("Errors")}}
- -

Mensagem

- -
SyntaxError: missing } after property list
-
- -

Tipo de erro

- -

{{jsxref("SyntaxError")}}

- -

O que deu errado?

- -

Aconteceu um engano na sintaxe do inicializador do objeto em algum lugar. Pode ser que você esqueceu de colocar uma chave, mas também pode ser uma vírgula que foi esquecida, por exemplo. Verifique também se alguma chave de finalização ou parêntesis estão em algum lugar que não deveriam estar. Indente ou formate o código de uma maneira legível pode te ajudar a enxergar no meio dessa selva.

- -

Exemplos

- -

Vírgula esquecida

- -

Muitas vezes esquecemos uma vígula no inicializador de objeto:

- -
var obj = {
-  a: 1,
-  b: { minhaProp: 2 }
-  c: 3
-};
-
- -

O código correto deve ser:

- -
var obj = {
-  a: 1,
-  b: { minhaProp: 2 },
-  c: 3
-};
-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/errors/missing_curly_after_property_list/index.html b/files/pt-br/web/javascript/reference/errors/missing_curly_after_property_list/index.html new file mode 100644 index 0000000000..b10562516e --- /dev/null +++ b/files/pt-br/web/javascript/reference/errors/missing_curly_after_property_list/index.html @@ -0,0 +1,52 @@ +--- +title: 'SyntaxError: missing } after property list' +slug: Web/JavaScript/Reference/Errors/Fecha_chaves_esquecida_apos_lista_propriedades +tags: + - Erro de Sintaxe + - Erros + - JavaScript + - SyntaxError +translation_of: Web/JavaScript/Reference/Errors/Missing_curly_after_property_list +--- +
{{jsSidebar("Errors")}}
+ +

Mensagem

+ +
SyntaxError: missing } after property list
+
+ +

Tipo de erro

+ +

{{jsxref("SyntaxError")}}

+ +

O que deu errado?

+ +

Aconteceu um engano na sintaxe do inicializador do objeto em algum lugar. Pode ser que você esqueceu de colocar uma chave, mas também pode ser uma vírgula que foi esquecida, por exemplo. Verifique também se alguma chave de finalização ou parêntesis estão em algum lugar que não deveriam estar. Indente ou formate o código de uma maneira legível pode te ajudar a enxergar no meio dessa selva.

+ +

Exemplos

+ +

Vírgula esquecida

+ +

Muitas vezes esquecemos uma vígula no inicializador de objeto:

+ +
var obj = {
+  a: 1,
+  b: { minhaProp: 2 }
+  c: 3
+};
+
+ +

O código correto deve ser:

+ +
var obj = {
+  a: 1,
+  b: { minhaProp: 2 },
+  c: 3
+};
+
+ +

Veja também

+ + diff --git a/files/pt-br/web/javascript/reference/errors/missing_parenthesis_after_argument_list/index.html b/files/pt-br/web/javascript/reference/errors/missing_parenthesis_after_argument_list/index.html new file mode 100644 index 0000000000..83844d17b5 --- /dev/null +++ b/files/pt-br/web/javascript/reference/errors/missing_parenthesis_after_argument_list/index.html @@ -0,0 +1,38 @@ +--- +title: Erro de sintaxe falta ) depois da lista de argumentos +slug: Web/JavaScript/Reference/Errors/Fata_parênteses_após_lista_argumento +translation_of: Web/JavaScript/Reference/Errors/Missing_parenthesis_after_argument_list +--- +
{{jsSidebar("Errors")}}
+ +

Mensagem

+ +
Erro de sintaxe: Falta ) depois da lista de argumento
+
+ +

Tipo de Erro

+ +

{{jsxref("Erro de sintaxe")}}.

+ +

O que houve de errado?

+ +

Ocorreu um erro quando a função foi chamada. Pode ter sido um erro de escrita, falta de operador, ou uma string fora das aspas, por exemplo.

+ +

Exemplos

+ +

Pela falta do operador "+" para fazer a concatenação da string, o JavaScript esperou um argumento para a função log ser "PI: ". Nesse caso, deveria ser finalizado com parênteses de fechamento ')'.

+ +
console.log("PI: " Math.PI);
+// SyntaxError: missing ) after argument list
+
+ +

Você pode corrigir a chamada do log adicionand o operador "+":

+ +
console.log("PI: " + Math.PI);
+// "PI: 3.141592653589793"
+ +

Veja também:

+ + diff --git a/files/pt-br/web/javascript/reference/errors/not_defined/index.html b/files/pt-br/web/javascript/reference/errors/not_defined/index.html new file mode 100644 index 0000000000..6642b81b44 --- /dev/null +++ b/files/pt-br/web/javascript/reference/errors/not_defined/index.html @@ -0,0 +1,66 @@ +--- +title: 'ReferenceError: "x" não está definido' +slug: Web/JavaScript/Reference/Errors/Não_definido +translation_of: Web/JavaScript/Reference/Errors/Not_defined +--- +
{{jsSidebar("Errors")}}
+ +

Mensagem

+ +
ReferenceError: "x" is not defined
+
+ +

Tipo de erro

+ +

{{jsxref("ReferenceError")}}

+ +

O que deu errado?

+ +

Há uma variavel inexistente referenciada em algum lugar. Essa variável precisa ser declarada ou você precisa ter certeza que ela está disponível no seu atual script ou {{Glossary("escopo")}}.

+ +
+

Nota: Quando carregar uma biblioteca (como o JQuery) tenha certeza que ela está carregada antes que você acesse as variáveis dela, como "$". Coloque na tag {{HTMLElement("script")}} para carregar a biblioteca antes do seu código usá-lo.

+
+ +

Exemplos

+ +

Variável não declarada

+ +
foo.substring(1); // ReferenceError: foo is not defined
+
+ +

A variável "foo" não está definida em lugar nenhum. Ela precisa ser uma string e assim o método {{jsxref("String.prototype.substring()")}} irá funcionar.

+ +
var foo = "bar";
+foo.substring(1); // "ar"
+ +

Escopo Errado

+ +

Uma variável precisa estar disponível no atual contexto de execução. Variáveis definidas dentro de uma function não podem ser acessadas de outros lugares fora da função, porque a variável é definida apenas no escopo da função

+ +
function numbers () {
+  var num1 = 2,
+      num2 = 3;
+  return num1 + num2;
+}
+
+console.log(num1); // ReferenceError num1 is not defined.
+ +

Entretanto, uma função pode acessar todas as variáveis e funções definidas dentro do escopo no qual elas estão definidas. Em outras palavras, uma função definida no escopo global pode acessar todas as variáveis no escopo global.

+ +
var num1 = 2,
+    num2 = 3;
+
+function numbers () {
+  return num1 + num2;
+}
+
+console.log(num1); // 2
+ +

Veja também

+ + diff --git "a/files/pt-br/web/javascript/reference/errors/n\303\243o_definido/index.html" "b/files/pt-br/web/javascript/reference/errors/n\303\243o_definido/index.html" deleted file mode 100644 index 6642b81b44..0000000000 --- "a/files/pt-br/web/javascript/reference/errors/n\303\243o_definido/index.html" +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: 'ReferenceError: "x" não está definido' -slug: Web/JavaScript/Reference/Errors/Não_definido -translation_of: Web/JavaScript/Reference/Errors/Not_defined ---- -
{{jsSidebar("Errors")}}
- -

Mensagem

- -
ReferenceError: "x" is not defined
-
- -

Tipo de erro

- -

{{jsxref("ReferenceError")}}

- -

O que deu errado?

- -

Há uma variavel inexistente referenciada em algum lugar. Essa variável precisa ser declarada ou você precisa ter certeza que ela está disponível no seu atual script ou {{Glossary("escopo")}}.

- -
-

Nota: Quando carregar uma biblioteca (como o JQuery) tenha certeza que ela está carregada antes que você acesse as variáveis dela, como "$". Coloque na tag {{HTMLElement("script")}} para carregar a biblioteca antes do seu código usá-lo.

-
- -

Exemplos

- -

Variável não declarada

- -
foo.substring(1); // ReferenceError: foo is not defined
-
- -

A variável "foo" não está definida em lugar nenhum. Ela precisa ser uma string e assim o método {{jsxref("String.prototype.substring()")}} irá funcionar.

- -
var foo = "bar";
-foo.substring(1); // "ar"
- -

Escopo Errado

- -

Uma variável precisa estar disponível no atual contexto de execução. Variáveis definidas dentro de uma function não podem ser acessadas de outros lugares fora da função, porque a variável é definida apenas no escopo da função

- -
function numbers () {
-  var num1 = 2,
-      num2 = 3;
-  return num1 + num2;
-}
-
-console.log(num1); // ReferenceError num1 is not defined.
- -

Entretanto, uma função pode acessar todas as variáveis e funções definidas dentro do escopo no qual elas estão definidas. Em outras palavras, uma função definida no escopo global pode acessar todas as variáveis no escopo global.

- -
var num1 = 2,
-    num2 = 3;
-
-function numbers () {
-  return num1 + num2;
-}
-
-console.log(num1); // 2
- -

Veja também

- - diff --git "a/files/pt-br/web/javascript/reference/errors/n\303\243onomeado_func\303\243o_declara\303\247\303\243o/index.html" "b/files/pt-br/web/javascript/reference/errors/n\303\243onomeado_func\303\243o_declara\303\247\303\243o/index.html" deleted file mode 100644 index 6f01588059..0000000000 --- "a/files/pt-br/web/javascript/reference/errors/n\303\243onomeado_func\303\243o_declara\303\247\303\243o/index.html" +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: 'Erro de sintaxe: declaração de função requer um nome' -slug: Web/JavaScript/Reference/Errors/NãoNomeado_funcão_declaração -tags: - - Erro - - Erro de Sintaxe - - JavaScript - - Statement -translation_of: Web/JavaScript/Reference/Errors/Unnamed_function_statement ---- -
{{jsSidebar("Errors")}}
- -

Mensagem

- -
Errodesintaxe: Identificador Esperado(Edge)
-Errodesintaxe: declaração de função requer um nome [Firefox]
-Errodesintaxe: Token inesperado ( [Chrome]
-
- -

Tipo de erro

- -

{{jsxref("Errodesintaxe")}}

- -

O que estava errado?

- -

Existe uma declaração no código que requer um nome. Você precisa checar como as funções são definidas e se você precisa providenciar um nome, se a função em questão precisa ser uma expressão de função, um {{Glossary("IIFE")}} ou se o código da função está colocado corretamente neste contexto.

- -

Exemplos

- -

Statements vs expressions

- -

Uma  declaração de função (ou declaração de função) requer um nome, isso não vai funcionar:

- -
function () {
-  return 'Olha mundo';
-}
-// SyntaxError: function statement requires a name
-
- -

Você pode usar uma expressão de função ao invés de uma atribuição.

- -
var saudar = function() {
-  return 'Ola mundo';
-};
- -

Ou, sua função pode ser pretendida a ser uma IIFE (Immediately Invoked Function Expression), qual é uma função que será em breve definida. Você vai precisar de um pouco mais de colchetes neste caso:

- -
(function () {
-
-})();
- -

Funçoes etiquetadas

- -

Se usar labels, precisará providenciar um nome de função depois da  palavra function . Isto não funciona:

- -
function Saudacao() {
-  alemao: function () {
-    return "Moin";
-  }
-}
-// SyntaxError: a função declaração requer um nome
-
- -

Isso funciona ,veja o exemplo:

- -
function Saudacao() {
-  alemao: function g() {
-    return "Moin";
-  }
-}
- -

Métodos de Objetos

- -

Se pretende criar um metodo para um objeto, voce precisa-rá criar um objeto (hehehe). A seguir uma sintaxe sem nome depois de function é válida.

- -
var saudacao = {
-  alemao: function () {
-    return "Moin";
-  }
-};
- -

Callback Sintaxe

- -

Alem disso,cheque sua sintaxe usando callbacks. Colchetes e virgulas ficam facilmente atrapalhar e dificultar.

- -
promessa.then(
-  function() {
-    console.log("sucesso");
-  });
-  function() {
-    console.log("erro");
-}
-// SyntaxError: function statement requires a name
-
- -

O correto seria:

- -
promise.then(
-  function() {
-    console.log("success");
-  },
-  function() {
-    console.log("error");
-  }
-);//sempre que abrir feche();
-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/errors/unnamed_function_statement/index.html b/files/pt-br/web/javascript/reference/errors/unnamed_function_statement/index.html new file mode 100644 index 0000000000..6f01588059 --- /dev/null +++ b/files/pt-br/web/javascript/reference/errors/unnamed_function_statement/index.html @@ -0,0 +1,116 @@ +--- +title: 'Erro de sintaxe: declaração de função requer um nome' +slug: Web/JavaScript/Reference/Errors/NãoNomeado_funcão_declaração +tags: + - Erro + - Erro de Sintaxe + - JavaScript + - Statement +translation_of: Web/JavaScript/Reference/Errors/Unnamed_function_statement +--- +
{{jsSidebar("Errors")}}
+ +

Mensagem

+ +
Errodesintaxe: Identificador Esperado(Edge)
+Errodesintaxe: declaração de função requer um nome [Firefox]
+Errodesintaxe: Token inesperado ( [Chrome]
+
+ +

Tipo de erro

+ +

{{jsxref("Errodesintaxe")}}

+ +

O que estava errado?

+ +

Existe uma declaração no código que requer um nome. Você precisa checar como as funções são definidas e se você precisa providenciar um nome, se a função em questão precisa ser uma expressão de função, um {{Glossary("IIFE")}} ou se o código da função está colocado corretamente neste contexto.

+ +

Exemplos

+ +

Statements vs expressions

+ +

Uma  declaração de função (ou declaração de função) requer um nome, isso não vai funcionar:

+ +
function () {
+  return 'Olha mundo';
+}
+// SyntaxError: function statement requires a name
+
+ +

Você pode usar uma expressão de função ao invés de uma atribuição.

+ +
var saudar = function() {
+  return 'Ola mundo';
+};
+ +

Ou, sua função pode ser pretendida a ser uma IIFE (Immediately Invoked Function Expression), qual é uma função que será em breve definida. Você vai precisar de um pouco mais de colchetes neste caso:

+ +
(function () {
+
+})();
+ +

Funçoes etiquetadas

+ +

Se usar labels, precisará providenciar um nome de função depois da  palavra function . Isto não funciona:

+ +
function Saudacao() {
+  alemao: function () {
+    return "Moin";
+  }
+}
+// SyntaxError: a função declaração requer um nome
+
+ +

Isso funciona ,veja o exemplo:

+ +
function Saudacao() {
+  alemao: function g() {
+    return "Moin";
+  }
+}
+ +

Métodos de Objetos

+ +

Se pretende criar um metodo para um objeto, voce precisa-rá criar um objeto (hehehe). A seguir uma sintaxe sem nome depois de function é válida.

+ +
var saudacao = {
+  alemao: function () {
+    return "Moin";
+  }
+};
+ +

Callback Sintaxe

+ +

Alem disso,cheque sua sintaxe usando callbacks. Colchetes e virgulas ficam facilmente atrapalhar e dificultar.

+ +
promessa.then(
+  function() {
+    console.log("sucesso");
+  });
+  function() {
+    console.log("erro");
+}
+// SyntaxError: function statement requires a name
+
+ +

O correto seria:

+ +
promise.then(
+  function() {
+    console.log("success");
+  },
+  function() {
+    console.log("error");
+  }
+);//sempre que abrir feche();
+
+ +

Veja também

+ + diff --git a/files/pt-br/web/javascript/reference/functions/default_parameters/index.html b/files/pt-br/web/javascript/reference/functions/default_parameters/index.html new file mode 100644 index 0000000000..82dc54abd8 --- /dev/null +++ b/files/pt-br/web/javascript/reference/functions/default_parameters/index.html @@ -0,0 +1,210 @@ +--- +title: Parâmetros Predefinidos +slug: Web/JavaScript/Reference/Functions/Parametros_Predefinidos +tags: + - ECMA2015 + - ECMAScript6 + - Function + - Functions + - Função + - Funções + - JavaScript +translation_of: Web/JavaScript/Reference/Functions/Default_parameters +--- +
{{jsSidebar("Functions")}}
+ +

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

+ +

Sintaxe

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

Descrição

+ +

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

+ +

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

+ +
function multiply(a, b) {
+  b = (typeof b !== 'undefined') ? b : 1;
+
+  return a * b;
+}
+
+multiply(5, 2); // 10
+multiply(5, 1); // 5
+multiply(5);    // 5
+
+ +

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

+ +
function multiply(a, b = 1) {
+  return a * b;
+}
+
+multiply(5, 2); // 10
+multiply(5, 1); // 5
+multiply(5);    // 5
+ +

Exemplos

+ +

Passando undefined vs. outros valores "falsy"

+ +

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

+ +
function test(num = 1) {
+  console.log(typeof num);
+}
+
+test();          // 'number' (num é definido para 1)
+test(undefined); // 'number' (num é definido para 1 também)
+
+// teste com outros values "falsy":
+test('');        // 'string' (num é definido para '')
+test(null);      // 'object' (num é definido para null)
+ +

Avaliado em tempo de chamada

+ +

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

+ +
function append(value, array = []) {
+  array.push(value);
+  return array;
+}
+
+append(1); //[1]
+append(2); //[2], not [1, 2]
+
+
+ +

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

+ +
function callSomething(thing = something()) { return thing }
+
+function something(){
+  return "sth";
+}
+
+callSomething();  //sth
+ +

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

+ +

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

+ +
function singularAutoPlural(singular, plural = singular+"s",
+                            rallyingCry = plural + " ATTACK!!!") {
+  return [singular, plural, rallyingCry ];
+}
+
+//["Gecko","Geckos", "Geckos ATTACK!!!"]
+singularAutoPlural("Gecko");
+
+//["Fox","Foxes", "Foxes ATTACK!!!"]
+singularAutoPlural("Fox","Foxes");
+
+//["Deer", "Deer", "Deer ... change."]
+singularAutoPlural("Deer", "Deer", "Deer peaceably and respectfully
+   petition the government for positive change.")
+
+ +

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

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

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

+ +

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

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

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

+ +

Antes do Gecko 26 {{geckoRelease(26)}}, o seguinte código resultaria em um {{jsxref("SyntaxError")}}. Isto foi corrigido no {{bug(777060)}} e funciona como esperado em versões posteriores:

+ +
function f(x=1, y) {
+  return [x, y];
+}
+
+f(); // [1, undefined]
+
+ +

Parâmetro desestruturado com valores padrões

+ +

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

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

Especificações

+ + + + + + + + + + + + + + +
EspecificaçãoStatusComentário
{{SpecName('ES6', '#sec-function-definitions', 'Function Definitions')}}{{Spec2('ES6')}}Definição Inicial.
+ +

Compatibilidade nos navegadores

+ +
+

{{Compat("javascript.functions.default_parameters")}}

+
+ +

Veja também

+ + diff --git a/files/pt-br/web/javascript/reference/functions/definicoes_metodos/index.html b/files/pt-br/web/javascript/reference/functions/definicoes_metodos/index.html deleted file mode 100644 index ac02cb9deb..0000000000 --- a/files/pt-br/web/javascript/reference/functions/definicoes_metodos/index.html +++ /dev/null @@ -1,200 +0,0 @@ ---- -title: Definições de Método -slug: Web/JavaScript/Reference/Functions/Definicoes_metodos -tags: - - ECMAScript 2015 - - Funções - - JavaScript - - Objeto - - Sintaxe -translation_of: Web/JavaScript/Reference/Functions/Method_definitions ---- -
{{JsSidebar("Functions")}}
- -

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

- -

{{EmbedInteractiveExample("pages/js/functions-definitions.html")}}

- - - -

Sintaxe

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

Descrição

- -

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

- -

Dado o seguinte código:

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

Agora você pode reduzi-lo para isto:

- -
var obj = {
-  foo() {},
-  bar() {}
-};
- -

Generator methods

- -

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

- - - -
// Utilizando a propriedade com nome (pre-ES6)
-var obj2 = {
-  g: function*() {
-    var indice = 0;
-    while(true)
-      yield indice++;
-  }
-};
-
-// O mesmo objeto utilizando a sintaxe reduzida
-var obj2 = {
-  * g() {
-    var indice = 0;
-    while(true)
-      yield indice++;
-  }
-};
-
-var coisa = obj2.g();
-console.log(coisa.next().value); // 0
-console.log(coisa.next().value); // 1
- -

Métodos assíncronos

- -

{{jsxref("Statements/funcoes_assincronas", "Funções assíncronas", "", 1)}} também podem ser definidas usando a sintaxe reduzida.

- -
// Utilizando a propriedade com nome (pre-ES6)
-var obj3 = {
-  f: async function () {
-    await alguma_promise;
-  }
-};
-
-// O mesmo objeto com a sintaxe reduzida
-var obj3 = {
-  async f() {
-    await alguma_promise;
-  }
-};
- -

Generator methods assíncronos

- -

  Os generator methods também podem ser {{jsxref("Statements/funcoes_assincronas", "assíncronos", "", 1)}}

- -
var obj4 = {
-  f: async function* () {
-    yield 1;
-    yield 2;
-    yield 3;
-  }
-};
-
-// O mesmo objeto com a sintaxe reduzida
-var obj4 = {
-  async* f() {
-   yield 1;
-   yield 2;
-   yield 3;
-  }
-};
- -

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

- -

Métodos assim definidos não são construtores e lançarão um {{jsxref("TypeError")}} se você tentar instanciá-los.

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

Exemplos

- -

Caso de teste simples

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

Nome de propriedades computados

- -

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

- -
var bar = {
-  foo0 : function (){return 0;},
-  foo1(){return 1;},
-  ["foo" + 2](){return 2;},
-};
-
-console.log(bar.foo0()); // 0
-console.log(bar.foo1()); // 1
-console.log(bar.foo2()); // 2
- -

Especificações

- - - - - - - - - - - - - - - - - - - -
EspecificaçõesEstadoComentário
{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}} 
- -

Compatibilidade de browser

- - - -

{{Compat("javascript.functions.method_definitions")}}

- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/functions/method_definitions/index.html b/files/pt-br/web/javascript/reference/functions/method_definitions/index.html new file mode 100644 index 0000000000..ac02cb9deb --- /dev/null +++ b/files/pt-br/web/javascript/reference/functions/method_definitions/index.html @@ -0,0 +1,200 @@ +--- +title: Definições de Método +slug: Web/JavaScript/Reference/Functions/Definicoes_metodos +tags: + - ECMAScript 2015 + - Funções + - JavaScript + - Objeto + - Sintaxe +translation_of: Web/JavaScript/Reference/Functions/Method_definitions +--- +
{{JsSidebar("Functions")}}
+ +

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

+ +

{{EmbedInteractiveExample("pages/js/functions-definitions.html")}}

+ + + +

Sintaxe

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

Descrição

+ +

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

+ +

Dado o seguinte código:

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

Agora você pode reduzi-lo para isto:

+ +
var obj = {
+  foo() {},
+  bar() {}
+};
+ +

Generator methods

+ +

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

+ + + +
// Utilizando a propriedade com nome (pre-ES6)
+var obj2 = {
+  g: function*() {
+    var indice = 0;
+    while(true)
+      yield indice++;
+  }
+};
+
+// O mesmo objeto utilizando a sintaxe reduzida
+var obj2 = {
+  * g() {
+    var indice = 0;
+    while(true)
+      yield indice++;
+  }
+};
+
+var coisa = obj2.g();
+console.log(coisa.next().value); // 0
+console.log(coisa.next().value); // 1
+ +

Métodos assíncronos

+ +

{{jsxref("Statements/funcoes_assincronas", "Funções assíncronas", "", 1)}} também podem ser definidas usando a sintaxe reduzida.

+ +
// Utilizando a propriedade com nome (pre-ES6)
+var obj3 = {
+  f: async function () {
+    await alguma_promise;
+  }
+};
+
+// O mesmo objeto com a sintaxe reduzida
+var obj3 = {
+  async f() {
+    await alguma_promise;
+  }
+};
+ +

Generator methods assíncronos

+ +

  Os generator methods também podem ser {{jsxref("Statements/funcoes_assincronas", "assíncronos", "", 1)}}

+ +
var obj4 = {
+  f: async function* () {
+    yield 1;
+    yield 2;
+    yield 3;
+  }
+};
+
+// O mesmo objeto com a sintaxe reduzida
+var obj4 = {
+  async* f() {
+   yield 1;
+   yield 2;
+   yield 3;
+  }
+};
+ +

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

+ +

Métodos assim definidos não são construtores e lançarão um {{jsxref("TypeError")}} se você tentar instanciá-los.

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

Exemplos

+ +

Caso de teste simples

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

Nome de propriedades computados

+ +

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

+ +
var bar = {
+  foo0 : function (){return 0;},
+  foo1(){return 1;},
+  ["foo" + 2](){return 2;},
+};
+
+console.log(bar.foo0()); // 0
+console.log(bar.foo1()); // 1
+console.log(bar.foo2()); // 2
+ +

Especificações

+ + + + + + + + + + + + + + + + + + + +
EspecificaçõesEstadoComentário
{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}} 
+ +

Compatibilidade de browser

+ + + +

{{Compat("javascript.functions.method_definitions")}}

+ +

Veja também

+ + diff --git a/files/pt-br/web/javascript/reference/functions/parametros_predefinidos/index.html b/files/pt-br/web/javascript/reference/functions/parametros_predefinidos/index.html deleted file mode 100644 index 82dc54abd8..0000000000 --- a/files/pt-br/web/javascript/reference/functions/parametros_predefinidos/index.html +++ /dev/null @@ -1,210 +0,0 @@ ---- -title: Parâmetros Predefinidos -slug: Web/JavaScript/Reference/Functions/Parametros_Predefinidos -tags: - - ECMA2015 - - ECMAScript6 - - Function - - Functions - - Função - - Funções - - JavaScript -translation_of: Web/JavaScript/Reference/Functions/Default_parameters ---- -
{{jsSidebar("Functions")}}
- -

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

- -

Sintaxe

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

Descrição

- -

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

- -

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

- -
function multiply(a, b) {
-  b = (typeof b !== 'undefined') ? b : 1;
-
-  return a * b;
-}
-
-multiply(5, 2); // 10
-multiply(5, 1); // 5
-multiply(5);    // 5
-
- -

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

- -
function multiply(a, b = 1) {
-  return a * b;
-}
-
-multiply(5, 2); // 10
-multiply(5, 1); // 5
-multiply(5);    // 5
- -

Exemplos

- -

Passando undefined vs. outros valores "falsy"

- -

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

- -
function test(num = 1) {
-  console.log(typeof num);
-}
-
-test();          // 'number' (num é definido para 1)
-test(undefined); // 'number' (num é definido para 1 também)
-
-// teste com outros values "falsy":
-test('');        // 'string' (num é definido para '')
-test(null);      // 'object' (num é definido para null)
- -

Avaliado em tempo de chamada

- -

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

- -
function append(value, array = []) {
-  array.push(value);
-  return array;
-}
-
-append(1); //[1]
-append(2); //[2], not [1, 2]
-
-
- -

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

- -
function callSomething(thing = something()) { return thing }
-
-function something(){
-  return "sth";
-}
-
-callSomething();  //sth
- -

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

- -

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

- -
function singularAutoPlural(singular, plural = singular+"s",
-                            rallyingCry = plural + " ATTACK!!!") {
-  return [singular, plural, rallyingCry ];
-}
-
-//["Gecko","Geckos", "Geckos ATTACK!!!"]
-singularAutoPlural("Gecko");
-
-//["Fox","Foxes", "Foxes ATTACK!!!"]
-singularAutoPlural("Fox","Foxes");
-
-//["Deer", "Deer", "Deer ... change."]
-singularAutoPlural("Deer", "Deer", "Deer peaceably and respectfully
-   petition the government for positive change.")
-
- -

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

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

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

- -

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

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

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

- -

Antes do Gecko 26 {{geckoRelease(26)}}, o seguinte código resultaria em um {{jsxref("SyntaxError")}}. Isto foi corrigido no {{bug(777060)}} e funciona como esperado em versões posteriores:

- -
function f(x=1, y) {
-  return [x, y];
-}
-
-f(); // [1, undefined]
-
- -

Parâmetro desestruturado com valores padrões

- -

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

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

Especificações

- - - - - - - - - - - - - - -
EspecificaçãoStatusComentário
{{SpecName('ES6', '#sec-function-definitions', 'Function Definitions')}}{{Spec2('ES6')}}Definição Inicial.
- -

Compatibilidade nos navegadores

- -
-

{{Compat("javascript.functions.default_parameters")}}

-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/global_objects/array/contains/index.html b/files/pt-br/web/javascript/reference/global_objects/array/contains/index.html deleted file mode 100644 index a0f794df1a..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/array/contains/index.html +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: Array.prototype.includes() -slug: Web/JavaScript/Reference/Global_Objects/Array/contains -tags: - - Array - - ECMAScript7 - - Experimental - - Expérimental(2) - - JavaScript -translation_of: Web/JavaScript/Reference/Global_Objects/Array/includes ---- -
{{JSRef("Global_Objects", "Array")}}
- -

Sumário

- -

O método includes() determina se um array contém um determinado elemento, retornando true ou false apropriadamente.

- -

Sintaxe

- -
array.includes(searchElement[, fromIndex])
- -

Parâmetros

- -
-
searchElement
-
O elemento a buscar
-
fromIndex
-
Opcional. A posição no array de onde a busca pelo searchElement se iniciará. Por padrão, 0.
-
- -

Exemplos

- -
[1, 2, 3].includes(2);     // true
-[1, 2, 3].includes(4);     // false
-[1, 2, 3].includes(3, 3);  // false
-[1, 2, 3].includes(3, -1); // true
-[1, 2, NaN].includes(NaN); // true
-
- -

Polyfill

- -
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
-if (!Array.prototype.includes) {
-  Object.defineProperty(Array.prototype, 'includes', {
-    value: function(searchElement, fromIndex) {
-
-      // 1. Let O be ? ToObject(this value).
-      if (this == null) {
-        throw new TypeError('"this" is null or not defined');
-      }
-
-      var o = Object(this);
-
-      // 2. Let len be ? ToLength(? Get(O, "length")).
-      var len = o.length >>> 0;
-
-      // 3. If len is 0, return false.
-      if (len === 0) {
-        return false;
-      }
-
-      // 4. Let n be ? ToInteger(fromIndex).
-      //    (If fromIndex is undefined, this step produces the value 0.)
-      var n = fromIndex | 0;
-
-      // 5. If n ≥ 0, then
-      //  a. Let k be n.
-      // 6. Else n < 0,
-      //  a. Let k be len + n.
-      //  b. If k < 0, let k be 0.
-      var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
-
-      // 7. Repeat, while k < len
-      while (k < len) {
-        // a. Let elementK be the result of ? Get(O, ! ToString(k)).
-        // b. If SameValueZero(searchElement, elementK) is true, return true.
-        // c. Increase k by 1.
-        // NOTE: === provides the correct "SameValueZero" comparison needed here.
-        if (o[k] === searchElement) {
-          return true;
-        }
-        k++;
-      }
-
-      // 8. Return false
-      return false;
-    }
-  });
-}
-
- -

Especificações

- -

Proposta ES7: https://github.com/domenic/Array.prototype.contains/blob/master/spec.md

- -

Compatibilidade

- -
{{Compat("javascript.builtins.Array.includes")}}
- -

Veja Também

- - diff --git a/files/pt-br/web/javascript/reference/global_objects/array/filter/index.html b/files/pt-br/web/javascript/reference/global_objects/array/filter/index.html new file mode 100644 index 0000000000..c7b0c08915 --- /dev/null +++ b/files/pt-br/web/javascript/reference/global_objects/array/filter/index.html @@ -0,0 +1,227 @@ +--- +title: Array.prototype.filter() +slug: Web/JavaScript/Reference/Global_Objects/Array/filtro +tags: + - Array + - ECMAScript 5 + - JavaScript + - Prototype + - metodo +translation_of: Web/JavaScript/Reference/Global_Objects/Array/filter +--- +
{{JSRef}}
+ +

O método filter() cria um novo array com todos os elementos que passaram no teste implementado pela função fornecida.

+ +
function isBigEnough(value) {
+  return value >= 10;
+}
+
+var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
+// filtrado é [12, 130, 44]
+
+ +

Sintaxe

+ +
var newArray = arr.filter(callback[, thisArg])
+ +

Parâmetros

+ +
+
callback
+
Função é um predicado, para testar cada elemento do array. Retorna true para manter o elemento, false caso contrário, recebendo três argumentos:
+
+
+
element
+
+

O elemento que está sendo processado no array.

+
+
index
+
O índice do elemento atual que está sendo processado no array.
+
array
+
O array para qual filter foi chamada.
+
+
+
thisArg {{Optional_inline}}
+
Opcional. Valor a ser usado como this durante a execução do callback.
+
+ +

Valor de retorno

+ +

Um novo array com os elementos que passaram no teste.

+ +

Descrição

+ +

filter() chama a função callback fornecida, uma vez para cada elemento do array, e constrói um novo array com todos os valores para os quais o callback retornou o valor true ou  um valor que seja convertido para true. O callback é chamado apenas para índices do array que possuem valores atribuídos; Ele não é invocado para índices que foram excluídos ou para aqueles que não tiveram valor atribuído. Elementos do array que não passaram no teste do callback são simplesmente ignorados, e não são incluídos no novo array.

+ +

callback é invocado com estes três argumentos:

+ +
    +
  1. o valor do elemento
  2. +
  3. o índice do elemento
  4. +
  5. o objeto do array a ser preenchido
  6. +
+ +

Se o parâmetro thisArg for provido para o filter, ele será passado para o callback quando invocado, para ser usado como o valor do this. Caso contrário, será passado undefined como o valor de this. O valor do this finalmente observado pela função de callback é determinado de acordo com a regra que define o valor do this geralmente visto por uma função.

+ +

filter() não altera o array a partir da qual foi invocado.

+ +

O intervalo de elementos processados pela função filter() é definido antes da invocação do primeiro callback. Elementos que forem adicionados ao array depois da invocação do filter() não serão visitados pelo callback. Se elementos existentes no array forem alterados ou deletados, os valores deles que serão passados para o callback são os que eles tiverem quando o  filter() visitá-los; Elementos que forem deletados não são visitados.

+ +

Exemplos

+ +

Exemplo: Filtrando todos os valores pequenos

+ +

Os exemplos a seguir usam filter() para criar um array filtrado em que todos os elementos com valores menores que 10 são removidos.

+ +
function isBigEnough(value) {
+  return value >= 10;
+}
+var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
+// filtered is [12, 130, 44]
+
+ +

Exemplo: Filtrando entradas inválidas para JSON

+ +

O exemplo a seguir usa filter() para criar um JSON filtrado com todos seus elementos diferentes de zero, e id numérico.

+ +
var arr = [
+  { id: 15 },
+  { id: -1 },
+  { id: 0 },
+  { id: 3 },
+  { id: 12.2 },
+  { },
+  { id: null },
+  { id: NaN },
+  { id: 'undefined' }
+];
+
+var invalidEntries = 0;
+
+function filterByID(obj) {
+  if ('id' in obj && typeof(obj.id) === 'number' && !isNaN(obj.id)) {
+    return true;
+  } else {
+    invalidEntries++;
+    return false;
+  }
+}
+
+var arrByID = arr.filter(filterByID);
+
+console.log('Filtered Array\n', arrByID);
+// [{ id: 15 }, { id: -1 }, { id: 0 }, { id: 3 }, { id: 12.2 }]
+
+console.log('Number of Invalid Entries = ', invalidEntries);
+// Number of Invalid Entries = 4
+
+ +

Procurando em um array

+ +

O exemplo a seguir usa filter() para filtrar o conteúdo de um array baseado em um critério de busca

+ +
var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
+
+/**
+ * Array filters items based on search criteria (query)
+ */
+function filterItems(query) {
+  return fruits.filter(function(el) {
+      return el.toLowerCase().indexOf(query.toLowerCase()) > -1;
+  })
+}
+
+console.log(filterItems('ap')); // ['apple', 'grapes']
+console.log(filterItems('an')); // ['banana', 'mango', 'orange']
+ +

Implementação ES2015

+ +
const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
+
+/**
+ * Array filters items based on search criteria (query)
+ */
+const filterItems = (query) => {
+  return fruits.filter(el => el.toLowerCase().indexOf(query.toLowerCase()) > -1);
+};
+
+console.log(filterItems('ap')); // ['apple', 'grapes']
+console.log(filterItems('an')); // ['banana', 'mango', 'orange']
+ +

Polyfill

+ +

filter() foi adicionado ao padrão ECMA-262 na 5ª edição; assim como pode não estar presente em todas as implementações do padrão. Você pode trabalhar com isso adicionando o seguinte código no início de seus scripts, permitindo o uso do filter() na implementação ECMA-262 que não tem suporte nativo. Esse algoritmo é exatamente aquele especificado na 5ª edição do ECMA-262, assumindo que fn.call veja o valor original de {{jsxref("Function.prototype.call()")}}, e que {{jsxref("Array.prototype.push()")}} tenha seu valor original.

+ +
if (!Array.prototype.filter) {
+  Array.prototype.filter = function(fun/*, thisArg*/) {
+    'use strict';
+
+    if (this === void 0 || this === null) {
+      throw new TypeError();
+    }
+
+    var t = Object(this);
+    var len = t.length >>> 0;
+    if (typeof fun !== 'function') {
+      throw new TypeError();
+    }
+
+    var res = [];
+    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
+    for (var i = 0; i < len; i++) {
+      if (i in t) {
+        var val = t[i];
+
+        // NOTE: Technically this should Object.defineProperty at
+        //       the next index, as push can be affected by
+        //       properties on Object.prototype and Array.prototype.
+        //       But that method's new, and collisions should be
+        //       rare, so use the more-compatible alternative.
+        if (fun.call(thisArg, val, i, t)) {
+          res.push(val);
+        }
+      }
+    }
+
+    return res;
+  };
+}
+
+ +

Especificações

+ + + + + + + + + + + + + + + + + + + +
EspecificaçãoStatusComentário
{{SpecName('ES5.1', '#sec-15.4.4.20', 'Array.prototype.filter')}}{{Spec2('ES5.1')}}Definição inicial. Implementada no JavaScript 1.6.
{{SpecName('ES6', '#sec-array.prototype.filter', 'Array.prototype.filter')}}{{Spec2('ES6')}}
+ +

Compatibilidade de Browser

+ +
{{Compat("javascript.builtins.Array.filter")}}
+ +

Veja também

+ + + + diff --git a/files/pt-br/web/javascript/reference/global_objects/array/filtro/index.html b/files/pt-br/web/javascript/reference/global_objects/array/filtro/index.html deleted file mode 100644 index c7b0c08915..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/array/filtro/index.html +++ /dev/null @@ -1,227 +0,0 @@ ---- -title: Array.prototype.filter() -slug: Web/JavaScript/Reference/Global_Objects/Array/filtro -tags: - - Array - - ECMAScript 5 - - JavaScript - - Prototype - - metodo -translation_of: Web/JavaScript/Reference/Global_Objects/Array/filter ---- -
{{JSRef}}
- -

O método filter() cria um novo array com todos os elementos que passaram no teste implementado pela função fornecida.

- -
function isBigEnough(value) {
-  return value >= 10;
-}
-
-var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
-// filtrado é [12, 130, 44]
-
- -

Sintaxe

- -
var newArray = arr.filter(callback[, thisArg])
- -

Parâmetros

- -
-
callback
-
Função é um predicado, para testar cada elemento do array. Retorna true para manter o elemento, false caso contrário, recebendo três argumentos:
-
-
-
element
-
-

O elemento que está sendo processado no array.

-
-
index
-
O índice do elemento atual que está sendo processado no array.
-
array
-
O array para qual filter foi chamada.
-
-
-
thisArg {{Optional_inline}}
-
Opcional. Valor a ser usado como this durante a execução do callback.
-
- -

Valor de retorno

- -

Um novo array com os elementos que passaram no teste.

- -

Descrição

- -

filter() chama a função callback fornecida, uma vez para cada elemento do array, e constrói um novo array com todos os valores para os quais o callback retornou o valor true ou  um valor que seja convertido para true. O callback é chamado apenas para índices do array que possuem valores atribuídos; Ele não é invocado para índices que foram excluídos ou para aqueles que não tiveram valor atribuído. Elementos do array que não passaram no teste do callback são simplesmente ignorados, e não são incluídos no novo array.

- -

callback é invocado com estes três argumentos:

- -
    -
  1. o valor do elemento
  2. -
  3. o índice do elemento
  4. -
  5. o objeto do array a ser preenchido
  6. -
- -

Se o parâmetro thisArg for provido para o filter, ele será passado para o callback quando invocado, para ser usado como o valor do this. Caso contrário, será passado undefined como o valor de this. O valor do this finalmente observado pela função de callback é determinado de acordo com a regra que define o valor do this geralmente visto por uma função.

- -

filter() não altera o array a partir da qual foi invocado.

- -

O intervalo de elementos processados pela função filter() é definido antes da invocação do primeiro callback. Elementos que forem adicionados ao array depois da invocação do filter() não serão visitados pelo callback. Se elementos existentes no array forem alterados ou deletados, os valores deles que serão passados para o callback são os que eles tiverem quando o  filter() visitá-los; Elementos que forem deletados não são visitados.

- -

Exemplos

- -

Exemplo: Filtrando todos os valores pequenos

- -

Os exemplos a seguir usam filter() para criar um array filtrado em que todos os elementos com valores menores que 10 são removidos.

- -
function isBigEnough(value) {
-  return value >= 10;
-}
-var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
-// filtered is [12, 130, 44]
-
- -

Exemplo: Filtrando entradas inválidas para JSON

- -

O exemplo a seguir usa filter() para criar um JSON filtrado com todos seus elementos diferentes de zero, e id numérico.

- -
var arr = [
-  { id: 15 },
-  { id: -1 },
-  { id: 0 },
-  { id: 3 },
-  { id: 12.2 },
-  { },
-  { id: null },
-  { id: NaN },
-  { id: 'undefined' }
-];
-
-var invalidEntries = 0;
-
-function filterByID(obj) {
-  if ('id' in obj && typeof(obj.id) === 'number' && !isNaN(obj.id)) {
-    return true;
-  } else {
-    invalidEntries++;
-    return false;
-  }
-}
-
-var arrByID = arr.filter(filterByID);
-
-console.log('Filtered Array\n', arrByID);
-// [{ id: 15 }, { id: -1 }, { id: 0 }, { id: 3 }, { id: 12.2 }]
-
-console.log('Number of Invalid Entries = ', invalidEntries);
-// Number of Invalid Entries = 4
-
- -

Procurando em um array

- -

O exemplo a seguir usa filter() para filtrar o conteúdo de um array baseado em um critério de busca

- -
var fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
-
-/**
- * Array filters items based on search criteria (query)
- */
-function filterItems(query) {
-  return fruits.filter(function(el) {
-      return el.toLowerCase().indexOf(query.toLowerCase()) > -1;
-  })
-}
-
-console.log(filterItems('ap')); // ['apple', 'grapes']
-console.log(filterItems('an')); // ['banana', 'mango', 'orange']
- -

Implementação ES2015

- -
const fruits = ['apple', 'banana', 'grapes', 'mango', 'orange'];
-
-/**
- * Array filters items based on search criteria (query)
- */
-const filterItems = (query) => {
-  return fruits.filter(el => el.toLowerCase().indexOf(query.toLowerCase()) > -1);
-};
-
-console.log(filterItems('ap')); // ['apple', 'grapes']
-console.log(filterItems('an')); // ['banana', 'mango', 'orange']
- -

Polyfill

- -

filter() foi adicionado ao padrão ECMA-262 na 5ª edição; assim como pode não estar presente em todas as implementações do padrão. Você pode trabalhar com isso adicionando o seguinte código no início de seus scripts, permitindo o uso do filter() na implementação ECMA-262 que não tem suporte nativo. Esse algoritmo é exatamente aquele especificado na 5ª edição do ECMA-262, assumindo que fn.call veja o valor original de {{jsxref("Function.prototype.call()")}}, e que {{jsxref("Array.prototype.push()")}} tenha seu valor original.

- -
if (!Array.prototype.filter) {
-  Array.prototype.filter = function(fun/*, thisArg*/) {
-    'use strict';
-
-    if (this === void 0 || this === null) {
-      throw new TypeError();
-    }
-
-    var t = Object(this);
-    var len = t.length >>> 0;
-    if (typeof fun !== 'function') {
-      throw new TypeError();
-    }
-
-    var res = [];
-    var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
-    for (var i = 0; i < len; i++) {
-      if (i in t) {
-        var val = t[i];
-
-        // NOTE: Technically this should Object.defineProperty at
-        //       the next index, as push can be affected by
-        //       properties on Object.prototype and Array.prototype.
-        //       But that method's new, and collisions should be
-        //       rare, so use the more-compatible alternative.
-        if (fun.call(thisArg, val, i, t)) {
-          res.push(val);
-        }
-      }
-    }
-
-    return res;
-  };
-}
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - -
EspecificaçãoStatusComentário
{{SpecName('ES5.1', '#sec-15.4.4.20', 'Array.prototype.filter')}}{{Spec2('ES5.1')}}Definição inicial. Implementada no JavaScript 1.6.
{{SpecName('ES6', '#sec-array.prototype.filter', 'Array.prototype.filter')}}{{Spec2('ES6')}}
- -

Compatibilidade de Browser

- -
{{Compat("javascript.builtins.Array.filter")}}
- -

Veja também

- - - - diff --git a/files/pt-br/web/javascript/reference/global_objects/array/includes/index.html b/files/pt-br/web/javascript/reference/global_objects/array/includes/index.html new file mode 100644 index 0000000000..a0f794df1a --- /dev/null +++ b/files/pt-br/web/javascript/reference/global_objects/array/includes/index.html @@ -0,0 +1,106 @@ +--- +title: Array.prototype.includes() +slug: Web/JavaScript/Reference/Global_Objects/Array/contains +tags: + - Array + - ECMAScript7 + - Experimental + - Expérimental(2) + - JavaScript +translation_of: Web/JavaScript/Reference/Global_Objects/Array/includes +--- +
{{JSRef("Global_Objects", "Array")}}
+ +

Sumário

+ +

O método includes() determina se um array contém um determinado elemento, retornando true ou false apropriadamente.

+ +

Sintaxe

+ +
array.includes(searchElement[, fromIndex])
+ +

Parâmetros

+ +
+
searchElement
+
O elemento a buscar
+
fromIndex
+
Opcional. A posição no array de onde a busca pelo searchElement se iniciará. Por padrão, 0.
+
+ +

Exemplos

+ +
[1, 2, 3].includes(2);     // true
+[1, 2, 3].includes(4);     // false
+[1, 2, 3].includes(3, 3);  // false
+[1, 2, 3].includes(3, -1); // true
+[1, 2, NaN].includes(NaN); // true
+
+ +

Polyfill

+ +
// https://tc39.github.io/ecma262/#sec-array.prototype.includes
+if (!Array.prototype.includes) {
+  Object.defineProperty(Array.prototype, 'includes', {
+    value: function(searchElement, fromIndex) {
+
+      // 1. Let O be ? ToObject(this value).
+      if (this == null) {
+        throw new TypeError('"this" is null or not defined');
+      }
+
+      var o = Object(this);
+
+      // 2. Let len be ? ToLength(? Get(O, "length")).
+      var len = o.length >>> 0;
+
+      // 3. If len is 0, return false.
+      if (len === 0) {
+        return false;
+      }
+
+      // 4. Let n be ? ToInteger(fromIndex).
+      //    (If fromIndex is undefined, this step produces the value 0.)
+      var n = fromIndex | 0;
+
+      // 5. If n ≥ 0, then
+      //  a. Let k be n.
+      // 6. Else n < 0,
+      //  a. Let k be len + n.
+      //  b. If k < 0, let k be 0.
+      var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
+
+      // 7. Repeat, while k < len
+      while (k < len) {
+        // a. Let elementK be the result of ? Get(O, ! ToString(k)).
+        // b. If SameValueZero(searchElement, elementK) is true, return true.
+        // c. Increase k by 1.
+        // NOTE: === provides the correct "SameValueZero" comparison needed here.
+        if (o[k] === searchElement) {
+          return true;
+        }
+        k++;
+      }
+
+      // 8. Return false
+      return false;
+    }
+  });
+}
+
+ +

Especificações

+ +

Proposta ES7: https://github.com/domenic/Array.prototype.contains/blob/master/spec.md

+ +

Compatibilidade

+ +
{{Compat("javascript.builtins.Array.includes")}}
+ +

Veja Também

+ + diff --git a/files/pt-br/web/javascript/reference/global_objects/array/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/array/prototype/index.html deleted file mode 100644 index e863d9cc69..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/array/prototype/index.html +++ /dev/null @@ -1,206 +0,0 @@ ---- -title: Array.prototype -slug: Web/JavaScript/Reference/Global_Objects/Array/prototype -tags: - - Array - - JavaScript - - Propriedade -translation_of: Web/JavaScript/Reference/Global_Objects/Array/prototype ---- -
{{JSRef}}
- -

Descrição

- -

Instâncias de {{jsxref("Global_Objects/Array", "Array")}} herdam de Array.prototype. Como em todos os construtores, você pode mudar o  protótipo desse construtor para modificar todas as instâncias de {{jsxref("Global_Objects/Array", "Array")}}.

- -

Contudo, a adição de métodos não-padronizados ao objeto array pode causar problemas futuros, seja com seu próprio código, ou na adição de novas funcionalidades ao JavaScript.

- -

Um fato pouco conhecido: O próprio Array.prototype é um {{jsxref("Global_Objects/Array", "Array")}}

- -
Array.isArray(Array.prototype); // true
-
- -

Propriedades

- -
-
Array.prototype.constructor
-
Especifica a função que cria um objeto do protótipo.
-  
-
{{jsxref("Array.prototype.length")}}
-
Reflete o número de elementos em um array.
-
- -

Métodos

- -

Métodos modificadores

- -

Esses métodos modificam o array:

- -
-
{{jsxref("Array.prototype.copyWithin()")}} {{experimental_inline}}
-
Copia uma sequência de elementos do array dentro do array.
-
{{jsxref("Array.prototype.fill()")}} {{experimental_inline}}
-
Preenche todos os elementos de um array com um elemento estático, começando de um índice inicial até um índice final.
-
{{jsxref("Array.prototype.pop()")}}
-
Remove e retorna o último elemento de um array.
-
{{jsxref("Array.prototype.push()")}}
-
Adiciona um ou mais elementos ao fim de um array e retorna o novo comprimeiro do array.
-
{{jsxref("Array.prototype.reverse()")}}
-
Reverte a ordem dos elementos de um array - o primeiro vira o último e o último vira o primeiro.
-
{{jsxref("Array.prototype.shift()")}}
-
Remove o primeiro elemento de um array e o retorna.
-
{{jsxref("Array.prototype.sort()")}}
-
Ordena os elementos do array em questão e retorna o array.
-
{{jsxref("Array.prototype.splice()")}}
-
Adiciona e/ou remove elementos de um array.
-
{{jsxref("Array.prototype.unshift()")}}
-
Adiciona um ou mais elementos ao início de um array e retorna o novo comprimento do array.
-
- -

Métodos de acesso

- -

Esses métodos não modificam o array, mas sim retornam alguma representação dele.

- -
-
{{jsxref("Array.prototype.concat()")}}
-
Retorna um novo array formado por esse array concatenado com outro(s) array(s) e/ou valores.
-
{{jsxref("Array.prototype.contains()")}} {{experimental_inline}}
-
Verifica se o array possui cer, retornandotrue ou false apropriadamente.
-
{{jsxref("Array.prototype.join()")}}
-
Retorna uma string com todos os elementos do array
-
{{jsxref("Array.prototype.slice()")}}
-
Retorna um novo array com uma parte do array sobre o qual o método foi chamado
-
{{jsxref("Array.prototype.toSource()")}} {{non-standard_inline}}
-
Retorna um array literal representando o array especificado; você pode usar esse valor para criar um novo array. Esse método sobrescreve o método {{jsxref("Object.prototype.toSource()")}}.
-
{{jsxref("Array.prototype.toString()")}}
-
Retonar uma string representando o array e seus elementos. Esse método sobrescreve o método {{jsxref("Object.prototype.toString()")}}.
-
{{jsxref("Array.prototype.toLocaleString()")}}
-
Retonar uma string adequada ao idioma do usuário representando o array e seus elementos. Esse método sobrescreve o método {{jsxref("Object.prototype.toLocaleString()")}}.
-
{{jsxref("Array.prototype.indexOf()")}}
-
Representa o índice da primeira ocorrência de um valor especificado no array, ou -1 se o valor não estiver incluso no array.
-
{{jsxref("Array.prototype.lastIndexOf()")}}
-
Representa o índice da última ocorrência de um valor especificado no array, ou -1 se o valor não estiver incluso no array
-
- -

Métodos de iteração

- -

Vários métodos tomam como funções de argumento para serem chamados de volta ao processar o array. Quando esses métodos são chamados, o `length` do array é amostrado e qualquer elemento adicionado além deste comprimento (length)  de dentro da função (callback) não é visitado. Outras alterações para o array (Definindo o valor de ou apagando um elemento) pode afetar os resultados da operação se o método visita o elemento alterado posteriormente. Enquanto o comportamento específico destes métodos nestes casos é bem definido, não se deve confiar nisso para não confundir os outros que possoam ler seu código. Em vez disso, deve-se copiar para um novo array para modificá-lo.

- -
-
{{jsxref("Array.prototype.forEach()")}}
-
Chama a função para cada elemento no array.
-
{{jsxref("Array.prototype.entries()")}} {{experimental_inline}}
-
Retorna um novo objeto Array Iterator que contem o par chave/valor para cada índice no array.
-
{{jsxref("Array.prototype.every()")}}
-
Retorna true se todos elementos no array satisfizer a função de teste fornecida.
-
{{jsxref("Array.prototype.some()")}}
-
Retorna true se pelo menos um elemento no array satisfizer a função de teste fornecida.
-
{{jsxref("Array.prototype.filter()")}}
-
Cria um novo array com todos os elementos do array para qual a função de filtragem fornecida retorne true.
-
{{jsxref("Array.prototype.find()")}} {{experimental_inline}}
-
Retorna o valor encontrado no array, se um elemento no array satisfizer a funçào de teste fornecida ou  `undefined` se não for encontrado.
-
{{jsxref("Array.prototype.findIndex()")}} {{experimental_inline}}
-
Retorna o índice no array, se um elemento no array satisfizer a função de teste fornecida ou -1 se não for encontrado.
-
{{jsxref("Array.prototype.keys()")}} {{experimental_inline}}
-
Retorna um novo Array Iterator que contem a chave para cada índice no array.
-
{{jsxref("Array.prototype.map()")}}
-
Cria um novo array com os resultados da função fornecida chamada em cada elemento na array.
-
{{jsxref("Array.prototype.reduce()")}}
-
Aplica uma função contra um acumulador e cada valor do array (da esquerda para direita) para reduzi-los a um único valor.
-
{{jsxref("Array.prototype.reduceRight()")}}
-
Aplica uma função contra um acumulador e cada valor do array (da direita para esquerda) para reduzi-los a um único valor.
-
{{jsxref("Array.prototype.values()")}} {{experimental_inline}}
-
Retorna um novo objeto Array Iterator que contem os valores de cada índice no array.
-
{{jsxref("Array.prototype.@@iterator()", "Array.prototype[@@iterator]()")}} {{experimental_inline}}
-
Retorna um novo objeto Array Iterator que contem os valores de cada índice no array.
-
- -

Métodos genéricos

- -

Vários métodos do objeto Array em Javascript foram feitos para serem aplicados genericamentes em todos os objetos que "pareçam" Arrays. Isso é, eles podem ser usados em qualquer objeto que possuam uma propriedade length (comprimento), e que possa ser usado a partir de propriedades numéricas (como índices no formato array[5]). Alguns métodos, como {{jsxref("Array.join", "join")}}, apenas lêem e as propriedades numéricas do objeto sobre o qual eles sãochamados. Outros, como {{jsxref("Array.reverse", "reverse")}}, exigem que as propriedades numéricas e length sejam mutáveis; sendo assim, esses métodos não podem ser chamados em objetos como {{jsxref("Global_Objects/String", "String")}}, que não permitem que nenhuma das duas propriedades sejam modificadas.

- -

Especifiações

- - - - - - - - - - - - - - - - - - - - - - - - -
EspecificaçãoSituaçãoComentário
ECMAScript 1st Edition.PadrãoDefinição inicial
{{SpecName('ES5.1', '#sec-15.4.3.1', 'Array.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-array.prototype', 'Array.prototype')}}{{Spec2('ES6')}} 
- -

Compatibilidade com Navegadores

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
CaracterísticaChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
CaracterísticaAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/global_objects/bigint/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/bigint/prototype/index.html deleted file mode 100644 index ff8de05541..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/bigint/prototype/index.html +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: BigInt.prototype -slug: Web/JavaScript/Reference/Global_Objects/BigInt/prototype -tags: - - BigInt - - JavaScript - - Propriedade - - Prototipo - - Referencia -translation_of: Web/JavaScript/Reference/Global_Objects/BigInt/prototype ---- -
{{JSRef}}
- -

A propriedade BigInt.prototype representa o protótipo para o  construtor {{JSxRef("BigInt")}} .

- -

{{JS_Property_Attributes(0, 0, 0)}}

- -

Descrição

- -

Todas instância de {{JSxRef("BigInt")}} herdam de BigInt.prototype. O objeto protótipo do construtor {{JSxRef("BigInt")}} pode ser modificado para afetar todas instâncias de {{JSxRef( "BigInt")}} .

- -

Propriedades

- -
-
BigInt.prototype.constructor
-
Retorna a função que cria instâncias deste objeto. Por padrão é o objeto
- {{JSxRef("BigInt")}}.
-
- -

Métodos

- -
-
{{JSxRef("BigInt.prototype.toLocaleString()")}}
-
Retorna uma string com uma representação sensível ao idioma para este número. Sobrescreve o método {{JSxRef("Object.prototype.toLocaleString()")}}
-  
-
{{JSxRef("BigInt.prototype.toString()")}}
-
Retorna uma string respresentando o objeto específicado em um base específica. Sobrescreve o método {{JSxRef("Object.prototype.toString()")}} .
-
{{JSxRef("BigInt.prototype.valueOf()")}}
-
Retorna o valor primitivo de um objeto específicado. Sobrescreve o método {{JSxRef("Object.prototype.valueOf()")}}.
-
- -

Especificações

- - - - - - - - - - - - -
EspecificaçõesEstado
{{SpecName('ESDraft', '#sec-bigint.prototype', 'BigInt.prototype')}}{{Spec2('ESDraft')}}
- -

Compatibilidade

- - - -

{{Compat("javascript.builtins.BigInt.prototype")}}

diff --git a/files/pt-br/web/javascript/reference/global_objects/boolean/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/boolean/prototype/index.html deleted file mode 100644 index 99603a019f..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/boolean/prototype/index.html +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: Boolean.prototype -slug: Web/JavaScript/Reference/Global_Objects/Boolean/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/Boolean -translation_of_original: Web/JavaScript/Reference/Global_Objects/Boolean/prototype ---- -
{{JSRef}}
- -

A propriedade Boolean.prototype representa o prototype para o construtor de {{jsxref("Boolean")}}.

- -
{{js_property_attributes(0, 0, 0)}}
- -

Descrição

- -

Instancias de {{jsxref("Boolean")}} herdam de Boolean.prototype. Você pode usar os construtores do objeto prototype para adicionar propriedados ou metodos para todas as instancias de {{jsxref("Boolean")}} instances.

- -

Propriedades

- -
-
Boolean.prototype.constructor
-
Retorna a função que criou a instancia do prototype. Esta é a função {{jsxref("Boolean")}} por padrão.
-
- -

Métodos

- -
-
{{jsxref("Boolean.prototype.toSource()")}} {{non-standard_inline}}
-
Retorna a string contendo o codigo do objeto {{jsxref("Boolean")}} ;  pode-se usar esta string para criar um objeto equivalente. Sobreescreve o método {{jsxref("Object.prototype.toSource()")}}.
-
{{jsxref("Boolean.prototype.toString()")}}
-
Retorna uma string com valor "true" ou "false" dependendo qual o valor do objeto. Sobreescreve o método {{jsxref("Object.prototype.toString()")}}.
-
{{jsxref("Boolean.prototype.valueOf()")}}
-
Retorna o valor primitivo do objeto {{jsxref("Boolean")}}. Sobreescreve o método {{jsxref("Object.prototype.valueOf()")}}.
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - -
EspecificaçãoStatusComentário
{{SpecName('ES1')}}{{Spec2('ES1')}}Definição inicial. Implementano no JavaScript 1.0.
{{SpecName('ES5.1', '#sec-15.6.3.1', 'Boolean.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-boolean.prototype', 'Boolean.prototype')}}{{Spec2('ES6')}} 
- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Suporte básico{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Suporte básico{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
diff --git a/files/pt-br/web/javascript/reference/global_objects/function/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/function/prototype/index.html deleted file mode 100644 index 3b45ee5fe2..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/function/prototype/index.html +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: Function.prototype -slug: Web/JavaScript/Reference/Global_Objects/Function/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/Function -translation_of_original: Web/JavaScript/Reference/Global_Objects/Function/prototype ---- -
{{JSRef}}
- -

A propriedade Function.prototype representa o objeto prototype de {{jsxref("Function")}}.

- -

Descrição

- -

Objetos {{jsxref("Function")}} herdam de Function.prototypeFunction.prototype não pode ser modificado.

- -

Propriedades

- -
-
{{jsxref("Function.arguments")}} {{deprecated_inline}}
-
Um vetor correspondente aos argumentos passados a uma função. Isto é depreciado como propriedade de {{jsxref("Function")}}. Use em vez disso o objeto {{jsxref("Functions/arguments", "arguments")}} disponível dentro da função.
-
{{jsxref("Function.arity")}} {{obsolete_inline}}
-
Usado para especificar o número de argumentos esperados pela função. Foi removido, utilize em vez disso a propriedade {{jsxref("Function.length", "length")}}.
-
{{jsxref("Function.caller")}} {{non-standard_inline}}
-
Especifica a função que invocou a função sendo executada.
-
{{jsxref("Function.length")}}
-
Especifica o número de argumentos esperados pela função.
-
{{jsxref("Function.name")}}
-
O nome da função.
-
{{jsxref("Function.displayName")}} {{non-standard_inline}}
-
O nome de exibição da função.
-
Function.prototype.constructor
-
Especifica a função que cria o prototype do objeto. Veja {{jsxref("Object.prototype.constructor")}} para mais detalhes.
-
- -

Métodos

- -
-
{{jsxref("Function.prototype.apply()")}}
-
Chama uma função e define seu this com o valor fornecido. Argumentos podem ser passados como um objeto {{jsxref("Array")}}.
-
{{jsxref("Function.prototype.bind()")}}
-
Cria uma nova função que, quando chamada, tem seu this definido com o valor fornecido, com uma sequência de argumentos determinada precedendo quaisquer argumentos fornecidos quando a nova função é chamada.
-
{{jsxref("Function.prototype.call()")}}
-
Chama (executa) uma função e define seu this com o valor fornecido. Argumentos podem ser passados como são.
-
{{jsxref("Function.prototype.isGenerator()")}} {{non-standard_inline}}
-
Retorna true se a função é um gerador; se não, retorna false.
-
{{jsxref("Function.prototype.toSource()")}} {{non-standard_inline}}
-
Retorna uma string representando o código-fonte da função. Sobrescreve o método {{jsxref("Object.prototype.toSource")}}.
-
{{jsxref("Function.prototype.toString()")}}
-
Retorna uma string representando o código-fonte da função. Sobrescreve o método {{jsxref("Object.prototype.toString")}}.
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Definição inicial. Implementada no JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.3.5.2', 'Function.prototype')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-function-instances-prototype', 'Function.prototype')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-function-instances-prototype', 'Function.prototype')}}{{Spec2('ESDraft')}}
- -

Compatibilidade de navegadores

- -
- - -

{{Compat("javascript.builtins.Function.prototype")}}

-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/global_objects/intl/numberformat/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/intl/numberformat/prototype/index.html deleted file mode 100644 index dce89ef41e..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/intl/numberformat/prototype/index.html +++ /dev/null @@ -1,126 +0,0 @@ ---- -title: Intl.NumberFormat.prototype -slug: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/prototype -tags: - - Internacionalização - - JavaScript - - NumberFormat - - Property - - Propriedade - - Prototipo - - Prototype -translation_of: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat -translation_of_original: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/prototype ---- -
{{JSRef}}
- -

A propriedade Intl.NumberFormat.prototype representa o objeto do protótipo do construtor de {{jsxref("NumberFormat", "Intl.NumberFormat")}}.

- -
{{js_property_attributes(0, 0, 0)}}
- -

Descrição

- -

Veja {{jsxref("NumberFormat")}} para uma descrição sobre instâncias de Intl.NumberFormat.

- -

As instâncias de {{jsxref("NumberFormat", "Intl.NumberFormat")}} herdam de Intl.NumberFormat.prototype. Modificações ao objeto do protótipo são herdados por todas as instâncias de {{jsxref("NumberFormat", "Intl.NumberFormat")}}.

- -

Propriedades

- -
-
Intl.NumberFormat.prototype.constructor
-
Uma referência a Intl.NumberFormat.
-
{{jsxref("NumberFormat.format", "Intl.NumberFormat.prototype.format")}}
-
Getter; retorna uma função que formata um número de acordo com a localização e as opçõe de formatação do objeto {{jsxref("NumberFormat")}}.
-
- -

Métodos

- -
-
{{jsxref("NumberFormat.resolvedOptions", "Intl.NumberFormat.prototype.resolvedOptions()")}}
-
Retorna um novo objeto com propriedades refletindo a localização e as opções de agrupamento obtidos durante a inicialização do objeto.
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - -
EspecificaçãoStatusComentários
{{SpecName('ES Int 1.0', '#sec-11.2.1', 'Intl.NumberFormat.prototype')}}{{Spec2('ES Int 1.0')}}Definição inicial.
{{SpecName('ES Int 2.0', '#sec-11.2.1', 'Intl.NumberFormat.prototype')}}{{Spec2('ES Int 2.0')}} 
{{SpecName('ES Int Draft', '#sec-Intl.NumberFormat.prototype', 'Intl.NumberFormat.prototype')}}{{Spec2('ES Int Draft')}} 
- -

Compatibilidade do navegador

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
CaracterísticasChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Suporte básico{{CompatChrome("24")}}{{CompatGeckoDesktop("29")}}{{CompatIE("11")}}{{CompatOpera("15")}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
CaracterísticasAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Suporte básico{{CompatNo}}{{CompatChrome("26")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/global_objects/map/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/map/prototype/index.html deleted file mode 100644 index b20baf56cc..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/map/prototype/index.html +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: Map.prototype -slug: Web/JavaScript/Reference/Global_Objects/Map/prototype -tags: - - ECMAScript 2015 - - JavaScript - - Mapa - - Propriedade -translation_of: Web/JavaScript/Reference/Global_Objects/Map -translation_of_original: Web/JavaScript/Reference/Global_Objects/Map/prototype ---- -
{{JSRef}}
- -

A propriedade Map.prototype representa o protótipo para o construtor {{jsxref("Map")}}.

- -
{{js_property_attributes(0,0,0)}}
- -

Descrição

- -

Instâncias de {{jsxref("Map")}} herdam de {{jsxref("Map.prototype")}}. Você pode utilizar o objeto protótipo do  construtor para adicionar propriedades ou métodos para todas as instâncias de Map.

- -

Propriedades

- -
-
Map.prototype.constructor
-
Retorna a função que criou um protótipo da instância. Isso é a funçao de {{jsxref("Map")}} por padrão.
-
{{jsxref("Map.prototype.size")}}
-
Retorna o número de pares chave/valor no objeto Map.
-
- -

Metódos

- -
-
{{jsxref("Map.prototype.clear()")}}
-
Remove todas os pares chave/valor do objeto Map.
-
{{jsxref("Map.delete", "Map.prototype.delete(chave)")}}
-
Remove qualquer valor associado à chave passada e retorna o valor que Map.prototype.has(chave) deveria retornar anteriormente. Map.prototype.has(chave) irá retornar false após tal remoção ser feita.
-
{{jsxref("Map.prototype.entries()")}}
-
Retorna um novo objeto Iterador que contem um array de [chave, valor] para cada elemento no objeto Map pela ordem de inserção.
-
{{jsxref("Map.forEach", "Map.prototype.forEach(callbackFn[, thisArg])")}}
-
Chama callbackFn uma vez para cada par chave/valor presente no objeto Map, pela ordem de inserção. Se um parâmetro thisArg for fornecido para o forEach, ele será utilizado como o valor this para cada callback.
-
{{jsxref("Map.get", "Map.prototype.get(chave)")}}
-
Retorna o valor associado para a chave, ou undefined se esta não existir no objeto Map.
-
{{jsxref("Map.has", "Map.prototype.has(key)")}}
-
Retorna um valor booleano caso um valor tenha sido associado à chave no objeto Map ou não.
-
{{jsxref("Map.prototype.keys()")}}
-
Retorna um novo objeto Iterador que contem as chaves para cada elemento no objeto Map object pela ordem de inserção.
-
{{jsxref("Map.set", "Map.prototype.set(key, value)")}}
-
Configura o valor par a chave no objeto Map. Retorna o objeto Map.
-
{{jsxref("Map.prototype.values()")}}
-
Retorna um novo objeto Iterador que contém os valores para cada elemento no objeto Map pela ordem de inserção.
-
{{jsxref("Map.@@iterator", "Map.prototype[@@iterator]()")}}
-
Retorna um novo objeto Iterator que contém um array de [chave, valor] para cada elemento no objeto Map pela ordem de inserção.
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-map.prototype', 'Map.prototype')}}{{Spec2('ES2015')}}Definição inicial.
{{SpecName('ESDraft', '#sec-map.prototype', 'Map.prototype')}}{{Spec2('ESDraft')}} 
- -

Compatibilidade com os navegadores

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support38{{ CompatGeckoDesktop("13") }}11257.1
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}38{{CompatGeckoMobile("13")}}{{CompatNo}}{{CompatNo}} -

8

-
-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/global_objects/number/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/number/prototype/index.html deleted file mode 100644 index 9dd96bc9b3..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/number/prototype/index.html +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: Number.prototype -slug: Web/JavaScript/Reference/Global_Objects/Number/prototype -tags: - - JavaScript - - Número - - Propriedade - - Prototipo -translation_of: Web/JavaScript/Reference/Global_Objects/Number -translation_of_original: Web/JavaScript/Reference/Global_Objects/Number/prototype ---- -
{{JSRef}}
- -

A propriedade Number.prototype representa o protótipo para o construtor {{jsxref("Number")}}.

- -
{{js_property_attributes(0, 0, 0)}}
- -

Descrição

- -

Todas instâncias {{jsxref("Number")}} herdam de Number.prototype. O objeto 'prototype' do construtor {{jsxref("Number")}} pode ser modificado para afetar todas instâncias {{jsxref( "Number")}}.

- -

Propriedades

- -
-
Number.prototype.constructor
-
Retorna a função que criou esta instância do objeto. Por padrão, este é o objeto {{jsxref("Number")}}.
-
- -

Métodos

- -
-
{{jsxref("Number.prototype.toExponential()")}}
-
Retorna uma 'string' representando o número em notação exponencial.
-
{{jsxref("Number.prototype.toFixed()")}}
-
Retorna uma 'string' representando o número em notação em ponto fixo.
-
{{jsxref("Number.prototype.toLocaleString()")}}
-
Retorna uma 'string'  com uma representação sensível ao idioma deste número.  Substitui o método {{jsxref("Object.prototype.toLocaleString()")}}.
-
{{jsxref("Number.prototype.toPrecision()")}}
-
Retorna uma 'string' representando o número para uma precisão específica em notação ponto fixo ou exponencial.
-
{{jsxref("Number.prototype.toSource()")}} {{non-standard_inline}}
-
Retorna uma objeto literal representando um objeto específicado {{jsxref("Number")}}; você pode usar este valor para criar um novo objeto. Substitui o método {{jsxref("Object.prototype.toSource()")}}.
-
{{jsxref("Number.prototype.toString()")}}
-
Retorna uma 'string' representando o objeto especificado na raiz especificada (base). Substitui o método {{jsxref("Object.prototype.toString()")}}.
-
{{jsxref("Number.prototype.valueOf()")}}
-
Retorna o valor primitivo do objeto especificado. Substitui o método {{jsxref("Object.prototype.valueOf()")}}.
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EspecificaçãoSituaçãoComentários
{{SpecName('ES1')}}{{Spec2('ES1')}}Definição inicial. Implementado em JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.7.4', 'Number')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-properties-of-the-number-prototype-object', 'Number')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-properties-of-the-number-prototype-object', 'Number')}}{{Spec2('ESDraft')}} 
- -

Compatibilidade de navegadores

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - -
ConfiguraçãoChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Suporte básico{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
ConfiguraçãoAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Suporte básico{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/global_objects/object/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/object/prototype/index.html deleted file mode 100644 index d0c07076a0..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/object/prototype/index.html +++ /dev/null @@ -1,227 +0,0 @@ ---- -title: Object.prototype -slug: Web/JavaScript/Reference/Global_Objects/Object/prototype -tags: - - JavaScript - - Objeto - - Propriedade -translation_of: Web/JavaScript/Reference/Global_Objects/Object -translation_of_original: Web/JavaScript/Reference/Global_Objects/Object/prototype ---- -
{{JSRef("Global_Objects", "Object")}}
- -

Sumário

- -

A propriedade Object.prototype representa o {{jsxref("Global_Objects/Object", "Object")}} protótipo do objeto.

- -

{{js_property_attributes(0, 0, 0)}}

- -

Descrição

- -

Praticamente todos os objetos em JavaScript descendem de {{jsxref("Global_Objects/Object", "Object")}}; todos os métodos e propriedades herdados de Object.prototype, embora possam ser sobrescritos (exceto um Objeto com protótipo nulo, i.e. Object.create(null)). Por exemplo, outros protótipos construtores sobrescrevem a propriedade construtora e fornece seus próprios {{jsxref("Object.prototype.toString()", "toString()")}} métodos.

- -

Modificações no Objeto protótipo do objeto são propagadas a todos objetos através do encadeamento de protótipos, a menos que as propriedades e métodos  submetidos às mudanças sejam sobrescritos mais além no encadeamento dos protótipos. Este recurso oferece um mecânismo muito poderoso apesar de perigoso para sobrescrita e extensão de objetos.

- -

Propriedades

- -
-
{{jsxref("Object.prototype.constructor")}}
-
Especifica a função que cria um objeto protótipo.
-
{{jsxref("Object.prototype.__proto__")}} {{non-standard_inline}}
-
Aponta para o objeto que foi usado como protótipo quando o objeto foi instanciado.
-
{{jsxref("Object.prototype.__noSuchMethod__")}} {{non-standard_inline}}
-
Permite definir uma função que será executada quando um membro indefinido do objeto for chamado como método.
-
{{jsxref("Object.prototype.__count__")}} {{obsolete_inline}}
-
Usado para retornar um número de propriedades enumeráveis diretamente num objeto definido pelo usuário, mas foi removida.
-
{{jsxref("Object.prototype.__parent__")}} {{obsolete_inline}}
-
Usado para apontar a um contexto do objeto, mas foi removida.
-
- -

Métodos

- -
-
{{jsxref("Object.prototype.__defineGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
Associa uma função com uma propriedade que, quando acessada, executa uma função e retorna seu valor de retorno.
-
{{jsxref("Object.prototype.__defineSetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
Associa uma função com uma propriedade que, quando definida, executa uma função que modifica a propriedade.
-
{{jsxref("Object.prototype.__lookupGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
Retorna a função associada com a propriedade específicada pelo {{jsxref("Object.defineGetter", "__defineGetter__")}} método.
-
{{jsxref("Object.prototype.__lookupSetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
Retorna a função associada com a propriedade especificada pelo {{jsxref("Object.defineSetter", "__defineSetter__")}} método.
-
{{jsxref("Object.prototype.hasOwnProperty()")}}
-
Retorna um boolean indicando se um objeto contém a propriedade especificada como uma propriedade direta de um objeto e não herdada através da cadeia de protótipo.
-
{{jsxref("Object.prototype.isPrototypeOf()")}}
-
Retorna uma indicação booleana se o objeto especificado está na cadeia de protótipo do objeto este método é chamado.
-
{{jsxref("Object.prototype.propertyIsEnumerable()")}}
-
Retorna um boolean indicando se o atributo interno ECMAScript DontEnum attribute está definido.
-
{{jsxref("Object.prototype.toSource()")}} {{non-standard_inline}}
-
Retorna uma string contendo o código de um objeto literal representando o objeto que este método é  chamado; você pode usar este valor para criar um novo objeto.
-
{{jsxref("Object.prototype.toLocaleString()")}}
-
Chama {{jsxref("Object.toString", "toString()")}}.
-
{{jsxref("Object.prototype.toString()")}}
-
Retorna uma representação do objeto em forma de string.
-
{{jsxref("Object.prototype.unwatch()")}} {{non-standard_inline}}
-
Remove um ponto de escuta da propriedade do objeto.
-
{{jsxref("Object.prototype.valueOf()")}}
-
Retorna o valor primitivo do objeto especificado.
-
{{jsxref("Object.prototype.watch()")}} {{non-standard_inline}}
-
Adiciona um ponto de escuta à propriedade do objeto.
-
{{jsxref("Object.prototype.eval()")}} {{obsolete_inline}}
-
Usado para avaliar uma string de código JavaScript no contexto do objeto especificado, mas foi removido.
-
- -

Exemplos

- -

Quando é alterado o comportamento de um método de um Objeto protótipo, considere injetar código envolvendo sua extensão antes ou depois ta lógica existente. Por exemplo, este (não testado) código irá pré-condicionalmente executar uma lógica personalizada antes da lógica embutida ou a extensão de alguém será executada.

- -

Quando uma função é chamada os argumentos para a chamada são segurados no array de argumentos como "variável". Por exemplo, na chamada "minhaFuncao(a, b, c)", os argumentos no corpo da minhaFuncao irão conter 3 elementos array correspondentes a (a, b, c). Quando modificamos os protótipos com ganchos, simplesmente passamos this & a variável arguments (o estado de chamada) para o comportamento atual pela chamada apply() na função. Este padrão pode ser usado por qualquer protótipo, tal como Node.prototype, Function.prototype, etc.

- -
var current = Object.prototype.valueOf;
-
-// Desde que minha propriedade "-prop-value" é transversal e não está
-// sempre na mesma cadeia de protótipo, desejo modificar Object.prototype:
-Object.prototype.valueOf = function() {
-  if (this.hasOwnProperty("-prop-value") {
-    return this["-prop-value"];
-  } else {
-    // Isto não parece com um de meus objetos, então vamos retroceder ao
-    // comportamento padrão para reproduzir o comportamento atual o que
-    // pudermos. O apply se comporta como o"super" em outras linguagens.
-    // Mesmo que valueOf() não receba argumentos, alguns outros ganchos podem.
-    return current.apply(this, arguments);
-  }
-}
- -

Desde que JavaScript não tem exatamente objetos de subclasse, protótipo é uma forma usual de trabalhar para fazer um objeto "classe base" de certas funções que agem como objetos. Por exemplo:

- -
var Person = function() {
-  this.canTalk = true;
-  this.greet = function() {
-    if (this.canTalk) {
-      console.log('Hi, I\'m ' + this.name);
-    }
-  };
-};
-
-var Employee = function(name, title) {
-  this.name = name;
-  this.title = title;
-  this.greet = function() {
-    if (this.canTalk) {
-      console.log("Hi, I'm " + this.name + ", the " + this.title);
-    }
-  };
-};
-Employee.prototype = new Person();
-
-var Customer = function(name) {
-  this.name = name;
-};
-Customer.prototype = new Person();
-
-var Mime = function(name) {
-  this.name = name;
-  this.canTalk = false;
-};
-Mime.prototype = new Person();
-
-var bob = new Employee('Bob', 'Builder');
-var joe = new Customer('Joe');
-var rg = new Employee('Red Green', 'Handyman');
-var mike = new Customer('Mike');
-var mime = new Mime('Mime');
-bob.greet();
-joe.greet();
-rg.greet();
-mike.greet();
-mime.greet();
-
- -

O retorno será:

- -
Hi, I'm Bob, the Builder
-Hi, I'm Joe
-Hi, I'm Red Green, the Handyman
-Hi, I'm Mike
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - -
EspecificaçõesSituaçãoComentário
ECMAScript 1st Edition. Implemented in JavaScript 1.0.PadrãoDefinição inicial.
{{SpecName('ES5.1', '#sec-15.2.3.1', 'Object.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-object.prototype', 'Object.prototype')}}{{Spec2('ES6')}} 
- -

Compatibilidade com Navegadores

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
AspectoChromeFirefox (Gecko)Internet ExplorerOperaSafari
Suporte básico{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
AspectoAndroidChrome para AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Suporte básico.{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

 

diff --git a/files/pt-br/web/javascript/reference/global_objects/promise/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/promise/prototype/index.html deleted file mode 100644 index d0be3d870c..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/promise/prototype/index.html +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: Promise.prototype -slug: Web/JavaScript/Reference/Global_Objects/Promise/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/Promise -translation_of_original: Web/JavaScript/Reference/Global_Objects/Promise/prototype ---- -
{{JSRef("Global_Objects", "Promise")}}
- -

Sumário

- -

A propriedade Promise.prototype representa o protótipo para o construtor {{jsxref("Promise")}}.

- -
{{js_property_attributes(0,0,0)}}
- -

Descrição

- -

{{jsxref("Promise")}} instância herdada de {{jsxref("Promise.prototype")}}. Você pode usar o objeto construtor para adicionar propriedades ou métodos  para todas as instâncias de Promise.

- -

Propriedades

- -
-
Promise.prototype.constructor
-
Retorna a função que cria uma instância. Isso é a função padrão {{jsxref("Promise")}}.
-
- -

Métodos

- -
-
{{jsxref("Promise.catch", "Promise.prototype.catch(onRejected)")}}
-
Adiciona um callback que trata rejeição para a promise e, retorna uma nova promise resolvendo o valor retornado do callback, se ele for chamado, ou para seu valor original de conclusão se a promise for realizada.
-
{{jsxref("Promise.then", "Promise.prototype.then(onFulfilled, onRejected)")}}
-
Adiciona os métodos de tratamento da realização e rejeição da promise e, retorna uma nova promise resolvendo para o valor do método chamado.
-
- -

Especificações

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES6', '#sec-promise.prototype', 'Promise.prototype')}}{{Spec2('ES6')}}Initial definition.
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support32{{CompatGeckoDesktop(24.0)}} as Future
- {{CompatGeckoDesktop(25.0)}} as Promise behind a flag[1]
- {{CompatGeckoDesktop(29.0)}} by default
{{CompatNo}}197.1
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatGeckoMobile(24.0)}} as Future
- {{CompatGeckoMobile(25.0)}} as Promise behind a flag[1]
- {{CompatGeckoMobile(29.0)}} by default
{{CompatNo}}{{CompatNo}}iOS 832
-
- -

[1] Gecko 24 has an experimental implementation of Promise, under the initial name of Future. It got renamed to its final name in Gecko 25, but disabled by default behind the flag dom.promise.enabled. Bug 918806 enabled Promises by default in Gecko 29.

- -

See also

- - diff --git a/files/pt-br/web/javascript/reference/global_objects/set/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/set/prototype/index.html deleted file mode 100644 index 1f2ca2c70b..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/set/prototype/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: Set.prototype -slug: Web/JavaScript/Reference/Global_Objects/Set/prototype -tags: - - Propriedade - - Prototipo - - set -translation_of: Web/JavaScript/Reference/Global_Objects/Set -translation_of_original: Web/JavaScript/Reference/Global_Objects/Set/prototype ---- -
{{JSRef}}
- -

A propriedade Set.prototype representa o protótipo do construtor do objeto {{jsxref("Set")}}.

- -
{{js_property_attributes(0,0,0)}}
- -

Descrição

- -

Instâncias de {{jsxref("Set")}} herdam de {{jsxref("Set.prototype")}}. Você pode usar o construtor do objeto protótipo para adicionar propriedades ou métodos para todas as instâncias de Set .

- -

Propriedades

- -
-
Set.prototype.constructor
-
Retorna a função que criou o protótipo de uma instância. Esta é a função {{jsxref("Set")}} por padrão.
-
{{jsxref("Set.prototype.size")}}
-
Retorna o número de valores no objeto Set.
-
- -

Métodos

- -
-
{{jsxref("Set.add", "Set.prototype.add(value)")}}
-
Anexa um novo elemento com o valor passado ao objeto Set . Retorna o objeto Set.
-
{{jsxref("Set.prototype.clear()")}}
-
Remove todos os elementos do objeto Set.
-
{{jsxref("Set.delete", "Set.prototype.delete(value)")}}
-
Remove o elemento associado ao value e retorna o valor que Set.prototype.has(value) teria retornado anteriormente. Set.prototype.has(value) irá retornar false depois disso.
-
{{jsxref("Set.prototype.entries()")}}
-
Retorna um novo objeto Iterator que contém um array de [value, value] para cada elemento no objeto Set , em ordem de inserção. Isso é similar ao objeto Map, para que cada entrada tenha o mesmo valor para sua chave evalor aqui.
-
{{jsxref("Set.forEach", "Set.prototype.forEach(callbackFn[, thisArg])")}}
-
Chama callbackFn uma vez para cada valor presente no objeto Set, em ordem de inserção. Se um parâmetro thisArg for passado para o forEach, ele será usado como valor de this para cada callback.
-
{{jsxref("Set.has", "Set.prototype.has(value)")}}
-
Retorna um booleano afirmando se um elemento está presente com o dado valor no objeto Set ou não.
-
{{jsxref("Set.prototype.keys()")}}
-
É a mesma função que a função values() e retorna um novo objeto Iterator que contém os valores para cada elemento no objeto Set  em ordem de inserção.
-
{{jsxref("Set.prototype.values()")}}
-
Retorna um novo objeto Iterator que contém os values para cada elemento no objeto Set  em ordem de inserção.
-
{{jsxref("Set.prototype.@@iterator()", "Set.prototype[@@iterator]()")}}
-
Retorna um novo objeto Iterator que contém os values para cada elemento do objeto Set em ordem de inserção.
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - -
EspecificaçãoStatusComentário
{{SpecName('ES2015', '#sec-set.prototype', 'Set.prototype')}}{{Spec2('ES2015')}}Definição inicial.
{{SpecName('ESDraft', '#sec-set.prototype', 'Set.prototype')}}{{Spec2('ESDraft')}} 
- -

Compatibilidade de navegadores

- - - -

{{Compat("javascript.builtins.Set.prototype")}}

- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/global_objects/string/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/string/prototype/index.html deleted file mode 100644 index a0df7b93ea..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/string/prototype/index.html +++ /dev/null @@ -1,177 +0,0 @@ ---- -title: String.prototype -slug: Web/JavaScript/Reference/Global_Objects/String/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/String -translation_of_original: Web/JavaScript/Reference/Global_Objects/String/prototype ---- -
{{JSRef}}
- -

A String.prototype representa o prototipo de objeto  {{jsxref("String")}}.

- -
{{js_property_attributes(0, 0, 0)}}
- -

Descrição

- -

Todas as instâncias {{jsxref("String")}} herdam de String.prototype. Alterações na String são propagadas para todas as instâncias {{jsxref("String")}}.

- -

Propriedades

- -
-
String.prototype.constructor
-
Especifica a função que cria o protótipo de um objeto.
-
{{jsxref("String.prototype.length")}}
-
Reflete o comprimento da string.
-
N
-
Usado para acessar o caractere na posição N onde N é um número inteiro entre 0 e um menor que o valor da length. Estas propriedades são apenas de leitura.
-
- -

Métodos

- -

Métodos não relacionados ao HTML

- -
-
{{jsxref("String.prototype.charAt()")}}
-
Retorna o caractere (exatamente uma unidade de código UTF-16) no índice especificado.
-
{{jsxref("String.prototype.charCodeAt()")}}
-
Retorna um número que é o valor da unidade de código UTF-16 em dado índice.
-
{{jsxref("String.prototype.codePointAt()")}}
-
Retorna um número inteiro não negativo Number que é o valor de posição de código da posição de código inicial em dado índice.
-
{{jsxref("String.prototype.concat()")}}
-
Combina o texto de duas strings e retorna uma nova string.
-
{{jsxref("String.prototype.includes()")}}
-
 Determina se uma string deve ser encontrada dentro de outra string.
-
{{jsxref("String.prototype.endsWith()")}}
-
Determina se uma string termina com os caracteres de outra string.
-
{{jsxref("String.prototype.indexOf()")}}
-
Retorna o índice dentro do objeto String chamado da primeira ocorrência do valor especificado, ou -1 se não encontrado.
-
{{jsxref("String.prototype.lastIndexOf()")}}
-
Retorna o índice dentro do objeto String chamado da última ocorrência do valor especificado, ou -1 se não encontrado.
-
{{jsxref("String.prototype.localeCompare()")}}
-
Retorna um número indicando se uma string de referência vem antes ou depois ou é o mesmo que uma string dada em ordem de classificação.
-
{{jsxref("String.prototype.match()")}}
-
Usado para combinar uma expressão regular com uma string.
-
{{jsxref("String.prototype.normalize()")}}
-
Retorna o Formulário de Normalização Unicode do valor string chamado.
-
{{jsxref("String.prototype.padEnd()")}}
-
Empacota a string atual desde o final com uma string dada para criar uma nova string de um dado comprimento.
-
{{jsxref("String.prototype.padStart()")}}
-
Empacota a string atual desde o início com uma string dada para criar uma nova string de um dado comprimento.
-
{{jsxref("String.prototype.quote()")}} {{obsolete_inline}}
-
Envolve a cadeia entre aspas duplas ("" ").
-
{{jsxref("String.prototype.repeat()")}}
-
Retorna uma string consistindo elementos do objeto repetido pelas vezes definidas.
-
{{jsxref("String.prototype.replace()")}}
-
Usado para encontrar uma combinação entre uma expressão regular e uma string, e para substituir uma substring combinada com uma nova substring.
-
{{jsxref("String.prototype.search()")}}
-
Executa a procura por uma combinação entre uma expressão regular e uma string especificada.
-
{{jsxref("String.prototype.slice()")}}
-
Extrai uma seção de uma string e retorna uma nova string.
-
{{jsxref("String.prototype.split()")}}
-
Separa um objeto String em um array de strings separando a string em substrings.
-
{{jsxref("String.prototype.startsWith()")}}
-
Determina se uma string começa com os caracteres de outra string.
-
{{jsxref("String.prototype.substr()")}}
-
Retorna os caracteres em uma string começando no local especificado através do número especificado de caracteres.
-
{{jsxref("String.prototype.substring()")}}
-
Retorna os caracteres em uma string entre dois índices na string.
-
{{jsxref("String.prototype.toLocaleLowerCase()")}}
-
Os caracteres dentro de uma string são convertidos para letras minúsculas enquanto respeita a localidade atual. Para a maioria das línguas, irá retornar o mesmo que toLowerCase().
-
{{jsxref("String.prototype.toLocaleUpperCase()")}}
-
Os caracteres dentro de uma string são convertidas para letra maiúscula enquanto respeita a localidade atual. Para a maioria das línguas, irá retornar o mesmo que toUpperCase().
-
{{jsxref("String.prototype.toLowerCase()")}}
-
Retorna o valor da string de chamada convertido em minúsculas.
-
{{jsxref("String.prototype.toSource()")}} {{non-standard_inline}}
-
Retorna um objeto literal representando o objeto especificado; Você pode usar esse valor para criar um novo objeto. Substitui o metodo:{{jsxref("Object.prototype.toSource()")}}
-
{{jsxref("String.prototype.toString()")}}
-
Retorna uma string que representa o objeto especificado. Substitui o metodo:{{jsxref("Object.prototype.toString()")}}
-
{{jsxref("String.prototype.toUpperCase()")}}
-
Retorna o valor da string de chamada convertido em maiúscula.
-
{{jsxref("String.prototype.trim()")}}
-
Retira o espaço em branco desde o início e o fim da string. Parte do padrão ECMAScript 5.
-
{{jsxref("String.prototype.trimLeft()")}} {{non-standard_inline}}
-
Retira o espaço em branco do lado esquerdo da string.
-
{{jsxref("String.prototype.trimRight()")}} {{non-standard_inline}}
-
Retira o espaço em branco do lado esquerdo da string.
-
{{jsxref("String.prototype.valueOf()")}}
-
Retorna o valor primitivo do objeto especificado. Substitui o metodo: {{jsxref("Object.prototype.valueOf()")}} 
-
{{jsxref("String.prototype.@@iterator()", "String.prototype[@@iterator]()")}}
-
Retorna um novo objeto  Iterator que repete sobre os pontos de código de um valor String, retornando cada ponto de código como um valor String.
-
- -

Métodos de envoltório HTML

- -

Esses métodos são de uso limitado, pois fornecem apenas um subconjunto das tags e atributos HTML disponíveis.

- -
-
{{jsxref("String.prototype.anchor()")}}
-
{{htmlattrxref("name", "a", "<a name=\"name\">")}} (alvo hipertexto)
-
{{jsxref("String.prototype.big()")}} {{deprecated_inline}}
-
{{HTMLElement("big")}}
-
{{jsxref("String.prototype.blink()")}} {{deprecated_inline}}
-
{{HTMLElement("blink")}}
-
{{jsxref("String.prototype.bold()")}} {{deprecated_inline}}
-
{{HTMLElement("b")}}
-
{{jsxref("String.prototype.fixed()")}} {{deprecated_inline}}
-
{{HTMLElement("tt")}}
-
{{jsxref("String.prototype.fontcolor()")}} {{deprecated_inline}}
-
{{htmlattrxref("color", "font", "<font color=\"color\">")}}
-
{{jsxref("String.prototype.fontsize()")}} {{deprecated_inline}}
-
{{htmlattrxref("size", "font", "<font size=\"size\">")}}
-
{{jsxref("String.prototype.italics()")}} {{deprecated_inline}}
-
{{HTMLElement("i")}}
-
{{jsxref("String.prototype.link()")}}
-
{{htmlattrxref("href", "a", "<a href=\"url\">")}} (link para URL)
-
{{jsxref("String.prototype.small()")}} {{deprecated_inline}}
-
{{HTMLElement("small")}}
-
{{jsxref("String.prototype.strike()")}} {{deprecated_inline}}
-
{{HTMLElement("strike")}}
-
{{jsxref("String.prototype.sub()")}} {{deprecated_inline}}
-
{{HTMLElement("sub")}}
-
{{jsxref("String.prototype.sup()")}} {{deprecated_inline}}
-
{{HTMLElement("sup")}}
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EspecificacoesStatusComentarios
{{SpecName('ES1')}}{{Spec2('ES1')}}Definição inicial.
{{SpecName('ES5.1', '#sec-15.5.3.1', 'String.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-string.prototype', 'String.prototype')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-string.prototype', 'String.prototype')}}{{Spec2('ESDraft')}} 
- -

Compatibilidade entre browsers

- - - -

{{Compat("javascript.builtins.String.prototype")}}

- -

Veja também 

- - diff --git a/files/pt-br/web/javascript/reference/global_objects/weakmap/prototype/index.html b/files/pt-br/web/javascript/reference/global_objects/weakmap/prototype/index.html deleted file mode 100644 index c3e0334a3b..0000000000 --- a/files/pt-br/web/javascript/reference/global_objects/weakmap/prototype/index.html +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: WeakMap.prototype -slug: Web/JavaScript/Reference/Global_Objects/WeakMap/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/WeakMap -translation_of_original: Web/JavaScript/Reference/Global_Objects/WeakMap/prototype ---- -
{{JSRef("Global_Objects", "WeakMap")}}
- -

Sumário

- -

A propriedade WeakMap.prototype representa o prototype fara o construtor {{jsxref("WeakMap")}}.

- -
{{js_property_attributes(0,0,0)}}
- -

Descrição

- -

Instâncias {{jsxref("WeakMap")}} herdam de {{jsxref("WeakMap.prototype")}}. Você pode usar o objeto prototype do construtor para adicionar propriedades ou métodos para todas as instâncias WeakMap.

- -

Propriedades

- -
-
WeakMap.prototype.constructor
-
Retorna a função construtora das instâncias, neste caso a própria {{jsxref("WeakMap")}}.
-
- -

Metodos

- -
-
{{jsxref("WeakMap.prototype.clear()")}}
-
Remove todos os pares chave/valor do objeto WeakMap
-
{{jsxref("WeakMap.delete", "WeakMap.prototype.delete(key)")}}
-
Remove qualquer valor associado à  keyWeakMap.prototype.has(key) e retorna false após.
-
{{jsxref("WeakMap.get", "WeakMap.prototype.get(key)")}}
-
Retorna o valor associado a key, ou undefined se nenhum existir.
-
{{jsxref("WeakMap.has", "WeakMap.prototype.has(key)")}}
-
Retorna um Boolean verificando se há algum valor associado a key no objeto WeakMap ou não.
-
{{jsxref("WeakMap.set", "WeakMap.prototype.set(key, value)")}}
-
Configura um valor para key no objeto WeakMap. Retorna undefined.
-
- -

Especificações

- - - - - - - - - - - - - - -
EspecificaçãoStatusComentário
{{SpecName('ES6', '#sec-weakmap.prototype', 'WeakMap.prototype')}}{{Spec2('ES6')}}Especificação inicial.
- -

Compatibilidade de browsers 

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
RecursoChromeFirefox (SpiderMonkey)Internet ExplorerOperaSafari
Suporte básico{{CompatVersionUnknown}}{{CompatGeckoDesktop("6.0")}}11{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - -
RecursoAndroidFirefox Mobile (SpiderMonkey)IE MobileOpera MobileSafari Mobile
Suporte básico{{CompatNo}}{{CompatGeckoMobile("6.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

Notas para o Chrome

- - - -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/operators/arithmetic_operators/index.html b/files/pt-br/web/javascript/reference/operators/arithmetic_operators/index.html deleted file mode 100644 index 4ca87eaddd..0000000000 --- a/files/pt-br/web/javascript/reference/operators/arithmetic_operators/index.html +++ /dev/null @@ -1,329 +0,0 @@ ---- -title: Arithmetic operators -slug: Web/JavaScript/Reference/Operators/Arithmetic_Operators -tags: - - JavaScript - - Operadores -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Arithmetic_Operators ---- -
{{jsSidebar("Operadores")}}
- -

Operadores aritméticos tem valores numéricos (literais ou variáveis) como seus operadores e retornam um valor numérico único. Os operadores aritméticos padrões são adição (+), subtração (-), multiplicação (*), e divisão (/).

- -

Adição (+)

- -

O operador de adição produz a soma dos operadores numéricos ou a concatenação de strings.

- -

Sintaxe

- -
Operador: x + y
-
- -

Exemplos

- -
// Número + Número -> adição
-1 + 2 // 3
-
-// Booleano + Número -> adição
-true + 1 // 2
-
-// Booleano + Booleano -> adição
-false + false // 0
-
-// Número + String -> concatenação
-5 + "foo" // "5foo"
-
-// String + Booleano -> concatenação
-"foo" + false // "foofalse"
-
-// String + String -> concatenação
-"foo" + "bar" // "foobar"
-
- -

Subtração (-)

- -

O operador de subtração subtrai os dois operandos, produzindo sua diferença.

- -

Sintaxe

- -
Operador: x - y
-
- -

Exemplos

- -
5 - 3 // 2
-3 - 5 // -2
-"foo" - 3 // NaN
- -

Divisão (/)

- -

O operador de divisão produz o quociente de seus operandos onde o operando da esquerda é o dividendo e o da direita é o divisor.

- -

Sintaxe

- -
Operador: x / y
-
- -

Exemplos

- -
1 / 2      // retorna 0.5 em JavaScript
-1 / 2      // retorna 0 em Java
-// (nenhum dos números é explicitamente um número de ponto flutuante)
-
-1.0 / 2.0  // retorna 0.5 em JavaScript e Java
-
-2.0 / 0    // retorna Infinity em JavaScript
-2.0 / 0.0  // retorna Infinity também
-2.0 / -0.0 // retorna -Infinity em JavaScript
- -

Multiplicação (*)

- -

O operador de multiplicação produz o produto dos operandos.

- -

Sintaxe

- -
Operador: x * y
-
- -

Exemplos

- -
2 * 2 // 4
--2 * 2 // -4
-Infinity * 0 // NaN
-Infinity * Infinity // Infinity
-"foo" * 2 // NaN
-
- -

Módulo (%)

- -

O operador de módulo retorna o primeiro operando módulo o segundo, isto é, var1 módulo var2, na sentença anterior, onde var1 e var 2 são variáveis. A função módulo é o resto inteiro da divisão de var1 por var2. Existe uma proposta de ter um operador real de módulo em uma versão futura do ECMAScript.

- -

Sintaxe

- -
Operador: var1 % var2
-
- -

Examples

- -
12 % 5 // 2
--1 % 2 // -1
-NaN % 2 // NaN
-
- -

Exponenciação (**)

- -

O operador de exponenciação retorna o resultado do primeiro operando elevado ao segundo operando. É o mesmo que var1var2, onde var1 e var2 são variáveis. O operador de exponenciação é associativo à direita, ou seja, a ** b ** c é igual a a ** (b ** c).

- -

Sintaxe

- -
Operador: var1 ** var2
-
- -

Notas

- -

Em várias linguagens como PHP e Python e outras que tem o operador de exponenciação (**), a exponenciação tem prioridade do que operações unárias, como + e  -, mas tem algumas exceções. Por exemplo, no Bash o operador ** é definido por ter menos prioridade do que operadores unários. No JavaScript, é impossível escrever uma expressão de exponenciação ambígua, i.e. você não pode colocar um operador unário (+/-/~/!/delete/void/typeof) imediatamente antes do número base.

- -
-2 ** 2;
-// 4 no Bash, -4 em outras linguagens.
-// Isso é inválido no JavaScript, pois a operação é ambígua.
-
-
--(2 ** 2);
-// -4 no JavaScript e a intenção do autor não é ambígua.
-
- -

Exemplos

- -
2 ** 3 // 8
-3 ** 2 // 9
-3 ** 2.5 // 15.588457268119896
-10 ** -1 // 0.1
-NaN ** 2 // NaN
-
-2 ** 3 ** 2 // 512
-2 ** (3 ** 2) // 512
-(2 ** 3) ** 2 // 64
-
- -

Para inverter o sinal do resultado de uma expressão de exponenciação:

- -
-(2 ** 2) // -4
-
- -

Para forçar a base de uma expressão de exponenciação para ser um número negativo:

- -
(-2) ** 2 // 4
-
- -
-

Nota: JavaScript também tem  um operador de lógica binária ^ (XOR). ** e ^ são diferentes (por exemplo : 2 ** 3 === 8 enquanto 2 ^ 3 === 1.)

-
- -

Incremento (++)

- -

O operador de incremento incrementa (adiciona um a) seu operando e retorna um valor;

- - - -

Sintaxe

- -
Operador: x++ or ++x
-
- -

Exemplos

- -
// Posfixo
-var x = 3;
-y = x++; // y = 3, x = 4
-
-// Prefixo
-var a = 2;
-b = ++a; // a = 3, b = 3
-
- -

Decremento (--)

- -

O operador de decremento decrementa (subtrai um de) seu operando e retorna um valor.

- - - -

Sintaxe

- -
Operador: x-- or --x
-
- -

Exemplos

- -
// Posfixo
-var x = 3;
-y = x--; // y = 3, x = 2
-
-// Prefixo
-var a = 2;
-b = --a; // a = 1, b = 1
-
- -

Negação Unária (-)

- -

O operador de negação unária precede seu operando e o nega.

- -

Sintaxe

- -
Operador: -x
-
- -

Exemplos

- -
var x = 3;
-y = -x; // y = -3, x = 3
-
- -

Soma Unária (+)

- -

O operador de soma unária precede seu operando e calcula para seu operando mas tenta convertê-lo para um número, caso ainda não o seja. Apesar da negação unária (-) também poder converter não-números, a soma unária é a forma mais rápida e a forma preferida de converter alguma coisa em um número, porque ele não realiza nenhuma outra operação no número. Ele pode converter strings que representam inteiros e ponto flutuante, bem como os valores de não-string true, false, e null. Inteiros em formato decimal e hexadecimal ("0x"-prefixado) são suportados. Números negativos são suportados (não os hexadecimais). Caso não possa analisar um determinado valor, o operador retornará NaN.

- -

Sintaxe

- -
Operador: +x
-
- -

Exemplos

- -
+3     // 3
-+"3"   // 3
-+true  // 1
-+false // 0
-+null  // 0
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - -
EspecificaçãoStatusComentário
ECMAScript 1ª Edição.PadrãoDefinição inicial.
{{SpecName('ES5.1', '#sec-11.3')}}{{Spec2('ES5.1')}}Definido em várias seções da especificação: Operadores aditivos, Operadores Multiplicativos, Expressões Posfixas, Operadores Unários.
{{SpecName('ES6', '#sec-postfix-expressions')}}{{Spec2('ES6')}}Definido em várias seções da especificação: Operadores aditivos, Operadores Multiplicativos, Expressões Posfixas, Operadores Unários.
- -

Compatibilidade com Navegadores

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/operators/atribuicao_via_desestruturacao/index.html b/files/pt-br/web/javascript/reference/operators/atribuicao_via_desestruturacao/index.html deleted file mode 100644 index 6b1a100b4b..0000000000 --- a/files/pt-br/web/javascript/reference/operators/atribuicao_via_desestruturacao/index.html +++ /dev/null @@ -1,445 +0,0 @@ ---- -title: Atribuição via desestruturação (destructuring assignment) -slug: Web/JavaScript/Reference/Operators/Atribuicao_via_desestruturacao -translation_of: Web/JavaScript/Reference/Operators/Destructuring_assignment ---- -
{{jsSidebar("Operators")}}
- -

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

- -

Sintaxe

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

Descrição

- -

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

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

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

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

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

- -

Desestruturação de array

- -

Atribuição básica de variável

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

Atribuição separada da declaração

- -

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

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

Valores padrão

- -

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

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

Trocando variáveis

- -

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

- -

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

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

Analisando um array retornado de uma função

- -

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

- -

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

- -
function f() {
-  return [1, 2];
-}
-
-var a, b;
-[a, b] = f();
-console.log(a); // 1
-console.log(b); // 2
-
- -

Ignorando alguns valores retornados

- -

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

- -
function f() {
-  return [1, 2, 3];
-}
-
-var [a, , b] = f();
-console.log(a); // 1
-console.log(b); // 3
-
- -

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

- -
[,,] = f();
-
- -

Atribuindo o resto de um array para uma variável

- -

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

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

Extraindo valores do resultado de uma expressão regular

- -

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

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

Desestruturação de objeto

- -

Atribuição básica

- -
var o = {p: 42, q: true};
-var {p, q} = o;
-
-console.log(p); // 42
-console.log(q); // true
-
- -

Atribuição sem declaração

- -

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

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

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

- -

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

- -

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

-
- -

Atribuição para variáveis com novos nomes

- -

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

- -
var o = {p: 42, q: true};
-var {p: foo, q: bar} = o;
-
-console.log(foo); // 42
-console.log(bar); // true  
- -

Valores padrão

- -

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

- -
var {a=10, b=5} = {a: 3};
-
-console.log(a); // 3
-console.log(b); // 5
- -

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

- -

Versão ES5

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

Versão ES2015

- -
function drawES2015Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {}) {
-  console.log(size, cords, radius);
-  // do some chart drawing
-}
-
-drawES2015Chart({
-  cords: { x: 18, y: 30 },
-  radius: 30
-});
- -

Objeto aninhado e desestruturação de array

- -
var metadata = {
-    title: "Scratchpad",
-    translations: [
-       {
-        locale: "de",
-        localization_tags: [ ],
-        last_edit: "2014-04-14T08:43:37",
-        url: "/de/docs/Tools/Scratchpad",
-        title: "JavaScript-Umgebung"
-       }
-    ],
-    url: "/en-US/docs/Tools/Scratchpad"
-};
-
-var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata;
-
-console.log(englishTitle); // "Scratchpad"
-console.log(localeTitle);  // "JavaScript-Umgebung"
- -

For de iteração e desestruturação

- -
var people = [
-  {
-    name: "Mike Smith",
-    family: {
-      mother: "Jane Smith",
-      father: "Harry Smith",
-      sister: "Samantha Smith"
-    },
-    age: 35
-  },
-  {
-    name: "Tom Jones",
-    family: {
-      mother: "Norah Jones",
-      father: "Richard Jones",
-      brother: "Howard Jones"
-    },
-    age: 25
-  }
-];
-
-for (var {name: n, family: { father: f } } of people) {
-  console.log("Name: " + n + ", Father: " + f);
-}
-
-// "Name: Mike Smith, Father: Harry Smith"
-// "Name: Tom Jones, Father: Richard Jones"
- -

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

- -
function userId({id}) {
-  return id;
-}
-
-function whois({displayName: displayName, fullName: {firstName: name}}){
-  console.log(displayName + " is " + name);
-}
-
-var user = {
-  id: 42,
-  displayName: "jdoe",
-  fullName: {
-      firstName: "John",
-      lastName: "Doe"
-  }
-};
-
-console.log("userId: " + userId(user)); // "userId: 42"
-whois(user); // "jdoe is John"
- -

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

- -

Nomes computados de propriedade de objeto e desestruturação

- -

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

- -
let key = "z";
-let { [key]: foo } = { z: "bar" };
-
-console.log(foo); // "bar"
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - -
EspeficiaçãoSituaçãoComentário
{{SpecName('ES2015', '#sec-destructuring-assignment', 'Destructuring assignment')}}{{Spec2('ES2015')}}Definição inicial.
{{SpecName('ESDraft', '#sec-destructuring-assignment', 'Destructuring assignment')}}{{Spec2('ESDraft')}}
- -

Compatibilidade do navegador

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FuncionalidadeChromeFirefox (Gecko)EdgeInternet ExplorerOperaSafari
-

Suporte básico

-
{{CompatChrome(49.0)}}{{ CompatGeckoDesktop("1.8.1") }}14{{CompatNo}}{{CompatNo}}7.1
-

Nomes computados de propriedades

-
{{CompatChrome(49.0)}}{{ CompatGeckoDesktop("34") }}14{{CompatNo}}{{CompatNo}}{{CompatNo}}
Operador spread{{CompatChrome(49.0)}}{{ CompatGeckoDesktop("34") }}12[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FuncionalidadeAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Suporte básico{{CompatNo}}{{CompatChrome(49.0)}}{{ CompatGeckoMobile("1.0") }}{{CompatNo}}{{CompatNo}}8{{CompatChrome(49.0)}}
Nomes computados de propriedades{{CompatNo}}{{CompatChrome(49.0)}}{{ CompatGeckoMobile("34") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatChrome(49.0)}}
Operador spread{{CompatNo}}{{CompatChrome(49.0)}}{{ CompatGeckoMobile("34") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(49.0)}}
-
- -

[1] Requer "Enable experimental Javascript features" para funciona sob `about:flags`

- -

Notas específicas do Firefox

- - - -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/operators/bitwise_operators/index.html b/files/pt-br/web/javascript/reference/operators/bitwise_operators/index.html deleted file mode 100644 index b8b2e654c4..0000000000 --- a/files/pt-br/web/javascript/reference/operators/bitwise_operators/index.html +++ /dev/null @@ -1,559 +0,0 @@ ---- -title: Bitwise operators -slug: Web/JavaScript/Reference/Operators/Bitwise_Operators -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Bitwise_Operators ---- -
{{jsSidebar("Operators")}}
- -
- -
Operadores bit-a-bit são são operadores tratados como sequência de 32 bits ( zeros e uns ), preferencialmente como decimal, hexadecimal, ou números octais. Por exemplo, o número decimal 9 tinha como representação binária de 1001. Operadores bit-a-bit realizam as operações em tais representações binárias, mas retornam valores numéricos no padrão Javascript.
- -
{{EmbedInteractiveExample("pages/js/expressions-bitwiseoperators.html")}}
- - - -

A seguinte tabela resume os Operadores bit-a-bit:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
OperadorUsoDescrição
Bitwise ANDa & bRetorna 1 em cada posição de bit para à qual o bit correspondente de ambos eram 1s.
Bitwise ORa | b -

Retorna 1 para cada posição de bit para à qual o correspondente de um ou ambos eram 1s.

-
Bitwise XORa ^ bRetorna 1 para cada posição de bit para à qual o bit correspondente de um mas não ambos eram 1s.
Bitwise NOT~ aInverte os bits de seus operandos.
Left shifta << bJogam a  em representação binária b (< 32) bits à esquerda, mudando de zeros à diretia.
Sign-propagating right shifta >> bJogam a  em representação binária b (< 32) bits à direita, descartando bits que foram tornados off.
Zero-fill right shifta >>> b  Jogam a  em representação binária b (< 32) bits à direita, descartando bits que foram tornados off, e jogando 0s para à esquerda.
- -

Inteiros assinados em 32-bit

- -

Os operandos de todos os operadores bit-a-bit são assinados como inteiros de 32-bit em duas formas complementares. Duas formas complementares significa que uma negativa contrapartida (e.g. 5 vs. -5) são todos os bits daqueles números invertidos (bit-a-bit NOT de um número, a.k.a. complementos de um número) mais um. Por example, os seguintes encodes inteiros são 314:

- -
00000000000000000000000100111010
-
- -

Os seguintes encodes ~314, i.e. são os únicos complementos de  314:

- -
11111111111111111111111011000101
-
- -

Finalmente, os seguintes encodes -314, i.e. são dois complementos de 314:

- -
11111111111111111111111011000110
-
- -

As duas garantias complementares daquele bit mais à esquerda que é zero quando o número é positivo e 1 quando o número é negativo. Aliás, isto é chamado de sign bit ou bit assinalado.

- -

O número 0 é o inteiro composto completamente de 0 bits.

- -
0 (base 10) = 00000000000000000000000000000000 (base 2)
-
- -

O número -1 é o inteiro que é composto completamente de 1 bits.

- -
-1 (base 10) = 11111111111111111111111111111111 (base 2)
-
- -

O número -2147483648 (representação hexadecimal: -0x80000000) é o inteiro completamente composto de 0 bits exceto o primeiro (left-most) único.

- -
-2147483648 (base 10) = 10000000000000000000000000000000 (base 2)
-
- -

O número 2147483647 (representação hexadecimal: 0x7fffffff) é o inteiro composto completamente por bits 1, exceto pelo primeiro (o mais à esquerda).

- -
2147483647 (base 10) = 01111111111111111111111111111111 (base 2)
-
- -

Os números -2147483648 e 2147483647 são, respectivamente, o minimo e o máximo inteiro representáveis atráves de um número de 32 bits assinados.

- -

Operadores lógico bit-abit

- -

Conceitualmente, os operadores lógicos bit-abit funcionam da seguinte forma:

- - - -

& (Bitwise AND)

- -

Performa a operação AND em cada par de bits. a AND b retorna 1, apenas quando a e b são 1. A tabela verdade para a operação AND é:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
aba AND b
000
010
100
111
- -
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
-    14 (base 10) = 00000000000000000000000000001110 (base 2)
-                   --------------------------------
-14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
-
- -

Performar a operação AND bit-a-bit de qualquer número x com 0 retornará 0. Performar a operação AND bit-a-bit de qualquer número x com -1 retornará x.

- -

| (Bitwise OR)

- -

Performa a operação OR em cada par de bits. a OR b retorna 1 se pelo menos a ou pelo menos b é 1. As tabela versão para a operação OR é:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
aba OR b
000
011
101
111
- -
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
-    14 (base 10) = 00000000000000000000000000001110 (base 2)
-                   --------------------------------
-14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
-
- -

Performar a operação OR de qulalquer número x com 0 retornará 0. Performar a operação OR de qualquer número X com -1 retornará -1.

- -

^ (Bitwise XOR)

- -

Performs the XOR operation on each pair of bits. a XOR b yields 1 if a and b are different. The truth table for the XOR operation is:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
aba XOR b
000
011
101
110
- -
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
-    14 (base 10) = 00000000000000000000000000001110 (base 2)
-                   --------------------------------
-14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
-
- -

Bitwise XORing any number x with 0 yields x. Bitwise XORing any number x with -1 yields ~x.

- -

~ (Bitwise NOT)

- -

Performs the NOT operator on each bit. NOT a yields the inverted value (a.k.a. one's complement) of a. The truth table for the NOT operation is:

- - - - - - - - - - - - - - - - -
aNOT a
01
10
- -
 9 (base 10) = 00000000000000000000000000001001 (base 2)
-               --------------------------------
-~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
-
- -

Bitwise NOTing any number x yields -(x + 1). For example, ~-5 yields 4.

- -

Note that due to using 32-bit representation for numbers both ~-1 and ~4294967295 (232-1) results in 0.

- -

Operadores de deslocamento bit a bit

- -

The bitwise shift operators take two operands: the first is a quantity to be shifted, and the second specifies the number of bit positions by which the first operand is to be shifted. The direction of the shift operation is controlled by the operator used.

- -

Shift operators convert their operands to 32-bit integers in big-endian order and return a result of the same type as the left operand. The right operand should be less than 32, but if not only the low five bits will be used.

- -

<< (Left shift)

- -

This operator shifts the first operand the specified number of bits to the left. Excess bits shifted off to the left are discarded. Zero bits are shifted in from the right.

- -

For example, 9 << 2 yields 36:

- -
.    9 (base 10): 00000000000000000000000000001001 (base 2)
-                  --------------------------------
-9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
-
- -

Bitwise shifting any number x to the left by y bits yields x * 2 ** y.

- -

>> (Sign-propagating right shift)

- -

This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Copies of the leftmost bit are shifted in from the left. Since the new leftmost bit has the same value as the previous leftmost bit, the sign bit (the leftmost bit) does not change. Hence the name "sign-propagating".

- -

For example, 9 >> 2 yields 2:

- -
.    9 (base 10): 00000000000000000000000000001001 (base 2)
-                  --------------------------------
-9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
-
- -

Likewise, -9 >> 2 yields -3, because the sign is preserved:

- -
.    -9 (base 10): 11111111111111111111111111110111 (base 2)
-                   --------------------------------
--9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
-
- -

>>> (Zero-fill right shift)

- -

This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Zero bits are shifted in from the left. The sign bit becomes 0, so the result is always non-negative.

- -

For non-negative numbers, zero-fill right shift and sign-propagating right shift yield the same result. For example, 9 >>> 2 yields 2, the same as 9 >> 2:

- -
.     9 (base 10): 00000000000000000000000000001001 (base 2)
-                   --------------------------------
-9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
-
- -

However, this is not the case for negative numbers. For example, -9 >>> 2 yields 1073741821, which is different than -9 >> 2 (which yields -3):

- -
.     -9 (base 10): 11111111111111111111111111110111 (base 2)
-                    --------------------------------
--9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
-
- -

Examples

- -

Flags and bitmasks

- -

The bitwise logical operators are often used to create, manipulate, and read sequences of flags, which are like binary variables. Variables could be used instead of these sequences, but binary flags take much less memory (by a factor of 32).

- -

Suppose there are 4 flags:

- - - -

These flags are represented by a sequence of bits: DCBA. When a flag is set, it has a value of 1. When a flag is cleared, it has a value of 0. Suppose a variable flags has the binary value 0101:

- -
var flags = 5;   // binary 0101
-
- -

This value indicates:

- - - -

Since bitwise operators are 32-bit, 0101 is actually 00000000000000000000000000000101, but the preceding zeroes can be neglected since they contain no meaningful information.

- -

A bitmask is a sequence of bits that can manipulate and/or read flags. Typically, a "primitive" bitmask for each flag is defined:

- -
var FLAG_A = 1; // 0001
-var FLAG_B = 2; // 0010
-var FLAG_C = 4; // 0100
-var FLAG_D = 8; // 1000
-
- -

New bitmasks can be created by using the bitwise logical operators on these primitive bitmasks. For example, the bitmask 1011 can be created by ORing FLAG_A, FLAG_B, and FLAG_D:

- -
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
-
- -

Individual flag values can be extracted by ANDing them with a bitmask, where each bit with the value of one will "extract" the corresponding flag. The bitmask masks out the non-relevant flags by ANDing with zeroes (hence the term "bitmask"). For example, the bitmask 0100 can be used to see if flag C is set:

- -
// if we own a cat
-if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
-   // do stuff
-}
-
- -

A bitmask with multiple set flags acts like an "either/or". For example, the following two are equivalent:

- -
// if we own a bat or we own a cat
-// (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true
-if ((flags & FLAG_B) || (flags & FLAG_C)) {
-   // do stuff
-}
-
- -
// if we own a bat or cat
-var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110
-if (flags & mask) { // 0101 & 0110 => 0100 => true
-   // do stuff
-}
-
- -

Flags can be set by ORing them with a bitmask, where each bit with the value one will set the corresponding flag, if that flag isn't already set. For example, the bitmask 1100 can be used to set flags C and D:

- -
// yes, we own a cat and a duck
-var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
-flags |= mask;   // 0101 | 1100 => 1101
-
- -

Flags can be cleared by ANDing them with a bitmask, where each bit with the value zero will clear the corresponding flag, if it isn't already cleared. This bitmask can be created by NOTing primitive bitmasks. For example, the bitmask 1010 can be used to clear flags A and C:

- -
// no, we don't have an ant problem or own a cat
-var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010
-flags &= mask;   // 1101 & 1010 => 1000
-
- -

The mask could also have been created with ~FLAG_A & ~FLAG_C (De Morgan's law):

- -
// no, we don't have an ant problem, and we don't own a cat
-var mask = ~FLAG_A & ~FLAG_C;
-flags &= mask;   // 1101 & 1010 => 1000
-
- -

Flags can be toggled by XORing them with a bitmask, where each bit with the value one will toggle the corresponding flag. For example, the bitmask 0110 can be used to toggle flags B and C:

- -
// if we didn't have a bat, we have one now,
-// and if we did have one, bye-bye bat
-// same thing for cats
-var mask = FLAG_B | FLAG_C;
-flags = flags ^ mask;   // 1100 ^ 0110 => 1010
-
- -

Finally, the flags can all be flipped with the NOT operator:

- -
// entering parallel universe...
-flags = ~flags;    // ~1010 => 0101
-
- -

Conversion snippets

- -

Convert a binary String to a decimal Number:

- -
var sBinString = '1011';
-var nMyNumber = parseInt(sBinString, 2);
-alert(nMyNumber); // prints 11, i.e. 1011
-
- -

Convert a decimal Number to a binary String:

- -
var nMyNumber = 11;
-var sBinString = nMyNumber.toString(2);
-alert(sBinString); // prints 1011, i.e. 11
-
- -

Automate Mask Creation

- -

You can create multiple masks from a set of Boolean values, like this:

- -
function createMask() {
-  var nMask = 0, nFlag = 0, nLen = arguments.length > 32 ? 32 : arguments.length;
-  for (nFlag; nFlag < nLen; nMask |= arguments[nFlag] << nFlag++);
-  return nMask;
-}
-var mask1 = createMask(true, true, false, true); // 11, i.e.: 1011
-var mask2 = createMask(false, false, true); // 4, i.e.: 0100
-var mask3 = createMask(true); // 1, i.e.: 0001
-// etc.
-
-alert(mask1); // prints 11, i.e.: 1011
-
- -

Reverse algorithm: an array of booleans from a mask

- -

If you want to create an Array of Booleans from a mask you can use this code:

- -
function arrayFromMask(nMask) {
-  // nMask must be between -2147483648 and 2147483647
-  if (nMask > 0x7fffffff || nMask < -0x80000000) {
-    throw new TypeError('arrayFromMask - out of range');
-  }
-  for (var nShifted = nMask, aFromMask = []; nShifted;
-       aFromMask.push(Boolean(nShifted & 1)), nShifted >>>= 1);
-  return aFromMask;
-}
-
-var array1 = arrayFromMask(11);
-var array2 = arrayFromMask(4);
-var array3 = arrayFromMask(1);
-
-alert('[' + array1.join(', ') + ']');
-// prints "[true, true, false, true]", i.e.: 11, i.e.: 1011
-
- -

You can test both algorithms at the same time…

- -
var nTest = 19; // our custom mask
-var nResult = createMask.apply(this, arrayFromMask(nTest));
-
-alert(nResult); // 19
-
- -

For the didactic purpose only (since there is the Number.toString(2) method), we show how it is possible to modify the arrayFromMask algorithm in order to create a String containing the binary representation of a Number, rather than an Array of Booleans:

- -
function createBinaryString(nMask) {
-  // nMask must be between -2147483648 and 2147483647
-  for (var nFlag = 0, nShifted = nMask, sMask = ''; nFlag < 32;
-       nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
-  return sMask;
-}
-
-var string1 = createBinaryString(11);
-var string2 = createBinaryString(4);
-var string3 = createBinaryString(1);
-
-alert(string1);
-// prints 00000000000000000000000000001011, i.e. 11
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-11.7')}}{{Spec2('ES5.1')}}Defined in several sections of the specification: Bitwise NOT operator, Bitwise shift operators, Binary bitwise operators
{{SpecName('ES6', '#sec-bitwise-shift-operators')}}{{Spec2('ES6')}}Defined in several sections of the specification: Bitwise NOT operator, Bitwise shift operators, Binary bitwise operators
{{SpecName('ESDraft', '#sec-bitwise-shift-operators')}}{{Spec2('ESDraft')}}Defined in several sections of the specification: Bitwise NOT operator, Bitwise shift operators, Binary bitwise operators
- -

Browser compatibility

- - - -

{{Compat("javascript.operators.bitwise")}}

- -

See also

- - diff --git a/files/pt-br/web/javascript/reference/operators/comma_operator/index.html b/files/pt-br/web/javascript/reference/operators/comma_operator/index.html new file mode 100644 index 0000000000..be374104d0 --- /dev/null +++ b/files/pt-br/web/javascript/reference/operators/comma_operator/index.html @@ -0,0 +1,102 @@ +--- +title: Operador Vírgula +slug: Web/JavaScript/Reference/Operators/Operador_Virgula +translation_of: Web/JavaScript/Reference/Operators/Comma_Operator +--- +
+ {{jsSidebar("Operators")}}
+

Sumário

+

operador vírgula avalia o valor de seus operandos (da esquerda para a direita) e retorna o valor do último operando.

+

Sintaxe

+
expr1, expr2, expr3...
+

Parameters

+
+
+ expr1, expr2, expr3...
+
+ Quaisquer expressões.
+
+

Descrição

+

Você pode usar o operador vírgula quando desejar incluir múltiplas expressões em um lugar que requer uma única expressão. O uso mais comum desse operador é suprir múltiplos parâmetros em um loop for.

+

Exemplo

+

Se a é um array de 2 dimensões com 10 elementos de um lado, o seguinte código usa o operador vírgula para incrementar duas variáveis mutuamente. Note que a vírgula na declaração var não é o operador vírgula, porque ele não existe dentro de uma expressão. Além disso, ela é uma caractere especial nas declarações var para combinar múltiplas delas em uma única. Embora praticamente a vírgula comporte-se quase que igualmente ao operador vírgula. O código imprime os valores dos elementos diagonais da matriz:

+
for (var i = 0, j = 9; i <= 9; i++, j--)
+  document.writeln("a[" + i + "][" + j + "] = " + a[i][j]);
+
+

Especificações

+ + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
1ª Edição ECMAScript.PadrãoDefinição inicial.
{{SpecName('ES5.1', '#sec-11.14', 'Comma operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-comma-operator', 'Comma operator')}}{{Spec2('ES6')}} 
+

Compatibilidade de Navegadores

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
CaracterísticaChromeFirefox (Gecko)Internet ExplorerOperaSafari
Suporte Básico{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
CaracterísticaAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Suporte Básico{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+

Veja também

+ diff --git a/files/pt-br/web/javascript/reference/operators/conditional_operator/index.html b/files/pt-br/web/javascript/reference/operators/conditional_operator/index.html new file mode 100644 index 0000000000..9b36afca80 --- /dev/null +++ b/files/pt-br/web/javascript/reference/operators/conditional_operator/index.html @@ -0,0 +1,171 @@ +--- +title: Operador Condicional Ternário +slug: Web/JavaScript/Reference/Operators/Operador_Condicional +tags: + - JavaScript + - Operadores Condicionais +translation_of: Web/JavaScript/Reference/Operators/Conditional_Operator +--- +
{{jsSidebar("Operators")}}
+ +

Sumário

+ +

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

+ +

Sintaxe

+ +
condition ? expr1 : expr2 
+ +

Parâmetros

+ +
+
condition
+
Uma expressão que é avaliada como true ou false.
+
+ +
+
expr1, expr2
+
Expressões com valores de qualquer tipo.
+
+ +

Descrição

+ +

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

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

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

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

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

+ +
var firstCheck = false,
+    secondCheck = false,
+    access = firstCheck ? "Access denied" : secondCheck ? "Access denied" : "Access granted";
+
+console.log( access ); // logs "Access granted"
+ +

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

+ +
var stop = false, age = 16;
+
+age > 18 ? location.assign("continue.html") : stop = true;
+
+ +

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

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

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

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

Especificações

+ + + + + + + + + + + + + + + + + + + + + + + + +
EspecificaçõesStatusComentários
ECMAScript 1st Edition.StandardDefinição inicial. Implementado em JavaScript 1.0
{{SpecName('ES5.1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ES6')}} 
+ +

Compatibilidade dos navegadores (browser)

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

Veja também

+ + diff --git a/files/pt-br/web/javascript/reference/operators/destructuring_assignment/index.html b/files/pt-br/web/javascript/reference/operators/destructuring_assignment/index.html new file mode 100644 index 0000000000..6b1a100b4b --- /dev/null +++ b/files/pt-br/web/javascript/reference/operators/destructuring_assignment/index.html @@ -0,0 +1,445 @@ +--- +title: Atribuição via desestruturação (destructuring assignment) +slug: Web/JavaScript/Reference/Operators/Atribuicao_via_desestruturacao +translation_of: Web/JavaScript/Reference/Operators/Destructuring_assignment +--- +
{{jsSidebar("Operators")}}
+ +

A sintaxe de atribuição via desestruturação (destructuring assignment) é uma expressão JavaScript que possibilita extrair dados de arrays ou objetos em variáveis distintas.

+ +

Sintaxe

+ +
var a, b, rest;
+[a, b] = [1, 2];
+console.log(a); // 1
+console.log(b); // 2
+
+[a, b, ...rest] = [1, 2, 3, 4, 5];
+console.log(a); // 1
+console.log(b); // 2
+console.log(rest); // [3, 4, 5]
+
+({a, b} = {a:1, b:2});
+console.log(a); // 1
+console.log(b); // 2
+
+// ES2016 - não implementado em Firefox 47a01
+({a, b, ...rest} = {a:1, b:2, c:3, d:4});
+
+ +

Descrição

+ +

As expressões de objeto e matriz literais fornecem uma maneira fácil de criar pacotes ad hoc de dados .

+ +
var x = [1, 2, 3, 4, 5];
+ +

A atribuição via desestruturação usa sintaxe similar, mas no lado esquerdo da atribuição são definidos quais elementos devem ser extraídos da variável de origem.

+ +
var x = [1, 2, 3, 4, 5];
+var [y, z] = x;
+console.log(y); // 1
+console.log(z); // 2
+
+ +

Esse recurso é semelhante aos recursos presentes em linguagens como Perl e Python.

+ +

Desestruturação de array

+ +

Atribuição básica de variável

+ +
var foo = ["one", "two", "three"];
+
+var [one, two, three] = foo;
+console.log(one); // "one"
+console.log(two); // "two"
+console.log(three); // "three"
+
+ +

Atribuição separada da declaração

+ +

Uma variável pode ter seu valor atribuído via desestruturação separadamente da declaração dela.

+ +
var a, b;
+
+[a, b] = [1, 2];
+console.log(a); // 1
+console.log(b); // 2
+
+ +

Valores padrão

+ +

Uma variável pode ser atribuída de um padrão, no caso em que o valor retirado do array é undefined.

+ +
var a, b;
+
+[a=5, b=7] = [1];
+console.log(a); // 1
+console.log(b); // 7
+
+ +

Trocando variáveis

+ +

Os valores de duas variáveis podem ser trocados em uma expressão de desestruturação.

+ +

Sem atribuição via desestruturação, trocar dois valores requer uma variável temporária (ou, em algumas linguagens de baixo nível, o Algoritmo XOR Swap).

+ +
var a = 1;
+var b = 3;
+
+[a, b] = [b, a];
+console.log(a); // 3
+console.log(b); // 1
+
+ +

Analisando um array retornado de uma função

+ +

Sempre foi possível retornar uma matriz de uma função. A desestruturação pode tornar mais conciso o trabalho com um valor de retorno do tipo array.

+ +

Neste exemplo, f() returna os valores [1, 2] como saída, que podem ser analisados em uma única linha com desestruturação.

+ +
function f() {
+  return [1, 2];
+}
+
+var a, b;
+[a, b] = f();
+console.log(a); // 1
+console.log(b); // 2
+
+ +

Ignorando alguns valores retornados

+ +

Você pode ignorar valores retornados que você não tem interesse:

+ +
function f() {
+  return [1, 2, 3];
+}
+
+var [a, , b] = f();
+console.log(a); // 1
+console.log(b); // 3
+
+ +

Você também pode ignorar todos os valores retornados:

+ +
[,,] = f();
+
+ +

Atribuindo o resto de um array para uma variável

+ +

Ao desestruturar um array, você pode atribuir a parte restante deste em uma viáriável usando o padrão rest:

+ +
var [a, ...b] = [1, 2, 3];
+console.log(a); // 1
+console.log(b); // [2, 3]
+ +

Extraindo valores do resultado de uma expressão regular

+ +

Quando o método de expressão regular exec() encontra um resultado, ele retorna um array que contém primeiro toda a porção resultante da string e depois cada uma das porções da string resultante envolvidas por parênteses na expressão regular. A atribuição via desestruturação lhe permite extrair as partes desses array facilmente, ignorando a porção resultante completa se não precisar.

+ +
var url = "https://developer.mozilla.org/en-US/Web/JavaScript";
+
+var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
+console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]
+
+var [, protocol, fullhost, fullpath] = parsedURL;
+
+console.log(protocol); // "https"
+
+ +

Desestruturação de objeto

+ +

Atribuição básica

+ +
var o = {p: 42, q: true};
+var {p, q} = o;
+
+console.log(p); // 42
+console.log(q); // true
+
+ +

Atribuição sem declaração

+ +

Uma variável pode ter seu valor atribuído via desestruturação separadamente da sua declaração.

+ +
var a, b;
+
+({a, b} = {a:1, b:2});
+ +
+

Os parênteses ( ... ) ao redor da declaração de atribuição é uma sintaxe necessária  quando se utiliza a atribuição via desestruturação de objeto literal sem uma declaração.

+ +

{a, b} = {a:1, b:2} não é uma sintaxe stand-alone válida, pois {a, b} no lado esquerdo é considarada um bloco, não um objeto literal.

+ +

No entanto, ({a, b} = {a:1, b:2}) é valida, assim como var {a, b} = {a:1, b:2}

+
+ +

Atribuição para variáveis com novos nomes

+ +

Uma variável pode ser extraída de um objeto e atribuída a uma variável com um nome diferente da propriedade do objeto.

+ +
var o = {p: 42, q: true};
+var {p: foo, q: bar} = o;
+
+console.log(foo); // 42
+console.log(bar); // true  
+ +

Valores padrão

+ +

Uma variável pode ser atribuída de um padrão, no caso em que o valor retirado do objeto é undefined.

+ +
var {a=10, b=5} = {a: 3};
+
+console.log(a); // 3
+console.log(b); // 5
+ +

Definindo um valor padrão de parâmetro de função

+ +

Versão ES5

+ +
function drawES5Chart(options) {
+  options = options === undefined ? {} : options;
+  var size = options.size === undefined ? 'big' : options.size;
+  var cords = options.cords === undefined ? { x: 0, y: 0 } : options.cords;
+  var radius = options.radius === undefined ? 25 : options.radius;
+  console.log(size, cords, radius);
+  // now finally do some chart drawing
+}
+
+drawES5Chart({
+  cords: { x: 18, y: 30 },
+  radius: 30
+});
+ +

Versão ES2015

+ +
function drawES2015Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {}) {
+  console.log(size, cords, radius);
+  // do some chart drawing
+}
+
+drawES2015Chart({
+  cords: { x: 18, y: 30 },
+  radius: 30
+});
+ +

Objeto aninhado e desestruturação de array

+ +
var metadata = {
+    title: "Scratchpad",
+    translations: [
+       {
+        locale: "de",
+        localization_tags: [ ],
+        last_edit: "2014-04-14T08:43:37",
+        url: "/de/docs/Tools/Scratchpad",
+        title: "JavaScript-Umgebung"
+       }
+    ],
+    url: "/en-US/docs/Tools/Scratchpad"
+};
+
+var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata;
+
+console.log(englishTitle); // "Scratchpad"
+console.log(localeTitle);  // "JavaScript-Umgebung"
+ +

For de iteração e desestruturação

+ +
var people = [
+  {
+    name: "Mike Smith",
+    family: {
+      mother: "Jane Smith",
+      father: "Harry Smith",
+      sister: "Samantha Smith"
+    },
+    age: 35
+  },
+  {
+    name: "Tom Jones",
+    family: {
+      mother: "Norah Jones",
+      father: "Richard Jones",
+      brother: "Howard Jones"
+    },
+    age: 25
+  }
+];
+
+for (var {name: n, family: { father: f } } of people) {
+  console.log("Name: " + n + ", Father: " + f);
+}
+
+// "Name: Mike Smith, Father: Harry Smith"
+// "Name: Tom Jones, Father: Richard Jones"
+ +

Extraindo campos de objetos passados como parâmetro de função

+ +
function userId({id}) {
+  return id;
+}
+
+function whois({displayName: displayName, fullName: {firstName: name}}){
+  console.log(displayName + " is " + name);
+}
+
+var user = {
+  id: 42,
+  displayName: "jdoe",
+  fullName: {
+      firstName: "John",
+      lastName: "Doe"
+  }
+};
+
+console.log("userId: " + userId(user)); // "userId: 42"
+whois(user); // "jdoe is John"
+ +

Isso extrai o id, displayName e firstName do objeto user e os imprime na tela.

+ +

Nomes computados de propriedade de objeto e desestruturação

+ +

Nomes computados de propriedades, como em objetos literais, podem ser usados com desestruturação.

+ +
let key = "z";
+let { [key]: foo } = { z: "bar" };
+
+console.log(foo); // "bar"
+
+ +

Especificações

+ + + + + + + + + + + + + + + + + + + +
EspeficiaçãoSituaçãoComentário
{{SpecName('ES2015', '#sec-destructuring-assignment', 'Destructuring assignment')}}{{Spec2('ES2015')}}Definição inicial.
{{SpecName('ESDraft', '#sec-destructuring-assignment', 'Destructuring assignment')}}{{Spec2('ESDraft')}}
+ +

Compatibilidade do navegador

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FuncionalidadeChromeFirefox (Gecko)EdgeInternet ExplorerOperaSafari
+

Suporte básico

+
{{CompatChrome(49.0)}}{{ CompatGeckoDesktop("1.8.1") }}14{{CompatNo}}{{CompatNo}}7.1
+

Nomes computados de propriedades

+
{{CompatChrome(49.0)}}{{ CompatGeckoDesktop("34") }}14{{CompatNo}}{{CompatNo}}{{CompatNo}}
Operador spread{{CompatChrome(49.0)}}{{ CompatGeckoDesktop("34") }}12[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FuncionalidadeAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Suporte básico{{CompatNo}}{{CompatChrome(49.0)}}{{ CompatGeckoMobile("1.0") }}{{CompatNo}}{{CompatNo}}8{{CompatChrome(49.0)}}
Nomes computados de propriedades{{CompatNo}}{{CompatChrome(49.0)}}{{ CompatGeckoMobile("34") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatChrome(49.0)}}
Operador spread{{CompatNo}}{{CompatChrome(49.0)}}{{ CompatGeckoMobile("34") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(49.0)}}
+
+ +

[1] Requer "Enable experimental Javascript features" para funciona sob `about:flags`

+ +

Notas específicas do Firefox

+ + + +

Veja também

+ + diff --git a/files/pt-br/web/javascript/reference/operators/inicializador_objeto/index.html b/files/pt-br/web/javascript/reference/operators/inicializador_objeto/index.html deleted file mode 100644 index ac59b4e7f8..0000000000 --- a/files/pt-br/web/javascript/reference/operators/inicializador_objeto/index.html +++ /dev/null @@ -1,392 +0,0 @@ ---- -title: Inicializador de Objeto -slug: Web/JavaScript/Reference/Operators/Inicializador_Objeto -tags: - - ECMAScript 2015 - - JSON - - JavaScript - - Literal - - Métodos - - Objeto - - Propriedades - - mutação -translation_of: Web/JavaScript/Reference/Operators/Object_initializer ---- -
{{JsSidebar("Operadores")}}
- -

Objetos podem ser inicializados utilizando new Object(), Object.create(), ou a notação literal. Um inicializador de objetos é uma lista de zero ou mais pares de propriedade: valor, separados por vírgula e fechado por um par de chaves ({}).

- -

Sintaxe

- -
var o = {};
-var o = { a: "foo", b: 42, c: {} };
-
-var a = "foo", b = 42, c = {};
-var o = { a: a, b: b, c: c };
-
-var o = {
-  propriedade: function ([parâmetros]) {},
-  get propriedade() {},
-  set propriedade(valor) {},
-};
-
- -

Novas notações em ECMAScript 2015

- -

Por favor, verifique o suporte das anotações na tabela de compatibilidade. Em ambientes que não dão suporte às anotações, ocorrerá erros de sintaxe.

- -
// // Abreviação em nomes de propriedades (ES2015)
-var a = "foo", b = 42, c = {};
-var o = { a, b, c };
-
-// // Abreviação em nomes de métodos (ES2015)
-var o = {
-  property([parameters]) {},
-  get property() {},
-  set property(value) {},
-};
-
-// Nomes de propriedades computados (ES2015)
-var prop = "foo";
-var o = {
-  [prop]: "hey",
-  ["b" + "ar"]: "there",
-};
- -

Descrição

- -

Um inicializador de objetos é uma expressão que descreve a inicialização de um {{jsxref("Object")}}. Objects consiste de propriedades, as quais descrevem um objeto. Os valores das propriedades de um objeto podem ser tipos de dados {{Glossary("primitivos")}} ou outros objetos .

- -

Criando objetos

- -

Um objeto vazio, sem propriedades, pode ser criado como: 

- -
var object = {};
- -

Contudo, a vantagem em utilizar a notação literal ou o inicializador é a possibilidade de rapidamente criar objetos com propriedades dentro de chaves ({}). Você simplesmente cria uma lista de pares chave: valor, separados por vírgula. O código abaixo cria um objeto com três propriedades, sendo as chaves "foo", "age" e "baz", com seus respectivos valores, tipo string de valor "bar", tipo number de valor 42 e, por último, um outro objeto com seus respectivos pares de chave: valor

- -
var object = {
-  foo: "bar",
-  age: 42,
-  baz: { myProp: 12 },
-}
- -

Acessando propriedades

- -

Uma vez que você criou um objeto, é interessante que possa ler ou alterá-lo. As propriedades de um objeto podem ser acessadas utilizando a notação de ponto ou colchetes. Veja assessores de propriedade para mais informações.

- -
object.foo; // "bar"
-object["age"]; // 42
-
-object.foo = "baz";
-
- -

Definições de propriedade

- -

Nós temos aprendido como descrever propriedades utilizando a sintaxe inicializador. No entanto, às vezes, há variáveis que queremos inserir em nosso objeto. Então teremos um código parecido como abaixo: 

- -
var a = "foo",
-    b = 42,
-    c = {};
-
-var o = {
-  a: a,
-  b: b,
-  c: c
-};
- -

Com ECMAScript 2015, há uma notação mais curta que possibilita atingir o mesmo resultado: 

- -
var a = "foo",
-    b = 42,
-    c = {};
-
-// Abreviação em nomes de propriedades (ES2015)
-var o = { a, b, c };
-
-// Em outras palavras,
-console.log((o.a === { a }.a)); // true
-
- -

Duplicação em nomes de propriedades

- -

Quando se está utilizando o mesmo nome para suas propriedades, a última sobrescreverá as anteriores.

- -
var a = {x: 1, x: 2};
-console.log(a); // { x: 2}
-
- -

Em códigos ECMAScript 5 no modo estrito, duplicação em nomes de propriedades serão consideradas {{jsxref("SyntaxError")}}. Porém, com a introdução de "nomes de propriedades computadas", tornou-se possível a duplicação das propriedades em tempo de execução. Assim, ECMAScript 2015 removeu a restrição.

- -
function haveES2015DuplicatePropertySemantics(){
-  "use strict";
-  try {
-    ({ prop: 1, prop: 2 });
-
-    // No error thrown, duplicate property names allowed in strict mode
-    return true;
-  } catch (e) {
-    // Error thrown, duplicates prohibited in strict mode
-    return false;
-  }
-}
- -

Definição de métodos

- -

Uma propriedade de um objeto pode se referir à function, ou aos métodos getter ou setter.

- -
var o = {
-  propriedade: function ([parâmetros]) {},
-  get propriedade() {},
-  set propriedade(valor) {},
-};
- -

No ECMAScript 2015, uma notação abreviada está disponível, dispensando o uso da palavra reservada "function".

- -
// Abreviações em nomes de métodos (ES2015)
-var o = {
-  propriedade([parâmetros]) {},
-  get propriedade() {},
-  set propriedade(valor) {},
-  * gerador() {}
-};
- -

Com ECMAScript 2015, há uma forma concisa em criar propriedades cujo valor é uma função gerador. 

- -
var o = {
-  * gerador() {
-    ...........
-  }
-};
- -

Mas em ECMAScript 5, você escreveria (lembrar que em ES5 não há geradores):

- -
var o = {
-  generator: function *() {
-    ...........
-  }
-};
- -

Para mais informações e exemplos, veja definições de método.

- -

Nomes de propriedades computados

- -

Começando com ECMAScript 2015, a sintaxe inicializador de objeto também suporta "nomes de propriedades computados". Isso permite que você possa inserir uma expressão dentro de colchetes [], que será computada como o nome de uma propriedade. Isto é semelhante à notação de chaves utilizado em acessor de propriedade, utilizado para ler a alterar as propriedades existentes em um objeto. Segue um exemplo utilizando a mesma sintaxe em objetos literais: 

- -
// Nomes de propriedades computados (ES2015)
-var i = 0;
-var a = {
-  ["foo" + ++i]: i,
-  ["foo" + ++i]: i,
-  ["foo" + ++i]: i
-};
-
-console.log(a.foo1); // 1
-console.log(a.foo2); // 2
-console.log(a.foo3); // 3
-
-var param = 'size';
-var config = {
-  [param]: 12,
-  ["mobile" + param.charAt(0).toUpperCase() + param.slice(1)]: 4
-};
-
-console.log(config); // { size: 12, mobileSize: 4 }
- -

Mutação Prototype 

- -

Uma definição de propriedade na forma de  __proto__: valor or "__proto__": valor não cria uma propriedade com o nome  __proto__.  Inclusive, se o valor fornecido for um objeto ou null, muda o [[Prototype]] do objeto criado para o valor informado. (Se o valor fornecido não é um objeto ou null, o valor não será alterado.)

- -
var obj1 = {};
-assert(Object.getPrototypeOf(obj1) === Object.prototype);
-
-var obj2 = { __proto__: null };
-assert(Object.getPrototypeOf(obj2) === null);
-
-var protoObj = {};
-var obj3 = { "__proto__": protoObj };
-assert(Object.getPrototypeOf(obj3) === protoObj);
-
-var obj4 = { __proto__: "not an object or null" };
-assert(Object.getPrototypeOf(obj4) === Object.prototype);
-assert(!obj4.hasOwnProperty("__proto__"));
-
- -

Apenas uma única mudança em prototype é permitida em um objeto: múltiplas mudanças gera erro de sintaxe. 

- -

Definições de propriedade que não utilizam da notação de ":", não são consideradas mudanças de prototype: são definições de propriedades que se comportam de forma semelhante às definições utilizando qualquer outro nome. 

- -
var __proto__ = "variable";
-
-var obj1 = { __proto__ };
-assert(Object.getPrototypeOf(obj1) === Object.prototype);
-assert(obj1.hasOwnProperty("__proto__"));
-assert(obj1.__proto__ === "variable");
-
-var obj2 = { __proto__() { return "hello"; } };
-assert(obj2.__proto__() === "hello");
-
-var obj3 = { ["__prot" + "o__"]: 17 };
-assert(obj3.__proto__ === 17);
-
- -

Notação de objeto literal vs JSON

- -

A notação de objeto literal não é a mesma de JavaScript Object Notation (JSON).  Mesmo que possuam semelhanças, há as seguintes diferenças:

- - - -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Definição inicial.
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}getter e setter adicionados.
{{SpecName('ES6', '#sec-object-initializer', 'Object Initializer')}}{{Spec2('ES6')}}Abreviações de nomes em propriedades/métodos e nomes de propriedados computados foram adicionados.
{{SpecName('ESDraft', '#sec-object-initializer', 'Object Initializer')}}{{Spec2('ESDraft')}} 
- -

Compatibilidade de Browser

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Suporte básico{{CompatChrome(1.0)}}{{CompatGeckoDesktop("1.0")}}111
Nomes de propriedades computados{{CompatVersionUnknown}}{{CompatGeckoDesktop("34")}}{{CompatNo}}{{CompatNo}}7.1
Abreviação em nomes de propriedades{{CompatVersionUnknown}}{{CompatGeckoDesktop("33")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
Abreviação em nomes de métodos{{CompatChrome(42.0)}}{{CompatGeckoDesktop("34")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Suporte básico{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}111{{CompatChrome(1.0)}}
Nomes de propriedades computados{{CompatNo}}{{CompatVersionUnknown}}{{CompatGeckoMobile("34")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
Abreviação em nomes de propriedades{{CompatNo}}{{CompatVersionUnknown}}{{CompatGeckoMobile("33")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
Abreviação em nomes de métodos{{CompatNo}}{{CompatChrome(42.0)}}{{CompatGeckoMobile("34")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatChrome(42.0)}}
-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/operators/nullish_coalescing_operator/index.html b/files/pt-br/web/javascript/reference/operators/nullish_coalescing_operator/index.html new file mode 100644 index 0000000000..609bfa29fd --- /dev/null +++ b/files/pt-br/web/javascript/reference/operators/nullish_coalescing_operator/index.html @@ -0,0 +1,159 @@ +--- +title: Operador de coalescência nula +slug: Web/JavaScript/Reference/Operators/operador_de_coalescencia_nula +tags: + - JavaScript + - Operador + - Operadores lógicos + - Referencia + - coalescencia nula + - duas interrogações + - nulidade +translation_of: Web/JavaScript/Reference/Operators/Nullish_coalescing_operator +--- +

{{JSSidebar("Operators")}}

+ +

O operador de coalescência nula (??) é um operador lógico que retorna o seu operando do lado direito quando o seu operador do lado esquerdo é {{jsxref("null")}} ou {{jsxref("undefined")}}. Caso contrário, ele retorna o seu operando do lado esquerdo.

+ +

Ao contrário do operador lógico OR (||), o operando esquerdo é retornado se houver um valor falsy (falso) que não seja null ou undefined. Em outras palavras, se você usar || para obter algum valor padrão para outra variável foo, você pode enfrentar comportamentos inesperados se você considerar algum valor falseável como utilizável (eg. '' ou 0). Veja abaixo alguns exemplos:

+ +
{{EmbedInteractiveExample("pages/js/expressions-nullishcoalescingoperator.html")}}
+ + + +

Sintaxe

+ +
exprEsq ?? exprDir
+
+ +

Descrição

+ +

O operador de coalescência nula retorna os resultados da expressão de seu lado direito se a expressão de seu lado esquerdo for {{jsxref("null")}} ou {{jsxref("undefined")}}.

+ +

Endereçando um valor padrão à variável

+ +

Inicialmente, quando se deseja endereçar um valor padrão à variável, um padrão comum é utilizar o operador lógico OR  (||):

+ +
let foo;
+
+//  foo nunca é endereçado a nenhum valor, portanto, ainda está indefinido
+let someDummyText = foo || 'Hello!';
+ +

Entretanto, devido ao || ser um operador lógico booleano, o operando do lado esquerdo é coagido para um valor booleano para sua avaliação, e, qualquer valor falseável (0, '', NaN, null, undefined) não é retornado. Este comportamento pode causar consequencias inesperadas se você considerar 0, '', or NaN como valores válidos.

+ +
let count = 0;
+let text = "";
+
+let qty = count || 42;
+let message = text || "Olá!";
+console.log(qty);     // 42 e não 0
+console.log(message); // "hi!" e não ""
+
+ +

O operador de coalescência nula evita esta cilada pois retorna o segundo operando apenas quando o primeiro é avaliado entre os valores null ou undefined (mas nehum outro valor falseável):

+ +
let myText = ''; // Uma string vazia (que também é um valor falseável)
+
+let notFalsyText = myText || 'Olá mundo';
+console.log(notFalsyText); // Olá mundo
+
+let preservingFalsy = myText ?? 'Olá vizinhança';
+console.log(preservingFalsy); // '' (Pois myText não é undefined e nem null)
+
+ +

Curto-circuito

+ +

Assim como os operadores lógicos OR e AND, a expressão do lado direito não é avaliada se o lado esquerdo não for avaliado entre null e nem undefined.

+ +
function A() { console.log('A foi chamado'); return undefined;}
+function B() { console.log('B foi chamado'); return false;}
+function C() { console.log('C foi chamado'); return "foo";}
+
+console.log( A() ?? C() );
+// Imprime "A foi chamado" então "C foi chamado" e por fim "foo"
+// Como A() retornou undefined então ambas expressões foram avaliadas
+
+console.log( B() ?? C() );
+// Imprime "B foi chamado" então "false"
+// Como B() retornou false (e não null ou undefined), a expressão
+// do lado direito não foi avaliada.
+
+ +

Sem encadeamento com os operadores AND e OR

+ +

Não é possível encadear ambos operadores AND (&&) e OR (||) diretamente com o ??. Um SyntaxError será disparado nesse tipo de caso.

+ +
null || undefined ?? "foo"; // Dispara um SyntaxError
+true || undefined ?? "foo"; // Dispara um SyntaxError
+ +

Entretanto, explicitar diretamente a precedência por meio de parênteses resulta no comportamento correto:

+ +
(null || undefined) ?? "foo"; // retorna "foo"
+
+ +

Relacionamento com o operador de encadeamento opcional (?.)

+ +

O operador de coalescêcia nula trata undefined e null como valores específicos e então executa o operador de encadeamento opcional (?.) o qual é útil para acessar uma propriedade de um objeto, o qual pode ser null ou undefined.

+ +
let foo = { someFooProp: "oi" };
+
+console.log(foo.someFooProp?.toUpperCase());  // "OI"
+console.log(foo.someBarProp?.toUpperCase()); // undefined
+
+ +

Exemplo

+ +

Neste exemplo, nós iremos prover valores padrão, mas manter valores que não sejam (advinha???) null ou undefined.

+ +
const nullValue = null;
+const emptyText = ""; // falseável (falsy)
+const someNumber = 42;
+
+const valA = nullValue ?? "padrão para A";
+const valB = emptyText ?? "padrão para B";
+const valC = someNumber ?? 0;
+
+console.log(valA); // "padrão para A"
+console.log(valB); // "" (pois a string vazia não é null ou undefined)
+console.log(valC); // 42
+
+ +

Especificações

+ + + + + + + + + + + + + + + + +
EspecificaçãoStatuscomentário
Proposal for the "nullish coalescing" operatorStage 4
+ +

Compatibilidade de navegadores

+ + + +

{{Compat("javascript.operators.nullish_coalescing")}}

+ +

Progresso de implementação

+ +

A seguinte tabela fornece o status diário de implementação para este recurso, porque este recurso ainda não atingiu a estabilidade entre navegadores. Os dados são gerados pela execução de testes de recursos relevantes no Test262, a plataforma de testes padrão do JavaScript, em "edições noturnas", ou último release de cada motor JavaScript dos navegadores.

+ +
{{EmbedTest262ReportResultsTable("coalesce-expression")}}
+ +

Veja também

+ + diff --git a/files/pt-br/web/javascript/reference/operators/object_initializer/index.html b/files/pt-br/web/javascript/reference/operators/object_initializer/index.html new file mode 100644 index 0000000000..ac59b4e7f8 --- /dev/null +++ b/files/pt-br/web/javascript/reference/operators/object_initializer/index.html @@ -0,0 +1,392 @@ +--- +title: Inicializador de Objeto +slug: Web/JavaScript/Reference/Operators/Inicializador_Objeto +tags: + - ECMAScript 2015 + - JSON + - JavaScript + - Literal + - Métodos + - Objeto + - Propriedades + - mutação +translation_of: Web/JavaScript/Reference/Operators/Object_initializer +--- +
{{JsSidebar("Operadores")}}
+ +

Objetos podem ser inicializados utilizando new Object(), Object.create(), ou a notação literal. Um inicializador de objetos é uma lista de zero ou mais pares de propriedade: valor, separados por vírgula e fechado por um par de chaves ({}).

+ +

Sintaxe

+ +
var o = {};
+var o = { a: "foo", b: 42, c: {} };
+
+var a = "foo", b = 42, c = {};
+var o = { a: a, b: b, c: c };
+
+var o = {
+  propriedade: function ([parâmetros]) {},
+  get propriedade() {},
+  set propriedade(valor) {},
+};
+
+ +

Novas notações em ECMAScript 2015

+ +

Por favor, verifique o suporte das anotações na tabela de compatibilidade. Em ambientes que não dão suporte às anotações, ocorrerá erros de sintaxe.

+ +
// // Abreviação em nomes de propriedades (ES2015)
+var a = "foo", b = 42, c = {};
+var o = { a, b, c };
+
+// // Abreviação em nomes de métodos (ES2015)
+var o = {
+  property([parameters]) {},
+  get property() {},
+  set property(value) {},
+};
+
+// Nomes de propriedades computados (ES2015)
+var prop = "foo";
+var o = {
+  [prop]: "hey",
+  ["b" + "ar"]: "there",
+};
+ +

Descrição

+ +

Um inicializador de objetos é uma expressão que descreve a inicialização de um {{jsxref("Object")}}. Objects consiste de propriedades, as quais descrevem um objeto. Os valores das propriedades de um objeto podem ser tipos de dados {{Glossary("primitivos")}} ou outros objetos .

+ +

Criando objetos

+ +

Um objeto vazio, sem propriedades, pode ser criado como: 

+ +
var object = {};
+ +

Contudo, a vantagem em utilizar a notação literal ou o inicializador é a possibilidade de rapidamente criar objetos com propriedades dentro de chaves ({}). Você simplesmente cria uma lista de pares chave: valor, separados por vírgula. O código abaixo cria um objeto com três propriedades, sendo as chaves "foo", "age" e "baz", com seus respectivos valores, tipo string de valor "bar", tipo number de valor 42 e, por último, um outro objeto com seus respectivos pares de chave: valor

+ +
var object = {
+  foo: "bar",
+  age: 42,
+  baz: { myProp: 12 },
+}
+ +

Acessando propriedades

+ +

Uma vez que você criou um objeto, é interessante que possa ler ou alterá-lo. As propriedades de um objeto podem ser acessadas utilizando a notação de ponto ou colchetes. Veja assessores de propriedade para mais informações.

+ +
object.foo; // "bar"
+object["age"]; // 42
+
+object.foo = "baz";
+
+ +

Definições de propriedade

+ +

Nós temos aprendido como descrever propriedades utilizando a sintaxe inicializador. No entanto, às vezes, há variáveis que queremos inserir em nosso objeto. Então teremos um código parecido como abaixo: 

+ +
var a = "foo",
+    b = 42,
+    c = {};
+
+var o = {
+  a: a,
+  b: b,
+  c: c
+};
+ +

Com ECMAScript 2015, há uma notação mais curta que possibilita atingir o mesmo resultado: 

+ +
var a = "foo",
+    b = 42,
+    c = {};
+
+// Abreviação em nomes de propriedades (ES2015)
+var o = { a, b, c };
+
+// Em outras palavras,
+console.log((o.a === { a }.a)); // true
+
+ +

Duplicação em nomes de propriedades

+ +

Quando se está utilizando o mesmo nome para suas propriedades, a última sobrescreverá as anteriores.

+ +
var a = {x: 1, x: 2};
+console.log(a); // { x: 2}
+
+ +

Em códigos ECMAScript 5 no modo estrito, duplicação em nomes de propriedades serão consideradas {{jsxref("SyntaxError")}}. Porém, com a introdução de "nomes de propriedades computadas", tornou-se possível a duplicação das propriedades em tempo de execução. Assim, ECMAScript 2015 removeu a restrição.

+ +
function haveES2015DuplicatePropertySemantics(){
+  "use strict";
+  try {
+    ({ prop: 1, prop: 2 });
+
+    // No error thrown, duplicate property names allowed in strict mode
+    return true;
+  } catch (e) {
+    // Error thrown, duplicates prohibited in strict mode
+    return false;
+  }
+}
+ +

Definição de métodos

+ +

Uma propriedade de um objeto pode se referir à function, ou aos métodos getter ou setter.

+ +
var o = {
+  propriedade: function ([parâmetros]) {},
+  get propriedade() {},
+  set propriedade(valor) {},
+};
+ +

No ECMAScript 2015, uma notação abreviada está disponível, dispensando o uso da palavra reservada "function".

+ +
// Abreviações em nomes de métodos (ES2015)
+var o = {
+  propriedade([parâmetros]) {},
+  get propriedade() {},
+  set propriedade(valor) {},
+  * gerador() {}
+};
+ +

Com ECMAScript 2015, há uma forma concisa em criar propriedades cujo valor é uma função gerador. 

+ +
var o = {
+  * gerador() {
+    ...........
+  }
+};
+ +

Mas em ECMAScript 5, você escreveria (lembrar que em ES5 não há geradores):

+ +
var o = {
+  generator: function *() {
+    ...........
+  }
+};
+ +

Para mais informações e exemplos, veja definições de método.

+ +

Nomes de propriedades computados

+ +

Começando com ECMAScript 2015, a sintaxe inicializador de objeto também suporta "nomes de propriedades computados". Isso permite que você possa inserir uma expressão dentro de colchetes [], que será computada como o nome de uma propriedade. Isto é semelhante à notação de chaves utilizado em acessor de propriedade, utilizado para ler a alterar as propriedades existentes em um objeto. Segue um exemplo utilizando a mesma sintaxe em objetos literais: 

+ +
// Nomes de propriedades computados (ES2015)
+var i = 0;
+var a = {
+  ["foo" + ++i]: i,
+  ["foo" + ++i]: i,
+  ["foo" + ++i]: i
+};
+
+console.log(a.foo1); // 1
+console.log(a.foo2); // 2
+console.log(a.foo3); // 3
+
+var param = 'size';
+var config = {
+  [param]: 12,
+  ["mobile" + param.charAt(0).toUpperCase() + param.slice(1)]: 4
+};
+
+console.log(config); // { size: 12, mobileSize: 4 }
+ +

Mutação Prototype 

+ +

Uma definição de propriedade na forma de  __proto__: valor or "__proto__": valor não cria uma propriedade com o nome  __proto__.  Inclusive, se o valor fornecido for um objeto ou null, muda o [[Prototype]] do objeto criado para o valor informado. (Se o valor fornecido não é um objeto ou null, o valor não será alterado.)

+ +
var obj1 = {};
+assert(Object.getPrototypeOf(obj1) === Object.prototype);
+
+var obj2 = { __proto__: null };
+assert(Object.getPrototypeOf(obj2) === null);
+
+var protoObj = {};
+var obj3 = { "__proto__": protoObj };
+assert(Object.getPrototypeOf(obj3) === protoObj);
+
+var obj4 = { __proto__: "not an object or null" };
+assert(Object.getPrototypeOf(obj4) === Object.prototype);
+assert(!obj4.hasOwnProperty("__proto__"));
+
+ +

Apenas uma única mudança em prototype é permitida em um objeto: múltiplas mudanças gera erro de sintaxe. 

+ +

Definições de propriedade que não utilizam da notação de ":", não são consideradas mudanças de prototype: são definições de propriedades que se comportam de forma semelhante às definições utilizando qualquer outro nome. 

+ +
var __proto__ = "variable";
+
+var obj1 = { __proto__ };
+assert(Object.getPrototypeOf(obj1) === Object.prototype);
+assert(obj1.hasOwnProperty("__proto__"));
+assert(obj1.__proto__ === "variable");
+
+var obj2 = { __proto__() { return "hello"; } };
+assert(obj2.__proto__() === "hello");
+
+var obj3 = { ["__prot" + "o__"]: 17 };
+assert(obj3.__proto__ === 17);
+
+ +

Notação de objeto literal vs JSON

+ +

A notação de objeto literal não é a mesma de JavaScript Object Notation (JSON).  Mesmo que possuam semelhanças, há as seguintes diferenças:

+ + + +

Especificações

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Definição inicial.
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}getter e setter adicionados.
{{SpecName('ES6', '#sec-object-initializer', 'Object Initializer')}}{{Spec2('ES6')}}Abreviações de nomes em propriedades/métodos e nomes de propriedados computados foram adicionados.
{{SpecName('ESDraft', '#sec-object-initializer', 'Object Initializer')}}{{Spec2('ESDraft')}} 
+ +

Compatibilidade de Browser

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Suporte básico{{CompatChrome(1.0)}}{{CompatGeckoDesktop("1.0")}}111
Nomes de propriedades computados{{CompatVersionUnknown}}{{CompatGeckoDesktop("34")}}{{CompatNo}}{{CompatNo}}7.1
Abreviação em nomes de propriedades{{CompatVersionUnknown}}{{CompatGeckoDesktop("33")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
Abreviação em nomes de métodos{{CompatChrome(42.0)}}{{CompatGeckoDesktop("34")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Suporte básico{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.0")}}111{{CompatChrome(1.0)}}
Nomes de propriedades computados{{CompatNo}}{{CompatVersionUnknown}}{{CompatGeckoMobile("34")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
Abreviação em nomes de propriedades{{CompatNo}}{{CompatVersionUnknown}}{{CompatGeckoMobile("33")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
Abreviação em nomes de métodos{{CompatNo}}{{CompatChrome(42.0)}}{{CompatGeckoMobile("34")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatChrome(42.0)}}
+
+ +

Veja também

+ + diff --git a/files/pt-br/web/javascript/reference/operators/operador_condicional/index.html b/files/pt-br/web/javascript/reference/operators/operador_condicional/index.html deleted file mode 100644 index 9b36afca80..0000000000 --- a/files/pt-br/web/javascript/reference/operators/operador_condicional/index.html +++ /dev/null @@ -1,171 +0,0 @@ ---- -title: Operador Condicional Ternário -slug: Web/JavaScript/Reference/Operators/Operador_Condicional -tags: - - JavaScript - - Operadores Condicionais -translation_of: Web/JavaScript/Reference/Operators/Conditional_Operator ---- -
{{jsSidebar("Operators")}}
- -

Sumário

- -

O operador condicional (ternário) é o único operador JavaScript que possui três operandos. Este operador é frequentemente usado como um atalho para a instrução if.

- -

Sintaxe

- -
condition ? expr1 : expr2 
- -

Parâmetros

- -
-
condition
-
Uma expressão que é avaliada como true ou false.
-
- -
-
expr1, expr2
-
Expressões com valores de qualquer tipo.
-
- -

Descrição

- -

Se condition é true, o operador retornará o valor de expr1; se não, ele retorna o valor de exp2. Por exemplo, para exibir uma mensagem diferente baseada no valor da variável isMember, você poderá utilizar o código (statement) seguinte:

- -
"The fee is " + (isMember ? "$2.00" : "$10.00")
-
- -

Conforme o resultado da operação, você também poderá atribuir a variáveis:

- -
var elvisLives = Math.PI > 4 ? "Yep" : "Nope";
- -

Também são possíveis múltiplas avaliaçãoes ternárias (nota: o operador condicional é associativo a direita):

- -
var firstCheck = false,
-    secondCheck = false,
-    access = firstCheck ? "Access denied" : secondCheck ? "Access denied" : "Access granted";
-
-console.log( access ); // logs "Access granted"
- -

Você também pode usar avaliações ternárias no espaço livre de modo a fazer diferentes operações:

- -
var stop = false, age = 16;
-
-age > 18 ? location.assign("continue.html") : stop = true;
-
- -

Você também pode fazer mais do que uma única operação em cada caso, separando-os por vírgula:

- -
var stop = false, age = 23;
-
-age > 18 ? (
-    alert("OK, you can go."),
-    location.assign("continue.html")
-) : (
-    stop = true,
-    alert("Sorry, you are much too young!")
-);
-
- -

Você também pode fazer mais de uma operação durante a atribuição de um valor. Neste caso, o último valor separado por vírgula dentro dos parênteses será o valor a ser atribuído.

- -
var age = 16;
-
-var url = age > 18 ? (
-    alert("OK, you can go."),
-    // alert returns "undefined", but it will be ignored because
-    // isn't the last comma-separated value of the parenthesis
-    "continue.html" // the value to be assigned if age > 18
-) : (
-    alert("You are much too young!"),
-    alert("Sorry :-("),
-    // etc. etc.
-    "stop.html" // the value to be assigned if !(age > 18)
-);
-
-location.assign(url); // "stop.html"
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - -
EspecificaçõesStatusComentários
ECMAScript 1st Edition.StandardDefinição inicial. Implementado em JavaScript 1.0
{{SpecName('ES5.1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ES6')}} 
- -

Compatibilidade dos navegadores (browser)

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/operators/operador_de_coalescencia_nula/index.html b/files/pt-br/web/javascript/reference/operators/operador_de_coalescencia_nula/index.html deleted file mode 100644 index 609bfa29fd..0000000000 --- a/files/pt-br/web/javascript/reference/operators/operador_de_coalescencia_nula/index.html +++ /dev/null @@ -1,159 +0,0 @@ ---- -title: Operador de coalescência nula -slug: Web/JavaScript/Reference/Operators/operador_de_coalescencia_nula -tags: - - JavaScript - - Operador - - Operadores lógicos - - Referencia - - coalescencia nula - - duas interrogações - - nulidade -translation_of: Web/JavaScript/Reference/Operators/Nullish_coalescing_operator ---- -

{{JSSidebar("Operators")}}

- -

O operador de coalescência nula (??) é um operador lógico que retorna o seu operando do lado direito quando o seu operador do lado esquerdo é {{jsxref("null")}} ou {{jsxref("undefined")}}. Caso contrário, ele retorna o seu operando do lado esquerdo.

- -

Ao contrário do operador lógico OR (||), o operando esquerdo é retornado se houver um valor falsy (falso) que não seja null ou undefined. Em outras palavras, se você usar || para obter algum valor padrão para outra variável foo, você pode enfrentar comportamentos inesperados se você considerar algum valor falseável como utilizável (eg. '' ou 0). Veja abaixo alguns exemplos:

- -
{{EmbedInteractiveExample("pages/js/expressions-nullishcoalescingoperator.html")}}
- - - -

Sintaxe

- -
exprEsq ?? exprDir
-
- -

Descrição

- -

O operador de coalescência nula retorna os resultados da expressão de seu lado direito se a expressão de seu lado esquerdo for {{jsxref("null")}} ou {{jsxref("undefined")}}.

- -

Endereçando um valor padrão à variável

- -

Inicialmente, quando se deseja endereçar um valor padrão à variável, um padrão comum é utilizar o operador lógico OR  (||):

- -
let foo;
-
-//  foo nunca é endereçado a nenhum valor, portanto, ainda está indefinido
-let someDummyText = foo || 'Hello!';
- -

Entretanto, devido ao || ser um operador lógico booleano, o operando do lado esquerdo é coagido para um valor booleano para sua avaliação, e, qualquer valor falseável (0, '', NaN, null, undefined) não é retornado. Este comportamento pode causar consequencias inesperadas se você considerar 0, '', or NaN como valores válidos.

- -
let count = 0;
-let text = "";
-
-let qty = count || 42;
-let message = text || "Olá!";
-console.log(qty);     // 42 e não 0
-console.log(message); // "hi!" e não ""
-
- -

O operador de coalescência nula evita esta cilada pois retorna o segundo operando apenas quando o primeiro é avaliado entre os valores null ou undefined (mas nehum outro valor falseável):

- -
let myText = ''; // Uma string vazia (que também é um valor falseável)
-
-let notFalsyText = myText || 'Olá mundo';
-console.log(notFalsyText); // Olá mundo
-
-let preservingFalsy = myText ?? 'Olá vizinhança';
-console.log(preservingFalsy); // '' (Pois myText não é undefined e nem null)
-
- -

Curto-circuito

- -

Assim como os operadores lógicos OR e AND, a expressão do lado direito não é avaliada se o lado esquerdo não for avaliado entre null e nem undefined.

- -
function A() { console.log('A foi chamado'); return undefined;}
-function B() { console.log('B foi chamado'); return false;}
-function C() { console.log('C foi chamado'); return "foo";}
-
-console.log( A() ?? C() );
-// Imprime "A foi chamado" então "C foi chamado" e por fim "foo"
-// Como A() retornou undefined então ambas expressões foram avaliadas
-
-console.log( B() ?? C() );
-// Imprime "B foi chamado" então "false"
-// Como B() retornou false (e não null ou undefined), a expressão
-// do lado direito não foi avaliada.
-
- -

Sem encadeamento com os operadores AND e OR

- -

Não é possível encadear ambos operadores AND (&&) e OR (||) diretamente com o ??. Um SyntaxError será disparado nesse tipo de caso.

- -
null || undefined ?? "foo"; // Dispara um SyntaxError
-true || undefined ?? "foo"; // Dispara um SyntaxError
- -

Entretanto, explicitar diretamente a precedência por meio de parênteses resulta no comportamento correto:

- -
(null || undefined) ?? "foo"; // retorna "foo"
-
- -

Relacionamento com o operador de encadeamento opcional (?.)

- -

O operador de coalescêcia nula trata undefined e null como valores específicos e então executa o operador de encadeamento opcional (?.) o qual é útil para acessar uma propriedade de um objeto, o qual pode ser null ou undefined.

- -
let foo = { someFooProp: "oi" };
-
-console.log(foo.someFooProp?.toUpperCase());  // "OI"
-console.log(foo.someBarProp?.toUpperCase()); // undefined
-
- -

Exemplo

- -

Neste exemplo, nós iremos prover valores padrão, mas manter valores que não sejam (advinha???) null ou undefined.

- -
const nullValue = null;
-const emptyText = ""; // falseável (falsy)
-const someNumber = 42;
-
-const valA = nullValue ?? "padrão para A";
-const valB = emptyText ?? "padrão para B";
-const valC = someNumber ?? 0;
-
-console.log(valA); // "padrão para A"
-console.log(valB); // "" (pois a string vazia não é null ou undefined)
-console.log(valC); // 42
-
- -

Especificações

- - - - - - - - - - - - - - - - -
EspecificaçãoStatuscomentário
Proposal for the "nullish coalescing" operatorStage 4
- -

Compatibilidade de navegadores

- - - -

{{Compat("javascript.operators.nullish_coalescing")}}

- -

Progresso de implementação

- -

A seguinte tabela fornece o status diário de implementação para este recurso, porque este recurso ainda não atingiu a estabilidade entre navegadores. Os dados são gerados pela execução de testes de recursos relevantes no Test262, a plataforma de testes padrão do JavaScript, em "edições noturnas", ou último release de cada motor JavaScript dos navegadores.

- -
{{EmbedTest262ReportResultsTable("coalesce-expression")}}
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/operators/operador_virgula/index.html b/files/pt-br/web/javascript/reference/operators/operador_virgula/index.html deleted file mode 100644 index be374104d0..0000000000 --- a/files/pt-br/web/javascript/reference/operators/operador_virgula/index.html +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Operador Vírgula -slug: Web/JavaScript/Reference/Operators/Operador_Virgula -translation_of: Web/JavaScript/Reference/Operators/Comma_Operator ---- -
- {{jsSidebar("Operators")}}
-

Sumário

-

operador vírgula avalia o valor de seus operandos (da esquerda para a direita) e retorna o valor do último operando.

-

Sintaxe

-
expr1, expr2, expr3...
-

Parameters

-
-
- expr1, expr2, expr3...
-
- Quaisquer expressões.
-
-

Descrição

-

Você pode usar o operador vírgula quando desejar incluir múltiplas expressões em um lugar que requer uma única expressão. O uso mais comum desse operador é suprir múltiplos parâmetros em um loop for.

-

Exemplo

-

Se a é um array de 2 dimensões com 10 elementos de um lado, o seguinte código usa o operador vírgula para incrementar duas variáveis mutuamente. Note que a vírgula na declaração var não é o operador vírgula, porque ele não existe dentro de uma expressão. Além disso, ela é uma caractere especial nas declarações var para combinar múltiplas delas em uma única. Embora praticamente a vírgula comporte-se quase que igualmente ao operador vírgula. O código imprime os valores dos elementos diagonais da matriz:

-
for (var i = 0, j = 9; i <= 9; i++, j--)
-  document.writeln("a[" + i + "][" + j + "] = " + a[i][j]);
-
-

Especificações

- - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
1ª Edição ECMAScript.PadrãoDefinição inicial.
{{SpecName('ES5.1', '#sec-11.14', 'Comma operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-comma-operator', 'Comma operator')}}{{Spec2('ES6')}} 
-

Compatibilidade de Navegadores

-

{{ CompatibilityTable() }}

-
- - - - - - - - - - - - - - - - - - - -
CaracterísticaChromeFirefox (Gecko)Internet ExplorerOperaSafari
Suporte Básico{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
-
- - - - - - - - - - - - - - - - - - - - - -
CaracterísticaAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Suporte Básico{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
-

Veja também

- diff --git "a/files/pt-br/web/javascript/reference/operators/operadores_de_compara\303\247\303\243o/index.html" "b/files/pt-br/web/javascript/reference/operators/operadores_de_compara\303\247\303\243o/index.html" deleted file mode 100644 index d5e946a438..0000000000 --- "a/files/pt-br/web/javascript/reference/operators/operadores_de_compara\303\247\303\243o/index.html" +++ /dev/null @@ -1,251 +0,0 @@ ---- -title: Operadores de comparação -slug: Web/JavaScript/Reference/Operators/Operadores_de_comparação -tags: - - Comparando String - - Comparação - - Igualdade - - Operadores - - Relacionais -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Comparison_Operators ---- -
{{jsSidebar("Operators")}}
- -

O JavaScript possui comparações estritas e conversão de tipos. Uma comparação estrita (e.g., ===) somente é verdade se os operandos forem do mesmo tipo e de conteúdo correspondente. A comparação abstrata mais comumente utilizada (e.g. ==) converte os operandos no mesmo tipo antes da comparação. Para comparações abstratas relacionais (e.g., <=), os operandos são primeiro convertidos em primitivos, depois para o mesmo tipo, depois comparados.

- -

Strings são comparadas baseadas na ordenação lexicografica padrão, usando valores Unicode.

- -
{{EmbedInteractiveExample("pages/js/expressions-comparisonoperators.html")}}
- - - -

Características de comparação:

- - - -

Operadores de Igualdade 

- -

Igualdade (==)

- -

O operador de igualdade converte o operando se ele não for do mesmo tipo, então aplica a comparação estrita. Se ambos os operandos são objetos, então o JavaScript compara referencias internas que são iguais quando os operandos se referem ao mesmo objeto em memória.

- -

Sintaxe

- -
x == y
-
- -

Exemplos

- -
1    ==  1         // verdade
-'1'  ==  1         // verdade
-1    == '1'        // verdade
-0    == false      // verdade
-0    == null       // falso
-var object1 = {'key': 'value'}, object2 = {'key': 'value'};
-object1 == object2 // falso
-0    == undefined  // falso
-null == undefined  // verdade
-
- -

Desigualdade (!=)

- -

O operador de desigualdade retorna true (verdade) se os operandos não são iguais. Se os dois operandos não são do mesmo tipo, o JavaScript tenta converter os operandos para o tipo apropriado para a comparação. Se ambos os operandos são objetos, então o JavaScript compara referências internas que não são iguais quando os operandos se referem a objetos diferentes na memória.

- -

Sintaxe

- -
x != y
- -

Exemplos

- -
1 !=   2     // verdade
-1 !=  '1'    // falso
-1 !=  "1"    // falso
-1 !=  true   // falso
-0 !=  false  // falso
-
- -

Identidade / igualdade estrita (===)

- -

O operador de identidade retorna true (verdade) se os operandos são estritamente iguais (veja acima) sem conversão de tipo

- -

Sintaxe

- -
x === y
- -

Exemplos

- -
3 === 3   // verdade
-3 === '3' // falso
-var object1 = {'key': 'value'}, object2 = {'key': 'value'};
-object1 === object2 //f also
- -

Non-identity / desigualdade estrita (!==)

- -

O operador desigualdade estrita (Non-identity) retorna verdadeiro se os operandos não são iguais e / ou não são do mesmo tipo.

- -

Sintaxe

- -
x !== y
- -

Exemplos

- -
3 !== '3' // verdade
-4 !== 3   // verdade
-
- -

Operadores relacionais

- -

Cada um desses operadores chamará a função valueOf () em cada operando antes que uma comparação seja feita.

- -

Operador Maior (>)

- -

O operador de Maior retorna true se o operando da esquerda for maior que o operando da direita.

- -

Sintaxe

- -
x > y
- -

Exemplos

- -
4 > 3 // verdade
-
- -

Operador maior ou igual (>=)

- -

O operador maior ou igual retorna true se o operando da esquerda for maior ou igual ao operando da direita.

- -

Sintaxe

- -
 x >= y
- -

Exemplos

- -
4 >= 3 // verdade
-3 >= 3 // verdade
-
- -

Operador Menor (<)

- -

O operador menor retorna true (verdadeiro) se o operando da esquerda for menor que o operando da direita.

- -

Sintaxe

- -
 x < y
- -

Exemplos

- -
3 < 4 // verdade
-
- -

Operador menor ou igual (<=)

- -

O operador menor ou igual retorna true (verdadeiro) se o operando da esquerda for menor ou igual ao operando da direita.

- -

Sintaxe

- -
 x <= y
- -

Exemplos

- -
3 <= 4 // verdade
-
- -

Usando Operadores de Igualdade

- -

Os operadores de igualdade padrão (== e! =) Usam o Algoritmo de Comparação de Igualdade Abstrata 

- -

para comparar dois operandos. Se os operandos forem de tipos diferentes, ele tentará convertê-los para o mesmo tipo antes de fazer a comparação. Por exemplo, na expressão 5 == '5', a sequência à direita é convertida em {{jsxref ("Number" )}} antes da comparação ser feita.

- -

Os operadores de igualdade estrita (=== e! ==) usam o Algoritmo de comparação estrita de igualdade e se destinam a executar comparações de igualdade em operandos do mesmo tipo. Se os operandos são de tipos diferentes, o resultado é sempre falso, então 5! == '5'.
-
- Use operadores de igualdade estrita se os operandos precisarem ser de um tipo específico e também de valor ou se o tipo exato dos operandos for importante. Caso contrário, use os operadores de igualdade padrão, que permitem comparar a identidade de dois operandos, mesmo que não sejam do mesmo tipo.
-
- Quando a conversão de tipos está envolvida na comparação (por exemplo, comparação não estrita), o JavaScript converte os tipos {{jsxref ("String")}}, {{jsxref ("Number")}}, {{jsxref ("Booleano" )}} ou {{jsxref ("Object")}}) operandos da seguinte forma:

- - - -
Nota: Os objetos String são do Tipo Objeto, não String! Os objetos de string raramente são usados, portanto, os seguintes resultados podem ser surpreendentes:
- -
// true, pois ambos os operandos são do tipo String (ou seja, primitivos de string):
-'foo' === 'foo'
-
-var a = new String('foo');
-var b = new String('foo');
-
-// falso (false) pois a e b, embora do tipo "Objeto", são instâncias diferentes
-a == b
-
-// falso (false) pois a e b, embora do tipo "Objeto", são instâncias diferentes
-a === b
-
-// verdadeiro (true) pois o objeto a e 'foo' (String) são de tipos diferentes e, o Objeto (a)
-// é convertido para String ('foo') antes da comparação
-a == 'foo'
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EspecificaçãoStatusComentário
{{SpecName('ES1')}}{{Spec2('ES1')}}Definição Inicial. Implementado em JavaScript 1.0
{{SpecName('ES3')}}{{Spec2('ES3')}}Adicionandos os operadores === e !== . Implementado em JavaScript 1.3
{{SpecName('ES5.1', '#sec-11.8')}}{{Spec2('ES5.1')}}Definidos em várias seções das especificações: Operadores Relacionais , Operadores de Igualdade
{{SpecName('ES6', '#sec-relational-operators')}}{{Spec2('ES6')}}Definidos em várias seções das especificações: Operadores Relacionais , Operadores de Igualdade
{{SpecName('ESDraft', '#sec-relational-operators')}}{{Spec2('ESDraft')}}Definidos em várias seções das especificações: Operadores Relacionais , Operadores de Igualdade
- -

Compatilidade entre navegadores

- - - -

{{Compat("javascript.operators.comparison")}}

- -

Consulte também

- - - -
-
-
diff --git a/files/pt-br/web/javascript/reference/operators/operadores_logicos/index.html b/files/pt-br/web/javascript/reference/operators/operadores_logicos/index.html deleted file mode 100644 index e3a3ee6e8c..0000000000 --- a/files/pt-br/web/javascript/reference/operators/operadores_logicos/index.html +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: Operadores Lógicos -slug: Web/JavaScript/Reference/Operators/Operadores_Logicos -tags: - - Operador - - Operadores lógicos - - Referencia - - e - - não - - ou -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Logical_Operators ---- -
{{jsSidebar("Operators")}}
- -

Resumo

- -

Operadores lógicos são tipicamente usados com valores Booleanos (lógicos). Quando eles o são, retornam um valor booleano. Porém, os operadores && e || de fato retornam o valor de um dos operandos especificos, então se esses operadores são usados com valores não booleanos, eles podem retornar um valor não booleano.

- -

Descrição

- -

Os operadores lógicos são descritos na tabela abaixo:

- - - - - - - - - - - - - - - - - - - - - - - - -
OperadorUtilizaçãoDescrição
Logical AND (&&)expr1 && expr2Retorna expr1 se essa pode ser convertido para falso; senão, retorna expr2. Dessa forma, quando usado para valores Booleanos, && retorna verdadeiro se ambos os operandos forem verdadeiro ; senão, retorna falso.
Logical OR (||)expr1 || expr2Retorna expr1 se essa pode ser convertido para verdadeiro; senão, retorna expr2. Dessa forma, quando usado para valores Booleanos, || retorna verdadeiro se qualquer dos operandos for verdadeiro; se ambos são falso, retorna falso.
Logical NOT (!)!expr -

Retorna falsose o seu operando pode ser convertido para verdadeiro; senão, retorna verdadeiro.

-
- -

Se um valor pode ser convertido para verdadeiro, este valor é chamado de {{Glossary("truthy")}}. Se um valor pode ser convertido para falso, este valor é chamado de {{Glossary("falsy")}}.

- -

Exemplos de expressões que podem ser convertidas para falso são:

- - - -

Mesmo que os operadores && and || possam ser utilizados com operandos que não são valores Booleanos, eles ainda podem ser considerados como operadores booleanos visto que seus valores de saída sempre podem ser convertidos em valores booleanos.

- -

Avaliação de Curto-Circuito (Short-Circuit) 

- -

Como as expressões lógicas são avaliadas da esquerda pra direita, elas são testadas para possível avaliação de "curto-circuito" ("short-circuit") utilizando as seguintes regras:

- - - -

As regras de lógica garantem que essas avaliações estejam sempre corretas. Repare que a porção qualquer coisa das expressões acima não é avaliada, logo qualquer problema oriundo de tê-lo feito não é consumado. Note também  que a parte qualquer coisa das expressões acima pode ser qualquer expressão lógica unitária (conforme é indicado pelos parênteses).

- -

Por exemplo, as duas funções a seguir são equivalentes.

- -
function shortCircuitEvaluation() {
-  // logical OR (||)
-  doSomething() || doSomethingElse();
-
-  // logical AND (&&)
-  doSomething() && doSomethingElse();
-}
-
-function equivalentEvaluation() {
-
-  // logical OR (||)
-  var orFlag = doSomething();
-  if (!orFlag) {
-    doSomethingElse();
-  }
-
-
-  // logical AND (&&)
-  var andFlag = doSomething();
-  if (andFlag) {
-    doSomethingElse();
-  }
-}
- -

Contudo, as expressões a seguir não são equivalentes, devido a precedência do operador, e reforçam a importância de que o operador do lado direito (right hand) seja uma única expressão (agrupada com o uso de parênteses, caso seja necessário).

- -
 false && true || true       // retorna true
- false && (true || true)     // retorna falso
- -

AND Lógico (&&)

- -

O código a seguir demonstra exemplos do operador && (AND lógico). 

- -
a1 = true  && true       // t && t retorna true
-a2 = true  && false      // t && f retorna false
-a3 = false && true       // f && t retorna false
-a4 = false && (3 == 4)   // f && f retorna false
-a5 = 'Cat' && 'Dog'      // t && t retorna "Dog"
-a6 = false && 'Cat'      // f && t retorna false
-a7 = 'Cat' && false      // t && f retorna false
-a8 = ''    && false      // f && f retorna ""
-a9 = false && ''         // f && t retorna false
-
- -

OR Lógico (||)

- -

O código a seguir demonstra exemplos do operador || (OR lógico).

- -
o1 = true  || true       // t || t retorna true
-o2 = false || true       // f || t retorna true
-o3 = true  || false      // t || f retorna true
-o4 = false || (3 == 4)   // f || f retorna false
-o5 = 'Cat' || 'Dog'      // t || t retorna "Cat"
-o6 = false || 'Cat'      // f || t retorna "Cat"
-o7 = 'Cat' || false      // t || f retorna "Cat"
-o8 = ''    || false      // f || f retorna false
-o9 = false || ''         // f || f retorna ""
- -

NOT Logico (!)

- -

O código a seguir demonstra exemplos do operador ! (NOT lógico) .

- -
n1 = !true               // !t returns false
-n2 = !false              // !f returns true
-n3 = !'Cat'              // !t returns false
- -

Regras de conversão

- -

Convertendo AND para OR

- -

A operação a seguir, envolvendo Booleanos:

- -
bCondition1 && bCondition2
- -

é sempre igual a:

- -
!(!bCondition1 || !bCondition2)
- -

Convertendo OR to AND

- -

A operação a seguir, envolvendo Booleanos:

- -
bCondition1 || bCondition2
- -

é sempre igual a:

- -
!(!bCondition1 && !bCondition2)
- -

Convertendo entre dois NOT

- -

A seguinte operação envolvendo Booleanos:

- -
!!bCondition
- -

é sempre igual a:

- -
bCondition
- -

Removendo parenteses aninhados

- -

Como as expressões lógicas são avaliadas da esquerda pra direita, é sempre possível remover os parênteses de uma expressão complexa seguindo algumas regras:

- -

Removendo AND aninhado

- -

A seguinte operação composta envolvendo Booleanos:

- -
bCondition1 || (bCondition2 && bCondition3)
- -

é igual a :

- -
bCondition1 || bCondition2 && bCondition3
- -

Removendo OR aninhado

- -

A operação composta a seguir, envolvendo Booleanos:

- -
bCondition1 && (bCondition2 || bCondition3)
- -

é sempre igual a:

- -
!(!bCondition1 || !bCondition2 && !bCondition3)
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - -
EspecificaçãoEstatusComentário
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-11.4.9', 'Logical NOT Operator')}}
- {{SpecName('ES5.1', '#sec-11.11', 'Binary Logical Operators')}}
{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-logical-not-operator', 'Logical NOT operator')}}
- {{SpecName('ES6', '#sec-binary-logical-operators', 'Binary Logical Operators')}}
{{Spec2('ES6')}}
- -

Compatibilidade com o Navegador

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
RecursoChromeFirefox (Gecko)Internet ExplorerOperaSafari
Logical AND (&&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Logical OR (||){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Logical NOT (!){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome para AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Logical AND (&&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Logical OR (||){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Logical NOT (!){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -

Retrocompatibilidade: Comportamento no  JavaScript 1.0 e1.1

- -

Os operadores  && and || se comportam da seguinte maneira:

- - - - - - - - - - - - - - - - - - - -
OperadorUtilizaçãoComportamento
&&expr1 && expr2Se o primeiro operando (expr1) pode ser convertido para falso, o operador &&  retorna false ao invés do valor do expr1.
||expr1 || expr2If the first operand (expr1) can be converted to true, the || operator retorna true rather than the value of expr1.
- -

Veja Também

- - diff --git a/files/pt-br/web/javascript/reference/operators/spread_operator/index.html b/files/pt-br/web/javascript/reference/operators/spread_operator/index.html deleted file mode 100644 index a877d131bc..0000000000 --- a/files/pt-br/web/javascript/reference/operators/spread_operator/index.html +++ /dev/null @@ -1,201 +0,0 @@ ---- -title: Spread operator -slug: Web/JavaScript/Reference/Operators/Spread_operator -tags: - - JavaScript - - Operador -translation_of: Web/JavaScript/Reference/Operators/Spread_syntax -translation_of_original: Web/JavaScript/Reference/Operators/Spread_operator ---- -
{{jsSidebar("Operators")}}
- -

A sintaxe de propagação (Spread) permite que um objeto iterável, como um array ou string, seja expandida em locais onde zero ou mais argumentos (para chamadas de função) ou elementos (para literais de array) sejam esperados ou uma expressão de objeto seja expandida em locais onde zero ou mais pares de chave-valor (para literais de objeto) são esperados.

- -

Sintaxe

- -

Para chamadas de função:

- -
minhaFuncao(...objIteravel);
-
- -

Para array literais:

- -
[...objIteravel, 4, 5, 6]
- -

Desestruturação:

- -
[a, b, ...objIteravel] = [1, 2, 3, 4, 5];
- -

Exemplos

- -

Uma melhor aplicação

- -

Exemplo: é comum usar {{jsxref( "Function.prototype.apply")}} em casos onde você quer usar um array como argumentos em uma função.

- -
function minhaFuncao(x, y, z) { }
-var args = [0, 1, 2];
-minhaFuncao.apply(null, args);
- -

Com o spread do ES2015 você pode agora escrever isso acima como:

- -
function minhaFuncao(x, y, z) { }
-var args = [0, 1, 2];
-minhaFuncao(...args);
- -

Qualquer argumento na lista de argumento pode usar a sintaxe spread e pode ser usado várias vezes.

- -
function minhaFuncao(v, w, x, y, z) { }
-var args = [0, 1];
-minhaFuncao(-1, ...args, 2, ...[3]);
- -

Um literal array mais poderoso

- -

Exemplo:  Hoje se você tiver um array e quer criar um novo array com esse existente fazendo parte dele, a sintaxe literal do array não é mais suficiente e você deve voltar para o código imperativo, usando uma combinação de push, splice, concat, etc. Com a sintaxe spread isso se torna muito mais sucinto:

- -
var partes = ['ombros', 'joelhos'];
-var letra = ['cabeca', ...partes, 'e', 'dedos']; // ["cabeca", "ombros", "joelhos", "e", "dedos"]
-
- -

Assim como em spread para listas de argumentos ... pode ser usado em qualquer lugar no literal do array e pode ser usado várias vezes.

- -

Apply para new

- -

Exemplo: No ES5 não é possível usar new com apply. (Em ES5 termos, apply faz uma [[Call]] e nao um [[Construct]].) Em ES2015 a sintaxe spread naturalmente suporta isso:

- -
var camposData = lerCamposData(bancoDeDados);
-var d = new Date(...camposData);
- -

Um push melhor

- -

Exemplo: {{jsxref("Global_Objects/Array/push", "push")}} é frequentemente usado para adicionar um array no final de um array existente. No ES5 isso é geralmente feito assim:

- -
var arr1 = [0, 1, 2];
-var arr2 = [3, 4, 5];
-// Acrescenta todos itens do arr2 ao arr1
-Array.prototype.push.apply(arr1, arr2);
- -

No ES2015 com spread isso se torna:

- -
var arr1 = [0, 1, 2];
-var arr2 = [3, 4, 5];
-arr1.push(...arr2);
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - -
EspecificaçãoStatusComentário
{{SpecName('ES2015', '#sec-array-initializer')}}{{Spec2('ES2015')}}Definido em várias seções da especificação: Inicializador do arrayListas de argumento
{{SpecName('ESDraft', '#sec-array-initializer')}}{{Spec2('ESDraft')}} 
- -

Compatibilidade com browser

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Operação spread em array literais{{CompatChrome("46")}}{{ CompatGeckoDesktop("16") }}{{CompatNo}}{{CompatNo}}7.1
Operação spread em chamadas de função{{CompatChrome("46")}}{{ CompatGeckoDesktop("27") }}{{CompatNo}}{{CompatNo}}7.1
Operação spread em desestruturação{{CompatNo}}{{ CompatGeckoDesktop("34") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Operação spread em array literais{{CompatNo}}{{CompatChrome("46")}}{{ CompatGeckoMobile("16") }}{{CompatNo}}{{CompatNo}}8{{CompatChrome("46")}}
Operação spread em chamadas de função{{CompatNo}}{{CompatChrome("46")}}{{ CompatGeckoMobile("27") }}{{CompatNo}}{{CompatNo}}8{{CompatChrome("46")}}
Operação spread em desestruturação{{CompatNo}}{{CompatNo}}{{ CompatGeckoDesktop("34") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatNo}}
-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/statements/async_function/index.html b/files/pt-br/web/javascript/reference/statements/async_function/index.html new file mode 100644 index 0000000000..808f0b0306 --- /dev/null +++ b/files/pt-br/web/javascript/reference/statements/async_function/index.html @@ -0,0 +1,149 @@ +--- +title: Funções assíncronas +slug: Web/JavaScript/Reference/Statements/funcoes_assincronas +tags: + - Função + - assíncrono +translation_of: Web/JavaScript/Reference/Statements/async_function +--- +
{{jsSidebar("Statements")}}
+ +

A declaração async function define uma função assíncrona, que retorna um objeto {{jsxref("Global_Objects/AsyncFunction","AsyncFunction")}}.

+ +
+

Você também pode definir funções assíncronas usando uma {{jsxref("Operators/async_function", "expressão async function")}}.

+
+ +

Sintaxe

+ +
async function nome([param[, param[, ... param]]]) {
+   instruções
+}
+
+ +
+
nome
+
O nome da função.
+
+ +
+
param
+
O nome de um parâmetro a ser passado para a função.
+
+ +
+
instruções
+
As instruções que compõem o corpo da função.
+
+ +

Descrição

+ +

Quando uma função assíncrona é chamada, ela retorna uma {{jsxref("Promise")}}. Quando a função assíncrona retorna um valor, a Promise será resolvida com o valor retornado. Quando a função assíncrona lança uma exceção ou algum valor, a Promise será rejeitada com o valor lançado.

+ +

Uma função assíncrona pode conter uma expressão {{jsxref("Operators/await", "await")}}, que pausa a execução da função assíncrona e espera pela resolução da Promise passada, e depois retoma a execução da função assíncrona e retorna o valor resolvido.

+ +
+

A proposta das funções async/await é de simplificar o uso de forma síncrona das Promises e executar alguns procedimentos em um grupo de Promises. Assim como Promises são similares a callbacks estruturados, funções async/await são similares à junção de generators com Promises.

+
+ +

Exemplos

+ +

Exemplo simples

+ +
function resolverDepoisDe2Segundos(x) {
+  return new Promise(resolve => {
+    setTimeout(() => {
+      resolve(x);
+    }, 2000);
+  });
+}
+
+async function adicionar1(x) {
+  var a = resolverDepoisDe2Segundos(20);
+  var b = resolverDepoisDe2Segundos(30);
+  return x + await a + await b;
+}
+
+adicionar1(10).then(v => {
+  console.log(v);  // exibe 60 depois de 2 segundos.
+});
+
+async function adicionar2(x) {
+  var a = await resolverDepoisDe2Segundos(20);
+  var b = await resolverDepoisDe2Segundos(30);
+  return x + a + b;
+}
+
+adicionar2(10).then(v => {
+  console.log(v);  // exibe 60 depois de 4 segundos.
+});
+
+ +

Reescrevendo uma cadeia de Promise com uma função async

+ +

Uma API que retorna uma {{jsxref("Promise")}} vai resultar em uma cadeia de Promises e separa a função em várias partes. Considere o seguinte código:

+ +
function pegarDadosProcessados(url) {
+  return baixarDados(url) // retorna uma Promise
+    .catch(e => {
+      return baixarDadosReservas(url) // retorna uma Promise
+    })
+    .then(v => {
+      return processarDadosNoWorker(v); // retorna uma Promise
+    });
+}
+
+ +

pode ser escrita em uma única função async desta forma:

+ +
async function pegarDadosProcessados(url) {
+  let v;
+  try {
+    v = await baixarDados(url);
+  } catch(e) {
+    v = await baixarDadosReservas(url);
+  }
+  return processarDadosNoWorker(v);
+}
+
+ +

Note que no exemplo acima não tem a instrução await na instrução do return, porque o valor retornado de uma função async é implícitamente passado por um {{jsxref("Promise.resolve")}}.

+ +

Especificações

+ + + + + + + + + + + + + + + + +
EspecificaçãoSituaçãoComentário
{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}}{{Spec2('ESDraft')}}Definição inicial no ES2017.
+ +

Compatibilidade de browser

+ +
{{Compat("javascript.statements.async_function")}}
+ +
+ +

Notas específicas do Firefox

+ + + +

Veja também

+ + diff --git a/files/pt-br/web/javascript/reference/statements/default/index.html b/files/pt-br/web/javascript/reference/statements/default/index.html deleted file mode 100644 index 8e0fb07927..0000000000 --- a/files/pt-br/web/javascript/reference/statements/default/index.html +++ /dev/null @@ -1,187 +0,0 @@ ---- -title: default -slug: Web/JavaScript/Reference/Statements/default -tags: - - JavaScript - - Keyword - - Palavra-chave -translation_of: Web/JavaScript/Reference/Statements/switch -translation_of_original: Web/JavaScript/Reference/Statements/default ---- -
{{jsSidebar("Statements")}}
- -

A palavra-chave default pode ser usada em duas situações no JavaScript: com uma declaração {{jsxref("Statements/switch", "switch")}}, ou com uma declaração {{jsxref("Statements/export", "export")}}.

- -

Sintaxe

- -

Com uma declaração {{jsxref("Statements/switch", "switch")}}:

- -
switch (expressao) {
-  case value1:
-    //Declarações executadas quando o resultado da expressao for value1
-    [break;]
-  default:
-    //Declarações executadas quando nenhum dos valores for igual o da expressao
-    [break;]
-}
- -

Com a declaração {{jsxref("Statements/export", "export")}}:

- -
export default nameN 
- -

Descrição

- -

Para mais detalhes, veja as páginas:

- - - -

Exemplos

- -

Usando default em declarações switch

- -

No exemplo a seguir, se a variável expr for "Laranjas" ou "Maças", o programa encontra os valores com o case "Laranjas" ou "Maças"  e executa a declaração correspondente. A palavra-chave default vai ajudar em qualquer outro caso e executará a declaração associada.

- -
switch (expr) {
-  case 'Laranjas':
-    console.log('Laranjas custam R$0,59.');
-    break;
-  case 'Maças':
-    console.log('Maças custam R$0,32.');
-    break;
-  default:
-    console.log('Desculpe, nós não temos ' + expr + '.');
-}
- -

Usando default com export

- -

Se você quiser exportar apenas um valor ou precisa de um valor fallback para um módulo, uma exportação padrão (default export) pode ser usada:

- -
// module "my-module.js"
-let cube = function cube(x) {
-  return x * x * x;
-};
-export default cube;
- -

Então, no outro script, isso pode ser passado direto para o import do default export:

- -
// module "my-module.js"
-import myFunction from 'my-module';
-console.log(myFunction(3)); // 27
-
- -

Especificações

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EspecificaçãoSituaçãoComentário
{{SpecName('ES6', '#sec-switch-statement', 'switch statement')}}{{Spec2('ES6')}} 
{{SpecName('ES6', '#sec-exports', 'Exports')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-switch-statement', 'switch statement')}}{{Spec2('ESDraft')}} 
{{SpecName('ESDraft', '#sec-exports', 'Exports')}}{{Spec2('ESDraft')}} 
- -

Compatibilidade de navegadores

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Switch default{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Export default{{CompatNo}}{{CompatUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Switch default{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Export default{{CompatNo}}{{CompatNo}}{{CompatUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/statements/funcoes_assincronas/index.html b/files/pt-br/web/javascript/reference/statements/funcoes_assincronas/index.html deleted file mode 100644 index 808f0b0306..0000000000 --- a/files/pt-br/web/javascript/reference/statements/funcoes_assincronas/index.html +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: Funções assíncronas -slug: Web/JavaScript/Reference/Statements/funcoes_assincronas -tags: - - Função - - assíncrono -translation_of: Web/JavaScript/Reference/Statements/async_function ---- -
{{jsSidebar("Statements")}}
- -

A declaração async function define uma função assíncrona, que retorna um objeto {{jsxref("Global_Objects/AsyncFunction","AsyncFunction")}}.

- -
-

Você também pode definir funções assíncronas usando uma {{jsxref("Operators/async_function", "expressão async function")}}.

-
- -

Sintaxe

- -
async function nome([param[, param[, ... param]]]) {
-   instruções
-}
-
- -
-
nome
-
O nome da função.
-
- -
-
param
-
O nome de um parâmetro a ser passado para a função.
-
- -
-
instruções
-
As instruções que compõem o corpo da função.
-
- -

Descrição

- -

Quando uma função assíncrona é chamada, ela retorna uma {{jsxref("Promise")}}. Quando a função assíncrona retorna um valor, a Promise será resolvida com o valor retornado. Quando a função assíncrona lança uma exceção ou algum valor, a Promise será rejeitada com o valor lançado.

- -

Uma função assíncrona pode conter uma expressão {{jsxref("Operators/await", "await")}}, que pausa a execução da função assíncrona e espera pela resolução da Promise passada, e depois retoma a execução da função assíncrona e retorna o valor resolvido.

- -
-

A proposta das funções async/await é de simplificar o uso de forma síncrona das Promises e executar alguns procedimentos em um grupo de Promises. Assim como Promises são similares a callbacks estruturados, funções async/await são similares à junção de generators com Promises.

-
- -

Exemplos

- -

Exemplo simples

- -
function resolverDepoisDe2Segundos(x) {
-  return new Promise(resolve => {
-    setTimeout(() => {
-      resolve(x);
-    }, 2000);
-  });
-}
-
-async function adicionar1(x) {
-  var a = resolverDepoisDe2Segundos(20);
-  var b = resolverDepoisDe2Segundos(30);
-  return x + await a + await b;
-}
-
-adicionar1(10).then(v => {
-  console.log(v);  // exibe 60 depois de 2 segundos.
-});
-
-async function adicionar2(x) {
-  var a = await resolverDepoisDe2Segundos(20);
-  var b = await resolverDepoisDe2Segundos(30);
-  return x + a + b;
-}
-
-adicionar2(10).then(v => {
-  console.log(v);  // exibe 60 depois de 4 segundos.
-});
-
- -

Reescrevendo uma cadeia de Promise com uma função async

- -

Uma API que retorna uma {{jsxref("Promise")}} vai resultar em uma cadeia de Promises e separa a função em várias partes. Considere o seguinte código:

- -
function pegarDadosProcessados(url) {
-  return baixarDados(url) // retorna uma Promise
-    .catch(e => {
-      return baixarDadosReservas(url) // retorna uma Promise
-    })
-    .then(v => {
-      return processarDadosNoWorker(v); // retorna uma Promise
-    });
-}
-
- -

pode ser escrita em uma única função async desta forma:

- -
async function pegarDadosProcessados(url) {
-  let v;
-  try {
-    v = await baixarDados(url);
-  } catch(e) {
-    v = await baixarDadosReservas(url);
-  }
-  return processarDadosNoWorker(v);
-}
-
- -

Note que no exemplo acima não tem a instrução await na instrução do return, porque o valor retornado de uma função async é implícitamente passado por um {{jsxref("Promise.resolve")}}.

- -

Especificações

- - - - - - - - - - - - - - - - -
EspecificaçãoSituaçãoComentário
{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}}{{Spec2('ESDraft')}}Definição inicial no ES2017.
- -

Compatibilidade de browser

- -
{{Compat("javascript.statements.async_function")}}
- -
- -

Notas específicas do Firefox

- - - -

Veja também

- - diff --git a/files/pt-br/web/javascript/reference/template_literals/index.html b/files/pt-br/web/javascript/reference/template_literals/index.html new file mode 100644 index 0000000000..e2a11abfa4 --- /dev/null +++ b/files/pt-br/web/javascript/reference/template_literals/index.html @@ -0,0 +1,140 @@ +--- +title: Template strings +slug: Web/JavaScript/Reference/template_strings +translation_of: Web/JavaScript/Reference/Template_literals +--- +
{{JsSidebar("More")}}
+ +

Template Strings são strings que permitem expressões embutidas. Você pode utilizar string multi-linhas e interpolação de string com elas.

+ +

Basicamente é uma nova forma de criar strings e tornar o seu código um pouco mais legível.

+ +

Sintaxe

+ +
`corpo de texto`
+
+`texto linha 1
+ texto linha 2`
+
+`texto string ${expression} texto string`
+
+tag `texto string ${expression} texto string`
+
+ +

Descrição

+ +

Template strings são envolvidas por (acentos graves) (` `) em vez de aspas simples ou duplas. Template strings podem possuir placeholders. Estes são indicados por um cifrão seguido de chaves (${expression}). As expressões nos placeholders, bem como o texto em volta delas são passados a uma função. A função padrão apenas concatena as partes em uma string única. Se existir uma expressão precedendo a template string (função tag exemplo), a template string é definida como "tagged template string". No caso, a expressão tag (geralmente uma função) é chamada pela template string processada, que você pode manipular antes de produzir o resultado.

+ +
`\`` === '`' // --> true
+ +

Strings multi-linhas

+ +

Qualquer caracter de nova linha inserido no código é parte da template string. Utilizando strings normais, você teria de usar a síntaxe a seguir para obter strings multi-linhas:

+ +
console.log('texto string linha 1\n' +
+'texto string linha 2');
+// "texto string linha 1
+// texto string linha 2"
+ +

Para obter o mesmo efeito com strings multi-linhas, você agora pode escrever:

+ +
console.log(`texto string linha 1
+texto string linha 2`);
+// "texto string linha 1
+//  texto string linha 2"
+ +

Interpolação de Expressões

+ +

Para encapsular expressões dentro de strings, você precisava utilizar a seguinte sintaxe:

+ +
var a = 5;
+var b = 10;
+console.log('Quinze é ' + (a + b) + ' e\nnão ' + (2 * a + b) + '.');
+// "Quinze é 15 e
+// não 20."
+ +

Agora, com template strings, você pode utilizar as substituições sintáticas tornando o código mais legível:

+ +
var a = 5;
+var b = 10;
+console.log(`Quinze é ${a + b} e
+não ${2 * a + b}.`);
+// "Quinze é 15 e
+// não 20."
+ +

Tagged template strings

+ +

Uma forma mais avançada dos template string são os template strings com marcações ou tags, ou tagged template strings. Com eles, você tem a possibilidade de modificar a saída dos template strings usando uma função. O primeiro argumento contém um array de literais ("Hello" e "World" neste exemplo). Do segundo em diante e cada argumento subsequente contém valores previamente processados (algumas vezes chamados cooked) pelas expressões de substituição ("15" e "50" no caso do exemplo). No final, a função retorna a string ja manipulada:

+ +
var a = 5;
+var b = 10;
+
+function tag(strings, ...values) {
+  console.log(strings[0]); // "Hello "
+  console.log(strings[1]); // " world"
+  console.log(values[0]);  // 15
+  console.log(values[1]);  // 50
+
+  return "Bazinga!";
+}
+
+tag`Hello ${ a + b } world ${ a * b}`;
+// "Bazinga!"
+
+ +

Strings Raw

+ +

A propriedade especial raw, disponível no primeiro argumento da função da tagged template string acima, permite o acesso as strings de maneira pura (raw) exatamente como elas foram especificadas:

+ +
function tag(strings, ...values) {
+  return strings.raw[0];
+}
+
+tag`string text line 1 \n string text line 2`;
+// "string text line 1 \\n string text line 2"
+
+ +

Adicionalmente, o método {{jsxref("String.raw()")}} permite a criação de strings cruas, exatamente como as template functions e as concatenações deveram criar.

+ +
String.raw`Hi\n${2+3}!`; // "Hi\\n5!"
+ +

Especificações

+ + + + + + + + + + + + + + + + + + + +
EspecificaçãoStatusComentário
{{SpecName('ES2015', '#sec-template-literals', 'Template Literals')}}{{Spec2('ES2015')}}Definição inicial. Definido em várias seções da especificação: Template Literals, Tagged Templates
{{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}}{{Spec2('ESDraft')}}Definido em várias seções da especificação: Template Literals, Tagged Templates
+ +

Compatibidade com navegadores

+ +
+ + +

{{Compat("javascript.grammar.template_literals")}}

+
+ +

Veja também

+ + diff --git a/files/pt-br/web/javascript/reference/template_strings/index.html b/files/pt-br/web/javascript/reference/template_strings/index.html deleted file mode 100644 index e2a11abfa4..0000000000 --- a/files/pt-br/web/javascript/reference/template_strings/index.html +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: Template strings -slug: Web/JavaScript/Reference/template_strings -translation_of: Web/JavaScript/Reference/Template_literals ---- -
{{JsSidebar("More")}}
- -

Template Strings são strings que permitem expressões embutidas. Você pode utilizar string multi-linhas e interpolação de string com elas.

- -

Basicamente é uma nova forma de criar strings e tornar o seu código um pouco mais legível.

- -

Sintaxe

- -
`corpo de texto`
-
-`texto linha 1
- texto linha 2`
-
-`texto string ${expression} texto string`
-
-tag `texto string ${expression} texto string`
-
- -

Descrição

- -

Template strings são envolvidas por (acentos graves) (` `) em vez de aspas simples ou duplas. Template strings podem possuir placeholders. Estes são indicados por um cifrão seguido de chaves (${expression}). As expressões nos placeholders, bem como o texto em volta delas são passados a uma função. A função padrão apenas concatena as partes em uma string única. Se existir uma expressão precedendo a template string (função tag exemplo), a template string é definida como "tagged template string". No caso, a expressão tag (geralmente uma função) é chamada pela template string processada, que você pode manipular antes de produzir o resultado.

- -
`\`` === '`' // --> true
- -

Strings multi-linhas

- -

Qualquer caracter de nova linha inserido no código é parte da template string. Utilizando strings normais, você teria de usar a síntaxe a seguir para obter strings multi-linhas:

- -
console.log('texto string linha 1\n' +
-'texto string linha 2');
-// "texto string linha 1
-// texto string linha 2"
- -

Para obter o mesmo efeito com strings multi-linhas, você agora pode escrever:

- -
console.log(`texto string linha 1
-texto string linha 2`);
-// "texto string linha 1
-//  texto string linha 2"
- -

Interpolação de Expressões

- -

Para encapsular expressões dentro de strings, você precisava utilizar a seguinte sintaxe:

- -
var a = 5;
-var b = 10;
-console.log('Quinze é ' + (a + b) + ' e\nnão ' + (2 * a + b) + '.');
-// "Quinze é 15 e
-// não 20."
- -

Agora, com template strings, você pode utilizar as substituições sintáticas tornando o código mais legível:

- -
var a = 5;
-var b = 10;
-console.log(`Quinze é ${a + b} e
-não ${2 * a + b}.`);
-// "Quinze é 15 e
-// não 20."
- -

Tagged template strings

- -

Uma forma mais avançada dos template string são os template strings com marcações ou tags, ou tagged template strings. Com eles, você tem a possibilidade de modificar a saída dos template strings usando uma função. O primeiro argumento contém um array de literais ("Hello" e "World" neste exemplo). Do segundo em diante e cada argumento subsequente contém valores previamente processados (algumas vezes chamados cooked) pelas expressões de substituição ("15" e "50" no caso do exemplo). No final, a função retorna a string ja manipulada:

- -
var a = 5;
-var b = 10;
-
-function tag(strings, ...values) {
-  console.log(strings[0]); // "Hello "
-  console.log(strings[1]); // " world"
-  console.log(values[0]);  // 15
-  console.log(values[1]);  // 50
-
-  return "Bazinga!";
-}
-
-tag`Hello ${ a + b } world ${ a * b}`;
-// "Bazinga!"
-
- -

Strings Raw

- -

A propriedade especial raw, disponível no primeiro argumento da função da tagged template string acima, permite o acesso as strings de maneira pura (raw) exatamente como elas foram especificadas:

- -
function tag(strings, ...values) {
-  return strings.raw[0];
-}
-
-tag`string text line 1 \n string text line 2`;
-// "string text line 1 \\n string text line 2"
-
- -

Adicionalmente, o método {{jsxref("String.raw()")}} permite a criação de strings cruas, exatamente como as template functions e as concatenações deveram criar.

- -
String.raw`Hi\n${2+3}!`; // "Hi\\n5!"
- -

Especificações

- - - - - - - - - - - - - - - - - - - -
EspecificaçãoStatusComentário
{{SpecName('ES2015', '#sec-template-literals', 'Template Literals')}}{{Spec2('ES2015')}}Definição inicial. Definido em várias seções da especificação: Template Literals, Tagged Templates
{{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}}{{Spec2('ESDraft')}}Definido em várias seções da especificação: Template Literals, Tagged Templates
- -

Compatibidade com navegadores

- -
- - -

{{Compat("javascript.grammar.template_literals")}}

-
- -

Veja também

- - -- cgit v1.2.3-54-g00ecf