자바스크립트 완벽 가이드 5장 정리
포스트
취소

자바스크립트 완벽 가이드 5장 정리

해당 포스트는 자바스크립트 완벽 가이드라는 교재로 스터디를 하면서 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

SetMap 모두 각자의 메서드들을 갖고 있는데 대부분 직관적으로 기능을 알 수 있는 네이밍이고, 자주 사용하는 자료구조가 아니기 때문에 외우는 것보단 필요한 경우에 찾아서 사용하는 게 더 낫다고 생각합니다.

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에 어떤 값이든 들어갈 수 있다는 점입니다.
객체는 keystring | 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같은 경우는 뒤에서 더 자세하게 설명한다고 설명을 대부분 생략했기 때문에 제외했습니다.

📮 레퍼런스

  1. « 자바스크립트 완벽 가이드 » ( 데이비드 플래너건 지음, 한성용 옮김, 인사이트, 2022 )
  2. javascript info - Set과 Map
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

이펙티브 타입스크립트 2장 ( 6 ~ 18 )

코어 자바스크립트 3장 ( this )