Kissing JavaScript
Tags: javascript, firstpost
Published: 2020-03-18 17:37:39

Recently @ben asked [What makes for readable code?](https://dev.to/ben/what-makes-for-readable-code-34o7) 

There, I answered in a kind of philosophical way, but since then, I'm feeling the need to bring a more practical answer. So, I decided to accept @jmfayard's  [advice](https://dev.to/jmfayard/yes-you-should-write-that-firstpost-481), and write my first post on dev.to.

Someone once said me: the most readable code is... no code at all. 

I think this is not possible (yet). But maybe we could reduce the amount of code we write to achieve the same results without loosing readability or better yet, increase it. Focusing in terseness and readability.

I have a couple of practices I use to make my code shorter and easier to read (by myself 6 months ahead).

As a fan of the functional model, the better of my toolbox are simple functions and closures. 

The first tip I want to share is the `test()` function. 

This is one I use a lot because it helps me to reduce the complexity of my conditionals, and the amount of letters I must type and read.

```JavaScript
function test(source, v, ifnot) {
  if (!source || !v) return ifnot
  if (Array.isArray(source) && source.indexOf(v) >= 0) return v || ifnot
  if (source instanceof RegExp) return v.match(source) || ifnot
  if (typeof source == 'object') return source[v] || ifnot
  if (typeof source == 'string' && source.includes(v)) return v || ifnot
  return (source == v) ? v : ifnot
}

if(typeof window == 'object') 
  window.test = test
else global.test = test
```
I know, its a lot of `if`s for a little function, but this is its beauty, concentrated complexity for upper comfort.   

### How to use it?

I use wherever I need to test the presence of an item in a collection and also for nullability and equality).

Using it, one can write:

```JavaScript
if (test(array,'value'))
```
instead of
```JavaScript
if (Array.isArray(array) && array.indexOf('value') >= 0)
```
Also, you don't need to care if the collection is an array, object, regexp, string or null. Its always the same call. And it returns the third parameter `ifnot` if the match is falsy, this helps on string concatenations.

### A lovely use case

Lets use it in a very common pattern in JS, the `parameter,options,callback` call model, where a function receives some parameters (hopefully a few), plus a configuration object and a callback function to be called when the task is finished (All optional).

```JavaScript
function kiss(name='', op, cb){
  let s = `💋  I kiss you ${ name }`
  if (test(op, 'again')) s += ' (One more)'
  if (!cb) cb = test(op, 'callback')
  if (cb) s = cb(s)
  if (!test(op, 'secret')) console.log(s)  
  return s
}

// some different ways to call kiss()

kiss()

kiss('Honey') 

let s = kiss('Sweetie', {secret:true}) 

kiss('Cariño', 'again', 
  s => s + '\n   Wow! This is good! 😍'))
```

Note how we can pass options as string, or property of the `op` object.

Also, you can pass the callback parameter as the last parameter of the function call or a member of `op`. (Not always needed, but useful for delegation).

Another pattern that is very common in my code, is the use of single letter variables as a way to reduce the amount of code my brain must decode.

Every time I use `s` I mean a generic string without a specific name. As well `i` for index, `r` for result, `n` for number, `v` for any value and so on.

One may take care and don't abuse of this power. Too much abbreviations can make your code cryptic. I only use when the meaning is obvious, and mostly for local variables.

Here, I opted to use `op` instead of `options` and `cb` for `callback`, but I really understand if you prefer the full names.

Let me know if you enjoyed this little adventure and how would you use, change or extend the function `test()`. 

If you guys and girls like it, I would love to bring some other little tips like this in the future.

Thanks for reading.