- 以下js對象用JSON.stringify()執行后,是什么樣的?**
- 如何將最終的JSON字符串里面姓名相關的內容全部換成大寫,也就是把"Good"--->"GOOD",把"Man"--->"MAN"
var friend={
firstName: 'Good',
'lastName': 'Man',
'address': undefined,
'phone': ["1234567",undefined],
'fullName': function(){
return this.firstName + ' ' + this.lastName;
}
};
相關js函數介紹
將JS數據結構轉化為JSON字符串——JSON.stringify#
這個函數的函數簽名是這樣的:
JSON.stringify(value[, replacer [, space]])
下面將分別展開帶1~3個參數的用法,最后是它在序列化時做的一些“聰明”的事,要特別注意。
-
基本使用---僅需一個參數###
傳入一個JSON格式的JS對象或者數組,JSON.stringify({"name":"Good Man","age":18})返回一個字符串"{"name":"Good Man","age":18}"
-
第二個參數可以是函數,也可以是一個數組###
如果第二個參數是一個函數,那么序列化過程中的每個屬性都會被這個函數轉化和處理
如果第二個參數是一個數組,那么只有包含在這個數組中的屬性才會被序列化到最終的JSON字符串中
如果第二個參數是null,那作用上和空著沒啥區別,但是不想設置第二個參數,只是想設置第三個參數的時候,就可以設置第二個參數為null
- 第二個參數是函數
var friend={
"firstName": "Good",
"lastName": "Man",
"phone":"1234567",
"age":18
};
var friendAfter=JSON.stringify(friend,function(key,value){
if(key==="phone")
return "(000)"+value;
else if(typeof value === "number")
return value + 10;
else
return value; //如果你把這個else分句刪除,那么結果會是undefined
});
console.log(friendAfter);
//輸出:{"firstName":"Good","lastName":"Man","phone":"(000)1234567","age":28}
如果制定了第二個參數是函數,那么這個函數必須對每一項都有返回,這個函數接受兩個參數,一個鍵名,一個是屬性值,函數必須針對每一個原來的屬性值都要有新屬性值的返回。
- 第二個參數為數組
var friend={
"firstName": "Good",
"lastName": "Man",
"phone":"1234567",
"age":18
};
//注意下面的數組有一個值并不是上面對象的任何一個屬性名
var friendAfter=JSON.stringify(friend,["firstName","address","phone"]);
console.log(friendAfter);
//{"firstName":"Good","phone":"1234567"}
//指定的“address”由于沒有在原來的對象中找到而被忽略
如果第二個參數是一個數組,那么只有在數組中出現的屬性才會被序列化進結果字符串,只要在這個提供的數組中找不到的屬性就不會被包含進去,而這個數組中存在但是源JS對象中不存在的屬性會被忽略,不會報錯。
- 第三個參數用于美化輸出——不建議用
指定縮進用的空白字符,可以取以下幾個值
是字符串的話,就用該字符串代替空格,最多取這個字符串的前10個字符
沒有提供該參數 等于 設置成null 等于 設置一個小于1的數
var friend={
"firstName": "Good",
"lastName": "Man",
"phone":{"home":"1234567","work":"7654321"}
};
//直接轉化是這樣的:
//{"firstName":"Good","lastName":"Man","phone":{"home":"1234567","work":"7654321"}}
var friendAfter=JSON.stringify(friend,null,4);
console.log(friendAfter);
{
"firstName": "Good",
"lastName": "Man",
"phone": {
"home": "1234567",
"work": "7654321"
}
}
JSON.stringify函數的其他作用#
- 鍵名不是雙引號的(包括沒有引號或者是單引號),會自動變成雙引號;字符串是單引號的,會自動變成雙引號
最后一個屬性后面有逗號的,會被自動去掉 - 非數組對象的屬性不能保證以特定的順序出現在序列化后的字符串中
這個好理解,也就是對非數組對象在最終字符串中不保證屬性順序和原來一致 - 布爾值、數字、字符串的包裝對象在序列化過程中會自動轉換成對應的原始值
也就是你的什么new String("bala")會變成"bala",new Number(2017)會變成2017 - undefined、任意的函數以及 symbol 值(symbol詳見ES6對symbol的介紹
出現在非數組對象的屬性值中:在序列化過程中會被忽略
出現在數組中時:被轉換成 null
JSON.stringify({x: undefined, y: function(){return 1;}, z: Symbol("")});
//出現在非數組對象的屬性值中被忽略:"{}"
JSON.stringify([undefined, Object, Symbol("")]);
//出現在數組對象的屬性值中,變成null:"[null,null,null]"
- NaN、Infinity和-Infinity,不論在數組還是非數組的對象中,都被轉化為null
- 所有以 symbol 為屬性鍵的屬性都會被完全忽略掉,即便 replacer 參數中強制指定包含了它們
- 不可枚舉的屬性會被忽略
將JSON字符串解析為JS數據結構——JSON.parse#
這個函數的函數簽名是這樣的:
JSON.parse(text[, reviver])
如果第一個參數,即JSON字符串不是合法的字符串的話,那么這個函數會拋出錯誤,所以如果你在寫一個后端返回JSON字符串的腳本,最好調用語言本身的JSON字符串相關序列化函數,而如果是自己去拼接實現的序列化字符串,那么就尤其要注意序列化后的字符串是否是合法的,合法指這個JSON字符串完全符合JSON要求的嚴格格式
值得注意的是這里有一個可選的第二個參數,這個參數必須是一個函數,這個函數作用在屬性已經被解析但是還沒返回前,將屬性處理后再返回。
var friend={
"firstName": "Good",
"lastName": "Man",
"phone":{"home":"1234567","work":["7654321","999000"]}
};
//我們先將其序列化
var friendAfter=JSON.stringify(friend);
//'{"firstName":"Good","lastName":"Man","phone":{"home":"1234567","work":["7654321","999000"]}}'
//再將其解析出來,在第二個參數的函數中打印出key和value
JSON.parse(friendAfter,function(k,v){
console.log(k);
console.log(v);
console.log("----");
});
影響 JSON.stringify 的神奇函數——object.toJSON#
如果你在一個JS對象上實現了toJSON方法,那么調用JSON.stringify去序列化這個JS對象時,JSON.stringify會把這個對象的toJSON方法返回的值作為參數去進行序列化。
var info={
"msg":"I Love You",
"toJSON":function(){
var replaceMsg=new Object();
replaceMsg["msg"]="Go Die";
return replaceMsg;
}
};
JSON.stringify(info);
//出si了,返回的是:'"{"msg":"Go Die"}"',說好的忽略函數呢