Возможно, вы слышали о том, что в JavaScript ES6 появились новые объекты — так называемые прокси. Тем, кто знает о том, что такое прокси-объекты, и умеет с ними работать, они могут принести немалую пользу. Сегодня мы публикуем перевод материала, который направлен на то, чтобы объяснить всем желающим особенности работы с прокси-объектами JS на множестве примеров.
Также откройте в новой вкладке наш предыдущий пост: JavaScript-прокси: и красиво, и полезно
let proxy = new Proxy(target, handler);
let proxyTest = new Proxy({}, {})
if (proxyTest instanceof Object) {
document.write("Proxy supported!");
}
let obj = {
c: "car",
b: "bike"
};
document.write(obj.b, "
"); //Результат -> "bike"
document.write(obj.c, "
"); //Результат -> "car"
document.write(obj.l); //Результат -> "undefined"
get
. Обработчик передаст целевой объект и запрошенный ключ перехватчику.let handler = {
get: function(target, name) {
return name in target ? target[name] : "Key does not exist";
}
}
let obj = {
c: "car",
b: "bike"
};
let proxyObj = new Proxy(obj, handler);
document.write(proxyObj.b, "
"); //Результат -> "bike"
document.write(proxyObj.c, "
"); //Результат -> "car"
document.write(proxyObj.l); //Результат -> "Key does not exist"
get
выполняется при попытке доступа к свойству объекта с использованием прокси. Метод get
принимает параметр target
(объект, с которым нужно работать через прокси) и property
(свойство, к которому мы пытаемся получить доступ).var p = new Proxy(target, {
get: function(target, property, receiver) {
}
});
target
: целевой объект.property
: имя свойства, с которым нужно работать.receiver
: прокси-объект или объект, унаследованный от прокси-объектаget
до вывода его на экран.let handler = {
get: function(target, name) {
return name in target ? target[name]*10 : "Key does not exist";
}
}
let obj = {
a: 1,
b: 2
};
let proxyObj = new Proxy(obj, handler);
document.write(proxyObj.a, "
"); //Результат -> 10
document.write(proxyObj.b, "
"); //Результат -> 20
document.write(proxyObj.c); //Результат -> "Key does not exist"
set
выполняется при попытке установки свойства объекта с использованием прокси. Метод set
принимает параметр target
(объект, доступ к которому мы собираемся получить), property
(свойство, которое мы собираемся устанавливать), и value
(значение свойства, которое мы собираемся установить).var p = new Proxy(target, {
set: function(target, property, value, receiver) {
}
});
target
: целевой объект.property
: имя свойства, которое нужно устанавливать.value
: новое значение интересующего нас свойства.receiver
: объект, которому изначально была направлена операция присваивания. Обычно — это сам прокси. Однако обработчик set
может быть вызван не напрямую, а через цепочку прототипов или каким-то другим способом.proxyObj
).proxyObj
попытаться задать новое свойство объекта, будет вызван перехватчик и в объекте будет сохранено значение свойства, изменённое им.let handler = {
set: function(target, name, value) {
target[name] = value*10;
}
}
let obj = {
a: 1,
b: 2
};
let proxyObj = new Proxy(obj, handler);
proxyObj.c = 3;
document.write(proxyObj.a, "
"); //Результат -> 1
document.write(proxyObj.b, "
"); //Результат -> 2
document.write(proxyObj.c); //Результат -> 30
has
вызывается при выполнении оператора in
. Метод has
принимает параметры target
(целевой объект) и property
(свойство, доступ к которому нужно контролировать с помощью прокси-объекта).var p = new Proxy(target, {
has: function(target, property) {
}
});
target
: целевой объект.property
: имя свойства, существование которого будет проверяться.ar
. Для начала проверим, существует ли ключ, и, если это так, проверим, содержит ли он интересующую нас подстроку. Если будут выполнены оба условия, мы вернём логическое значение true
, в противном случае — вернём false
.const handler = {
has: function(target, key) {
if (key in target && key.includes("ar")) {
return true;
}
return false;
}
};
const user = {
car: 'Bentley',
bar: 4,
hotel: "no",
};
const proxy = new Proxy(user, handler);
document.write('car' in proxy, "
"); // Результат -> true
document.write('car' in user, "
"); // Результат -> true
document.write('hotel' in proxy, "
"); // Результат -> false
document.write('hotel' in user, "
"); // Результат -> true
document.write('spacebar' in proxy, "
"); // Результат -> false
document.write('spacebar' in user); // Результат -> false
apply
позволяет вызывать прокси с параметрами. Он позволяет переопределять функции. Метод apply
принимает параметры target
(целевой объект или целевая функция), thisArg
(аргумент this
для использования при вызове) и argumentsList
(список всех аргументов в виде массива).var p = new Proxy(target, {
apply: function(target, thisArg, argumentsList) {
}
});
target
: целевой объект.thisArg
: аргумент this
для вызова.argumentsList
: список аргументов для вызова.function multiply(a, b) {
return a * b;
}
const handler = {
apply: function(target, thisArg, argumentsList) {
return target(argumentsList[0], argumentsList[1]) + 1;
}
};
var proxy = new Proxy(multiply, handler);
document.write(multiply(2, 5), "
"); // Результат -> 10
document.write(proxy(2, 5)); // Результат -> 11
construct
выполняется при вызове оператора new
. Для того чтобы этот перехватчик мог нормально функционировать, нужно, чтобы целевой объект, для работы с которым его планируется вызывать, можно было бы создать командой вида new Target()
.var p = new Proxy(target, {
construct: function(target, argumentsList, newTarget) {
}
});
target
: целевой объект.argumentList
: список аргументов для конструктора.newTarget
: исходный конструкторfunction formatCurrency(format) {
this.format = format;
}
const handler = {
construct: function(target, args) {
return new target("$" + args[0]);
}
};
const proxy = new Proxy(formatCurrency, handler);
document.write(new proxy('100').format); // Результат -> $100
deleteProperty
вызывается при обращению к методу delete
. Он принимает параметры target
(целевой объект или целевая функция), и property
(свойство, команду удаления которого мы хотим обрабатывать).var p = new Proxy(target, {
deleteProperty: function(target, property) {
}
});
target:
целевой объект.property
: имя свойства, в операцию удаления которого нужно вмешаться.const cars = {
merc: 's320',
buggati: 'veyron',
};
const handler = {
deleteProperty: function(target, prop) {
if (prop in target) {
document.write(`${prop} has been removed
`); // Результат -> merc has been removed
delete target[prop];
}
}
};
document.write(cars.merc, "
"); // Результат -> "s320"
const proxy = new Proxy(cars, handler);
delete proxy.merc;
document.write(cars.merc, "
"); // Результат -> undefined
К сожалению, не доступен сервер mySQL