From 074785cea106179cb3305637055ab0a009ca74f2 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:42:52 -0500 Subject: initial commit --- .../proxy/handler/deleteproperty/index.html | 131 ++++++ .../global_objects/proxy/handler/index.html | 134 ++++++ .../global_objects/proxy/handler/set/index.html | 179 ++++++++ .../reference/global_objects/proxy/index.html | 482 +++++++++++++++++++++ .../global_objects/proxy/proxy/apply/index.html | 111 +++++ .../global_objects/proxy/proxy/get/index.html | 127 ++++++ .../global_objects/proxy/proxy/index.html | 125 ++++++ .../global_objects/proxy/revocable/index.html | 91 ++++ 8 files changed, 1380 insertions(+) create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/handler/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/handler/set/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/proxy/apply/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/proxy/get/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/proxy/index.html create mode 100644 files/ru/web/javascript/reference/global_objects/proxy/revocable/index.html (limited to 'files/ru/web/javascript/reference/global_objects/proxy') 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 +--- +
{{JSRef}}
+ +

Метод handler.deleteProperty() является "ловушкой" (функция-перехватчик) для оператора {{jsxref("Operators/delete", "delete")}}.

+ +
{{EmbedInteractiveExample("pages/js/proxyhandler-deleteproperty.html", "taller")}}
+ + + +

Синтаксис

+ +
var p = new Proxy(target, {
+  deleteProperty: function(target, property) {
+  }
+});
+
+ +

Параметры

+ +

Следующие параметры передаются в метод deleteProperty.

+ +
+
target
+
Целевой объект.
+
property
+
Имя или {{jsxref("Symbol")}} свойства, которое нужно удалить.
+
+ +

this в момент вызова ссылается на объект handler.

+ +

Возвращаемое значение

+ +

Метод deleteProperty должен возвращать {{jsxref("Boolean")}}. Значение true, если свойство было успешно удалено, в противном случае false.

+ +

Описание

+ +

Метод handler.deleteProperty() является "ловушкой" для оператора {{jsxref("Operators/delete", "delete")}}.

+ +

Перехваты

+ +

Данная "ловушка" может перехватывать следующие операции:

+ + + +

Инварианты

+ +

Если следующие инварианты нарушены, то прокси выдаст ошибку {{jsxref("TypeError")}}:

+ + + +

Примеры

+ +

Следующий код перехватывает действие оператора {{jsxref("Operators/delete", "delete")}}.

+ +
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
+
+ +

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

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-delete-p', '[[Delete]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-delete-p', '[[Delete]]')}}{{Spec2('ESDraft')}} 
+ +

Совместимость с браузерами

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.deleteProperty")}}

+
+ +

Смотри также

+ + 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 +--- +
{{JSRef}}
+ +

Объект-обработчик прокси - это объект, который содержит ловушки для {{jsxref("Proxy", "proxies", "", 1)}}.

+ +

Методы

+ +

Все ловушки ставятся по желанию разработчика. Если ловушка не была определена, то, по умолчанию, операция перенаправляется на исходный объект (target).

+ +
+
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}
+
Ловушка для {{jsxref("Object.getPrototypeOf")}}.
+
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}
+
Ловушка для {{jsxref("Object.setPrototypeOf")}}.
+
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}
+
Ловушка для {{jsxref("Object.isExtensible")}}.
+
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}
+
Ловушка для {{jsxref("Object.preventExtensions")}}.
+
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
+
Ловушка для {{jsxref("Object.getOwnPropertyDescriptor")}}.
+
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}
+
Ловушка для {{jsxref("Object.defineProperty")}}.
+
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}
+
Ловушка для оператора {{jsxref("Operators/in", "in")}}.
+
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}
+
Ловушка для получения значений из свойств.
+
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}
+
Ловушка для установки значений в свойства.
+
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}
+
Ловушка для оператора {{jsxref("Operators/delete", "delete")}}.
+
{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}
+
Ловушка для {{jsxref("Object.getOwnPropertyNames")}} и {{jsxref("Object.getOwnPropertySymbols")}}.
+
{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}
+
Ловушка для вызова функции.
+
{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}
+
Ловушка для оператора {{jsxref("Operators/new", "new")}}.
+
+ +

Некоторые нестандартные ловушки устарели и были удалены.

+ +

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

+ + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ES2015')}}Определении при инициализации.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ESDraft')}}Обработчик enumerate был удален.
+ +

Совместимость с браузерами

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support49 [1]{{ CompatGeckoDesktop("18") }}12{{CompatOpera(36)}}{{CompatSafari(10)}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{ CompatGeckoDesktop("18") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] Разрешен по умолчанию.

+ +

Смотрите также

+ + 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 +--- +
{{JSRef}}
+ +

Метод handler.set() является ловушкой для установки значения свойству.

+ +

Синтаксис

+ +
var p = new Proxy(target, {
+  set: function(target, property, value, receiver) {
+  }
+});
+
+ +

Параметры

+ +

Следующие параметры передаются методу set() . this привязан к обработчику

+ +
+
target
+
Исходный обьект, который проксируется.
+
property
+
Имя свойства, в которое устанавливается значение value.
+
value
+
Значение, устанавливаемое в свойство property.
+
receiver
+
Объект, которому первоначально было присвоено задание. Обычно это сам прокси. Но обработчик set() также может быть вызван косвенно, через цепочку прототипов или различными другими способами.
+      Например, предположим, что скрипт выполняет
obj.name = "jen", при этом obj не является прокси и не имеет собственного свойства .name, но имеет прокси в цепочке прототипов. Будет вызван обработчик прокси set() , а obj будет передан в качестве получателя.
+
+
+ +

Возвращаемые результаты

+ +

Метод set должен возвращать boolean значение.

+ + + +

Описание

+ +

Метод handler.set является ловушкой для установки значения свойству.

+ +

Перехват

+ +

Эта ловушка может перехватывать следующие операции:

+ + + +

Инварианты

+ +

Если нарушены следующие инваринаты, то proxy выбросит {{jsxref("TypeError")}}:

+ + + +

Примеры

+ +

Следующий код перехватывает установку значения свойству.

+ +
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
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
СпецификацияСтатусКомментарий
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver', '[[Set]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver', '[[Set]]')}}{{Spec2('ESDraft')}}
+ +

Совместимость с браузерами

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("61")}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatSafari("10.1")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

Смотрите также

+ + 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 +--- +
Объект Proxy позволяет создать прокси для другого объекта, может перехватывать и переопределить основные операции для данного объекта.
+ +

Введение

+ +

Прокси используются программистами для объявления расширенной семантики JavaScript объектов. Стандартная семантика реализована в движке JavaScript, который обычно написан на низкоуровневом языке программирования, например C++. Прокси позволяют программисту определить поведение объекта при помощи JavaScript. Другими словами они являются инструментом метапрограммирования.

+ +

Примечание: реализация прокси в SpiderMonkey является прототипом, в котором прокси API и семантика не стабильны. Также, реализация в SpiderMonkey может не соответствовать последней версии спецификации. Она может быть изменена в любой момент и предоставляется исключительно как экспериментальная функция. Не полагайтесь на неё в производственном коде.

+ +

Эта страница описывает новый API (называемый «непосредственным проксированием»), который является частью Firefox 18. Для просмотра старого API (Firefox 17 и ниже) посетите страницу описания старого прокси API.

+ +

Терминология

+ +
+
механизм полного перехвата (или "intercession API")
+
Технический термин для этой функции.
+
прокси (proxy)
+
Объект, оборачивающий исходный объект.
+
обработчик (handler)
+
Объект-заменитель, содержащий ловушки. Определяет, какие операции будут перехвачены, также переопределяет перехваченные операции.
+
ловушки (traps)
+
Методы, которые предоставляют доступ к свойствам. Это аналогично концепции ловушек в операционных системах.
+
цель (target)
+
Исходный объект, который виртуализируется прокси. Он часто используется в качестве источника данных в прокси. Для него проверяются инварианты относительно расширяемости и настраиваемости свойств.
+
+ +

Прокси

+ +

Прокси - это новые объекты; невозможно выполнить "проксирование" существующего объекта. Пример создания прокси:

+ +
var p = new Proxy(target, handler);
+
+ +

Где:

+ + + +

Обработчик

+ +

Все ловушки опциональны. В случае, если ловушка не задана, то стандартным поведением будет перенаправление операции к объекту-цели.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
JavaScript кодМетод обработчикаОписание
Object.getOwnPropertyDescriptor(proxy, name)getOwnPropertyDescriptor
+ function(target, name) -> PropertyDescriptor | undefined
Должен возвращать верный объект-описание свойства или undefined, чтобы показать, что свойство с именем name существует в эмулируемом объекте.
+

Object.getOwnPropertyNames(proxy)
+ Object.getOwnPropertySymbols(proxy)
+ Object.keys(proxy)

+
ownKeys function(target) -> [string | symbol]Возвращает массив всех собственных (не унаследованных) имён свойств эмулируемого объекта.
Object.defineProperty(proxy,name,pd)defineProperty function(target, name, propertyDescriptor) -> anyЗадаёт новое свойство, атрибуты которого определяются предоставленным propertyDescriptor. Возвращаемое значение метода игнорируется.
delete proxy.namedeleteProperty function(target, name) -> booleanУдаляет именованное свойство из прокси. Возвращает true в случае успешного удаления свойства name.
Object.preventExtensions(proxy)preventExtensions function(target) -> booleanДелает объект нерасширяемым. Возвращает true при успешном выполнении.
name in proxyhas function(target, name) -> boolean
+

proxy.name (in the context of "getting the value")

+ +

receiver.name (if receiver inherits from a proxy and does not override name)

+
get function(target, name, receiver) -> anyreceiver — это прокси или объект, унаследованный от прокси.
+

proxy.name = val (in the context of "setting the value")

+ +

receiver.name = val (if receiver inherits from a proxy and does not override name)

+
set function(target, name, val, receiver) -> booleanreceiver — это прокси или объект, унаследованный от прокси.
+

proxy(...args)
+ proxy.apply(thisValue, args)
+ proxy.call(thisValue, ...args)

+
apply function(target, thisValue, args) -> anytarget должен быть функцией.
new proxy(...args)construct function(target, args) -> objecttarget должен быть функцией.
+ +

Инварианты

+ +

Несмотря на то, что прокси предоставляют много возможностей пользователям, некоторые операции не перехватываются для сохранения постоянства языка:

+ + + +

Примеры

+ +

Простой пример

+ +

Объект, возвращающий значение 37, в случае отсутствия свойства с указанным именем:

+ +
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
+
+ +

Перенаправляющий прокси

+ +

В данном примере мы используем JavaScript объект, к которому наш прокси направляет все запросы:

+ +
var target = {};
+var p = new Proxy(target, {});
+
+p.a = 37; // операция перенаправлена прокси
+
+console.log(target.a); // 37. Операция была успешно перенаправлена
+
+ +

Проверка

+ +

При помощи Proxy вы можете легко проверять передаваемые объекту значения:

+ +
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; // Вызовет исключение
+
+ +

Дополнение конструктора

+ +

Функция прокси может легко дополнить конструктор новым:

+ +
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
+
+ +

Манипуляция DOM элементами

+ +

Иногда возникает необходимость переключить атрибут или имя класса у двух разных элементов:

+ +
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'
+
+ +

Изменение значений и дополнительные свойства

+ +

Прокси объект products проверяет передаваемые значения и преобразует их в массив в случае необходимости. Объект также поддерживает дополнительное свойство latestBrowser на чтение и запись.

+ +
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'
+
+ +

Поиск элемента массива по его свойству

+ +

Данный прокси расширяет массив дополнительными возможностями. Как вы видите, вы можете гибко "задавать" свойства без использования Object.defineProperties. Данный пример также может быть использован для поиска строки таблицы по её ячейке. В этом случае целью будет table.rows.

+ +
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
+
+ +

Пример использования всех перехватчиков

+ +

В данном примере, использующем все виды перехватчиков, мы попытаемся проксировать не нативный объект, который частично приспособлен для этого - docCookies, созданном в разделе "little framework" и опубликованном на странице document.cookie.

+ +
/*
+  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);
+ +

Смотрите также

+ + + +

Лицензионные примечания

+ +

Некоторое содержимое (текст, примеры) данной страницы было скопировано или адаптировано со страниц вики ECMAScript, имеющей лицензию CC 2.0 BY-NC-SA

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 +--- +
{{JSRef}}
+ +

Метод handler.apply() является ловушкой для вызова функции.

+ +
{{EmbedInteractiveExample("pages/js/proxyhandler-apply.html", "taller")}}
+ + + +

Синтаксис

+ +
const p = new Proxy(target, {
+  apply: function(target, thisArg, argumentsList) {
+  }
+});
+
+ +

Параметры

+ +

Методу apply() передаются следующие параметры. this связан с объектом-обработчиком.

+ +
+
target
+
Исходный объект.
+
thisArg
+
Аргумент this для вызова.
+
argumentsList
+
Список аргументов для вызова.
+
+ +

Возврат значения

+ +

Метод apply() может возвращать значение.

+ +

Описание

+ +

Метод handler.apply() является ловушкой для вызова функции.

+ +

Перехват

+ +

Ловушка может перехватывать следующие операции:

+ + + +

Инварианты

+ +

Если следующие инваринаты нарушены, то прокси выбросит {{jsxref("TypeError")}}.

+ +

Исходный объект target должен быть самовызываемым. То есть, это должна быть функция-объект.

+ +

Примеры

+ +

Ловушка для вызова функции

+ +

Следующий код ловит вызов функции.

+ +
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
+
+ +

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

+ + + + + + + + + + + + +
Спецификация
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}
+ +

Совместимость с браузерами

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.apply")}}

+
+ +

Смотрите также

+ + 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 +--- +
{{JSRef}}
+ +

Метод handler.get() является ловушкой для получения значения свойства.

+ +
{{EmbedInteractiveExample("pages/js/proxyhandler-get.html", "taller")}}
+ + + +

Syntax

+ +
const p = new Proxy(target, {
+  get: function(target, property, receiver) {
+  }
+});
+
+ +

Параметры

+ +

Следующие параметры передаются методу get(). this привязан к обработчику.

+ +
+
target
+
Исходный объект, который проксируется.
+
property
+
Наименование или {{jsxref("Symbol")}} получаемого свойства. 
+
receiver
+
Прокси или объект, наследуемый от прокси..
+
+ +

Возвращаемое значение

+ +

Метод get() может возвращать значение.

+ +

Описание

+ +

Метод handler.get() является ловушкой для получения значения свойства.

+ +

Перехват

+ +

Эта ловушка может перехватывать следующие операции:

+ + + +

Инварианты

+ +

Если следующие инваринаты нарушены, то прокси выбросит {{jsxref("TypeError")}}:

+ + + +

Примеры

+ +

Ловушка для получения значения свойства

+ +

Следующий код перехватывает получение значения свойства.

+ +
const p = new Proxy({}, {
+  get: function(target, property, receiver) {
+    console.log('called: ' + property);
+    return 10;
+  }
+});
+
+console.log(p.a); // "called: a"
+                  // 10
+
+ +

Следующий код нарушает инвариант.

+ +
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
+
+ +

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

+ + + + + + + + + + + + +
Спецификация
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver', '[[Get]]')}}
+ +

Совместимость с браузерами

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.get")}}

+
+ +

Смотрите также

+ + 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 +--- +
{{JSRef}}
+ +

The Proxy() constructor is used to create {{jsxref("Proxy")}} objects.

+ +

Syntax

+ +
new Proxy(target, handler)
+ +

Parameters

+ +
+
target
+
A target object to wrap with Proxy. It can be any sort of object, including a native array, a function, or even another proxy.
+
handler
+
An object whose properties are functions that define the behavior of the proxy when an operation is performed on it.
+
+ +

Description

+ +

Use the Proxy() constructor to create a new Proxy object. This constructor takes two mandatory arguments:

+ + + +

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 handler object, you can customise specific aspects of the proxy's behavior. For example, by defining get() you can provide a customised version of the target's property accessor.

+ +

Handler functions

+ +

This section lists all the handler functions you can define. Handler functions are sometimes called traps, because they trap calls to the underlying target object.

+ +
+
{{JSxRef("Global_Objects/Proxy/Proxy/apply", "handler.apply()")}}
+
A trap for a function call.
+
{{JSxRef("Global_Objects/Proxy/Proxy/construct", "handler.construct()")}}
+
A trap for the {{JSxRef("Operators/new", "new")}} operator.
+
{{JSxRef("Global_Objects/Proxy/Proxy/defineProperty", "handler.defineProperty()")}}
+
A trap for {{JSxRef("Object.defineProperty")}}.
+
{{JSxRef("Global_Objects/Proxy/Proxy/deleteProperty", "handler.deleteProperty()")}}
+
A trap for the {{JSxRef("Operators/delete", "delete")}} operator.
+
{{JSxRef("Global_Objects/Proxy/Proxy/get", "handler.get()")}}
+
A trap for getting property values.
+
{{JSxRef("Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
+
A trap for {{JSxRef("Object.getOwnPropertyDescriptor")}}.
+
{{JSxRef("Global_Objects/Proxy/Proxy/getPrototypeOf", "handler.getPrototypeOf()")}}
+
A trap for {{JSxRef("Object.getPrototypeOf")}}.
+
{{JSxRef("Global_Objects/Proxy/Proxy/has", "handler.has()")}}
+
A trap for the {{JSxRef("Operators/in", "in")}} operator.
+
{{JSxRef("Global_Objects/Proxy/Proxy/isExtensible", "handler.isExtensible()")}}
+
A trap for {{JSxRef("Object.isExtensible")}}.
+
{{JSxRef("Global_Objects/Proxy/Proxy/ownKeys", "handler.ownKeys()")}}
+
A trap for {{JSxRef("Object.getOwnPropertyNames")}} and {{JSxRef("Object.getOwnPropertySymbols")}}.
+
{{JSxRef("Global_Objects/Proxy/Proxy/preventExtensions", "handler.preventExtensions()")}}
+
A trap for {{JSxRef("Object.preventExtensions")}}.
+
{{JSxRef("Global_Objects/Proxy/Proxy/set", "handler.set()")}}
+
A trap for setting property values.
+
{{JSxRef("Global_Objects/Proxy/Proxy/setPrototypeOf", "handler.setPrototypeOf()")}}
+
A trap for {{JSxRef("Object.setPrototypeOf")}}.
+
+ +

Examples

+ +

Selectively proxy property accessors

+ +

In this example the target has two properties, notProxied and proxied. We define a handler that returns a different value for proxied, and lets any other accesses through to the target.

+ +
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"
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-proxy-constructor', 'Proxy constructor')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Proxy.Proxy")}}

+ +

See also

+ + 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 +--- +
{{JSRef}}
+ +

Метод Proxy.revocable() используется, чтобы создать отменяемый {{jsxref("Proxy")}} объект.

+ +

Синтаксис

+ +
Proxy.revocable(target, handler);
+
+ +

Параметры

+ +
{{ Page("/docs/Web/JavaScript/Reference/Global_Objects/Proxy", "Parameters") }}
+ +

Возвращаемое значение

+ +

Создаётся и возвращается отменяемый Proxy объект.

+ +

Описание

+ +

Отменяемый Proxy - объект со следующими двумя свойствами {proxy: proxy, revoke: revoke}.

+ +
+
proxy
+
Объект Proxy, созданный с помощью вызова new Proxy(target, handler).
+
revoke
+
Функция, не принимающая аргументов, которая сделает недействительным (выключит) proxy.
+
+ +

Если вызовется функция revoke(), proxy становится неиспользуемым: Любой proxy-перехватчик событий объекта будет вызывать исключение {{jsxref("TypeError")}}. Как только proxy отменена, она останется отменённой и дальше, и может быть собрана сборщиком мусора. Повторный вызов revoke() не будет иметь никакого эффекта.

+ +

Примеры

+ +
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-перехватчиков событий
+
+ +

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

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy.revocable', 'Proxy Revocation Functions')}}{{Spec2('ES2015')}}Изначальное определение.
{{SpecName('ESDraft', '#sec-proxy.revocable', 'Proxy Revocation Functions')}}{{Spec2('ESDraft')}} 
+ +

Совместимость браузерами

+ + + +

{{Compat("javascript.builtins.Proxy.revocable")}}

+ +

Смотрите также

+ + -- cgit v1.2.3-54-g00ecf