2011-04-03 61 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