2011-04-03 31 views
2

我想解析嵌入在我的html文件中的json字符串。 这是简化代码。JSON字符串中的意外的空键值

<html> 
<head> 
<script src="./jquery-1.4.4.min.js" type="text/javascript"></script> 
<script> 
    function parse_json(){ 
    var jtext = $("#mtxt").text(); 
    var jdata = jQuery.parseJSON(jtext); 
    JSON.parse(JSON.stringify(jdata), function (key, value){ 
      alert("key=" + key + " value=" + value); 
      if(key== ""){ 
        alert("value in string" + JSON.stringify(value));    
      } 
    }); 
    } 
    $(document).ready(function() { 
    $("#run").click(function() { 
     parse_json(); 
    }); 
    }); 
</script> 
</head> 

<body> 
<a id="run" href="#">run</a> 
<div id="mtxt"> 
{"caller": "539293493"} 
</div> 
</body> 
</html> 

当我解析它,除了预期的“调用者”值,我得到一个额外的空“键”和“价值”。 第一个提醒让我

key= value=[object Object] 

第二警报给我

value in string{} 

这是怎么回事?为什么这个额外的入口

回答

3

好的,你传递第二个参数给JSON.parse(),这是reviver回调。每the JSON docs,此回调执行“...对于最终结果的每个级别的每个键和值,每个值将被替换为reviver函数的结果,这可用于将通用对象改为伪类的实例,或将日期字符串转换为日期对象

由于您的reviver回调函数没有返回任何内容,因此您的对象得到错误操纵和失真。我不相信你在这里使用reviver。我从来没有见过它在任何地方使用,我使用JSON.parse很多。

您的代码应该是这样的:

function parse_json() 
{ 
    var jtext = $("#mtxt").text(), 
     jdata = JSON.parse($.trim(jtext)), 
     key, 
     value; 

    for(key in jdata) 
    { 
     if(Object.prototype.hasOwnProperty.call(jdata, key)) 
     { 
      value = jdata[key]; 
      //prefer console.log here... 
      alert('key: ' + key + ', value: ' + value) 
     } 
    } 
} 

$(function() 
{ 
    $('#run').click(function() 
    { 
     parse_json(); 
    }); 
}); 

演示:http://jsfiddle.net/hjVqf/

+0

我想迭代一个json字典列表,我不知道它们的键值。所以我不得不使用reviver函数。有没有办法解决? – Neo 2011-04-04 00:01:01

+0

我给你一个解决方法... – JAAulde 2011-04-04 00:01:35

+0

你在答案中错过了'value = jdata [key]'。否则,它完美的作品。 – Neo 2011-04-04 08:28:03

2

好吧,我一直在this上的jsfiddle鬼混。我注意到你没有做的事情之一是为reviver函数返回一个值。根据微软的JSON.parse docs,函数的要点是返回将更新DOM对象的修改后的(如果需要的话)版本的value属性。现在,它还表示:

一个函数,用于过滤和转换结果 。反序遍历反序列化的对象 ,并且在后序 (每个对象在其所有 成员已恢复后都会恢复)中为每个对象的 成员调用 reviver函数。

好了,所以我觉得这里的关键是,函数运行两次的原因,是因为它的运行的第一件(简单"caller": "539293493"),然后为对象本身({"caller": "539293493"})。

您会注意到,在我的链接示例中,使用添加的return value;语句,具有空白键的对象是整个对象。

+0

所以基本上reviver函数也被调用到Object上,这是它的返回值。为什么会有人想要这种行为?什么是解决方法? – Neo 2011-04-04 00:01:37

+0

@Neo,正如我在回复中所述,“行为的目的是”用于将通用对象改为伪类的实例,或将日期字符串转换为Date对象。“您不需要这样做,是不使用它。请仔细阅读这里的回复(这两个都是现场直播 - Drackir从我那里得到了+1),并看看我给你的代码和演示。 – JAAulde 2011-04-04 00:05:52

+0

@Neo:函数的返回值是'value'。在函数的第一次运行中,'value =“539293493”'。第二次运行时,'value = {“caller”:“539293493”}'。如果你看看我链接到的MS文档页面,你会注意到该函数的目的是在JSON对象内部转换对象,如果有必要的话。该函数不用于迭代对象的属性。至于解决方法,@JAAulde用一个更新了他的答案。 – 2011-04-04 00:43:14