EDIT Febbraio 2012: la risposta qui sotto non è più accurata. __proto__ viene aggiunto a ECMAScript 6 come "normativo facoltativo", il che significa che non è necessario implementarlo, ma se lo è, deve seguire il set di regole specificato. Questo è attualmente irrisolto ma almeno farà parte ufficialmente delle specifiche di JavaScript.
Questa domanda è molto più complicata di quanto sembri in superficie, e al di là del grado di retribuzione della maggior parte delle persone per quanto riguarda la conoscenza degli interni di Javascript.
La prototypeproprietà di un oggetto viene utilizzata durante la creazione di nuovi oggetti figlio di tale oggetto. La modifica non si riflette nell'oggetto stesso, piuttosto si riflette quando quell'oggetto viene utilizzato come costruttore per altri oggetti e non ha alcuna utilità nel modificare il prototipo di un oggetto esistente.
function myFactory(){};
myFactory.prototype = someOtherObject;
var newChild = new myFactory;
newChild.__proto__ === myFactory.prototype === someOtherObject; //true
Gli oggetti hanno una proprietà interna [[prototype]] che punta al prototipo corrente. Il modo in cui funziona è che ogni volta che viene chiamata una proprietà su un oggetto, inizierà dall'oggetto e poi risalirà attraverso la catena [[prototype]] finché non trova una corrispondenza, o fallisce, dopo il prototipo dell'oggetto radice. Questo è il modo in cui Javascript consente la creazione runtime e la modifica degli oggetti; ha un piano per cercare ciò di cui ha bisogno.
La __proto__proprietà esiste in alcune implementazioni (molte ora): qualsiasi implementazione di Mozilla, tutte quelle webkit che conosco, alcune altre. Questa proprietà punta alla proprietà interna [[prototype]] e consente la modifica post-creazione sugli oggetti. Qualsiasi proprietà e funzione passerà istantaneamente per corrispondere al prototipo grazie a questa ricerca concatenata.
Questa funzionalità, sebbene sia ora standardizzata, non è ancora una parte richiesta di JavaScript e nei linguaggi che la supportano ha un'alta probabilità di abbattere il codice nella categoria "non ottimizzato". I motori JS devono fare del loro meglio per classificare il codice, specialmente il codice "caldo" a cui si accede molto spesso, e se stai facendo qualcosa di stravagante come la modifica __proto__, non ottimizzeranno affatto il tuo codice.
Questo post https://bugzilla.mozilla.org/show_bug.cgi?id=607863 discute specificamente delle attuali implementazioni __proto__e delle differenze tra di loro. Ogni implementazione lo fa in modo diverso, perché è un problema difficile e irrisolto. Tutto in Javascript è modificabile, tranne a.) La sintassi b.) Oggetti host (il DOM esiste al di fuori di Javascript tecnicamente) e c.) __proto__. Il resto è completamente nelle mani di te e di ogni altro sviluppatore, quindi puoi capire perché __proto__sporge come un pollice dolorante.
C'è una cosa che __proto__consente che altrimenti sarebbe impossibile: la designazione di un prototipo di oggetti in fase di esecuzione separato dal suo costruttore. Questo è un caso d'uso importante ed è uno dei motivi principali per cui __proto__non è già morto. È abbastanza importante che sia stato un serio punto di discussione nella formulazione di Harmony, o che presto sarà conosciuto come ECMAScript 6. La capacità di specificare il prototipo di un oggetto durante la creazione farà parte della prossima versione di Javascript e questa sarà la campana che indica __proto__i giorni è formalmente numerata.
A breve termine, puoi utilizzarlo __proto__se stai prendendo di mira i browser che lo supportano (non IE, e nessun IE lo farà mai). È probabile che funzionerà in webkit e moz per i prossimi 10 anni poiché ES6 non sarà finalizzato fino al 2013.
Brendan Eich - re: Approach of new Object methods in ES5 :
Spiacente, ma impostabile __proto__, a parte il caso d'uso dell'inizializzatore di oggetti (cioè, su un nuovo oggetto non ancora raggiungibile, analogo a Object.create di ES5), è un'idea terribile. Scrivo questo dopo averlo progettato e realizzato settable __proto__oltre 12 anni fa.
... la mancanza di stratificazione è un problema (considera i dati JSON con una chiave "__proto__"). E peggio ancora, la mutabilità significa che le implementazioni devono verificare la presenza di catene di prototipi ciclici per evitare ilooping. [sono richiesti controlli costanti per la ricorsione infinita]
Infine, la modifica di __proto__un oggetto esistente può rompere i metodi non generici nel nuovo oggetto prototipo, che non può funzionare sull'oggetto ricevente (diretto) il cui __proto__viene impostato. Questa è semplicemente una cattiva pratica, una forma di confusione di tipo intenzionale, in generale.