前段時間勾股有提到stringify是支持三個參數,刷新的了我的認知,后來查到文檔才發現還真的是支持三個參數的。
參考資料:
stringify方法顧名思義,就是把JSON序列換,其語法如下:
JSON.stringify(value[, replacer [, space]])
注意到它接收三個參數,后面2個參數是可選的。
只傳一個參數
var data = {name:"niuzai",info:{age:18,sex:"male"}};
JSON.stringify(data); //{"name":"niuzai","info":{"age":18,"sex":"male"}}
這里要注意:stringily對data里的數據類型有一些要求:
- 非數組對象的屬性不能保證以特定的順序出現在序列化后的字符串中。
- 就是不能保證hash結構的順序是按照定義輸出
JSON.stringify({x: 5, y: 6});
// '{"x":5,"y":6}' 或者 '{"y":6,"x":5}' 都可能
- 布爾值、數字、字符串的包裝對象在序列化過程中會自動轉換成對應的原始值。
undefined
、任意的函數以及 symbol 值,在序列化過程中會被忽略(出現在非數組對象的屬性值中時)或者被轉換成null
(出現在數組中時)。
var obj = {"undefined":undefined,"func":function(){},"symbol":Symbol("")};
JSON.stringify(data); //"{}"
var arr = [undefined,Symbol(""),function(){}];
JSON.stringify(arr); //[null,null,null]
- 所有以 symbol 為屬性鍵的屬性都會被完全忽略掉,即便
replacer
參數中強制指定包含了它們。
JSON.stringify({[Symbol("foo")]: "foo"}); //'{}'
- 不可枚舉的屬性會被忽略
JSON.stringify( Object.create(null, { x: { value: 'x', enumerable: false }, y: { value: 'y', enumerable: true } }) );
// '{"y":"y"}'
兩個參數
第二個參數很有意思,可以為一個過濾函數,也可以是一個數組。
當為數組時被序列化的值的每個屬性都會經過該函數的轉換和處理,當為數組時則只有包含在這個數組中的屬性名才會被序列化到最終的 JSON 字符串中。
過濾函數
過濾函數還是比較有意思的,你可以控制輸出,比如之前提到的會被忽略的類型,可以在這里人工的處理,強制輸出(當然是別的類型)。
var data = {
name:"niuzai",
info:{
age:18,
sex:"male"
}
};
JSON.stringify(data, function(key, val){
console.log("key is %s", key);
console.log("val is %s", typeof(val));
return val;
});
//key is
//key is
//val is object
//key is name
//val is string
//key is info
//val is object
//key is age
//val is number
//key is sex
//val is string
"{"name":"niuzai","info":{"age":18,"sex":"male"}}"
注意:這里一定要return一個值給下一個遍歷函數作為參數傳入,如果不return的話,后面的遍歷就沒法玩下去了。
數組
JSON.stringify(data, ["name", "info", "sex"]);
//age由於不在列表里,所以沒被序列化
//"{"name":"niuzai","info":{"sex":"male"}}"
三個參數
第三參數space
用來控制結果字符串里面的間距。如果是一個數字, 則在字符串化時每一級別會比上一級別縮進多這個數字值的空格(最多10個空格);如果是一個字符串,則每一級別會比上一級別多縮進用該字符串(或該字符串的前十個字符)。
JSON.stringify(data,null,10);
//每一個層級比上一個多10個空格
"{
"name": "niuzai",
"info": {
"age": 18,
"sex": "male"
}
}"
JSON.stringify(data,null,'\t');
//每一個層級比上一個多一個制表符
"{
"name": "niuzai",
"info": {
"age": 18,
"sex": "male"
}
}"
toJSON 方法
如果一個被序列化的對象擁有 toJSON
方法,那么該 toJSON
方法就會覆蓋該對象默認的序列化行為
var data = {
name:"niuzai",
info:{
age:18,
sex:"male"
},
toJSON:function(){
return "by toJSON";
}
};
JSON.stringify(data);
//""by toJSON"";
注意:這里的toJSON必須是一個function,如果是別的類型就不行了,比如之前提到的數組。