最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript: Is there a way to use a string as a callback without eval()? - Stack Overflow

programmeradmin2浏览0评论

So I need to make make a callback in one of my functions, but due to the way the whole program is working, I need to pass the callback function name in the form of a string rather than the function itself.

For example:

function doThings(callback){
    alert('hello');
    eval(callback + '();');
}

function test(){
    alert('world!');
}

var func = 'test';

doThings(func);

In short, I'm trying to dynamically change which function is used, and I have to use a string to represent the callback function rather than an actual function reference.

I keep reading eval is evil - is there any way to do this without eval()?

EDIT: I do not have the ability to list out the functions in an object beforehand. I also need to pass an array as individual arguments to this function, and for some reason .apply() doesn't get along well with window[callback]()

So I need to make make a callback in one of my functions, but due to the way the whole program is working, I need to pass the callback function name in the form of a string rather than the function itself.

For example:

function doThings(callback){
    alert('hello');
    eval(callback + '();');
}

function test(){
    alert('world!');
}

var func = 'test';

doThings(func);

In short, I'm trying to dynamically change which function is used, and I have to use a string to represent the callback function rather than an actual function reference.

I keep reading eval is evil - is there any way to do this without eval()?

EDIT: I do not have the ability to list out the functions in an object beforehand. I also need to pass an array as individual arguments to this function, and for some reason .apply() doesn't get along well with window[callback]()

Share Improve this question edited Nov 2, 2016 at 10:41 geekman asked Nov 2, 2016 at 10:09 geekmangeekman 1231 silver badge6 bronze badges 3
  • Which environment are you in? In a browser you might do doThings(window[func]), window['test']() etc., so you can access the function by name from the parent scope object. – DevDig Commented Nov 2, 2016 at 10:14
  • @DevDig It's in browser. I tried that, but doing window[func]().apply(null, args) doesn't work. I should have mentioned that earlier. I need to also pass an array as individual arguments to the function. With that said, is it necessarily insecure to use eval() if I'm limiting all of the variables in it to being alphanumeric? How is this less secure than say generating SQL and sanitizing inputs? – geekman Commented Nov 2, 2016 at 10:39
  • window[func]() should do the trick as well as window[func].apply(null, args). Some informations about evil eval: javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval – DevDig Commented Nov 2, 2016 at 11:01
Add a comment  | 

3 Answers 3

Reset to default 10

You can do this, in this way.

function doThings(callback){
    alert('hello');
    window[callback]();
}

function test(){
    alert('world!');
}

var func = 'test';

doThings(func);

Or you can pass the full function in string and use the Function constructor.

function doThings(callback){
    alert('hello');
    (new Function('return '+callback)())();
}

function test(){
    alert('world!');
}

var func = test.toString();

doThings(func);

Store the functions in an object. Use the property names to access them.

function doThings(callback) {
  alert('hello');
  my_possible_functions[callback]();
}

function test() {
  alert('world!');
}

var my_possible_functions = {};
my_possible_functions.test = test;


var func = 'test';
doThings(func);

A very similar answer to @Quentin's but with additional checks

  • Check if its a part of current Object
  • Check if value is of type function. If value is not a function, it will break your code.

function doThings(callback) {
  console.log('hello ', callback);
  try {
    callbackList[callback]()
  } catch (ex) { 
    console.log(ex.message)
  }
  
  callbackList.hasOwnProperty(callback) && typeof(callbackList[callback]) === 'function' && callbackList[callback]()
}

Object.prototype.test3 = function() {
  console.log("this should not be called");
}

var callbackList = {
  test: function test() {
    console.log('world!');
  },
  test2: "World"
}

doThings('test');
doThings("test2");
doThings("test3");

发布评论

评论列表(0)

  1. 暂无评论