Instantly share code, notes, and snippets.

What would you like to do?
Defining JavaScript functions, the ES6 way
<!DOCTYPE html>
<meta charset=utf-8 />
<title>Defining JavaScript functions, the ES6 way</title>
<h1>Defining JavaScript functions, the ES6 way</h1>
<em>Use Firefox 22 (Firefox Nightly)</em>
// old school
var square = function(x) {
return x * x;
// Expression closures
// doc:
// *Edit:* I've been told that Expression Closures are not part of ES6. Still cool.
var square = function(x) x * x;
// Arrow functions
// spec:
var square = x => { return x * x; };
// Arrow function + expression closure
var square = x => x * x;
// Destructuring assignment
// doc:
var squareAndCube = x => [x*x, x*x*x];
var [s,c] = squareAndCube(3);
console.log(s + ", " + c);

This comment has been minimized.

srirangan commented Mar 28, 2013

Examples 2 and 4 remind me of Scala. I may be in a minority but I don't find defining old-school functions as much of a pain. It's okay, really!


This comment has been minimized.

andreipfeiffer commented Mar 28, 2013

Having multiple options to write the same thing will only decrease readability.
Instead of spending 2 seconds to write the "function()" string, you will spend more time to read code, on the long run.

So, I'm not happy at all about the new ES6 syntax.


This comment has been minimized.

somethingkindawierd commented Mar 28, 2013

Regarding the last example, squareAndCube, it seems like something I might try but later refactor into more traditional code after I return to it confused by what it's doing.

The Mozilla docs cite swapping/rotating multiple variables as a benefit to this type of function. Perhaps. However, when I end up needing to swap values in my own code it typically points to a problem in my design that can be fixed elsewhere.


This comment has been minimized.

maxw3st commented Mar 28, 2013

To me it looks like a "Pitman" shorthand version of JavaScript. It clearly can cut down file sizes, but also makes it more difficult to read and interpret. That said, it looks to be a good way to re-factor code for production, but I'd want to have the same code saved in the traditional format also.


This comment has been minimized.

jerone commented Mar 28, 2013

In C# we call example 3 and 4 Lambda Expressions.


This comment has been minimized.

robotlolita commented Mar 29, 2013

Everyone saying that "writing function isn't that much of a problem" clearly is missing the point of "why shorter function syntax." Yes, writing "function ... return" isn't the problem, the problem is when you try to use the paradigm the language was supposed to (according to Brendan) support: JS is a wannabe functional language that doesn't make functional programming easy.


var square = function(x){ return x * x }
var add = function(a){ return function(b){ return a + b }}
var compose = function(f){ return function(g) { return function(){ return f(g.apply(this, arguments)) }}}
var squarePlus2 = compose(add(2))(square)
squarePlus2(4) // => 18


var square = x => x * x
var add = a => b => a + b
var compose = f => g => (...xs) => f(g.apply(this, xs))
var squarePlus2 = compose(add(2))(square)
squarePlus2(4) // => 18

With (Haskell):

square x = x * x
add a b = a + b
compose f g xs = f (g xs)
squarePlus2 = compose (add 2) square
squarePlus2 4 -- => 18

This comment has been minimized.

rwaldron commented Apr 1, 2013

@paulrouget Just a heads up, expression closures are not part of ES6


This comment has been minimized.

allenwb commented Apr 1, 2013

But curly-free, auto returning expression bodies for arrow functions are part of ES6. Basically example 2 (expression closures) isn't a standard part of ES6 but all the other examples are.


This comment has been minimized.

jiyinyiyong commented May 22, 2013

Hope I can still use CoffeeScript to handle this..


This comment has been minimized.

boban984 commented Jan 12, 2016

Arrows are not meant to replace normal functions, u can't use bind,call or apply to change the 'this', the 'this' value will be lexically bound from the function the arrow was declared inside.
I also think arrow functions don't have constructors.
This is very different to how a regular function works, although at first glance they may seem very similar.


This comment has been minimized.

CamiloMM commented Sep 3, 2016

@boban984: I was curious about your statements so I went and checked (Chrome v52). Let's see:

let wrapper = {
    method1: function() { return this },
    method2() { return this },
    method3: () => this,
    method4: function() { return (() => this)() },
    method5: function() { return (() => this) },
    method6: () => (() => this)(),
    method7: () => (() => this),

// all the following are true
wrapper.method1() === wrapper
wrapper.method2() === wrapper
wrapper.method3() === window
wrapper.method4() === wrapper
wrapper.method5()() === wrapper
wrapper.method6() === window
wrapper.method7()() === window

// of particular interest:
let wm4 = wrapper.method4.bind('wow')
let wm5 = wrapper.method5.bind('nice')
`${wm4()} ${wm5()()}` === 'wow nice'

I'm not sure why it acts like this, I thought this would always be window in an arrow function.

I also think arrow functions don't have constructors.

You don't need those, because you have classes now. I'm not sure everyone was fond of prototypal inheritance (though personally I liked it).

Moreover, you can always use traditional functional notation when you want the way it behaves. This new fat arrow notation makes Javascript more productive for functional programming (and brings it closer to languages like Haskell, while also having OOP features), and anyone who thinks it's not readable might want to stick to mantaining WordPress blog-sites and using drag-and-drop GUIs with big buttons.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment