,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對象一樣處理它。
者: 一川 來源:前端萬有引力
前幾天看到前端胖頭魚的一篇文章《就因?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ù)類型理解的深度,和各種極端的邊界情況的處理能力。
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]])
注意:
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 |
其實(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, '"')
}
}
}
《MDN:JSON.stringify()》
《就因?yàn)镴SON.stringify,我的年終獎(jiǎng)差點(diǎn)打水漂了》
我們平時(shí)開發(fā)中將JSON.stringify應(yīng)用最多的可能就是淺層的對象進(jìn)行深拷貝,也就是進(jìn)行序列化處理。但是當(dāng)我們進(jìn)行手撕代碼的時(shí)候,需要考慮各種邊界情況,這對于我們來說就比較麻煩,作為面試也是對數(shù)據(jù)類型的全面考察。
*請認(rèn)真填寫需求信息,我們會在24小時(shí)內(nèi)與您取得聯(lián)系。