Functions without ”function”

With the release of ES2015 comes three new ways to create functions in JavaScript.

// Arrow functions
const add = (x, y) => {
return x + y
}
// Concise methods
const MathUtils = {
add (x, y) {
return x + y
}
}
// Classes
class Point {
constructor (x, y) {
this.x = x
this.y = y
}
}
// Turns out, `Point` is still just a function.

People have a great time pointing at JavaScript and sarcastically saying things like “GREAT! Now there are 10 bajillion ways to create a function in JavaScript!”

I think there are 5?

// The 3 we just saw and ...
// Declarations
function add (x, y) {
return x + y
}
// Expressions
var add = function (x, y) {
return x + y
}

During our React Workshops we throw people into the fire with all three of these new ways to create functions. Invariably, folks want to know our opinion about when to use which form of function. My Answer?

Never type the word “function” ever again.

I (and most people I know) expect the value of `this` to either be the object who defined the method (or class instance), or the current `this` where the function is defined. I get that if I never type the word “function”.

When I make decisions about my code style, I frame my decisions with this question: “What would I teach a complete beginner?” because things that are good for beginners are good for everybody. The best programmers write code beginners understand.

I once thought changing the value of `this` was awesome. It could be employed to reuse code by “borrowing” methods — like this trick:

function iAmAJSHacker () {
var args = Array.prototype.slice.call(arguments, 0)
// ...
}

After several years of writing JavaScript every day, I think `slice` is the only method I’ve ever borrowed in real code. Additionally, in ES2015 there’s a better way with rest parameters:

function iAmAJSHacker (...args) {
// TADA!
}

Since I don’t actually have a use-case for borrowing functions, I don’t need to use the expression and declaration forms that make it possible to borrow them: eliminating decisions like that feels great.

Additionally, if I just never type the word “function” ever again, I will never have to screw around with binding `this` (should I pass the third arg to `map`? Should I bind at the usage or in the constructor? etc. etc.)

See?

const buy = (price, taco) => {
doAjaxStuff(price, taco)
}
class CoolThing extends React.Component {
buy (taco) {
// `this` is what we expect because I used arrows in render
buy(this.props.price, taco)
}
  render () {
const { tacos } = this.props
return (
<ul>
{tacos.map((taco) => (
<li>
{taco.name}
<button onClick={() => this.buy(taco)}/>
</li>
))}
</ul>
)
}
}

Now, the concise object methods can still be “borrowed”, but if I never type the word function there will be no conversations about function binding, all we have to do is not talk about borrowing functions anymore, and, hopefully, the era of worrying about context is over.