관리 메뉴

꿈꾸는 개발자

옵셔널 체이닝 '?.' 정리하기(JS/TS) 본문

프로그래밍언어/TypeScript

옵셔널 체이닝 '?.' 정리하기(JS/TS)

rickysin 2023. 5. 10. 17:10

목적

옵셔널 체이닝을 JS DeepDive를 접하면서 처음으로 알게 됐지만, 그 이후 크게 사용하는 경우가 개인적으로 없어서 잊고 지내고 있다가.....타입스크립트로 개발을 본격적으로 시작하면서 옵셔널 체이닝의 강력함을 깨닫고 잊었던 기억을 다시 되살리고자 옵셔널 체이닝에 대해 정리하고자 한다. 

 

옵셔널 체이닝의 프로퍼티가 없는 중첩 객체를 접근할 때 보다 안전하게 접근을 할 수 있다. 

예시

let user = {}; // 주소 정보가 없는 사용자

alert(user.address.street); // TypeError: Cannot read property 'street' of undefined

보통 위와 같은 경우에선 타입 에러가 발생하게 된다. 이전에는 && 연산자를 주로 사용해서 위와 같은 상황을 해결하곤 했다. 

let user = {}; // 주소 정보가 없는 사용자

alert( user && user.address && user.address.street ); // undefined, 에러가 발생하지 않습니다.

하지만 위 코도는 너무 복잡해 보인다. 

 

사용법

?. 의 경우 앞의 대상이 undefined이거나 null일 때 평가를 중단하고 undefined를 반환한다. 

let user = {}; // 주소 정보가 없는 사용자

alert( user?.address?.street ); // undefined, 에러가 발생하지 않습니다.

처음에 나왔던 에러 코드를 위와 같이 변경하면 에러가 나지 않는다! 그냥 undefined을 반환할 뿐!

 

javascript.info에 따르면 옵셔널 체이닝의 남용은 바람직하지 않다고 말한다. 

위의 예시의 경우 user는 무조건 있어야 하고,나머지 address는 필수는 아니기 때문에 user.address?.street로 작성하는 것이 바람직하다. (이유는 실수로 user에 값을 할당하지 않았을 때 바로 알아채기 위해) 

 

위에서 언급했듯이 undefined이거나 null일 때 평가를 즉시 멈추기 때문에 데이터가 실행되지 않는다

 

다양한 사용법

 

let user1 = {
  admin() {
    alert("관리자 계정입니다.");
  }
}

let user2 = {};

user1.admin?.(); // 관리자 계정입니다.
user2.admin?.();

객체 메서드에서도 사용이 가능하다. user2.admin?.()의 경우 속성이 없기 때문에 판단을 바로 멈춘다. 

 

delete user?.name; // user가 존재하면 user.name을 삭제합니다.
위와 같이 delete와 혼합해서 사용할 수도 있다. 

개인적인 용법

        <S.CommentShow>
          {data?.map((comment: PortfolioCommentAPI) => {
            const { id, content, createdAt, userName, portfolioCommentId, portfolioId } = comment;
            return (
              <CommentItem
                key={id}
                id={id}
                content={content}
                createdAt={createdAt}
                userName={userName}
                portfolioCommentId={portfolioCommentId}
                portfolioId={portfolioId}
              />
            );
          })}
        </S.CommentShow>

위처럼 data가 undefined일 경우가 있을 수 있기 때문에 typescript 환경에서 에러가 발생하게 된다(물론 JS에서도 에러이다-런타임에서 발생하게 될듯?) 타입스크립트의 강점은 컴파일 타임에서 에러를 잡아주기 때문에 사전에 수정을 해야 한다. 따라서 위와 같은 상황에서 data?.map()을 사용하면 간단하게 해결할 수 있다. 


참고 자료

https://ko.javascript.info/optional-chaining

 

옵셔널 체이닝 '?.'

 

ko.javascript.info