在JavaScript中,JSON.stringify()方法用于將 JavaScript 對象或值轉換為 JSON 字符串。如果對象有toJSON方法,JSON.stringify 就會調用對象的toJSON方法,以toJSON方法返回的值為序列化值 。
舉個例子,以下腳本等效于 JSON.stringify({ answer: 42 }).
const json = JSON.stringify({
answer: { toJSON: () => 42 }
});
console.log(json); // {"answer":42}
與 ES6 類結合
toJSON非常有利于ES6類對象正常序列化。舉個例子,你通過Error類型擴展一個HTTPError類。
class HTTPError extends Error {
constructor(message, status) {
super(message);
this.status = status;
}
}
JavaScript不會很好的序列化錯誤信息。默認情況下,以下腳本只會輸出:{“status”:404},沒有錯誤信息及錯誤堆棧跟蹤。
class HTTPError extends Error {
constructor(message, status) {
super(message);
this.status = status;
}
}
const e = new HTTPError('Fail', 404);
console.log(JSON.stringify(e)); // {"status":404}
但如果在HTTPError類型中添加toJSON方法,效果會好很多。
class HTTPError extends Error {
constructor(message, status) {
super(message);
this.status = status;
}
toJSON() {
return { message: this.message, status: this.status };
}
}
const e = new HTTPError('Fail', 404);
console.log(JSON.stringify(e)); // {"message":"Fail","status":404}
你還可以通過toJSON方法添加更多調試信息,假如你的NODE_ENV處于開發環境,你可以為錯誤添加堆棧信息,方便調試。
class HTTPError extends Error {
constructor(message, status) {
super(message);
this.status = status;
}
toJSON() {
const ret = { message: this.message, status: this.status };
if (process.env.NODE_ENV === 'development') {
ret.stack = this.stack;
}
return ret;
}
}
const e = new HTTPError('Fail', 404);
// {"message":"Fail","status":404,"stack":"Error: Fail\n at ...
console.log(JSON.stringify(e));
toJSON最好的地方是可以幫你處理嵌套信息。通過toJSON你仍然可以正確地序列化數組中深層嵌套的HTTPError實例和HTTPError實例。
class HTTPError extends Error {
constructor(message, status) {
super(message);
this.status = status;
}
toJSON() {
return { message: this.message, status: this.status };
}
}
const e = new HTTPError('Fail', 404);
// {"nested":{"message":"Fail","status":404},"arr":[{"message":"Fail","status":404}]}
console.log(JSON.stringify({
nested: e,
arr: [e]
}));
很多類庫都是通過toJSON來JSON.stringify自定義化。如 Express 的res.json()方法、Axios POST requests序列化對象等。
toJSON() 實際應用
Moment.js類庫為對象自定義了toJSON方法:
function toJSON () {
// JSON.stringify(new Date(NaN)) === 'null'
return this.isValid() ? this.toISOString() : 'null';
}
你可以直接調用toJSON序列化日期對象:
const moment = require('moment');
console.log(moment('2019-06-01').toJSON.toString());
Node.js buffers 對象也自定toJSON方法:
const buf = Buffer.from('abc');
console.log(buf.toJSON.toString());
// Prints:
function toJSON() {
if (this.length > 0) {
const data = new Array(this.length);
for (var i = 0; i < this.length; ++i)
data[i] = this[i];
return { type: 'Buffer', data };
} else {
return { type: 'Buffer', data: [] };
}
}
Mongoose文檔對象也具有toJSON()函數,以確保Mongoose文檔對象的內部狀態不會出現在JSON.stringify()輸出中。
小結
toJSON()函數是JavaScript構建類時重要的工具。通過這種方式,您可以控制JavaScript如何將你的類實例序列化為json字符串。 toJSON()函數可以幫助您解決許多問題,例如確保日期對象得到正確的格式或Node.js緩沖對象正常序列化。下次構造ES6類型時,一定要記得嘗試哦。
版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。