3

在 JavaScript 中,函数是否可以将自己的函数调用作为字符串返回?

function getOwnFunctionCall(){
    //return the function call as a string, based on the parameters that are given to the function.
}

我希望这个函数简单地将它自己的函数调用作为字符串返回(如果它甚至可以这样做的话):

var theString = getOwnFunctionCall(5, "3", /(a|b|c)/);
//This function call should simply return the string "getOwnFunctionCall(5, \"3\", "\/(a|b|c)\/")".
4

6 回答 6

2

我把这个放在 jsFiddle 上:http: //jsfiddle.net/pGXgh/

function getOwnFunctionCall() {
    var result = "getOwnFunctionCall(";
    for (var i=0; i < arguments.length; i++) {
        var isString = (toString.call(arguments[i]) == '[object String]');
        var quote = (isString) ? "\"" : "";
        result += ((i > 0) ? ", " : "");
        result += (quote + arguments[i] + quote);
    }
    return result + ")";
}

alert(getOwnFunctionCall(5, "3", /(a|b|c)/));

请注意,这应该适用于您的示例,但仍需要适用于作为参数包含的任意复杂对象/JSON。

于 2013-05-01T19:05:53.817 回答
2

http://jsfiddle.net/WkJE9/4/

function DisplayMyName() 
{
   //Convert function arguments into a real array then let's convert those arguments to a string.
   var args = [].slice.call(arguments).join(',');

   // Get Function name
   var myName = arguments.callee.toString();
   myName = myName.substr('function '.length);
   myName = myName.substr(0, myName.indexOf('('));

   return(myName + " ("+ args + ")"); 
}

var functionText = DisplayMyName(5, "3", /(a|b|c)/) //returns DisplayMyName(5, "3", /(a|b|c)/)
alert(functionText);
于 2013-05-01T19:06:39.807 回答
1

使用隐式arguments变量,您可以提取函数参数和函数名称:

function getOwnFunctionCall() {
    var args = arguments; // Contains the arguments as an array
    var callee = arguments.callee; // The caller function
    // Use this to construct your string
}

编辑

一些评论指出,这callee不是可以依赖的。但是,如果这是您要在每个方法中执行的操作,则只需使用您定义的函数名称:

var functionName = "getOwnFunctionCall"; // But you can really just use it inline...
于 2013-05-01T18:54:25.310 回答
1

如果您需要这样做,并且需要在全局严格中进行,并且您不想对名称进行硬编码:

function args(arg){
 var me;
  try{ badCAll654(); }catch(y){  me=String(y.stack).split("args")[1].split("\n")[1].trim().split("@")[0].replace(/^at /,"").split(" ")[0].trim() }
  return  me +"("+[].slice.call(arg).join(", ")+")";
}



function getOwnFunctionCall() {
  "use strict";
  return args(arguments);
}


getOwnFunctionCall(1,true, /dd/);

这可能是一个很好的调试工具,但我不建议在生产站点/应用程序上使用它;它会对性能产生相当大的影响。此模式仅适用于 chrome 和 firefox,但适用于全局“使用严格”。

IE9 不那么严格,因此您可以执行以下操作:

function args(arg){
 var me=arg.callee+'';
  return  me.split("(")[0].split("function")[1].trim() +"("+[].slice.call(arg).join(", ")+")";
}   

function getOwnFunctionCall() {
  "use strict";
  return args(arguments);
}


getOwnFunctionCall(1,true, /dd/);

如果你填充 trim()s,它也应该在 IE8 中工作。如果你不使用严格,你可以做更酷的事情,比如记录调用被记录函数的函数。如果您想要参数的名称而不仅仅是值,您甚至可以撕掉该函数的源代码以查找对记录函数的调用。复杂且毫无价值,但可能。

再说一次,你真的应该只将它用于调试!

于 2013-05-01T19:32:23.107 回答
0

根据您的评论

我一直在尝试寻找方法来防止评估 eval 语句中的特定函数,这是解决该问题的一种潜在解决方案。

你所要求的可能不是你真正需要的。为什么不在 ing 之前覆盖您想要阻止的功能eval并在之后恢复它们:

var blacklist = [ 'alert', 'setTimeout' ];

var old = {};

// Save the blacklisted functions and overwrite
blacklist.forEach(function(name) {
    old[name] = window[name];
    window[name] = function() {
        console.log(name + ' has been disabled for security reasons');
    }
});

eval('alert("Hello world")');

// restore the original functions
blacklist.forEach(function(name) {
    window[name] = old[name];
});
于 2013-05-01T19:08:24.973 回答
0

函数是否可以将自己的函数调用作为字符串返回?

不,您不能通过什么表达式提取您的参数到函数中 - 您只能访问它们的值。当然,您可以模拟带有原始值的调用字符串,但您永远不知道它们是作为变量、文字还是整个表达式传递给函数的。

也许,Mozilla 的toSource方法可以帮助你。

于 2013-05-01T19:09:17.633 回答