자바스크립트 비구조화 할당 사용하기(Beautiful Destructuring in JS)

자바스크립트에서 객체 비구조화(Object Destructuring)를 사용하는 아름다운 방법
from. How to Use Object Destructuring in Javascript(Dmitri Pavlutin)

비구조화 할당(Destructuring Assignment)이란 배열 또는 객체 안의 속성값를 풀어 편리하게 변수에 넣는 것을 말합니다.
한 번 선언으로 여러 속성값 추출, 하부 객체에서 접근, 값이 존재하지 않는 경우 기본값 설정 등이 가능합니다.

백 번의 설명보다 하나의 샘플 코드가 더 유용하므로 하나씩 알아보도록 하겠습니다.

1. 비구조화 할당의 필요성

자바스크립트 ES2015 환경에서 객체의 속성값을 가져오려면 다음과 같은 코드를 사용합니다.

const flower = {
  name: 'Rose',
  color: 'Red'
};

const name = flower.name;
const color = flower.color;

console.log(name);    // 'Rose'
console.log(color);    //  'Red'

flower.name 값을 name 변수에 넣고, flower.color 값을 color 변수에 넣습니다.

하지만 위와 같이 값을 대입하면 반복되는 부분이 발생합니다. 바로 ‘name’과 ‘color’입니다.

대입 과정에서 name이 변수 선언에 한 번, 그리고 flower 객체의 속성 접근에 한 번, 총 두 번이 사용됩니다.

color도 마찬가지입니다.

비구조화 할당은 이런 번거로움을 없애고자 할 때 사용합니다.

비구조화 할당을 사용하면 객체에서 속성을 가져와 같은 이름의 변수에 대입할 때 속성명을 한번 더 명시할 필요가 없습니다.

게다가 속성이 여러 개일지라도 한번의 선언으로 해결이 가능합니다.

아래 코드에서는 위 코드를 리팩토링하여 비구조화 할당을 사용합니다.

const flower = {
 name: 'Rose',
 color: 'Red'
};

const { name, color } = flower;

console.log(name);   // 'Rose'
console.log(color);  // 'Red'

‘const { name, color } = flower’가 바로 객체 비구조화입니다.
이 구문으로 name과 color 변수를 선언하고, flower.name과 flower.color 속성의 값을 같은 이름 변수에 할당합니다.

다음은 객체의 속성값에 접근하는 두 가지 방법입니다.

const name = flower.name;
const color = flower.color;

// 위와 아래는 같은 결과

const { name, color } = flower;

속성명과 변수명이 중복되지 않으므로 비구조화가 훨씬 깔끔하고 편리한 것을 알 수 있습니다.

2. 속성값 가져오기

객체 비구조화의 기본 문법은 간단합니다.

const { identifier } = expression;

여기서 identifier는 속성에 접근할 이름이고, expression은 identifier가 접근하는 객체입니다.

비구조화를 하면 identifier 변수는 접근한 속성값을 갖게 됩니다.

위와 같은 코드이지만 속성 접근자를 사용하게 되면 다음과 같습니다.

const identifier = expression.identifier;

위 내용을 토대로 비구조화 할당을 연습해 보겠습니다.

const flower = {
  name: 'Rose',
  color: 'Red'
};

const { name } = flower;

console.log(name);  // 'Rose'

‘const { name } = flower;’는 name 변수를 선언하고, flower.name의 속성값을 대입하는 비구조화 할당입니다.

3. 여러 속성값 한번에 가져오기

여러 속성값을 가진 객체의 비구조화는 쉼표를 사용하면 됩니다.

const { identifier1, identifier2, ..., identifierN } = expression;

여기서 identifier1, identifier2, …, identifierN은 속성에 접근할 이름이고, expression은 identifier가 접근하는 객체입니다. 비구조화를 하면 각 identifier 변수는 접근한 속성값을 갖게 됩니다.

속성 접근자를 사용하는 코드는 다음과 같습니다.

const identifier1 = expression.identifier1;
const identifier2 = expression.identifier2;
// ......
const identifierN = expression.identifierN;

그럼 두 개의 속성값을 할당하는 첫 번째 샘플 코드를 다시 확인해 보겠습니다.

const flower = {
 name: 'Rose',
 color: 'Red'
};

const { name, color } = flower;

console.log(name);   // 'Rose'
console.log(color);  // 'Red'

‘const { name, color } = flower;’는 name, color 두 변수를 생성하고, 각각 flower.name과 flower.color의 속성값을 할당합니다.

4. 기본값 설정하기

비구조화를 하더라도 객체에 동일한 속성명이 존재하지 않는 경우 undefined가 할당됩니다.

const flower = {
  name: 'Rose',
  color: 'Red'
};

const { meaning } = flower;

console.log(meaning);  // undefined 

위와 같이 속성이 존재하지 않는 경우 기본값 설정이 가능하며, 문법은 다음과 같습니다.

const { identifier = defaultValue } = expression;

identifier가 expression 객체의 속성에 접근하는 이름이 됩니다. expression 객체 내 identifier 속성이 존재하지 않으면 지정한 기본값인 defaultValue가 대입됩니다.

다음 코드와 같은 기능을 합니다.

const identifier = expression.identifier === undefined ? defaultValue : expression.identifier;

기본값 설정 옵션을 더해 코드를 수정해 보겠습니다.

const flower = {
  name: 'Rose',
  color: 'Red'
}

const { meaning = 'love' } = flower;

console.log(meaning)  // 'love'

undefined 대신 ‘love’가 대입됩니다.

5. 별명(alias) 정하기

객체의 속성명과 다른 이름으로 변수를 선언하고 싶을 때는 별명을 지정하면 됩니다.

const { identifier: aliasIdentifier } = expression;

여기서 identifier는 속성에 접근하는 이름이며, aliasIdentifier는 변수로 사용할 이름입니다. 비구조화를 하면 aliasIdentifier가 속성값을 갖습니다.

다음 코드와 같은 의미입니다.

const aliasIdentifier = expression.identifier;

실제 별명을 적용한 코드는 다음과 같습니다.

const flower = {
  name: 'Rose',
  color: 'Red'
};

const { color: realColor } = flower;

console.log(realColor); // 'Red'
console.log(color); // 에러 발생(color is not defined)

위 코드는 realColor로 변수를 선언하고, flower.color값을 할당하여 비구조화를 진행합니다.

6. 내부 객체의 속성값 가져오기

앞에서 확인한 샘플은 원시형 데이터 타입(String, Number 등)의 속성을 갖는 일반 객체입니다.

그러나 일부는 객체 안에 또 다른 객체를 갖습니다. 물론 이러한 형태를 가진 객체도 비구조화 할당이 가능합니다.

const { nestedObject: { identifier } } = expression;

nestedObject는 내부 객체명이고, identifier는 내부 객체의 속성명입니다.

비구조화 할당을 통해 identifier가 내부 객체의 속성값을 가지며, 다음 코드와 같은 의미입니다.

const identifier = expression.nestedObject.identifier;

내부 객체의 깊이는 제한이 없으며, 중괄호{ }만 추가해주면 됩니다.

const { propA: { propB: { propC: {......} } } } = object;

다음 샘플을 통해 내부 객체에 접근하여 비구조화 할당을 진행하는 코드를 확인해 보겠습니다.

const flower = {
  name: 'Rose',
  color: 'Red',
  blooming: {
   season: 'spring'
  }
};

//Object destructuring
const { blooming: { season } } = flower;

console.log(season) // 'spring'

‘const { blooming: { season } } = flower;’는 내부 객체 blooming의 season 속성값을 할당합니다.

7. 동적 이름으로 속성값 가져오기

동적 이름(Dynamic Name)의 사용도 가능합니다.

const { [propName]: identifier } = expression;

propName은 속성명(주로 string 타입)이며, identifier는 값이 할당될 변수의 이름입니다.

다음 코드와 같은 의미를 갖습니다.

const identifier = expression[propName];

다음 샘플을 통해 속성명으로 사용되는 prop을 확인하겠습니다.

const flower = {
  name: 'Rose',
  color: 'Red'
};

const prop = 'name';
const { [prop]: flowerName } = expression;

console.log(flowerName); // 'Rose'

‘const { [prop]: flowerName } = expression’에서 flowerName 변수에 flower[prop] 속성값을 할당하며, prop은 접근할 속성명을 가진 변수입니다.

8. 비구조화 할당 후 남겨진 객체

나머지 데이터를 관리하는 문법은 비구조화 할당에서 유용하게 사용할 수 있습니다.

const { identifier, ...rest } = expression;

위 코드에서 identifier를 제외한 나머지 속성은 rest 변수에 할당됩니다.

아래 코드에서 name 속성을 제외한 나머지 속성을 정리하는 샘플을 확인해 보겠습니다.

const flower = {
  name: 'Rose',
  color: 'Red'
};

const { name, ...realColor } = flower;

console.log(realColor) // { realColor: 'Red' }

name 속성값을 할당한 뒤 나머지 속성들은 realColor 변수에 할당합니다.

9. 자주 사용되는 구문

앞에서 확인한대로 비구조화는 속성값을 변수에 할당합니다.

변수 타입은 const, let, var 모두 사용이 가능하며, 이미 선언된 변수에도 할당이 가능합니다.

let을 사용한 방법은 다음과 같습니다.

//let
const flower = {
  name: 'Rose',
};

let { name } = flower;

console.log(name); // 'Rose'

var를 사용한 방법은 다음과 같습니다.

//var
const flower = {
  name: 'Rose',
};

var { name } = flower;

console.log(name); // 'Rose'

이미 선언된 변수에 할당하는 방법은 다음과 같습니다.

//existing variable

let name;

const flower = {
  name: 'Rose',
};

({ name } = flower);

console.log(name); // 'Rose'

for…of 반복문을 사용한 비구조화 할당은 다음과 같습니다.

const flowers = [
  { name: 'Rose' },
  { name: 'Lily' }
];

for (const { name } of flowers) {
  console.log(name) //'Rose', 'Lily'
}

사실 비구조화는 할당이 가능한 곳이면 어디든지 사용이 가능하다고 볼 수 있습니다.

예를 들면 다음과 같이 함수 파라미터의 비구조화도 가능합니다.

const flowers = [
  { name: 'Rose' },
  { name: 'Lily' }
];

const names = flowers.map(
  function({ name }) {
    return name;
  }
)

console.log(names); // ['Rose', 'Lily']

‘function({ name })’은 함수의 파라미터를 비구조화하여, name 변수에 name 속성을 할당합니다.

10. 변수 값 서로 교환(swap)

비구조화 할당을 사용하면 두 변수의 값을 편리하게 교환할 수도 있으며, 기존처럼 데이터를 임시로 보관할 변수가 필요하지 않습니다.

let a = 1;
let b = 2;

//기존 교환 방법
const temp = a;
a = b;
b = temp;

//비구조화를 통한 교환
[a, b] = [b, a];

11. 정리

비구조화 할당은 객체의 속성값을 빠르고 쉽게 변수에 할당할 수 있는 아주 강력한 기능을 제공합니다.
특히 간결한 문법과 여러 변수를 한 번에 선언할 수 있는 점이 매력적입니다.


비구조화 할당에 대해 간결하면서도 누구나 이해하기 쉽도록 작성된 좋은 글을 접하게 되어 좋은 정보를 나누고자 양해를 구하여 국내에 맞게 번역하고 일부 내용을 추가하여 글을 올리게 되었습니다. 궁금하신 사항은 댓글 남겨주세요.

출처: https://dmitripavlutin.com/javascript-object-destructuring/

Useful Shortcut Keys For Visual Studio Code(VS code단축키 모음)

효율적인 작업을 위한 비쥬얼 스튜디오 코드(VS Code) 단축키 모음

Sometimes we need some shortcut keys for improving efficiency and avoiding irritable repeating works.

But occasionally, we use it because just seems cool!

VS code shortcut keys will help you and your work faster.

You can also check or edit shortcuts keys at File – Preferences – Keyboard Shortcuts.

Or follow default set version as below.

단축키는 효율성을 높이거나 반복되는 작업에 자주 사용하곤 합니다.

그 작업이 게임이건 사무용 프로그램이건 말이죠.

단축키를 쓰면 실력자로 보이기도 하고, 약간은 숙련자로 보이기도 하는 것 같습니다.

익숙한 단축키부터 유용한 단축키까지 VS Code에서 사용할 수 있는 단축키를 정리해보았습니다.

물론 File – Preferences – Keyboard Shortcuts에서 단축키의 수정도 가능합니다.


SHORTCUT KEYS FOR VS CODE

EDIT
CopyCtrl + C복사
CutCtrl + X잘라내기
PasteCtrl + V붙여넣기
Select AllCtrl + A전체 선택
Undo(↔Redo)Ctrl + Z실행취소(↔다시실행)
Redo(↔Undo)Ctrl + Y다시실행(↔실행취소)
Copy LineAlt + Shift + ↑/↓행 복사하기
Move LineAlt + ↑/↓행 옮기기
Insert Line AboveCtrl + Shift + Enter한 줄 삽입하기(위쪽)
Indent LineCtrl + ]들여쓰기
Line CommentCtrl + /코멘트 (라인)
Block CommentAlt + Shift + A코멘트 (블록)
FindCtrl + F찾기
ReplaceCtrl + H바꾸기
Trigger SuggestionCtrl + Space완성 제안
Close EditorCtrl + W에디터 닫기
SaveCtrl + S저장하기
Reopen closed EditorCtrl + Shift + T닫은 에디터 열기
Full Screen ModeF11풀스크린
Sidebar visibilityCtrl + B사이드바 열기
Show TerminalCtrl + `터미널 열기
Debug
Start/ContinueF5시작/계속
StopShift + F5정지
BreakpointF9브레이크 포인트

VS Code 터미널 Terminal에서 yarn 실행하기

How to use ‘yarn’ with VS Code terminal


VS Code와 yarn을 설치하고 VS Code의 터미널에서 yarn을 사용하려고 하면 다음과 같이 에러가 뜨는 경우가 있어요.

이는 스크립트의 실행 권한으로 발생하는 문제인데요. Node.js command prompt 등의 프롬프트를 따로 열고 실행하면 문제없지만 하나의 툴(VS Code)로 코드도 편집하고 프롬프트 명령도 사용할 수 있으면 좋잖아요.

다음과 같이 간단한 작업을 통해 문제를 해결할 수 있습니다.

1. Windows PowerShell 을 관리자 권한으로 실행


2. 주어진 권한 상태 확인(get-ExecutionPolicy)

get-ExecutionPolicy 명령을 입력하면 권한이 Restricted로 설정되어 있는 것을 확인할 수 있어요.
간단하게 이 권한을 RemoteSigned로 변경해주면 됩니다.


3. Set-ExecutionPolicy RemoteSigned 입력 -> y

Set-ExecutionPolicy RemoteSigned를 실행하면 변경 여부를 묻고, y를 입력하면 변경이 완료!
get-ExecutionPolicy 명령을 통해 변경된 권한을 확인할 수 있어요.


4. 작동 여부 확인

이제 자유를 얻은 VS Code 터미널에서 yarn 명령을 실행해 만족스러운 결과를 확인합니다.

개발자의 영어 사전(Developers’ terms in English)

Developers’ terms in English and Korean for foreign works

공부와 번역 일을 하면서 문장 번역과 업무에 핵심이 되는 개발 용어들을 틈틈이 정리하여 업데이트하는 포스트

  • anonymous function 익명 함수
  • arrow function 화살표 함수
  • ascending order 오름차순
  • assign 할당하다
  • braces { } 중괄호 (=curly brackets)
  • brackets [ ] 대괄호
  • boilerplate 상용구
  • cascade 연속, 종속
  • closure 클로저 (자바스크립트 클로저 포스팅)
  • curly brackets { } 중괄호 (=braces)
  • declarative programming 선언형 프로그래밍
  • deprecated 더 이상 사용되지 않는, 사라지게 될
  • descending order 내림차순
  • DOM (Document Object Model) 문서 객체 모델
  • duplicate 복사하다, 복제하다
  • execute 실행하다
  • first-class function 일등 함수 (함수와 변수를 구분하지 않는 함수)
  • function 함수
  • function call operator 함수 호출 연산자 ( )
  • functional programming 함수형 프로그래밍
  • global variable 전역변수
  • IIFE (Immediately Invoked Function Expression) 즉시 실행 함수
  • immutable 불변의
  • imperative programming 명령형 프로그래밍
  • impure function 불순 함수
  • inheritance 상속
  • invoke 호출하다
  • LOC(Lines of Code) 코드 라인
  • local variable 지역변수
  • loop 루프 / 반복 실행
  • manipulate 조작하다
  • memoization 메모이제이션(동일한 계산(또는 함수 생성) 반복 시 이전 계산 값을 메모리에 저장하여 반복 계산을 피함)
  • migration 이동, 이주
  • method 메서드
  • mutable 가변의
  • object 객체
  • object literal 객체 리터럴
  • object oriented programming (OOP) 객체 지향 프로그래밍
  • operand 피연산자
  • opinionated 의견이 있는, 고집이 있는, 방안을 제시하는, 제한을 두는(Angular 프레임워크 특징 설명 시 자주 사용)
  • parallel 병행의, 병렬의
  • parentheses ( ) 소괄호
  • parse 분석하다
  • pure fuction 순수 함수
  • quotation mark 따옴표
  • reactive programming 반응형 프로그래밍
  • recursive function 재귀 함수
  • regular expression 정규 표현
  • REST (REpresentational State Transfer) REST
  • response 응답, 리스폰스
  • request 요청, 리퀘스트
  • robust 탄탄한, 강력한
  • shallow copy 얕은 복사(동일한 객체를 참조)
  • snippet 조각, 단편, 코드 조각
  • syntax 문법
  • ternary operator 삼항연산자
  • UI (User Interface) UI
  • unopinionated 의견이 없는, 방안을 제시하지 않는, 제한을 두지 않는(Express 프레임워크 특징 설명 시 자주 사용)
  • variable 변수

자바스크립트 클로저 파헤치기(What is Javascript Closure)

Venezia

자바스크립트에서 변수는 전역(global)변수와 지역(local)변수가 있어요.

전역변수는 위치에 상관없이 모든 함수가 접근 가능하지만 지역변수는 해당 스코프 내부에서만 접근이 가능합니다.

하지만 클로저를 사용하면 전역변수처럼 지역변수를 사용할 수 있어요. 안전성을 보장하면서요.

전역변수

함수는 함수 내 선언된 모든 변수에 접근할 수 있어요.

샘플1


function testFunction( ) {

  let abc = 10;

   return abc * 2;

}


또한 함수 외부의 변수에도 접근할 수 있어요.

샘플2


let abc = 10;

function testFunction( ) {

   return abc * 2;


샘플2에서 abc는 전역변수입니다. 웹 페이지에서 전역 변수는 window 객체에 속합니다. 

전역변수는 페이지 내 모든 스크립트가 접근하여 사용하거나 변경할 수 있어요.

샘플1에서 abc는 지역변수입니다. 지역변수는 변수를 선언한 함수 내에서만 사용이 가능해요. 

다른 함수나 스크립트 코드에게는 감춰져 있는 것이죠.

전역변수와 지역변수는 이름이 같아도 다른 변수입니다. 하나를 수정해도 다른 변수는 영향을 받지 않죠.

선언자(var, let, const) 없이 생성된 변수는 모두 전역변수입니다. 특정 함수 안에서 생성 되었다고 해도 말이죠.

function testFunction() {

   abc = 10;

}

변수의 생명 주기(lifetime)

전역변수는 페이지가 종료될 때(다른 페이지로 넘어가거나 윈도우 창을 종료)까지 유효합니다.

그리고 지역변수는 함수가 호출될 때 생성되어 함수가 종료될 때까지 유효합니다.

숫자 카운팅의 문제

모든 함수에서 접근이 가능한 변수를 만들어 숫자 카운팅에 사용해보도록 하겠습니다.

전역 변수와 함수를 사용해 숫자를 카운팅합니다.

샘플3


let cnt = 0;

function addNum(){

   cnt += 1;

}

addNum();

addNum();      

// 결과:2


하지만 위의 코드는 addNum() 함수가 아닌 다른 코드로도 cnt 변수에 접근하여 수정이 가능합니다. 

따라서 cnt 변수는 addNum() 함수 내부에 존재해야 다른 코드에서 접근할 수 없습니다.

샘플4


let cnt = 0;

function addNum() {

   let cnt = 0;

  cnt += 1;

}

addNum();

addNum();

// 결과는 2일 것 같지만 0이 반환


같은 이름의 전역변수를 선언하였기 때문에 결과는 2가 아닌 0이 됩니다. 

그럼 함수의 반환값을 사용해 전역변수를 사용하지 않는 접근 방법을 확인해보겠습니다.

샘플5


function addNum() {

   let cnt = 0;

   cnt += 1;

   return cnt;

}

addNum();

addNum();

// cnt는 2가 되어야 하지만 결과는 1이 반환


함수 내부에 선언한 지역변수는 함수 호출 시마다 리셋되므로 의도한대로 작동하지 않습니다.

자바스크립트는 이 문제를 내부 함수(inner function)를 사용해 해결합니다.

자바스크립트의 중첩 함수(Nested function)

모든 함수는 전역 스코프에 접근할 수 있습니다. 

그리고 자바스크립트의 모든 함수는 자신을 감싸고 있는 부모 스코프에 접근이 가능합니다. 

자바스크립트는 중첩 함수를 지원하며, 중첩 함수 역시 자신을 감싸고 있는 부모 스코프에 접근이 가능합니다.

아래 샘플을 확인해보면 내부함수 plus()는 부모 함수에 있는 cnt 변수에 접근이 가능합니다.

샘플6


function addNum() {

   let cnt = 0;

   function plus() {

      cnt += 1;

   }

   plus();  

   return cnt;

}


cnt = 0을 한번만 선언할 방법과 plus() 함수에 접근할 수 있는 방법을 찾으면 위에서 확인한 숫자 카운팅의 딜레마 문제를 해결할 수 있습니다.

여기서 우리는 클로저를 사용할 수 있습니다.

클로저를 확인하기 전에 먼저 즉시실행함수(IIFE, Immediately Invoked Function Expressions)에 대해 간략히 알아보겠습니다.

즉시실행함수는 호출없이 자동으로 실행되는 함수로, 함수를 괄호로 묶고 반드시 끝에 ()를 붙여야 합니다.

아래는 즉시실행함수의 표현식 샘플입니다.

샘플7


(function() {

  let abc = “self-invoking”;

})();


그럼 이제 클로저를 확인해보겠습니다.

Austria(2013)

자바스크립트 클로저(Closure)

클로저는 즉시실행함수를 이용합니다.

샘플8


const addNum = (function() {

   let cnt = 0;

   return function() {

   cnt += 1

   return cnt;

   })();

addNum();

addNum();

// 결과:2


addNum 변수에는 즉시실행함수의 반환값이 할당됩니다. 

즉시실행함수는 한번만 실행되며, cnt를 0으로 선언한 후 함수 표현식을 반환합니다.

이를 통해 addNum은 함수가 되며, 부모 스코프가 종료되어도 부모 스코프에 존재하는 cnt 변수에 접근이 가능하게 됩니다.

이것이 바로 자바스크립트의 클로저입니다. 클로저는 이와 같이 함수에서 상태 유지가 가능한 개별적인 변수들을 갖도록 합니다. 

cnt는 익명함수의 스코프에 의해 보호받으며, 오직 addNum 함수만을 사용해 접근이 가능합니다.


클로저는 부모 함수가 종료된 후에도 부모 스코프의 변수에 접근이 가능한 함수로, 특정 함수만 변수에 접근할 수 있도록 하기 위한 안전 장치라고 보면 됩니다. 
참고로 클로저로 접근하는 변수와 부모 스코프에 존재했던 변수는 완전히 같은 공간을 참조하는 것은 아니고 각각 독립적인 객체입니다.


참고자료 https://www.w3schools.com/js/js_function_closures.asp

새로운 시작

좋은 계기를 통해 블로그를 시작하게 되었습니다.

공부하는 것과 느끼는 것 그리고 다양한 관심사에 대한 정보를 공유하도록 하겠습니다.

Budapest(2013)