Skip to content

Commit

Permalink
자나깨나 감기조심...
Browse files Browse the repository at this point in the history
  • Loading branch information
BEMELON authored Feb 21, 2024
1 parent b9a4899 commit 87080ac
Showing 1 changed file with 368 additions and 0 deletions.
368 changes: 368 additions & 0 deletions 09회차(34장~37장)/황규도.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,368 @@

# 34장: 이터러블
## 34.1 이터레이션 프로토콜
> ES6에서 도입된 프로토콜로, 순회 가능한 데이터 컬랙션을 만들기 위해 정의된 규칙이다.
- ES6 이전에는 데이터 컬랙션마다 서로 다른 순회 방법을 제공했다.
- ES6 이후, 이터레이션 프로토콜을 통하여 **순회 방법을 일원화**하였다.
- [[33. 7번째 데이터 타입 Symbol|Symbol]] 을 이용하여 메소드를 직접 구현하거나, 프로토타입 체인을 통해 `Symbol.iterator`에 접근시 **이터레이터**를 반환
- **이터레이터** : `next` 메소드를 가지며, 메소드 호출시 `value`와 `done` 프로터피를 갖는 **Result 객체**
### 34.1.1 이터러블
> 이터러블(Iterable) 프로토콜을 준수한 객체
- 이터러블 객체는 `for ... or` 문으로 순회할 수 있으며, [[35. 스프레드 문법|스프레드 문법]][[36. 디스트럭처링 할당|디스트럭처링 할당]]의 대상으로 사용될 수 있다.
``` javascript
const [a, ...rest] = array;
console.log(a, rest); // 1, [2, 3]
```

### 34.1.2 이터레이터
> `Symbol.iterator` 메소드 호출시, 이터레이터 프로토콜을 준수한 **이터레이터를 반환**한다.
- 이터레이터는 `next` 메소드를 갖는다.
- `next` 메소드는, 각 요소를 순회하기 위한 포인터의 역할을 한다.
- `next` 메소드 호출시, `value` 와 `done` 의 프로퍼티를 갖는 객체를 반환한다.
- `value` : 실제 값
- `done` : 완료 여부
## 34.2 빌트인 이터러블

## 34.3 for...of 문
> 이터러블 객체는 `for...or` 문으로 순회할 수 있다.
- `for...in` 문은 모든 프로토타입의 프로퍼티 중, `[[Enumerable]]``true`인 프로퍼티를 순회한다.
- `for...of`문은 `next` 메소드를 호출하여 반환된 **Result 객체**`value` 프로퍼티를 변수에 할당한다.
- `Done` 이 `true` 이면 이터러블의 순회를 중단한다.
## 34.4 이터러블과 유사 배열 객체
- **유사 배열 객체** : 인덱스로 프로퍼티 값에 접근할 수 있고 `length` 프로퍼티를 갖는 객체
``` javascirpt
const arrayLike = {
0: 1,
1: 2,
2: 3,
length: 3
}
console.log(arrayLike[2]); // 3
```
- 유사 배열 객체는 이터러블일 수도 있다.
## 34.5 이터레이션 프로토콜의 필요성
## 34.6 사용자 정의 이터러블
- **사용자 정의 이터러블**: 이터러블을 준수하지 않은 일반 객체가 이터레이션 프로토콜을 구현한 경우

### 34.6.1 사용자 정의 이터러블 구현
- 이렇게 직접 구현하고 사용할 수 있다.
``` javascript
const fibonacci = {
[Symbol.iterator]() {
let [pre, cur] = [0, 1]
const max = 10
return {
next() {
[pre, cur] = [cur, pre + cur]
return { value : cur, done: cur >= max };
}
}
}
}

for (const num of fibonacci) {
console.log(num); // 1 2 3 5 8
}
```
### 34.6.2 이터러블을 생성하는 함수
- 외부에서 값을 받아, 이터러블을 반환하는 함수를 만들면 더욱 깔끔하다.
``` javascript
const fibonacciFunc = function (max) {
let [pre, cur] = [0, 1];

return {
[Symbol.iterator]() {
let [pre, cur] = [0, 1]
const max = 10
return {
next() {
[pre, cur] = [cur, pre + cur]
return { value : cur, done: cur >= max };
}
}
}
}
}

for (const num of fibonacci) {
console.log(num); // 1 2 3 5 8
}
```

### 34.6.3 이터러블이면서 이터레이터인 객체를 생성하는 함수
### 34.6.4 무한 이터러블과 지연 평가
- 이터러블은 **지연 평가**(`Lazy evaluation`) 을 통해 데이터를 생성한다.
- **지연 평가** : 데이터가 필요한 시점에서야 데이터를 생성하는 기법


# 35장: 스프레드 문법
> `...`을 통하여 하나로 뭉쳐있는 여러 값들의 집합을 펼쳐, 개별적인 값들의 목록으로 만드는 문법
``` javascript

console.log(...[1, 2, 3]); // 1, 2, 3
console.log(...'Hello') // H e l l o

// 이터러블이 아닌 일반 객체는 스프레드 문법의 대상이 아니다
console.log(... {a : 1, b: 2 })
```

- 스프레드 문법의 결과는 **값이 아니기 때문에 변수에 할당할 수 없다.**
## 35.1 함수 호출문의 인수 목록에서 사용하는 경우
- 목록으로 펼쳐서 인수 목록으로 전달할 때 유용하다.
``` javascript
consoe.log(Math.max(...[1, 2, 3]));
```

## 35.2 배열 리터럴 내부에서 사용하는 경우

### 35.2.1 concat
- ES5에서 사용하던 `concat` 메소드를 더욱 효과적으로 사용할 수 있다.
``` javascript
// ES5
var arr = [1, 2].concat([3, 4])
console.log(arr)

// ES6
const arr = [...[1, 2], ...[3, 4]];
console.log(arr)
```
### 35.2.2 splice
- ES5에서 사용하던 `splice` 메소드를 더욱 효과적으로 사용할 수 있다.
``` javascript
// ES6
var arr1 = [1, 4]
var arr2 = [2, 3]

arr1.splice(1, 0, ...arr2)
console.log(arr1); // [1, 2, 3, 4]
```
### 35.2.3 배열 복사
``` javascript
const origin = [1, 2];

// 얕은 복사
const copy = [...origin]

console.log(copy); // [1, 2]
```
### 35.2.4 이터러블을 배열로 변환

## 35.3 객체 리터럴 내부에서 사용하는 경우
- 곧 표준 사양으로 올라올 **스프레드 프로퍼티**를 이용하면 객체 리터럴에서도 스프레드 문법을 사용할 수 있다.
- 스프레드는 이터러블이어야 하지만, **스프레드 프로퍼티는 일반 객체를 대상으로 스프레드 문법을 허용**
``` javascript
const merged = { x : 1, y : 2, ...{ a: 3, b : 4} }
console.log(merged)
```


# 36장: 디스트럭처링 할당
> [[34. 이터러블|이터러블]] 또는 객체를 디스트럭처링(Destructuring)하여 1개 이상의 **변수에 개별적으로 할당**하는 것.
## 36.1 배열 디스트럭처링 할당
``` javascript
const arr = [1, 2, 3]

const [one, two, three] = arr;

// 1. 기본값을 할당할 수 있다
const [a, b, c = 3] = [1, 2]

// 1.1 당연히, 할당값이 우선이다
const [a, b, c = 3] = [1, 2, 4]
console.log(c) // 4

// 2. rest 파라미터를 사용할 수 있다.
const [x, ...y] = [1, 2, 3];
console.log(x, y); // 1, [2, 3]
```

## 36.2 객체 디스트럭처링 할당
- 객체의 프로퍼티 키를 기준으로 할당할 수 있다.
``` javascript
const obj = {
a : 1,
b : 2,
}

const { a , b } = obj;

console.log(a, b) // 1, 2
```

- 객체를 인수로 전달받는 매개변수에서도 적용이 가능하다.
``` javascript
function printTodo({ content, completed }) {
console.log(content, completed)
}

printTodo({ id : 1, content: 'content', completed: true })
```

- 배열과 객체 디스트럭처링을 섞어서 사용할 수 있다.
``` javascript
const user = {
name: 'Lee',
address: {
zipCode: '03068',
city : 'Seoul'
}
};

const { address: { city } } = user;
console.log(city);
```


# 37장: Set과 Map
## 37.1 Set
> 중복되지 않은 유일한 값들의 집합
### 37.1.1 Set 객체의 생성
- `Set` 생성자 함수는 [[34. 이터러블|이터러블]] 을 인수로 전달받아 `Set` 객체를 생성
``` javascript
new Set([1, 2, 3, 4, 5])
new Set('hello')

new Set([1, 2, 3, 3, 5]) // {1, 2, 3, 5}
```
### 37.1.2 요소 개수 확인
> `Set.prototype.size`를 통해 요소의 개수를 확인할 수 있다.
- 접근자 프로퍼티이기 때문에, 숫자를 변경할 수 없다.
``` javascript
const set = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
console.log(set.size); // 10

set.size = 5
console.log(set.size); // 10
```
### 37.1.3 요소 추가
> `Set.prototype.add` 메소드를 통해 요소를 추가한다.
``` javascript
const set = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
console.log(set.size); // 10

set.add(11);
console.log(set) // Set { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }
```
### 37.1.4 요소 존재 여부 확인
> `Set.prototype.has` 메소드를 통해 특정 요소가 존재하는 지 확인한다
``` javascript
const set = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

console.log(set.has(5)); // true
```
### 37.1.5 요소 삭제
> `Set.prototype.delete` 메소드를 통해 특정 요소를 삭제한다.
``` javascript
const set = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

set.delete(5);
console.log(set); // Set { 1, 2, 3, 4, 6, 7, 8, 9, 10 }
```
### 37.1.6 요소 일괄 삭제
> `Set.prototype.clear` 메소드를 통해 일괄 삭제한다.
``` javascript
const set = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

set.clear();
console.log(set); // Set {}
```
### 37.1.7 요소 순회
> `Set.prototype.forEach` 메소드를 통해 순회할 수 있다.
- 이 때, 3개의 인자를 받게 된다.
- `v` : 현재 순회 중인 요소 값
- `v2` : 현재 순회 중인 요소 값
- `set` : 순회중인 set 객체
`forEach` 호환성을 준수하기 위하 다음과 같이 설계하였다.
``` javascript
const set = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

set.forEach((v, v2, set) => console.log(v, v2, set))
```

- `Set` 객체는 [[34. 이터러블|이터러블]] 이기 때문에 스프레드 문법과 배열 디스트럭처링의 대상이 될 수 있다.
### 37.1.8 집합 연산
> 구현되어 있는 건 없지만, 함수형 언어 잘 써서 구현할 수 있다.
## 37.2 Map
### 37.2.1 Map 객체의 생성
> `Map` 생성자 함수로 생성할 수 있다
``` javascript
const map = new Map()
console.log(map) // Map {}

// 중복된 값이 있다면 덮어써진다.
const map2 = new Map([['name', 'John'], ['age', 30]])
console.log(map2) // Map { 'name' => 'John', 'age' => 30 }
```
### 37.2.2 요소 개수 확인
``` javascript
const map = new Map([['name', 'John'], ['age', 30]])
console.log(map.size)
```
### 37.2.3 요소 추가
> `Map.prototype.set` 메소드를 사용해서 추가할 수 있다.
``` javascript
const map = new Map([['name', 'John'], ['age', 30]])
map.set('job', 'developer')
console.log(map) // Map { 'name' => 'John', 'age' => 30, 'job' => 'developer' }
```
### 37.2.4 요소 취득
> `Map.prototype.get` 메소드를 통해서 획득할 수 있다.
``` javascript
const map = new Map([['name', 'John'], ['age', 30]])
console.log(map.get('name')) // John
```

### 37.2.5 요소 존재 여부 확인
> `Map.prototype.has` 메소드를 통해서 존재 여부를 확인할 수 있다.
``` javascript
const map = new Map([['name', 'John'], ['age', 30]])
console.log(map.has('name')) // true
```

### 37.2.6 요소 삭제
> `Map.prototype.delete` 메소드를 통해 삭제할 수 있다.
``` javascript
const map = new Map(['key', 'value'])
map.delete('key')
console.log(map.has('key')) // false
```
### 37.2.7 요소 일괄 삭제
> `Map.prototype.clear` 메소드를 통해 일괄로 날릴 수 있다.
``` javascript
const map = new Map(['key', 'value'])
map.clear()
console.log(map.size) // 0
```

### 37.2.8 요소 순회
> `Map.prototype.forEach` 메소드를 통해 순회할 수 있다.
- 이 때, 3개의 인자를 받게 된다.
- `v` : 현재 순회 중인 요소 값
- `k` : 현재 순회 중인 요소 키
- `map` : 순회중인 map 객체
`forEach` 호환성을 준수하기 위하 다음과 같이 설계하였다.
``` javascript
const map = new Map([['key', 'value'], ['key2', 'value2']]);

map.forEach((v, k, map) => console.log(v, k, map));
```

0 comments on commit 87080ac

Please sign in to comment.