Baseline Widely available
Proxy 对象ç¨äºå建ä¸ä¸ªå¯¹è±¡ç代çï¼ä»èå®ç°åºæ¬æä½çæ¦æªåèªå®ä¹ï¼å¦å±æ§æ¥æ¾ãèµå¼ãæä¸¾ã彿°è°ç¨çï¼ã
æ¯è¯<dfn>handler</dfn>
å 嫿æå¨ï¼trapï¼çå ä½ç¬¦å¯¹è±¡ï¼å¯è¯ä¸ºå¤çå¨å¯¹è±¡ã
æä¾å±æ§è®¿é®çæ¹æ³ãè¿ç±»ä¼¼äºæä½ç³»ç»ä¸æè·å¨çæ¦å¿µã
被 Proxy 代çèæåç对象ãå®å¸¸è¢«ä½ä¸ºä»£ççåå¨åç«¯ãæ ¹æ®ç®æ éªè¯å ³äºå¯¹è±¡ä¸å¯æ©å±æ§æä¸å¯é ç½®å±æ§çä¸åéï¼ä¿æä¸åçè¯ä¹ï¼ã
const p = new Proxy(target, handler)åæ°
target
è¦ä½¿ç¨ Proxy
å
è£
çç®æ 对象ï¼å¯ä»¥æ¯ä»»ä½ç±»åç对象ï¼å
æ¬åçæ°ç»ï¼å½æ°ï¼çè³å¦ä¸ä¸ªä»£çï¼ã
handler
ä¸ä¸ªé叏以彿°ä½ä¸ºå±æ§ç对象ï¼å屿§ä¸ç彿°åå«å®ä¹äºå¨æ§è¡åç§æä½æ¶ä»£ç p
çè¡ä¸ºã
Proxy.revocable()
å建ä¸ä¸ªå¯æ¤éçProxy
对象ã
handler
对象æ¯ä¸ä¸ªå®¹çº³ä¸æ¹ç¹å®å±æ§çå ä½ç¬¦å¯¹è±¡ãå®å
嫿 Proxy
çå个æè·å¨ï¼trapï¼ã
ææçææå¨é½æ¯å¯éçãå¦ææ²¡æå®ä¹æä¸ªææå¨ï¼é£ä¹å°±ä¼ä¿çæºå¯¹è±¡çé»è®¤è¡ä¸ºã
handler.getPrototypeOf()
Object.getPrototypeOf
æ¹æ³çææå¨ã
handler.setPrototypeOf()
Object.setPrototypeOf
æ¹æ³çææå¨ã
handler.isExtensible()
Object.isExtensible
æ¹æ³çææå¨ã
handler.preventExtensions()
Object.preventExtensions
æ¹æ³çææå¨ã
handler.getOwnPropertyDescriptor()
Object.getOwnPropertyDescriptor
æ¹æ³çææå¨ã
handler.defineProperty()
Object.defineProperty
æ¹æ³çææå¨ã
handler.has()
in
æä½ç¬¦çææå¨ã
handler.get()
屿§è¯»åæä½çææå¨ã
handler.set()
屿§è®¾ç½®æä½çææå¨ã
handler.deleteProperty()
delete
æä½ç¬¦çææå¨ã
handler.ownKeys()
Object.getOwnPropertyNames
æ¹æ³å Object.getOwnPropertySymbols
æ¹æ³çææå¨ã
handler.apply()
彿°è°ç¨æä½çææå¨ã
handler.construct()
new
æä½ç¬¦çææå¨ã
ä¸äºä¸æ åçææå¨å·²ç»è¢«åºå¼å¹¶ä¸ç§»é¤äºã
ç¤ºä¾ åºç¡ç¤ºä¾å¨ä»¥ä¸ç®åçä¾åä¸ï¼å½å¯¹è±¡ä¸ä¸åå¨å±æ§åæ¶ï¼é»è®¤è¿åå¼ä¸º 37
ãä¸é¢ç代ç 以æ¤å±ç¤ºäº get
handler ç使ç¨åºæ¯ã
const handler = {
get: function (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 对象ï¼ä»£çä¼å°ææåºç¨å°å®çæä½è½¬åå°è¿ä¸ªå¯¹è±¡ä¸ã
let target = {};
let p = new Proxy(target, {});
p.a = 37; // æä½è½¬åå°ç®æ
console.log(target.a); // 37. æä½å·²ç»è¢«æ£ç¡®å°è½¬å
éªè¯
éè¿ä»£çï¼ä½ å¯ä»¥è½»æ¾å°éªè¯åä¸ä¸ªå¯¹è±¡çä¼ å¼ãä¸é¢ç代ç 忤å±ç¤ºäº set
handler çä½ç¨ã
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");
}
}
// The default behavior to store the value
obj[prop] = value;
// 表示æå
return true;
},
};
let person = new Proxy({}, validator);
person.age = 100;
console.log(person.age);
// 100
person.age = "young";
// æåºå¼å¸¸ï¼Uncaught TypeError: The age is not an integer
person.age = 300;
// æåºå¼å¸¸ï¼Uncaught RangeError: The age seems invalid
æ©å±æé 彿°
æ¹æ³ä»£çå¯ä»¥è½»æ¾å°éè¿ä¸ä¸ªæ°æé 彿°æ¥æ©å±ä¸ä¸ªå·²æçæé 彿°ãè¿ä¸ªä¾å使ç¨äºconstruct
åapply
ã
function extend(sup, base) {
var descriptor = Object.getOwnPropertyDescriptor(
base.prototype,
"constructor",
);
base.prototype = Object.create(sup.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 èç¹
ææ¶ï¼æä»¬å¯è½éè¦äºæ¢ä¸¤ä¸ªä¸åçå
ç´ ç屿§æç±»åãä¸é¢ç代ç 以æ¤ä¸ºç®æ ï¼å±ç¤ºäº set
handler ç使ç¨åºæ¯ã
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");
}
}
// é»è®¤è¡ä¸ºæ¯åå¨è¢«ä¼ å
¥ setter 彿°ç屿§å¼
obj[prop] = newval;
// 表示æä½æå
return true;
},
},
);
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
çéå 屿§ï¼è¿ä¸ªå±æ§å¯ä»¥åæ¶ä½ä¸º getter å setterã
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;
// 表示æå
return true;
},
},
);
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'
éè¿å±æ§æ¥æ¾æ°ç»ä¸çç¹å®å¯¹è±¡
以ä¸ä»£ç为æ°ç»æ©å±äºä¸äºå®ç¨å·¥å
·ãå¦ä½ æè§ï¼éè¿ Proxyï¼æä»¬å¯ä»¥çµæ´»å°âå®ä¹â屿§ï¼èä¸éè¦ä½¿ç¨ Object.defineProperties
æ¹æ³ã以ä¸ä¾åå¯ä»¥ç¨äºéè¿åå
æ ¼æ¥æ¥æ¾è¡¨æ ¼ä¸çä¸è¡ãå¨è¿ç§æ
åµä¸ï¼target æ¯ 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 ç number; 宿¯ 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];
}
}
// éè¿ name è·å product
if (result) {
return result;
}
// éè¿ type è·å products
if (prop in types) {
return types[prop];
}
// è·å product type
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
ä¸ä¸ªå®æ´ç traps
å表示ä¾
åºäºæå¦ç®çï¼è¿é为äºå建ä¸ä¸ªå®æ´ç traps
å表示ä¾ï¼æä»¬å°å°è¯ä»£çä¸ä¸ªç¹å«éç¨äºè¿ç±»æä½çéåç对象ï¼ç±ä¸ä¸ªç®åç cookie æ¡æ¶å建ç docCookies
å
¨å±å¯¹è±¡ã
/*
const docCookies = â¦â¦éè¿ä»¥ä¸é¾æ¥è·åâdocCookiesâ对象ï¼
https://reference.codeproject.com/dom/document/cookie/simple_document.cookie_framework
*/
const docCookies = new Proxy(docCookies, {
get(target, key) {
return target[key] ?? target.getItem(key) ?? undefined;
},
set(target, key, value) {
if (key in target) {
return false;
}
return target.setItem(key, value);
},
deleteProperty(target, key) {
if (!(key in target)) {
return false;
}
return target.removeItem(key);
},
ownKeys(target) {
return target.keys();
},
has(target, key) {
return key in target || target.hasItem(key);
},
defineProperty(target, key, descriptor) {
if (descriptor && "value" in descriptor) {
target.setItem(key, descriptor.value);
}
return target;
},
getOwnPropertyDescriptor(target, key) {
const value = target.getItem(key);
return value
? {
value,
writable: true,
enumerable: true,
configurable: false,
}
: undefined;
},
});
/* Cookie æµè¯ */
console.log((docCookies.myCookie1 = "First value"));
console.log(docCookies.getItem("myCookie1"));
docCookies.setItem("myCookie1", "Changed value");
console.log(docCookies.myCookie1);
è§è æµè§å¨å
¼å®¹æ§ åè çæå£°æ
ä¸äºå 容ï¼å¦ææ¬ãä¾åï¼æ¯å¤å¶èªæä¿®æ¹èªECMAScript wikiï¼çæå£°æ CC 2.0 BY-NC-SAï¼ã
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