-
객체 - 참조에 의한 객체 복사Javascript 2021. 7. 3. 15:09
객체와 원시 타입의 근본적인 차이
객체를 변수에 저장하면
1. 객체는 메모리 내 어딘가에 저장되고
2. 변수에는 객체가 메모리 내 어디에 위치하는지 알려주는 참조값이 저장된다.
따라서 객체가 할당된 변수를 복사할 때는 객체의 참조값이 복사되고 객체는 복사되지 않는다.
따라서 하나의 객체에 접근하거나 조작할 땐 여러 변수를 사용할 수 있다.
let user = { name: 'John'}; let admin = user; // 변수 admin에 user에 저장된 객체의 참조 값을 복사함 admin.age: 30; // 'admin' 참조 값에 의해 변경됨 alert(user.age); // 30이 출력됨, 'user' 참조 값을 이용해 변경사항을 확인함
참조에 의한 비교
두 변수가 같은 객체를 참조하는 경우 ==,=== 둘 다 true 반환
let a = {}; let b = a; // 참조에 의한 복사 alert( a == b ); // true, 두 변수는 같은 객체를 참조합니다. alert( a === b ); // true
이번에는 두 객체가 둘 다 비어있는 객체지만, 두 객체는 서로 다른 참조값을 가지기 때문에 동등(==),일치(===)하지 않다.
let a = {}; let b = {}; alert( a == b ); // false alert( a === b ); // false
객체 복사
Object.assign 사용
Object.assign(객체1,객체2,객체3, ... )
객체1 - 목표로 하는 객체
객체2, 객체3 - 복사하고자 하는 객체
사용 예시
let user = { name: "John" }; let permissions1 = { canView: true }; let permissions2 = { canEdit: true }; let permissions3 = { name: "Janna" }; // permissions1과 permissions2의 프로퍼티를 user로 복사합니다. Object.assign(user, permissions1, permissions2, permission3); // now user = { name: "Janna", canView: true, canEdit: true }
여기서 name같이 복사할 객체에 동일한 이름을 가진 프로퍼티가 있는 경우에는 기존 값이 덮어씌워 진다.
중첩 객체 복사
프로퍼티가 다른 객체에 대한 참조 값인 경우
Object.assign : 얕은 복사
let user = { name: "John", sizes: { height: 182, width: 50 } }; let clone = Object.assign({}, user); alert( user.sizes === clone.sizes ); // true, 같은 객체입니다. // user와 clone는 sizes를 공유합니다. user.sizes.width++; // 한 객체에서 프로퍼티를 변경합니다. alert(clone.sizes.width); // 51, 다른 객체에서 변경 사항을 확인할 수 있습니다.
user객체의 sizes는 객체의 참조값이다.
따라서 프로퍼티를 복사하는 것 만으로는 객체를 복사할 수 없다. Ojbect.assign으로 복사해도 참조값이 복사돼서 같은 sizes를 공유하게 된다.
이 문제를 해결하려면 user[key]의 각 값을 검사하면서, 그 값이 객체인 경우 객체의 구조도 복사해주는 반복문을 사용해야 한다.
이런 방식을 '깊은 복사(deep cloning)'라고 한다.
자바스크립트 라이브러리 lodash의 메서드 _.cloneDeep(obj)를 사용해서 깊은 복사를 처리할 수 있다.
'Javascript' 카테고리의 다른 글
객체 - new 연산자와 생성자 함수 (0) 2021.07.03 객체 - 메서드와 this (0) 2021.07.03 객체 - 객체 (0) 2021.07.03 코드 품질 - 테스트 자동화와 Mocha (0) 2021.07.02 코드 품질 - 주석 작성법 (0) 2021.07.02