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?

5
  • 2
    Use Function constructor instead. Commented Mar 6, 2018 at 7:01
  • Function(this.selectedFunction.body) gives function anonymous(){} around the actual function and my problem is related to passing the data to this function Commented Mar 6, 2018 at 7:02
  • 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. Commented Mar 6, 2018 at 7:09
  • Actually it does need to validate parameters ; maybe I should send a Json object and process on that Commented Mar 6, 2018 at 7:13
  • How to do it the way function node of NODE-RED does. Anyone has idea about it? Commented Mar 6, 2018 at 7:46

5 Answers 5

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

Sign up to request clarification or add additional context in comments.

6 Comments

You didn't specify any arguments in the new Function() call.
This only works if the function uses arguments instead of named parameters.
@Barmar yes, I have added a version with named parameters as well.
Your function body is the whole function, not just the body.
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.
|
13

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));

5 Comments

he only has the function body, not the whole function.
What if the parameter isn't named lim?
He has to know how his parameters have to be named in his body-strings. Otherwise @gurvinder372 's answer will suit better.
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.
I fully agree with you
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);

Comments

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
}

Comments

0

var body = "console.log(arguments)"

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

1 Comment

This looks identical to the first half of Gurvinder's answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.