Proxies are a rather strategic feature that is primarily intended for implementing bindings or advanced library abstractions. Don't worry if you don't see an immediate use case for your own code. In fact, if you did, you should think at least twice before using them -- more often than not they are overkill, and there is a simpler and more efficient way to achieve the same thing.
For more info on proxies, check out this article by Assistant Professor Tom Van Cutsem. Together with Google's Mark Miller, Tom actually played a key role in the proposal of proxies for inclusion in a future ECMAScript standard during his work at the es-lab project.
Finally, check out Sindre Sorhus's negative-array project for an example of simple use case.
UPDATE:
Today, it's almost 5 years since this question was asked. While they have become part of the ECMAScript 2015 standard (aka ES6) in 2015, many browsers still haven't implemented them :
If you want to know which browsers support proxies by the time you're reading this answer, take a look at CanIUse.
Things have evolved a bit! Firefox supports Proxies natively. Using the implementation of harmony-reflect.js, you can try using proxies according to the proposed specification of Direct Proxies. This works with current Firefox or latest Chrome.
Possible use case: You have an object that represents a node in a graph containing an id, type, and arbitrary other user-defined properties. The library drawing this node to the screen wants to save screen-coordinates and similar directly to this node as well. This could possibly overwrite existing properties.
You can now hand over a proxy to the drawing library that catches access to the drawing specific properties of the node. And then, redirect them to an internal namespace property of the node - for example, drawing - to separate this data.
This way, all data according to one node can be kept in a single place. There is no need to copy and transform it around for different libraries and maybe later change the same properties in different places.
Most of the proxy "functionality" can kind of already be implemented in current Javascript. For example, getters and setters can be made as explicit "setXXX" or "getXXX" methods.
The largest up front advantages of proxies I can think of are
Taking existing behavior that currently resides in evil browser objects and allow it to be implemented with pure Javascript. (Great for browser implementors and for people writing shims)
Give you more freedom to change an implementation without breaking the interface (for example, if a property is removed from an object you might put a magic getter in its place to avoid breaking old code).
That said, I'm still curious about what other nice things are possible this new feature :)
I wrote a little code using the new proxies to make the childnodes inside the DOM be available as properties of their parent node and multi-get, multi-set and function multi-call them, similarly to the query-selectors. This cannot be done dynamically without the proxies, and using proxies made this whole code be less than one KB.
Generally talking proxies makes prototyping and meta-programming be dynamic and easy.
发布评论
评论(7)
代理是一个相当具有战略意义的功能,主要用于实现绑定或高级库抽象。如果您没有看到自己的代码的直接用例,请不要担心。事实上,如果您这样做了,那么在使用它们之前您应该至少三思而后行——它们往往是矫枉过正的,并且有一种更简单、更有效的方法来实现同样的目标。
原始提案页面上有几个示例:http://wiki.ecmascript.org/doku。 php?id=harmony:代理
Proxies are a rather strategic feature that is primarily intended for implementing bindings or advanced library abstractions. Don't worry if you don't see an immediate use case for your own code. In fact, if you did, you should think at least twice before using them -- more often than not they are overkill, and there is a simpler and more efficient way to achieve the same thing.
There are a couple of examples on the original proposal page: http://wiki.ecmascript.org/doku.php?id=harmony:proxies
有关代理的更多信息,请查看本文由助理教授汤姆·范·卡特森 (Tom Van Cutsem) 撰写。在 es-lab 项目。
此外,请注意DirectProxies。 js 已被新的 reflect.js 取代垫片。
最后,查看 Sindre Sorhus 的 negative-array 项目,了解以下示例:简单的用例。
更新:
今天,距离提出这个问题已经快五年了。虽然它们已于 2015 年成为 ECMAScript 2015 标准(又名 ES6)的一部分,但许多浏览器仍未实现它们:
如果您在阅读本文时想知道哪些浏览器支持代理回答,看看 CanIUse。
For more info on proxies, check out this article by Assistant Professor Tom Van Cutsem. Together with Google's Mark Miller, Tom actually played a key role in the proposal of proxies for inclusion in a future ECMAScript standard during his work at the es-lab project.
Further, note that DirectProxies.js has been superseded by the new reflect.js shim.
Finally, check out Sindre Sorhus's negative-array project for an example of simple use case.
UPDATE:
Today, it's almost 5 years since this question was asked. While they have become part of the ECMAScript 2015 standard (aka ES6) in 2015, many browsers still haven't implemented them :
If you want to know which browsers support proxies by the time you're reading this answer, take a look at CanIUse.
事情已经发生了一些变化! Firefox 本身支持代理。使用 harmony-reflect.js 的实现,您可以尝试根据建议的直接代理规范使用代理。此功能适用于当前的 Firefox 或最新的 Chrome。
可能的用例:您有一个对象,该对象表示图形中的节点,其中包含
id
、type
和任意其他用户定义的属性。将该节点绘制到屏幕上的库想要保存屏幕坐标,并且也直接与该节点类似。这可能会覆盖现有属性。您现在可以将代理移交给绘图库,以捕获对节点的绘图特定属性的访问。然后,将它们重定向到节点的内部命名空间属性 - 例如,
drawing
- 以分隔此数据。这样,一个节点的所有数据都可以保存在一个地方。无需为不同的库复制和转换它,也无需稍后在不同的地方更改相同的属性。
Things have evolved a bit! Firefox supports Proxies natively. Using the implementation of harmony-reflect.js, you can try using proxies according to the proposed specification of Direct Proxies. This works with current Firefox or latest Chrome.
Possible use case: You have an object that represents a node in a graph containing an
id
,type
, and arbitrary other user-defined properties. The library drawing this node to the screen wants to save screen-coordinates and similar directly to this node as well. This could possibly overwrite existing properties.You can now hand over a proxy to the drawing library that catches access to the drawing specific properties of the node. And then, redirect them to an internal namespace property of the node - for example,
drawing
- to separate this data.This way, all data according to one node can be kept in a single place. There is no need to copy and transform it around for different libraries and maybe later change the same properties in different places.
大多数代理“功能”已经可以在当前的 Javascript 中实现。例如,getter 和 setter 可以作为显式的“setXXX”或“getXXX”方法。
我能想到的代理最大的前期优势是
采用当前驻留在邪恶浏览器对象中的现有行为,并允许使用纯Javascript 来实现它。 (对于浏览器实现者和编写垫片的人来说非常有用)
给你更多的自由来更改实现而不破坏接口(例如,如果从对象中删除属性,你可以在其位置放置一个神奇的 getter 以避免破坏旧代码)。
也就是说,我仍然很好奇这个新功能还可能带来哪些其他好处:)
Most of the proxy "functionality" can kind of already be implemented in current Javascript. For example, getters and setters can be made as explicit "setXXX" or "getXXX" methods.
The largest up front advantages of proxies I can think of are
Taking existing behavior that currently resides in evil browser objects and allow it to be implemented with pure Javascript. (Great for browser implementors and for people writing shims)
Give you more freedom to change an implementation without breaking the interface (for example, if a property is removed from an object you might put a magic getter in its place to avoid breaking old code).
That said, I'm still curious about what other nice things are possible this new feature :)
首先我想指出的是,根据以下内容: http://wiki .ecmascript.org/doku.php?id=harmony:direct_proxies 直接代理是 ES 代理的最新规范,现在是草案的一部分,这意味着一旦发布,这将成为 ES6 标准live,以及最新的 gecko 引擎: https:// /developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy 已使用直接代理。
我使用新代理编写了一些代码,使 DOM 内的子节点可用作其父节点的属性,并可对其进行多重获取、多重设置和函数多重调用,与查询选择器类似。如果没有代理,这无法动态完成,并且使用代理使整个代码小于 1 KB。
一般来说,代理使原型设计和元编程变得动态且简单。
First of all I would like to point out that according to this: http://wiki.ecmascript.org/doku.php?id=harmony:direct_proxies the direct proxies are the latest specification of the ES proxies and its now part of the draft, which means that this gonna be the ES6 standard, once it goes live, as well as the latest gecko engine: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy using direct proxies already.
I wrote a little code using the new proxies to make the childnodes inside the DOM be available as properties of their parent node and multi-get, multi-set and function multi-call them, similarly to the query-selectors. This cannot be done dynamically without the proxies, and using proxies made this whole code be less than one KB.
Generally talking proxies makes prototyping and meta-programming be dynamic and easy.
对象失败安全访问,无需 eval,例如:
someObj.someMethod.someFunction('param1');
//--> someObj 不存在(具有故障安全功能,不会引发错误)
Object fail safe access, without eval, for example:
someObj.someMethod.someFunction('param1');
//--> someObj doesn't exist (with fail safe, no error thrown)
我在一个库中将 ES6 Proxies 与 ES6 Promises 一起使用来实现延迟加载:
https://github.com/Daniel-Abrecht/Crazy-Loading
ES6 代理目前在 Firefox 45 和 Edge 13 以及 Chrome 49 中工作。
I used ES6 Proxies together with ES6 Promises in a library in order to implement Lazy Loading:
https://github.com/Daniel-Abrecht/Crazy-Loading
ES6 Proxies are currently working in Firefox 45 and Edge 13, and Chrome 49.