--- title: Object.prototype.__proto__ slug: Web/JavaScript/Reference/Global_Objects/Object/proto translation_of: Web/JavaScript/Reference/Global_Objects/Object/proto original_slug: Web/JavaScript/Referencje/Obiekty/Object/proto ---
Ostrzeżenie: Zmiana [[Prototype]]
obiektu, ze względu na sposób w jaki współczesny JavaScript optymalizuje dostęp do właściwości, jest bardzo powolną operacją (W każdej przeglądarce!). Efekty modyfikacji łańcucha dziedziczenia są rozległe, nie chodzi tu tylko o wydłużenie czasu potrzebnego na wykonanie operacji obj.__proto__ = ...
, skutki wpływają na każdy fragment kodu który odwołuje się do jakiejkolwiek właściwości obiektu, którego [[Prototype]]
został zmieniony. Dlatego jeżeli zależy ci na wydajności powinieneś unikać tej operacji. Zamiast tego, stwórz nowy obiekt z porządanym [[Prototype]]
za pomocą {{jsxref("Object.create()")}}.
Ostrzeżenie: Mimo że w dzisiejszych czasach Object.prototype.__proto__
jest wspierany w niemal każdej przeglądarce, jego istnienie oraz zachowanie zostały ujednolicone w specyfikacji ECMAScript 2015 jedynie jako legacy feature aby zapewnić kompatybilność z przeglądarkami. Dla lepszego wsparcia rekomenduje się używanie {{jsxref("Object.getPrototypeOf()")}}.
Właściwość __proto__
obiektu {{jsxref("Object.prototype")}} jest operatorem dostępu (metoda getter i setter) która operuje na wewnętrznym [[Prototype]]
(na obiekcie lub na {{jsxref("Global_Objects/null", "null")}}) obiektu do którego się odnosi.
Użycie __proto__
jest kontrowersyjne i podchodzi się do niego z niechęcią. Oryginalnie nigdy nie pojawiło się w specyfikacji EcmaScript, ale nowoczesne przeglądarki postanowiły mimo wszystko to zaimplementować. Dopiero niedawno właściwość __proto__
znalazła swoje miejsce w specyfikacji ECMAScript 2015 aby zapewnić kompatybilność z tymi przeglądarkami. Jest ona jednak przestarzała ze względu na {{jsxref("Object.getPrototypeOf")}}/{{jsxref("Reflect.getPrototypeOf")}} oraz {{jsxref("Object.setPrototypeOf")}}/{{jsxref("Reflect.setPrototypeOf")}} (choć modyfikowanie [[Prototype]]
wciąż jest operacją powolną, która powinna być unikana przez wzgląd na wydajność).
Właściwość __proto__
może być również używana w notacji literałowej aby ustawić [[Prototype]]
tworzonego obiektu, jako alterantywa do {{jsxref("Object.create()")}}. Zobacz: inicjalizator obiektu / notacja literałowa.
var Kolo = function () {}; var ksztalt = {}; var kolo = new Kolo(); // Ustawianie prototypu obiektu // ZDEPRECJONOWANE. Używamy tego tylko dla przykładu. NIE RÓB TEGO w prawdziwym kodzie. ksztalt.__proto__ = kolo; // Sprawdzenie prototypu obiektu console.log(ksztalt.__proto__ === kolo); // true
var ksztalt = function () {}; var p = { a: function () { console.log('aaa'); } }; ksztalt.prototype.__proto__ = p; var kolo = new ksztalt(); kolo.a(); // aaa console.log(ksztalt.prototype === kolo.__proto__); // true // albo var ksztalt = function () {}; var p = { a: function () { console.log('aaa'); } }; var kolo = new ksztalt(); kolo.__proto__ = p; circle.a(); // aaa console.log(ksztalt.prototype === kolo.__proto__); // false // albo function ksztalt() {}; ksztalt.prototype.a = function () { console.log('aaa'); } var kolo = new ksztalt(); kolo.a(); // aaa console.log(kolo.__proto__ === ksztalt.prototype); // true // albo var ksztalt = function () {}; ksztalt.prototype.a = function () { console.log('aaa'); } var kolo = { __proto__: ksztalt.prototype }; kolo.a(); // aaa console.log(kolo.__proto__ === ksztalt.prototype); // true
Uwaga: __proto__
zapisujemy jako dwie podłogi, następnie pięć liter "proto", następnie dwie kolejne podłogi.
Metoda getter właściwości __proto__
daje nam dostęp do wewnętrznej wartości [[Prototype]]
obiektu. Dla obiektów stworzonych przy użyciu literału jest to {{jsxref("Object.prototype")}}. Dla tablic stworzonych przy użyciu literału jest to {{jsxref("Array.prototype")}}. Dla funkcji ta wartość to {{jsxref("Function.prototype")}}. Dla obiektów stworzonych przy użyciu new Funkcja
, gdzie Funkcja
to jeden z wbudowanych konstruktorów dostarczanych przez JavaScript ({{jsxref("Array")}}, {{jsxref("Boolean")}}, {{jsxref("Date")}}, {{jsxref("Number")}}, {{jsxref("Object")}}, {{jsxref("String")}}, i tak dalej — wliczając nowe konstrukotry, które mogą zostać dodane w przyszłości), ta wartość to zawsze Funkcja.prototype
. Dla obiektów stworzonych przy użyciu new Funkcja
, gdzie Funkcja
to funkcja zdefiniowana w kodzie, wartość ta przyjmuje taką samą wartość jak Funkcja.prototype
.
Metoda setter właściwości __proto__
umożliwia modyfikowanie [[Prototype]]
obiektu. W tym celu obiekt musi być roszerzalny według funkcji {{jsxref("Object.isExtensible()")}}, jeżeli nie jest {{jsxref("Global_Objects/TypeError", "TypeError")}} zostanie wyrzucony. Dostarczana wartość musi być obiektem albo typem {{jsxref("Global_Objects/null", "null")}}. Podanie jakiejkolwiek innej wartości nie zrobi nic.
Aby zrozumieć w jaki sposób prototypy używane są do dziedziczenia, zobacz artykuł o dziedziczeniu oraz łańcuchu prototypów.
Właściwość __proto__
jest prostym operatorem pamięci na {{jsxref("Object.prototype")}} składającym się z metody getter i setter. Dostęp do właściwości __proto__
który ostatecznie konsultuje się z {{jsxref("Object.prototype")}} znajdzie tę właściwość, ale dostęp który nie konsultuje {{jsxref("Object.prototype")}} nie znajdzie jej. Jeżeli jakaś inna właściwość __proto__
zostanie znaleziona, zanim {{jsxref("Object.prototype")}} zostanie skonsultowany, to właściwość ta przesłoni tą znalezioną w {{jsxref("Object.prototype")}}.
Specification | Status | Comment |
---|---|---|
{{SpecName('ES2015', '#sec-additional-properties-of-the-object.prototype-object', 'Object.prototype.__proto__')}} | {{Spec2('ES2015')}} | Dołączony (normatywnie) jako jeden z dodatkowych ECMAScript legacy features dla przeglądarek (zauważ że specyfikacja jedynie ujednoliciła coś, co było już zaimplementowane w przeglądarkach). |
{{SpecName('ESDraft', '#sec-additional-properties-of-the-object.prototype-object', 'Object.prototype.__proto__')}} | {{Spec2('ESDraft')}} |
Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Basic support | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatIE("11")}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} |
Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Basic support | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} |
Mimo, że specyfikacja ECMAScript 2015 określa iż wsparcie dla __proto__
jest wymagane tylko dla przeglądarek internetowych (w zasadzie normatywnie), to inne środowiska równieź mogą wspierać tę funkcjonalność.