The article is not very good, with both factual mistakes and missing important sub-properties
> 2. Array helper functions
`map`, `filter`, `reduce`, `some` and `every` were actually added in ES5.1. Only `find` and the unlisted `findIndex` come from ES6.
Meanwhile Array.from which was added in ES6 goes unlisted.
> 3. Arrow functions
While the reduction in definition boilerplate is great, missing is the very important (and convenient!) fact that arrow functions resolve `this` lexically (as a normal variable rather than a special case).
> 4. Classes
Would have benefited from mentioning the most convenient feature of classes by far: the `super` proxy to calling a method of the superclass on `this` (most useful with constructors): the ES5
<Superclass>.prototype.aMethod.call(this)
becomes:
super.aMethod()
which also helps a lot when moving methods around.
> 6. Template strings
Missing: you can "tag" template strings to invoke user-defined functions on the contents and do intermediate processing and interpolation yourself e.g.
sql`foo ${bar}`
will invoke `sql(['foo ', ''], <value of bar>)`.
> 7. Default function arguments
Missing note: unlike e.g. Python, default arguments are dynamic and sequential (similar to let<star>[0]) so you can define a `function foo(a, b=a)`.
> 8. Rest and spread operators
Actually the opposite for once, mentions that rest and spread operators can be used with object content, sadly that's currently a stage3 proposal, definitely not part of ES6.
> 9. Destructing
Missing notes:
* the destructuring is recursive (you're not limited to a single level)
* you don't have to "[assign values] to variables of the same name as properties" when destructuring objects:
let {name: a} = a_call();
will bind the value of the property "name" to the "a" local variable.
* you can provide default values to the destructuring pattern e.g.
let [a, b=3] = [1]
this can be combined with renaming for object destructuring
[0] http://docs.racket-lang.org/reference/let.html#%28form._%28%... can't use an actual star there because HN comment formatting remains a complete trash fire and thus decides to emphasize half my comment and swallow the mark of the first list item. And still does not print let∗.
I agree that the article needs some work, but there really is nothing wrong with still using var. I'm in the Kyle Simpson camp and just use var for everything except if I'm actually creating a constant or block scoping comes into play or I need to prevent the hoisting of a variable. That way, it's clear what I'm doing and what my intentions are.
> That way, it's clear what I'm doing and what my intentions are.
It's the exact opposite since you're defaulting to the most permissive binding style.
Defaulting to `const` would actually make it clear what your intent is: you use `let` if you need mutable bindings and you use `var` if you need hoisting.
If you default to `var` your intent is apparently to make use of mutable bindings and hoisting everywhere, at which point I can only expect that you put your variable declarations at the bottom of your function blocks after the `return` statement.
Defaulting to const does nothing. If you or someone else decides later that it should be reassignable, then they'll change it and not think about it. If const is rare in your code, people will be aware of what const means in that context.
If you're putting your variable declarations after your return statement, then you probably have other problems. I also don't know why you would ever expect someone to do that.
> Defaulting to const does nothing. If you or someone else decides later that it should be reassignable, then they'll change it and not think about it.
Which they'll do regardless. `const` is an indication that the binding is not updated in the rest of the scope and thus that said scope can be perused without needing to consider an update to the binding itself. It is a guarantee of SSA, nothing more and nothing less.
> If const is rare in your code, people will be aware of what const means in that context.
The same as above which you apparently assert is "nothing"?
> If you're putting your variable declarations after your return statement
Why would I do that? I'm not adamantly using `var` when I have no reason to.
If everything is a constant then nothing is a constant.
Code bases change and some things that a coder did not foresee needing to be reassignable may later need to be reassignable. There aren't frequent cases that switching them becomes a problem, and as a result, people switch them. Since they do get switched so often, people stop thinking about when it really matters or if there was some intent to it originally being written that way. If everything is a constant, then the cases where it matters and the cases where it doesn't get blended together and it's impossible to differentiate the two.
When real, true constants are the only things declared with const, then it's abundantly clear what the intention of the coder was and that the value should never be changed nor should it ever be switched over to let/var.
Likewise with let, in the few cases where it's used it draws others' attention to the use of block scoping or the avoidance of hoisting. It's rare that those things really come into play, so the few cases where it's present really stand out.
tl;dr Block scoping and constants are the exception, not the DEFAULT, so you should write code accordingly.
> If you're putting your variable declarations after your return statement
What I meant here is that people shouldn't keep using var just so they can continue writing bad code.
> There aren't frequent cases […] Since they do get switched so often
They don't. In fact they almost never do.
> tl;dr Block scoping and constants are the exception
That's literally the opposite of reality. Constant bindings (single-assignment) and block-scoped bindings are by far the most common state of affairs even if not formally stated.
> What I meant here is that people shouldn't keep using var just so they can continue writing bad code.
Maybe you should tell the you of two comments ago who's apparently arguing for exactly that?
What's with the hostility? I'm just trying to express my opinion. You can disagree and state your point without being insulting.
Sure, when I say frequent, I don't mean its happening all the time all over the place, I just means it can and does happen without consequence. Block scoping and constants, in the sense that it's important that they're block scoped and constant, are the exception. Most variables are single-assignment not out of necessity. And I bet most people think in function scope, regardless of how the compiler works.
It all still comes down to intent. If you're always defaulting to using const, your intention is not really showing through.
I think a good case can be made that examples meant to illustrate a single new feature are better if the only new features they use are that one and any others that are necessary to make a reasonable example.
That is one thing which miffed me a bit about Python 3.6's f-strings. Whether their addition is useful or not may be up for debate but the inability to process them in userland seems one hell of a missed opportunity.
> 2. Array helper functions
`map`, `filter`, `reduce`, `some` and `every` were actually added in ES5.1. Only `find` and the unlisted `findIndex` come from ES6.
Meanwhile Array.from which was added in ES6 goes unlisted.
> 3. Arrow functions
While the reduction in definition boilerplate is great, missing is the very important (and convenient!) fact that arrow functions resolve `this` lexically (as a normal variable rather than a special case).
> 4. Classes
Would have benefited from mentioning the most convenient feature of classes by far: the `super` proxy to calling a method of the superclass on `this` (most useful with constructors): the ES5
becomes: which also helps a lot when moving methods around.> 6. Template strings
Missing: you can "tag" template strings to invoke user-defined functions on the contents and do intermediate processing and interpolation yourself e.g.
will invoke `sql(['foo ', ''], <value of bar>)`.> 7. Default function arguments
Missing note: unlike e.g. Python, default arguments are dynamic and sequential (similar to let<star>[0]) so you can define a `function foo(a, b=a)`.
> 8. Rest and spread operators
Actually the opposite for once, mentions that rest and spread operators can be used with object content, sadly that's currently a stage3 proposal, definitely not part of ES6.
> 9. Destructing
Missing notes:
* the destructuring is recursive (you're not limited to a single level)
* you don't have to "[assign values] to variables of the same name as properties" when destructuring objects:
* you can provide default values to the destructuring pattern e.g. [0] http://docs.racket-lang.org/reference/let.html#%28form._%28%... can't use an actual star there because HN comment formatting remains a complete trash fire and thus decides to emphasize half my comment and swallow the mark of the first list item. And still does not print let∗.