원래 한참 전에 정리했어야 하는 글인데, 친구가 구조분해할당을 사용하지 않고
개발하는 것을 보고 번뜩 생각나서 글을 막 급하게 작성하게 되었답니다.
계속 기술 블로그를 작성할 때 편하게 반말로 작성을 해보았으니,
글을 쓰는 연습도 할 겸 존댓말을 사용하며 구조분해할당에 대해 정리해볼까 합니다.
단순히 "특정 문법이다"라고 정의하기엔 범위와 사용도가 조금 많이 넓은
구조분해할당을, 어떻게 우리가 조미료처럼 사용할 수 있는지에 대해 다루어보겠습니다.
또한, 구조분해할당과 같이 사용되는 스프레드 연산자(전개 연산자)와,
객체에 값을 할당할 때 도움을 주는 ES6의 숨겨진 문법도 알아보겠습니다.
먼저, 구조분해할당이란 무엇일까요? 단어끼리 말을 뜯어보겠습니다.
구조, 분해, 할당. 구조를 분해한 다음, 다시 할당한다는 그런 뜻으로 짐작이 됩니다.
실제 기능과 똑같습니다. MDN의 말을 참고하여 구조분해할당을 설명해보겠습니다.
구조 분해 할당 구문은 배열이나 객체의 속성을 해체하여
그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.
먼저 위에서 설명한 것처럼, 배열이나 객체에 속해 있는 특정한 속성을
변수로 새로 선언하여 사용할 수 있게 하는 문법입니다.
이해가 되시나요? 더 쉽게 예시를 한번 들어보겠습니다.
const person = {
name: "Park ubin",
age: 18,
gender: "M"
}
다음과 같은 person이라는 객체가 있다고 생각해보겠습니다.
person에는 이름과 나이, 성별을 나타내는 세 가지의 속성이 존재합니다.
여기서 만약 제가, person의 name이라는 속성을
따로 변수로 사용하고 싶다면 어떻게 해야할까요?
const name = person.name;
console.log(name); // Park ubin
다음과 같이 선언하고 사용할 수 있겠죠?
그런데, 이를 더 명시적으로, 혹은 간단하게 사용할 수 있는 법은 없을까요?
정답부터 알려드리자면, 선언을 할 때 변수명 앞뒤로 중괄호를 감싸주면 됩니다.
const { name } = person;
console.log(name); // Park ubin
const { userName } = person;
console.log(userName); // undefined
다음 예제처럼 사용할 수 있겠네요. 두 번째 선언문은 잘못된 예시입니다.
중괄호를 통해 값을 대입하려면, 해당 객체에 있는 속성과 변수명이 같아야 합니다.
우리는 이를 구조분해할당이라고 부릅니다.
구조분해할당에 대해 이렇게 간단히 "중괄호를 사용하면 쓸 수 있다!"로만 알고 있다면
그렇게 알고 있던 개발자가 개발을 진행할 때 구조분해할당을 사용할 수 있다고
판단하는 상황이나 코드의 수들이 현저히 떨어집니다.
구조분해할당을 유연하게 사용하려면, 우리는 더 깊게 파고들어가 왜
중괄호를 사용해야 할당이 되는지에 대해서 알아보아야 합니다.
const { name } = person;
해당 코드를 조금 바꾸어 예시를 들어보겠습니다.
한 객체가 다른 한 객체에게 자신을 할당해주는 코드를 제시해보겠습니다.
let person1 = {
name: "park ubin",
age: 18
}
const person2 = {
name: "hong gil dong",
age: 24,
}
person1 = person2;
다음 코드는 단순히 객체와 객체간에 값을 대입해주는 코드입니다.
그런데 우리는, 이 객체를 선언하지 않고도 익명으로 사용할 수 있답니다.
바로 위에서 사용한 것과 같이, 객체를 여는 중괄호만 열어준다면, 소위 말하는
익명 객체(실제론 없는 용어입니다)를 사용할 수 있는 것이죠.
그렇다면 이 익명객체에서 할당받는 객체 중 자신이 받고 싶은 속성만 작성해준다면
그 속성만 골라서 변수로 선언 및 할당을 진행할 수 있답니다.
const { name, age } = person2;
지금가지 구조분해할당을 나름의 제 예시대로 설명해보았습니다.
오류가 있다면 피드백 환영합니다.
함수의 props가 객체라면, 이를 선언하는 단에서 구조분해할당을 진행할 수 있습니다.
props에 대한 자세한 정보를 지정하기 위해 간단한 타입스크립트 예제를 제시하겠습니다.
interface FunctionPropsType {
title: string;
content: string;
}
const postWrite = (props: FunctionPropsType) => {
const { title, content } = props;
console.log(title, content);
}
다음과 같은 함수가 있다고 가정하겠습니다. postWrite라는 함수의 첫 번째 줄에서,
구조분해할당을 사용해 title과 content라는 변수를 각각 선언 및 할당한 코드입니다.
이를 props를 받는 단에서 바로 할당하여 사용하는 법도 있습니다.
const postWrite = ({ title, content }: FunctionPropsType) => {
console.log(title, content);
}
어떤가요? 코드의 가독성도 줄어들고, props라는 이름의 객체가 아니라 함수가
title과 content라는 속성들을 props로 들고온다는 점도 더 명시적으로 알 수 있습니다.
이런 구조분해할당을 여러 곳에서 유용하게 사용한다면, 더욱 가독성이 좋고
명시적인 질 좋은 코드를 작성할 수 있습니다.
위에서 설명한 것처럼, 구조분해할당은 객체 뿐만이 아니라 배열을 사용할 때에도
이용할 수 있는 문법입니다. 이제 배열의 경우에 대해 알아보겠습니다.
구조분해할당의 본질은 똑같으나, 작동하는 방식이 조금 다릅니다.
이에 대해 코드와 함께 알아보겠습니다.
const ages = [12, 51, 23, 44, 17, 9];
const [age] = ages;
console.log(age); // 12
다음의 코드는 ages라는 나이들이 들어있는 배열에서 age라는 변수를
구조분해할당으로 선언하여 값을 가져오는 코드입니다.
배열에서의 구조분해할당은 객체와 다르게, 대괄호로 감싸 사용합니다.
보통 객체에서 사용할 때는 그 사이에 공백을 주지만, 배열에서는 주지 않습니다.
배열에서 구조분해할당을 사용하면, 배열의 인덱스 번호대로 값을 가져옵니다.
만약 저기서 age를 3개를 선언한다면, 차례대로 12, 51, 23이 할당될 것입니다.
const [age1, age2, age3] = ages;
console.log(age1, age2, age3); // 12 51 23
배열을 통한 구조분해할당은 객체의 구조분해할당보단 사용 범위가 좁은 면이 있습니다.
하지만 예를 들면, 어떤 라이브러리가 두 개의 값을 던져준다고 하는데,
첫 번째 값만 받아야 하거나 할 때 값을 받은 후 인덱스에 접근하는 방식이 아니라
구조분해할당을 통해서 유쾌한 코드를 만들어낼 수 있습니다.
다음과 같이 말이죠.
...
const res = [data, status];
const data = res[0];
/////////////////////////
const res = [data, status];
const [data] = res;
두 코드 중, 어떤 코드가 더 보기 좋나요?
저는 index에 접근하지 않고도 data라는 값을 가져오는 밑의 코드가 더 좋다고 생각합니다.
이제 객체와 배열, 둘 다 구조분해할당을 사용하는 방법을 알아보았으니,
이를 조금 더 유쾌하게 사용할 수 있게 도와주는 스프레드 연산자에 대해 알아보겠습니다.
스프레드 연산자는 "..."라는 키워드를 사용합니다. 코드의 남은 나머지들을
전부 가져오는 연산자이기도 합니다.
예시를 들어보겠습니다.
const post = {
title: "안녕하세요",
content: "반갑습니당",
author: "ubin"
}
const { title, ...postData } = post;
console.log(title); // 안녕하세요
console.log(postData); // {content: '반갑습니당', author: 'ubin'}
만약 내가 title만 따로 변수로 칭하고, postData라는 content와 author가 들어있는
다른 객체를 만들고 싶다면, 이런 식으로 ... 키워드를 통해 스프레드 연산자를
이용할 수 있습니다.
재미있는 점은, 스프레드 연산자를 사용하면 값을 전부 꺼내줍니다.
말그대로, 1번 객체 안에 또 2번 객체가 있는 상황이라면, 2번 객체가
스프레드 연산자를 사용했을 때 값이 객체가 아닌 속성으로 반환되는 것이죠.
말이 조금 어려울 수 있습니다. 코드를 통해 알아보겠습니다.
const name = "park ubin";
const school = {
schoolName: "Busan Software Meister High School",
location: "Busan",
established: 2021
}
const parkUbin = {
personName: name,
...school
}
console.log(parkUbin);
/**
{
personName: 'park ubin',
schoolName: 'Busan Software Meister High School',
location: 'Busan',
established: 2021
}
*/
이해가 되나요? 스프레드 연산자를 사용하지 않았을 경우엔 객체가 들어갑니다.
const wrongParkUbin = {
personName: name,
school
}
console.log(wrongParkubin);
/**
{
personName: 'park ubin',
school: {
schoolName: 'Busan Software Meister High School',
location: 'Busan',
established: 2021
}
}
*/
어떤 차이인지 이해가 되셨나요? 따라서 구조분해 할당과 스프레드 연산자를
잘 섞어 사용한다면 더욱 유쾌한 코드를 작성할 수 있을 겁니다.
배열로도 사용하는 방법은 똑같습니다.
배열에서 스프레드 연산자를 사용하면, 남은 배열들을 전부 리턴해줍니다.
const ages = [10, 18, 6, 52, 34, 28];
const [age1, age2, ...age3] = ages;
console.log(age1, age2, age3); // 10 18 [6, 52, 34, 28]
이 또한 배열 내에서 스프레드 연산자를 사용하면 속성들만 리턴됩니다.
const newAges = [20, ...ages];
console.log(newAges); // [20, 10, 18, 6, 52, 34, 28]
이제 조금 더 유쾌하게 구조분해할당을 사용할 수 있을 것 같습니다!
할당하려는 객체 속성의 이름과 변수명이 같다면 이름을 두 번 적지 않아도 됩니다.
코드를 보며 설명해보겠습니다.
const title = "안녕";
const postContent = "반가워";
const post = {
title,
contents: postContent
}
이해가 되시나요? 다음은 title:title과 같이 써주어야 작동하지만,
이름이 같은 변수끼리는 따로 콜론을 써주고 할당해주는 문법이 없더라도 자동으로
할당이 된답니다.
이를 아까 배운 구조분해할당과 합쳐서 사용한다면, 훨씬 깔끔하고 유쾌한 코드를
작성할 수 있을 것입니다.
구조분해할당에 대해서 깔끔히 정리를 해보았습니다.
처음으로 존댓말을 사용하며 글을 작성하니 여러가지 장단점이 있는 것 같네요.
개인적으로 구조분해할당은 자바스크립트만이 가지고 있는 마법이라고 생각합니다.
잘만 사용한다면 매우 유쾌하고 좋은 코드를 짤 수 있기 때문입니다.
이 글을 읽고 나서 객체를 사용할 때,
구조분해할당을 사용하면 더 좋은 코드가 되지 않을까 라는 생각이 가끔씩이라도
떠오르신다면 좋을 것 같습니다.
우리모두 화이팅!!
ㅘ ㅜ