해당 포스트는 자바스크립트 완벽 가이드라는 교재로 스터디를 하면서 5장을 정리한 포스트입니다.
주관적으로 해석한 내용이 들어가 있어서 잘못된 내용이 포함될 수 있습니다.
또한 교재의 모든 내용을 정리하지 않고 주관적인 판단에 의해 필요한 내용만 작성했습니다.
📌 용어 정리
1. 표현식 ( expression )
표현식은 “평가”를 통해 값이 바뀝니다.
2. 문 ( statement )
JavaScript
의 문장이나 명령어라고 할 수 있습니다.
문은 “실행”을 통해 어떤 동작을 “수행”합니다.
부수효과(side effect
)가 있는 문은 표현식은 그 자체로 문이 될 수 있으며, “표현문”이라고 부릅니다.
( x++
, func()
(side effect
가 있는 함수라 가정 즉, 비순수함수) )
ex) 표현문, 선언문, 제어문(조건문, 반복문) 등이 존재
➰ 반복문
1. for ~ of 문
이터레이터 프로토콜을 지킨 객체에서만 동작합니다.
기본적으로 iterator protocol
을 지키는 객체는 string
, array
, Map
, Set
입니다.
array
의 경우 동적으로 순회하기 때문에 반복 중간에 배열에 변화가 생긴다면 원하는 결과와 다른 결과가 나올 가능성이 높습니다.
1
2
3
4
5
6
7
const numbers = [1,2,3];
// 반복문 시작할 때가 아닌 한번 순회할 때마다 numbers를 확인하기 때문에 `push()`로 원본을 수정한다면 무한으로 반복하게 됩니다.
for(let number of numbers) {
console.log(number);
numbers.push(10);
}
일반적인 객체는 iterator protocol
에 대한 구현이 없기 때문에 for ~ of
는 사용할 수 없습니다.
하지만 Object.entries()
, Object.keys()
, Object.value()
를 이용하면 됩니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const person = {
name: "alice",
age: 26,
gender: true,
};
// array destructuring
for (const [key, value] of Object.entries(person)) {
console.log(key, value);
}
for (const key of Object.keys(person)) {
console.log(key);
}
for (const value of Object.values(person)) {
console.log(value);
}
2. for ~ in
객체를 반복시킬 때 사용하는 문법입니다.
객체의 프로퍼티 이름 즉, key
를 기준으로 순회합니다.
단, 열거 가능(enumerable
)하지 않은 프로퍼티와 Symbol
인 프로퍼티는 제외합니다.
하지만 프로토타입 체인에서 열거 가능한 프로퍼티가 있다면 순회 대상이 됩니다.
그래서 for ~ in
보다는 for ~ of
+ Object.keys()
와 같은 조합을 선호한다고 하네요.
( 아직은 말의 의도를 정확하게 이해하지 못함 )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const person = {
name: "alice",
age: 26,
gender: true,
};
for (const key in person) {
console.log(key); // "name", "age", "gender"
}
const arr = ["a", "b", "c"];
// 아래 결과로 배열이 어떤 형태의 객체인지 조금은 유추가 가능하죠.
for (const key in arr) {
console.log(key); // "0", "1", "2"
}
3. for ~ await 문
비동기 처리를 위한 문이라는데 아직 사용해본적이 없고 이후에 설명한다고 해서 생략하겠습니다.
👍 Set과 Map
Set
과 Map
모두 각자의 메서드들을 갖고 있는데 대부분 직관적으로 기능을 알 수 있는 네이밍이고, 자주 사용하는 자료구조가 아니기 때문에 외우는 것보단 필요한 경우에 찾아서 사용하는 게 더 낫다고 생각합니다.
1. Set
Set
은 배열 내의 중복된 요소를 모두 제거하고 하나만 남겨둡니다.
1
2
3
4
5
6
7
8
9
const alpha = Set(["a", "a", "b", "b", "b", "c", "d", "d"]);
// 이터러블하기 때문에 "for ~ of"가 가능합니다.
for(const a of alpha) {
console.log(a);
}
// 배열로 되돌리기 ( 이터러블 하기 때문에 "spread operator"를 사용할 수 있습니다. )
const arr = [...alpha]
2. Map
Map
은 객체와 유사한 형태를 갖습니다.
key
가 있고 그 key
에 해당하는 value
가 있죠.
객체와의 차이점은 key
에 어떤 값이든 들어갈 수 있다는 점입니다.
객체는 key
에 string
| Symbol
만 들어갈 수 있습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const arr = [1, 2];
const map1 = new Map([
[1, "first"],
[true, "second"],
[arr, "third"],
]);
console.log(map1.get(arr)); // "third"
// 이터러블하기 때문에 "for ~ of"가 가능합니다.
for(const [key, value] of map1) {
console.log(key, value);
}
// 이터러블 하기 때문에 "spread operator"를 사용할 수 있습니다.
console.log(...map1);
점프문
1. break
문을 바로 탈출합니다.
2. continue
루프에서 사용하고 현재 실행중인 반복을 멈추고 바로 다음 반복으로 넘어갑니다.
3. return
함수를 바로 탈출합니다.
4. yield
제너레이터 함수에서 사용하며 다음 next()
가 실행되기 전까지 함수의 실행을 멈춥니다.
5. throw
예외 처리에서 사용되며 가장 가까운 catch(){}
로 이동합니다.
만약에 함수에서 실행되었다면 함수를 호출한 곳까지 가서 catch(){}
를 찾습니다.
catch(){}
가 없다면 에러로 프로그램을 종료합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const func = () => {
const x = 10;
// ... 무언가 처리
// (1) 에러 발생!
if (true) {
throw new Error("내가 만든 에러");
// (2) 하지만 "func()"내부에는 catch(){}가 없음
}
};
// (3) "func()""를 호출한 곳으로 와서 catch(){}를 찾음
try {
func();
} catch (error) {
// (4) 실행
console.error(error);
}
6. try ~ catch ~ finally
예외가 발생할 수 있는 곳에 사용하는 구문입니다.
“코드를 애초에 예외 없이 작성하면 되는거 아닌가?”라고 생각할 수 있겠지만 네트워크 요청 같은 경우에는 항상 성공한다는 보장이 없기 때문에 try ~ catch
를 써주는 것이 좋습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(async () => {
try {
// 아래와 같이 실행하면 문제 없이 "try{}"문 동작 후에 "finally{}"문 동작하고 종료됨
// const data = await (await fetch("https://api.github.com/users/1-blue")).json();
// 아래는 비정상적인 요청이기 때문에 예외가 발생해서 "catch(){}"로 들어가게 됩니다.
const data = await (await fetch("없는 URL")).json();
console.log(data);
} catch (error) {
console.error("아무튼 에러 >> ", error);
} finally {
console.log("반드시 실행");
}
})();
기타 문
1. debugger
런타임 즉, 실행하는 경우 debugger
를 만나면 이후 코드를 중단하고 디버거가 실행되어 현재 call stack
과 같은 정보를 얻을 수 있습니다.
2. use strict
코드의 최상단에 "use strict"
를 사용하면 됩니다.
엄격 모드가 켜져서 표준에 어긋나지만 JavaScript
의 관대함으로 포용해주던 문법들을 사용하면 사전에 에러를 표시해줍니다.
😶 마무리
이번 챕터는 문에 대해 상세하게 설명한 챕터였습니다.
근데 문에 대해서 상세하게 정리할만한 내용이 없다고 생각해서 작성한 내용이 거의 없습니다.
if
, for
, while
, switch ~ case
같은 경우에는 기본적으로 알고 있을 것이고, 그 외의 특수한 문들 with
같은 경우는 저자도 사용하지 않는게 좋다라고 설명하기 때문에 굳이 정리할 필요가 있나 생각해서 제외했습니다.
do ~ while
, label
, continue
같은 경우는 보통 코드를 읽는 흐름(위 -> 아래, 좌 -> 우)을 바꿔버리는 좋지 않은 문들이라고 알고 있어서 정리하지 않았습니다.
그리고 class
, for await
, yield
, export
, import
같은 경우는 뒤에서 더 자세하게 설명한다고 설명을 대부분 생략했기 때문에 제외했습니다.
📮 레퍼런스
- « 자바스크립트 완벽 가이드 » ( 데이비드 플래너건 지음, 한성용 옮김, 인사이트, 2022 )
- javascript info - Set과 Map