3

My object has a call back:

var MyObject = {
CallBack: "function (whichSubMenuIsClicked, subMenuObjectTag) { self.doStuff(whichSubMenuIsClicked.SubMenuItem, whichSubMenuIsClicked.HeaderColumnName, whichSubMenuIsClicked.DivIdentifier);}",
}

The callback is a string. Now I need to execute it using MyObject.CallBack(param1, param2) How can this be done using jquery or javascript. The self in this case is the original widget calling another widget. Thus the call back is on the original widget.

5
  • 1
    WTH would you write a function as a string if it shell be used as a function? Commented Nov 23, 2012 at 14:13
  • 1
    In case not all the answers are clear, you should not be doing this. If you are receiving a function in JSON and therefore it needs to be a string, then you shouldn't be receiving a function in JSON. This approach needs to be reconsidered. It is inefficient and, as with any use of eval, insecure. Commented Nov 23, 2012 at 14:19
  • @zetlen: It is only insecure when the source of the string can't be trusted - as with every script. Also have a look at When is eval() not evil? Commented Nov 23, 2012 at 14:35
  • @Bergi you are absolutely right. Opening up a new execution context has its own security problems, but they are edge cases compared to the overall problems with running any untrusted code. Commented Nov 23, 2012 at 15:38
  • @zetlen: You are receiving all/many functions as string: downloading them as .js file by a browser request. The key here is: can the source trusted or not. Commented Jun 1, 2015 at 6:10

4 Answers 4

3

Just don't have the function as a string.

Have the function as a function:

var MyObject = {
   CallBack: function (whichSubMenuIsClicked, subMenuObjectTag) {
                  self.doStuff(whichSubMenuIsClicked.SubMenuItem, whichSubMenuIsClicked.HeaderColumnName, whichSubMenuIsClicked.DivIdentifier);
             }
}
Sign up to request clarification or add additional context in comments.

Comments

1

Use the Function constructor, which accepts a list of parameter names followed by the function body:

var MyObject = {
    CallBack: "self.doStuff(whichSubMenuIsClicked.SubMenuItem, whichSubMenuIsClicked.HeaderColumnName, whichSubMenuIsClicked.DivIdentifier)",
};

var myfunc = new Function("whichSubMenuIsClicked", "subMenuObjectTag", MyObject.CallBack);

Comments

0

You should write the function as a function, as @Curt demonstrated. Only if you really have no other choice than getting it as a string (e.g. from user input), you would first need to parse it to executable code which you then could call. The way to do so is eval. A problem will become the reference self, which is not a variable inside your function and would be assumed global. Yet, you can use a with statement to work around that:

var MyObject = {
    CallBack: "function (whichSubMenuIsClicked, subMenuObjectTag) { self.doStuff(whichSubMenuIsClicked.SubMenuItem, whichSubMenuIsClicked.HeaderColumnName, whichSubMenuIsClicked.DivIdentifier);}",
};
var widget = {doStuff: console.log};
var fn;
with( {self: widget} ) {
    fn = eval( MyObject.CallBack );
}
fn({SubMenuItem: "…", HeaderColumnName: "…", DivIdentifier: "…"});

9 Comments

You don't need eval, the Function constructor is purpose built for this.
@Asad: Is it? Where is the difference? Also, the OP already has a full function string, and not a parameter list + function body code. Also, the Function constructor does not seem to be able to handle the self variable.
The difference is that the Function constructor will never execute any statements passed to to it, whereas the eval function would execute any malicious statements sneaked in. This is pretty much the entire point behind the hubbub over the use of eval. I'm not sure what you mean by "handling the self variable".
Of course Function does not execute any line of code - only you execute the resulting function. And malicious statements could be "sneaked" into a function body as well, there's no difference.
Here's the difference: eval('function(){};alert("LOL")') vs. new Function('//note that you can't sneak in code that will be immediately executed')
|
-2

Very bad approach but You can do it by eval()

var MyObject = { CallBack: "AName = function(param1, param2) { alert(param1 + param2); }", }

eval(MyObject.CallBack+"(1,2)"); 

Demo

13 Comments

If the only solution to your problem is eval, change the problem.
@RoryMcCrossan, "Never" really?
@RoryMcCrossan You certainly don't have to use it here, but there are indeed times when eval is useful. Metaprogramming, for instance!
@Starx yup never. I edited my comment as you changed your answer, but you should never use eval.
Doesn't deserve a downvote; yes eval is terrible, but this answers the OP's question.
|

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.