얕은 복사(Spread 연산자), 깊은 복사(JSON.parse()), Rest Parameter

2023. 5. 24. 17:50JS

반응형

얕은 복사: 주소값까지만 복사함

깊은 복사: 실제 데이터까지 복사함

※ Spread 연산자(...)

→ 하나로 뭉쳐져 있는 값들의 집합을 전개해주는 연산자이다.

// ex1)
let arr = [1, 2, 3, 4, 5];
console.log(arr);     // [1, 2, 3, 4, 5]
console.log(...arr);  // 1, 2, 3, 4, 5

// ex2)
let str = "Hello";
console.log(str); // Hello
console.log(...str) // H e l l o

 

참조 타입의 복사

let origin = {
   name: "otter",
   age: 25
};

let copy = origin;
console.log(origin.name); // "otter"

//복사한 객체 프로퍼티 값 변경
copy.name = rabbit;

//원본 데이터도 변경됨
console.log(origin.name); // "rabbit"

 

얕은 복사

Spread 연산자(...)를 통해서 하나로 응집되어있는 값들을 전개하고 다시 {} 로 묶어서 객체를 생성한다.

let origin = {
   name: "otter",
   age: 25
};

let copy = {...origin};

console.log(copy); // {name: "otter", age: 25}

let arr = [1, 2, 3, 4, 5];
let secArr = [6, 7, 8];

let copy2 = [...arr, ...secArr]

console.log(copy2) // [1, 2, 3, 4, 5, 6, 7, 8]

 

깊은 복사

아래의 예시는 얕은 복사를 했을 경우의 문제가 있는 코드이다.

let origin = {
   name: "otter",
   age: 25,
   favoriteFood: {
      first: "sushi",
      second: "hamburger"
   }
};

//얕은 복사
const copy = {...origin};

//복사한 객체안의 객체의 프로퍼티 변경
copy.favoriteFood.first = "cold noodle";

//원본데이터도 변경됨
console.log(origin.favoriteFood); // {first: "cold noodle", second: "hanburger"}

 

그럼 객체 안에 또 객체가 있는경우까지 모조리 복사가 가능도록 수정해보자.

let origin = {
   name: "otter",
   age: 25,
   favoriteFood: {
      first: "sushi",
      second: "hamburger"
   }
};

//JSON 데이터 포맷으로 변경(문자열)
const copy = JSON.stringify(origin);

//깊은 복사
const deepCopy = JSON.parse(copy);

JSON.stringify 로 복사하고자 하는 객체를 문자열로 변환시키면 객체의 주소값을 잃어버리게 된다. 이 상태에서 객체형태로 다시 parse후 새로운 변수로 할당하면 새로운 주소값을 가지게 되는 원리이다.

 

Rest Parameter

객체에서 필요한 값만을 복사해서 새로운 객체를 만드려면 아래와 같은 방법을 사용한다. 깊은 복사를 하더라도 필요한 데이터만을 뽑아와서 복사하는건 불가능하다.

let origin = {
   name: "otter",
   age: 25,
   petName: "cherry",
   hobby: "playing game"
};

const essentialData = {
   name: origin.name,
   age: origin.age
};

 

이때 Rest Parameter를 사용한다.

const {petName, hobby, ...rest} = origin;

console.log(petName); // cherry
console.log(hobby); // playing game
console.log(rest); // {name: "otter", age: 25}. --> 내가 필요한 프로퍼티들만 뽑은 새로운 객체

지금 필요한 데이터는 name과 age 이므로 위와같이 필요하지 않은 객체의 실제 키값을 적어주고, Spread연산자와 rest 변수명을 합쳐서 반드시 맨 마지막에 rest라는 새로운 변수명에 필요한 나머지 데이터들을 할당해준다.

Rest Parameter의 변수명은 반드시 rest일 필요가 없다. 단순히 변수명이기 때문이다. any와 같은걸로도 많이 쓴다.

반응형

'JS' 카테고리의 다른 글

구조분해할당  (0) 2023.05.24
createElement, appendChild  (0) 2023.05.22
<ul>, <ol>, <li>  (0) 2023.05.21
브라우저의 web storage  (0) 2023.05.21
JS코드에서 지정한 innerHTML  (0) 2023.04.27