1. 程式人生 > >JSON.parse和JSON.stringify 引數詳解

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,則當前屬性會從所屬物件中刪除,比如:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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