json雖然簡單圣拄,但這些細節(jié)你未必知道

基本介紹

JSON的全稱是JavaScript Object Notation绅你,它并不是編程語言纪岁,而是一種可以在服務器和客戶端之間傳輸?shù)臄?shù)據(jù)格式凑队,本來是JavaScript的子集,但現(xiàn)在已獨立存在于各種編程語言中幔翰。

它有以下使用場景

  • 網絡數(shù)據(jù)傳遞時漩氨,比如http請求中參數(shù)
  • 項目里某些配置文件,比如package.json文件
  • 非關系型數(shù)據(jù)庫(NoSQL)將json作為存儲格式

語法

它的文件以 .json 為后綴名遗增,但json文件頂層的代碼有嚴格限制叫惊,只能寫以下三種,不然代碼會直接標紅~

1做修、簡單值
數(shù)字(Number)霍狰、字符串(String,不支持單引號)饰及、布爾類型(Boolean)蔗坯、null類型

2、對象值
由key燎含、value組成宾濒,key是字符串類型,必須添加雙引號屏箍,值可以是簡單值绘梦、對象值橘忱、數(shù)組值

3、數(shù)組值
簡單值卸奉、對象值钝诚、數(shù)組值

1_json支持的格式.png

序列化 stringify

在http請求中攜帶參數(shù)經常用到json格式,但我們一般不會在代碼中直接使用json榄棵,因為json數(shù)據(jù)中操作屬性并不方便敲长,大多數(shù)時候是使用對象,將對象轉成json格式就可以通過 stringify 方法秉继。

stringify方法有三個參數(shù)

  • 參數(shù)一(必傳)祈噪,傳入一個對象,表示對于哪個對象進行stringify操作
  • 參數(shù)二(可選)尚辑,傳入數(shù)組或者函數(shù)辑鲤,數(shù)組里包括對象的key值,表示對于對象中的指定key值的數(shù)據(jù)進行序列化杠茬,傳入函數(shù)表示對指定的key/value值進行操作
  • 參數(shù)三(可選)月褥,用于改變序列化之后的json數(shù)據(jù)展現(xiàn)格式

我們對以下對象進行操作

const user = {
  name: "alice",
  age: 20,
  friends: ["lisa", "macus", "windy"],
  info: {
    teacher: "kiki",
  },
};
直接轉換

當只傳入一個參數(shù)時,進行基本的序列化操作

const str1 = JSON.stringify(user);
console.log(str1);
2_stringify基本使用.png
操作指定的key值
const str2 = JSON.stringify(user, ["name", "friends"]);
const str3 = JSON.stringify(user, (key, value) => {
  if (key === "age") {
    return value + 1;
  }
  return value;
});
console.log(str2);
console.log(str3);

當傳入第二個參數(shù)時瓢喉,傳入數(shù)組宁赤,表示只對 key值為“name”,“friends”的數(shù)據(jù)進行序列化栓票;傳入函數(shù)决左,表示操作 key 值為“age”的時候,value+1

3_stringify的第二個參數(shù).png
改變json展現(xiàn)格式
const str4 = JSON.stringify(user, null, 2);
const str5 = JSON.stringify(user, null, "*");
console.log(str4);
console.log(str5);

傳入第三個參數(shù)走贪,2表示換行空2格佛猛,* 表示換行及每行內容前加 * 號

4_stringify的第三個參數(shù).png
toJson方法

如果原對象中有toJSON方法,那么stringify方法直接調用toJSON方法坠狡。我們給上面的對象加上toJSON方法继找,所有的stringify方法的執(zhí)行結果都會變化。

const user = {
  name: "alice",
  age: 20,
  friends: ["lisa", "macus", "windy"],
  info: {
    teacher: "kiki",
  },
  toJSON(){
    return 'hello world'
  }
};

const str1 = JSON.stringify(user);
const str2 = JSON.stringify(user, ["name", "friends"]);
const str3 = JSON.stringify(user, (key, value) => {
  if (key === "age") {
    return value + 1;
  }
  return value;
});
const str4 = JSON.stringify(user, null, 2);
const str5 = JSON.stringify(user, null, "*");

console.log(str1);
console.log(str2);
console.log(str3);
console.log(str4);
console.log(str5);

stringify方法的執(zhí)行結果都變成了 toJSON 方法的返回值

5_toJSON方法.png

解析 parse

接口請求返回的參數(shù)中一般是json數(shù)據(jù)逃沿,我們要使用首先得通過parse方法將它轉成對象婴渡。

parse方法可以接收兩個參數(shù)

  • 參數(shù)一(必傳),json數(shù)據(jù)凯亮,表示將哪一個json數(shù)據(jù)轉成對象
  • 參數(shù)二(可選)边臼,傳入函數(shù),表示對指定的key/value值進行操作
const str =
  '{"name":"alice","age":21,"friends":["lisa","macus","windy"],"info":{"teacher":"kiki"}}';
  
const obj1 = JSON.parse(str)
const obj2 = JSON.parse(str, (key, value)=>{
  if(key === 'age'){
    return value - 1
  }
  return value
})

console.log(obj1)
console.log(obj2)

傳入函數(shù)触幼,處理 key值為age時的數(shù)據(jù)硼瓣,此時操作 value - 1

6_parse方法.png

拷貝

拷貝有以下幾種形式,拷貝出來的內存地址指向不一樣

直接賦值

通過等于符號可以將一個對象賦值給另一個對象置谦。

const user = {
  name: "alice",
  info: {
    hobbies: "tennis",
  },
};
const person = user;
user.name = "lisa";

console.log("user", user);
console.log("person", person);

但它們其實指向的是同一個對象堂鲤,如果操作其中一個對象的值,另外一個對象也會發(fā)生變化

7_直接賦值.png

在內存中表現(xiàn)如下

8_直接賦值內存圖.png

淺拷貝

淺拷貝只會遍歷一層媒峡,如果對象中還有value值為對象或者數(shù)組的情況瘟栖,那么更深一層不會被拷貝,展開運算符或者Object.assign可以進行淺拷貝谅阿。

const user = {
  name: "alice",
  info: {
    hobbies: "tennis",
  },
};
const consumer = { ...user };
user.name = "lisa";
user.info.hobbies = "swimming";

console.log("user", user);
console.log("consumer", consumer);

淺拷貝后半哟,user和consumer已經不是同一個對象了,但他們倆當中的info仍然指向同一個對象签餐,修改其中一個info中的屬性寓涨,另一個也會變化

9_淺拷貝.png

在內存中表現(xiàn)如下

10_淺拷貝內存圖.png

深拷貝

深拷貝表示拷貝出來的對象與原對象完全無關,操作任意屬性都不會互相影響氯檐,通過 stringify 和 parse 方法可以實現(xiàn)深拷貝戒良。

const user = {
  name: "alice",
  info: {
    hobbies: "tennis",
  },
};

const human = JSON.parse(JSON.stringify(user));
user.name = "lisa";
user.info.hobbies = "swimming";

console.log("user", user);
console.log("human", human);

此時user和human不是指向同一個對象,他們中的info對象也不是同一個對象

11_深拷貝.png

在內存中表現(xiàn)如下

12_深拷貝內存圖.png
stringify和parse實現(xiàn)深拷貝存在問題

雖然stringify和parse可以實現(xiàn)深拷貝冠摄,但是這種方式仍存在一些問題糯崎,如果對象中存在【方法、undefined河泳、Symbol】沃呢,會直接被移除

const user = {
  name: "alice",
  height: undefined,
  [Symbol("age")]: 20,
  info: {
    hobbies: "tennis",
  },
  study() {
    console.log("I love reading~");
  },
};
const people = JSON.parse(JSON.stringify(user));

console.log("user", user);
console.log("person", people);

只剩下符合json規(guī)范的數(shù)據(jù)

13_stringify實現(xiàn)深拷貝的問題.png

因為存在這種問題,所以一般不會用stringify和parse方法拆挥,可以自己編寫處理深拷貝的方法薄霜,至于自定義深拷貝方法,留在后面的文章中詳細介紹纸兔。

以上就是json相關內容黄锤,關于js高級,還有很多需要開發(fā)者掌握的地方食拜,可以看看我寫的其他博文鸵熟,持續(xù)更新中~

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市负甸,隨后出現(xiàn)的幾起案子流强,更是在濱河造成了極大的恐慌,老刑警劉巖呻待,帶你破解...
    沈念sama閱讀 219,589評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件打月,死亡現(xiàn)場離奇詭異,居然都是意外死亡蚕捉,警方通過查閱死者的電腦和手機奏篙,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人秘通,你說我怎么就攤上這事为严。” “怎么了肺稀?”我有些...
    開封第一講書人閱讀 165,933評論 0 356
  • 文/不壞的土叔 我叫張陵第股,是天一觀的道長。 經常有香客問我话原,道長夕吻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,976評論 1 295
  • 正文 為了忘掉前任繁仁,我火速辦了婚禮涉馅,結果婚禮上,老公的妹妹穿的比我還像新娘黄虱。我一直安慰自己稚矿,他們只是感情好,可當我...
    茶點故事閱讀 67,999評論 6 393
  • 文/花漫 我一把揭開白布悬钳。 她就那樣靜靜地躺著盐捷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪默勾。 梳的紋絲不亂的頭發(fā)上碉渡,一...
    開封第一講書人閱讀 51,775評論 1 307
  • 那天,我揣著相機與錄音母剥,去河邊找鬼滞诺。 笑死,一個胖子當著我的面吹牛环疼,可吹牛的內容都是我干的习霹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼炫隶,長吁一口氣:“原來是場噩夢啊……” “哼淋叶!你這毒婦竟也來了?” 一聲冷哼從身側響起伪阶,我...
    開封第一講書人閱讀 39,359評論 0 276
  • 序言:老撾萬榮一對情侶失蹤煞檩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后栅贴,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體斟湃,經...
    沈念sama閱讀 45,854評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,007評論 3 338
  • 正文 我和宋清朗相戀三年檐薯,在試婚紗的時候發(fā)現(xiàn)自己被綠了凝赛。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,146評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖墓猎,靈堂內的尸體忽然破棺而出捆昏,到底是詐尸還是另有隱情陶衅,我是刑警寧澤直晨,帶...
    沈念sama閱讀 35,826評論 5 346
  • 正文 年R本政府宣布搀军,位于F島的核電站,受9級特大地震影響罩句,放射性物質發(fā)生泄漏。R本人自食惡果不足惜敛摘,卻給世界環(huán)境...
    茶點故事閱讀 41,484評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望兄淫。 院中可真熱鬧屯远,春花似錦捕虽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽晌端。三九已至捅暴,卻和暖如春咧纠,著一層夾襖步出監(jiān)牢的瞬間蓬痒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評論 1 272
  • 我被黑心中介騙來泰國打工漆羔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留梧奢,地道東北人。 一個月前我還...
    沈念sama閱讀 48,420評論 3 373
  • 正文 我出身青樓钧椰,卻偏偏與公主長得像粹断,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嫡霞,可洞房花燭夜當晚...
    茶點故事閱讀 45,107評論 2 356

推薦閱讀更多精彩內容