참조에 의한 복사, 값에 의한 복사가 무슨 뜻인지 알아보자.
헷갈렸던 개념들을 다시 정리함으로써 모호한 정의를 명확히 정의해보자.
- 객체와 원시 타입의 근본적인 차이 중 하나는 객체는 ‘참조에 의해(by reference)’ 저장되고 복사된다는 것임.
- 원시값(문자열, 숫자, 불린 값)은 ‘값 그대로’ 저장·할당되고 복사됨.
- 예시로 살펴 보자.
🔴 값에 의한 복사
- 두 개의 독립된 변수에 각각 문자열
"Hello!"
가 저장.
let message = "Hello!"; let phrase = message;


🟠 참조에 의한 객체 복사
- 객체의 동작방식은 다르다!
- 변수엔 객체가 그대로 저장되는 것이 아니라, 객체가 저장되어있는 '메모리 주소’인 객체에 대한 '참조 값’이 저장됨.
- 따라서 객체가 할당된 변수를 복사할 땐 객체의 참조 값이 복사되고 객체는 복사되지 않음.
let user = { name: "John" }; let admin = user;


비유를 하자면 원시 타입은 개별의 서랍과 열쇠를 관리하는 것이고, 객체 타입은 여러 열쇠로 하나의 서랍을 관리하는 것이라 할 수 있음.
🟡 참조에 의한 비교
- 객체 비교 시 동등 연산자
==
와 일치 연산자===
는 동일하게 동작함.
- 비교 시 피연산자인 두 객체가 동일한 객체인 경우에 참을 반환함.
let a = {}; let b = a; // 참조에 의한 복사 alert( a == b ); // true, 두 변수는 같은 객체를 참조합니다. alert( a === b ); // true
let a = {}; let b = {}; // 독립된 두 객체 alert( a == b ); // false
(코딩 실수 주의!)
obj1 > obj2
같은 대소 비교나 obj == 5
같은 원시값과의 비교에선 객체가 원시형으로 변환됨.동등함의 비교 시
==
는 강제변환을 허용하지만, ===
는 강제변환을 허용하지 않음.
간혹 '===
은 type을 비교한다'라고 답하는 경우가 있는데 중요한 것은 비교 과정에서 강제변환의 개입 여부임.🟢 객체 복사
- 객체를 복사하려면 어떻게 해야 할까?
- 자바스크립트는 객체 복제 내장 메서드를 지원하지 않기 때문에 복잡함.
- 불행 중 다행인 건 객체를 복제해야 할 일은 거의 없다는 것!
- 그래도 해본다면 다음과 같이 할 수 있음.
let user = { name: "John", age: 30 }; let clone = {}; for (let key in user) { clone[key] = user[key]; }

Object.assign
을 사용하면 반복문 없이도 간단하게 객체를 복사할 수 있음.
let user = { name: "John", age: 30 }; let clone = Object.assign({}, user);

- 객체의 모든 프로퍼티가 원시 값인 경우엔 위와 같은 방식으로 복사할 수 있음.
- 프로퍼티가 다른 객체에 대한 참조 값일 땐 어떻게 해야 할까?
let user = { name: "John", sizes: { height: 182, width: 50 } }; let clone = Object.assign({}, user);

- 이 문제를 해결하려면
user[key]
의 각 값을 검사하면서, 그 값이 객체인 경우 객체의 구조도 복사해주는 반복문을 사용해야 함.
- 이런 방식을 '깊은 복사(deep cloning)'라고 함.
- 재귀함수를 이용한 복사.
- JSON.stringify()로 객체를 json 문자열로 변환후 JSON.parse()를 이용해 다시 자바스크립트 객체로 만들어줌.
lodash
라이브러리 사용.
🟣코테 예제로 보는 심화 학습
다단계 칫솔 판매🟤 요약
- 객체는 참조에 의해 할당되고 복사됨.
- 변수엔 ‘객체’ 자체가 아닌 메모리상의 주소인 '참조’가 저장됨.
- 따라서 객체가 할당된 변수를 복사하거나 함수의 인자로 넘길 땐 객체가 아닌 객체의 참조가 복사됨.
- 객체의 '진짜 복사본’을 만들려면 '얕은 복사(shallow copy)' 또는 '깊은 복사’를 하면 됨.
- 이때 얕은 복사본은 중첩 객체를 처리하지 못함.
참고자료 :
<YOU DONT KNOW JS 타입과 문법, 스코프와 클로저> p.127