[클린코드 JS] 07. 조건 및 분기 다루기

Serin-B·2023년 6월 27일
0

클린코드JS

목록 보기
7/15
post-thumbnail

오늘은 조건 및 분기를 깔끔하고 간단하게 다루는 방법에 대해 알아보자.

Truthy vs Falsy

Truthy란 불리언을 기대하는 문맥에서 true로 평가되는 값을 말한다. 아래 Falsy 한 값으로 정의된 값이 아니면 모두 Truthy로 평가된다.

Falsy 값 8가지
false , 0 , -0 , 0n ,NaN , '' , null ,undefined

이러한 TruthyFalsy 를 활용하여 아래처럼 조건문을 만들거나 분기 처리할 수 있다.

const str = 'hello'
if(str){
// true 로 취급된다! 그러므로 if 문 안의 코드가 실행된다.
} 

const arr = []
if(arr.length){
 // arr.length === 0 이다.
//false 로 취급되므로 if 문 안의 코드는 실행되지 않는다.
}

논리 연산자 활용하기

논리 연산자를 활용하면 훨씬 간단하게 조건문을 설정하고, 분기 처리할 수 있다.

&& : And 연산자
모든 조건이 참이면 뒤의 값 반환, 하나라도 거짓이면 거짓인 값 반환

true && true // true
true && false //false
false && true //false
false && false //false
false&&'' //false
true&&'' // ''
33&&44 //44
33&&false //false

|| : Or 연산자
모든 조건이 참이라면 앞의 값, 모든 조건이 거짓이라면 뒤의 값, 하나라도 참이면 참인 값 반환

true || true // true
true || false // true
false || true // true
false || false //false
true||'' // true
''||false // false
false||'' // ''

?? : Null 병합 연산자
앞에 오는 값이 null 또는 undefined이면 뒤에오는 값을, 아니라면 앞의 값을 반환

null ?? true // true
null ?? [] // []
null ?? NaN //NaN
null ?? undefined //undefined
undefined ?? false //false
undefined ?? '' // ''
undefined ?? undefined //undefined
undefined ?? null // null
'' ?? null // ''
55 ?? undefined //55

아래와 같이 단축 평가로 사용할 수 있다.

function fetchData(){
  return state.data || 'Fetching...'
  //state.data 가 있으면 return state.data
  //state.data 가 없으면 return 'Fetching...'
}

function Welcome(){
  return (
    {isLogin && <h1>hello, {userName}</h1>}
    // isLogin이 true면 뒷 부분도 나타남
    // isLogin이 false면 뒷 부분도 안나타남
  )
}

function Hello(name){
  return 'Hello ' + (name ?? '이름 없음')
}
Hello('영희') // Hello 영희
Hello('') // Hello 
Hello() // Hello 이름 없음

||?? 의 차이점
null과 undefined, 숫자 0을 구분 지어 다뤄야 할 때 이 차이점은 매우 중요한 역할을 한다!

let height = 0;
console.log(height || 100); // 100
console.log(height ?? 100); // 0

height || 100은 height에 0을 할당했지만 0을 falsy 한 값으로 취급했기 때문에 null이나 undefined를 할당한 것과 동일하게 처리한다.

반면 height ?? 100의 평가 결과는 height가 정확하게 null이나 undefined일 경우에만 100이 된다.

따라서 nullundefined 만 예외 처리해주고 싶을때는 ?? 를 써야 한다!

부정 조건문 지양하기

부정 연산자를 붙이면 두 번 생각을 해야하므로 되도록 긍정 조건문을 사용하고, 필요한 경우에는 각 조건마다 부정 연산자!를 붙여 사용하자. (괄호로 긍정 조건을 묶어 한 번에 부정 연산자를 사용하면 사고하기 더 어렵다.)

//Bad case
if(!(isUser&&isAdult)){
  // isUser 와 isAdult 둘 다 참인 경우의 반대 상황에서 실행
  // 즉, isUser 와 isAdult 모두 false 인 경우 실행
}

// Better case : 괄호를 벗기고 각 조건에 부정연산자 사용
if(!isUser&&!isAdult){
  // isUser 와 isAdult 모두 false 인 경우 실행
}

삼항연산자

if/else문의 대체재.
앞에서부터 조건문, 물음표(?), 조건문이 참(truthy)일 경우 실행할 표현식, 콜론(:), 조건문이 거짓(falsy)일 경우 실행할 표현식 으로 이루어진다.

condition ? 'condition이 true 일 경우' : 'condition이 false 일 경우'

간단한 조건을 다룰 때에는 짧은 코드로 같은 효과를 낼 수 있기 때문에 if/else 대신 삼항연산자를 많이 사용한다. 특히 리엑트 JSX 내부에서는 if/else 문을 사용할 수 없기 때문에 삼항 연산자가 많이 사용된다.

function Level(level){
  return (
  <div className={level>10 ? 'green' : 'yellow'}>{level}</div>
  )
}

조건이 길어질 경우에는 ?: 를 기준으로 줄바꿈을 해주면 보기 편하다. 이중으로 삼항 연산자를 사용하는 경우에는 괄호로 범위를 묶어주면 우선적으로 살펴볼 수 있도록 사고를 돕는다.

condition1
  ? (condition2 ? '두개 다 만족' : 'condition1만 만족') 
  : 'condition1 불만족'

⊕ 단, 지나친 숏코딩은 지향하자! 코드는 결국 사람이 읽는 것이다. 짧고 간략한 코드를 지향하는 것은 쉽게 코드를 파악하고 이해하기 위함이다. 지나친 숏코딩으로 인해 가독성이 사라진다면 의미가 없다.

괄호로 우선순위 표현하기

연산자 우선순위 라는 것이 있다. 그러나 이것을 일일히 외워서 사용하기는 쉽지 않으므로, 괄호를 사용하여 명시적으로 우선순위를 표현 및 설정해주는 것이 좋다.

function (){
  return a / ( b * c )
}

if((isLogin && isVaildToken) || isUser){
}

else 와 else if 지양하기

else 와 else if 를 습관적으로 사용하는 경우가 있는데, 불필요한 경우가 대반사이므로 되도록 사용을 지양하는게 좋다.

특히 else if 의 경우 else문 내부에서 if 문을 한 번 더 실행하는 것과 같으므로 그냥 if 문만 사용해도 충분히 의도대로 작동하는 코드를 작성할 수 있다.

if(num<=5){
  return 'not bad'
}else if(num<=50){
  return 'good'
}else{
  return 'great'
}

// 리펙토링
if(num<=5){
  return 'not bad'
}
if(num<=50){
  return 'good'
}
return 'great'

Early Return

예외 상황 또는 특정 상황이 있다면 Early Return 으로 빠르게 종료해주는 것이 좋다. 함수를 빠르게 종료할 수 있으며, 인간이 사고하기 훨씬 편하다.

function login(isLogin, isVaildToken, user){
  //로그인 하지 않은 유저인 경우
  if(!isLogin){
    //유효한 토큰을 가진 경우
    if(isVaildToken){
      //닉네임이 없는 경우 회원가입으로 보내기
      if(!user.nickName){
        return registerUser(user)
        // !isLogin && isVaildToken && user.nickName 인 경우
      }else{
        refreshToken()
        return '로그인 성공'
      }
    //토큰이 없는 경우
    }else{
      throw new Error('No token')
    }
  }
}
function login(isLogin, isVaildToken, user){
  //로그인 한 경우 얼리 리턴
  if(isLogin){
    return
  }
  // 유효하지 않은 토큰 가진 경우 에러 던지고 얼리 리턴
  if(!isVaildToken){
    throw new Error('No token')
  }
  // 이름이 없는 경우 회원가입으로 얼리 리턴
  if(!user.nickName){
    return registerUser(user)
  }
  // 위의 경우의 수 모두 아닌 경우에는 리프레쉬 토큰 + 로그인 성공
  refreshToken()
  return '로그인 성공'
}

참조

  • 도서 Clean Code(클린 코드) / 로버트 C. 마틴 / 2013.12.24.
  • Udemy 강의 클린코드 자바스크립트 / Poco Jang / 2023. 5.
profile
프론트엔드 개발자

0개의 댓글

관련 채용 정보