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(). Дивіться: Ініціалізація об'єктів / синтаксис літералів.

Опис

Функція-гетер __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.

Приклади

Використання __proto__

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

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

// Отримати прототип об'єкта
console.log(shape.__proto__ === circle); // true

const ShapeA = function () {};
const ShapeB = {
    a() {
        console.log('aaa');
    }
};
console.log(ShapeA.prototype.__proto__ = ShapeB);

const shapea = new ShapeA();
shapea.a(); // aaa
console.log(ShapeA.prototype === shapea.__proto__); // true

// або
const ShapeC = function () {};
const ShapeD = {
    a() {
        console.log('a');
    }
};

const shapeC = new ShapeC();
shapeC.__proto__ = ShapeD;
shapeC.a(); // a
console.log(ShapeC.prototype === shapeC.__proto__); // false

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

const a = new Test();
console.log(a.__proto__ === Test.prototype); // true
a.myname(); // myname

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

var obj = {
    __proto__: fn.prototype
};

obj.myname(); // myname

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

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

BCD tables only load in the browser

Див. також