JavaScrip中處理JSON數(shù)據(jù)的4個(gè)技巧分享
你是否曾經(jīng)在處理JSON數(shù)據(jù)時(shí)遇到過(guò)這樣的場(chǎng)景:從服務(wù)器拿到一串?dāng)?shù)據(jù),卻發(fā)現(xiàn)日期變成了奇怪的字符串格式;或者想序列化一個(gè)對(duì)象,卻總有些屬性莫名其妙地丟失了?
別擔(dān)心,今天我就來(lái)分享JSON數(shù)據(jù)處理中最實(shí)用的4個(gè)技巧,讓你從此告別這些煩惱!
基礎(chǔ)但至關(guān)重要的兩個(gè)方法
先來(lái)說(shuō)說(shuō)最基礎(chǔ)的JSON.stringify()和JSON.parse()。這兩個(gè)方法看似簡(jiǎn)單,但很多人其實(shí)并沒(méi)有完全掌握它們的精髓。
JSON.stringify()用于將JavaScript對(duì)象轉(zhuǎn)換成JSON字符串。舉個(gè)最簡(jiǎn)單的例子:
const user = {
name: '張三',
age: 25,
isAdmin: true
};
const jsonString = JSON.stringify(user);
console.log(jsonString);
// 輸出: {"name":"張三","age":25,"isAdmin":true}
而JSON.parse()則正好相反,它把JSON字符串解析成JavaScript對(duì)象:
const jsonString = '{"name":"張三","age":25,"isAdmin":true}';
const user = JSON.parse(jsonString);
console.log(user.name); // 輸出: 張三
看起來(lái)很簡(jiǎn)單對(duì)吧?但問(wèn)題往往就出在這些基礎(chǔ)操作上。比如當(dāng)你嘗試序列化包含函數(shù)、undefined或者循環(huán)引用的對(duì)象時(shí),就會(huì)遇到各種意外情況。
第二個(gè)參數(shù)的妙用
很多人不知道,JSON.stringify()和JSON.parse()都支持第二個(gè)參數(shù),這個(gè)參數(shù)能幫你解決很多實(shí)際問(wèn)題。
在JSON.stringify()中,第二個(gè)參數(shù)叫做replacer,它可以是一個(gè)函數(shù)或者數(shù)組,用來(lái)控制哪些屬性應(yīng)該被序列化。
比如你有一個(gè)用戶(hù)對(duì)象,但不想序列化密碼字段:
const user = {
name: '張三',
age: 25,
password: '123456' // 敏感信息,不想序列化
};
// 使用replacer函數(shù)過(guò)濾掉password字段
const jsonString = JSON.stringify(user, (key, value) => {
if (key === 'password') {
return undefined; // 返回undefined的字段不會(huì)被序列化
}
return value;
});
console.log(jsonString); // 輸出: {"name":"張三","age":25}
你也可以直接傳遞一個(gè)包含需要序列化的屬性名的數(shù)組:
const jsonString = JSON.stringify(user, ['name', 'age']);
console.log(jsonString); // 輸出: {"name":"張三","age":25}
處理日期對(duì)象的經(jīng)典問(wèn)題
這是實(shí)際開(kāi)發(fā)中最常見(jiàn)的問(wèn)題之一。JavaScript的Date對(duì)象在序列化后會(huì)變成ISO格式的字符串,但反序列化時(shí)卻不會(huì)自動(dòng)轉(zhuǎn)換回Date對(duì)象。
const data = {
name: '事件記錄',
createdAt: new Date() // 這是一個(gè)Date對(duì)象
};
const jsonString = JSON.stringify(data);
console.log(jsonString);
// 輸出: {"name":"事件記錄","createdAt":"2023-10-05T08:30:00.000Z"}
// 當(dāng)我們反序列化時(shí)
const parsedData = JSON.parse(jsonString);
console.log(typeof parsedData.createdAt); // 輸出: string
// createdAt現(xiàn)在是一個(gè)字符串,不是Date對(duì)象了!
這時(shí)候就需要用到JSON.parse()的第二個(gè)參數(shù)reviver函數(shù)了:
const parsedData = JSON.parse(jsonString, (key, value) => {
// 檢查字符串是否符合ISO日期格式
if (typeof value === 'string' &&
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/.test(value)) {
return new Date(value); // 如果是日期字符串,轉(zhuǎn)換為Date對(duì)象
}
return value; // 否則保持原樣
});
console.log(typeof parsedData.createdAt); // 輸出: object
console.log(parsedData.createdAt instanceof Date); // 輸出: true
這個(gè)技巧在實(shí)際項(xiàng)目中特別有用,特別是當(dāng)你需要處理來(lái)自API的包含日期字段的數(shù)據(jù)時(shí)。
自定義序列化行為:toJSON方法
有時(shí)候,你可能想對(duì)某個(gè)對(duì)象的序列化過(guò)程有更精細(xì)的控制。這時(shí)候可以實(shí)現(xiàn)toJSON方法。
當(dāng)JSON.stringify()遇到一個(gè)對(duì)象有toJSON方法時(shí),它會(huì)調(diào)用這個(gè)方法并使用其返回值進(jìn)行序列化。
class User {
constructor(name, age, password) {
this.name = name;
this.age = age;
this.password = password;
}
// 自定義序列化行為
toJSON() {
return {
name: this.name,
age: this.age,
// 不包含password字段
// 可以添加計(jì)算屬性
isAdult: this.age >= 18
};
}
}
const user = new User('李四', 20, 'secret');
const jsonString = JSON.stringify(user);
console.log(jsonString);
// 輸出: {"name":"李四","age":20,"isAdult":true}
這種方法特別適合當(dāng)你需要為特定類(lèi)定義統(tǒng)一的序列化規(guī)則時(shí)。
實(shí)際應(yīng)用場(chǎng)景
讓我們來(lái)看一個(gè)綜合應(yīng)用的例子。假設(shè)我們正在開(kāi)發(fā)一個(gè)任務(wù)管理系統(tǒng):
class Task {
constructor(title, dueDate) {
this.title = title;
this.dueDate = dueDate; // Date對(duì)象
this.createdAt = new Date(); // 創(chuàng)建時(shí)間
this.isCompleted = false;
}
complete() {
this.isCompleted = true;
}
// 自定義序列化
toJSON() {
return {
title: this.title,
dueDate: this.dueDate,
createdAt: this.createdAt,
isCompleted: this.isCompleted,
// 添加計(jì)算屬性
isOverdue: !this.isCompleted && this.dueDate < new Date()
};
}
}
// 創(chuàng)建任務(wù)實(shí)例
const task = new Task('完成項(xiàng)目報(bào)告', new Date('2023-10-10'));
// 序列化時(shí)使用replacer確保日期格式正確
const replacer = (key, value) => {
if (value instanceof Date) {
return value.toISOString(); // 統(tǒng)一轉(zhuǎn)換為ISO格式
}
return value;
};
const taskJson = JSON.stringify(task, replacer);
console.log(taskJson);
// 反序列化時(shí)使用reviver恢復(fù)Date對(duì)象
const reviver = (key, value) => {
if (typeof value === 'string' &&
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/.test(value)) {
return new Date(value);
}
return value;
};
const parsedTask = JSON.parse(taskJson, reviver);
console.log(parsedTask.dueDate instanceof Date); // 輸出: true
避免常見(jiàn)陷阱
在使用這些技巧時(shí),有幾點(diǎn)需要特別注意:
性能考慮:replacer和reviver函數(shù)會(huì)對(duì)每個(gè)屬性執(zhí)行,在處理大型對(duì)象時(shí)可能影響性能。只在必要時(shí)使用它們。
錯(cuò)誤處理:JSON.parse()在遇到無(wú)效JSON時(shí)會(huì)拋出異常,記得用try-catch包裝:
try {
const data = JSON.parse(invalidJsonString);
} catch (error) {
console.error('解析JSON失敗:', error);
// 適當(dāng)?shù)腻e(cuò)誤處理邏輯
}
安全性:永遠(yuǎn)不要直接解析來(lái)自不可信源的JSON數(shù)據(jù),這可能帶來(lái)安全風(fēng)險(xiǎn)。始終驗(yàn)證和清理輸入數(shù)據(jù)。
總結(jié)
JSON數(shù)據(jù)處理看似簡(jiǎn)單,但其中有很多細(xì)節(jié)和技巧。掌握JSON.stringify()和JSON.parse()的高級(jí)用法,特別是第二個(gè)參數(shù)和toJSON方法,能讓你在處理復(fù)雜數(shù)據(jù)場(chǎng)景時(shí)游刃有余。
記住,好的工具要用在合適的地方。選擇最適合你當(dāng)前需求的方法,而不是一味追求最復(fù)雜的解決方案。
到此這篇關(guān)于JavaScrip中處理JSON數(shù)據(jù)的4個(gè)技巧分享的文章就介紹到這了,更多相關(guān)JavaScrip處理JSON數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js復(fù)制網(wǎng)頁(yè)內(nèi)容并兼容各主流瀏覽器的代碼
js 復(fù)制網(wǎng)頁(yè)內(nèi)容的方法代碼有很多不過(guò)要兼容各瀏覽器就不多了,下面有個(gè)不錯(cuò)的方法,大家可以嘗試操作下2013-12-12
微信小程序Page中data數(shù)據(jù)操作和函數(shù)調(diào)用方法
這篇文章主要介紹了微信小程序Page中data數(shù)據(jù)操作和函數(shù)調(diào)用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
利用Js的console對(duì)象,在控制臺(tái)打印調(diào)式信息測(cè)試Js的實(shí)現(xiàn)
下面小編就為大家?guī)?lái)一篇利用Js的console對(duì)象,在控制臺(tái)打印調(diào)式信息測(cè)試Js的實(shí)現(xiàn)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-11-11
JavaScript原生對(duì)象常用方法總結(jié)(推薦)
下面小編就為大家?guī)?lái)一篇JavaScript原生對(duì)象常用方法總結(jié)(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-05-05
JavaScript異步編程 Async/Await 使用從原理到最佳實(shí)踐記錄
Async/Await 的引入徹底改變了 JavaScript 異步編程的面貌,通過(guò)本文的講解,相信小伙伴們可以掌握 Async/Await 的使用精髓,將使您的 JavaScript 代碼在保持高性能的同時(shí),獲得質(zhì)的可讀性和可維護(hù)性提升,感興趣的朋友一起看看吧2025-05-05
解決使用layui的時(shí)候form表單中的select等不能渲染的問(wèn)題
今天小編就為大家分享一篇解決使用layui的時(shí)候form表單中的select等不能渲染的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09
JS Thunk 函數(shù)的含義和用法實(shí)例總結(jié)
這篇文章主要介紹了JS Thunk 函數(shù)的含義和用法,結(jié)合實(shí)例形式總結(jié)分析了JS Thunk 函數(shù)的具體含義、用法及操作注意事項(xiàng),需要的朋友可以參考下2020-04-04
頁(yè)面js遇到亂碼問(wèn)題的解決方法是和無(wú)法轉(zhuǎn)碼的情況
在老項(xiàng)目里加些js文件和老項(xiàng)目的編碼格式不一致出現(xiàn)亂碼,由于兩個(gè)文件都不能轉(zhuǎn)格式,于是百度個(gè)不錯(cuò)的方法在此與大家分享下2014-04-04
javascript面向?qū)ο罂焖偃腴T(mén)實(shí)例
這篇文章主要介紹了javascript面向?qū)ο罂焖偃腴T(mén)實(shí)例,以一個(gè)簡(jiǎn)單實(shí)例分析了javascript面向?qū)ο蟮闹袑?duì)象的定義與使用技巧,需要的朋友可以參考下2015-01-01

