구조분해할당
객체와 배열는 자바스크립트에서 가장 많이 쓰이는 자료구조이다. 키를 가진 데이터 여러 개를 하나의 엔티티에 저장할 땐 객체를, 컬렉션에 데이터를 순서대로 저장할 땐 배열을 사용한다.
개발을 하다 보면 함수에 객체 또는 배열을 전달해야 하는 경우가 생기는데 그 중 데이터 전체가 아닌 일부만 필요한 경우가 생기기도 한다.
이럴 때 객체나 배열을 변수로 '분해'할 수 있게 해주는 특별한 문법 구조인 구조 분해 할당(destructuring assignment)을 사용할 수 있다. 이 외에도 함수의 매개변수가 많거나 매개변수 기본값이 필요한 경우 등에서 구조분해는 그 진가를 발휘한다.
분해는 파괴를 의미하지 않는다. 어떤 것을 복사한 이후 변수로 분해하여 코드의 양이 줄어든다.
배열이 어떻게 변수로 분해될까?
// 이름과 성을 요소로 가진 배열
let arr = ["Bora", "Lee"]
// 구조 분해 할당을 이용해
// firstName엔 arr[0]을
// surname엔 arr[1]을 할당하였습니다.
let [firstName, surname] = arr;
alert(firstName); // Bora
인덱스를 이용해 배열에 접근하지 않고도 변수로 이름과 성을 사용할 수 있게 되었다.
아래 예시처럼 split 같은 반환 값이 배열인 메서드를 함께 활용해도 좋다.
let [firstName, surname] = "Bora Lee".split(' ');
객체 구조 분해
기본할당
ar o = {p: 42, q: true};
var {p, q} = o;
console.log(p); // 42
console.log(q); // true
선언 없는 할당: 구조 분해를 통해 변수의 선언과 분리하여 변수에 값을 할당할 수 있습니다.
var a, b;
({a, b} = {a: 1, b: 2});
참고: 할당 문을 둘러싼 (..)는 선언 없이 객체 리터럴 (object literal)비구조화 할당을 사용할 때 필요한 구문.
{a,b} = {a:1, b:2} 는 유효한 독립구문이 아니다. 좌변의 {a, b}이 객체 리터럴이 아닌 블록으로 간주되기 때문이다. 하지만
({a,b} = {a:1, b:2}) 는 유효한데, var {a, b} = {a:1, b:2} 와 같다. (..) 표현식 앞에는 세미콜론이 있어야 한다. 그렇지 않을 경우 이전 줄과 연결되어 함수를 실행하는데 이용될 수 있다.
새로운 변수 이름으로 할당하기
객체로부터 속성을 해체하여 객체의 원래 속성명과는 다른 이름의 변수에 할당할 수 있다.
var o = {p: 42, q: true};
var {p: foo, q: bar} = o;
console.log(foo); // 42
console.log(bar); // true
기본값
객체로부터 해체된 값이 undifined인 경우, 변수에 기본값을 할당할 수 있다.
var {a = 10, b = 5} = {a: 3};
console.log(a); // 3
console.log(b); // 5
기본값 갖는 새로운 이름의 변수에 할당하기
새로운 변수명 할당과 기본값 할당을 한번에 할 수 있다.
var {a: aa = 10, b: bb = 5} = {a: 3};
console.log(aa); // 3
console.log(bb); // 5
함수 매개변수의 기본값 설정하기
ES5 버전
function drawES5Chart(options) {
options = options === undefined ? {} : options;
var size = options.size === undefined ? 'big' : options.size;
var cords = options.cords === undefined ? { x: 0, y: 0 } : options.cords;
var radius = options.radius === undefined ? 25 : options.radius;
console.log(size, cords, radius);
// 이제 드디어 차트 그리기 수행
}
drawES5Chart({
cords: { x: 18, y: 30 },
radius: 30
});
ES2015 버전
function drawES2015Chart({size = 'big', cords = { x: 0, y: 0 }, radius = 25} = {}) {
console.log(size, cords, radius);
// 차트 그리기 수행
}
drawES2015Chart({
cords: { x: 18, y: 30 },
radius: 30
});
위 drawES2015Chart 함수의 원형에서 구조 분해된 자변에 빈 오브젝터 리터럴을 할당하는 것을 볼수 있다 {size = 'big', cords= {x: 0, y: 0}, radius =25} ={}. 빈 오브젝트를 우변에 할당하지 않고도 함수를 작성할 수 있다. 하지만, 지금의 형태에서는 단순히 drawES2015Chart() 와 같이 어떤 매개변수 없이도 호출할수 있지만, 우변의 빈 오브젝트 할당을 없앤다면 함수 호출시 적어도 하나의 인자가 제공되어야 한다.
중첩된 객체 및 배열의 구조분해
var metadata = {
title: "Scratchpad",
translations: [
{
locale: "de",
localization_tags: [ ],
last_edit: "2014-04-14T08:43:37",
url: "/de/docs/Tools/Scratchpad",
title: "JavaScript-Umgebung"
}
],
url: "/en-US/docs/Tools/Scratchpad"
};
var { title: englishTitle, translations: [{ title: localeTitle }] } = metadata;
console.log(englishTitle); // "Scratchpad"
console.log(localeTitle); // "JavaScript-Umgebung"
어떻게 title: englishTitle 이고 translations: [{title: localeTitle}] 인걸까?
for of 반복문과 구조 분해
var people = [
{
name: "Mike Smith",
family: {
mother: "Jane Smith",
father: "Harry Smith",
sister: "Samantha Smith"
},
age: 35
},
{
name: "Tom Jones",
family: {
mother: "Norah Jones",
father: "Richard Jones",
brother: "Howard Jones"
},
age: 25
}
];
for (var {name: n, family: { father: f } } of people) {
console.log("Name: " + n + ", Father: " + f);
}
// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"
이 예제는 user객체로부터 id, displayName 및 firstName을 해체해 출력합니다.
계산된 속성 이름과 구조 분해
계산된 속성 이름은, 객체 리터럴과 비슷하게 구조 분해에도 사용될 수 있습니다.
let key = "z";
let { [key]: foo } = { z: "bar" };
console.log(foo); // "bar"
객체 구조 분해에서 Rest
rest속성은 구조 분해 패턴으로 걸러지지 않은 열거형 속성의 키를 가진 나머지 항목들을 모은다.
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // { c: 30, d: 40 }
속성 이름이 유효한 JavaScript 식별자명이 아닌 경우
구조 분해는 JavaScript 식별자 이름으로 적합하지 않은 속성명이 제공된 경우에도 이용할 수 있다. 이 때는 대체할 유효한 식별자명을 제공해야한다. >> fizz-buzz는 왜 유효?
const foo = { 'fizz-buzz': true };
const { 'fizz-buzz': fizzBuzz } = foo;
console.log(fizzBuzz); // "true"
'Sparta x 이노베이션 캠프 > JavaScript' 카테고리의 다른 글
TIL) 논리 연산자 || OR (0) | 2022.08.30 |
---|---|
TIL : JavaScript 대괄호, 중괄호, 소괄호 사용 정리 (0) | 2022.08.25 |
TIL : JavaScript filter() (0) | 2022.08.20 |
WIL : JavaScript의 ES란?, ES5/ES6 문법 차이 - 2022.08.15 (0) | 2022.08.15 |
2주차: React 과제 - Javascript에 대한 이해 (0) | 2022.08.06 |