Despite what people may say, ES6 is turning out to be a pretty great language all around. Type coercion is still pretty annoying and is there to stay, but the new features are all mostly well done.
Now if we can only get the bind operator [1] in a timely manner, everything will be awesome.
Hadn't seen that proposal before. It's definitely interesting.
My first impression is that it's kind of confusing to read, but I suspect I'd get used to it.
Sort of similar to some of the destructuring assignment stuff, e.g. `let { address: { street } } = user;`. Awkward at first, but now I'm kind of into it – although I still think people are likely to abuse it.
Also keep in mind that Traceur adds its own global runtime, I usually recommend 6to5 instead (despite what the name suggests, it supports some ES7 features as well and even JSX).
A lot of these features look great, and some of them are even useful. I think it's a shame that async/await has to wait for ES7. It would really give some direction to the node community and give JS an edge for async programming. Generators just look like another awkward attempt to avoid callbacks by jumping through different hoops.
Generators have long been used in the Python community for reasons other than callback avoidance (they are lazy sequences). Generators in ES6 (as well as several other features) seem to be inspired by Python.
There's no reason we'll have to wait for ES7. Seeing as how good 6 to 5 transpilers already are, I'm sure you'll be able to use await relatively soon.
Generators in Python are a very useful feature (lazy sequences, like you said), so maybe I spoke to soon. However, I don't think people should be lauding this feature as some kind of solution to callback hell.
I just feel like priority-wise, users would benefit most from modules (which made it), async/await, maybe class syntactic sugar, then everything else.
FWIW, most of the stuff I've read on using generators to wrangle async has stressed that that's not the aim of the protocol, it's just a useful side-effect. But I think you are right, which is a bit of a shame really, given how useful generators can be - most every detailed article quickly skips through pretend toy examples, then <drumroll>aaaand async
As much as it sucks that it probably won't be in v8 or iojs native for a bit.. you can use co/koa for now, or you can use 6to5 or another transpiler to get the async/await features now.
what?? So it uses parens if there are no params, but not otherwise?
Template Strings:
`In JavaScript this is
not legal.`
Seriously another String delimiter?
`Hello ${name}, how are you ${time}?`
Why aren't we just using #{} like everyone else?
// Construct an HTTP request prefix is used to interpret the replacements and construction
GET`http://foo.org/bar?a=${a}&b=${b}...
What??
Destructuring:
var [a, , b] = [1,2,3];
Is that seriously just whitespace and another comma?
Splats (spreads?)
f(...[1,2,3]) == 6
... means destructure?
This is not readable code:
let fibonacci = {
[Symbol.iterator]() {
let pre = 0, cur = 1;
return {
next() {
[pre, cur] = [cur, pre + cur];
return { done: false, value: cur }
}
}
}
}
for (var n of fibonacci) {
// truncate the sequence at 1000
if (n > 1000)
break;
print(n);
}
Modules are cool.
Promises are cool.
Tail call optimization is cool.
This is not readable code:
// Proxying a normal object
var target = {};
var handler = {
get: function (receiver, name) {
return `Hello, ${name}!`;
}
};
var p = new Proxy(target, handler);
p.world === 'Hello, world!';
Is about as readable as it gets (inspired by C#, Java8, CoffeeScript), as a benefit of succinct syntax sugar we get intuitive `this` binding - i.e. pit of success.
[ 'prop_' + (() => 42)() ]: 42
> what?? So it uses parens if there are no params, but not otherwise?
Again not surprising, a leading `=>` would be a syntax error so `()` is an obvious compromise which can be naturally be extended to add args, e.g:
evens.map((v) => v + 1)
> Seriously another String delimiter?
`Hello ${name}, how are you ${time}?`
Yep, String interpolation is incredibly useful especially in JavaScript which does a lot of string munging - this will lead to more succinct, readable code. Should be obvious why they didn't want to break existing JS by re-using "" double-quotes.
> Why aren't we just using #{} like everyone else?
Who's everyone else (Ruby inspired langs)? Scala uses ${1 + 1} or $var shorthand (same as Groovy, Kotlin, JSP EL, Haxe), C# 6 uses {var}, Swift uses \(var) whilst Python and Java have string formats that use %(var)
var [a, , b] = [1,2,3];
> Is that seriously just whitespace and another comma?
It's clearly ignoring matching the second element. Some languages choose to use `_` as a special ignore placeholder, JavaScript chose not to. Either way is not unintuitive with what it does so that's ok.
The other features are extremely useful if you need them, otherwise you can happily ignore them and use the subset you're comfortable with.
let fibonacci = {
[Symbol.iterator]() {
let pre = 0, cur = 1;
return {
next() {
[pre, cur] = [cur, pre + cur];
return { done: false, value: cur }
}
}
}
}
for (var n of fibonacci) {
// truncate the sequence at 1000
if (n > 1000)
break;
print(n);
}
I love how the only comment is explaining what "if (n > 1000) break;" does
Sure, you abuse the new syntax to make unreadable code, but most people will probably use it to abbreviate much of the syntax noise that plagues Javascript today.
Maybe its just me but the only things that I really like from this document are "Unicode", and "Tail Call", though some other things may be nice, the verbosity is killing me, how many new keywords, synatic constructs, and symbols are coming in with ECMA6?
Though I have no say in the matter, for my 2 cents, I just wish they had used ECMA6 to remove things (mainly those listed here: http://johnkpaul.github.io/presentations/empirejs/javascript... and in Crockfords famous book http://archive.oreilly.com/pub/a/javascript/excerpts/javascr...) for instance.
In JavaScript you can't make any backward incompatible changes, let alone remove anything. Because what browser would want to implement stuff that breaks websites for its users?
It seems a little odd that class functions do not need a keyword. Speaking of which it would have been nice if we could use the shorter `func` instead of `function`. But in any case, I'm just glad private class members didn't make the cut. Whomever was responsible for that, thank you!
While a lot of these changes are cool, I'm worried that starting to work with javascript just got a lot harder. Although, I do appreciate the Class foo extends bar {...} syntax, now maybe we can have one simple way of doing inheritance which is readable to someone new to javascript.
A lot of it just feels like cleaner versions of patterns people have been using for a long time. There's a few things I'm worried about:
* Tagged template strings might have some potential to be abused in interesting ways, since it looks like the tag function doesn't actually have to return a string.
* The Object destructuring/enhanced literals (and the Object rest/spread proposal in ES7) still take a lot of mental energy for me to parse. I'm worried they could be a maintenance liability in large projects, but that remains to be seen.
* Async functions/generators in ES7 will probably take a while to get used to, as well, but I felt the same way about Promises when they were first introduced, and they didn't turn out to be too bad. I don't have an issue with normal Promises/generators, so this might just be a matter of me needing to see the async stuff as a whole instead of the sum of its parts.
JavaScript is a mainstream language. That means average people like myself can be very productive with it. It is easy to learn and it's easy to find people who can maintain JS code.
But it seems you need to be an academic in programming languages just to figure out what these new features do, and why they are needed.
I'm afraid that the rapid development will make it harder to learn the language. And will introduce a lot of pitfalls and edge cases.
It honestly blows my mind that there is backlash against ES6. The new features solve so many pain points I've experienced in MVC and library development:
- ridiculously verbose syntax for anonymous functions
- lack of a module system
- no string interpolation (seriously!)
- no block scoping - super annoying
- lack of language level support for immutability
- clumsy 'this' management
- clumsy variadic functions
- competing promise implementations
- competing and poorly interoperating class implementations
... And so on. This is a huge step forward and it should help redefine Javascript coding style in a much better way. My only complaint is that they didn't deprecate poorly designed features of the past.
I've never read any programming books or taken any classes, I've just read a lot of code written by others and also written some myself. Here's my advice after 15 years of reading both brilliant and shitty JS code:
a) Don't use anonymous functions ... You want your program to be easy to understand, so come up with a name for the function and put it as a sub-function at the bottom of the current function.
b) I love the Nodejs implementation of modules and I would say it's the main reason behind Nodejs success. But it doesn't make sense in the HTTP world. Imagine having to download 100 dependency files each time you visit a webpage.
c) I have a keyboard macro for " + + ". So if you don't save an extra keystroke, what's the deal? It might be useful if you have nasty habits like building HTML or SQL by concatenating strings though. (don't do that).
d) Just declare your variables at the top of the function and stop worrying about scope, (while listening to Bobby McFerrin.)
e) I can somewhat agree here. But where it's really needed you should make a copy or clone function. And if it's not really needed you shouldn't. Makes you write less complicated code because of laziness.
f) Give it a name!
function Car() {var car = this;}
Or if you don't want people to understand your code:
var that = this;
g) You are probably trying to make your function do too much! If you Do want to have one function to rule them all, pass an object to it.
h) It's possible to make async code intuitive. Stop using anonymous functions will help a lot! But it's not That easy. Promises is just another (ineffective; it just threats the symptoms) paradigm to reason with async code.
i) We don't need classes. The prototype already work great. It might be hard to learn but once you understand it's brilliant! (I don't blame you if you never will, it's hard to learn an old dog to sit).
I encourage you to use the paradigms you believe in, and also to try different solutions, and think outside the box. But don't force certain paradigms by changing the language itself. One exception being Node.js where you are forced into making modules. (but some people are stubborn and use Browserify to circumvent it).
I'm aware there are workarounds for all of these things, but they all result in a ridiculous amount of boilerplate and syntactic noise. To me, naming a simple function that's an argument to, say, `.map(...)` and putting it at the bottom of a function is pretty heavyweight.
Many of your suggestions are just optimizing for the current state of JS instead of thinking about how to best leverage the many brilliant syntactic advances from throughout the industry. I guess there's no point in arguing. Change is coming, and people can keep writing super verbose JS if they like; I'll be writing code that more directly reflects the actual important logic.
I can't come up with a real world use for the .map function, but then I only use Arrays when I do evil things like writing optimized code. If I however would end up in a situation where I wanted to do:
var odds = evens.map(v => v + 1);
I would write this instead:
var odds = increment(evens, n);
But it's never as simple as this, evens would probably be some sort of async object and you probably want to call another function once the "incrementation" has completed.
The only thing => does is to make the syntax more complex (and ugly) by saving a few keystrokes. And even worse, it's a treatment for a symptom from anonymous functions, that you shouldn't even use in the first place. And will be used everywhere, because we are lazy. But the time saved, will have to be used for mind juggling, to figure out what goes where in the syntax.
That said, I don't think all new stuff is useless. For example Object.defineProperty (ES5) that actually Adds to the language, and makes it possible to do things you couldn't do before. Like defining a set function.
That is a loaded example that deliberately leaves out the implementation details to disguise the productivity gains. If you really can't see the productivity difference between writing this:
var elems = ['#hp','#mp','#gp'];
var getVal = function (x) { return $(x).val() };
var mtVals = [];
for (var x = 0; x < elems.length; x++) {
mtVals.push(getVal(elems[x]));
}
... then maybe you should actually go read some of those programming books you're so dismissive of.
I'll try to interpret the code ...
You have an array of string values.
You use the .map function to iterate through all the strings.
For each string you change the string to whatever is returned from $(x).val()
(basically just juggling data, you should make a real world example.)
I have seen Jquery before so I know $ returns a document element. And if you pass # into it, it will return getElementById().
And .val() returns .value
So my guess is that you want to get the values of hp, mp, gp, whatever that is. I don't understand why you want them in an array though!? Wouldn't it be better to store them in an associative array? So that you don't have to remember what position in the array points to what value.
Try this instead:
var signupForm = getFormData("signupForm");
alert( "Your name is " + signupForm["name"] );
Or without the abstraction:
var name = document.getElementById("name").value;
A little more characters to type, but you don't have to learn a framework to know what it does. A trick here is to use keyboard macros to do the boilerplate. Don't var PI = Math.PI because of laziness.
I prefer document.getElementById("myKitten") because it's easier to read and more describing then just $("#myKitten")
If it's too long to type, and you use it often, make a macro for it.
When naming stuff, keep it short and simple though.
Also, you shouldn't hide logic behind names. I was actually wrong about evens.map(v => v + 1); If that's what you want to do, then write that. It's a thin line though, it might be hard to know what "v" is in that context.
this is an interesting perspective that I don't really understand and hope you will expand on. Which parts of the es6 changes do you feel you need to be an academic to understand? The es5 spec is 6 years old at this point and it feels to me like es6 is taking forever to be implemented. Most of the changes are there to make things more consistent and reduce pitfalls and edge cases - let and const to solve the problems with var, fat arrows make functions cleaner and solve the this binding problem, classes and modules formalize what everyone has been trying to do in JS for years just in different ways. No doubt there's some learning to do, but on the whole it seems like a very conservative and solid list of enhancements.
The majority of JS developers do not know what a scope is, what Destructuring and Rest + Spread means, what a generator does, and have never heard of Map + Set + WeakMap + WeakSet.
Getting it to play nicely with my code coverage tool was a bit tricky, but aside from that it wasn't bad at all.
Bear in mind that ES6 is fully backwards-compatible with ES5, so you can set up a transpiler without having to actually rewrite your whole codebase right off the bat. It's pretty easy to upgrade gradually if you need or want to.
Unfortunately Symbols are not that useful when it comes to private properties in classes. A better approach would be to use use weakmaps to have private properties.
The problem with symbols is the absence of symbol literal syntax(along with the fact that one can access symbols through reflection).
It's really hard to find browser support information for each of those.
And every browser vendor chooses to develop every feature in different pace and order.
I know about that. But seemingly it only shows limited set of browser versions.
For me the most important thing is: what was the first version to support this feature. So I know I can actually use it -- comparing to my users' browser usage stats.
`var` is still there, but it is scoped differently - `let` scopes to blocks, e.g. if (foo) { let baz = 'quux'; ... }
`let` in function scope is the same as `var`, in block scope it's narrow, it's basically the thing you want. `var` couldn't change, though, it would have broken existing code - hence `let`/
Now if we can only get the bind operator [1] in a timely manner, everything will be awesome.
[1]: http://wiki.ecmascript.org/doku.php?id=strawman:bind_operato...