將一個 JavaScript 對象或值轉(zhuǎn)換為 JSON 字符串。如果指定了一個 replacer 函數(shù),則可以選擇性地替換值,或者指定的 replacer 是數(shù)組,則可選擇性地僅包含數(shù)組指定的屬性。
參數(shù)一:JSON 值
將要序列化成 一個 JSON 字符串的值,在轉(zhuǎn)換時需要注意如下事項:
1.轉(zhuǎn)換值包含 toJSON 方法
如果一個被序列化的對象擁有 toJSON 方法,那么該 toJSON 方法就會覆蓋該對象默認(rèn)的序列化行為:不是該對象被序列化,而是調(diào)用 toJSON 方法后的返回值會被序列化,例如:
var obj = {
foo: "foo",
toJSON: function () {
return "bar";
},
};
JSON.stringify(obj); // '"bar"'
JSON.stringify({ x: obj }); // '{"x":"bar"}'
toJSON 的正確用法應(yīng)該是,返回一個能夠被字符串化的安全的 JSON 值。
2.布爾值、數(shù)字、字符串的包裝對象在序列化過程中會自動轉(zhuǎn)換成對應(yīng)的原始值
// "[3,\"false\",false]"
JSON.stringify([new Number(3), new String("false"), new Boolean(false)]);
3.undefined、任意的函數(shù)以及 symbol 值,在序列化過程中會被忽略或者被轉(zhuǎn)換成 null
出現(xiàn)在非數(shù)組對象的屬性值中,就會被忽略,其中 Symbol 無論出現(xiàn)在鍵或值都會被忽略:
const object = {
[Symbol("foo")]: "foo",
foo: Symbol(100),
boo: function () {},
bof: undefined,
};
JSON.stringify(object); // "{}"
出現(xiàn)在數(shù)組中,會被轉(zhuǎn)換為 null,另外 NaN, Infinity 等數(shù)值也會被轉(zhuǎn)為 null
const array1 = [Symbol("foo"), function () {}, undefined, NaN, Infinity];
JSON.stringify(array); // "[null,null,null,null,null]"
4.對包含循環(huán)引用的對象(對象之間相互引用,形成無限循環(huán))執(zhí)行此方法,會拋出錯誤。
5.非數(shù)組對象的屬性不能保證以特定的順序出現(xiàn)在序列化后的字符串中。
6.其他類型的對象,包括 Map/Set/WeakMap/WeakSet,僅會序列化可枚舉的屬性,不可枚舉的屬性默認(rèn)會被忽略:
JSON.stringify(
Object.create(null, {
x: { value: "x", enumerable: false },
y: { value: "y", enumerable: true },
})
);
// "{\"y\":\"y\"}"
7.Date 日期調(diào)用了 toJSON() 將其轉(zhuǎn)換為了 string 字符串(同 Date.toISOString()),因此會被當(dāng)做字符串處理。
// "\"2006-01-02T15:04:05.000Z\""
console.log(JSON.stringify(new Date(2006, 0, 2, 15, 4, 5)));
參數(shù)二:replacer(可選)
1.replacer 作為函數(shù)
replacer 作為函數(shù),在序列化過程中,被序列化的值的每個屬性都會經(jīng)過該函數(shù)的轉(zhuǎn)換和處理。它有兩個參數(shù),鍵(key)和值(value),它們都會被序列化。
在開始時, replacer 函數(shù)會被傳入一個空字符串作為 key 值,代表著要被 stringify 的這個對象。隨后每個對象或數(shù)組上的屬性會被依次傳入。
function replacer(key, value) {
if (typeof value === "string") {
return undefined;
}
return value;
}
var foo = {
foundation: "Mozilla",
model: "box",
week: 45,
transport: "car",
month: 7,
};
var jsonString = JSON.stringify(foo, replacer); // {"week":45,"month":7}
2.replacer 作為數(shù)組
replacer 作為數(shù)組,則只有包含在這個數(shù)組中的屬性名才會被序列化到最終的 JSON 字符串中;
var foo = {
foundation: "Mozilla",
model: "box",
week: 45,
transport: "car",
month: 7,
};
JSON.stringify(foo, ["week", "month"]);
// '{"week":45,"month":7}', 只保留 “week” 和 “month” 屬性值。
3.replacer 未提供或為 null
如果該參數(shù)為 null 或者未提供,則對象所有的屬性都會被序列化。
參數(shù)三:space(可選)
指定縮進用的空白字符串,用于美化輸出(pretty-print);
JSON.stringify({ uno: 1, dos: 2 }, null, "\t");
// '{ \
// "uno": 1, \
// "dos": 2 \
// }'
1.space 值是數(shù)字
如果參數(shù)是個數(shù)字,它代表有多少的空格;上限為 10。該值若小于 1,則意味著沒有空格;在字符串化時每一級別會比上一級別縮進多這個數(shù)字值的空格。
2.space 值是字符串
如果該參數(shù)為字符串(當(dāng)字符串長度超過 10 個字母,取其前 10 個字母),該字符串將被作為空格;每一級別會比上一級別多縮進該字符串。
3.space 未提供或為 null
如果該參數(shù)沒有提供(或者為 null),將沒有空格。