내일배움캠프에서 Node.js 주특기 입문 강의를 수강하고 개인 과제로 기본적인 CRUD API를 구현하던 중이었다. 계속해서 오류가 나는데, 전부 request로 받은 데이터들을 서버에서 변수에 할당할 때 잘못 할당하게 되어서 나타난 오류들이었다. 늦은 시간이었어서 졸리다보니 집중이 잘 안된 탓도 있겠지만, 구조 분해 할당이 정확하게 어떤 문법인지 좀 더 실습을 통해서 익숙해져야겠다는 생각이 들었다.
기본개념에 대해서는 다음 링크를 참고하면 된다. 여기서는 특히 객체의 구조 분해 할당을 연습해보고 익숙해지려고 한다.
기본 개념 참고
구조 분해 할당의 경우 여러가지 상황과 경우가 있겠지만, 문법의 이름 자체가 그 목적과 일치한다고 생각된다. 자바스크립트에는 객체
나 배열
이 존재하는데, 그 객체
나 배열
을 변수로 분해해서 전체가 아닌 일부를 사용할 수 있게 해준다.
단축 속성명의 경우에는 코드를 좀 더 간단화해서 직관적으로 읽히게 만들고 곧 가독성을 높여 줄 수 있다.
어떤 식으로 사용되는지 간단하게 살펴보겠다.
let options = { title: "Menu", width: 100, height: 200 };
let {title, width, height} = options; // 구조분해할당 사용
console.log(title, width, height); // Menu 100 200
위 코드에서 used 구조 분해 할당
주석이 작성된 부분을 좀 더 분석해서 보자. // used 구조 분해 할당
이 작성된 부분의 코드의 의미는 다음과도 같다.
let {title, width, height} = { title: "Menu", width: 100, height: 200 }
console.log(title, width, height) // Menu 100 200
대입 연산자 =
의 오른쪽 객체에 있는 각 속성 값이 왼쪽 객체의 변수에 저장된 것을 알 수 있다. 나는 개인적으로 여기서 이상하다고 생각한 것이 왼쪽의 변수 선언부의 모양이었다.
{ }
로 감싸서 오른쪽의 객체와 전체 형식이 맞춰지므로 내부의 속성과 값 쌍들이 해당 위치의 변수에 할당된다는 것은 직관적으로 이해하기가 쉬웠지만, 좀 더 세밀하게 생각했을 때 아래 코드와 같이 되어야 하는 것이 아닌가?
생각한 것이다.
// 내 머릿속 어색했던 상황
let title = title: "menu"
let width = width: 100
let height = height: 200
게다가 사실 왼쪽의 선언부도(뭐 단순히 문법을 그렇게 정의했다면 할 말이 없겠지만) 객체의 형식을 가지고 있으면서 속성명과 값 중에 하나가 생략된 모양새를 가지고 있다.
사실 이 부분을 이해하려면 먼저 단축 속성명 (shorthand property names) 이라는 문법에 대해서 알고가는 것이 좋다. 왜냐하면 객체를 구조분해할당 할 때 사용되는 위의 1번째와 2번째 코드의 문법들은 단축 속성명이 사용된 것이기 때문이다.
단축 속성명은 객체를 정의 할 때 객체의 key
값과 value
의 값이 같으면, key
와 value
값을 각각 표기하지 않고 한 번만 표기하는 것을 의미한다. 자세한 설명은 위의 링크를 참고하면 좋다.
예시 코드를 통해 살펴보겠다.
let a = 123
let b = '원 투 쓰리'
let c = 'one two three'
let testArray = { a, b, c } // 단축 속성명 사용
console.log(testArray) // {a: 123, b: '원투쓰리', c: 'one two three'}
위 코드에서 단축 속성명 문법이 사용된 부분을 살펴보자. 만약 우리가 단축 속성명의 사용없이 객체 리터럴로 콘솔에 출력된 testArray
와 같은 객체를 만들려면 다음과 같이 코드를 짜야한다.
let testArray = { a: 123, b: '원 투 쓰리', c: 'one two three' }
하지만 단축 속성명 문법의 기능은 객체의 key
값과 value
의 값이 같으면, 한 번만 표기해서 속성명과 속성값을 정의할 수 있다는 것이다. 그래서 단축 속성명이 사용된 let testArray = {a, b, c}
부분을 풀어쓰자면 다음과 같다.
let testArray = { a: a, b: b, c: c }
위 객체에서 왼 쪽의 a, b, c
는 속성의 이름이고, 오른쪽의 a, b, c
는 값이 할당된 변수를 속성의 값으로 지정한 것이다. 그런데 둘이 같으니까 한 번 사용으로 둘 모두를 정의하는 것이 단축 속성명이다.
객체의 구조 분해 할당
에서는 단축 속성명이 기본적으로 사용되는 문법들이 예시로 나와서 이를 모르면 원활하게 이해가 가지 않는다. 물론 직관적으로는 알 수 있겠지만 쓰다보면 뭔가 어색함을 느끼게 된다(다른 사람들은 모르겠는데 나는 좀 많이 느껴진 것 같다)
객체를 구조 분해 할당 할 때, 주의할 점은 속성들을 분해해서 할당할 때, 할당하는 변수명은 반드시 속성명과 같아야 한다. 다르게 설정하면 할당되지 않는다. 사실 이것이 단축 속성명이 사용된 증거라고 생각한다. 다시 처음의 예제 코드로 돌아가서 생각해보자.
let options = { title: "Menu", width: 100, height: 200 };
let { title, width, height } = options;
console.log(title, width, height) // Menu 100 200
let { myTitle, myWidth, myHeight } = options;
console.log(title, width, height) // undefined undefined undefined
위 예제처럼 할당하려는 변수명을 options 객체의 속성명과 일치시키지 않으면 속성값들이 할당되지 않는다. 왜냐하면 변수를 선언한 객체 자체가 단축 속성명을 통해서 생성된 것이기 때문이다.
위 코드를 좀 더 풀어서 보면 다음과 같다.
// 가독성을 위해서 줄바꿈을 사용해서 표현했다.
let { title: title, width: width, height: height } =
{ title: "Menu", width: 100, height: 200 };
let { myTitle: myTitle, myWidth: myWidth, myHeight: myHeight } =
{ title: "Menu", width: 100, height: 200 };
만약에 단순히 속성명을 다르게 했을 때 할당되지 않는 것이 문법 오류라면 syntexError 등의 에러코드가 발생했겠지만 에러가 발생하지 않고 값이 undefined로 나타난다.
이렇게 되는 원리에 대해서는 위의 참고 링크들을 통해 살펴보면 알 수 있겠지만 아래에 한번 정리해본다.
구조 분해 할당
이 아니라 구조 변형 할당
이라고 불러야 하지 않을까?위의 사실을 통해서 다음과 같은 결론이 유추된다.
let options = { title: "Menu", width: 100, height: 200 }
let { title: myTitle, width: myWidth, height: myHeight } = options
console.log(title, width, height) // Uncaught ReferenceError
console.log(myTitle, myWidth, myHeight) // Menu 100 200
위 콘솔 출력의 결과를 보면 구조 분해 할당이 단축 속성명과 아울러서 어떤 식으로 작동되는지 어느정도 이해할 수 있다고 생각한다.