일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 한화시스템 5기
- 프론트엔드강의
- 리액트JSX문법
- 자바스크립트
- 노마드코더 #북클럽
- 문자열과 불변성
- JSX문법
- 노마드코더 #개발자북클럽
- 패스트캠퍼스
- 코딩애플 자바스크립트
- 한화시스템 부트캠프
- 유사배열
- 프론트엔드웹개발의모든것초격차패키지Online
- 패스트캠퍼스 강의 패키지
- 한화시스템 부트캠프 5기
- 엘리스트랙 프리트랙
- 노마드북챌리닞
- 코딩애플
- 프론트엔드 강의 패키지
- 자바스크립트 연산자
- 프론트엔드 강의
- 패스트캠퍼스이벤트
- 프론트엔드웹개발의모든것초격차패키지
- 코딩애플자바스크립트
- 딥 다이브
- 원시값
- deep dive
- 패스트캠퍼스 프론트엔드
- 강의 패키지
- 모던 딥다이브
- Today
- Total
개발자 연쨘
[딥 다이브] 연산자2, 제어문 본문
🐰 지수 연산자🐰
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문 대용으로 쓰지 말아야 하는 이유 중 하나이다.
'스터디 > 모던 자바스크립트 Deep Dive' 카테고리의 다른 글
[딥 다이브] 객체 리터럴 (4) | 2024.01.11 |
---|---|
[딥 다이브] 타입 변환과 단축 평가 (1) | 2024.01.07 |
[딥 다이브] 연산자 (36) | 2023.12.20 |
[딥 다이브] 데이터 타입 (2) | 2023.12.14 |
[딥 다이브]표현식과 문 (2) | 2023.12.07 |