JSON.parse和JSON.stringify 參數詳解


JSON.parse和JSON.stringify這兩個瀏覽器自帶(IE6/7除外)的方法平常我們經常用到,但是一般都只是用到了他們的第一個參數,比如字符串轉對象:JSON.parse('{}')   對象轉字符串:JSON.stringify({})

今天特意看了下這兩個方法的定義,第二個可選參數也是非常有用。

1. JSON.parse(text[, reviver]) 

text :     要被解析成JSON對象的字符串

reviver : 如果是一個函數,則規定了原始值如何被解析改造,在被返回之前。 function(key, value){ return value;}

             如果指定了 reviver 函數,則解析出的 JavaScript 值(解析值)會經過一次轉換后才將被最終返回(返回值)

             按照key的順序從左到右,如果value為對象則先遍歷對象里的屬性,最里層的屬性先開始,一級級往外,最終到達頂層,也就是解析值本身分別的去調用 reviver 函數

             如果 reviver 返回 undefined,則當前屬性會從所屬對象中刪除,比如:

JSON.parse('{"p": 5}', function (k, v) {
    if(k === '') return v;     // 如果到了最頂層,則直接返回屬性值,(最頂層key為空字符串)
    return v * 2;              // 否則將屬性值變為原來的 2 倍。
});                            // { p: 10 }

JSON.parse('{"1": 1, "2": 2,"3": {"4": 4, "5": {"6": 6}}}', function (k, v) {
    console.log(k); // 輸出當前的屬性名,從而得知遍歷順序是從內向外的,
                    // 最后一個屬性名會是個空字符串。
    return v;       // 返回原始屬性值,相當於沒有傳遞 reviver 參數。
});

// 1
// 2
// 4
// 6
// 5
// 3 
// ""\

2.  JSON.stringify(value [, replacer] [, space])

value :       要轉換的值

replacer : 可選參數,只能為函數或數組。

                如果replacer是函數則表示轉換前每個屬性會先調用該函數。function(key, value){ return value;}  如果此函數返回 undefined,則排除該成員。和                                 JSON.parse一樣根對象的鍵是一個空字符串:""。

                如果 replacer 是一個數組,則僅轉換該數組中具有鍵值的成員。    成員的轉換順序與鍵在數組中的順序一樣。    當 value 參數也為數組時,將忽略 replacer 數組。

space    : 可選。向返回值 JSON 文本添加縮進、空格和換行符以使其更易於讀取。

               如果 space 是一個數字,則返回值文本在每個級別縮進指定數目的空格。    如果 space 大於 10,則文本縮進 10 個空格。  

               如果 space 是一個非空字符串(例如“\t”),則返回值文本在每個級別中縮進字符串中的字符。

               如果 space 是長度大於 10 個字符的字符串,則使用前 10 個字符。

如果 value 具有 toJSON 方法,則 JSON.stringify 函數將使用該方法的返回值。    如果 toJSON 方法的返回值為 undefined,則不轉換成員,這使對象能夠確定自己的 JSON 表示形式。將不會轉換不具有 JSON 表示形式的值,例如 undefined。    在對象中,將丟棄這些值。    在數組中,會將這些值替換為 null。   

字符串值以引號開始和結束。    所有 Unicode 字符可括在引號中,但必須使用反斜杠進行轉義的字符除外。    以下字符的前面必須是反斜杠:   

  • 引號 (")

  • 反斜杠 (\)

  • 退格鍵 (b)

  • 換頁符 (f)

  • 換行符 (n)

  • 回車符 (r)

  • 水平制表符 (t)

  • 四個十六進制數字 (uhhhh)

在序列化過程中,如果 value 參數對應有 toJSON 方法,則 JSON.stringify 將首先調用 toJSON 方法。    如果該方法不存在,則使用原始值。    接下來,如果提供 replacer 參數,則該值(原始值或 toJSON 返回值)將替換為 replacer 參數的返回值。    最后,根據可選 space 參數向該值添加空格以生成最終的 JSON 文本。   

eg:第二個參數為數組

var contact = {}; 
contact.firstname = "Jesper"; 
contact.surname = "Aaberg"; 
contact.phone = ["555-0100", "555-0120"]; 
 
var memberfilter = []; 
memberfilter[0] = "surname"; 
memberfilter[1] = "phone"; 
var jsonText = JSON.stringify(contact, memberfilter, "\t"); 
document.write(jsonText); 
// Output: 
// { "surname": "Aaberg", "phone": [ "555-0100", "555-0120" ] }

第二個參數為函數:

var continents = []; 
continents[0] = "Europe"; 
continents[1] = "Asia"; 
continents[2] = "Australia"; 
continents[3] = "Antarctica"; 
continents[4] = "North America"; 
continents[5] = "South America"; 
continents[6] = "Africa"; 
 
var jsonText = JSON.stringify(continents, replaceToUpper); 
 
function replaceToUpper(key, value) { 
if (key=='') {return value;} //默認會將整個對象傳進來,先過濾掉
return value.toString().toUpperCase(); } //Output: // "EUROPE,ASIA,AUSTRALIA,ANTARCTICA,NORTH AMERICA,SOUTH AMERICA,AFRICA"

對象含有toJSON屬性

var contact = {}; 
contact.firstname = "Jesper"; 
contact.surname = "Aaberg"; 
contact.phone = ["555-0100", "555-0120"]; 
 
contact.toJSON = function() 
 { 
    var replacement = {}; 
    for (var val in this)  //當前屬性所屬的對象會作為 this 值
    { 
        if (typeof (this[val]) === 'string') 
            replacement[val] = this[val].toUpperCase(); 
        else 
            replacement[val] = this[val] 
    } 
    return replacement; 
}; 
 
var jsonText = JSON.stringify(contact); 
document.write(jsonText); 
 
// Output: 
'{"firstname":"JESPER","surname":"AABERG","phone":["555-0100","555-0120"]}' 

如果對象有toJSON屬性方法,而且第二個參數又是函數,則會先調用對象的toJSON屬性方法,然后把返回的值再調用第二個函數參數,最后得到的值即為JSON.stringify返回的值:

var a = {
    'a': 'aa',
    'aa': 'aaa',
    'toJSON': function() {
        var obj = {};
        for (var i in this) {   //toJSON屬性也會加進來
            obj[i] = this[i] + 'xxx'
        }
        return obj;
    }
};
var b = JSON.stringify(a,
function(k, v) {
    if (k == '') {
        return v;
    } else {
        return v + 'ddd'
    }
});
console.log(b)
//輸出:
{
    "a": "aaxxxddd",
    "aa": "aaaxxxddd",
    "toJSON": "function (){var obj={};for(var i in this){obj[i]=this[i]+'xxx' } return obj;}xxxddd"
}

 參考:

https://technet.microsoft.com/zh-cn/sysinternals/cc836459

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM