본문 바로가기
개발/Javascript

[js] spread 연산자 (ft. 전개 연산자, 불변성, 얕은 복사)

by 코딩하는 갓디노 2021. 6. 27.

spread operartor

 

자바스크립트 es6, 
스프레드 연산자 입니다.

 


spread 연산자

하나의 배열 데이터를 spread 연산자를 이용해 출력하면, 문자 데이터 형태로 출력됩니다.

 

spread 연산자 예제

const fruits = ['apple', 'banana', 'orange'];

console.log(...fruits);
//결과
apple banana orange
------------------------------
console.log('apple', 'banana', 'orange'); 와 같은 결과
즉, 쉼표로 구분되면서 각각의 아이템으로 전개되어 들어가집니다.



spead 연산자를 이용한 객체 데이터 생성 예제 1

일일이 배열 데이터 안의 요소를 나열할 필요 없이 spread 연산자를 이용해 손쉽게 객체 value값으로 출력할 수 있습니다.

const fruits = ['apple', 'banana', 'orange'];
const toObject = (a, b, c) => {
  return {
    a: a,
    b: b,
    c: c
  }
};
console.log(toObject(...fruits));
//결과
{a: "apple", b: "banana", c: "orange"}
---------------------------------------------------
여기서 spread 연산자를 사용하지 않는다면,
아래와 같이 일일이 배열 인덱스를 지정해 주어야 같은 결과가 출력됩니다.
console.log(toObject(fruits[0],fruits[1],fruits[2]));

 

여기서 toObject 함수를 축약형 표현 

  • 리턴 키워드 안에 하나의 로직만 담고 있다면, return 키워드가 { }가 생략 가능합니다.
  • 객체 데이터를 축약형으로 반환하고 싶다면, ( )로 { }를 한번 더 감싸 줍니다. 
const toObject = (a, b, c) => ({ a, b, c });

 

spead 연산자를 이용한 객체 데이터 생성 예제 2 - 매개변수에 spread 연산자 적용

매개변수에 spread 연산자를 사용하면,
배열의 개수와 매개변수 개수가 일치하지 않을 경우, 배열의 나머지 요소들을 받아내는 역할을 하고,
이를 rest parameter라고 부릅니다.

const fruits = ['apple', 'banana', 'orange', 'tomato'];//orange, tomoto가 나머지 아이템
const toObject = (a, b, ...c) => { //c는 rest parameter
  return {
    a: a,
    b: b,
    c: c
  }
};
console.log(toObject(...fruits));
//결과
{a: "apple", b: "banana", c: Array(2)}
a: "apple"
b: "banana"
c: (2) ["orange", "tomato"] //나머지를 배열로 반환

 

2개의 object를 합치는 방법 2가지

spread 연산자 예제

const fruit = { name: "banana", color: "yellow" };
const detail = { price: 20, origin: "USA", birth: "2021-06-09" };
const union = { ...fruit, ...detail };
console.log(union);
//결과
{name: "banana", color: "yellow", price: 20, origin: "USA", birth: "2021-06-09"}

 

여기서 객체에 key를 업데이트하고 싶을 경우,

const union = { ...fruit, ...detail, price: 50 };
console.log(union);
//결과
{name: "banana", color: "yellow", price: 50, origin: "USA", birth: "2021-06-09"}

기존의 값은 바뀌지 않으면서 price 만 업데이트가 됩니다. 

 

Object.assign() 예제

const fruit = { name: "banana", color: "yellow" };
const detail = { price: 20, origin: "USA", birth: "2021-06-09" };
const union = Object.assign(fruit, detail);
//결과
{name: "banana", color: "yellow", price: 20, origin: "USA", birth: "2021-06-09"}

 

push 대신 사용하는 스프레드 연산자 예제

배열에서 하나의 값을 추가할 때, push를 사용하면, 마지막 인자로 추가가 됩니다.

const fruit = ["banana", "apple"];
fruit.push("strawberry");
console.log(fruit); //(3) ["banana", "apple", "strawberry"]

 

push는 기존의 fruit을 수정하는 것이지만,
spread 연산자를 사용하여 요소를 추가한 새로운 배열을 만들게 됩니다.

let fruit = ["banana", "apple"];
fruit = [...fruit, "strawberry"];
console.log(fruit); //(3) ["banana", "apple", "strawberry"]

 

불변성

데이터 불변성

불변성이란 기존의 값을 그대로 유지하면서 새로운 값을 추가하는 것으로
객체가 생성된 이후  상태를 변경할  없는 디자인 패턴을 의미합니다.

 

원시 데이터

  • 원시 데이터 종류: String, Number, Boolean, undefined, null
  • 데이터가 불변합니다.
  • 데이터의 생김새가 같으면 똑같은 메모리 주소를 바라보고 있고, 이를 같은 데이터라고 해도 무방합니다.

 

참조형 데이터

  • 참조형 데이터: Object, Array, Function 
  • 데이터가 불변하지 않습니다. -> 변수 선언할 때마다 새로운 메모리 주소에 각 참조형 데이터들이 할당됩니다. 
  • 데이터의 생김새가 같아도, 서로 같은 데이터가 아닐 수 있습니다. 
  • 할당 연산자(a=b)를 사용할 때, 메모리를 바라보고 있는 여러 개의 변수들이 있을 때 한쪽 변수(a), 속성의 값을 수정했을 경우, 다른 변수(b) 속성의 값도 바뀌는 경우가 있습니다. -> 불변성을 지키지 못함
  • 이 문제를 해결하기 위해 복사(얕은 복사)를 이용하여 불변성을 지켜줍니다.

 

얕은 복사

얕은 복사 - Object.assign()

Object.assign({ }, 변수);

 

Object.assign() 얕은 복사 예제 1

const user = {
  name: 'goddino',
  gender: 'female',
  blog: ['goddino.tistory.com/']
}

const copyUser = Object.assign({}, user); //user를 copyUser에 얕은 복사
console.log(copyUser === user);

user.gender = 'male'; //user 속성 값 변경
console.log('user', user);
console.log('copyUser', copyUser); //불변
//결과
false
user {name: "goddino", gender: "male", blog: Array(1)}
copyUser {name: "goddino", gender: "female", blog: Array(1)}

 

얕은 복사 - spread 연산자

spread operator 얕은 복사 예제 2

const user = {
  name: 'goddino',
  gender: 'female',
  blog: ['goddino.tistory.com/']
}

const copyUser = {...user}; //spread 연산자로 copyUser에 user를 얕은 복사
console.log(copyUser === user); //false ->불변성이 지켜졌음

user.gender = 'male';
console.log('user', user);
console.log('copyUser', copyUser); //불변
//결과
false
user {name: "goddino", gender: "male", blog: Array(1)}
copyUser {name: "goddino", gender: "female", blog: Array(1)}

 

spread operator 얕은 복사(불변성 X) 예제 3 

여기서 user.blog 데이터는 배열이고, 배열은 참조형 데이터이기 때문에,
배열에 push로 데이터를 추가되면서 불변성이 지켜지지 않아, copyUser.blog가 user.blog와 똑같이 변합니다.

const user = {
  name: 'goddino',
  gender: 'female',
  blog: ['goddino.tistory.com/']
}

const copyUser = {...user}; //얕은 복사
user.gender = 'male';

user.blog.push('kiki.tistory.com/'); //push로 배열에 데이터 추가
console.log(copyUser.blog === user.blog); //true ->불변성이 안지켜졌음
console.log('user', user);
console.log('copyUser', copyUser);
//결과
true
user {name: "goddino", gender: "male", blog: Array(2)}
	blog: (2) ["goddino.tistory.com/", "kiki.tistory.com/"]
	gender: "male"
	name: "goddino"

copyUser {name: "goddino", gender: "female", blog: Array(2)}
	blog: (2) ["goddino.tistory.com/", "kiki.tistory.com/"]
	gender: "female"
	name: "goddino"
반응형

댓글