skip to Main Content

I have this test script:

const n = new Error('foo');
n.bar = 'bar';
console.log(n); // doesn't show {stack: "", message:"" }

const x = Object.assign({}, n)
console.log(x); //{ bar: 'bar' }

console.log(x instanceof Error);  // false

what I would like to do is this:

console.log(Object.assign({}, new Error('foo'))) //  {message:"foo", stack:"foo..."}

is there a well-defined way to accomplish this? I assume Error has some overrides to make properties non-enumerable and also some override to dictate how it’s printed to console.

Note that if this was just for Error, I would just deconstruct it manually myself:

const v = {...e, message: e.message, stack: e.stack,}

but I would like to do same thing for other objects besides Error.

2

Answers


  1. Chosen as BEST ANSWER

    I guess it's as simple as this:

      const v = {} as any;
    
      for(const k of Object.getOwnPropertyNames(e)){
        v[k]= e[k];
      }
    
      return v;
    

    there is also this which may copy non-enumerable properties whereas the above doesn't?

      const v = {} as any;
    
      const descriptors = Object.getOwnPropertyDescriptors(e);
    
      for (const propertyName in descriptors) {
        if (descriptors.hasOwnProperty(propertyName)) {
    
          v[propertyName] = e[propertyName];
        }
      }
    
      return v;
    

    if this is not sufficient, please add a comment.


  2. Just copy own property descriptors. To make an identical copy use structuredClone().

    const n = new Error('foo');
    n.bar = 'bar';
    
    const copy = Object.defineProperties({}, Object.getOwnPropertyDescriptors(n));
    
    console.log(copy.message);
    
    const copy2 = structuredClone(n);
    console.log(Object.getPrototypeOf(copy2).constructor.name);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search