我有一个对象数组,每个对象都有一个函数,例如:
var array = [];
var object = {
param1: 0,
param2: 0,
function1: function(){
param1 += 1;
},
function2: function(){
param2 = new Date().getTime();
}
}
for(var i=0; i<5; i++){
array.push(object);
}
然后我想将此数组转换为JSON并保留函数,因此我执行以下操作:
var json = JSON.stringify(array, function(key, val){
if(typeof(val) === "function"){
return val.toString();
}else{
return val;
}
});
然后我想让我的对象返回数组,所以我执行以下操作:
var newArray = JSON.parse(json);
但我的问题从这里开始。我在JSON变量中保存的函数被转换为字符串,因此我无法运行它,例如:
alert(newArray[0].param1); //It return 0
newArray[0].function1(); //It says "Uncaught TypeError: string is not a function"
alert(newArray[0].param1); //Do not show anything
我该如何解决这个问题?我该如何运行此功能?我尝试使用eval()而没有成功。我想在没有jQuery或任何插件的情况下解决它。
答案 0 :(得分:4)
这可能会对您有所帮助:
反序列化函数时,必须使用new Function(arguments, functionBody);
对其进行实例化。
例如:
var func = function(a, b) {
return a * b;
};
var funcStr = func.toString();
// From http://stackoverflow.com/questions/14885995/how-to-get-a-functionss-body-as-string
var funcBody = funcStr.match(/function[^{]+\{([\s\S]*)\}$/)[1];
var newFunc = new Function(['a', 'b'], funcBody);
alert(newFunc(4, 3));
函数是非常复杂的对象(特别是因为可变范围和闭包),所以除非你序列化简单函数,否则这可能会给你带来意想不到的结果。
答案 1 :(得分:0)
您不能调用String,因为String不是Function。 如果你使用eval函数,可能会调用字符串,但似乎不是你想知道的最终答案。
var object = {
param1: 0,
param2: 0,
function1: "param1 += 1;",
function2: "param2 = new Date().getTime();"
};
不幸的是,这段代码存在绑定问题。 因为eval具有不同的背景,所以无法找到params。
Christophe L在上面评论过一个很好的答案。 我认为我们可以清除eval上下文问题,进行一些小编辑。
我们要做的就是将newFunc的上下文作为绑定对象。 您可以在以下代码中看到它
var array = [];
var object = {
param1: 0,
param2: 0,
function1: function(){
this.param1 += 1;
},
function2: function(){
this.param2 = new Date().getTime();
}
};
for(var i=0; i<5; i++){
array.push(object);
}
var json = JSON.stringify(array, function(key, val){
if(typeof(val) === "function"){
return val.toString();
}else{
return val;
}
});
var newArray = JSON.parse(json);
var funcStr = newArray[0].function1.toString();
// From http://stackoverflow.com/questions/14885995/how-to-get-a-functionss-body-as-string
var funcBody = funcStr.match(/function[^{]+\{([\s\S]*)\}$/)[1];
var newFunc = new Function('jsonFunc', funcBody);
newFunc.apply(object);
console.log(object.param1);