반복문을 통해 동일한 코드를 여러 번 반복할 수 있다.
while (condition) {
// 코드
// '반복문 본문(body)'이라 불림
}
condition 조건에 따라 본문 코드가 실행된다.
let i = 0;
while (i < 3) { // 0, 1, 2가 출력됩니다.
alert( i );
i++;
}
위 처럼 while문 내부에서 조건을 변화시켜 원하는 만큼 반복시킬 수 있다.
본문이 한 줄이면 대괄호를 쓰지 않아도 된다.
let i = 3; while (i) alert(i--);
do...while을 사용하면 condition을 반복문 아래로 옮길 수 있다.
맨 처음 본문을 무조건 한 번 실행한다는 점이 while문과 다른 점이다.
do {
// 반복문 본문
} while (condition);
대부분의 상황에서는 while을 사용하면 된다.
가장 많이 사용되는 반복문이다.
for (begin; condition; step) {
// ... 반복문 본문 ...
}
예시)
for (let i = 0; i < 3; i++) { // 0, 1, 2가 출력됩니다.
alert(i);
}
구성요소
인라인 변수 선언
for (let i = 0; i < 3; i++) { alert(i); // 0, 1, 2 } alert(i); // Error: i is not defined다음과 같이
i를 인라인으로 선언하여 사용할 수도 있는데, 해당 반복문 안에서만 변수 접근이 가능하다.
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++ );
}
각 요소를 생략은 가능하지만 ; 세미콜론은 꼭 넣어줘야 한다.
대개 반복문의 condition이 falsy가 되면 반복문이 종료된다.
하지만 특별 지시자 break를 사용하면 언제든지 반복문을 빠져나올 수 있다.
let sum = 0;
while (true) {
let value = +prompt("숫자를 입력하세요.", '');
if (!value) break; // (*)
sum += value;
}
alert( '합계: ' + sum );
(*)의 break는 사용자가 아무 입력을 하지 않거나, Cancel버튼을 눌렀을 때 활성화된다.
반복문 시작이나 끝 지점에서 조건을 확인하는게 아니라, 본문 가운데나 여러 곳에서 조건 확인을 해야하는 경우 이렇게 break문을 사용하면 좋다.
continue 지시자는 현재 실행중인 반복을 멈추고, 다음 반복을 강제로 실행시키도록 한다.(조건을 통과할 때)
예시)
for (let i = 0; i < 10; i++) {
// 조건이 참이라면 남아있는 본문은 실행되지 않습니다.
if (i % 2 == 0) continue;
alert(i); // 1, 3, 5, 7, 9가 차례대로 출력됨
}
위 코드는 짝수인 경우에 continue가 실행되어 alert문을 실행하지 않고 건너뛰는 방식이다.
continue는 중첩을 줄이는 데 도움이 된다.for (let i = 0; i < 10; i++) { if (i % 2) { alert( i ); } }다음 코드도 홀수를 출력하는 코드인데,
if문이 내부에 하나 더 있다.
'?' 조건부 연산자의 오른쪽에는
break나continue가 올 수 없다.(i > 5) ? alert(i) : continue; // 여기에 continue를 사용하면 안 됩니다.이러한 코드는 문법 에러가 발생한다.
?조건부 연산자를if대용으로 쓰면 안되는 이유 중 하나이다.if문 예시)
if (i > 5) { alert(i); } else { continue; }
여러 개의 중첩문을 한 번에 빠져나와야 하는 경우에 사용한다.
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
let input = prompt(`(${i},${j})의 값`, '');
// 여기서 멈춰서 아래쪽의 `완료!`가 출력되게 하려면 어떻게 해야 할까요?
}
}
alert('완료!');
위 예시에서 그냥 break를 사용한다면 내부에 있는 for문만 빠지게 될 것이다.
그래서 레이블(label)을 사용한다.
레이블이란 반복문 앞에 : 콜론과 함께 쓰이는 식별자다.
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('완료!');
또는 레이블을 별도의 줄에 써주는 것도 가능하다.
outer:
for (let i = 0; i < 3; i++) { ... }
레이블을 통해서 continue 지시자도 사용할 수 있다.
레이블이 마음대로 '점프'할 수 있게는 해주지 않는다.
틀린 예시)break label; // 아래 for 문으로 점프할 수 없습니다. label: for (...)레이블은 반드시
break나continue지시자 위에 있어야 한다.
switch문은 하나 이상의 case문으로 구성된다. 대개 default문도 있지만, 필수는 아니다.
예시)
switch(x) {
case 'value1': // if (x === 'value1')
...
[break]
case 'value2': // if (x === 'value2')
...
[break]
default:
...
[break]
}
x와 case문의 값 value1을 비교해 일치하면 실행, 다르면 다음 case로 넘어간다.break문을 만나거나, switch문이 끝나면 코드 실행을 멈춘다.default문이 있는 경우 모든 case문에서 매칭이 안된 경우 default문이 실행된다.case문 안에 break문이 없는 경우는 조건에 만족하든 안하든 다음 case문을 실행한다.break없는 switch문 예시)
let a = 2 + 2;
switch (a) {
case 3:
alert( '비교하려는 값보다 작습니다.' );
case 4:
alert( '비교하려는 값과 일치합니다.' );
case 5:
alert( '비교하려는 값보다 큽니다.' );
default:
alert( "어떤 값인지 파악이 되지 않습니다." );
}
위 예시 결과는 다음과 같다.
alert( '비교하려는 값과 일치합니다.' );
alert( '비교하려는 값보다 큽니다.' );
alert( "어떤 값인지 파악이 되지 않습니다." );
switch/case문 인수에 어떤 표현식이든 올 수 있다.
예시)let a = "1"; let b = 0; switch (+a) { case b + 1: alert("표현식 +a는 1, 표현식 b+1는 1이므로 이 코드가 실행됩니다."); break; default: alert("이 코드는 실행되지 않습니다."); }
코드가 같은 case문은 한 곳에 묶을 수 있다.
let a = 3;
switch (a) {
case 4:
alert('계산이 맞습니다!');
break;
case 3: // (*) 두 case문을 묶음
case 5:
alert('계산이 틀립니다!');
alert("수학 수업을 다시 들어보는걸 권유 드립니다.");
break;
default:
alert('계산 결과가 이상하네요.');
}
switch문은 일치 비교(===)로 조건을 확인해서 자료형까지 같아야 해당 case문이 실행된다. (==는 동등 비교)
예시)
let arg = prompt("값을 입력해주세요.");
switch (arg) {
case '0':
case '1':
alert( '0이나 1을 입력하셨습니다.' );
break;
case '2':
alert( '2를 입력하셨습니다.' );
break;
case 3:
alert( '이 코드는 절대 실행되지 않습니다!' );
break;
default:
alert( '알 수 없는 값을 입력하셨습니다.' );
}
해당 예시 코드에서 case 3부분은 자료형이 달라 실행되지 않는다.
스크립트를 작성하다 보면 유사한 동작의 코드를 여러 곳에서 필요하는 경우가 있다.
함수를 사용하면 코드 중복을 줄일 수 있다.
예시에서의 alert(message), prompt(message, default) 부분들이 내장 함수를 사용한 것이다.
function name(parameters) {
...함수 본문...
}
function 키워드와 함께 사용하고, 함수 이름, 매개변수, 함수 본문으로 구성된다.
이렇게 정의한 함수는 name('Hello')와 같은 형태로 함수 이름 옆에 괄호 및 매개변수를 붙여 호출할 수 있다.
함수 내에서 선언한 지역 변수(local variable)은 해당 함수에서만 접근할 수 있다.
function showMessage() {
let message = "안녕하세요!"; // 지역 변수
alert( message );
}
showMessage(); // 안녕하세요!
alert( message ); // ReferenceError: message is not defined (message는 함수 내 지역 변수이기 때문에 에러가 발생합니다.)
함수 외부에서 선언한 변수(outer variable)는 함수 내부에서도 접근할 수 있다.
let userName = 'John';
function showMessage() {
let message = 'Hello, ' + userName;
alert(message);
}
showMessage(); // Hello, John
함수 외부 변수에 접근하는 것 뿐만 아니라, 수정도 할 수 있다.
let userName = 'John';
function showMessage() {
userName = "Bob"; // (1) 외부 변수를 수정함
let message = 'Hello, ' + userName;
alert(message);
}
alert( userName ); // 함수 호출 전이므로 John 이 출력됨
showMessage();
alert( userName ); // 함수에 의해 Bob 으로 값이 바뀜
만약 함수 내부에서 외부 변수와 동일한 이름을 가진 변수가 선언되면, 해당 내부 변수가 외부 변수를 가려 함수 내부에서는 해당 내부 변수에만 접근해서 사용하게 된다.
let userName = 'John';
function showMessage() {
let userName = "Bob"; // 같은 이름을 가진 지역 변수를 선언합니다.
let message = 'Hello, ' + userName; // Bob
alert(message);
}
// 함수는 내부 변수인 userName만 사용합니다,
showMessage();
alert( userName ); // 함수는 외부 변수에 접근하지 않습니다. 따라서 값이 변경되지 않고, John이 출력됩니다.
전역 변수
위 예시의userName처럼 함수 외부에 선언된 변수를 전역 변수(global variable)이라고 한다.
변수는 가능한 연관된 함수 내에 선언하고, 전역 변수는 가급적 사용하지 않는 것이 좋다.
매개변수를 이용해 데이터를 함수 내부에 전달할 수 있다.
그리고 함수에 전달된 매개변수는 지역 변수에 복사되어 사용하여, 해당 값을 수정해도 외부 변수에는 영향을 미치지 않는다.
예시)
function showMessage(from, text) {
from = '*' + from + '*'; // "from"을 좀 더 멋지게 꾸며줍니다.
alert( from + ': ' + text );
}
let from = "Ann";
showMessage(from, "Hello"); // *Ann*: Hello
// 함수는 복사된 값을 사용하기 때문에 바깥의 "from"은 값이 변경되지 않습니다.
alert( from ); // Ann
매개변수에 값을 전달하지 않으면 undefined가 된다.
function showMessage(from, text){
...
}
다음과 같은 형태의 함수가 있을 때 showMessage('Ann')처럼 두 인자 중, 일부분의 인수만 전달할 수 있다.
전달되지 않은 text는 undefined인 상태이다.
이때 기본값을 설정하면 인자로 값이 전달되지 않아도 해당 변수를 특정 값으로 초기화 할 수 있다.
function showMessage(from, text = "no text given") {
...
}
또는 다음과 같이 표현식을 기본값으로 설정할 수도 있다. 해당 예시에서는 매개변수가 없을 때만 기본값을 평가하게 된다.
function showMessage(from, text = anotherFunction()) {
// anotherFunction()은 text값이 없을 때만 호출됨
// anotherFunction()의 반환 값이 text의 값이 됨
}
undefined와 비교해 매개변수가 생략되었는지 확인function showMessage(text) {
if (text === undefined) {
text = '빈 문자열';
}
alert(text);
}
showMessage(); // 빈 문자열
||를 사용// 매개변수가 생략되었거나 빈 문자열("")이 넘어오면 변수에 '빈 문자열'이 할당됩니다.
function showMessage(text) {
text = text || '빈 문자열';
...
}
??를 사용// 매개변수 'count'가 넘어오지 않으면 'unknown'을 출력해주는 함수
function showCount(count) {
alert(count ?? "unknown");
}
showCount(0); // 0
showCount(null); // unknown
showCount(); // unknown
함수를 호출한 부분에 특정 값을 반환할 수 있다.
이러한 값을 반환 값(return value)라고 한다.
예시)
function sum(a, b) {
return a + b;
}
let result = sum(1, 2);
alert( result ); // 3
함수에서 return 지시자를 만나는 경우 함수 실행은 즉시 중단되고, 함수를 호출한 부분에 값을 반환한다.
다음 같이 함수 내부에서 여러 return문이 올 수도 있다.
function checkAge(age) {
if (age >= 18) {
return true;
} else {
return confirm('보호자의 동의를 받으셨나요?');
}
}
다음 같이 return만 명시해 함수를 종료할 수도 있다.
function showMovie(age) {
if ( !checkAge(age) ) {
return;
}
alert( "영화 상영" ); // (*)
// ...
}
return문이 없거나return지시자만 있는 경우 함수는undefined를 반환한다.function doNothing() { /* empty */ } alert( doNothing() === undefined ); // truefunction doNothing() { return; } alert( doNothing() === undefined ); // true
return과 값 사이에 줄바꿈을 하면 안된다.return (some + long + expression + or + whatever * f(a) + f(b))위와 같이 작성하는 경우
return문 끝에 자동으로;세미콜론이 들어가게 되어 의도하지 않는 동작을 하게 된다.
return문을 여러 줄에 걸쳐 작성하고 싶으면,return지시자가 있는 줄에서 시작하도록 작성해야 한다.return ( some + long + expression + or + whatever * f(a) + f(b) )
함수는 어떤 동작을 수행하기 위한 코드를 모아놓은 것이다. 그래서 함수 이름은 대개 동사이다.
간결하고 명확하게 함수가 어떤 동작을 하는지 설명할 수 있게 네이밍하는게 중요하다.
접두어를 사용한 변수 네이밍 예시)
show...: 무언가를 보여주는 함수get...: 값을 반환하는 함수calc...: 계산하는 함수create...: 생성하는 함수check...: 확인하고 boolean값을 반환하는 함수함수 예시)
showMessage(..) // 메시지를 보여줌
getAge(..) // 나이를 나타내는 값을 얻고 그 값을 반환함
calcSum(..) // 합계를 계산하고 그 결과를 반환함
createForm(..) // form을 생성하고 만들어진 form을 반환함
checkPermission(..) // 승인 여부를 확인하고 true나 false를 반환함
함수는 하나의 동작만 담당해야 한다.
함수 이름에 언급된 동작만 수행하고, 그 이외의 동작을 수행해서는 안된다.
아주 짧은 이름
아주 빈번하게 쓰이는 함수들 중 이름이 아주 짧은 함수가 있다.
jQuery에서 쓰이는$,Lodash라이브러리의_와 같은 함수들이 있다.
네이밍 규칙은 지켜지지 않지만, 빈번하게 쓰여 간단한 네이밍으로 작성된 함수들이다.
함수를 간결하게 만드는 것이 중요하다. 함수가 길어지면 잘게 쪼갤 때가 되었다는 신호로 받아들여야 한다.
디버깅이 쉬워지고 함수 자체로 주석 역할까지 할 수 있다.
n까지의 소수를 출력하는 코드를 비교해보자.
showPrimes(n)만으로 작성된 코드function showPrimes(n) {
nextPrime: for (let i = 2; i < n; i++) {
for (let j = 2; j < i; j++) {
if (i % j == 0) continue nextPrime;
}
alert( i ); // 소수
}
}
showPrimes(n)과 isPrime(n)으로 작성된 코드function showPrimes(n) {
for (let i = 2; i < n; i++) {
if (!isPrime(i)) continue;
alert(i); // a prime
}
}
function isPrime(n) {
for (let i = 2; i < n; i++) {
if ( n % i == 0) return false;
}
return true;
}
두 번째 함수를 나눈 코드가 더 이해하기 쉬운 것을 알 수 있다.
이렇게 함수를 활용하면 코드가 정돈되고 가독성이 높아지는 효과가 있다.
javascript에서 함수는 특별한 종류의 값으로 취급된다.
지금까지 함수 선언을 함수 선언문방식으로 함수를 만들었다.
function sayHi() {
alert( "Hello" );
}
다른 방식으로도 함수를 선언할 수 있다.
다음은 함수 표현식을 사용해 함수를 선언한 것이다.
let sayHi = function() {
alert( "Hello" );
};
함수를 생성하고 변수에 값을 할당하는 것처럼 함수를 할당하고 있다.
함수는 값이기 때문에 alert를 이용해 함수 코드를 출력할 수도 있다.
function sayHi() {
alert( "Hello" );
}
alert( sayHi ); // 함수 코드가 보임
마지막 코드에서 sayHi뒤에 괄호가 없어서 함수가 실행되지 않는다. 소스 코드가 문자형으로 형변환 되어 출력된다.
함수는 값이기 때문에 변수처럼 복사해 다른 변수에 할당하는 것도 가능하다.
function sayHi() { // (1) 함수 생성
alert( "Hello" );
}
let func = sayHi; // (2) 함수 복사
func(); // Hello // (3) 복사한 함수를 실행(정상적으로 실행됩니다)!
sayHi(); // Hello // 본래 함수도 정상적으로 실행됩니다.
(2)번에서 sayHi에 괄호를 붙인다면 해당 함수 결과가 저장되었을텐데, 위 같이 작성해 함수 그 자체를 변수에 저장하게 되었다.
함수 표현식 끝에는 왜 세미콜론
;이 붙을까?function sayHi() { // ... } let sayHi = function() { // ... };
if {...},for {...},function f {...}와 같이 중괄호로 만든 코드 블록 끝에는;이 없어도 된다.- 함수 표현식에서는
let sayHi = ...;같이 구문의 값과 같은 역할을 하기 때문에;이 필요하다.
함수를 값처럼 전달할 수 있어 사용되는 개념이다.
아래 예시를 보자.
매개변수가 3개 있는 함수 ask(question, yes, no)를 작성한다.
question: 질문 내용yes: Yes라고 대답한 경우 실행되는 함수no: No라고 대답한 경우 실행되는 함수예시)
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
function showOk() {
alert( "동의하셨습니다." );
}
function showCancel() {
alert( "취소 버튼을 누르셨습니다." );
}
// 사용법: 함수 showOk와 showCancel가 ask 함수의 인수로 전달됨
ask("동의하십니까?", showOk, showCancel);
여기서 인수로 전달되는 showOk, showCancel을 콜백 함수 또는 콜백이라고 부른다.
함수를 인수로 전달하고, 전달 받은 함수를 나중에 호출(called back)하는 것이 콜백 함수의 개념이다.
위 코드를 함수 표현식으로 작성하면 코드가 더 짧아진다.
표현식으로 작성한 예시)
function ask(question, yes, no) {
if (confirm(question)) yes()
else no();
}
ask(
"동의하십니까?",
function() { alert("동의하셨습니다."); },
function() { alert("취소 버튼을 누르셨습니다."); }
);
ask 함수 내부에 표현식 형태로 함수를 선언한 것이다.
이렇게 이름이 없는 함수를 익명 함수(anonymous function)이라고 부른다.
익명 함수는 변수에 할당된 것이 아니라 ask함수 외부에서는 접근할 수 없다. 위 예시는 이러한 의도를 가지고 구현하여 바깥에서 접근하지 못해도 문제가 없다.
함수 표현식과 선언문의 차이를 정리하겠다.
첫째로 문법이다.
// 함수 선언문
function sum(a, b) {
return a + b;
}
// 함수 표현식
let sum = function(a, b) {
return a + b;
};
두 번째로 javascript 엔진이 언제 함수를 생성하는지 차이가 있다.
함수 선언문은 스크립트 어디에서 선언하든 상관 없이 사용할 수 있다.
이는 스크립트를 실행하기 전 초기화 단계에서 전역에 선언된 함수 선언문을 찾고 해당 함수를 생성하기 때문이다.
sayHi("John"); // Hello, John
function sayHi(name) {
alert( `Hello, ${name}` );
}
그러나 함수 표현식으로 정의된 함수는 선언되기 전에는 접근이 불가능하다.
sayHi("John"); // error!
let sayHi = function(name) { // (*) 마술은 일어나지 않습니다.
alert( `Hello, ${name}` );
};
함수 표현식은 실행 흐름이 표현식에 다다랐을 경우 만들어진다. (*) 줄에 실행 흐름이 도달했을 경우 함수가 만들어진다.
세 번째로 스코프의 차이가 있다.
(strict mode에서) 함수 선언문이 코드 블록 내부에 위치하면 블록 내에서만 접근 가능하고, 블록 외부에서는 해당 함수에 접근하지 못한다.
함수 선언식 예제)
let age = prompt("나이를 알려주세요.", 18);
// 조건에 따라 함수를 선언함
if (age < 18) {
function welcome() {
alert("안녕!");
}
} else {
function welcome() {
alert("안녕하세요!");
}
}
// 함수를 나중에 호출합니다.
welcome(); // Error: welcome is not defined
함수 표현식 예제)
let age = prompt("나이를 알려주세요.", 18);
let welcome;
if (age < 18) {
welcome = function() {
alert("안녕!");
};
} else {
welcome = function() {
alert("안녕하세요!");
};
}
welcome(); // 제대로 동작합니다.
함수 선언문 vs 함수 표현식
함수 선언문을 사용해 함수를 선언하는 걸 먼저 고려하는게 좋다. 함수 선언문으로 함수를 정의하면, 함수를 선언하기 전에 호출할 수 있어 코드 구성이 좀 더 자유로워진다.
다른 장점으로 가독성이 더 좋아진다.let f = function(…) {…}로 사용하는 것 보다function f(…) {…}를 찾는 게 더 쉽다.
그러나 함수 선언 방식이 적합하지 않거나, 위 예시처럼 조건에 따라 함수를 선언해야 하는 경우라면 함수 표현식을 사용해야 한다.
let func = (arg1, arg2, ...argN) => expression
다음과 같은 형태로 함수를 선언하는 방식인데, 문법의 생김새에 의해 화살표 함수(arrow function)이라 부른다.
함수 표현식보다 간단한 방법으로 함수를 선언할 수 있다.
위 화살표 함수는 표현식으로는 다음과 같이 쓸 수 있다.
let func = function(arg1, arg2, ...argN) {
return expression;
};
다음은 더 구체적인 예시이다.
let sum = (a, b) => a + b;
/* 위 화살표 함수는 아래 함수의 축약 버전입니다.
let sum = function(a, b) {
return a + b;
};
*/
alert( sum(1, 2) ); // 3
let double = n => n * 2;
// let double = function(n) { return n * 2 }과 거의 동일합니다.
alert( double(3) ); // 6
let sayHi = () => alert("안녕하세요!");
sayHi();
구문이 여러 개인 함수를 화살표 함수로 표현하는 경우는 중괄호 + return 지시자로 명시적으로 결과값을 반환해주어 표현해야 한다.
let sum = (a, b) => { // 중괄호는 본문 여러 줄로 구성되어 있음을 알려줍니다.
let result = a + b;
return result; // 중괄호를 사용했다면, return 지시자로 결괏값을 반환해주어야 합니다.
};
alert( sum(1, 2) ); // 3
기존 선언식, 표현식으로 표현한 함수를 화살표 함수로 작성하는 방법을 알아보았는데 여기서 끝이 아니다.
화살표 함수는 이 외에도 다른 기능이 추가되는데 이는 이후 "화살표 함수 다시 살펴보기"에서 추가적으로 다룰 예정이다.
지금까지 정리한 내용 중 실수할 수 있는 부분 중심으로 요약해본다.
여러 개의 구문은 세미콜론 ;을 기준으로 구분한다.
alert('Hello'); alert('World');
줄 바꿈도 여러 구문을 구분하는데 사용된다.
alert('Hello')
alert('World')
위 코드는 세미콜론 자동 삽입이라는 동작 방식 덕분에 정상적으로 동작되는데, 세미콜론 자동 삽입이 의도와 다르게 동작하는 경우도 있다.
alert("이 메시지가 출력된 후에 에러가 발생합니다.")
[1, 2].forEach(alert)
코드 블록({...})이나, 코드 블록과 함께 구성되는 문법(ex. 반복문)을 제외하고는 세미콜론을 붙이는 것을 권장한다.
모던 자바스크립트에서 지원하는 기능을 사용하려면 스크립트 최상단에 use strict를 기입해야 한다.
use strict를 선언하지 않으면 코드는 정상적으로 동작하지만 하위 호환성을 지키며 옛날 방식으로 동작한다.
참고로, 클래스와 같은 모던한 기능을 사용하면 strict mode를 자동으로 활성화 시켜준다.
letvar (let 사용을 권장)const (상수 선언)변수명 명명 규칙은 다음과 같다.
$나 _만 사용 가능하다.자바스크립트는 동적 타이핑을 허용해, 자료형을 바꿔가며 값을 할당할 수 있다.
let x = 5;
x = "John";
8가지 자료형을 지원한다.
typeof 연산자는 값의 자료형을 반환해준다. but 2가지 예외상황이 있다.
typeof null == "object" // 언어 자체의 오류
typeof function(){} == "function" // 함수는 특별하게 취급됩니다.
호스트 환경이 브라우저인 경우 다음 UI 함수를 이용해 상호작용 할 수 있다.
question을 사용자에게 보여주고, '확인' 버튼을 누르면 사용자의 입력 값을 반환, '취소' 버튼을 누르면 null을 반환한다.question을 사용자에게 보여주고, '확인' 버튼을 누르면 true, 그 외의 경우 false를 반환한다.message를 담은 alert창을 보여준다.세 함수 모두 모달창을 띄워주는데, 모달 창이 닫히기 전까지 코드 실행이 중지되고 모달 창 외의 페이지의 그 무엇과도 상호작용 할 수 없다.
자바스크립트는 다음 연산자들을 제공한다.
* + - / % **연산이 있다.a=b 형태의 할당 연산자와 a*=2 형태의 복합 할당 연산자가 있다.cond ? resultA : resultB 형태로 사용하고, cond을 만족하면 resultA, 아니면 resultB를 반환한다.&&와 OR 연산자 ||는 단락 평가를 수행하고, 평가가 멈춘 시점의 값을 반환한다.!는 자료형을 boolean형으로 바꾼 뒤 그 역을 반환한다.??는 실제 값이 정의된 피연산자를 찾는데 사용된다. a??b에서 a가 null, undefined가 아니면 a를 반환하고 그 외에는 b를 반환한다.==는 다른 값끼리 비교할 때 피연산자 자료형을 숫자형으로 바꾼 뒤 비교를 진행한다.null, undefined는 자기끼리 비교할 때는 true, 다른 자료형과 비교할 때는 false를 반환한다.< > <= >=도 피연산자 자료형을 숫자로 바꾼 후 비교를 진행하지만,===는 피연산자 형변환을 하지 않고 비교한다. 형이 다르면 무조건 false를 반환한다.// 1
while (condition) {
...
}
// 2
do {
...
} while (condition);
// 3
for(let i = 0; i < 10; i++) {
...
}
for(let...) 안쪽에 선언한 변수는 반복문 내에서만 사용 가능하다. let을 생략하고 기존 선언된 변수를 사용하는 것도 가능하다.break, continue는 현재 실행중인 반복문 또는 반복을 빠져나갈 때 사용한다. 레이블은 중첩 반복문을 빠져나갈 때 사용한다.switch문은 내부적으로 === 일치 연산자를 사용해 비교한다. 그래서 자료형까지 동일해야한다.
세 가지 방법으로 함수를 선언할 수 있다.
function sum(a, b) {
let result = a + b;
return result;
}
let sum = function(a, b) {
let result = a + b;
return result;
};
// 화살표(=>) 우측엔 표현식이 있음
let sum = (a, b) => a + b;
// 대괄호{ ... }를 사용하면 본문에 여러 줄의 코드를 작성할 수 있음. return문이 꼭 있어야 함.
let sum = (a, b) => {
// ...
return a + b;
}
// 인수가 없는 경우
let sayHi = () => alert("Hello");
// 인수가 하나인 경우
let double = n => n * 2;
function sum(a = 1, b = 2) {...}return문이 없는 경우는 undefined를 반환한다.