20200703
Plan
- 你不知道的 js 下卷 第 7 章 元编程
Notes
7.4 代理 Proxy
代理的局限性
代理有很多 traps,但是有些操作无法被拦截
var obj = {};
var handlers = {...}
pobj = new Proxy(obj, handlers)
typeof obj;
String obj;
obj + " ";
obj === pobj;
obj == pobj;
可取消的代理
let { proxy: pobj, revoke: prevoke } = Proxy.revocalble(obj, handlers);
// prevoke 是一个函数,执行后,traps会被取消
// 一旦取消,触发任意trap都会报错 --TypeError
代理在先,代理在后
前面的例子都是 代理在先 的模式,因为所有的 obj 都被代理包裹了一层,要访问 obj,需要先访问代理。
下面的例子是代理在后的例子
var handers = {
get(target, key, context) {
return () => {
context.speak(key + "!");
};
},
};
catchall = new Proxy({}, handlers);
greater = {
speak(who = "someone") {
console.log("hello ", who);
},
};
Object.setPrototypeOf(greeter, catchall);
greater.speak(); // hello someone
greater.spaek("world"); // hello world
greeter.everyone(); // hello everyone!
上面的例子,通过 obj 本事去访问了 proxy 的 trap,所以是代理在后。
关于代理在前和代理在后,在希望访问某个不存在的属性时提供错误信息的时候,代理在后的模式下,代码比较优雅简洁。
// 将上面的例子中的handler修改一下
var handers = {
get() {
// 属性不存在
},
set() {
// 属性不存在
},
};
// 这样能工作的原因是因为,只有当 obj 中的属性不存在时,才会 trap 到 handler 中的 get 和 set
代理 hack [[prototype]] 链
demo 模拟原型,原理非常简单: