Pass generic form parameters through an array

Asked

Viewed 44 times

0

Having a variable number of arguments and a generic function. I want to do something like:

f(g,vetorArgs){
   return ()=>{
        //...codigo arbitrario
        g(vetorArgs[0],vetorArgs[1],vetorArgs[2],...,vetorArgs[n])
       //...mais codigo arbitrario
   }
}

In short the problem is that I need to call a function g within a function f however the function g is generic and can have an indefinite amount of arguments from 1 to n

My doubt is how to transform all the elements of vetorArgs in arguments to the function g.

The only thing I could think of was to concatenate the arguments and use eval.

f(g,vetorArgs){
    strAux = ''
        vetorArgs.forEach(arg => {
            strAux = strAux + ',' + arg
        })
        strArgs = strAux.substring(1)
        strExec = 'g('+strArgs+')'
        eval(strExec)

    return ()=>{
        //...codigo arbitrario
        eval(strExec)
       //...mais codigo arbitrario
   }

}

[Solved]

With the help of @Luiz Felipe I managed to reach the condition I wanted Upshot:

f(g,vetorArgs){
    return ()=>{
        //...codigo arbitrario
        g(...vetorArgs);  /* ou g.apply(null,vetorArgs)*/
       //...mais codigo arbitrario
   }
}

1 answer

2


Assuming vetorArgs be an array, you can use the scattering operator to "spread" the arguments to a function, which will accept a varied number of arguments - resource that called parameters Rest. Thus:

function myFunction(...args) {
  for (let i = 0; i < args.length; i++) {
    console.log(args[i]); 
  }
}

const vectorArgs = [1, 2, 3, 4];

myFunction(...vectorArgs);

These two features were introduced with the Ecmascript 2015 specification (alias ES6). So, if you need to do this in environments that might not support these features, you can use the method apply, who receives a array in its second argument and "spreads" its elements as arguments to the function.

And from within, you can use the object (array like) arguments to access them. So:

function myFunction() {
  for (var i = 0; i < arguments.length; i++) {
    console.log(arguments[i]);
  }
}

var vectorArgs = [1, 2, 3, 4];

// O primeiro argumento é o valor da variável "this" dentro da função a ser invocada.
// Neste caso pode ser `undefined`.
myFunction.apply(undefined, vectorArgs);

But note that in the first example, args is in fact a array, which was constructed using parameter notation Rest. In the second example, as said above, arguments is not a array, despite having a similar "signature". Thus, it is said that arguments is an object array-like.

So, if you receive a function as argument, you can use either of the above two modes:

// Utilizando o operador de espalhamento:
function withRest(fn, vector) {
  fn(...vector);
}

// Utilizando o método `apply`, presente no protótipo das funções.
function withArguments(fn, vector) {
  fn.apply(undefined, vector);
}

function g(a, b, c) {
  console.log(a + b + c);
}

withRest(g, [1, 2, 3]); // 6
withArguments(g, [1, 2, 3]); // 6 

But I really don’t see why something like this should be done. It seems to me that you are just re-implementing the apply or complicating something you don’t need.

What’s the difference between:

// Sua implementação:
f(g, [1, 2, 3]);

And:

g(...[1, 2, 3]);

Or:

g.apply(undefined, [1, 2, 3]);
  • In my case there is already a function defined f(a,b,c) and another g(a,b) and I want to be able to call inside an Encapsulator &#Xa function;encapsuladora (functionGenerica,vetorArrays){functionGenerica(vetorArrays[0],...,vetorArrays[n])} f(...vetArgs) and the g(...vetArgs)

  • 1

    @le314u, I edited the answer.

  • Okay, please see if it’s more understandable.

  • In the case that you mentioned at the end, my first implementation was trying to replicate ( even though I didn’t want to), after its explanation I managed to reach my goal of fact that was to encapsulate a function that performs another using the Rest parameter

Browser other questions tagged

You are not signed in. Login or sign up in order to post.