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
é 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
e Object.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
Specification |
---|
ECMAScript Language Specification # sec-object.prototype.__proto__ |
Compatibilidade com navegadores
BCD tables only load in the browser
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.