JSON.stringify實(shí)例詳解以及靈活運(yùn)用
前言
工作中經(jīng)常使用 JSON.stringify 方法存儲(chǔ) localStorage,深拷貝對(duì)象,用的最多的就是第一個(gè)參數(shù),甚至不知道它還有第二個(gè)和第三個(gè)參數(shù),所以詳細(xì)的整理了一下 JSON.stringify 用法和特性,使我們能夠真正的能靈活運(yùn)用這個(gè)方法。
語(yǔ)法
JSON.stringify(value[, replacer [, space]])
參數(shù)
replacer 參數(shù)
replacer 參數(shù)可以是一個(gè)函數(shù)或者一個(gè)數(shù)組。作為函數(shù),它有兩個(gè)參數(shù),鍵(key)和值(value),它們都會(huì)被序列化。
值得注意的是,在開(kāi)始時(shí), replacer 函數(shù)會(huì)被傳入一個(gè)空字符串作為 key 值,value代表著要被 stringify 的這個(gè)對(duì)象。隨后每個(gè)對(duì)象或數(shù)組上的屬性會(huì)被依次傳入。
總的來(lái)說(shuō) replacer 參數(shù)就是用來(lái)手動(dòng)忽略一些不想被序列化的屬性,有點(diǎn)類似過(guò)濾器的作用
var foo = { id: 1, name: "sf", age: 18, }; //作為函數(shù),函數(shù)沒(méi)有返回值或者返回值為 undefined 時(shí),忽略這個(gè)屬性值 JSON.stringify(foo, (key, value) => { if (typeof value === "string") { return undefined; } return value; }); //{"id":1,"age":18} //作為數(shù)組,數(shù)組的值代表將被序列化成 JSON 字符串的屬性名 JSON.stringify(foo, ['id',"name"]); //{"id":1,"name":"sf"}
space 參數(shù)
space 參數(shù)用來(lái)控制結(jié)果字符串里面的間距。如果是一個(gè)數(shù)字, 則在字符串化時(shí)每一級(jí)別會(huì)比上一級(jí)別縮進(jìn)多這個(gè)數(shù)字值的空格(最多10個(gè)空格);如果是一個(gè)字符串,則每一級(jí)別會(huì)比上一級(jí)別多縮進(jìn)該字符串(或該字符串的前10個(gè)字符)。實(shí)際使用基本都是用來(lái)美化輸出。
let a = JSON.stringify({ a: 1, b: 2 }, null, 2); let b = JSON.stringify({ a: 1, b: 2 }, null, " "); console.log(a == b); //true JSON.stringify({ a: 1, b: 2 }, null, "--"); // { // --"a": 1, // --"b": 2 // }
特性描述
1. undefined、Symbol值、函數(shù)
- 出現(xiàn)在對(duì)象屬性值中: undefined、Symbol值、函數(shù),在序列化過(guò)程中將會(huì)被忽略
- 出現(xiàn)在數(shù)組中: undefined、Symbol值、函數(shù) 會(huì)被轉(zhuǎn)化為 null
- 單獨(dú)轉(zhuǎn)換時(shí): 會(huì)返回 undefined
const obj = { a: "a", b: undefined, c: Symbol(), d: function () {}, }; JSON.stringify(obj) // {"a":"a"} const arry = [undefined, Symbol("c"), function () {}]; JSON.stringify(arry); //[null,null,null] JSON.stringify(undefined); // undefined JSON.stringify(Symbol(111)); // undefined JSON.stringify(function () {}); // undefined
2. 非數(shù)組對(duì)象的屬性不能保證以特定的順序出現(xiàn)在序列化后的字符串中
正如在第一特性所說(shuō),JSON.stringify() 序列化時(shí)會(huì)忽略一些特殊的值,所以不能保證序列化后的字符串還是以特定的順序出現(xiàn)(數(shù)組除外)。
3. 布爾值、數(shù)字、字符串的包裝對(duì)象在序列化過(guò)程中會(huì)自動(dòng)轉(zhuǎn)換成對(duì)應(yīng)的原始值
JSON.stringify([new Boolean(true), new Number(1), new String("a")]); // [true,1,"a"]
4. 轉(zhuǎn)換值如果有 toJSON() 方法,該方法定義什么值將被序列化
const obj = { a: "aaa", toJSON() { return "hello world"; }, }; JSON.stringify(obj); // "hello world"
5. 對(duì)包含循環(huán)引用的對(duì)象(對(duì)象之間相互引用,形成無(wú)限循環(huán))執(zhí)行此方法,會(huì)拋出錯(cuò)誤。
const obj = { name: "loopObj", }; const loopObj = { obj, }; // 對(duì)象之間形成循環(huán)引用,形成閉環(huán) obj.loopObj = loopObj; JSON.stringify(obj); //TypeError: Converting circular structure to JSON
6. 所有以 symbol 為屬性鍵的屬性都會(huì)被完全忽略掉,即便 replacer 參數(shù)中強(qiáng)制指定包含了它們。
. 對(duì)包含循環(huán)引用的對(duì)象(對(duì)象之間相互引用,形成無(wú)限循環(huán))執(zhí)行此方法,會(huì)拋出錯(cuò)誤。
const obj = { a: "aaa", [Symbol("foo")]: "foo", }; JSON.stringify(obj); // {"a":"aaa"} JSON.stringify(obj, function (k, v) { if (typeof k === "symbol") { return "a symbol"; } }); // undefined
7. 日期調(diào)用了 toJSON() 將其轉(zhuǎn)換為了 string 字符串(同Date.toISOString()),因此會(huì)被當(dāng)做字符串處理。
JSON.stringify({ date: new Date("2022-02-02"), }) // {"date":"2022-02-02T00:00:00.000Z"}
8. NaN 和 Infinity 格式的數(shù)值及 null 都會(huì)被當(dāng)做 null。
JSON.stringify([NaN, Infinity, 1 / 0, Number("a")]); // [null,null,null,null]
9. 其他類型的對(duì)象,包括 Map/Set/WeakMap/WeakSet,僅會(huì)序列化可枚舉的屬性。
// 不可枚舉的屬性默認(rèn)會(huì)被忽略: JSON.stringify( Object.create(null, { x: { value: "x", enumerable: false }, y: { value: "y", enumerable: true }, }) ); // "{"y":"y"}"
應(yīng)用
localStorage
localStorage 中的鍵值對(duì)總是以字符串的形式存儲(chǔ),所以當(dāng)我們需要把一個(gè)對(duì)象存在 localStorage 中時(shí),只能用 JSON.stringify 將其轉(zhuǎn)化成字符串存儲(chǔ),使用的時(shí)候用 JSON.parse 方法去取
const userInfo = { user: "admin" }; localStorage.setItem("userInfo", JSON.stringify(userInfo)); JSON.parse(localStorage.getItem("userInfo")); // {user: 'admin'}
對(duì)象深拷貝
使用 JSON.parse(JSON.stringify) 是實(shí)現(xiàn)對(duì)象的深拷貝最簡(jiǎn)單粗暴的方法。但是由于 JSON.stringify 的一些特性,會(huì)產(chǎn)生問(wèn)題,例如:
- undefined、Symbol、 函數(shù), 對(duì)象中會(huì)被忽略,數(shù)組中會(huì)被序列化成 null。
- NaN、Infinity 和 -Infinity 會(huì)被序列化成 null。
- 循環(huán)引用問(wèn)題,stringify 會(huì)報(bào)錯(cuò)。
當(dāng)確定不存在以上情況時(shí),才考慮使用 JSON.parse(JSON.stringify) 進(jìn)行深拷貝。
屬性過(guò)濾
當(dāng)接口返回一大堆數(shù)據(jù),我們只想存某幾個(gè)屬性的時(shí)候,通過(guò) replacer 函數(shù)過(guò)濾屬性是一個(gè)不錯(cuò)的小技巧。
var foo = { id: 1, name: "sf", age: 18, }; localStorage.setItem("user", JSON.stringify(foo, ["id", "name"])); localStorage.getItem("user"); //{"id":1,"name":"sf"}
總結(jié)
到此這篇關(guān)于JSON.stringify實(shí)例詳解以及靈活運(yùn)用的文章就介紹到這了,更多相關(guān)JSON.stringify運(yùn)用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript正則函數(shù)中test和match的區(qū)別解析
在javascript中,用于檢測(cè)一個(gè)字符串是否匹配某個(gè)模式用的比較多的就是test和match方法。,這篇文章主要介紹了js正則函數(shù)中test和match的區(qū)別,需要的朋友可以參考下2022-11-11一篇文章告訴你如何用事件委托實(shí)現(xiàn)JavaScript留言板功能
這篇文章主要為大家介紹了事件委托實(shí)現(xiàn)JavaScript留言板功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2021-12-12動(dòng)態(tài)加載圖片路徑 保持JavaScript控件的相對(duì)獨(dú)立性
根據(jù)新界面的要求,需要一部分圖片來(lái)增強(qiáng)日期控件的美觀性??紤]到既要實(shí)現(xiàn)加載圖表的目標(biāo),又要保持控件的獨(dú)立性以便將來(lái)的移植。2010-09-09JS獲取input file絕對(duì)路徑的方法(推薦)
下面小編就為大家?guī)?lái)一篇JS獲取input file絕對(duì)路徑的方法(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-08-08JavaScript數(shù)據(jù)結(jié)構(gòu)yocto queue隊(duì)列鏈表代碼分析
這篇文章主要為大家介紹了JavaScript數(shù)據(jù)結(jié)構(gòu)yocto queue隊(duì)列鏈表代碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12js實(shí)現(xiàn)淘寶首頁(yè)的banner欄效果
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)淘寶首頁(yè)的banner欄效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11淺談javascript 函數(shù)表達(dá)式和函數(shù)聲明的區(qū)別
javascript中聲明函數(shù)的方法有兩種:函數(shù)聲明式和函數(shù)表達(dá)式.究竟他們用起來(lái)有什么區(qū)別呢,今天就本著打破砂鍋問(wèn)到底的精神,好好來(lái)說(shuō)說(shuō)這個(gè)讓人神魂顛倒的--函數(shù)聲明。2016-01-01Bootstrap中的fileinput 多圖片上傳及編輯功能
這篇文章主要介紹了Bootstrap中的fileinput 多圖片上傳及編輯功能的實(shí)現(xiàn),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-09-09JS使用正則表達(dá)式實(shí)現(xiàn)常用的表單驗(yàn)證功能分析
這篇文章主要介紹了JS使用正則表達(dá)式實(shí)現(xiàn)常用的表單驗(yàn)證功能,結(jié)合實(shí)例形式分析了JS基于正則表達(dá)式的表單驗(yàn)證功能原理、實(shí)現(xiàn)技巧與操作注意事項(xiàng),需要的朋友可以參考下2020-04-04使用原生javascript創(chuàng)建通用表單驗(yàn)證——更鋒利的使用dom對(duì)象
使用原生javascript創(chuàng)建通用表單驗(yàn)證——更鋒利的使用dom對(duì)象,學(xué)習(xí)js的朋友可以參考下。2011-09-09