본 강의는 Programmers의 Hello, JavaScript: 자바스크립트 입문 강의를 기반으로 작성되었으나, 작성자에 의견에 따라 일부 내용이 추가되거나 수정되어 작성된 포스트입니다
if, if/else, else if )조건문은 조건식( condition )이 참( true )일 경우 해당 코드 블록을 실행한다. 만약 거짓이라면 해당 코드 블록은 실행되지 않는다.
if가장 기본적인 코드다. condition 이 참일 경우 코드 블록을 실행한다.
if (condition) {
// 코드 블록
}
아래 예제를 살펴보자.
let x = 15;
if (x > 10) {
console.log("x는 10보다 큽니다");
// [output] x는 10보다 큽니다
}
위 예제에서 if 문 안의 조건문, x > 10이 참( true ) 이므로 x는 10보다 큽니다 가 출력된다.
if/elseif 문의 조건식이 참이 아닐 경우, else 문을 실행한다.
if (condition) {
// 조건식이 참일 때 실행할 코드 블록
} else {
// 조건식이 거짓일 때 실행할 코드 블록
}
아래 예제를 살펴보자.
let x = 5;
if (x > 10) {
console.log("x는 10보다 큽니다");
} else {
console.log("x는 10보다 작거나 같습니다");
}
위 예제에서는 x 의 값은 5 이므로, if 문의 x > 10 조건에 만족하지 않는다. 따라서 x는 10보다 작거나 같습니다 가 출력된다.
else ifelse if 문은 여러 개의 조건을 체크할 때 사용된다. 순차적으로 조건을 확인하며, 만약 마지막까지 참이 없을 경우 else 문을 실행한다.
if (condition1) {
// 조건식1이 참일 때 실행할 코드 블록
} else if (condition2) {
// 조건식2가 참일 때 실행할 코드 블록
} else if (condition3) {
// 조건식3이 참일 때 실행할 코드 블록
} else {
// 모든 조건이 거짓일 때 실행할 코드 블록
}
아래 예제를 살펴보자.
let x = 7;
if (x > 10) {
console.log("x는 10보다 큽니다");
} else if (x > 5) {
console.log("x는 5보다 큽니다");
} else {
console.log("x는 5보다 작거나 같습니다");
}
위 예제에서는 아래와 같이 진행된다.
1. if (x > 10) = false
2. else if (x > 5) = true
3. console.log("x는 5보다 큽니다"); 실행
switch)switch 문은 주어진 값에 대해 여러 조건( case )를 비교해 해당하는 조건의 코드 블록을 실행한다.
아래처럼 사용한다.
switch (expression) {
case value1:
// 실행할 코드 블록
break;
case value2:
// 실행할 코드 블록
break;
//...
default:
// 모든 조건이 일치하지 않을 때 실행할 코드 블록
}
expression 은 비교할 값이고, 각 case 마다 value 값에 맞는 코드 블록이 실행된다.
break 는 각 case 문이 끝나면 반드시 적어줘야 한다. break 는 해당 case 의 코드 블록을 실행한 후, switch 에서 빠져나오도록 한다.
default 는 만약 모든 case 가 일치하지 않을 경우 실행하는 코드 블록이다. 이는 선택적으로 사용할 수 있다.
아래 예제를 살펴보자.
let operator = prompt("연산자를 입력하세요. (+, -, *, /)");
let num1 = Number(prompt("첫 번째 숫자를 입력하세요."));
let num2 = Number(prompt("두 번째 숫자를 입력하세요."));
let result;
switch (operator) {
case "+":
result = num1 + num2;
break;
case "-":
result = num1 - num2;
break;
case "*":
result = num1 * num2;
break;
case "/":
result = num1 / num2;
break;
default:
alert("잘못된 연산자입니다");
}
alert("계산 결과: " + result);
위 예제는 간단한 사칙연산 계산기를 switch 문을 이용해 만든 것이다.
또 다른 예제를 살펴보자.
console.log("Menu");
console.log("1. Ice Americano");
console.log("2. Cafe Latte");
console.log("3. Cappuccino");
console.log("4. Tea");
let choice = parseInt(prompt("메뉴 선택"));
console. log(choice + "번 메뉴 선택됨");
switch (choice) {
case 1:
console.log("아이스 아메리카노 / 1500원");
break;
case 2:
console.log("카페 라떼 / 1800원");
break;
case 3:
console.log("카푸치노 / 2000원");
break;
case 4:
console.log("홍차 / 1300원");
break;
default:
console.log("존재하지 않는 메뉴");
break;
}
위는 prompt() 로 입력받은 메뉴가 무엇인지 console.log() 로 출력해주는 예제다.
while, do while)조건( condition )에 따라 코드 블록을 반복적으로 수행한다.
while형식은 다음과 같다.
while (condition) {
// 반복적으로 실행할 코드 블록
}
switch 문의 두번째 예제를 약간 바꿔보자. 기존에는 일회성으로 실행됬지만, 이제는 사용자가 원할때까지 메뉴를 담고, exit 을 입력하면 종료와 동시에 최종 가격을 제시하도록 구현해보자.
console.log("Menu");
console.log("1. Ice Americano");
console.log("2. Cafe Latte");
console.log("3. Cappuccino");
console.log("4. Tea");
let total = 0
let cart = {
"아이스 아메리카노": 0,
"카페 라떼": 0,
"카푸치노": 0,
"홍차": 0,
}
let isEnd = false;
while(!isEnd) {
let choice = prompt("메뉴 선택");
switch (choice) {
case "1":
console.log("아이스 아메리카노 / 1500원");
cart["아이스 아메리카노"] += 1;
total += 1500;
break;
case "2":
console.log("카페 라떼 / 1800원");
cart["카페 라떼"] += 1;
total += 1800;
break;
case "3":
console.log("카푸치노 / 2000원");
cart["카푸치노"] += 1;
total += 2000;
break;
case "4":
console.log("홍차 / 1300원");
cart["홍차"] += 1;
total += 1300;
break;
case "exit":
isEnd = true;
break;
default:
console.log("존재하지 않는 메뉴");
break;
}
}
console.log("======= 정 산 =======");
console.log(`아이스 아메리카노: ${cart["아이스 아메리카노"]} 잔`);
console.log(`카페 라떼: ${cart["카페 라떼"]} 잔`);
console.log(`카푸치노: ${cart["카푸치노"]} 잔`);
console.log(`홍차: ${cart["홍차"]} 잔`);
console.log("--------");
console.log(`총 ${total} 원`);

위 예제처럼 while(!isEnd) 의 condition 은 prompt 에 exit 이 입력됙 전까지 true 이므로, 메뉴를 사용자가 원할때까지 추가할 수 있다.
while 문에서도 break;를 사용해 코드 블록을 빠져나올 수 있다.
while 에서 continue 를 사용하면 현재 반복을 중지하고, 다음 반복을 처음부터 진행한다.
do whiledo while 문은 while 과 유사하지만, 조건식의 검사를 반복문의 마지막에 수행한다. 즉, 최초 한번은 무조건 실행하고, 그 다음에도 또 실행할지는 한번 더 돌기 전에 확인한다.
형식은 다음과 같다.
do {
// 최소한 한 번 실행될 코드 블록
} while (condition);
위 예제를 변형하면 아래와 같이 사용할 수 있다.
console.log("Menu");
console.log("1. Ice Americano");
console.log("2. Cafe Latte");
console.log("3. Cappuccino");
console.log("4. Tea");
let total = 0
let cart = {
"아이스 아메리카노": 0,
"카페 라떼": 0,
"카푸치노": 0,
"홍차": 0,
}
let isEnd = false;
do {
let choice = prompt("메뉴 선택");
switch (choice) {
case "1":
console.log("아이스 아메리카노 / 1500원");
cart["아이스 아메리카노"] += 1;
total += 1500;
break;
case "2":
console.log("카페 라떼 / 1800원");
cart["카페 라떼"] += 1;
total += 1800;
break;
case "3":
console.log("카푸치노 / 2000원");
cart["카푸치노"] += 1;
total += 2000;
break;
case "4":
console.log("홍차 / 1300원");
cart["홍차"] += 1;
total += 1300;
break;
case "exit":
isEnd = true;
break;
default:
console.log("존재하지 않는 메뉴");
break;
}
} while(!isEnd);
console.log("======= 정 산 =======");
console.log(`아이스 아메리카노: ${cart["아이스 아메리카노"]} 잔`);
console.log(`카페 라떼: ${cart["카페 라떼"]} 잔`);
console.log(`카푸치노: ${cart["카푸치노"]} 잔`);
console.log(`홍차: ${cart["홍차"]} 잔`);
console.log("--------");
console.log(`총 ${total} 원`);
for, for in)forfor 문은 일반적으로 가장 많이 사용하는 반복문이다. 기본적으로 while 과 비슷하다.for 문에는 초기화식, 조건식, 증감식이 들어가며, 해당 조건에 맞을 경우 코드 블록을 실행한다.
형식은 다음과 같다.
for ([initialization]; [condition]; [final-expression]) {
// 반복적으로 실행할 코드 블록
}
초기화(initialization): 반복문이 시작될 때 단 한 번 실행 되는 구문
조건식(condition): 반복문이 실행될 때 마다 검사할 조건, 참( true )일 경우 반복문이 실행
증감식(final-expression): 반복문이 실행될 때 마다 실행되는 구문
초기화는 항상 실행된다.
아래 예제를 살펴보자.
for (let i = 1; i <= 5; i++) {
console.log(i);
// [output] 1
// [output] 2
// [output] 3
// [output] 4
// [output] 5
}
변수 i 를 선언과 동시에 1 로 초기화 하고, i 가 5 보다 작다면 조건문을 실행한 후, i 의 값을 1 증가 시키는 for 문이다.
다만, for 을 사용하는 경우 별도의 변수의 값을 이용해 배열의 위치를 확인할 수 밖에 없다. (index 를 이용한다)
횟수가 정해져 있는 반복문일 경우:
for을 사용
정해져 있지 않은 반복문일 경우:while을 사용
하는 것이 가독성을 높일 수 있다.
for infor in 은 객체의 속성이나 배열의 요소를 반복할 때 더욱 편리하게 사용할 수 있다.
index 를 이용할 수 밖에 없는for 문과 달리, for in 은 속성명 등을 사용할 수 있다.
형식은 다음과 같다.
for (var in obj) {
// 반복적으로 실행할 코드 블록
}
아래 예제를 살펴보자.
let obj = {
a: 1,
b: 2,
c: 3
};
let keys = Object.keys(obj);
for (let i = 0; i < keys.length; i++) {
let prop = keys[i];
console.log(prop + ': ' + obj[prop]);
}
이 예제에서는 obj 라는 객체의 속성에 접근하기 위해 Object.keys() 함술르 사용해 객체의 속성명들을 배열로 만들고, 그 배열의 길이만큼 for 문을 실행한다. 그리고 실행될 때 마다 i 의 값에 +1 하고, 배열의 길이보다 길어지면 반복문을 중지한다.
너무 비효율적이지 않은가?
아래 예제와 비교해보자.
let obj = {
a: 1,
b: 2,
c: 3
};
for (let prop in obj) {
console.log(prop + ': ' + obj[prop]);
}
(TIP. 속성명 in 객체명 을 사용하면 속성명이 객체 안에 있는지를 불리언 Boolean 값으로 반환해준다)
위 예제는 for in 을 활용해 작성한 코드다. 훨씬 가독성이 높고, 효율적이지 않은가? 따라서, 적절한 상황에 따라 while, do while, for, for in 을 사용해야 한다.
자세한 내용은 변수의 선언 방식에 대해 설명할 때 알아보았다. 자세한 내용은 여기서 확인해보자.
변수의 shadowing은 변수 이름이 중복되어 발생하는 문제다. 블록 내부에서 동일한 이름의 변수가 선언되면, 해당 블록에서는 내부에서 선언된 변수가 우선적으로 참조된다. 이 때, 외부에서 선언된 변수는 블록 내부에서 가려지게(shadowing) 되어 외부 변수를 참조할 수 없다.
아래 예제를 살펴보자.
let num = 10;
if (true) {
let num = 5;
console.log(num); // 내부 num 변수 참조
// [output] 5
}
console.log(num); // 외부 num 변수 참조
// [output] 10
따라서, 함수 안에서만 값이 유지되어야 되는 경우 블록 스코프(Block Scope) 범위를 갖고 있는 let 또는 const 보다 함수 스코프(Function Scope)의 범위를 갖고 있는 var 를 사용하면 된다.
(다만 스코프 예측이 어렵고, 호이스팅(hoisting) 발생 가능성 때문에 권장되지는 않는다)
method)와 thismethod)메소드는 객체가 갖고 있는 함수를 의미한다. 예전에 설명한 것 처럼 객체에는 다양한 타입이 값으로 들어갈 수 있는데, 이 때 함수가 그 값으로 들어간 것을 의미한다.
이 때 메소드 내부에서 this 키워드는 해당 메소드가 속한 객체를 가리킨다.
아래 예제를 살펴보자.
let person = {
name: "John",
age: 30,
greet: function() {
console.log("Hello, my name is " + this.name + " and I am " + this.age + " years old.");
}
};
person.greet(); // Hello, my name is John and I am 30 years old.
여기서 greet 은 메소드고, console.log() 에서 name 과age 를 출력하고 싶어한다.
이 때 name 과 age 는 greet 메소드가 속한 person 이라는 객체에 값이 존재하는데, greet 에서 이 객체 속성에 대한 값에 접근하기 위해 this 를 사용해주면 쉽게 접근이 가능하다.
closure)클로저는 함수(parent) 내부에서 생성된 변수와 함수(child)는 해당 함수(parent)가 호출될 때마다 새롭게 생성이 되며, 생성된 여러 함수의 독립성을 유지할 수 있다.
아래 예제를 살펴보자.
function makeCounter() {
let count = 0;
return function() {
count++;
console.log(count);
};
}
let counter1 = makeCounter();
counter1(); // 1
counter1(); // 2
counter1(); // 3
let counter2 = makeCounter();
counter2(); // 1
counter2(); // 2
여기서 보면 makeCounter() 함수가 총 두개(counter1, counter2) 생성되는데, 이 두 함수의 내부 변수와 함수 모두 다 독립성을 유지해 각각 1, 2, ... 를 출력할 수 있다.