2020. 8. 12. 22:20ㆍProgramming Languages/JavaScript
객체와 원시 타입의 근본적인 차이 중 하나는 객체는 참조에 의한 복사에 의해 저장되고 복사된다는 것입니다. 원시값(문자열, 숫자, 불린 값)은 값 자체가 저장되고 복사됩니다.
const message = "Hello";
const text = message;
위 코드를 실행하면 아래와 같이 두 개의 독립된 변수에 각각 문자열 "Hello"가 저장됩니다.
그런데 객체의 동작방식은 이와 다릅니다.
변수엔 객체가 그대로 저장되는 것이 아니라, 객체가 저장되어있는 '메모리 주소'인 객체에 대한 '참조 값'이 저장됩니다.
객체는 메모리 내 어딘가에 저장되고, 변수 user엔 객체를 참조할 수 있는 값이 저장됩니다.
let user = { name: "John" };
let admin = user;
admin.name = "Anna"; // user와 같은 메모리 주소를 공유하기 때문에 name이 변경됨
console.log(user.name); // "Anna"가 출력됨.
객체를 비교할 때 ==와 ===는 동일하게 동작합니다. 비교 시 피연산자인 두 객체가 동일한 객체인 경우에, 즉 같은 참조값을 가지고 있다면 참을 반환합니다.
let a = {name: "John"};
let b = a;
console.log(a === b); // true
하지만 프로퍼티가 동일하다고 같은 참조값을 가지는 것은 아닙니다. 아래의 예시를 보면 같은 프로퍼티를 가졌지만 false가 출력되는 것을 볼 수 있습니다. 왜냐하면 위 예시는 b에 참조에 의한 복사를 통해 a의 참조값을 복사한 것이고 아래 예시는 각각의 독립된 참조값을 가지는 객체 a와 b를 선언한 것이기 때문입니다.
let a = {name: "John"};
let b = {name: "John"};
console.log(a === b); // false
그렇다면 객체를 복사하여 기존의 객체와 똑같은 객체를 만드려면 어떻게 해야 될까요?
먼저 for문을 활용하는 방법이 있습니다. 아래 코드를 봅시다.
let user = {
name: "John",
age: 30,
};
let clone = {};
// clone 객체에 user의 프로퍼티를 모두 복사합니다.
for (let key in user) {
clone[key] = user[key];
}
console.log(clone.name); // "John"
두 번째로 Object.assign을 사용하는 방법이 있습니다.
위 사진은 assign 메소드의 사용 방법을 설명해놓은 것입니다. 한 번 정독하시면 좋을 것 같습니다.
사용 방법을 간단히 알아봅시다.
target: object - 복사한 프로퍼티들을 담을 객체입니다.
... sources: any[] - 복사하고자하는 객체입니다. 필요에 따라 얼마든지 객체를 인수로 사용할 수 있다는 것을 나타냅니다.
sources 를 복사하고 target에 담은 뒤 target을 반환합니다. 예시를 한 번 봅시다.
let user = {
name: "John",
age: 30
};
let city = { city: "Seoul" };
let hasGirlFriend = { hasGirlFriend: false };
// city와 hasGirlFriend의 프로퍼티를 복사합니다.
Object.assign(user, city, hasGirlFriend);
/* user = {
name: "John",
age: 30,
city: "Seoul",
hasGirlFriend: false,
}
*/
만약 동일한 프로퍼티 키가 있는 경우엔 기존 값이 새로운 값으로 덮어쓰기됩니다.
let user = {
name: "John",
}
let clone = Object.assign({}, user);
위와 같이 빈 객체에 user 프로퍼티를 복사하여 clone이라는 객체를 만들 수도 있습니다.
만약 복사하는 객체의 프로퍼티 중 값이 객체인 경우에는 어떻게 될까요?
이런 경우에는 프로퍼티 값의 참조값이 복사됩니다. 즉, 값이 복사되지 않고 참조값이 복사되어 복사한 객체에서 값을 수정할 경우 기존의 객체값이 변경됩니다. 이 문제를 해결하려면 프로퍼티 값을 검사하면서, 그 값이 객체라면 객체의 구조도 복사해주는 반복문을 사용해야 합니다. 이런 방식을 '깊은 복사(deep cloning)'이라고 합니다. 이 경우는 저도 아직 접헤보지 않아서 이 정도로만 설명하겠습니다. 이런 것도 있다고 생각합시다.
'Programming Languages > JavaScript' 카테고리의 다른 글
[JavaScript] Promise (0) | 2021.05.12 |
---|---|
[JavaScript] 가비지 컬렉션 (0) | 2020.08.17 |
[JavaScript] 객체 (0) | 2020.08.11 |
[JavaScript] Prototype (0) | 2020.08.02 |
[JavaScript] 함수(Function) (0) | 2020.08.02 |