6

我正在尝试传播错误,以便我可以在不影响原始错误的情况下更改错误。

const error = new Error('Error test');

const freeError = {...error};
console.log(error, freeError);

但输出是一个空对象{}。我期望freeError至少有一个 message 属性,但没有

这是 JavaScript 功能的一部分,还是我的代码或引擎有问题?

我知道解决这个问题的方法,但它需要额外的工作{...error, message: error.message}。所以,是的,我需要的只是澄清一下,这样我就可以确定我没有遗漏任何东西。谢谢你。

4

3 回答 3

12

对象传播只复制可枚举自己的属性,至少在某些环境中,message它不是可枚举的自己的属性。

在 Chrome 中,它是不可枚举的自己的属性,而在 Firefox 中,它是以下属性Error.prototype

const error = new Error('Error test');

// Chrome logs an object (including "enumerable": false,)
console.log(Object.getOwnPropertyDescriptor(error, 'message'));

// Firefox logs an object (including "enumerable": false,)
console.log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(error), 'message'));

它依赖于实现。我会手动提取您需要的所有属性:

const error = new Error('Error test');
const { message, stack } = error;
const freeError = { message, stack };
console.log(freeError);

于 2020-01-23T08:29:58.613 回答
3

首先,请注意你所做的不是解构——它被称为对象传播

传播对象只考虑ownPropertys。Error实例没有任何非继承属性。这就是为什么console.log(error)还输出{}

const error = new Error('Error test');

const freeError = {...error};
console.log(error, freeError);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Properties

因为继承的属性不是传播结果对象的一部分,所以error确实有一个消息属性(从它的原型继承),而freeError没有它。

检查这个例子:

const str = new String('Hello world');

const freeStr = { ...str };

console.log(str.length); // 11
console.log(freeStr.length); // undefined

如您所见str ,确实有一个length属性(从 继承String prototype),而freeStr 没有它(与您的示例中的原因相同)。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_instances

同样,请参阅此处的 MDN:https ://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_instances

于 2020-01-23T08:30:01.310 回答
1
const freeError = {...error};   

类似于

const freeError = Object.assign({}, error);

如果你想获得属性,

const freeError = Object.assign({message: error.message}, error);
于 2020-01-23T08:32:18.847 回答