diff options
| author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
|---|---|---|
| committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
| commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
| tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/javascript/reference/global_objects/proxy | |
| parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
| download | translated-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/proxy')
8 files changed, 1380 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html b/files/ru/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html new file mode 100644 index 0000000000..a796a08e26 --- /dev/null +++ b/files/ru/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html @@ -0,0 +1,131 @@ +--- +title: handler.deleteProperty() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty +tags: + - Прокси + - метод +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/deleteProperty +--- +<div>{{JSRef}}</div> + +<p>Метод <strong><code>handler.deleteProperty()</code></strong> является "ловушкой" (функция-перехватчик) для оператора {{jsxref("Operators/delete", "delete")}}.</p> + +<div>{{EmbedInteractiveExample("pages/js/proxyhandler-deleteproperty.html", "taller")}}</div> + + + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="brush: js">var p = new Proxy(target, { + deleteProperty: function(target, property) { + } +}); +</pre> + +<h3 id="Параметры">Параметры</h3> + +<p>Следующие параметры передаются в метод <code>deleteProperty</code>.</p> + +<dl> + <dt><code>target</code></dt> + <dd>Целевой объект.</dd> + <dt><code>property</code></dt> + <dd>Имя или {{jsxref("Symbol")}} свойства, которое нужно удалить.</dd> +</dl> + +<p><code>this</code> в момент вызова ссылается на объект handler.</p> + +<h3 id="Возвращаемое_значение">Возвращаемое значение</h3> + +<p>Метод <code>deleteProperty</code> должен возвращать {{jsxref("Boolean")}}. Значение <code>true</code>, если свойство было успешно удалено, в противном случае <code>false</code>.</p> + +<h2 id="Описание">Описание</h2> + +<p>Метод <code><strong>handler.deleteProperty()</strong></code> является "ловушкой" для оператора {{jsxref("Operators/delete", "delete")}}.</p> + +<h3 id="Перехваты">Перехваты</h3> + +<p>Данная "ловушка" может перехватывать следующие операции:</p> + +<ul> + <li>Удаление свойства: <code>delete proxy[foo]</code> and <code>delete proxy.foo</code></li> + <li>{{jsxref("Reflect.deleteProperty()")}}</li> +</ul> + +<h3 id="Инварианты">Инварианты</h3> + +<p>Если следующие инварианты нарушены, то прокси выдаст ошибку {{jsxref("TypeError")}}:</p> + +<ul> + <li>Свойство не может быть удалено, если оно неконфигурируемое собственное свойство целевого объекта.</li> +</ul> + +<h2 id="Примеры">Примеры</h2> + +<p>Следующий код перехватывает действие оператора {{jsxref("Operators/delete", "delete")}}.</p> + +<pre class="brush: js">var p = new Proxy({}, { + deleteProperty: function(target, prop) { + if (prop in target){ + delete target[prop] + console.log('property removed: ' + prop) + return true + } + else { + console.log('property not found: ' + prop) + return false + } + } +}) + +var result + +p.a = 10 +console.log('a' in p) // true + +result = delete p.a // "property removed: a" +console.log(result) // true +console.log('a' in p) // false + +result = delete p.a // "property not found: a" +console.log(result) // false +</pre> + +<h2 id="Спецификации">Спецификации</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-delete-p', '[[Delete]]')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-delete-p', '[[Delete]]')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<div> + + +<p>{{Compat("javascript.builtins.Proxy.handler.deleteProperty")}}</p> +</div> + +<h2 id="Смотри_также">Смотри также</h2> + +<ul> + <li>{{jsxref("Proxy")}}</li> + <li>{{jsxref("Proxy.handler", "handler")}}</li> + <li>{{jsxref("Operators/delete", "delete")}} operator</li> + <li>{{jsxref("Reflect.deleteProperty()")}}</li> +</ul> diff --git a/files/ru/web/javascript/reference/global_objects/proxy/handler/index.html b/files/ru/web/javascript/reference/global_objects/proxy/handler/index.html new file mode 100644 index 0000000000..eef887a246 --- /dev/null +++ b/files/ru/web/javascript/reference/global_objects/proxy/handler/index.html @@ -0,0 +1,134 @@ +--- +title: Proxy handler +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler +tags: + - ECMAScript 2015 + - JavaScript + - NeedsTranslation + - Proxy + - TopicStub + - Прокси + - Русский + - ловушки +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy +--- +<div>{{JSRef}}</div> + +<p>Объект-обработчик прокси - это объект, который содержит ловушки для {{jsxref("Proxy", "proxies", "", 1)}}.</p> + +<h2 id="Методы">Методы</h2> + +<p><span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>Все ловушки ставятся по желанию разработчика.</span></span> <span class="ChMk0b JLqJ4b"><span>Если ловушка не была определена, то, по умолчанию, операция перенаправляется на исходный объект (target).</span></span></span></p> + +<dl> + <dt>{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}</dt> + <dd>Ловушка для {{jsxref("Object.getPrototypeOf")}}.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}</dt> + <dd>Ловушка для {{jsxref("Object.setPrototypeOf")}}.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}</dt> + <dd>Ловушка для {{jsxref("Object.isExtensible")}}.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}</dt> + <dd>Ловушка для {{jsxref("Object.preventExtensions")}}.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}</dt> + <dd>Ловушка для {{jsxref("Object.getOwnPropertyDescriptor")}}.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}</dt> + <dd>Ловушка для {{jsxref("Object.defineProperty")}}.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}</dt> + <dd>Ловушка для оператора {{jsxref("Operators/in", "in")}}.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}</dt> + <dd>Ловушка для получения значений из свойств.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}</dt> + <dd>Ловушка для установки значений в свойства.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}</dt> + <dd>Ловушка для оператора {{jsxref("Operators/delete", "delete")}}.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}</dt> + <dd>Ловушка для {{jsxref("Object.getOwnPropertyNames")}} и {{jsxref("Object.getOwnPropertySymbols")}}.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}</dt> + <dd>Ловушка для вызова функции.</dd> + <dt>{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}</dt> + <dd>Ловушка для оператора {{jsxref("Operators/new", "new")}}.</dd> +</dl> + +<p>Некоторые нестандартные ловушки <a href="/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features#Proxy">устарели и были удалены</a>.</p> + +<h2 id="Спецификации">Спецификации</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Спецификация</th> + <th scope="col">Статус</th> + <th scope="col">Комментарий</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Определении при инициализации.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td>Обработчик <code>enumerate</code> был удален.</td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>49 [1]</td> + <td>{{ CompatGeckoDesktop("18") }}</td> + <td>12</td> + <td>{{CompatOpera(36)}}</td> + <td>{{CompatSafari(10)}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{ CompatGeckoDesktop("18") }}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<p>[1] <a href="https://www.chromestatus.com/features/4811188005240832">Разрешен по умолчанию</a>.</p> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li>{{jsxref("Proxy")}}</li> +</ul> diff --git a/files/ru/web/javascript/reference/global_objects/proxy/handler/set/index.html b/files/ru/web/javascript/reference/global_objects/proxy/handler/set/index.html new file mode 100644 index 0000000000..88b030ecc4 --- /dev/null +++ b/files/ru/web/javascript/reference/global_objects/proxy/handler/set/index.html @@ -0,0 +1,179 @@ +--- +title: handler.set() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/set +tags: + - Прокси + - метод +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/set +--- +<div>{{JSRef}}</div> + +<p><span id="result_box" lang="ru"><span title="The handler.set() method is a trap for setting a property value. +">Метод <strong>handler.set()</strong> является ловушкой для установки </span></span><span lang="ru"><span title="The handler.set() method is a trap for setting a property value. +">значения </span></span><span id="result_box" lang="ru"><span title="The handler.set() method is a trap for setting a property value. +">свойств</span></span><span lang="ru"><span title="The handler.set() method is a trap for setting a property value. +">у</span></span><span lang="ru"><span title="The handler.set() method is a trap for setting a property value. +">.</span></span></p> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="brush: js notranslate">var p = new Proxy(target, { + set: function(target, property, value, receiver) { + } +}); +</pre> + +<h3 id="Параметры">Параметры</h3> + +<p><span id="result_box" lang="ru"><span>Следующие параметры передаются методу </span></span><code>set()</code> <span lang="ru"><span>.</span> </span><code>this</code><span lang="ru"><span> привязан к обработчику</span></span></p> + +<dl> + <dt><code>target</code></dt> + <dd>Исходный обьект, который проксируется.</dd> + <dt><code>property</code></dt> + <dd><span id="result_box" lang="ru"><span>Имя свойства, в которое устанавливается значение </span></span><code>value</code><span lang="ru"><span>.</span></span></dd> + <dt><code>value</code></dt> + <dd><span id="result_box" lang="ru"><span>Значение, устанавливаемое в свойство </span></span><code>property</code><span lang="ru"><span>.</span></span></dd> + <dt><code>receiver</code></dt> + <dd><span id="result_box" lang="ru"><span>Объект, которому первоначально было присвоено задание.</span> <span>Обычно это сам прокси.</span> <span>Но обработчик </span></span><code>set()</code><span lang="ru"><span> также может быть вызван косвенно, через цепочку прототипов или различными другими способами.</span><br> + <span>Например, предположим, что скрипт выполняет </span></span><code><var>obj</var>.name = "jen"</code><span lang="ru"><span>, при этом </span></span><code><var>obj</var></code><span lang="ru"><span> не является прокси и не имеет собственного свойства </span></span><code>.name</code><span lang="ru"><span>, но имеет прокси в цепочке прототипов.</span> Б<span>удет вызван обработчик прокси </span></span><code>set()</code><span lang="ru"><span> , а </span></span><code><var>obj</var></code><span lang="ru"><span> будет передан в качестве получателя.</span></span></dd> + <dd></dd> +</dl> + +<h3 id="Возвращаемые_результаты">Возвращаемые результаты</h3> + +<p>Метод <code>set</code> <span id="result_box" lang="ru"><span>должен возвращать boolean значение</span></span>.</p> + +<ul> + <li>Возвращает <code>true</code>, если <span id="result_box" lang="ru"><span>присвоение выполнено успешно</span></span>.</li> + <li>Если метод <code>set()</code> возвращает <code>false</code>, <span id="result_box" lang="ru"><span>а присваивание произошло в коде строгого режима, то будет выброшена</span></span> {{jsxref("TypeError")}}.</li> +</ul> + +<h2 id="Описание">Описание</h2> + +<p>Метод <code><strong>handler.set</strong></code> <span id="result_box" lang="ru"><span title="The handler.set() method is a trap for setting a property value. +">является ловушкой для установки </span></span><span lang="ru"><span title="The handler.set() method is a trap for setting a property value. +">значения </span></span><span id="result_box" lang="ru"><span title="The handler.set() method is a trap for setting a property value. +">свойств</span></span><span lang="ru"><span title="The handler.set() method is a trap for setting a property value. +">у</span></span>.</p> + +<h3 id="Перехват">Перехват</h3> + +<p>Эта ловушка может перехватывать следующие операции:</p> + +<ul> + <li>Установка значения свойству: <code>proxy[foo] = bar</code> and <code>proxy.foo = bar</code></li> + <li>Установка значения наследованному свойству: <code>Object.create(proxy)[foo] = bar</code></li> + <li>{{jsxref("Reflect.set()")}}</li> +</ul> + +<h3 id="Инварианты">Инварианты</h3> + +<p>Если нарушены следующие инваринаты, то proxy выбросит {{jsxref("TypeError")}}:</p> + +<ul> + <li><span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>Невозможно изменить значение свойства так, чтобы оно отличалось от значения соответствующего свойства целевого объекта, если соответствующее свойство целевого объекта не является доступным для записи и не настраиваемым свойством данных.</span></span></span></li> + <li><span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>Невозможно установить значение свойства, если соответствующее свойство целевого объекта является неконфигурируемым свойством средства доступа, для которого в качестве атрибута [[Set]] указано значение undefined.</span></span></span></li> + <li><span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>В строгом режиме при возврате из обработчика </span></span></span><code>set()</code><span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span> значения </span></span></span><code>false</code><span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>, будет выброшено исключение {{jsxref ("TypeError")}}</span></span></span>.</li> +</ul> + +<h2 id="Примеры">Примеры</h2> + +<p><span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>Следующий код перехватывает установку значения свойству</span></span></span><span lang="ru"><span>.</span></span></p> + +<pre class="brush: js notranslate">var p = new Proxy({}, { + set: function(target, prop, value, receiver) { + target[prop] = value + console.log('property set: ' + prop + ' = ' + value) + return true + } +}) + +console.log('a' in p) // false + +p.a = 10 // "property set: a = 10" +console.log('a' in p) // true +console.log(p.a) // 10 +</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Спецификация</th> + <th scope="col">Статус</th> + <th scope="col">Комментарий</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver', '[[Set]]')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver', '[[Set]]')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<div>{{CompatibilityTable}}</div> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatChrome("61")}}</td> + <td>{{CompatGeckoDesktop("18")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatSafari("10.1")}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatGeckoMobile("18")}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li>{{jsxref("Proxy")}}</li> + <li>{{jsxref("Proxy.handler", "handler")}}</li> + <li>{{jsxref("Reflect.set()")}}</li> +</ul> diff --git a/files/ru/web/javascript/reference/global_objects/proxy/index.html b/files/ru/web/javascript/reference/global_objects/proxy/index.html new file mode 100644 index 0000000000..2d8e5ae557 --- /dev/null +++ b/files/ru/web/javascript/reference/global_objects/proxy/index.html @@ -0,0 +1,482 @@ +--- +title: Прокси +slug: Web/JavaScript/Reference/Global_Objects/Proxy +tags: + - ECMAScript6 + - JavaScript + - NeedsUpdate + - Reference + - Объект + - Прокси +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy +--- +<div><font><font>Объект </font></font><code>Proxy</code><font><font> позволяет создать прокси</font><font> для другого объекта, может перехватывать и переопределить основные операции для данного объекта.</font></font></div> + +<h2 id="Введение">Введение</h2> + +<p>Прокси используются программистами для объявления расширенной семантики JavaScript объектов. Стандартная семантика реализована в движке JavaScript, который обычно написан на низкоуровневом языке программирования, например C++. Прокси позволяют программисту определить поведение объекта при помощи JavaScript. Другими словами они являются <strong>инструментом метапрограммирования</strong>.</p> + +<p><strong>Примечание</strong>: реализация прокси в SpiderMonkey является прототипом, в котором прокси API и семантика не стабильны. Также, реализация в SpiderMonkey может не соответствовать последней версии спецификации. Она может быть изменена в любой момент и предоставляется исключительно как экспериментальная функция. <strong>Не полагайтесь на неё в производственном коде.</strong></p> + +<p>Эта страница описывает новый API (называемый «непосредственным проксированием»), который является частью Firefox 18. Для просмотра старого API (Firefox 17 и ниже) посетите страницу описания <a href="/en-US/docs/JavaScript/Old_Proxy_API" title="/en-US/docs/JavaScript/Old_Proxy_API">старого прокси API</a>.</p> + +<h2 id="Терминология">Терминология</h2> + +<dl> + <dt>механизм полного перехвата (или "intercession API")</dt> + <dd>Технический термин для этой функции.</dd> + <dt>прокси (proxy)</dt> + <dd>Объект, оборачивающий исходный объект.</dd> + <dt>обработчик (handler)</dt> + <dd>Объект-заменитель, содержащий ловушки. О<span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>пределяет, какие операции будут перехвачены, также переопределяет перехваченные операции.</span></span></span></dd> + <dt>ловушки (traps)</dt> + <dd>Методы, которые предоставляют доступ к свойствам. Это аналогично концепции ловушек в операционных системах.</dd> + <dt>цель (target)</dt> + <dd>Исходный объект, который виртуализируется прокси. Он часто используется в качестве источника данных в прокси. Для него проверяются инварианты относительно расширяемости и настраиваемости свойств.</dd> +</dl> + +<h2 id="Прокси">Прокси</h2> + +<p>Прокси - это новые объекты; невозможно выполнить "проксирование" существующего объекта. Пример создания прокси:</p> + +<pre class="brush: js notranslate">var p = new Proxy(target, handler); +</pre> + +<p>Где:</p> + +<ul> + <li><code>target</code> — исходный объект (может быть объектом любого типа, включая массив, функцию и даже другой прокси объект).</li> + <li><code>handler</code> — объект-обработчик, методы (ловушки) которого определяют поведение прокси во время выполнения операции над ним.</li> +</ul> + +<h2 id="Обработчик">Обработчик</h2> + +<p>Все ловушки опциональны. В случае, если ловушка не задана, то стандартным поведением будет перенаправление операции к объекту-цели.</p> + +<table class="standard-table"> + <thead> + <tr> + <th>JavaScript код</th> + <th>Метод обработчика</th> + <th>Описание</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>Object.getOwnPropertyDescriptor(proxy, name)</code></td> + <td><code><strong>getOwnPropertyDescriptor</strong><br> + function(target, name) -> PropertyDescriptor | undefined</code></td> + <td>Должен возвращать верный объект-описание свойства или <code>undefined</code>, чтобы показать, что свойство с именем <code>name</code> существует в эмулируемом объекте.</td> + </tr> + <tr> + <td> + <p><code>Object.getOwnPropertyNames(proxy)</code><br> + <code><code>Object.getOwnPropertySymbols(proxy)</code></code><br> + <code><code><code>Object.keys(proxy)</code></code></code></p> + </td> + <td><code><code><strong>ownKeys</strong></code> function(target) -> [string | symbol]</code></td> + <td>Возвращает массив всех собственных (не унаследованных) имён свойств эмулируемого объекта.</td> + </tr> + <tr> + <td><code>Object.defineProperty(proxy,name,pd)</code></td> + <td><code><strong>defineProperty</strong> function(target, name, propertyDescriptor) -> any</code></td> + <td>Задаёт новое свойство, атрибуты которого определяются предоставленным <code>propertyDescriptor</code>. Возвращаемое значение метода игнорируется.</td> + </tr> + <tr> + <td><code>delete proxy.name</code></td> + <td><code><strong>deleteProperty</strong> function(target, name) -> boolean</code></td> + <td>Удаляет именованное свойство из прокси. Возвращает <code>true</code> в случае успешного удаления свойства <code>name</code>.</td> + </tr> + <tr> + <td><code>Object.preventExtensions(proxy)</code></td> + <td><code><strong>preventExtensions</strong> function(target) -> boolean</code></td> + <td>Делает объект нерасширяемым. Возвращает <code>true</code> при успешном выполнении.</td> + </tr> + <tr> + <td><code>name in proxy</code></td> + <td><code><strong>has</strong> function(target, name) -> boolean</code></td> + <td></td> + </tr> + <tr> + <td> + <p><code>proxy.name</code> (in the context of "getting the value")</p> + + <p><code>receiver.name</code> (if <code>receiver</code> inherits from a proxy and does not override <code>name</code>)</p> + </td> + <td><code><strong>get</strong> function(target, name, receiver) -> any</code></td> + <td><code>receiver</code> — это прокси или объект, унаследованный от прокси.</td> + </tr> + <tr> + <td> + <p><code>proxy.name = val</code> (in the context of "setting the value")</p> + + <p><code>receiver.name = val</code> (if <code>receiver</code> inherits from a proxy and does not override <code>name</code>)</p> + </td> + <td><code><strong>set</strong> function(target, name, val, receiver) -> boolean</code></td> + <td><code style="font-style: normal;">receiver</code> — это прокси или объект, унаследованный от прокси.</td> + </tr> + <tr> + <td> + <p><code>proxy(...args)<br> + proxy.apply(thisValue, args)<br> + proxy.call(thisValue, ...args)</code></p> + </td> + <td><code><strong>apply</strong> function(target, thisValue, args) -> any</code></td> + <td><code>target</code> должен быть функцией.</td> + </tr> + <tr> + <td><code>new proxy(...args)</code></td> + <td><code><strong>construct</strong> function(target, args) -> object</code></td> + <td><code>target</code> должен быть функцией.</td> + </tr> + </tbody> +</table> + +<h2 id="Инварианты">Инварианты</h2> + +<p>Несмотря на то, что прокси предоставляют много возможностей пользователям, некоторые операции не перехватываются для сохранения постоянства языка:</p> + +<ul> + <li>Простой и строгий оператор равенства (<code>==</code>, <code>===</code>) не перехватывается. <code>p1 === p2</code> равны, только если <code>p1</code> и <code>p2</code> ссылаются на один и тот же прокси.</li> + <li>Текущая реализация <code>Object.getPrototypeOf(proxy)</code> всегда возвращает <code>Object.getPrototypeOf(target)</code>, потому что в ES2015 перехватчик getPrototypeOf пока не реализован.</li> + <li><code>typeof proxy</code> всегда возвращает <code>typeof target</code>. В частности, <code>proxy</code> может быть использован как функция только если <code>target </code>является функцией.</li> + <li><code>Array.isArray(proxy)</code> всегда возвращает <code>Array.isArray(target)</code>.</li> + <li><code>Object.prototype.toString.call(proxy)</code> всегда возвращает <code>Object.prototype.toString.call(target)</code>, потому что в ES2015 перехватчик Symbol.toStringTag пока не реализован.</li> +</ul> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Простой_пример">Простой пример</h3> + +<p>Объект, возвращающий значение <code>37</code>, в случае отсутствия свойства с указанным именем:</p> + +<pre class="brush: js notranslate">var handler = { + get: function(target, name){ + return name in target? + target[name] : + 37; + } +}; + +var p = new Proxy({}, handler); +p.a = 1; +p.b = undefined; + +console.log(p.a, p.b); // 1, undefined +console.log('c' in p, p.c); // false, 37 +</pre> + +<h3 id="Перенаправляющий_прокси">Перенаправляющий прокси</h3> + +<p>В данном примере мы используем JavaScript объект, к которому наш прокси направляет все запросы:</p> + +<pre class="brush: js notranslate">var target = {}; +var p = new Proxy(target, {}); + +p.a = 37; // операция перенаправлена прокси + +console.log(target.a); // 37. Операция была успешно перенаправлена +</pre> + +<h3 id="Проверка">Проверка</h3> + +<p>При помощи <code>Proxy</code> вы можете легко проверять передаваемые объекту значения:</p> + +<pre class="brush: js notranslate">let validator = { + set: function(obj, prop, value) { + if (prop === 'age') { + if (!Number.isInteger(value)) { + throw new TypeError('The age is not an integer'); + } + if (value > 200) { + throw new RangeError('The age seems invalid'); + } + } + + // Стандартное сохранение значения + obj[prop] = value; + } +}; + +let person = new Proxy({}, validator); + +person.age = 100; +console.log(person.age); // 100 +person.age = 'young'; // Вызовет исключение +person.age = 300; // Вызовет исключение +</pre> + +<h3 id="Дополнение_конструктора">Дополнение конструктора</h3> + +<p>Функция прокси может легко дополнить конструктор новым:</p> + +<pre class="brush: js notranslate">function extend(sup, base) { + var descriptor = Object.getOwnPropertyDescriptor( + base.prototype, 'constructor', + ); + + const prototype = {...base.prototype} + + base.prototype = Object.create(sup.prototype); + base.prototype = Object.assign(base.prototype, prototype); + + var handler = { + construct: function(target, args) { + var obj = Object.create(base.prototype); + this.apply(target, obj, args); + return obj; + }, + apply: function(target, that, args) { + sup.apply(that, args); + base.apply(that, args); + }, + }; + var proxy = new Proxy(base, handler); + descriptor.value = proxy; + Object.defineProperty(base.prototype, 'constructor', descriptor); + return proxy; +} + +var Person = function(name) { + this.name = name; +}; + +var Boy = extend(Person, function(name, age) { + this.age = age; +}); + +Boy.prototype.sex = 'M'; + +var Peter = new Boy('Peter', 13); +console.log(Peter.sex); // "M" +console.log(Peter.name); // "Peter" +console.log(Peter.age); // 13 +</pre> + +<h3 id="Манипуляция_DOM_элементами">Манипуляция<span style="font-size: 1.71428571428571rem;"> DOM </span><span style="font-size: 1.71428571428571rem;">элементами</span></h3> + +<p>Иногда возникает необходимость переключить атрибут или имя класса у двух разных элементов:</p> + +<pre class="brush: js notranslate">let view = new Proxy({ + selected: null +}, +{ + set: function(obj, prop, newval) { + let oldval = obj[prop]; + + if (prop === 'selected') { + if (oldval) { + oldval.setAttribute('aria-selected', 'false'); + } + if (newval) { + newval.setAttribute('aria-selected', 'true'); + } + } + + // Стандартное сохранение значения + obj[prop] = newval; + } +}); + +let i1 = view.selected = document.getElementById('item-1'); +console.log(i1.getAttribute('aria-selected')); // 'true' + +let i2 = view.selected = document.getElementById('item-2'); +console.log(i1.getAttribute('aria-selected')); // 'false' +console.log(i2.getAttribute('aria-selected')); // 'true' +</pre> + +<h3 id="Изменение_значений_и_дополнительные_свойства">Изменение значений и дополнительные свойства</h3> + +<p>Прокси объект <code>products</code> проверяет передаваемые значения и преобразует их в массив в случае необходимости. Объект также поддерживает дополнительное свойство <code>latestBrowser</code> на чтение и запись.</p> + +<pre class="brush: js notranslate">let products = new Proxy({ + browsers: ['Internet Explorer', 'Netscape'] +}, +{ + get: function(obj, prop) { + // Дополнительное свойство + if (prop === 'latestBrowser') { + return obj.browsers[obj.browsers.length - 1]; + } + + // Стандартный возврат значения + return obj[prop]; + }, + set: function(obj, prop, value) { + // Дополнительное свойство + if (prop === 'latestBrowser') { + obj.browsers.push(value); + return; + } + + // Преобразование значения, если оно не массив + if (typeof value === 'string') { + value = [value]; + } + + // Стандартное сохранение значения + obj[prop] = value; + } +}); + +console.log(products.browsers); // ['Internet Explorer', 'Netscape'] +products.browsers = 'Firefox'; // передаётся как строка (по ошибке) +console.log(products.browsers); // ['Firefox'] <- проблем нет, значение - массив + +products.latestBrowser = 'Chrome'; +console.log(products.browsers); // ['Firefox', 'Chrome'] +console.log(products.latestBrowser); // 'Chrome' +</pre> + +<h3 id="Поиск_элемента_массива_по_его_свойству">Поиск элемента массива по его свойству</h3> + +<p>Данный прокси расширяет массив дополнительными возможностями. Как вы видите, вы можете гибко "задавать" свойства без использования <a href="/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperties"><code>Object.defineProperties</code></a>. Данный пример также может быть использован для поиска строки таблицы по её ячейке. В этом случае целью будет <a href="/en-US/docs/DOM/table.rows"><code>table.rows</code></a>.</p> + +<pre class="brush: js notranslate">let products = new Proxy([ + { name: 'Firefox', type: 'browser' }, + { name: 'SeaMonkey', type: 'browser' }, + { name: 'Thunderbird', type: 'mailer' } +], +{ + get: function(obj, prop) { + // Стандартное возвращение значения; prop обычно является числом + if (prop in obj) { + return obj[prop]; + } + + // Получение количества продуктов; псевдоним products.length + if (prop === 'number') { + return obj.length; + } + + let result, types = {}; + + for (let product of obj) { + if (product.name === prop) { + result = product; + } + if (types[product.type]) { + types[product.type].push(product); + } else { + types[product.type] = [product]; + } + } + + // Получение продукта по имени + if (result) { + return result; + } + + // Получение продуктов по типу + if (prop in types) { + return types[prop]; + } + + // Получение типов продуктов + if (prop === 'types') { + return Object.keys(types); + } + + return undefined; + } +}); + +console.log(products[0]); // { name: 'Firefox', type: 'browser' } +console.log(products['Firefox']); // { name: 'Firefox', type: 'browser' } +console.log(products['Chrome']); // undefined +console.log(products.browser); // [{ name: 'Firefox', type: 'browser' }, { name: 'SeaMonkey', type: 'browser' }] +console.log(products.types); // ['browser', 'mailer'] +console.log(products.number); // 3 +</pre> + +<h3 id="Пример_использования_всех_перехватчиков">Пример использования всех перехватчиков</h3> + +<p>В данном примере, использующем все виды перехватчиков, мы попытаемся проксировать <em>не нативный</em> объект, который частично приспособлен для этого - <code>docCookies,</code> созданном в разделе <a href="https://developer.mozilla.org/en-US/docs/DOM/document.cookie#A_little_framework.3A_a_complete_cookies_reader.2Fwriter_with_full_unicode_support" title="https://developer.mozilla.org/en-US/docs/DOM/document.cookie#A_little_framework.3A_a_complete_cookies_reader.2Fwriter_with_full_unicode_support">"little framework" и опубликованном на странице <code>document.cookie</code></a>.</p> + +<pre class="brush: js notranslate">/* + var docCookies = ... получить объект "docCookies" можно здесь: + https://developer.mozilla.org/en-US/docs/DOM/document.cookie#A_little_framework.3A_a_complete_cookies_reader.2Fwriter_with_full_unicode_support +*/ + +var docCookies = new Proxy(docCookies, { + "get": function (oTarget, sKey) { + return oTarget[sKey] || oTarget.getItem(sKey) || undefined; + }, + "set": function (oTarget, sKey, vValue) { + if (sKey in oTarget) { return false; } + return oTarget.setItem(sKey, vValue); + }, + "deleteProperty": function (oTarget, sKey) { + if (sKey in oTarget) { return false; } + return oTarget.removeItem(sKey); + }, + "enumerate": function (oTarget, sKey) { + return oTarget.keys(); + }, + "iterate": function (oTarget, sKey) { + return oTarget.keys(); + }, + "ownKeys": function (oTarget, sKey) { + return oTarget.keys(); + }, + "has": function (oTarget, sKey) { + return sKey in oTarget || oTarget.hasItem(sKey); + }, + "hasOwn": function (oTarget, sKey) { + return oTarget.hasItem(sKey); + }, + "defineProperty": function (oTarget, sKey, oDesc) { + if (oDesc && "value" in oDesc) { oTarget.setItem(sKey, oDesc.value); } + return oTarget; + }, + "getPropertyNames": function (oTarget) { + return Object.getPropertyNames(oTarget).concat(oTarget.keys()); + }, + "getOwnPropertyNames": function (oTarget) { + return Object.getOwnPropertyNames(oTarget).concat(oTarget.keys()); + }, + "getPropertyDescriptor": function (oTarget, sKey) { + var vValue = oTarget[sKey] || oTarget.getItem(sKey) + return vValue ? { + "value": vValue, + "writable": true, + "enumerable": true, + "configurable": false + } : undefined; + }, + "getOwnPropertyDescriptor": function (oTarget, sKey) { + var vValue = oTarget.getItem(sKey); + return vValue ? { + "value": vValue, + "writable": true, + "enumerable": true, + "configurable": false + } : undefined; + }, + "fix": function (oTarget) { + return "not implemented yet!"; + }, +}); + +/* Проверка cookies */ + +alert(docCookies.my_cookie1 = "First value"); +alert(docCookies.getItem("my_cookie1")); + +docCookies.setItem("my_cookie1", "Changed value"); +alert(docCookies.my_cookie1);</pre> + +<h2 id="See_also" name="See_also" style="line-height: 30px; font-size: 2.14285714285714rem;">Смотрите также</h2> + +<ul> + <li><a class="external" href="http://jsconf.eu/2010/speaker/be_proxy_objects.html">"Proxies are awesome" презентация Brendan Eich на JSConf</a> (<a class="external" href="http://www.slideshare.net/BrendanEich/metaprog-5303821">слайды</a>)</li> + <li><a class="external" href="http://wiki.ecmascript.org/doku.php?id=harmony:proxies">Страница предложения ECMAScript Harmony Proxy</a> и <a class="external" href="http://wiki.ecmascript.org/doku.php?id=harmony:proxies_semantics">страница ECMAScript Harmony proxy semantics</a></li> + <li><a class="external" href="http://soft.vub.ac.be/~tvcutsem/proxies/">Руководство по прокси</a></li> + <li><a href="/en-US/docs/JavaScript/Old_Proxy_API" title="/en-US/docs/JavaScript/Old_Proxy_API">Старая страница Proxy API</a></li> + <li><a href="/en-US/docs/JavaScript/Reference/Global_Objects/Object/watch"><code>Object.watch</code></a> - не стандартная возможность, поддерживается только в движке Gecko.</li> +</ul> + +<h2 id="Лицензионные_примечания">Лицензионные примечания</h2> + +<p>Некоторое содержимое (текст, примеры) данной страницы было скопировано или адаптировано со страниц <a class="external" href="http://wiki.ecmascript.org/doku.php">вики ECMAScript</a>, имеющей лицензию <a class="external" href="http://creativecommons.org/licenses/by-nc-sa/2.0/">CC 2.0 BY-NC-SA</a></p> diff --git a/files/ru/web/javascript/reference/global_objects/proxy/proxy/apply/index.html b/files/ru/web/javascript/reference/global_objects/proxy/proxy/apply/index.html new file mode 100644 index 0000000000..81ea9d0605 --- /dev/null +++ b/files/ru/web/javascript/reference/global_objects/proxy/proxy/apply/index.html @@ -0,0 +1,111 @@ +--- +title: handler.apply() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply +tags: + - Прокси + - вызов функции + - ловушка +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply +--- +<div>{{JSRef}}</div> + +<p>Метод <strong><code>handler.apply()</code></strong> является ловушкой для вызова функции.</p> + +<div>{{EmbedInteractiveExample("pages/js/proxyhandler-apply.html", "taller")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox notranslate">const <var>p</var> = new Proxy(<var>target</var>, { + apply: function(<var>target</var>, <var>thisArg</var>, <var>argumentsList</var>) { + } +}); +</pre> + +<h3 id="Параметры">Параметры</h3> + +<p>Методу <code>apply()</code> передаются следующие параметры. <code>this</code> связан с объектом-обработчиком.</p> + +<dl> + <dt><code><var>target</var></code></dt> + <dd>Исходный объект.</dd> + <dt><code><var>thisArg</var></code></dt> + <dd>Аргумент <code>this</code> для вызова.</dd> + <dt><code><var>argumentsList</var></code></dt> + <dd>Список аргументов для вызова.</dd> +</dl> + +<h3 id="Возврат_значения">Возврат значения</h3> + +<p>Метод <code>apply()</code> может возвращать значение.</p> + +<h2 id="Описание">Описание</h2> + +<p>Метод <code><strong>handler.apply()</strong></code> является ловушкой для вызова функции.</p> + +<h3 id="Перехват">Перехват</h3> + +<p>Ловушка может перехватывать следующие операции:</p> + +<ul> + <li><code><var>proxy</var>(...<var>args</var>)</code></li> + <li>{{jsxref("Function.prototype.apply()")}} и {{jsxref("Function.prototype.call()")}}</li> + <li>{{jsxref("Reflect.apply()")}}</li> +</ul> + +<h3 id="Инварианты">Инварианты</h3> + +<p>Если следующие инваринаты нарушены, то прокси выбросит {{jsxref("TypeError")}}.</p> + +<p>Исходный объект <code><var>target</var></code> должен быть самовызываемым. То есть, это должна быть функция-объект.</p> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Ловушка_для_вызова_функции">Ловушка для вызова функции</h3> + +<p>Следующий код ловит вызов функции.</p> + +<pre class="brush: js notranslate">const p = new Proxy(function() {}, { + apply: function(target, thisArg, argumentsList) { + console.log('called: ' + argumentsList.join(', ')); + return argumentsList[0] + argumentsList[1] + argumentsList[2]; + } +}); + +console.log(p(1, 2, 3)); // "called: 1, 2, 3" + // 6 +</pre> + +<h2 id="Спецификации">Спецификации</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Спецификация</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<div> + + +<p>{{Compat("javascript.builtins.Proxy.handler.apply")}}</p> +</div> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li>{{jsxref("Proxy")}}</li> + <li>{{jsxref("Proxy.handler", "handler")}}</li> + <li>{{jsxref("Function.prototype.apply()")}}</li> + <li>{{jsxref("Function.prototype.call()")}}</li> + <li>{{jsxref("Reflect.apply()")}}</li> +</ul> diff --git a/files/ru/web/javascript/reference/global_objects/proxy/proxy/get/index.html b/files/ru/web/javascript/reference/global_objects/proxy/proxy/get/index.html new file mode 100644 index 0000000000..2d6be05af5 --- /dev/null +++ b/files/ru/web/javascript/reference/global_objects/proxy/proxy/get/index.html @@ -0,0 +1,127 @@ +--- +title: handler.get() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get +--- +<div>{{JSRef}}</div> + +<p>Метод <strong><code>handler.get()</code></strong> является ловушкой для получения значения свойства.</p> + +<div>{{EmbedInteractiveExample("pages/js/proxyhandler-get.html", "taller")}}</div> + +<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div> + +<h2 id="Syntax">Syntax</h2> + +<pre class="syntaxbox notranslate">const <var>p</var> = new Proxy(<var>target</var>, { + get: function(<var>target</var>, <var>property</var>, <var>receiver</var>) { + } +}); +</pre> + +<h3 id="Параметры">Параметры</h3> + +<p>Следующие параметры передаются методу <code>get()</code>. <code>this</code> привязан к обработчику.</p> + +<dl> + <dt><code><var>target</var></code></dt> + <dd>Исходный объект, который проксируется.</dd> + <dt><code><var>property</var></code></dt> + <dd>Наименование или {{jsxref("Symbol")}} получаемого свойства. </dd> + <dt><code><var>receiver</var></code></dt> + <dd><span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>Прокси или объект, наследуемый от прокси.</span></span></span>.</dd> +</dl> + +<h3 id="Возвращаемое_значение"><span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>Возвращаемое значение</span></span></span></h3> + +<p>Метод <code>get()</code> может возвращать значение.</p> + +<h2 id="Описание">Описание</h2> + +<p>Метод <code><strong>handler.get()</strong></code> является ловушкой для получения значения свойства.</p> + +<h3 id="Перехват">Перехват</h3> + +<p>Эта ловушка может перехватывать следующие операции:</p> + +<ul> + <li>Доступ к свойству: <code><var>proxy</var>[<var>foo</var>]</code>and <code><var>proxy</var>.<var>bar</var></code></li> + <li>Доступ к наследованному свойству: <code>Object.create(<var>proxy</var>)[<var>foo</var>]</code></li> + <li>{{jsxref("Reflect.get()")}}</li> +</ul> + +<h3 id="Инварианты">Инварианты</h3> + +<p>Если следующие инваринаты нарушены, то прокси выбросит {{jsxref("TypeError")}}:</p> + +<ul> + <li><span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>Значение, сообщаемое для свойства, должно быть таким же, как значение соответствующего свойства целевого объекта, если свойство целевого объекта является неперезаписываемым, не настраиваемым свойством собственных данных.</span></span></span></li> + <li><span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>Значение, сообщаемое для свойства, должно быть </span></span></span>undefined, <span class="VIiyi" lang="ru"><span class="ChMk0b JLqJ4b"><span>если соответствующее свойство целевого объекта не является настраиваемым собственным свойством доступа, которое</span></span></span> <code>undefined</code> как и его атрибут <code>[[Get]]</code> attribute.</li> +</ul> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Ловушка_для_получения_значения_свойства">Ловушка для получения значения свойства</h3> + +<p>Следующий код перехватывает получение значения свойства.</p> + +<pre class="brush: js notranslate">const p = new Proxy({}, { + get: function(target, property, receiver) { + console.log('called: ' + property); + return 10; + } +}); + +console.log(p.a); // "called: a" + // 10 +</pre> + +<p>Следующий код нарушает инвариант.</p> + +<pre class="brush: js notranslate">const obj = {}; +Object.defineProperty(obj, 'a', { + configurable: false, + enumerable: false, + value: 10, + writable: false +}); + +const p = new Proxy(obj, { + get: function(target, property) { + return 20; + } +}); + +p.a; // TypeError is thrown +</pre> + +<h2 id="Спецификации">Спецификации</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Спецификация</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver', '[[Get]]')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<div> + + +<p>{{Compat("javascript.builtins.Proxy.handler.get")}}</p> +</div> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li>{{jsxref("Proxy")}}</li> + <li>{{jsxref("Proxy.handler", "handler")}}</li> + <li>{{jsxref("Reflect.get()")}}</li> +</ul> diff --git a/files/ru/web/javascript/reference/global_objects/proxy/proxy/index.html b/files/ru/web/javascript/reference/global_objects/proxy/proxy/index.html new file mode 100644 index 0000000000..1bf6b70b43 --- /dev/null +++ b/files/ru/web/javascript/reference/global_objects/proxy/proxy/index.html @@ -0,0 +1,125 @@ +--- +title: Proxy() constructor +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy +tags: + - Constructor + - JavaScript + - NeedsTranslation + - Proxy + - Reference + - TopicStub +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy +--- +<div>{{JSRef}}</div> + +<p>The <code><strong>Proxy()</strong></code> constructor is used to create {{jsxref("Proxy")}} objects.</p> + +<h2 id="Syntax">Syntax</h2> + +<pre class="syntaxbox notranslate">new Proxy(<var>target</var>, <var>handler</var>)</pre> + +<h3 id="Parameters">Parameters</h3> + +<dl> + <dt><code><var>target</var></code></dt> + <dd>A target object to wrap with <code>Proxy</code>. It can be any sort of object, including a native array, a function, or even another proxy.</dd> + <dt><code><var>handler</var></code></dt> + <dd>An object whose properties are functions that define the behavior of the proxy when an operation is performed on it.</dd> +</dl> + +<h2 id="Description">Description</h2> + +<p>Use the <code>Proxy()</code> constructor to create a new <code>Proxy</code> object. This constructor takes two mandatory arguments:</p> + +<ul> + <li><code>target</code> is the object for which you want to create the proxy</li> + <li><code>handler</code> is the object that defines the custom behavior of the proxy.</li> +</ul> + +<p>An empty handler will create a proxy that behaves, in almost all respects, exactly like the target. By defining any of a set group of functions on the <code>handler</code> object, you can customise specific aspects of the proxy's behavior. For example, by defining <code>get()</code> you can provide a customised version of the target's <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors">property accessor</a>.</p> + +<h3 id="Handler_functions">Handler functions</h3> + +<p>This section lists all the handler functions you can define. Handler functions are sometimes called <em>traps</em>, because they trap calls to the underlying target object.</p> + +<dl> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/apply", "handler.apply()")}}</dt> + <dd>A trap for a function call.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/construct", "handler.construct()")}}</dt> + <dd>A trap for the {{JSxRef("Operators/new", "new")}} operator.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/defineProperty", "handler.defineProperty()")}}</dt> + <dd>A trap for {{JSxRef("Object.defineProperty")}}.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/deleteProperty", "handler.deleteProperty()")}}</dt> + <dd>A trap for the {{JSxRef("Operators/delete", "delete")}} operator.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/get", "handler.get()")}}</dt> + <dd>A trap for getting property values.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}</dt> + <dd>A trap for {{JSxRef("Object.getOwnPropertyDescriptor")}}.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/getPrototypeOf", "handler.getPrototypeOf()")}}</dt> + <dd>A trap for {{JSxRef("Object.getPrototypeOf")}}.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/has", "handler.has()")}}</dt> + <dd>A trap for the {{JSxRef("Operators/in", "in")}} operator.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/isExtensible", "handler.isExtensible()")}}</dt> + <dd>A trap for {{JSxRef("Object.isExtensible")}}.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/ownKeys", "handler.ownKeys()")}}</dt> + <dd>A trap for {{JSxRef("Object.getOwnPropertyNames")}} and {{JSxRef("Object.getOwnPropertySymbols")}}.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/preventExtensions", "handler.preventExtensions()")}}</dt> + <dd>A trap for {{JSxRef("Object.preventExtensions")}}.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/set", "handler.set()")}}</dt> + <dd>A trap for setting property values.</dd> + <dt>{{JSxRef("Global_Objects/Proxy/Proxy/setPrototypeOf", "handler.setPrototypeOf()")}}</dt> + <dd>A trap for {{JSxRef("Object.setPrototypeOf")}}.</dd> +</dl> + +<h2 id="Examples">Examples</h2> + +<h3 id="Selectively_proxy_property_accessors">Selectively proxy property accessors</h3> + +<p>In this example the target has two properties, <code>notProxied</code> and <code>proxied</code>. We define a handler that returns a different value for <code>proxied</code>, and lets any other accesses through to the target.</p> + +<pre class="brush: js notranslate">const target = { + notProxied: "original value", + proxied: "original value" +}; + +const handler = { + get: function(target, prop, receiver) { + if (prop === "proxied") { + return "replaced value"; + } + return Reflect.get(...arguments); + } +}; + +const proxy = new Proxy(target, handler); + +console.log(proxy.notProxied); // "original value" +console.log(proxy.proxied); // "replaced value"</pre> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('ESDraft', '#sec-proxy-constructor', 'Proxy constructor')}}</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + + + +<p>{{Compat("javascript.builtins.Proxy.Proxy")}}</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Meta_programming"><code>Proxy</code> and <code>Reflect</code> in the JavaScript Guide</a></li> + <li>{{jsxref("Global_Objects/Reflect", "Reflect")}}</li> +</ul> diff --git a/files/ru/web/javascript/reference/global_objects/proxy/revocable/index.html b/files/ru/web/javascript/reference/global_objects/proxy/revocable/index.html new file mode 100644 index 0000000000..fbc4009f60 --- /dev/null +++ b/files/ru/web/javascript/reference/global_objects/proxy/revocable/index.html @@ -0,0 +1,91 @@ +--- +title: Proxy.revocable() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/revocable +tags: + - ECMAScript 2015 + - JavaScript + - Proxy + - метод +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/revocable +--- +<div>{{JSRef}}</div> + +<p>Метод <code><strong>Proxy.revocable()</strong></code> используется, чтобы создать отменяемый {{jsxref("Proxy")}} объект.</p> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox">Proxy.revocable(target, handler); +</pre> + +<h3 id="Параметры">Параметры</h3> + +<div>{{ Page("/docs/Web/JavaScript/Reference/Global_Objects/Proxy", "Parameters") }}</div> + +<h3 id="Возвращаемое_значение">Возвращаемое значение</h3> + +<p>Создаётся и возвращается отменяемый <code>Proxy</code> объект.</p> + +<h2 id="Описание">Описание</h2> + +<p>Отменяемый <code>Proxy</code> - объект со следующими двумя свойствами <code>{proxy: proxy, revoke: revoke}</code>.</p> + +<dl> + <dt><code>proxy</code></dt> + <dd>Объект <code>Proxy</code>, созданный с помощью вызова <code>new Proxy(target, handler)</code>.</dd> + <dt><code>revoke</code></dt> + <dd>Функция, не принимающая аргументов, которая сделает недействительным (выключит) <code>proxy</code>.</dd> +</dl> + +<p>Если вызовется функция <code>revoke()</code>, <code>proxy</code> становится неиспользуемым: Любой <code>proxy</code>-перехватчик событий объекта будет вызывать исключение {{jsxref("TypeError")}}. Как только <code>proxy</code> отменена, она останется отменённой и дальше, и может быть собрана сборщиком мусора. Повторный вызов <code>revoke()</code> не будет иметь никакого эффекта.</p> + +<h2 id="Примеры">Примеры</h2> + +<pre class="brush: js">var revocable = Proxy.revocable({}, { + get: function(target, name) { + return "[[" + name + "]]"; + } +}); +var proxy = revocable.proxy; +console.log(proxy.foo); // "[[foo]]" + +revocable.revoke(); + +console.log(proxy.foo); // Вызвано исключение TypeError +proxy.foo = 1 // TypeError снова +delete proxy.foo; // Всё ещё TypeError +typeof proxy // "object", typeof не вызывает никаких proxy-перехватчиков событий +</pre> + +<h2 id="Спецификации">Спецификации</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-proxy.revocable', 'Proxy Revocation Functions')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Изначальное определение.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-proxy.revocable', 'Proxy Revocation Functions')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_браузерами">Совместимость браузерами</h2> + +<div class="hidden">Таблица совместимости с браузерами на этой странице сгенерирована из структурированных данных. Если вы хотите внести свой вклад, добавить данные, пожалуйста посетите <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> и отправьте нам pull request.</div> + +<p>{{Compat("javascript.builtins.Proxy.revocable")}}</p> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li>{{jsxref("Proxy")}}</li> +</ul> |
