제로초 JavaScript 강의 - 변수, 상수, 조건문 if, switch
- 제로초 JavaScript 강의 - 변수, 상수, 조건문 if, switch
Review
제로초님의 강의도 정말 좋다.
사실 재미가 조금 없긴 하지만 이론은 정말 정확하게 말씀해주셔서 오히려 더 도움이 된다.
단점이긴 하지만 나의 경우는 하나가 이해가 안되면 뒤로 넘어가지 못하고 이해가 될 때까지
파고 드는 성격이 있어서... 하나하나 정확하게 설명해주시는 강사님이 나에게 맞다.
열심히 들어서 얼른 리액트도 공부해야지 !
파이팅 -
- 제로초 JavaScript 강의 - 변수, 상수, 조건문 if, switch
<변수>
: 프로그램을 만들 때 잠시 특정한 값을 저장해야 하는 상황이 자주 발생한다.
이때 사용하는 것이 변수이다. 변수를 사용하면 다음과 같이 값을 저장할 수 있다.
> let total = 5000 + 8000 + 10000 + 9000;
< undefined
더하기 연산자의 결과인 32000을 total이라는 이름으로 저장했다.
변수를 선언함과 동시에 값을 넣는 것을 "초기화했다" 라고 표현한다.
=는 대입 연산자인데, + 보다 연산자 우선순위가 낮아서 위의 코드에서 +가 먼저 실행되고 나서
=가 실행된다.
그렇기 때문에 콘솔에 total을 입력하면 저장된 32000이 출력된다.
> total;
< 32000
대입 연산자라는 것이 우항의 식을 왼쪽에 넣는다는 개념으로 이해하면 쉽고,
'같다' 라는 개념이 아니라 '넣는다' 라는 표현이 더 정확하다.
또는 console.log(변수)로 변수의 값을 콘솔에 출력할 수 있다.
> console.log(total);
32000
< undefined
이렇게 total처럼 값을 저장하고 저장한 값을 불러올 수 있게 하는 것이 변수(variable)다.
변수를 만드는 행위는 선언(declaration)한다고 표현한다.
변수를 만드는 방법은 세 가지가 있는데, let,const,var이다.
앞에서 사용한 let부터 살펴보자.
let 변수명 = 식;
let 다음에 선언하고자 하는 변수명(변수의 이름)을 적고, 그 뒤에 대입 연산자인 =를 입력한다.
= 뒤에는 변수에 저장할 식을 입력하면 된다.
앞의 예제를 다시 보자.
> let total = 5000 + 8000 + 10000 + 9000;
< undefined
먼저 let으로 시작하는 명령을 선언문이라고 한다.
total은 변수명입니다. 대입 연산자보다 더하기 연산자의 우선순위가 높기 때문에 숫자를 더하는
식이 먼저 계산된다. 그리고 계산된 값 32000이 대입 연산자를 통해 total 변수의 값으로 저장된다.
변수를 선언함과 동시에 값을 대입하는 행위를 초기화(initialization)라고 합니다.
끝으로, 변수 선언은 항상 결괏값이 undefined로 출력된다.
변수의 이름과 값은 어디에 저장될까?
바로 컴퓨터의 메모리에 저장된다. 내용물이 든 상자를 예로 들어 보자.
상자에는 이름표가 붙어 있고, 상자는 창고에 들어 있다.
여기서 내용물이 값(32000)이고, 이름표가 변수명(total)이며, 창고가 메모리다.
사람이 창고에서 상자의 이름표를 보고 내용물을 찾듯이 개발자도 메모리에서 값을 변수명으로
가져올 수 있다. 상자를 만드는 것은 프로그램에서 변수 선언하는 것과 같다.
상자에 내용물을 넣는 것은 = 연산자를 사용하는 것과 같다.
변수는 메모리 안에 저장되어 있으므로 메모리를 초기화(변수의 초기화와는 다름)하면 메모리에
저장되어 있던 변수도 같이 사라진다.
웹 브라우저를 새로고침하면 메모리가 초기화된다.
새로고침한 후에 앞에서 만들었던 string 변수를 콘솔에 입력하면 에러가 발생한다.
> string;
Uncaught ReferenceError: string is not defined
string이라는 변수가 정의(define)되지 않았다고 나온다.
메모리가 초기화되어 저장했던 total과 string 변수가 없어진 것이다.
변수를 선언할 때 변수에 값을 대입하지 않아도 된다.
> let empty;
< undefined
값을 대입하지 않은 변수를 입력하면 undefined가 출력된다.
> empty;
< undefined
undefined는 기본값의 역할을 한다. 이렇게 변수를 선언할 때 값을 대입하지 않으면
기본으로 값이 undefined가 된다.
이미 선언한 변수를 다시 선언하면 에러가 발생한다.
> let empty; let empty;
Uncaught SyntaxError: Identifier 'empty' has already been declared
따라서 변수명이 겹치지 않게 주의해야 한다.
<변수명 짓기>
: 변수명은 변수의 값이 무엇인지 알려 주는 역할을 하기 때문에 자세하게 짓기를 권장한다.
변수명은 제약 사항이 있는데, 특수문자 $와 _만 사용할 수 있으며, 숫자로 시작해서는 안 된다.
> let er^ror = 'No!';
Uncaught SyntaxError: Unexpected token '^'
> let 2error = 'No!';
Uncaught SyntaxError: Invalid or unexpected token
_와 $ 말고 다른 특수문자가 들어가거나 숫자로 시작하는 변수명을 입력하면 에러가 발생한다.
하지만 이를 제외하면 한글이나 한자, 유니코드(https://ko.wikipedia.org/wiki/유니코드)까지도
변수명으로 쓸 수 있다.
> let 한글 = 'Yes!';
< undefined
> let 漢字 = 'Yes!';
< undefined
> let ಠ_ಠ = 'Yes!';
< undefined
한국 사람만 보는 코드라면 변수명을 한글로 지어도 된다.
또 중국 사람만 본다면 한자로 지어도 된다. 하지만 여러분이 만든 프로그램이 전 세계에서 널리
쓰이길 원한다면 공용어인 영어로 변수명을 짓는 게 좋다.
변수명으로 사용할 수 없는 단어도 있다.
이를 예약어(reserved word)라고 하는데, 예약어는 자바스크립트 프로그래밍에서 특정한 역할을
하므로 변수명으로 쓰지 않는다.
> let let = 'No!';
Uncaught SyntaxError: let is disallowed as a lexically bound name
> let var = 'No!';
Uncaught SyntaxError: Unexpected token 'var'
- 예약어의 종류
: await, break, case, catch, class, const, continue, debugger, default, delete, do, else,
enum, export, extends, false, finally, for, function, if, import, in, instanceof, new,
null, return, super, switch, this, throw, true, try, typeof, var, void, while, with, yield
let도 변수로 사용할 수 없는데 예약어는 아니다.
따라서 모두 외울 필요가 없다. 예약어를 사용하면 에러가 발생하기 때문에 변수를 선언할
때 에러를 확인하면 된다.
let으로 변수를 선언할 때는 콘솔의 결괏값이 undefined이지만,
변수의 값을 바꿀 때는 결과로 바꾼 값이 나온다.
같은 대입 연산자를 사용했는데, 결과가 다르다. 왜 그럴까?
> let change = '바꿔 봐';
< undefined
> change = '바꿨다';
< "바꿨다"
이는 let의 역할 때문이다.
let이 없을 때는 코드가 식이라서 대입한 값이 결괏값으로 출력되지만, let이 앞에 붙는 순간
선언문이 된다. 여기서 문(statement)이라는 개념이 나온다. 문은 식과 다르게 결괏값이 없고
식의 자리에 사용할 수 없다.
변수에 넣은 값을 비울 때도 있다. 이때는 undefined를 대입하거나 null을 대입하는 것 2가지
방법이 있다.
> change = undefined;
< undefined
> change = null;
< null
두 경우 모두 변수의 값을 빈 값으로 바꾼다는 점에서 동일하지만, undefined와 null이 다른 값이기
때문에 다른 의미를 부여할 수 있다.
많은 개발자가 null을 대입해 값을 의도적으로 지웠다는 의미를 부여한다.
<상수 만들기>
: let 외에도 변수를 선언하는 예약어로 const와 var가 있다.
const부터 알아보자. const는 상수(constant)의 줄임말이다. 변수와 상수는 어떤 차이가 있을까?
변수(變數)는 변하는 수, 상수(常數)는 변하지 않는 수라는 뜻이다.
상수랑 변수는 반대 개념 아닌가? 상수와 변수의 뜻을 살펴보면 완전히 반대 개념임을 알 수 있다.
그런데 왜 let과 var, const를 묶어 변수라고 통칭했을까? const는 엄밀히 말해 상수가 아니기
때문이다. const는 나중에 배우는 객체의 내부 값에는 적용되지 않는다.
따라서 엄밀한 의미에서 상수가 아니므로 자바스크립트 커뮤니티에서는 보통 const도 변수라고
부른다. 다만, 앞으로 나올 특성을 가진 변수라고 생각하면 된다.
상수를 왜 사용할까? 코딩을 하다 보면 변수의 값을 수정할 일이 생각보다 그리 많지 않고 실수로
값을 수정하는 일을 막기 위해 상수를 사용한다.
let string1 = '엄청 긴 문자열입니다.';
string1 변수가 나중에 실수로 수정되는 것을 막기 위해 const로 바꿀 수 있다.
const string1 = '엄청 긴 문자열입니다.';
이렇게 상수로 만들면 string1이 수정되지 않음이 보장되기 때문에 더 안전하게 코딩할 수 있다.
let에서는 처음 값을 대입한 후에 다른 값을 대입해 수정할 수 있었다. 하지만 const는 상수이므로
한번 대입하면 다른 것을 대입할 수 없다.
> const value = '상수입니다.';
< undefined
> value = '바꿀 수 없습니다.';
Uncaught TypeError: Assignment to constant variable.
const도 식이 아니라 선언문이기 때문에 콘솔에 undefined가 출력됩니다. 그리고 다른 값을
대입하면 에러가 발생한다. 하지만 값을 바꿀 수 없다는 뜻은 아니다.
나중에 객체를 배울 때 값을 바꾸는 방법을 살펴보자.
const로 선언한 상수도 다시 선언할 수 없다. 앞에서 선언한 value 상수를 다시 선언해 보자.
> const value = '다시 선언할 수 없습니다.';
Uncaught SyntaxError: Identifier 'value' has already been declared
또한, 한번 값을 대입하면 다른 값을 대입할 수 없다는 특성 때문에 상수 선언 시 초기화
(선언과 동시에 값을 대입하는 것)하지 않으면 에러가 발생한다.
> const wrong;
Uncaught SyntaxError: Missing initializer in const declaration
여기서 나타나는 에러들은 외워두는 것이 좋다.
<var 알아보기>
: var를 사용해 변수를 선언하는 방법이 있다.
var는 변수(variable)의 줄임말이다. 예전에는 많이 사용했지만, 다소 이해하기 어려운 특성
때문에 const와 let을 사용해 변수를 선언하는 방식으로 옮겨 가고 있다.
다만, 과거에 작성된 코드에서는 var를 많이 사용하므로 var의 특성은 알아 두어야 한다.
> var variable = '다시 선언할 수 있습니다.';
< undefined
> variable;
< "다시 선언할 수 있습니다."
var로 변수를 선언한 모습이다. var로 변수를 선언하면 특별히 변수문(variable statement)이라고
한다.
> var variable2;
< undefined
> variable2;
< undefined
선언할 때 초기화하지 않으면 값에 undefined가 대입된다. 여기까지는 let과 상당히 비슷하다.
하지만 다른 점도 있다. 기존에 선언했던 variable 변수를 다시 선언해도 에러가 발생하지 않는다.
> var variable = '다시 선언할 수 있습니다.';
< undefined
이러한 특징 때문에 실수로 변수를 다시 선언하는 문제가 발생할 수 있다.
또한, 다음과 같이 예약어나 다름없는 이름을 변수명으로 사용할 수 있다.
> var undefined = 'defined';
< undefined
> var Infinity = 0;
< undefined
> var let = 'const';
< undefined
undefined, Infinity, let은 자바스크립트에서 각자 역할이 있는 예약어이다.
이러한 이름을 변수명으로 쓰면 같은 코드를 보는 다른 개발자가 매우 헷갈릴 수 있다.
var 대신 let을 사용하면 에러가 발생해 해당 이름의 사용을 막는다.
> let undefined = 'defined';
Uncaught SyntaxError: Identifier 'undefined' has already been declared
> let Infinity = 0;
Uncaught SyntaxError: Identifier 'Infinity' has already been declared
> let let = 'const';
Uncaught SyntaxError: let is disallowed as a lexically bound name
이외에도 var를 사용할 때 직관적으로 알기 어려운 부분이 많다.
<퀴즈>
a와 b라는 변수에 어떠한 값이 들어 있습니다. 두 변수의 값을 서로 바꿔 보세요.
힌트 두 값을 바꾸기 위해서는 변수 하나를 더 만들어야 합니다.
a = 5, b = 3 이라는 값을 만든 경우,
두 값을 서로 바꾸려면 임의로 하나의 변수를 하나 만들어야 한다.
a = b 이런 식으로 해버리면 5 라는 값이 사라지기 때문에, let c = a 라는 선언을
해놓고 나서 a = b, b = c 이렇게 작성하면 두 변수의 값이 서로 바뀐다.
a = 3, b = 5
<조건문 if 알아보기>
: 앞에서 첫 번째 문으로 선언문을 알아보았다. 두 번째 문으로 조건문이 있다.
조건문은 주어진 조건에 따라 코드를 실행하거나 실행하지 않는 문이다.
if (로그인한 사용자)
정보를 보여 준다;
if 뒤에 나오는 소괄호 안에 조건(식)을 넣고, 다음 줄에 실행문을 넣으면 된다.
들여쓰기는 중요하지 않지만 보기 좋게 두 칸을 띄어 쓴다. if 조건을 기본 형식으로
표현하면 다음과 같다.
if (조건식)
실행문;
조건문은 조건식과 실행문으로 구분된다. 조건식이 참인 값이면 내부의 실행문이 실행되고,
거짓인 값이면 실행문이 실행되지 않는다.
만약 실행문이 둘 이상이면 실행문들을 중괄호로 감싼다.
if와 (, )와 { 사이는 띄어도 되고 띄우지 않아도 된다.
if (조건식) {
실행문1;
실행문2;
실행문3;
}
다음 코드를 실행해보자. 콘솔 창에서 줄바꿈은 Shift+Enter를 누르면 된다.
코드를 다 입력한 후에 Enter를 눌러 실행한다.
> if (true) {
console.log('Hello, if!');
}
Hello, if!
< undefined
조건식이 true이다. true는 참인 값이므로 실행문이 실행되어 콘솔에 Hello, if!가 출력된다.
반대로 조건식이 false면 거짓인 값이므로 콘솔에 실행결과가 표시되지 않는다.
> if (false) {
console.log('Hello, if!');
}
< undefined
false, '', 0, NaN, null, undefined만 거짓인 값이고, 나머지는 참인 값이라고 보면 된다.
true라는 값을 직접 넣어줄 필요 없이 true로 형 변환되는 값(참인 값)이나 그것을 담고
있는 변수를 넣어도 된다. 조건식에 변수를 넣어 보자.
> let condition = true;
if (condition) {
console.log('Hello, if!');
}
Hello, if!
condition 변수가 true라는 값을 가지기 때문에 조건식에 condition 변수가 들어가면
실행문이 실행된다.
이번에는 값을 직접 넣었다.
> if (0) {
console.log(‘Hello, if!’);
}
(표시되지 않음)
0은 불 값으로 형 변환하면 false가 되므로 실행문이 실행되지 않는다.
중괄호 안에서 여러 개의 실행문을 실행할 수도 있다. 조건식이 참인 값이라면 실행문은
위에서 아래로 차례대로 실행된다.
> if (true) {
console.log('Hello, if!');
console.log('Hello, again!');
}
Hello, if!
Hello, again!
조건식이 false이므로 실행문이 실행되지 않는다. 하지만 console.log('Bye, if')는 조건문의
실행문이 아니라 일반 문이라서 실행된다. 중괄호가 없으면 바로 다음 문만 조건문에 포함되기
때문이다. 이처럼 실행문이 하나일 때 중괄호를 사용하지 않으면 조건문의 범위를 한눈에
알아보기 어려우므로 항상 실행문을 중괄호로 묶어 확실히 조건문의 일부임을 표시하는 것이 좋다.
> if (false) {
console.log('Hello, if!');
}
console.log('Bye, if');
Bye, if
<else를 사용해 두 방향으로 분기하기>
: 만약 조건식이 false일 때 값을 포도로 수정하고 싶다면 어떻게 해야 할까?
이를 위해 else가 존재한다.
if (조건식) { // 조건식이 참인 값일 때 실행
실행문;
} else { // 조건식이 거짓인 값일 때 실행
실행문;
}
let value = '사과';
let condition = false;
if (condition) {
value = ‘바나나’;
} else {
value = ‘포도’;
}
console.log(value);
포도
if 문 뒤에 else를 붙이고 다시 중괄호 안에 실행문을 입력하면 된다.
else 문에도 if 문과 마찬가지로 실행문을 여러 개 넣을 수 있고, 실행문이 하나인 경우 중괄호를
생략할 수 있다.
<else if를 사용해 여러 방향으로 분기하기>
: 앞에서 else 문을 사용해 조건이 true인 경우와 false인 경우, 두 가지를 분기 처리해 보았다.
하지만 이 세상 모든 것이 참과 거짓으로만 나뉘지는 않는다.
예를 들어, 점수에 따른 학점을 생각해보자.
90점 이상이면 A+, 80점 이상이면 A, 70점 이상이면 B+, 60점 이상이면 B, 60점 미만은 F인
수업이 있다고 가정해보자. 경우의 수가 다섯 가지나 된다.
이럴 때 else if 문을 사용할 수 있다. 세 가지 경우의 수를 표현하는 조건문은 다음과 같습니다.
if (조건식) {
실행문;
} else if (조건식) {
실행문;
} else {
실행문;
}
if 문 뒤에 else if 문을 적고, 그 뒤에 else if 문에 해당하는 조건식과 실행문을 추가한다.
else if 문도 if 문이나 else 문과 마찬가지로 실행문을 여러 개 넣을 수 있고 실행문이 하나인
경우에는 중괄호를 생략할 수도 있다.
else if 문 뒤에 else 문이 반드시 나와야 하는 것은 아니다.
if 문과 else if 문만 사용해도 되고, if 문과 else 문을 사용해도 된다. 단, else if 문이나 else 문을
단독으로 사용할 수는 없다. 항상 if 문이 처음에 나와야 한다.
세 가지 경우의 수를 else 문 없이 표현하면 다음과 같다.
if (조건식) {
실행문;
} else if (조건식) {
실행문;
} else if (조건식) {
실행문;
}
else if 문은 if 문과 else 문(생략 가능) 사이에 원하는 만큼 넣을 수 있다.
else if 문을 이용해 점수에 따른 학점을 코드로 표현했다.
> const score = 90;
if (score >= 90) { // 90점 이상
console.log('A+');
} else if (score < 90 && score >= 80) { // 90점 미만 80점 이상
console.log('A');
} else if (score < 80 && score >= 70) { // 80점 미만 70점 이상
console.log('B+');
} else if (score < 70 && score >= 60) { // 70점 미만 60점 이상
console.log('B');
} else { // 60점 미만
console.log('F');
}
A+
조건식은 불 값으로 형 변환되므로 논리 연산자를 사용해 식의 결괏값이 true나 false가
되게 만들었다.
여기서 조건문이 위에서부터 아래로 차례대로 실행된다는 특성을 이용해 논리적으로
생각해보면 코드를 더 효율적으로 수정할 수 있다.
코드를 정리하자면 다음과 같다.
> const score = 90;
if (score >= 90) { // 90점 이상
console.log('A+');
} else if (score >= 80) { // 80점 이상
console.log('A');
} else if (score >= 70) { // 70점 이상
console.log('B+');
} else if (score >= 60) { // 60점 이상
console.log('B');
} else { // 60점 미만
console.log('F');
}
A+
중복되는 말을 굳이 반복해서 적을 필요가 없고 간략하게 줄일 수 있다.
<중첩 if 문 사용하기>
: if나 else, else if 문의 중괄호 안에 실행문을 넣을 수 있다는 사실을 활용할 수 있다.
조건문도 문이므로 중괄호 안에 다시 넣을 수 있다.
> let first = true;
let second = false;
if (first) {
console.log('첫 번째 조건 충족!');
if (second) {
console.log('두 번째 조건도 충족!');
} else {
console.log('두 번째 조건은 불충족!');
}
} else {
console.log('첫 번째 조건 불충족!');
}
첫 번째 조건 충족!
두 번째 조건은 불충족!
코드가 많이 복잡해졌다. 하지만 이럴 때에도 위에서부터 차례대로 한 줄씩 생각해 보면 된다.
먼저 first 변수의 값이 true이므로 첫 조건문의 if 문이 실행됩니다. 하지만 second 변수의 값은
false라서 두 번째 조건문은 if 문이 아닌 else 문이 실행된다.
중첩 if 문은 피하는 것이 좋다.
중첩 if 문은 논리적으로 if-else if-else 문으로 변환할 수 있다. 조건문이 중첩되어 들여쓰기가
깊어질수록 코드는 읽기 어려워진다. 따라서 중첩 if 문을 if-else if-else 문으로 변환해 코드의
가독성을 높이길 권장한다.
앞 예제의 중첩 if 문을 바꿔 보자.
> let first = true;
let second = false;
if (first && second) { // first와 second 모두 true
console.log('첫 번째 조건 충족!');
console.log('두 번째 조건도 충족!');
} else if (first) { // first만 true
console.log('첫 번째 조건 충족!');
console.log('두 번째 조건은 불충족!');
} else { // 둘 다 false
console.log('첫 번째 조건 불충족!');
}
이처럼 중첩 if 문은 펴서 들여쓰기 깊이를 줄이는 것이 좋습니다.
좀 어렵지만 천천히 논리적으로 생각하는 연습을 해야한다 ! 이렇게 바꾸면 어떨까, 저렇게
바꾸면 어떨까 끊임없이 고민하고 코드의 가독성을 높이는 연습을 해야지 -
<switch 문으로 분기하기>
: 조건문에는 if 문 외에도 switch 문이 있다.
if 문과 switch 문은 조건이 충족되면 실행된다는 공통점도 있지만 차이점도 있다.
switch (조건식) {
case 비교 조건식:
실행문;
}
switch 문에는 조건식 두 개가 사용된다.
switch 옆 소괄호 조건식의 값이 case의 비교 조건식 값과 일치(===)하면 해당 실행문이
실행된다. 보통 조건식에 변수를 넣고, 비교 조건식에는 변수와 비교할 값을 넣는다.
> let value = 'A';
switch (value) {
case 'A':
console.log('A');
}
A
실행문을 여러 개 둘 수도 있다. 이때는 if 문과는 다르게 중괄호가 없어도 된다.
단, 중괄호가 있는 것과 없는 것에는 차이가 있다. 이 부분은 나중에 다루도록 하겠다.
> let value = 'A';
switch (value) {
case 'A':
console.log('A');
console.log('B');
}
A
B
if 문의 else if처럼 여러 방향으로 분기할 수도 있다. case를 여러 번 사용하면 된다.
> let value = 'B';
switch (value) {
case 'A':
console.log('A');
case 'B':
console.log('B');
case 'C':
console.log('C');
}
B
C
콘솔에 B가 출력될 것이라고 예상했겠지만, 실제로는 B와 C 모두 출력된다.
switch 문은 일치하는 case를 발견하면 일치 여부와 상관없이 그 아래 case들의 실행문을
모두 실행한다. 따라서 원하는 결과만 얻으려면 수동으로 case에서 빠져나와야 한다.
이때 break 문이 사용된다.
> let value = 'B';
switch (value) {
case 'A':
console.log('A');
break;
case 'B':
console.log('B');
break;
case 'C':
console.log('C');
break;
}
B
각 case에 break 문을 추가했더니 정확히 일치하는 case만 실행된다
어떠한 case도 일치하지 않을 때 실행하는 case도 만들 수 있다.
단, 이때는 case 대신 default라는 특수한 예약어를 사용한다.
> let value = 'F';
switch (value) {
case 'A':
console.log('A');
break;
case 'B':
console.log('B');
break;
case 'C':
console.log('C');
break;
default:
console.log('아무것도 일치하지 않음');
}
아무것도 일치하지 않음
'F'는 어떠한 case에도 해당하지 않으므로 default 부분이 실행된다.
default에는 break 문을 붙이지 않아도 된다. 맨 마지막 case라서 다음에 실행될 것이 없기
때문이다.
* 내용 출처