JavaScript JSON.stringify()的使用總結
一、使用方法
1、基本用法
jsON.stringify()可以把一個javascript物件序列化為一個JSON字串。
let json1 = { title: "Json.stringify",author: [ "浪裡行舟" ],year: 2021 }; let jsonText = JSON.stringify(json1);
預設情況下,JSON.stringify()會輸出不包含空格或縮排的JSON字串,因此jsonText的值是這樣的:
"{"title":"Json.stringify","author":["浪裡行舟"],"year":2021}"
在序列化javaScript物件時,所有函式和原型成員都會有意地在結果中省略。此外,值為undefined的任何屬性也會被跳過。最終得到的就是所有例項屬性均為有效JSON資料型別的表示。
在JSON.stringify()方法一共能接受3個引數,其中兩個可選的引數(分別是第二、第三個引數)。這兩個可選引數可以用於指定其他序列化JavaScript物件的方式。第二個引數是過濾器,可以是陣列或函式;第三個引數是用於縮排結果JSON字串的選項。單獨或組合使用這些引數可以更好地控制JSON序列化。
2、第二個引數--過濾器
如果第二個引數是一個數組,那麼JSON.stringify()返回的結果只會包含該陣列中列出的物件屬性。比如下面的例子:
letjson1={ title:"Json.stringify",author:[ "浪裡行舟" ],year:2021,like:'frontend',weixin:'frontJS' }; letjsonText=JSON.stringify(json1,['weixin']);
在這個例子中,JSON.stringify()方法的第二個引數是一個包含一個字串的陣列:"weixin"。它對應著要序列化的物件中的屬性,因此結果JSON字串中只會包含這個屬性:
"{"weixin":"frontJS"}"
如果第二個引數是一個函式,則行為又有不同。提供的函式接收兩個引數:屬性名(key)和屬性值(value)。可以根據這個key決定要對相應屬性執行什麼操作。這個key始終是字串,只是在值不屬於某個鍵/值對時會是空字串。
conststudents=[ { name:'james',score:100,},{ name:'jordon',score:60,{ name:'kobe',score:90,} ]; functionreplacer(key,value){ if(key==='score'){ if(value===100){ return'S'; }elseif(value>=90){ return'A'; }elseif(value>=70){ return'B'; }elseif(value>=50){ return'C'; }else{ return'E'; } } returnvalue; } console.log(JSON.stringify(students,replacer,4))
上面的程式碼,我們通過replacer將成績從百分制替換為成績等級。
值得注意的是,如果stringify的第二個引數為函式那麼它的返回值如果是undefined,那麼對應的屬性不會被序列化,如果返回其他的值,那麼用返回的值替代原來的值進行序列化。
3、第三個引數--字串縮排
JSON.stringify()方法的第三個引數控制縮排和空格。在這個引數是數值時,表示每一級縮排的空格數。例如,每級縮排4個空格,可以這樣:
letjson1={ title:"Json.stringify",year:2021 }; letjsonText=JSON.stringify(json1,null,4);
這樣得到的jsonText格式如下:
{
"title":"Json.stringify","author":[
"浪裡行舟"
],"year":程式設計客棧2021
}
JSON.stringify()在處理資料的時候同時考慮了資料轉換和方便閱讀,只不過,方便閱讀這一點,常常被人忽略。
4、toJSON()方法--自定義JSON序列化
有時候,物件需要在JSON.stringify()之上自定義JSON序列化。此時,可以在要序列化的物件中新增toJSON()方法,序列化時會基於這個方法返回適當的JSON表示。
下面的物件為自定義序列化而添加了一個toJSON()方法:
let json1 = { title: "Json.stringify",year: 2021,like: 'frontend',weixin: 'frontJS',toJSON: function () { return this.author } }; console.log(JSON.stringify(json1)); // ["浪裡行舟"]
注意,箭頭函式不能用來定義toJSON()方法。主要原因是箭頭函式的詞法作用域是全域性作用域,在這種情況下不合適。
二、使用場景
1、判斷陣列是否包含某物件,或者判斷物件是否相等。
//判斷陣列是否包含某物件 letdata=[ {name:'浪裡行舟'},{name:'前端工匠'},{name:'前端開發'},],val={name:'浪裡行舟'}; console.log(JSON.stringify(data).indexOf(JSON.stringify(val))!==-1);//true
我們還可以使用JSON.stringify()方法,來判斷兩個物件是否相等。
//判斷物件是否相等
letobj1={
&nbbTBJOdeuubsp;a:1,b:2
}
letobj2={
a:1,b:2,}
console.log(JSON.stringify(obj1)===JSON.stringify(obj2))//true
不過這種方式存在著較大的侷限性,物件如果調整了鍵的順序,就會判斷出錯!
//調整物件鍵的位置後 letobj1={ a:1,b:2 } letobj2={ b:2,a:1,} console.log(JSON.stringify(obj1)===JSON.stringify(obj2))//false
2、使用localStorage/sessionStorage時
localStorage/sessionStorage預設只能儲存字串,而實際開發中,我們往往需要儲存物件型別,那麼此時我們需要在儲存時利用json.str程式設計客棧ingify()將物件轉為字串,在取本地快取時,使用json.parse()轉回物件即可。
//存資料 functionsetLocalStorage(key,val){ window.localStorage.setItem(key,JSON.stringify(val)); }; //取資料 functiongetLocalStorage(key){ letval=JSON.parse(window.localStorage.getItem(key)); returnval; }; //測試 setLocalStorage('Test',['前端工匠','浪裡行舟']); console.log(getLocalStorage('Test'));
3、實現物件深拷貝
開發中,有時候怕影響原資料,我們常深拷貝出一份資料www.cppcns.com做任意操作,使用JSON.stringify()與JSON.parse()來實現深拷貝是很不錯的選擇。
letarr1=[1,3,{ username:'kobe' }]; letarr2=JSON.parse(JSON.stringify(arr1)); arr2[2].username='duncan'; console.log(arr1,arr2)
這是利用JSON.stringify將物件轉成JSON字串,再用JSON.parse把字串解析成物件,一去一來,新的物件產生了,新物件會開闢新的棧,實現深拷貝。
這種方法雖然可以實現陣列或物件深拷貝,但不能處理函式和正則,因為這兩者基於JSON.stringify和JSON.parse處理後,得到的正則就不再是正則(變為空物件),得到的函式就不再是函式(變為null)了。
letarr1=[1,function(){},{ username:'kobe' }]; letarr2=JSON.parse(JSON.stringify(arr1)); arr2[3].username='duncan'; console.log(arr1,arr2)
三、使用注意事項
JSON.stringify()雖然功能很強大,但是有些屬性無法被stringify,所以在開發中需注意以下幾種情況,以免產生一些始料未及的BUG。
1、被轉換值中有 NaN 和 Infinity
let myObj = { name: "浪裡行舟",age: Infinity,money: NaN,}; console.log(JSON.stringify(myObj)); // {"name":"浪裡行舟","age":null,"money":null} JSON.stringify([NaN,Infinity]) // [null,null]
2、被轉換值中有 undefined、任意的函式以及 symbol 值
分為兩種情況:
- 陣列,undefined、任意的函式以及symbol值在序列化的過程中會被轉換成 null
JSON.stringify([undefined,Symbol("")]); //'[null,null]'
- 非陣列,undefined、任意的函式以及symbol值在序列化的過程中會被忽略
JSON.stringify({x:undefined,y:function(){},z:Symbol("")}); //'{}'
3、迴圈引用
如果一個物件的屬性值通過某種間接的方式指向該物件本身,那麼就是一個迴圈引用。比如:
let bar = { a: { c: foo } }; let foo = { b: bar }; JSON.stringify(foo)
這種情況下,序列化會報錯的:
//錯誤資訊 UncaughtReferenceError:fooisnotdefined at<anonymous>:3:8
4、含有不可列舉的屬性值時
不可列舉的屬性預設會被忽略:
let personObj = Object.create(null,{ name: { value: "浪裡行舟",enumerable: false },year: { value: "2021",enumerable: true },}) console.log(JSON.stringify(personObj)) // {"year":"2021"}
四、總結
JSON.stringify()用於將JavaScript物件序列化為JSON字串,這方法有一些選項可以用來改變預設的行為,以實現過濾或修改流程。不過也應該注意有些屬性是無法被 stringify,所以開發時候http://www.cppcns.com應該避開這些坑!
以上就是JavaScript JSON.stringify()的使用總結的詳細內容,更多關於JavaScript JSON.stringify()的使用的資料請關注我們其它相關文章!