이근둥
근둥이의 블로그
이근둥
전체 방문자
875,057
오늘
0
어제
428

공지사항

  • 전체보기 (107)
    • 웹 (9)
    • 언어 & 프레임워크 (53)
      • JavaScript (7)
      • TypeScript (0)
      • Node.js (11)
      • Vue.js (3)
      • React (0)
      • React Native (0)
      • C & C++ (19)
      • Java & JSP (9)
      • Python (4)
    • 컴퓨터 과학 (3)
      • 알고리즘 (0)
      • 자료구조 (3)
    • 기타 (9)
      • Linux (1)
      • Git (2)
      • DialogFlow (4)
    • 일상 (13)
      • 게임 (13)
    • 칼럼 (9)
      • 회고 (0)
      • 나만의 글 (0)
      • 제품 리뷰 (9)
    • __Dev__ (9)
      • Release (9)
반응형

인기 글

  • 웹 푸시 알림(Web Push Notification)
    2022.06.13
    웹 푸시 알림(Web Push Notification)
  • [Tomcat] 아파치 톰캣 서버 포트 변경하기
    2018.08.24
    [Tomcat] 아파치 톰캣 서버 포트 변경하기
  • [Node.js] 실시간 채팅 서비스 만들기(5) - 채팅⋯
    2018.05.31
    [Node.js] 실시간 채팅 서비스 만들기(5) - 채팅⋯
  • [Vue 3] Composition API와 템플릿 참조(⋯
    2020.10.02
    [Vue 3] Composition API와 템플릿 참조(⋯
  • [Vue 3] Composition API 살펴보기
    2020.03.04
    [Vue 3] Composition API 살펴보기

태그

  • 파티클
  • 웹 확장
  • 프로그레시브 웹 앱
  • Deemo
  • 자바 프로젝트
  • spread syntax
  • Composition API
  • vue3
  • Java FX
  • composition-api
  • 자바
  • vue
  • javascript
  • WWDC
  • pwa
  • 이클립스
  • vuex
  • vue-next
  • ES6
  • Hello World!
  • 전개 구문
  • vue.js
  • Scanner
  • self
  • java
  • 이펙트
  • AstroWar
  • Vue 3
  • 출간
  • WWDC20

최근 댓글

  • 어디에서도 이런 친절한 설명은 받을 수 없었습니다. 응용⋯
    미쳤다...
  • 정말 너무 감사합니다 선생님 많은 도움이 되고있습니다 어떻⋯
    김준태
  • 커서 위치이동 함수까지 했는데 컴파일하면 Makefile.⋯
    Qour94
  • iOS의 경우 애플에서 개발하고 있는 webkit 엔진을 ⋯
    이근둥
  • android, IOS에서 된다고 했는데 Notifica⋯
    삽자루부대

최근 글

  • 웹 푸시 알림(Web Push Notification)
    2022.06.13
    웹 푸시 알림(Web Push Notification)
  • 스택(Stack)
    2022.05.26
    스택(Stack)
  • 배열(Array)
    2022.05.25
    배열(Array)
  • C언어로 배우는 자료구조
    2022.05.24
    C언어로 배우는 자료구조
  • [Vue 3] Composition API와 템플릿 참조(⋯
    2020.10.02
    [Vue 3] Composition API와 템플릿 참조(⋯

블로그 메뉴

  • 홈
  • 미디어로그
  • 방명록
hELLO · Designed By 정상우.
이근둥

근둥이의 블로그

[JavaScript] 전개 구문 활용 (Spread syntax)
언어 & 프레임워크/JavaScript

[JavaScript] 전개 구문 활용 (Spread syntax)

2019. 8. 7. 15:31
반응형

이번 포스팅에서는 ES6 에 추가된 전개 구문(Spread syntax, ...) 활용 트릭을 몇 가지 소개하려고 한다.

구글링을 해보면 꽤 많은 트릭과 활용 방법들이 있는데, 그 중 간단하면서 자주 사용할 수 있는 내용으로 구성해보았으니 한 번 알아보도록 하자.

Rest parameter

나머지 파라미터

Rest parameter는 전개 구문에 해당하는 내용은 아니지만 

눈에 보이는 코드 상으로 유사하니

한 번 알아보려고 한다.

 

Rest parameter는 이미 널리 사용하고 있을텐데, 함수의 매개변수 갯수가 정해져있지 않을 때 사용하게 된다.

 

const sum = (acc, ...nums) => {
  for (let num of nums) {
    acc += num;
  }
  return acc;
};

sum(0, 10, 20, 30); // 60

위와 같이 정해지지 않은 갯수의 매개변수를 받는 함수를 ...variable 형태로 구현할 수 있다.

 

Rest 파라미터는 함수에 바인딩되는 arguments 와 다르게 유사 배열이 아닌 자바스크립트 표준 배열로 대체되며,
함수의 마지막 매개변수만 Rest parameter 가 될 수 있다는 제약조건이 있다.

// Error
const f = (a, ...b, c) => {

}

마지막 파라미터만 Rest 파라미터가 될 수 있기 때문에 위의 코드는 문법적으로 유효하지 않다.

Immutable data pattern

불변 데이터 패턴

자바스크립트의 경우 **원시 타입(Primitive type)**은 모두 **불변 값(immutable value)**이다.

 

원시 타입 외의 값들은 모두 변경 가능(mutable)하며 대표적으로 object 타입이 이에 해당한다.

 

아래 예제로 위 설명을 이해해보도록 하자.

var myStr = 'Hello';
myStr = 'World';

문자열(string) 타입은 자바스크립트의 원시 타입에 해당한다.

 

myStr 변수는 'Hello' 라는 문자열 리터럴 값을 참조하고 있었고, 그 아래에서 'World' 라는 문자열을 참조하고 있다.

 

'Hello' 라는 문자열 값이 'World' 로 바뀐것이 아니라 참조(reference)하던 대상이 변경된 것이다.

 

메모리상에서 'Hello' 라는 문자열 데이터와 'World'라는 문자열 데이터가 독립적으로 생성되었고, myStr 변수가 이를 참조했을 뿐이다.

var obj = {
  name: 'Tom',
};

var objClone = obj;
objClone.name = 'Jerry';

반대로 원시 타입이 아닌 다른 객체들은 값을 변경할 수 있다.

 

위 코드를 확인해보면 obj 객체에는 name 프로퍼티가 존재하고 Tom 이라는 문자열 값이 들어있다.

 

objClone.name = 'Jerry' 라는 코드가 실행되면 객체는 mutable value 이므로 objClone 의 name 값이 변경된다.

여기서 한 가지 문제점이 있다면 기존의 obj의 name 값도 함께 변경되는 문제가 발생한다.

 

메모리상에 존재하는 하나의 객체를 obj, objClone 이 함께 참조하고 있기 때문이다.

위의 코드가 의도한 동작이 아니라면 디버깅을 진행할 때 꽤 골치 아플 수 있다.

 

이 때문에 immutable 한 객체가 필요한 경우 Object.freeze, Object.assign 등을 통해 모습은 같지만 서로 다른 객체를 만들어 참조 문제를 해결하는데, 전개 구문을 활용하여 Immutable 객체를 생성할 수 있다.

(React를 사용하는 경우 자주 직면할 것이다.)

 

const a = {
  name: 'Tom',
  age: 10,
};

const b = a;
b.name = 'Jerry'; // a, b 의 name 모두 변경된다.

const c = { ...a };

console.log(a === b); // true
console.log(a === c); // false

위 방식은 a가 참조하고 있는 객체를 얕은 복사하여 c에 할당한다.

 

만약 a가 참조하고 있는 객체 내부에서 원시값이 아닌 다른 객체(Nested object)가 있다면, 해당 객체의 참조는 그대로 유지되기 때문에 얕은 복사라고 이야기한다. (a 가 참조하던 객체만 복사했을 뿐, 안에 들어있는 객체는 복사되지 않았기 때문)

 

객체 내에서 참조하고 있는 객체 까지 모두 복사를 하려면 깊은 복사를 진행해야 한다.

 

한 가지 예를 들어보자.


좋아하는 것에 대한 정보(객체)를 person 이 가지고 있었고,person 을 복사하여 otherPerson 에 새로운 객체를 할당했다.

복사된 객체인 otherPerson 의 favorite은 기존 person 이 가지고 있던 faroviteThing 객체를 그대로 참조하는 형태가 된다.

이 상태에서 otherPerson.favorite 값을 수정하면 person 의 favorite 도 함께 변경된다.

 

메모리를 들여다보면, person, otherPerson, favoriteThing 3가지 객체만이 존재하는 모습일 것이다.

사람만 복제되어 두개의 객체가 되었을 뿐 좋아하는 것 하나를 서로 참조하고 있는 형태이다.

var favoriteThing = {
  type: 'Animal',
  name: 'Cat',
};

var person = {
  name: 'Tom',
  favorite: favoriteThing,
};

var otherPerson = { ...person };

// true
console.log(person.favorite === otherPerson.favorite);

이처럼 중첩된 상태의 객체를 모두 복사하려면 깊은 복사를 수행해야 하고, 깊은 복사는 여러 라이브러리에서 유틸로 지원하거나 얕은 복사를 재귀적으로 반복하여 구현할 수 있으니 참고하면 좋을 것 같다.

Optional spreading

선택적 전개

const available = true;

const obj = {
  user: 'James',
  age: 16,
  ...available && { key: 'kygX1LWpWr' },
};

console.log(obj); // { user: "James", age: 16, key: "kygX1LWpWr" }

 

available 변수는 유효한 상태를 나타내는 변수라고 하자.

 

obj 가 참조하는 객체에는 user, age 프로퍼티가 고정적으로 존재하며, key 프로퍼티는 조건이 유효할 때에만 프로퍼티에 추가되어야 한다. (즉, 조건에 따라 포함될 수도, 안 될 수도 있는 "선택적" 인 프로퍼티이다)

 

위 예제 코드는 key 프로퍼티를 선택적으로 추가할 수 있도록 작성한 코드라고 볼 수 있다.

 

a && b 연산은 a 가 truety value일 때 b 의 값을 반환한다.
a || b 는 반대로 a 가 falsy value일 때 b 의 값을 반환한다.

 

흔히 사용하는 AND, OR 논리연산자가 맞지만 실제 동작은 조건에 따라 앞, 뒤의 피연산자가 반환된다.
(이 부분에 대해서는 나중에 다시 이야기 해보도록 하겠다)

 

truety, falsy 값이라 함은 논리연산시 true 또는 false 로 평가되는 값을 의미하며,

대표적으로 아래의 값을 예로 들 수 있다.

  • Truety: 1, '비어있지 않은 문자열', { k: 1 }, [1, 2, 3], {}, []
  • Falsy: 0, '', NaN, undefined, null

(falsy 값을 제외한 모든 값은 truety 값으로 봐도 된다)

 

본론으로 넘어오자면 available 변수의 값이 truety 값인 경우 AND 연산자 뒤의 { key: '값' } 이 반환된다.

논리 연산 이후 전개 구문(...) 부분이 평가되기 때문에 ...{ key: '값' } 형태가 된다.

 

반대로 available 변수의 값이 falsy 값인 경우 false 가 반환되며 false 는 객체가 아니기 때문에 obj에는 아무런 영향을 주지 않게 된다.

 

그냥 쉽게 key 프로퍼티에 빈 값을 할당해도 되지만, 아래와 같이 객체의 key 값에 의존하는 로직이 존재하는 경우가 있을 수 있다.

const obj = {
  // 중략...
  key: available ? { key: '값' } : undefined,
};

Object.keys(obj); // ['user', 'age', 'key'];

이처럼 조건에 따라 user, age 프로퍼티만 가지는 객체 혹은 user, age, key 모두 가지는 객체를 단 한 줄로 만들 수 있다.


지금까지 3가지 유형을 알아보았다.

알아두면 유용하게 사용하는 경우가 분명 생길테니 알아두면 좋을 것 같다.

반응형
저작자표시 비영리 동일조건
    '언어 & 프레임워크/JavaScript' 카테고리의 다른 글
    • [JavsScript] self란 무엇인가?
    • [JavaScript] 심볼 (Symbol)
    • [JQuery] Ajax 동기 방식으로 사용하기
    • [JavaScript] 비동기 함수(Async/Await)
    ES6, javascript, spread syntax, 전개 구문
    이근둥
    이근둥
    새로운 것을 좋아하는 프론트엔드 개발자 ✨
    댓글쓰기

    티스토리툴바