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.
The fundamental idea of the object spread operator is to create a new plain object using the own properties of an existing 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, ...
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.
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.
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.
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
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.
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:
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);
First off, please note that what you are doing is not destructuring - it is called object spread.
Spreading objects only takes ownProperty
s 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).
Again, see MDN here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_instances
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With