새오의 개발 기록

클린코드 자바스크립트: 분기 처리하기 본문

클린코드

클린코드 자바스크립트: 분기 처리하기

새오: 2023. 1. 19. 20:52

값식문

 

  • 프로그래밍 언어를 사용해 결국 컴퓨터를 이해시키고자 하기 때문에 문법을 간과해서는 안됨.
  • 값과 식과 문을 구분해서 사용하자.
  • (): 함수
  • {}: 값 또는 식

 

// 값이 들어가야 하는 자리에 '식'이 들어서 안 됨
<div id={if (condition) {'msg'}}> Hello World</div>

// 삼항연산자는 '값'으로 귀결되기 때문에 사용 가능
<div id={condition ? 'msg' : null}> Hello World</div>

 

  • 바로 리턴되는 분기문은 논리 연산자 사용하는 것이 좋음

 

if (condition) {return <span>one</span>}
{conditionOne && <span>one</span>

 

 

삼항 연산자

 

  • 삼항 연산자로 숏코딩 하는 것도 좋지만 삼항 연산자를 일관성있게 사용하는 것이 중요함.
  • 삼항 연산자에는 '조건', '참', '거짓' 3개의 피연산자가 존재
  • 삼항 연산자를 과도하게 사용하기보다 if로 조건을 나누기
  • 조건이 여러 개인 경우 가독성을 생각해서 switch를 사용하는 방법도 있음
  • 삼항 연산자를 사용해도 좋은 경우
      1. 삼항 연산자를 사용해서 무언가에 값을 만들고 변수에 담아 내는 경우
      2. 함수가 반환하는게 값인 경우
  • 삼항 연산자를 사용하지 않는게 좋은 경우
    • 조건을 기준으로 거짓만 필요하거나, 참만 필요한 경우에는 삼항 연산자 사용할 필요 없음
    • 반환 값이 없는 함수

 

const welcomeMessage = (isLogin) => {
	const name = isLogin ? getName() : '이름없음' ; // nullable 대응하는 코드
    return '안녕하세요 ${name}`;
}; 


function alertMessage(isAdult) {
	isAdult ? alert('입장이 가능합니다.') : alert('입장이 불가능합니다.');
    // alert는 값을 반환하지 않는 함수이므로 삼항 연산자에 사용하면 안 됨
    // 빈값이라(undefined) 참/거짓 식별 불가
    // 단지 숏코딩일뿐 -> if문이 더 낫다
}

 

 

 

 

Truthy & Falsy

 

  1. boolean이 아니어도 참과 거짓으로 귀결되는 값 존재 
  2. 참 같은 값: boolean을 기대하는 문맥에서 true로 평가되는 값
  3. 따로 거짓 같은 값으로 정의된 값이 아니면 모두 참 같은 값으로 평가됨
    1. 거짓 같은 값: false, 0, -0, 0n, "", null, undefined와 NaN 등)
  4. null, undefined를 검사할 때 유용함
if (name === undefined) {
	return '사람이 없네요.';
}

// 엄격한 검사 아닌 경우 간단하게 사용 가능

if (!name) {
	return 사람이 없네요.';
}

 

 

 

 

참 같은 값 - MDN Web Docs 용어 사전: 웹 용어 정의 | MDN

JavaScript에서, 참 같은 값(Truthy)인 값이란 불리언을 기대하는 문맥에서 true로 평가되는 값입니다. 따로 거짓 같은 값으로 정의된 값이 아니면 모두 참 같은 값으로 평가됩니다. (예: false, 0, -0, 0n, "

developer.mozilla.org

 

 

거짓같은 값 - MDN Web Docs 용어 사전: 웹 용어 정의 | MDN

거짓 같은 값(Falsy, falsey로 쓰이기도 함) 값은 불리언 문맥에서 false로 평가되는 값입니다.

developer.mozilla.org

 

 

short-circuit evalutaion

 

  • 단축 연산자를 사용하여 불필요한 분기문을 줄이자
  • AND 연산자와 OR 연산자

 

 // 참->참->리턴
true && true && '도달 O'
//참거짓 =>리턴
true && false && '도달 X'

//거짓 -> 거짓 => 리턴
false || false || '도달 O'
//참 -> 즉시 리턴
true || true || '도달 X'

 

  • OR 연산자
  • Default값 있는 경우에 유용하게 사용 가능

 

// before
function fetchData() {
	if (State.data) {
    return state.data;
    } else {
    return 'Fetching..';
    }
}

// after: 기본값 있는 경우에 유용하게 사용 가능
function fetchData() {
	return state.data || 'Fetching...';
}

// before
function favoriteDog(someDog){
    let favoriteDog;
    if(someDog){
        favoriteDog = dog;
    }
    else {
        favoriteDog = '냐옹';
    }
    return favoriteDog + '입니다.';
}


// after
function favoriteDog(someDog){
    return (someDog || '냐옹') + '입니다.';
}

 

 

 

else-if 피하기

 

  1. else if의 경우 if문 처리 후 else에서 다시 if문 작동되는 흐름임 -> 불필요한 로직
  2. if문으로 나누기
  3. if문으로 어렵다면 switch를 사용하기

 

else 피하기

 

  1. 자바스크립트는 return 이후의 코드 실행하지 않음
  2. 습관적 else 사용 지양해야 함
  3. 로직이 의도하는 대로 흘러갈 수 있도록 고려해서 else문이 필요하지 않다면 사용하지 않아야 함

 

// 사용자에게 인사를 하는 함수로 미성년자 사용자가 오면 report하고자 함.

function getHelloCustomer(user) {
	if(user.age < 20) {
    	report(user)
    }
    else{
    	return '안녕하세요.'
    }
}
// 미성년자 사용자에게는 안녕하세요가 안 됨 



// else문 삭제하고 의도대로 동작함
function getHelloCustomer(user) {
	if(user.age < 20) {
    	report(user)
    }
    return '안녕하세요.'
}

 

 

Early Return

 

  1. 하나의 로직에 많은 의존성을 담고 있을 때 로직을 종료하기 위해 사용
  2. 동작할 필요가 없는 로직의 경우 return 처리하여 함수를 미리 종료시키기
  3. 가독성 향상

 

// 높은 의존성, 나쁜 가독성

function loginService(isLogin, user) {
  if (!isLogin) {
    if (checkToken()) {
      if (!user.nickName) {
        return registerUser(user);
      } else {
        refreshToken();
      }
    } else {
      throw new Error("No Token");
    }
  }
}


// 위의 코드를 early return 처리함

function loginService(isLogin, user) {
  if (isLogin) {
    return;
  }
  if (!checkToken()) {
    throw new Error("No Token");
  }
  if (!user.nickName) {
    return registerUser(user);
  }

		login();
}

function login(){

	refreshToken();
  return "로그인 성공";
}

 

부정 조건문 지양하기

 

  1. 부정 조건문은 직관적이지 않음
  2. if문에는 긍정 조건이 오고 그 뒤에 else 실행되기 때문에 굳이 순서를 바꿔할 필요가 없음
  3. 부정 조건문을 사용할 수 있는 경우
    1. early return
    2. form validation
    3. 보안, 검사 로직

 

Default Case 고려하기

 

  1. 사용자의 실수로 에러 발생할 수 있음. 프론트엔드 개발자는 이를 예방하기 위해 default 케이스를 고려하는 것이 좋음
  2. 예측 가능한 앱을 만들자
  3. 함수 작성 시 매개변수가 없어도 동작하도록 하는 것도 같은 것

 

function safeParseInt(number, radix){
	return parseInt(number, radix || 10);
}

 

 

 

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

 

  1. 괄호 사용해서 우선순위 눈에 보이도록 하기
  2. 증가/증감 연산자 지양하고 명시적인 코드 작성하기
  3. 예측 가능하고 디버깅 하기 쉬운 코드 작성하기 -> 연산자 우선순위 몰라도 읽을 수 있도록

 

if ((isLogin && token) || user)

function increment() {
	number; // bad case
    number = number + 1 // good case
}

 

Nullish coalescing operator(Null 병합 연산자)

 

  • 0은 falsy라서 false로 리턴되기 때문에 의도치 않은 결과 발생함
function createElement(Type, height) {
	const element = document.createElement(Type || 'div');
    
    element.style.height = String(height || 10) + 'px';
    
    return elemet;
}



const el = createElement('div', 0);

el.style.height
// 숫자 0이 값이 아닌 falsy로 해석되어 기본값인 10이 들어감
// '10px'

 

  • falsy일 때는 || 사용하고, null과 undefined를 구분할 때만 Null 병합 연산자로 쉽게 사용 가능(최신 문법)
  • 물음표 2개 사용으로 Null 병합 연산자 사용 가능

 

function safeParseInt(number,radix){
	return parseInt(number, radix ?? 10);	
}

 

 

Nullish coalescing operator - JavaScript | MDN

널 병합 연산자 (??) 는 왼쪽 피연산자가 null 또는 undefined일 때 오른쪽 피연산자를 반환하고, 그렇지 않으면 왼쪽 피연산자를 반환하는 논리 연산자이다.

developer.mozilla.org

 

 

드모르간의 법칙

 

  • 쉽게 연산 가능

 

const isValidUser = true;
const isValidToken = true;


if (isValidToken && isValidUser) {
	console.log('로그인 성공!');
}


// 로그인 실패도 만들라는 요청처럼 다양한 요구사항 발생할 수 있음
// 매우 번거로움
const isValidUser = false;
const isValidToken = false;

if (!(isValidToken && isValidUser)) {
	console.log('로그인 실패!');
}

// 드모르간의 법칙으로 간단히 구현 가능
!(A && B) == !A || !B

 

 

 

 

참고: 유데미 클린코드 자바스크립트 강의