JSON.stringify() 方法

admin發表於2019-07-12

功能非常簡單的一個方法,但是有很多細節需要注意,本文通過程式碼例項詳細介紹。

由此方法的名稱入手,從 simplify 單詞分析開始:

(1).simplify 是由 simple 衍化而來,加上 ify 字尾,變成一個動詞,功能是使 ... 簡單化。

(2).同樣的道理,stringify 是由 string 衍化而來,加上 ify 字尾,功能是使 ... 字串化。

JSON.stringify() 的定義是將引數轉換為 JSON,其實就是將引數轉換為字串。

當然轉換是需要遵循一定規則的,後面會分步進行詳細介紹。

語法結構:

[JavaScript] 純文字檢視 複製程式碼
JSON.stringify(value [, replacer] [, space])

引數解析:

(1).value:必需,要被轉換的 JavaScript 值,通常情況下是物件直接量或者陣列。

(2).replacer:可選,對 value 進行轉換的函式或者陣列。

(3).space:可選,向返回的 JSON 中的內容新增縮排、空白和換行符以使其更易於閱讀。

上面對引數的作用做了一下簡單介紹,讓讀者對其有一個初步印象,具體作用在下面程式碼例項中介紹。

程式碼例項如下:

絕大多數時候此方法是對物件或者陣列的操作,實際專案中最為常見。

又由於此方法的操作就是將引數轉換為 JSON,所以很多朋友想當然認為 JSON 只能是如下兩種類似形式:

[JavaScript] 純文字檢視 複製程式碼
{
  "webName":"螞蟻部落",
  "url":"softwhy.com",
  "age":2
}

再來看一個和陣列相互巢狀的形式:

[JavaScript] 純文字檢視 複製程式碼
{
  "web": [
    { "webName":"螞蟻部落" , "url":"softwhy.com" },
    { "webName":"網易" , "url":"163.com" }
  ]
}

其實並不是只有上述兩種形式,看如下程式碼例項:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
console.log(JSON.stringify(5));
console.log(JSON.stringify(true));
console.log(JSON.stringify("antzone"));
console.log(JSON.stringify(null));
console.log(JSON.stringify(undefined));
console.log(JSON.stringify(function(){}));
console.log(JSON.stringify(Symbol("前端教程")));

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201907/12/165711syl4xf2x6o6ybx7l.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

具有結果的都是JSON資料,並不僅僅是物件或者陣列被轉換後的字串是JSON。

上述程式碼分析如下:

(1).數字會被轉換為字串"5"。

(2).布林值true被轉換為字串"true"。

(3).字串"antzone",列印結果帶有雙引號,字串本身帶有雙引號,JSON.stringify()方法將"antzone"整體作為字串處理,所以處理的結果是"\"antozne\"",如果是用單引號包裹,也會被轉換為雙引號。

(4).null會被轉換為字串"null"。

(5).undefined、function函式和Symbol資料會被忽略。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
console.log(JSON.stringify(new Date()));

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201907/12/165736iugo0rb0hkndjrb1.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

列印出一段與時間日期相關的字串,這是因為時間日期物件具有toJSON方法。

轉換過程中,如果物件具有toJSON方法,那麼會首先呼叫此方法,具體參閱toJSON() 方法一章節。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let antzone={
  webName:'螞蟻部落',
  target:"分享互助",
  age:5
}
console.log(JSON.stringify(antzone));

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201907/12/165820u30aatozttuzom0w.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

上述程式碼只有一個引數,可以看到屬性被雙引號包裹,這一點要特別注意,一定是雙引號。

如果屬性值原本是字串,那麼一定也要用雙引號包裹,如果原來是單引號,也要轉換為雙引號。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let arr=["螞蟻部落",'分享互助',3];
console.log(JSON.stringify(arr));

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201907/12/165850msahsogb22gshlgp.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

類似,陣列中的資料,如果原本是字串,一定要採用雙引號包裹。

具有兩個引數的情況:

JSON.stringify()第二個引數可以是兩種形式,一種是函式,第二種是陣列,下面分別做一下介紹。

1.當是函式的情況:

具有兩個引數,分別是物件屬性和屬性值,或者陣列索引和陣列值。

它的返回值對於value引數的序列化結果有直接的影響。

(1).如果返回值是undefined,那麼value引數序列化的結果為 undefined 或者當前遞迴序列化物件的屬性被刪除。

(2).如果返回值是一個物件,那麼該物件會被遞迴序列化。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let arr=["螞蟻部落","antzone",5];
function done(key,value){
}
let jsonStr=JSON.stringify(arr,done);
console.log(jsonStr);

上面的程式碼中,陣列被序列化後的結果為undefined,因為第二個引數函式的返回值是undefined。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let obj={
  webName:"antzone",
  age:2,
  target:"分享互助",
  team:{
    a:"jquery專區",
    b:"css專區"
  }
}
function done(key,value){
  if(value=="antzone"){
    return undefined;
  }
  else{
    return value;
  }
}
let jsonStr=JSON.stringify(obj,done);
console.log(jsonStr);

屬性值為"antzone",對應屬性就會被刪除,如果此函式返回的值是物件的話,會將此返回的物件遞迴序列化。

2.當是陣列的時候:

(1).如果value引數是陣列,那麼第二個引數陣列不起任何作用。

如果物件屬性名稱在陣列元素中存在,那麼此屬性將會被保留,否則會被刪除。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let one=["螞蟻部落","antzone","分享互助",3];
let two=["antzone",3];
let jsonStr=JSON.stringify(one,two);
console.log(jsonStr);

第二個陣列引數不會起到任何作用。

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let obj={
  antzone:"螞蟻部落",
  target:"分享互助",
  age:3
}
let arr=["antzone",3];
let jsonStr=JSON.stringify(obj,arr);
console.log(jsonStr);

第二個引數陣列會對物件屬性進行過濾,如果物件屬性名稱在陣列中存在,那麼就會保留,否則刪除。

具有三個引數的情況:

可以向返回值JSON文字新增縮排,具體規則如下:

(1).如果宣告此引數,則將生成返回值文字,而沒有任何額外空白。

(2).如果是數字,則返回值文字在每個級別縮排指定數目空格,如果space大於10,則縮排10個空格。

(3).如果是一些轉義字元,比如“\t”,表示回車,那麼它每行一個回車。

(4).如果是非空字串,則返回值文字在每個級別字串前面附加上返回的字串即可。

(5).如果是長度大於10個字元的字串,則使用前10個字元。

(6).由於這個比較簡單,就不給出程式碼了,通常情況下,第三個引數都是省略的。

undefined、function和Symbol處理:

在文章的開頭部分已經提到過,JSON資料不支援上述三種型別資料。

但是在不同的上下文中,JSON.stringify() 方法對它們的處理方式不同。

直接通過JSON.stringify() 方法轉換三種資料,方法的返回值是undefined,也可以認為被轉換為了undefined。

如果上述三種型別的值作為物件屬性,那麼會直接被忽略,程式碼如下:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let antzone={
  webName:"螞蟻部落",
  age:undefined,
  func:function(){},
  sy:Symbol("前端教程")
}
console.log(JSON.stringify(antzone));

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201907/13/100103n0yxzcgkzfkkokay.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

可以看到值為上述三種型別的屬性直接被無視了。

如果上述三種型別的值作為陣列成員,那麼會被轉換為null,程式碼如下:

[JavaScript] 純文字檢視 複製程式碼執行程式碼
let arr=["螞蟻部落",undefined,function(){},Symbol("前端教程")];
console.log(JSON.stringify(arr));

程式碼執行效果截圖如下:

a:3:{s:3:\"pic\";s:43:\"portal/201907/13/100523m4q024mb13553jly.jpg\";s:5:\"thumb\";s:0:\"\";s:6:\"remote\";N;}

可以看到三種型別的資料,在陣列中被轉換成了null。

相關文章