EDYCJA Luty 2012: poniższa odpowiedź nie jest już aktualna. __proto__ jest dodawany do ECMAScript 6 jako „normatywny opcjonalny”, co oznacza, że nie jest wymagany do zaimplementowania, ale jeśli jest, musi być zgodny z podanym zestawem reguł. Obecnie jest to nierozwiązane, ale przynajmniej będzie oficjalnie częścią specyfikacji JavaScript.
To pytanie jest o wiele bardziej skomplikowane, niż się wydaje na pierwszy rzut oka, i wykracza poza poziom płac większości ludzi, jeśli chodzi o znajomość wewnętrznych elementów Javascript.
prototypeWłaściwość obiektu jest używany przy tworzeniu nowych obiektów podrzędnych tego obiektu. Zmiana nie odbija się w samym obiekcie, a raczej jest odzwierciedlana, gdy ten obiekt jest używany jako konstruktor dla innych obiektów i nie ma pożytku ze zmiany prototypu istniejącego obiektu.
function myFactory(){};
myFactory.prototype = someOtherObject;
var newChild = new myFactory;
newChild.__proto__ === myFactory.prototype === someOtherObject; //true
Obiekty mają wewnętrzną właściwość [[prototyp]], która wskazuje na bieżący prototyp. Działa to tak, że za każdym razem, gdy wywoływana jest właściwość obiektu, zaczyna się ona od obiektu, a następnie przechodzi w górę przez łańcuch [[prototyp]], aż znajdzie dopasowanie lub niepowodzenie po głównym prototypie obiektu. W ten sposób Javascript umożliwia budowanie i modyfikowanie obiektów w środowisku wykonawczym; ma plan poszukiwania tego, czego potrzebuje.
Ta __proto__właściwość istnieje w niektórych implementacjach (obecnie dużo): we wszystkich implementacjach Mozilli, we wszystkich webkitach, które znam, w innych. Ta właściwość wskazuje na wewnętrzną właściwość [[prototyp]] i umożliwia modyfikację obiektów po utworzeniu. Wszelkie właściwości i funkcje zostaną natychmiast przełączone w celu dopasowania do prototypu dzięki wyszukiwaniu łańcuchowemu.
Ta funkcja, choć jest obecnie standaryzowana, nadal nie jest wymaganą częścią JavaScript, aw językach obsługujących ją istnieje duże prawdopodobieństwo, że kod zostanie umieszczony w kategorii „niezoptymalizowana”. Silniki JS muszą zrobić wszystko, co w ich mocy, aby sklasyfikować kod, szczególnie ten „gorący”, do którego dostęp jest bardzo często, a jeśli robisz coś wymyślnego, na przykład modyfikowanie __proto__, w ogóle nie zoptymalizują Twojego kodu.
Ten post https://bugzilla.mozilla.org/show_bug.cgi?id=607863 szczegółowo omawia bieżące implementacje __proto__i różnice między nimi. Każda implementacja robi to inaczej, ponieważ jest to trudny i nierozwiązany problem. Wszystko w Javascript jest zmienne, z wyjątkiem a.) Składni b.) Obiektów hosta (technicznie rzecz biorąc, DOM istnieje poza JavaScriptem) ic.) __proto__. Reszta jest całkowicie w rękach Ciebie i każdego innego programisty, więc możesz zobaczyć, dlaczego __proto__wystaje jak bolący kciuk.
Jest jedna rzecz, która __proto__pozwala na to, co w innym przypadku jest niemożliwe: wyznaczenie prototypu obiektów w czasie wykonywania, niezależnie od jego konstruktora. Jest to ważny przypadek użycia i jeden z głównych powodów, dla których __proto__nie jest martwy. Na tyle ważne, że był to poważny punkt dyskusji przy formułowaniu Harmony lub wkrótce będzie znany jako ECMAScript 6. Możliwość określenia prototypu obiektu podczas tworzenia będzie częścią kolejnej wersji Javascript i będzie to dzwon wskazujący __proto__dni są formalnie numerowane.
Na krótką metę możesz użyć, __proto__jeśli kierujesz reklamy na przeglądarki, które go obsługują (nie IE i żaden IE nigdy tego nie zrobi). Prawdopodobnie będzie działać w webkit i moz przez następne 10 lat, ponieważ ES6 nie zostanie sfinalizowany do 2013 roku.
Brendan Eich - re: Approach of new Object methods in ES5 :
Przepraszam, ale możliwe do __proto__ustalenia, poza przypadkiem użycia inicjatora obiektu (tj. Na nowym obiekcie nieosiągalnym jeszcze, analogicznie do Object.create w ES5), jest okropnym pomysłem. Piszę to po zaprojektowaniu i wdrożeniu ustawialnego __proto__ponad 12 lat temu.
... brak stratyfikacji jest problemem (rozważ dane JSON z kluczem "__proto__"). Co gorsza, zmienność oznacza, że implementacje muszą sprawdzać cykliczne łańcuchy prototypów, aby uniknąć iloopingu. [wymagane są ciągłe sprawdzanie nieskończonej rekurencji]
Wreszcie, mutacja __proto__na istniejącym obiekcie może zepsuć nieogólne metody w nowym prototypowym obiekcie, który prawdopodobnie nie będzie działał na odbiorniku (bezpośrednim) obiekcie, który __proto__jest ustawiany. Jest to po prostu zła praktyka, ogólnie rzecz biorąc, rodzaj zamierzonego pomieszania.