-
[JAVASCRIPT-모던자바스크립트] 참조에 의한 객체 복사Javascript& React study 2021. 10. 10. 05:00728x90반응형SMALL
객체와 원시 타입의 근본적인 차이 중 하나는 객체는 '참조에 의해(by reference)'저장되고 복사된다는 것이다.
원시값(문자열 숫자,불린값)은 값 그대로 저장 할당되고 복사는 아래와 같이 된다.
let message = "Hello"; let phraaw = message;
예시를 실행하면 두 개의 독립된 변수에 각각 문자열 "Hello!"가 저장됩니다.
하지만 객체의 동작방식은 이와 다르다고 할 수 있다. 변수엔 객체가 그대로 저장되는 것이 아니라 객체가 저장되어있는 '메모리 주소'인 객체에 대한 '참조 값'이 저장된다.
그림을 통해 변수 user에 객체를 할당할 떄 무슨 일이 일어나는지 알아보자
let user = { name : "John" }
객체는 메모리 내 어딘가에 저장되며 변수 user에는 객체를 '참조'할 수 있는 값이 저장된다. 따라서 객체가 할당된 변수를 복사할 땐 객체의 참조 값이 복사되고 객체는 복사되지 않는다.
let user = { name : "John" }; let admin = user; // 참조값을 복사함
변수는 두 개이지만 각 변수엔 동일 객체에 대한 참조 값이 저장된다. 그렇기 때문에 객체에 접근하거나 객체를 조작할 때에는 여러 변수를 사용할 수 있다.
let user = { name : 'John' }; let admin = user; admin.name = 'Pete'; // 'admin' 참조 값에 의해 변경됨 alert (user.name); // 'Pete'가 출력됨 '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같은 원시값과의 비교에선 객체가 원시형으로 변환된다.
객체 복사, 병합과 Object.assign
객체가 할당된 변수를 복사하면 동일한 객체에 대한 참조 값이 하나 더 만들어진다는 것을 배웠다.
객체를 복사하고 싶다면 기존에 있던 객체와 똑같으면서 독립적인 객체를 만들 방법은 없을까? 하지만 자바스크립트에서는 객체 복사 메서드를 지원하지 않기 때문에 조금 어렵다. 객체를 복제해야 할 일은 거의 없으나 참조에 의한 복사로 해결 가능한 일이 대다수라고 할 수 있다.
정말 복제가 필요한 상황이라고 한다면 새로운 객체를 만든 뒤 기존 객체의 프로퍼티들을 순회해 원시 수준까지 프로퍼티를 복사하면 된다.
let user = { name : "John", age : 30 }; let clone = {}; // 새로운 빈 객체 // 빈 객체에 user 프로퍼티 전부를 복사해 넣는다. for (let key in user) { clone[key] = user[key]; } // 이제 clone은 완전히 독립적인 복제본이 되었다. clone.name = "Pete"; // clone의 데이터를 변경합니다. alert( user.name ); // 기존 객체에는 여전히 John이 있다.
Object.assign을 사용하는 방법은 아래와 같다.
Object.assign(dest, [src1, src2, src3...])
- 첫 번째 인수 dest는 목표로 하는 객체이다.
- 이어지는 인수 src1,...srcN은 복사하고자 하는 객체이다. ...은 필요에 따라 얼마든지 많은 객체를 인수로 사용할 수 있다.
- 객체 src1, ... srcN의 프로퍼티를 dest에 복사한다. dest를 제외한 인수(객체)의 프로퍼티 전부가 첫 번쨰 인수 (객체)로 복사된다.
- 마지막으로 dest를 반환한다.
assign 메서드를 사용해 여러 객체를 하나로 병합하는 예시를 보자
let user = { name : "John" }; let permissions1 = { canView: true }; let permissions2 = { canView: true }; // permissions1과 permissions2의 프로퍼티를 user로 복사합니다. Object.assign(user, permissions1, permissions2); // now user = { name: "John", canView: true, canEdit: true }
목표 객체 (user) 에 동일한 이름을 가진 프로퍼티가 있는 경우 기존 값이 덮어씌워 집니다.
let user = { name : "John" } Object.assign(user, { name: 'Pete' }); alert(user.name); // user = { name: "Pete" }
Object.assign을 사용하면 반복문 없이도 간단하게 객체를 복사할 수 있다.
let user = { name : "John", age : 30 }; let clone = Object.assign({}, user);
user에 있는 모든 프로퍼티가 빈 배열에 복사되고 변수에 할당된다.
728x90반응형LIST'Javascript& React study' 카테고리의 다른 글
[JAVASCRIPT-모던자바스크립트] 가비지 컬랙션2 (0) 2021.10.15 [JAVASCRIPT-모던자바스크립트] 참조에 의한 객체 복사2 / 가비지 컬랙션 (0) 2021.10.14 [JAVASCRIPT-모던자바스크립트] 객체 기본에 대해서 알아보자3 (0) 2021.10.09 [JAVASCRIPT-모던자바스크립트] 객체 기본에 대해서 알아보자2 (1) 2021.10.08 [JAVASCRIPT-모던자바스크립트] 객체 기본에 대해서 알아보자 (2) 2021.10.07