EDITAR Febrero de 2012: la respuesta a continuación ya no es precisa. __proto__ se está agregando a ECMAScript 6 como "normativo opcional", lo que significa que no se requiere que se implemente, pero si lo está, debe seguir el conjunto de reglas dado. Esto no está resuelto actualmente pero al menos será oficialmente parte de la especificación de JavaScript.
Esta pregunta es mucho más complicada de lo que parece en la superficie, y más allá del nivel de pago de la mayoría de las personas en lo que respecta al conocimiento de los componentes internos de Javascript.
La prototype
propiedad de un objeto se utiliza al crear nuevos objetos secundarios de ese objeto. Cambiarlo no se refleja en el objeto en sí, sino que se refleja cuando ese objeto se utiliza como constructor de otros objetos y no tiene ninguna utilidad para cambiar el prototipo de un objeto existente.
function myFactory(){};
myFactory.prototype = someOtherObject;
var newChild = new myFactory;
newChild.__proto__ === myFactory.prototype === someOtherObject; //true
Los objetos tienen una propiedad [[prototype]] interna que apunta al prototipo actual. La forma en que funciona es cada vez que se llama a una propiedad en un objeto, comenzará en el objeto y luego irá hacia arriba a través de la cadena [[prototype]] hasta que encuentre una coincidencia, o falle, después del prototipo del objeto raíz. Así es como Javascript permite la construcción y modificación de objetos en tiempo de ejecución; tiene un plan para buscar lo que necesita.
La __proto__
propiedad existe en algunas implementaciones (muchas ahora): cualquier implementación de Mozilla, todas las webkit que conozco, algunas otras. Esta propiedad apunta a la propiedad interna [[prototype]] y permite la modificación posterior a la creación en los objetos. Todas las propiedades y funciones cambiarán instantáneamente para coincidir con el prototipo debido a esta búsqueda encadenada.
Esta característica, aunque está estandarizada ahora, todavía no es una parte requerida de JavaScript, y en los lenguajes que la soportan tiene una alta probabilidad de derribar su código en la categoría "no optimizado". Los motores JS deben hacer todo lo posible para clasificar el código, especialmente el código "activo" al que se accede con mucha frecuencia, y si está haciendo algo elegante como modificar__proto__
, no optimizarán su código en absoluto.
Esta publicación https://bugzilla.mozilla.org/show_bug.cgi?id=607863 analiza específicamente las implementaciones actuales __proto__
y las diferencias entre ellas. Cada implementación lo hace de manera diferente, porque es un problema difícil y sin resolver. Todo en Javascript es mutable, excepto a.) La sintaxis b.) Objetos de host (el DOM existe técnicamente fuera de Javascript) y c.)__proto__
. El resto está completamente en manos de usted y de cualquier otro desarrollador, por lo que puede ver por qué __proto__
sobresale como un pulgar dolorido.
Hay una cosa que __proto__
permite que de otro modo sea imposible de hacer: la designación de un prototipo de objetos en tiempo de ejecución separado de su constructor. Este es un caso de uso importante y es una de las razones principales por las __proto__
que aún no está muerto. Es bastante importante que haya sido un punto de discusión serio en la formulación de Harmony, o que pronto se conocerá como ECMAScript 6. La capacidad de especificar el prototipo de un objeto durante la creación será parte de la próxima versión de Javascript y esto será la campana que indica __proto__
los días está formalmente numerada.
A corto plazo, puede usarlo __proto__
si se dirige a navegadores que lo admitan (no IE, y ningún IE lo hará). Es probable que funcione en webkit y moz durante los próximos 10 años, ya que ES6 no se finalizará hasta 2013.
Brendan Eich - re: Enfoque de nuevos métodos de objetos en ES5 :
Lo siento, ... pero configurable __proto__
, aparte del caso de uso del inicializador del objeto (es decir, en un nuevo objeto aún no accesible, análogo al Object.create de ES5), es una idea terrible. Escribo esto habiendo diseñado e implementado configurables hace __proto__
más de 12 años.
... la falta de estratificación es un problema (considere los datos JSON con una clave "__proto__"
). Y lo que es peor, la mutabilidad significa que las implementaciones deben verificar las cadenas de prototipos cíclicos para evitar el ilooping. [se requieren comprobaciones constantes para la recursividad infinita]
Por último, la mutación __proto__
en un objeto existente puede romper métodos no genéricos en el nuevo objeto prototipo, que no puede funcionar en el objeto receptor (directo) que __proto__
se está configurando. Esto es simplemente una mala práctica, una forma de confusión de tipo intencional, en general.