Development/Etc

[모던 자바스크립트] 이름은 Optional, 적용은 Required

bbubbush 2022. 9. 17. 17:54

들어가며

ES6부터 객체의 값을 안정적으로 가져오는 옵셔널이 도입됐다. 개념도 쉽고 적용하기도 쉽기 때문에 활용도가 높다. 더 이야기할 게 없으니 바로 알아보자 🙂

 

 

전통적인 객체 프로퍼티 확인

개발하면서 발생할 수 있는 상황을 통해 전통적인 방식의 프로퍼티 확인 방식을 보려고 한다. 이번 목표는 책ID로 책 정보를 찾아 작가의 이름을 출력하는 코드를 만드는 것이다. 먼저 책의 정보가 어떻게 구성되었는지 보자.

// book은 이런 형태로 데이터 구조를 갖는다.
const sampleBook = {
  bookId: 1,
  title: '객체지향의 사실과 오해',
  isbn: '9788998139766',
  author: {
    name: '조영호',
  },
}

 

특별한 것 없이 최소한의 정보를 담았다. 마저 기능개발을 해보자.

 

const book = bookService.findBookById(bookId);
const author = book['author'];
alert(`작가의 이름은 ${author['name']} 입니다.`);

간단하게 개발이 끝났지만 테스트 하던 중 오류가 발생했다. 오류는 크게 세 가지 유형이었다.

 

  1. bookService.findBookById()는 bookId에 맞는 데이터가 없으면 null을 리턴한다.
  2. 작가 정보가 없는(저자: 미상) 책은 book[’author’] 정보가 null 혹은 undefined로 리턴된다.
  3. book[’author’][’name’] 값이 없는 경우도 작가가 미상인 경우다.

모든 유형에서 데이터가 없을 때 빈 값을 보내주면 좋으련만 이런 경우에는 꼭 담당 개발자가 수정할 수 없다고 이야기한다. 별 수 없으니 내 코드를 수정해야겠다.

const book = bookService.findBookById(bookId);
if (!book || book == null || book == undefined) {
  return;
}
if (book['author'] == null || book['author'] == undefined) {
  alert(`작가의 이름은 미상(알 수 없음) 입니다.`);
  return;
}
const author = book['author'];
if (author['name'] == null || author['name'] == undefined) {
  alert(`작가의 이름은 미상(알 수 없음) 입니다.`);
  return;
}
alert(`작가의 이름은 ${author['name']} 입니다.`);

 

여러 번의 테스트를 거쳐 코드가 문제없음을 확인했다. 기능에 문제는 없지만 프로퍼티를 확인하는 코드가 중간중간 섞여 비즈니스 로직을 한눈에 파악하기 어렵다.

전통적인 프로터피 확인 방식은 이렇게 if 구문을 통해 원하는 프로터피의 값을 확인하는 과정을 반복한다. 이는 코드의 가독성이 떨어지고 유지보수의 어려움으로 자연스럽게 이어진다.

 

Optional을 활용한 프로퍼티 확인

선택적인을 뜻하는 옵셔널프로퍼티가 있으면 값을 가져오고, 없으면(= null이거나 undefined인 경우) undefined를 반환하는 문법이다. 값을 확인할 객체의 뒤에 “?.” 문법을 붙여 사용한다. 다음은 옵셔널은 통해 수정된 코드다.

const book = bookService.findBookById(bookId);
let authorName = '미상(알 수 없음)';
if (book?.['author']?.['name']) {
  authorName = book['author']['name'];
}
alert(`작가의 이름은 ${authorName} 입니다.`);

 

프로퍼티를 확인하는 코드가 사라지니 코드의 목적이 선명하게 보인다. 이게 옵셔널의 장점이다.

 

조금 더 설명하면 전통적인 방식은 객체의 프로퍼티가 가리키는 다른 객체로 이동하는 순간마다 확인하고 진행하는 코드를 작성해야 했다. 반면, 옵셔널을 사용하면 최종적으로 알고 싶은 데이터까지 바로 접근이 가능하다. 그래서 코드를 간결하게 만들 수 있다.

 

‘이렇게 좋고 편한데 모든 프로퍼티를 읽을 때 옵셔널을 쓰면 되지 않을까?’

 

 

분명 이렇게 생각하는 개발자가 있을까 봐 미리 대답을 드린다. 꼭 필요할 때만 사용하라고! 옵셔널은 장점만큼 단점도 명확하다. 디버깅이 힘들다. 옵셔널 체이닝의 결과가 undefined일 때, 어디에서 undefined가 되었는지 알기 어렵기 때문이다. 차라리 옵셔널을 안 썼다면 런타임 오류가 발생해서 확인할 수 라도 있다. 그래서 객체가 확실히 존재하는 경우에는 옵셔널을 지양하라고 권고한다.

 

마지막으로 주의점을 살펴보고 끝내자. 옵셔널은 프로퍼티를 읽거나 삭제는 가능하지만 값을 할당할 때는 사용이 불가능하다. 프로퍼티를 읽는 경우는 이미 봤으니 삭제와 값 할당의 경우를 보자.

const book = {
  bookId: 2,
  title: 'Hello JS',
  isbn: '1234567890123',
  author: {
    name: 'bbubbush'
  },
}

delete book?.price;  // 가능
book?.price = 1000;  // 불가능

 

논리적으로 생각해보면 이해가 된다. 삭제하려는 프로퍼티가 없으면 객체를 그대로 두면 된다. 그러니깐 삭제는 옵셔널을 사용할 수 있다.

 

그런데 ‘만약 프로퍼티가 있을 때만 값을 할당한다? 그러면 프로퍼티를 생성해서 넣어야 하나? 아니면 객체를 프로퍼티가 없는 이유가 있을 테니 값을 할당하면 안 되나?’ 혼란스럽다. 그래서 읽기와 삭제는 되지만 값을 할당하는 건 불가능한 것 같다.(주관적 생각)

 

 

마치며

객체의 프로퍼티를 쉽게 다룰 수 있는 옵셔널 문법을 알아보았다. 개념도 간단하고 사용방법도 쉬워서 실무에 적용하기 좋다고 생각한다. 한결 직관적인 코드가 여러분의 시간을 아껴줄 것이다. 진짜로.

 

 

[모던 자바스크립트 관련 글]

 

[모던 자바스크립트] var를 사용하지 않아야 하는 이유

2022.09.03 - [Development/Etc] - [모던 자바스크립트] var를 사용하지 않아야 하는 이유 들어가며 ES6에서는 변수를 사용하기 위해 새로운 문법인 let과 const를 지원하면서 동시에, var의 사용을 지양하라고

bbubbush.tistory.com

 

[모던 자바스크립트] Array 스마트하게 사용하기

들어가며 배열(Array)은 맵과 함께 데이터를 관리하기 위한 가장 효율적인 자료구조다. 이번에는 배열로 무엇을 할 수 있는지 보면서 for 구문의 지옥에서 벗어날 수 있는 것을 목표로 한다. 고전

bbubbush.tistory.com

 

[모던 자바스크립트] Object 기깔나게 사용하기

들어가며 자바스크립트에서 맵(Map)은 ES6가 되어서야 등장했다. 다른 언어에 비하면 상당히 늦은 편이다. 왜일까? 바로 객체(Object)라는 대안이 있었기 때문이다. 따라서 맵을 어떻게 사용하는지

bbubbush.tistory.com

 

[모던 자바스크립트] 어썸한 Funtion 변경사항

들어가며 자바스크립트는 함수로 대표된다고 해도 과언이 아니다. 이제는 객체지향적인 방식으로 작업하는 개발자도 많지만 과거부터 함수를 정의하고 사용해왔기에 아직까지 함수 지향적인

bbubbush.tistory.com

 

[모던 자바스크립트] Promise 한 방에 뿌수기

들어가며 아마 ES6의 내용 중 이해하기 가장 어려운 내용이 프로미스가 아닐까 생각한다. 다른 변경사항은 기능에 충실한 반면, 프로미스는 특정한 상황을 해결하기 위해 등장했기 때문이라 생

bbubbush.tistory.com