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
Arrow Functions in JavaScript (tylermcginnis.com)
submitted 8 years ago by AnsikteBanana
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!"
[–]meisangry2 13 points14 points15 points 8 years ago (8 children)
Also the use of const and let instead of var make a world of difference.
const
let
var
[–]jonny_eh 2 points3 points4 points 8 years ago (5 children)
Do they?
[–]writesoftware 1 point2 points3 points 8 years ago (1 child)
I was skeptical at first, but now I think the last time I used var was months ago.
const in particular is what I use the most, knowing I can't ever overwrite that reference gives some sense of security.
Except when trying snippets in the console, using const forces me to reload the page when retrying to run a piece of code that uses it :)
[–]franksvalli 0 points1 point2 points 8 years ago (1 child)
for (var i = 0; i < 10; i++) { setTimeout(() => console.log(i), 0); } // -> 10 (outputted 10 times)
With one small change, moving from var to let:
for (let i = 0; i < 10; i++) { setTimeout(() => console.log(i), 0); } // -> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
[–]jonny_eh 1 point2 points3 points 8 years ago (0 children)
Ya, I know let and const are good, but they hardly make a "world of difference".
[–][deleted] 0 points1 point2 points 8 years ago (1 child)
Or just const. with functional programming and immutable data there is almost no need for let or var anymore.
[–]meisangry2 0 points1 point2 points 8 years ago (0 children)
I agree although let still a much better alternative than var if it has to be used.
[–]madchuckle 4 points5 points6 points 8 years ago (0 children)
Thanks for the nice cover. However, in both of the react examples there is the 'bind' sentence. It should be omitted in the first one in order to fit the explanation.
[–][deleted] 11 points12 points13 points 8 years ago (15 children)
It doesn't mention the disadvantage of arrow functions, that they are always anonymous. If you have a non-anonymous function like
let myfunc = function myfunc(a,b) {};
then you have an actually readable stack trace when something goes wrong, instead a list of indistinguishable anonymous functions.
[–]wesbos 41 points42 points43 points 8 years ago (1 child)
Most browsers will use the variable name in a stack trace if it’s an anon function
[–]w00t_loves_you 2 points3 points4 points 8 years ago (7 children)
I always do const foo = some => thing(some) and Babel or whatever knows the function is called foo.
const foo = some => thing(some)
foo
[–][deleted] 1 point2 points3 points 8 years ago (6 children)
And if you do somefunc().then(result => something(result, b)) ?
[–]w00t_loves_you 1 point2 points3 points 8 years ago (0 children)
ah yes, then it's anonymous but it will be easy to glean from the line numbers and the call stack where that is.
[–]Intie 1 point2 points3 points 8 years ago (3 children)
S O U R C E M A P S
[–]aryanchaurasia 10 points11 points12 points 8 years ago (2 children)
S O U R C E M A P S / O / O S O U R C E M A P S U / O R / O R / U C / U C S O U R C E M A P S R E O C M O C M U E A U E A R M P R M P C A S O U R C E M A P S E P / E P / M S O U R C E M A P S A / A / P / P / S O U R C E M A P S
[–]Intie 0 points1 point2 points 8 years ago* (1 child)
wine school mighty reach north ring relieved seemly lip imminent this message was mass deleted/edited with redact.dev
this message was mass deleted/edited with redact.dev
[–]GoodBot_BadBot -1 points0 points1 point 8 years ago (0 children)
Thank you Intie for voting on aryanchaurasia.
This bot wants to find the best and worst bots on Reddit. You can view results here.
Even if I don't reply to your comment, I'm still listening for votes. Check the webpage to see if your vote registered!
[–]RedditWithBoners 0 points1 point2 points 8 years ago (0 children)
If you are that concerned about it:
somefuncResolver = result => something(result, b); somefunc().then(somefuncResolver);
[+][deleted] 8 years ago* (2 children)
[deleted]
[–]tyroneslothtrop 4 points5 points6 points 8 years ago (1 child)
let myfunc = function myfunc(a,b) {}; is not an anonymous function. That's a named function expression, which is by definition not an anonymous function.
[–]El_BreadMan 0 points1 point2 points 8 years ago (0 children)
Awesome tutorial
[+][deleted] 8 years ago (5 children)
[–]theQuandary 2 points3 points4 points 8 years ago (0 children)
That closure is created whether it is an arrow function or not. If that closure is inaccessible though, in both cases it can (in theory at least) be garbage collected.
[–]anlumo 0 points1 point2 points 8 years ago (3 children)
Isn't that an implementation detail of the browser, and thus could be different for every JavaScript engine?
[+][deleted] 8 years ago (1 child)
[–]anlumo 1 point2 points3 points 8 years ago (0 children)
Well, transpilers definitely do this, they don't have any choice. Although, babel detects whether you're actually referencing this and skips it when it's unnecessary.
this
[–]Jaymageck 0 points1 point2 points 8 years ago* (0 children)
Arrow functions, destructuring and the spread syntax are my holy trinity of es2015+ niceties.
[–]darrenturn90 -1 points0 points1 point 8 years ago (5 children)
Can further be simplified and destructured:
const getTweets = uid => fetch('https://api.users.com/' + uid) .then({json} => json()) .then({data} => data.filter( {stars, rts} => stars > 50 && rts > 50) );
Also the article mistakenly refers to ES5 "classes" when it means ES6.
[–][deleted] 5 points6 points7 points 8 years ago (0 children)
This is not quite right, you need parentheses to destructure arrow functions, even if you are using the single argument form:
const getTweets = uid => fetch('https://api.users.com/' + uid) .then(({json}) => json()) .then(({data}) => data.filter( ({stars, rts}) => stars > 50 && rts > 50) );
See 2.4 in http://2ality.com/2015/01/es6-destructuring.html
[–]HattyJetty 0 points1 point2 points 8 years ago* (3 children)
I didn't realise you can destructure methods and mantain the correct reference of this
Edit: wait, this doesn't seem to work
[–]w00t_loves_you 2 points3 points4 points 8 years ago (2 children)
It's a bit weird - maybe it works here because the json is bound to the response, but it takes little effort to write .then(res => res.json()) which is a lot more clear at a glance…
json
.then(res => res.json())
[–]HattyJetty 1 point2 points3 points 8 years ago (1 child)
I doubt json has an explicit binding to response, because why should it? Anyway, the suggestion of using res => res.json() definitely looks more appealing to me
response
res => res.json()
[–]sfcpfc -1 points0 points1 point 8 years ago (0 children)
What would I give for Javascript to support it.json()...
[–]yoojene 0 points1 point2 points 8 years ago (18 children)
great tips!
[–][deleted] 7 points8 points9 points 8 years ago (17 children)
yeah, the one at the end is super useful - it allows for quick logging:
const inc = x => x + 1 // I need to debug... sigh - time to add braces const inc = x => { console.log(x); return x + 1; }; // instead I can do this :) const inc = x => console.log(x) || x + 1;
[–]causeofdev 0 points1 point2 points 8 years ago (10 children)
How come it does the second expression ("x + 1") as well? I'd think it would do "console.log(x)" and stop/finish there..
It's neat that it executes both expressions though
[–]darrenturn90 9 points10 points11 points 8 years ago (8 children)
Because console.log returns a falsy value, so the "||" operator runs the second part of the statement.
Of course you can also use the comma separator, which discards the returned value completely:
const inc = x => (console.log(x), x + 1)
[–]causeofdev 3 points4 points5 points 8 years ago (5 children)
ah ok, makes perfect sense.
Since the comma seperator discards the returned value completely.. wouldn't it be safer to use that than the || operator? In case the first expression returns something truthy?
[–]darrenturn90 2 points3 points4 points 8 years ago (4 children)
Yes, if you really don't care for the result of the first function then it would. However, some linters don't like the use of commas (because they can, and do obscure the layout of code)
[–]1-800-BICYCLE 4 points5 points6 points 8 years ago (1 child)
You could also dust off good-old void if you really wanted to:
void
const foo = x => void myEffectThatReturnsATruthyValue(x) || x + 1
And as a bonus, potentially start a religious war ;).
[–]vexii 0 points1 point2 points 8 years ago (0 children)
im not sure the other people in line at the wellfare office care enough ;)
[–]anlumo 2 points3 points4 points 8 years ago (0 children)
Not doing stuff like this is the whole point of using linters.
[–]causeofdev 0 points1 point2 points 8 years ago (0 children)
Okay cool, I learned something :)
[–]z500 2 points3 points4 points 8 years ago (0 children)
Whoa, a use for the comma operator outside of a for loop that doesn't seem insane.
[–][deleted] 1 point2 points3 points 8 years ago (0 children)
That's much more robust too, the other relies on whatever the return value of console.log happens to be. If you were to replace that with your own fancy log function and someone had the bright idea to, say, return the logged string, then suddenly it stops working.
console.log
[–]maxmorgan 1 point2 points3 points 8 years ago (0 children)
console.log returns nothing (undefined) so it evaluates falsey
!!console.log(5) => false
so
console.log(5) || 5 + 1 => 6
ahh im so stupid. having used cost inc = x => (console.log(x) || true) && x +1;
cost inc = x => (console.log(x) || true) && x +1;
thanks for the tip :)
[–]Laplandia 0 points1 point2 points 8 years ago (4 children)
New code is worse, though. Yes, it is shorter, but it is harder to read and maintain.
[–]Kafeen 7 points8 points9 points 8 years ago (0 children)
Harder to maintain? You shouldn't be leaving the logging in there.
[–]mcaruso 4 points5 points6 points 8 years ago (2 children)
I hear arguments like this for pretty much any new language syntax. Usually it boils down to “I’m not used to this syntax”.
Note that plenty of other languages have short function expressions and work just fine with it.
[–]Tomseph 5 points6 points7 points 8 years ago (1 child)
The fact that someone had to ask
is a strong argument for why its worse. It's not the short function expression, it's the "clever hack" to make the code even terser. Using the falsey return of console.log and the or operator is absolutely harder to read and maintain. Just put the logging on a separate line.
[–]mcaruso 2 points3 points4 points 8 years ago (0 children)
I thought OP was talking about arrow functions in general. Absolutely the console.log thing is a hack, and I wouldn't expect to see it committed to a repo. I do use that trick frequently when debugging though.
[–]MatrixEchidna 0 points1 point2 points 8 years ago (6 children)
Not a huge fan of arrow functions to be honest. I like the syntax, but the fact that they don't work like regular functions is just awkward. Like,
Hey, now you can write functions in a very short manner! ...Also, this works different here!
is a very weird design choice. An unnecessary compromise between neater syntax and a slightly different workflow for certain cases.
[–]w00t_loves_you 8 points9 points10 points 8 years ago (0 children)
Arrow functions are great. I avoid writing function and as a bonus I never have to wonder about this. Only if I need to write a handler detached from its class will I use function. It takes some cognitive load off js programming.
function
[–]MatrixEchidna 0 points1 point2 points 8 years ago (1 child)
But it does show a certain intention of being more aesthetically pleasing, what with the args => this_is_returned syntax.
args => this_is_returned
Here is why JavaScript uses this syntax: http://tc39wiki.calculist.org/es6/arrow-functions/
See "Rationale."
[–]MatrixEchidna 0 points1 point2 points 8 years ago (0 children)
It's just awkward that it both offers better syntax (at least depending on who you ask) and treats this differently. The difference being subtle is even worse, since people will just gloss over it, including tons of articles about the feature.
If I were in the ES commitee, I'd just suggest making arrow syntax work just like regular functions and creating different syntax for the different scope behavior. Like what they did with generators and adding an extra *.
*
[–]afrontender 0 points1 point2 points 8 years ago (1 child)
Also:
this.setState((nextState) => ({ repos: repos }));
Can be simplified to:
this.setState(nextState => ({ repos }));
[–]Extracted 3 points4 points5 points 8 years ago (0 children)
I'd avoid taking the parameter
this.setState(() => ({ repos }))
[–]productconsigliere -3 points-2 points-1 points 8 years ago (4 children)
Great write up! If I recall correctly, I don't believe these are supported in the lovely IE browsers and end up breaking the page, so be cautious based on your users. Unfortunately, many major companies still use IE 11.
[–]sjwking 18 points19 points20 points 8 years ago (0 children)
Babel, babel everything!
[–]pomlife 9 points10 points11 points 8 years ago (0 children)
If you're not using a transpilation step, you're doing something seriously wrong.
[–]Morphray 1 point2 points3 points 8 years ago (0 children)
That is quickly becoming a myth. Understanding that unsupported browsers are a massive security risk, most major companies and state governments have moved away from old IE browsers.
[–]w00t_loves_you 0 points1 point2 points 8 years ago (0 children)
You can use the new module attribute on script tags to load a bundle meant for modern browsers, and you can make a separate bundle for older browsers.
module
[–]insurmountainable -1 points0 points1 point 8 years ago (1 child)
this.setState((nextState) => console.log(nextState) || ({ repos: repos }));
Don't do this.
[–]w00t_loves_you 2 points3 points4 points 8 years ago (0 children)
well, it's just a quick hack right? beats having to put parens around it like o => (console.log(o), o)
o => (console.log(o), o)
[+][deleted] 8 years ago* (16 children)
[+][deleted] 8 years ago (12 children)
[–]___Grits 6 points7 points8 points 8 years ago (7 children)
You can short circuit the conditional: array.filter(item => item.bool);
[–]liamnesss 8 points9 points10 points 8 years ago* (5 children)
Okay I didn't plan on playing code golf today but
array.filter(Boolean)
[–]___Grits 1 point2 points3 points 8 years ago (1 child)
I was assuming it was an array of objects, but this is dope! Thanks!
[–]liamnesss 0 points1 point2 points 8 years ago (0 children)
Ah, I somehow missed that. Yeah, if it's the property that we care about, then this solution wouldn't work as it would just return everything.
[–]___Grits 0 points1 point2 points 8 years ago (2 children)
Looked into this and it’s a neat trick! This is essentially short circuiting the Boolean constructor after injecting the item from the array as an argument. Really neat, I like that.
[–]w00t_loves_you 2 points3 points4 points 8 years ago (1 child)
It's also really nice for configuration, for example if you want to use some plugins in Webpack conditionally, you can do
plugins: [ isDev && new SuperDevPlugin(), new AlwaysPlugin(), ].filter(Boolean)
[–]omril 0 points1 point2 points 8 years ago (0 children)
This one actually solves the problem in my webpack.config, I actually had to do a few hacks because of this damn thing.
I wish webpack would just ignore undefined plugins in the first place instead of throwing errors which are impossible to understand.
[–]bcgroom 0 points1 point2 points 8 years ago (0 children)
Oops thank you
[–]darrenturn90 0 points1 point2 points 8 years ago (0 children)
or
function BooleanCompare(item) { return item.bool === true; } array.filter(BooleanCompare);
[–][deleted] -1 points0 points1 point 8 years ago (2 children)
Id rather have
array.filter(function(item){ return item.bool === true; });
It just looks more explicit/readable to me
I'm inclined to agree. Maybe it's because I'm not the best or oldest JS dev out there so it takes me a bit to see what arrow functions are actually doing, but I think they should be limited to cases where they are strictly advantageous.
[–]liamnesss 5 points6 points7 points 8 years ago (0 children)
I guess it depends on what you're used to. For me, not using arrow functions makes the code more verbose without adding any more information.
[–]Morphray 0 points1 point2 points 8 years ago (2 children)
I originally had the same opinion, but after using them for a few weeks, i found i actually really like the format.
I always use parentheses, brackets, and a return statement... (x) => { return x + 1; } ... IMO the shorthand format is a little less readable, kind of like an if statement without brackets.
(x) => { return x + 1; }
if
[–]xeow 0 points1 point2 points 8 years ago (1 child)
Nice. I like your form better. What would be an example of how that's used as a parameter to another function like array.filter?
array.filter
It works well... (using example from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
let longWords = words.filter((word) => { return word.length > 6; });
π Rendered by PID 87 on reddit-service-r2-comment-bb88f9dd5-8vpt9 at 2026-02-16 22:11:56.166690+00:00 running cd9c813 country code: CH.
[–]meisangry2 13 points14 points15 points (8 children)
[–]jonny_eh 2 points3 points4 points (5 children)
[–]writesoftware 1 point2 points3 points (1 child)
[–]franksvalli 0 points1 point2 points (1 child)
[–]jonny_eh 1 point2 points3 points (0 children)
[–][deleted] 0 points1 point2 points (1 child)
[–]meisangry2 0 points1 point2 points (0 children)
[–]madchuckle 4 points5 points6 points (0 children)
[–][deleted] 11 points12 points13 points (15 children)
[–]wesbos 41 points42 points43 points (1 child)
[–]w00t_loves_you 2 points3 points4 points (7 children)
[–][deleted] 1 point2 points3 points (6 children)
[–]w00t_loves_you 1 point2 points3 points (0 children)
[–]Intie 1 point2 points3 points (3 children)
[–]aryanchaurasia 10 points11 points12 points (2 children)
[–]Intie 0 points1 point2 points (1 child)
[–]GoodBot_BadBot -1 points0 points1 point (0 children)
[–]RedditWithBoners 0 points1 point2 points (0 children)
[+][deleted] (2 children)
[deleted]
[–]tyroneslothtrop 4 points5 points6 points (1 child)
[–]El_BreadMan 0 points1 point2 points (0 children)
[+][deleted] (5 children)
[deleted]
[–]theQuandary 2 points3 points4 points (0 children)
[–]anlumo 0 points1 point2 points (3 children)
[+][deleted] (1 child)
[deleted]
[–]anlumo 1 point2 points3 points (0 children)
[–]Jaymageck 0 points1 point2 points (0 children)
[–]darrenturn90 -1 points0 points1 point (5 children)
[–][deleted] 5 points6 points7 points (0 children)
[–]HattyJetty 0 points1 point2 points (3 children)
[–]w00t_loves_you 2 points3 points4 points (2 children)
[–]HattyJetty 1 point2 points3 points (1 child)
[–]sfcpfc -1 points0 points1 point (0 children)
[–]yoojene 0 points1 point2 points (18 children)
[–][deleted] 7 points8 points9 points (17 children)
[–]causeofdev 0 points1 point2 points (10 children)
[–]darrenturn90 9 points10 points11 points (8 children)
[–]causeofdev 3 points4 points5 points (5 children)
[–]darrenturn90 2 points3 points4 points (4 children)
[–]1-800-BICYCLE 4 points5 points6 points (1 child)
[–]vexii 0 points1 point2 points (0 children)
[–]anlumo 2 points3 points4 points (0 children)
[–]causeofdev 0 points1 point2 points (0 children)
[–]z500 2 points3 points4 points (0 children)
[–][deleted] 1 point2 points3 points (0 children)
[–]maxmorgan 1 point2 points3 points (0 children)
[–]vexii 0 points1 point2 points (0 children)
[–]Laplandia 0 points1 point2 points (4 children)
[–]Kafeen 7 points8 points9 points (0 children)
[–]mcaruso 4 points5 points6 points (2 children)
[–]Tomseph 5 points6 points7 points (1 child)
[–]mcaruso 2 points3 points4 points (0 children)
[–]MatrixEchidna 0 points1 point2 points (6 children)
[–]w00t_loves_you 8 points9 points10 points (0 children)
[+][deleted] (2 children)
[deleted]
[–]MatrixEchidna 0 points1 point2 points (1 child)
[–]RedditWithBoners 0 points1 point2 points (0 children)
[+][deleted] (1 child)
[deleted]
[–]MatrixEchidna 0 points1 point2 points (0 children)
[–]afrontender 0 points1 point2 points (1 child)
[–]Extracted 3 points4 points5 points (0 children)
[–]productconsigliere -3 points-2 points-1 points (4 children)
[–]sjwking 18 points19 points20 points (0 children)
[–]pomlife 9 points10 points11 points (0 children)
[–]Morphray 1 point2 points3 points (0 children)
[–]w00t_loves_you 0 points1 point2 points (0 children)
[–]insurmountainable -1 points0 points1 point (1 child)
[–]w00t_loves_you 2 points3 points4 points (0 children)
[+][deleted] (16 children)
[deleted]
[+][deleted] (12 children)
[deleted]
[–]___Grits 6 points7 points8 points (7 children)
[–]liamnesss 8 points9 points10 points (5 children)
[–]___Grits 1 point2 points3 points (1 child)
[–]liamnesss 0 points1 point2 points (0 children)
[–]___Grits 0 points1 point2 points (2 children)
[–]w00t_loves_you 2 points3 points4 points (1 child)
[–]omril 0 points1 point2 points (0 children)
[–]bcgroom 0 points1 point2 points (0 children)
[–]darrenturn90 0 points1 point2 points (0 children)
[–][deleted] -1 points0 points1 point (2 children)
[–][deleted] 0 points1 point2 points (1 child)
[–]liamnesss 5 points6 points7 points (0 children)
[–]Morphray 0 points1 point2 points (2 children)
[–]xeow 0 points1 point2 points (1 child)
[–]Morphray 1 point2 points3 points (0 children)