javascript

[Javascript] ... 사용 방법 [구조 분해 할당 (배열, 객체 분해하기)]

sewonzzang123 2022. 1. 10.
반응형

 

 

객체와 배열은 자바스크립트에서 가장 많이 쓰이는 자료 구조입니다.

함수에 객체나 배열을 전달해야 하는 경우가 생기곤 합니다. 가끔은 객체나 배열에 저장된 데이터 전체가 아닌 일부만 필요한 경우가 있습니다.

 

이럴 때 객체나 배열을 변수로 '분해' 하는 특별한 문법인 구조 분해 할당 (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 같은 반환 값이 배열인 메서드를 함께 활용해도 좋습니다.

  • 구조 분해 할당이란 명칭은 어떤 것을 복사한 이후에 변수로 '분해'해준다는 의미 때문에 붙여졌습니다.
    이 과정에서 분해 대상은 수정 또는 파괴되지 않습니다.

    배열의 요소를 직접 변수에 할당하는 것보다 코드 양이 줄어든다는 점만 다릅니다.
    // let [firstName, surName] = arr;
    let firstName = arr[0];
    let surName = arr[1];​
    쉼표를 사용하면 필요하지 않은 배열 요소를 버릴 수 있습니다.두 번째 요소는 생략되었지만, 세 번째 요소는 title이라는 변수에 할당된 것을 확인할 수 있습니다. 할당된 변수가 없기 때문에 네 번째 요소 역시 생략되었습니다.
    // 두 번째 요소는 필요하지 않음.
    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

 

구조 분해 할당

 

ko.javascript.info

 

반응형

댓글