-
[JavaScript] JavaScript에서의 값과 참조, 객체 복사2024년 12월 26일
- 유니얼
-
작성자
-
2024.12.26.:57
728x90JavaScript는 데이터 타입에 따라 복사와 동작 방식이 다릅니다. 원시 타입(Primitive Type)과 참조 타입(Reference Type)의 차이점, 그리고 객체 복사에서의 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)에 대해 이해하는 것은 코드 작성에 중요한 영향을 미칩니다. 이 글에서는 JavaScript에서의 값과 참조, 객체 복사에 대해 자세히 알아보겠습니다.
1. 원시 타입과 참조 타입의 차이
JavaScript의 데이터 타입은 크게 원시 타입과 참조 타입으로 나뉩니다.
1-1. 원시 타입
- JavaScript에서 원시 타입에는 string, number, boolean, null, undefined, symbol, bigint가 포함됩니다.
- 값 자체가 저장되고, 복사하면 독립적인 값이 생성됩니다.
예제
let myAddress = 'Seoul'; let oldAddress = myAddress; // 값 복사 myAddress = 'Busan'; console.log(myAddress); // Busan console.log(oldAddress); // Seoul
myAddress를 변경해도 oldAddress는 영향을 받지 않습니다. 두 변수는 각각 독립적인 값을 가집니다.
1-2. 참조 타입
- 객체, 배열, 함수는 **참조 타입(Reference Type)**입니다.
- 복사 시 값이 아닌 **참조(Reference)**를 복사합니다.
- 여러 변수가 동일한 메모리 주소를 참조하므로, 하나를 변경하면 다른 변수에도 영향을 미칩니다.
예제
const profile = { address: 'Seoul' }; const copiedProfile = profile; // 참조 복사 copiedProfile.address = 'Busan'; console.log(profile.address); // Busan console.log(copiedProfile.address); // Busan
copiedProfile의 address를 변경하면 profile도 영향을 받습니다. 두 변수가 동일한 객체를 참조하고 있기 때문입니다.
2. 객체 복사: 얕은 복사와 깊은 복사
2-1. 얕은 복사(Shallow Copy)
- 얕은 복사는 객체의 1단계 속성만 복사하며, 중첩된 객체나 배열은 참조만 복사합니다.
- Object.assign()이나 스프레드 연산자(...)를 사용합니다.
예제: Object.assign
const profile = { address: 'Seoul', family: ['Tony', 'Chris'] }; const shallowCopy = Object.assign({}, profile); shallowCopy.address = 'Daegu'; shallowCopy.family.push('Levin'); console.log(profile); // { address: 'Seoul', family: [ 'Tony', 'Chris', 'Levin' ] } console.log(shallowCopy); // { address: 'Daegu', family: [ 'Tony', 'Chris', 'Levin' ] }
address는 독립적으로 복사되었지만, family는 참조가 복사되어 원본 객체도 변경되었습니다.
2-2. 깊은 복사(Deep Copy)
- 깊은 복사는 객체의 모든 중첩 구조를 새로운 메모리 공간에 복사합니다.
- JSON 방법(JSON.parse(JSON.stringify()))이나 외부 라이브러리(lodash)를 사용할 수 있습니다.
예제: JSON 방식
const profile = { address: 'Seoul', family: ['Tony', 'Chris'] }; const deepCopy = JSON.parse(JSON.stringify(profile)); deepCopy.address = 'Busan'; deepCopy.family.push('Levin'); console.log(profile); // { address: 'Seoul', family: [ 'Tony', 'Chris' ] } console.log(deepCopy); // { address: 'Busan', family: [ 'Tony', 'Chris', 'Levin' ] }
깊은 복사를 사용하면 원본 객체와 복사본이 완전히 독립적입니다.
단점: JSON 방식은 **함수, undefined, symbol**과 같은 데이터는 복사되지 않습니다.
3. 얕은 복사와 깊은 복사의 차이
복사 유형 설명 결과 얕은 복사 객체의 1단계 속성만 복사하며, 중첩된 객체나 배열은 참조만 복사 중첩된 구조는 여전히 참조를 공유 깊은 복사 객체의 모든 중첩 구조를 새로운 메모리 공간에 복사 원본과 복사본이 완전히 독립적 비교 예제
// 얕은 복사 const shallowCopy = Object.assign({}, profile); shallowCopy.family.push('Levin'); // 원본 객체에도 영향을 줌 // 깊은 복사 const deepCopy = JSON.parse(JSON.stringify(profile)); deepCopy.family.push('Levin'); // 원본 객체는 영향을 받지 않음
4. 객체 복사를 위한 팁
1, 얕은 복사는 Object.assign 또는 스프레드 연산자(...)를 사용하세요.
const shallowCopy = { ...profile };
2, 깊은 복사가 필요할 경우:
- 간단한 객체: JSON.parse(JSON.stringify())
- 복잡한 객체: 외부 라이브러리(lodash)를 사용
const deepCopy = _.cloneDeep(profile);
3, 중첩 구조가 없는 단순 객체라면 얕은 복사로 충분합니다.
5. 결론
JavaScript에서 데이터 복사 방식을 이해하는 것은 코드의 동작을 예측하고, 의도하지 않은 부작용을 방지하는 데 매우 중요합니다.
- 원시 타입: 값 자체를 복사하며 독립적으로 동작합니다.
- 참조 타입: 객체의 참조를 복사하며, 하나의 변수를 변경하면 다른 변수도 영향을 받습니다.
- 얕은 복사: 1단계 속성만 복사하며, 중첩된 객체는 참조를 공유합니다.
- 깊은 복사: 객체의 모든 중첩 구조를 복사하며, 원본과 복사본이 완전히 독립적입니다.
상황에 따라 얕은 복사와 깊은 복사를 적절히 활용하여 안정적이고 유지보수하기 쉬운 코드를 작성하세요!
반응형다음글이전글이전 글이 없습니다.댓글