Mindshift: Part 3

Understanding JavaScript Arrow Functions

As of Chrome 45, you can now create anonymous functions in JavaScript using the arrow operator =>

The purpose of this operator is to simplify function definition syntax and sort out some annoying behaviour of the self-reference object this inside a function.

In this post, we’ll just run through the use of the arrow function; then in the next post, we’ll look at some hardcore functional concepts that can be implemented using arrow functions.

Santa’s Little Helper (Function)

Seeing as its nearly Christmas time, let’s take for our example a function that Santa might use for deciding which kids have been naughty or nice. Here, Santa has a list of kids and he wants to filter out all the naughty ones. To define such a filter, you could use the standard, familiar syntax as follows:

Ok, fine. That’s pretty straightforward.

However, let’s look at what we are actually trying to achieve here. We want the function passed to filter to examine the isNaughty property of the current array element, and return a Boolean value based on whether that property contains a certain value.

OK, simple enough.

Getting Down to Bare Bones

However, the "function(k) {" syntax is merely packaging that can (if you’re not careful) divert your attention away from what we’re actually trying to do.

If you have read my earlier Mindshift blogs, you’ll remember that functional programming focusses on the what not the how of the task at hand; therefore, it would be nice to omit the function keyword in places where a function can be assumed.

Here’s where the arrow operator comes in…

If we look only at the anonymous function passed to the array filter, it is simply the following:

Using the arrow operator, this can be reduced down simply to this:

That’s it!

So we can replace the good_kids assignment shown above with the following:

What’s happened here is that an assumption has been made. That is simply that an anonymous function is required at this point in the coding; therefore, strip out all the unnecessary syntax and focus only on what that function should do.

So in this simple case, the following syntax is omitted:

  1. The function keyword
  2. The parentheses around the parameter k
  3. The curly braces that would normally delimit the function’s code block
  4. The return keyword
  5. Since filter returns a new array, we can immediately find out how many kids have not been naughty by getting the length of this new array

What we’re left with is exactly what the function should do, without being distracted by all the syntactical packaging.

When reading an anonymous function declared by the arrow operator, you must be careful to remember that the name prior to the arrow operator is the name of the parameter, not the name of the function – all arrow functions are anonymous. In fact, in this minimal case, all the normal syntax to declare a function can be stripped away.

Notice that in the case where the anonymous function contains only a single expression, then the value of this expression equates to the value of the function, which in turn makes the need to use the return keyword superfluous.

Passing Zero or Multiple Parameters

Let’s say however, that we want to use the arrow operator to create an anonymous function that requires zero parameters, or two or more parameters. This is done simply by using a pair of parentheses to delimit the zero or more parameters. If it makes you feel more comfortable, you can always use parentheses around the parameter list, but in the case of there being a single parameter, the parentheses are not required.

So here’s an anonymous function that takes two parameters and counts the number of nice children.

In this case, the anonymous function takes two parameters acc and k, where acc is an accumulator and k is the current kid.

This function can now be passed to a reduce function in order to count the number of nice kids.

Similarly, to count the naughty kids, we could do this:

But that requires us to loop around the array twice: once to count the nice kids and a second time to count the naughty kids.

Arrow Functions Containing Multiple Statements

Up till now, our arrow functions have contained just a single expression; however, if we want to create a function that contains multiple expressions, then we must revert to using curly braces to denote a coding block.

Notice also that the return statement has popped up again. This is because in a function containing multiple expressions, it is not possible to assume that the last expression in the code block will be the required return value (for instance, when a conditional such as switch or if is used). Therefore the return value must be explicitly identified using the return keyword.

To be honest though, once you start putting multiple statements into an arrow function, the benefits of the previously compact syntax are somewhat overshadowed; however, there is still another benefit to using arrow functions – and this can clear up a lot confusion that has previously befuddled people starting out with JavaScript.

Arrow Functions and the Self-Reference Object this

When you declare a regular JavaScript function, at runtime, the self-reference variable this could be bound to a variety of different objects, depending on how that function has been called. this could be bound to:

  • A brand new object if the function is a constructor. I.E. the function has been invoked using the new keyword
  • undefined if called in strict mode
  • If called as an object method, then this is bound to the context of the calling function.
  • Any object passed to apply(), bind() or call()

Within an arrow function however, the value of this always refers to this of the function within which it has been declared. In other words, you have what is called a “lexical” this. The value of this is what you would expect it to be by looking at the lexical scope of the code at design time.

Consider how the following block of code behaves:

As every JavaScript programmer has discovered to their cost, the above code does not work as expected because the setInterval function delays the invocation of the are_you_nice function for some period of time (1000 milliseconds in this case).

When are_you_nice is then finally executed, the self-reference variable this within it no longer resolves to the expected context provided by the Kid constructor function.

This is just a pain that JavaScript developers have learnt to accept, and generally speaking, people code around it by creating a temporary variable (usually called that) in the closure created by function Kid, then referring to it in the callback function are_you_nice.

However, if we convert function are_you_nice to an arrow function, then all the this and that shenanigans disappear, because the this in an arrow function is always a “lexical” this. In other words, the this in an arrow function always refers to the same this of the function within which it was declared – even if the invocation of the arrow function is delayed because its being used as a callback.

Ahhh, that makes life a lot simpler…

Well, that’s a quick overview of JavaScript’s new arrow functions. If you want to read more about arrow functions, then visit the Mozilla Developer Network.

In the next blog, we’ll take a look at using arrow functions in the most minimal way possible – that is, defining functions that take only one parameter and contain only one expression. Then from this minimal definition, we’ll see how we can build up some very powerful function expressions.

Merry Christmas and a Happy New Year!

Chris W

All source code from the Mindshift blog series can be found on GitHub