Object.prototype.__proto__

Deprecated
This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.

Застереження: Зміна властивості об'єкта [[Prototype]], за природою того, як сучасні рушії JavaScript оптимізують доступ до властивостей, є дуже повільною операцією в кожному переглядачі та рушії JavaScript. Ефект для продуктивності від зміни спадкування є витонченим та обширним, і не обмежується лише часом, витраченим на команду  obj.__proto__ = ..., але може поширюватися на будь-який код, що має доступ до будь-якого об'єкта, чия властивість [[Prototype]] була змінена. Якщо ви дбаєте про продуктивність, вам варто уникати присвоювати  [[Prototype]] об'єкта. Замість цього створіть новий об'єкт з бажаною властивістю [[Prototype]], використовуючи Object.create().

Застереження: В той час, як властивість Object.prototype.__proto__ підтримується більшістю нинішніх переглядачів, її існування та точна поведінка були стандартизовані у специфікації ECMAScript 2015 тільки в якості legacy-функціональності для сумісності з веб-переглядачами. Для кращої підтримки рекомендовано натомість використовувати Object.getPrototypeOf().

Властивість Object.prototype __proto__ - це властивість-аксесор (функція-гетер та функція-сетер), яка відкриває внутрішню властивість [[Prototype]] (або об'єкт, або null) об'єкта, через який до неї звертаються.

Використання __proto__ є суперечливим і не заохочується. Ця властивість ніколи не включалась у специфікації мови EcmaScript, але сучасні переглядачі вирішили все одно її реалізувати. Тільки останнім часом властивість __proto__ була стандартизована у специфікації мови ECMAScript 2015 для сумісності веб-переглядачів, і буде підтримуватись у майбутньому. Її використання не рекомендоване на користь  Object.getPrototypeOf/Reflect.getPrototypeOf та Object.setPrototypeOf/Reflect.setPrototypeOf (хоча, все одно, присвоєння [[Prototype]] об'єкта є повільною операцією, якої бажано уникати, якщо продуктивність має значення).

Властивість __proto__ також може бути використана при визначенні об'єктного літералу, щоб встановити властивість об'єкта [[Prototype]] при створенні, як альтернатива Object.create(). Дивіться: Ініціалізація об'єктів / синтаксис літералів.

Синтаксис

var Circle = function () {};
var shape = {};
var circle = new Circle();

// Присвоїти прототип об'єкта.
// НЕ РЕКОМЕНДОВАНО. Цей код написаний лише для прикладу. НЕ РОБІТЬ ЦЬОГО у справжньому коді.
shape.__proto__ = circle;

// Отримати прототип об'єкта
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

// або
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

// або
function test() {};
test.prototype.myname = function () {
    console.log('myname');
};

var a = new test();
console.log(a.__proto__ === test.prototype); // true
a.myname(); // myname


// або
var fn = function () {};
fn.prototype.myname = function () {
    console.log('myname');
};

var obj = {
    __proto__: fn.prototype
};

obj.myname(); // myname

Заувага: це два підкреслення, за ними п'ять літер "proto", за ними ще два підкреслення.

Опис

Функція-гетер __proto__ відкриває значення внутрішньої властивості об'єкта [[Prototype]]. Для об'єктів, що були створені об'єктним літералом, ця величина дорівнює Object.prototype. Для об'єктів, створених літералами масивів, це значення дорівнює Array.prototype. Для функцій воно дорівнює Function.prototype. Для об'єктів, створених через new fun, де fun є однією з вбудованих функцій-конструкторів JavaScript (Array, Boolean, Date, Number, Object, String і так далі — в тому числі нові конструктори, додані з розвитком JavaScript), це значення завжди дорівнює fun.prototype. Для об'єктів, створених за допомогою new fun, де fun - це функція, визначена у скрипті, це значення дорівнює значенню fun.prototype. (Якщо тільки конструктор не повернув явно інший об'єкт, або значення fun.prototype не було переприсвоєне після створення екземпляра).

Сетер __proto__ дозволяє змінювати властивість об'єкта [[Prototype]]. Об'єкт має бути розширюваним згідно з Object.isExtensible(): якщо це не так, викидається TypeError. Надана величина має бути об'єктом або null. Передача будь-якого іншого значення не дасть ніякого результату.

Щоб зрозуміти, як прототипи використовуються для наслідування, дивіться статтю посібника Наслідування та ланцюжок прототипів.

Властивість __proto__ - це проста властивість-аксесор Object.prototype, що складається з функції-гетера та функції-сетера. Звернення до властивості __proto__, яке зрештою звертається до Object.prototype, знайде цю властивість, але звернення, яке не звертається до Object.prototype, не знайде її. Якщо інша властивість __proto__ буде знайдена до того, як відбудеться звернення до Object.prototype, то ця властивість сховає знайдену у Object.prototype.

Специфікації

Специфікації Статус Коментар
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Object.prototype.__proto__' in that specification.
Standard Включено у (нормативний) додаток для legacy-функціональності ECMAScript для веб-переглядачів (зауважте, що специфікація кодифікує те, що вже реалізовано).
ECMAScript Latest Draft (ECMA-262)
The definition of 'Object.prototype.__proto__' in that specification.
Draft

Сумісність з веб-переглядачами

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
__proto__
Deprecated
Chrome Full support YesEdge Full support 12Firefox Full support 1IE Full support 11Opera Full support YesSafari Full support YesWebView Android Full support YesChrome Android Full support YesFirefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support Yesnodejs Full support Yes

Legend

Full support  
Full support
Deprecated. Not for use in new websites.
Deprecated. Not for use in new websites.

Примітки щодо сумісності

Хоча специфікація ECMAScript 2015 вказує, що підтримка властивості __proto__ обов'язкова тільки для веб-переглядачів (хоча є нормативною), інші середовища також можуть її підтримувати для використання legacy-коду.

Див. також