[JS] 구조분해 할당

학미새🐥·2023년 5월 5일
0

모던자스 정리

구조분해 할당은 함수에 객체나 배열의 일부만 전달해야할 때 이를 변수로 분해할 수 있게 해주는 특별한 문법이다.

배열 분해하기

// 이름과 성을 요소로 가진 배열
let arr = ["Bora", "Lee"]

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

위와 같은 방법이 배열을 변수로 분해한 과정이다.
이렇게 구조분해할당을 하면 각 요소에 arr[0], arr[1] 처럼 인덱스로 접근하지 않고도 사용할 수 있다.

이 방법을 통해 각 배열의 요소를 변수에 할당하는 코드의 길이를 줄일 수 있다.

쉼표를 사용하면 특정 요소를 버리고 나머지 요소만 변수로 분해할 수 있다.

let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];
alert( title ); // Consul

위와 같인 코드에서는 두번째 요소를 할당할 변수가 비어있기 때문에, Caesar는 버려지고 Julius와 Consul만 각각의 변수에 담기게 된다.

이런 구조분해할당은 모든 iterable에서 가능하다.
즉, 배열이 아닌 문자열도 구조 분해가 가능하다.

let [a, b, c] = "abc"; // ["a", "b", "c"]
let [one, two, three] = new Set([1, 2, 3]);

또한 할당 연산자의 좌측에도 일반 변수로 구성된 배열 뿐만 아니라 할당 가능한 모든 것이 올 수 있다.
예를들어 아래와 같이 객체의 값에도 구조 분해 할당이 가능하다.

let user = {};
[user.name, user.surname] = "Bora Lee".split(' ');

alert(user.name); // Bora

.entries()

.entries() 를 사용해서 key와 value를 한번에 입력하여 객체의 키와 값을 순회할 수 있다.

let user = {
  name: "John",
  age: 30
};

// 객체의 키와 값 순회하기
for (let [key, value] of Object.entries(user)) {
  alert(`${key}:${value}`); // name:John, age:30이 차례대로 출력
}

변수 교환 트릭

두 변수에 저장된 값을 SWAP하고자 할 때 원래는 임시 변수를 만들어서 3번의 대입연산을 통해 SWAP 할 수 있었다.
하지만 구조 분해 할당을 사용하면 한줄로 매우 쉽게 SWAP이 가능하다.

let guest = "Jane";
let admin = "Pete";

// 변수 guest엔 Pete, 변수 admin엔 Jane이 저장되도록 값을 교환함
[guest, admin] = [admin, guest];

alert(`${guest} ${admin}`); // Pete Jane

...

구조 분해 할당은 모두 각각의 요소로 분해하는 것이 아니라, 일부는 요소로, 나머지는 하나의 배열로 묶어서 구조 분해 할당을 할 수도 있다.
그럴 땐, 추출하고 싶은 요소는 각각의 변수명을 붙여주고, 한데 묶을 나머지는 ...arr 를 통해 arr라는 하나의 배열로 묶어줄 수 있다.

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
  • 구조분해할 때, 만약 변수에 할당해줄 배열의 요소가 없다면 에러는 발생하지 않고 undefined로 취급된다.
  • 만약 undefined가 아닌 기본값을 설정해주고 싶다면 = 를 사용하자
// 기본값
let [name = "Guest", surname = "Anonymous"] = ["Julius"];

alert(name);    // Julius (배열에서 받아온 값)
alert(surname); // Anonymous (기본값)

객체 분해하기

  • 배열 뿐만 아니라 객체도 구조 분해 할당이 가능하다.
  • 형태 : let {var1, var2} = {var1:…, var2:…}
    위와 같이 객체를 구조분해 할당하면 각각의 변수명과 같은 키 값에 해당되는 값이 변수에 할당된다.
let options = {
  title: "Menu",
  width: 100,
  height: 200
};

let {title, width, height} = options;	// 이때 title,width,height의 순서는 상관없다

alert(title);  // Menu
alert(width);  // 100
alert(height); // 200

만약 키와 다른 이름을 가진 변수에 저장하고 싶다면, 다음과 같은 형태를 사용한다.
let {키 명1: 원하는 변수명1, 키 명2: 원하는 변수명2, 키 명3} = 객체;

  • 배열과 같이 할당연산자를 통해 기본값을 설정하는 것도 가능하다.
let options = {
  title: "Menu"
};

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

alert(title);  // Menu
alert(width);  // 100
alert(height); // 200
  • 객체에서도 배열과 동일하게 ...를 사용하여 나머지 프로퍼티를 묶는 것이 가능하다.
let options = {
  title: "Menu",
  height: 200,
  width: 100
};

// title = 이름이 title인 프로퍼티
// rest = 나머지 프로퍼티들
let {title, ...rest} = options;

// title엔 "Menu", rest엔 {height: 200, width: 100}이 할당됩니다.
alert(rest.height);  // 200
alert(rest.width);   // 100

중첩 구조 분해

  • 객체나 배열 내부에 또다른 객체나 배열이 포함되어있을 수 있다.
  • 이럴 때 중첩된 데이터의 정보를 추출하는 것을 중첩 구조 분해 라고 한다.
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

똑똑한 함수 매개변수

  • 함수의 매개변수가 많아지면 가독성이 떨어지고 순서가 틀리면 오류가 발생하게 된다.
  • 이럴 땐, 매개변수를 하나의 객체로 모아 함수로 전달하고,
  • 전달받은 함수에서 이를 분해해서 사용하면 편리하다.
// 함수에 전달할 객체
let options = {
  title: "My menu",
  items: ["Item1", "Item2"]
};

// 똑똑한 함수는 전달받은 객체를 분해해 변수에 즉시 할당함
function showMenu({title = "Untitled", width = 200, height = 100, items = []}) {
  // title, items – 객체 options에서 가져옴
  // width, height – 기본값
  alert( `${title} ${width} ${height}` ); // My Menu 200 100
  alert( items ); // Item1, Item2
}

showMenu(options);
  • React에서 컴포넌트의 인수가 {}로 감싸져있는 것이 바로 이 구조 분해 할당 때문이었던 것이다.
profile
뭐든 다해보려는 공대생입니다

0개의 댓글