Growth from the root - Vanilla JavaScript - 참조에 의한 객체 복사

이형준·2023년 4월 3일
post-thumbnail

1. 객체 vs 원시 타입(string, number, bigint, boolean, undefined, symbol,null) 의 차이

✍객체는 참조에 의해 저장되고 복사됨, 원시값은 값 그대로 저장, 할당, 복사 됨.

let message = "hello!"
let phrase = message;

✏️ 위 예시를 실행하면 각 각 독립된 변수에 문자열 "hello!" 가 저장됨.


✅ 그런데 객체는 다름, 그대로 저장이 아니라, 객체가 저정되어있는 메모리 주소 인 객체에 대한 참조 값이 저장 됨.

let user = {
  name : "jhon"
};

✏️ 객체는 메모리 내 어딘가에 저장 -> user엔 객체를 참조 할 수 있는 값이 저장.

let user = {name : jhon};

let admin = user; // 참조값을 복사함

✏️ 변수는 두 개 이지만, 각 변수엔 동일 객체에 대한 참조 값이 저장됨.
따라서, 객체에 접근하거나 조작 할 땐 여러 변수를 사용할 수 있음.

let user = {name : "jhon"};

let admin = user;

admin.name = "peter" // admin 참조 값에 의해 변경됨.

console.log(user.name) // "peter" 가 출력됨

✏️ 객체가 서럽장, 변수는 열쇠 : 서랍장은 하나, 열쇠는 두개




2. 참조에 의한 비교

✍ 객체 비교 시 ==(동등연산자)와 ===(일치연산자)는 동일하게 동작
비교 시 동일한 객체인 경우에 참을 반환.

let a = {};
let b = a; // 참조에 의한 복사

console.log(a == b) // true, 두 변수는 같은 객체를 참조함
console.log(a === b) // true
let a = {};
let b = {}; // 독립된 두 객체

console.log(a == b) // false

✏️ "obj1 > obj2" 같은 대소 비교나 "obj3 == 3"같은 원시값과의 비교에서 객체는 원시형으로 반환.



3. 객체 복사, 병합과 Object.assign

✍ 기존에 있던 객체와 똑같으면서 독립적인 객체를 만들고 싶을 때는 ?

let user = {
 name : "jhon",
 age : 30
};

let clone = {}; // 새로운 빈 객체

// 빈 객체에 user 프로퍼티 전부를 복사해 넣습니다.
for (let key in user){
clone[key] = user[key];
}

// clone 는 완전히 독립적인 복제본임.
clone.name = "pete" // clone의 데이터를 변경
console.log(user.name); // 기존 객체에는 여전히 jhon 이 있음.

✍ object.assign 를 사용하는 방법도 있음.

object.assign(dest, [src1, src2, src3 ... ])

// 첫 번째 인수 dest는 목표로 하는 객체
// 이어지는 인수 src1, ... 는 복사하고자 하는 객체
// 객체 src1, ... 의 프로퍼티를 dest애 복사 -> dest를 제외한 인수의 프로퍼티 전부가 첫 번째 인수로 복사됨.





4. 중첩 객체 복사

✍ 지금까진 user의 프로퍼티가 원시값인 경우만 가정함, 그런데 프로퍼티가 다른 객체의 참조 값이라면 ?

let user = {
	nmae : "jhon",
 	sizes : {
   	height : 182,
     	width : 50
   }
}
console.log(user.sizes.height); // 182

✏️ "clone.sizes = user.sizes" 로 프로퍼티를 복사하는 것으로는 객체를 복제 할 수 없음.
"user.sizes" 는 객체이기 때문에 참조 값이 복사됨, "clone.sizes = user.sizes"로 복사하면 clone과 user 는 같은 sizes 를 공유함.

✅ 이러한 문제를 해결하려면 user[key] 의 각 값을 검사하면서, 그 값이 객체인 경우 그 구조까지 복사해주는 반복문을 사용해야 함. 이러한 방식을 "깊은 복사" 라고 함.

profile
프론트엔드 개발자 이형준입니다.

0개의 댓글