Object.prototype.\_\_proto\_\_
==============================

**Aviso:** **Cuidado:** Alterando o `[[Prototype]]` de um objeto é, pela natureza que as engines do Javascript modernos otimizam os acessos à propriedades, uma operação muito lenta, em \*\**TODOS* \*\*os mecanismos browsers e JavaScript. Os efeitos no desempenho de alteração na herança são sutis e distantes, e não se limitam simplesmente ao tempo gasto em na declaração `obj.__proto__ = ...`, mas podem se estender para ***qualquer*** código que tenha acesso a ***qualquer*** objeto cujo `[[Prototype]]` foi alterado. Se você se preocupa com desempenho, evite configurar o `[[Prototype]]` de um objeto. Ao invés disso, crie um novo objeto com o `[[Prototype]]` desejado usando `Object.create()`.

**Aviso:** **Cuidado:** Enquanto `Object.prototype.__proto__` é suportado hoje em dia em quase todos os navegadores, a existência e o comportamento exato foram padronizados na especificação ECMAScript 2015 como um recurso legado para assegurar compatibilidade com os navegadores. Para melhor suporte, recomenda-se que apenas `Object.getPrototypeOf()` seja usado em vez disso.

A propriedade `__proto__` de `Object.prototype` (en-US) é uma propriedade de acesso (uma função getter e uma setter) que expõe o interno `[[Prototype]]` (ou um objeto ou `null`) de um objeto o qual é acessado.

O uso de `__proto__` é controverso, e foi desencorajado. Nunca foi incluído originalmente na especificação do idioma EcmaScript, mas os navegadores modernos decidiram implementá-lo de qualquer maneira. Somente recentemente, a propriedade `__proto__` foi padronizada na especificação de linguagem ECMAScript 2015 para navegadores para garantir compatibilidade, e então ser suportada no futuro. É obsoleta a favor de `Object.getPrototypeOf`/`Reflect.getPrototypeOf` (en-US) e `Object.setPrototypeOf`/`Reflect.setPrototypeOf` (en-US) (embora ainda, definir `[[Prototype]]` é uma operação lenta que deve ser evitada se o desempenho for uma preocupação).

A propriedade `__proto__` também pode ser usada em uma definição literal de objeto para definir o objeto `[[Prototype]]` na criação, como uma alternativa para `Object.create()`. Veja: object initializer / literal syntax.

Sintaxe
-------


```js
var shape = {};
var circle = new Circle();

// Define o objeto prototype.
// OBSOLETO. Isto é somente exemplo. NÃO FAÇA ISSO em código real.
shape.__proto__ = circle;

// Retorna o objeto prototype
console.log(shape.__proto__ === circle); // true
```



```js
var shape = function () {};
var p = {
  a: function () {
    console.log("aaa");
  },
};
shape.prototype.__proto__ = p;

var circle = new shape();

circle.a(); //aaa

console.log(shape.prototype === circle.__proto__); //true

//ou

var shape = function () {};
var p = {
  a: function () {
    console.log("a");
  },
};

var circle = new shape();
circle.__proto__ = p;

circle.a(); // a

console.log(shape.prototype === circle.__proto__); //false

//ou

function test() {}
test.prototype.myname = function () {
  console.log("myname");
};
var a = new test();

console.log(a.__proto__ === test.prototype); //true

a.myname(); //myname

//ou

var fn = function () {};
fn.prototype.myname = function () {
  console.log("myname");
};

var obj = {
  \_\_proto\_\_: fn.prototype,
};

obj.myname(); //myname
```


Nota: são dois underscores(underlines), seguidos de cinco caracteres "proto", seguidos por mais dois underscores(underlines).

Descrição
---------

A função getter de `__proto__` expõe o valor interno de `[[Prototype]]` de um objeto. Para objetos criado usando um objeto literal, este valor é `Object.prototype` (en-US). Para os objetos criados usando literais de matrizes, esse valor é `Array.prototype`. Para funções, esse valor é `Function.prototype` (en-US). Para objeto criados usando `new fun`, onde `fun` é uma função construtora built-in fornecida pelo JavaScript (`Array`, `Boolean`, `Date`, `Number`, `Object`, `String`, e assim por diante — incluindo novos construtores adicionados como evolução do JavaScript), este valor é sempre `fun.prototype`. Para objetos criados usando `new fun`, onde `fun` é uma função definida em um script, esse valor é o valor de `fun.prototype`. (Ou seja, se o construtor não retornou um outro objeto explicitamente, ou o `fun.prototype` foi reatribuído desde que a instância foi criada).

O setter `__proto__` permite ao `[[Prototype]]` de um objeto sejá mutável. O objeto deve ser extensível de acordo com `Object.isExtensible()`: se não for, um erro `TypeError` é emitido. O valor fornecido deve ser um objeto ou `null`. Fornecer qualquer outro valor não fará nada.

Para entender como os prototypes são usados para herança, veja o artigo:Inheritance and the prototype chain.

A propriedade `__proto__` é simplesmente uma propriedade acessora `Object.prototype` (en-US) consistindo de uma função getter e setter. Um acesso de propriedade para `__proto__` que eventualmente consulte `Object.prototype` (en-US) irá encontrar esta propriedade, mas um acesso que não consulta `Object.prototype` (en-US) não a encontrará. Se alguma outra propriedade `__proto__` for encontrada antes de consultar `Object.prototype` (en-US), essa propriedade irá ocultar a que encontrou `Object.prototype` (en-US).

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

| Specification |
| --- |
| ECMAScript Language Specification # sec-object.prototype.\_\_proto\_\_ |

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

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

Notas de compatibilidade
------------------------

Enquanto a especificação ECMAScript 2015 dita que o suporte para `__proto__` é requerido *somente* para navegadores (apesar de ser normativo), outros ambientes podem suportar também para uso legado.

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

* `Object.prototype.isPrototypeOf()`
* `Object.getPrototypeOf()`
* `Object.setPrototypeOf()`