Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object spread an Error results in no message property [duplicate]

I'm trying to spread an Error so that I can alter the error without affecting the original error.

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

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

But the output is an empty object {}. I'm expecting the freeError have at least a message property, but there is none.

Is this a part of JavaScript feature or is there something wrong with my code or engine?

I know a way to fix this, but it requires an extra work {...error, message: error.message}. So, yeah, all I need is a clarification so that I can be sure that I am not missing something. Thank you.

like image 451
SnekNOTSnake Avatar asked Jan 23 '20 08:01

SnekNOTSnake


People also ask

Does object spread create new object?

The fundamental idea of the object spread operator is to create a new plain object using the own properties of an existing object.

Can Spread operator be used on object?

Spread syntax can be used when all elements from an object or array need to be included in a new array or object, or should be applied one-by-one in a function call's arguments list. There are three distinct places that accept the spread syntax: Function arguments list ( myFunction(a, ...

Does spread operator overwrite property?

The spread operator lets us expand elements such as objects and arrays. Lets see how it works. This way of using the spread operator is also handy for overwriting properties in existing objects.

Is object assign same as spread?

The difference is that Object. assign changes the object in-place, while the spread operator ( ... ) creates a brand new object, and this will break object reference equality.

What is the difference between missingobject and object spread?

Object spread extracts no properties from nothing, missingObject and two. Of course, there is no reason to use object spread on primitive values. 3. Object rest properties After extracting properties of an object to variables using a destructuring assignment, the remaining properties can be collected into a rest object.

What happens when you use object spread on primitive values?

That's easy: When spreading properties an of undefined, null or a primitive value no properties are extracted, and no error is thrown. The result is a plain empty object: Object spread extracts no properties from nothing, missingObject and two. Of course, there is no reason to use object spread on primitive values. 3. Object rest properties

What is object spread syntax?

Luckily object spread syntax (an ECMAScript proposal at stage 3) is a step forward how to manipulate objects, providing a short and easy to follow syntax. In the example above, ...cat copies the properties of cat into a new object dog. .sound property receives the final value 'woof'. This article guides through object spread and rest syntax.

Can I define a new property using the spread operator?

However, the spread operator ( ...) can define a new property. Suppose you have an object called blueSquare whose the color property is readonly: The following uses the spread operator ( ...) to merge the style and blueSquare objects:


2 Answers

Object spread only copies enumerable own properties, and at least in some environments, the message is not an enumerable own property.

In Chrome, it's a non-enumerable own property, and in Firefox, it's a property of 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'));

It's implementation-dependent. I'd manually extract all properties you need:

const error = new Error('Error test');
const { message, stack } = error;
const freeError = { message, stack };
console.log(freeError);
like image 124
CertainPerformance Avatar answered Oct 26 '22 23:10

CertainPerformance


First off, please note that what you are doing is not destructuring - it is called object spread.

Spreading objects only takes ownPropertys into account. Error instances don't have any non-inherited properties. That is why console.log(error) also outputs {}:

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

Because inherited properties are not part of the spread result object, error does have a message property (inherited from its prototype), whereas freeError does not have it.

Check this example:

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

const freeStr = { ...str };

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

As you can see str does have a length property (inherited from the String prototype), whereas freeStr does not have it (for the same reason as in your example).

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

Again, see MDN here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_instances

like image 37
connexo Avatar answered Oct 26 '22 23:10

connexo