객체와 배열은 자바스크립트에서 가장 많이 쓰이는 자료 구조입니다.
함수에 객체나 배열을 전달해야 하는 경우가 생기곤 합니다. 가끔은 객체나 배열에 저장된 데이터 전체가 아닌 일부만 필요한 경우가 있습니다.
이럴 때 객체나 배열을 변수로 '분해' 하는 특별한 문법인 구조 분해 할당 (destructiong assignment)을 사용 할 수 있습니다.
이 외에도 함수의 매개변수가 많거나 매개변수 기본값이 필요한 경우 등에서 구조 분해는 그 진가를 발휘합니다.
배열 분해하기
// 이름과 성을 요소로 가진 배열
let arr = ["sewon", "jang"];
// 구조 분해 할당을 이용해 firstName엔 arr[0]을, surName엔 arr[1]을 할당하였습니다.
let [firstName, surName] = arr;
console.log(firstName); // sewon
console.log(surName); //jang
이제 인덱스를 이용해 배열에 접근하지 않고도 변수로 이름과 성을 사용할 수 있게 되었습니다.
아래 예시처럼 split 같은 반환 값이 배열인 메서드를 함께 활용해도 좋습니다.
- 구조 분해 할당이란 명칭은 어떤 것을 복사한 이후에 변수로 '분해'해준다는 의미 때문에 붙여졌습니다.
이 과정에서 분해 대상은 수정 또는 파괴되지 않습니다.
배열의 요소를 직접 변수에 할당하는 것보다 코드 양이 줄어든다는 점만 다릅니다.
쉼표를 사용하면 필요하지 않은 배열 요소를 버릴 수 있습니다.두 번째 요소는 생략되었지만, 세 번째 요소는 title이라는 변수에 할당된 것을 확인할 수 있습니다. 할당된 변수가 없기 때문에 네 번째 요소 역시 생략되었습니다.// let [firstName, surName] = arr; let firstName = arr[0]; let surName = arr[1];
할당 연산자 우측엔 모든 이터러블이 올 수 있습니다.// 두 번째 요소는 필요하지 않음. let [firstName, ,title] = ["aa","bb","cc","dd"]; console.log(title); // cc
배열뿐만 아니라 모든 이터러블(iterable, 반복 가능한 객체)에 구조 분해 할당을 적용할 수 있습니다.
두 변수에 저장된 값을 교환할 때 구조 분해 할당을 사용할 수 있습니다.let [a,b,c] = "abc"; // ["a","b","c"] let [one, two, three] = new Set([1,2,3]);
let guest = "Jane"; let admin = "Peter"; // 변수 guest엔 Peter, 변수 admin엔 Jane이 저장되도록 값을 교환함 [guest,admin] = [admin,guest]; console.log(`${guest} ${admin}`);
'...'로 나머지 요소 가져오기
배열 앞쪽에 위치한 값 몇 개만 필요하고 그 이후 이어지는 나머지 값들은 한데 모아서 저장하고 싶을 때가 있습니다.
이럴 때는 점 세 개 ...를 붙인 매개변수 하나를 추가하면 '나머지(rest)' 요소를 가져올 수 있습니다.
let [name1, name2, ...rest] = ["aa","bb","cc","dd"];
console.log(name1); // aa
console.log(name2); // bb
//'rest'는 배열입니다.
console.log(rest[0]); // cc
console.log(rest[1]); // dd
console.log(rest.length); //2
rest는 나머지 배열 요소들이 저장된 새로운 배열이 됩니다. rest 대신에 다른 이름을 사용해도 되는데, 변수 앞의 점 세 개(...)와 변수가 가장 마지막에 위치해야 한다는 점은 지켜줘야 합니다.
기본값
할당하고자 하는 변수의 개수가 분해하고자 하는 배열의 길이보다 크더라도 에러가 발생하지 않습니다.
할당할 값이 없으면 undefined로 취급되기 때문입니다.
let [firstName, surName] = [];
console.log(firstName); //undefined
console.log(surName); //undefined
=을 이용하면 할당할 값이 없을 때 기본으로 할당해 줄 값인 '기본 값(default value)'을 설정할 수 있습니다.
let [name="Guest", surName="anonymous"] = ["Julius"];
console.log(name); // Julius (배열에서 받아온 값)
console.log(surName); //anonymous (기본 값)
복잡한 표현식이나 함수 호출도 기본값이 될 수 있습니다. 이렇게 기본식으로 표현식이나 함수를 설정하면 할당할 값이 없을 때 표현식이 평가되거나 함수가 호출됩니다.
// name의 prompt만 실행됨
let [surName = prompt('성을 입력하세요.'), name = prompt('이름을 입력하세요.')] = ["김"];
console.log(surName); //김
console.log(name); //prompt에서 받아온 값
객체 분해하기
구조 분해 할당으로 객체도 분해할 수 있습니다.
기본 문법은 다음과 같습니다.
let {var1, var2} = {var1:..., var2:...}
할당 연산자 우측엔 분해하고자 하는 객체를, 좌측엔 상응하는 객체 프로퍼티인 "패턴"을 넣습니다. 분해하려는 객체 프로퍼티의 키 목록으로 패턴을 사용하는 예시를 살펴봅시다.
let option = { title : "title!!", width:100, height:100};
let {title, width, height} = option;
console.log(title); // title!!
console.log(width); // 100
console.log(height); //100
프로퍼티 options.title, options.width, options.height에 저장된 값이 상응하는 변수에 할당된 것을 확인할 수 있습니다.,
순서는 중요하지 않습니다.
할당 연산자 좌측엔 좀 더 복잡한 패턴이 올 수 있습니다. 분해하려는 객체의 프로퍼티와 변수의 연결을 원하는 대로 조정할 수도 있습니다.
좌측 패턴에 콜론( : ) 을 사용하면 다른 이름을 가진 변수에 저장할 수 있습니다.
let option = { title : "title!!", width:100, height:100};
let {title, width:w, height:h} = option;
console.log(title); // title!!
console.log(w); // 100
console.log(h); //100
콜론은 '분해하려는 객체의 프로퍼티 : 목표변수'와 같은 형태로 사용합니다.
프로퍼티가 없는 경우를 대비해서 =를 사용해 기본값을 설정하는 것도 가능합니다.
let option = { title : "title!!"};
let {title, width=100, height=200} = option;
console.log(title); // title!!
console.log(width); // 100
console.log(height); // 200
( ...으로 나머지 요소 가져오기, 기본값은 배열과 같습니다.)
중첩 구조 분해
객체나 배열이 다른 객체나 배열을 포함하는 경우, 좀 더 복잡한 패턴을 사용하면 중첩 배열이나 객체의 정보를 추출할 수 있습니다. 이를 중첩 구조 분해 ( nested desctructuring )라고 부릅니다.
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 전용 변수는 없다는 점에 유의해야 합니다.
똑똑한 함수 매개변수
함수에 매개변수가 많은데 이 중 상당수는 선택적으로 쓰이는 경우가 종종 있습니다.
사용자 인터페이스와 연관된 함수에서 이런 상황을 자주 볼 수 있습니다.
let options = {
title: "My menu",
items: ["Item1", "Item2"]
};
// 기본값을 사용해도 괜찮은 경우 아래와 같이 undefined를 여러 개 넘겨줘야 합니다.
//showMenu("My Menu", undefined, undefined, ["Item1", "Item2"])
// 매개변수가 많아질수록 가독성은 점점 떨어진다. 이것을 구조 분해로 리팩토링을 하면 가독성 좋은 코드가 완성 될 수 있다.
// 중첩 객체와 콜론을 조합하면 좀 더 복잡한 구조 분해도 가능하다.
function showMenu({
title = "Untitled",
width: w = 100, // width는 w에,
height: h = 200, // height는 h에,
items: [item1, item2] // items의 첫 번째 요소는 item1에, 두 번째 요소는 item2에 할당함
}) {
alert( `${title} ${w} ${h}` ); // My Menu 100 200
alert( item1 ); // Item1
alert( item2 ); // Item2
}
showMenu(options);
함수 매개변수를 구조 분해할 땐, 반드시 인수가 전달된다고 가정하고 사용된다는 점에 유의해야 합니다.
모든 인수에 기본값을 할당해 주려면 빈 객체를 명시적으로 전달해야 합니다.
showMenu({}); // 모든 인수에 기본값이 할당됩니다.
showMenu(); // 에러가 발생할 수 있습니다.
// 이 문제를 예방하려면 빈 객체 {}를 인수 전체의 기본 값으로 만들면 됩니다.
function showMenu({ title = "Menu", width = 100, height = 200 } = {}) {
alert( `${title} ${width} ${height}` );
}
showMenu(); // Menu 100 200
이렇게 인수 객체의 기본값을 빈 객체 {} 로 설정하면 어떤 경우든 분해할 것이 생겨서 함수에 인수를 하나도 전달하지 않아도 에러가 발생하지 않습니다.
요약
- 구조 분해 할당을 사용하면 객체나 배열을 변수로 연결할 수 있습니다.
- 객체 분해하기:object의 프로퍼티 prop의 값은 변수 varName에 할당되는데, object에 prop이 없으면 default가 varName에 할당됩니다.
- 연결할 변수가 없는 나머지 프로퍼티들은 객체 rest에 복사됩니다.
let {prop : varName = default, ...rest} = object
- 배열 분해하기:array의 첫 번째 요소는 item1에, 두 번째 요소는 변수 item2에 할당되고, 이어지는 나머지 요소들은 배열 rest 저장됩니다.
let [item1 = default, item2, ...rest] = array
- 할당 연산자 좌측의 패턴과 우측의 구조가 같으면 중첩 배열이나 객체가 있는 복잡한 구조에서도 원하는 데이터를 뽑아낼 수 있습니다.
출처 : https://ko.javascript.info/destructuring-assignment
'javascript' 카테고리의 다른 글
[Javascript] label(레이블) 구문 (0) | 2022.01.11 |
---|---|
[Javascript] JSON stringify 사용법, parse 사용법(JSON과 메서드) (0) | 2022.01.10 |
[javascript] 화살표 함수 (()=>, Arrow Function) (0) | 2022.01.09 |
[javascript] Symbol (0) | 2022.01.08 |
[javascript] 옵셔널 체이닝 '?.' (0) | 2022.01.07 |
댓글