티스토리 뷰
JavsScript에서 물음표를 사용하는 사례가 몇 가지 있는데, 예를 들어 삼항연산자 / null 병합 연산자 등, 그 중에 하나가 바로 optional chainig 이다. 나는 사실 옵셔널 체이닝이라는 단어를 잘 몰라서 물음표 연산자라고만 생각했었는데, 이게 잘 사용하면 코드가 간결해지는 효과가 탁월한 것 같다.
예를들어 깊이 중첩된 오브젝트 내의 한 데이터에 접근한다고 하자. 그럼 다음과 같이 표현하는게 일반적인데,
let nestedProp = obj.first && obj.first.second;
이 뜻은 obj.first.second에 접근하기 전에 obj.first가 존재하는지 먼저 확인하라는 의미이다.
만약 다음과 같이 코드를 작성하게 된다면 obj.first가 없을 때, 에러를 발생시키게 된다.
let nestedProp = obj.first.second;
그럼 혹시 저 깊이 중첩의 중첩의 중첩이 된 데이터가 있다면 마냥 &&와 &&와 &&의 조합으로 검증을 해야할까? 이런 문제를 해결하기 위하여 사용되는 것이 optional Chaning이다. 옵셔널 체이닝은 다음과 같은 형식으로 사용하는데,
let nestedProp = obj.first?.second;
obj.first를 먼저 확인하고, null 혹은 undefined가 아닐 시, second의 데이터를 찾아 nestedProp 변수에 할당하라는 의미이다. obj.first가 null 혹은 undefined를 반환했을 때, 더이상 second가 존재하는지의 판단은 하지 않고 해당 값 (null || undefined)을 nestedProp에 반환시킨다.
참고로 이와 같이 우측의 데이터 존재 여부를 확인 하기 전에 undefined를 발현하고, 반환하는 현상을 '단락평가'라고 칭한다.
옵셔널 체이닝은 또한 함수에도 사용할 수 있는데, 다음과 같이 사용한다면
let result = someInterface.customMethod?.();
someInterface.customMethod 함수가 존재하지 않을 때, undefined를 반환하여 에러를 없앨 수 있다. 함수가 존재한다면 그대로 수행하여 결과값을 반환받을것이다.
하지만 someInterface 자체가 없다면 여전히 에러를 발생하게 될텐데, 상단과 같은 코드를 응용하여 다음과 같이 작성하면 간단하게 해결할 수 있다.
let result = someInterface?.customMethod?.();
이와 같은 방식으로 모든 것을 검증하면 상관은 없지만 개인적으로 옵셔널 체이닝 남발하는 것은 비추천한다. 미관상으로 모든 단어의 끝에 물음표가 붙게 된다면 오히려 더 지저분한 코드가 되기 때문이다. 그러니 옵셔널 체이닝은 꼭 존재하지 않아도 되는, 즉 있어도 없어도 되는 데이터의 존재를 확인할 때 사용하는 것이 좋을 것 같다.
MDN에서 좋은 예시가 하나 있어서 소개한다.
하단 코드에서 catch 부분을 보면 error가 캐치 되었고, onError가 파라미터로 넘어왔을 때, err.message를 띄우는데 이 검증을 마무리하기까지 총 5줄의 코드가 사용되었다.
// Written as of ES2019
function doSomething(onContent, onError) {
try {
// ... do something with the data
}
catch (err) {
if (onError) { // Testing if onError really exists
onError(err.message);
}
}
}
하지만 옵셔널 체이닝을 사용한다면 단 3줄. catch문을 제외한 내부 로직만 본다면 무려 3줄을 1줄로 줄여서 표현할 수 있는 것이다. (물론 1줄로 압축할 수 있다고 무조건 좋은 코드는 절대 아니다.)
// Using optional chaining with function calls
function doSomething(onContent, onError) {
try {
// ... do something with the data
}
catch (err) {
onError?.(err.message); // no exception if onError is undefined
}
}
옵셔널 체이닝은 심지어 다음과 같은 형식으로 배열 혹은 오브젝트에 접근도 가능하다.
let nestedProp = obj?.['prop' + 'Name'];
let arrayItem = arr?.[42];
다만 이를 응용하여 할당하게 되면 에러를 발생하니 주의하자!
let object = {};
object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
뿐만 아니라 null 병합 연산자와 함께 사용도 가능한데, 이는 나중에 null 병합 연산자 포스팅 할 기회가 될 때 예시를 찾아봐야겠다.
아무튼 내가 이해한 혹은 느낀 옵셔널 체이닝의 가장 큰 장점은 깊은 곳 까지 이해가 가능하고, 그 이해를 짧은 식으로 표현할 수 있다는 점이다. 다만 단점으로는 최신 문법이라 지원하지 않는, 예를 들어 IE, 브라우저에서는 폴리필이 필요하다.
상단의 모든 이해와 예시는 MDN을 참고하였다.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/Optional_chaining
'JavaScript > JS' 카테고리의 다른 글
DOM과 virtualDom. 그리고 shadowDom인데 이제 섀도우 돔을 중심으로 (0) | 2022.06.15 |
---|---|
console API 란? (0) | 2022.05.20 |
JS setTimeout에 event loop / task Queue / call Stack을 곁들인.. (0) | 2022.05.18 |
JS 커스텀 이벤트(custom Event) 생성 및 실행(dispatchEvent) (0) | 2022.05.17 |
프론트엔드에서 에러 처리하기 - 기본문법 (0) | 2022.04.04 |
- Total
- Today
- Yesterday
- storybookUI
- 리액트
- vue
- npm
- 프론트엔드
- 크롬
- 사파리
- 깃명령어
- BFCache
- react
- 리코일
- 센트리
- CSS
- TIL
- js
- 리액트훅
- 자바스크립트
- reacthook
- Git
- gitRebase
- 깃
- 리액트상태관리
- js테스트
- 센트리모니터링
- 모바일사파리
- 프론트앤드
- 김민태
- javascript
- frontend
- sentry
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |