📌 참고 사이트
논리 연산자
ko.javascript.info
📋 논리 연산자
➡️ JS에는 세 가지의 논리 연산자 || (OR), && (AND), ! (NOT)이 있다.
➡️ 논리 연산자의 피연산자로 불린형뿐만 아니라 모든 타입의 값을 받을 수 있다.
📋 || (OR)
➡️ OR 연산자는 || 이다.
➡️ 피연산자 중 하나라도 true이면 true를 반환하고, 모두 false일 때만 false를 반환한다.
➡️ OR 연산자로 가능한 조합은 다음과 같다.
console.log(true || true); // true
console.log(true || false); // true
console.log(false || true); // true
console.log(false || false); // false
➡️ 피연산자가 불린형(true / false)이 아닐 경우 평가를 위해 불린형으로 변환한다.
if (1 || 0) { // if (true || false) 와 동일하게 동작한다.
alert('truthy!');
}
위와 같은 경우 1은 true, 0은 false로 변환후 동작한다. true || false는 true이므로 실행문이 실행된다.
➡️ OR 연산자는 주어진 조건 중 하나라도 참인지를 테스트하는 용도로 if문에서 자주 사용된다.
즉, if문에서 여러 조건을 넣을 때 하나만 만족해도 코드를 실행하도록 하기 위해 ||를 사용한다.
let hour = 12;
let isWeekend = true;
if (hour < 10 || hour > 18 || isWeekend) { // hour < 10과 hour > 18은 false이지만 isWeekend는 true이므로 true가 됨.
alert('영업시간이 아닙니다.'); // alert문 실행
}
📋 첫 번째 truthy를 찾는 OR 연산자 ||
📍 OR 연산자와 피연산자가 여러 개인 경우
let result = value 1 || value 2 || value 3 이런 형식으로 있으면 다음과 같은 알고리즘에 따라 연산을 수행한다.
1️⃣ 가장 왼쪽 피연산자인 value1부터 시작해 오른쪽으로 하나씩 나아가며 피연산자를 평가한다.
2️⃣ 평가 과정에서는 각 피연산자가 불린형이 아닐 경우 불린형으로 변환한다. 변환 후 그 값이 true이면 연산을 멈추고 해당 피연산자의 변환 전 원래 값을 반환하고 종료한다.
3️⃣ 피연산자를 평가하니 모두 false가 나와 모든 피연산자 평가를 마친 경우에는 마지막 피연산자를 반환한다.
💡 OR(||) 연산자를 여러 개 체이닝하면 가장 먼저 참인 값을 반환한다. 피연산자가 모두 거짓이라면 마지막 피연산자를 반환한다. (형 변환을 하지 않은 원래 값을 반환하는 것이 핵심!)
alert(1 || 0); // 1 (1은 참이므로, 그리고 거기서 종료되므로 0은 평가되지 않음.)
alert(null || 1); // 1 (null은 거짓이지만 1이 참이므로)
alert(null || 0 || 1); // 1 (null과 0은 거짓이지만 1이 참이므로)
alert(undefined || null || 0); // 0 (undefined, null, 0 모두 불린형에서 거짓이므로 마지막 값 반환)
위와 같은 OR 연산자의 기능을 이용하면 여러 용도로 OR 연산자를 활용할 수 있다.
➡️ 변수 또는 표현식으로 구성된 목록에서 첫 번째 truthy 얻기
let firstName = "";
let lastName = "";
let nickName = "바이올렛";
alert(firstName || lastName || nickName || "익명");
// firstName과 lastName은 빈 문자열이어서 false, nickName에서 true이므로 nickName의 값 "바이올렛" 반환
➡️ 단락 평가
OR 연산자 || 는 왼쪽부터 시작해서 오른쪽으로 평가를 진행하는데, truthy를 만나면 나머지 값들은 건드리지 않은 채 평가를 멈추는 프로세스를 '단락 평가' 라고 한다. (앞에서도 계속 봐온 원리이다.)
true || alert("not printed"); // 그냥 true만 반환되고 평가 멈춤.
false || alert("printed"); // 처음 값이 false이므로 다음 값 alert("printed") 실행
📋 && (AND)
➡️ AND 연산자는 &&이다.
➡️ AND 연산자는 두 피연산자가 모두 true일 때만 true를 반환하고, 하나라도 false이면 false를 반환한다.
➡️ AND 연산자로 가능한 조합은 다음과 같다.
console.log(true && true); // true
console.log(false && true); // false
console.log(true && false); // false
console.log(false && false); // false
➡️ OR과 마찬가지로 AND 연산자도 if문에 사용될 수 있고, 피연산자 타입에 제약이 없다. (불린형이 아닌 피연산자는 불린형으로 변환되어 평가된다.)
// ex 1)
let hour = 12;
let minute = 30;
if (hour == 12 && minute == 30) { // 둘 다 true이므로 아래의 실행문 실행
alert('현재 시각은 12시 30분입니다.');
}
// ex2)
if (1 && 0) { // 1과 0을 불린형으로 변환하면 각각 true, false이므로 false가 되어 실행문 실행 X
alert('if 문 안에 falsy가 들어가 있으므로 alert 창은 실행되지 않는다.);
}
📋 첫 번째 falsy를 찾는 AND 연산자 &&
📍 AND 연산자와 피연산자가 여러 개인 경우
result = value1 && value2 && value3 과 같은 형태의 코드가 있다고 하자. 이것은 다음과 같은 알고리즘을 통해 동작한다. (OR 연산자에서의 매커니즘과 유사)
1️⃣ 가장 왼쪽 피연산자부터 시작해 오른쪽으로 한칸씩 나아가며 피연산자를 평가한다.
2️⃣ 평과 과정에서, 각 피연산자는 하나씩 불린형으로 변환되고, 그 값이 false이면 평가를 멈추고 해당 피연산자의 변환 전 원래 값을 반환 후 종료하고, true이면 오른쪽의 값을 평가해 나간다.
3️⃣ 피연산자 모두가 true여서 모든 피연산자의 평가가 종료된 경우 마지막 피연산자가 반환된다.
💡 AND 연산자는 가장 먼저 거짓인 피연산자를 반환하고, 거짓인 피연산자가 존재하지 않는다면 마지막 피연산자를 반환한다.
console.log(1 && 0); // 0 (첫 번째는 true이지만 두 번째에서 false이므로 원래 값 0 반환)
console.log(1 && 5); // 5 (첫 번째와 두 번째 모두 true이므로 마지막 것 반환)
console.log(null && 5); // null (첫번째부터 false이므로 첫 번째 피연산자 반환하고 종료)
console.log(0 && "아무거나 와도 상관 없습니다."); // 0 (바로 위 코드와 같은 원리)
console.log(1 && 2 && null && 3); // null (1과 2는 true이지만 null에서 false이므로)
console.log(1 && 2 && 3); // 3 (1, 2, 3 모두 true이므로 마지막 값 반환)
📍 AND(&&)의 우선순위가 더 위
AND 연산자 &&의 우선순위는 OR 연산자 ||의 우선순위보다 더 높다.
따라서 a && b || c && d는 괄호를 사용한 (a && b) || (c && d)와 동일하게 작동한다.
📍 if문을 &&로 대체해서 작성하기
AND 연산자 &&를 if문을 짧게 줄이는 용도로 사용될 수 잇다.
let x = 1;
(x > 0) && console.log('0보다 큽니다!');
위의 경우 x가 1이므로 x > 0 조건이 true가 되어 console.log('0보다 큽니다!')가 실행되게 된다.
(console.log 부분에서는 평가 결과에 상관 없이 무조건 출력된다. 따라서 console.log 부분의 실행을 좌우하는 것은 x > 0의 true 여부이다.)
위 코드의 길이가 짧긴 하지만 if문을 사용한 예시가 가독성이 좋고 구현 의도를 더 잘 나타낼 수 있으므로 위와 같은 경우에는 if를 사용하고 AND 연산자는 목적에 맞게 사용해야 한다.
let x = 1;
if (x > 0) {
console.log('0보다 큽니다!');
}
📋 ! (NOT)
➡️ 논리 연산자 NOT은 !로 나타낸다.
➡️ NOT 연산자는 인수를 하나만 받는다.
➡️ NOT 연산자는 피연산자를 불린형 (true / false)로 변환 후 그의 역(반대)을 반환한다.
➡️ NOT 연산자 2개를 연달아 사용(!!)하면 값을 불린형으로 변환할 수 있다. (역의 역이므로 원래 값의 불린형이 그대로 나옴. 내장 함수 Boolean을 사용한 것과 같음.)
console.log(!true); // false (true의 역 반환)
console.log(!0); // true (0을 불린형으로 반환하면 false이므로 이의 역 true 반환)
console.log(!!"non-empty-string"); // true (비어있지 않은 문자열은 true)
console.log(!!null); // false (null은 불린형으로 false)
✏️ 과제
📍 다음 OR 연산의 결과는 무엇일까?
alert(null || 2 || undefined);
🅰️
답은 2 이다.
|| 는 OR 연산자이므로 왼쪽에서부터 시작하여 가장 먼저 true가 되는 값을 반환한다.
null은 불린형에서 false이므로 오른쪽 값의 평가로 넘어가고, 2는 불린형으로 true이므로 원래 값인 2가 반환되고 평가가 종료된다.
📍 OR 연산자의 피연산자가 alert라면?
다음 코드의 결과를 예측해 보자.
alert(alert(1) || 2 || alert(3));
🅰️
답은 알림 창에 1과 2가 차례로 출력된다는 것이다.
알아두어야 할 것은 alert 메서드는 특정 값을 반환하지 않고 undefined를 반환한다.
1️⃣ 첫번째 피연산자인 alert(1)을 평가한다. 이때 얼럿 창에 1이 출력된다.
2️⃣ alert 메서드는 undefined를 반환하기 때문에 평가 결과가 false가 되고, OR 연산자는 truthy한 값을 찾기 위해 다음 피연산자를 평가하게 된다.
3️⃣ 두번째 피연산자인 2를 평가하는데, 이것은 불린형에서 true이므로 실행이 멈추고 2가 반환된다. 이 2는 가장 바깥에 있는 alert 함수의 피연산자가 되어 두 번째로 얼럿 창에 출력되게 된다.
이로써 alert(3)까지 평가가 진행되지 않으므로 3은 출력되지 않는다.
📍 다음 AND 연산의 결과는 무엇일까?
alert(1 && null && 2);
🅰️
답은 null이 알림창에 출력된다는 것이다.
AND 연산자를 사용하면 왼쪽에서부터 시작하여 가장 먼저 false가 되는 값이 반환되게 된다.
첫번째 피연산자는 1이므로 평가 결과는 true가 되어 false인 값을 찾기 위해 다음 피연산자를 검사하는데, null은 불리언형으로 false이기 때문에 null을 출력하고 종료한다.
📍 AND 연산자의 피연산자가 alert라면?
아래 코드의 결과를 예측해 보자.
alert(alert(1) && alert(2));
🅰️
답은 1과 undefined가 차례로 알림 창에 출력되는 것이다.
첫 번째 피연산자인 alert(1)에서 1이 알림창에 출력 후 undefined가 반환된다. undefined는 불리언값으로 false이므로 여기에서 평가가 종료되게 된다. (AND 연산자에서)
그리고 alert(1)은 undefined를 반환하므로 가장 바깥에 있는 alert문의 인자로 undefined가 들어가서 undefined가 알림창에 뜨고 끝나게 되는 것이다.
📍 OR, AND, OR 연산자로 구성된 표현식
아래 코드의 결과를 예측해 보자.
alert(null || 2 && 3 || 4);
🅰️
답은 알림창에 3이 출력된다는 것이다.
AND 연산자(&&)가 OR 연산자(||) 보다 우선순위가 더 높기 때문에 2 && 3이 가장 먼저 실행되게 된다.
AND 연산자는 왼쪽에서부터 가장 먼저 false가 되는 값을 찾고, 그런 값이 없을 경우 (모두 true일 경우) 마지막 값을 반환하기 때문에 2 && 3에서는 3이 반환된다.
그러고 나서 null || 3 || 4가 실행되는데, 첫 번째 피연산자인 null은 불리언값으로 false이므로 다음 값을 평가하게 되고, 3은 불리언값으로 true이기 때문에 3이 반환되고 평가가 종료되게 된다. (OR 연산자에서는 첫 번째로 true가 되는 값이 반환된다.)
마지막으로는 alert(3)이 실행되고, 3이 알림창에 출력되게 된다.
📍 사이 범위 확인하기
age(나이)가 14세 이상 90세 이하에 속하는지를 확인하는 if문을 논리 연산자를 사용하여 작성해라.
if (age >= 14 && age <= 90)
➡️ 14세부터 90세 사이에 속하는지를 확인해야 하므로 age >= 14와 age <= 90의 조건을 모두 만족해야지 참이 되도록 코드를 짜야 한다. 따라서 AND 연산자를 사용하였다.
📍 바깥 범위 확인하기
age(나이)가 14세 이상 90세 이하에 속하지 않는지를 확인하는 if문을 작성하라.
답안은 NOT 연산자(!)를 사용한 답안과 사용하지 않은 답안 2가지를 작성하라.
<NOT 연산자를 사용하지 않은 답안>
if (age < 14 || age > 90)
age가 14세 이상 90세 이하에 속하지 않게 하기 위해서는 age가 14세 미만이거나 90세를 초과하면 된다.
둘 중에 하나만 만족해도 참이 되므로 OR 연산자를 사용하였다.
<NOT 연산자를 사용한 답안>
if (!(age >= 14 && age <= 90))
age의 값이 14 이상과 90 이하에 모두 속하지 않을(! 연산자와 AND 연산자 이용) 경우를 나타낸다.
이것을 if (!(14 <= age <= 90)) 와 같은 식으로 작성하면 우리가 원하는 의도대로 실행되지 않음에 주의해야 한다. JS에서는 비교 연산자를 체인 형태로 연결할 수 없기 때문이다.
* 14 <= age <= 90에서 연산자는 <=만 쓰였으므로 동일한 연산자는 동일한 우선순위를 가지므로 좌측부터 실행된다. 따라서 age값에 따라 14 <= age는 ture 또는 false를 반환한다.
이제 true <= 90 또는 false <= 90의 평가가 이루어지는데, 비교 연산자 실행 시 피연산자가 숫자로 형변환이 되므로 각각 1 <= 90 과 0 <= 90의 비교라고 할 수 있다. 1과 0 모두 90보다 작거나 같으므로 결론적으로는 age값에 무관하게 14 <= age <= 90은 항상 true가 된다.
여기에 ! (NOT 연산자)를 붙이면 반대로 항상 false가 되므로 이후에 이어질 블록 안의 실행문이 실행되지 않게 된다.
📍 "if"에 관한 고찰
아래 표현식에서 어떤 alert가 실행되며, if(...) 안에 표현식이 있다면 어떤 일이 일어날까?
if (-1 || 0) alert('first');
if (-1 && 0) alert('second');
if (null || -1 && 1) alert('third');
1️⃣ 알림창에 first가 출력된다.
OR연산자이고, 첫번째 피연산자 -1에서 true이므로 true로 평가가 종료되고 실행문인 alert가 실행되게 된다.
2️⃣ 명시적으로 일어나는 일이 없다.
AND 연산자이고, 첫번째 피연산자 -1은 true이지만 두번째 피연산자 0에서 false이므로 결과가 false가 되어 alert문이 실행되지 않는다.
3️⃣ 알림창에 third가 출력된다.
OR 연산자보다 AND 연산자의 우선순위가 높으므로 -1 && 1이 먼저 평가된다. -1과 1 모두 불리언형으로 true이기 때문에 평가 결과는 true가 되고, 마지막 피연산자인 1이 반환된다.
그 다음으로 null || 1에서 null은 false이지만 1은 true이므로 평가 결과가 true가 되어 alert문이 실행되게 된다.
📍 로그인 구현하기
프롬프트(prompt) 대화상자를 이용하여 간이 로그인 창을 구현해 보자.
프롬프트(prompt) 대화상자를 이용해 간이 로그인 창을 구현해 보자.
사용자가 "Admin"을 입력하면 비밀번호를 물어보는 프롬프트 대화상자를 띄운다. 이때 아무런 입력도 하지 않거나 Esc를 누르면 "취소되었습니다."라는 메시지를 보여준다. 틀린 비밀번호를 입력했다면 "인증에 실패하였습니다." 라는 메시지를 보여준다.
비밀번호 확인 절차는 다음과 같다.
1️⃣ 맞는 비밀번호 "TheMaster"를 입력했다면 "환영합니다!"라는 메시지를 보여준다.
2️⃣ 틀린 비밀번호를 입력했다면 "인증에 실패하였습니다."라는 메시지를 보여준다.
3️⃣ 빈 문자열을 입력하거나 입력을 취소했다면 "취소되었습니다." 라는 메시지를 보여준다.
* 힌트: 프롬프트 창에 아무것도 입력하지 않으면 빈 문자열인 ''가, ESC를 누르면 null이 반환된다.
💻 HTML
<!DOCTYPE html>
<html>
<head>
<title>로그인 구현하기</title>
</head>
<body>
<script src="./로그인 구현하기.js"></script>
</body>
</html>
💻 JS
// 사용자 이름이 Admin인지 확인하기
let checkUserName = prompt('사용자 이름을 입력해 주세요.');
const correctName = 'Admin';
const correctPassword = 'TheMaster';
if (checkUserName === null || checkUserName === '') {
alert('취소되었습니다.');
} else if (checkUserName !== correctName) {
alert('권한이 없는 사용자입니다.');
} else {
// 비밀번호 확인하기
let checkPassword = prompt('비밀번호를 입력해 주세요.');
if (checkPassword === null || checkPassword === '') {
alert('취소되었습니다.');
} else if (checkPassword !== correctPassword) {
alert('인증에 실패하였습니다.');
} else {
alert('환영합니다!');
}
}
* 사이트에 나와있는 정답 코드
let userName = prompt("사용자 이름을 입력해주세요.", '');
if (userName == 'Admin') {
let pass = prompt('비밀번호:', '');
if (pass == 'TheMaster') {
alert( '환영합니다!' );
} else if (pass == '' || pass == null) {
alert( '취소되었습니다.' );
} else {
alert( '인증에 실패하였습니다.' );
}
} else if (userName == '' || userName == null) {
alert( '취소되었습니다.' );
} else {
alert( "인증되지 않은 사용자입니다." );
}
'Javascript study' 카테고리의 다른 글
[Javascript] while과 for 반복문 (0) | 2023.07.14 |
---|---|
[Javascript] nullish 병합 연산자 '??' (0) | 2023.07.12 |
[Javascript] if와 '?'를 사용한 조건 처리 (0) | 2023.07.09 |
[Javascript] 비교 연산자 (0) | 2023.07.08 |
[Javascript] 기본 연산자와 수학 (0) | 2023.07.06 |
댓글