整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          JSON(JavaScript Object Not

          JSON(JavaScript Object Notation)數(shù)據(jù)格式

          ,JSON(JavaScript Object Notation):是一種輕量級的數(shù)據(jù)交互格式,基于 ECMAScript 的一個(gè)子集,采用完全獨(dú)立于編程語言的文本格式來存儲和表示數(shù)據(jù)。在JSON出現(xiàn)之前,常用XML來傳遞數(shù)據(jù),XML是一種純文本格式,適合在網(wǎng)絡(luò)上交換數(shù)據(jù)。JSON 比 XML 更小、更快,更易解析,JavaScript原生支持JSON。

          2,JSON語法結(jié)構(gòu):JSON數(shù)據(jù)由鍵值對組成,每個(gè)鍵值對之間用逗號分隔,整個(gè)數(shù)據(jù)以大括號 {} 包裹表示一個(gè)對象,或者以中括號 [] 包裹表示一個(gè)數(shù)組。基本語法結(jié)構(gòu)為:

          對象(Object):{} 包裹,鍵對應(yīng)的值之間使用冒號,健值對之間用逗號。如

          { "name": "張3", "age": 30 }


          數(shù)組(Array): [] 包裹,元素之間使用逗號分隔。如:

          [ "apple", "banana", "orange" ]

          [ {"name": "張3", "age": 30}, {"name": "李4", "age": 25} ]

          3,規(guī)則:數(shù)據(jù)在名稱/值對中,數(shù)據(jù)由逗號分隔,大括號保存對象,中括號保存數(shù)組。

          4,JSON值:數(shù)字(整數(shù)/浮點(diǎn)數(shù))、字符串(雙引號)、布爾值(true/false)、數(shù)組(中括號)、對象(大括號)、null。

          JavaScript中,你可以使用in運(yùn)算符或hasOwnProperty()方法來檢查一個(gè)JSON對象是否包含某個(gè)屬性(字段)。如果對象包含該字段,你可以直接使用點(diǎn)符號(.)或方括號([])表示法來讀取它的值。

          以下是使用in運(yùn)算符和hasOwnProperty()方法檢查對象屬性并讀取其值的示例程序:

          // 假設(shè)我們有一個(gè)JSON對象  
          var jsonObject={  
              "name": "Alice",  
              "age": 30,  
              "city": "New York"  
          };  
            
          // 要檢查的字段名  
          var fieldName="age";  
            
          // 使用 'in' 運(yùn)算符檢查字段是否存在  
          if (fieldName in jsonObject) {  
              console.log("字段 '" + fieldName + "' 存在,其值為:" + jsonObject[fieldName]);  
          } else {  
              console.log("字段 '" + fieldName + "' 不存在");  
          }  
            
          // 或者使用 'hasOwnProperty()' 方法檢查字段是否存在  
          if (jsonObject.hasOwnProperty(fieldName)) {  
              console.log("字段 '" + fieldName + "' 存在,其值為:" + jsonObject.age);  
              // 或者使用動態(tài)屬性訪問方式  
              console.log("字段 '" + fieldName + "' 存在,其值為:" + jsonObject[fieldName]);  
          } else {  
              console.log("字段 '" + fieldName + "' 不存在");  
          }  
            
          // 如果要讀取的字段名是動態(tài)的,則必須使用方括號表示法  
          var dynamicFieldName="city";  
          if (dynamicFieldName in jsonObject) {  
              console.log("動態(tài)字段 '" + dynamicFieldName + "' 存在,其值為:" + jsonObject[dynamicFieldName]);  
          }

          在這個(gè)示例中,我們首先定義了一個(gè)名為jsonObject的JSON對象,然后定義了一個(gè)要檢查的字段名fieldName。我們使用in運(yùn)算符和hasOwnProperty()方法來檢查該字段是否存在于對象中。如果存在,我們就使用點(diǎn)符號(在字段名已知且不是動態(tài)的情況下)或方括號表示法(在字段名是動態(tài)的情況下)來讀取它的值。

          請注意,雖然在這個(gè)例子中我們使用了術(shù)語“JSON對象”,但實(shí)際上jsonObject是一個(gè)普通的JavaScript對象。在JavaScript中,JSON(JavaScript Object Notation)通常用于表示數(shù)據(jù)的序列化格式,即字符串形式的對象表示。但是,一旦JSON字符串被解析成JavaScript對象(例如,通過JSON.parse()方法),你就可以像處理任何其他JavaScript對象一樣處理它。

          者: 一川 來源:前端萬有引力

          1寫在前面

          前幾天看到前端胖頭魚的一篇文章《就因?yàn)镴SON.stringify,我的年終獎(jiǎng)差點(diǎn)打水漂了》,講的就是JSON.stringify在工程開發(fā)中的應(yīng)用,線上用戶不能提交表單。因?yàn)樽侄沃薪?jīng)過JSON.stringify后的字符串對象缺少value key,導(dǎo)致后端parse之后無法正確讀取value值,進(jìn)而報(bào)接口系統(tǒng)異常,用戶無法進(jìn)行下一步動作。本篇文章就將詳細(xì)談?wù)凧SON.stringify,并將帶著你進(jìn)行自己手寫一個(gè)JSON.stringify,站在全局考察自己對于各種數(shù)據(jù)類型理解的深度,和各種極端的邊界情況的處理能力。

          2JSON.stringify()

          JSON.stringify是日常開發(fā)中經(jīng)常用到的JSON對象中的一個(gè)方法,用于將一個(gè) JavaScript 對象或值轉(zhuǎn)換為 JSON 字符串,如果指定了一個(gè) replacer 函數(shù),則可以選擇性地替換值,或者指定的 replacer 是數(shù)組,則可選擇性地僅包含數(shù)組指定的屬性。

          簡而言之,就是用于將對象轉(zhuǎn)換成JSON字符串。

          JSON.stringify(value[, replacer [, space]]) 
          • value:必填參數(shù),需要序列化的JSON對象。
          • replacer:可選參數(shù)。
            • 函數(shù)類型:則在序列化過程中,被序列化的值的每個(gè)屬性都會經(jīng)過該函數(shù)的轉(zhuǎn)換和處理;
            • 數(shù)組類型:則只有包含在這個(gè)數(shù)組中的屬性名才會被序列化到最終的 JSON 字符串中;
            • null或未提供:則對象所有的屬性都會被序列化。
          • space:可選參數(shù),用來控制字符串之間的間距。
          • 指定縮進(jìn)用的空白字符串,用于美化輸出(pretty-print);
          • 數(shù)字類型,它代表有多少的空格;上限為10。小于1,意味著沒有空格;
          • 字符串類型,當(dāng)字符串長度超過10個(gè)字母,取其前10個(gè)字母,該字符串將被作為空格;
          • null或未提供,將沒有空格。

          注意:

          • 循環(huán)引用的對象(對象之間相互引用,形成無限循環(huán))執(zhí)行此方法,會拋出錯(cuò)誤。
          • 布爾值、數(shù)字、字符串的包裝對象在序列化過程中會自動轉(zhuǎn)換成對應(yīng)的原始值。
          • undefined、任意的函數(shù)以及symbol值,在序列化過程中會被忽略(出現(xiàn)在非數(shù)組對象的屬性值中時(shí))或者被轉(zhuǎn)換成 null(出現(xiàn)在數(shù)組中時(shí))。函數(shù)、undefined被單獨(dú)轉(zhuǎn)換時(shí),會返回 undefined,如JSON.stringify(function(){}) or JSON.stringify(undefined)。這就是為什么對象中有這些類型的屬性,不能使用JSON.parse(JSON.stringify())來進(jìn)行深拷貝。
          • Date 日期調(diào)用了 toJSON() 將其轉(zhuǎn)換為了 string 字符串(同Date.toISOString()),因此會被當(dāng)做字符串處理。
          • NaN 和 Infinity 格式的數(shù)值及 null 都會被當(dāng)做 null。
          • 其他類型的對象,包括 Map/Set/WeakMap/WeakSet,僅會序列化可枚舉的屬性。
          const user={name:"yichuan",age:18,university:"SCU"}; 
          //1.序列化對象 
          console.log(JSON.stringify(user));//'{"name":"yichuan","age":18,"university":"SCU"}' 
           
          //2.序列化基礎(chǔ)數(shù)據(jù)類型 
          console.log(JSON.stringify("平"));//"平" 
          console.log(JSON.stringify(18));//"18" 
          console.log(JSON.stringify(true));//"true" 
          console.log(JSON.stringify(null));//"null" 
          console.log(JSON.stringify(undefined));//undefined 
           
          //3.使用replacer函數(shù) 
          console.log(JSON.stringify(user,function(key,value){ 
             return typeof value==="number" ? 666 : "sixsixsix"; 
          }));//'{name:"sixsixsix",age:666,university:"sixsixsix"}' 
           
          //4.指定數(shù)組 
          console.log(JSON.stringify(user,["name"]));//'{"name":"yichuan"}' 
           
          //5.指定字符串間的間距 
          console.log(JSON.stringify(user,null,2)); 
          /* 
          { 
            "name": "yichuan", 
            "age": 18, 
            "university": "SCU" 
          } 
          */ 
           
          //6.指定字符串的間距”*“ 
          console.log(JSON.stringify(user,null,"*****")); 
          /* 
          { 
          *****"name": "yichuan", 
          *****"age": 18, 
          *****"university": "SCU" 
          } 
          */ 

          整理歸納:

          JSON.stringify

          輸入

          輸出

          基礎(chǔ)數(shù)據(jù)類型

          string

          string


          number

          字符串類型的字符串


          boolean

          "true"/"false"


          undefined

          undefined


          null

          "null"


          NaN和Infinity

          "null"


          symbol

          undefined


          BigInt

          報(bào)錯(cuò)

          引用數(shù)據(jù)類型

          function

          undefined


          Array數(shù)組中出現(xiàn)了function、undefined、symbol

          string/"null"

          | | | regExp | "{}" | | | Date | Date的toJSON()字符串 | | | 普通object |

          • 如果有toJSON()方法,那么序列化toJSON()的返回值
          • 如果屬性值中出現(xiàn)了function、undefined、symbol則忽略
          • 所有以symbol為屬性鍵的屬性都會被完全忽略掉 |

          3手撕JSON.stringify()

          其實(shí)現(xiàn)場手撕代碼還是有點(diǎn)麻煩的,需要考慮到對各種類型的數(shù)據(jù)進(jìn)行處理,考慮各種邊界情況。

          function stringify(data){ 
           const type=typeof data; 
            //可能為基礎(chǔ)數(shù)據(jù)類型的處理 
            if(type !=="object"){ 
             //判斷是否為NaN或Infinity或者null 
              if(Number.isNaN(data)||data===Infinity){ 
               return "null"; 
              } 
              //判斷可能為function、undefined、symbol類型 
              if(type==="function" || type==="undefined" || type==="symbol" ){ 
               return undefined 
              } 
              //判斷字符串或數(shù)值的處理 
              if(type==="string" || type==="number"){ 
               return `"${data}"` 
              } 
              if (typeof data==='bigint') { 
                throw new TypeError('Do not know how to serialize a BigInt') 
              } 
              if (isCyclic(data)) { 
                throw new TypeError('Converting circular structure to JSON') 
              } 
              return String(data); 
            }else{ 
             //null 
              if(type==="null"){ 
               return "null" 
              }else if(data.toJSON && typeof data.toJSON==="function"){ 
                //遞歸 
               return stringify(data.toJSON); 
              }else if(Array.isArray(data)){ 
               const arr=[]; 
                //對于數(shù)組類型有很多種情況 
                data.forEach((item,index)=>{ 
                 //判斷可能為function、undefined、symbol類型 
                  if(type==="function" || type==="undefined" || type==="symbol" ){ 
                    arr[index]="null" 
                  }else{ 
                    arr[index]=stringify(item); 
                  } 
                }); 
                result=`"${arr}"`; 
                return arr.result.replace(/'/g,""); 
              }else{ 
               //普通對象 
                const arr=[]; 
                //遍歷對象 
                Object.keys(data).forEach((key)=>{ 
                 //key如果是symbol類型,忽略 
                  if(data[key]!=="symbol"){ 
                    if(typeof data[key]!=="undefined" && typeof data[key]!=="function" && typeof data[key]!=="symbol"){ 
                      arr.push(`"${key}":stringify(data[key])`); 
                    } 
                  } 
                   
                }) 
                return `{${arr}}`.replace(/'/g, '"') 
              } 
            } 
          } 

          4參考文章

          《MDN:JSON.stringify()》

          《就因?yàn)镴SON.stringify,我的年終獎(jiǎng)差點(diǎn)打水漂了》

          5寫在最后

          我們平時(shí)開發(fā)中將JSON.stringify應(yīng)用最多的可能就是淺層的對象進(jìn)行深拷貝,也就是進(jìn)行序列化處理。但是當(dāng)我們進(jìn)行手撕代碼的時(shí)候,需要考慮各種邊界情況,這對于我們來說就比較麻煩,作為面試也是對數(shù)據(jù)類型的全面考察。


          主站蜘蛛池模板: 国产在线一区二区在线视频| 亚洲一区二区三区91| 亚洲天堂一区二区三区四区| 日本美女一区二区三区| 日韩精品乱码AV一区二区| chinese国产一区二区| 尤物精品视频一区二区三区 | 久久国产三级无码一区二区| 亚洲一区二区三区电影| 国产成人无码一区二区三区在线| 狠狠综合久久av一区二区| 人妻少妇精品视频三区二区一区| 精品国产一区二区三区久久久狼 | 国产高清视频一区二区| 国产精品亚洲一区二区在线观看| 国产成人一区二区三中文| 亚洲欧美日韩中文字幕在线一区 | 国产美女视频一区| 无码少妇一区二区浪潮av| 久久精品国产一区二区| 亚洲国产成人一区二区精品区| 久久精品国产一区二区三| 亚洲福利秒拍一区二区| 日韩在线一区视频| 国产一区中文字幕| 中文字幕乱码一区二区免费| 亚洲国产一区国产亚洲| 无码精品前田一区二区| 免费一区二区无码视频在线播放 | 亚洲男人的天堂一区二区| 日韩一本之道一区中文字幕| 一区二区三区日韩精品| 理论亚洲区美一区二区三区| 少妇无码AV无码一区| 亚洲AV成人精品日韩一区| 国产一区二区三区高清视频| 亚洲综合av一区二区三区不卡| 免费人人潮人人爽一区二区| 中文字幕一区二区三区久久网站| 国产一区二区三区不卡在线观看 | 国产一区二区三区在线观看影院|