33

当我创建一个新的 Error 对象时,我可以看到它的消息或名称,但我无法通过使用标准方式看到它的键列表,这让我感到很困惑。这是为什么?

> err = new Error("an error")
[Error: an error]
> err.message
'an error'
> err.name
'Error'
> Object.keys(err)
[]
> JSON.stringify(err)
'{}'
4

2 回答 2

34

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属性。)

于 2013-08-16T16:34:43.453 回答
0

这是我用来通过 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',
};
*/

这会捕获所有错误对象值,即使在接收自定义错误对象时也是如此。

于 2021-12-29T23:11:15.233 回答