1. 문(statement)이란?
2. 조건문 - if/else, switch
3. 반복문 - for
4. for/of
5. for/in
6. 점프 - break, continue, 라벨
- 문장이나 명령어라고 할 수 있다.
- 문(statement)는 세미콜론으로 끝난다(구분한다).
;
세미콜론 하나만 있으면 빈 문(statement)이다.
- 표현식은 '평가'를 통해 값으로 바뀌지만, 문은 '실행'을 통해 어떤 동작을 수행한다.
- 할당이나 함수 호출처럼 사이드 이펙트가 있는 표현식은 그 자체로 문이 될 수 있다.
- 자바스크립트 인터프리터는 문들을 작성된 순서대로 실행한다.
- 표현문, 선언문, 제어문 등이 있다.
if
,else
키워드 뒤에는 문 하나만 올 수 있다.else if
라는 건 없다. else 뒤에 하나의 문이 올 수 있는데 그 하나의 문이 if문인 것이다.
- 뒤에 오는 문을
{}
로 감싸는 경우가 많다.- 중괄호를 쓰는 것이 훨씬 가독성이 뛰어난 것 같다.
// if
if (expression) statement;
// if else
if (expression) statement1;
else statement2;
switch(expression)
의expression
과 case 표현식을===
로 비교해서 일치하면 해당 case의 코드 문을 실행한다.- 일치하는
case
를 찾으면 그 시점부터 하단의 내용이 전부 출력된다. default
로 일치하는case
가 없을 경우를 분기시킨다. eslint에서는 default를 꼭 사용하도록 강제한다.- 오류를 줄이기 위해 case 문을 블록으로 감싸는 것도 때때로 필요하다.
const browser = 'Whale';
switch (browser) {
// case 문을 {}로 감싸기
case 'IE': {
console.log('go away!');
break; // 종료, break가 case일치 시점부터 하단의 내용이 전부 출력
}
case 'Chrome': // or 의 경우 붙여 씀
case 'Whale':
console.log('come here!');
break;
default:
//일치하는 case가 없는 경우
console.log('what!?');
}
// print: come here!
- 코드양은 비슷하다. 어떻게 분리하는지가 중요하다.
- 맵핑을 사용하면 내부 로직을 숨기고 전체 로직만 가독성있게 확인할 수 있다.
const moveUp = () => console.log('위로 이동');
const moveDown = () => console.log('아래로 이동');
const moveLeft = () => console.log('왼쪽으로 이동');
const moveRight = () => console.log('오른쪽으로 이동');
const saveLog = moveType => console.log('SaveLog: ' + moveType);
function move(moveType) {
if (moveType === 'up') {
moveUp();
saveLog('위');
} else if (moveType === 'down') {
moveDown();
saveLog('아래');
} else if (moveType === 'left') {
moveLeft();
saveLog('왼쪽');
} else if (moveType === 'right') {
moveRight();
saveLog('오른쪽');
}
}
const moveUp = () => console.log('위로 이동');
const moveDown = () => console.log('아래로 이동');
const moveLeft = () => console.log('왼쪽으로 이동');
const moveRight = () => console.log('오른쪽으로 이동');
const saveLog = moveType => console.log('SaveLog: ' + moveType);
const moveMap = {
up() {
moveUp();
saveLog('위');
},
down() {
moveDown();
saveLog('아래');
},
left() {
moveLeft();
saveLog('왼쪽');
},
right() {
moveRight();
saveLog('오른쪽');
},
};
function move(moveType) {
moveMap[moveType]();
}
for (initialize; test; increment) {
statement;
}
initiallize
: 변수 선언문 또는 할당문. 루프를 시작하기 전 한 번 평가test
: 조건식. 이 조건을 평가해 참인 경우 statement를 실행statement
: 조건식이 참인 경우 반복 실행될 문increment
: statement의 끝에서 변수를 다시 테스트하기 직전에 업데이트initialize
,test
,increment
세 가지 전부 생략가능하다. 단 세미콜론은 필수- 세 가지 전부 생략한 경우 =>
for (;;)
- 세 가지 전부 생략한 경우 =>
ES6
에서 추가.- 이터러블 객체에서만 동작한다.
- 이터러블은
Symbol.iterator
메서드를 갖고 있다. 이 메서드가 있어야for/of
를 사용할 수 있다. ES6
에서 유사 배열 객체인arguments
,NodeList
,HTMLCollection
객체에Symbol.iterator
메서드를 구현하여 이터러블이 되었다.
- 이터러블은
- 일반 객체를 순회하고자 할 땐
Object.entries
,Object.values
,Object.keys
를 사용한다.
for (variable declaration of iterable) {
statement
}
iterable
을 순회하면서iterable
요소를 변수에 할당한다.- 내부적으로는 이터레이터의
next
메서드를 호출하여next
메서드가 반환한result
객체의value 프로터피 값
을 변수에 할당한다. result
객체의done 프로퍼티 값
이true
면 순회를 중단한다.
const iterable = [1, 2, 3];
for (const item of iterable) console.log(item);
// 1
// 2
// 3
const iterable = [1, 2, 3]; // 배열은 이터러블이다.
const iterator = iterable[Symbol.iterator](); // 이터레이터 생성
for (;;) {
const result = iterator.next(); // next 메서드를 호출해 이터러블을 순회
console.log(result); // next 메서드가 반환한 result 객체
if (result.done) break; // done 프로퍼티 값이 true면 순회 중단
const item = result.value; // value 프로퍼티 값이 item 변수에 할당
console.log(item);
}
// { value: 1, done: false }
// 1
// { value: 2, done: false }
// 2
// { value: 3, done: false }
// 3
// { value: undefined, done: true }
// 위의 코드와 똑같은 코드
- 자바스크립트 초창기부터 존재했다.
- 객체의 프로퍼티를 순회하며 열거한다.
- 순회하는 객체의 프로퍼티뿐만 아니라 상속받은 프로토타입의 프로퍼티까지 열거한다.
- 단, 프로퍼티의 속성
[[Enumerable]]
의 값이 true인 것만 열거할 수 있다.[[Enumerable]]
은 프로퍼티의 열거 가능 여부를 나타내며 불리언 값이다.
- 프로퍼티의 키가
Symbol
인 프로퍼티는 열거하지 않는다. - 열거할 때 순서를 보장하지 않는다.
for (variable declaration of object) {
statement
}
- 변수에 object 객체의 프로퍼티 키가 할당된다.
const dog = {
name: 'Enum',
age: '5',
__proto__: { gender: 'male' },
walwal: function () {
console.log('왈왈');
},
[Symbol()]: 10, // 키가 심볼인 프로퍼티는 열거 x
};
for (const key in dog) {
console.log(`${key}: ${dog[key]}`);
}
// name: Enum
// age: 5
// walwal: () => console.log('왈왈') // 열거 순서를 보장하지 않는다.
// gender: male // 상속된 프로퍼티도 열거한다.
- 성능이 낮다.
- 객체 자신의 고유 프로퍼티만 열거하려면 =>
Object.entries
,Object.values
,Object.keys
- 배열은
forEach
- 자바스크립트 인터프리터가 소스 코드의 다른 위치로 이동하게 한다.
break
: 루프를 비롯한 다른 문의 끝으로 이동continue
: 루프 바디의 나머지를 생략하고 루프 맨 위로 돌아가 새 반복을 시작
// 예시
function solution(s) {
let count = 0;
for (let x = 0; x < s.length; x++) {
let state = true;
const stack = [];
const replaced = [...s.substring(x), ...s.substring(0, x)];
for (const bracket of replaced) {
if (isOpen(bracket)) {
stack.push(bracket);
continue; // 아래 생략하고 다시 맨 위로 돌아감
}
if (isMatched(stack[stack.length - 1], bracket)) {
stack.pop();
continue; // 아래 생략하고 다시 맨 위로 돌아감
}
state = false;
break; // 루프 문의 끝으로 이동, 밑에 if문으로 이동함
}
if (state === true && stack.length === 0) count++;
}
return count;
}
- 문 앞에 라벨을 붙여
break
,continue
를 사용할 때 문을 특정할 수 있다. identifier: statement
// 예시 1
loop1: for (let i = 1; i <= 3; i++) {
loop2: for (let j = 10; j <= 13; j++) {
if (j === 12) break loop2; // loop2를 탈출하지만 loop1은 계속 진행
console.log(i, j);
}
}
// 1 10
// 1 11
// 2 10
// 2 11
// 3 10
// 3 11
// 예시 2
loop1: for (let i = 1; i <= 3; i++) {
loop2: for (let j = 10; j <= 13; j++) {
if (j === 12) break loop1; // loop1을 즉시 탈출
console.log(i, j);
}
}
// 1 10
// 1 11