Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

104
Vistas
Implement redux compose function but get RangeError

I am trying to re-implement redux compose function, instead of using reduce i use a for loop, here is my code:

function compose(...funcs) {
  if (funcs.length === 0) {
    return (arg) => arg;
  }

  if (funcs.length === 1) {
    return funcs[0];
  }

  let result;
  for (let i = funcs.length - 1; i > -1; i--) {
    result = result
      ? (...args) => funcs[i](result(...args))
      : (...args) => funcs[i](...args);
  }

  return result;
}

// test
function fn1(x) {
  return x + 1;
}

function fn2(x) {
  return x * 10;
}

function fn3(x) {
  return x - 1;
}

console.log(compose(fn3, fn2, fn1)(10)); // 109

It is expected to log 109 since (10 + 1) * 10 - 1 is 109, however it gives me such error:

RangeError: Maximum call stack size 

Looks like i am doing some recursion but all i did is just a for loop, no sure where is the problem of my code?

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

I think the issue is like the below example:

a = () => 2;
a = () => 3 * a();
console.log(a); 
// this prints () => 3 * a() in console
// so when you call a(), it will call 3 * a(), which will again call 3 * a() and so on
// leading to infinite recursion

My solution is slightly different using bind function based on this reference link: https://stackoverflow.com/a/6772648/4688321.

I think bind creates a new copy of the function result and binds it to a new object. Not using bind leads to recursion because then the code becomes like the above example, result calls result.

function compose(...funcs) {
  if (funcs.length === 0) {
    return (arg) => arg;
  }

  if (funcs.length === 1) {
    return funcs[0];
  }

  let result;
  for (let i = funcs.length - 1; i > -1; i--) {
    if (i == funcs.length - 1)
      result = (...args) => funcs[i](...args);
    else {
      let temp = result.bind({});
      result = (...args) => funcs[i](temp(...args));
    }
  }
  return result;
}

// test
function fn1(x) {
  console.log("fn1");
  return x + 1;
}

function fn2(x) {
  console.log("fn2");
  return x * 10;
}

function fn3(x) {
  console.log("fn3");
  return x - 1;
}

//console.log(compose(fn3, fn2, fn1));
let ret = compose(fn3, fn2, fn1);
console.log(ret(10)); // 109

about 4 years ago · Juan Pablo Isaza Denunciar

0

Rather than trying to combine functions at the time of compose, it seems much easier to combine them at the time the resulting function is called:

function compose(...funcs) {
  if (funcs.length === 0) {
    return (arg) => arg
  }

  return function (...args) {
    let result = funcs .at (-1) (...args)
    for (let i = funcs.length - 2; i > -1; i--) {
      result = funcs [i] (result)
    }
    return result
  }
}

// test
function fn1(x) {
  return x + 1;
}

function fn2(x) {
  return x * 10;
}

function fn3(x) {
  return x - 1;
}

console.log(compose(fn3, fn2, fn1)(10)); // 109

However, again, reduce make for a much cleaner implementation:

const compose = (...fns) => (arg) => 
  fns .reduceRight ((a, fn) => fn (a), arg)

or if you want to allow the rightmost function to receive multiple variables, then

const compose = (...fns) => (...args) => 
  fns .reduceRight ((a, fn) => [fn (...a)], args) [0]
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda