Cover image for Kissing JavaScript

Kissing JavaScript

bittnkr profile image bittnkr ・3 min read

Recently @ben asked What makes for readable code?

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, 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.

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 ifs 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:

if (test(array,'value'))

instead of

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).

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()



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.

Posted on Mar 18 by:

bittnkr profile



Thinking about bits.


markdown guide