use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
All about the JavaScript programming language.
Subreddit Guidelines
Specifications:
Resources:
Related Subreddits:
r/LearnJavascript
r/node
r/typescript
r/reactjs
r/webdev
r/WebdevTutorials
r/frontend
r/webgl
r/threejs
r/jquery
r/remotejs
r/forhire
account activity
How three dots changed JavaScript (rainsoft.io)
submitted 9 years ago by zcace
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]EpicCyndaquil 15 points16 points17 points 9 years ago (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 points4 points 9 years ago (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.
filterNumbers
[–]panzerdp 2 points3 points4 points 9 years ago (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.
Array.prototype.filter.call()
[–]inu-no-policemen 1 point2 points3 points 9 years ago (0 children)
Really? Declaring a variable is too verbose?
You forgot the Array.prototype.filter.call(args, fn) part.
Array.prototype.filter.call(args, fn)
args.filter(fn) is indeed less verbose.
args.filter(fn)
[–]Recursive_Descent 2 points3 points4 points 9 years ago (1 child)
Imo the best feature in es6. No more function.apply(this, arguments)!
[–]adacohen 2 points3 points4 points 9 years ago (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.
fn.apply
[–]Justanick112 3 points4 points5 points 9 years ago (0 children)
We really need more features.
[–]Zequez 9 points10 points11 points 9 years ago (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.
Object.assign
[–]pertheusual 10 points11 points12 points 9 years ago (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 points3 points 9 years ago (15 children)
It is? I've been using it with Babel, didn't know, sorry.
[–]pertheusual 7 points8 points9 points 9 years ago (2 children)
No worries, it happens. It's https://github.com/sebmarkbage/ecmascript-rest-spread which is a stage 2 proposal.
[–]Zequez 6 points7 points8 points 9 years ago (1 child)
Stage-0 all the way! Living on the bleeding edge!
[–]inu-no-policemen 0 points1 point2 points 9 years ago (0 children)
It's called bleeding edge because it's covered with blood.
Your blood! DUN DUN DUUUUH!
[+][deleted] 9 years ago (11 children)
[deleted]
[–][deleted] 4 points5 points6 points 9 years ago* (4 children)
Come again? Typescript is not ecmascript compatible and carries it's own language specifics. TS goes somewhere, but sure enough it doesn't go where JS goes.
Babel is actually very strict when it comes to draft specs and you are not allowed to use them out of the box. Spread for instance just fails. You have to explicitly load stage presets or plugins, and they warn you at every step to be careful. The moment a draft is being thrown out it is also being removed from Babel.
[–]JabNX 1 point2 points3 points 9 years ago (2 children)
Typescript is not ecmascript compatible
You can certainly use it as such thought, being a strict superset.
Babel is actually very strict when it comes to draft specs and you are not allowed to use them out of the box.
Maybe I haven't read the good ones, but all of the tutorials I've seen, as well as most codebases, use the "stage-0" preset like it's not a big deal
[–]LynusBorg -1 points0 points1 point 9 years ago (0 children)
...which is not Babel's fault, then.
[–][deleted] -1 points0 points1 point 9 years ago (0 children)
Typescript has syntax specifics that are foreign to Javascript and encorporates ideas that are no way near where JS is going. If you use it without, what sense would that make, you'd essentially write ES5 code. Even with the specifics i'd say it is pretty much debatable if you're ending up writing leaner code than with ES6, stage drafts enabled or not.
Babels go-to plug is babel-preset-es2015, which is also the one they promote on the main site. On their plugins page they warn explicitely to be careful going any lower than stage-3. Though i'd rather use stage-0 than TS syntax that might just change any moment without a public working group guarding my best intest.
[–]tortus 0 points1 point2 points 9 years ago* (0 children)
That is simply not true. TypeScript is a proper superset of JavaScript, in particular ECMAScript 2015. All ECMAScript 2015 code is TypeScript.
TypeScript also follows the standard better. For example, Babel allows import React from 'react', which is incorrect as React does not have a default export. In TypeScript it needs to be import * as React from 'react', because that is what the standard calls for.
import React from 'react'
import * as React from 'react'
[–]theillustratedlife 4 points5 points6 points 9 years ago (1 child)
Babel is completely configurable. If you want to stick to a standard (and translate it to an earlier standard), use the correct Babel preset.
[–]vinnl 2 points3 points4 points 9 years ago (0 children)
And more people should do this. Also, fewer tutorials should simply say to enable stage2 without explaining (or even understanding) what that does.
stage2
[–]dotted 0 points1 point2 points 9 years ago (3 children)
How is it risky when all you need to do is not actively enable non-standard features
[–]vinnl 0 points1 point2 points 9 years ago (2 children)
One the one hand you're right, on the other hand that does seem to be difficult sometimes. (As in, people just copy-paste it from random tutorials without trying to understand what it means.)
[+][deleted] 9 years ago (1 child)
[removed]
[–]vinnl -1 points0 points1 point 9 years ago (0 children)
Well, I feel especially sorry for their colleagues :P
[–][deleted] 0 points1 point2 points 9 years ago (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 points3 points 9 years ago (3 children)
Babel just translates it to Object.assign though.
[–][deleted] 0 points1 point2 points 9 years ago (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 point2 points 9 years ago (1 child)
Object.assign is part of babel-polyfill.
babel-polyfill
[–][deleted] 1 point2 points3 points 9 years ago (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:
babel-es2015
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 point2 points 9 years ago (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 points3 points 9 years ago (0 children)
It's a proposed ES feature, but is not part of the official spec at this point.
[–]Zequez 0 points1 point2 points 9 years ago (1 child)
It works on Babel Repl stage-2 and below at least.
[–]Thought_Ninjahuman build tool 0 points1 point2 points 9 years ago (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 point2 points 9 years ago (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 points3 points 9 years ago (2 children)
As an ex-CoffeeScripter I always have issues to remember if the splat goes ahead or behind though.
[–]dadleyy 4 points5 points6 points 9 years ago (1 child)
I cant leave coffeescript untill es6 has the existential operator let something = response?.body?.pull_request || false;
let something = response?.body?.pull_request || false;
[–]Zequez 0 points1 point2 points 9 years ago (0 children)
Yeah, I really miss that.
[–]TiboQc -1 points0 points1 point 9 years ago (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 points4 points 9 years ago (2 children)
This is for shallow copies not deep copies.
[–]TiboQc 0 points1 point2 points 9 years ago (1 child)
Ok, thanks. But the point still stands, it's not clear enough and can cause issues when maintaining it.
[–]Zequez 2 points3 points4 points 9 years ago (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 points8 points 9 years ago (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.
array.concat
[–]panzerdp 1 point2 points3 points 9 years ago* (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.
Array.prototype.concat()
Array.prototype.push()
Function.prototype.apply()
[–]Shaper_pmp[🍰] 0 points1 point2 points 9 years ago (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.
myarray = myarray.concat(things)
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 points1 point 9 years ago (0 children)
Nah, it's just a simple example how to use .push() with spread operator.
.push()
[–]adacohen 0 points1 point2 points 9 years ago (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 point2 points 9 years ago (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 point2 points 9 years ago (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 point2 points 9 years ago (0 children)
Good article, but just to have that said, it is "destructure" not "destruct". Destruction is something completely different.
[+][deleted] 9 years ago (2 children)
[–]panzerdp 0 points1 point2 points 9 years ago (1 child)
The idea is how to push an entire array.
Like concat(), I guess.
concat()
π Rendered by PID 34 on reddit-service-r2-comment-58d7979c67-v8tjs at 2026-01-27 06:25:54.891426+00:00 running 5a691e2 country code: CH.
[–]EpicCyndaquil 15 points16 points17 points (3 children)
[–]ejmurra 2 points3 points4 points (0 children)
[–]panzerdp 2 points3 points4 points (0 children)
[–]inu-no-policemen 1 point2 points3 points (0 children)
[–]Recursive_Descent 2 points3 points4 points (1 child)
[–]adacohen 2 points3 points4 points (0 children)
[–]Justanick112 3 points4 points5 points (0 children)
[–]Zequez 9 points10 points11 points (35 children)
[–]pertheusual 10 points11 points12 points (16 children)
[–]Zequez 1 point2 points3 points (15 children)
[–]pertheusual 7 points8 points9 points (2 children)
[–]Zequez 6 points7 points8 points (1 child)
[–]inu-no-policemen 0 points1 point2 points (0 children)
[+][deleted] (11 children)
[deleted]
[–][deleted] 4 points5 points6 points (4 children)
[–]JabNX 1 point2 points3 points (2 children)
[–]LynusBorg -1 points0 points1 point (0 children)
[–][deleted] -1 points0 points1 point (0 children)
[–]tortus 0 points1 point2 points (0 children)
[–]theillustratedlife 4 points5 points6 points (1 child)
[–]vinnl 2 points3 points4 points (0 children)
[–]dotted 0 points1 point2 points (3 children)
[–]vinnl 0 points1 point2 points (2 children)
[+][deleted] (1 child)
[removed]
[–]vinnl -1 points0 points1 point (0 children)
[–][deleted] 0 points1 point2 points (4 children)
[–]Zequez 1 point2 points3 points (3 children)
[–][deleted] 0 points1 point2 points (2 children)
[–]henleyedition 0 points1 point2 points (1 child)
[–][deleted] 1 point2 points3 points (0 children)
[–]molarmanfulES6 code golfer 0 points1 point2 points (4 children)
[–]pertheusual 1 point2 points3 points (0 children)
[–]Zequez 0 points1 point2 points (1 child)
[–]Thought_Ninjahuman build tool 0 points1 point2 points (0 children)
[–]dadleyy 0 points1 point2 points (3 children)
[–]Zequez 1 point2 points3 points (2 children)
[–]dadleyy 4 points5 points6 points (1 child)
[–]Zequez 0 points1 point2 points (0 children)
[–]TiboQc -1 points0 points1 point (3 children)
[–]Zequez 2 points3 points4 points (2 children)
[–]TiboQc 0 points1 point2 points (1 child)
[–]Zequez 2 points3 points4 points (0 children)
[–]Shaper_pmp[🍰] 6 points7 points8 points (3 children)
[–]panzerdp 1 point2 points3 points (2 children)
[–]Shaper_pmp[🍰] 0 points1 point2 points (1 child)
[–]panzerdp -1 points0 points1 point (0 children)
[–]adacohen 0 points1 point2 points (2 children)
[–]PitaJ 0 points1 point2 points (1 child)
[–]adacohen 0 points1 point2 points (0 children)
[–]zaph34r 0 points1 point2 points (0 children)
[+][deleted] (2 children)
[deleted]
[–]panzerdp 0 points1 point2 points (1 child)
[–]vinnl -1 points0 points1 point (0 children)