개발자 연쨘

[딥 다이브] 연산자2, 제어문 본문

스터디/모던 자바스크립트 Deep Dive

[딥 다이브] 연산자2, 제어문

연쨘 2024. 1. 3. 01:07

🐰 지수 연산자🐰

ES7에서 도입된 지수 연산자는 좌항의 피연산자를 밑으로,
우항의 피연산자를 지수로 거듭 제곱하여 숫자 값을 반환한다.

2 ** 2;   // -> 4
2 ** 2.5; // -> 5.65685424949238
2 ** 0;   // -> 1
2 ** -2;  // -> 0.25

 

 

지수 연산자가 도입되기 이전에는 Math.pow 메서드 사용

Math.pow(2, 2);   // -> 4
Math.pow(2, 2.5); // -> 5.65685424949238
Math.pow(2, 0);   // -> 1
Math.pow(2, -2);  // -> 0.25

 

 

아래 예시에서는 ** 이 지수 연산자가  Math.pow메서드보다 가독성이 좋다.

// 지수 연산자의 결합 순서는 우항에서 좌항이다. 즉, 우결합성을 갖는다.
2 ** (3 ** 2); // -> 512
Math.pow(2, Math.pow(3, 2)); // -> 512

 

 

음수를 거듭제곱의 밑으로 사용해 계산하려면 다음과 같이 괄호로 묶어야한다!

-5 ** 2;
// SyntaxError: Unary operator used immediately before exponentiation expression.
// Parenthesis must be used to disambiguate operator precedence

(-5) ** 2; // -> 25

 

 

지수 연산자는 다른 산술 연산자와 마찬가지로 할당 연산자와 함께 사용 ⭕

var num = 5;
num **= 2; //num = num ** 2; -> 25

 

 

지수 연산자이항 연산자 중에서 우선순위가 가장 높다.

2 * 5 ** 2; // -> 50

 

 

이밖에도 ?., ??, delete, new, instanceof, in ... 등 다양한 연산자가 있다.
앞으로 나올 다른 주제와 밀접한 관계가 있어 해당 주제를 소개 할 때 알아보기로 하자!


🐰 연산자의 부수 효과 🐰

대부분의 연산자는 다른 코드에 영향 ❌
예를 들어 1*2는 값2를 생성할 뿐, 다른 코드에 영향을 주진 않는다.

하지만 일부 연산자는 다른 코드에 영향을 주는 부수 효과가 있다.

 

부수 효과가 있는 연산자
할당 연산자(=), 증가/감소 연산자(++/--), delete(프로퍼티 삭제) 연산자가 있다.

let x;

// 할당 연산자는 변수 값이 변하는 부수 효과가 있다.
// 이는 x 변수를 사용하는 다른 코드에 영향을 준다.
x = 1;
console.log(x); // 1

// 증가/감소 연산자(++/--)는 피연산자의 값을 변경하는 부수 효과가 있다.
// 피연산자 x의 값이 재할당되어 변경된다. 이는 x 변수를 사용하는 다른 코드에 영향을 준다.
x++;
console.log(x); // 2

var o = { a: 1 };

// delete 연산자는 객체의 프로퍼티를 삭제하는 부수 효과가 있다.
// 이는 o 객체를 사용하는 다른 코드에 영향을 준다.
delete o.a;
console.log(o); // {}

 


🐰 연산자 우선순위 🐰

연산자 우선순위란 여러 개의 연산자로 이뤄진 문이

실행될 때 연산자가 실행되는 순서를 말한다.
우선순위가 높을수록 먼저 실행된다.

우선순위 연산자
1 ()
2 new(매개변수 존재), .(dot), [ ](프로퍼티 접근), ( )(함수 호출), ?.(옵셔널 체이닝 연산자)
3 new(매개변수 미존재)
4 x++, x--
5 !x, +x, -x, ++x, --x, typeof, delete
6 ** (이항 연산자 중에서 우선순위가 가장 높다)
7 *, /, %
8 +, -
9 <, <=, >, >=, in(프로퍼티 존재 확인),
instanceof(좌변의 객체과 우변의 생성자 함수와 연결된 인스턴스 인지 판별)
10 ==, !=, ===, !==
11 ??(null 병합 연산자)
12 &&
13 ||
14 ? ... : ...
15 할당연산자 (=, +=, -=, ...)
16 ,

 

 

연산자는 종류가 너무 많아 기억하기 어렵고 실수하기도 쉽다.
연산자 우선순위가 가장 높은 그룹 연산자를 사용하여

우선순위를 명시적으로 조절하는것을 권장한다.

 

// 그룹 연산자를 사용하여 우선순위를 명시적으로 조절
10 * (2 + 3); // -> 50

 

아래로 갈수록 우선 순위 낮아짐!

1. ()
2. 단항 연산자 ( --, ++, +, -, ! )
3. 지수 연산자 (**)
4. 산술 연산자 ( *, /, %, +, - )
5. 비교 연산자 ( >, >=, <, <=, ==, ===, !==, != )
6. 논리 연산자 ( &&, || )
7. 삼항 연산자 (?...:...)
8. 대입 연산자 ( =, +=, -=, *=, /=, %= )

 

-x + 3 // 단항연산자가 더 높으므로 x의 부호를 바꾸고 -> 이항 연산자 덧셈 실행
x + 3 * y // * -> +
x + 3 > y -2 // 비교연산자(>) 보다 산술 연산자 '+', '-'가 먼저 수행
x > 3 && x < 5//비교연산자(>, <) -> 논리연산자(&&)
result = x + y * 3; // * -> + -> 대입 연산자(=)

 

🌼 비트 연산자 제외한 우선순위 ↓

더보기

자바스크립트 연산자 우선순위(비트 연산자 제외)

순위 기능 연산자
1 괄호 ()
2 증감/ 논리 연산자 not ++, --, !
3 지수 연산자 **
4 산술 연산자 곱셈 *, /, %
5 산술 연산자 덧셈 +, -
6 비교 연산자 대소 <, <=, >, >=
7 비교 연산자 같음 ==, ===, !=, !==
8 논리 연산자 and &&
9 논리 연산자 or ||
10 대입연산자 =, +=, -=, *=. /=, %=

 


🐰 연산자 결합 순서 🐰

연산자 결합 순서란 연산자의 어느 쪽(좌항 또는 우항)부터 평가를 수행할 것인지를 나타내는 순서이다.

결합 순서 연산자
좌항 우항 +, -, /, %, <, <=, >, >=, &&, ||, ., [], (), ??, ?., in, instanceof
좌항 우항  ++, --, 할당연산자(=, +=, -=, ...), !x, +x, -x, ++x, --x, typeof, delete, ? ... : ..., **

 

 

단항연산자, 지수 연산자, 할당연산자만 우항에서 좌항!

 

 

✍🏻 우선 순위가 같은 연산자 일 때, 어떤 것을 먼저??

//우선 순위가 같은 연산자 일 때, 어떤 것을 먼저??
3 + 4 - 5 // + -> -
x = y = 3 // y = 3 -> x = 3

 

+와 -의 우선순위는 같이 이럴 때 결합규칙을 보면 왼쪽에서 오른쪽으로 계산된다.
대입연산자일 경우 오른쪽에서 완쪽으로 계산이 되므로 오른쪽 부터 계산이 진행된다.

 

 

연산자와 우선순위의 결합법칙 요약!
1.
산술 > 비교 > 논리 > 대입 ! 대입이 맨 마지막에 수행!
2. 단항 (피연산자 1개) > 이항 (피연산자 2개) !
단항 연산자의 우선순위가 이항연산자보다 높다.
3. 단항연산자와 지수연산자, 대입 연산자를 제외한
모든 연산의 진행 방식은 왼쪽에서 오른쪽이다. 

 


🐰 제어문 🐰

제어문은 주어진 조건에 따라 코드 블록을 실행(조건문)하거나 반복 실행(반복문)할 때 사용한다.
일반적으로 코드는 위에서 아래 방향으로 순차적으로 실행된다.

제어문은 코드의 실행 순서를 인위적으로 제어할 수 있다.

 

하지만 코드의 실행 순서를 인위적으로 제어하면 직관적인 코드의 흐름을 혼란스럽게
만들 수 있고 가독성을 해친다.

 

이러한 문제점을 나중에 살펴볼 forEach, map, filter, reduce 같은 고차 함수를 사용한
함수형 프로그래밍 기법에서
제어문의 사용을 억제하여 복잡성을 조금은 해결 할 수 있다.

 

 


🐰 블록문 🐰

블록문은 0개  이상의 문을 중괄호로 묶은 것으로, 코드 블록 또는 블록이라고 부르기도 한다.

자바스크립트블록문을 하나의 실행 단위로 취급한다.

 

블록문은 단독으로 사용할 수도 있으나

일반적으로 제어문이나 함수를 정의할 때 사용하는 것이 일반적이다.

 

보통 문의 끝에는 세미콜론을 붙이는 것이 일반적이나,

블록문은 언제나 문의 종료를 의미하는 자체 종결성을 갖기 때문에
블록문의 끝에 세미콜론을 붙이지 않는다.

// 블록문
{
  let foo = 10;
}

// 제어문
let x = 1;
if (x < 10) {
  x++;
}

// 함수 선언문
function sum(a, b) {
  return a + b;
}

 


🐰 조건문 🐰

조건문은 주어진 조건식의 평가 결과에  따라 블록문의 실행을 결정한다.
조건식은 불리언 값으로 평가될 수 있는 표현식이다.

자바스크립트는 if...else문과 switch문으로 두가지 조건문을 제공한다.

 

if...else문

if...else문은 불리언 값으로 평가될 수 있는 표현식이다.

조건식의 평가 결과가 true일 경우 if 문의 코드 블록이 실행된다.

false일 경우 else문의 코드 실행 !

if (조건식) {
  // 조건식이 참이면 이 코드 블록이 실행된다.
} else {
  // 조건식이 거짓이면 이 코드 블록이 실행된다.
}

 

if문의 조건식은 불리언 값으로 평가되어야한다.

만약 if문의 조건식이 불리언 값이 아니면
자바스크립트 엔진에 의해 암묵적으로 불리언 값으로 강제 변환된다.

 

조건식을 추가하여 조건에 따라 실행될 코드 블록을 늘리고 싶다면 => else if문

if (조건식1) {
  // 조건식1이 참이면 이 코드 블록이 실행된다.
} else if (조건식2) {
  // 조건식2이 참이면 이 코드 블록이 실행된다.
} else {
  // 조건식1과 조건식2가 모두 거짓이면 이 코드 블록이 실행된다.
}

 

 

if문은 무조건 사용해야하지만, else if문과 else문은 사용하지 않아도 되고 사용해도 된다. 
if문과 else문은 1번만 사용해야하지만 else if문은 필요에 따라 여러번 사용하여도 된다.

let num = 2;
let kind;

// if 문
if (num > 0) {
  kind = '양수'; // 음수를 구별할 수 없다
}
console.log(kind); // 양수

// if…else 문
if (num > 0) {
  kind = '양수';
} else {
  kind = '음수'; // 0은 음수가 아니다
}
console.log(kind); // 양수

// if…else if 문
if (num > 0) {
  kind = '양수';
} else if (num < 0) {
  kind = '음수';
} else {
  kind = '영';
}
console.log(kind); // 양수

 

 

 

만약 코드 블록 내의 문이 하나뿐이라면 중괄호 생략 ⭕

let num = 2;
let kind;

if (num > 0)      kind = '양수';
else if (num < 0) kind = '음수';
else              kind = '영';

console.log(kind); // 양수

 

 

 

대부분의 if...else문삼항 조건 연산자 바꿔 쓸 수 있다.

// x가 짝수이면 result 변수에 문자열 '짝수'를 할당하고, 홀수이면 문자열 '홀수'를 할당한다.
let x = 2;
let result;

if (x % 2) { // 2 % 2는 0이다. 이때 0은 false로 암묵적 강제 변환된다.
  result = '홀수';
} else {
  result = '짝수';
}

console.log(result); // 짝수
//삼항 조건 연산자로 변경
let x = 2;

// 0은 false로 취급된다.
let result = x % 2 ? '홀수' : '짝수';
console.log(result); // 짝수

 

 

🐯💬 삼항 조건 연산자 예시

아래의 예제는 두 가지 경우의 수(홀 or 짝)를 갖는 경우다.

만약 경우의 수가 세 가지 (양수 or 음수 or 영)이라면 다음과 같이 바꿔 쓸 수 있다.

let num = 2;

// 0은 false로 취급된다.
let kind = num ? (num > 0 ? '양수' : '음수') : '영';

console.log(kind); // 양수

num > 0 ? '양수' : '음수'  ➡️   표현식

즉, 삼항 조건 연산자는 값으로 평가되는 표현식(값처럼 사용 ⭕  👉🏻  변수 할당 ⭕)

if...else문은 표현식이 아닌 문 ➡️  (값처럼 사용 ❌  👉🏻  변수 할당❌)

 

🌼 그럼 각자 언제 써야하나?

조건에 따라 단순히 값을 결정하여 변수에 할당하는 경우 -> 삼항 조건 연산자

조건에 따라 실행해야 할 내용이 복잡하여 여러 줄의 문이 필요 -> if...else문

 

switch문

switch문은 주어진 표현식을 평가하여
그 값과 일치하는 표현식을 갖는 case 문으로 실행 흐름을 옮긴다.

case문은 상황을 의미하는 표현식을 지정하고 콜론으로 마친다.
그 뒤에 실행할 문들을 위치시킨다.

 

만약 일치하는 case문이 없다면 실행 순서는 default문으로 이동한다.

default 문의 사용은 선택사항이다!

switch (표현식) {
  case 표현식1:
    switch 문의 표현식과 표현식1이 일치하면 실행될 문;
    break;
  case 표현식2:
    switch 문의 표현식과 표현식2가 일치하면 실행될 문;
    break;
  default:
    switch 문의 표현식과 일치하는 표현식을 갖는 case 문이 없을 때 실행될 문;
}

 

if...else 문의 조건식은 불리언 값으로 평가되어야하지만!

switch 문은 문자열이나 숫자 값인 경우가 많다.

 

if...else ➡️ 논리적 참, 거짓으로 실행할 코드 블록 결정

switch  ➡️ 논리적 참, 거짓보다는 다양한case(상황)에 따라 실행할 코드 블록 결정

 

 

 

아래 예제를 보면,switch문의 표현식, 즉 month 변수의 평가 결과인숫자 값 11과 일치하는 case문으로 실행 흐름이 이동한다.

// 월을 영어로 변환한다. (11 → 'November')
var month = 11;
var monthName;

switch (month) {
  case 1: monthName = 'January';
  case 2: monthName = 'February';
  case 3: monthName = 'March';
  case 4: monthName = 'April';
  case 5: monthName = 'May';
  case 6: monthName = 'June';
  case 7: monthName = 'July';
  case 8: monthName = 'August';
  case 9: monthName = 'September';
  case 10: monthName = 'October';
  case 11: monthName = 'November';
  case 12: monthName = 'December';
  default: monthName = 'Invalid month';
}

console.log(monthName); // Invalid month

이 결과값은 뭐가 나올거라고 생각하는가?

month에 11이니까 case가 11인 November가 나올꺼라 생각한다면 땡!😎

 

결론부터 말하자미나 default문의 Invalid month가 나온다.

switch문의 실행 흐름대로 동작한 것은 맞지만 case마다 문을 실행한 후

switch문을 탈출하지 않고 switch문이 끝날 때까지

이후의 모든 case문과 default문을 실행했기 때문이다.

이것을 폴스루라 한다.

 

이러한 폴스루발생하는 이유는 case문에 해당하는 문의

마지막에 break문을 사용하지 않았기 때문이다.

 

[ 위 예제에서는 November로 이동하고 그 case에서 탈출하지 못하고

마지막문인 default까지 실행된것이다. ]

 

break의 역할 => 코드 블록에서 탈출하는 역할

break문이 없다면 case문의 표현식과 일치하지 않더라고

실행 흐름이 다음  case문으로 연이어 이동한다.

 

따라서 옳바르게 코드를 수정하면 아래와 같은 코드가 된다.

// 월을 영어로 변환한다. (11 → 'November')
var month = 11;
var monthName;

switch (month) {
  case 1: monthName = 'January';
    break;
  case 2: monthName = 'February';
    break;
  case 3: monthName = 'March';
    break;
  case 4: monthName = 'April';
    break;
  case 5: monthName = 'May';
    break;
  case 6: monthName = 'June';
    break;
  case 7: monthName = 'July';
    break;
  case 8: monthName = 'August';
    break;
  case 9: monthName = 'September';
    break;
  case 10: monthName = 'October';
    break;
  case 11: monthName = 'November';
    break;
  case 12: monthName = 'December';
    break;
  default: monthName = 'Invalid month';
}

console.log(monthName); // November

보통은 default문에는 break를 생략하는것이 일반적!

default문은 switch문의 맨 마지막에 위치하므로 default문의 실행이 종료되면,

switch문을 빠져나간다. -> 따라서 break문 필요❌

 

 

break문을 생략한 폴스루현상이 발생하는게 유용한 경우도 있다.

(여러개의 case문이 하나의 조건으로 사용)

아래는 윤년인지 판별하는 2월의 일수를 계산하는 예제이다.

var year = 2000; // 2000년은 윤년으로 2월이 29일이다.
var month = 2;
var days = 0;

switch (month) {
  case 1: case 3: case 5: case 7: case 8: case 10: case 12:
    days = 31;
    break;
  case 4: case 6: case 9: case 11:
    days = 30;
    break;
  case 2:
    // 윤년 계산 알고리즘
    // 1. 연도가 4로 나누어떨어지는 해(2000, 2004, 2008, 2012, 2016, 2020...)는 윤년이다.
    // 2. 연도가 4로 나누어떨어지더라도 연도가 100으로 나누어떨어지는 해(2000, 2100, 2200...)는 평년이다.
    // 3. 연도가 400으로 나누어떨어지는 해(2000, 2400, 2800...)는 윤년이다.
    days = ((year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0)) ? 29 : 28;
    break;
  default:
    console.log('Invalid month');
}

console.log(days); // 29

 

switch문은 다양한 키워드를 사용해야하고 폴스루가 발생하는 등 문법도 복잡하다!

따라서 C 언어 기반으로 하는 프로그래밍 언어는 대부분 switch문을 지원하지만

파이썬과 같이 switch문을 지원하지 않는 프로그래밍 언어도 있다.

 

만약 switch문과 if...else문 두개 모두로 해결할 수 있다면 if...else를 사용하길 권장한다.

하지만, 조건이 너무 많아서 switch문이 가독성이 더 좋다면 switch문을 사용하는게 좋다.

 


🐰 반복문 🐰

반복문은 조건식의 평가 결과가 참인 경우 코드 블록을 실행한다.

그 후 조건식을 다시 평가하여 여전히 참인 경우

코드 블록을 다시 실행한다. (조건이 거짓이 될 때까지 실행)

자바스크립트에서는 for문, while문, do...while문을 제공한다.

🐯💬 반복문을 대체할 수 있는 다양한 기능
자바스크립트는 배열을 순회할 때 사용하는 forEach 메서드,
객체의 프로퍼티를 열거할 때 사용하는 for...in

for...in문 :
객체 반복, 순서없이, 눈에 안 보이는 것들도 객체가 가지고 있으면 다 반복


ES6에서 도입된 이터러블을 순회할 수 있는
for...of문과 같이 반복문을 대체할 수 있단 다양한 기능을 제공한다.

for...of문:
순서 있음 콜렉션 전용, Array, Set, Map, String 같은거...
일단 배열, 문자열에서는 for...of 사용하자.

참고로 forEach(콜백함수 형태)와 이것들의 차이
forEach는 중간에 break구문 사용 못한다는점이다.
실행 도중에 멈출 수 없음!!

 

for 문         

for문은 조건식이 거짓으로 평가될 때까지 코드 블록을 반복 실행한다.

가장 일반적으로 사용되는 for문의 형태는 아래와 같다.

for (초기화식; 조건식; 증감식) {
  조건식이 참인 경우 반복 실행될 문;
}

 

 

✨for문은 아주 중요하다. for문의 동작법을 살펴보자.

for (var i = 0; i < 2; i++) {
  console.log(i);
}//0 1

                                           

        

// for (let i = 0; i < 2; i++) alert(i)

//실행함
let i = 0
//i < 2; true이면 → alert(i) 실행 → i++; 실행 
if (i < 2) { alert(i); i++ }
//i < 2; true이면 → alert(i) 실행 → i++; 실행 
if (i < 2) { alert(i); i++ }

 

위에 예제를 보면

i변수 0 으로 초기화 -> i가 2보다 작을 때까지 코드 블록 2번 반복실행

*주의 : 변수 선언문은 딱 한 번만 실행된다. 

 

 

for문의 변수 선언문, 조건식, 증감식은 모두 옵션이므로 반드시 사용할 필요는 없다.

단, 어떤 식도 선언하지 않으면 무한루프가 된다.

*무한루프란 !? -> 코드 블록을 무한히 반복 실행하는 문

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

for (; i < 3; i++) { // 위에서 i변수를 초기화시켜주어 생략하였습니다.
  alert( i ); // 0, 1, 2
}

 

let i = 0;

for (; i < 3;) {//증감식도 생략가능 이렇게 될 경우 아래에서 볼 while(i < 3)과 동일
  alert( i++ );
}

 

for (;;) {
  // 끊임 없이 본문이 실행됩니다. -> 무한루프
}

❗for문의 구성요소를 생략할 때 주의할 점은 두 개의 ; 세미콜론을

꼭 넣어주어야 한다는 점이다. 하나라도 없으면 문법 에러가 발생!

 

 

for문 내에 for문을 중첩해서 사용할 수 있다. => 중첩 for문

아래 예제는 두 눈의 합이 6이 되는 모든 경우의 수를 출력하기 위해 이중  for문을 사용한 것이다.

for (var i = 1; i <= 6; i++) {//i가 한번돌때마다
  for (var j = 1; j <= 6; j++) {//j는 6번 반복
    if (i + j === 6) console.log(`[${i}, ${j}]`);//조건문
  }
}
//[1, 5]
//[2, 4]
//[3, 3]
//[4, 2]
//[5, 1]

 

 

 

while 문

 while문은 주어진 조건식의 평가 결과가 참이면 코드 블록을 계속해서 반복 실행한다.

 

for문은 언제쓰고 while문은 언제쓰는건데🐰?💬 : 

for문은 반복 횟수가 명확 할 때 주로 사용!
while문은 반복 횟수가 불명확할 때 주로 사용!

 

while문은 조건문의 평가 결과가 거짓이 되면 코드 블록 실행 ❌ -> 종료

만약 조건식의 평가 결과가 불리언 값이 아니면 불리언 값으로 강제 변환한다.

let count = 0;

// count가 3보다 작을 때까지 코드 블록을 계속 반복 실행한다.
while (count < 3) {
  console.log(count); // 0 1 2
  count++;
}

 

 

조건식의 평가 결과가 언제나 참이면 무한루프가 된다.

// 무한루프
while (true) { ... }

 

 

 

무한루프에서 탈출하기 위해서는 코드 블록 내에 if문으로 탈출 조건을 만들고
break문으로 코드 블록을 탈출한다.

let count = 0;

// 무한루프
while (true) {
  console.log(count);
  count++;
  // count가 3이면 코드 블록을 탈출한다.
  if (count === 3) break;
} // 0 1 2

 

 

do...while 문

do...while문은 코드 블록을 먼저 실행하고 조건식을 평가한다.

따라서 코드 블록은 무조건 한 번 이상 실행된다.

let count = 0;

// count가 3보다 작을 때까지 코드 블록을 계속 반복 실행한다.
do {
  console.log(count);
  count++;
} while (count < 3); // 0 1 2

 

 


 

🐰 break  🐰

break문은 레이블 문, 반복문(for, for...in, for...of, while, do...while),

switch문의 코드 블록을 탈출한다.

레이블 문, 반복문, switch문의 코드 블록 외에

break문을 사용하면 문법 에러가 발생한다.

 

 

if (true) {//조건문
  break; // Uncaught SyntaxError: Illegal break statement
}

 

 

*레이블문 : 식별자가 붙은 문

// foo라는 레이블 식별자가 붙은 레이블 문
foo: console.log('foo');

 

 

 

레이블문은 프로그래밍의 실행 순서를 제어하는 데 사용!

사실 switch 문의 case문과 default문도 레이블문이다.
레이블문을 탈출하려면 break문에 레이블 식별자를 지정한다.

// foo라는 식별자가 붙은 레이블 블록문
foo: {
  console.log(1);
  break foo; // foo 레이블 블록문을 탈출한다.
  console.log(2);//실행안됨
}

console.log('Done!');

 

 

 

중첩된 for문의 내부 for문에서 break문을 실행하면

내부 for문을 탈출하여 외부 for문으로 진입.

이때 내부 for문이 아닌 외부 for문을 탈출하려면 레이블문 사용!

// outer라는 식별자가 붙은 레이블 for 문
outer: for (var i = 0; i < 3; i++) {
  for (var j = 0; j < 3; j++) {
    // i + j === 3이면 outer라는 식별자가 붙은 레이블 for 문을 탈출한다.
    if (i + j === 3) break outer;
    console.log(`inner [${i}, ${j}]`);
  }
}

console.log('Done!');

 

레이블문은 중첩된 for문 외부로 탈출할 때 유용하지만 그 밖의 경우에는 일반적으로 권장❌

레이블문을 사용하면 프로그램의 흐름이 복잡해져서 가독성 나빠짐! 

 

break문은 레이블문뿐만 아니라 반복문, switch문에서도 사용 가능!

이 경우에는 break문에 레이블 식별자를 지정

break문은 반복문을 더 이상 진행하지 않아도 될 때 불필요한 반복을 회피할 수 있어 유용하다! 

 

 

🐯💬 다음은 문자열에서 특정 문자의 위치를 검색하는 예시다.

let string = 'Hello World.';
let search = 'l';
let index;

// 문자열은 유사배열이므로 for 문으로 순회할 수 있다.
for (let i = 0; i < string.length; i++) {
  // 문자열의 개별 문자가 'l'이면
  if (string[i] === search) {
    index = i;
    break; // 반복문을 탈출한다.
  }
}

console.log(index); // 2

// 참고로 String.prototype.indexOf 메서드를 사용해도 같은 동작을 한다.
console.log(string.indexOf(search)); // 2

 


 

🐰 continue문 🐰

continue문은 반복문의 코드 블록 실행을 현 지점에서 중단하고

반복문의 증감식으로 실행 흐름을 이동시킨다.

break문처럼 반복문을 탈출하지❌

 

다음은 문자열에서 특정 문자의 개수를 세는 예시이다!

let string = 'Hello World.';
let search = 'l';
let count = 0;

// 문자열은 유사배열이므로 for 문으로 순회할 수 있다.
for (let i = 0; i < string.length; i++) {
  // 'l'이 아니면 현 지점에서 실행을 중단하고 반복문의 증감식으로 이동한다.
  if (string[i] !== search) continue;
  count++; // continue 문이 실행되면 이 문은 실행되지 않는다.
}

console.log(count); // 3

// 참고로 String.prototype.match 메서드를 사용해도 같은 동작을 한다.
const regexp = new RegExp(search, 'g'); //정규 표현식 생성 코드
console.log(string.match(regexp).length); // 3

* match메소드 =>  정규 표현식에 맞는 부분을 찾아 배열로 반환.

만약 일치하는 부분이 없으면 null !

 

* new RegExp(찾을요소, g) => 정규 표현식 생성 코드 !

여기서 뒤에오는 g는 플래그라고 한다.

 

      g플래그 대신 올 수 있는것

       👉🏻 g : 문자열 전체에서 일치하는 모든 부분 찾음

       👉🏻 i : 대소문자 구분 없는 검색

       👉🏻 m : 여러 줄 모드에서 검색

       👉🏻 없을때 : 첫 번째 일치하는 부분만 찾음

 

 

 

아래 예제의 for문은 다음 코드와 동일하게 동장한다.

for (let i = 0; i < string.length; i++) {
  // 'l'이면 카운트를 증가시킨다.
  if (string[i] === search) count++;
}

 

위와 같이 if문 내에서 실행해야 할 코드가 한 줄이라면 continue문❌ => 가독성 더 좋음!

하지만 if문 내에서 실행해야 할 코드가 길다면 continue문⭕ => 가독성이 좋다.

// continue 문을 사용하지 않으면 if 문 내에 코드를 작성해야 한다.
for (let i = 0; i < string.length; i++) {
  // 'l'이면 카운트를 증가시킨다.
  if (string[i] === search) {
    count++;
    // code
    // code
    // code
  }
}

// continue 문을 사용하면 if 문 밖에 코드를 작성할 수 있다.
for (let i = 0; i < string.length; i++) {
  // 'l'이 아니면 카운트를 증가시키지 않는다.
  if (string[i] !== search) continue;

  count++;
  // code
  // code
  // code
}

 

‘?’ 오른쪽엔 break나 continue가 올 수 없습니다.

표현식이 아닌 문법 구조(syntax construct)는 삼항 연산자 ?에 사용할 수 없다.
특히 break나 continue 같은 지시자는 삼항 연산자에 사용하면❌

if (i > 5) {
  alert(i);
} else {
  continue;
}​


물음표를 사용해서 위 조건문을 아래와 같이 바꿈

(i > 5) ? alert(i) : continue; // 여기에 continue를 사용하면 안 된다.


이런 코드는 문법 에러를 발생시킨다.

이는 물음표 연산자 ?를 if문 대용으로 쓰지 말아야 하는 이유 중 하나이다.

 

728x90