객체 복사 방법 (structuredClone)

Dansoon·2023년 3월 6일
0
post-thumbnail

객체 복사 방법

얕은 복사 (Shallow copy)

객체의 복사본을 생성하면서 객체의 속성을 참조한다.

복사된 객체와 원본 객체는 같은 속성을 가르키기 때문에 복사본에서 속성을 변경하면

원복객체도 값이 변경된다.

깊은 복사 (Deep copy)

객체의 복사본을 생성하면서 객체의 속성까지 새로운 객체로 복사한다.

복사본을 변경해도 원본값이 변경되지 않는다.

참조에 의한 객체 복사 (얕은 복사)

객체와 원시 타입의 근본적인 차이는 객체는 참조에 의해 저장되고 복사된다는 것이다.

const user = { name: 'kim' };

const manager = user // 참조값을 복사함

manager.name = 'park'

console.log(user.name) // park

변수는 두 개이지만 각 변수엔 동일 객체에 대한 참조 값이 저장된다.

복사된 객체를 변경하면 같은 속성을 공유하기 때문에 원복 객체도 값이 변경된다.

객체 복사, 병합과 Object.assign (얕은 복사)

const obj = { a: 1, b: 2 }
const newObj = { b: 4, c: 5 }

const copy = Object.assign(obj, newObj)

console.log(copy) // Object { a: 1, b: 4, c: 5 }

assign 메서드는 여러 객체를 하나로 병합하는 함수이다.
하지만 객체 복사시 값은 값을 참조하는 건 여전하다.

JavaScript spread operator (전개 구문) (얕은 복사? 깊은 복사?)

const a = [1, 2, 3, 4, 5]
const b = [...a]
b[0] = 2
console.log(a) [1,2,3,4,5]
console.log(b) [2,2,3,4,5]

const a = { name: 'kim' }
const b = { ...a }
b.name = 'park'
console.log(a) { name: 'kim' }
console.log(b) { name: 'park' }

const a = [{ name: 'kim' }]
const b = [...a]
b[0].name = 'park'
console.log(a) [{ name: 'park' }]
console.log(b) [{ name: 'park' }]

spread operator는 깊은 복사일까? 위의 예시를 보면 1depth의 값에서는 깊은 복사인 반면

depth가 늘수록 값을 공유한다. 그래서 1depth의 경우 spread oprator를 사용해 깊은 복사를 할 수 있다.

JSON.stringfy() (깊은 복사)

 const obj = { name:'kim' }
 const copyObj = JSON.parse(JSON.stringfy(obj))

 console.log(obj===copyObj) // false

객체를 문자열로 변환후 다시 객체로 변환한다.
객체에 함수나 심볼 등의 값이 포함되어 있으면 제외된다.

또한 Date 객체를 복사할 경우 문자열이 반환되기 때문에 정확한 정보를 유지하지 않을 수 있다.

structuredClone (깊은 복사)

자바스크립트에서 지원하는 깊은 복제 메서드이다.

const obj = { name:'kim' }
const copyObj = structuredClone(obj)

console.log(obj === copyObj) // false

structuredClone은 JSON.stringfy()의 많은 단점을 해결한다.
구조적 복제는 순환되는 데이터 구조를 처리할 수 있고 내장 데이터 타입을 지원할 수 있으며 일반적으로 더 빠르다.

하지만 브라우저에서만 사용가능하며 복사할 수 없는 개체(DOM 노드)와 함수, 심볼 등의 값을 복사하지 못한다.

lodash의 cloneDeep() (깊은 복사)

기존에 있던 객체와 똑같으면서 독립적인 객체를 만들고 싶다면 lodash의 메서드인 _.cloneDeep(obj)를 사용할 수 있다.

import { cloneDeep } front 'lodash' // 사용할 메서드만 호출해준다.
const obj = { name:'kim'}
const newObj = obj

console.log(obj===newObj) // false

lodash라이브러리에서 제곡하는 cloneDeep 메서드는 객체의 모든 속성을 재귀적으로 복사함으로 함수, 심동값도 복사할 수 있다.

객체값에 심볼, 함수 등이 포함되어 있는경우 lodash에서 제공하는 cloneDeep을 사용할 수 있다.

개인적으로는 lodash의 기능중 많은 기능을 사용하지 않으므로 가져올때

패키지를 가져올때 특정 기능만 가져와서 require를통해 변수로 할당해 사용한다.

하지만 그렇지 않은경우가 대부분이기 때문에 structuredClone과 같은 기능을 사용하는 경우가 더 많은것 같다.

profile
front engineer🧑🏻‍💻

0개의 댓글