자신만의 기준을 확립하고 일관성을 유지하는 것이 중요하다.
삼항연산자에는 3개의 피연산자가 있다.
조건 ? 참[식] : 거짓[식]
const ternary = condition ? ((a === 0) ? 'zero' : 'positive') : 'negative';
삼항연산자의 식에 void를 쓰지 않는다.
void는 리턴값이 없다. undefined값이 들어가게 됨. 억지로 숏코딩 하는 것과 같다. 차라리 if문을 사용하는 것이 좋다.
isLogin ? alert('로그인 성공!') : alert('로그인 실패!') // alert는 void // => Refactor if(isLogin) { alert('로그인 성공!'); } else { alert('로그인 실패!'); }
// AND
true && true && '도달' // 모두 참이어야 함.
true && false && '미도달' // 거짓 조건 때문에 도달하지 못함.
//OR
false || false || '도달' // 참을 찾아 도달함.
true || true || '미도달' // 참을 바로 찾아 리턴. 뒷 조건까지 도달할 필요가 없음.
예시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를 사용하는 것은 조건을 제대로 지정하지 않은 것이다.
if(조건1) {
} else if(조건2) {}
// => Refactor
if(조건1){}
if(조건2){}
// 위와 같이 쓰거나 switch문을 사용하는 것이 낫다.
하나의 함수가 두가지 역할을 할 때 문제가 생긴다.
if(user.name) {return '참'}
else {return '거짓'}
위의 형태로 써버릇하지 말자. 의도한 대로 작동하지 않을 수 있다.
조건을 만족하지 않을 때 else문이 실행되지 않을 수 있다.
else는 if문의 조건문을 뒤집은 조건문이기 때문이다.
//=> Refactor
if(user.name) {return '참'}
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)) {}
부정조건문을 사용하는 예외
- 유효성 검증
- 얼리리턴
- 보안, 검사하는 로직
// 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
type ?? 'div' //type이 0이어도 의도한대로 작동된다.
- null or undefined =>
??
- falsy =>
||
- true = not true
- false = not false
if(!(isToken && isUser)) {} // => Refactor : 괄호를 없애고 다 뒤집는다. if(!isToken || !isUser) {}