---
# System prepended metadata

title: javascript-postbox

---

# javascript-postbox

<table>
  <tr>
    <td align="center">
      <a href="https://github.com/mansaout">
        <img src="https://avatars.githubusercontent.com/u/41741221?v=4" width="100px;" alt="Yellow"/><br />
        <sub><b>Yellow</b><br></sub>
      </a>
    </td>
    <td align="center">
      <a href="https://github.com/healtheloper">
        <img src="https://avatars.githubusercontent.com/u/58503584?v=4" width="100px;" alt="Park"/><br />
        <sub><b>Park</b><br></sub>
      </a>
    </td>
  </tr>
</table>

<br>

## 🧐 어떤 생각으로 미션시작?

- 한글코딩 
    - `왜?` : 드라이버가 코드를 설명할 때 한글로 스켈레톤 코드를 작성하면서 보여주다가 오히려 한글 코드가 더 이해가 잘되는 느낌을 받아서 실제로 <a href="https://youtu.be/edWbHp_k_9Y?t=865">한글로 코딩을 하는 사례</a> 도 있다고 들어서 한번 해보면 재밌겠다라는 생각으로 한글코딩을 시작 했습니다.

- 중간에 네비게이터의 로직이 이해가 안된다면 멈추고 생각하기
    - 두 사람이 완벽히 코드에 대해서 이해를 해야 피드백이 원활히 이루어질 수 있다는 생각으로 진행했습니다.


<br>

## 📕 미션 별 초기 설계
### 미션 1

- html 뼈대 먼저 만들기
  - 마을지도, 버튼, 마을 정보(총 ~개의 마을입니다)
- 마을 class 만들기

  - 속성: Width, Height, Positions, box:object
  - 메서드: 포함되는 마을 만들기

- 랜덤한 범위 지정해주는 함수 만들기
- validation 함수(다른 마을과 겹치지 않는지) 만들기

### 구현하면서 바뀐점

- 마을 class 속성
    - 가로길이, 세로길이, 좌표(->상대좌표), 우체통:object(`new 우체통`)
    - ﹢우체통크기, 마을이름, 자식마을
        - 우체통크기 또한 랜덤으로 만들어 져야 해서 서버에서 데이터를 받는 구조를 생각했을 때 우체통 크기 또한 포함되어야 한다고 생각이 듦
        - 마을이름이 포함되어야 한다는 것을 늦게 확인함...
        - 마을이 자식마을의 정보를 갖는다고 할 때, 배열 형태로 갖고 마을과 동일한 속성을 갖게 될 것이라고 생각해서 서버에서 재귀적으로 생성해 데이터를 넣어 줄 수 있도록 하였음
        - 재귀적으로 생성할 때 무한히 만들어 질 수 없도록 마을의 최소 길이를 설정해서 해당 범위를 벗어나면 재귀함수를 `return` 하도록 했습니다.
        <br>
        ```javascript
        const 마을최소길이 = 100;

        const 마을생성 = ({ 기준가로길이, 기준세로길이, 기준사분면 }) => {
          if (기준가로길이 < 마을최소길이 || 기준세로길이 < 마을최소길이) return;
            
          return Array(마을개수랜덤생성())
                    .fill(0)
                    .map((_, i) => {
                      ...
                      const 자식마을 = 마을생성({
                        기준가로길이: 가로길이,
                        기준세로길이: 세로길이,
                        기준사분면: 자식사분면,
                      });
                      ...
                    })
        };
        ```
    - 메서드: 포함되는 마을 만들기
        - 메서드 대신 서버에서 재귀적으로 생성하여 넘겨주는 방식으로 변경

- validation 함수
    - 처음엔 임의로 랜덤한 좌표를 지정하고, 좌표를 기준을 했을 때 가로+세로길이를 더해서 해당 영역에 사각형이 있는지를 판단하는 알고리즘을 만들어 `validation` 을 해야할 것이라고 생각 했습니다
    - 위 알고리즘이 매우 복잡할 것이라고 생각이 들었고, 마을 안에 포함되는 자식마을의 형태로 구현을 하고, 그 마을의 영역을 4등분 해서 사용하자고 제약을 걸면 크게 겹칠일도 없을 것이라고 생각하여 따로 만들지 않았습니다

<br>

### 미션 2

- 빨간 우체통이 있는 마을 출력, 우체통 크기 순 출력, 2초 뒤 마을 색상 변경

    1. 우체통이 있는 마을을 돔 탐색해 새로운 배열(`우체통마을들`)로 모으기
        - `우체통마을들` 이라는 배열에 해당 마을들을 추가

    2. 우체통이 있는 마을 이름 출력
        - `우체통마을들` 배열을 순회하면서 에서 각 마을의 이름과, 총 마을 개수를 가져와 출력

    3. 우체통마을을 우체통크기 순으로 버블정렬 후 크기순 이름 출력
        - `우체통마을들` 배열을 우체통 크기 순으로 버블 정렬
        - 순회하면서 마을 이름 출력


    7. 2초 딜레이 후 우체통마을의 색상 변경
        - 2초 딜레이
        - `우체통마을들` 배열 순회하면서 각 마을의 `style.border`을 인라인 변경

```javascript=
  버튼.addEventListener("click", async () => {
    우체통마을찾기(클래스로요소찾기("townMap"));
    마을정보출력();
    await 딜레이(2000);
    우체통마을들.forEach((마을) => {
      우체통마을색상변경(마을);
    });
  });

const 마을정보출력 = () => {
  const 우체통마을이름들 = 우체통마을이름들확인(우체통마을들);
  클래스로요소찾기("townCount").innerHTML = `${우체통마을이름들.join(", ")} 총 ${우체통마을이름들.length}개의 마을입니다.`;
  우체통마을들.파크옐로우정렬((a, b) => 우체통크기확인(b) - 우체통크기확인(a));
  클래스로요소찾기("boxSize").innerHTML = `우체통은 크기는 ${우체통마을이름들확인(우체통마을들)} 순입니다.`;
};
```

<br>

### 미션 3

- `Express` 에서 랜덤한 로직으로 마을 데이터 생성해서 전달
    - 미션 1과 동시에 진행하면서, 마을 데이터의 구조를 짜보고 시작을 했습니다.
    - 마을 데이터 구조를 먼저 짜니 `Client` 에서 해당 데이터 구조를 바탕으로 `Class` 구조를 구상하기가 수월했습니다.

- `fetch` 요청을 보내면 서버에서 마을데이터르르 생성해 json으로 전달

```javascript

// 서버
app.get("/town", (req, res) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.json(데이터얻기());
});


// 클라이언트
const 마을정보가져오기 = async () => {
  const res = await fetch("http://127.0.0.1:3000/town");
  return res.json();
};
```

### 미션 섹션 외 구현

- `querySelector` -> `클래스로요소찾기`
    - `querySelector` 라는 `DOM API` 가 `Document` 라는 `DOM Tree` 를 순회하며 `요소`를 찾는 것 이라고 생각해서, `Tree` 를 탐색하기 위한 `DFS 알고리즘` 을 사용하면 되지 않을까? 라는 생각으로 시작했습니다.
    - `DFS` 가 콜스택에 계속 쌓여서 `Return` 받는 값을 상상하기가 조금 어려웠는데, 디버깅툴로 확인을 해도 이해를 하기 쉽지 않은 부분이 있어서 `DFS 알고리즘` 을 좀 더 공부해보려고 합니다.
    - `DFS` 로직 안에서 두 번째 인자로 받는 `클래스` 를 `셀렉터` 같은 이름으로 바꾸어서 내부 로직은 `셀렉터`에 따라 `찾은노드` 를 찾는 함수를 별도로 만든다면 다양한 `셀렉터`로 `요소`를 찾을 수 있지 않을까란 생각을 했고 이 부분은 천천히 확장해보려고 합니다.
    
```javascript
const dfs = (시작점, 클래스) => {
  const 자식노드들 = [...시작점.children];
  const 찾은노드 = 자식노드들.find((자식노드) =>
    자식노드.classList.contains(클래스)
  );
  if (찾은노드) {
    return 찾은노드;
  } else {
    return 자식노드들.map((자식노드) => dfs(자식노드, 클래스)).find((v) => v);
  }
};

const 클래스로요소찾기 = (클래스) => {
  return dfs(document.body, 클래스);
};
```

- `Array.prototype.sort` -> `Array.prototype.파크옐로우정렬`

    - `배열` 을 인자로 받아서 `배열` 을 `Return` 하는 함수 형태로 정렬을 만들어 보려다가, 기존에 `sort` 처럼 똑같이 동작을 할 수 있도록 만들어 보고 싶다는 생각이 들어서 `Array.prototype` 의 메소드로 추가하는 방식을 해보면 어떨까? 라는 의견으로 만들어 보게 되었습니다.
    - `callback` 을 인자로 받기 때문에 `callback` 을 실제로 어떻게 사용해야 하는지에 대해 생각하는게 조금 어려웠는데, 재밌는 경험이었습니다.
    - `정렬` 과 관련해서 다양한 알고리즘이 존재하지만, 페어프로그래밍 특성상 복잡한 알고리즘을 따라치기보다는 실제로 정렬을 어떻게 해야할지 생각을 직접 구현해보는 식으로 정렬을 구현해서 `버블정렬` 처럼 만들게 되었습니다. `버블정렬` 말고도 다양한 알고리즘을 공부해보려 합니다.

```javascript
Array.prototype.파크옐로우정렬 = function (callback) {
  const arr = this;
  for (let i = 0; i < arr.length - 1; i++) {
    for (let k = 0; k < arr.length - i - 1; k++) {
      const a = arr[k];
      const b = arr[k + 1];
      const diff = callback(a, b);
      if (diff > 0) {
        arr[k] = b;
        arr[k + 1] = a;
      }
    }
  }
  return arr;
};
```

- `setTimeout` -> `딜레이`

    - `밀리초`를 인자로 받아 해당 시간만큼 setTimeout를 실행하고 프로미스를 반환하는 딜레이 함수 구현했습니다.
    - 오직 지연을 시키는 역할만 하기 때문에 인자로 `밀리초`만 받고, 해당시간이 지난 후 resolve() 해줬습니다.

```javascript
const 딜레이 = (밀리초) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve();
    }, 밀리초);
  });
};

async () => {
  await 딜레이(2000);
  //2초뒤에 실행
}()
```

## ☺️ 느낀점

`Park` : `한글코딩` 으로 처음 코딩을 해보았는데, 생각보다 가독성이 훨씬 좋아졌다는 생각도 들었고, 변수, 함수명을 `한글->영어` 로 번역하는 단계를 1 단계 줄여서 코딩을 하는 시간도 물리적으로 줄었다고 느꼈습니다. 페어프로그래밍을 하면서 가장 신의 한수가 아니었나 라는 생각이 들었고 재밌는 경험이었습니다. 코딩 중간중간에 `나의 로직을 이해했는지 확인하고 설명하는 과정`을 중간중간에 갖게되니 나의 로직에 대해서 더 생각하게 되고 피드백도 받을 수 있어서 좋았습니다. 

 
`Yellow` :
`한글코딩`이 굉장히 재밌는 경험이었습니다. 기존에 많은 고민이 필요했던 변수, 함수명 이름 짓는 과정을 줄일 수 있어서 좋았고, 또한 가독성이 높아져 프로그래밍하는데 (특히 페어프로그래밍) 큰 도움을 받은 것 같습니다. if, const, let 같은 기존 자바스크립트 문법은 영어로, 저희가 새롭게 만든 변수명, 함수명은 한글로 작성한 것이 로직과 저희가 만든 것을 더 잘 분리해 볼 수 있어서 가독성이 올라간 것 같습니다.
특정 기능을 구현하기전에 서로 본인이 가진 생각을 같이 공유하고 의견을 나누는 과정이, 혼자 고민하고 학습하는 것보다 저에게 더 효과적이었습니다.