对于Javascript应用程序,我需要能够让用户保存对象的状态。这涉及保存一组先前动态或通过GUI创建的自定义函数,并稍后加载这些存储的函数。基本上我需要序列化和反序列化函数。
现在我使用Function对象的.toString()方法实现序列化部分:
func.toString().replace('"', '\"').replace(/(\r)/g, ' ').replace(/(\n)/g, ' ').replace(/(\t)/g, ' ')
这给了我像这样美丽的“序列化”功能(请注意该功能未命名):
"function (someParameter) {this.someFunctionName(return 'something';}"
反序列化这是我奋斗的地方。我目前用于反序列化函数的最佳解决方案是:
var func = eval( 't =' + so.actions[i].func);
请注意我在将序列化函数添加到t =
之前如何在其上调用eval()
之前。我不喜欢这样做,因为它创建了一个全局变量,但我无法找到解决方法。如果不在前面加上这个,我收到一个“SyntaxError:Unexpected token(”。当前置var t =
时,eval()不会返回该函数,而是undefined
。
是否有其他方法可以“反序列化”未命名的函数?
PS:我知道在用户输入上使用eval()的安全隐患。在可预见的将来,我是该软件的唯一用户,因此目前这不是问题。
答案 0 :(得分:6)
您可以使用Function构造函数来避免创建全局变量:
var func = Function("return " + so.actions[i].func)();
这相当于:
var func = eval("(function () { return " + so.actions[i].func + " })()");
要注意的一件事是周围的闭包,你将无法捕捉,因此当你序列化和反序列化时,函数内的变量将“改变”。
修改强>
我不是在想,你当然可以这样做:
var func = eval("(" + so.actions[i].func + ")");
答案 1 :(得分:0)
这应该有效:
eval('var func = ' + so.actions[i].func);