С пÑиÑ
одом ECMAScript 2015, в JavaScript Ð²Ð²ÐµÐ´ÐµÐ½Ñ Ð¾Ð±ÑекÑÑ Proxy
и Reflect
, позволÑÑÑие пеÑеÑ
ваÑиÑÑ Ð¸ пеÑеопÑеделиÑÑ Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ðµ ÑÑндаменÑалÑнÑÑ
пÑоÑеÑÑов ÑзÑка (ÑакиÑ
как поиÑк ÑвойÑÑв, пÑиÑвоение, иÑеÑиÑование, вÑзов ÑÑнкÑий и Ñак далее). С помоÑÑÑ ÑÑиÑ
двÑÑ
обÑекÑов Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе пÑогÑаммиÑоваÑÑ Ð½Ð° меÑа ÑÑовне JavaScript.
ÐведÑннÑй в ECMAScript 6, обÑÐµÐºÑ Proxy
позволÑÐµÑ Ð¿ÐµÑеÑ
ваÑиÑÑ Ð¸ опÑеделиÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑкое поведение Ð´Ð»Ñ Ð¾Ð¿ÑеделÑннÑÑ
опеÑаÑий. ÐапÑимеÑ, полÑÑение ÑвойÑÑва обÑекÑа:
var handler = {
get: function (target, name) {
return name in target ? target[name] : 42;
},
};
var p = new Proxy({}, handler);
p.a = 1;
console.log(p.a, p.b); // 1, 42
ÐбÑÐµÐºÑ Proxy
опÑеделÑÐµÑ target
(в данном ÑлÑÑае новÑй пÑÑÑой обÑекÑ) и handler
- обÑÐµÐºÑ Ð² коÑоÑом Ñеализована оÑÐ¾Ð±Ð°Ñ ÑÑнкÑиÑ-ловÑÑка get
. "ÐÑокÑиÑованнÑй" Ñаким обÑазом обÑекÑ, пÑи доÑÑÑпе к его неÑÑÑеÑÑвÑÑÑÐµÐ¼Ñ ÑвойÑÑÐ²Ñ Ð²ÐµÑнÑÑ Ð½Ðµ undefined,
а ÑиÑловое знаÑение 42.
ÐополниÑелÑнÑе пÑимеÑÑ Ð´Ð¾ÑÑÑÐ¿Ð½Ñ Ð² ÑпÑавоÑнике Proxy
.
Ð ÑазговоÑе о ÑÑнкÑиÑÑ
обÑекÑа Proxy
пÑÐ¸Ð¼ÐµÐ½Ð¸Ð¼Ñ ÑледÑÑÑие ÑеÑминÑ:
ÐбÑÐµÐºÑ - обÑÑÑка, ÑодеÑжаÑий в Ñебе ÑÑнкÑии-ловÑÑки.
ÐеÑодÑ, ÑеализÑÑÑие доÑÑÑп к ÑвойÑÑвам. Ð Ñвоей конÑепÑии они аналогиÑÐ½Ñ Ð¼ÐµÑодам пеÑÐµÑ Ð²Ð°Ñа(hooking) в опеÑаÑионнÑÑ ÑиÑÑÐµÐ¼Ð°Ñ .
ÐбÑекÑ, коÑоÑÑй обоÑаÑиваеÑÑÑ Ð² Proxy. ЧаÑÑо иÑполÑзÑеÑÑÑ Ð»Ð¸ÑÑ ÐºÐ°Ðº внÑÑÑеннее Ñ ÑанилиÑе Ð´Ð»Ñ Proxy обÑекÑа. ÐÑовеÑка на наÑÑÑение огÑаниÑений (invariants), ÑвÑзаннÑÑ Ñ Ð½ÐµÑаÑÑиÑÑемоÑÑÑÑ Ð¾Ð±ÑекÑа или неконÑигÑÑиÑÑемÑми ÑвойÑÑвами обÑекÑа пÑоизводиÑÑÑ Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑеÑной Ñели.
ÐекоÑоÑÑе оÑобенноÑÑи Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¾Ð±ÑекÑа, коÑоÑÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑоÑ
ÑÐ°Ð½ÐµÐ½Ñ Ð¿Ñи ÑеализаÑии полÑзоваÑелÑÑкого Ð¿Ð¾Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð½Ð°Ð·Ð²Ð°Ð½Ñ invariants. ÐÑли в обÑабоÑÑике наÑÑÑÐµÐ½Ñ Ñакие огÑаниÑениÑ, бÑÐ´ÐµÑ Ð²ÑбÑоÑена оÑибка TypeError
.
Ð ÑледÑÑÑей ÑаблиÑе пеÑеÑиÑÐ»ÐµÐ½Ñ Ð»Ð¾Ð²ÑÑки, доÑÑÑпнÑе Ð´Ð»Ñ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð² обÑекÑе Proxy
. СмоÑÑиÑе подÑобнÑе обÑÑÑÐ½ÐµÐ½Ð¸Ñ Ð¸ пÑимеÑÑ Ð² докÑменÑаÑии.
handler.getPrototypeOf()
Object.getPrototypeOf()
Reflect.getPrototypeOf()
__proto__
Object.prototype.isPrototypeOf()
instanceof
меÑод getPrototypeOf
должен веÑнÑÑÑ object или null
.target
неÑаÑÑиÑÑем, меÑод Object.getPrototypeOf(proxy)
должен возвÑаÑаÑÑ ÑÐ¾Ñ Ð¶Ðµ ÑезÑлÑÑÐ°Ñ ÑÑо и Object.getPrototypeOf(target)
.handler.setPrototypeOf()
Object.setPrototypeOf()
Reflect.setPrototypeOf()
еÑли Ñелевой обÑÐµÐºÑ target
неÑаÑÑиÑÑем, знаÑение паÑамеÑÑа prototype
должно бÑÑÑ ÑавнÑм знаÑÐµÐ½Ð¸Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÐ¼Ð¾Ð¼Ñ Ð¼ÐµÑодом Object.getPrototypeOf(target)
. handler.isExtensible()
Object.isExtensible()
Reflect.isExtensible()
Object.isExtensible(proxy)
должно возвÑаÑаÑÑ Ñоже знаÑение, ÑÑо и Object.isExtensible(target)
. handler.preventExtensions()
Object.preventExtensions()
Reflect.preventExtensions()
Object.preventExtensions(proxy)
возвÑаÑÐ°ÐµÑ true
ÑолÑко в Ñом ÑлÑÑае, еÑли Object.isExtensible(proxy)
Ñавно false
. handler.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor()
Reflect.getOwnPropertyDescriptor()
меÑод getOwnPropertyDescriptor
должен возвÑаÑаÑÑ object или undefined
.target
.target
и target
не ÑаÑÑиÑÑем.target
и target
не ÑаÑÑиÑÑем.target
или еÑли оно ÑÑÑеÑÑвÑÐµÑ Ð¸ ÑвлÑеÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÑемÑм, ÑобÑÑвеннÑм ÑвойÑÑвом Ñелевого обÑекÑа target
.Object.getOwnPropertyDescriptor(target)
Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿Ñименено к ÑÐµÐ»ÐµÐ²Ð¾Ð¼Ñ Ð¾Ð±ÑекÑÑ ÑеÑез меÑод Object.defineProperty и Ñ
Ñо не вÑÐ·Ð¾Ð²ÐµÑ Ð¾Ñибки.handler.defineProperty()
Object.defineProperty()
Reflect.defineProperty()
Object.defineProperty(target, prop, descriptor)
не вÑÐ·Ð¾Ð²ÐµÑ Ð¾Ñибки.defineProperty
веÑнÑÑ false
, ÑÑо вÑÐ·Ð¾Ð²ÐµÑ Ð¾ÑÐ¸Ð±ÐºÑ TypeError
.handler.has()
Property query: foo in proxy
foo in Object.create(proxy)
Reflect.has()
handler.get()
Property access: proxy[foo]
and proxy.bar
Object.create(proxy)[foo]
Reflect.get()
undefined,
еÑли ÑооÑвеÑÑÑвÑÑÑее ÑвойÑÑво Ñелевого обÑекÑа ÑвлÑеÑÑÑ Ð½ÐµÐºÐ¾Ð½ÑигÑÑиÑÑемÑм и обÑÑнÑÑо в геÑÑÐµÑ Ð¸ ÑеÑÑеÑ, где ÑеÑÑÐµÑ Ñавен undefined
.handler.set()
Property assignment: proxy[foo] = bar
and proxy.foo = bar
Object.create(proxy)[foo] = bar
Reflect.set()
undefined
.false
из обÑабоÑÑика set
вÑÐ·Ð¾Ð²ÐµÑ Ð¾ÑÐ¸Ð±ÐºÑ TypeError
.handler.deleteProperty()
Property deletion: delete proxy[foo]
and delete proxy.foo
Reflect.deleteProperty()
СвойÑÑво не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ñдалено, еÑли оно ÑÑÑеÑÑвÑÐµÑ Ð² Ñелевом обÑекÑе как ÑобÑÑвенное, неконÑигÑÑиÑÑемое ÑвойÑÑво. handler.enumerate()
Property enumeration / for...in: for (var name in proxy) {...}
Reflect.enumerate()
ÐеÑод enumerate
должен возвÑаÑаÑÑ Ð¾Ð±ÑекÑ. handler.ownKeys()
Object.getOwnPropertyNames()
Object.getOwnPropertySymbols()
Object.keys()
Reflect.ownKeys()
ownKeys
должен возвÑаÑаÑÑ ÑпиÑок.String
или Symbol
.handler.apply()
proxy(..args)
Function.prototype.apply()
and Function.prototype.call()
Reflect.apply()
ÐгÑаниÑений неÑ. handler.construct()
new proxy(...args)
Reflect.construct()
ÐбÑабоÑÑик должен возвÑаÑаÑÑ Object
. ÐÑзÑваемÑй Proxy
ÐеÑод Proxy.revocable()
ÑоздаÑÑ Ð¾ÑзÑваемÑй обÑÐµÐºÑ Proxy
. Такой пÑокÑи обÑÐµÐºÑ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¾Ñозван ÑÑнкÑией revoke
, коÑоÑÐ°Ñ Ð¾ÑклÑÑÐ°ÐµÑ Ð²Ñе ловÑÑки-обÑабоÑÑики. ÐоÑле ÑÑого лÑбÑе опеÑаÑии над пÑокÑи обÑекÑом вÑзовÑÑ Ð¾ÑÐ¸Ð±ÐºÑ TypeError
.
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 Ð½ÐµÑ Ð»Ð¾Ð²ÑÑек
РеÑлекÑиÑ
Reflect
ÑÑо вÑÑÑоеннÑй обÑекÑ, пÑедоÑÑавлÑÑÑий меÑÐ¾Ð´Ñ Ð´Ð»Ñ Ð¿ÐµÑеÑ
ваÑÑваемÑÑ
опеÑаÑий JavaScript. ÐÑо Ñе же ÑамÑе меÑодÑ, ÑÑо имеÑÑÑÑ Ð² обÑабоÑÑикаÑ
Proxy. ÐбÑÐµÐºÑ Reflect
не ÑвлÑеÑÑÑ ÑÑнкÑией.
Reflect
Ð¿Ð¾Ð¼Ð¾Ð³Ð°ÐµÑ Ð¿Ñи пеÑеÑÑлке ÑÑандаÑÑнÑÑ
опеÑаÑий из обÑабоÑÑика к ÑÐµÐ»ÐµÐ²Ð¾Ð¼Ñ Ð¾Ð±ÑекÑÑ.
ÐапÑимеÑ, меÑод Reflect.has()
ÑÑо ÑÐ¾Ñ Ð¶Ðµ опеÑаÑÐ¾Ñ in
но в виде ÑÑнкÑии:
Reflect.has(Object, "assign"); // true
УлÑÑÑÐµÐ½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ apply
Ð ES5 обÑÑно иÑполÑзÑеÑÑÑ Ð¼ÐµÑод Function.prototype.apply()
Ð´Ð»Ñ Ð²Ñзова ÑÑнкÑии в опÑеделÑнном конÑекÑÑе (Ñ Ð¾Ð¿ÑеделÑннÑм this)
и Ñ Ð¿Ð°ÑамеÑÑами, заданнÑми в виде маÑÑива (или маÑÑива-подобного обÑекÑа).
Function.prototype.apply.call(Math.floor, undefined, [1.75]);
С меÑодом Reflect.apply
ÑÑа опеÑаÑÐ¸Ñ Ð¼ÐµÐ½ÐµÐµ гÑомоздка и более понÑÑна:
Reflect.apply(Math.floor, undefined, [1.75]);
// 1;
Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
// "hello"
Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index;
// 4
Reflect.apply("".charAt, "ponies", [3]);
// "i"
ÐÑовеÑка ÑÑпеÑноÑÑи опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾ ÑвойÑÑва
ÐеÑод Object.defineProperty
, в ÑлÑÑае ÑÑпеÑ
а опеÑаÑии, возвÑаÑÐ°ÐµÑ Ð¾Ð±ÑекÑ, а пÑи неÑдаÑе вÑзÑÐ²Ð°ÐµÑ Ð¾ÑÐ¸Ð±ÐºÑ TypeError
. Ðз-за ÑÑого опÑеделение ÑвойÑÑв ÑÑебÑÐµÑ Ð¾Ð±ÑабоÑки блоком try...catch
Ð´Ð»Ñ Ð¿ÐµÑеÑ
ваÑа возможнÑÑ
оÑибок. ÐеÑод Reflect.defineProperty
, в ÑÐ²Ð¾Ñ Ð¾ÑеÑедÑ, возвÑаÑÐ°ÐµÑ ÑÑпеÑноÑÑÑ Ð¾Ð¿ÐµÑаÑии в виде бÑлева знаÑениÑ, благодаÑÑ ÑÐµÐ¼Ñ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзование пÑоÑÑого if...else
ÑÑловиÑ:
if (Reflect.defineProperty(target, property, attributes)) {
// ÑÑпеÑ
} else {
// ÑÑо-Ñо поÑло не Ñак
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4