구조 분해 할당

Happhee·2022년 4월 22일
1

AvenJS

목록 보기
6/17
post-thumbnail

개발을 하다 보면 객체나 배열에 저장된 데이터 전체가 아닌 일부만 필요한 경우가 생긴다.
이를 위해서 자바스크립트에서 가장 유용하고, 많이 쓰이는 문법이 구조 분해 할당이다.

지금부터 구조 분해 할당을 알아보고, 사용법을 익혀보자.


✨ Destructing Assignment

객체나 배열을 변수로 분해할 수 있게 해주는 문법이 바로 구조 분해 할당(Destructuring Assignment)이다.

구조 분해 할당이라고 해서 특별하게 문법적 형태가 다른 것은 아니다.
기존 변수 할당 방식처럼 왼쪽에는 변수 이름을 오른쪽에는 분해할 대상을 대입하는 형식으로 작성한다.

예제로 적용시켜보자


✨ 배열 분해하기

  • 배열 할당과 동시에 구조 분해 할당을 진행한다.
let [ first, second, third ] = [ 'orange', 'apple', 'strawberry' ];

console.log(first);		// orange
console.log(second);	// apple
console.log(third);		// strawberry
  • 미리 배열을 저장하고, 여기서 구조 분해 할당을 진행한다.
let fruits = [ 'orange', 'apple', 'strawberry' ];
let [ first, second, third ] = fruits;

console.log(first);		// orange
console.log(second);	// apple
console.log(third);		// strawberry
  • ... 문법을 사용하여 구조 분해 할당을 진행한다.
let fruits = [ 'orange', 'apple', 'strawberry' ];
let [ first, ...rest ] = fruits;

console.log(rest);		// [ 'apple', 'strawberry' ];

위의 형태와 기능은 Rest 파라미터에서도 대응되고, 남은 인수를 묶어서 배열로 반환 받았다.
즉, 구조 분해 할당에서는 first에는 'orange'가 대입되고, 나머지를 ...rest로 받아서 [ 'apple', 'strawberry' ]와 같이 rest 변수에 배열로 할당한다.

Rest 파라미터

... 문법의 역할이 Rest일 때, 파라미터에서 쓰이면 Rest 파라미터라고 하고, 배열의 구조 분해 할당에 쓰이면 Rest elements가 된다.

  • 쉼표를 사용하여 요소를 무시한다.
let fruits = [ 'orange', 'apple', 'strawberry' ];
let [ , , third ] = fruits;

console.log(third);		// strawberry

첫 번째와 두 번째 요소는 생략되었지만, 세 번째 요소를 third에 할당된다.

  • 할당 연산자 우측에는 모든 iterable이 올 수 있다.
let fruit = "orange";
let [ alphabet1, alphabet2, alphabet3 ] = fruit;

console.log(alphabet1);		// o
console.log(alphabet2);		// r
console.log(alphabet3);		// a

let [ first, second, third ] =  new Set([ 'orange', 'apple', 'strawberry' ]);
console.log(first);		// orange
console.log(second);	// apple
console.log(third);		// strawberry

fruit이라는 문자열에 대해 구조 분해 할당을 진행하면, 문자열을 구성하는 문자들을 순서대로 변수에 할당 할 수 있다. 또한, Set이라는 iterable 반복 가능한 객체에 구조 분해 할당을 진행하는 것도 가능하다.

  • 할당 연산자 좌측에는 어떤 것도 가능하다.
let dancer = {};
[ dancer.name , dancer.age ] = "seohee 24".split(' ');

console.log(dancer);

심지어는 객체 프로퍼티를 추가하는 것도 가능하다.

  • .entries( )로 순회하면서 변수로 분해 할당을 진행한다.
let dancer = {
  name : "seohee",
  age : 24,
  favoriteSong : "살짝 설렜어"
};
for( const [ key, value ] of Object.entries(dancer)){
  console.log(`${key} 👉 ${value}`);
}

Object.entries(obj)를 진행하면 배열을 반환받게 되고, 이에 대해 for ... of를 진행할 때 key, value를 할당받는 방식으로 구조 분해 할당을 진행한다.

결과는 아래와 같다.

  • 변수의 교환도 가능하다.
let fruit1 = "orange";
let fruit2 = "apple";

[ fruit1, fruit2 ] = [ fruit2, fruit1 ];

console.log(`fruit1 👉 ${fruit1}`);
console.log(`fruit2 👉 ${fruit2}`);

  • 기본값을 설정한다.
let [ name = "SEOHEE", age = 12, favoriteSong = "살짝 설렜어" ]  = [ "seohee", 24 ];

console.log(name);			// "seohee"
console.log(age);			// 24
console.log(favoriteSong);	// "살짝 설렜어"

할당할 값이 없을 때는 favoriteSong처럼 기본값을 가져온다.


✨ 객체 분해하기

배열의 분해 대상이 array의 value(element)인 반면, 객체의 분해 대상은 객체의 property이다.

let { let1, let2 } = { let1: ..., let2: ...}
  • 할당 연산자 우측에 분해하고자 하는 객체를 넣고, 좌측에는 객체에 상응하는 객체 프로퍼티의 패턴을 넣어준다.
let dancer = {
  name : "seohee",
  age : 24,
  favoriteSong : "살짝 설렜어"
};
let { name, favoriteSong, age } = dancer;

console.log(name);			// "seohee"
console.log(age);			// 24
console.log(favoriteSong);	// "살짝 설렜어"

키 목록에 있다면, 순서에 상관없이 구조 분해 할당이 진행됨을 알 수 있다.

  • 객체 프로퍼티를 프로퍼티 키와 다른 이름을 가진 변수로도 저장이 가능하다.
let { name : NAME, favoriteSong : SONG, age : AGE } = dancer;

console.log(NAME);			// "seohee"
console.log(AGE);			// 24
console.log(SONG);	// "살짝 설렜어"
  • 프로퍼티가 없는 경우를 대비하여 =을 사용해 기본값을 설정한다.
let { name : NAME, favoriteSong : SONG, practiceTime = "24hr" } = dancer;

console.log(NAME);			// "seohee"
console.log(SONG);			// "살짝 설렜어"
console.log(practiceTime);	// "24hr"

dancer라는 객체에 practiceTime이라는 프로퍼티 키 값은 존재하지 않는다. 때문에 기본값으로 지정된 값을 해당 변수에 할당한다.

  • ... rest도 사용이 가능하다.
let { name : NAME, ...rest } = dancer;

console.log(NAME);			
console.log(rest);			

name 프로퍼티 이후에 선언된 나머지 프로퍼티들을 rest에 할당하게 된다.

❗️ let 없이 사용하는 객체 구조 분해 할당은 불가능하다 ❗️

let name, age, favoriteSong;
{ name, age, favoriteSong } = dancer;

Uncaught SyntaxError: Unexpected token '='이라는 오류를 나타낸다.
왜냐하면, 자바스크립트는 { } 중괄호에 대해 코드 블록 인식을 진행하기 때문이다.
따라서 이를 해결하기 위해서는 ( ) 괄호로 코드 블록을 감싸 자바스크립트가 코드 블록이 아닌 표현식으로 해석하도록 유도 해야 한다.

let name, age, favoriteSong;
({ name, age, favoriteSong } = dancer);

✨ 중첩 구조 분해

객체나 배열이 다른 객체나 배열을 포함하는 경우, 중첩 구조 분해를 진행해야 한다.

👇 예제 코드를 살펴보자.

let group = {
  artist : {
    name : "IVE",
    age : 19
  },
  title : "LOVE DIVE",
  members : [ "name1", "name2", "name3", "name4", "name5", "name6" ]
};

let { artist : { name, age }, title = "ELEVEN",  members : [ member1, member2, , member4, ...rest ] } = group;

console.log(`artist 👉 ${name} , ${age}`);
console.log(`title 👉 ${title}`);
console.log(`members 👉 ${member1} , ${member2}, ${member4}, ${rest}`);

group안에 있는 artist 객체의 프로퍼티 name,age를 가져오고, group의 프로퍼티 title을 할당 한 뒤,
members 배열의 값을 콤마와 ...으로 구분하여 중첩 구조 분해를 실행하였다.


✨ 똑똑한 함수 매개변수

함수에 매개변수가 많은 경우, 선택적으로 쓰이는 경우가 발생한다.

👇 함수를 호출할 때 필요한 매개변수를 4개로 가지는 showDance라는 함수를 작성했다.

function showDance(agency = "Untitled", artist = "Unknown", performanceTime = 0, songs= []) {
  console.log(`소속사 👉 ${agency}`);
  console.log(`아티스트 👉 ${artist}`);
  console.log(`공연시간 👉 ${performanceTime}`);
  console.log(`공연할 곡 👉 ${songs}`);
}
  • 함수를 호출할 때 매개변수를 3개만 입력한 경우이다. 매개변수 순서대로 값이 할당되고, 비어있는 인자에는 아무런 값을 할당하지 않는 결과를 보였다.

  • 중간에 , 콤마로 빈 공간을 만들어 매개변수를 원하는 순서대로 전달한 경우이다.SyntaxError를 발생시키게 된다.
    따라서 비어있는 인자를 전달할 때는 undefined를 명시해주어야 한다.
    performanceTime의 초기값이 0이기 때문에 undefined로 할당한 변수에는 초기값을 할당시키고, 나머지에는 매개변수로 전달한 값을 할당한다.

💡 구조 분해를 사용하면 가독성이 높아진다

// 함수에 전달할 객체
let danceInfo = {
  agency: "Starship",
  artist : "IVE",
  songs: ["ELEVEN", "LOVE DIVE"]
};

function showDance({agency = "Untitled", artist = "Unknown", performanceTime = 0, songs= []}) {
  console.log(`소속사 👉 ${agency}`);
  console.log(`아티스트 👉 ${artist}`);
  console.log(`공연시간 👉 ${performanceTime}`);
  console.log(`공연할 곡 👉 ${songs}`);
}
showDance(danceInfo);

위에서 작성한 함수에서 객체를 생성하는 중괄호 { } 방식으로 매개변수를 만들어주고, 원하는 전달 값을 가진 객체를 해당 함수의 매개변수로 넘겨주면 잘 작동한다.

  • 빈 객체를 넣게 되면 모든 매개변수에 초기값이 할당된다
    업로드중..

  • 하지만, 아무것도 전달하지 않으면 TypeError가 발생하게 된다.업로드중..

함수 매개변수를 구조 분해 할 때에는 반드시 인수가 전달된다고 가정하고 사용해야 한다.
즉, 모든 인수에 기본값을 할당하는 작업이 필요하다.

  • 중첩 객체와 콜론을 조합하여 복잡한 구조 분해도 가능하다.
let group = {
  artist : {
    name : "IVE",
    age : 19
  },
  title : "LOVE DIVE",
  members : [ "name1", "name2", "name3", "name4", "name5", "name6" ]
};

function showDance({
  artist : { name, age }, 
  title = "ELEVEN", 
  members:  [ member1, member2, , member4, ...rest ] 
}) {
  console.log(`artist 👉 ${name} , ${age}`);
  console.log(`title 👉 ${title}`);
  console.log(`members 👉 ${member1} , ${member2}, ${member4}, ${rest}`);
}

showDance(group);

업로드중..


🌈 결론

구조 분해 할당을 사용하면 객체나 배열을 변수로 쉽게 만들 수 있다는 장점이 있다. 하지만, 원하는 요소를 변수로 만들기 위해 순서나 값이 비어있는 경우 등등을 생각하며 코드를 작성해야 한다.


📚 학습할 때, 참고한 자료 📚

profile
즐기면서 정확하게 나아가는 웹프론트엔드 개발자 https://happhee-dev.tistory.com/ 로 이전하였습니다

0개의 댓글