본문 바로가기

Javascript/Clean Code

3. 분기 다루기 - 1 (값식문, 삼항 연산자, Truthy & Falsy, 단축평가)

■ 순서

1.값식문 

2.삼항 연산자 다루기 

3.Truthy & Falsy

4.단축평가(short-circuit evaluation)

==============================

아래 부분은 "3.분기 다루기 - 2"에서 나옵니다.

5.else if 피하기

6.else 피하기

7.Early Return

8.부정 조건문 지양하기

9.Default Case 고려하기

10.명시적인 연산자 사용 지향하기

11.Nullish coalescing operator

12.드모르간의 법칙

 


1.값식문

-.문법

: 개발자는 프로그래밍 언어를 사용하기 때문에, 문법에러나 오타가 나면 장애나 서비스 오류가 날 수가 있다.

사소한 문법하나하나는 당연히 중요하다. 하지만 문법을 지키는 것은 생각보다 어렵다.

 

아래의 React를 보면, 우리가 보낸 것이 변형되서 아래와 같이 작성이 된다.

// This JSX:
ReactDOM.render(
  <div id="msg">Hello World!</div>,
  mountNode
);

// IS transformed to this JS:
ReactDOM.render(React.createElement('div', {id: 'msg'}, 'Hello World!'), mountNode);

 

만일 아래와 같이 value(값)이 들어가는 자리에 if 문이 들어갔다면 맞는 문법일까? 

값이 들어가는 자리에 문(문장)이 들어갔으므로 틀린 문법이 된다.

// This JSX:
<div id={if (condition) {'msg'}}>Hello World!</div>

React.createElement("div", {id, if (condition) {'msg'}}, "Hello World!");

const obj = {id: if (condition) {'msg'}}

 

아래와 같이 삼항연산자가 들어간다면 값으로 귀결이 되기 떄문에 사용이 가능하다.

ReactDOM.render(<div id={condition ? 'msg' : null}>Hello World!</div>, mountNode)

 

그럼에도 불구하고 if문을 사용하려면?

아래와 같이 즉시 실행함수인 경우에는 사용이 가능하다.

{(() => {
  switch (this.state.color) {
    case 'red' :
      return '#FF0000';
    case 'green':
      return '#00FF00';
    case 'blue':
      return '#000FF';
  }
})()}

 

또는 아래와 같이 값과 식으로도 if문 없이 사용이 가능하다.

<p>{this.state.color || 'white'}</p>

 

다른 예로는 for문을 들수가 있다.

for문도 간단하게 아래와 같이 map으로 변경을 할 수가 있다.

{(() => {
  const rows = [];
  
  for (let i = 0; i < objectRows.length; i++) {
    rows.push(<Object key={i} data={objectRows[i]} />);
  }
  
  return rows;
})}

//위를 아래와 같이 간단하게 값식만으로 변경할 수 있다.

{objectRows.map((obj, i)) => (
  <ObjectRow key={i} data={obj} />
))}

 

추가적으로 예제를 보면, 

{(() => {
  if (conditionOne) return <span>One</span>;
  if (conditionTwo) return <span>Two</span>;
  else conditionOne;
  return <span>Three</span>;
})()}


//이 부분을 리팩토링 해보자면

{conditionOne && <span>One</span>}
{conditionTwo && <span>Two</span>}
{!conditionTwo && <span>Three</span>}

 

■ 정리

문장이 들어가면 안되는 곳에 문장을 넣으면 안된다.

그런 곳에 굳이 써야 한다면 고차함수로 표현을 해주는 것이 좋다.

 


2.삼항 연산자 다루기

: 삼항 연산자를 쓰는 것은 좋지만 일관성을 가지고 있어야 한다.

삼항 연산자는 3개의 "피"연산자를 취한다.

조건 ? 참(식) : 거짓(식)

 

참과 거짓에는 for문 / if문 등 식이 들어가면 안된다. 식이 들어가야 한다.

 

아래와 같이 과도하게 삼항연산자를 쓰면 알아보기가 힘들어 진다.

이와 같은 경우에는 switch문으로 바꾸는 것이 좋다.

function example() {
  return condition1 ? value
  : condition2 ? value2
  : condition3 ? value3
  : value4;
}

 

위를 아래와 같이 바꾸는 것이 좋다.

const temp = condition1; condition2; condition3;

switch (key) {
  case value:
  
    break;
   
  default:
    break;
}

 

두번째 케이스는 사람이 보기에 헷갈리므로 괄호로 한번 감싸주는 것이 좋다.

const example = condition1
  ? a === 0 ? 'zero' : 'positive'
  : 'negative';
  
  
//위는 큰 문제는 없지만 if를 두번 썻기 때문에 괄호로 한번 감싸주는 것이 좋다.

const example = condition1
  ? (a === 0 ? 'zero' : 'positive')
  : 'negative';

 

 

세번째 케이스는 bad case이다.

: 두개다 실행을 하면 undefined로 귀결이 되기 때문에, 이럴때는 오히려 if문을 사용해주는 것이 더 좋아보인다.

: 삼항연산자는 실행해서 값을 변수로 받아올 때 주로 사용을 한다.

function alertMessage(isAdult) {
  isAdult
    ? alert('입장이 가능합니다.') : alert('입장이 불가합니다.');
}

3.Truthy & Falsy

: 위의 if문과 아래의 if문은 동일하게 작동한다. 

: Truthy와 Falsy를 사용하면 코드를 간결하게 만들수 있다.

if ('string'.length > 0) {

}

if ('string'.length) {

}


if (10) {
}

if (boolean) {
}

 

Truthy가 되는 값들

if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)

 

Falsy가 되는 값들

if (false)
if (null)
if (undefined)
if (0)
if (-0)
if (0n)
if (NaN)
if ("")

4.단축평가

: 아래와 같이 and와 or을 사용하면 뒤쪽까지 가지 않더라도 단축되는 코드들이 있다.

true && true && '도달 O' //도달 O

true && false && '도달 x" //도달 x



//OR

false || false || '도달 O' //도달 O

true || true || '도달 X'   //true 바로 참이라서 true로 귀결이 되어버림.

 

첫번째 예시

아래와 같이 if문을 간단하게 리턴을 해줄수가 있다.

state.data가 값이 있으면 state.data를 리턴, 그렇지 않으면 fetching을 나타내준다.

function fetchDate() {
  if (state.data) {
    return state.data;    
  } else {
    return 'Fetching...';
  }
}

//위는 아래와 같이 쓸수 있다.

function fetchData() {
  return state.data || 'Fetching...'; //state.data가 값이 있으면 state.data를 리턴, 그렇지 않으면 fetching을 나타내준다.
}

 

 

두번째 예시

: 존재할때 if문을 실행하라는 것을 간단하게 논리연산자 or로 만들었다.

function favoriteDog(someDog) {
  let favoriteDog;
  if (someDog) {
    favoriteDog = dog;
  } else {
    favoriteDog = '냐옹';
  }
  return favoriteDog
}

favoriteDog() // 매개변수 안넘기면 냐용
favoriteDog('포메') // 넘기면 강아지 입니다로 호출됨


return (someDog || '냐용') + '입니다'; // 아무것도 안넣으면 someDog가 undefined로 되고 냐용이 나온다.
//넣으면 someDog 입니다가 나온다.

 

 

세번째 예시

: if문이 반복된 것을 논리연산자로 간단하게 변형을 하였다.

const getActiveUserName(user, isLogin) {
  if (isLogin) {
    if (user) {
      if (user.name) {
        return user.name
      } else {
        return '이름없음';
      }
    }
  }
}


//위는 아래와 같이 변경을 할 수가 있다. if + if를 &&로 묶어주었다.

const getActiveUserName(user, isLogin) {
  if (isLogin && user) {    
    if (user.name) {
    return user.name
    } else {
    return '이름없음';
    }
  }  
}

//위는 또 아래와 같이 변형이 가능하다.

const getActiveUserName(user, isLogin) {
  if (isLogin && user) {    
    return user.name || '이름없음';
  }  
}