본문 바로가기
JavaScript

구조 분해 할당

by oncerun 2021. 10. 23.
반응형

 

개발을 하다 보면 함수에 객체나 배열을 전달해야 하는 경우가 존재합니다. 이때 객체나 배열에 저장된 데이터 전체가 아닌 일부만 필요한 경우가 생깁니다.

 

이럴 때 객체나 배열을 변수로 분해할 수 있게 해주는 특별한 문법인 구조 분해 할당(destructuring assigment)을 사용할 수 있습니다. 이 외에도 함수의 매개변수가 많거나 매개변수 기본값이 필요한 경우 등에서 구조 분해(destructuring)는 매우 매력적입니다.

 

 

배열 분해

let arr = [ 'sungil', 'yu'];

// 구조 분해 할당을 이용해,  firstName, subName에 arr[0], arr[1] 을 할당하였습니다.
let [ firstName, subName ] = arr;


let [firstName, subName] = 'Sungil Yu'.split(' ');


// 할당 연산자 우측엔 모든 이터러블이 올 수 있습니다.
let [a, b, c] = 'abc';

let [one, two, three] = new Set([1,2,3]);

 

Object.entries()는 연속적인 배열을 반환하는 객체의 for..in 열거 가능한 속성 [key, value]을 반환합니다.

 

이 메서드와 구조 분해를 조합하면 객체의 키와 값을 순회해 변수로 분해 할당할 수 있습니다.

 

 

 i  변수 교환 트릭

 

두 변수에 저장된 값을 교환할 때 temp 변수를 선언해 처리하는 것보다 더 멋진 방법을 사용할 수 있습니다.

let girl = 'hi i\'m girl';
let boy = 'hi i\'m boy';

[ girl, boy] =  [ boy, girl];

이 방법은  두 개뿐만 아니라 여러 개도 처리할 수 있음을 뜻합니다.

 

 

 

...로 가져오기

배열 앞쪽에 위치한 값 몇 개만 추출하고, 그 이후 나머지 값들은 한데 모아서 저장하고 싶을 때,...라는 매개변수 하나를 추가하면 rest 요소를 가져올 수 있습니다.

 

let [name1, name2, ...rest] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];

alert(name1); // Julius
alert(name2); // Caesar

// `rest`는 배열입니다.
alert(rest[0]); // Consul
alert(rest[1]); // of the Roman Republic
alert(rest.length); // 2

 * 변수 앞의 점 세 개와 변수가 가장 마지막에 위치해야 한다는 점은 약속이다.

 

 

default 값 할당

할당하고자 하는 변수의 개수가 분해하고자 하는 배열의 길이보다 크더라도 에러가 발생하지 않습니다.

할당할 값이 없는 경우 undefined로 취급되기 때문입니다. 

 

let [ a, b ] =[];

a , b // undefined

= 를 이용하면 할당할 값이 없을 때

let [ a = 'A', b = 'B' ] =[];

a  , b // A, B

default 값을 할당해줄 수 있습니다.  표현식이나, 함수 호출도 기본값이 될 수 있습니다. 

let [ a = prompt('a 값이 존재하지 않습니다.'), b = prompt('b 값이 존재하지 않습니다.') ] =[];

 

 

객체 분해

구조 분해 할당으로 객체도 분해할 수 있습니다.

 

할당 연산자 우측에는 분해하고자 하는 객체를 좌측엔 상응하는 객체 프로퍼티를 나열합니다.

 

let options = {
  title: "Menu",
  width: 100,
  height: 200
};

let {title, width, height} = options;

순서가 바뀌어도 정상적으로 동작합니다.

 

객체 프로퍼티를 프로퍼티 키와 다른 이름을 가진 변수에 저장할 수도 있습니다.

 

콜론(:)을 사용하여 객체의 프로퍼티 값을 다른 변수에 저장할 수 있습니다.

let options = {
  title: "Menu",
  width: 100,
  height: 200
};

// { 객체 프로퍼티: 목표 변수 }
let {width: w, height: h, title} = options;

// width -> w
// height -> h
// title -> title

alert(title);  // Menu
alert(w);      // 100
alert(h);      // 200

또한 콜론과 할당 연산자를 동시에 진행할 수도 있습니다. 

let options = {
  title: "Menu",
};

// { 객체 프로퍼티: 목표 변수 }
let {width: w = 100, height: h = 100, title} = options;

 

... 나머지 패턴

let person = {
	name : 'name',
	age : 13,
	phoneNo = '01034534323',
};


let {name, ...rest} = person;

rest.age // 13,
rest.phoneNo // 01034534323

분해하려는 객체의 프로퍼티 개수가 할당하려는 변수의 개수보다 많다면, rest pattern을 사용하여, 배열의 나머지 처리와 동일하게, 나머지 프로퍼티를 어딘가에 할당하는 게 가능합니다. 

참고사항은 모던 브라우저는 나머지 패턴을 지원하지만, IE를 비롯한 구식 브라우저는 나머지 패턴을 지원하지 않기 때문에, 바벨을 이용하여, 변환해야 합니다..

 

 

 i 할당자 let, const 없이 사용할 시 주의할 점

 

할당 연산을 통하여 분해한 값을 할당할 때 자바스크립트는 표현식 안에 있지 않으면서 주요 코드 흐름 상에 있는 {...}를 코드 블록으로 인식합니다.

 

따라서 할당 문을(...)로 감싸서 코드 블록이 아닌 표현식으로 해석하도록 해야 합니다.

let a, b, c;

({a, b, c} = { a: 1, b:2, c:3});

 

 

객체나 배열이 다른 객체나 배열을 포함하는 경우 좀 더 복잡한 패턴을 사용하면, 중첩 배열이나, 객체의 정보의 추출할 수 있습니다.

let options = {
  size: {
    width: 100,
    height: 200
  },
  items: ["Cake", "Donut"],
  extra: true
};

// 코드를 여러 줄에 걸쳐 작성해 의도하는 바를 명확히 드러냄
let {
  size: { // size는 여기,
    width,
    height
  },
  items: [item1, item2], // items는 여기에 할당함
  title = "Menu" // 분해하려는 객체에 title 프로퍼티가 없으므로 기본값을 사용함
} = options;

alert(title);  // Menu
alert(width);  // 100
alert(height); // 200
alert(item1);  // Cake
alert(item2);  // Donut

 

여기서 주목해야 할 점은 size와 items 전용 변수가 없다는 점을 유의해야 합니다.

 

 

함수 매개변수로써의 구조 분해 활용

다음과 같은 코드가 존재합니다.

function setConfig( title ='Untitled', width =200, height = 300, items = [] ) {
}

다음 함수는 매개변수로 동일한 자리에 값을 넣어야 하며, 기본값을 사용하기 위해서는 각 자리에 undefined를 넣어주어야 합니다.

 

구조 분해를 활용하면 다음과 같이 리팩터링 될 수 있습니다.

 

// 함수에 전달할 객체
let config = {
  title: "My menu",
  items: ["Item1", "Item2"]
};


function setConfig( {title ='Untitled', width =200, height = 300, items = []} ) {
}


setConfig(config);

title과 items의 값은 객체로부터 가져오며, width, height는 기본값을 사용하는 구조 분해를 이용한 코드입니다.

만약 모든 인수에 기본값을 할당해주려면 명시적으로 {} 빈객체를 전달해야 합니다.

 

반응형

'JavaScript' 카테고리의 다른 글

JavaScript Execution Context  (0) 2021.11.27
Number Property  (0) 2021.11.22
JS module  (0) 2021.10.23
Fetch API  (0) 2021.10.17
Fetch API Response  (0) 2021.10.16

댓글