瞭解JSON.stringify()
阿新 • • 發佈:2020-07-27
//JSON.stringify() 方法用於將 JavaScript 值轉換為 JSON 字串。 // ## 語法 // JSON.stringify(value[, replacer[, space]]) // - value: // 必需, 要轉換的 JavaScript 值(通常為物件或陣列)。 // - replacer: // 可選。用於轉換結果的函式或陣列。 // 如果 replacer 為函式,則 JSON.stringify 將呼叫該函式,並傳入每個成員的鍵和值。使用返回值而不是原始值。如果此函式返回 undefined,則排除成員。根物件的鍵是一個空字串:""。 // 如果 replacer 是一個數組,則僅轉換該陣列中具有鍵值的成員。成員的轉換順序與鍵在陣列中的順序一樣。 // - space: // 可選,文字新增縮排、空格和換行符,如果 space 是一個數字,則返回值文字在每個級別縮排指定數目的空格,如果 space 大於 10,則文字縮排 10 個空格。space 也可以使用非數字,如:\t。 // 常用JSON.stringify()有那些=>資料的深拷貝 let obj = { a: '你好', b: '你好b', c: '防守打法c' } let obj1 = JSON.parse(JSON.stringify(obj)) obj1.a = "你好a" console.log(obj) // {a: "你好", b: "你好b", c: "防守打法c"} console.log(obj1) // {a: "你好a", b: "你好b", c: "防守打法c"} console.log(JSON.stringify(obj)) // {"a":"你好","b":"你好b","c":"防守打法c"} // ### 返回值 // 對於undefined、任意的函式,symbol作為物件屬性值的時候,JSON.stringify() 將跳過(忽略)對他們進行序列化 // 對於undefined、任意的函式以及 symbol 作為陣列元素值時,JSON.stringify() 將會將它們序列化為 null // 對於undefined、任意的函式以及 symbol 被 JSON.stringify() 作為單獨的值進行序列化時,都會返回 undefined const data = { a: "aaa", b: undefined, c: Symbol("dd"), fn: function() { return true; } }; console.log(JSON.stringify(data)); // {"a":"aaa"} console.log(JSON.parse(JSON.stringify(data))) // 延伸問題: // 物件裡的屬性值存在undefined如何去掉擁有undefined屬性值的屬性? // ### 非陣列物件的屬性不能保證以特定的順序出現在序列化後的字串中 const data = { a: "aaa", b: undefined, c: Symbol("dd"), fn: function() { return true; }, d: "ddd" }; JSON.stringify(data); // 輸出:? // "{"a":"aaa","d":"ddd"}" JSON.stringify(["aaa", undefined, function aa() { return true }, Symbol('dd'),"eee"]) // 輸出:? // "["aaa",null,null,null,"eee"]" // JSON.stringify() 序列化時會忽略一些特殊的值,所以不能保證序列化後的字串還是以特定的順序出現(陣列除外)。 // ### 轉換值如果有 toJSON() 函式,該函式返回什麼值,序列化結果就是什麼值,並且忽略其他屬性的值。 JSON.stringify({ say: "hello JSON.stringify", toJSON: function() { return "today i learn"; } }) // "today i learn" // ### JSON.stringify() 將會正常序列化 Date 的值 JSON.stringify({ now: new Date() }); // "{"now":"2019-12-08T07:42:11.973Z"}" // 實際上 Date 物件自己部署了 toJSON() 方法(同Date.toISOString()),因此 Date 物件會被當做字串處理。 // ### NaN 和 Infinity 格式的數值及 null 都會被當做 null。 JSON.stringify(NaN) // "null" JSON.stringify(null) // "null" JSON.stringify(Infinity) // "null" // ### 迴圈引用報錯 // 對包含迴圈引用的物件(物件之間相互引用,形成無限迴圈)執行此方法,會丟擲錯誤。 const obj = { name: "loopObj" }; const loopObj = { obj }; // 物件之間形成迴圈引用,形成閉環 obj.loopObj = loopObj; // 封裝一個深拷貝的函式 function deepClone(obj) { return JSON.parse(JSON.stringify(obj)); } // 執行深拷貝,丟擲錯誤 deepClone(obj) /** VM44:9 Uncaught TypeError: Converting circular structure to JSON --> starting at object with constructor 'Object' | property 'loopObj' -> object with constructor 'Object' --- property 'obj' closes the circle at JSON.stringify (<anonymous>) at deepClone (<anonymous>:9:26) at <anonymous>:11:13 */