描述 JSON.stringify()的作用就是把 JavaScript 對象或數組或其他簡單值轉換為字元串。它還可以用於對象的深拷貝;對 JSON 字元串進行格式化(縮進);在轉換之前對值進行替換操作。 特殊類型的處理 JSON.stringify()遇到函數、日期等類型的值會進行特殊處理。為了讓 ...
描述
JSON.stringify()
的作用就是把 JavaScript 對象或數組或其他簡單值轉換為字元串。它還可以用於對象的深拷貝;對 JSON 字元串進行格式化(縮進);在轉換之前對值進行替換操作。
特殊類型的處理
JSON.stringify()
遇到函數、日期等類型的值會進行特殊處理。為了讓輸出結果好看一些,在函數的第三個參數,指明字元串化後的結果縮進 2 個空格:
let jsonStr = JSON.stringify(
{
func: function () {},
date: new Date(),
unde: undefined,
null: null,
nan: NaN,
infi: Infinity,
infi0: -Infinity,
regp: new RegExp(/Android|iPad/)
},
null,
2
);
console.log(jsonStr);
輸出結果如下所示:
{
"date": "2022-08-31T13:34:25.223Z",
"null": null,
"nan": null,
"infi": null,
"infi0": null,
"regp": {}
}
JSON.stringify()
對以下類型的值進行特殊處理:
- 函數:函數直接被忽略,不輸出到字元串中。
- Date:原本 new 一個日期的結果時 "Wed Aug 31 2022 21:38:37 GMT+0800 (中國標準時間)",在被字元串化之後變成瞭如上格式。
- undefined:undefined 直接被忽略,不輸出。
- null:null 就是 null 本身。
- NaN:Nan 類型被轉化成 null。
- Infinity 和 -Infinity:都被轉化成 null。
- RegExp:RegExp 直接輸出一個空對象 {}。
運用場景
對象深拷貝
通過=
無法真正拷貝一個對象,而是引用對象的記憶體地址,詳細請看JavaScript - 對象引用和複製。
JSON.stringify()
和JSON.parse()
一起搭配使用就可以深拷貝一個對象:
let obj = { age: 10, name: "XiaoMing" };
let copy = JSON.parse(JSON.stringify(obj));
obj.age = 12;
copy.age = 14;
console.log(obj.age, copy.age); // => 12, 14
修改原對象obj
的 age 屬性之後不影響深拷貝之後的對象copy
的屬性。
存儲對象到 LocalStorage
window.localStorage.setItem(key, value)
的兩個參數都只接受字元串類型的值,如果強行把對象、數組存儲到本地存儲裡面,最終的結果是:
所以,這時候就不得不把對象、數組進行字元化,也就是用JSON.stringify()
:
let obj = { age: 10, name: "XiaoMing" };
window.localStorage.setItem("obj", JSON.stringify(obj));
然後就能正常顯示出對象了:
如果從本地存儲中拿這個值,不要忘記用JSON.parse()
解析字元串。
第二個參數
第二個參數可以傳遞一個函數也可以傳遞一個數組,每一種類型都有不同的作用。傳遞函數我們可以對原對象做一個過濾處理或者其他的操作,傳遞數組就是輸出結果只保留數組裡面給的那幾個 key 以及對應的值。
傳遞函數
函數接收兩個值,key 和 value。key 不可以被改變,value 可以改變,且在改變之後必須要把 value 返回出去,否則無法執行下一步,導致最終只輸出一個空。
let obj = { age: 10, name: "XiaoMing" };
let json = JSON.stringify(obj, (key, value) => {
if (key === "age") {
value = 20;
}
return value;
});
console.log(json);
列印結果:
傳遞數組
對於輸出結果,我們要進行一些取捨,就可以傳遞一個數組,指定只輸出哪些 key 和 value:
let obj = { age: 10, name: "XiaoMing" };
let json = JSON.stringify(obj, ["age"]);
console.log(json);
列印結果:
那如果希望字元化後的對象只保留除了一些 key 以外的所有其他 key 和 value 呢?我寫了一個exclude
函數,只針對於對象,去除不需要的對象欄位,其餘都保留輸出:
function exclude(obj, exc) {
for (let i in exc) {
delete obj[exc[i]];
}
return Object.keys(obj);
}
let obj = { age: 10, name: "XiaoMing", school: "希望小學", address: "北京市朝陽區xxx號" };
let json = JSON.stringify(obj, exclude(obj, ["age", "address"]));
列印結果:
第三個參數
預設列印輸出的 JSON 字元串是一行,沒有任何縮進的,第三個參數就是縮進多少個空格。
JSON.stringify(obj, exclude(obj, ["age", "address"]), 2);
縮進 2 個字元的結果:
{
"name": "XiaoMing",
"school": "希望小學"
}