我最近了解了 ES6 代理,但我没有看到使用它的充分理由。我的意思是,使用 Proxy 可以做的所有事情都可以在没有它的情况下完成,除非我遗漏了一些东西。
例如,大多数人在谈到代理时都会谈论验证,但可以应用一些 JS 优点来进行验证,这样每个人都很好。如果有人能让我了解代理的一些主要用例,我将不胜感激。谢谢!
我的意思是,使用 Proxy 可以做的每一件事,没有它也可以完成......
如果这是真的,TC39 就不会添加代理。但事实上,有些事情是你没有 Proxy 就无法做到的。 考虑捕获对不存在的属性的访问的常见需求:
const o = { foo: "bar" };
console.log(o.blarg);
通常希望以默认方式以外的方式处理该问题,即访问
o.blarg
导致
undefined
:
const o = { foo: "bar" };
console.log(`foo: ${o.foo}`);
console.log(`blarg: ${o.blarg}`);
代理让我们通过
get
陷阱
做到这一点。例如,您可以抛出错误:
const o = { foo: "bar" };
const p = new Proxy(o, {
get(target, prop, receiver) {
if (prop in target) {
return target[prop];
}
throw new Error(`Property "${prop}" doesn't exist in object`);
}
});
console.log(`foo: ${p.foo}`);
console.log(`blarg: ${p.blarg}`);
另一个例子是能够挂钩获取对象属性列表的各种操作。如果没有代理,就没有办法连接到它。
使用 代理,这很简单:您可以使用 has
trap
或
ownKeys
trap,具体取决于您想要挂钩的内容。就其他用例而言:代理是实现Facade模式
元编程的动态编程(如在动态语言中,而不是解决问题的方法),并且绝对不是任何可以用代理完成的事情都可以完成没有他们。事实上,这确实是代理存在的原因:启用以前不可能的全新功能。 代理使您能够拦截对对象的操作,否则这些操作将纯粹由 JavaScript 引擎负责;属性访问和修改是两个明显的例子。
T.J. 的回答是一个很好的例子,说明了没有代理就无法做到的事情。再给您介绍一下,我正在使用代理来启用客观实体的单例实例,以允许将其支持数据存储换出并替换为全新的对象,而不会影响指向这些对象的引用。
要在没有代理的情况下执行此操作,我们必须迭代对象的每个字段并将它们交换为新对象中的新字段。虽然 JavaScript 确实足够动态,足以允许这种情况成为可能,但代理允许以一种更优雅的方式解决它:代理的隐藏后备存储只需替换为新对象,并且所有未来的属性访问都只需指向新的后备存储而不是旧的后备存储,而对对象(实际上是代理)的外部引用则不需要更明智。对他们来说,它看起来好像是同一个对象(因为它确实是),但现在它背后恰好有完全不同的数据。
这只是代理的用途之一。由于他们的活力,他们确实非常强大。我刚刚认识他们,但我已经可以说我已经爱上他们了。 :)
proxyObj.newProp = 9
,Proxy 将微笑并毫无偏见地设置新属性。