Jacob Clark Jacob Clark - 7 months ago 17
Javascript Question

How to avoid multiple variable re-declarations on function outputs in JavaScript

Consider the following example

function doSomethingToAVariable(variable){
return variable + 1
}

function doSomethingToAVariableASecondTime(variable){
return variable + 2
}

function doSomethingToAVariableLastly(variable){
return variable + 3
}

var myVariable = 0;
myVariable = doSomethingToAVariable(myVariable);
myVariable = doSomethingToAVariableASecondTime(myVariable);
myVariable = doSomethingToAVariableLastly(myVariable);

console.log(myVariable); // 6


How do I avoid the nasty myVariable re-declarations? Could wrapping each of the functions into a Promise chain be a solution?

Answer

Function composition to the rescue.
Take a look at libraries for functional programming, like Ramda, or lodash-fp.

here a plain JS snippet to compose functions:

//the compose-method you find in your regular FP-libs
var compose = (...funcs) => (value) => funcs.reduceRight((v,fn)=>fn(v), value);
//or a function wich takes the functions in opposite order, 
//wich might be more common to you
var pipe = (...funcs) => (value) => funcs.reduce((v,fn)=>fn(v), value);

compose is a direct mapping of the composition you try to build

var composition = (value) => a(b(c(value)));
var composition = compose(a, b, c);
//it calls the functions from right to left

pipe is more oriented on your known imperative style to process a value step by step

var composition = function(value){
    value = c(value);
    value = b(value);
    value = a(value);
    return value;
}
//pipe the value through c, then through b, then through a
var fn = pipe(c, b, a);
//wich in the end does exactly the same as the code built by compose

so back to your code:

var composition = pipe(
    doSomethingToAVariable,
    doSomethingToAVariableASecondTime,
    doSomethingToAVariableLastly
);
//or
var composition = compose(
    doSomethingToAVariableLastly,
    doSomethingToAVariableASecondTime,
    doSomethingToAVariable
);

//and run it
var myVariable = composition(0);