[javascript] 논리연산자, 제대로 알고 쓰자
resilient
·2021. 11. 3. 00:48
코드를 짜다보면, 논리 연산자를 사용해야 하는 경우가 많습니다.
제가 최근에 짠 아래 코드를 볼까요?(정말...'이게 최선인가?'를 몇 번이고 생각하면서, 일단은 만든 코드입니다)
리액트에서 랜더링 해주는 페이지 중 일부 입니다.
보다시피 리액트에서 조건부 렌더링을 구현할 때 function을 위해서 정의해 주는 방식 말고 이렇게 직접적으로 사용하는 경우가 종종 있습니다.
제가 짠 코드를 간단하게 설명드리자면,
- user가 없을 때 (로그인이 되어있을 때 받아오는 props값)
- user가 있는데 wallet_address가 없을 때
- user 도 있고 wallet_address가 있는데 eventStatus가 없을 때
- user 도 있고 wallet_address도 있고 eventStatus도 있을 때
의 순서대로 논리 연산자를 수행하고, 렌더링 하게 해 줍니다. (이때, eventStatus는 default 가 0 인 field입니다.)
여기서 문제가 발생했습니다.
위에 사진처럼 버튼 옆에 0이 출력이 되고 있었습니다.
Elements를 확인해봐도
이게 어디서 나온 지 전혀 이해할 수 없었습니다..
무조건 논리 연산자 부분에서 뭔가 오류가 있는 거 같은데 도저히 모르겠다 라고 생각한 순간!
1 && 2 && 0 && 3 은 0을 뱉어내는 자바스크립트의 논리 연산자를 떠올렸습니다.
결국에는 user.model안에 있는 eventStatus field의 default를 삭제해줬고, 에러를 고쳤습니다.
그래서, 논리 연산자 때문에 왜 잘못 렌더링이 된 걸까?
논리 연산자에 대해 자세하게 알아보겠습니다.
OR
or연산자는 javascript에서 || 로 표현합니다. or 연산자는 두 피연산자 중 하나만 참 이어도 true를 반환해줍니다.
or연산자는 다음 순서에 따라 연산을 수행합니다.
- 가장 왼쪽 피연산자부터 시작해 오른쪽으로 나아가며 피연산자를 평가합니다.
- 각 피연산자를 불린 형으로 변환합니다. 변환 후 그 값이 true이면 연산을 멈추고 해당 피연산자의 변환 전 원래 값을 반환합니다.
- 피연산자 모두를 평가한 경우(모든 피연산자가 false로 평가되는 경우)엔 마지막 피연산자를 반환합니다.
위에서 핵심은 반환 값이 형 변환을 하지 않은 원래 값이라는 점입니다!
AND
and연산자는 javascript에서 &&로 표현합니다. or 연산자는 두 피연산자가 모두가 참일 때 true를 반환합니다.
or 연산자와 마찬가지로 and 연산자의 피연산자도 타입에 제약이 없습니다.
예를 들어 1 && 0이라는 논리형이 있을 때, 피연산자가 숫자형이지만 논리형으로 바뀌어서 true && false가 돼서 결국은 false가 됩니다.
AND 연산자 &&는 다음 순서에 따라 동작합니다.
- 가장 왼쪽 피연산자부터 시작해 오른쪽으로 나아가며 피연산자를 평가합니다.
- 각 피연산자는 불린 형으로 변환됩니다. 변환 후 값이 false이면 평가를 멈추고 해당 피연산자의 변환 전 원래 값을 반환합니다.
- 피연산자 모두가 평가되는 경우(모든 피연산자가 true로 평가되는 경우)엔 마지막 피연산자가 반환됩니다.
여기서 AND와 OR의 차이점은 AND 연산자가 첫 번째 falsy를 반환하는 반면, OR은 첫 번째 truthy를 반환한다는 것입니다.
그리고 또 다른 특징들을 살펴보면
- && 의 우선순위가 || 보다 높습니다.
- if문을 &&나 || 로 대체하면 좋지 않습니다. 그 이유는 if문을 사용한 예시가 코드에서 무엇을 구현하고자 하는지 더 명백하기 때문입니다.
자, 이제 저의 오류를 분석해볼까요?
default가 0인 eventStatus가 있는 줄의 코드를 보시면
user가 있다 = 1 && user.wallet_address 가 있다 = 1 && user.eventStatus가 있다 = 0 이기 때문에 결과적으로 0이 나오기 때문에 0을 출력해준 것이었습니다.
and, or 나 &&, || 연산자를 대충 알고 쓰다가 이런 경험을 해보니, 역시 사용하려면 확실히 알고 사용해야 한다는 생각을 또 한번 했습니다.
#Reference
'Language > Javascript' 카테고리의 다른 글
[javascript 자바스크립트] 실행 컨텍스트(Execution Context) 란? (0) | 2021.12.03 |
---|---|
[javascript 자바스크립트] NPM, 그리고 YARN (0) | 2021.11.12 |
[javscript] 자바스크립트 테스트코드, Jest 란? (0) | 2021.08.13 |
[javascript 자바스크립트] 순환참조 란? (0) | 2021.07.31 |
[javascript 자바스크립트] 이벤트루프 란? (0) | 2021.07.30 |