javascript

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

sewonzzang123 2022. 1. 10.
반응형

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

 

 

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

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

 

이럴 때 객체나 배열을 변수로 '분해' 하는 특별한 문법인 구조 분해 할당 (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

 

반응형

댓글