자바스크립트에는 &&
(AND) 와 ||
(OR), !
(NOT) 논리 연산자가 존재한다.
일반적으로 boolean 값과 사용하여 참/거짓을 반환하는 데 쓰이지만, 자바스크립트에서는 논리 연산자의 피연산자가 반드시 boolean 값일 필요는 없으며 반환 값도 항상 boolean 타입인 것은 아니다.
Truthy
& Falsy
자바스크립트에는 truthy
와 falsy
라는 개념이 있다. 참/거짓을 판단하는 컨텍스트에서 truthy
한 값은 true로, falsy
한 값은 false로 판단된다.
falsy
로 판단되는 값은 다음과 같다.
falsy
한 값을 제외한 모든 값은 truthy 이다.
&&
(AND) 연산자와 ||
(OR)연산자true
이면 true
, 한 쪽이라도 false
이면 false
를 반환한다.false
이면 false
, 한 쪽이라도 true
이면 true
를 반환한다.console.log(true && true) // true
console.log(true && false) // false
console.log(false && true) // false
console.log(false && false) // false
console.log(true || true) // true
console.log(true || false) // true
console.log(false || true) // true
console.log(false || false) // false
그러나 실제로 이는 피연산자를 boolean 타입의 true 혹은 false로 변환하는 것이 아니라 두 피연산자 중 하나를 선택하여 반환하는 식으로 작동한다. truthy 와 falsy 한 값에 논리 연산자를 적용해 보면 이를 확인할 수 있다.
console.log(3 && 6) // 6
console.log(3 && 0) // 0
console.log("" && "truthy") // ""
console.log(NaN && undefined) // NaN
console.log([] || 3) // []
console.log([] || null) // []
console.log(undefined || {}) // {}
console.log(null || undefined) // undefined
truthy 와 falsy 한 값에 논리 연산자를 적용하면, true 혹은 false로 변환 되어 반환되는 것이 아니다. 위와 같이 입력한 그대로의 두 값 중 하나를 선택하여 반환하는 것을 볼 수 있다!
이 원리를 응용해 보자.
const globalErrorHandler = (err, req, res, next) => {
if (err.statusCode) {
res.status(err.statusCode).json({ message: err.message});
} else {
res.status(500).json({ message: err.message});
}
};
const globalErrorHandler = (err, req, res, next) => {
res.status(err.statusCode || 500).json({ message: err.message});
};
!
(NOT) 연산자truthy 한 값이 들어오면 false를 반환하고, falsy 한 값이 들어오면 true 를 반환한다.
const getUserPoint = async (userId) => {
const [result] = await appDataSource.query(
`SELECT
amount
FROM points
WHERE points.user_id = ?;`,
[userId]
);
if (!result) {
throw new Error("존재하지 않는 유저입니다")
}
return result.amount;
}
! undefined
=== true
이므로 아래의 if문 내로 들어가 에러를 발생시게 된다. if (!result) {
throw new Error("존재하지 않는 유저입니다")
}
또한 ! 는 true 혹은 false를 반환한다는 점을 이용하여,
!!
과 같이 사용하여 truthy 한 값이 들어오면 true를 반환하고, falsy 한 값이 들어오면 false 를 반환하도록 truthy/falsy 한 값을 boolean 타입으로 형변환을 시키는 데 사용할 수도 있다.
const doesUserIdExist = async (userId) => {
const [result] = await appDataSource.query(
`SELECT EXISTS (
SELECT id
FROM users
WHERE users.id = ?
) as registerd
`,
[userId]
);
return !!parseInt(result.registerd);
!!
를 이용해 true 혹은 false로 변환해 주므로 이 함수의 결과물은 true 혹은 false로 깔끔하게 리턴된다!