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完成函数序列化
我还编写了一个更完整的库,可以:
JSON.stringify
对函数进行适当的序列化(例如,当我们希望使其成为更大的序列化“数据包”的一部分时,这会很方便)eval
中,以取消“JSON ish”转义字符串的转义(JSON不允许函数+代码,因此我们必须使用eval
),然后在另一个eval
中取回我们想要的对象/#sourceMappingURL
(或旧版本/@sourceMappingURL
)在堆栈跟踪中显示正确的函数名Codebuilder
使用来修复此问题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 "";
}
}