当我创建一个新的 Error 对象时,我可以看到它的消息或名称,但我无法通过使用标准方式看到它的键列表,这让我感到很困惑。这是为什么?
> err = new Error("an error")
[Error: an error]
> err.message
'an error'
> err.name
'Error'
> Object.keys(err)
[]
> JSON.stringify(err)
'{}'
当我创建一个新的 Error 对象时,我可以看到它的消息或名称,但我无法通过使用标准方式看到它的键列表,这让我感到很困惑。这是为什么?
> err = new Error("an error")
[Error: an error]
> err.message
'an error'
> err.name
'Error'
> Object.keys(err)
[]
> JSON.stringify(err)
'{}'
JavaScript 属性可能是不可枚举的,这意味着它们不会出现在for..in
循环或Object.keys
结果中。
您可以使用Object.getOwnPropertyNames
直接在对象上获取所有属性(可枚举或不可枚举)。我说“直接”是因为普通枚举查找对象的原型链以获取父原型上的可枚举属性,而getOwnPropertyNames
没有。
因此,Object.getOwnPropertyNames(err)
只显示
['stack',
'arguments',
'type',
'message']
该name
属性是一个不可枚举的属性,Error.prototype
并且永远不会直接在Error
实例上设置。(原型回顾:当你尝试访问err.name
时,查找err
结果什么也没有,所以解释器会查看Error.prototype
,它确实有一个name
属性。)
这是我用来通过 http 请求发送整个错误对象的方法:
// Creating a custom error
const newError = new Error('This is a new error!');
newError.name = 'Error Name';
// Function that re-create error as a regular JS Object
const getErrorObject = (error) =>
Object.getOwnPropertyNames(error).reduce((acc, curr) => {
acc[curr] = error[curr];
return acc;
}, {});
getErrorObject(newError);
/** Output:
{
message: 'This is a new error!',
name: 'Error Name',
stack: 'Error Name: This is a new error!\n at <anonymous>:1:20',
};
*/
这会捕获所有错误对象值,即使在接收自定义错误对象时也是如此。