【问题标题】:How to get a functions's body as string?如何将函数的主体作为字符串获取?
【发布时间】:2013-02-14 23:32:50
【问题描述】:

我想知道如何将函数体转换成字符串?

function A(){
  alert(1);
}

output = eval(A).toString() // this will come with  function A(){  ~ }

//output of output -> function A(){ alert(1); }

//How can I make output into alert(1); only???

【问题讨论】:

  • 我能问一下为什么你要这样做吗?
  • 我想定制一些东西...
  • 您要自定义什么?回应什么?起到什么作用?
  • 对不起,我想将 2 个函数合并为一个自定义函数......
  • @DavidThomas 例如将函数转换为 base64 数据以便在 web worker 中运行。这比在代码中添加 bas64 废话要好得多...

标签: javascript function


【解决方案1】:

如果你要做一些丑陋的事情,用正则表达式来做:

A.toString().match(/function[^{]+\{([\s\S]*)\}$/)[1];

【讨论】:

  • 非常感谢!!!我还可以问一下,您是否有任何参考网站正在提供有关如何使用正则表达式的良好教学??
  • 我不同意 OP 的做法,但我同意:“如果你要做一些丑陋的事情(你也可以)用正则表达式来做。” =D
  • 是的,我知道这很难看..但仍然取决于你在构建什么..js中的函数只是值,它意味着字符串..
  • “如果你要做一些丑陋的事情,那就用正则表达式来做吧:”本周名言!
  • 这不适用于像() => {} 这样定义的函数。运行此代码作为示例(() => {console.log(1);}).toString().match(/function[^{]+\{([\s\S]*)\}$/)[1];
【解决方案2】:

不要使用正则表达式。

const getBody = (string) => string.substring(
  string.indexOf("{") + 1,
  string.lastIndexOf("}")
)

const f = () => { return 'yo' }
const g = function (some, params) { return 'hi' }
const h = () => "boom"

console.log(getBody(f.toString()))
console.log(getBody(g.toString()))
console.log(getBody(h.toString())) // fail !

【讨论】:

  • 如果我的函数带有这样的默认值的参数将不起作用:function fn(a = {}) { return "hello"; }
【解决方案3】:

您可以将函数字符串化并通过删除其他所有内容来提取主体:

A.toString().replace(/^function\s*\S+\s*\([^)]*\)\s*\{|\}$/g, "");

但是,没有充分的理由这样做,toString 实际上并不适用于所有环境。

【讨论】:

  • 或更简洁:f.toString().replace(/(^.*?\{|\}$)/g, "")
  • 这不适用于像 () => {} 这样定义的函数。运行此代码作为示例(() => {console.log(1);}).toString().replace(/^function\s*\S+\s*\([^)]*\)\s*\{|\}$/g, "");
  • @MattClimbs 当然不是,答案是 2013 年的 :-) 它也不适用于简洁的方法、生成器、异步函数……如果你想用默认值识别 ES6 函数参数初始化器,你需要一个合适的解析器——正则表达式是不够的。
【解决方案4】:

目前,开发人员在 Ecmascript 的新版本中使用 箭头函数

因此,我想分享the answer here which is the answer of Frank

    function getArrowFunctionBody(f) {
      const matches = f.toString().match(/^(?:\s*\(?(?:\s*\w*\s*,?\s*)*\)?\s*?=>\s*){?([\s\S]*)}?$/);
      if (!matches) {
        return null;
      }
      
      const firstPass = matches[1];
      
      // Needed because the RegExp doesn't handle the last '}'.
      const secondPass =
        (firstPass.match(/{/g) || []).length === (firstPass.match(/}/g) || []).length - 1 ?
          firstPass.slice(0, firstPass.lastIndexOf('}')) :
          firstPass
      
      return secondPass;
    }
    
    const K = (x) => (y) => x;
    const I = (x) => (x);
    const V = (x) => (y) => (z) => z(x)(y);
    const f = (a, b) => {
      const c = a + b;
      return c;
    };
    const empty = () => { return undefined; };
    console.log(getArrowFunctionBody(K));
    console.log(getArrowFunctionBody(I));
    console.log(getArrowFunctionBody(V));
    console.log(getArrowFunctionBody(f));
    console.log(getArrowFunctionBody(empty));

question here

【讨论】:

  • 在我的例子中,我使用了:^(?:\s*function)?.*\(.*\)(?:\s*=>)?\s*\{[ \t]*\r?\n?([^]*)(?=\}),它不需要 } 的特殊情况,因为它使用了前瞻组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-06
  • 2010-10-06
  • 2015-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多