aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/web/javascript/reference/classes/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/pt-br/web/javascript/reference/classes/index.html')
-rw-r--r--files/pt-br/web/javascript/reference/classes/index.html364
1 files changed, 364 insertions, 0 deletions
diff --git a/files/pt-br/web/javascript/reference/classes/index.html b/files/pt-br/web/javascript/reference/classes/index.html
new file mode 100644
index 0000000000..62f5d0270f
--- /dev/null
+++ b/files/pt-br/web/javascript/reference/classes/index.html
@@ -0,0 +1,364 @@
+---
+title: Classes
+slug: Web/JavaScript/Reference/Classes
+tags:
+ - Classes
+ - Constructor
+ - ECMAScript6
+ - Herança
+ - Intermediário
+ - JavaScript
+translation_of: Web/JavaScript/Reference/Classes
+---
+<div>{{JsSidebar("Classes")}}</div>
+
+<p>Classes em JavaScript são introduzidas no ECMAScript 2015 e são simplificações da linguagem para as heranças baseadas nos protótipos. A sintaxe para classes <strong>não</strong> introduz um novo modelo de herança de orientação a objetos em JavaScript. Classes em JavaScript provêm uma maneira mais simples e clara de criar objetos e lidar com herança.</p>
+
+<h2 id="Definindo_classes">Definindo classes</h2>
+
+<p>As Classes são, de fato, "funções especiais", e, assim como você pode definir <a href="https://wiki.developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/function">"function expressions"</a> e <a href="https://wiki.developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Statements/function">"function declarations"</a>, a sintaxe de uma classe possui dois componentes: <a href="/en-US/docs/Web/JavaScript/Reference/Operators/class">"class expressions</a>" e  <a href="/en-US/docs/Web/JavaScript/Reference/Statements/class">"class declarations"</a>.</p>
+
+<h3 id="Declarando_classes">Declarando classes</h3>
+
+<p>Uma maneira de definir uma classe é usando uma declaração de classe. Para declarar uma classe, você deve usar a palavra-chave <code>class</code> seguida pelo nome da classe (aqui "Retangulo").</p>
+
+<pre class="brush: js">class Retangulo {
+ constructor(altura, largura) {
+ this.altura = altura;
+ this.largura = largura;
+ }
+}</pre>
+
+<h4 id="Uso_antes_da_declaração_Hoisting_-_Tradução_Literal_Lançamento">Uso antes da declaração (Hoisting - Tradução Literal: Lançamento)</h4>
+
+<p>Uma diferença importante entre <strong>declarações de funções</strong> das <strong>declarações de classes</strong>, é que  declararações de  funções são {{Glossary("Hoisting", "hoisted")}} e declarações de classes não são. Primeiramente deve declarar sua classe para só então acessá-la, pois do contrário o código a seguir irá lançar uma exceção: {{jsxref("ReferenceError")}}:</p>
+
+<pre class="brush: js example-bad">const p = new Retangulo(); // Erro de referência (ReferenceError)
+
+class Retangulo {}
+</pre>
+
+<h3 id="Expressões_de_Classes">Expressões de Classes</h3>
+
+<p>Uma <strong>Expressão de Classe</strong> (class expression) é outra forma para definir classes. Expressões de Classes podem possuir nomes ou não (anônimas). O nome dado para uma expressão de classe é local ao corpo da classe.</p>
+
+<pre class="brush: js">// sem nome
+let Retangulo = class {
+ constructor(altura, largura) {
+ this.altura = altura;
+  this.largura = largura;
+ }
+};
+
+// nomeada
+let Retangulo = class Retangulo {
+ constructor(altura, largura) {
+  this.altura = altura;
+  this.largura = largura;
+  }
+};
+</pre>
+
+<p><strong>Nota:</strong> As <strong>expressões de classe</strong> também sofrem com o mesmo problema de {{Glossary("Hoisting", "hoisted")}} mencionados em <strong>declarações </strong>de classe.</p>
+
+<h2 id="Corpo_de_uma_classe_e_definições_de_métodos">Corpo de uma classe e definições de métodos</h2>
+
+<p>O corpo de uma classe é a parte que está entre chaves <code>{}</code>. É aí onde você define os membros da classe, como os métodos, ou os construtores.</p>
+
+<h3 id="Modo_Estrito_strict_mode">Modo Estrito (strict mode)</h3>
+
+<p>Os corpos das Declarações de Classes e das Expressões de Classes são executados em <a href="https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Strict_mode">modo estrito</a>.</p>
+
+<h3 id="Construtor">Construtor</h3>
+
+<p>O método <code><a href="/en-US/docs/Web/JavaScript/Reference/Classes/constructor">constructor</a></code> é um tipo especial de método para criar e iniciar um objeto criado pela classe. Só pode existir um método especial com o nome "constructor" dentro da classe. Um erro de sintáxe {{jsxref("SyntaxError")}} será lançado se a classe possui mais do que uma ocorrência do método <code>constructor</code>.</p>
+
+<p>Um construtor pode usar a palavra-chave <code>super</code> para chamar o construtor de uma classe pai.</p>
+
+<h3 id="Métodos_Protótipos">Métodos Protótipos</h3>
+
+<p>Veja também <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">definições de métodos (method definitions)</a>.</p>
+
+<pre class="brush: js">class Retangulo {
+ constructor(altura, largura) {
+ this.altura = altura; this.largura = largura;
+ }
+ //Getter
+ get area() {
+ return this.calculaArea()
+ }
+
+ calculaArea() {
+ return this.altura * this.largura;
+ }
+}
+
+const quadrado = new Retangulo(10, 10);
+
+console.log(quadrado.area);</pre>
+
+<h3 id="Métodos_estáticos">Métodos estáticos</h3>
+
+<p>A palavra-chave <code><a href="/en-US/docs/Web/JavaScript/Reference/Classes/static">static</a></code> define um método estático de uma classe. Métodos estáticos são chamados sem a instanciação da sua classe e não podem ser chamados quando a classe é instanciada. Métodos estáticos são geralmente usados para criar funções de utilidades por uma aplicação.</p>
+
+<pre class="brush: js">class Ponto {
+ constructor(x, y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ static distancia(a, b) {
+ const dx = a.x - b.x;
+ const dy = a.y - b.y;
+
+ return Math.hypot(dx, dy);
+ }
+}
+
+const p1 = new Ponto(5, 5);
+const p2 = new Ponto(10, 10);
+
+p1.distancia; //undefined
+p2.distancia; //undefined
+
+console.log(Ponto.distancia(p1, p2));</pre>
+
+<h3 id="Empacotando_com_protótipos_e_métodos_estáticos">Empacotando com protótipos e métodos estáticos</h3>
+
+<p>Quando um método estático ou protótipo é chamado sem um objeto "this" configurado (ou com "this" como boolean, string, number, undefined ou null), então o valor "this" será <strong><code>undefined</code></strong> dentro da função chamada. Autoboxing não vai acontecer. O comportamento será o mesmo mesmo se escrevemos o código no modo não-estrito.</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">class</span> <span class="class-name token">Animal</span> <span class="punctuation token">{</span>
+ falar<span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ <span class="keyword token">return</span> <span class="keyword token">this</span><span class="punctuation token">;</span>
+ <span class="punctuation token">}</span>
+ <span class="keyword token">static</span> comer<span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ <span class="keyword token">return</span> <span class="keyword token">this</span><span class="punctuation token">;</span>
+ <span class="punctuation token">}</span>
+<span class="punctuation token">}</span>
+
+<span class="keyword token">let</span> obj <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Animal</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;
+obj.falar(); // Animal {}</span>
+<span class="keyword token">let</span> falar <span class="operator token">=</span> obj<span class="punctuation token">.</span>falar<span class="punctuation token">;</span>
+falar<span class="punctuation token">()</span><span class="punctuation token">;</span> <span class="comment token">// undefined</span>
+
+Animal.comer(); // class Animal
+<span class="keyword token">let</span> comer <span class="operator token">=</span> Animal<span class="punctuation token">.</span>comer<span class="punctuation token">;</span>
+<span class="function token">comer</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// undefined</span></code></pre>
+
+<p>Se escrevemos o código acima usando classes baseadas em função tradicional, então o autoboxing acontecerá com base no valor de "this" para o qual a função foi chamada.</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">Animal</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> <span class="punctuation token">}</span>
+
+Animal<span class="punctuation token">.</span>prototype<span class="punctuation token">.</span>falar <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ <span class="keyword token">return</span> <span class="keyword token">this</span><span class="punctuation token">;</span>
+<span class="punctuation token">}</span>
+
+Animal<span class="punctuation token">.</span>comer <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
+ <span class="keyword token">return</span> <span class="keyword token">this</span><span class="punctuation token">;</span>
+<span class="punctuation token">}</span>
+
+<span class="keyword token">let</span> obj <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Animal</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
+<span class="keyword token">let</span> falar <span class="operator token">=</span> obj<span class="punctuation token">.</span>falar<span class="punctuation token">;</span>
+falar<span class="punctuation token">()</span><span class="punctuation token">;</span> <span class="comment token">// objeto global</span>
+
+<span class="keyword token">let</span> comer <span class="operator token">=</span> Animal<span class="punctuation token">.</span>comer<span class="punctuation token">;</span>
+comer<span class="punctuation token">()</span><span class="punctuation token">;</span> <span class="comment token">// objeto global</span></code></pre>
+
+<h3 id="Propriedades_de_instância">Propriedades de instância</h3>
+
+<p>Propriedades de instâncias devem ser definidas dentro dos métodos da classe:</p>
+
+<pre><code>class Retangulo {
+ constructor(altura, largura) {
+ this.altura = altura;
+ this.largura = largura;
+ }
+}</code>
+</pre>
+
+<p>Propriedades de dados estáticos e propriedades de dados prototipados (prototype) devem ser definidos fora da declaração do corpo da classe.</p>
+
+<pre><code>Retangulo.larguraEstatico = 20;
+Retangulo.prototype.larguraPrototipagem = 25;</code></pre>
+
+<h2 id="Sub_classes_com_o_extends">Sub classes com o <code>extends</code></h2>
+
+<p>A palavra-chave <code><a href="/en-US/docs/Web/JavaScript/Reference/Classes/extends">extends</a></code> é usada em uma <em>declaração de classe</em>, ou em uma <em>expressão de classe </em>para criar uma classe como filha de uma outra classe.</p>
+
+<pre class="brush: js">class Animal {
+ constructor(nome) {
+  this.nome = nome;
+  }
+
+  falar() {
+ console.log(this.nome + ' emite um barulho.');
+  }
+}
+
+class Cachorro extends Animal {
+ falar() {
+ console.log(this.nome + ' latidos.');
+  }
+}
+
+<code class="language-js"><span class="keyword token">let</span> cachorro <span class="operator token">=</span> <span class="keyword token">new</span> </code>Cachorro<code class="language-js"><span class="punctuation token">(</span><span class="string token">'Mat'</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
+cachorro<span class="punctuation token">.</span></code>falar<code class="language-js"><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code>
+</pre>
+
+<p>Se existir um contrutor nas subclasses, é necessário primeiro chamar super() antes de usar a keyword "this".</p>
+
+<p>Também é possivel ampliar (extends) "classes" baseadas em funções tradicionais.</p>
+
+<pre class="brush: js">function Animal (nome) {
+ this.nome = nome;
+}
+
+Animal.prototype.falar = function() {
+  console.log(this.nome + ' faça barulho.');
+}
+
+class Cachorro extends Animal {
+  falar() {
+    console.log(this.nome + ' lati.');
+  }
+}
+
+let cachorro = new Cachorro('Mitzie');
+cachorro.falar(); // Mitzie lati.</pre>
+
+<p>Note que classes não extendem objetos normais (não construíveis). Se você quer herdar de um objeto, é necessário utilizar {{jsxref("Object.setPrototypeOf()")}}:</p>
+
+<pre class="brush: js"><code>let Animal = {
+  falar() {
+  console.log(this.nome + ' faça barulho.');
+ }
+};
+
+class Cachorro {
+ constructor(nome) {
+  this.nome = nome;
+</code> }
+}
+
+Object.setPrototypeOf(Cachorro.prototype, Animal);
+
+let cachorro = new Cachorro('Mitzie');
+cachorro.falar(); //Mitzie faça barulho.</pre>
+
+<h2 id="Species">Species</h2>
+
+<p>Você pode querer retornar um objeto {{jsxref("Array")}} na sua classe <code>MinhaArray</code> derivada de array. O padrão Species permite a sobrescrita do construtor padrão.</p>
+
+<p>Por exemplo, quando utilizando um método como {{jsxref("Array.map", "map()")}} que retorna o construtor padrão, você pode querer que esse método retorne um objeto <code>Array</code> ao invés do objeto <code>MinhaArray</code>. O {{jsxref("Symbol.species")}} te permite fazer isso:</p>
+
+<pre class="brush: js">class MinhaArray extends Array {
+  // Sobrescreve species para o construtor da classe pai Array
+  static get [Symbol.species]() { return Array; }
+}
+
+let a = new MinhaArray(1,2,3);
+let mapped = a.map(x =&gt; x * x);
+
+console.log(mapped instanceof MyArray); // false
+console.log(mapped instanceof Array); // true
+</pre>
+
+<h2 id="Chamada_da_classe_pai_com_super">Chamada da classe pai com <code>super</code></h2>
+
+<p>A palavra-chave (keyword) <code>super</code> é utilizada para chamar funções que pertencem ao pai do objeto.</p>
+
+<pre class="brush: js">class Gato {
+  constructor(nome) {
+  this.nome = nome;
+  }
+
+  falar() {
+  console.log(this.nome + ' faça barulho.');
+  }
+}
+
+class Leao extends Gato {
+  falar() {
+  super.falar();
+  console.log(this.nome + ' roars.');
+  }
+}
+
+let leao = new Leao('Fuzzy');
+leao.falar();
+
+// Fuzzy faça barulho.
+// Fuzzy roars.
+
+</pre>
+
+<h2 id="Mix-ins">Mix-ins</h2>
+
+<p>Subclasses abstratas ou <em>mix-ins</em> são templates para classes. Uma classe do ECMAScript pode apenas ter uma classe pai, assim sendo, não é possível a classe ter herança múltipla.</p>
+
+<p>Para se ter um comportamento similar ao de herança múltipla no ECMAScript usa-se mix-ins, uma forma de implementar mix-ins é usar um template de subclasse que é uma função que instancia uma classe base e retorna uma subclasse extendida desta classe base:</p>
+
+<pre class="brush: js">class Humano {
+  constructor(nome) {
+    this.nome = nome;
+  }
+  andar() {
+    return this.nome+' andou um passo'
+  }
+}
+
+const HumanoFalante = Base =&gt; class extends Base {
+  falar() {
+    return this.nome+' diz: olá mundo!'
+  }
+}
+
+const HumanoFalanteMixado = Base =&gt; class extends Base {}
+
+const HumanoFinal = HumanoFalanteMixado(HumanoFalante(Humano))
+
+const humano = new HumanoFinal('Bill Gates')
+
+console.log(humano.andar())
+console.log(humano.falar())
+</pre>
+
+<h2 id="Especificações">Especificações</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Especificação</th>
+ <th scope="col">Status</th>
+ <th scope="col">Comentário</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ES6', '#sec-class-definitions', 'Class definitions')}}</td>
+ <td>{{Spec2('ES6')}}</td>
+ <td>Definição inicial.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Compatibilidade_de_navegadores">Compatibilidade de navegadores</h2>
+
+
+
+<p>{{Compat("javascript.classes")}}</p>
+
+<h2 id="Rodando_com_Scratchpad">Rodando com Scratchpad</h2>
+
+<p>Uma classe não pode ser redefinida. Se você estiver rodando código com Scratchpad (Menu do Firefox Ferramentas &gt; Web Developer &gt; Scratchpad) e você acionar 'Run' a uma definição de uma classe com o mesmo nome duas vezes, você verá um confuso SyntaxError: redeclaration of let &lt;class-name&gt; (Erro de Sintaxe: redeclaração de let &lt;nome-da-classe&gt;).</p>
+
+<p>Para reacionar (re-run) uma definição, use o menu do Scratchpad em Execute &gt; Reload and Run (Executar &gt; Atualizar e Rodar).<br>
+ Por favor, vote no bug <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1428672">#1428672</a>.</p>
+
+<h2 id="Veja_também">Veja também</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions">Funções</a></li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/class">Declaração de <code>classes</code> (class declaration</a>)</li>
+ <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/class">Expressão de <code>classes</code> (class expression</a>)</li>
+ <li>{{jsxref("Operators/super", "super")}}</li>
+ <li><a href="https://hacks.mozilla.org/2015/07/es6-in-depth-classes/">Blog post: "ES6 In Depth: Classes"</a></li>
+</ul>