å ç¼ç¨
Proxy å Reflect 对象å
è®¸ä½ æ¦æªå¹¶èªå®ä¹åºæ¬è¯è¨æä½ï¼ä¾å¦å±æ§æ¥æ¾ãèµå¼ãæä¸¾å彿°è°ç¨çï¼ãåå©è¿ä¸¤ä¸ªå¯¹è±¡ï¼ä½ å¯ä»¥å¨ JavaScript è¿è¡å
级å«çç¼ç¨ã
代ç
Proxy 对象å¯ä»¥æ¦æªæäºæä½å¹¶å®ç°èªå®ä¹è¡ä¸ºã
ä¾å¦è·åä¸ä¸ªå¯¹è±¡ä¸ç屿§ï¼
let handler = {
get(target, name) {
return name in target ? target[name] : 42;
},
};
let p = new Proxy({}, handler);
p.a = 1;
console.log(p.a, p.b); // 1, 42
Proxy 对象å®ä¹äºä¸ä¸ª targetï¼è¿éæ¯ä¸ä¸ªç©ºå¯¹è±¡ï¼åä¸ä¸ªå®ç°äº get é·é±ç handler 对象ãè¿éï¼ä»£çç对象å¨è·åæªå®ä¹ç屿§æ¶ä¸ä¼è¿å undefinedï¼èæ¯è¿å 42ã
æ´å¤ä¾ååè§ Proxy 页é¢ã
æ¯è¯
å¨è®¨è®ºä»£ççåè½æ¶ä¼ç¨å°ä»¥ä¸æ¯è¯ï¼
handler-
å å«é·é±çå ä½ç¬¦å¯¹è±¡ï¼ä¸è¯ä½âå¤çå¨âï¼ã
- é·é±
-
æä¾å±æ§è®¿é®çæ¹æ³ï¼è¿ç±»ä¼¼äºæä½ç³»ç»ä¸é·é±çæ¦å¿µï¼ã
target-
代çæèæåç对象ï¼ä¸è¯ä½âç®æ âï¼ãå®é常ç¨ä½ä»£ççåå¨å端ãJavaScript ä¼éªè¯ä¸ä¸å¯æ©å±æ§æä¸å¯é ç½®å±æ§ç¸å ³çä¸åå¼ã
- ä¸åå¼
-
å®ç°èªå®ä¹æä½æ¶ä¿æä¸åçè¯ä¹ç§°ä¸ºä¸åå¼ãå¦æä½ ç ´åäºå¤çå¨çä¸åå¼ï¼åä¼å¼å
TypeErrorå¼å¸¸ã
å¤çå¨åé·é±
以ä¸è¡¨æ ¼ä¸æ»ç»äº Proxy 对象å¯ç¨çé·é±ã详ç»çè§£éåä¾å请çåè页ã
| å¤çå¨ / é·é± | æ¦æªçæä½ | ä¸åå¼ |
|---|---|---|
handler.getPrototypeOf()
|
Object.getPrototypeOf()Reflect.getPrototypeOf()__proto__Object.prototype.isPrototypeOf()instanceof
|
|
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.isExtensible(proxy)
å¼ä¸º falseï¼é£ä¹
Object.preventExtensions(proxy) åªå¯è½è¿å
trueã
|
handler.getOwnPropertyDescriptor()
|
Object.getOwnPropertyDescriptor()Reflect.getOwnPropertyDescriptor()
|
|
handler.defineProperty()
|
Object.defineProperty()Reflect.defineProperty()
|
|
handler.has()
|
|
|
handler.get()
|
|
|
handler.set()
|
|
|
handler.deleteProperty()
|
|
妿åå¨ä¸ä¸ªå¯¹åºäº target
ç屿§æ¯ä¸å¯é
ç½®çèªæå±æ§ï¼é£ä¹è¯¥å±æ§ä¸è½è¢«å é¤ã
|
handler.ownKeys()
|
Object.getOwnPropertyNames()Object.getOwnPropertySymbols()Object.keys()Reflect.ownKeys()
|
|
handler.apply()
|
proxy(..args)Function.prototype.apply()Function.prototype.call()Reflect.apply()
|
ä¸åå¨å
³äº handler.apply æ¹æ³çä¸åå¼ã
|
handler.construct()
|
new proxy(...args)Reflect.construct()
|
è¿åå¼å¿
é¡»æ¯ä¸ä¸ª Objectã |
坿¤éç Proxy
å¯ä»¥ç¨ Proxy.revocable() æ¹æ³æ¥åå»ºå¯æ¤éç Proxy 对象ãè¿æå³çå¯ä»¥éè¿ revoke 彿°æ¥æ¤éå¹¶å
³éä¸ä¸ªä»£çã
æ¤åï¼å¯¹ä»£çè¿è¡çä»»æçæä½é½ä¼å¯¼è´ TypeErrorã
const revocable = Proxy.revocable(
{},
{
get(target, name) {
return `[[${name}]]`;
},
},
);
const proxy = revocable.proxy;
console.log(proxy.foo); // "[[foo]]"
revocable.revoke();
console.log(proxy.foo); // TypeError: Cannot perform 'get' on a proxy that has been revoked
proxy.foo = 1; // TypeError: Cannot perform 'set' on a proxy that has been revoked
delete proxy.foo; // TypeError: Cannot perform 'deleteProperty' on a proxy that has been revoked
console.log(typeof proxy); // "object", `typeof` ä¸ä¼è§¦åä»»ä½é·é±
åå°
Reflect æ¯ä¸ä¸ªå
置对象ï¼å®ä¸ºå¯æ¦æªç JavaScript æä½æä¾äºæ¹æ³ãè¿äºæ¹æ³ä¸ä»£çå¤ç卿æä¾çæ¹æ³ç±»ä¼¼ã
Reflect 并䏿¯ä¸ä¸ªå½æ°å¯¹è±¡ã
Reflect å°é»è®¤æä½ä»å¤çå¨è½¬åå° targetã
以 Reflect.has() 为ä¾ï¼ä½ å¯ä»¥å° in è¿ç®ç¬¦ä½ä¸ºå½æ°ï¼
Reflect.has(Object, "assign"); // true
æ´å¥½ç apply 彿°
å¨ä¸åå© Reflect çæ
åµä¸ï¼æä»¬éå¸¸ä½¿ç¨ Function.prototype.apply() æ¹æ³è°ç¨ä¸ä¸ªå
·æç»å® this å¼å arguments æ°ç»ï¼æç±»æ°ç»å¯¹è±¡ï¼ç彿°ã
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)) {
// success
} else {
// failure
}