[함께보면 좋은 글] 문(장)과 표현식
표현문(expression statement) : 할당, 함수 호출처럼 부수효과가 있는 표현식이자 문장
선언문(declaration statement) : 변수 선언 또는 함수 정의
제어문(control structure) : 동작의 기본 실행 순서를 바꾸는 문장
할당문, ++
--
delete
연산자, 함수 호출 등
let myNum = 42;
myNum++;
let myFunction = function(){
myNum--;
console.log(myNum);
}
myFunction(); // 42
문 블록 { }
안에 ;
세미 콜론으로 구분하여 여러 문을 하나의 복합문으로 묶을 수 있다.
{}
블록은 ;
세미콜론으로 끝나지 않는다.{}
블록 안에 들어 있는 각 문은 들여쓴다.{
x = Math.Pi;
cx = Math.cos(x);
console.log("con(𝜋) =" + cx);
}
문 자리에 ;
만 작성
빈 바디를 갖는 반복문(loop)를 만들 때 주로 사용
const a = [1, 2, 3, 4, 5];
for(let i = 0; i<a.length; a[i++] = 0);
// for문의 body 자리에 { } 대신 ; 사용
// 이 for문의 의도는 a의 모든 요소들이 0으로 초기화하는 것
console.log(a); // [ 0, 0, 0, 0, 0 ]
if ( 조건1 ) {
조건1이 true일 때 동작;
} else if ( 조건2 ) {
조건2가 true일 때 동작;
} else {
조건1, 조건2가 모두 false일 때 동작;
}
{ }
중괄호 및 들여쓰기
를 주의해야한다. 특정한 값과 일치(===
)하는 지에 대한 조건을 만들 때 효과적이다.
값
뿐만아니라 타입
도 같아야 한다.각 case
의 마지막에 break;
를 적어 일치하는 case에서 종료될 수 있도록 끝을 지정해주어야 한다.
default:
)까지 모두 실행한다함수
안에서 switch문을 쓸 때에는 break 대신 return
을 써도 된다.어떤 case와도 일치하지 않는 경우 default:
를 실행한다.
// [심리테스트] 마음에 드는 동물을 골라주세요.
// 1 토끼 2 고양이 3 코알라 4 강아지
let myChoice = 2;
switch(myChoice) {
case 1:
console.log('토끼를 선택한 당신, ...');
break;
case 2:
console.log('고양이를 선택한 당신, ...');
break;
case 3:
console.log('코알라를 선택한 당신, ...');
break;
case 4:
console.log('강아지를 선택한 당신, ...');
break;
default:
console.log('1에서 4사이의 숫자를 선택해 주세요.');
}
// 고양이를 선택한 당신, ...
① 조건문 밖에서 변수를 선언하여, 그 결과를 조건문 밖에서 사용할 때,
② 반복 횟수가 정해져있지 않을 때 사용 할 수 있다.
while(true)
일 때 조건과 연관된 변수가 변하지 않는 경우 무한 루프
에 빠지게 되므로
(무한 루프를 의도한 것이 아니라면)
루프를 반복할 때마다 변수가 바뀔 수 있도록 지정해줘야 한다.
// 30보다 큰 수 중 가장 작은 7의 배수는?
let i = 30;
while(i % 7 !== 0){
i++
}
console.log(i); // 35
동작을 실행 후 조건을 평가하기 때문에 적어도 1회 이상 동작을 실행한다.
while(조건) 문장의 마지막에 ;
세미콜론을 마지막에 반드시 붙여주어야 한다.
let i = 30;
do {
i++;
} while (i % 7 !== 0); // 세미콜론 필수
console.log(i); // 35
변수 선언
, 조건
, 변수 변화
모두 생략할 수 있지만, ;
세미콜론은 필수이다.
조건 부분을 생략하면 무한 루프에 빠질 수 있다.
배열은 '동적'으로 순회하기 때문에 반복 도중 배열 자체에 변화가 생기면 반복 결과가 달라질 수 있다.
let myArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
for (i = 0; i < myArray.length; i++) {
myArray.splice(i, 1); // i번째 인덱스 1개 삭제
}
console.log(myArray); // [ 2, 4, 6, 8, 10 ]
// 제일 처음 루프에서는 myArray[1] 은 2이지만, 1이 삭제 된 후 myArray[1] 은 3이다.
of 의 왼쪽 변수에 배열의 모든 요소가 순회하며 할당된다.
배열(Array)
, 문자열(String)
, 세트(Set)
, 맵(Map)
과 같은 이터러블(iterable) 객체에서 동작한다.
일반적인 객체에 for of 반복문을 사용할 경우 TypeError 발생한다.
Object.keys(객체)
, Object.values(객체)
, Objecct.Entries(객체)
에서는 사용 가능😄
이모지는 UTF-16 문자 2 개로 이루어져 있어 length 가 2이지만,
(ES6 이후) 하나의 프로퍼티 네임으로, 이모지 1개당 1번의 반복을 실행한다.
console.log("😀".length); // 2
let myArray = ["😀", "♥︎", "a", "☺︎", 1];
let i = 0;
for (el of myArray) {
i++;
console.log(`${i}회 반복 : ${el}`);
}
/*
1회 반복 : 😀
2회 반복 : ♥︎
3회 반복 : a
4회 반복 : ☺︎
5회 반복 : 1
*/
[함께보면 좋은 글] Map과 Set
Map 객체의 이터레이터는 키-값의 쌍을 순회한다.
첫 번째 요소가 키, 두번째 요소가 값인 배열을 순회한다.
let myMap = new Map();
myMap.set("1", "문자열 1");
myMap.set(2, "숫자형 2");
myMap.set(true, "불린형 트루");
console.log(myMap);
// Map(3) { '1' => '문자열 1', 2 => '숫자형 2', true => '불린형 트루' }
for (let [key, value] of myMap) {
console.log(`myMap의 키 ${key}은(는) ${typeof key} 타입이고, 값은 ${value} 입니다.`);
}
/*
myMap의 키 1은(는) string 타입이고, 값은 문자열 1 입니다.
myMap의 키 2은(는) number 타입이고, 값은 숫자형 2 입니다.
myMap의 키 true은(는) boolean 타입이고, 값은 불린형 트루 입니다.
*/
객체의 모든 key가 in 왼쪽의 변수에 순회하며 할당된다.
배열에 사용할 경우 인덱스 번호가 key역할을 한다.
다음 프로퍼티는 for in 문을 실행하더라도 열거되지 않는다.
let myObj = { x: 1, y: 2, z: 3 };
for (key in myObj) {
console.log(key);
console.log(myObj[key]);
}
// x 1 y 2 z 3
break
: 반복문(loop) 또는 다른 문의 끝으로 이동continue
: 반복문(loop)의 해당 회차의 나머지를 생략하고 새로운 반복 시작return
: 함수를 빠져나와 값을 전달yield
: 제너레이터 함수에서 사용하는 return 비슷한 문throw
: 예외를 발생시킨다.try
, catch
, finally
문과 함께 사용label 이름:
주로 반복문(loop)
또는 조건문
에서 사용한다.
label
을 사용하면, break
또는 continue
를 만났을 때 label
이 있는 곳으로 루프를 빠져나갈 수 있다.
let myAry = [[11, 12, 13, 14], [21, 22, 23, 24], [31, 32, 33, 34], [41, 42, 43, 44]];
// laber 없이 break; 사용했을 때 : 가까운 loop만 빠져나간다.
for (let i = 0; i < myAry.length; i++) {
for (let j = 0; j < myAry[i].length; j++) {
if (myAry[i][j] === 22) {
break;
}
console.log(myAry[i][j]);
}
} // 11 12 13 14 21 31 32 33 34 41 42 43 44
// label을 사용했을 때 : 해당 label로 빠져나간다.
outloof: for (let i = 0; i < myAry.length; i++) {
for (let j = 0; j < myAry[i].length; j++) {
if (myAry[i][j] === 22) {
break ouutloof;
}
console.log(myAry[i][j]);
}
} // 11 12 13 14 21
break;
자동으로 ;
세미 콜론 삽입된 것으로 인식자신을 포함한 가장 가까문 loop 또는 switch 문을 빠져나간다.
일반 { }
문 블록도 빠져나갈 수 있지만,
❌ label을 쓰더라도 함수 밖
으로는 빠져나갈 수 없다.
function myFunction() {
onelabel: { // 조건문, 반복문이 아닌 일반 { } 도 빠져나갈 수 있다.
console.log("normal");
break onelabel;
console.log("it wouldn't be printed");
}
console.log("Is it printed?");
}
myFunction();
/* normal
Is it printed? */
// 하지만 함수 밖으로는 빠져나갈 수 없다.
onelabel: function myFunction() { // 함수 밖으로 label 지정
{
console.log("normal");
break onelabel;
console.log("it wouldn't be printed");
}
console.log("Is it printed?");
}
myFunction(); // SyntaxError: Undefined label 'onelabel'
continue를 만나는 순간 현재 반복을 멈추고 다음 반복으로 넘어간다.
(label이 있든 없든) 반복문(loop) 바디 안에서만 사용할 수 있다.
for (j = 1; j < 5; j++) {
if (j === 3) {
continue;
}
console.log(j);
} // 1 2 4
return;
만 사용할 수도 있으며, 이 경우 undefined
를 반환한다.return
과 반환하는 값
사이에 줄을 바꿀 수 없다.지정된 객체의 프로퍼티가 해당 블록의 스코프 안에 있는 변수인 것처럼 코드 블록을 실행한다.
❌ 사용하지 않는 것이 좋다.
웹 브라우저에서 개발자 도구를 열고 debugger 프로그램을 통해 변수 값을 출력하거나 콜 스택을 살펴볼 수 있다.
strict 모드는 자바스크립트의 중요한 결함을 수정하고, 더 강력히 에러를 체크하며, 보안을 강화한 것이다.
전체 스크립트
또는 특정 함수
에 적용 가능하다.맨 처음
, 함수에 적용하는 경우 바디의 맨 처음
에만 존재할 수 있고, 이 앞에 실제 문이 있어서는 안된다.class 바디
, ES6 모듈
안에 있는 코드는 'use strict'을 명시적으로 사용하지 않았더라도 자동으로 strict 모드를 따른다.선언 후
사용할 수 있다.// 일반 모드
x = 3;
console.log(x); // 3
// strict 모드
"use strict";
x = 3; // ReferenceError: x is not defined
console.log(x);
this
값은 undefined
이다.전역 객체
이다.call()
이나 apply()
로 호출했을 때 this
값은 전달된 첫 번째 인자
이다.null
이나 undefined
값이 전역 객체
로 대체되며 객체
가 아닌 값은 객체
로 변환된다.읽기 전용
프로퍼티에 할당, 확장 불가능한 객체
에 새 프로퍼티 생성, 변경 불가(non-configurable)
프로퍼티 삭제(delete)하면 TypeError 발생한다.delete
연산자 뒤 변수, 함수, 함수 매개변수 등 유효하지 않은 식별자
를 사용하면 SyntaxError가 발생한다. 같은 이름의 매개변수
가 2개 이상 있으면 SyntaxError 발생한다.[함께 보면 좋은 글] 함수 선언문과 함수 표현식 차이
클래스 선언은 호이스팅 되지 않으며, 선언하기 전에 사용할 수 없다
함수나 클래스를 하나의 모듈안에서 정의한 후 export(내보내기)
로 값을 내보내고,
사용하고 싶은 다른 모듈에서 import(가져오기)
로 가져오면, 다른 모듈에서도 사용할 수 있다.