TIL 11 | JavaScript : Control Flow

meow·2020년 7월 19일
0

JavaScript

목록 보기
2/46

Boolean Logic

프로그래밍에서 비교란 주어진 값들이 같은지, 다른지, 큰지, 작은지를 구분하는 것을 의미한다. 이때 비교 연산자를 사용하는데 비교 연산자의 결과는 truefalse 중의 하나다. true는 비교 결과가 참이라는 의미이고, false는 거짓이라는 뜻이다.

Comparison Operators


==는 동등연산자로 ""0, false를 구분하지 못한다. ===는 일치연산자(strict equality operator)로 형변환 없이 값을 비교한다.

Logical Operators

자바스크립트엔 세 종류의 논리 연산자 ||(OR), &&(AND), !(NOT)이 있다. 연산자에 '논리’라는 수식어가 붙긴 하지만 논리 연산자는 피연산자로 불린형뿐만 아니라 모든 타입의 값을 받을 수 있다. 연산 결과 역시 모든 타입이 될 수 있다.

false

  • false
  • 0
  • ""
  • null
  • undefined
  • Nan

이외의 모든 것은 true이다.

Conditionals

if

조건에 따라 결과를 설정할 수 있다. if문과 else 절로 조건을 걸고 그에 따른 코드를 실행한다. else 절은 if 조건에 거짓결과가 나올 때 실행된다.

let year = prompt('ECMAScript-2015 명세는 몇 년도에 출판되었을까요?', '');

if (year == 2015) {
  alert( '정답입니다!' );
} else {
  alert( '오답입니다!' ); // 2015 이외의 값을 입력한 경우
}

유사하지만 약간씩 차이가 있는 조건 여러 개를 처리해야 할 때가 있다. 이때 else if로 복수조건을 처리할 수 있다.

let year = prompt('ECMAScript-2015 명세는 몇 년도에 출판되었을까요?', '');

if (year < 2015) {
  alert( '숫자를 좀 더 올려보세요.' );
} else if (year > 2015) {
  alert( '숫자를 좀 더 내려보세요.' );
} else {
  alert( '정답입니다!' );
}

조건부 연산자 '?'

조건에 따라 다른 값을 변수에 할당해줘야 할 때가 있다.

let accessAllowed;
let age = prompt('나이를 입력해 주세요.', '');

if (age > 18) {
  accessAllowed = true;
} else {
  accessAllowed = false;
}

alert(accessAllowed);

'물음표(question mark) 연산자’라고도 불리는 '조건부(conditional) 연산자’를 사용하면 위 예시를 더 짧고 간결하게 변형할 수 있다.

조건부 연산자는 물음표?로 표시한다. 피연산자가 세 개이기 때문에 조건부 연산자를 '삼항(ternary) 연산자’라고 부르는 사람도 있다. 참고로, 자바스크립트에서 피연산자가 3개나 받는 연산자는 조건부 연산자가 유일하다.

문법

let result = condition ? value1 : value2;

평가 대상인 condition이 truthy라면 value1이, 그렇지 않으면 value2가 반환된다.

let accessAllowed = (age > 18) ? true : false;

age > 18 주위의 괄호는 생략 가능하다. 물음표 연산자는 우선순위가 낮으므로 비교 연산자 >가 실행되고 난 뒤에 실행된다.

아래 예시는 위 예시와 동일하게 동작한다.

// 연산자 우선순위 규칙에 따라, 비교 연산 'age > 18'이 먼저 실행됩니다.
// (조건문을 괄호로 감쌀 필요가 없습니다.)
let accessAllowed = age > 18 ? true : false;

비교 연산자 자체가 true나 false를 반환하기 때문에 위 예시에서 물음표 연산자를 사용하지 않아도 된다.

// 동일하게 동작함
let accessAllowed = age > 18;

다중 ‘?’

물음표 연산자?를 여러 개 연결하면 복수의 조건을 처리할 수 있다.

예시

let age = prompt('나이를 입력해주세요.', 18);

let message = (age < 3) ? '아기야 안녕?' :
  (age < 18) ? '안녕!' :
  (age < 100) ? '환영합니다!' :
  '나이가 아주 많으시거나, 나이가 아닌 값을 입력 하셨군요!';

alert( message );

위 코드는 아래와 동일하게 동작한다.

if (age < 3) {
  message = '아기야 안녕?';
} else if (age < 18) {
  message = '안녕!';
} else if (age < 100) {
  message = '환영합니다!';
} else {
  message = '나이가 아닌 값을 입력 하셨군요!';
}

부적절한 '?'

물음표 연산자?는 조건에 따라 반환 값을 달리하려는 목적으로 만들어졌다. 이런 목적에 부합하는 곳에 물음표를 사용해야한다. 여러 분기를 만들어 처리할 때는 if를 사용하자.

'?' 사용

let company = prompt('자바스크립트는 어떤 회사가 만들었을까요?', '');

(company == 'Netscape') ?
   alert('정답입니다!') : alert('오답입니다!');

if 사용

let company = prompt('자바스크립트는 어떤 회사가 만들었을까요?', '');

if (company == 'Netscape') {
  alert('정답입니다!');
} else {
  alert('오답입니다!');
}

출처 : https://ko.javascript.info/ifelse#ref-167

While Loops

여러 동작을 반복해야 하는 경우 while 반복문 또는 for 반복문을 사용할 수 있다.

while 반복문의 문법

while (condition) {
  // 코드
  // '반복문 본문(body)'이라 불림
}

예시 1

console.log("Print all odd numbers between 300 and 333");

var third = 300;

while(third <= 333) {
    if(third % 2 == 1) { // third를 2로 나누었을때 나머지가 1
    console.log(third);
    }
    third++; // third = third + 1
}

예시 2

var answer = prompt("Are we there yet?");


while(answer.indexOf("yes") === -1) {
    var answer = prompt("are we there yet?");
    }

alert("yay!")
  • indexOf : 부분 문자열의 있으면 위치를 알려준다. 없으면 -1 을 출력한다.
let str = 'Widget with id';

alert( str.indexOf('Widget') ); // 0, str은 'Widget'으로 시작함
alert( str.indexOf('widget') ); // -1, indexOf는 대·소문자를 따지므로 원하는 문자열을 찾지 못함

alert( str.indexOf("id") ); // 1, "id"는 첫 번째 위치에서 발견됨 (Widget에서 id)
  • ‘무한’ 반복문은 보통 while(true)를 써서 만든다. 무한 반복문은 여타 반복문과 마찬가지로 break 지시자를 사용해 멈출 수 있다.

For Loops

for 반복문의 문법

for (begin; condition; step) {
  // ... 반복문 본문 ...
}

예시 1

for (let i = 0; i < 3; i++) { // 0, 1, 2가 출력됩니다.
  alert(i);
}

while Loop vs For Loop

// For Loops
for(var count = 0; count < 6; count++) {
console.log(count);
}

// While Loops
var count = 1;

while(count < 6) {
console.log("count is: " + count);
count++
}

구성 요소 생략하기

for문의 구성 요소를 생략하는 것도 가능하다. 반복문이 시작될 때 아무것도 할 필요가 없으면 begin을 생략하는 것이 가능하다.

예시

let i = 0; // i를 선언하고 값도 할당하였습니다.

for (; i < 3; i++) { // 'begin'이 필요하지 않기 때문에 생략하였습니다.
  alert( i ); // 0, 1, 2
}

step 역시 생략이 가능하다.

let i = 0;

for (; i < 3;) {
  alert( i++ );
}

위와 같이 for문을 구성하면 while (i < 3)과 동일해진다. 모든 구성 요소를 생략할 수도 있는데, 이렇게 되면 무한 반복문이 만들어진다.

for (;;) {
  // 끊임 없이 본문이 실행됩니다.
}

for문의 구성요소를 생략할 때 주의할 점은 두 개의 ; 세미콜론을 꼭 넣어주어야 한다는 점이다. 하나라도 없으면 문법 에러가 발생한다.

반복문 빠져나오기

대개는 반복문의 조건이 falsy가 되면 반복문이 종료된다. 그런데 특별한 지시자인 break를 사용하면 언제든 원하는 때에 반복문을 빠져나올 수 있다.
아래 예시의 반복문은 사용자에게 일련의 숫자를 입력하도록 안내하고, 사용자가 아무런 값도 입력하지 않으면 반복문을 '종료’한다.

let sum = 0;
while (true) {
  let value = +prompt("숫자를 입력하세요.", '');
  if (!value) break; // (*)
  sum += value;
}
alert( '합계: ' + sum );

(*)로 표시한 줄에 있는 break는 사용자가 아무것도 입력하지 않거나 Cancel버튼을 눌렀을 때 활성화된다. 이때 반복문이 즉시 중단되고 제어 흐름이 반복문 아래 첫 번째 줄로 이동한다.

반복문의 시작 지점이나 끝 지점에서 조건을 확인하는 것이 아니라 본문 가운데 혹은 본문 여러 곳에서 조건을 확인해야 하는 경우, '무한 반복문 + break’ 조합을 사용하면 좋다.

다음 반복으로 넘어가기

continue 지시자는 break의 '가벼운 버전’이다. continue는 전체 반복문을 멈추지 않는다. 대신에 현재 실행 중인 이터레이션을 멈추고 반복문이 다음 이터레이션을 강제로 실행시키도록 한다(조건을 통과할 때). continue는 현재 반복을 종료시키고 다음 반복으로 넘어가고 싶을 때 사용할 수 있다.

아래 반복문은 continue를 사용해 홀수만 출력한다.

for (let i = 0; i < 10; i++) {

  // 조건이 참이라면 남아있는 본문은 실행되지 않습니다.
  if (i % 2 == 0) continue;

  alert(i); // 1, 3, 5, 7, 9가 차례대로 출력됨
}

i가 짝수이면 continue가 본문 실행을 중단시키고 다음 이터레이션이 실행되게 한다(i가 하나 증가하고, 다음 반복이 실행됨). 따라서 alert 함수는 인수가 홀수일 때만 호출된다.

break/continue와 레이블

여러 개의 중첩 반복문을 한 번에 빠져나와야 하는 경우가 종종 생깁니다.

ij를 반복하면서 프롬프트 창에 (0,0)부터 (2,2)까지를 구성하는 좌표 (i, j)를 입력하게 해주는 예시를 살펴봅시다.

for (let i = 0; i < 3; i++) {

  for (let j = 0; j < 3; j++) {

    let input = prompt(`(${i},${j})의 값`, '');

    // 여기서 멈춰서 아래쪽의 `완료!`가 출력되게 하려면 어떻게 해야 할까요?
  }
}

alert('완료!');

사용자가 Cancel 버튼을 눌렀을 때 반복문을 중단시킬 방법이 필요합니다.

input 아래에 평범한 break 지시자를 사용하면 안쪽에 있는 반복문만 빠져나올 수 있습니다. 이것만으론 충분하지 않습니다(중첩 반복문을 포함한 반복문 두 개 모두를 빠져나와야 하기 때문이죠 – 옮긴이). 이럴 때 레이블을 사용할 수 있습니다.

레이블(label) 은 반복문 앞에 콜론과 함께 쓰이는 식별자입니다.

labelName: for (...) {
  ...
}

반복문 안에서 break <labelName>문을 사용하면 레이블에 해당하는 반복문을 빠져나올 수 있습니다.

outer: for (let i = 0; i < 3; i++) {

  for (let j = 0; j < 3; j++) {

    let input = prompt(`(${i},${j})의 값`, '');

    // 사용자가 아무것도 입력하지 않거나 Cancel 버튼을 누르면 두 반복문 모두를 빠져나옵니다.
    if (!input) break outer; // (*)

    // 입력받은 값을 가지고 무언가를 함
  }
}
alert('완료!');

위 예시에서 break outerouter라는 레이블이 붙은 반복문을 찾고, 해당 반복문을 빠져나오게 해줍니다. 따라서 제어 흐름이 (*)에서 alert('완료!')로 바로 바뀝니다.

레이블을 별도의 줄에 써주는 것도 가능합니다.

outer:
for (let i = 0; i < 3; i++) { ... }

continue 지시자를 레이블과 함께 사용하는 것도 가능합니다. 두 가지를 같이 사용하면 레이블이 붙은 반복문의 다음 이터레이션이 실행됩니다.

  • 레이블은 마음대로 '점프’할 수 있게 해주지 않습니다.
    레이블을 사용한다고 해서 원하는 곳으로 마음대로 점프할 수 있는 것은 아닙니다.

아래 예시처럼 레이블을 사용하는 것은 불가능합니다.

break label; // 아래 for 문으로 점프할 수 없습니다.
label: for (...)

breakcontinue는 반복문 안에서만 사용할 수 있고, 레이블은 반드시 break이나 continue 지시자 위에 있어야 합니다.

function 응용해보기

1. 거꾸로 출력하기

// *** printReverse() ***
console.log("Connected");

function printReverse(arr){
    for(var i = arr.length - 1; i >= 0; i--){
        console.log(arr[i]);
    }
}

printReverse([3,6,2,5])

2. 겹치는 element 찾기

// *** isUniform() ***

function isUniform(arr){
    var first = arr[0];
    for(var i = 0; i < arr.length, i++){
        if(arr[i] !== first){
            return false;
        }
    }
    return true;
}

function isUniform(arr){
    var first = arr[0];
    arr.forEach(function(element){
        if(element !== first){
            return false;
        }
    });
    return true;
}

3. 총합 계산하기

// *** sumArray() ***

function sumArray(arr){
    var total = 0;
    arr.forEach(function(element){
        total += element;
    });
    return total;
}

4. 최고값 알아내기

// *** max() ***

function max(arr){
    var max = arr[0];
    for(var i = 1; i < arr.length, i++){
        if(arr[i] > max){
        max = arr[i]
        }
    }
    return max;
}

참고자료 : https://ko.javascript.info/while-for

profile
🌙`、、`ヽ`ヽ`、、ヽヽ、`、ヽ`ヽ`ヽヽ` ヽ`、`ヽ`、ヽ``、ヽ`ヽ`、ヽヽ`ヽ、ヽ `ヽ、ヽヽ`ヽ`、``ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ`ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ、ヽ、ヽ``、ヽ`、ヽヽ 🚶‍♀ ヽ``ヽ``、ヽ`、

0개의 댓글