5 ms·
Use cases for ES6 proxies
- xpaulbettsx 10y agoHere's one way we're using ES6 proxies at Slack: https://github.com/paulcbetts/electron-remote https://github.com/paulcbetts/electron-remote Create a proxy for an ES6 module that actually creates a separate process in a task pool and executes the method there.
- cjhveal 10y agoThis is a great article. Proxies really have gotten lost in the hype around ES6. Surely it's in part because JS developers have obvious pain points with async control flow and clumsy syntax, so things like generators and generous helpings of syntactic sugar are the most visible changes. However, I'm inclined to think that the level of abstraction and the complex API make it difficult for many developers to recognize their use cases or even play around with them.
- spion 10y agoIts because proxies are too hard to compile to ES5. Every function call, array access, property access etc is potentially going to end up calling a proxy, and as such will have to be compiled to impossible-to-read code. Also, all of the examples given there can be implemented more elegantly using decorators. The more useful cases are dynamically generated method names (e.g. for ORMs) and array index access (e.g. MobX) for non-array datastructures, both of which could've been handled with a less invasive language feature...
- jannes 10y agoWhat do you think about immutable data structures as a use case? (e.g. https://facebook.github.io/immutable-js/ https://facebook.github.io/immutable-js/)
- qwertyuiop924 10y agoOn the contrary, I can think of tons of uses for proxies, from Ruby-style MethodMissing, to object.observe functionality.
- brycepj 10y agoLove those ideas.
- spion 10y agoFor a dynamic set of properties, an observable dictionary is better. For a fixed and known set of properties, its possible to enumerate them with "@observable" decorators beforehand (e.g. see MobX) Method missing is an alternative to proxies, not a feature. IMO, a lot of use cases for proxies are mistakes and/or better handled without them.
- qwertyuiop924 10y agoWhat? No. MethodMissing is far more limited than proxies. Proxies are effectively a far more complex version of Python's properties. @observable isn't part of the language, and indeed may use proxies under the surface.
- spion 10y agoYes, method missing is a far more limited alternative to proxies. But its not a use case for proxies, they just have intersecting sets of use cases. It doesn't make sense to "just" implement method_missing, you would do that so that you can implement other things on top of method_missing. @observable does not need proxies. Only implementing operator[] does. Which also could've been done with a far more limited feature, namely adding a symbol for the [] method. Proxies are just silly.
- wrong_variable 10y agoI didn't read the username but then saw 'MobX' and went 'wait a minute'
- iamleppert 10y agoNone of that code is any more clear, either conceptually or syntactically than a simply implemented and well designed library that does something purposeful and applied, like their "application" of handling validation. And if you want "private" variables in javascript, just use a closure! Do people who write these blog posts even know basic javascript these days? If you really want all the features of java [said no one ever], than why don't you just.....use java?? It's just extra cruft we're going to have to support now in our javascript runtimes. </slams door>
- nickfargo 10y ago> just use a closure! Of course, but that means allocating a closure object per method per instance. When people say they want private variables, they mean they want them available in regular prototype-mounted methods. Proxies are one way ES6 lets you implement that. (Another is to use a WeakMap structure alongside a constructor, where each instance created by the constructor is mapped to a separate object that holds the "private" properties of that instance. Methods close over the WeakMap, but, crucially, are defined once on the constructor's prototype.)
- iamleppert 10y agoThere's nothing preventing you from defining your private variable, method, whatever within the same scope as your prototype method. That could mean (for commonJS anyways) the same file. As long as you don't export those, they are effectively private.
- Touche 10y agoThose wouldn't be private to each instance though, they'd be shared by all instances.
- adrusi 10y agoI suppose I don't know for sure how JS runtimes implement them, but closures ought to be very cheap. They just need a reference to a static block of code and to any variables declared or referenced within. The most expensive part of using a closure is a heap allocation, and one extra allocation while creating an object in javascript is almost always negligible.
- madeofpalk 10y agoOne use case for us was throwing an exception when accessing an undefined property, for a very specific part of our app. Made debugging loads easier.
- scarlac 10y ago> This may be due to slow or limited support in Safari (no versions support it) It's worth noting that Safari Tech Preview actually does support it. It shows from the compatibility table that he links to. I also tested it just now, in Release 8.
- jannes 10y agoI think another reason is that ES6 proxies are impossible to polyfill. My favorite use case would be Facebook's immutable library[1], which uses awkward set(), setIn() and updateIn() methods for changing its data structures. But as an ES5+ library it wouldn't want to require the consuming code to do ES6 transpilation. [1]: https://facebook.github.io/immutable-js/ https://facebook.github.io/immutable-js/
- vertex-four 10y agoIt could reasonably provide an ES5 API over a transpiled ES6 core, for ES5 consumers to use while allowing ES6 consumers to use its ES6 API.
- __s 10y agoI have an AI which spends a large portion of time cloning game state. I'd consider proxies to implement ergonomic copy-on-write if they were portable
- brycepj 10y agoI'm intrigued, can you elaborate?
- lrsjng 10y agoanother great use case is dependency injection as seen in https://larsjung.de/ghor/ https://larsjung.de/ghor/
- zbjornson 10y agoA lot of these use cases are achievable using Object.defineProperty/Properties. In most cases I think defineProperty even provides a nicer API because it's per-property instead of per-trap. The 'has' trap can't be achieved completely with defineProperty (although you can make a property non-enumerable, which achieves the same goal in some cases). https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- inian 10y agoOne case where proxies are useful is when you do not know the properties of an Object before hand. Object.defineProperty cannot help you there..