запустить функцию javascript из строковой переменной и передать параметры

Мне нужно вызвать определяемую пользователем функцию javascript из моего плагина costom jquery и передать ей параметры, например:

function test(data)
    {
      var myfunc="function(data){alert(data);}"; //this is user defined function I   retrieved from html tag attribute
      var fn=new Function("("+myfunc+")();");
      fn.apply(this,arguments);
      return fn;
} 
test("hello");

Результат не определен, как я могу передать параметр данных из тестовой функции в пользовательскую функцию? заранее спасибо!

обновление вопроса:

Я пишу плагин jquery для обработки запроса ajax, очень похожего на ненавязчивый ajax asp.net mvc, я получаю функцию callfack ajax из атрибута тега html, например:

<div data-ajax-success="function(data,status,xhr){alert(data);}"....

значение атрибута data-ajax-success определяется пользователем, оно может быть в следующих форматах:

data-ajax-success="function(data,status,xhr){alert(data);}"
data-ajax-success="function(data){alert(data);}"
data-ajax-success="function(){alert('hello');}"
data-ajax-success="functionName"

Мне нужно проанализировать это значение атрибута как функцию javascript и передать параметры обратного вызова jquery ajax этой функции, где значением data-ajax-success является имя функции, я мог бы правильно вызвать его, используя следующий метод, определенный в Micrsoft jquery-unobtrusive-ajax.js:

function getFunction(code, argNames) {
        var fn = window, parts = (code || "").split(".");
        while (fn && parts.length) {
            fn = fn[parts.shift()];
        }
        if (typeof (fn) === "function") {
            return fn;
        }
        argNames.push(code);
        return Function.constructor.apply(null, argNames);
    }

но когда data-ajax-success является телом функции, я не мог передать ему параметр, вот мой пример кода, который обрабатывает обратный вызов ajax:

loadData: function (index, options) {
complete: function (xhr,status) {
            $(context.loading).hide(context.loadingDuration);
            getFunction(context.onComplete, ["xhr", "status"]).apply(this, arguments);
            },
        success:function (data, status, xhr) {
            $(context.updateTarget).html(data);
            getFunction(context.onSuccess, ["data", "status", "xhr"]).apply(this, arguments);
            },
            error: getFunction(context.onFailure, ["xhr", "status", "error"])
});

      $.ajax(options);
  }

кто-нибудь может мне помочь? большое спасибо!


person Webdiyer    schedule 19.09.2012    source источник
comment
Можете ли вы более подробно объяснить, откуда именно берется строка "function(data){alert(data);}"?   -  person Tomalak    schedule 19.09.2012
comment
Помогает ли это? (Используя eval)   -  person keyser    schedule 19.09.2012
comment
Могу я быть первым, кто укажет, что в целом это выглядит очень плохой идеей, и вы, вероятно, делаете это неправильно.   -  person nickf    schedule 19.09.2012


Ответы (4)


MDN описывает синтаксис объекта Function следующим образом:

new Function ([arg1[, arg2[, ... argN]],] functionBody)

Вот соответствующий пример:

// Example can be run directly in your JavaScript console

// Create a function that takes two arguments and returns the sum of those arguments
var adder = new Function("a", "b", "return a + b");

// Call the function
adder(2, 6);
// > 8

Применительно к вашему примеру кода он должен выглядеть так:

var fn=new Function("data",myfunc);

Справка:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function

person Gung Foo    schedule 19.09.2012

Вы не передаете аргумент функции fn.

Измените эту часть:

var fn=new Function("("+myfunc+")();");

к этому:

var fn=new Function("("+myfunc+")("+data+");");

Но если вы определяете такую ​​функцию, переменная data должна содержать строку json:

var fn=new Function("("+myfunc+")("+JSON.stringify(data)+");");
person timidboy    schedule 19.09.2012

Я думаю, вы неправильно используете конструктор функций. См. эту ссылку для справки:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function?redirectlocale=en-US&redirectslug=Core_JavaScript_1.5_Reference%2FObjects%2FFunction#Example.3A_Specifying_arguments_with_the_Function_constructor

person German Latorre    schedule 19.09.2012

Я решил это, изменив этот метод Microsoft:

  function getFunction(code, argNames) {
    var fn = window, parts = (code || "").split(".");
    while (fn && parts.length) { fn = fn[parts.shift()]; }
    if (typeof (fn) === "function") { return fn; } //onSuccess="functionName"
    if ($.trim(code).toLowerCase().indexOf("function")==0) { return new Function("return (" + code + ").apply(this,arguments);");} //onSuccess="function(data){alert(data);}"
    argNames.push(code);
    try {return Function.constructor.apply(null, argNames); //onSuccess="alert('hello');return false;"
    }catch(e){alert("Error:\r\n"+code + "\r\nis not a valid callback function");}
}
person Webdiyer    schedule 27.09.2012