es6 nodejs compose

const compose = (...fns) => {
  let len = fns.length;
  let fn_index = len - 1;
  let fn_result;

  function invoke(...args) {
    fn_result = len ? fns[fn_index].apply(this, args) : args[0]
    if(fn_index <= 0){
      fn_index = len - 1;
      return fn_result;
    }else{
      fn_index--;
      return invoke.call(null, fn_result);
    }
  }

  return invoke;
}

const compose2 = (...fns) => {
  const length = fns.length;
  let index = length;
  while(index--){
    if(typeof(fns[index]) !== 'function'){
      throw new TypeError(`fns ${index} not a function.`)
    }
  }

  return (...args) => {
    let index = 0;
    let result = length ? fns[index].apply(this, args) : args[0]
    while(++index < length) {
      result = fns[index].call(this, result)
    }
    return result;
  }
}

const compose2Right = (...fns) => {
  return compose2.apply(null, fns.reverse())
}

const upperName = compose(str => str.toUpperCase(), (firstName, lastName) => firstName + ',' + lastName)
const name = upperName('flex', 'react')
console.log(name)

const upperName2 = compose2((firstName, lastName) => firstName + ',' + lastName, str => str.toUpperCase())
const name2 = upperName2('flex', 'react')
console.log(name2)

const upperName3 = compose2Right(str => str.toUpperCase(), (firstName, lastName) => firstName + ',' + lastName)
const name3 = upperName3('flex', 'react')
console.log(name3)

const upperName4 = compose2()
const name4 = upperName4('a','b')
console.log(name4)

const upperName5 = compose()
const name5 = upperName5('a','b')
console.log(name5)