Human Readable JavaScript
Tags: javascript, learning, beginners, webdev
Published: 2019-09-17 12:03:22

---
title: Human Readable JavaScript
published: true
description: There are plenty of optional characters when defining functions. When used in functional methods these options increase. What are they? And how do they affect readability?
tags: javascript, learning, beginners, webdev
cover_image: https://thepracticaldev.s3.amazonaws.com/i/iourlvxqrjg3ea6ujcrf.png
canonical_url: https://tenmilesquare.com/human-readable-javascript/
---

For a long time, humans needed to "speak" like machines in order to communicate with them. And that's still true, we still have the need for people who work in assembly and other low-level languages. But for many of us, these complexities are abstracted away. Our job, is to focus on what is readable for humans and let the machines interpret our code.

This consideration is never more apparent than a situation in which identical code can be written in numerous ways. So today, I want to talk less about how something works, and more about how it reads. There is another post in here somewhere about functional JavaScript, but let's assume we're talking about `map`.

`map` is a function available for arrays in JavaScript. Think of it as `for each`. It takes a function as an argument and runs each element in the array through that function. The difference is that it doesn't alter the original array at all. The result is a new array.

### Example
```javascript
const arr = [1,2,3]
let multipliedByTwo = arr.map(el => el*2)
// multipledByTwo is [2,4,6]
```

Ok, so we know what map does. But look at the code snippet above. An incredibly terse function that multiplies a variable by two.

So let's take a look at all the different ways we could write that same logic.

## Optional Parentheses

The first optional addition we can make is to add parentheses to the parameter definition of the internal function. This makes that piece of code start to look more like a typical function definition. 
```javascript
const arr = [1,2,3]
let multipliedByTwo = arr.map((el) => el*2)
```
What's interesting about this is that the only reason we don't need them is because we're only passing one argument.

```javascript
const arr = [1,2,3]
let multipliedByTwo = arr.map((el, index) => el*2)
```
In cases where we pass more than one argument, the parens are not optional. Our example is `map`, if it were `reduce` we would always use the parentheses.

So let's take stock for a moment. Do we lose anything by adding the parentheses? Do we gain anything? We're adding two characters, what information does that convey? These are the things we need to ask ourselves as we develop code for our teammates and future selves to maintain and read.

### Curly braces and `return`

We can go a step further with making that internal function adhere to official function syntax. Doing so requires curly braces and the `return` keyword.

```javascript
const arr = [1,2,3]
let multipliedByTwo = arr.map((el) => { return el*2})
```
How do we feel about this code now? It certainly reads more clearly as a function. Do the braces and `return` add more bulk? Does our view of this change depending on the logic being returned?

As it turns out, this is again non-optional if our function logic is more than one line.


```javascript
const arr = [1,2,3]
let multipliedByTwo = arr.map(
(el) => { 
  if(el%2 === 0) {
      return el*2
  } else {
      return el+1
  }
})
```

Interesting. Does our opinion of the extra characters change based on the use case? What does that mean for consistency throughout our code?

### Use a separate function

As we know and have seen, `map` takes a function as an argument and passes each element in our array into it. Perhaps we could, or should, define our internal logic outside of the `map`. As it stands, it looks a bit like pyramid code.

```javascript
const arr = [1,2,3]

const timesTwo = (el) => el*2

let multipliedByTwo = arr.map((el) => timesTwo(el))
```
What do we think? Realistically it's almost the same number of characters as the original version. But what about our example from above with more complex logic?

```javascript
const arr = [1,2,3]

const timesTwoOrPlusOne = (el) => { 
  if(el%2 === 0) {
      return el*2
  } else {
      return el+1
  }
}

let multipliedByTwo = arr.map((el) => timesTwoOrPlusOne(el))
```

Did this change your view? Or does it look cluttered and repetitive?

### Just a function

Functional programming is an interesting paradigm. In part because of the way it allows us to write code. Again we're reminded that `map` takes a function as an argument. So why not give it a function.

```javascript
const arr = [1,2,3]

const timesTwo = (el) => el*2

let multipliedByTwo = arr.map(timesTwo)
```

Yes, this is valid. `map` knows to pass the element it gets to the function and use the result. We can get even more in the weeds by determining what form our `timesTwo` function could take. Right now it's a terse one-liner.

And note that `map` is really smart. We can pass the same function even if that function now uses both the element and the index to arrive at a return value!

```javascript
const arr = [1,2,3]

const timesTwoPlusIndex = (el, index) => (el*2) + index

let multipliedByTwo = arr.map(timesTwoPlusIndex)
```

Does this seem readable? `multipledByTwo` is certainly pleasant to read, but where is `timesTwoPlusIndex` located in our codebase? Is it hard to track down? If someone is looking at this for the first time do they know it's a function? Or do they assume it's an object or array variable? 

> Functions are objects in JavaScript, but ignore that duplication for the moment.

### How do we determine what is readable

There is no one size fits all syntax. Who is your audience? Polyglots or JavaScript experts? Who is maintaining your code? How many people work in this codebase? All of these things matter.

It entirely depends on the use case, and consistency is important. However, seeing all the different representations of the same functionality is eye-opening. All of these examples will be built into the same minified code. So the decision for us, as developers, is based on human readability. It's completely absent of machine performance and functionality considerations. 

I've posed a lot of questions and not a lot of answers. I have my own opinions but would love to hear yours. Which of these are the most readable? Are there versions you prefer to write? Let's discuss it below!