삼항연산자: ternary conditional operator

자신만의 기준을 확립하고 일관성을 유지하는 것이 중요하다.
삼항연산자에는 3개의 피연산자가 있다.

조건 ? 참[식] : 거짓[식]

  • 삼항연산자를 중첩적으로 쓰지 않는다.
    조건이 너무 많은 경우 차라리 switch문을 활용한다.
    조건에 괄호를 감싸 가독성을 높인다.
const ternary = condition ? ((a === 0) ? 'zero' : 'positive') : 'negative';
  • nullable 한 상황에서 삼항연산자를 활용한다.
  • 값을 반환하는 경우, 변수를 만드는 경우에 사용한다.
  • 피연산자가 3개가 아닐 때 억지로 삼항연산자를 쓰지 말것.(true, falsy 사용)

삼항연산자의 식에 void를 쓰지 않는다.

void는 리턴값이 없다. undefined값이 들어가게 됨. 억지로 숏코딩 하는 것과 같다. 차라리 if문을 사용하는 것이 좋다.

isLogin ? alert('로그인 성공!') : alert('로그인 실패!') // alert는 void
// => Refactor
if(isLogin) {
  alert('로그인 성공!');
} else {
  alert('로그인 실패!');
}

Truthy & Falsy

  • null, undefined도 대응 가능하다.

단축평가 : short circuit evaluation

  • 논리연산자를 활용해 단축평가를 작성한다.
// AND
true && true && '도달' // 모두 참이어야 함.
true && false && '미도달' // 거짓 조건 때문에 도달하지 못함.
//OR
false || false || '도달' // 참을 찾아 도달함.
true || true || '미도달' // 참을 바로 찾아 리턴. 뒷 조건까지 도달할 필요가 없음.
  • default value 표현할 때 활용한다.

예시1

state.data ? state.data : 'fetching . . .'
=> Refactor
return state.data || 'fetching'

예시2

function sayFavorite(name) {
  let favorite;
  if(name) favorite = name;
  else favorite = '생각중';
  return favorite + '입니다';
}
=> Refactor : undefined는 falsy이다.
function sayFavorite(name) {
  return (name || '생각중') + '입니다';
}

예시3

const getActiveUsername(user, isLogin) {
  if(isLogin){
    if(user) {
      if(user.username){}
    } else {
      return '이름없음'}
  }
}
=> Refactor
if(isLogin && user) {
 return user.username || '이름없음';
}

else If 지양

else if를 사용하는 것은 조건을 제대로 지정하지 않은 것이다.

if(조건1) {
} else if(조건2) {}

// => Refactor
if(조건1){}
if(조건2){}
// 위와 같이 쓰거나 switch문을 사용하는 것이 낫다.

else 지양

하나의 함수가 두가지 역할을 할 때 문제가 생긴다.

if(user.name) {return '참'}
else {return '거짓'}

위의 형태로 써버릇하지 말자. 의도한 대로 작동하지 않을 수 있다.
조건을 만족하지 않을 때 else문이 실행되지 않을 수 있다.
else는 if문의 조건문을 뒤집은 조건문이기 때문이다.

//=> Refactor
if(user.name) {return '참'}
return '참이 아님'

Early return

함수를 미리 종료하는 것. depth를 줄이고, 명확하며 사고하기 편하다.
조건에 대한 의존성을 줄이자. 조건은 언제든지 추가되거나 바뀔 수 있다.

function loginService(isLogin, user) {
  if(!isLogin) { //1. 로그인 여부 check
    if(checkToken()) { //2. 토큰 존재여부 check
      if(!user.nickname) { //3. 기 가입유저 확인 -> 가입 | 로그인 성공
        return registerUser(user);
      } else {
        refreshToken();
        return 'login success';
      }
    } else {
      throw new Error('no token');
    }
  }
}
//=> Refactor
function login() { //3-1. 로그인 로직 추상화해 함수로 뽑기.
  refreshToken();
  return 'login success';
}
function loginService(isLogin, user) {
  if(isLogin) { //1. 로그인여부 확인해서 실행할 필요가 없을 때(이미 로그인한경우) 함수 종료.
    return;
  }
  if(!checkToken()) { //2. 토큰 존재여부 체크, 없는 경우 에러 출력.
    throw new Error('no token');
  }
  login(); //3-2. early return 조건을 모두 패스한 경우 로그인 함수 실행.
}

부정조건문 지양

부정조건문은 명확하지 않고, 불필요하게 연산을 여러 번 하게 한다.
프로그래밍 언어 자체도 if문이 먼저 오고, true부터 실행시킨다.

if(!isNaN(3)){} // isNaN이 아니다: 숫자이다.
//=> Refactor
function isNumber(num){
  return !Number.isNaN(num) && typeof num === 'number';
}
if(isNumber(3)) {}

부정조건문을 사용하는 예외

  • 유효성 검증
  • 얼리리턴
  • 보안, 검사하는 로직

default case

  • 인자가 들어오지 않아도 디폴트값을 주어서 처리할 수 있도록 한다.
  • edge case를 고려한다.
  • 사용자의 실수를 예방한다.
// case1
function sum(x,y) {
  x = x || 1; //디폴트값을 주어 sum()만 해도 실행될 수 있도록 한다.
  y = y || 1;
  return x + y;
}

// case2
function createElem(type, height, width) {
  const elem = document.createElement(type || 'div');
  element.style.height = height || 100;
  element.style.width = width || 100;
  return element;
}

// case3 : parseInt의 두번째 인자의 디폴트값은 10이 아니다.
// 기존에 존재하는 메서드들을 함수로 만들어서 좀 더 안전하게 사용할 수 있다.
function safeParseInt(num, redix){
  return parseInt(num, redix || 10);
}

// case4 : React에서의 예시
const Root = () => {
  <Router>
    <Switch>
      <Route 1 />
      <Route 2 />
      <Route component={NotFound}/> //디폴트값을 항상 고려한다.
    </Switch>
  </Router>
}

명시적 연산자 사용

  • 괄호를 적극 활용하자. 우선순위를 지정한다.
  • 예측가능하고 디버깅이 쉬운 코드를 작성하자.
number++ //++number || number++ 보다
//=> Refactor
number = number + 1

널 병합 연산자 nullish coalescing operator

  • (주의!) 우선순위가 낮다.
  • 숫자 0은 falsy에 해당한다. 0을 전달하고싶어도 false로 귀결될 수 있다.
  • null, undefined만 평가할 때 사용하자.
type ?? 'div' //type이 0이어도 의도한대로 작동된다.
  • null or undefined => ??
  • falsy => ||

드 모르간의 법칙

  • true = not true
  • false = not false
if(!(isToken && isUser)) {}
// => Refactor : 괄호를 없애고 다 뒤집는다.
if(!isToken || !isUser) {}

결론

  • 습관적으로 조건을 사용하지 말자.
  • 조건에 대해 잘 정의하고 연산자의 목적을 생각해봐야한다.
profile
주니어 플러터 개발자의 고군분투기

0개의 댓글