aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/reference/global_objects/object/proto/index.html
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
commit074785cea106179cb3305637055ab0a009ca74f2 (patch)
treee6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/javascript/reference/global_objects/object/proto/index.html
parentda78a9e329e272dedb2400b79a3bdeebff387d47 (diff)
downloadtranslated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz
translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2
translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip
initial commit
Diffstat (limited to 'files/ru/web/javascript/reference/global_objects/object/proto/index.html')
-rw-r--r--files/ru/web/javascript/reference/global_objects/object/proto/index.html151
1 files changed, 151 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/global_objects/object/proto/index.html b/files/ru/web/javascript/reference/global_objects/object/proto/index.html
new file mode 100644
index 0000000000..3ee717a370
--- /dev/null
+++ b/files/ru/web/javascript/reference/global_objects/object/proto/index.html
@@ -0,0 +1,151 @@
+---
+title: Object.prototype.__proto__
+slug: Web/JavaScript/Reference/Global_Objects/Object/proto
+tags:
+ - JavaScript
+ - Object
+ - Property
+ - Prototype
+ - Reference
+ - Référence(2)
+translation_of: Web/JavaScript/Reference/Global_Objects/Object/proto
+---
+<div>{{JSRef("Global_Objects", "Object")}}</div>
+
+<div class="warning">
+<p><strong>Предупреждение:</strong> Изменение прототипа <code>[[Prototype]]</code> объекта является, по самой природе оптимизации доступа к свойствам в современных движках JavaScript, очень медленной операцией, это справедливо для <strong><em>любого</em></strong> браузера и движка JavaScript. Изменение прототипов очень тонко и обширно влияет на производительность, причём это влияние не ограничивается просто временем для операции присваивания <code>obj.__proto__ = ...</code>, оно может распространяться на <strong><em>любой</em></strong> код, который имеет доступ к <strong><em>любому</em></strong> объекту, чей прототип <code>[[Prototype]]</code> был изменён. Если вы заботитесь о производительности, вы никогда не должны изменять прототип <code>[[Prototype]]</code> объекта. Вместо этого создайте объект с нужным прототипом <code>[[Prototype]]</code>, с помощью метода {{jsxref("Object.create()")}}.</p>
+</div>
+
+<div class="warning">
+<p><strong>Предупреждение:</strong> хотя на сегодняшний момент большинство браузеров поддерживают свойство <code>Object.prototype.__proto__</code>, его поведение только недавно было стандартизировано в новой спецификации ECMAScript 6. Если вам требуется поддержка браузеров до этой спецификации, рекомендуется использовать вместо него метод {{jsxref("Object.getPrototypeOf()")}}.</p>
+</div>
+
+<h2 id="Summary" name="Summary">Сводка</h2>
+
+<p>Свойство <code>__proto__</code> объекта {{jsxref("Object.prototype")}} является свойством доступа (комбинацией геттера и сеттера), которое расширяет внутренний прототип <code>[[Prototype]]</code> объекта (являющийся объектом или {{jsxref("Global_Objects/null", "null")}}), через который осуществлялся доступ.</p>
+
+<p>Использование свойства <code>__proto__</code> вызывает споры и многих оно разочаровало. Ранее оно никогда не включалось в спецификацию EcmaScript, но современные браузеры всё равно решили его реализовать. Сегодня свойство <code>__proto__</code> стандартизировано в спецификации ECMAScript 6 и будет поддерживаться в будущем. Тем не менее, изменение прототипа <code>[[Prototype]]</code> объекта всё ещё остаётся медленной операцией, которую следует избегать, если вы беспокоитесь о производительности.</p>
+
+<p>Свойство <code>__proto__</code> также может использоваться при определении литерала объекта, устанавливая прототип <code>[[Prototype]]</code> объекта при его создании. Этот способ может рассматриваться как альтернатива методу {{jsxref("Object.create()")}}. Смотрите также <a href="/ru/docs/Web/JavaScript/Reference/Operators/Object_initializer">литеральный синтаскис инициализации объекта</a>.</p>
+
+<h2 id="Syntax" name="Syntax">Синтаксис</h2>
+
+<pre class="brush: js">var shape = {}, circle = new Circle();
+
+// Установка прототипа объекта
+shape.__proto__ = circle;
+// Получение прототипа объекта
+console.log(shape.__proto__ === circle); // true
+</pre>
+
+<p>Обратите внимание: название свойства состоит из двух подчёркиваний, следующих за ними пяти символов «proto» и следующих за ними ещё двух подчёркиваний.</p>
+
+<h2 id="Description" name="Description">Описание</h2>
+
+<p>Геттер свойства <code>__proto__</code> расширяет значение внутреннего прототипа <code>[[Prototype]]</code> объекта. Для объектов, созданных с использованием литеральной формы создания объекта, это значение равно {{jsxref("Object.prototype")}}. Для функций это значение равно {{jsxref("Function.prototype")}}. Для объектов, созданных с использованием формы <code>new fun</code>, где <code>fun</code> является одной из встроенных функций-конструкторов, предоставляемых JavaScript ({{jsxref("Global_Objects/Array", "Array")}}, {{jsxref("Global_Objects/Boolean", "Boolean")}}, {{jsxref("Global_Objects/Date", "Date")}}, {{jsxref("Global_Objects/Number", "Number")}}, {{jsxref("Global_Objects/Object", "Object")}}, {{jsxref("Global_Objects/String", "String")}} и так далее — включая новые конструкторы, добавленные в процессе развития JavaScript), это значение равно <code>fun.prototype</code>. Для объектов, созданных с использованием формы <code>new fun</code>, где <code>fun</code> является функцией, определённой в скрипте, это значение равно значению <code>fun.prototype</code> во время вычисления <code>new fun</code>. Именно поэтому при присваивании <code>fun.prototype</code> нового значения, ранее созданные экземпляры <code>fun</code> продолжат использовать предыдущее значение в качестве своего прототипа <code>[[Prototype]]</code>, а последующие вызовы <code>new fun</code> будут использовать вновь присвоенное значение в качестве своего прототипа <code>[[Prototype]]</code>.</p>
+
+<p>Геттер <code>__proto__</code> позволяет прототипу <code>[[Prototype]]</code> объекта быть изменяемым. Объект должен быть расширяемым в соответствии с {{jsxref("Object.isExtensible()")}}: если это не так, выкидывается исключение {{jsxref("Global_Objects/TypeError", "TypeError")}}. Предоставляемое значение должно быть объектом или {{jsxref("Global_Objects/null", "null")}}. Предоставление любого другого значения ничего не даст.</p>
+
+<p>Для понимания того, как прототипы используются для наследования, смотрите статью руководства <a href="/ru/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain">«Наследование и цепочки прототипов»</a>.</p>
+
+<p>Свойство <code>__proto__</code> является простым свойством доступа на объекте {{jsxref("Object.prototype")}} — свойством, состоящим из геттера и сеттера. Свойство <code>__proto__</code> будет найдено, если, в конечном итоге, его поиск пройдёт через {{jsxref("Object.prototype")}}, но при доступе к нему не через {{jsxref("Object.prototype")}}, оно найдено не будет. Если перед просмотром {{jsxref("Object.prototype")}} буден найдено какое-нибудь другое свойство <code>__proto__</code>, оно скроет искомое свойство {{jsxref("Object.prototype")}}.</p>
+
+<pre class="brush: js">var noProto = Object.create(null);
+
+console.log(typeof noProto.__proto__); // undefined
+console.log(Object.getPrototypeOf(noProto)); // null
+
+noProto.__proto__ = 17;
+
+console.log(noProto.__proto__); // 17
+console.log(Object.getPrototypeOf(noProto)); // null
+
+var protoHidden = {};
+Object.defineProperty(protoHidden, '__proto__',
+ { value: 42, writable: true, configurable: true, enumerable: true });
+
+console.log(protoHidden.__proto__); // 42
+console.log(Object.getPrototypeOf(protoHidden) === Object.prototype); // true
+</pre>
+
+<h2 id="Examples" name="Examples">Примеры</h2>
+
+<p>В следующем примере создаётся новый экземпляр <code>Employee</code>, а затем проверяется, что его свойство <code>__proto__</code> является тем же самым объектом, что и его конструктор <code>prototype</code>.</p>
+
+<pre class="brush: js">// Декларируем функцию, используемую как конструктор
+function Employee() {
+ /* инициализируем экземпляр */
+}
+
+// Создаём новый экземпляр Employee
+var fred = new Employee();
+
+// Проверка на эквивалентность
+fred.__proto__ === Employee.prototype; // true
+</pre>
+
+<p>В этот момент <code>fred</code> унаследован от <code>Employee</code>, однако присваивание другого объекта в <code>fred.__proto__</code> может изменить это:</p>
+
+<pre class="brush: js">function Cow() {
+ /* инициализируем экземпляр */
+}
+
+// Присваиваем __proto__ новый объект
+fred.__proto__ = Cow.prototype;
+</pre>
+
+<p>Теперь <code>fred</code> наследуется непосредственно от <code>Cow.prototype</code>, а не от <code>Employee.prototype</code>, и теряет свойства, изначально унаследованные от <code>Employee.prototype</code>.</p>
+
+<p>Однако, это применяется только к {{jsxref("Object.isExtensible()", "расширяемым", "", 1)}} объектам, у нерасширяемых объектов свойство <code>__proto__</code> не может быть изменено:</p>
+
+<pre class="brush: js">var obj = {};
+Object.preventExtensions(obj);
+
+obj.__proto__ = {}; // выкинет TypeError
+</pre>
+
+<p>Обратите внимание, что свойство <code>__proto__</code> может быть переопределено даже у объекта <code>Object.prototype</code>, если новая цепочка заканчивается {{jsxref("Global_Objects/null", "null")}}:</p>
+
+<pre class="brush: js">var b = {};
+
+Object.prototype.__proto__ =
+ Object.create(null, // [[Prototype]]
+ { hi: { value: function() { alert('hi'); } } });
+
+b.hi();
+</pre>
+
+<p>Если свойство <code>__proto__</code> объекта {{jsxref("Object.prototype")}} не установлено в {{jsxref("Global_Objects/null", "null")}}, или в другой объект, чья цепочка прототипов, в конечном итоге, явно не заканчивается значением {{jsxref("Global_Objects/null", "null")}}, будет выкинуто исключение {{jsxref("Global_Objects/TypeError", "TypeError")}} «циклическое значение __proto__», поскольку цепочка должна заканчиваться {{jsxref("Global_Objects/null", "null")}} (как это и происходит на {{jsxref("Object.prototype")}} при нормальных обстоятельствах).</p>
+
+<h2 id="Specifications" name="Specifications">Спецификации</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th scope="col">Спецификация</th>
+ <th scope="col">Статус</th>
+ <th scope="col">Комментарии</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ES6', '#sec-additional-properties-of-the-object.prototype-object', 'Object.prototype.__proto__')}}</td>
+ <td>{{Spec2('ES6')}}</td>
+ <td>Включён в (нормативное) приложение для дополнительных возможностей ECMAScript для веб-браузеров (обратите внимание, что спецификация закрепляет то, что уже реализовано).</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Browser_compatibility" name="Browser_compatibility">Совместимость с браузерами</h2>
+
+<div class="note">
+<p><strong>Примечание:</strong> спецификация ES6 требует поддержку свойства <code>__proto__</code> только в браузерах и не требует его поддержку в других окружениях (хотя оно и рекомендуется в качестве обязательного). Если ваш код должен работать в не-браузерных окружениях, вместо свойства рекомендуется использовать методы {{jsxref("Object.getPrototypeOf()")}} и {{jsxref("Object.setPrototypeOf()")}}.</p>
+</div>
+
+<div>{{Compat("javascript.builtins.Object.proto")}}</div>
+
+<h2 id="See_also" name="See_also">Смотрите также</h2>
+
+<ul>
+ <li>{{jsxref("Object.prototype.isPrototypeOf()")}}</li>
+ <li>{{jsxref("Object.getPrototypeOf()")}}</li>
+ <li>{{jsxref("Object.setPrototypeOf()")}}</li>
+</ul>