전체 페이지뷰

2018년 10월 20일 토요일

JavaScript의 조건문과 논리연산자

조건문 if와 삼항 연산자 ?에 대해서 알아봅니다.

if 문


조건을 평가하여 참이면 코드를 실행합니다.
let year = prompt('ECMAScript-2015 specification이 정해진 해는?''');
if (year == 2015alert'맞았습니다!' );
cs
if (조건) 다음에 줄바꿈을 하지 않는군요. 문장이 여러 줄이면 { }로 감싸줍니다.
if (year == 2015) {
  alert"맞았습니다." );
  alert"똑똑하시네요!" );
}
cs

문장이 하나라도 가급적 { }로 감싸서 가독성을 높이는 편을 권장합니다.

Boolean 변환

if 문 다음에 오는 괄호에서는 표현식을 평가하여 boolean 변환을 합니다. 타입변환 설명을 상기합시다.

0, 빈 문자열, null, undefined, NaNfalse, 그 외의 것은 true입니다.

따라서 아래 대괄호 안은 실행되지 않습니다.
if (0) { // 0은 false
  ...
}
cs

반면 아래는 무조건 실행됩니다.
if (1) { // 1은 true
  ...
}
cs

미리 평가한 변수를 넘겨주는 것도 가능합니다.
let cond = (year == 2015); //true or false 
if (cond) {
  ...
}
cs


else

하나의 조건이 더 붙었을 때 사용합니다.

if (조건) { ...
} else { ...
}

let year = prompt('ECMAScript-2015 specification이 만들어진 해는?''');
if (year == 2015) {
  alert'맞았습니다!' );
else {
  alert'이걸 틀려?' ); // any value except 2015
}
cs


여러 개의 조건: else if

if (조건) { ...
} else if (조건) { ...
} else {...
}
의 문법을 사용합니다.

let year = prompt('ECMAScript-2015 specification이 만들어진 해는?''');
if (year < 2015) {
  alert'너무 빠름...' );
else if (year > 2015) {
  alert'너무 늦음' );
else {
  alert'정확해요!' );
}
cs

else if는 몇개고 더 올 수 있으며, 마지막이 else로 끝나지 않아도 상관없습니다.


삼항연산자: ?


다른 언어에서 쓰이는 삼항연산자와 마찬가지입니다.

조건 ? 값1: 값2

의 형태로 간단히 쓰입니다.
let accessAllowed = (age > 18) ? true : false;
cs

age가 18보다 크면 true, 아니면 falseaccessAllowed에 저장합니다.

* 참고 
위의 예는 그냥 단순히 
let accessAllowed = age > 18;
cs
로만 써도 똑같습니다.


여러 개의 ? 연산자


중첩을 허용하므로 여러 개의 ? 연산이 가능합니다.
let age = prompt('age?'18);
let message = (age < 3) ? 'Hi, baby!' :
  (age < 18) ? 'Hello!' :
  (age < 100) ? 'Greetings!' :
  'What an unusual age!';
alert( message );
cs



?연산자의 비전통적 용법


가끔 ?if를 대체하여 쓰이기도 합니다.

let company = prompt('Which company created JavaScript?''');
(company == 'Netscape') ?
   alert('Right!') : alert('Wrong.');
cs
let company = prompt('Which company created JavaScript?''');
if (company == 'Netscape') {
  alert('Right!');
else {
  alert('Wrong.');
}
cs

는 같은 기능을 수행합니다.

그러나 위와 같이 if를 대체하는 용도로 ?를 사용하는 것은 가독성을 떨어뜨리므로 삼가합시다.



논리 연산자


세 개의 논리 연산자, &&(AND), ||(OR), !(NOT)이 존재합니다.
이 연산은 boolean 타입 말고도 모든 타입의 자료에 적용할수 있고, 결과 또한 모든 타입이 가능합니다.


|| : OR

result = a || b
의 형태로 사용됩니다.

전통적인 프로그래밍 영역에서 논리 OR은 boolean만을 다룹니다. 인자 중 하나라도 true가 있으면 true를 반환하고, 전부 false이면 false죠.

alerttrue || true );   // true
alertfalse || true );  // true
alerttrue || false );  // true
alertfalse || false ); // false
cs

자바스크립트에서는 좀 더 다양하게 사용할 수 있습니다.

예를 들어, 1을 true, 0은 false로 간주하여 사용하기도 합니다.
if (1 || 0) { // ( true || false )와 같은 
  alert'truthy!' );
}
cs

대부분의 경우 ||if 문 안에서 비교문과 함께 사용됩니다.
let hour = 12;
let isWeekend = true;
if (hour < 10 || hour > 18 || isWeekend) {
  alert'The office is closed.' ); // it is the weekend
}
cs


OR은 처음 나오는 true를 찾습니다.

위에 언급한 것들은 다분히 전통적인 사용방식이며, 이제 자바스크립트 고유의 것들을 좀 더 알아봅니다.

result = value1 || value2 || value3

의 다중 OR 문이 있다고 할 때


  • 좌에서 우로 피연산자를 평가합니다.
  • 각각의 피연산자는 boolean으로 변환됩니다. 그 결과가 true 이면 평가를 멈추고 boolean 변환 전 원래의 값을 반환합니다.
  • 평가 결과 전부 false이면 가장 마지막 값을 반환합니다.

예를 들어,
alert1 || 0 ); // 1 (1이 true)
alerttrue || 'no matter what' ); // true 
alertnull || 1 ); // 1 (1이 처음 나오는 true값)
alertnull || 0 || 1 ); // 1 (위와 같음)
alert( undefined || null || 0 ); // 0 (전부 false, 마지막 값 반환)
cs

이런 사용법 때문에 전통적 OR기법과는 다른 재미있는 결과가 나오게 됩니다.

1. 인자들로부터 처음 나오는 true값을 찾음

null/undefined가 포함된 여러 개의 변수가 있다고 가정합시다. 이들로부터 실제 데이터가 들어있는 첫번째 변수를 찾고자 할 때 다음과 같이 OR을 사용할 수 있습니다.

let currentUser = null;
let defaultUser = "John";
let name = currentUser || defaultUser || "unnamed";
alertname ); // "John" 
cs

만약 변수 defaultUsernull이나 undefined라고 하면 "unnamed"가 출력됩니다.

2. 간단한 순회 평가

값들뿐 아니라 간단한 표현식들도 피연산자가 될수 있습니다. OR은 좌에서 우로 그것들을 평가하다가 true에 해당하는 값이 나오면 평가를 멈추고 그 값을 반환하는데 이 과정을 short-circuit evaluation이라고 합니다.

다음의 예를 봅시다.
let x;
 
true || (x = 1);
 
alert(x); // undefined, (x = 1)이 평가 되지 않음 
cs

첫번째 인자를 false로 놓으면 두번째가 실행됩니다.
let x;
 
false || (x = 1);
 
alert(x); // 1
cs

이것은 아주 간단한 케이스로서 if 문을 간단하게 대치할 수 있습니다.
물론 대부분의 경우 보통의 if문으로 하는 것이 가독성을 좋게 한다는 점은 잊지 맙시다.



&&: AND


다들 아시다시피 둘 다 true여야 true를 반환하는 연산자입니다.

alerttrue && true );   // true
alertfalse && true );  // false
alerttrue && false );  // false
alertfalse && false ); // false
 
let hour = 12;
let minute = 30;
 
if (hour == 12 && minute == 30) {
  alert'Time is 12:30' );
}
cs


OR에서와 마찬가지로 boolean말고도 어떤 값도 올 수 있습니다.

AND는 처음으로 나오는 false값을 찾습니다.

result = value1 && value2 && value3

처럼 여러개의 피연산자로 이루어진 && 문장이 있다고 할 때,

OR에서와 마찬가지로 좌에서 우의 방향으로 피연산자를 boolean 변환하여 평가하고, false가 나오는 순간 멈추어 원래의 값을 반환합니다. 모두가 true이면 마지막 피연산자 값을 반환합니다.

// if the first operand is truthy,
// AND returns the second operand:
alert1 && 0 ); // 0
alert1 && 5 ); // 5
 
// if the first operand is falsy,
// AND returns it. The second operand is ignored
alertnull && 5 ); // null
alert0 && "no matter what" ); // 0
cs


AND의 연산 우선순위는 OR보다 높습니다.
그래서 a && b || c && d 라는 식이 있다면,
이것은 ( a && b ) || (c && d) 와 동일합니다.

OR에서처럼 AND도 if를 대체하여 쓰이는 경우가 간혹 있는데
let x = 1;
 
(x > 0&& alert'Greater than zero!' );
cs

let x = 1;
 
if (x > 0) {
  alert'Greater than zero!' );
}
cs
는 동일한 기능을 수행합니다.


!: NOT


문법은 매우 간단합니다.
result = !value;

이 연산자는 한 개의 피연산를 받아 boolean으로 변환한 후 반대의 결과를 리턴합니다.
alert!true ); // false
alert!0 ); // true
cs

두개의 !이 사용되는 경우가 있습니다.
alert!!"non-empty string" ); // true
alert!!null ); // false
cs

첫 !이 주어진 값에 NOT을 연산하고, 그것을 두번째 !으로 NOT으로 연산하여 주어진 값을 boolean으로 변환하는 효과를 줍니다.

그러나 이보다는 주어진 내장 Boolean()함수를 사용하는 편이 좋겠죠.
alertBoolean("non-empty string") ); // true
alertBoolean(null) ); // false
cs

!의 우선 순위는 논리연산자 중 가장 높아 언제나 &&, ||보다 먼저 수행됩니다.

==========================================================
이어진 연습문제 중에 흥미로운 것이 있어 소개합니다.

* 다음의 코드는 무엇을 출력할까요?

alertalert(1|| 2 || alert(3) );
cs

첫 OR이 alert(1)을 판정하면서 1을 표시하는 창을 띄웁니다.
그러나 alert(1)은 값을 반환하는 것이 아니라서 undefined이고 따라서 false이므로 다음으로 넘어갑니다.
2를 판정하면 true이므로 alert(3)까지 도달하지 않고 멈춰서 창에 2를 띄웁니다.

*아래의 코드 결과는?
alertnull || 2 && 3 || 4 );
cs


&&의 우선순위가 높으므로 2&&3부터 평가합니다. 그 결과는 3이므로
null || 3 || 4 가 되고, 그 중 첫번째 true 값인 3이 반환되어 화면에 3만 출력됩니다.

댓글 없음:

댓글 쓰기