# | Column 1 | shallow copy | deep copy | inner objects | methods | built-in types | circular references |
---|---|---|---|---|---|---|---|
1 | for (const key in obj) | + | - | - | - | - | - |
2 | Object.assign({}, obj) | + | - | - | - | - | - |
3 | Spread operator {…obj} | + | - | - | - | - | - |
4 | JSON.parse(JSON.stringify(obj)) | - | + | + | - | - | - |
5 | Recursion | - | + | + | + | - | - |
6 | structuredClone() | - | + | + | - | + | + |
For…in
cycle with conditionals if we know levels:- shallow copy ⇒ If our object contains objects, they will remain shared references
Object.assign({}, obj)
:- shallow copy ⇒ If our object contains objects, they will remain shared references
- turns getters into simple properties
- summons all object’s getters
Spread
operator:- shallow copy ⇒ If our object contains objects, they will remain shared references
JSON.parse(JSON.stringify(obj))
:- a temporary, potentially big string just to pipe it back into a parser
- things like Maps, Sets, RegExps, Dates, ArrayBuffers and other built-in types just get lost at serialization
Recursion
if we don’t know levelsStructured cloning
- structuredClone(user)
- new MessageChannel()
- history.replaceState(obj, document.title)
- new Notification('', {data: obj, silent: true}).data