prototypejs 1.6到1.7 json问题

时间:2011-02-12 13:25:06

标签: javascript json prototypejs

我有一个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);
}});

1 个答案:

答案 0 :(得分:1)

您发布的示例数据中包含的内容是不是 JSON。在严格的JSON中,属性的值可以是

  • 一个字符串
  • 一个数字
  • 布尔truefalse
  • 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函数。