JavaScript函数是否可以将其自身的函数调用返回为字符串?

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
如果参数是复杂对象的实例,你会怎么处理? - zzzzBov
1
不是的。你有什么特别想做的吗? - sciritai
@sciritai 我一直在尝试找到防止eval语句中特定函数被评估的方法,这是解决该问题的一个潜在解决方案。 - Anderson Green
1
@AndersonGreen 如果不在执行JavaScript之前对其进行消毒处理,那么它就非常难以消毒处理,甚至在理论上也是不可能的。 - ComFreek
每当我看到“[空白]是否可能”这样的问题时,我就会想给出一个单词的答案:“是的”。大多数技术问题都有可能的解决方案。如果你真的想让别人展示如何完成任务,也许在未来提出一个“如何”问题会更好。 - Shawn
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仍然需要改进。


当字符串、正则表达式和数字被用作参数时,此函数能够正常工作。然而,当一个函数被用作参数时,它会打印出函数的源代码而不是函数的名称。我会尝试修复这个问题。 - Anderson Green
是的,您绝对需要为每种对象类型编写特殊情况格式。如果传递了一个对象,您是否想要原始对象的变量名称? - LouD

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

当函数被用作参数时,这个不起作用:http://jsfiddle.net/WkJE9/2/ - Anderson Green
返回警告的本地代码...无论如何,您都不应该为参数分配变量alert的值。 - KingKongFrog

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...

在严格模式下,这将失败。Callee 不再是 arguments 对象的有效属性。 - Stephen
2
需要注意的是,在严格模式下不允许使用arguments.callee,并且规范编写者对其持谨慎态度。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments/callee - mwcz

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,在全局"use strict"下才能正常工作。
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(),它应该在IE8中起作用。如果您不使用strict,您甚至可以做更酷的事情,例如记录调用正在记录的函数的函数。如果您想要参数的名称而不仅仅是值,则可以撕开该函数的源代码以查找对已记录函数的调用。复杂而毫无意义,但是可能性存在。 再次强调,您应该仅将其用于调试!

0

根据您的评论

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

您所要求的可能不是您真正需要的。为什么不在 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];
});

为什么要移除它们?只需将它们变为空的私有函数。例如:function(code){ var alert,prompt; eval(code) } - dandavis

0

一个函数能否返回自己的函数调用字符串?

不行。你无法提取传递给函数的参数表达式 - 你只能访问它们的值。当然,你可以使用原始值模拟调用字符串,但你永远不知道它们是作为变量、字面量还是整个表达式传递给函数的。

也许,Mozilla 的 toSource 方法 可以帮助你解决这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接