我有一个json解析问题,将我的应用程序从原型1.6.1更新到1.7.0 这是我的json的一个非常简化的模型,保存在tmp.js:
{
"text":"hello world",
"fn": function(){alert('hello world')
}
这是我的代码:
new Ajax.Request('tmp.js', {
onSuccess: function(transport){
var json = transport.responseText.evalJSON();
var button = new Element('button')
.update(json.text)
.observe('click', function(){
json.fn();
});
$('my_div').update(button);
}});
所有这一切都与1.6.1一起正常工作:它产生了一个按钮,在点击时提醒“你好世界”。 这在v.1.7.0中不起作用,因为我的json无效。我知道它不应该包含函数,而只包含数据。
我的问题是:为什么它适用于1.6.1(并且仍然有效)并且有一种方法可以用1.7.0完成相同的操作。我需要通过ajax获取一个包含用户定义函数的js对象。
谢谢
更新: 重建功能是一个很好的解决方案,我想我将来会使用它。 无论如何,我发现eval()函数似乎是一个很好的快速解决方案:
tp.js JSON:
{
"text":"hello world",
"fn": "my_alert('hello world')"
}
JS
function my_alert(string){
alert(string);
}
new Ajax.Request('tmp.js', {
onSuccess: function(transport){
var json = transport.responseText.evalJSON();
var button = new Element('button')
.update(json.text)
.observe('click', function(){
eval(json.fn);
});
$('my_div').update(button);
}});
答案 0 :(得分:1)
您发布的示例数据中包含的内容是不是 JSON。在严格的JSON中,属性的值可以是
true
或false
null
无法在JSON中包含函数定义。 (嗯,这不完全正确;你可以自由地使用字符串,数字,数组,对象等来描述一个函数,使得代码可以在解析JSON之后重构它关键是不允许使用直接的JavaScript函数表达式。)
你可以做的一个简单,有点令人不安的事情是将函数体保存为字符串,然后通过调用
重新构建它foo.fn = new Function(foo.fn);
一旦JSON解析完成。
编辑更多详情:
“Function()”构造函数将表示参数名称的字符串列表作为其参数,后跟一个用作函数体的字符串。因此,如果您想编写一个完整的JavaScript函数,您可能希望它看起来像一个对象:
{
'foo': 'plain property',
'someFunction': {
'arguments': [ 'x', 'y' ],
'body': 'if (x > y) return "x"; return "y";'
}
}
现在将“someFunction”变成真正的函数,你可以使用这样的东西:
function reconstructFunction(descr) {
var params = (descr.arguments || []).slice(0);
params.push(descr.body);
return Function.apply(null, params);
}
然后你可以将JSON中的函数描述符传递给类似的东西,然后你就可以调用真正的JavaScript函数。