| [ Web Proxy ] |
| Viewing: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Proxy | [Back] [Original] |
Get to know MDN better
Proxy Object
Proxy 2
target: handler: target
const target = {
message1: "hello",
message2: "everyone",
};
const handler1 = {};
const proxy1 = new Proxy(target, handler1);
console.log(proxy1.message1); // hello
console.log(proxy1.message2); // everyone
const target = {
message1: "hello",
message2: "everyone",
};
const handler2 = {
get(target, prop, receiver) {
return "world";
},
};
const proxy2 = new Proxy(target, handler2);
handler2
console.log(proxy2.message1); // world
console.log(proxy2.message2); // world
Reflect Proxy Reflect Reflect.get
const target = {
message1: "hello",
message2: "everyone",
};
const handler3 = {
get(target, prop, receiver) {
if (prop === "message2") {
return "world";
}
return Reflect.get(...arguments);
},
};
const proxy3 = new Proxy(target, handler3);
console.log(proxy3.message1); // hello
console.log(proxy3.message2); // world
Reflect Reflect Reflect
[[Get]] obj.x [[Get]]
length length [[DefineOwnProperty]] length length
[[GetPrototypeOf]] |
getPrototypeOf() |
[[SetPrototypeOf]] |
setPrototypeOf() |
[[IsExtensible]] |
isExtensible() |
[[PreventExtensions]] |
preventExtensions() |
[[GetOwnProperty]] |
getOwnPropertyDescriptor() |
[[DefineOwnProperty]] |
defineProperty() |
[[HasProperty]] |
has() |
[[Get]] |
get() |
[[Set]] |
set() |
[[Delete]] |
deleteProperty() |
[[OwnPropertyKeys]] |
ownKeys() |
[[Call]] |
apply() |
[[Construct]] |
construct() |
delete obj.x "x" in obj false [[Delete]] [[HasProperty]] delete obj.x
JavaScript Reflect /push() get() set()
[[Set]] [[DefineOwnProperty]] 2 [[Set]] [[DefineOwnProperty]] obj.x = 1 [[Set]] Object.defineProperty() [[DefineOwnProperty]] [[DefineOwnProperty]]
Proxy() Proxy
:
Proxy.prototype Proxy
Proxy.revocable() Proxy
37 get()
const handler = {
get(obj, prop) {
return prop in obj ? obj[prop] : 37;
},
};
const 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
const target = {};
const p = new Proxy(target, {});
p.a = 37; //
console.log(target.a); // 37
JavaScript DOM Map
class Secret {
#secret;
constructor(secret) {
this.#secret = secret;
}
get secret() {
return this.#secret.replace(/\d+/, "[REDACTED]");
}
}
const secret = new Secret("123456");
console.log(secret.secret); // [REDACTED]
//
const proxy = new Proxy(secret, {});
console.log(proxy.secret); // TypeError: Cannot read private member #secret from an object whose class did not declare it
get this secret proxy #secret secret this
const proxy = new Proxy(secret, {
get(target, prop, receiver) {
// Reflect.get(target, prop, receiver)
// `this`
return target[prop];
},
});
console.log(proxy.secret);
this
class Secret {
#x = 1;
x() {
return this.#x;
}
}
const secret = new Secret();
const proxy = new Proxy(secret, {
get(target, prop, receiver) {
const value = target[prop];
if (value instanceof Function) {
return function (...args) {
return value.apply(this === receiver ? target : this, args);
};
}
return value;
},
});
console.log(proxy.x());
JavaScript JavaScript Map [[MapData]]
const proxy = new Proxy(new Map(), {});
console.log(proxy.size); // TypeError: get size method called on incompatible Proxy
"this-recovering"
Proxy set()
const validator = {
set(obj, prop, value) {
if (prop === "age") {
if (!Number.isInteger(value)) {
throw new TypeError("");
}
if (value > 200) {
throw new RangeError("");
}
}
//
obj[prop] = value;
//
return true;
},
};
const person = new Proxy({}, validator);
person.age = 100;
console.log(person.age); // 100
person.age = "young"; //
person.age = 300; //
2 Proxy 2
selected view set()
HTML view.selected 'aria-selected' true view.selected 'aria-selected' true 'aria-selected' false
const view = new Proxy(
{
selected: null,
},
{
set(obj, prop, newVal) {
const oldVal = obj[prop];
if (prop === "selected") {
if (oldVal) {
oldVal.setAttribute("aria-selected", "false");
}
if (newVal) {
newVal.setAttribute("aria-selected", "true");
}
}
//
obj[prop] = newVal;
//
return true;
},
},
);
const item1 = document.getElementById("item-1");
const item2 = document.getElementById("item-2");
// select item1:
view.selected = item1;
console.log(`item1: ${item1.getAttribute("aria-selected")}`);
// item1: true
// selecting item2 de-selects item1:
view.selected = item2;
console.log(`item1: ${item1.getAttribute("aria-selected")}`);
// item1: false
console.log(`item2: ${item2.getAttribute("aria-selected")}`);
// item2: true
products latestBrowser
const products = new Proxy(
{
browsers: ["Firefox", "Chrome"],
},
{
get(obj, prop) {
//
if (prop === "latestBrowser") {
return obj.browsers[obj.browsers.length - 1];
}
//
return obj[prop];
},
set(obj, prop, value) {
//
if (prop === "latestBrowser") {
obj.browsers.push(value);
return true;
}
//
if (typeof value === "string") {
value = [value];
}
//
obj[prop] = value;
//
return true;
},
},
);
console.log(products.browsers);
// ['Firefox', 'Chrome']
products.browsers = "Safari";
// ()
console.log(products.browsers);
// ['Safari'] <-
products.latestBrowser = "Edge";
console.log(products.browsers);
// ['Safari', 'Edge']
console.log(products.latestBrowser);
// 'Edge'
| ECMAScript 2027 LanguageSpecification # sec-proxy-objects |
| Web Proxy Viewer | New URL | Original Page |