在我們的應用程序的NodeJS,我們通過默認的Error對象擴展定義自定義錯誤類:Object.defineProperty覆蓋只讀屬性
"use strict";
const util = require("util");
function CustomError(message) {
Error.call(this);
Error.captureStackTrace(this, CustomError);
this.message = message;
}
util.inherits(CustomError, Error);
這使我們與堆棧跟蹤throw CustomError("Something");
顯示正確了, instanceof Error
和instanceof CustomError
都正常工作。
然而,對於我們的API在返回錯誤(通過HTTP),我們希望將錯誤轉換成JSON。調用JSON.stringify()
上的錯誤導致"{}"
,這顯然不是真正的消費者描述。
爲了解決這個問題,我想重寫CustomError.prototype.toJSON()
,返回一個對象常量錯誤的姓名和消息。然後JSON.stringify()
只想字符串化該對象和所有將工作偉大:
// after util.inherits call
CustomError.prototype.toJSON =() => ({
name : "CustomError",
message : this.message
});
不過,我很快發現,這將引發TypeError: Cannot assign to read only property 'toJSON' of Error
。當我試圖寫入原型時,這可能是有意義的。所以我改變了構造來代替:
function CustomError(message) {
Error.call(this);
Error.captureStackTrace(this, CustomError);
this.message = message;
this.toJSON =() => ({
name : "CustomError",
message : this.message
});
}
這樣(我的預期),則CustomError.toJSON功能將被使用,並且CustomError.prototype.toJSON(從錯誤)將被忽略。
不幸的是,這只是拋出在對象的構造錯誤:Cannot assign to read only property 'toJSON' of CustomError
。
下一個我試圖從文件,其中排序在正在拋出了沒有錯誤的問題解決了去除"use strict";
,雖然toJSON()
功能不使用JSON.stringify()
可言。
在這一點上,我只是絕望,只是嘗試隨機的東西。最後,我結束了使用Object.defineProperty()
,而不是直接分配給this.toJSON
:
function CustomError(message) {
Error.call(this);
Error.captureStackTrace(this, CustomError);
this.message = message;
Object.defineProperty(this, "toJSON", {
value:() => ({
name : "CustomError",
message : this.message
})
});
這完美的作品。在嚴格模式下,沒有錯誤被調用,JSON.stringify()
返回{"name:" CustomError", "message": "Something"}
就像我想要的那樣。
所以,雖然它的工作原理,因爲我希望它到現在爲止,我還是想知道:
- 爲什麼這項工作到底是什麼?我期望它是相當於
this.toJSON = ...
,但顯然它不是。 - 它應該這樣工作嗎?即依靠這種行爲是否安全?
- 如果不是,我應該如何正確覆蓋toJSON方法? (如果可能的話)
看看[我的答案在這裏](http://stackoverflow.com/questions/22960493/i-dont-understand-writable-and-configurable-property-attributes-of-objects/22960738#22960738)和看看這是你問的問題。謝謝! –
@ Qantas94Heavy這的確很奇怪,但至少可以解釋爲什麼我無法正常分配給屬性。我仍然沒有從你的評論中的[鏈接文章](https://esdiscuss.org/topic/set-and-inherited-readonly-data-properties)中獲得:Object.defineProperty是否工作(即覆蓋無論如何,只讀原型屬性)通過設計還是我不應該依賴的這種意外行爲? – Lapixx