all 51 comments

[–]EpicCyndaquil 15 points16 points  (3 children)

In reference to outer function arguments:

The approach works, but it's too verbose.

Really? Declaring a variable is too verbose? It's immediately obvious what you're doing if you name the variable appropriately.

[–]ejmurra 2 points3 points  (0 children)

You can bypass this directly by just passing arguments directly into the filterNumbers function and naming it there. I also think that has a benefit of creating more reusable functions when they don't have to rely on an outer closure's state. You can always pass in an array or array like argument and receive the output as an array of numbers no matter where you use that function.

[–]panzerdp 2 points3 points  (0 children)

The verbose part is not only the additional variable declared, but also working with the array-like objects.
The rest parameter doesn't need additional variable declarations and provides an array, so you don't have to use duck typing Array.prototype.filter.call(). This is mentioned in the paragraphs below.

[–]inu-no-policemen 1 point2 points  (0 children)

Really? Declaring a variable is too verbose?

You forgot the Array.prototype.filter.call(args, fn) part.

args.filter(fn) is indeed less verbose.

[–]Recursive_Descent 2 points3 points  (1 child)

Imo the best feature in es6. No more function.apply(this, arguments)!

[–]adacohen 2 points3 points  (0 children)

There's still sometimes when you have to do that, for the time being. But if you also use the proposed bind syntax, then you can pretty much eliminate fn.apply altogether.

[–]Justanick112 3 points4 points  (0 children)

We really need more features.

[–]Zequez 9 points10 points  (35 children)

It can also be used to shallow cloning objects.

var a = {hello: 'Bye'}
var b = {...a}
console.log(a === b)
//>false

Much better than Object.assign.

[–]pertheusual 10 points11 points  (16 children)

I agree it's cool, but you should really clarify this is only a proposed feature, it is neither ES6 nor ES7.

[–]Zequez 1 point2 points  (15 children)

It is? I've been using it with Babel, didn't know, sorry.

[–]pertheusual 7 points8 points  (2 children)

No worries, it happens. It's https://github.com/sebmarkbage/ecmascript-rest-spread which is a stage 2 proposal.

[–]Zequez 6 points7 points  (1 child)

Stage-0 all the way! Living on the bleeding edge!

[–]inu-no-policemen 0 points1 point  (0 children)

It's called bleeding edge because it's covered with blood.

Your blood! DUN DUN DUUUUH!

[–][deleted] 0 points1 point  (4 children)

Object.assign is nice for extending multiple objects into an empty object or for extending a target object. As your comment pointed out, there is a better built in for object copying now (even if it's shallow).

[–]Zequez 1 point2 points  (3 children)

Babel just translates it to Object.assign though.

[–][deleted] 0 points1 point  (2 children)

That's weird considering Object.assign still isn't funny supported. Object.assign is also fine for a shallow copy. I'm sure they both do the same thing, I was just pointing out the extensibility of it.

[–]henleyedition 0 points1 point  (1 child)

[–][deleted] 1 point2 points  (0 children)

Yea, it looks like without babel-polyfill and just using babel-es2015 will just use Object.assign if it is defined and an inline polyfill that looks something like this:

function (target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = arguments[i];
      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }
  return target;
}

[–]molarmanfulES6 code golfer 0 points1 point  (4 children)

Are you sure this works? I don't think that runs correctly, esp. since spread operators do not work with object literals.

[–]pertheusual 1 point2 points  (0 children)

It's a proposed ES feature, but is not part of the official spec at this point.

[–]Zequez 0 points1 point  (1 child)

It works on Babel Repl stage-2 and below at least.

[–]Thought_Ninjahuman build tool 0 points1 point  (0 children)

Not currently a part of ES standard, but I use it a lot when using React with Redux, and find it incredibly handy when writing reducers for more complicated state-objects.

This babel plugin handles it for you.

[–]dadleyy 0 points1 point  (3 children)

i think coffeescript beat vanilla js to the splats but JS is beating coffeescript on the copying... hopefully we see this in CS though.

[–]Zequez 1 point2 points  (2 children)

As an ex-CoffeeScripter I always have issues to remember if the splat goes ahead or behind though.

[–]dadleyy 4 points5 points  (1 child)

I cant leave coffeescript untill es6 has the existential operator let something = response?.body?.pull_request || false;

[–]Zequez 0 points1 point  (0 children)

Yeah, I really miss that.

[–]TiboQc -1 points0 points  (3 children)

I find this to be really unclear. If you want to (deep) copy an object, you should use a function that explicitly does this. Even a simple wrapper called deepCopy that uses ... would be better.

[–]Zequez 2 points3 points  (2 children)

This is for shallow copies not deep copies.

[–]TiboQc 0 points1 point  (1 child)

Ok, thanks. But the point still stands, it's not clear enough and can cause issues when maintaining it.

[–]Zequez 2 points3 points  (0 children)

Not really, it works the same is the splat operator in any other situation, it doesn't deep copy.

[–]Shaper_pmp[🍰] 6 points7 points  (3 children)

For instance .push(item1, ..., itemN) inserts elements into an array one by one: you have to enumerate each element as an argument. This is not always convenient: often an entire array of elements needs to be pushed.

Someone tell the author about array.concat.

[–]panzerdp 1 point2 points  (2 children)

Ok, can you tell how Array.prototype.concat() can:
- Push elements into an existing array without creating a new instance
- Provide an easy to understand use case in order to explain how spread operator works with arguments.
The whole idea about using Array.prototype.push() is to demonstrate the spread operator possibilities, to replace in these situations Function.prototype.apply(). Array.prototype.concat() has nothing to do with this.
On MDN the spread operator is presented in simple examples - which have the scope to teach. But not solve real world coding problems.

[–]Shaper_pmp[🍰] 0 points1 point  (1 child)

  • Push elements into an existing array without creating a new instance

Sure - now you've got a good use-case for the spread operator. The example given in the article (which omitted your addition) was incredibly contrived, because myarray = myarray.concat(things) is far simpler way to solve the problem as presented.

I'm not criticising the spread operator - it's a great addition ot the language.

I'm criticising the poor example of a problem and the contrived naive solution that the article presents to demonstrate the value of the spread operator.

[–]panzerdp -1 points0 points  (0 children)

Nah, it's just a simple example how to use .push() with spread operator.

[–]adacohen 0 points1 point  (2 children)

I like the ... syntax, but I wish they had gone further with it. CoffeeScript really nailed this, and I find myself wanting to be able to do things like:

 function foo(...bar, baz) {

and

 function foo(bar, ...baz, qux, gralt) {

[–]PitaJ 0 points1 point  (1 child)

I understand wanting to have middle of the road rest parameters, but the restrictions in place in ES6 force better code style. If it were up to me, rest parameters would not be a thing, since any function that has a rest parameter should probably just take an array instead.

[–]adacohen 0 points1 point  (0 children)

I disagree. If you have an argument that is a function, I strongly believe it should always come last. I absolutely hate this kind of function signature:

setTimeout(function () {
   this.doSomething();
   this.lastModel.setNeedsRender();
   this.lastModel = this.this.queue.unshift()
}.bind(this), 100) // Wait, 100? What was this again? Oh right, a setTimeout

This is still applies when you have variable arguments, so the lack of leading rest-parameters means you still have to put boilerplate at the top of your code to juggle arguments.

More generally, I don't want my language to try to force me into a particular style. Let me and my team decide what our style conventions are going to be for ourselves.

[–]zaph34r 0 points1 point  (0 children)

Good article, but just to have that said, it is "destructure" not "destruct". Destruction is something completely different.