Skip to content

Commit

Permalink
3주차 발표 자료, 퀴즈 추가 (#15)
Browse files Browse the repository at this point in the history
* docs: 스터디 진행 방식 문서 작성

* Add: 배열 비슷한 객체 발표 자료 추가

* Add: 배열/성긴 배열 발표 자료 추가

* Add: 타입 변환 발표 자료 추가

* Docs: 3주차 발표자료 하이퍼링크 추가

* Add: 3주차 퀴즈 추가

* Docs: 3주차 퀴즈 하이퍼링크 추가

* Update: toPrimitive 추상 작업 코드 변경

- 가져온 함수를 실행하도록 코드 변경
  • Loading branch information
areumsheep authored Dec 25, 2022
1 parent 7190b37 commit 24cc35c
Show file tree
Hide file tree
Showing 10 changed files with 838 additions and 0 deletions.
104 changes: 104 additions & 0 deletions week3/QUIZ.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
## 📝 3주차 퀴즈

### 빈 칸 채우기

ex) 스터디 리더는 (양아름) 입니다.

1. 배열과 비슷하지만 배열 메서드가 없는 객체를 ()라 한다.
2. ()는 나머지 연산자가 존재하지 않을 때 모든 인수를 얻는 유일한 방법이었다.
3. 배열을 생성하는 방법 중 ES6에서 추가된 방법은 (), () 이다.
4. 인덱스가 연속적이지 않은 배열을 ()라고 한다.
5. 자바스크립트 타입 변경하는 방법에는 (), () 총 2가지가 있다.
6. ECMAScript가 아닌 JavaScript 언어 내부에서 정의된 작업을 ()라고 한다. ES6에서는 재정의하여 사용할 순 있지만, 직접 실행시킬 수는 없다.

### O / X 퀴즈 (만약 X라면 이유도 작성하면 좋아요!)

ex) 스터디는 매주 목요일마다 진행됩니다.
X, 매주 금요일마다 진행됩니다.

1. V8 엔진을 사용하는 크롬을 기준으로 배열 비슷한 객체를 사용하는 것이 배열을 사용하는 것보다 좋다.
****:

2. 배열 비슷한 객체를 배열로 변경하는 방법은 Array.of()를 사용하면 된다.
****:

3. `+` 연산자는 ToPrimitive 추상 작업이 일어난다.
****:

4. ToPrimitive 추상 작업에는 파라미터의 PreferredType을 통해 3가지 선호 알고리즘이 존재한다.
****:

5. `-` 연산자는 ToPrimitive 추상 작업이 일어난다.
****:

### 코드 퀴즈

1. 배열 비슷한 객체를 간단히 코드로 구현해보세요!

```javascript
// 배열 비슷한 객체 구현해보기
const arrayLike = {};
```

2. 배열 생성하는 5가지 방법을 모두 이용해 간단히 코드로 구현해보세요!

```javascript
// 1) 배열 리터럴

// 2) 분해 연산자

// 3) Array() 생성자

// 4) Array.of()

// 5) Array.from()
// * 선택사항인 두 번째 인자를 사용한 코드를 구현해보세요!
```

3. ToPrimitive 추상 작업을 구현한 코드입니다. 주석으로 표현한 빈칸을 직접 채워보세요!
(자바스크립트의 ToPrimitive 추상 작업을 임의로 구현한 코드로, 동일하지 않습니다.)

```javascript
const toPrimitive = (input, PreferredType) => {
let hint = 'default';

if (PreferredType === 'String') {
hint = 'string';
} else if (PreferredType === 'Number') {
hint = 'number';
}

if (input[Symbol.toPrimitive]) {
const getToPrimitive = input[Symbol.toPrimitive](hint);
if (typeof getToPrimitive !== 'object') {
return getToPrimitive();
} else {
throw new TypeError('Cannot convert object to primitive value');
}
} else {
if (hint === 'default') {
// 여기에는 어떤 코드가 들어갈까요?
// 힌트: 선호 없음 알고리즘은 기본적으로 숫자를 더 선호합니다.
}
return OrdinaryToPrimitive(input, hint);
}
};

const OrdinaryToPrimitive = (input, hint) => {
let methodNames = [];
// 여기에는 어떤 코드가 들어갈까요?
// 힌트: hint의 값에 따라 실행할 메서드의 순서가 다릅니다. 이 코드를 통해 선호하는 알고리즘을 지정할 수 있습니다.

for (const methodName of methodNames) {
const method = input[methodName];
if (typeof method === 'function') {
const result = method.call(input);
if (typeof result !== 'object') {
return result;
}
}
}

throw new TypeError('Cannot convert object to primitive value');
};
```
9 changes: 9 additions & 0 deletions week3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
## 🔍 3주차 발표자료

- [배열-비슷한-객체](배열-비슷한-객체.md)
- [배열-성긴-배열](배열-성긴-배열.md)
- [타입-변환](타입-변환.md)

## 🤨 3주차 퀴즈

- [퀴즈 확인하기](QUIZ.md)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added week3/images/배열-비슷한-객체/Untitled.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added week3/images/배열-성긴-배열/Untitled.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added week3/images/타입-변환/Untitled 1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added week3/images/타입-변환/Untitled.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
104 changes: 104 additions & 0 deletions week3/배열-비슷한-객체.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# 배열 비슷한 객체

> **Create Date**: 2022/12/21
> **Update Date**: 2022/12/21
>
> [노션에서 확인하기](https://areumsheep.notion.site/331542f240fa46c1b111f2e7f8fc929c)
자바스크립트에는 배열과 비슷한 객체가 존재합니다.
영어로는 array-like object라고 합니다.

코드를 봐볼까요?

```jsx
const arrayLike = {
0: 'math',
1: 'english',
2: 'science',
length: 3,
};

console.log(arrayLike[0]); // => math
```

콘솔로 출력하는 부분을 보면 기존 배열과 비슷하게 동작하는 걸 보실 수 있습니다!
하지만 가장 큰 차이점은…!!

push, indexOf, forEach 같은 배열 메서드가 없다는 것입니다.

![자동완성에도 뜨지 않습니다.](images/배열-비슷한-객체/Untitled.png)

자동완성에도 뜨지 않습니다.

## 알아야 하는 이유는…?

> vanilla JS를 사용하다보면 array-like object를 리턴하는 DOM API가 있습니다.
> 이걸 인식하지 못한다면 배열로 해석하고 `왜 배열 메서드가 작동하지 않지?` 하며 고민에 빠질 수 있습니다.
>
> array-like object를 인식하고 처리하는 방법을 안다면 쉽게 해결할 수 있을 것입니다!!
>
> **출처**: [https://daily.dev/blog/why-do-you-need-to-know-about-array-like-objects](https://daily.dev/blog/why-do-you-need-to-know-about-array-like-objects)
## 우리 주변에 존재하는 array-like object

### arguments

```jsx
function test() {
for (const argument of arguments) {
console.log(argument);
}
}

test('a', 'b', 'c');
```

예전에는 나머지 연산자 (…) 가 존재하지 않아 **arguments**를 사용하는 것이 모든 인수를 얻는 유일한 방법이었습니다. (화살표 함수에서 arguments에 접근하면 외부 함수에서 arguments를 찾습니다.)

여기서 arguments는 array-like object입니다.
위 코드를 forEach로 사용하려면 에러가 발생합니다.

![Untitled](images/배열-비슷한-객체/Untitled%201.png)

### querySelectorAll

```jsx
const items = document.querySelectorAll('.items');
```

클래스 명이 items인 모든 element를 가져오는 코드입니다.
해당 코드의 리턴 값은 NodeList이며 NodeList는 array-like object입니다.

## array-like를 사용하는 것이 좋을까요?

```jsx
Array.prototype.forEach.call(arrayLike, (value, index) => {
console.log(`${index}: ${value}`);
});
// This logs '0: a', then '1: b', and finally '2: c'.
```

array-like object를 이렇게 이용한다면 배열 메서드를 사용할 수도 있습니다.
그럼 array-like 사용을 지향하는 것이 과연 좋을까요…?

크롬에 내장되어 있는 자바스크립트 엔진을 만든 V8의 블로그를 보면 array-like object보다 array가 더 최적화가 되어있다고 합니다.

그렇기에 배열 내장 기능을 두 번 이상 사용할 계획이라면 실제 배열로 전환하여 사용하는 것을 추천합니다.

> ⛰️ However, this is slower than calling `forEach` on a proper array, which is highly optimized in V8. If you plan on using array built-ins on this object more than once, consider turning it into an actual array beforehand:
> In general, avoid array-like objects whenever possible and use proper arrays instead.
>
> **그러나 이것은 V8에서 고도로 최적화된 배열에서 forEach로 호출하는 것보다 느립니다. 해당 객체에서 배열 내장 기능을 두 번 이상 사용할 계획이라면 사전에 실제 배열로 전환하는 것을 고려하십시오.
> 일반적으로 가능하면 항상 배열과 같은 객체를 피하고 적절한 배열을 대신 사용하십시오.**
>
> 출처: [https://v8.dev/blog/elements-kinds#prefer-arrays-over-array-like-objects](https://v8.dev/blog/elements-kinds#prefer-arrays-over-array-like-objects)
## 참고 자료

- [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)
- [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections#working_with_array-like_objects](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections#working_with_array-like_objects)
- [https://v8.dev/blog/elements-kinds#prefer-arrays-over-array-like-objects](https://v8.dev/blog/elements-kinds#prefer-arrays-over-array-like-objects)
- [https://daily.dev/blog/why-do-you-need-to-know-about-array-like-objects](https://daily.dev/blog/why-do-you-need-to-know-about-array-like-objects)
- [https://2ality.com/2013/05/quirk-array-like-objects.html](https://2ality.com/2013/05/quirk-array-like-objects.html)
- [https://www.oreilly.com/library/view/javascript-the-definitive/9781449393854/ch07s11.html](https://www.oreilly.com/library/view/javascript-the-definitive/9781449393854/ch07s11.html)
- [https://javascript.info/rest-parameters-spread](https://javascript.info/rest-parameters-spread)
134 changes: 134 additions & 0 deletions week3/배열-성긴-배열.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# 배열 / 성긴 배열

> **Create Date**: 2022/12/21
> **Update Date**: 2022/12/22
>
> [노션에서 확인하기](https://areumsheep.notion.site/5e4b76a797c6495186f38865a2aeec30)
여러분들은 배열에 대해 잘 알고 계실겁니다.
하지만 조금 더 세세하게 알아보는 계기가 되었으면 하여 준비한 자료입니다!

## 배열 생성하는 방법

배열을 만드는 방법은 여러가지입니다.

### 배열 리터럴

```jsx
const empty = [];
const misc = [1.1, true, 'a']; //타입이 다른 요소가 세 개 있고 콤마로 끝난 배열

const 성긴_배열 = [1, , 3]; // 이게 바로 성긴 배열입니다.
성긴_배열[1]; // => undefined
```

**성긴 배열**은 배열 리터럴에 콤마를 연속해서 썼는데 그 사이에 값이 없는 배열입니다.
값을 생략한 위치에 실제로 배열 요소가 존재하진 않지만 검색하면 undefined가 리턴됩니다.

### 분해 연산자

```jsx
const a = [1, 2, 3];
const b = [0, ...a, 4]; // => 0,1,2,3,4
```

분해 연산자는 배열을 얕게 복사할 때도 유용합니다.
또, 분해 연산자는 모든 이터러블 객체에서 동작하기에 이터러블인 문자열도 분해 연산자를 사용할 수 있습니다.

> 현재의 이터러블 객체는 **for/of 루프의 대상이 될 수 있는 객체**라고 생각하셔도 좋습니다!
```jsx
const digits = [...'abcdefghijklmnop'];
```

![Untitled](images/배열-성긴-배열/Untitled.png)

### Array() 생성자

```jsx
// 1) 인자 없이 호출
const a = new Array(); // []

// 2) 배열 길이를 나타내는 숫자 인자 하나로 호출
const b = new Array(10); // => [10] (X) / [ , , , , , , , , , ] (O) length - 10

// 3) 배열 요소를 두 개 이상 쓰거나, 숫자가 아닌 요소를 하나만 넘겨 호출
const c = new Array(5, 4, 3, 2, 1, 'testing'); // => [ 5, 4, 3, 2, 1, 'testing' ]
new Array('test'); // => ["test"];
```

### Array.of()

Array() 생성자를 사용하면 숫자 하나의 인자를 넘기면 그 숫자인 배열이 생성됩니다.
ES6에서는 이 문제점을 해결합니다.

```jsx
Array.of(); // => []
Array.of(10); // => [10]
```

### Array.from()

Array.from()도 ES6에서 생성된 중요한 메서드입니다.

이 메서드는 첫 번째 인자로 이터러블 객체나 배열 비슷한 객체(array-like object)를 받으며 새 배열을 만들어 반환합니다.

```jsx
const copy = Array.from(original);
```

다음과 같이 쉽게 복사할 수 있습니다.

중요한 메서드인 이유는 **array-like object를 진정한 배열로 바꾸는 방법**이기 때문입니다!!!!
웹 브라우저 메서드(DOM API)의 일부가 배열 비슷한 객체를 반환하므로 이들을 배열로 변환하면 작업이 간단해질 때가 많습니다.

또, Array.from()은 선택 사항으로 두 번째 인자를 받습니다.
두 번째 인자로 함수를 넘기면 새 배열을 생성할 때 첫 번째 인자의 배열을 이 함수에게 전달하고 반환 값을 배열에 저장합니다.

```jsx
const a = Array.from([1, 2, 3], (x) => x + x); // => [2, 4, 6]
```

동적으로 배열을 생성할 때는 `Array() - fill() - map()` / `Array.from( () => {} )` 중 후자가 더 좋습니다.

```jsx
// 1) Array + fill + map
console.log(
Array(5) // 1. [,,,,]
.fill(0) // 2. [0,0,0,0,0]
.map((item, index) => item + index + 1) // 3. [1,2,3,4,5]
);

// 2) Array.from()
console.log(Array.from([0, 0, 0, 0, 0], (item, index) => item + index + 1));
```

Array() - fill() - map()을 사용하면 Array()를 fill()하며 한 번씩 반복할 것입니다.
또, map() 까지 반복하여 돈다면 Array.from()으로 콜백함수를 도는 것보다 더 시간이 소요됩니다.

Array.from() 으로 새 배열을 생성할 때 각 요소를 함수에 전달하고 반환 값을 저장한다면 2번 반복되지 않기에 더 빠르게 결과를 가질 수 있습니다.

## 성긴 배열 (희소 배열)

위에서 잠깐 이야기했지만, 성긴 배열은 **인덱스가 연속적이지 않은 배열**입니다.

일반적으로 배열의 length는 배열의 포함된 요소의 개수입니다. 하지만 성긴 배열의 경우 length가 요소 개수보다 큽니다.

```jsx
const a = [1, , , 5];
// 요소 개수: 2
// length: 4
```

대부분의 자바스크립트 배열은 성기지 않은 배열입니다.

실제로 성긴 배열을 다뤄야 할 때가 있더라도 아마 코드에서는 그 배열을 undefined 요소가 포함된 빽빽한 배열로 취급할 것입니다.

```jsx
console.log(a[1]); // => undefined
```

## 참고 자료

- 자바스크립트 완벽가이드
- [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/fill](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/fill)
Loading

0 comments on commit 24cc35c

Please sign in to comment.