How to pass parameters to an eval based function inJavascript
Asked Answered
C

4

13

I am storing function body in string with function name.

function fnRandom(lim){
    var data=[];
    for(var i=0;i<lim;i++)
    {
        data=data.concat(Math.floor((Math.random() * 100) + 1));
    }
return data;
}

After selecting the functionName from a drop down I use eval to execute function body.

JSON.stringify(eval(this.selectedFunction.body));

I want to pass 'lim' to this execution or can I use functionName as initiating point for execution somehow?

Chaille answered 6/3, 2018 at 7:0 Comment(5)
Use Function constructor instead.Skillern
Function(this.selectedFunction.body) gives function anonymous(){} around the actual function and my problem is related to passing the data to this functionChaille
Does this.selectedFunction include any information about the parameters? If not, this will be difficult, because there's no way to know which undeclared variables in the body are parameters versus global variables.Housetop
Actually it does need to validate parameters ; maybe I should send a Json object and process on thatChaille
How to do it the way function node of NODE-RED does. Anyone has idea about it?Chaille
S
22

Use Function constructor

var body = "console.log(arguments)"

var func = new Function( body );
func.call( null, 1, 2 ); //invoke the function using arguments

with named parameters

var body = "function( a, b ){ console.log(a, b) }"
var wrap = s => "{ return " + body + " };" //return the block having function expression
var func = new Function( wrap(body) );
func.call( null ).call( null, 1, 2  ); //invoke the function using arguments
Skillern answered 6/3, 2018 at 7:4 Comment(6)
You didn't specify any arguments in the new Function() call.Housetop
This only works if the function uses arguments instead of named parameters.Housetop
@Housetop yes, I have added a version with named parameters as well.Skillern
Your function body is the whole function, not just the body.Housetop
If function is only body in OP's case, then named parameters cannot be used since we don't know the names of parameters used in the bodySkillern
I know, I wrote that in a comment above. I think he has a design problem that makes this impossible to solve in a general way.Housetop
P
11

Eval evaluates whatever you give it to and returns even a function.

var x = eval('(y)=>y+1');
x(3) // return 4

So you can use it like this:

var lim = 3;
var body = 'return lim+1;';
JSON.stringify(eval('(lim) => {' + body + '}')(lim)); //returns "4"

Another way using Function:

var lim = 3;
JSON.stringify((new Function('lim', this.selectedFunction.body))(lim));
Pretence answered 6/3, 2018 at 7:9 Comment(5)
he only has the function body, not the whole function.Housetop
What if the parameter isn't named lim?Housetop
He has to know how his parameters have to be named in his body-strings. Otherwise @Skillern 's answer will suit better.Pretence
Yes, I think he has some fundamental design problems because of that. A solution like this doesn't work with arbitrary functions. He really needs to store more information in this.selectedFunction than just the body.Housetop
I fully agree with youPretence
I
4

You can use the Function object.

var param1 = 666;
var param2 = 'ABC';
var dynamicJS = 'return `Param1 = ${param1}, Param2 = ${param2}`';
var func = new Function('param1', 'param2', dynamicJS);
var result = func(param1, param2);
console.log(result);
Interloper answered 27/2, 2021 at 10:54 Comment(0)
O
0

I'm using vuejs, so the code will be like this

getTargetfunction(funcN, o_id, i_id) {
            console.log(funcN, o_id, i_id);
            const x = o_id;
            const y = i_id;
            eval("this." + funcN + "(x,y)");
        },

in the developer mozilla eval()

Indirect eval works in the global scope rather than the local scope, and the code being evaluated doesn't have access to local variables within the scope where it's being called.

  function test() {
  const x = 2;
  const y = 4;
  // Direct call, uses local scope
  console.log(eval("x + y")); // Result is 6
  console.log(eval?.("x + y")); // Uses global scope, throws because x is undefined
}
Owens answered 8/1, 2023 at 21:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.