728x90
스프레드 연산자는 얕은 복사를 수행한다.
- 하지만, 모든 값이 복사되는 방식이 다름!
- Primitive 타입(원시값) → 새로운 값이 복사됨
- Object 타입 (참조값) → 기존 객체의 참조(reference) 가 복사됨
코드 실행 결과
const test = {
name: "bob",
profile: {
email: "test@",
},
};
// 얕은 복사 (Shallow Copy)
const test2 = { ...test };
test2.name = "w"; // (1) 새로운 값으로 변경
test2.profile.email = "changed@"; // (2) 중첩 객체 내부 값 변경
console.log(test); // 원본 객체
console.log(test2); // 복사된 객체
출력 결과
// 원본 객체 (test)
{
"name": "bob",
"profile": {
"email": "changed@"
}
}
// 복사된 객체 (test2)
{
"name": "w",
"profile": {
"email": "changed@"
}
}
왜 name은 따로 변경되고, email은 함께 변경될까?
(1) name = "bob" → Primitive 값 (원시 타입)
- name은 문자열(Primitive Type) 이므로 새로운 값이 복사됨
- 즉, test2.name을 변경해도 test.name에는 영향 없음
(2) profile = { email: "test@" } → Object (참조 타입)
- profile은 객체(Object, Reference Type) 이므로,
- ...test 사용 시, profile의 참조(reference) 가 복사됨
- 즉, test.profile과 test2.profile은 같은 객체를 가리킴
- 따라서 test2.profile.email을 변경하면 test.profile.email도 변경됨
728x90
해결 방법: 깊은 복사 (Deep Copy)
중첩 객체까지 복사하려면 structuredClone() 또는 JSON.parse(JSON.stringify()) 같은 깊은 복사 방법을 사용해야 한다.
(1) structuredClone() (최신 브라우저, Node.js 17+)
const test = {
name: "bob",
profile: {
email: "test@",
},
};
const test2 = structuredClone(test);
test2.profile.email = "changed@";
console.log(test); // 원본 유지됨
console.log(test2); // 변경됨
(2) JSON.parse(JSON.stringify()) (중첩 객체 복사)
const test = {
name: "bob",
profile: {
email: "test@",
},
};
const test2 = JSON.parse(JSON.stringify(test));
test2.profile.email = "changed@";
console.log(test); // 원본 유지됨
console.log(test2); // 변경됨
👉 결론:
✔ Primitive 값은 새로운 값으로 복사되지만, Object는 참조만 복사되므로 같은 객체를 가리킴
728x90
'Category > JavaScript' 카테고리의 다른 글
원시값(Primitive)과 객체의 차이 (0) | 2025.03.20 |
---|---|
JavaScript에서 export와 import의 개념과 사용법 (0) | 2025.03.15 |
Axios: HTTP 요청을 쉽게 만드는 JavaScript 라이브러리 (3) | 2024.11.11 |
[JavaScript] 브라우저의 기본 동작 막기 event.preventDefault() (1) | 2024.11.07 |
자바스크립트 reduce() (1) | 2024.10.29 |