Everybody only say "avoid using", "it can lead to confusion", "typeof x behaves weird", and for the most part they are right.
But nobody is able to give you one single reason as to why you would want to use the constructor instead.
When you have many variables that has the same value, then you will allocate much more memory, if you instead construct a new class instances and use that one instead, then you would only allocate 1 single item. and the rest of your variables would just be pointers to the same object.
This could technically increase speed when you use structuredClone (but i don't know, haven't bench tested it)
Something that i have tested out at least is to see how much disc space you allocate when using IndexedDB.
// small simple kv indexeddb storage
let p,query=(e,...r)=>(p??=new Promise((e=>{const r=indexedDB.open("kv");r.onupgradeneeded=()=>r.result.createObjectStore("kv"),r.onsuccess=()=>{const t=r.result;query=(e,...r)=>{const n=t.transaction("kv","readwrite").objectStore("kv")[e](...r);return new Promise(((e,r)=>{n.onsuccess=()=>e(n.result),n.onerror=()=>r(n.error)}))},e()}}))).then((()=>query(e,...r)));
var kv=(...e)=>query(...e);
var arr = Array(1024).fill('a'.repeat(1024))
await kv('put', arr, 'stuff')
await kv('get', 'stuff')
var est = await navigator.storage.estimate()
est.usageDetails.indexedDB // chrome 105 allocated 1055761 bytes
now if we do the same thing but using slightly different thing by using string constructor instead:
// Now you are using the same instance instead.
var arr = Array(1024).fill(new String('a'.repeat(1024)))
await kv('put', arr, 'stuff')
await kv('get', 'stuff')
var est = await navigator.storage.estimate()
est.usageDetails.indexedDB // chrome 105 allocated 7353 bytes
now you saved about 1055761-7353 = 1048408 bytes...
If you want to test this out for yourself, always open up a new inkognito window and await
both put/get operators, estimate can maybe give wrong value otherwise. and deleting it may not always clean up properly, that's why you should create a new inkognito window every time you want to compare stuff.
But in the end: yeaa... maybe don't use the constructor after all. it's almost never a good thing.
Just wanted you to know what the "real" differences is by using objects instead
...also if you use NodeJS v8.serialize(value)
then the same example will yield a smaller Buffer when you use the same object instances (as the rest will just be pointers)
another reason for using objects instead could be if you wanted to do something with WeakRef, WeakMap where simple literals isn't acceptable.