Esta tradução está incompleta. Por favor, ajude a traduzir este artigo.

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

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 é 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.getPrototypeOfObject.setPrototypeOf/Reflect.setPrototypeOf (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

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
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. Para os objetos criados usando literais de matrizes, esse valor é Array.prototype. Para funções, esse valor é Function.prototype. 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 consistindo de uma função getter e setter. Um acesso de propriedade para __proto__ que eventualmente consulte Object.prototype irá encontrar esta propriedade, mas um acesso que não consulta Object.prototype não a encontrará. Se alguma outra propriedade __proto__ for encontrada antes de consultar Object.prototype, essa propriedade irá ocultar a que encontrou Object.prototype.

Especificações

Especificação Status Comentários
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Object.prototype.__proto__' in that specification.
Padrão Included in the (normative) annex for additional ECMAScript legacy features for Web browsers (note that the specification codifies what is already in implementations).
ECMAScript Latest Draft (ECMA-262)
The definition of 'Object.prototype.__proto__' in that specification.
Rascunho  

Compatibilidade de navegadores

Estamos convertendo nossos dados de compatibilidade para o formato JSON. Esta tabela de compatibilidade ainda usa o formato antigo, pois ainda não convertemos os dados que ela contém. Descubra como você pode ajudar!
Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Yes) (Yes) 11 (Yes) (Yes)
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support (Yes) (Yes) (Yes) (Yes) (Yes) (Yes)

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

Etiquetas do documento e colaboradores

Colaboradores desta página: KyryIx, Treze, manzettidenis
Última atualização por: KyryIx,