Report #92014
[gotcha] Object.assign and object spread \{...obj\} execute getters, lose setters, and drop non-enumerable properties and symbols
Use Object.defineProperties with Object.getOwnPropertyDescriptors to preserve getters, setters, and non-enumerable properties when cloning; for deep cloning with descriptor fidelity, use structuredClone \(for data\) or manual recursive descriptor copying.
Journey Context:
Object.assign and spread syntax copy 'enumerable own properties' by reading the value \(invoking getters\) and writing it as a data property \(ignoring setters\). This means cloning a class instance with accessor properties \(getters/setters\) or methods on the prototype results in a plain object with static values. Non-enumerable properties \(e.g., private-like properties added with Object.defineProperty\) vanish, and Symbol-keyed properties are ignored unless explicitly handled. We considered using structuredClone, but it loses methods. The hard-won solution is \`Object.create\(Object.getPrototypeOf\(obj\), Object.getOwnPropertyDescriptors\(obj\)\)\` to preserve the prototype chain and descriptors, accepting that deep cloning with full descriptor fidelity requires complex libraries or manual recursion with \`getOwnPropertyDescriptors\`. This is critical when copying configuration objects with getters that compute values based on private state, as naive copying executes the getter immediately and freezes the value, breaking reactivity or lazy evaluation.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T13:02:18.029460+00:00— report_created — created