




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第強(qiáng)大的JSON.stringify如何使用目錄前言三參數(shù)replacer九特性特性一:undefined、函數(shù)、Symbol值特性二:toJSON()方法特性三:布爾值、數(shù)字、字符串的包裝對(duì)象特性四:NaNInfinitynull特性五:Date對(duì)象特性六:Symbol特性七:BigInt特性八:循環(huán)引用特性九:可枚舉屬性六妙用localStorage屬性過濾三思而后行之深拷貝對(duì)象的map函數(shù)刪除對(duì)象屬性對(duì)象判斷數(shù)組對(duì)象去重參考鏈接
前言
JSON.stringify作為日常開發(fā)中經(jīng)常使用的方法,你真的能靈活運(yùn)用它嗎?
學(xué)習(xí)本文之前,小包想讓大家?guī)е鴰讉€(gè)問題,一起來深入學(xué)習(xí)stringify。
stringify函數(shù)有幾個(gè)參數(shù),每個(gè)參數(shù)分別有啥用啊stringify序列化準(zhǔn)則有哪些啊函數(shù)序列化中會(huì)如何處理null、undefined、NaN等特殊的值又會(huì)如何處理ES6后增加的Symbol類型、BigInt序列化過程中會(huì)有特別處理嗎stringify為什么不適合做深拷貝你能想到那些stringify的妙用
整個(gè)文章的脈絡(luò)跟下面思維導(dǎo)圖一致,大家可以先留一下印象。
三參數(shù)
在日常編程中,我們經(jīng)常JSON.stringify方法將某個(gè)對(duì)象轉(zhuǎn)換成JSON字符串形式。
conststu={
name:'zcxiaobao',
age:18
//{"name":"zcxiaobao","age":18}
console.log(JSON.stringify(stu));
但stringify真的就這么簡(jiǎn)單嗎?我們先來看一下MDN中對(duì)stringify的定義。
MDN中指出:JSON.stringify()方法將一個(gè)JavaScript對(duì)象或值轉(zhuǎn)換為JSON字符串,如果指定了一個(gè)replacer函數(shù),則可以選擇性地替換值,或者指定的replacer是數(shù)組,則可選擇性地僅包含數(shù)組指定的屬性。
看完定義,小包就一驚,stringfy不止一個(gè)參數(shù)嗎?當(dāng)然了,stringify有三個(gè)參數(shù)。
咱們來看一下stringify語法和參數(shù)介紹:
JSON.stringify(value[,replacer[,space]])
value:將要序列后成JSON字符串的值。replacer(可選)如果該參數(shù)是一個(gè)函數(shù),則在序列化過程中,被序列化的值的每個(gè)屬性都會(huì)經(jīng)過該函數(shù)的轉(zhuǎn)換和處理;
如果該參數(shù)是一個(gè)數(shù)組,則只有包含在這個(gè)數(shù)組中的屬性名才會(huì)被序列化到最終的JSON字符串中
如果該參數(shù)為null或者未提供,則對(duì)象所有的屬性都會(huì)被序列化。
space(可選):指定縮進(jìn)用的空白字符串,用于美化輸出如果參數(shù)是個(gè)數(shù)字,它代表有多少的空格。上限為10。
該值若小于1,則意味著沒有空格
如果該參數(shù)為字符串(當(dāng)字符串長(zhǎng)度超過10個(gè)字母,取其前10個(gè)字母),該字符串將被作為空格
如果該參數(shù)沒有提供(或者為null),將沒有空格
replacer
我們來嘗試一下replacer的使用。
replacer作為函數(shù)
replacer作為函數(shù),它有兩個(gè)參數(shù),鍵(key)和值(value),并且兩個(gè)參數(shù)都會(huì)被序列化。
在開始時(shí),replacer函數(shù)會(huì)被傳入一個(gè)空字符串作為key值,代表著要被stringify的這個(gè)對(duì)象。理解這點(diǎn)很重要,replacer函數(shù)并非是上來就把對(duì)象解析成鍵值對(duì)形式,而是先傳入了待序列化對(duì)象。隨后每個(gè)對(duì)象或數(shù)組上的屬性會(huì)被依次傳入。如果函數(shù)返回值為undefined或者函數(shù)時(shí),該屬性值會(huì)被過濾掉,其余按照返回規(guī)則。
//repalcer接受兩個(gè)參數(shù)keyvalue
//keyvalue分別為對(duì)象的每個(gè)鍵值對(duì)
//因此我們可以根據(jù)鍵或者值的類型進(jìn)行簡(jiǎn)單篩選
functionreplacer(key,value){
if(typeofvalue==="string"){
returnundefined;
returnvalue;
//function可自己測(cè)試
functionreplacerFunc(key,value){
if(typeofvalue==="string"){
return()=
returnvalue;
constfoo={foundation:"Mozilla",model:"box",week:45,transport:"car",month:7};
constjsonString=JSON.stringify(foo,replacer);
JSON序列化結(jié)果為{week:45,month:7}
但如果序列化的是數(shù)組,若replacer函數(shù)返回undefined或者函數(shù),當(dāng)前值不會(huì)被忽略,而將會(huì)被null取代。
constlist=[1,'22',3]
constjsonString=JSON.stringify(list,replacer)
JSON序列化的結(jié)果為[1,null,3]
replacer作為數(shù)組
作為數(shù)組比較好理解,過濾數(shù)組中出現(xiàn)的鍵值。
constfoo={foundation:"Mozilla",model:"box",week:45,transport:"car",month:7};
constjsonString=JSON.stringify(foo,['week','month']);
JSON序列化結(jié)果為{week:45,month:7},只保留week和month屬性值。
九特性
特性一:undefined、函數(shù)、Symbol值
出現(xiàn)在非數(shù)組對(duì)象屬性值中:undefined、任意函數(shù)、Symbol值在序列化過程中將會(huì)被忽略出現(xiàn)在數(shù)組中:undefined、任意函數(shù)、Symbol值會(huì)被轉(zhuǎn)化為null單獨(dú)轉(zhuǎn)換時(shí):會(huì)返回undefined
//1.對(duì)象屬性值中存在這三種值會(huì)被忽略
constobj={
name:'zc',
age:18,
//函數(shù)會(huì)被忽略
sayHello(){
console.log('helloworld')
//undefined會(huì)被忽略
wife:undefined,
//Symbol值會(huì)被忽略
id:Symbol(111),
//[Symbol('zc')]:'zc',
//輸出結(jié)果:{"name":"zc","age":18}
console.log(JSON.stringify(obj));
//2.數(shù)組中這三種值會(huì)被轉(zhuǎn)化為null
constlist=[
'zc',
18,
//函數(shù)轉(zhuǎn)化為null
functionsayHello(){
console.log('helloworld')
//undefined轉(zhuǎn)換為null
undefined,
//Symbol轉(zhuǎn)換為null
Symbol(111)
//["zc",18,null,null,null]
console.log(JSON.stringify(list))
//3.這三種值單獨(dú)轉(zhuǎn)化將會(huì)返回undefined
console.log(JSON.stringify(undefined))//undefined
console.log(JSON.stringify(Symbol(111)))//undefined
console.log(JSON.stringify(functionsayHello(){
console.log('helloworld')
}))//undefined
特性二:toJSON()方法
轉(zhuǎn)換值如果有toJSON()方法,toJSON()方法返回什么值,序列化結(jié)果就返回什么值,其余值會(huì)被忽略。
constobj={
name:'zc',
toJSON(){
return'returntoJSON'
//returntoJSON
console.log(JSON.stringify(obj));
特性三:布爾值、數(shù)字、字符串的包裝對(duì)象
布爾值、數(shù)字、字符串的包裝對(duì)象在序列化過程中會(huì)自動(dòng)轉(zhuǎn)換成對(duì)應(yīng)的原始值
JSON.stringify([newNumber(1),newString("zcxiaobao"),newBoolean(true)]);
//[1,"zcxiaobao",true]
特性四:NaNInfinitynull
特性四主要針對(duì)JavaScript里面的特殊值,例如Number類型里的NaN和Infinity及null。此三種數(shù)值序列化過程中都會(huì)被當(dāng)做null。
//[null,null,null,null,null]
JSON.stringify([null,NaN,-NaN,Infinity,-Infinity])
//特性三講過布爾值、數(shù)字、字符串的包裝對(duì)象在序列化過程中會(huì)自動(dòng)轉(zhuǎn)換成對(duì)應(yīng)的原始值
//隱式類型轉(zhuǎn)換就會(huì)調(diào)用包裝類,因此會(huì)先調(diào)用Number=NaN
//之后再轉(zhuǎn)化為null
//1/0=Infinity=null
JSON.stringify([Number('123a'),+'123a',1/0])
特性五:Date對(duì)象
Date對(duì)象上部署了toJSON方法(同Date.toISOString())將其轉(zhuǎn)換為字符串,因此JSON.stringify()將會(huì)序列化Date的值為時(shí)間格式字符串。
//"2025-03-06T08:24:56.138Z"
JSON.stringify(newDate())
特性六:Symbol
特性一提到,Symbol類型當(dāng)作值來使用時(shí),對(duì)象、數(shù)組、單獨(dú)使用分別會(huì)被忽略、轉(zhuǎn)換為null、轉(zhuǎn)化為undefined。
同樣的,所有以Symbol為屬性鍵的屬性都會(huì)被完全忽略掉,即便replacer參數(shù)中強(qiáng)制指定包含了它們。
constobj={
name:'zcxiaobao',
age:18,
[Symbol('lyl')]:'unique'
functionreplacer(key,value){
if(typeofkey==='symbol'){
returnvalue;
//undefined
JSON.stringify(obj,replacer);
通過上面案例,我們可以看出,雖然我們通過replacer強(qiáng)行指定了返回Symbol類型值,但最終還是會(huì)被忽略掉。
特性七:BigInt
JSON.stringify規(guī)定:嘗試去轉(zhuǎn)換BigInt類型的值會(huì)拋出TypeError
constbigNumber=BigInt(1)
//UncaughtTypeError:DonotknowhowtoserializeaBigInt
console.log(JSON.stringify(bigNumber))
特性八:循環(huán)引用
特性八指出:對(duì)包含循環(huán)引用的對(duì)象(對(duì)象之間相互引用,形成無限循環(huán))執(zhí)行此方法,會(huì)拋出錯(cuò)誤
日常開發(fā)中深拷貝最簡(jiǎn)單暴力的方式就是使用JSON.parse(JSON.stringify(obj)),但此方法下的深拷貝存在巨坑,關(guān)鍵問題就在于stringify無法處理循環(huán)引用問題。
constobj={
name:'zcxiaobao',
age:18,
constloopObj={
//形成循環(huán)引用
obj.loopObj=loopObj;
JSON.stringify(obj)
/*UncaughtTypeError:ConvertingcircularstructuretoJSON
--startingatobjectwithconstructor'Object'
|property'loopObj'-objectwithconstructor'Object'
---property'obj'closesthecircle
atJSON.stringify(anonymous)
atanonymous:10:6
特性九:可枚舉屬性
對(duì)于對(duì)象(包括Map/Set/WeakMap/WeakSet)的序列化,除了上文講到的一些情況,stringify也明確規(guī)定,僅會(huì)序列化可枚舉的屬性
//不可枚舉的屬性默認(rèn)會(huì)被忽略
//{"age":18}
JSON.stringify(
Object.create(
null,
name:{value:'zcxiaobao',enumerable:false},
age:{value:18,enumerable:true}
六妙用
localStorage
localStorage對(duì)象用于長(zhǎng)久保存整個(gè)網(wǎng)站的數(shù)據(jù),保存的數(shù)據(jù)沒有過期時(shí)間,直到手動(dòng)去刪除。通常我們以對(duì)象形式進(jìn)行存儲(chǔ)。
單純調(diào)用localStorage對(duì)象方法
constobj={
name:'zcxiaobao',
age:18
//單純調(diào)用localStorage.setItem()
localStorage.setItem('zc',obj);
//最終返回結(jié)果是[objectObject]
//可見單純調(diào)用localStorage是失敗的
console.log(localStorage.getItem('zc'))
localStorage配合JSON.stringify方法
localStorage.setItem('zc',JSON.stringify(obj));
//最終返回結(jié)果是{name:'zcxiaobao',age:18}
console.log(JSON.parse(localStorage.getItem('zc')))
屬性過濾
來假設(shè)這樣一個(gè)場(chǎng)景,后端返回了一個(gè)很長(zhǎng)的對(duì)象,對(duì)象里面屬性很多,而我們只需要其中幾個(gè)屬性,并且這幾個(gè)屬性我們要存儲(chǔ)到localStorage中。
方案一:解構(gòu)賦值+stringify
//我們只需要a,e,f屬性
constobj={
a:1,b:2,c:3,d:4,e:5,f:6,g:7
//解構(gòu)賦值
const{a,e,f}=obj;
//存儲(chǔ)到localStorage
localStorage.setItem('zc',JSON.stringify({a,e,f}))
//{"a":1,"e":5,"f":6}
console.log(localStorage.getItem('zc'))
使用stringify的replacer參數(shù)
//借助replacer作為數(shù)組形式進(jìn)行過濾
localStorage.setItem('zc',JSON.stringify(obj,['a','e','f']))
//{"a":1,"e":5,"f":6}
console.log(localStorage.getItem('zc'))
當(dāng)replacer是數(shù)組時(shí),可以簡(jiǎn)單的過濾出我們所需的屬性,是一個(gè)不錯(cuò)的小技巧。
三思而后行之深拷貝
使用JSON.parse(JSON.stringify)是實(shí)現(xiàn)對(duì)象的深拷貝最簡(jiǎn)單暴力的方法之一。但也正如標(biāo)題所言,使用該種方法的深拷貝要深思熟慮。
循環(huán)引用問題,stringify會(huì)報(bào)錯(cuò)函數(shù)、undefined、Symbol會(huì)被忽略NaN、Infinity和-Infinity會(huì)被序列化成null...
因此在使用JSON.parse(JSON.stringify)做深拷貝時(shí),一定要深思熟慮。如果沒有上述隱患,JSON.parse(JSON.stringify)是一個(gè)可行的深拷貝方案。
對(duì)象的map函數(shù)
在使用數(shù)組進(jìn)行編程時(shí),我們會(huì)經(jīng)常使用到map函數(shù)。有了replacer參數(shù)后,我們就可以借助此參數(shù),實(shí)現(xiàn)對(duì)象的map函數(shù)。
constObjectMap=(obj,fn)={
if(typeoffn!=="function"){
thrownewTypeError(`${fn}isnotafunction!`);
//先調(diào)用JSON.stringify(obj,replacer)實(shí)現(xiàn)map功能
//然后調(diào)用JSON.parse重新轉(zhuǎn)化成對(duì)象
returnJSON.parse(JSON.stringify(obj,fn));
//例如下面給obj對(duì)象的屬性值乘以2
constobj={
a:1,
b:2,
c:3
console.log(ObjectMap(obj,(key,val)={
if(typeofvalue==="number"){
returnvalue*2;
returnvalue;
很多同學(xué)有可能會(huì)很奇怪,為什么里面還需要多加一部判斷,直接returnvalue*2不可嗎?
上文講過,replacer函數(shù)首先傳入的是待序列化對(duì)象,對(duì)象*2=NaN=toJSON(NaN)=undefined=被忽略,就沒有后續(xù)的鍵值對(duì)解析了。
刪除對(duì)象屬性
借助replacer函數(shù),我們還可以刪除對(duì)象的某些屬性。
constobj={
name:'zcxiaobao',
age:18
//{"age":18}
JSON.stringify(obj,(key,val)={
//返回值為undefined時(shí),該屬性會(huì)被忽略
if(key==='name'){
returnundefined;
returnval;
對(duì)象判斷
JSON.stringify可以將對(duì)象序列化為字符串,因此我們可以借助字符串的方法來實(shí)現(xiàn)簡(jiǎn)單的對(duì)象相等判斷。
//判斷數(shù)組是否包含某對(duì)象
constnames=[
{name:'zcxiaobao'},
{name:'txtx'},
{name:'mymy'},
constzcxiaobao={name:'zcxiaobao'};
//true
JSON.stringify(names).includes(JSON.stringify(zcxiaobao))
//判斷對(duì)象是否相等
constd1={type:'div'}
constd2={type:'div'}
//true
JSON.stringify(d1)===JSON.stringify(d2);
數(shù)組對(duì)象去重
借助上面的思想,我們還能實(shí)現(xiàn)簡(jiǎn)單的數(shù)組對(duì)象去重。
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 小型公司人員管理制度
- 實(shí)習(xí)轉(zhuǎn)正考核管理制度
- 醫(yī)療器材采購(gòu)管理制度
- 全民健身室內(nèi)管理制度
- 單位出入登記管理制度
- 巡防隊(duì)員車輛管理制度
- 計(jì)算機(jī)網(wǎng)絡(luò)技術(shù)的執(zhí)行與評(píng)估試題及答案
- 醫(yī)院庫(kù)房物資管理制度
- 印刷企業(yè)銷毀管理制度
- 數(shù)據(jù)包轉(zhuǎn)發(fā)與路由分析技術(shù)試題及答案
- 整形醫(yī)院雙眼皮培訓(xùn)課件
- Meta分析很全的課件
- 電商倉(cāng)庫(kù)流程及診斷
- 施工場(chǎng)地平整施工方案
- 靜脈治療課件
- NPUAP壓瘡指南更新的解讀
- 2020年華為采購(gòu)物料環(huán)保規(guī)范?V4
- IPQC制程檢驗(yàn)流程圖
- 進(jìn)料檢驗(yàn)報(bào)告單
- 2022年江蘇省南京市中考?xì)v史試題(含答案)
- YYT 1182-2020 核酸擴(kuò)增檢測(cè)用試劑(盒)
評(píng)論
0/150
提交評(píng)論