None 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.
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.)
There'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.
I 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.
Well, if you weren't careful and didn't use UAP, proxies can save your bacon. They are also useful for object.observe like functionality. And that's pretty cool.
Right when I started to enjoy the in some ways lisp-like style you can program in JavaScript all these ES6 stuff came along.
I have to say, I do not like it either. The problem is that now the language becomes more and more impure introducing syntax and keywords left and right. The language lives inside browser. The old ways to do it will never go away, it will just get worse and worse and become a mixture of all kinds of patterns. All of this just because some people cannot wrap their head around scoping and prototypes.
I am fine with the rapid pace of change in tooling or libraries, but I think browsers could improve in other areas (DOM), so we could still move forward.
> Right when I started to enjoy the in some ways lisp-like style you can program in JavaScript all these ES6 stuff came along.
To be honest, it's _easier_ to do nice functional-programming in Javascript with ES6 in my opinion, just due to the cleaner syntax for destructuring assignment, lambdas, and block-scoped variables.
Sure I can write functional es6, but now what is going to stop my coworkers from writing Java in JavaScript with es6?
Pretty much the only thing JavaScript had going for it was it's simplicity. Maybe simple is the wrong word, perhaps smallness is better. Sure js packed a ton of wtf into a small language, but once you grokked the weirdness of scoping etc. you were set to understand almost all its code. This is even better if you restricted yourself to the "good parts" ala Douglas Crockford as pretty much all js devs do now. It is a crummy version scheme that you actually get to use in your day job.
Sure arrow functions and "real" classes are objectively better, but I'm afraid of how enterprisey devs are going to react to them. I can foresee Java style coding guidelines being imposed upon es6 that would be very much opposed to functional styles of coding. It is a bit immature, but a lot of the hesitancy for es6 seems to be of this sort of fear that the Java dev culture will feel more at home with es6 and then stop ignoring js possible changing js dev culture in the process.
People have been doing pseudo-classical inheritance in JavaScript since forever ago, but every framework had their own slightly different way of doing it. Might as well give them a "blessed" syntax to standardize on.
I can't help but say it - but nobody programs in Angular or React, people program in JavaScript. When using a framework like Angular or React there are plenty of reasons to use ES6 classes, whether in the view code, or in more idiosyncratic app actors like utils or business logic ... the benefits of having a standardised syntax should be obvious. Likewise, many people contribute to these libraries and frameworks, again using a standard syntax for common patterns is obviously beneficial to my mind.
I was just illustrating the fact that there are already communities with standards. It is fine for me that some use CoffeeScript or TypeScript. There are much smaller communities in other programming languages, which also work great, so I don't see a benefit in combining them. In the contrary I would say most of the time the bigger the community gets the lower the standard falls.
I agree with you and the parent, but let me play devil's advocate for a minute...
CSS? Put that sh!t in feature freeze, like, yesterday. Because javascript.
Javascript? Put that sh!t in feature freeze, like yesterday, because wasm.
Except... at least the reflection API's seem to "get it"—that you can't just keep adding features willy-nilly. I'll take a new metaprogramming feature that deprecates an equal number of old ones. And if you look at the MDN article the OP referred to, the reflection API is apparently intended to obsolete several existing built-ins. And as the OP also indicates, Proxy also lets programmers implement things that would otherwise be the VM's job.
But of course, unlike the auto industry, we can't actually realize obsolescence, so, like I said, I agree with you.
True. I just fear that all languages are approaching each other until we arrive at some mess that is optionally statically-typed, object-oriented, but with functional patterns.
This 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.
Its 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...
For 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.
Yes, 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.
I 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.
A 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).
> 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.
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.