<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>j_jhwww.log</title>
        <link>https://velog.io/</link>
        <description>이것저것 생각나는 대로.</description>
        <lastBuildDate>Sat, 22 Jan 2022 04:59:17 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>j_jhwww.log</title>
            <url>https://images.velog.io/images/j_jhwww/profile/db697a43-dfbd-4691-83c9-d535678b51c3/KakaoTalk_20210201_232044690.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. j_jhwww.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/j_jhwww" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[React] < a >태그 ,  Link 컴포넌트  차이점]]></title>
            <link>https://velog.io/@j_jhwww/React-a-Link-%EC%B0%A8%EC%9D%B4%EC%A0%90</link>
            <guid>https://velog.io/@j_jhwww/React-a-Link-%EC%B0%A8%EC%9D%B4%EC%A0%90</guid>
            <pubDate>Sat, 22 Jan 2022 04:59:17 GMT</pubDate>
            <description><![CDATA[<p>첫 프로젝트에 투입되어 개발하는 도중, 사소한 궁금증이 생겼다.
페이지를 이동시켜 줄 때 사용되는, 굉장히 기본적이지만 <code>&lt;a&gt;</code>태그와 <code>Link</code> 컴포넌트의 차이점에 대해서 알아보자. </p>
<hr>
<h2 id="a">&lt; a &gt;</h2>
<pre><code class="language-javascript">&lt; a href= &#39;url&#39; /&gt;</code></pre>
<p>기존 html을 사용할 때 쓰이던 방법으로 페이지를 새롭게 불러오면서 리액트 앱의 상태들도 초기화되고, 새로 렌더링을 하게 된다. 즉, 브라우저 주소를 이동하고 페이지 자체를 새로고침한다. 따라서 상태 값이 유지되지 못하고 속도도 저하된다.</p>
<br/>

<h2 id="link">Link</h2>
<pre><code class="language-javascript">import { Link } from &#39;react-router-dom&#39;;

&lt; Link to= &#39;url&#39; /&gt;</code></pre>
<p>HTML5 History API를 사용해서 브라우저의 주소만 바꿀 뿐, 페이지를 새로 불러오지는 않는다. 필요한 부분만 재렌더링 되고 나머지 데이터는 그대로 유지된 채 재사용되기에 데이터를 필요한 부분만 불러들일 수 있어 속도향상에 도움이 된다.</p>
<hr>
<p>SPA(Single Page Application) 방식으로 화면을 렌더링하는 프레임워크인 리액트에서는 새롭게 페이지를 불러오는 방식보다는 필요한 부분만 업데이트하는 방식인 Link컴포넌트를 사용하는 것을 권장한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Chatterbox Client 만들어보기]]></title>
            <link>https://velog.io/@j_jhwww/TIL-Chatterbox-Client</link>
            <guid>https://velog.io/@j_jhwww/TIL-Chatterbox-Client</guid>
            <pubDate>Sun, 21 Mar 2021 09:01:14 GMT</pubDate>
            <description><![CDATA[<p> 여러 사용자들과 같이 채팅을 할 수 있는 chat application의 클라이언트 부분을 만들어보자.</p>
<h4 id="서버를-이용하여-간단한-클라이언트를-구현해보자">서버를 이용하여 간단한 클라이언트를 구현해보자</h4>
<p><code>fetchAPI</code>를 활용하여 서버에 메서지를 요청하고(GET), 메세지를 보내게(POST)하는 기능을 만들어보자. 서버는 이미 AWS에 구축/배포되어 있는 서버를 사용하였다. 
<a href="https://github.com/Jeong-HW/im-sprint-chatterbox-client">Chatterbox Client Repository</a></p>
<hr>
<h4 id="html-구성-및-작동">HTML 구성 및 작동</h4>
<pre><code class="language-html">&lt;!doctype html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
    &lt;title&gt;chatterbox&lt;/title&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;styles/styles.css&quot;&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;main&quot;&gt;
      &lt;h1&gt;chatterbox&lt;/h1&gt;
      &lt;div id=&quot;send&quot;&gt;
        &lt;form class=&quot;submit&quot;&gt;
          &lt;input type=&quot;text&quot; class=&quot;inputUser&quot; /&gt;
          &lt;textarea class=&quot;inputChat&quot;&gt;&lt;/textarea&gt;
          &lt;button class=&quot;postbtn&quot; type=&quot;submit&quot;&gt;Post&lt;/button&gt;
          &lt;button class=&quot;clearbtn&quot; type=&quot;submit&quot;&gt;Clear&lt;/button&gt;
        &lt;/form&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div id=&quot;chats&quot;&gt;&lt;/div&gt;
    &lt;!-- your scripts --&gt;
    &lt;script src=&quot;scripts/app.js&quot;&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
<p><img src="https://images.velog.io/images/j_jhwww/post/4b62c291-f1c0-44ca-9748-f86dec147553/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-03-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.17.16.png" alt="">
매우 심플한 구성이다. 상단의 <code>inputbox</code>와 <code>textarea</code>에 각각 이름과 작성하고 싶은 내용을 적고 <code>POST</code>버튼을 클릭하면 다음과 같이 하단의 목록에 추가되면서 <code>json</code>타입으로 서버로 전송된다.
<img src="https://images.velog.io/images/j_jhwww/post/a38580c9-7337-4dd7-95c5-d52d2ecb4479/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-03-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.19.50.png" alt="">
<img src="https://images.velog.io/images/j_jhwww/post/d6ec80a2-2b75-412e-90fd-6027a86e48c3/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-03-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.25.37.png" alt="">
그리고 <code>Clear</code>버튼을 누르면 해당 알림창과 함께 모든 채팅 목록과 서버에 저장되어 있는 데이터들까지 한꺼번에 삭제한다.
<img src="https://images.velog.io/images/j_jhwww/post/e71d8f24-e250-4619-9909-0719d4f5a8eb/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-03-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.28.47.png" alt=""></p>
<hr>
<h4 id="javascript-code">JavaScript Code</h4>
<p>사용하기 편하게 <code>Singleton</code>패턴으로 작성하였다.</p>
<pre><code class="language-js">const githubID = &#39;Jeong-HW&#39;

const app = {
  server: `http://3.36.72.17:3000/${githubID}/messages`,//서버 주소값
  init: () =&gt; {                        //서버의 데이터값들을 불러와서 화면에 뿌려준다
    // TODO
    app.fetch().then(data =&gt; {
      for (let message of data) {
        app.renderMessage(message);
      }
    })
  },
  fetch: () =&gt; {                    //서버에서 받은 응답의 body속 JSON을 리턴한다
    // TODO
    return window.fetch(app.server)
      .then((response) =&gt; response.json());
  },
  send: (message) =&gt; {                    //서버로 데이터를 전송해준다
    window.fetch(app.server, {
      method: &#39;POST&#39;,
      body: JSON.stringify(message),
      headers: {
        &#39;Content-Type&#39;: &#39;application/json&#39;
      },
    })
    .then(response =&gt; response.json())
  },
  clearMessages: () =&gt; {                //화면 내 채팅목록에 있는 메시지들를 지워준다
    document.querySelector(&quot;#chats&quot;).innerHTML = &quot;&quot;;
  },
  renderMessage: (message) =&gt; {                //서버에 저장되어 있는 데이터들을 DOM을 이용하여 화면 상에 나타내준다
    const chatsArea = document.querySelector(&quot;#chats&quot;);

    const chat = document.createElement(&#39;div&#39;);
    chat.classList.add(&#39;chat&#39;);

    chat.innerHTML = 
    `&lt;div class=&quot;username&quot;&gt;${message.username}&lt;/div&gt;
    &lt;div&gt;${message.text}&lt;/div&gt;
    &lt;div&gt;${message.date}&lt;/div&gt;`;

    chatsArea.prepend(chat);  //prepend를 사용하면 상단에서부터 추가된다
  },
  reset: () =&gt; {                    //서버로 메시지를 초기화 요청을 보낸다.
    return window.fetch(`http://3.36.72.17:3000/${githubID}/clear`,{
      method: &#39;POST&#39;
    })
    .then(res =&gt; res.json())
    .then(data =&gt; app.clearMessages())    //html 화면 상 채팅 목록들도 모두 삭제
  }
};

app.init();</code></pre>
<hr>
<p><code>POST</code>버튼과 <code>Clear</code>버튼에 이벤트 생성</p>
<pre><code class="language-js">const postbutton = document.querySelector(&#39;.postbtn&#39;)

//POST버튼
if(postbutton){
  postbutton.addEventListener(&#39;click&#39;,function(event){
    event.preventDefault();

    let message = {};
    let username = document.querySelector(&#39;.inputUser&#39;).value;
    let text = document.querySelector(&#39;.inputChat&#39;).value;

    message.username = username;
    message.text = text;
    message.roomname = &#39;main room&#39;
    message.date = new Date().toLocaleString();

    app.send(message);                //이름과 text내용을 받아와서 서버로 전송한다
    app.renderMessage(message)            //이후, 해당 데이터만 추가적으로 채팅목록에 추가해준다
    document.querySelector(&#39;.inputUser&#39;).value = &quot;&quot;;
    document.querySelector(&#39;.inputChat&#39;).value = &quot;&quot;;
  })
}

const clearbutton = document.querySelector(&#39;.clearbtn&#39;)

//Clear버튼
if(clearbutton){
  clearbutton.addEventListener(&#39;click&#39;,function(event){
    event.preventDefault();
    if(confirm(&#39;정말 삭제하시겠습니까?&#39;)===true){    //confirm메소드를 이용하여 삭제 시 알림창이 뜨도록 해준다.
      app.reset();
    }
    else{
      return;
    }
  })
}</code></pre>
<hr>
<p><code>fetchAPI</code>사용법은 어느 정도 익었으나, 확실하게 http 요청/응답 관련 공부를 좀 더 심도있게 해야겠다. 다음엔 서버 구현까지 해보면서 클라이언트-서버 간 통신을 확실하게 익혀야겠다.
<img src="https://images.velog.io/images/j_jhwww/post/0cf4cc02-bbde-40c6-8f49-7cc6ccbb1c2f/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-03-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.00.30.png" alt="">
<img src="https://images.velog.io/images/j_jhwww/post/7a41f48b-ba60-4579-ae21-a94f8d6add82/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202021-03-21%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.00.39.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조(Data Structure) : 스택/큐/그래프/트리]]></title>
            <link>https://velog.io/@j_jhwww/TIL%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0Data-Structure-%EC%8A%A4%ED%83%9D%ED%81%90%EA%B7%B8%EB%9E%98%ED%94%84%ED%8A%B8%EB%A6%AC</link>
            <guid>https://velog.io/@j_jhwww/TIL%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0Data-Structure-%EC%8A%A4%ED%83%9D%ED%81%90%EA%B7%B8%EB%9E%98%ED%94%84%ED%8A%B8%EB%A6%AC</guid>
            <pubDate>Sun, 07 Mar 2021 10:05:51 GMT</pubDate>
            <description><![CDATA[<h2 id="자료구조">자료구조</h2>
<ul>
<li>여러 데이터들의 묶음을 어떻게 저장하고 사용할지 정의하며, 특정한 상황에 문제를 해결하는데 사용된다.</li>
<li>자료(Data) : 문자,숫자,그림 등의 형태로 된 의미 단위</li>
</ul>
<p>자료를 더 효율적으로 저장하고, 관리하기 위해 사용하며, 잘 선택된 자료구조는 실행시간을 단축시켜주거나 메모리 용량의 절약을 이끌어 낼 수 있다.</p>
<h4 id="자료구조의-선택-기준">자료구조의 선택 기준</h4>
<ul>
<li>자료의 처리 시간</li>
<li>자료의 크기</li>
<li>자료의 활용 빈도</li>
<li>자료의 갱신 정도</li>
<li>프로그램의 용이성<br>

</li>
</ul>
<h4 id="자료구조의-전체-분류">자료구조의 전체 분류</h4>
<p><img src="https://images.velog.io/images/j_jhwww/post/c69c2cd7-9081-4414-a21c-878c98fbdb8f/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0.png" alt=""></p>
<hr>
<h2 id="1-스택stack">1. 스택(Stack)</h2>
<p>Stack은 <code>쌓다</code>, <code>쌓이다</code>, <code>포개지다</code> 와 같은 뜻을 가지고 있다. 마치 접시를 쌓아 놓은 형태와 비슷한 이 자료구조는 직역 그대로, 자료(data)를 쌓는 자료구조다. 이처럼 Stack의 특성은 입출이 하나인 제한적 접근에 있다.</p>
<p><strong>후입선출 (LIFO : last in, first out)</strong><br>👉 맨 위에 있는 데이터 즉, 제일 마지막에 저장한 데이터를 제일 먼저 꺼낸다.</p>
<p><img src="https://images.velog.io/images/j_jhwww/post/c8ed78bc-bc95-4a3e-a378-e7bcdf872d23/%EC%8A%A4%ED%83%9D.jpeg" alt=""></p>
<p><strong>[ 일상생활 예시 ]</strong>
브라우저에서 뒤로 가기, 앞으로 가기 기능을 구현</p>
<ol>
<li><p>새로운 페이지로 접속할 때 현재 페이지를 Prev Stack에 보관한다.</p>
</li>
<li><p>뒤로 가기 버튼을 눌러 이전 페이지로 돌아갈 때는 현재 페이지를 Next Stack에 보관하고 Prev Stack에 가장 나중에 보관된 페이지를 현재 페이지로 가져온다.</p>
</li>
<li><p>앞으로 가기 버튼을 눌러 앞서 방문한 페이지로 이동을 원할 때는 Next Stack의 가장 마지막으로 보관된 페이지를 가져온다.</p>
</li>
<li><p>마지막으로 현재 페이지를 Prev Stack에 보관한다.</p>
</li>
</ol>
<br>

<hr>
<h2 id="2-큐queue">2. 큐(Queue)</h2>
<p>Queue는 줄을 서서 기다리다, 대기 행렬 이라는 뜻을 가지고 있다. 
Stack과 반대되는 개념으로, 먼저 들어간 자료(data)가 먼저 나오는 FIFO(First In First Out) 의 특성을 가지고 있는 자료구조다. </p>
<p><strong>선입선출 (FIFO : first in, first out)</strong><br>👉 맨 앞에 있는 데이터 즉, 제일 처음에 저장한 데이터를 제일 먼저 꺼낸다.</p>
<p><img src="https://images.velog.io/images/j_jhwww/post/9082c79d-4c82-418a-bc10-e525204c58a7/%ED%81%90.png" alt=""></p>
<p><strong>[ 일상생활 예시 ]</strong>
명절에는 고향으로 가기 위해 많은 자동차들이 고속도로를 지나간다. 고속도로에는 톨게이트가 있고, 자동차는 톨게이트에 진입한 순서대로 통행료를 내고 빠져나온다.</p>
<p>톨게이트를 Queue 자료구조, 자동차는 자료(data)로 비유할 수 있다.</p>
<p>이처럼 Queue는 자료(data)가 입력된 순서대로 처리해야 할 필요가 있는 상황에서 사용된다.</p>
<br>

<hr>
<h2 id="3-그래프graph">3. 그래프(Graph)</h2>
<p>노드(정점=vertex)와 간선(edge)으로 구성된 자료구조. 
쉽게 말해, 여러 개의 점들이 서로 복잡하게 연결되어 있는 관계를 표현한 자료구조다.</p>
<p>방향성에 따라 무방향 그래프<code>(undirected graph/대칭 관계)</code>와 방향 그래프<code>(directed graph/비대칭 관계)</code>로 나뉘며 간선에 비용이나 가중치를 할당하는 가중치 그래프<code>(weighted graph)</code>가 있다. 그 외에 완전 그래프, 부분 그래프, 연결 그래프, 단절 그래프 등이 존재한다.</p>
<p><img src="https://images.velog.io/images/j_jhwww/post/af39b59a-c501-49af-9828-60613cb359b5/%EA%B7%B8%EB%9E%98%ED%94%84.png" alt=""></p>
<h4 id="그래프-용어">그래프 용어</h4>
<ul>
<li>정점(Vertex) : 연결한 객체들을 의미</li>
<li>인접 정점(Adjacent vertex) : 간선에 의해 직접 연결된 정점</li>
<li>간선(Edge) : 정점들을 연결하는 선</li>
<li>차수(Degree) : 정점에 연결되어 있는 간선의 수, 방향 그래프에서 진입/진출 차수의 합</li>
<li>진입차수(In-Degree) : 방향 그래프에서 정점을 머리로 하는 간선의 수, 정점으로 들어오는 간선</li>
<li>진출차수(Out-Degree) : 방향 그래프에서 정점을 꼬리로 하는 건선의 수, 정점에서 나가는 간선</li>
<li>경로(Path) : 정점<code>A</code>에서 정점<code>B</code>까지 간선에 따라 갈 수 있는 길을 순서대로 나열한 것<ul>
<li>단순 경로(Simple-path): 경로 중 반복되는 정점이 없는것, 같은 간선을 자나가지 않는 경로</li>
<li>사이클(Cycle) : 경로의 시작 정점과 마지막 정점이 같은 경로를 의미</li>
</ul>
</li>
</ul>
<br>

<h3 id="31-그래프-표현방식">3.1 그래프 표현방식</h3>
<p><strong>1) 인접행렬 방식 (Adjacency matrix)</strong>
그래프의 연결관계를 <code>이차원 배열</code> 로 나타내는 방식</p>
<blockquote>
<p>정점 A에서 정점 B로 가는 간선이 있으면 1, 아니면 0</p>
</blockquote>
<p><img src="https://images.velog.io/images/j_jhwww/post/d0e6aa26-cf07-4088-a3f0-2b6f41eb8585/%EC%9D%B8%EC%A0%91%ED%96%89%EB%A0%AC.png" alt=""></p>
<blockquote>
<p>하나의 정점에서 자기 자신으로의 자체 간선은 있을 수 없으므로 인접 행렬의 대각선의 값은 항상 0이다. 무방향 그래프에서는 간선<code>[a, b]</code>와 <code>[b, a]</code>가 같기 때문에, 대각선을 기준으로 윗부분과 아랫부분이 대칭을 이룬다.
그와 반대로, 방향 그래프에서는 간선<code>[a, b]</code>와 <code>[b, a]</code>가 서로 다른 간선이기 때문에 대칭을 이루지 않는다. </p>
</blockquote>
<ul>
<li>장점</li>
</ul>
<ol>
<li><p>2차원 배열 안에 모든 정점들의 간선 정보를 담기 때문에 배열의 위치를 확인하면 두 점에 대한 연결 정보를 조회할 때 O(1) 의 시간 복잡도면 가능하다. </p>
</li>
<li><p>구현이 비교적 간편하다.</p>
</li>
</ol>
<br>

<ul>
<li>단점</li>
</ul>
<ol>
<li><p>모든 정점에 대해 간선 정보를 대입해야 하므로 O(n²) 의 시간복잡도가 소요됩니다.</p>
</li>
<li><p>무조건 2차원 배열이 필요하기에 필요 이상의 공간이 낭비됩니다.</p>
</li>
</ol>
<br>

<p><strong>2) 인접리스트 방식 (Adjacency list)</strong>
인접 리스트는 각 정점이 어떤 정점과 인접한지 <code>리스트</code>의 형태로 볼 수 있는 표현 방식이다. 각 정점마다 하나의 리스트를 가지고 있으며, 이 리스트에는 자신과 인접한 다른 정점들이 담겨 있다.
<img src="https://images.velog.io/images/j_jhwww/post/3d37c13c-e23b-44ca-b88c-880d12fae7fe/%EC%9D%B8%EC%A0%91%EB%A6%AC%EC%8A%A4%ED%8A%B8.png" alt=""></p>
<ul>
<li>장점</li>
</ul>
<ol>
<li><p>정점들의 연결 정보를 탐색할 때 O(n) 의 시간이면 가능하다. (n: 간선의 갯수)</p>
</li>
<li><p>필요한 만큼의 공간만 사용하기때문에 공간의 낭비가 적다.</p>
</li>
</ol>
<br>

<ul>
<li>단점</li>
</ul>
<ol>
<li><p>특정 두 점이 연결되었는지 확인하려면 인접행렬에 비해 시간이 오래 걸린다. (배열보다 탐색 속도 느림)</p>
</li>
<li><p>구현이 비교적 어렵다.</p>
</li>
</ol>
<br>

<h4 id="그래프-탐색-방법">그래프 탐색 방법</h4>
<p>하나의 정점에서 시작하여 그래프에 있는 모든 정점을 한번씩 방문하는 것을 그래프 순회 또는 그래프 탐색 이라고 한다. 그래프 탐색 방법은 깊이 우선 탐색과 너비 우선 탐색이 있다.</p>
<p><strong>1) 깊이 우선 탐색 : DFS(Depth First Search)</strong>
깊이 우선 탐색은 시작 정점에서 한 방향으로 갈 수 있는 가장 먼 경로까지 깊이 탐색해가다가 더 이상 갈 곳이 없으면 가장 마지막에 만났던 갈림길 간선이 있는 정점으로 되돌아와서 다른 방향의 간선으로 탐색을 계속함으로써 모든 정점을 방문하는 순회 방법이다. <code>Stack 사용</code></p>
<p><strong>2) 너비 우선 탐색 : BFS(Breath Frist Search)</strong>
너비 우선 탐색은 시작 정점으로 부터 인접한 정점들을 모두 차례로 방문한 후, 방문했던 정점을 다시 시작점으로 하여 인접한 정점들을 차례로 방문하는 방법으로, 가까운 정점들을 먼저 방문하고 멀리 있는 정점들은 나중에 방문하는 순회 방법이다. <code>Queue 사용</code></p>
<p><img src="https://images.velog.io/images/j_jhwww/post/cb8c728e-27f7-4a04-8356-e23e03b3c4c1/DFS%20&%20BFS.gif" alt=""></p>
<hr>
<h2 id="4-트리tree">4. 트리(Tree)</h2>
<p>노드로 구성된 계층적 자료구조로 최상위 노드(루트)를 만들고, 그 아래 자식 노드를 추가하는 방식.
그래프의 여러 구조 중 사이클이 없는 그래프이며 일방향 그래프의 한 구조로, <code>최소연결트리</code>로 불린다.
그러므로, 루트에서 어떤 노드로 가는 경로는 유일하다.</p>
<p><img src="https://images.velog.io/images/j_jhwww/post/63f54b2a-a933-45e6-abd1-92ddcce47354/new%20%ED%8A%B8%EB%A6%AC.png" alt=""></p>
<h4 id="트리-용어">트리 용어</h4>
<ul>
<li>노드(node) : 트리의 구성요소</li>
<li>간선(edge) : 노드와 노드를 잇는 선 <ul>
<li>노드가 N개인 트리는 항상 N-1개의 간선(링크)를 가진다</li>
</ul>
</li>
<li>루트 노드(root node) : 트리의 최상위 존재하는 노드</li>
<li>단말 노드(leaf node) :  차수가 0인 노드, 즉 자식 노드가 없는 노드</li>
<li>내부 노드(internal node) : 차수가 1 이상인 노드, 단말 노드가 아닌 노드</li>
<li>부모(parent) : 부속트리(subtree)를 가진 노드</li>
<li>자식(child) : 부모에 속하는 노드</li>
<li>형제(sibling) : 같은 부모를 가지는 노드</li>
<li>크기(size) : 자신을 포함한 모든 자식 노드의 개수</li>
<li>차수(degree): 하위 트리 개수 / 간선 수 (degree) = 각 노드가 지닌 가지의 수</li>
<li>깊이(depth) : 루트 노드에서 어떤 노드에 도달하기 위해 거쳐야 하는 간선의 수 <ul>
<li>루트 노드의 깊이는 <code>0</code>이다</li>
</ul>
</li>
<li>높이(height) : 루트 노드에서 가장 깊숙히 있는 노드의 깊이</li>
<li>레벨(level) : 트리의 깊이와 정의가 비슷하지만 그 기준이 간선이 아닌 노드의 개수이다. 따라서 <code>depth + 1 = level</code>이 성립한다</li>
</ul>
<br>

<h3 id="4-1-이진탐색트리bst-binary-search-tree">4-1. 이진탐색트리(BST: Binary Search Tree)</h3>
<p>모든 왼쪽 자식들은 루트나 부모보다 작은 값이고, 모든 오른쪽 자식들은 루트나 부모보다 큰 값인 특징을 가지고 있는 이진 트리를 <code>이진 탐색 트리</code>라고 정의한다.</p>
<h4 id="이진트리binary-tree-란">이진트리(Binary Tree) 란?</h4>
<p>자식 노드가 최대 두 개인 노드들로 구성된 트리를 이진 트리라고 정의한다. 이 두 개의 노드는 왼쪽 자식과 오른쪽 자식으로 분류한다. 이진 트리는 자료의 삽입, 삭제 방법에 따라 정 이진 트리(Full binary tree), 완전 이진 트리(Complete binary tree), 포화 이진 트리(Perfect binary tree)로 나뉜다.</p>
<h4 id="이진트리의-종류">이진트리의 종류</h4>
<p><img src="https://images.velog.io/images/j_jhwww/post/26154a94-b0fd-46af-9763-63578f03c371/%EC%9D%B4%EC%A7%84%ED%8A%B8%EB%A6%AC%20%EC%A2%85%EB%A5%98.PNG" alt=""></p>
<ul>
<li>정 이진 트리: 각 노드가 0 개 혹은 2 개의 자식 노드를 갖는다.</li>
<li>포화 이진 트리: 정 이진 트리이면서 완전 이진 트리인 경우다. 모든 단말노드의 레벨이 동일하고, 모든 레벨이 가득 채워져 있는 트리다.</li>
<li>완전 이진 트리: 마지막 레벨을 제외한 모든 노드가 가득 차 있어야 하고, 마지막 레벨의 노드는 전부 차 있지 않아도 되지만 왼쪽이 채워져야 한다.</li>
</ul>
<h4 id="이진탐색트리-순회-종류">이진탐색트리 순회 종류</h4>
<p>1) 전위 순회 (Preorder) : 현재 노드 → 왼쪽 서브트리 → 오른쪽 서브트리</p>
<p><img src="https://images.velog.io/images/j_jhwww/post/afe08ed2-af90-4539-8006-27b24d44453d/%EC%A0%84%EC%9C%84%EC%88%9C%ED%9A%8C.png" alt=""></p>
<blockquote>
<p>** 결과값 : A → B → D → E → C → F → G**</p>
</blockquote>
<p>2) 중위 순회 (Inorder) : 왼쪽 서브트리 → 현재 노드 → 오른쪽 서브트리</p>
<p><img src="https://images.velog.io/images/j_jhwww/post/b2f30a74-8a6d-41c7-909e-4e648d81478f/%EC%A4%91%EC%9C%84%EC%88%9C%ED%9A%8C.png" alt=""></p>
<blockquote>
<p>** 결과값 : D → B → E → A → F → C → G**</p>
</blockquote>
<p>3) 후위 순회 (Postorder) : 왼쪽 서브트리 → 오른쪽 서브트리 → 현재 노드</p>
<p><img src="https://images.velog.io/images/j_jhwww/post/dfec496c-7477-44e7-b34a-b479174518be/%ED%9B%84%EC%9C%84%EC%88%9C%ED%9A%8C.png" alt=""></p>
<blockquote>
<p>** 결과값 : D → E → B → F → G → C → A**</p>
</blockquote>
<hr>
<p>참고 사이트 </p>
<p><a href="https://andrew0409.tistory.com/148">https://andrew0409.tistory.com/148</a></p>
<p><a href="https://coding-factory.tistory.com/610">https://coding-factory.tistory.com/610</a></p>
<p><a href="https://velog.io/@leobit/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0Data-Structure#1-%EA%B7%B8%EB%9E%98%ED%94%84graph">https://velog.io/@leobit/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0Data-Structure#1-%EA%B7%B8%EB%9E%98%ED%94%84graph</a></p>
<p><a href="https://kosaf04pyh.tistory.com/131">https://kosaf04pyh.tistory.com/131</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] Prototype Chain]]></title>
            <link>https://velog.io/@j_jhwww/TILJavaScript-Prototype-Chain</link>
            <guid>https://velog.io/@j_jhwww/TILJavaScript-Prototype-Chain</guid>
            <pubDate>Fri, 26 Feb 2021 07:47:23 GMT</pubDate>
            <description><![CDATA[<h3 id="prototype">Prototype</h3>
<p>자바스크립트의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결되어 있다. 그리고 이것은 마치 객체 지향의 상속 개념과 같이 부모 객체의 property 또는 method를 상속받아 사용할 수 있게 한다. 이러한 부모 객체를 <code>Prototype(프로토타입) 객체</code> 또는 줄여서 <code>Prototype(프로토타입)</code>이라 한다.
<code>Prototype 객체</code>는 생성자 함수에 의해 생성된 각각의 객체에 공유 property를 제공하기 위해 사용한다.
결론적으로 쉽게 설명하면, 모델의 청사진을 만들 때 쓰는 원형 객체(Original form)이다.</p>
<hr>
<h3 id="constructor-생성자-함수">constructor (생성자 함수)</h3>
<p><code>Prototype</code> 객체는 <code>constructor property</code>를 갖는다. 이 <code>constructor property</code>는 객체의 입장에서 자신을 생성한 객체를 가리킨다.</p>
<p>예를 들어 <code>Person()</code> 생성자 함수에 의해 생성된 객체를 <code>foo</code>이라고 하자. 이 <code>foo</code> 객체를 생성한 객체는 <code>Person()</code> 생성자 함수이다. 이때 <code>foo</code> 객체 입장에서 자신을 생성한 객체는 <code>Person()</code> 생성자 함수이며, <code>foo</code> 객체의 <code>Prototype</code> 객체는 <code>Person.prototype</code>이다. 따라서 <code>Prototype</code> 객체 <code>Person.prototype</code>의 <code>constructor property</code>는 <code>Person()</code> 생성자 함수를 가리킨다.</p>
<blockquote>
</blockquote>
<pre><code class="language-js">function Person(name) {
  this.name = name;
}
&gt;
var foo = new Person(&#39;Lee&#39;);
&gt;
// Person() 생성자 함수에 의해 생성된 객체를 생성한 객체는 Person() 생성자 함수이다.
console.log(Person.prototype.constructor === Person);
👉 true
&gt;
// foo 객체를 생성한 객체는 Person() 생성자 함수이다.
console.log(foo.constructor === Person);
👉 true
&gt;
// Person() 생성자 함수를 생성한 객체는 Function() 생성자 함수이다.
console.log(Person.constructor === Function);
👉 true</code></pre>
<hr>
<h3 id="prototype-chain">Prototype Chain</h3>
<p>자바스크립트는 특정 객체의 property나 method에 접근시 객체 자신의 것뿐 아니라 <code>__proto__</code> 가 가리키는 링크를 따라서 자신의 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 접근할 수 있다.
즉, 특정 객체의 프로퍼티나 메소드 접근시 만약 현재 객체의 해당 프로퍼티가 존재하지 않는다면 <code>__proto__</code>가 가리키는 링크를 따라 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 차례로 검색하는 것이 바로 프로토타입 체인이다.
<br>
<strong>Example</strong></p>
<blockquote>
</blockquote>
<p>💻 <strong>Code</strong></p>
<pre><code class="language-js">const car = {
    wheels: 4,
    drive(){
        console.log(&quot;drive...&quot;);
    },
};
&gt;
const bmw = {
    color: &quot;red&quot;,
    navigation: 1,
};
&gt;
bmw.__proto__=car;
&gt;
const x5 = {
    color: &quot;white&quot;,
    name: &quot;x5&quot;,
};
&gt;
x5.__proto__=bmw;</code></pre>
<blockquote>
<p>✔ <strong>Result</strong></p>
</blockquote>
<pre><code class="language-js">x5.name
👉 &quot;x5&quot;
&gt;
x5.color
👉 &quot;white&quot;
&gt;
x5.navigation
👉 1
&gt;
x5.drive();
👉 drive...</code></pre>
<blockquote>
<p><strong>주의해야할 점</strong></p>
</blockquote>
<pre><code class="language-js">x5
👉 {color: &quot;white&quot;, name: &quot;x5&quot;}
&gt;
&gt; 
for(let p in x5){
    console.log(p);
}
👉 color
👉 name
👉 navigation
👉 wheels
👉 drive
&gt;
&gt;
// color와 name을 제외한 나머지들은 Prototpye에서 정의한 property이다.  
for(p in x5){
    if(x5.hasOwnProperty(p)){
        console.log(&#39;o&#39;, p);
    } else{
        console.log(&#39;x&#39;, p);
    }
}
👉 o color
👉 o name
👉 x navigation
👉 x wheels
👉 x drive
&gt;  
&gt;
Object.keys(x5);
(2) [&quot;color&quot;, &quot;name&quot;]
Object.values(x5);
(2) [&quot;white&quot;, &quot;x5&quot;]</code></pre>
<blockquote>
</blockquote>
<p><strong>💻 constructor를 이용해보자</strong></p>
<pre><code class="language-js">const Bmw = function (color){
  this.color = color;
};
&gt;
Bmw.prototype = {
  constructor: Bmw,
  // 명시하지 않을 경우 z4.constructor === Bmw; 는 false값이 나온다
  // 이런 현상을 방지하기 위해 Prototype으로 덮어씌우지 않고 하나씩 property를 추가하는 것이 좋다
  wheels: 4,
  drive() {
    console.log(&quot;drive...&quot;);
  },
  navigation: 1,
  stop() {
    console.log(&quot;STOP!&quot;);
  },
};
&gt;
  &gt;
const z4 = new Bmw(&quot;blue&quot;);
&gt;
&gt;
z4.stop();
👉 STOP!
&gt;
z4 instanceof Bmw
👉 true
&gt;
z4.constructor === Bmw;
👉 true


</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[OOP (Object Oriented Programming)]]></title>
            <link>https://velog.io/@j_jhwww/TIL-OOP-Object-Oriented-Programming</link>
            <guid>https://velog.io/@j_jhwww/TIL-OOP-Object-Oriented-Programming</guid>
            <pubDate>Fri, 26 Feb 2021 02:52:14 GMT</pubDate>
            <description><![CDATA[<h3 id="oop-란">OOP 란?</h3>
<p><code>OOP</code>. 즉, 객체지향 프로그래밍은 프로그래밍 설계 철학이다. <code>OOP</code>의 모든 것은 <code>객체</code>로 그룹화되며 이 <code>객체</code>는 한번 만들고 나면, 메모리상에서 반환되기 전까지 <code>객체</code> 내의 모든 것이 유지된다. 
<code>OOP</code>가 등장하기 전에 절차지향 프로그래밍이 먼저 존재하였다. 절차지향 프로그래밍을 아주 간단하게 이야기하면, 특정 작업을 수행하기 위한 프로그램을 작성할 때, 정해진 절차에 순차적으로 맞춰 수행하는 것이다. 
그러나 <code>OOP</code>가 등장함에 따라, 단순히 별개의 변수와 함수로 순차적으로 작동하는 것을 넘어 데이터의 접근과 데이터의 처리 과정에 대한 모형을 만들어 내는 방식을 고안한 것이다. 그러므로 데이터와 기능이 별개로 취급되지 않고, 한번에 묶어서 처리할 수 있게 된 것이다.
이러한 객체 지향의 특징은 빠르게 현대 언어에 적용이 되었으며, <code>Javascript</code>는 엄밀히 말해 객체 지향 언어는 아니지만, 객체 지향 패턴으로 작성할 수 있다.</p>
<hr>
<h3 id="oop의-4가지-주요-개념">OOP의 4가지 주요 개념</h3>
<h4 id="1-캡슐화-encapsulation">1. 캡슐화 (Encapsulation)</h4>
<ul>
<li>데이터와 기능을 하나의 단위로 묶는 것</li>
<li>은닉 <code>Hiding</code> : 구현은 숨기고, 동작은 노출시킴</li>
<li>느슨한 결합 <code>Loose Coupling</code>에 유리: 언제든 구현을 수정할 수 있음</li>
</ul>
<p>캡슐화는 속성과 기능(메소드)을 따로 정의하는 것이 아닌, 하나의 객체 안에 넣어서 묶는 것이다.</p>
<p>캡슐화라는 개념에는 &quot;은닉화&quot;의 특징도 포함하고 있는데, 은닉화는 내부 데이터나 내부 동작이 외부로 노출되지 않도록 만드는 것이다. 따라서, 디테일한 구현이나 데이터는 숨기고, 동작만 노출시켜야 한다. 또한, 캡슐화의 장점으로는, 느슨한 결합을 할 수 있게 돕는다. </p>
<p>절차적 코드의 경우 데이터의 형태가 바뀔 때에 코드의 흐름에 큰 영향을 미치지만, 객체 지향의 경우 객체 내 메소드의 구현만 수정하고, 노출된 메소드를 사용하는 코드 흐름은 바뀌지 않도록 만들 수 있다.</p>
<h4 id="2-추상화-abstraction">2. 추상화 (Abstraction)</h4>
<p>추상화는 내부 구현은 아주 복잡한데, 실제로 노출되는 부분은 단순하게 만든다는 개념이다.</p>
<p>예를 들어 전화라는 객체가 있다면, 그 안에는 스피커와 마이크가 존재하고, 서킷 보드 등이 존재하는 등 내부 구현이 되어 있을 것이다. </p>
<p>그러나 실제로 우리가 사용할 때에는, 이러한 존재에 대해서는 생각하지 않고 단순히 수화기를 들고 버튼을 눌러서 해결하는 것으로 인터페이스(interface)를 단순화할 수 있다.</p>
<p>이러한 추상화를 통해 인터페이스가 단순해진다. 너무 많은 기능들이 노출되지 않은 덕분에 예기치 못한 사용상의 변화가 일어나지 않도록 만들 수 있다.</p>
<p>추상화는 캡슐화와 비교해서 종종 헷갈려하는 개념 중 하나다.</p>
<p>캡슐화가 코드나 데이터의 은닉에 포커스가 맞춰져있다면, 추상화는 클래스를 사용하는 사람이 필요하지 않은 메소드 등을 노출시키지 않고, 기능 단순한 이름으로 정의하는 것에 포커스가 맞춰져 있다.</p>
<p>클래스 정의 시, 메소드와 속성만 정의한 것을 인터페이스라고 부른다. 이것이 추상화의 본질이다.</p>
<h4 id="3-상속-inheritance">3. 상속 (Inheritance)</h4>
<p>상속은 부모 클래스의 특징을 자식 클래스가 물려받는 것이다.</p>
<p>부모/자식으로 이야기하기도 하지만, 보다 그 특징을 자세하게 설명하는 용어는 &quot;기본 클래스(base class)의 특징을 파생 클래스(derive class)가 상속받는다&quot;로 표현하는 것이 적합하다.
<img src="https://images.velog.io/images/j_jhwww/post/d748231d-866d-44b2-8042-882908a90d04/%EC%83%81%EC%86%8D.PNG" alt=""></p>
<h4 id="4-다형성-polymorphism">4. 다형성 (Polymorphism)</h4>
<p><code>Polymorphism</code>라는 단어의 <code>poly</code>는 &quot;많은&quot;, 그리고 <code>morph</code>는 &quot;형태&quot;라는 뜻을 가지고 있다. 즉 &quot;다양한 형태&quot;를 가질 수 있다는 설명이 된다.</p>
<p>&quot;말하다&quot;라는 동작의 본질은 &quot;입으로 소리를 내다&quot;를 의미한다. 그러나, 각기 다른 동물들이 &quot;말할 때&quot; 제각각의 소리를 내는 것처럼, 객체 역시 똑같은 메소드라 하더라도, 다른 방식으로 구현될 수 있다.</p>
<p>만일 언어 자체에서 다형성을 제공하지 않는다면, 기본(부모) 클래스에 종류별로 분기를 시켜서 하나하나 다르게 만들어야 할 것이다.</p>
<hr>
<h3 id="정리">정리</h3>
<p>캡슐화는 코드가 복잡하지 않게 만들고, 재사용성을 높인다.</p>
<p>추상화는 마찬가지로 코드가 복잡하지 않게 만들고, 단순화된 사용으로 인해 변화에 대한 영향을 최소화한다</p>
<p>상속 역시 불필요한 코드를 줄여 재사용성을 높인다.</p>
<p>다형성으로 인해 동일한 메소드에 대해 if/else if와 같은 조건문 대신 객체의 특성에 맞게 달리 작성하는 것이 가능해진다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] 화살표 함수]]></title>
            <link>https://velog.io/@j_jhwww/TILJavaScript-%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@j_jhwww/TILJavaScript-%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98</guid>
            <pubDate>Wed, 24 Feb 2021 14:43:43 GMT</pubDate>
            <description><![CDATA[<p>ES6에서 새로 도입한 화살표 함수(arrow function)와 일반 함수를 비교해본다. 보통 함수 표현식을 축약한 형태로 표시된다.</p>
<hr>
<h4 id="일반함수">일반함수</h4>
<blockquote>
</blockquote>
<pre><code class="language-js">const add = function (x, y) {
      return x + y
    }</code></pre>
<hr>
<h4 id="화살표-함수">화살표 함수</h4>
<p>일반적인 화살표 함수의 사용법</p>
<blockquote>
</blockquote>
<pre><code class="language-js">const add = (x, y) =&gt; {
  return x + y
}</code></pre>
<p><code>return</code>을 생략할 경우, 중괄호<code>{}</code>는 사용해서는 안된다.</p>
<blockquote>
</blockquote>
<pre><code class="language-js">const add = (x, y) =&gt; x + y</code></pre>
<p>필요에 따라 소괄호<code>()</code>를 붙일 수 있다.</p>
<blockquote>
</blockquote>
<pre><code class="language-js">const add = (x, y) =&gt; (x + y)</code></pre>
<hr>
<h4 id="화살표-함수를-이용한-클로저-함수-예제">화살표 함수를 이용한 클로저 함수 예제</h4>
<p>일반적인 함수 표현식</p>
<blockquote>
</blockquote>
<pre><code class="language-js">const adder = function(x) {
  return function(y) {
    return x + y
  }
}
&gt;
adder(5)(7) // 12</code></pre>
<p>화살표 함수를 이용하여 축소화 한다.</p>
<blockquote>
</blockquote>
<p>✔ 추가적으로, 파라미터가 단 한개라면, 소괄호를 생략할 수 있다</p>
<pre><code class="language-js">const adder = x =&gt; y =&gt; x + y</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[문서 객체 모델(DOM)]]></title>
            <link>https://velog.io/@j_jhwww/20210203TIL%EB%AC%B8%EC%84%9C-%EA%B0%9D%EC%B2%B4-%EB%AA%A8%EB%8D%B8DOM</link>
            <guid>https://velog.io/@j_jhwww/20210203TIL%EB%AC%B8%EC%84%9C-%EA%B0%9D%EC%B2%B4-%EB%AA%A8%EB%8D%B8DOM</guid>
            <pubDate>Wed, 03 Feb 2021 14:23:27 GMT</pubDate>
            <description><![CDATA[<h4 id="domdocument-object-model-이란">DOM(Document Object Model) 이란?</h4>
<p>DOM은 Document Object Model의 약자로, HTML(Document)에 접근하여 Object(JavaScript Object)처럼 HTML을 조작(Manipulation)할 수 있는 Model이라는 의미를 가지고 있으며, XML이나 HTML 문서에 접근하기 위한 일종의 인터페이스이다. 이 객체 모델은 문서 내의 모든 요소를 정의하고, 각각의 요소에 접근하는 방법을 제공한다.</p>
<p>이 중에서, 오늘 document 객체를 통해서 HTML 엘리먼트를 만들고(CREATE), 조회하고(READ), 갱신하고(UPDATE), 삭제하는(DELETE) 하는 방법들을 접했다.</p>
<p>오늘은 간단하게 대표적으로 이런 것들이 있구나라고 파악을 했고, 추가적으로 다른 명령어들도 찾아봐야겠다. </p>
<p>추후에 직접 실습을 해본 내용들을 따로 정리해야겠다.</p>
<hr>
<ul>
<li>CREATE: <code>createElement</code> , <code>append</code>, <code>appendChild</code></li>
<li>READ: <code>querySelector</code>, <code>querySelectorAll</code> , <code>getElementById</code></li>
<li>UPDATE: <code>textContent</code>, <code>classList</code>, <code>setAttribute</code></li>
<li>DELETE: <code>remove</code>, <code>removeChild</code>, (<code>innerHTML = &quot;&quot;</code> , <code>textContent = &quot;&quot;</code>)</li>
</ul>
<hr>
<p><em><strong>PS. CRUD란?</strong></em></p>
<blockquote>
</blockquote>
<pre><code>C reate : 생성
R ead   : 읽기(조회)
U pdate : 갱신(수정)
D elete : 삭제</code></pre><blockquote>
</blockquote>
<p>CRUD는 대부분의 컴퓨터 소프트웨어가 가지는 기본적인 데이터 처리 기능인 Create(생성), Read(읽기), Update(갱신), Delete(삭제)를 묶어서 일컫는 말이다. 
사용자 인터페이스가 갖추어야 할 기능(정보의 참조/검색/갱신)을 가리키는 용어로서도 사용된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] map,filter,reduce]]></title>
            <link>https://velog.io/@j_jhwww/20210201JavaScript-mapfilterreduce</link>
            <guid>https://velog.io/@j_jhwww/20210201JavaScript-mapfilterreduce</guid>
            <pubDate>Mon, 01 Feb 2021 14:14:42 GMT</pubDate>
            <description><![CDATA[<h4 id="내장고차함수built-in-higher-order-functions">내장고차함수(Built-in higher order functions)</h4>
<p>자바스크립트에는 기본적으로 내장(built-in)되어 있는 고차 함수들이 있다. 바로 배열 메소드들 중 일부가 고차 함수에 해당한다. 그 중에서 <code>map</code>,<code>filter</code>,<code>reduce</code>를 중점적으로 공부하였다. 참고로 이 메소드들은 모두 사본을 반환하며 원래의 배열은 바뀌지 않는다.
<br></p>
<hr>
<ul>
<li><strong>map</strong><ol>
<li>배열의 각 요소가<ol start="2">
<li>특정 논리(함수)에 의해</li>
</ol>
</li>
<li>다른 요소로 지정(map) 된다.</li>
</ol>
</li>
</ul>
<p>쉽게 말해 배열(array)내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 가진 새로운 배열을 만들어낸다.</p>
<blockquote>
</blockquote>
<p> 👉 <strong>arr.map(callback(currentValue[, index[, array]])[, thisArg])</strong><br>
<code>callback</code>: 새로운 배열 요소를 생성하는 함수. 다음 세 가지 인수를 가진다.<br>
<code>currentValue</code>: 처리할 현재 요소.<br>
<code>index(Optional)</code>: 처리할 현재 요소의 인덱스.<br>
<code>array(Optional)</code>: <code>map</code>을 호출한 배열.<br></p>
<hr>
<p><code>thisArg(Optional)</code>: <code>callback</code>을 실행할 때 <code>this</code>로 사용되는 값</p>
<blockquote>
<p>ex.1)</p>
</blockquote>
<pre><code class="language-js">var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
  return num * 2;
});
// doubles는 이제 [2, 8, 18]
// numbers는 그대로 [1, 4, 9]</code></pre>
<blockquote>
<p>ex.2)</p>
</blockquote>
<pre><code class="language-js">var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots는 [1, 2, 3]
// numbers는 그대로 [1, 4, 9]</code></pre>
<hr>
<ul>
<li><strong>filter</strong><ol>
<li>배열의 각 요소가<ol start="2">
<li>특정 논리(함수)에 따르면, 사실(boolean)일 때</li>
</ol>
</li>
<li>따로 분류한다(filter).</li>
</ol>
</li>
</ul>
<p>배열의 filter 메소드는 배열의 요소 중 특정 조건을 만족하는 요소들만을 걸러내는(filter) 메소드이다. 예를 들어, 수(number)를 요소로 갖는 배열 중 짝수만을 걸러내거나, 18 보다 작은 수만을 걸러내는 식이다. 문자열(string)을 요소로 갖는 배열 중 길이가 10 이하인 문자열만 걸러내거나, &#39;student&#39; 같은 특정한 문자열을 걸러낼 수도 있다.</p>
<blockquote>
</blockquote>
<p> 👉 <strong>arr.filter(callback(element[, index[, array]])[, thisArg])</strong><br>
<code>callback</code>: 각 요소를 시험할 함수. <code>true</code>를 반환하면 요소를 유지하고, <code>false</code>를 반환하면 버린다. 다음 세 가지 매개변수를 받는다.<br>
<code>element</code>: 처리할 현재 요소.<br>
<code>index(Optional)</code>: 처리할 현재 요소의 인덱스.<br>
<code>array(Optional)</code>: <code>filter</code>를 호출한 배열.<br></p>
<hr>
<p><code>thisArg(Optional)</code>: <code>callback</code>을 실행할 때 <code>this</code>로 사용되는 값</p>
<blockquote>
<p>ex.1) </p>
</blockquote>
<pre><code class="language-js">function isBigEnough(value) {
  return value &gt;= 10;
}
var filtered = [12, 5, 8, 130, 44].filter(isBigEnough);
// filtered 는 [12, 130, 44]</code></pre>
<blockquote>
<p>ex.2)</p>
</blockquote>
<pre><code class="language-js">// 함수 표현식
const isEven = function (num) {
  return num % 2 === 0;
};
let arr = [1, 2, 3, 4];
&gt;
let output = arr.filter(isEven);
console.log(output); // -&gt;&gt; [2, 4]
&gt;
const isLteFive = function (str) {
  // Lte = less then equal
  return str.length &lt;= 5;
};
&gt;
arr = [&#39;hello&#39;, &#39;code&#39;, &#39;states&#39;, &#39;happy&#39;, &#39;hacking&#39;];
// output = arr.filter(길이 5 이하)
// &#39;길이 5 이하&#39;를 판별하는 함수가 조건으로서 filter 메소드의 인자로 전달
let output = arr.filter(isLteFive);
console.log(output); // -&gt;&gt; [&#39;hello&#39;, &#39;code&#39;, &#39;happy&#39;]</code></pre>
<hr>
<ul>
<li><strong>reduce</strong><ol>
<li>배열의 각 요소를<ol start="2">
<li>특정 응축 방법(함수)에 따라</li>
</ol>
</li>
<li>원하는 하나의 형태로</li>
<li>응축한다(reduction).</li>
</ol>
</li>
</ul>
<p>reduce() 메소드는 배열의 각 요소에 대해 주어진 reducer 함수를 실행하고, 하나의 결과값을 반환한다.</p>
<blockquote>
</blockquote>
<p> 👉 <strong>arr.reduce(callback[, initialValue])</strong><br>
<code>callback</code>: 배열의 각 요소에 대해 실행할 함수. 다음 네 가지 인수를 받는다.<br>
<code>accumulator</code>: 누산기<sup>accmulator</sup>는 콜백의 반환값을 누적한다. 콜백의 이전 반환값 또는, 콜백의 첫 번째 호출이면서 <code>initialValue</code>를 제공한 경우에는 <code>initialValue</code>의 값이다.<br>
<code>currentValue</code>: 처리할 현재 요소.<br>
<code>currentIndex(Optional)</code>: 처리할 현재 요소의 인덱스. <code>initialValue</code>를 제공한 경우 0, 아니면 1부터 시작한다.<br>
<code>array(Optional)</code>: <code>reduce</code>를 호출한 배열<br></p>
<hr>
<p><code>initialValue(Optional)</code>: <code>callback</code>의 최초 호출에서 첫 번째 인수에 제공하는 값. 초기값을 제공하지 않으면 배열의 첫 번째 요소를 사용한다. 빈 배열에서 초기값 없이 <code>reduce</code>를 호출하면 오류가 발생한다.</p>
<p>콜백의 최초 호출 때 <code>accumulator</code>와 <code>currentValue</code>는 다음 두 가지 값 중 하나를 가질 수 있다. 만약 <code>reduce()</code> 함수 호출에서 <code>initialValue</code>를 제공한 경우, <code>accumulator</code>는 <code>initialValue</code>와 같고 <code>currentValue</code>는 배열의 첫 번째 값과 같다. <code>initialValue</code>를 제공하지 않았다면, <code>accumulator</code>는 배열의 첫 번째 값과 같고 <code>currentValue</code>는 두 번째와 같다.</p>
<blockquote>
<p>ex.1) </p>
</blockquote>
<pre><code class="language-js">var sum = [0, 1, 2, 3].reduce(function (accumulator, currentValue) {
  return accumulator + currentValue;
}, 0);    --&gt; 초기값 0으로 설정
// sum is 6</code></pre>
<blockquote>
<p>ex.2)</p>
</blockquote>
<pre><code class="language-js">var sum = [0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array) {
  return accumulator + currentValue;
}, 10); --&gt; 초기값 10으로 설정
// sum is 20</code></pre>
<table>
<thead>
<tr>
<th align="center"></th>
<th align="center">accumulator</th>
<th align="center">currentValue</th>
<th align="center">currentIndex</th>
<th align="center">array</th>
<th align="center">반환값</th>
</tr>
</thead>
<tbody><tr>
<td align="center">1번째 호출</td>
<td align="center">10</td>
<td align="center">0</td>
<td align="center">0</td>
<td align="center">[0, 1, 2, 3, 4]</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">2번째 호출</td>
<td align="center">10</td>
<td align="center">1</td>
<td align="center">1</td>
<td align="center">[0, 1, 2, 3, 4]</td>
<td align="center">11</td>
</tr>
<tr>
<td align="center">3번째 호출</td>
<td align="center">11</td>
<td align="center">2</td>
<td align="center">2</td>
<td align="center">[0, 1, 2, 3, 4]</td>
<td align="center">13</td>
</tr>
<tr>
<td align="center">4번째 호출</td>
<td align="center">13</td>
<td align="center">3</td>
<td align="center">3</td>
<td align="center">[0, 1, 2, 3, 4]</td>
<td align="center">16</td>
</tr>
<tr>
<td align="center">5번째 호출</td>
<td align="center">16</td>
<td align="center">4</td>
<td align="center">4</td>
<td align="center">[0, 1, 2, 3, 4]</td>
<td align="center">20</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] 일급객체와 고차함수]]></title>
            <link>https://velog.io/@j_jhwww/2021.02.01-TILToday-I-Learned</link>
            <guid>https://velog.io/@j_jhwww/2021.02.01-TILToday-I-Learned</guid>
            <pubDate>Mon, 01 Feb 2021 12:17:11 GMT</pubDate>
            <description><![CDATA[<h4 id="일급객체first-class-citizen와-고차함수higher-order-function">일급객체(first-class citizen)와 고차함수(higher order function)</h4>
<ul>
<li>일급객체<ul>
<li>변수에 할당(assignment)할 수 있다.</li>
<li>다른 함수의 인자(argument)로 전달될 수 있다.</li>
<li>다른 함수의 결과로서 리턴될 수 있다.</li>
</ul>
</li>
</ul>
<p>이는 함수를 데이터(<code>string</code>, <code>number</code>, <code>boolean</code>, <code>array</code>, <code>object</code>)를 다루듯이 다룰 수 있다는 걸 의미한다. 변수에 저장할 수 있기 때문에 배열의 요소나 객체의 속성값으로 저장하는 것도 가능하다.
<br></p>
<ul>
<li>고차함수
고차 함수(higher order function)는 함수를 인자(argument)로 받거나 함수를 리턴하는 함수를 말한다. 이 때 다른 함수(caller)의 인자(argument)로 전달되는 함수를 콜백 함수(callback function)라고 한다. <p>콜백 함수를 전달받은 함수는 이 콜백 함수를 호출(invoke)할 수 있다. caller는 조건에 따라 콜백 함수의 실행 여부를 결정할 수도 있고, 심지어 여러 번 실행할 수도 있다. 특히 콜백 함수는 어떤 작업이 완료되었을 때 호출되는 경우가 많아서 답신 전화를 뜻하는 콜백이라는 이름이 붙여졌다.</p>
</li>
</ul>
<hr>
<ol>
<li>다른 함수를 인자로 받는 경우<pre><code class="language-js">function double(num) {
return num * 2;
}
</code></pre>
</li>
</ol>
<p>function doubleNum(func, num) {
  return func(num);
}</p>
<p>// 함수 doubleNum은 다른 함수를 인자로 받는 고차 함수.
// 함수 doubleNum의 첫 번째 인자 func에 함수가 들어올 경우
// 함수 func는 함수 doubleNum의 콜백 함수.
// 아래와 같은 경우, 함수 double은 함수 doubleNum의 콜백 함수.
let output = doubleNum(double, 4);
console.log(output); // -&gt; 8</p>
<pre><code>***
2. 함수를 리턴하는 경우
```js
function adder(added) {
  return function (num) {
    return num + added;
  };
}

// 함수 adder는 다른 함수를 리턴하는 고차 함수입.
// adder는 인자 한 개를 입력받아서 함수(익명 함수)를 리턴.
// 리턴되는 익명 함수는 인자 한 개를 받아서 added와 더한 값을 리턴.

// adder(5)는 함수이므로 함수 호출 연산자 &#39;()&#39;를 사용할 수 있다.
let output = adder(5)(3); // -&gt; 8
console.log(output); // -&gt; 8

// adder가 리턴하는 함수를 변수에 저장할 수 있다.
// javascript에서 함수는 일급 객체이기 때문이다.
const add3 = adder(3);
output = add3(2);
console.log(output); // -&gt; 5</code></pre><hr>
<ol start="3">
<li>함수를 인자로 받고, 함수를 리턴하는 경우<pre><code class="language-js">function double(num) {
return num * 2;
}
</code></pre>
</li>
</ol>
<p>function doubleAdder(added, func) {
  const doubled = func(added);
  return function (num) {
    return num + doubled;
  };
}</p>
<p>// 함수 doubleAdder는 고차 함수다.
// 함수 doubleAdder의 인자 func는 함수 doubleAdder의 콜백 함수다.
// 함수 double은 함수 doubleAdder의 콜백으로 전달되었다.</p>
<p>// doubleAdder(5, double)는 함수이므로 함수 호출 기호 &#39;()&#39;를 사용할 수 있다.
doubleAdder(5, double)(3); // -&gt; 13</p>
<p>// doubleAdder가 리턴하는 함수를 변수에 저장할 수 있다. (일급 객체)
const addTwice3 = doubleAdder(3, double);
addTwice3(2); // --&gt; 8</p>
<pre><code>***



</code></pre>]]></description>
        </item>
    </channel>
</rss>