Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript获取函数体_Javascript_Regex - Fatal编程技术网

javascript获取函数体

javascript获取函数体,javascript,regex,Javascript,Regex,我有一个功能 var test = function () {alert(1);} 如何获取此函数的主体 我假设唯一的方法是解析test.toString()方法的结果,但是还有其他方法吗?如果解析是唯一的方法,那么正则表达式将如何到达主体?(非常需要正则表达式的帮助,因为我不熟悉它们)2015年更新 在重新审视函数反编译的状态时,可以说,在某些经过深思熟虑的用例和环境中(例如:具有用户定义函数的Node.js worker),反编译通常是安全的 它应该和eval放在同一个桶里,eval是一个

我有一个功能

var test = function () {alert(1);}
如何获取此函数的主体


我假设唯一的方法是解析test.toString()方法的结果,但是还有其他方法吗?如果解析是唯一的方法,那么正则表达式将如何到达主体?(非常需要正则表达式的帮助,因为我不熟悉它们)

2015年更新

在重新审视函数反编译的状态时,可以说,在某些经过深思熟虑的用例和环境中(例如:具有用户定义函数的Node.js worker),反编译通常是安全的

它应该和eval放在同一个桶里,eval是一个强大的工具,有它的位置,但只能在很少的情况下使用三思而后行,这是我唯一的建议。

结论来自:

  • 它仍然不是标准的
  • 用户定义的功能通常看起来正常
  • 有一些古怪的引擎(特别是在源代码方面) 位置、空格、注释、死代码)
  • 未来可能会有一些古怪的引擎(特别是移动的或不寻常的) 具有保守内存/功耗的设备)
  • 绑定函数不显示其原始源(但保留 标识符(有时)
  • 您可能会遇到非标准扩展(如Mozilla的expression) (关闭)
  • ES6即将推出,功能现在看起来与以前大不相同 他们过去
  • 缩小程序/预处理器不是你的朋友

“函数反编译”-获取 函数对象的字符串表示形式

函数反编译通常是 建议不要使用,因为它是 语言的非标准部分,以及 因此,导致代码被删除 不可互操作且可能 容易出错

@kangax on

试试这个:

/\{(\s*?.*?)*?\}/g.exec(test.toString())[0]
test.toString()将保存您的整个声明

/{(\s*?。?)?}/g将匹配大括号之间的所有内容

如果(!!!)您可以获得
toString()
,那么您只需将子字符串从第一个
indexOf(“{”)
取到
lastIndexOf(“}”)
。所以,像这样的“有效”()

" Solução proposta pelo Paulo Torres没有grupo A.P.D.A.没有facebook。

最简单的用例 如果您只想执行函数体(例如,使用
eval
或使用
Worker
API),您可以简单地添加一些代码来规避提取函数体的所有陷阱(如其他人所述,这通常是个坏主意):

我正在使用这个技巧

使用精确的Stacktrace完成函数序列化 我还编写了一个更完整的库,可以:

  • 将任何类型的函数序列化为字符串
  • 能够将该字符串表示形式发送到任何其他地方,使用任何自定义参数执行它,并能够复制原始stacktrace
  • 请注意,大部分代码都会确保我们在稍后执行序列化函数时获得准确的stacktrace

    演示该逻辑的简化版本:

  • 使用
    JSON.stringify
    对函数进行适当的序列化(例如,当我们希望使其成为更大的序列化“数据包”的一部分时,这会很方便)
  • 然后,我们将其包装在一个
    eval
    中,以取消“JSON ish”转义字符串的转义(JSON不允许函数+代码,因此我们必须使用
    eval
    ),然后在另一个
    eval
    中取回我们想要的对象
  • 我们还使用
    /#sourceMappingURL
    (或旧版本
    /@sourceMappingURL
    )在堆栈跟踪中显示正确的函数名
  • 您会发现Stacktrace看起来不错,但它没有提供与我们在其中定义序列化函数的文件相关的正确行和列信息,这就是为什么my
    Codebuilder
    使用来修复此问题
  • 我使用我(现在稍微过时)的RPC库中的
    CodeBuilder
    内容,在这里您可以找到一些如何使用它的示例:


  • 扩展@Polygene润滑剂”:

    使用:

    受试者:

    var y = /* olo{lo} */
        /* {alala} */function/* {ff} */ x/*{s}ls{
    }ls*/(/*{*{*/)/* {ha-ha-ha} */
    /*
    
    it's a function
    
    */
    {
      return 'x';
    // }
    }
    /*
    */
    
    function getFunctionBody(fn) {
        function removeCommentsFromSource(str) {
            return str.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:([\s;])+\/\/(?:.*)$)/gm, '$1');
        }
        var s = removeCommentsFromSource( fn.toString() );
        return s.substring(s.indexOf('{')+1, s.lastIndexOf('}'));
    };
    
    getFunctionBody(y);
    /*
    "
      return 'x' 
    "
    */
    
    由和:

    var y = /* olo{lo} */
        /* {alala} */function/* {ff} */ x/*{s}ls{
    }ls*/(/*{*{*/)/* {ha-ha-ha} */
    /*
    
    it's a function
    
    */
    {
      return 'x';
    // }
    }
    /*
    */
    
    function getFunctionBody(fn) {
        function removeCommentsFromSource(str) {
            return str.replace(/(?:\/\*(?:[\s\S]*?)\*\/)|(?:([\s;])+\/\/(?:.*)$)/gm, '$1');
        }
        var s = removeCommentsFromSource( fn.toString() );
        return s.substring(s.indexOf('{')+1, s.lastIndexOf('}'));
    };
    
    getFunctionBody(y);
    /*
    "
      return 'x' 
    "
    */
    


    已使用:

    此代码在使用ES6箭头函数时提供主体,如
    var testFn=(q)=>q+1

    function getFunctionBody(test){  
        var entire = test.toString(); // note: not safe-guarded; this part may fail like this!
        return entire.substring((entire.indexOf("{")+1)||(entire.indexOf("=>")+2),  entire.lastIndexOf("}")!==-1?entire.lastIndexOf("}"):entire.length);
    }
    
    //testing/showcase code
    var tests = [
        function () {alert(1);},
        ()=>{return 1;},
        q=>q+1
    ];
    
    for (var i=0;i<tests.length;i++){
        console.log(tests[i],getFunctionBody(tests[i]));
    }
    
    函数getFunctionBody(测试){
    var-entill=test.toString();//注意:没有安全保护;这部分可能会像这样失败!
    返回整.substring((整.indexOf(“{”)+1)| |(整.indexOf(“=>”)+2),整.lastIndexOf(“}”)!=-1?整.lastIndexOf(“}”):整.length);
    }
    //测试/展示代码
    var测试=[
    函数(){alert(1);},
    ()=>{return 1;},
    q=>q+1
    ];
    
    对于(var i=0;i您可以尝试以下功能:

    function extractFunctionBody(fn) {
        var reg = /function \((.*)\)[ ]?{(.*)}$/g;
        var match = reg.exec(fn.toString().replace(/\n/g, ";"));
        if (match){
            return match[2];
        } else {
            return "";
        }
    }
    

    test.toString()
    与您需要的有何不同?您能举个例子吗?Pekka,test.toString()返回:function(){alert(1);}我需要获取主体:alert(1);这就是我提到regext的原因。虽然不建议使用regext,但我认为当您想要显示正在运行的代码时,这可能很有用(例如,对于javascript教程)问这个问题的人通常不是编写教程的人。根据生产中使用的非标准功能,将导致难以调试的代码,也就是死亡之吻。我否决了这一点,认为这不是问题的实际答案,然后立即投票支持这一点,认为这是一个很好的建议。谎言!eval应该在任何地方和远程使用它是JavaScript提供的最强大的工具。它是在运行时将字符串转换为真实对象的最佳方式,并且允许您从语言内部扩展语言本身。就像在浏览器中使用零runt编写Smalltalk或Perl一样
    function extractFunctionBody(fn) {
        var reg = /function \((.*)\)[ ]?{(.*)}$/g;
        var match = reg.exec(fn.toString().replace(/\n/g, ";"));
        if (match){
            return match[2];
        } else {
            return "";
        }
    }