<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>_jouz_ryul.log</title>
        <link>https://velog.io/</link>
        <description>💻 소프트웨어 엔지니어를 꿈꾸는 개발 신생아👶</description>
        <lastBuildDate>Tue, 12 Jul 2022 09:45:15 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>_jouz_ryul.log</title>
            <url>https://images.velog.io/images/_jouz_ryul/profile/814a66c0-1336-11ea-ae51-435a1758dfdc/RIMG0026.JPG</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. _jouz_ryul.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/_jouz_ryul" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[리액트의 디자인 철학 - scheduling]]></title>
            <link>https://velog.io/@_jouz_ryul/%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%9D%98-%EB%94%94%EC%9E%90%EC%9D%B8-%EC%B2%A0%ED%95%99-scheduling</link>
            <guid>https://velog.io/@_jouz_ryul/%EB%A6%AC%EC%95%A1%ED%8A%B8%EC%9D%98-%EB%94%94%EC%9E%90%EC%9D%B8-%EC%B2%A0%ED%95%99-scheduling</guid>
            <pubDate>Tue, 12 Jul 2022 09:45:15 GMT</pubDate>
            <description><![CDATA[<p>어쩌면 몰라도 되는 리액트 깊숙한 곳의 이야기
출처: <a href="https://reactjs.org/docs/design-principles.html#scheduling">https://reactjs.org/docs/design-principles.html#scheduling</a></p>
<p>컴포넌트가 함수로 작성되어 있을 지라도, 리액트를 사용하면 개발자가 직접 그 컴포넌트를 호출하지 않는다. 모든 컴포넌트는 render 되어야 할 것들의 description을 리턴하고 그 description은 <code>&lt;LikeButton&gt;</code>과 같은 user-written 컴포넌트와 <code>div</code>와 같은 platform-specific 컴포넌트 모두를 포함한다. <code>&lt;LikeButton&gt;</code>를 미래의 어느 시점에 unroll하는것 또는 재귀적으로 컴포넌트들의 render 결과에 따라 UI 트리에 변화를 실제 적용하는 것은 리액트의 책임(up to React)이다.</p>
<p>이는 미묘한 차이이지만 굉장히 강력하다. 개발자가 컴포넌트 함수를 호출하지 않고 리액트에 위임 (let React call it)하는 것은 리액트가, 필요하다면, 호출을 지연시키는 권한을 (has the power) 가지고 있다는 뜻이다. 현재의 리액트 (v.16 이전) tree를 재귀적으로 순회(walk)하고 single tick안에 모든 업데이트된 트리의 render 함수를 호출한다. 하지만 미래에는 리액트가 <a href="https://github.com/facebook/react/issues/6170">프레임 드랍을 방지하기 위해 몇몇 업데이트를 지연</a>시키기 시작할 것이다.  </p>
<p>이는 리액트 디자인 철학 중 하나의 보편적 주제다. 몇 유명한 라이브러리들은 새로운 데이터가 available 할 때 computation이 실행되는 방식의 &#39;push&#39; implementation으로 접근한다. 하지만 리액트는 연산을 정말 필요할 때 까지 지연시킬 수 있는 &quot;pull&quot; 방식을 고집하고자 한다.</p>
<p>리액트는 generic 데이터 processing 라이브러리가 아니라 유저 인터페이스를 빌딩하기 위한 라이브러리다. 우리는 (리액트팀은) 리액트가 어플리케이션에서 어떤 연산이 비교적 급한지 아닌지 알 수 있기에 유니크한 위치에 있다고 생각한다. </p>
<p>만약 어떤게 offscreen일때, 우리는 연관된 모든 로직을 지연시킬 수 있다. 만약 데이터가 frame rate보다 더 빨리 응답으로 도착한다면, 업데이트를 하나로 합치고 일괄처리 할 수 있다. 또한 프레임 드랍을 방지하기 위해 유저 인터렉션으로 부터 오는 work들의 우선순위를 정할 수 있다: high priority(버튼 클릭으로 인한 애니메이션) to low priority(네트워크로 부터 막 loaded된 컨텐츠를 그리는 일)</p>
<p>정확하게는 현재 이 장점을 살리고 있지 않다. 하지만 이러한 일들을 할 수 있는 자유 떄문에 리액트 팀은 스케쥴링 컨트롤 할 수 있는것을 선호하며, <code>setState()</code>가 비동기로 처리되는 이유이다. 개념적으로 우리는 이것들이 &quot;업데이트를 스케쥴링&quot;하는 것으로 생각한다. </p>
<p>사용자가 직접 Functional Reactive Programming의 일부 변형에서 흔히 볼 수 있는 &quot;push&quot; 기반 페러다임으로 직접 뷰를 구성(compose)하도록 둔다면 스케쥴링을 컨트롤 하는 것은 리액트팀에게 더 힘들것이다. 리액튼 팀은 &quot;glue&quot; 코드를 갖길 원한다.</p>
<p>React로 돌아가기 전에 실행되는 사용자 코드의 양이 최소가 되는 것이 React의 핵심 목표이다.
(아마 리액트가 직접 관여하는 부분이, 개발자의 코드로서보다, 많은 것을 ideal 하다고 생각한다는 뜻인듯?) 이렇게 하면 React가 UI에 대해 알고 있는 내용에 따라 작업을 예약하고 청크로 분할할 수 있는 기능을 유지할 수 있게된다. </p>
<p>There is an internal joke in the team that React should have been called “Schedule” because React does not want to be fully “reactive”.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 Virtual DOM에 대해서 간단하게]]></title>
            <link>https://velog.io/@_jouz_ryul/%EB%A6%AC%EC%95%A1%ED%8A%B8-Virtual-DOM%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EA%B0%84%EB%8B%A8%ED%95%98%EA%B2%8C</link>
            <guid>https://velog.io/@_jouz_ryul/%EB%A6%AC%EC%95%A1%ED%8A%B8-Virtual-DOM%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EA%B0%84%EB%8B%A8%ED%95%98%EA%B2%8C</guid>
            <pubDate>Tue, 12 Jul 2022 01:51:55 GMT</pubDate>
            <description><![CDATA[<p>리액트에서 <code>Virtual DOM</code>은 무엇이고 리액트에서는 왜 이것을 사용하는가에 대해 간략하게 정리해보자</p>
<hr>
<h1 id="real-dom">Real DOM</h1>
<p>DOM, Document Object Model,은 어플리케이션의 UI를 나타내는 간단한 단어다.
어플리케이션 UI 상태의 변화가 있을 때 마다 DOM은 업데이트되고 변화를 적용하여 나타낸다.
하지만 DOM의 잦은 조작은 어플리케이션 퍼포먼스에 영향을 주어 속도 저하를 야기한다. </p>
<h1 id="무엇-때문에-dom-조작은-속도-저하를-야기하는가">무엇 때문에 DOM 조작은 속도 저하를 야기하는가</h1>
<p>DOM은 트리 자료 구조로 나타나있다. 그렇기 때문에, DOM의 changes와 updates는 빠르다. 하지만 변화 후, update된 element와 그의 자식들은 어플리케이션 UI를 업데이트하기 위해 re-render되어야한다. 
UI의 re-rendering 혹은 re-painting이 바로 속도 저하를 야기한다. 
따라서, UI 컴포넌트가 많은수록 모든 DOM 업데이트를 위해 모두 re-render되어야 할 수 있어 DOM 업데이트에 들어가는 비용이 비싸진다 (소요될 작업량이 많아진다로 이해하면 될듯). </p>
<h1 id="virtual-dom">Virtual DOM</h1>
<p>위의 이슈로 인해 Virtual DOM의 컨셉이 나왔고 실제 DOM보다 월등히 뛰어난 성능을 자랑한다.
Virtual DOM은 그저 단지 DOM의 가상 representation일 뿐이다. 어플리케이션의 상태가 변화할 때 마다, Virtual DOM이 real DOM 대신 업데이트 된다.</p>
<p>간혹 Virtual DOM과 real DOM이 하는 일이 동일해보이기 때문에 double work 하는 것이 아닌지 의문을 갖고 real DOM을 업데이트 하는 것 보다 Virtual DOM이 더 빠른지에 대해 의문을 갖을 수 있다.</p>
<p>왜 Virtual DOM이 실제 DOM보다 빠른지에 대해 알아보자</p>
<h1 id="왜-virtual-dom이-더-빠른가">왜 Virtual DOM이 더 빠른가</h1>
<p>UI에 새로운 element가 추가가 되면, tree로 구성된 virtual DOM이 생성된다. 각각 element는 이 트리에서 node이다. 만약 이 elements 중 어느 하나의 element의 상태가 변화하면, 새로운 Virtual DOM 트리가 생성된다. 이 새로운 트리는 이전 Virtual DOM 트리와 <code>diff</code>, 즉 비교가 된다. </p>
<p>비교가 끝난 후, Virtual DOM은 real DOM에 적용할 가장 가능성 높은 (혹은 효율적인) 방법을 계산한다. 이 과정은 실제 DOM 상의 최소한의 작동을 보장한다. 실제 DOM을 업데이트 하는것에 대한 퍼포먼스 비용을 줄이는 것이다. </p>
<p>다음 이미지는 virtual DOM tree와 비교 과정을 보여준다.
<img src="https://velog.velcdn.com/images/_jouz_ryul/post/8c6bf08e-ed99-4118-9900-314890bee76f/image.png" alt="virtual DOM and diffing process"></p>
<p>빨간색 원은 변화된 노드들을 나타낸다. 이러한 노드들은 그들의 state가 변화된 UI element를 나타낸다. 
이전 버전의 Virtual DOM tree와 새로운 버전의 Virtual DOM tree 사이의 차이가 계산된다. 부모의 하위 subtree들은 업데이트된 UI를 표현하기 위해 모두 re-render된다. 그러면 이 업데이트된 트리가 실제 DOM으로 일괄 업데이트 된다. </p>
<h1 id="리액트는-virtual-dom을-어떻게-사용하는가">리액트는 Virtual DOM을 어떻게 사용하는가</h1>
<p>리액트에서 모든 UI 조각들은 컴포넌트이며 각 컴포넌트는 상태(state)를 갖는다. 리액트는 observerable pattern을 따르고 모든 상태 변화를 listen한다. 컴포넌트의 상태가 변화하면, 리액트는 Virtual DOM tree를 업데이트 한다. Virtual DOM의 업데이트가 끝나면, 리액트는 현재 버전의 Virtual DOM과 이전 버전의 Virtual DOM을 비교한다. 이 과정을 <code>diffing</code>이라고 부른다. </p>
<p>리액트가 어떤 Virtual DOM object가 변화했는지 알게되면, 리액트는 그 변화된 objects만 실제 DOM에 업데이트한다. 이는 실제 DOM을 직접 조정(manipulating) 하는 것과 비교하여 훨신 나은 퍼포먼스를 만들어 낸다. 이 것이 리액트를 high perfomance javascript library로 돋보이게 하는 것이다. </p>
<p>다시 말해, 개발자는 단지 UI가 어떤 상태로 변화되길 리액트에 말하면, 리액트는 그 상태와 DOM이 일치하도록 보장한다. 이 때문에 개발자들은 리액트 내부에서 속성 변화, 이벤트 핸들링 또는 수동 DOM 업데이트가 어떻게 작동되는지 알 필요없게 된다. </p>
<p>이 모든 세부 정보들은 리액트 개발자로 부터 추상화된다. 개발자가 해야할 일은 필요할 때에 맞게 컴포넌트의 상태를 변화시켜주면 나머지는 리액트가 알아서 처리해준다. 이는 리액트를 사용함에 있어 뛰어난 dx (developer experience)를 경험하게 해준다.</p>
<h1 id="render-함수">render() 함수</h1>
<p><code>render()</code> 함수는 UI가 업데이트되고 렌더되는 곳이다. <code>render()</code> 함수는 리액트에서 필수적인 lifecycle method다. </p>
<p><code>render()</code> 함수는 리액트 elements의 트리가 생성되는 엔트리 포인트다. 컴포넌트의 state나 props가 업데이트되면 <code>render()</code> 함수는 리액트 element의 다른 tree를 반환한다. 컴포넌트 내부에서 <code>setState()</code>가 사용되면, 리액트는 상태 변화를 즉시 감지하고 컴포넌트를 re-render한다. </p>
<p>그 후 리액트는 변화가 적용된 가장 최신의 트리에 해당하는 UI로 가장 효율적으로 업데이트하는 방법을 계산한다. </p>
<p>이 떄가 리액트가 먼저 virtual DOM을 업데이트 하고 실제 DOM에서 변화된 objects만 업데이트 하는 떄이다. </p>
<h1 id="batch-update">Batch Update</h1>
<p>리액트는 실제 DOM을 업데이트 하기 위해 <code>batch update mechanism</code>을 따른다.
각 상태 업데이트에 대한 operation을 보내는 대신 실제 DOM에 대한 업데이트를 일괄적으로 보낸다.</p>
<p>UI 리페인팅이 가장 비싼 부분이고 리액트는 UI 리페인트 하기 위해 오직 batched 업데이트들만 실제 DOM이 받을 수 있도록 효율적으로 확신한다. </p>
<p>참고: <a href="https://velopert.com/3236">https://velopert.com/3236</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DOM Node와 Element]]></title>
            <link>https://velog.io/@_jouz_ryul/DOM-Node%EC%99%80-Element</link>
            <guid>https://velog.io/@_jouz_ryul/DOM-Node%EC%99%80-Element</guid>
            <pubDate>Tue, 28 Jun 2022 04:54:51 GMT</pubDate>
            <description><![CDATA[<p>시작은 React reconciliation, 그 전에는 React18에 적용된 Suspense, useTransition 등에 대한 궁금증에서부터였다. 관련 글을 읽다보니 자주 나오는 개념인 DOM node, element 등에 대한 이해도를 높이고자 정리하는 글</p>
<hr>
<h1 id="dom-node와-element의-차이">DOM Node와 Element의 차이</h1>
<p>Document Object Model, DOM, 은 HTML 혹은 XML 문서를 각 노드가 문서의 객체인 트리 구조로서 처리하기 위한 <code>interface</code>이다. DOM은 tree를 query (불러오기), 구조와 스타일을 변경하기 위한 여러 메소드들을 제공하기도 한다.</p>
<p>DOM은 또한 element라는 단어를 사용한다: node와 상당히 비슷하다. 그럼 두개는 무엇이 다른지 알아보자</p>
<h1 id="1-dom-node">1. DOM Node</h1>
<p>node와 element의 차이를 알아보기 위해서 node가 무엇인지 알아보는게 중요하다.</p>
<p>더 큰 관점에서 보면 DOM document는 노드 계층으로 구성된다. 각 노드는 부모와 자식 혹은 각각 가질 수 있다. 다음 HTML 문서를 살펴보자</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;My Page&lt;/title&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;!-- Page Body --&gt;
    &lt;h2&gt;My Page&lt;/h2&gt;
    &lt;p id=&quot;content&quot;&gt;Thank you for visiting my web page!&lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>위 html은 다음과 같은 계층으로 표현이 가능하다.</p>
<pre><code>ㄴ DOCTYPE: html
ㄴ HTML
    ㄴHEAD
        ㄴTITLE
            ㄴ#text: My Page
    ㄴBODY
        ㄴ#comment: Page Body
        ㄴH2
            ㄴtext: My Page
        ㄴP id=&quot;content&quot;
            ㄴ#text: Thank you for visiting my web page!</code></pre><p><code>&lt;html&gt;</code> 은 <code>&lt;head&gt;</code> and <code>&lt;body&gt;</code> node들을 자식으로 가지고 있는 document tree의 node이다. </p>
<p><code>&lt;body&gt;</code> 또한 세개의 자식을 갖는 노드다. <code>&lt;!-- Page Body --&gt;</code>, heading <code>&lt;h2&gt;</code>, 그리고 paragraph <code>&lt;p&gt;</code>. <code>&lt;body&gt;</code> node의 부모는 <code>&lt;html&gt;</code> node다.</p>
<p>HTML document의 tag들은 노드를 대표한다. 더 흥미로운건 text 또한 노드이다. paragraph node <code>&lt;p&gt;</code> 는 text node <code>&quot;Thank you for visiting my web page!&quot;</code>를 자식으로 갖는다.</p>
<h2 id="11-node-types">1.1 Node Types</h2>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node">DOM Node 인터페이스</a>를 살펴보면 <code>Node.nodeType</code> 속성으로 노드의 타입을 구분할 수 있다.</p>
<p><code>Node.nodeType</code>는 노드의 타입을 나타내는 다음의 값들이 있다.</p>
<ul>
<li><code>Node.ELEMENT_NODE</code></li>
<li><code>Node.ATTRIBUTE_NODE</code></li>
<li><code>Node.TEXT_NODE</code></li>
<li><code>Node.CDATA_SECTION_NODE</code></li>
<li><code>Node.PROCESSING_INSTRUCTION_NODE</code></li>
<li><code>Node.COMMENT_NODE</code></li>
<li><code>Node.DOCUMENT_NODE</code></li>
<li><code>Node.DOCUMENT_TYPE_NODE</code></li>
<li><code>Node.DOCUMENT_FRAGMENT_NODE</code></li>
<li><code>Node.NOTATION_NODE</code></li>
</ul>
<p>위 상수들은 노드 유형을 의미 있게 나타낸다: 예를 들면, <code>Node.ELEMENT_NODE</code>은 element node를 나타낸다. </p>
<p>예를 들어, paragraph node를 선택하고 선택된 노드의 타입을 살펴보자</p>
<pre><code class="language-javascript">const paragraph = document.querySelector(&#39;p&#39;);
paragraph.nodeType === Node.ELEMENT_NODE; // =&gt; true</code></pre>
<p>예상대로 <code>paragraph.nodeType</code>은 paragraph가 element인 것을 알 수 있듯, <code>Node.ELEMENT_NODE</code>값을 가지고 있다. </p>
<p>paragraph는 또한 text node를 가지고 있다.</p>
<pre><code class="language-javascript">const paragraph = document.querySelector(&#39;p&#39;);
const firstChild = paragraph.childNodes[0];
firstChild.nodeType === Node.TEXT_NODE; // =&gt; true</code></pre>
<p>또한 노드 타입에는 노드의 전체 document tree를 나타내는 <code>Node.DOCUMENT_NODE</code> 타입이 있다.</p>
<pre><code class="language-javascript">document.nodeType === Node.DOCUMENT_NODE; // =&gt; true</code></pre>
<hr>
<h1 id="2-dom-element">2. DOM Element</h1>
<p>DOM Node가 무엇인지 잘 파악했으니 element와 구분점을 알아보자.</p>
<p>node에 대해 이해가 높다면 답은 명확하다: element은 <code>Node.ELEMENT_NODE</code> 라는 특정 타입의 노드이다. </p>
<p>간단하게 element는 HTML의 tag를 사용해 작성된 node라고 볼 수 있다. <code>&lt;html&gt;</code>, <code>&lt;head&gt;</code>, <code>&lt;title&gt;</code>, <code>&lt;body&gt;</code>, <code>&lt;h2&gt;</code> 등 모두 tag로 대변될 수 있기 때문에 element이다.</p>
<p>하지만 document type, comment, text 노드는 모두 tag로 작성되지 않았기 때문에 element가 아니다. </p>
<p><code>Node</code>는 node의 constructor이고 <code>HTMLElement</code>는 Javascript DOM에서 element의 constructor이다. paragraph은 node이면서 element이기에 <code>Node</code>와 <code>HTMLElement</code>의 instance다.</p>
<pre><code class="language-javascript">const paragraph = document.querySelector(&#39;p&#39;);
paragraph instanceof Node;        // =&gt; true
paragraph instanceof HTMLElement; // =&gt; true</code></pre>
<p>element는 node의 subtype으로도 볼 수 있다: 고양이(element)와 동물(node)의 관계</p>
<hr>
<h1 id="3-dom-속성-nodes-and-elements">3. DOM 속성: nodes and elements</h1>
<p>node와 element의 구분을 차치하고, 오직 node 혹은 오직 element를 위한 DOM 속성들을 구분해볼 필요가 있다. </p>
<p>다음 Node 타입의 속성은 Node 혹은 NodeList로 평가된다. </p>
<pre><code class="language-javascript">node.parentNode; // Node or null
node.firstChild; // Node or null
node.lastChild;  // Node or null
node.childNodes; // NodeList</code></pre>
<p>하지만 다음 속성들은 element 혹은 element collection(<code>HTMLCollection</code>)이다.</p>
<pre><code class="language-javascript">node.parentElement; // HTMLElement or null
node.children;      // HTMLCollection</code></pre>
<p><code>node.childNodes</code>와 <code>node.children</code> 모두 children list를 반환하는데 왜 구분이 되어 있을까? 다음 예제 코드로 살펴보자</p>
<pre><code class="language-html">&lt;p&gt;
  &lt;b&gt;Thank you&lt;/b&gt; for visiting my web page!
&lt;/p&gt;</code></pre>
<p> 그 후 paragraph의 <code>childNodes</code>와 <code>children</code>을 살펴보면,</p>
<pre><code class="language-javascript">const paragraph = document.querySelector(&#39;p&#39;);
paragraph.childNodes; // NodeList:       [HTMLElement, Text]
paragraph.children;   // HTMLCollection: [HTMLElement]</code></pre>
<p><code>paragraph.childNodes</code> collection은 2개의 노드를 갖는다: bold element인 <code>&lt;b&gt;Thank you&lt;/b&gt;</code>와 text node인 <code>for visiting my web page!</code></p>
<p>하지만 <code>paragraph.children</code> collection은 bold element인 <code>&lt;b&gt;Thank you&lt;/b&gt;</code>만 가지고있다. <code>paragraph.children</code>은 오직 element만 가지고 있을 수 있기 때문에 타입이 element(<code>Node.ELEMENT_NODE</code>)가 아닌 text 타입(<code>Node.TEXT_NODE</code>)를 갖는 text node는 포함되지 않는다. </p>
<hr>
<h1 id="4-정리">4. 정리</h1>
<p>DOM document는 노드 의 계층적 collection이다. 각 node는 부모, 자식 혹은 둘다 가질 수 있다. 
즉 HTML의 계층을 표현할 수 있는 모든것은 다 Node다.</p>
<p>element은 <code>Node.ELEMENT_NODE</code> 라는 특정 타입의 노드로 HTML 문서의 tag를 사용해 작성된 node다. 
Node는 element를 포함한다: 동물(Node)과 고양이(element)의 관계. 또한 Node이면서 element인 경우도 있다: paragraph.</p>
<p>다만, Document node (<code>Node.DOCUMENT_NODE</code>)은 절대 부모를 가질 수 없다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[component, element 그리고 instance in React]]></title>
            <link>https://velog.io/@_jouz_ryul/component-element-%EA%B7%B8%EB%A6%AC%EA%B3%A0-instance-in-React</link>
            <guid>https://velog.io/@_jouz_ryul/component-element-%EA%B7%B8%EB%A6%AC%EA%B3%A0-instance-in-React</guid>
            <pubDate>Tue, 28 Jun 2022 03:26:19 GMT</pubDate>
            <description><![CDATA[<p>**
React component 와 element 이미 익숙한 개념이다.
React Reconiliation을 정리하다보니 또한 여러번 나오는 개념이다. 
문맥상 해당 글들을 이해하기에는 큰 어려움은 없으나 사실 위의 개념들은 서로 구분되는 개념들로써 정확한 의미 해석 및 문맥을 이해하려면 어떻게 분류되는 것인지 알 필요가 있다고 생각이 들어 리액트 공식문서에서 <a href="https://reactjs.org/blog/2015/12/18/react-components-elements-and-instances.html">React Components, Elements, and Instances</a>를 정리한 글이다.
**</p>
<hr>
<h1 id="react-components-elements-and-instances">React Components, Elements, and Instances</h1>
<p>컴포넌트와, 그의 instance 그리고 element간의 구분은 헷갈리는 개념이다. 왜 그들은 모두 스크린에 그려진 어떤 것을 지칭하면서 다른 단어들로 사용되는가?</p>
<hr>
<h1 id="managing-the-instances">Managing the Instances</h1>
<p>만약 React에 새로운 사람이라면, class형 컴포넌트와 instance를 접한적이 있을 것이다. 예를 들면, <code>Button</code> 컴포넌트를 만들기 위해 class를 만들었을 것이다. 어플리케이션이 작동할 때, 화면에는 해당 컴포넌트의 여러 instance들이 나타날 것이고, 각각의 instance들은 고유한 상태와 속성들을 가지고 있다. 이것이 전통적인 객체지향 UI 프로그래밍 (object-oriented UI programming)이다. </p>
<p>이 전통적인 UI 모델에서 child component instance를 만들고 지우는 것은 개발자의 책임 (몫)이다. 만약 <code>Form</code> 컴포넌트가 <code>Button</code> 컴포넌트를 render 하길 원한다면, <code>Form</code> 컴포넌트는 <code>Button</code> 컴포넌트 instance를 만들고 새로운 정보 (new props, state)에 대응하여 수동적으로 최신 상태를 유지해줘야 한다. </p>
<pre><code class="language-javascript">class Form extends TraditionalObjectOrientedView {
  render() {
    // Read some data passed to the view
    const { isSubmitted, buttonText } = this.attrs;

    if (!isSubmitted &amp;&amp; !this.button) {
      // Form is not yet submitted. Create the button!
      this.button = new Button({
        children: buttonText,
        color: &#39;blue&#39;
      });
      this.el.appendChild(this.button.el);
    }

    if (this.button) {
      // The button is visible. Update its text!
      this.button.attrs.children = buttonText;
      this.button.render();
    }

    if (isSubmitted &amp;&amp; this.button) {
      // Form was submitted. Destroy the button!
      this.el.removeChild(this.button.el);
      this.button.destroy();
    }

    if (isSubmitted &amp;&amp; !this.message) {
      // Form was submitted. Show the success message!
      this.message = new Message({ text: &#39;Success!&#39; });
      this.el.appendChild(this.message.el);
    }
  }
}</code></pre>
<p>위 코드는 프로그램 설계 언어 (pseudocode) 이지만 Backbone과 같이 object-oriented 방식으로 지속, 동일하게 동작하는 라이브러리로 composite (합성) UI를 작성할 때 대체로 작성되는 코드이다. </p>
<p>각 컴포넌트 instance는 그들의 DOM node와 children 컴포넌트들의 instance를 지속적으로 참조해야 하고 ( keep references to ) 알맞은 시기 (time)에 만들고, 업데이트하고 그리고 삭제해야한다. 컴포넌트의 상태(state)의 발생 가능성의 제곱만큼 코드 라인의 수는 늘어나고 부모가 그들의 children component instance에 직접적으로 접근이 가능해야하는 점은 미래에 이들을 분리 (decouple) 하기 어렵게 만든다. </p>
<p>즉, Button의 속성에 따라 (의존하여) 버튼이 스크린에 나타나고 없어지고 혹은 변화하는 등의 관리가 필요한데 해당 컴포넌트가 많으면 많아질수록 instance가 늘어나는 것 뿐만 아니라 instances를 조작하는 코드들도 늘어난다. 이말인즉슥, 관리할 코드가 늘어나고 비대해진 컴포넌트가 만들어져간다. 그렇기에 분리가 어려워진다.</p>
<p>그렇다면 리액트는 어떻게 다른가?</p>
<hr>
<h1 id="elements-describe-the-tree">Elements describe the TREE</h1>
<p>이 문제에 대해 리액트에서는 <code>elements</code>가 해결사로 등장한다. <strong><code>elements</code>는 컴포넌트 instance 혹은 DOM node와 그들의 속성들에 대한 정보를 가지고있는 (describing) plain object다.</strong> 이 plain object는 컴포넌트 타입 (예를 들면 a <code>Button</code> or <code>Form</code>), 해당 컴포넌트 인스턴스나 DOM node의 속성 (예: <code>color</code> 등)과 해당 컴포넌트 인스턴스나 DOM node의 자식 elements에 대한 정보만 가지고 있다. </p>
<p>element는 실제 인스턴스는 아니다. 대신, element는 개발자가 화면에 표현하고 싶은 것을 React에 전달하는 방식이다. 우리는 element에 그 어떤 method를 실행할 수 없다. element는 그냥 (just) <code>type: (string | ReactClass)</code> and <code>props: Object</code>라는 두개의 fields를 가진 불변성의 설명을 담고있는 객체일 뿐이다. </p>
<h2 id="dom-elements">DOM Elements</h2>
<p>element의 <code>type</code>이 string 이라면 DOM node에서 해당 tag 이름으로 대변되고 element의 <code>props</code>는 해당 속성dp 해당한다. 아래 예제 코드는 React가 render할 것에 대한 예제 코드이다. </p>
<pre><code class="language-javascript">{
  type: &#39;button&#39;,
  props: {
    className: &#39;button button-blue&#39;,
    children: {
      type: &#39;b&#39;,
      props: {
        children: &#39;OK!&#39;
      }
    }
  }
}</code></pre>
<p>위 예제 코드는 element를 나타내는 코드로서 다음 예제의 html을 plain object로서 나타낸 방법일 뿐이다. </p>
<pre><code class="language-html">&lt;button class=&#39;button button-blue&#39;&gt;
  &lt;b&gt;
    OK!
  &lt;/b&gt;
&lt;/button&gt;</code></pre>
<p>위 두 예제에서 볼 수 있듯이 element는 <strong>nested</strong> 될 수 있다. 컨벤션에 따르면 element tree를 생성할때, 자식 element들은 그들을 가지고 있는 element의 <code>children</code> props으로 명시해줘야 한다. </p>
<p>여기서 중요한 것은 child와 parent elements들은 모두 단지 설명 (description)일뿐 실제 instance는 아니다 라는 점이다. 우리가 child와 parent elements들을 만들 때 화면에 나타나는 것들과는 무관하다. 우리는 자유롭게 그들을 만들고 치워버릴수 있고 이는 큰 영향이 없다. 
(실제 화면 적용에 중요한 역할을 하는 것은 instance라는 뜻으로 이해)</p>
<p>parsed 될 필요가 없는 React element는 횡단하기에 쉽고 (쉽게 순회가 가능하다? 쉽게 순회하며 조작이 쉽다? 파싱 과정이 없기에) 단지 그저 객체이기에 실제 DOM element보다 훨씬 가볍다. </p>
<h2 id="component-elements">Component Elements</h2>
<p>하지만, elements의 <code>type</code>은 React 컴포넌트에 상승하여 함수 혹은 클래스가 될 수 있다.</p>
<pre><code class="language-javascript">{
  type: Button,
  props: {
    color: &#39;blue&#39;,
    children: &#39;OK!&#39;
  }
}</code></pre>
<p>이것은 리액트의 핵심 아이디어다. </p>
<p><strong>컴포넌트를 묘사하는 element 또한 DOM node를 묘사하는 element와 같이 element다. 그들은 서로 nested될 수도 mixed 될 수 있다.</strong></p>
<p>이 기능 (feature)은 개발자로 하여금 <code>DangerButton</code>컴포넌트를 <code>Button</code> 컴포넌트가  DOM에 <code>&lt;button&gt;</code>, <code>&lt;div&gt;</code>를 렌더링할지 혹은 완전히 다른것을 렌더링 할지에 대한 걱정없이 특정 <code>color</code> 속성 값을 갖는 <code>Button</code> 컴포넌트로서 정의가 가능케 해준다. </p>
<pre><code class="language-javascript">const DangerButton = ({ children }) =&gt; ({
  type: Button,
  props: {
    color: &#39;red&#39;,
    children: children
  }
});</code></pre>
<p>또한 DOM elements와 component elements를 하나의 single element tree안에 mix하고 match 시킬 수 있다. </p>
<pre><code class="language-javascript">const DeleteAccount = () =&gt; ({
  type: &#39;div&#39;,
  props: {
    children: [{
      type: &#39;p&#39;,
      props: {
        children: &#39;Are you sure?&#39;
      }
    }, {
      type: DangerButton,
      props: {
        children: &#39;Yep&#39;
      }
    }, {
      type: Button,
      props: {
        color: &#39;blue&#39;,
        children: &#39;Cancel&#39;
      }
   }]
});</code></pre>
<p>jsx로 변환하면 다음과 같다.</p>
<pre><code class="language-jsx">const DeleteAccount = () =&gt; (
  &lt;div&gt;
    &lt;p&gt;Are you sure?&lt;/p&gt;
    &lt;DangerButton&gt;Yep&lt;/DangerButton&gt;
    &lt;Button color=&#39;blue&#39;&gt;Cancel&lt;/Button&gt;
  &lt;/div&gt;
);</code></pre>
<p>위처럼 mix and matching은 오로지 합성을 통해서만 상속과 합성 관계를 모두 표현할 수 있기에 컴포넌트들을 서로를 분리 (decouple) 되는것에 도움을 준다.</p>
<ul>
<li><code>Button</code>은 구체적인 속성을 갖는 DOM <code>&lt;button&gt;</code>이다.</li>
<li><code>DangerButton</code>은 구체적인 속성을 갖는 <code>Button</code>이다.</li>
<li><code>DeleteAccount</code>은 <code>&lt;div&gt;</code>안에 <code>Button</code>과 <code>DangerButton</code>을 포함한다.</li>
</ul>
<h2 id="components-encapsulate-element-trees">Components Encapsulate Element Trees</h2>
<p>리액트가 함수 혹은 클래스 <code>type</code>의 element를 마주치면, 해당 component에 주어진 해당 props에 맞게 어떤 element가 렌더링 되는지 묻는다. 
(When React sees an element with a function or class type, it knows to ask that component what element it renders to, given the corresponding props.)</p>
<p>다음과 같은 element를 리액트가 마주하면</p>
<pre><code class="language-javascript">{
  type: Button,
  props: {
    color: &#39;blue&#39;,
    children: &#39;OK!&#39;
  }
}</code></pre>
<p>리액트는 <code>Button</code> (as Component element)에게 무엇을 렌더링하는지 묻는다. <code>Button</code>은 다음 element를 반환한다.</p>
<pre><code class="language-javascript">{
  type: &#39;button&#39;,
  props: {
    className: &#39;button button-blue&#39;,
    children: {
      type: &#39;b&#39;,
      props: {
        children: &#39;OK!&#39;
      }
    }
  }
}</code></pre>
<p>리액트는 페이지의 모든 컴포넌트와 일치하는 DOM tag elements를 알아낼때까지 위의 일련의 과정을 계속 반복한다. </p>
<p>리액트는 마치 &quot;X는 Y이다.&quot;에 대해 온 세계의 모든 것을 다 알 때까지 계속 &quot;Y는 어떤 것&quot;인지 물어보는 어린 아이와 같다. </p>
<pre><code class="language-javascript">class Form extends TraditionalObjectOrientedView {
  render() {
    // Read some data passed to the view
    const { isSubmitted, buttonText } = this.attrs;

    if (!isSubmitted &amp;&amp; !this.button) {
      // Form is not yet submitted. Create the button!
      this.button = new Button({
        children: buttonText,
        color: &#39;blue&#39;
      });
      this.el.appendChild(this.button.el);
    }

    if (this.button) {
      // The button is visible. Update its text!
      this.button.attrs.children = buttonText;
      this.button.render();
    }

    if (isSubmitted &amp;&amp; this.button) {
      // Form was submitted. Destroy the button!
      this.el.removeChild(this.button.el);
      this.button.destroy();
    }

    if (isSubmitted &amp;&amp; !this.message) {
      // Form was submitted. Show the success message!
      this.message = new Message({ text: &#39;Success!&#39; });
      this.el.appendChild(this.message.el);
    }
  }
}</code></pre>
<p>위 class는 리액트에서는 다음과 같이 작성될 수 있다.</p>
<pre><code class="language-javascript">const Form = ({ isSubmitted, buttonText }) =&gt; {
  if (isSubmitted) {
    // Form submitted! Return a message element.
    return {
      type: Message,
      props: {
        text: &#39;Success!&#39;
      }
    };
  }

  // Form is still visible! Return a button element.
  return {
    type: Button,
    props: {
      children: buttonText,
      color: &#39;blue&#39;
    }
  };
};</code></pre>
<p>모든 elements 가 가진 DOM elements 를 알게 되기 떄문에 React는 해당 DOM elements 들을 적절한 때에 create, update, destroy한다. 따라서 Form UI modeling을 위와 같이 간단하게 구현할 수 있게 되는 것이다.</p>
<p>위 예제 코드처럼 props는 그저 컴포넌트의 input이고 컴포넌트는 element tree를 리턴한다.</p>
<p><strong>리턴된 element tree는 DOM nodes의 정보를 갖는 (describing DOM nodes) elements와 다른 컴포넌트의 정보를 갖는 (describing other components.) element를 모두 포함한다. 이는 개발자 (혹은 리액트 사용자)로 하여금 그들의 내부 DOM 구조에 의존하지 않는 독립적인 부분의 UI를 조합(compose)하게 해준다.</strong></p>
<p>우리는 (리액트 사용자는) 리액트가 instance들을 만들고, 업데이트하고 삭제하도록 위임 (let) 한다. 우리는 (리액트 사용자) 그것을 (instance) 컴포넌트로부터 반환된 element로써 설명(describe)한다. (아마 개발자는 instance에서 관심이 분리되고 그저 어떤 UI를 그릴지, 그것도 독립적으로, 리액트에 알려주기만 하면 되는데 그 방법은 컴포넌트 작성이고 리액트는 그 컴포넌트에서 리턴된 element로서 소통한다는 뜻인듯) 그 후 리액트는 instance들을 managing 하는 것을 담당한다. </p>
<h2 id="components-can-be-classes-or-functions">Components Can Be Classes or Functions</h2>
<p>위에서 살펴본 <code>Form</code>, <code>Message</code> 그리고 <code>Button</code> 코드들은 모두 리액트 컴포넌트들이다. 그들은 위 예제처럼 함수로 또는 <code>React.Component</code>의 상속자로서 class로 작성될 수 있다. 리액트 컴포넌트가 선언 (작성) 될 수 있는 방법은 다음 세 방법과 같다. </p>
<pre><code class="language-javascript">// 1) props의 함수로서
const Button = ({ children, color }) =&gt; ({
  type: &#39;button&#39;,
  props: {
    className: &#39;button button-&#39; + color,
    children: {
      type: &#39;b&#39;,
      props: {
        children: children
      }
    }
  }
});

// 2) React.createClass() factory를 사용해서
const Button = React.createClass({
  render() {
    const { children, color } = this.props;
    return {
      type: &#39;button&#39;,
      props: {
        className: &#39;button button-&#39; + color,
        children: {
          type: &#39;b&#39;,
          props: {
            children: children
          }
        }
      }
    };
  }
});

// 3) descending React.Component를 상속받은 ES6 class로서
class Button extends React.Component {
  render() {
    const { children, color } = this.props;
    return {
      type: &#39;button&#39;,
      props: {
        className: &#39;button button-&#39; + color,
        children: {
          type: &#39;b&#39;,
          props: {
            children: children
          }
        }
      }
    };
  }
}</code></pre>
<p>클래스형 컴포넌트는 함수형 컴포넌트보다 조금 더 powerful하다. 클래스형 컴포넌트는 해당 DOM node가 만들어지거나 지워질 때 일부 로컬 상태 (state)를 저장하고 custom 로직을 수행할 수 있다. </p>
<p>함수형 컴포넌트는 클래스형 컴포넌트 덜 powerful하나 더 simple하고 하나의 <code>render()</code> method를 가지고 있는 클래스형 컴포넌트와 동일하게 작동한다. 리액트 팀은 class에서만 사용가능한 기능이 필요하지 않는한 함수형 컴포넌트 사용을 권장한다. </p>
<h2 id="top-down-reconciliation">Top-Down Reconciliation</h2>
<pre><code class="language-javascript">ReactDOM.render({
  type: Form,
  props: {
    isSubmitted: false,
    buttonText: &#39;OK!&#39;
  }
}, document.getElementById(&#39;root&#39;));</code></pre>
<p>만약 위 코드를 실행하면 어떤 일이 일어날까?</p>
<p>리액트는 <code>Form</code> 컴포넌트에 주어진 <code>props</code>에 대해 어떤 element tree를 반환할지 물어볼 것이다. 
(React will ask the Form component what element tree it returns, given those props.)
리액트는 작성된 컴포넌트들을 이해하는 과정을 더 간단한 원어들로(primitive as original language 서서히 개선, 개량(refine)할 것이다. </p>
<pre><code class="language-javascript">// 개발자가 React에 주어진 props와 함께 Form 컴포넌트를 그려달라고 함
{
  type: Form,
  props: {
    isSubmitted: false,
    buttonText: &#39;OK!&#39;
  }
}

// Form 컴포넌트가 리액트에 return한 값
{
  type: Button,
  props: {
    children: &#39;OK!&#39;,
    color: &#39;blue&#39;
  }
}

// Button 컴포넌트가 return한 값. 하위에 더 이상의 children이 없는것으로 사료되어 React는 더 물어볼 것이 없음
{
  type: &#39;button&#39;,
  props: {
    className: &#39;button button-blue&#39;,
    children: {
      type: &#39;b&#39;,
      props: {
        children: &#39;OK!&#39;
      }
    }
  }
}</code></pre>
<p>위의 일련의 과정을 리액트에서는 <code>reconciliation</code> 이라고 불리는데 이 과정은 우리가 <code>ReactDOM.render()</code> 혹은 <code>setState()</code>을 호출할 때 시작된다. reconciliation이 끝나면 리액트는 최종 DOM tree가 어떻게 구성되어있는지 알게 되고 react-dom 혹은 react-native 같은 renderer가 DOM nodes를 업데이트하기 위해 필요한 최소한의 변화들을 적용한다.  </p>
<p>이런 점진적 (gradual) 정제과정은 React 어플리케이션이 최적화하기 쉬운 이유중 하나이다. 만약 컴포넌트 트리가 리액트가 능률적으로 방문 (visit. 아마 위 과정을 모두 훑어보는 것을 의미하는듯)하기에 너무 커진다면, <a href="https://reactjs.org/docs/optimizing-performance.html">props의 변화가 없다면 이 정제과정 (refining process)과 tree의 특정 부분을 비교 (diffing)하는 것을 건너뛰라고 말할 수 있기 때문이다.</a> 
만약 props들이 immutable, 불변하다면 props의 변화유무에 대해 계산하는 것은 굉장히 빠를 것이고 그렇기에 리액트와 불변성은 함께 시너지를 발휘하고 최소한의 노력(effort)으로 큰 최적화(optimization)를 제공할 수 있다. </p>
<p>이 글을 지금까지 보면서 알 수 있듯이, 컴포넌트와 element에 대해서는 많은 설명이 있지만 instance는 그렇지 않다. 그 이유는 다른 대부분의 object-oriented UI 프레임워크에 비해 리액트에서 instance는 그 중요도가 크지 않다. </p>
<p>클래스형 컴포넌트만 instance를 가지고 있고 우리는 절대 직접적으로 instance를 생성하지 않는다: 대신 리액트가 생성하는 일을 해준다. (maybe not only create, but update and destroy). <a href="https://reactjs.org/docs/refs-and-the-dom.html">비록 부모 컴포넌트 instance가 자식 컴포넌트 instance에 접근할 수 있는 mechanism</a>(ref를 말하는듯)이 존재하지만, 그 mechanism은 오직 꼭 필요한 행위(action)를 위해서만 사용되어야하고 일반적으로는 사용을 피해야한다. (ex: fields에 focus on을 하는 등)</p>
<p>리액트는 모든 클래스 컴포넌트에 대한 인스턴스를 만드는 것을 대신 해주기에 우리는 컴포넌트들 methods와 로컬 state와 함께 object-oriented 방식으로 작성할수 있지만 그것 외에도 instance는 리액트 프로그래밍 모델에서 그렇게 중요하지 않고 React에 의해 알아서 manage 된다.</p>
<hr>
<h1 id="정리">정리</h1>
<p>element는 우리가 화면에 나타내고 싶은 것을 DOM nodes나 다른 컴포넌트로서 설명을 하는 plain object이다. element는 다른 element를 자신들의 props로 가지고 있을 수 있다. React element를 생성하는 것은 저렴하다. 한번 element가 만들어지면 절대 불변이다 (never mutated).</p>
<p>컴포넌트는 여러 다른 방법으로 선언이 가능하다. 컴포넌트는 <code>render()</code> 메소드를 내포하는 클래스일 수 있다. 대안으로 더 간단한 방법은 함수로 정의되는 것이다. 두 경우 모두 props를 input으로 받고 element tree를 output으로서 반환한다.</p>
<p>만약 컴포넌트가 props들을 input으로 받는다면 (receives), 이는 특정 부모 컴포넌트가 해당 타입과 props와 함께 element를 리턴했기 때문이다. 그렇기에 React에서 props는 부모에서 자식으로 한방향으로 flow한다는 이유이다. </p>
<p>instance는 우리가 작성하는 컴포넌트 class안의 this로 대변되는 것이다. instance는 로컬 state를 보관하고 라이프사이클 이벤트들에 반응하기에 유용하다. </p>
<p>함수형 컴포넌트는 instances가 아예 없다. 클래스형 컴포넌트는 instances를 갖지만 리액트가 알아서 해주기에 우리는 직접 컴포넌트 instance를 만들 필요가 없다. </p>
<p>최종적으로 elements를 만들기 위해서는 <a href="https://reactjs.org/docs/react-api.html">React.createElement()</a>, <a href="https://reactjs.org/docs/react-api.html#createelement">JSX</a> 혹은 <a href="https://reactjs.org/docs/react-api.html#createfactory">element factory helper</a>를 사용한다. 
실제 코딩에 element를 plain objects로 작성하는 것을 권장하지 안흔ㄴ다. 그저 내부적으로 elements는 plain objects라는 것만 알아두자.</p>
<h2 id="정리-in-my-words">정리 in my words</h2>
<p>결국 React element는 기존 OOP UI model의 문제점을 개선하기 위함이라고 볼 수 있을 것 같다. 
컴포넌트가 많아질수록 instance도 많아지고 이는 각 instance에 대한 로직 (instance 조작)이 많아진다는 결론을 유추 가능하다. 이렇게 되면 하나의 컴포넌트가 수행해야할 일들이 많아질 수 있다는 뜻인데 결론적으로 부모와 자식의 분리가 어렵다는 뜻으로 볼 수 있다. 더 나아가 왜 hooks와 함수형 컴포넌트를 리액트 팀에서 권장하는지에 대한 힌트로도 볼 수 있다. 결국 부모와 자식의 분리뿐 아니라 로직과 ui의 분리도 어렵다고 볼 수 있지 않을까?</p>
<p>따라서 리액트에서는 element라는 개념을 활용했다. element는 그저 화면에 그려질 것들을 props와 type으로서 DOM node를 설명하는 것이다. 즉 다시말해 element는 그저 DOM node의 정보 객체라고 볼 수 있다. 또한 element는 다른 elements를 props로 가지고 있을 수 있는데 그렇기 떄문에 tree 구조가 될 수 있다. 이는 바꿔말해 우리가 컴포넌트를 작성하면 React가 실제 DOM tree와 같은 위계질서를 갖는 구조로 파악할 수 있다는 뜻이다. 또한 element의 타입은 element이거나 컴포넌트 일 수 있는데 이는 기존의 DOM node와 React component를 mix하고 nest하는 구조로 만들 수 있다는 것이다. </p>
<p>또한 reconciliation을 통해 react는 모든 dom tree를 완벽하게 알게되고, 리액트는 렌더링과 제거되는 부분을 적절하게 알고 따로 진행한다. 그리고 우리 작성한 elements에는 DOM tree에 전달할 정보만 담고 있으면 된다. 실제 Dom의 구조를 활용하는게 아니라 elements를 활용해서 나머지 로직들은 다른곳에서 제어하고, 필요한 정보만 독립적으로 UI로 관리 할 수 있도록 하여 기존의 UI모델링을 분리해서 간단하게 구현 할 수있게 된다.</p>
<p>결론의 결론은 element는 DOM tree에게 전달할 정보를 가지고 있는 순수 객체라고 보면 된다. </p>
<ol>
<li>element는 화면에 나타낼 DOM tree에 대한 정보를 가지고 있는 순수 객체</li>
<li>component는 props를 input으로 받아 DOM Node를 출력하는, 리액트로 만들어진 앱을 이루는 최소한의 단위</li>
<li>instance 클래스로 선언된 Component에서만 갖는 것.</li>
</ol>
<p><a href="https://velog.io/@_jouz_ryul/DOM-Node%EC%99%80-Element">DOM Node와 element 더 알아보기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 Reconciliation]]></title>
            <link>https://velog.io/@_jouz_ryul/%EB%A6%AC%EC%95%A1%ED%8A%B8-Reconciliation</link>
            <guid>https://velog.io/@_jouz_ryul/%EB%A6%AC%EC%95%A1%ED%8A%B8-Reconciliation</guid>
            <pubDate>Sat, 25 Jun 2022 13:35:40 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><code>render()</code>함수는 브라우저에서 UI를 render 하려할 때 마다 불리우는 함수이다. 최상위 render 함수는 React element들의 트리를 재귀적으로 리턴하는 함수라고 볼 수 있다. 그 후 다음 렌더 cycle에서 해당 컴포넌트의 트리는 다시 생성된다(regenerated). 리액트는 위 두개의 트리를 diff (변경점을 찾는것)해야 하고 실제 브라우저 DOM에 해당 diff를 적용해야한다. 리액트가 어느 부분의 UI가 변경되어야 하는지 결정하기 위해 하나의 트리와 다른 트리의diff에 사용하는 알고리즘을 <code>reconciliation</code>이라고 한다. 📎<a href="https://dev.to/burhanuday/react-internals-part-1-the-basics-concepts-and-the-prerequisites-31ah">React Internals (Part 1) - The Basic Concepts and the Prerequisites</a></p>
</blockquote>
<hr>
<h1 id="1-reconciliation">1. <a href="https://reactjs.org/docs/reconciliation.html">Reconciliation</a></h1>
<p>리액트는 매 업데이트마다 개발자가 정확히 무엇이 변경되는지 걱정할 필요없게 선언적 API를 제공한다. 이로 인해 어플리케이션 개발 (writing applications)은 엄청 쉬워졌지만 이것이 어떻게 React에 적용되었는지 (implemented, 주입되었는지) 명확하지 않다. 이 후의 글들은 high-performance app에서도 충분히 빠를 수 있게 컴포넌트 업데이트가 예측가능할 수 있도록 React의 <code>diffing 알고리즘</code>에 어떠한 결정을 내렸는지 설명할 것이다. </p>
<hr>
<h1 id="2-motivation-of-reconciliation">2. Motivation of reconciliation</h1>
<p>우리가 React를 사용할 때, render() 함수는 React 요소의 트리를 생성하는 것으로 생각이 드는 순간이 있을 것이다. state나 props가 갱신되면 render() 함수는 새로운 React 엘리먼트 트리를 return 한다. 그 후 React는 가장 최신의 트리 (the most recent tree)와 일치하는 UI로 업데이트 하기 위해 효과적으로 (efficiently) 할 수 있는 방법을 찾아내야한다. </p>
<p>하나의 트리를 다른 트리로 변환하기 위해 최소한의 연산을 하는 알고리즘 문제를 풀기 위해 일반적인 해결책들이 있다. 그러나 이러한 <a href="https://grfia.dlsi.ua.es/ml/algorithms/references/editsurvey_bille.pdf">최첨단의 알고리즘</a>도 n개의 엘리먼트가 있는 트리에 대해 O(n3)의 복잡도를 가진다.</p>
<p>React에 이 알고리즘을 적용한다면, 1000개의 엘리먼트를 그리기 위해 10억 번의 비교 연산을 수행해야 한다. 너무나도 비싼 연산이기에 React는 대신, 두 가지 가정을 기반하여 O(n) 복잡도의 휴리스틱 알고리즘을 구현했습니다.</p>
<p>첫번째로, 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어낸다.
두번째로, 개발자가 key prop을 통해, 여러 렌더링 사이에서 어떤 자식 엘리먼트가 변경되지 않아야 할지 표시해 줄 수 있다.</p>
<p>실제로 거의 모든 사용 사례에서 이 가정들은 들어맞았다. </p>
<hr>
<h1 id="3-the-diffing-algorithm-비교-알고리즘">3. The Diffing Algorithm: 비교 알고리즘</h1>
<p>두 개의 트리를 비교(diffing) 할 때, React는 먼저 두 엘리먼트의 루트(root) 엘리먼트부터 비교한다. 이후의 동작은 루트 엘리먼트의 타입에 따라 달라진다.</p>
<h2 id="31-dom-엘리먼트의-타입이-다른-경우">3.1. DOM 엘리먼트의 타입이 다른 경우</h2>
<p>두 루트 엘리먼트의 타입이 다른 모든 경우에는, React는 이전 트리를 버리고 처음부터 완전히 새로운 트리를 만든다. <code>&lt;a&gt;</code>에서 <code>&lt;img&gt;</code>로, <code>&lt;Article&gt;</code>에서 <code>&lt;Comment&gt;</code>로, 혹은 <code>&lt;Button&gt;</code>에서 <code>&lt;div&gt;</code>로 바뀌는 것 모두 트리 전체를 재구축하는 경우다.</p>
<p>트리를 버릴 때 이전 DOM 노드들은 모두 파괴되고 컴포넌트 인스턴스는 componentWillUnmount()가 실행된다. 새로운 트리가 만들어질 때, 새로운 DOM 노드들이 DOM에 삽입된다. 그에 따라 컴포넌트 인스턴스는 UNSAFE_componentWillMount()가 실행되고 componentDidMount()가 이어서 실행된다. 이전 트리와 연관된 모든 state는 사라진다.</p>
<p>루트 엘리먼트 아래의 모든 컴포넌트도 당연 모두 언마운트되고 그 state도 사라집니다. 예를 들어, 아래와 같은 비교가 일어나면,</p>
<pre><code class="language-jsx">&lt;div&gt;
  &lt;Counter /&gt;
&lt;/div&gt;

// when obove updated into below

&lt;span&gt;
  &lt;Counter /&gt;
&lt;/span&gt;

// then the explanation above the code block will be executed or getting into process</code></pre>
<p>이전 <code>Counter</code>는 사라지고, 새로 다시 마운트가 된다.</p>
<h2 id="32-dom-엘리먼트의-타입이-같은-경우">3.2. DOM 엘리먼트의 타입이 같은 경우</h2>
<p>같은 타입의 두 React DOM 엘리먼트를 비교할 때, React는 두 엘리먼트의 속성을 확인하여, 동일한 내역은 유지하고 변경된 속성들만 갱신한다. 예를 들어,</p>
<pre><code class="language-jsx">&lt;div className=&quot;before&quot; title=&quot;stuff&quot; /&gt;

&lt;div className=&quot;after&quot; title=&quot;stuff&quot; /&gt;</code></pre>
<p>위 두 엘리먼트를 비교할 때, React는 현재 DOM 노드 상에 className만 수정한다.
style이 갱신될 때, React는 또한 변경된 속성만을 갱신한다. 예를 들면,</p>
<pre><code class="language-jsx">&lt;div style={{color: &#39;red&#39;, fontWeight: &#39;bold&#39;}} /&gt;

&lt;div style={{color: &#39;green&#39;, fontWeight: &#39;bold&#39;}} /&gt;</code></pre>
<p>위 두 엘리먼트 사이에서 변경될 때, React는 fontWeight는 수정하지 않고 color 속성 만을 수정한다.
DOM 노드의 처리가 끝나면, React는 이어서 해당 노드의 children을 재귀적으로 처리한다.</p>
<h2 id="33-컴포넌트-엘리먼트의-타입이-같은-경우">3.3. 컴포넌트 엘리먼트의 타입이 같은 경우</h2>
<p>컴포넌트가 업데이트될 때, 인스턴스는 동일하게 유지되어 렌더링 간 state가 유지된다. React는 새로운 엘리먼트의 내용을 반영하기 위해 현재 컴포넌트 인스턴스의 props를 업데이트 하고 이때 해당 인스턴스의 UNSAFE_componentWillReceiveProps(), UNSAFE_componentWillUpdate(), componentDidUpdate를 호출합니다.
그 후, render() 메서드가 호출되고 비교 알고리즘이 이전 결과와 새로운 결과를 재귀적으로 처리합니다.</p>
<h2 id="34-children에-대한-재귀적-처리">3.4. children에 대한 재귀적 처리</h2>
<p>DOM 노드의 children에 대해 재귀적 처리를 할 때, 기본적으로 React는 list of children을 동시에 순회하고 차이점이 있으면 변경을 생성할 것이다.
예를 들어, children의 끝에 엘리먼트를 추가하면, 두 트리 사이의 변경은 잘 작동할 것이다.</p>
<pre><code class="language-jsx">&lt;ul&gt;
  &lt;li&gt;first&lt;/li&gt;
  &lt;li&gt;second&lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
  &lt;li&gt;first&lt;/li&gt;
  &lt;li&gt;second&lt;/li&gt;
  &lt;li&gt;third&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<p>React는 두 트리에서 <code>&lt;li&gt;first&lt;/li&gt;</code>가 일치하는 것을 확인하고, <code>&lt;li&gt;second&lt;/li&gt;</code>가 일치하는 것을 확인합니다. 그리고 마지막으로 <code>&lt;li&gt;third&lt;/li&gt;</code>를 트리에 추가한다.</p>
<p>하지만 위와 같이 단순하게 구현하면, 리스트의 맨 앞에 엘리먼트를 추가하는 경우 성능이 좋지 않을 것이다. 예를 들어, 아래의 두 트리 변환 예제는 형편없이 (poorly) 작동한다.</p>
<pre><code class="language-jsx">&lt;ul&gt;
  &lt;li&gt;Duke&lt;/li&gt;
  &lt;li&gt;Villanova&lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
  &lt;li&gt;Connecticut&lt;/li&gt;
  &lt;li&gt;Duke&lt;/li&gt;
  &lt;li&gt;Villanova&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<p>React는 <code>&lt;li&gt;Duke&lt;/li&gt;</code>와 <code>&lt;li&gt;Villanova&lt;/li&gt;</code> 종속 트리를 그대로 유지하는 대신 모든 자식을 변경할 것이다. 이러한 비효율은 문제가 될 수 있다.</p>
<h2 id="35-key">3.5. key</h2>
<p>이러한 위의 문제를 해결하기 위해, React는 key 속성을 지원한다. 자식들이 key를 가지고 있다면, React는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인할 것이다. 예를 들어, 위 비효율적인 예시에 key를 추가하여 트리의 변환 작업이 효율적으로 수행되도록 수정할 수 있다.</p>
<pre><code class="language-jsx">&lt;ul&gt;
  &lt;li key=&quot;2015&quot;&gt;Duke&lt;/li&gt;
  &lt;li key=&quot;2016&quot;&gt;Villanova&lt;/li&gt;
&lt;/ul&gt;

&lt;ul&gt;
  &lt;li key=&quot;2014&quot;&gt;Connecticut&lt;/li&gt;
  &lt;li key=&quot;2015&quot;&gt;Duke&lt;/li&gt;
  &lt;li key=&quot;2016&quot;&gt;Villanova&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<p>이제 React는 &#39;2014&#39; key를 가진 엘리먼트가 새로 추가되었고, &#39;2015&#39;와 &#39;2016&#39; key를 가진 엘리먼트는 그저 이동만 하면 되는 것을 알게 된다.
실제로, key로 사용할 값을 정하는 것은 어렵지 않다. 그리려고 하는 엘리먼트는 일반적으로 식별자를 가지고 있을 것이고, 그대로 해당 데이터를 key로 사용하면 된다.</p>
<p>이러한 상황에 해당하지 않는다면, 여러분의 데이터 구조에 ID라는 속성을 추가해주거나 데이터 일부에 해시를 적용해서 key를 생성할 수 있다. 해당 key는 오로지 형제 사이에서만 유일하면 되고, 전역에서 유일할 필요는 없다.</p>
<p>최후의 수단으로 배열의 인덱스를 key로 사용할 수 있다. 항목들이 재배열되지 않는다면 이 방법도 잘 동작할 것이지만, 재배열되는 경우 비효율적으로 동작할 것이다.</p>
<p>인덱스를 key로 사용 중 배열이 재배열되면 컴포넌트의 state와 관련된 문제가 발생할 수 있는데, 컴포넌트 인스턴스는 key를 기반으로 갱신되고 재사용된다. 인덱스를 key로 사용하면, 항목의 순서가 바뀌었을 때 key 또한 바뀌게 되고 그 결과, 컴포넌트의 state가 엉망이 되거나 의도하지 않은 방식으로 바뀔 수도 있다.</p>
<hr>
<h1 id="4-고려-사항">4. 고려 사항</h1>
<p>reconciliation 알고리즘은 구현상의 세부사항일뿐이다. React는 항상 전체 앱을 재렌더링할 수도 있지만, 최종적으로 출력되는 결과는 항상 같을 것이다. 좀 더 정확히 말하자면, 여기서 말하는 재렌더링은 모든 컴포넌트의 render를 호출하는 것이지 React가 언마운트시키고 다시 마운트하는 것은 아니다. 즉, 앞서 설명했던 규칙에 따라 렌더링 전후에 변경된 부분만을 적용한다.</p>
<p>우리는 일반적인 사용 사례에서 더 빠르게 작동할 수 있도록 계속 휴리스틱 알고리즘을 개선하고 있다. 현재 적용된 방법은 한 종속 트리가 그 형제 사이에서 이동했다는 사실을 표현할 수는 있지만, 아예 다른 곳으로 이동했다는 사실은 표현할 수 없다. 알고리즘은 전체 종속 트리를 재렌더링할 것입니다.</p>
<p>React는 휴리스틱에 의존하고 있기 때문에, 휴리스틱이 기반하고 있는 가정에 부합하지 않는 경우 성능이 나빠질 수 있다.</p>
<p>알고리즘은 다른 컴포넌트 타입을 갖는 종속 트리들의 일치 여부를 확인하지 않는다. 매우 비슷한 결과물을 출력하는 두 컴포넌트를 교체하고 있다면, 그 둘을 같은 타입으로 만드는 것이 더 나을 수도 있다. React team은 실제 사용 사례에서 이 가정이 문제가 되는 경우를 발견하지 못했다.
key는 반드시 변하지 않고, 예상 가능하며, 유일해야 한다. 변하는 key(Math.random()으로 생성된 값 등)를 사용하면 많은 컴포넌트 인스턴스와 DOM 노드를 불필요하게 재생성하여 성능이 나빠지거나 자식 컴포넌트의 state가 유실될 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 Deep Dive] 타입변환과 단축 평가]]></title>
            <link>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%ED%83%80%EC%9E%85%EB%B3%80%ED%99%98%EA%B3%BC-%EB%8B%A8%EC%B6%95-%ED%8F%89%EA%B0%80</link>
            <guid>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%ED%83%80%EC%9E%85%EB%B3%80%ED%99%98%EA%B3%BC-%EB%8B%A8%EC%B6%95-%ED%8F%89%EA%B0%80</guid>
            <pubDate>Tue, 22 Mar 2022 23:52:20 GMT</pubDate>
            <description><![CDATA[<h1 id="9-타입변환과-단축평가">9. 타입변환과 단축평가</h1>
<p>타입변환은 코더의 의도에 따라 가시적으로 의도가 보이는 명시적 타입변환과 엔진에 의해 자동으로 변환되는 암묵적 타입변환이 있다. 단축평가는 값을 평가하여 코드 흐름을 제어할 떄 좀 더 간결하게 사용할 수 있는 연산문으로 대표되며 단축평가에서 예측가능한 코드를 위해 타입 변환이 어떻게 동작하는지 이해해보자. </p>
<hr>
<h2 id="91-타입변환이란">9.1 타입변환이란?</h2>
<p>자바스크립의 모든 값은 타입이 있고 이 타입은 개발자의 의도에 따라 다른 타입으로 변환할 수 있다. 
이를 <strong>명시적 타입 변환 / explicit coercion, 또는 타입 캐스팅 type casting이라고 한다.</strong></p>
<pre><code class="language-javascript">var x = 10;

//명시적 타입 변환
var str = x.toString(x);
console.log(typeof str, str); // &#39;string&#39;, &#39;10&#39;

console.log(x); // 10
// 그렇다고 기존 원시값과 타입이 변하지는 않는다.</code></pre>
<p>반대로 자바스크립트가 표현식을 평가하는 도중에 엔진에 의해 개발자의 의도와 상관없이 암묵적으로 타입이 자동 변환되기도 하는데 이를 <strong>암묵적 타입 변환 / implicit coercion 또는 타입 강제 전환 / type coercion</strong> 이라고 한다.</p>
<pre><code class="language-javascript">var x = 10;

var str = x + &#39;&#39;;

console.log(typeof str, str); // &#39;string&#39;, &#39;10&#39;

console.log(x); // 10
// 그렇다고 기존 원시값과 타입이 변하지는 않는다.</code></pre>
<p>위 두 예제에서 봤듯이 명시적 타입 변환이든 암묵적 타입 변환이 일어나든 기존 원시 값을 직접 변경하는 것은 아니며 이미 정리했든 원시 값은 변경 불가능한 값, immutable value이다. 
즉 기존 워시 값을 사용해 다른 타입의 새로운 원시 값을 사용하여 (생성하여) 평가에만 사용할 뿐 기존 변수에 재할당되지 않는다. 
단지 엔진이 표현식을 에러 없이 평가하기 위해 타입 변환을 통해 새로운 값을 만들어 단 한 번 사용한 후 버린다. </p>
<p>명시적 타입 변환은 개발자의 의지와 의도가 코드에 명백히 드러나는 반면 암묵적 타입 강제 변환은 암묵적으로 자동 변환되기 떄문에 코드 흐름에 따라 그 의도와 의미 (값의 타입) 예측과 추적이 예측하기 힘들어질 수 있다. 이는 곧 오류 발생 확률을 높히기도 한다. </p>
<h2 id="92-암묵적-타입-변환">9.2. 암묵적 타입 변환</h2>
<p>자바스크립트 엔진은 표현식을 평가할 때 코더의 의도와 상관없이 코드의 문맥을 고려해 암묵적으로 타입을 강제 변환할 때가 있다. </p>
<pre><code class="language-javascript">// 피연산자가 모두 문자열 타입이어야 하는 문맥
&#39;10&#39; + 2 // &#39;102&#39;

// 피연산자가 모두 숫자타입이어야 하는 문맥
5 * &#39;10&#39; // 50

// 피연산자 또는 표현식이 불리언 타입이어야 하는 문맥

!0 // true

if (1) {
// if문의 코드 블럭이 실행된다.
}</code></pre>
<p>위 예제처럼 표현식을 평가할 때 문맥에 부합하지 않는 상황이 발생하면 자바스크립트는 가급적 에러를 발생시키지 않도록 암묵적 타입 변환을 통해 표현식을 평가한다. 
암묵적 타입 변환이 발생하면 <code>원시 타입</code> 중 하나로 타입을 자동 변환한다. </p>
<h3 id="921-문자열-타입으로-변환">9.2.1. 문자열 타입으로 변환</h3>
<pre><code class="language-javascript">1 + &#39;2&#39; //  &#39;12&#39;</code></pre>
<p>전에 정리했듯이 피연산자중 하나 이상이 문자열이면 <code>+연산자</code>는 문자열 연결 연산자로 동작한다. 
문자열 연결 연산자의 역할은 문자열 값을 만드는 것이므로 모든 피연산자는 코드의 문맥에서 모두 문자열 타입이어야 한다. 
따라서 자바스크립트 엔진은 문자열 연결 연산자 표현식을 평가하기 위해 피연산자 중에서 문자열 타입이 아닌 피연산자를 문자열 타입으로 강제 변환한다. </p>
<p>이뿐만 아니라 <code>템플릿 리터럴</code>은 표현식의 평가 결과를 문자열 타입으로 암묵적으로 변환하는데 이처럼 피연산자 뿐만 아니라 표현식 또한 코드 문맥에 부합이 필요하다면 자바스크립트 엔진은 암묵적 타입 변환을 실행한다. </p>
<pre><code class="language-javascript">`1 + 1 = ${1 + 1}` // &quot;1 + 1 = 2&quot;</code></pre>
<p>문자열 타입이 아닌 값을 문자열 타입으로 강제 변환되는 예는 다음과 같다. </p>
<pre><code class="language-javascript">// 숫자타입
0 + &#39;&#39; // &quot;0&quot;
-0 + &#39;&#39; // &quot;0&quot;
1 + &#39;&#39; // &quot;1&quot;
-1 + &#39;&#39; // &quot;-1&quot;
NaN + &#39;&#39; // &quot;NaN&quot;
Infinity + &#39;&#39; // &quot;Infinity&quot;
-Infinity + &#39;&#39; // &quot;-Infinity&quot;


//boolean type
true + &#39;&#39; //  &#39;true&#39;
false + &#39;&#39; //  &#39;false&#39;

// null type
null + &#39;&#39; // &#39;null&#39;

// undefined type
undefined + &#39;&#39; // &#39;undefined&#39;

// Symbol type
(Symbol()) + &#39;&#39; // TypeError: Cannot convert a Symbol value to a string

// Object type
({}) + &#39;&#39; // &#39;[object Object]&#39;
Math + &#39;&#39; // &#39;[object Math]&#39;
[] + &#39;&#39; // &#39;&#39;
[10, 20] + &#39;&#39; // &quot;10,20&quot;
(function(){}) + &#39;&#39; //  &quot;function(){}&quot;
Array + &#39;&#39; // &quot;function Array() { [native code] }&quot;</code></pre>
<h3 id="922-숫자-타입으로-변환">9.2.2. 숫자 타입으로 변환</h3>
<p>연산식에서 <code>문자열 연결 연산자</code>을 제외한 모든 연산자는 <code>산술 연산자</code>이며 그 역할은 숫자 값을 만드는 것이다. 즉, 모든 피연산자는 코드 문맥상 모두 숫자 타입이어야 한다. 
따라서 산술 연산자 표현식을 평가하기 위해 산술 연산자의 피연산자 중에서 숫자 타입이 아닌 경우 숫자 타입으로 암묵적 타입 변환한다. 이때 숫자 타입으로 변환되지 않는 값은 <code>NaN</code>이 된다.</p>
<p>또한 숫자 타입 변환이 일어나는 문맥은 산술 연산자뿐만 아니라 <code>비교 연산자</code>에서도 일어난다. 
비교 연산자에서도 숫자 타입으로 암묵적 타입 변환이 일어나는 이유는 크기를 비교해야하기 떄문이다. </p>
<p>앞서 연산자 부분에서 <code>+ 단항 연산자</code>는 피연산자가 숫자 타입의 값이 아닐 경우 숫자 타입으로 강제 변환한다고 했다. 
<code>+ 단항 연산자</code>를 통해 다른 타입들이 숫자타입으로 어떻게 변환되는지 알아보자. </p>
<pre><code class="language-javascript">+&#39;&#39; //  0
+&#39;0&#39; // 0
+&#39;1&#39; // 1
+&#39;string&#39; // NaN

+true // 1 
+false // 0

+null // 0

+undefined // NaN

+Symbol() // TypeError: cannot convert a Symbol value to a number

+{} // NaN
+[] // 0
+[10,20] // NaN
+(function(){}) // NaN</code></pre>
<p>runjs로 이것저것 하다가 재밌는것을 발견했다.
object 타입 피연산자에 숫자 피연산자를 + 연산자로 연산하는 표현식을 실행해보면 신기한 결과가 나온다.
object 타입의 문자열로의 타입 강제전환 후 string + number인 경우처럼 + 연산자가 문자열 연결 연산자로 작동한 결과처럼 보였다. 
뇌피셜이긴 하지만 객체타입과 숫자타입의 피연산자를 + 연산자로 연산할 경우 객체타입은 문자열로 강제타입 변환 후 연산이 되는 것 같다. </p>
<pre><code class="language-javascript">// 분명 문자열 연결 연산자가 아닐것 이라고 생각했는데 
// 마치 &quot;&quot; + 1 처럼 작용됐다. 
[]+1 // &quot;1&quot;

// 분명 문자열 연결 연산자가 아닐것 이라고 생각했는데 
// 마치 ({} + &#39;&#39;) + 1 처럼 작용됐다. 
{} + 1 // &#39;[object Object]1&#39;
</code></pre>
<p>반대로 - 연산자의 경우 숫자타입 변환 예제처럼 작동한다. </p>
<pre><code class="language-javacript">console.log([] - 1) // -1
console.log({} - 1) // NaN
</code></pre>
<h3 id="923-불리언-타입으로-변환">9.2.3. 불리언 타입으로 변환</h3>
<p>불리언 타입으로 변환은 if 문이나 for문과 같은 제어문 또는 삼항 조건 연산자의 조선식을 활용할 때 사용된다. </p>
<pre><code class="language-javascript">if (true) console.log(&#39;1&#39;)
if (&#39;&#39;) console.log(&#39;2&#39;)
if (0) console.log(&#39;3&#39;)
if (&#39;str&#39;) console.log(&#39;4&#39;)
if (null) console.log(&#39;5&#39;)

// 1, 4
</code></pre>
<p>이때 자바스크립트 엔진은 불리언 타입이 아닌 값을 <strong>Truthy 값 또는 Falsy 값으로 구분</strong>한다. 
즉 불리언 값으로 평가되어야 할 문맥 (ex: 제어문의 조건식)에서 Truthy 값은 <code>true</code>로 Falsy 값은 <code>false</code>로 불리언 타입으로 암묵적 타입 변환한다. </p>
<ul>
<li>Falsy값들: <code>false</code>, <code>undefined</code>, <code>null</code>, <code>0</code>, <code>-0</code>, <code>NaN</code>, <code>&quot;&quot;</code></li>
</ul>
<p>Falsy 값들을 제외한 모든 값은 모두 true로 평가되는 Truthy 값이다.</p>
<pre><code class="language-javascript">//Truthy 값들
function isFalsy(value) {
  return !value
}

function isTruthy(value) {
  return !!value
}

isFalsy(false);
isFalsy(undefined);
isFalsy(null);
isFalsy(0);
isFalsy(-0);
isFalsy(NaN);
isFalsy(&#39;&#39;);
// all return false

isTruthy(true);
isTruthy(&#39;0&#39;);
isTruthy({});
isTruthy([]);
isTruthy(Infinity);
// all return true
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 Deep Dive] 연산자]]></title>
            <link>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Thu, 17 Mar 2022 06:29:31 GMT</pubDate>
            <description><![CDATA[<h1 id="7-연산자">7. 연산자</h1>
<p>연산자는 하나 이상의 <strong>표현식</strong>을 대상으로 <strong>산술, 할당, 비교, 논리, 타입, 지수 연산</strong> 등을 수행하여 하나의 값을 만든다. 이때 연산의 대상은 <strong>피연산자</strong>이다. 피연산자는 당연히 값으로 평가될 수 있는 <strong>표현식</strong>이어야하고 연산자 표현식도 <strong>값으로 평가</strong>될 수 있는 표현식이다. 
즉, 연산자는 값으로 평가된 피연산자 또는 값으로 평가된 표현식을 연산해 새로운 값 또는 표현식을 만든다. </p>
<h2 id="71-산술-연산자">7.1. 산술 연산자</h2>
<p>Algebra or Arithmetic operator
피연산자를 대상으로 수학적 계산을 통해 새로운 <strong>숫자 값</strong>을 만든다. 피연산자간 산술 연산이 불가능한 경우 NaN을 반환한다. </p>
<hr>
<h3 id="711-이항-산술-연산자--binary">7.1.1. 이항 산술 연산자 / Binary</h3>
<p>2개의 피연산자를 산술 연산하여 숫자 값을 만드는 연산자로서 사용된 피연산자의 값을 변경하는 side effect가 없는 것이 특징이다. 즉 언제나 <strong>새로운 값</strong>을 만들어낸다. </p>
<hr>
<pre><code class="language-javascript">+ 
//덧셈
- 
// 뺄셈
*
// 곱셀
/ 
//나눗셈
% 
// 나머지
5%2 = 1
// 5를 2로 나눈후 (정수만) 남은 값</code></pre>
<h3 id="712-단항-산술-연산자--unary">7.1.2. 단항 산술 연산자 / Unary</h3>
<p>1개의 피연산자만을 대상으로 산술 연산하여 숫자 값을 만든다. </p>
<hr>
<p><img src="https://images.velog.io/images/_jouz_ryul/post/bf2624e2-f6ee-4bbc-bf74-be4a7a7088e6/%E1%84%83%E1%85%A1%E1%86%AB%E1%84%92%E1%85%A1%E1%86%AB%20%E1%84%89%E1%85%A1%E1%86%AB%E1%84%89%E1%85%AE%E1%86%AF%20%E1%84%8B%E1%85%A7%E1%86%AB%E1%84%89%E1%85%A1%E1%86%AB%E1%84%8C%E1%85%A1.001.jpeg" alt="단항 산술 연산자 비교표"></p>
<p>증가, 감소 연산자는 피연산자의 값을 변경하는 부수 효과가 있다. 
다음 예제로 살펴보자.</p>
<pre><code class="language-javascript">var x = 1;

x++;

console.log(x)
// 2

x--;
console.log(x)
// 1
</code></pre>
<p>또한 증가, 감소 연산자는 연산자의 위치에 따라 값이 달라질 수 있다. </p>
<pre><code class="language-javascript">var x= 5, result;

//선할당 후증가 (postfix increment operator)
result = x++;

console.log( x, result )
// 6, 5

//선증가 후할당 (prefix increment operator)
result = ++x;

console.log( x, result)
// 7, 7

//선할당 후감소 (postfix increment operator)
result = x--;

console.log( x, result )
// 6, 7

//선감소 후할당 (prefix increment operator)
result = --x;

console.log( x, result)
// 5, 5
</code></pre>
<p>+, - 단항 연산자는 그 어떠한 피연산자에 주는 부수효과가 없다. 
다음예제를 통해 정리해보자.</p>
<pre><code class="language-javascript">+10
// 10
+(-10)
// 10
-(-10)
// 10

-&#39;10&#39; // -10. 문자열은 연사자의 피연사자일 때 숫자로 치환되는데 

-&#39;x&#39; // NaN. 숫자로 치환할 수 없는 문자열일 경우 NaN</code></pre>
<p>숫자 타입이 아닌 피연산자에 + 단항 연산자를 사용하면 피연산자를 숫자 타입으로 변환하여 반환한다. 
다만 피연산자를 변경하는 것이 아니라 단지 연산에 사용될 피연사자의 값을 숫자 타입으로 변환하여 연산에 사용한다. </p>
<pre><code class="language-javascript">var x = &#39;1&#39;;

console.log(+x); //1 as number

//부수효과 없음
console.log(x); // &quot;1&quot; as string

x = true;

console.log( +x ); // 1 as number

console.log(+x+1); // 2 as number. true는 숫자와 연산시 숫자 1로 치환된다.

//부수효과 없음
console.log(x); // true

x = false;

console.log( +x ); // 0 as number

console.log(+x+1); // 1 as number. false는 숫자와 연산시 숫자 0으로 치환된다.

//부수효과 없음
console.log(x); // false

x = &#39;x&#39;;

console.log(+x); // NaN

//부수효과 없음
console.log(x); //&#39;x&#39;</code></pre>
<h2 id="713-문자열-연결-연산자">7.1.3. 문자열 연결 연산자</h2>
<ul>
<li>연산자는 피연산자 중 하나 이상이 문자열인 경우 <strong>문자열 연결 연산자로 동작</strong>한다. 그 외의 경우는 산술 연산자로 동작.</li>
</ul>
<hr>
<pre><code class="language-javascript">//피연산자 중 하나 이상이 문자열인 경우
&quot;1&quot;+2; // &#39;12&#39; as string

1 + &#39;2&#39;; // 12 as string

// 피연산자 중 하나 이상이 문자열인 경우 외의 경우

1 + 2; // 3

1 + true; // 2

1+ false; // 1

1 + null; // 1. null 또한 산술 연산자로 작동한 연산식에서는 0으로 치환된다. 

1 + undefined; // NaN

+undefined; // NaN</code></pre>
<p>불리언 타입, null 타입이 산술 연산자로 동작한 연산식에 있을 경우 자바스크립트 엔진은 타입과 값을 변경한다. 또한 string 타입이 피연산자 중 하나로서 연산자가 문자열 연결 연산자로 동작할 경우 string은 number 타입과 값으로 변경된다. 다만 string값이 number의 값으로서 치환될 수 없을 경우 NaN으로 치환된다.</p>
<p>위의 일련의 변경 과정을 <strong>암묵적 타입 변환 (implicit coercion) 또는 타입 강제 변환 (type coercion)</strong> 이라고 한다. to be continue in CH.9 타입 변환과 단축 평가</p>
<h2 id="72-할당-연산자--assignment-operator">7.2. 할당 연산자 / Assignment operator</h2>
<p>변수에 값을 할당하는 여러 연산자</p>
<hr>
<p><img src="https://images.velog.io/images/_jouz_ryul/post/088e1e38-1037-4bfc-b4ce-fbecf0d3d89e/%E1%84%92%E1%85%A1%E1%86%AF%E1%84%83%E1%85%A1%E1%86%BC%20%E1%84%8B%E1%85%A7%E1%86%AB%E1%84%89%E1%85%A1%E1%86%AB%E1%84%8C%E1%85%A1.001.jpeg" alt="할당 연산자 비교표"></p>
<pre><code class="language-javascript">var x;

x= 10;
// 10

x +=5 // x = x+5
// 15

var str = &quot;My name is&quot;;

str += &quot;Lee&quot;; // str = str + &quot;Lee&quot;
// My Name is Lee</code></pre>
<p>앞서 표현식은 값으로 평가될 수 있는 문으로 문에는 표현식인 문과 아닌 문이 있다고 정리했다. </p>
<p>그렇다면 할당문은 표현식인 문일까?</p>
<p>할당문은 변수에 값을 할당하는 부수 효과만 일을 뿐 값으로 평가되지 않을 것 처럼 보인다. 
하지만 ** 값으로 평가되는 표현식인 문으로서 할당된 값으로 평가 ** 된다. </p>
<pre><code class="language-javascript">var x;

console.log(x=10);
// 10</code></pre>
<p>따라서 다음과 같은 동일한 값을 연쇄 할당도 할 수 있는 것이다. </p>
<pre><code class="language-javascript">var a, b, c;

a = b = c = 10;

console.log(a, b, c)
// 10, 10, 10</code></pre>
<h2 id="73-비교-연산자--comparison-operator">7.3. 비교 연산자 / Comparison operator</h2>
<p>좌항과 우항의 피연산자를 비교 후 결과를 불리언 값으로 반환하는 연산자. </p>
<hr>
<h3 id="731-동등일치-비교-연산자">7.3.1. 동등/일치 비교 연산자</h3>
<p>동등 비교 (loose equality) 연산자와 일치 비교 (strict equality) 연산자는 좌항과 우항의 피연산자가 같은 값으로 평가되는지 비교해 불리언 값을 반환한다. 다만 그 엄격성의 정도가 다르다.
<code>shallow vs deep</code></p>
<p><img src="https://images.velog.io/images/_jouz_ryul/post/55be98c9-b6d7-4baa-8407-a39c8dc6b650/%E1%84%87%E1%85%B5%E1%84%80%E1%85%AD%20%E1%84%8B%E1%85%A7%E1%86%AB%E1%84%89%E1%85%A1%E1%86%AB%E1%84%8C%E1%85%A1.001.jpeg" alt="비교 연산자 비교표"></p>
<p>동등 비교 연산자는 좌항과 우항의 피연산자를 비교할 때 먼저 <strong>암묵적 타입 변환</strong>을 통해 타입을 일치시킨 후 같은 값인지 비교한다. 즉, 좌항과 우항의 피연산자가 같은 타입이 아니더라도 암묵적 타입 변환 후 같은 값이라면 true일 수 있다. </p>
<pre><code class="language-javascript">5 ==5; // true

5 == &#39;5&#39;; // true</code></pre>
<p>이처럼 암묵적 타입 변환이 이뤄지기 때문에 결과를 예측하기 어렵고 의도치않은 결과가 나올 수 있다. 다음과 같다. </p>
<pre><code class="language-javascript">&#39;0&#39; == &#39;&#39;; // false
0 == &#39;&#39;; // true
0 == &#39;0&#39;; // true

false == &#39;false&#39;; // false
false == &#39;0&#39;; // true
false == 0; // true
false == null; // false
null == 0; // false*
false == undefined; //false
</code></pre>
<p>이처럼 동등 비교 연산자는 예측하기 어려운 결과를 만들어낸다. 대신 일치 비교 연산자, <code>deep comparison / deep equality</code>를 사용하는 것이 좋다.</p>
<p>** 추가적으로 같이 보면 좋을것들**
<code>truthy and falsey</code>
문자열 &#39;0&#39;은 문자열 연결 연산자로 작동하는 연산문에서 숫자 0 으로 타입 변경이 된다. 
false는 0으로 true는 1로 타입 변경 및 값이 변경된다. 
null은 0으로 타입과 값이 변경된다. 
하지만 비교 연산자에서 동등 비교 연산시 null은 null로서 남아있는다. </p>
<pre><code class="language-javascript">0 == null; // false</code></pre>
<p>일치비교 연산자는 좌항과 우항의 피연산자의 타입과 값이 모두 같은 경우에만 true를 반환한다. 
즉, 암묵적 타입 변환이 이뤄나지 않아 결과 예측이 쉽다. </p>
<pre><code class="language-javascript">5 ===5; // true
5 ===&#39;5&#39;; // false
</code></pre>
<p>하나 짚고 넘어가야할 부분은 NaN이다.</p>
<pre><code class="language-javascript">NaN === NaN; // false

&#39;1&#39; == NaN; // false
</code></pre>
<p>NaN은 자신과 일치하지 않은 유일한 값이다. 따라서 비교 연산자에서 값이 NaN인지 조사하려면 함수 <code>Number.isNaN</code>을 사용하여야 한다. </p>
<pre><code class="language-javascript">Number.isNaN(NaN); // true
Number.isNaN(10); // false
Number.isNaN(1 + undefined); // true</code></pre>
<p>숫자 0 또한 양의 0과 음의 0이 모두 존재하는데 이 둘을 비교하면 true가 반환된다. </p>
<pre><code class="language-javascript">0 === -0; // true
0 == -0; // true

// Object.is 함수를 이용하면 좀 더 예측 가능한 정확한 비교가 가능하다.

0 === -0; // true
Object.is(-0, +0); // false

NaN === NaN; // false
Object.is(NaN, NaN); // true</code></pre>
<h3 id="732-대소-관계-비교-연산자">7.3.2. 대소 관계 비교 연산자</h3>
<p>대소 관계 비교 연산자 비교표</p>
<table>
<thead>
<tr>
<th align="left"><center>대소 관계 비교 연산자</center></th>
<th align="center"><center>예제</center></th>
<th align="center"><center>설명</center></th>
<th align="right"><center>부수 효과</center></th>
</tr>
</thead>
<tbody><tr>
<td align="left"><center>&gt;</center></td>
<td align="center"><center> x &gt; y </center></td>
<td align="center"><center>x가 y보다 크다. </center></td>
<td align="right"><center>x</center></td>
</tr>
<tr>
<td align="left">&lt;</td>
<td align="center">x &lt; y</td>
<td align="center"><center>x가 y보다 작다.</center></td>
<td align="right"><center>x</center></td>
</tr>
<tr>
<td align="left"><center>&gt;=</center></td>
<td align="center"><center>x &gt;= y </center></td>
<td align="center"><center>x가 y보다 같거나 크다.</center></td>
<td align="right"><center>x</center></td>
</tr>
<tr>
<td align="left">&lt;=</td>
<td align="center">x &lt;= y</td>
<td align="center"><center>x가 y보다 작거나 같다.</center></td>
<td align="right"><center>x</center></td>
</tr>
</tbody></table>
<h2 id="74-삼항-조건-연산자--ternary-operator">7.4. 삼항 조건 연산자 / ternary operator</h2>
<p>삼항 조건 연산자는 조건식의 평가 결과에 따라 변환할 값을 결정한다. 부수 효과는 없고 다음과 같이 사용한다. </p>
<pre><code class="language-javascript">
var result = score &gt;=60 ? &#39;pass&#39; : &#39;fail&#39;
</code></pre>
<p><code>score</code>의 값이 60과 같거나 큰지에 대한 연산이 먼저 실행된다. 
<code>?</code>를 기준으로 좌항의 값이 참이면 <code>:</code>뒤의 값을 리턴하고 참이 아니면 fail을 리턴한다. 
삼항 연산자는 조건문의 줄임으로 사용될 수 있다.</p>
<pre><code class="language-javascript">var x = 2, result;
if (x%2) result = &#39;홀수&#39;;
else result = &#39;짝수&#39;;

var result = x % 2 ?&#39;홀수&#39; : &#39;짝수&#39;;
</code></pre>
<p>다만 차이점은 삼항 조건 연산자 표현식은 값처럼 사용할 수 있다. 즉 값으로 평가할 수 있는 표현식인 문이다. </p>
<h2 id="75-논리-연산자--logical-operator">7.5. 논리 연산자 / logical operator</h2>
<p>우항과 좌항의 피연산자 (부정 논리 연산자의 경우 우항의 피연산자)를 논리 연산한다.</p>
<hr>
<table>
<thead>
<tr>
<th align="left"><center>논리 연산자</center></th>
<th align="center"><center>의미</center></th>
<th align="right"><center>부수 효과</center></th>
</tr>
</thead>
<tbody><tr>
<td align="left"><center>ll</center></td>
<td align="center"><center>논리합(OR)</center></td>
<td align="right"><center>X</center></td>
</tr>
<tr>
<td align="left"><center>&amp;&amp;</center></td>
<td align="center"><center>논리곱(AND)</center></td>
<td align="right"><center>X</center></td>
</tr>
<tr>
<td align="left"><center>!</center></td>
<td align="center"><center>부정(NOT)</center></td>
<td align="right"><center>X</center></td>
</tr>
</tbody></table>
<pre><code class="language-javascript">
// 논리합 연산자
// || 기준 좌항의 값이 true일 경우 좌항을 return, false일 경우 우항을 return
true || true; // true
true || false; // true
false || true; // true
false || false; // true

// 논리곱 연산자
// &amp;&amp; 기준 좌항의 값이 true일 경우 우항을 return, false일 경우 좌항을 return
true &amp;&amp; true; // true
true &amp;&amp; false; // false
false &amp;&amp; true; // false
false &amp;&amp; false; // false

// 논리 부정 연산자
!false; // true
!true; // false</code></pre>
<p>논리 부정 연산자는 언제나 불리언 값을 반환한다. 만약 피연산자가 불리언 값이 아니면 불리언 타입으로 암묵적 타입 변환된다. 
자세한건 CH.9 단축평가에서....</p>
<h2 id="76-쉼표-연산자">7.6. 쉼표 연산자.</h2>
<p>왼쪽 피연산자부터 차례대로 피연산자를 평가하고 마지막 피연산자의 평가가 끝나면 마지막 피연산자의 평가 결과를 반환</p>
<pre><code class="language-javascript">var x, y, z;
x = 1, y=2, z=3; // 3</code></pre>
<h2 id="77-그룹-연산자">7.7. 그룹 연산자.</h2>
<p>소괄호로 피연산자를 감싸 연산식에서 평가 순서를 컨트롤할 수 있다. </p>
<pre><code class="language-javascript">10 *2 +3; // 23

10 * (2 +3); // 50</code></pre>
<h2 id="78-typeof-연산자">7.8. typeof 연산자</h2>
<p>피연산자의 데이터 타입을 문자열로 반환.
반환되는 문자열은 다음 7가지와 같다.</p>
<ol>
<li><code>stirng</code></li>
<li><code>number</code></li>
<li><code>boolean</code></li>
<li><code>undefined</code></li>
<li><code>symbol</code></li>
<li><code>object</code></li>
<li><code>function</code></li>
</ol>
<p><code>null</code>을 반환하는 경우는 없으며 예제는 다음과 같다. </p>
<pre><code class="language-javascript">typeof &#39;&#39;; // &quot;string&quot;
typeof 1; // &quot;number&quot;
typeof NaN; // &quot;number&quot;
typeof true; // &quot;boolean&quot;
typeof undefined; // &quot;undefined&quot;
typeof Symbol(); // &quot;symbol&quot;
typeof null; // &quot;object&quot;
typeof []; // &quot;object&quot;
typeof {}; // &quot;object&quot;
typeof new Date(); // &quot;object&quot;
typeof /test/gi; // &quot;object&quot;
typeof function() {}; // &quot;function&quot;
</code></pre>
<p><code>typeof null</code>의 경우 <code>object</code>를 반환하는데 이는 자바스크립트의 첫 번째 버전의 버그다.
따라서 값이 null 타입인지 확인할 떄는 일치 연산자(===)를 사용하는 것이 정확하다.</p>
<pre><code class="language-javascript">var foo = null;

typeof foo === null; // false
foo === null; // true</code></pre>
<h2 id="79-지수-연산자">7.9. 지수 연산자</h2>
<p>ES7에서 도입된 지수 연산자는 좌항의 피연산자를 밑으로, 우항의 피연산자를 지수로 거듭 제곱한다.</p>
<pre><code class="language-javascript">2 ** 2; // 4
2 ** 0; // 0

//지수연산자 도입전
Math.pow(2, 2); // 4
Math.pow(2, 0); // 0

//음수를 거듭제곱 시 괄호로 묵어야 한다.
-5 ** 2 // SyntaxError: ...

(-5) ** 2 // 25

// 할당 연산자와 함께 사용 가능
var num = 5;
num **= 2; // 25</code></pre>
<h2 id="710-그-외의-연산자">7.10. 그 외의 연산자</h2>
<table>
<thead>
<tr>
<th align="left"><center>연산자</center></th>
<th align="center"><center>개요</center></th>
<th align="right"><center>참고</center></th>
</tr>
</thead>
<tbody><tr>
<td align="left"><center>?.</center></td>
<td align="center"><center>옵셔널 체이닝 연산자</center></td>
<td align="right"><center>CH.9.4.2</center></td>
</tr>
<tr>
<td align="left"><center>??</center></td>
<td align="center"><center>null 병합 연산자</center></td>
<td align="right"><center>CH.9.4.3</center></td>
</tr>
<tr>
<td align="left"><center>delete</center></td>
<td align="center"><center>프로퍼티 삭제</center></td>
<td align="right"><center>CH.10.8</center></td>
</tr>
<tr>
<td align="left"><center>new</center></td>
<td align="center"><center>생성자 함수를 호출할 때 사용하여 인스턴스를 생성</center></td>
<td align="right"><center>CH.17.2.6</center></td>
</tr>
<tr>
<td align="left"><center>instanceof</center></td>
<td align="center"><center>좌변의 객체가 우변의 생성자 함수와 연결된 인스턴스인지 판별</center></td>
<td align="right"><center>CH.19.10</center></td>
</tr>
<tr>
<td align="left"><center>in</center></td>
<td align="center"><center>프로퍼티 존재 확인</center></td>
<td align="right"><center>CH.19.13.1</center></td>
</tr>
</tbody></table>
<h2 id="712-연산자-우선순위">7.12. 연산자 우선순위</h2>
<table>
<thead>
<tr>
<th align="center"><center>우선순위</center></th>
<th align="center"><center>참고</center></th>
</tr>
</thead>
<tbody><tr>
<td align="center"><center>1</center></td>
<td align="center"><center>()</center></td>
</tr>
<tr>
<td align="center"><center>2</center></td>
<td align="center"><center>new(매개변수 존재), ., [](프로퍼티 접근), ()(함수호출), ?.(옵셔널 체이닝 연산자)</center></td>
</tr>
<tr>
<td align="center"><center>3</center></td>
<td align="center"><center>new(매개변수 미존재)</center></td>
</tr>
<tr>
<td align="center"><center>4</center></td>
<td align="center"><center>x++, x--</center></td>
</tr>
<tr>
<td align="center"><center>5</center></td>
<td align="center"><center>!x, +x, -x, ++x, --x, typeof, delete</center></td>
</tr>
<tr>
<td align="center"><center>6</center></td>
<td align="center"><center>** (이항 연산자 중에서 우선순위가 가장 높다)</center></td>
</tr>
<tr>
<td align="center"><center>7</center></td>
<td align="center"><center>*, /, %</center></td>
</tr>
<tr>
<td align="center"><center>8</center></td>
<td align="center"><center>+, -</center></td>
</tr>
<tr>
<td align="center"><center>9</center></td>
<td align="center"><center>&lt;, &lt;=, &gt;, &gt;=, in, instanceof</center></td>
</tr>
<tr>
<td align="center"><center>10</center></td>
<td align="center"><center>==, !=, ===, !==</center></td>
</tr>
<tr>
<td align="center"><center>11</center></td>
<td align="center"><center>?? (null 병합 연산자)</center></td>
</tr>
<tr>
<td align="center"><center>12</center></td>
<td align="center"><center>&amp;&amp;</center></td>
</tr>
<tr>
<td align="center"><center>13</center></td>
<td align="center"><center>ll</center></td>
</tr>
<tr>
<td align="center"><center>14</center></td>
<td align="center"><center>? ~: ~</center></td>
</tr>
<tr>
<td align="center"><center>15</center></td>
<td align="center"><center>할당 연산자 (=, +=. -=. ...)</center></td>
</tr>
<tr>
<td align="center"><center>16</center></td>
<td align="center"><center>,</center></td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 Deep Dive] 데이터 타입]]></title>
            <link>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85</link>
            <guid>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85</guid>
            <pubDate>Wed, 16 Mar 2022 12:16:09 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트는 7개의 데이터 타입이 있다. 근데 이제 ES11에서 BigInt가 추가된</p>
<h2 id="6-데이터-타입">6. 데이터 타입</h2>
<p>7개의 데이터 타입은 원시타입과 객체타입으로 구분할 수 있다.</p>
<hr>
<p><img src="https://images.velog.io/images/_jouz_ryul/post/08e8717f-cf22-4c7e-a393-e2362a427088/%E1%84%83%E1%85%A6%E1%84%8B%E1%85%B5%E1%84%90%E1%85%A5%20%E1%84%90%E1%85%A1%E1%84%8B%E1%85%B5%E1%86%B8.001.jpeg" alt="자바스크립트의 데이터 타입"></p>
<p>숫자타입의 1과 문자열 타입의 &#39;1&#39;은 생김새는 비슷할지언정 전혀 다른 값이다. 
우선 생성한 목적과 용도가 다르고 두개의 다른 데이터 타입은 서로 확보해야 할 메모리 공간의 크기도 다르며 메모리에 저장되는 2진수도 다르다. 당연히 2진수도 읽어 들여 해석하는 방식도 다르고 값도 다르다. </p>
<h2 id="61-숫자-타입">6.1. 숫자 타입</h2>
<p>자바스크립트에게 숫자는 그냥 숫자다. 그게 정수던 실수던</p>
<hr>
<p>ECMAScript 스팩에 따르면 숫자 타입의 값은 배정밀도 64비트 부동소수점 형식을 따른다는데 간단히 말해 모든 숫자를 실수로 처리한다는 뜻이다. 즉 자바스크립트에게 숫자타입은 실수뿐이다. </p>
<pre><code class="language-javascript">var binary = 0b01000001; //2진수
var octal = 0o101; // 8진수
var hex = 0x41; // 16진수</code></pre>
<p>위 예제에서 각 변수에 할당된 평가된 값들은 모두 메모리에 배정밀도 64비트 부동소수점 형식의 2진수로 저장된다고 한다. 즉 각 진수에 따른 별도의 데이터 타입이 제공되지 않기 떄문에 위 평가된 값들은 모두 같다. </p>
<pre><code class="language-javascript">var binary = 0b01000001; //2진수
//65
var octal = 0o101; // 8진수
//65
var hex = 0x41; // 16진수
//65

console.log(binary === octal) 
// true
console.log(octal === hex)
// true</code></pre>
<p>심지어 정수와 실수 또한 아래와 같이 평가된다.</p>
<pre><code class="language-javascript">console.log(1 === 1.0)
// true</code></pre>
<p>하지만 또 아래와 같은 현상도 존재한다.</p>
<pre><code class="language-javascript">const a = 0.1
const b = 0.2

console.log(a+b === 0.3);
//false
console.log(0.30000000000000004 === a + b);
//true 


console.log(a === 0.10)
//true
console.log(a === 0.1000000000000001)
//false
console.log(a === 0.10000000000000001)
//true

console.log(0.300000000000000004 === a + b);
//false 
console.log(0.30000000000000004 === a + b);
//true </code></pre>
<p>이는 배정밀도 64비트 부동소수점 형식떄문이라는데 자세한 내용은 아래 링크에 
또한 추후에 정리할 예정이다. (아마 책 뒤에 내용이 나오지않을까 싶은데)
간단하게만 정리하자면 컴퓨터는 비트에 담긴 0과1을 사용해서 이진법으로 숫자를 표현하기 때문에 표현할 수 있는 숫자의 개수는 비트 수에 정비례한다. “유한개”인 표현방법으로 “무한개” 인 모든 수(실수)를 표현할 수 없기 때문에, 정확도를 낮추는 대신 표현할 수 있는 범위를 넓히는 방향을 택할 수 있다. 
*<em>즉 자바스크립트는 정확도를 낮추는 대신 표현할 수 있는 범위를 넓히는 방향을 택한것이다. *</em>
<a href="https://medium.com/@rnrjsah789/js%EC%97%90%EC%84%9C%EC%9D%98-64%EB%B9%84%ED%8A%B8-%EB%B6%80%EB%8F%99%EC%86%8C%EC%88%AB%EC%A0%90-c95e0cfec2b2">자바스크립트 64비트 부동 소숫점</a>
<a href="https://vanillaani.tistory.com/6">자바스크립트 소수점 계산 오류</a></p>
<h2 id="62-문자열-타입">6.2. 문자열 타입</h2>
<p>텍스트</p>
<hr>
<p>문자열 타입은 0개 이상의 16비트 유니코드 문자 (UTF-16)의 집합으로 작은따옴표, 큰따옴표 또는 백틱으로 감싸주면 문자열로 평가된다.
문자열은 원시 타입으로 변경 불가능한 값 (immutable value)이다. 문자열이 생성되면 그 문자열을 변경할 수 없는 이는 추후에 더 자세한 내용이 나온다. </p>
<h2 id="63-템플릿-리터럴">6.3. 템플릿 리터럴</h2>
<p>백틱</p>
<hr>
<p>백틱을 따옴표 대신 사용하여 감싸진 문자열이다. 
일반 문자열에서 허용됮 않는 개행이 허용되고 표현식또한 삽입할 수 있다. </p>
<pre><code class="language-javascript">/*
`나는
아직
배고프다
`
*/
`나는
아직
배고프다
`

const lastName = &quot;Lee&quot;
const firstName = &quot;Jouz&quot;
const greeting = `제 이름은 ${firstName} ${lastName} 입니다.`
console.log(greeting)
// 제 이름은 Jouz Lee 입니다. </code></pre>
<h2 id="64-불리언-타입">6.4. 불리언 타입</h2>
<p>논리적으로 참 거짓을 나타내는 true와 false 뿐이다. 
빈 문자열과 숫자 0은 falsey 하다. 
자바스크립트한테 <code>&#39;&#39;</code>와 <code>0</code>은 논리적으로 거짓이라고 해석해도 될까?</p>
<h2 id="65-undefined-타입">6.5. undefined 타입</h2>
<p><strong>undefined는 개발자가 의도적으로 할당하기 위한 값이 아니라 자바스크립트 엔진이 변수를 초기화 할 떄 사용하는 값이다.</strong>
자바슼므립트 엔진이 변수를 초기화하는 데 사용하는 <code>undefined</code>를 개발자가 의도적으로 변수에 할당한다면 본래 취지와 어긋날뿐더러 혼란을 줄 수 있으므로 권장하지 않는다고 한다.</p>
<h2 id="66-null-타입">6.6. null 타입</h2>
<p>위 undefined처럼 변수에 값이 없다는 것을 명시하고 싶을 때 사용할 수 있는 타입으로 null 값이 유일하다. <code>null</code>은 변수에 값이 없다는 것을 의도적으로 명시할 수 있고 변수에 null을 할당한다는 것은 이전 참조값을 더 이상 참조하지 않겠다는 의미다. 즉 이전 할당 값에 대한 참조를 명시적으로 제거하는 것 또한 의미할 수 있다.</p>
<p>하지만 <code>typeof</code>를 통해 null의 타입을 확인해보면 아래와 같다.</p>
<pre><code class="language-javascript">console.log(typeof null)

// object</code></pre>
<p>이에 대한 논리적인 이유는 없고 because the spec says so </p>
<h2 id="67-심볼-타입">6.7. 심볼 타입</h2>
<p>ES6에서 추가된 다른값과 중복되지 않는 유일무이한 값</p>
<hr>
<p>주로 이름이 충돌할 위험이 없는 객체의 유일한 프로퍼티 키를 만들기 위해 사용된다.
심벌 이외의 원시 값은 리터럴을 통해 생성하지만 심벌은 <code>Symbol</code>함수를 호출해 생성한다. 
이렇게 생성된 심볼값은 외부에 노출되지 않으며, 다른 값과 절대 중복되지 않는 <strong>유일무이한 값</strong>이다. </p>
<h2 id="69-데이터-타입의-필요성">6.9. 데이터 타입의 필요성</h2>
<p>데이터 타입에 따라 저장할 메모리 공간을 경제적으로 확보하고, 저장된 메모리의 범위를 미리 알 수 있게 되며, 해석에도 사용된다. </p>
<hr>
<p>자바스크립트 엔진은 값을 메모리에 저장하기에 앞서 저장할 공간을 미리 확보한다.
즉 데이터 타입에 따라 먼저 확보해야할 메모리 공간의 크기가 결정된다. 
이는 값을 저장할 때 낭비와 손실을 없애기 위함이다. </p>
<p>또한 앞서 메모리에 값이 저장될 때 2진수의 값으로 저장된다 정리하였고 메모리 셀 하나의 크기는 1바이트라고 정리하였다. 
그렇다면 만약 8비트 크기의 숫자 값을 메모리에 저장한다고 가정한다면 8개의 셀이 필요하고 바꿔말하면 8개의 메모리 주소가 변수에 할당된다는 뜻이다. </p>
<p>이때 8비트 크기의 값을 참조한다고 가정해보면 데이터 타입의 필요성을 더 정리해볼 수 있다. 
우선 참조 시 변수명 혹은 식별자를 통해 숫자 타입의 값 100이 저장되어 있는 메모리 공간의 선두 메모리 셀의 주소를 찾아갈 수 있다
그 후 데이터 타입을 통해 한번에 읽어 들여야 할 메모리 공간의 크기 또는 셀의 개수를 알 수 있게된다.
더 나아가 특정 메모리 공간에 저장된 2진수 값을 해석할 때 데이터 타입은 필수적이다. 
같은 2진수 값이여도 데이터 타입에 따라 해석한 값이 달라지기 때문이다. </p>
<p>정리하자면</p>
<ul>
<li>값을 저장할 떄 확보해야 하는 메모리 공간의 크기를 결정하기 위해</li>
<li>값을 참조할 때 한 번에 읽어 들여야 할 메모리 공간의 크기 (범주)를 결정하기 위해</li>
<li>읽어 들인 2진수 값을 어떻게 해석할지 결정하기 위해</li>
</ul>
<p>데이터 타입이 필요하다.</p>
<h2 id="610-동적-타이핑">6.10. 동적 타이핑</h2>
<p>동적 타입 언어와 정적 타입 언어중 자바스크립트는 동적 타입 언어이다. 
자바스크립트는 변수의 선언과 할당 단계가 나누어져있는데 선언이 아닌 할당에 의해 타입이 결정된다. 
타입 결정은 타입 추론으로도 볼 수 있고 재할당에 의해 변수의 값이 변하듯 타입 또한 변할 수 있다. 
동적 타입 언어는 유연성은 높지만 신뢰성은 떨어진다. 잘못된 타입 추론과 예측으로 복자성이 증가되고 처리 흐름을 추적하기 어렵기 때문이다. 우리가 변수명에 신경써야 하는 이유이기도 하다. </p>
<hr>
<p>자바스크립트는 변수를 선얼할 때 타입을 선언하지 않는다. 다만 키워드를 사용해 변수를 선언하는데 미리 선언한 데이터 타입의 값만 할당 할 수 있는 것이 아닌 어떠한 데이터 타입의 값도 자유롭게 할당할 수 있다. 
또한 변수는 데이터 타입을 갖지 않는다고 볼 수 있고 변수에 할당되어 있는 값에 의해 변수의 타입이 동적으로 결정된다고 표현하는게 더 정확하다.</p>
<p>정적 타입 언어는 변수 선언 시점에 미리 변수의 타입을 선언하여 결정되고 변수의 타입을 변경할 수 없지만 자바스크립트는 값을 할당하는 시점에 변수의 타입이 동적으로 결정되고 변수의 타입을 언제든지 자유롭게 변경할 수 있다. 
정리하자면 *<em>자바스크립트의 변수는 선언이 아닌 할당에 의해 타입이 결정 (타입 추론) 된다. 그리고 재할당에 의해 변수의 타입은 언제든지 동적으로 변한다. *</em>
이러한 특징을 동적 타이핑이라고 하며 자바스크립트를 정적 타입 언어와 구별하기 위해 동적 타입언어라 한다. </p>
<p>변수 값이 언제든지 변경될 수 있는 자바스크립트이기에 복잡한 프로그램에서는 변화하는 변수 값을 추적하기 어려울 수 있을뿐더러 해당 변수의 타입도 언제든지 변경될 수 있기에 값을 확인하기 전에는 타입을 확신하기 어렵다. 
또한 개발자의 의도와 상관없이 자바스크립트 엔진에 의해 암묵적으로 타입이 자동으로 변환되기도 한다. 
따라서 자바스크립트와 같은 모든 동적 타입 언어는 유연성은 높지만 신뢰성이 떨어질 수 밖에 없고 다음처럼 변수를 사용할 떄 주의해야한다. </p>
<ol>
<li><p>필요한 경우에 한해 제한적으로 사용한다. 변수 값은 재할당에 의해 언제든지 변경될 수 있음으로 잘못된 타입 예측에 의한 오류 발생 가능성이 크고 이는 변수가 많이 사용될 수록 오류가 발생할 확률도 높아진다는 뜻이다. 따라서 <strong>변수의 무분별한 남블을 삼가하고 필요한 만큼 최소한으로 유지</strong> 하도록 주의해야 한다.</p>
</li>
<li><p>변수의 <strong>유효범위, 즉 스코프를 최대한 좁게 만들어 부작용을 억제</strong>해아한다. to be continue CH.13 스코프</p>
</li>
<li><p>어디서든 참조/변경 가능한 <strong>전역변수 사용을 최소화</strong>한다. 전역 변수는 모든곳에서 참조, 변경이 가능하기에 의도치 않게 값이 변경될 가능성이 더 높고 이는 다른 사용처에서의 오류를 발생시키는 등 코드에 영향을 준다. 이는 곧 처리 흐름을 추적하기 어렵게 만들고 오류의 원일을 특정하기 어렵게 만든다. to be continue CH.14 전역 변수의 문제점</p>
</li>
<li><p>변수보다는 <strong>상수를 사용</strong>해 값의 변경을 언제한다. to be continue CH.15 const 키워드</p>
</li>
<li><p><strong>변수 이름은 변수의 목적이나 의미를 파악할 수 있도록 네이밍한다.</strong> 개발자의 의도를 나타내는 명확한 네이밍은 코드를 이해하기 쉽게 만들고 이는 협업과 생산성 향상에 도움을 준다. </p>
</li>
</ol>
<h2 id="정리하며">정리하며</h2>
<p>자바스크립트의 데이터 타입은 크게 원시타입과 객체 타입으로 나누어 볼 수 있고 또한 원시타입은 7가지로 나누어볼 수 있다. 데이터 타입은 간단하지만 중요하게 짚고 넘어가볼 필요가 있다. 
그 이유는 기본적으로 데이터 타입에 의해 메모리 공간을 미리 확보하고 정확한 위치로 참조할 수 있기 때문이다. 또한 가장 중요하게 데이터 타입에 의해 값의 해석이 달라지기 때문이다. 
또한 자바스크립트는 동적 타입 언어로서 7가지의 원시타입간뿐 아니라 모든 데이터 타입간 재할당에 의해 변수의 타입은 동적으로 변할 수 있다. 
이처럼 자바스크립트는 유연하지만 신뢰성이 떨어진다. 그렇기 때문에 타입스크립트를 써야한다. ㅎㅎ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 Deep Dive] 표현식과 문]]></title>
            <link>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%ED%91%9C%ED%98%84%EC%8B%9D%EA%B3%BC-%EB%AC%B8</link>
            <guid>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%ED%91%9C%ED%98%84%EC%8B%9D%EA%B3%BC-%EB%AC%B8</guid>
            <pubDate>Thu, 10 Mar 2022 23:26:39 GMT</pubDate>
            <description><![CDATA[<p>프로그램은 <strong>문의 집합</strong>으로 이뤄진 것으로 문을 작성하여 <strong>순서에 맞게 나열</strong>하는 것이 <strong>프로그래밍</strong>이다. 즉 문은 프로그램을 구성하는 기본 단위이자 최소 실행 단위이며 문은 표현식인 문과 표현식이 아닌문으로 나눌 수 있다.</p>
<h1 id="5-표현식과-문">5. 표현식과 문</h1>
<p>표현식은 그 자체로 표현식이면서 문이 될 수 있다. 하지만 모든 표현식이 문이 될 순 없다. </p>
<hr>
<h2 id="51-값">5.1. 값</h2>
<p>값은 표현식이 평가되어 생성된 결과</p>
<hr>
<p>식을 해석하여 값을 생성하거나 참조한다면 그것을 평가라 할 수 있고 그 값은 모두 데이터 타입을 가진다. 
이 들은 메모리에 2진수,즉 비트의 나열로 저장되는데 데이터 타입에 따라 같은 값일지라도 그 해석이 달라진다. 
12진수 <strong>0100 0001</strong>는 숫자타입으로는 65이지만 문자타입으로는 &#39;A&#39;다. </p>
<p>앞서 변수는 값을 저장하기 위해 확보한 메모리상의 공간 자체로서 그 공간을 인간친화적으로 식별하기위해 붙이는 이름이라고 정리했다. 따라서 변수에 할당되는 것은 값이다. </p>
<pre><code class="language-javascript">var sum = 10 + 20;</code></pre>
<p>위의 예제에서 변수 sum은 10 +20이 할당될 것 같다. 하지만 10+20은 표현식으로서 평가되어야 하고 그 평가의 결과인 30이 변수 sum에 할당된다. 즉 메모리에는 숫자 30이 저장된다.</p>
<h2 id="52-리터럴">5.2. 리터럴</h2>
<p>리터럴은 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 <strong>표기법</strong>이다.</p>
<hr>
<p>숫자 3은 숫자 리터럴이다. 인간에겐 아라비아 숫자가 더 이해가 빠를 것이다. 정리하면 인간이 이해하는 3 이라는 아라비아 숫자를 사용해 컴퓨터에게 전달하면 컴퓨터에게, 정확히는 자바스크립트 엔진에게는 숫자 리터럴 3이고 이를 평가하여 숫자 값 3을 생성한다. </p>
<p>이처럼 리터럴은 <strong>사람이 이해할 수 있는 문자</strong> (아라비아 숫자, 알파벳, 한글 등) 또는 <strong>미리 약속된 기호</strong> (&#39;&#39;, &quot;&quot;, ., [], {}, // 등)로 표기한 <strong>코드</strong>다. 
자바스크립트 엔진은 런타임 시점에 리터럴을 평가해 값을 생성하는데 따라서 리터럴은 <strong>값</strong>을 <strong>생성</strong>하기 위한 약속된 <strong>표기법</strong>이라고 할 수 있다.</p>
<p><strong>리터럴 종류</strong></p>
<ul>
<li>정수 리터럴 (100)</li>
<li>부동소수점 리터럴 (10.5)</li>
<li>2진수 리터럴 (0b01000001) // 0b로 시작</li>
<li>8진수 리터럴 0o101 // ES6에서 도입됐으며 0o으로 시작</li>
<li>16진수 리터럴 0x41 // ES6에서 도입됐으며 0x으로 시작</li>
<li>문자열 리터럴 (&#39;Hello&#39;, &quot;World&quot;)</li>
<li>불리언 리터럴 (true, false)</li>
<li>null 리터럴 (null)</li>
<li>undefined 리터럴 (undefined)</li>
<li>객체 리터럴 ({ name: &#39;Lee&quot;, address: &#39;Seoul&#39;})</li>
<li>배열 리터럴 ( [1,2,3])</li>
<li>함수 리터럴 ( function() {})</li>
<li>정규 표현식 리터럴 (/[A-Z]+/g)
등이 있다.</li>
</ul>
<h2 id="53-표현식">5.3. 표현식</h2>
<p>표현식은 값으로 평가될 수 있는 문이다. 표현식이 평가되면 새로운 값을 생성하거나 기존 값을 참조한다. 리터럴도 표현식이다.</p>
<hr>
<pre><code class="language-javascript">var scre = 100;</code></pre>
<p>100은 정수 리터럴로서 자바스크립트 엔진에 의해 평가되어 값을 생성하므로 리터럴은 그 자체로 표현식이다.</p>
<pre><code class="language-javascript">var score = 50 + 50;</code></pre>
<p>50 + 50 은 숫자 리터럴 50과 연산자 +로 이뤄져있다. 50+50도 평가되어 숫자 값 100을 생성하므로 표현식이다. 
위 코드의 변수 score를 참조하면 변수 값으로 평가된다. 비록 새로운 값을 생성하지는 않지만 값으로 평가되므로 표현식이라 할 수 있다. 
따라서 값으로 평가될 수 있는 문은 모두 표현식이고 표현식은 값처럼 사용할 수 있다. 이는 값이 위치할 수 있는 자리에는 표현식도 위치할 수 있다고 문법적으로 이해해볼 수 있다. </p>
<pre><code class="language-javascript">var x = 1;
var y= 1;

var z = x+ 1;
//or
var z = 1+ y;
// or
var z = x+ y;
</code></pre>
<h2 id="54-문">5.4. 문</h2>
<p>문을 작성하여 순서에 맞게 나열하는 것이 프로그래밍이다. 즉 문은 프로그램을 구성하는 최소 단위라고 볼 수 있다. </p>
<hr>
<p>문은 여러 토큰으로 구성되는데 <strong>토큰이란 문법적인 의미를 가지며, 문법적으로 더 이상 나눌 수 없는 코드의 기본 요소를 의미한다.</strong> 토큰의 예로는 키워드, 식별자, 연산자, 리터럴, 세미콜론 혹은 마침표 등이 있다. </p>
<p>또한 문을 명령문이라고도 부르는데 다르게 해석하면 ** 문은 컴퓨터에 내리는 명령** 이다. 예로는 선언문, 할당문, 조건문, 반복문 등이 있다. </p>
<p>문과 표현식을 구별하고 해석할 수 있으면 자바스크립트 엔진의 입장에서 코드를 해석해볼 수 있고 실행 결과를 예측하기는데 도움이 될 것이다. 이는 버그를 줄이고 코드의 품질을 높여줄 것이다.</p>
<h2 id="566-표현식인-문과-표현식이-아닌-문">5.6.6 표현식인 문과 표현식이 아닌 문</h2>
<p>표현식은 문의 일부일 수도 있고, 그 자체로 문이 될 수 있다. </p>
<hr>
<pre><code class="language-javascript">
var x;
// 변수 선언문은 값으로 평가될 수 없으므로 표현식이 아니다. 

// 선언문은 초기화 단계에서 undefined가 할당되어 값으로 평가되지 않을까 생각할 수 있지만
// 이해한 바로는 초기화 단계에서의 undefined의 할당은 목적이 있는 값의 할당이 아니라
// 자바스크립트가 인터프리터언어로서 갖는 코드 실행 방법으로 인해 쓰레기 값을 참조하게 되면
// 의도치 않은 값이 참조되는 것을 방지하기 위해 할당되는 것이기에 
// 선언문 자체가 undefined로 평가된 값을 할당되는 것으로 보이지만 
// 사실은 값으로 평가될 수 없는 과정이기에 표현식이 아니라고 하는것이 아닐까?

x = 1 + 2;
// 1, 2, 1 + 2, x = 1+ 2 모두 표현식
// x= 1 + 2는 표현식이면서 완전한 문이다. </code></pre>
<p>이처럼 표현식인 문과 표현식이 아닌 문이 있다. 바꿔말해 표현식은 문이지만 표현식이 아니라해서 문이 아닌것 또한 아니다. 이처럼 표현식과 문은 비슷하여 구분하기 힘들다. </p>
<p>하지만 변수에 할당을 해보면 표현식인문과 표현식이 아닌 문을 간단하고 명료하게 구별할 수 있다. 앞서 변수에는 값으로 평가되어지면 할당할 수 있다고 정리했다. 만약 문이 값으로 평가되면 변수에 할당 할 수 있는 것이고 값으로 문을 평가할 수 없다면 변수에 할당 할 수 없기에 에러가 발생한다. </p>
<pre><code class="language-javascript">var foo = var x // SyntaxError: Unexpected token var
/*
위의 코드는 예상치못한 토큰인 var가 있다는 문법오류를 내밷는다. 
토큰에 대해서는 아마 실행 컨텍스트 부분에서 자세히 다룰 것 같지만 
위에 정리한 토큰에 대한 간단한 정리를 대입해서 생각해보면 
값을 평가하는 부분에서 예약어에 해당하는 토큰이 존재한다면 문법적으로 맞지 않는다는 것이다. 
이렇게도 표현식인문과 표현식이 아닌 문을 구분해볼 수 있을까?
*/
var foo = x = 1+2;
/*
위 코드는 아무 에러 없이 실행이 된다.
따라서 x= 1+2는 값으로 사용될 수 있는 표현식인 문이다. 
*/
// [1]
var foo = 10;
if (true) {};
/*
두개의 문 모두 값으로 평가될 수 없다. 
1. 선언문
2. 조건문
*/

// [2]
var num = 10; 
//이라는 코드가 이미 존재했을 때

100 + num;

num = 200
/*
두개의 문 모두 값으로 평가될 수 있으며 100+ num은 표현식 문이고 num=100은 할당문 (재할당)이다. 
*/</code></pre>
<h2 id="정리하며">정리하며</h2>
<p><strong>문</strong>을 작성하여 <strong>순서에 맞게 나열</strong>하는 것이 <strong>프로그래밍</strong>이다. </p>
<p>또한 문을 명령문이라고도 부르는데 다르게 해석하면 ** 문은 컴퓨터에 내리는 명령** 이다. 예로는 선언문, 할당문, 조건문, 반복문 등이 있다. </p>
<p>문과 표현식을 구별하고 해석할 수 있으면 자바스크립트 엔진의 입장에서 코드를 해석해볼 수 있고 실행 결과를 예측하기는데 도움이 될 것이다. 이는 버그를 줄이고 코드의 품질을 높여줄 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 Deep Dive] 변수]]></title>
            <link>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B3%80%EC%88%98</guid>
            <pubDate>Thu, 03 Feb 2022 09:22:23 GMT</pubDate>
            <description><![CDATA[<p>아무리 복잡한 어플리케이션이라 할지라도 데이터를 <strong>입력</strong> 받아 처리하고 결과를 <strong>출력</strong> 하는 것이 전부이다. </p>
<h1 id="4-변수">4. 변수</h1>
<p>사람은 계산과 기억을 모두 두뇌에서 한다. 반면 컴퓨터는 CPU를 통해 연산하고, 메모리를 통해 데이터를 기억한다.</p>
<hr>
<h2 id="41-변수란-무엇인가-왜-필요한가">4.1. 변수란 무엇인가? 왜 필요한가?</h2>
<p>메모리는 데이터를 저장할 수 있는 메모리 셀의 집합체다. 메모리 셀 하나의 크기는 1바이트 (8비트)이며, 컴퓨터는 메모리 셀의 크기, 즉 1바이트 단위로 데이터를 저장하고 읽어들인다. </p>
<p>또한 각 셀은 고유의 <strong>메모리 주소</strong>를 갖는데 이는 메모리 공간의 위치이다. 0부터 메모리의 크기만큼 정수로 표현되는데 예를들어 4GB 메모리는 0부터 4,294,967,296 (0x00000000 ~ 0xFFFFFFFF)까지의 주소를 갖고 데이터 종류와 상관없이 모든 데이터는 2진수로 저장된다. </p>
<pre><code>//예제
10 + 20</code></pre><p>위와 같은 연산이 실행되면 10과 20은 메모리 상의 임의의 위치에 저장되고 CPU는 이 값을 읽어 연산을 한다. 연산의 결과로 생성된 숫자 값 30 또한 메모리 상의 임의의 위치에 저장된다. 하지만 문제는 여기서 시작한다. 연산 결과 값 30이 저장된 메모리 공간에 직접 접근하지 않는다면 이 값 30은 재사용할 수 없다는 문제가 있고 메모리 주소를 통해 값에 직접 접근하는 것 또한 치명적 오류를 발생시킬 가능성이 높은 매우 위험한 일이다. 이 때문에 자바스크립트에서는 직접적인 메모리 제어를 허용하지 않는 <strong>매니지드 언어</strong>이다. </p>
<p>자바스크립트가 직접적인 메모리 제어를 허용하지 않는 이유는 값이 저장될 메모리 주소가 매번 임의로 결정되기 때문이다. 코드가 실행될 때 메모리의 상황에 따라 메모리 주소가 임의로 결정되는 메커니즘으로 인해 동일한 컴퓨터에서 동일한 코드를 살행해도 메모리 주소는 변경된다. 즉 코드가 실행되기 이전에는 값이 저장된 메모리 주소를 알 방법이 없기 때문에 직접 접근하는 방법은 올바르지 못하다. </p>
<p>따라서 값을 저장하고 읽어 들여 재사용하기 위해 변수라는 메커니즘을 제공하는데 <strong>변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙힌 이름</strong>을 말한다. 
즉 변수는 값을 저장하고 참조하는 메커니즘으로, 값의 위치를 가리키는 상징적인 이름이다. 이 상징적인 이름은 컴파일러 또는 인터프리터에 의해 값이 저장된 메모리 공간의 주소로 치환되어 실행된다. 따라서 자바스크립트는 개발자가 직접 메모리 주소를 통해 값을 저장하고 참조할 필요없이 변수를 통해 안전하게 값에 접근할 수 있게 한다. </p>
<p>메모리 공간에 저장된 값을 식별할 수 있는 고유한 이름을 변수명이라하고 그 변수에 저장된 값을 변수 값이라고 한다. 또한 변수에 값을 저장하는 것을 할당이라 하고, 저장된 값을 읽어 들이는 것을 참조라 한다. 
즉 변수명은 사람을 위해 사람이 이해하기 쉬운 언어로 주소값에 별칭(상징적인 이름)을 지어주는 것이다. 변수명을 사용해 참조를 요청하면 자바스크립트 엔진은 변수 이름과 매핑된 메모리 주소를 통해 메모리에 접근하여 저장된 값을 반환한다. </p>
<p>코드는 컴퓨터에게 내리는 명령이지만 개발자를 위한 문서이기도 하다. 따라서 개발자의 의도를 나타내는 명확한 네이밍은 코드를 이해하기 쉽게 만들기 때문에 첫아이 이름을 짓듯이 심사숙고해서 지어야 한다. </p>
<h2 id="42-식별자">4.2. 식별자</h2>
<p>변수뿐만 아니라 모든 식별자를 사용하기 위해선 선언이 필요하다. </p>
<hr>
<p>식별자는 어떤 값을 구별해서 <strong>식별할 수 있는 고유한 이름</strong>으로 사람을 이름으로 구별해서 식별하듯 값도 식별자로 구별하여 식별할 수 있다. 
또한 식별자라는 용어는 변시 이름에만 사용되지 않고 함수, 클래스 등의 이름 모두 식별자로서 <strong>선언</strong>에 의해 자바스크립트 엔진에 식별자의 존재를 알린다. </p>
<h2 id="43-변수-선언">4.3. 변수 선언</h2>
<p>값을 할당하기 위한 준비</p>
<hr>
<p>변수 선언을 통해 메모리 공간상 저장될 값의 공간을 확보하고 공간의 주소와 변수명을 연결하여 값을 저장 (할당) 할 수 있게 준비하는 것이다. 이렇게 확보된 메모리 공간은 해제되기 전까지는 누구도 확보된 메모리 공간을 사용할 수 없도록 보호된다.</p>
<p><strong>변수를 사용하려면 반드시 var, let, const 키워드를 사용한 선언이 필요하다.</strong></p>
<blockquote>
<p><strong>키워드</strong>는 자바스크립트 코드를 해석하고 실행하는 자바스크립트 엔진이 수행할 동작을 규정한 일종의 명령어다. 자바스크립트 엔진은 키워드를 만나면 자신이 수행해야 할 약속된 동작을 수행한다. 예를 들어, var 키워드를 만나면 자바스크립트 엔진은 뒤에 오는 변수 이름으로 새로운 변수를 선언한다. </p>
</blockquote>
<pre><code>//예제
var score;</code></pre><p>위 변수 선언문은 변수 이름을 등록하고 저장할 메모리 공간을 확보한다. 
값이 할당되어 있지 않다고 하더라도 선언으로 인해 확보된 메모리 공간은 비어있지 않고 자바스크립트 엔진에 의해 <strong>undefined</strong>라는 값이 암묵적으로 할당되어 초기화된다. 
이는 자바스크립트의 독특한 특징으로 다음과 같은 2단계에 거쳐 변수 선언을 수행한다.</p>
<ul>
<li>선언 단계: 변수 이름을 등록해서 자바스크립트 엔진에 변수의 존재를 알린다. (변수를 실행 컨텍스트의 변수 객체에 등록하는 단계)</li>
<li>초기화 단계: 값을 저장하기 위한 메모리 공간을 확보하고 암묵적으로 undefined를 할당해 초기화한다. </li>
</ul>
<p>초기화란 변수가 언언된 이후 최초로 값을 할당하는 것으로 var 키워드로 선언한 변수는 undefined로 암묵적으로 최기화가 자동 수행된다. 따라서 키워드로 선언했지만 할당되지 않은 변수는 undefined라는 값을 갖는다. 이 초기화 단계를 거치는 이유는 확보된 메모리 공간에는 이전에 다른 어플리케이션이 사용했던 값이 남아 있는 수 있기 때문이다. 이러한 값을 쓰레기 값이라고 하는데 메모리 공간 확보 후 초기화 단계를 통해 쓰레기 값이 참조되는 것을 예방할 수 있다. </p>
<h2 id="44-변수-선언의-실행-시점과-변수-호이스팅">4.4. 변수 선언의 실행 시점과 변수 호이스팅</h2>
<p>자바스크립트 코드는 인터프리터에 의해 한 줄씩 순차적으로 실행된다. 호이스팅된 변수 선언은 빼고</p>
<hr>
<pre><code class="language-javascript">//예제
console.log(score)
var score</code></pre>
<p>위 예제에서 console.log(score)가 실행되면 참조 에러가 발생할 것 같지만 실은 undefined가 출력된다.
그 이유는 변수 선언이 런타임이 아니라 그 이전단계에서 먼저 실행되기 때문이다. 
자바스크립트 엔진은 소스코드를 실행하기에 앞서 평과 과정을 거치며 소스코드 실행을 위한 준비를 하는데 이때 엔진은 변수 선언을 포함한 모든 선언문을 소스코드에서 찾아내 먼저 실행한다. 
이러한 과정이 포함된 평과 과정이 끝나면 모든 선언문을 제외한 소스코드를 한 줄씩 순차적으로 실행한다. 
이렇게 <strong>변수 선언문이 마치 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트의 고유의 특징을 변수 호이스팅이라고 한다.</strong>
추가로 var, let, const, function, function*, class 키워드를 사용해서 선언하는 모든 식별자는 호이스팅된다. </p>
<blockquote>
<p><em>+TDZ 리서치 후 추가 필요(var, let, const 선언의 라이프 사이클)</em> </p>
<p>let, const선언 변수는 호이스팅되지 않는 것이 아니다. 스코프에 진입할 때 변수가 만들어지고 TDZ(Temporal Dead Zone)가 생성되지만, 코드 실행이 변수가 실제 있는 위치에 도달할 때까지 액세스할 수 없는 것이다. let/const변수가 선언된 시점에서 제어흐름은 TDZ를 떠난 상태가 되며, 변수를 사용할 수 있게 된다.</p>
</blockquote>
<h2 id="45-값의-할당">4.5. 값의 할당</h2>
<p>값의 할당은 런타임에 실행된다. </p>
<hr>
<p>할당 연산자 =를 사용하여 변수에 값을 할당한다.</p>
<pre><code class="language-javascript">//변수 선언과 값의 할당이 나누어져서 이뤄지는 케이스
var score;
score=80;

// 변수 선언과 갑의 할당이 하나의 문으로 실행
var score = 80;</code></pre>
<p>위 예제의 2개의 코드 라인은 정확히 동일하게 동작한다. 
하나의 문으로 단축 표현해도 선언과 할당을 2개의 문으로 나누어 각각 실행한다.
따라서 변수 선언과 값의 할당의 실행 시점이 다르다.
<strong>변수선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행되고
값의 할당은 소스코드가 순차적으로 실행되는 시점인 런타임에 실행된다.</strong> </p>
<p>재미있는 부분은 초기화 단계에서 변수 (메모리 공간)에 undefined가 할당된 후 변수에 값을 할당할 때는 이전 값이 저장되어 있던 메모리 공간을 지우고 그 공간에 값을 새롭게 저장하는 것이 아닌
새로운 공간을 확보하고 그곳에 값을 할당한다. </p>
<h2 id="46-값의-재할당">4.6. 값의 재할당</h2>
<p>이미 값이 할당된 변수에 새로운 값을 또다시 할당해보자. 단, const는 빼고</p>
<hr>
<pre><code class="language-javascript">var score = 80;
score = 90;</code></pre>
<p>var 키워드로 선언한 변수는 값을 재할당할 수 있다. 
엄밀히 따지고보면 var키워드로 선언한 변수는 선언과 동시에 undefined로 초기화 되기 때문에 변수에 처음 값을 할당하는 것도 사실은 재할당이다. 
어찌되었든 변수에 값을 재할당을 하게되면 이전 값이 저장되어 있던 메모리 공간을 지우고 재할당값을 새롭게 저장하는 것이 아니라 새로운 메모리 공간을 확보하고 그 메모리 공간에 재할당 값을 저장한다. 
그 결과로 변수의 이전값들은 어떤 변수도 값으로 갖고 있지 않는다. 즉 어떤 식별자와도 연결되어 있지 않다. 
이러한 불필요한 값들은 가비지 콜렉터에 의해 메모리에서 자동 해제된다. 단 언제인지는 예측 불가이다. </p>
<h2 id="47-마무리">4.7. 마무리</h2>
<p>어플리케이션의 근본은 데이터를 다루는 소프트웨어다. 아무리 복잡한 기능의 어플리케이션이라도 핵심은 데이터를 입력받아 처리하고 그 결과를 출력하는 것이다. 이런 어플리케이션은 프로그래밍 언어로 만들어지고 그 언어에서 변수는 데이터를 관리하기 위한 핵심 개념이다. </p>
<p>이 중요한 변수는 식별자로도 불리며 값을 지닌 듯 보이지만 사실 메모리 주소를 기억(참조)하고 있는, 인간이 프로그래밍을 함에 있어서 도움을 주기위한 메모리 주소값에 대한 인간 언어로 된 별명 정도이다. 따라서 프로그래밍적뿐만 아니라 현실 혹은 실전에서도 변수는 중요하다. 프로그래밍은 절대 혼자서 행해지지 않고 같이 협업을 통해 이뤄지기 때문이다. 즉 네이밍 규칙을 잘 협의하고 준수해야한다. 이는 함께 프로그래밍을 하는 사람들간 서로의 커뮤니케이션을 원할하게 도와준다. 명확한 커뮤니케이션은 변수의 존재 목적을 쉽게 이해할 수 있도록 의미를 명확하게 표현하고 일관성을 지킴으로 인해 높아진 가독성이 큰 도움이 되기 때문이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 Deep Dive] 프로그래밍과 자바스크립트]]></title>
            <link>https://velog.io/@_jouz_ryul/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive</link>
            <guid>https://velog.io/@_jouz_ryul/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive</guid>
            <pubDate>Thu, 03 Feb 2022 05:32:29 GMT</pubDate>
            <description><![CDATA[<h1 id="1-프로그래밍">1. 프로그래밍</h1>
<h2 id="11-프로그래밍이란">1.1. 프로그래밍이란?</h2>
<p>프로그래밍이란 0과 1밖에 알지 못하는 기계가 실행할 수 있을 정도로 <strong>정확하고 상세하게 요구사항을 설명하는 작업</strong>을 코드로 명령을 전달하는 것이다.</p>
<h2 id="12-프로그래밍-언어">1.2. 프로그래밍 언어</h2>
<p>이때 명령을 수행할 주체인 컴퓨터가 이해할 수 있는 언어, 즉 기계어로 명령을 전달해야하는데 이는 인간이 사용하는 언어와는 너무나도 체계가 다르기 때문에 매우 어려운 일이다.
따라서 가장 좋은 방법은 사람이 이해할 수 있는 약속된 구문 (문법:syntax)으로 구성된 <strong>프로그래밍 언어</strong>를 사용해 프로그램을 작성한 후 그 언어를 기계어로 변환하는 <strong>컴파일러</strong> 또는 <strong>인터프리터</strong> (번역기)를 이용하는 것이다. </p>
<p>다시말해 프로그래밍 언어란 사람과 컴퓨터 (컴파일러 또는 인터프리터) 모두가 이해할 수 있는 약속된 형태의 인공어이며 컴퓨터와 인간간 소통 (컴퓨터로의 명령)에 사용되는 일종의 표현수단이다. 
즉 프로그래밍은 프로그래밍 언어를 사용해 컴퓨터에게 실행을 요구하는 일종의 <strong>커뮤니케이션</strong>이며 <strong>구문(syntax)</strong> 과 <strong>의미(semantic)</strong> 의 조합으로 표현될 수 있다. </p>
<h2 id="13-구문과-의미">1.3. 구문과 의미</h2>
<p>결국 프로그래밍은 요구사항의 집합을 분석해서 적절한 자료구조와 함수의 집합으로 변환한 후 (구문), 그 흐름을 제어(의미)를 통해 컴퓨터에게 실행을 요구하는 커뮤니케이션이다.</p>
<h1 id="2-자바스크립트란">2. 자바스크립트란?</h1>
<h2 id="25-자바스크립트의-특징">2.5. 자바스크립트의 특징</h2>
<p>웹 브라우저에서 동작하는 유일한 프로그래밍 언어로 개발자가 별도의 컴파일 작업을 수행하지 않는 <strong>인터프리터 언어</strong>다. 인터프리터는 소스코드를 즉시 실행하고 컴파일러는 빠르게 동작하는 머신 코드를 생성하고 최적화하는 방법으로 대부분의 모던 자바스크립트 엔진 (크롬 V8)은 두 언어의 특징을 결합해 비교적 처리 속도가 느린 인터프리터의 단점을 해결했다. </p>
<blockquote>
</blockquote>
<p><em>[컴파일러 언어와 인터프리터 언어의 비교]</em><img src="https://images.velog.io/images/_jouz_ryul/post/c1f1e039-2694-4dd6-9de9-491efd7fafcb/Screen%20Shot%202022-02-03%20at%202.40.39%20PM.png" alt="컴파일러 언어와 인터프리터 언어의 비교"></p>
<blockquote>
<blockquote>
<p>대부분의 모던 브라우저에서 사용되는 인터프리터는 복장한 과정을 거치며 일부 소스코드를 컴파일한다. </p>
</blockquote>
</blockquote>
<p>또한 자바스크립트는 명령형, 함수형, 프로토타입 기반 객체지향 프로그래밍을 지원하는 <strong>멀티 패터다임 프로그래밍 언어</strong>로 클래스 기반 객체지향 언어보다 효율적이면서 강력한 <strong>프로토타입 기반의 객체지향 언어</strong>이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React에 GraphQL 한스푼 더하기: 2. Apollo Client]]></title>
            <link>https://velog.io/@_jouz_ryul/React%EC%97%90-GraphQL-%ED%95%9C%EC%8A%A4%ED%91%BC-%EB%8D%94%ED%95%98%EA%B8%B0-2.-Apollo-Client</link>
            <guid>https://velog.io/@_jouz_ryul/React%EC%97%90-GraphQL-%ED%95%9C%EC%8A%A4%ED%91%BC-%EB%8D%94%ED%95%98%EA%B8%B0-2.-Apollo-Client</guid>
            <pubDate>Sun, 16 Aug 2020 08:50:18 GMT</pubDate>
            <description><![CDATA[<h1 id="0-why">0. why?</h1>
<p>다시 말하지만 graphQL은 graphQL 서버와 통신하기 위한 쿼리 언어일뿐 서버 통신 방법이 아닐뿐더러 graphQL 역시 비동기로 처리가 된다. 
지난번 블로깅을 통해 graphQL 서버에 <strong>QUERY</strong>라는 요청하는 방법, 더 자세히는 문법에 대해 알아보았다. 
여러가지 문법을 통해 원하는대로 요청을 보내고 원하는대로 응답을 받고 또한 여러 상황에 대해서 서버와 통신하는 graphQL만의 문법을 알아보았다. 
그렇다면 실제로 서버와의 통신과정과 통신을 통한 응답을 우리가 만드는 어플리케이션에 가져올 수 있을까?</p>
<h1 id="10-apollo-client">1.0. Apollo Client</h1>
<blockquote>
<p>Apollo Client is a fully-featured caching GraphQL client with integrations for React, Angular, and more. It allows you to easily build UI components that fetch data via GraphQL.
출처:<a href="https://www.npmjs.com/package/apollo-client">npmjs-apollo-client</a></p>
</blockquote>
<p><a href="https://www.npmjs.com/">npmjs.com</a>에 나온 <code>Apollo Client</code>에 대한 설명이다. <code>graphQL API</code>를 어플리케이션 내에서 사용할 때 유용한 package들이 여러개 있는데 (예를 들면 페이스북의 <code>relay</code>) <code>Apollo Client</code>가 최고이며 가장 많이 사용된다고 하는데 이유들은 다음과 같다. </p>
<ol>
<li><code>Apollo Client</code>는 개발자로 하여금 <code>graphQL</code>을 통한 local과 remote 데이터 관리가 가능하게 해주는 종합적인 자바스크립트 상태관리 라이브러리 이고 (apollo의 cache 기능과 관련이 있다. 나중에 깊게 정리할 예정)</li>
<li>경제적이고, 예측 가능하고 선언적인 방법인 모던한 개발 방식과 일관되도록 코드를 작성하도록 도와주고</li>
<li>그 어떤 프레임워크던지 관계없이 자바스크립트 프론트엔드로 하여금 graphQL 서버로 부터 데이터 통신이 가능하고</li>
</ol>
<p>등등의 이유가 있다.
하지만 개인적으로 <code>Apollo Client</code>가 <code>graphQL</code>과 찰떡궁합인 이유는 (비록 relay를 사용해보지 못하였지만) <code>graphQL API</code>의 작동원리에 있다고 생각한다. </p>
<h2 id="11-graphql-api와-rest-api">1.1. graphQL API와 REST API</h2>
<p><code>graphQL API</code>의 작동방법을 간단하게 살펴보면 결국은 <code>fetch</code>이다. 
이 말이 무슨 뜻이냐 하면 <code>graphQL API</code>는 결국은 <code>REST API</code>와 다를바 없다는 뜻이다. 
REST API는 <code>url</code>로 접근하여 원하는 <code>method</code>를 코드로 작성하여서 서버와 통신을 한다. 
<code>graphQL</code>은 이와는 조금 다르게 단 하나의 <code>endpoint</code>인 <code>url</code>에 접근하여 원하는 방식과 데이터 필드를 <code>query</code>와 <code>mutation</code>을 통해서 통신한다. 
하지만 조금만 더 깊게 살펴보면 <code>graphQL API</code>는 기본적으로 우리가 원하는 정보를 query나 mutation으로 작성하여 <code>Axios</code>의 <code>fetch</code>와 함께 <code>POST</code> request를 서버로 보낸다. 
<code>graphQL API</code>는 모두 단 하나의 <code>endpoint</code>를 가진다는 차이점을 제외하면 결국 통신은 <code>fetch</code>,<code>POST</code> 등으로 이뤄진다는 점에서 큰 차이점은 없다. </p>
<p><img src="https://images.velog.io/images/_jouz_ryul/post/1ddf647d-0f97-4ce0-a0da-50cf0a5dd143/%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%202020-08-16%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%204.57.09.png" alt="">
위 이미지의 빨간색 박스 두개를 보듯이 실제 graphQL 통신은 <code>fetch</code>타입에 <code>POST</code> method임을 알 수 있다.
즉 apollo-client와 같은 패키지 없이 graphQL 서버와 통신하기 위해서는 우리가 원하는 정보와 함께 작성한 query를 Axios의 fetch와 함께 POST request로 보내야한다. 그 방법이 존재하는지 어떻게 하는지 알지도 못하지만 매우 복잡해 보이고 번거로워보인다. 
그래서 <code>apollo-client</code>를 이용하면 <code>apollo</code>가 직접 이런 방식으로 알아서 서버와 통신을 가능케 해주고 모든 설정을 다 자동으로 해주는 package를 제공해준다. </p>
<h1 id="20-react에-apollo-client-더하기">2.0. REACT에 Apollo-client 더하기</h1>
<p>위의 이유들 중 가장 손꼽히는 <code>apollo</code>의 장점은 cache기능으로서 불필요한 서버 통신을 최대한으로 줄여준다. 
더 나아가 리액트 개발자로서 <code>apollo-client</code>가 제공해주는 여러 <code>hook</code>들은 나로 하여금 <code>apollo</code>를 사용하지 않을 이유가 전혀 없다고 본다. 
물론 react말고도 다른 javascript 프론트엔드 프레임워크에서도 사용이 가능하지만 이상하리만큼 REACT에 대한 기능 제공이 많다. 
그럼 너무 감사하니 한번 기본 세팅을 적용해보자. 
<strong>Apollo-client에서 사용하는 여러 페키지가 있었지만 지금은 core-package하나면 충분히 사용이 가능하게 update되었다</strong></p>
<p><code>npm install @apollo/client graphql</code>
요 2개의 패키지만으로도 충분히 사용 가능하다.</p>
<p><code>@apollo/client</code>: 
이 싱글 페키지는 Apollo Client를 세팅하기 위해 필요한 사실상 거의 모든것이 들어있다. 
[in-memory cache, local state management, error handling, and a React-based view layer] 등등 graphQL서버와 통신을 위해 사용하는 <code>Apollo Client</code> 세팅을 할 수 있게 해준다.
<code>graphql</code>: 이 패키지는 <code>GraphQL</code> 쿼리들을 파싱하는 로직들을 제공해준다. </p>
<p>또한 <code>apoll-client</code>자체가 커뮤니티 오픈 소스 기반으로 개발된 라이브러리라 <a href="https://www.apollographql.com/docs/link/links/community/#gatsby-focus-wrapper">customized되고 공식 문서에서 인증해주는 패키지들</a>도 존재한다.</p>
<h2 id="21-client-설정하기">2.1. Client 설정하기</h2>
<p>역시나 <a href="https://www.apollographql.com/docs/react/get-started/">공식문서</a>에 잘 설명이 되어있다. 특히 react관련은 더더욱 다양하고 자세한 설명이 존재한다. 
공식문서에 따라 천천히 설정해보자. </p>
<pre><code class="language-javascript">import { ApolloClient, InMemoryCache } from &#39;@apollo/client&#39;;
import { gql } from &#39;@apollo/client&#39;;


const client = new ApolloClient({
  uri: &#39;endpoint of your graphQL server&#39;,
  cache: new InMemoryCache()
});

client
// client에 접근하여
  .query({
  // query요청임을 명시해주고
    query: gql`
      query GetRates {
        rates{
          currency
        }
      }
    `
  // query에서 우리가 원하는 내용을 명시해준다.
  // 이렇게 직접 명시도 가능하지만 지난번 블로그에서 정리했듯이 query내용을 직접 다른 파일에 정의해놓고 import해서 사용도 가능하다. 
  })
  .then(result =&gt; console.log(result));
// fetch타입의 post method임으로 Promise패턴으로 접근이 가능하다. 
</code></pre>
<p>이게 기본적인 <code>client</code> 설정과 그 설정에 접근하여 실제로 <code>Apollo-client</code> 도움으로 <code>graphQL</code> 서버와 통신하는 방법이다. 
하지만 우리는 개발자이기에 매번 요청마다 <code>client</code>를 설정하여 서버와 통신하는 방법보다 조금 더 개발자스러운 방법으로 해보자.</p>
<h2 id="22-provider">2.2. Provider</h2>
<p><code>Provider</code> 패턴을 통해 매번 <code>client</code>를 정의할 필요없이 <code>props</code>로 받아서 사용해보자. </p>
<pre><code class="language-javascript">import React from &#39;react&#39;;
import { render } from &#39;react-dom&#39;;

import { ApolloProvider } from &#39;@apollo/client&#39;;
import { ApolloClient, InMemoryCache } from &#39;@apollo/client&#39;;

function App() {
  const client = new ApolloClient({
  uri: &#39;https://48p1r2roz4.sse.codesandbox.io&#39;,
  cache: new InMemoryCache()
  });
  return (
    &lt;ApolloProvider client={client}&gt;
      &lt;div&gt;
        &lt;h2&gt;My first Apollo app 🚀&lt;/h2&gt;
      &lt;/div&gt;
    &lt;/ApolloProvider&gt;
  );
}

render(&lt;App /&gt;, document.getElementById(&#39;root&#39;));
</code></pre>
<p>이런식으로 <code>Provider</code> 패턴을 통해 <code>Provider</code>에 의해 감싸진 컴포넌트들은 어느 곳에서든 <code>client</code>를 <code>props</code>로 받아서 
서버와 통신이 가능해진다. </p>
<pre><code class="language-javascript">// getExchangeRatesQuery.js
import { gql } from &#39;@apollo/client&#39;;
export const EXCHANGE_RATES = gql`
  query GetExchangeRates {
    rates {
      currency
      rate
    }
  }
`;

// ExchangeRates.js
import { useQuery} from &#39;@apollo/client&#39;;
import {EXCHANGE_RATES} from &#39;getExchangeRatesQuery.js&#39;

function ExchangeRates() {
  const { loading, error, data } = useQuery(EXCHANGE_RATES);

  if (loading) return &lt;p&gt;Loading...&lt;/p&gt;;
  if (error) return &lt;p&gt;Error :(&lt;/p&gt;;

  return data.rates.map(({ currency, rate }) =&gt; (
    &lt;div key={currency}&gt;
      &lt;p&gt;
        {currency}: {rate}
      &lt;/p&gt;
    &lt;/div&gt;
  ));
}</code></pre>
<p>이렇게 <code>hook</code>사용이 가능한 함수형 컴포넌트에서는 <code>apollo-client</code>가 제공해주는 <code>hook</code>으로 사용이 가능하며
class형 컴포넌트에서는 <code>props.client</code>로 접근하여 사용이 가능해진다.</p>
<h1 id="30-마무리">3.0. 마무리</h1>
<p>이번 블로그에서 <code>client</code> 설정 즉, <code>apollo-client</code>를 설정하는 다양한 방법에 (Link, onError 등등) 대해서 함께 정리하려했다.
하지만 정말 이번주도 바쁘고 다음주도 바쁠예정이라 오늘은 블로깅이 부끄럽게 느껴질만큼 간단하지만 여기서 마무리 하려 한다. 
다음 블로깅에서는 다양한 client 설정 방법과 옵션설정들에 대해서 알아보고 추가로 실제로 <code>accessToken</code>과 <code>refreshToken</code>을 이용한 
인증 인가 부분을 개발하며 했었던 삽질과 해결 방법을 통해 <code>Apollo-client</code>의 error handling에 대해서 정리할 계획인다. 
개발하며 정리하고 넘어가고 싶은 부분이 정말 많은데 매번 일정에 쫒겨 정리를 못하는 모습에 반성만 하고 있는 내모습에 다시한번 반성하며 이번 블로깅은 여기서 끝.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[React에 GraphQL 한스푼 더하기:
1. graphQL 맛보기]]></title>
            <link>https://velog.io/@_jouz_ryul/React%EC%97%90-GraphQL-%ED%95%9C%EC%8A%A4%ED%91%BC-React-Apollo-%ED%95%9C%EC%8A%A4%ED%91%BC-%EB%8D%94%ED%95%98%EA%B8%B0-1</link>
            <guid>https://velog.io/@_jouz_ryul/React%EC%97%90-GraphQL-%ED%95%9C%EC%8A%A4%ED%91%BC-React-Apollo-%ED%95%9C%EC%8A%A4%ED%91%BC-%EB%8D%94%ED%95%98%EA%B8%B0-1</guid>
            <pubDate>Sun, 02 Aug 2020 13:50:20 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/_jouz_ryul/post/d9da9d44-50aa-4788-a4cd-fe0ec26075e7/kakaoTech_Img_04.png" alt=""></p>
<h1 id="0-why">0. Why?</h1>
<p>회사에서 graphQL을 사용함에 따라 간간히 공식문서와 니콜라스의 영상을 보며 개발을 하고있던 중
동료 개발자들과의 수다에서 이런 의문이 나왔다.
&quot;우리가 과연 graphQL을 사용한다고 말할 수 있을까요?&quot;
우리는 모두 아니라고 대답했고 제대로 사용하고 있는 것 같지도 않다고 대답했다. 
그냥 요청을 보내면 응답을 보내주는 수준이라고 말해 개발팀 모두가 빵터진적도 있었다.
적어도 일주일에 블로그 하나씩 작성하자는 다짐은 밀리고 밀리는 task들에 밀려 지켜지지 못했고
graphQL을 정리해보자라는 생각을 가진지 한달이 지나서야 겨우 글을 끄적이게 되었다. 
사실 지금도 일정에 맞춰 개발하기 위해 개발을 해야하지만
그간 graphQL과 Apollo를 겉핧기식으로 알고 사용하면서 한 이슈에 대해서 3시간 혹은 반나절의 시간을 낭비(?)하는 일들도 있었으니
나중을 위한 투자가 되지 않을까 라는 변명으로 잠시 개발을 쉬고 정리를 해보려한다.</p>
<p>GraphQL을 사용해보니 정말 좋은점은, 프론트엔드로서, 너무 편하다. 스키마에 정의된 타입들을 잘 정리해서 정의해주고 
원할 떄 쿼리와 뮤테이션을 사용하여 서버와 통신을 하면 끝이다. 
(반대로 백엔드에서 정말 과하다 싶을정도로 모든 로직 등등을 다 처리해준다.)
또한 cache 기능, 사용자가 우리 서비스를 사용하는 과정에 있어서 받아와서 사용하는 데이터들 중 그 특정 과정 떄문에 발생하는 
데이터의 null 값, 빈값 혹은 undefined 등등의 데이터 값을 처리하는 과정에 있어서 너무나도 편리하게 처리가 가능했다. 
REST와 비교하면 정말 편리하다. (페이스북 팀이 Native Mobile App에 사용하기 위해 사용했다는 이유가 너무나도 납득이 된다.)
또한 같이 사용하는 Apollo 라는 상태관리 라이브러리와도 궁합이 너무 좋은데
Apollo client에서 제공해주는 client/cache를 이용하면 사실상 global statemanagement도 가능하다.
거기에 React를 사용하는 개발자로서 hook이 제공된다는 점이 너무나도 좋다.(매일매일 apollo를 향해 절하고 싶은 마음이 들정도로)</p>
<p>이렇게 사용하기 편한만큼 GraphQl 공식문서만 봐도 너무나도 쉽게 사용이 가능하다. 
먼저 GraphQL에 대해서 알아보자.</p>
<h1 id="1-graphql">1. GraphQL</h1>
<blockquote>
<p>GraphQL 은 API를 위한 쿼리 언어이며 타입 시스템을 사용하여 쿼리를 실행하는 서버사이드 런타임입니다.
출처: <a href="https://graphql-kr.github.io/learn/">https://graphql-kr.github.io/learn/</a></p>
</blockquote>
<p>이렇게 공식문서에서 설명해주고 있다. 쉽게 말하자면 언어이자 문법이라고 생각하면 된다. 
REST와 가장 큰 차이점은 GraphQL은 단 하나의 endpoint만 가지고 있다는 것이다. 
말로 하니 어렵다. 코드로 살펴보자</p>
<pre><code class="language-json">{
  &quot;user&quot; : {
    &quot;name&quot; : &quot;Lee&quot;,
    &quot;age&quot; : 30,
    &quot;phoneType&quot;: &quot;IPhone&quot;
  }
}</code></pre>
<p>위와 같은 데이터를 서버로부터 받는다고 가정해보자. </p>
<p>REST API는 아래와 같이 요청할 것이다. </p>
<pre><code class="language-javascript">// REST API
fetch(&#39;http://example.com/user.json&#39;)
  .then(response =&gt; response.json())
  .then(data =&gt; console.log(data));</code></pre>
<p>GrapQL은 아래와 같이 요청하면 된다. </p>
<pre><code class="language-javascript">query {
  user {
    name
    age
    phoneType
  }
}</code></pre>
<p>여기서 큰 차이점이 하나 더 존재한다. 
만약 해당 API를 통해서 우리가 필요한 데이터가 <code>name</code>뿐이라고 치자.
그럼 우리는 쓸데없는 <code>age</code>와 <code>phoneType</code>의 데이터도 받아와야한다.
하지만 GraphQL은 <code>name</code>만 뽑아서 받아올 수 있다.
아래처럼</p>
<pre><code class="language-javascript">query {
  user {
    name
  }
}</code></pre>
<p>Facebook이 gql을 사용하게 된 이유도 </p>
<ol>
<li>커져만 가는 어플리케이션</li>
<li>증가하는 서버로부터 받아오는 데이터의 양</li>
<li>모바일로 서비스를 접속하고 이용하는 사용자가 증가</li>
</ol>
<p>한다는 점에서 데이터 통신을 가볍게(?)하기 위해서라는 것이 이해가 가는 부분이다. </p>
<p>이렇게 gql 언어를 사용하면 REST와 동일하게 서버로부터 요청을 통해 응답으로 데이터를 받을 수 있다. 
그럼 이 언어의 형태와 구성 그리고 문법에 대해서 알아보자. </p>
<h1 id="2-query--mutation">2. Query &amp; Mutation.</h1>
<p><code>Query</code>와 <code>Mutation</code>은 GraphQL 쿼리 언어로 실행할 수 있는 작업 유형들이다. 
이들 외에도 <code>Subscription</code>이라는 작업 유형이 존재한다. 
<img src="https://images.velog.io/images/_jouz_ryul/post/63b57cb5-ebd2-43cd-9879-71d919d42e16/%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%202020-08-02%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.18.45.png" alt=""></p>
<p><code>Subscription</code>은 웹소켓을 통한 실시간 양방향 통신을 구현할 때 사용되는데 이는 나중에 웹소켓을 정리하며 같이 정리하도록 하고
<code>Query</code>와 <code>Mutation</code>은 기본 REST API에서 CRUD인 <code>POST</code>, <code>GET</code>, <code>DELETE</code> 등등을 담당한다고 보면된다. 
그림에 나와있는 것처럼 <code>Query</code>는 GET, <code>Mutation</code>은 POST, PUT, DELETE 등의 행위를 하는 작업 유형이다. 
이들은 <code>Schema</code>와 <code>Docs</code>에 명시된, 일종의 API 명세에 입각하여 작성하면 된다. 
실제 Query와 Mutation의 실행에는 상태관리를 도와주는 Apollo Client 라이브러리를 주로 사용하는데 
이에 대한 설명과 방법은 다음 블로그에서 하고 이번 블로그에서는 작성법에 초점을 맞춰서 정리해보자. 
또한 <code>Query</code>와 <code>Mutation</code> 작업 유형의 실행을 &quot;서버에 쿼리를 날린다&quot; 혹은 &quot;서버에 쿼리를 한다&quot; 라고 통칭으로 사용한다. 
따라서 이에 입각하여 쿼리하는 방법에 대해서 알아보자. 그리고 그 전에 Schema와 Docs에 대해서 간단하게 정리를 먼저 해보자.</p>
<h1 id="3-schema--docs">3. Schema &amp; Docs</h1>
<p>Schema와 Docs는 API에 대한 명세라고 봐도 무방하다. 
쿼리 요청을 작성함에 있어 형태와 필요 요소가 정리된 문서 라고 생각하면 쉽다. 
그래도 말로만하니 뭔지 모르겠다.
예제를 살펴보자.</p>
<p><img src="https://images.velog.io/images/_jouz_ryul/post/124cf324-93a4-4691-b5d6-825fe8e326bd/%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%202020-08-02%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.41.52.png" alt=""><img src="https://images.velog.io/images/_jouz_ryul/post/e243f02d-4895-40ac-b042-edc0a3c0f75c/%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%202020-08-02%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.39.46.png" alt=""></p>
<p>위와 같이 Docs에는 우리가 요청할 수 있는 <code>Fields</code>들의 목록이 나와있다. 
그리고 Schema에는 <code>Fields</code>들의 목록과 함께 밑에 Type들이 명세되어 있는데 타입은 Fields들의 return의 형태,요소이자 모습이고
Fields는 우리가 받고자 하는 value의 key값들이라고 생각하면 쉽다. </p>
<h1 id="4-fields--types">4. Fields &amp; Types</h1>
<p>그래도 말로하니 어렵다. 위에 사용한 예제를 다시 가져와보자.</p>
<pre><code class="language-javascript">query {
  user {
    name
    age
    phoneType
  }
}</code></pre>
<p>위와 같이 서버에 쿼리를 하면 다음과 같은 응답이 올 것이다. </p>
<pre><code class="language-json">{
  &quot;user&quot; : {
    &quot;name&quot; : &quot;Lee&quot;,
    &quot;age&quot; : 30,
    &quot;phoneType&quot;: &quot;IPhone&quot;
  }
}</code></pre>
<p>위의 예제에서 <code>Fields</code>는 <code>user</code>, <code>name</code>, <code>age</code> 그리고 <code>phoneType</code>이다. 
그리고 응답으로 온 <code>Lee</code>, <code>30</code>, <code>IPhone</code> 그리고 그들을 포함하는 하나의 <code>객체</code>가 Types이다. 
이래도 어렵다. 실제 docs와 schema를 살펴보자. </p>
<p><img src="https://images.velog.io/images/_jouz_ryul/post/1b165380-7e85-4b5d-aac6-e8dfc8ed996c/%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%202020-08-02%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%208.53.04.png" alt=""></p>
<p>위의 사진에서 첫번째 칼럼에는 총 3개의 Fields가 존재한다. 이들 중 서버에 <code>collections</code>에 해당하는 데이터를 받아오자고 가정해보자. 
앞으로 우리가 작성할 요청은 우리가 특정한 fields로 구성된 하나의 객체를 서버로 요청하여 받아오는 것이다. 
그렇게 되면</p>
<ol>
<li><code>collections</code>는 해당 요청의 Field가 되고 이 field는 <code>Collection</code>이라는 GraphQL 객체타입들로 구성된 배열을 리턴한다. </li>
<li>두번째 칼럼에는 <code>Collection</code> 객체타입에 대해 나와있다. 즉 이 객체타입은 필드가 있는 타입으로 스키마는 대부분 객체타입이다. </li>
<li><code>id</code>, <code>title</code> 그리고 <code>items</code>는 <code>Collection</code> 타입의 필드들로서 GraphQL 쿼리의 <code>Collection</code> 타입 어디서든 사용이 가능한 필드다.</li>
<li><code>id</code>와 <code>title</code> 필드가 리턴하는 <code>ID</code>와 <code>String</code> 타입은 <code>Scalar</code>타입으로서 구체적인 데이터로 해석되는 쿼리의 끝이라고 보면 된다. 즉 <code>Collection</code> 타입이 <code>collections</code>필드의 하위 필드로서 존재하는것과 다르게 <code>Scalar</code>타입은 하위 필드가 존재하지 않는 데이터의 값 그 자체인 끝자락이라고 보면 된다. <code>Scalar</code>로서 존재할 수 있는 타입은 <a href="https://graphql-kr.github.io/learn/schema/#">공식문서 스키마-스칼라타입</a>에 잘 설명되어 있다. </li>
<li>반면 <code>items</code>필드는 <code>Item</code> 객체의 배열을 나타내고 있다. 즉 하위 필드를 작성해주어야 한다는 뜻이다. </li>
<li>세번째 칼럼을 보면 하위 필드로서 작성가능한 필드들이 명세되어있다. 여기서 데이터 타입뒤의 느낌표는 꼭 작성을 해줘야 하는 필드들이라고 보면 되고 느낌표가 없으면 필요에 의해서만 작성해주면 된다. </li>
</ol>
<p>역시 말로하니 뭔말인지 모르겠다. 직접 코드를 처보자.</p>
<pre><code class="language-javascript">query {
  id
  title
  items {
    id
    name
    price
    imageUrl
  }
}</code></pre>
<p>위와 같이 Docs를 보며 작성하면 된다. 
다시 말하지만 서버에 쿼리를 하는 것은 우리가 원하는 데이터들을 하나의 큰 객체안에 Fields로서 작성하여 요청하는 것이다. 
위에 대한 응답은 아래와 같을 것이다. </p>
<pre><code class="language-json">{
  &quot;data&quot;: {
    &quot;collections&quot;: [
      {
        &quot;id&quot;: &quot;cjwuuj5bz000i0719rrtw5gqk&quot;,
        &quot;title&quot;: &quot;Hats&quot;,
        &quot;items&quot;: [
          {
            &quot;id&quot;: &quot;cjwuuj5ip000j0719taw0mjdz&quot;,
            &quot;name&quot;: &quot;Brown Brim&quot;,
            &quot;price&quot;: 25,
            &quot;imageUrl&quot;: &quot;https://i.ibb.co/ZYW3VTp/brown-brim.png&quot;
          },
          {
            &quot;id&quot;: &quot;cjwuuj5j4000l0719l3ialwkj&quot;,
            &quot;name&quot;: &quot;Blue Beanie&quot;,
            &quot;price&quot;: 18,
            &quot;imageUrl&quot;: &quot;https://i.ibb.co/ypkgK0X/blue-beanie.png&quot;
          },
          {
            &quot;id&quot;: &quot;cjwuuj5je000n0719ch6nbhik&quot;,
            &quot;name&quot;: &quot;Brown Cowboy&quot;,
            &quot;price&quot;: 35,
            &quot;imageUrl&quot;: &quot;https://i.ibb.co/QdJwgmp/brown-cowboy.png&quot;
          },
          {
            &quot;id&quot;: &quot;cjwuuj5jh000p0719rtjatb2f&quot;,
            &quot;name&quot;: &quot;Grey Brim&quot;,
            &quot;price&quot;: 25,
            &quot;imageUrl&quot;: &quot;https://i.ibb.co/RjBLWxB/grey-brim.png&quot;
          },
          ...
        ]
      }
    ]
  }
}</code></pre>
<p>이게 기본적인 Query와 Mutation이다. 
Query와 Mutation은 단지 실행하는 작업 유형이 다를뿐 문법이나 형태는 둘이 동일하다. </p>
<p>그렇다면 어느 정도 감이 잡혔으면 문뜩 의문이 생길 것이다. 
만약 특정 id에 해당하는 데이터만 받아오고 싶으면 어떻게할 수 있을까?</p>
<h1 id="5-arguments">5. Arguments</h1>
<p>이는 우리가 함수에 인자를 넣어서 해당 인자에 대한 연산의 값이 return되듯이 
똑같이 Query와 Mutation에도 적용된다. 
위에 쿼리로 받아온 <code>collection</code> 객체의 배열중 첫번째 객체의 정보만 받아오고 싶으면 어떻게 해야할까?
이때 인자를 사용하면 된다. </p>
<p><strong>XX 물론 인자를 사용하는 부분은 apollo client를 사용해서 cache 데이터를 client 부분으로 사용이 가능하지만 이는 나중의 이야기이고 순수하게 사용하려면 백엔드에서 서버가 해당 인자를 인식하여 연산이 되도록 개발이 되어있어야한다. 해당 예제는 인자를 사용하는 로직이 개발이 되었다는 가정하에 정리하는 것XX</strong> </p>
<p><img src="https://images.velog.io/images/_jouz_ryul/post/f905dc60-35c7-40fb-80ed-40381637a2ba/%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%202020-08-02%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.11.11.png" alt="">
위와 같이 id를 받아 해당 id를 갖는 <code>Collection</code>타입의 필드들만 return 하는 API가 개발되어있다. 
우리가 할 일은 저 docs를 보고 단순히 작성해주면 된다. 
원하는 id값을 인자로 넣어주고 그 id에 해당하는 데이터 객체중 필요한 field를 작성해주면 된다. </p>
<pre><code class="language-javascript">query {
  collection (id:&quot;cjwuuprqs00240719lb9kvlqe&quot;) {
    id
    title
    items {
      id
      name
      price
      imageUrl
    }
  }
}</code></pre>
<p>그러면 아래와 같은 응답이 올것이다.
<img src="https://images.velog.io/images/_jouz_ryul/post/b39b58bb-6deb-4070-8726-dd7cf8108223/%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%202020-08-02%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.19.22.png" alt="">
만약 <code>items</code> 필드가 필요없다면 아래와 같이 요청하면 된다. </p>
<pre><code class="language-javascript">query {
  collection (id:&quot;cjwuuprqs00240719lb9kvlqe&quot;) {
    id
    title
  }
}</code></pre>
<p>그러면 아래와 같이 응답이 올 것이다. 
<img src="https://images.velog.io/images/_jouz_ryul/post/a314a6cf-845f-4a1a-8c22-5d41ff9f78eb/%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%202020-08-02%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.20.38.png" alt="">
이처럼 인자를 이용해서 해당 id에 match되는 field 값들을 가져왔다.
또한 인자와는 관련없이 내가 필요한 filed만 작성하여 쿼리하는 것은 모든 쿼리에 해당한다. </p>
<p>이제 슬슬 감이 잡히는 것 같다. 그럼 만약 위의 예제에서 더 나아가 2개의 id값에 해당하는 field만 가져오려면 어떻게 해야할까 궁금증이 생긴다. </p>
<h1 id="6-aliases">6. Aliases</h1>
<p>일명 별칭으로 각 결과 객체 필드가 동일한 타입을 리턴할 때 구분을 지을 수 있게 도와준다. 
만약 위의 예제에서 cjwuuprqs00240719lb9kvlqe와 cjwuuj5bz000i0719rrtw5gqk 두개의 아이디에 대한 데이터를 받아오려면 어떻게해야할까?</p>
<pre><code class="language-javascript">query {
  collection (id:&quot;cjwuuprqs00240719lb9kvlqe&quot;) {
    id
    title
  }
  collection (id:&quot;cjwuuj5bz000i0719rrtw5gqk&quot;) {
    id
    title
  }
}</code></pre>
<p>이렇게 쿼리를 하면 된다고 생각할 수 있지만 이렇게 하면 
<code>&quot;Fields \&quot;collection\&quot; conflict because they have differing arguments. Use different aliases on the fields to fetch both if this was intentional.&quot;</code>
이렇게 다른 aliases 즉 별칭을 사용하라는 에러 메시지가 나온다. 
그럼 원하는대로 별칭을 사용해보자.</p>
<pre><code class="language-javascript">query {
  firstUser: collection (id:&quot;cjwuuprqs00240719lb9kvlqe&quot;) {
    id
    title
  }
  secondUser: collection (id:&quot;cjwuuj5bz000i0719rrtw5gqk&quot;) {
    id
    title
  }
}</code></pre>
<p>과연 요청에 대한 응답은 데이터일것인가 아니면 에러 메시지일것인가</p>
<p><img src="https://images.velog.io/images/_jouz_ryul/post/eda8e544-e2c6-49b5-97f0-7d71236f719e/%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%202020-08-02%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.27.38.png" alt="">
짜잔! 두개의 별칭으로 나뉘어져 값이 들어왔고 추후에도 우리는 각각의 별칭으로 response에 접근/할당 하여 사용할 수 있게 된다. 
근데 찐 개발자는 반복되는 코드를 싫어해야한다고 들었다. 
찐개발자 흉내를 내보려보니 <code>id</code>와 <code>title</code> 두개의 fields를 반복적으로 작성하는게 귀찮다. 방법이 없을까?</p>
<h1 id="7-fragment">7. Fragment</h1>
<p>반복적으로 사용되는 value 등을 변수에 담아 혹은 더 나아가 변수에 담아 여러곳에서 사용하듯이
쿼리에서도 사용해보자!
기본적인 Fragment의 형태는 </p>
<pre><code class="language-javascript">fragment &lt;FragmentName&gt; on &lt;Type Name&gt; {
  &lt;fieldName&gt;
  &lt;fieldName&gt;
}</code></pre>
<p>이와 같다. 그럼 적용해보자!</p>
<pre><code class="language-javascript">query {
  firstUser: collection (id:&quot;cjwuuprqs00240719lb9kvlqe&quot;) {
    ...collectionFields
  }
  secondUser: collection (id:&quot;cjwuuj5bz000i0719rrtw5gqk&quot;) {
    ...collectionFields
  }
}
fragment collectionFields on Collection {
  id
  title
}</code></pre>
<p>응답은...
<img src="https://images.velog.io/images/_jouz_ryul/post/eec53496-415b-437a-904c-725e1af80032/%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%202020-08-02%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.34.34.png" alt="">
짜잔! 약간 개발자 스러운 코드가 되었다. 
사실 좀 더 자세하게 사용하려면 자세한 예제가 필요하다. 지금은 기본적인 형태만 알아보고 apollo-client를 정리할 때 실제
적용한 코드를 예제 삼아 정리하도록 하자.</p>
<h1 id="8-마무리">8. 마무리</h1>
<p>GraphQL 언어의 기초적인 문법들에 대해서 정리해보았다.
사실상 gql로 개발을 하다보니 위 문법들을 이것저것 짬뽕하여 사용하게 되는 수준까지 왔다. 
하지만 인터넷에는 정말 자료가 너무 부족하다 ㅠㅠ 
꼭 내가 궁금한 부분은 질문이 하다도없어서 3시간 6시간 반나절을 보내기도 한다. 
(다들 어떻게 그렇게 잘 개발하시는지 너무 부럽고 대단하다!)
이번 블로그에 정리된 기본 문법만 공부하고 실제로 바로 gql을 사용하여 개발을 시작했는데 
역시는 역시나 적용하는 부분은 졸큼 달랐다. 
그 부분을 다음 블로그에서 정리해보자 한다. 
apollo-client 세팅과 적용 그리고 실제로 gql과 apollo를 활용한 서버와의 통신 적용
이 두 주제를 블로깅 할건데
어떤것을 먼저해야할지 아직은 모르겠다. 
후자를 먼저하자니 apollo-client 세팅과 설정은 필수적이고
그렇다고 바로 apollo 정리를 하자니 아직 모르는것도 많고 gql을 보다가 너무 뜬금없어질 수 있기 때문이다. 
아무튼 다음에 알아볼 apollo는 정말 React와 찰떡궁합 (일부러 react를 메인 타겟으로 하고 만들어졌기 때문이지만)이고
이 또한 자료가 부족하여 광광 울고 머리 쥐어뜯으면서 개발했지만
진짜 apollo없으면 gql 어떻게 적용했을까 싶을정도로 짱짱맨이다. 
아무튼 그렇다 gql짱 apollo짱!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[아마존아 서버용 컴퓨터를 뿌려라: EC2]]></title>
            <link>https://velog.io/@_jouz_ryul/%EC%95%84%EB%A7%88%EC%A1%B4%EC%95%84-%EC%84%9C%EB%B2%84%EC%9A%A9-%EC%BB%B4%ED%93%A8%ED%84%B0%EB%A5%BC-%EB%BF%8C%EB%A0%A4%EB%9D%BC-EC2</link>
            <guid>https://velog.io/@_jouz_ryul/%EC%95%84%EB%A7%88%EC%A1%B4%EC%95%84-%EC%84%9C%EB%B2%84%EC%9A%A9-%EC%BB%B4%ED%93%A8%ED%84%B0%EB%A5%BC-%EB%BF%8C%EB%A0%A4%EB%9D%BC-EC2</guid>
            <pubDate>Sun, 19 Jul 2020 07:56:41 GMT</pubDate>
            <description><![CDATA[<p>현재 재직중인 회사에서 EC2와 nginX를 이용해서 서비스를 배포하고 관리한다. 
매번 서버나 배포쪽은 나몰라라 하고 언젠간 공부하겠지라는 무책임을 벗어나고자
리액트로 만든 프로젝트를 nginx로 EC2에서 배포하는 demo trial을 해보자 한다.
사전에 리서치를 하다보니 EC2 인스턴스 생성, nginX의 방식 등 모르는 부분이 너무 많았을 뿐더러
그 모든것들을 정리하고 싶지만 사실상 설정은 내가 건드는 것도 아니고 프론트 딴에서 배포함에 있어서 
하나하나 다 알 필요가 없다는 한 블로거의 말을 전적으로 수용하여 (핑계) 
간만한 설정-배포의 과정에 대해서만 정리해보도록 하자! 
(매번 하는 말이지만 나중에 언젠간... 짬밥의 힘을 빌려 정리할 것이다.......아마도...)</p>
<hr>
<h1 id="1-ec2란">1. EC2란?</h1>
<p>아마존 aws에서는 다양한 서비스를 제공해주는데 너무 많기도 하고 이해하기도 어려웠다.
그래서 그냥 간단하게 설명하자면
예전에는 각 회사마다 서버실을 따로 두고 서버관리자가 그것을 관리하며 확장하거나 유지 또는 보수를 하였다.
이 서버실에 필요한 컴퓨터, 서버, 각종 하드웨어 및 서비스들을 아마존에서 가상 머신을 통해 제공해주고
우리는 그것을 원격으로 제어한다고 생각하고 넘어가기로 했다.
말 그대로 아마존의 서버실을 우리 전용으로 계약하여 빌리는 것이다. </p>
<h1 id="2-ec2-인스턴스-생성">2. EC2 인스턴스 생성</h1>
<p>여담으로 코딩과 프로그래밍을 배우며 느낀것이지만 영어라 더더욱 그렇겠지만 참 용어들이 어렵고 와닿지 않는다.
인스턴스라....
한번 살짝 만들어보니 그냥 서버용 컴퓨터를 한대 맞추는 것이였다. 다만 나에게 배송오지 않고 아마존에서 보유(?)하며 우리는 그냥 돈만 내고 모니터링하며 제어하는 것이다. </p>
<h2 id="21-aws---ec2">2.1. AWS - EC2</h2>
<p><a href="https://aws.amazon.com/ko/free/?trk=ps_a134p000003yHYmAAM&amp;trkCampaign=acq_paid_search_brand&amp;sc_channel=PS&amp;sc_campaign=acquisition_KR&amp;sc_publisher=Google&amp;sc_category=Core-Main&amp;sc_country=KR&amp;sc_geo=APAC&amp;sc_outcome=acq&amp;sc_detail=aws&amp;sc_content=Brand_Core_aws_e&amp;sc_segment=444218215904&amp;sc_medium=ACQ-P%7CPS-GO%7CBrand%7CDesktop%7CSU%7CCore-Main%7CCore%7CKR%7CEN%7CText&amp;s_kwcid=AL!4422!3!444218215904!e!!g!!aws&amp;ef_id=Cj0KCQjwu8r4BRCzARIsAA21i_BGNDqBz79WYbaG2q12iBGLRotguamHO3xPeIxSVuENvmE-HiB7ACgaAjW3EALw_wcB:G:s&amp;s_kwcid=AL!4422!3!444218215904!e!!g!!aws&amp;all-free-tier.sort-by=item.additionalFields.SortRank&amp;all-free-tier.sort-order=asc">아마존 AWS</a>로 가서 콘솔에 로그인을 하면 다음과 같은 창이 뜰 것이다.
<img src="https://images.velog.io/images/_jouz_ryul/post/fdcb3d4d-4275-41c0-9abe-261d20d3dc00/%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%202020-07-18%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.42.59.png" alt="">
그럼 클릭이라고 나와있는 EC2를 클릭하면 아래와 같은 화면이 나올 것이다.
<img src="https://images.velog.io/images/_jouz_ryul/post/6a699d10-8fc0-4c0f-a530-49fc92239efd/%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%202020-07-18%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.44.31.png" alt="">
뭐라뭐라 참 많은 내용이 나와있다. 하지만 걱정하지말자 우리는 몰라도 된다.(아직은 아마도)
그럼 클릭이라고 나와있는 인스턴스 시작을 눌러보자.</p>
<h2 id="22-ami-선택하기">2.2. AMI 선택하기</h2>
<p>우리가 아마존한테 받을 가상 컴퓨터의 운영체제를 선택하는 것이다.
연습용이기에 무료로 사용 가능한 것을 선택할 것인데
<strong>프리티어 사용 가능</strong>이라고 적혀있는 운영체제는 무료로 사용이 가능하다.
그리고 이 운영체제에 대해서 무슨 기준으로 선택해야 하는지 리서치를 했지만
결국 연습용이기에 아무 의미가 없었고 나중에 접속할 때 방법이 조금 달라진다고 하니 그점만 유의해서
원하는 것을 고르면 된다.
나는 처음 EC2에 대해서 배울때 선택했던
<strong>Ubuntu Server 16.04 LTS (HVM)...</strong> 을 선택할 것이다. 아래와 같이.</p>
<p><img src="https://images.velog.io/images/_jouz_ryul/post/68ee3624-ed8b-4e04-94cc-a957af8a6903/%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%202020-07-18%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.54.23.png" alt=""></p>
<h2 id="23-인스턴스-유형-선택하기">2.3. 인스턴스 유형 선택하기</h2>
<p>아쉽(?)게도 무료로 사용하려면 하나의 선택지 밖에 없다.
인스턴스 유형이란 결국 우리가 아마존에서 맞추는 가상 컴퓨터의 사양을 세팅하는 것이다.
각각 유형 마다 사용 사례들이 있는데 추후 정말 서비스를 위해서 설정한다면 잘 읽어보고 맞는 인스턴스 유형을 선택하면 될 것 같다!
<img src="https://images.velog.io/images/_jouz_ryul/post/86e35645-818f-401f-94d2-4200d23e331c/%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%202020-07-18%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.59.23.png" alt="">
사진과 같이 선택하고 오른쪽 밑에 <strong>다음: 인스턴스 세부 정보 구성</strong>을 클릭하자</p>
<h2 id="24-인스턴스-세부-정보-구성">2.4. 인스턴스 세부 정보 구성</h2>
<p>이 부분에 사실 많은 시간을 투자해서 알아보았다.
특히 서브넷과 퍼블릿 ip 자동 할당에 대해서 알아보았는데
현재 역량으로 완벽히 이해하기란 쉽지 않았다.
결국 무엇을 위해서 설정해야하는지 대충 알았지만 
한 블로그에서 들어준 예가 사내용 인프라 서버였고
처음 EC2를 배울 때 내용으로 설정하였다. 
<img src="https://images.velog.io/images/_jouz_ryul/post/ddada7a5-f33d-49d6-b557-c59096e3553c/%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%202020-07-18%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.31.51.png" alt="">
기본적인 기본세팅은 위의 사진과 같고
실제로 많은 예제 블로그에서는 이 과정을 그냥 default값으로 설정하기도 한다.
<img src="https://images.velog.io/images/_jouz_ryul/post/5ab3274c-2f8c-47b1-9f70-d1056883e06c/%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%202020-07-18%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2011.33.53.png" alt="">
하지만 내가 wecode에서 들은 세션에서는 다음과 같이 세팅을 권장하였고
정확한 이유는 기억이 나지 않지만 추후 알아내서 정리할 것이다.
적용한 설정은 서브넷 옵션들 중 2a로 끝나는 것을 클릭하고
퍼블릭 ip 자동 할당을 활성화로 바꿔주었다</p>
<h2 id="25-스토리지추가--태그-추가">2.5. 스토리지추가 &amp; 태그 추가</h2>
<p>스토리지 추가는 별로 건들것이 없는 설정임으로 그냥 넘어가고
태그 추가는 그냥 이 EC2에 대한 간단한 메모라고 생각하면 된다.
자유롭게 남겨주자.
key를 Name으로 설정하고 값은 자유롭게 정해주자.</p>
<h2 id="26-보안-그룹-구성">2.6. 보안 그룹 구성</h2>
<p>보안과 관련된 설정을 하는 것인데 이 인스턴스에 접근하는, 권한과 관련된 설정을 하는 파트다.
네트워크를 통해서 누가 이 인스턴스에 접근할 수 있게 할 것인가, 어떤 방식의 접근만 허용하는지 설정하는 것이다. </p>
<p>먼저 나는 어느 ip든 무관하고 http와 ssh에 무관하게 접속이 가능한 웹 서비스를 배포하고 싶다.
그래서 아래와 같이 설정하였다.
<img src="https://images.velog.io/images/_jouz_ryul/post/078a000b-78f6-4674-9468-fd6688ac3dcc/%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%202020-07-19%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%201.07.49.png" alt="">
그 후 다음 단계를 진행하면 여태까지 설정한 인스턴스 정보가 나올 것이고 시작하기를 누르면 키 설정이 나올 것이다. </p>
<h1 id="3-키-페어-설정">3. 키 페어 설정</h1>
<p>아마 시작하기를 누르면 다음 사진과 같이 키 페어를 설정하는 창이 나올 것이다. 
이는 쉽게 말하면 인스턴스의 비밀번호와도 같은 것이다. 
좀 전에 설정한 보안 그룹 구성은 접속에 관한 이야기라면
이 키 페어는 인스턴스를 조작하고 제어하는 권한을 이 키로 설정하는 것이다. 
다음과 같이 설정해보자.
<img src="https://images.velog.io/images/_jouz_ryul/post/33f9495d-09b3-45db-832e-42b351771444/%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%202020-07-19%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%201.17.17.png" alt="">
키 페어 이름은 원하는 아무 이름이나 작성하고 키 페어 다운로드를 클릭하여 다운받자
그 후 인스턴스 시작을 누르면 끝!</p>
<p>다음편에 리액트 프로젝트 EC2로 띄워보기를 해보겠습니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Dive into patterns with React]]></title>
            <link>https://velog.io/@_jouz_ryul/Dive-into-patterns-with-React-fufjxqio</link>
            <guid>https://velog.io/@_jouz_ryul/Dive-into-patterns-with-React-fufjxqio</guid>
            <pubDate>Sat, 11 Jul 2020 13:50:00 GMT</pubDate>
            <description><![CDATA[<h2 id="0-flux-pattern">0. Flux Pattern</h2>
<p>As the Flux pattern which became the most famous and commonly used pattern in React after it had been brought out 
by Facebook Development team, some other patterns such as <strong>Provider pattern</strong>, <strong>Observer pattern</strong> and etc, 
had been introduced as state management libraries and APIs earns its fame by developers 
such as Redux, Context Api, Mobx and etc but all the patterns shares the same common principle: 
<strong>divide the components as smallest as possible, keep the unidirectional data flow, focus on single source of truth and keep it simple.</strong></p>
<p>Even though it is really taugh to look deep under the hood how each libraries works as Provider or Observer pattern, 
understanding basic flows or how it works is comes to important for developers to make better decision on optimizing application, in my opinion; 
it makes developers perfectly know when to use optimizing tools or skills such as <code>React.memo</code> or <code>useCallback</code> in application 
since it is the way of understanding how the flow of the state management libraries or APIs is looks like under the hood. </p>
<p><strong>__Therefore for this blog, let me take a brief explanation of patterns and compare those with pros and cons. 
__</strong></p>
<hr>
<h2 id="about-desingn-pattern-with-react">About desingn pattern with React</h2>
<h2 id="1-observer-pattern-redux">1. Observer Pattern: redux</h2>
<h3 id="11-about-observer-pattern">1.1. about Observer Pattern</h3>
<ul>
<li><p>depends on single source of truth.
: Observer Pattern is useful when connecting and synchronizing various objects or components depending on one state.</p>
</li>
<li><p>Observer which itself attached to the Subject and keep listen to it until the state has been changed.</p>
<h3 id="12-pros">1.2. pros</h3>
<ul>
<li>low dependencies among components which mean all components should not always be on the same tree level in order to be synchronized with state or data.
unidirectional data flow: makes us easy to track down the flow of data.<h3 id="13-cons">1.3. cons</h3>
</li>
<li>memory leak: to avoid un-used observer, it is required to detach the components which will not be used with Subject.</li>
</ul>
</li>
</ul>
<hr>
<h2 id="2-provdier-pattern-famously-known-for-context-api-data-flow">2. Provdier Pattern: famously known for context api data flow</h2>
<h3 id="21-about-observer-pattern">2.1. about Observer Pattern</h3>
<ul>
<li>highly useful for React Context which makes components to have global state.</li>
<li>this is highly useful for updating the child components by the changes on the object from parents components which are highly reusable throughout the numerous componets. </li>
<li>the most primitive point of Provider Pattern is that it makes us to avoid &quot;Prop Drilling&quot;.<h3 id="22-how-it-works-simply">2.2. How it works simply:</h3>
</li>
<li>Provider will set up some values into the Context Object at the highest tree level of Components.</li>
<li>Consumer which also called as Child Component will get a data directly from the context than receives it props from Parent Component.<h3 id="23-pros">2.3. Pros:</h3>
<ul>
<li>get free from &quot;Props Drilling&quot;: lower the dependency between parents and child components
unidirectional data flow: one single source of truth == flux pattern<h3 id="24-cons">2.4. Cons:</h3>
</li>
<li>invisibility among the connections between Context and Consumer: hard to identify which component is parent and where data is coming from.</li>
<li>have componets to use global values: general cohesiveness will be higher 
(dont get it perfectly but according to the Official Doc from React says that less Context used is preferred)</li>
</ul>
</li>
</ul>
<hr>
<h2 id="3-basic-and-core-concepts-to-follow-regradless-of-the-pattern-type">3. basic and core concepts to follow regradless of the pattern type</h2>
<h3 id="31-divide-the-components-as-smallest-as-possible">3.1. divide the components as smallest as possible</h3>
<h3 id="32-keep-the-unidirectional-data-flow">3.2. keep the unidirectional data flow</h3>
<h3 id="33-focus-on-single-source-of-truth">3.3. focus on single source of truth</h3>
<h3 id="34-keep-it-simple">3.4. keep it simple</h3>
<hr>
<h2 id="4-dive-into-context-pattern--provider-pattern-in-react-in-shallow-depth">4. dive into context pattern / provider pattern in React in shallow depth:</h2>
<p><strong>Using React Context Api in elegent way</strong></p>
<p>: composing the React Context Provider and useContex Hook in order to make easier and more confortable with re-using them.</p>
<p>Context is useful when sharing data throughout the project or app without passing data as props regardless of the depth among components: it is more likely using data as global variables or it available us to pass down the value or data to component tree without using props or regradless how depth they apart.</p>
<hr>
<h3 id="issues">Issues</h3>
<p>Context in React is used to share data which is located in global space in a component tree such as an authenticated user or preferred theme without passing that data as props. </p>
<p>And it is also possible to have multiple providers in one application 
But it would not be recommended to have that pattern since 
the purpose of using context api is sharing data without using props in multiple components regardless of how much they apart to each others .</p>
<p>However All the consumers that are descendants of Provider will re-render whenever the value prop changes which means all the components who are placed as children of Provder Components, will be re-rendered as value props changes. 
i.g) &lt;MyContext.Provider value={someValue}&gt;</p>
<p><del>This problem or issue can be handled by using pure component or React.memo, in my opinion.</del>
PureComponent and React.memo can&#39;t prevent other consumer components to be unintentionally re-render</p>
<h3 id="conclusion">Conclusion</h3>
<p>To overcome this, using useCallback to that value that commonly shared throughout the application. 
Use React.memo to the value for the provider value and
Use useCallback to the value that makes unintentional re-rendering.</p>
<p>It might be recommended to use context api for such thing as user authentication, for example, which is necessarily to be accessible throughout entire application as an aspect of Service that application provides.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 데이터 타입과 변수]]></title>
            <link>https://velog.io/@_jouz_ryul/JS-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EA%B3%BC-%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@_jouz_ryul/JS-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85%EA%B3%BC-%EB%B3%80%EC%88%98</guid>
            <pubDate>Fri, 19 Jun 2020 02:53:23 GMT</pubDate>
            <description><![CDATA[<h1 id="0-프롤로그">0. 프롤로그</h1>
<hr>
<p>몇일 전 개발을 하다가 JSON파일의 <code>number</code>타입의 <code>id</code>의 값을 
컴포넌트의 <code>id</code>값으로 할당하고 다시 JSON파일 속 <code>id</code>와 비교를 할 때 엄청난 애를 먹은적이있다.
filter를 이용해서 걸러내려는 함수를 작성했는데 콘솔에 같은 값이 찍히는대도 불구하고
filter함수가 걸러내질 못했다. 콘솔을 좀 더 잘 확인했다면 따옴표를 잘 보고 타입이 달랐다는 것을 알 수 있었겠지만 그거 하나 못봐서 3시간을 고생했다. <del>(좀 더 꼼꼼히 확인하자)</del>
너무나도 당연한 것이지만 HTML의 속성으로 부여된 id의 값은 string이라는 것을 간과해버렸다. 
<del>(할당한 id가 숫자 타입이라 당연 숫자로 인식되는줄 ㅠ)</del>
위 3시간의 삽질 아닌 삽질은 무한의 스트레스를 주었고 동시에 자괴감과 자존감을 바닥으로 짖눌러 버렸다. 
하지만 다음 날 긍정적인(<del>이라고 쓰고 생각없는 이라고 말하는</del>) 마인드로 <strong>덕분에</strong> 다시한번 자바스크립트 데이터 타입을 공부해봐야 겠다는 생각이 들어 다행이라고 결론짓고
이 참에 한번 간략하게 정리해보려한다. </p>
<h1 id="1-변수-선언과-할당">1. 변수 선언과 할당</h1>
<p>변수를 선언하고 값을 할당할 때 어떤일이 일어나고 후에 변수 값을 참조할 때 어떤 식으로 이루워지는지 간략하게 알아보기.</p>
<hr>
<p>프로그래밍은 변수를 통해 값을 저장하고 참조한다고 한다. 그래서 그 변수는 값의 위치를 나타내는 인간의 언어라고 한다. 변수를 할당했는데 값의 위치를 나타낸다니 정말 웃기는 짬뽕이다.
그 말인 즉슨 할당이라는 코드가 작성되면 컴퓨터는 어느 저장소 한곳에 그 값을 저장하는데 
변수가 그 값을 가지고 있는 것이 아니라 메모리상에 값이 저장된 저장소의 위치를 가지고 또는 가르키고 있는 것이다. (여태까지 가지고 있는줄)
<code>let bar = 1</code>이라고 선언 할당을 하면 <code>bar</code>의 값은 1 이지만 사실상 딥하게 <code>bar</code>를 파보면 컴퓨터의 언어로 본인이 저장한 저장소의 1이 어디에 저장되어있는지 위치를 알려주는 것이다. </p>
<p>더 나아가 메모리에 값을 저장하려면 먼저 메모리 공간을 확보하는데 이는 데이터 타입에 따라 다르다고 한다. 구글에 관련한 것들을 검색해보면 컴퓨터 공학적인 이야기가 엄청 나오는데
다 각설하고 자바스크립트에 관해서만 알아보자.</p>
<h2 id="11-자바스크립트의-데이터-할당">1.1. 자바스크립트의 데이터 할당</h2>
<p>자바스크립트는 동적인 언어이다. 그래서 타입들 또한 동적인데 이 말인 즉슨 다른 언어들은 (사용안해봐서 잘 모르지만 this is what google says)
선언과 함께 데이터 타입을 알려준다고 한다고 알고있다. 
하지만 자바스크립트는 그런것이 없다. 그냥 내가 string이든 number든 할당하고 싶은 것들을 선언과 함께 할당해주면 알아서 잘 인식해준다. 
자바스크립트는 변수의 타입지정이 따로 없이 값을 할당하는 과정에서 자동으로 알아서 변수의 타입을 결정한다. 그래서 자유롭게 재 할당이 가능한 것이다. 
<del>(그래서 Typescript가 대세로 떠오르고 있는것인가?)</del></p>
<p>어쨋든 자바스크립트는 선언과 할당 과정에서 별도의 타입 지정이 없이 타입 추론을 통해 알아서 결정해준다. 그렇기 때문에 자바스크립트 데이터 타입에 대해서 깊에 공부를 해보려 생각하지 않았나보다 <del>(변명)</del></p>
<h1 id="2-자바스크립트의-데이터-타입">2. 자바스크립트의 데이터 타입</h1>
<p>그럼 알아서 일어나는 자바스크립트의 데이터 타입 할당(?)을 조금 더 발전시켜서 공부해보자.
어떤 데이터 타입이 존재하고 할당될 때 변수는 그것들을 어떻게 사용하는 것인지.
크게 원시타입(primitive data type)과 객체(object/reference type)으로 나뉜다.</p>
<hr>
<h2 id="21-원시-타입-primitive-data-type">2.1. 원시 타입 (primitive data type)</h2>
<p>원시 타입이란 변경 불가능한 값이며 값에 의해 전달된다.
여기서 변경 불가능한 값이란 뜻은 immutable의 해석으로써 컴퓨터가 한번 데이터를 저장소에 저장하면
나중에 변수에 다른 원시타입의 값이 할당 되었을 때 저장된 위치의 값을 바꾸는 것이 아니라
저장소의 새로운 위치에 값을 저장하고 그 주소를 변수가 갖는다는 뜻이다. 
간단한 예를 보면</p>
<pre><code class="language-javascript">
//foo라는 변수에 숫자 1 할당.
let foo = 1

//...

//foo라는 변수에 숫자 20 재할당 
foo = 20</code></pre>
<p>이런식으로 <code>foo</code>에 1을 할당하고 나중에 20을 다시 할당한다고 가정해보자.
처음 코드를 읽어들일때 1은 메모리에 할당된다.
그리고 그 메모리의 위치를, 예를 들어, 100이라고 가정하자.
그 후에 <code>foo</code>를 사용하게 되면 컴퓨터는 메모리의 100 이라는 위치에서 그 값을 가져와서 사용하는 것이다.
만약 나중에 <code>foo</code>에 20을 재 할당하면 어떻게 될까?
컴퓨터는 메모리에서 100이라는 위치를 찾아가서 1을 20으로 바꾸는 것이 아니라
메모리의 새로운 위치에 20을 저장하고 변수 <code>foo</code>에 그 위치값을, 예를 들어, 200 이라면 200을 저장한다. 
이것이 불변성 <strong>immutable</strong>이다. (리액트에서 state관리할 때 정말 중요한 개념 + 배열과 객체인 데이터 가공시에도 매우 중요 )
원시 타입 데이터들은 할당된 값, 즉 원시 값을 직접 변형할 수 없고 대신 교체가 가능한 것이다. </p>
<p>반대로 뒤에서 살펴볼 mutable은 직접 변형이 가능하다. 물론 교체도 가능하지만 이로 인해 원본이 훼손되는 (의도치 않게) 경우가 발생한다.
특히 리액트에서는 state의 데이터를 mutate 하는 경우 리랜더링이 일어나지 않는 일도 발생한다. 
그렇기 때문에 <code>setState</code>를 이용해야하며 직접적으로 state의값을 건들여서는 안된다.
자세한건 나중에 mutation rhk non-mutation을 정리하며 알아볼 것인데 
어쨋든 배열과 객체도 똑같이 key의 value에 대해서 모두 메모리의 위치값을 가지고 있기 때문에 shallow copy를 하여 값을 변경하거나 변형시키면 원본도 훼손된다. 
여튼 좀 많이 조심해야한다. 내장 함수들 중에서도 배열과 객체를 mutate과 non-mutate하는 함수로 분류된다. (암튼 나중에 더 deep 하게 정리)</p>
<p>여튼 이런 원시 타입들은 
boolean
null
undefined
number
string
symbol (ES6에서 추가)
이 있다.</p>
<h3 id="211-number--string">2.1.1. number &amp; string</h3>
<p>데이터 타입에 대해서는 이름만 봐도 알 수 있으니 깊게 정리하지 않고 특징 몇개만 짚어서 같이 정리해보자.</p>
<p>기본적으로 자바스트립트는 이진수로 숫자를 저장한다고 한다. 
정수만을 위한 타입이 없고 실수라는데 아마 10 이라는 숫자도 10.000000 이런식으로 인식한다는 뜻인것 같다. 
그럼 소수점 몇까지 똑같은지 실험을 해봐야겠다.</p>
<pre><code class="language-javascript">console.log(10 === 10.000000000000001)
// false
console.log(10 === 10.0000000000000001)
// true</code></pre>
<p>소수점 15번째 자리까지만 인식가능하다. 
그럼 다음 경우는 어떨지 생각해보자.</p>
<pre><code class="language-javascript">console.log(0.3 === 0.1+0.2)
// true? false?</code></pre>
<p>답은 false 이다. 인터넷에 찾아보니 0.2의 2진수 표현이 정확하지 않다던데
이부분은 수학적으로 공부가 더 필요하다. 
아무튼 소수점을 비교할때는, 그리고 사용할 때는 조심하고 좀 더 알아보면서 사용해야한다. </p>
<p>그리고 string은 문자열이다. 즉 따옴표안에 적힌애들은 모두 문자열인데
특이한 것이 문자열과 숫자의 연산에서 웃긴 결과가 나온다.</p>
<pre><code class="language-javascript">console.log(&quot;1&quot;+1) 
//11
console.log(&quot;1&quot;-1) 
//0
console.log(1+&quot;1&quot;) 
//11
console.log(1-&quot;1&quot;)
//0
console.log(-1+&quot;1&quot;) 
  //-11
console.log(-1-&quot;1&quot;) 
  //-2
console.log(-&quot;1&quot;+&quot;1&quot;) 
  //-11
console.log(-&quot;1&quot;-&quot;1&quot;) 
  //-2
console.log(-&quot;1&quot;+1) 
//0
console.log(-&quot;1&quot;-1)
  //-2
console.log(+&quot;1&quot;+1) 
//2
console.log(+&quot;1&quot;+1) 
//2</code></pre>
<p>자바스크립트는 숫자로 이루어진 string을 연산하려 할때 기본적으로 숫자로 치환해서 연산한다고 한다. 
하지만 +를 만나는 경우 문자열 합성 기능이 있어서 문자열로 합성을 먼저 고려한다고 한다. </p>
<h3 id="212-boolean">2.1.2. boolean</h3>
<p>true와 false를 나타내는 값이다.</p>
<p>값이 할당되면 true가 되고 할당이 안되어 있으면 false이다. 
또한 그냥 하나의 변수에 true/false를 할당도 가능하다. 
&quot;&quot;, undefined, null, 0은 false이다. 
즉 0,&quot;&quot;, undefined, null이 할당된 값은 boolean check에서 false이다.</p>
<h2 id="22-원시-타입-primitive-data-type">2.2. 원시 타입 (primitive data type)</h2>
<p>원시타입을 제외한 나머지 값들인데
배열, 함수, 정규표현식 그리고 객체 타입인데 통괄적으로 객체타입으로 생각하면 된다. </p>
<p>간단하다.
이 다음에는 var let const와 호이스팅에 대해서 알아보고
그 다음에 더 ellaborate해서 스포크, 렉시컬, 클로저 그리고 실행문맥을 묶어서 알아보자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Promise and async/await]]></title>
            <link>https://velog.io/@_jouz_ryul/Promise-and-asyncawait</link>
            <guid>https://velog.io/@_jouz_ryul/Promise-and-asyncawait</guid>
            <pubDate>Sat, 06 Jun 2020 09:52:47 GMT</pubDate>
            <description><![CDATA[<p>The code written in Javascript is executed in synchronous way while, nowadays, the more and more asynchronous functions needed to be used.
Therefore, it is important to be familiar with the evolution of asynchronous behaviors and solutions provided by Javascript: callbacks, promise, async-await.</p>
<h1 id="callbacks">callbacks</h1>
<ul>
<li>be more precisely, it is about callback hell: callback in callback in callback in callback function and so on like the exaple below.</li>
</ul>
<pre><code class="language-javascript">const firstCall = () =&gt; {
  return fetch(&#39;someUrl&#39;,(response)=&gt; {
    let firstRes = response.json()
    let secondRes = firstRes.id
    return fetch(`otherUrl/${secondRes}`, (response)=&gt; {
      let thirdRes = response.userName
      return fetch(`someOtherUrl/${thirdRes}`), (response =&gt; {
        let fourthRes = response.phoneNumber
        return fetch(`getUserbill/${fourthRes}`, (response)=&gt; {
          let fifthRes = response.billAmount
          return fifthRes
        })
      })
    })
    })
}
firstCall()</code></pre>
<p>Using callbacks is really bad pattern with coding since it makes hard to not only track down the execution-flow, even for the developer who actually wrote it but also debug. </p>
<h1 id="promise">Promise</h1>
<p>As using Promise, it is really easy to track the code flow down, thankfully, but still the style with the Promise pattern doesn&#39;t looks like a synchronous flow a bit and throws some complexity compare to javascript functions we wrote.
It is because of all the callback functions returned by the Promise in order to keep chaining responses and handling asynchronous execution. </p>
<h1 id="async-await">async-await</h1>
<p>And now this is the newsest asynchronous solution or pattern brought by ES8, async - await.
This new pattern will have developers to write code about asynchronous execution in a style how synchronous execution fucntion written in.</p>
<ul>
<li><p>the declaration of <code>async</code>  defines an asynchronous function which returns an AsyncFunction object, which is the instance of the Async Function constructor, allows to use more efficiently and enables asynchronous, promise-based behavior</p>
</li>
<li><p>when an <code>async</code> function is called, it returns Promise with either resolved status when a function returns a value, or rejected status when a function throws an exception or some value</p>
</li>
<li><p>another keyword <code>await</code>, provided by <code>async</code>, will pause the execution of the function declared with <code>async</code></p>
</li>
<li><p>when Promise has been passed into, the execution resumed and returns the resolved value</p>
</li>
</ul>
<p>Example Code below</p>
<pre><code class="language-javascript">// standard promise pattern
let getData =() =&gt; {
  return fetch(&#39;someUrl&#39;)
  .then(response =&gt; console.log(response))
  .catch(error =&gt; console.log(error.message))
}

//async-await pattern
let getData = async() =&gt; {
  let responseFromServer = &quot;&quot;
  try {
    responseFromServer = await fetch(&#39;someUrl&#39;)
    console.log(responseFromServer)
  }
  catch(error) {
    responseFromServer = error
    console.log(responseFromServer.message)
  }
}</code></pre>
<p>Look how the code style in async-await is pretty much looks like the pattern of function executed syncrhonously, and the readability has been improved.</p>
<h1 id="little-deep-dive-from-the-shallow--of-async-await-just-a-bit">little deep dive from the shallow  of async-await (just a bit)</h1>
<ul>
<li><p>async function can have zero or as many <code>await</code> expression as needed</p>
</li>
<li><p><code>await</code> expression will pause or suspend the execution through out the entire async function, yielding control of execution and subsequently resuming progress only when an awaited promise-based operation is either fulfilled or rejected.</p>
</li>
<li><p>as Promise is always be returned value by async function, a resolved value of the Promise will be considered as a returned by the expression with <code>await</code></p>
</li>
<li><p>aysnc/await pattern, which is just a good-looking syntax of handling asynchronous execution, behaves similar to combination of generators and promises</p>
</li>
<li><p>as Async Function always returns a promise, a returned value without wrapped by promise will be wrapped by promise implicitly</p>
</li>
<li><p>easier to understand that the body of Async Function is divided by <code>await</code> expression; if there is none, it means there is no division</p>
</li>
<li><p>the very Top-level-code, up to and including the first <code>await</code> expression, runs synchronously; if there is none of <code>await</code> expression meaning that the function will execute in synchronously</p>
</li>
<li><p>if there is any <code>await</code> expression written, the execution of Async Function will be ended up asynchronously</p>
</li>
<li><p>the execution of Async Function will be suspended or losing control when the execution meets the first <code>await</code> expression configured with the pending Promise status</p>
</li>
<li><p>later when first <code>await</code> returns either resolve or rejected Promise, Async Function will re-gain the control over the execution until the progress meets the next <code>await</code> expression</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트와 엔진 그리고 실행 방식]]></title>
            <link>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%99%80-%EC%97%94%EC%A7%84-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%8B%A4%ED%96%89-%EB%B0%A9%EC%8B%9D</link>
            <guid>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%99%80-%EC%97%94%EC%A7%84-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%8B%A4%ED%96%89-%EB%B0%A9%EC%8B%9D</guid>
            <pubDate>Sat, 06 Jun 2020 05:37:27 GMT</pubDate>
            <description><![CDATA[<p>개발을 하다보면 에러를 마주치는 상황이 자주 발생하는데
대부분 외부 서버에서 데이터를 받아와서 처리하는 상황 등에서 발생하게 된다.
이에 대해 리서치를 해보면 대부분 자바스크립트의 비동기 함수로 인해 생긴 이슈들이라고 하는데
자바스크립트는 API 요청 등으로 대표되는 비동기 함수들에 대해서 평소와 다른 실행을 하게 되어 발생 한다고 한다. 
자바스크립트는 어떤 특성을 가지고 있길래 이런 이슈가 발생하는건지, 평소에는 어떻게 처리하는지 자바스크립트 엔진의 내부를 조금 살짝 깊게 한번 살펴보자.</p>
<h1 id="1-자바스크립트와-엔진의-특성">1. 자바스크립트와 엔진의 특성</h1>
<p>자바스크립트의 특성과 자바스크립트로 작성된 코드의 실행을 담당하는 엔진의 특성에 대해 알아보자.</p>
<h2 id="11-자바스크립트의-특성">1.1. 자바스크립트의 특성</h2>
<hr>
<p>javascript는 웹을 구성하는 3대장 중 하나다. HTML 그리고 CSS와 함께 웹 페이지를 구성하는데 사용된다. HTML이 웹페이지의 UI 구성을 만드는데 사용되고 CSS가 스타일링을 입힌 다면, 그 둘을 유저와의 상호작용을 구현하는데 javascript를 사용한다. 
초보자들이 배우기 쉽고 매우 자유로운 언어라고 한다. 
자유롭다는 말은 문법이 간단하고 멀티-패러다임 언어로 명령형, 함수형, 객체지향형 언어등 다양하게 활용이 가능해서 그런것 같다. 
<del>또한 객체 기반의 언어지만 하지만 상속과 클래스라는 개념은 없다.</del>
(이 부분은 추가 리서치 필요)</p>
<h2 id="12-크롬-v8엔진">1.2. 크롬 V8엔진</h2>
<hr>
<p>자바스크립트는 실행되는 환경에 따라 사용되는 엔진이 상이하기도 하다. 
일반적으로 chrome에 내장된 chrome V8 엔진이 대표적이다. 
V8엔진에 의해 실행되는 javascript는 compile(번역)과 interpreter(통역) 두개의 일련의 과정을 거쳐야한다. 
여담으로 V8엔진에는 원래 interpreter가 없었지만 2017년 5.9버전이 나오면서 추가 되었다.</p>
<p>어쨋든 compile도 하고 interpret도 거쳐야 하는 자바스크립트는 컴파일언어라고 하기도,
인터프리터 언어라고 하기도 애매하다. </p>
<p>아무튼 compile과 interpreter 두 개의 과정을 거치는 것이 특징인 자바스크립트는 이 과정들을 머신코드로 해석되고 통역되어 브라우저에서 인식할 수 있게 된다. 
또 다른 특징은 JIT(just-in-time)이라고 불리는 방식으로 위의 과정을 거치는데
말 그대로 브라우저가(대표적인 javascript가 실행되는 환경) javascript를 읽어 들이는 순간부터 compiler과 interpreter가 실행된다는 것이다. </p>
<p>그래도 가장 대표적인 특징은 V8엔진은 자바스크립트 코드를 단일 스레드, call stack에서 동기적으로 실행 한다.
이는 아마 V8엔진이 JIT 방식으로 compile과 interprete를 거쳐 머신 코드로 변환시키기 때문에 안정화 때문이지 않을까 하는 추측을 해본다. </p>
<h1 id="2-자바스크립트-엔진의-실행-방식">2. 자바스크립트 엔진의 실행 방식</h1>
<p>자바스크립트 엔진, 대표적으로 V8은 자바스크립트 코드를 <strong>동기적</strong>으로 실행 한다고 했다.
그럼 동기적으로 실행한다는 것이 무슨 뜻일까? 엔진 내부를 살짝 들여다보면서 살펴보자.</p>
<h2 id="21-동기적인-실행-방식">2.1. 동기적인 실행 방식</h2>
<hr>
<p>동기적으로 어떤 작업들을 한다는 말은 작업들을 한 작업 한 작업씩 처리한다는 뜻이다.
조금 더 자세히 살펴보자.
V8엔진은 싱글 스레드인 하나의 <strong>call stack</strong>을 가지고 있다. 
작업을 처리하는 공간인 call stack은 하나 밖에 없기 때문에 실행이 필요한 javascript 코드들은 이 하나의 call stack에 차곡 차곡 쌓인다. 
만약 5개의 코드가 실행이 필요해 call stack에 차곡 차곡 쌓였다. 
(실행 순서는 나중에 조금 더 자세히 살펴볼 것이다. 지금은 단지 동기적 처리 방식에 대해서만 설명)
이 5개의 작업들을 동기적으로 처리하면 다음과 같은 순서로 진행될 것이다.</p>
<p>1) 첫 번째 순서의 코드가 실행이 된다.
2) 이 때 다음 순서인 두 번째 순서의 코드는 실행이 되지 않는다. 그 대신 첫 번째 순서의 코드의 실행이 완료될 때 까지 대기하게 된다.
3) 일정 시간이 흐른 후 첫 번째 순서의 코드 실행이 완료되었다. 이제 두 번째 순서의 코드 실행이 시작된다.
4) 똑같이 세 번째 순서의 코드는 실행이 되지 않고 자신 앞 순서의 코드 실행이 완료 될 때까지 대기한다.
5) 쭉 반복</p>
<p>이렇게 작동하는 것이 동기적인 작동 방식인데 실행의 <strong>요청</strong>에 의해 작업이 시작되고 <strong>응답</strong>이 오면 작업을 완료하고 종료시킨다. 그 후 다음 작업에 대해 실행을 시작한다. 
자바스크립트 엔진의 call stack은 이 방식으로 javascript 코드를 실행한다. 
하지만 그 순서가 조금은 특이한데 바로 first-in, last-out, 즉 선입후출 방식으로 진행된다. </p>
<p>말로 먼저 설명하자면 함수 호출의 코드를 엔진이 읽어 들이면 call stack에 쌓는다. 
근데 방금 호출된 함수 안에는 또 다른 함수의 호출이 있다. 
그럼 안에서 호출된 함수에 대응하여 그 함수의 실행을 call stack에 쌓는데 이때는 처음 쌓인 call stack 위에 쌓인다.
안에서 호출된 함수 내부에는 또 다른 함수 호출이 없다. 그래서 엔진은 call stack에 쌓인
함수들을 실행하려 하는데 이 때 늦게 들어온 순서대로 코드실행을 진행한다. </p>
<h2 id="22-예제">2.2. 예제</h2>
<p>말로하니 역시나 어렵다. 다음 예제로 살펴보자.</p>
<pre><code class="language-javascript">const funcOne =() =&gt; {
  2️⃣console.log(&quot;No.1&quot;)
  3️⃣funcTwo()
}
const funcTwo =() =&gt; {
  4️⃣console.log(&quot;No.2&quot;)
  5️⃣funcThree()
}
const funcThree =()=&gt; {
  6️⃣console.log(&quot;No.3&quot;)
}
1️⃣funcOne()

// 결과값
&#39;No.1&#39;
&#39;No.2&#39;
&#39;No.3&#39;
</code></pre>
<p>위 코드는 중첩된 함수에 대한 예제이다. 실제로 호출이 되면 call stack에 쌓이는 모습을 살펴보자. 
<img src="https://images.velog.io/images/_jouz_ryul/post/54edaac9-909b-4082-ae0f-30608a3139c2/callstack1.gif" alt=""></p>
<p>위의 움짤처럼 쌓이고 위의 쌓인 순서대로 실행되고 실행이 완료되면 사라진다.
함수가 호출되어 call stack에 쌓이면 내부 코드를 순서대로 call stack에 쌓는걸 볼 수 있다. 
그 후 함수 내부에 다른 함수의 호출이 존재하면 그 함수를 call stack에 쌓는데 
그 함수가 실행이 완료되어 call stack에서 사라지기전에 외부함수의 실행도 완료되지 않는점을 명심하자. </p>
<h1 id="3-비동기-함수와-자바스크립트-엔진">3. 비동기 함수와 자바스크립트 엔진</h1>
<p>javascrit 엔진 V8이 자바스크립트 코드를 실행하는 과정을 보면 정말 똑똑하다. 
(실제로 공식 문서를 보면 매번 업데이트에 성능 향상과 최적화에 엄청 공을 들인다.)
성능적으로도 똑똑하지만 (컴퓨터도, 인터넷도 성능이 뛰어난 요즘시대이기에 처음 자바스크립트를 실행시켰을 때
나는 동기적으로 한번에 실행된다고 느꼈다. 하지만 정말 미묘하게 아<del>~</del>주 미묘하게 순서대로 실행되는 것이였다.) 브라우저애서 실행 된다는 점에서 JIT방식으로 실행을 하기 때문에 코드을 읽어 들어와 연산하여 인식하는 과정은 조금 불안정할 수 도 있다. 
그렇기 때문에 동기적인 방식으로 실행하는 것 같다는 느낌이 든다. 
순차대로 적은 코드들에 대해 순서를 보장해 주는 것이다.
그래서 자바스크립트 엔진을 어느 정도 (아주 조금이지만) 파해쳐보니 
조금 더 효율적이고 나은 코드 작성을 준수해야 되겠다는 생각이 크게 든다. 
(hoisting, execution context, lexical closure 등과 함께 날잡고 정리해야겠다.)</p>
<p>하지만 자바스크립트 엔진이 아무리 최적화하여 똑똑하게 실행을 처리한다고 한들 순서가 보장되지 못하는 경우가 발생하기도 한다. 바로 비동기 함수다. 
간단하게 비동기 함수는 자바스크립트의 원칙, 실행 순서를 보장 받는다,를 깨고 비동기로 처리된다. 즉 순서를 보장받지 못하고 뒤로 밀리게 된다. 
그럼 비동기 함수는 무엇이며 자바스크립트 엔진은 왜 이런식으로 처리하는 것일까?</p>
<hr>
<h2 id="31-비동기-함수">3.1. 비동기 함수</h2>
<p>대표적인 비동기 함수는 <strong>DOM 이벤트</strong> <strong>API요청</strong> <strong>setTimeout</strong>같은 내장 함수들이 있다. 
setTimeout으로 대표되는 DOM API, fetch 등으로 대표되는 XMLHttpRequest 등의 AJAX 등이 바로 비동기로 처리되는 대표적인 함수들이다. 
그런데 이들의 위치가 조금 생소하다. 이 형태를 javascript runtime의 모습으로 살펴보자.</p>
<hr>
<h2 id="32-javascript-runtime">3.2. Javascript Runtime</h2>
<p><img src="https://images.velog.io/images/_jouz_ryul/post/abe25e3b-f0b4-4026-9c83-a2f3679893c0/%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%202020-06-06%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2012.23.04.png" alt=""></p>
<p>자바스크립트 엔진에는 memory heap이라는 공간도 존재한다. 
설명상으로는 변수와 객체에 대한 모든 메모리 할당이 이루어 지는 곳이라고 하는데
조금 더 리서치가 필요한 부분이다.
하지만 이번 자바스크립트의 코드 실행 방식에는 큰 영향을 주는 것 같지 않다. (그래서 넘어가겠다는 소리)</p>
<p>어찌돼었던 이런 자바스크립트의 실행환경을 보면 엔진 밖에 <strong>Web API</strong>들이 모여있는 곳이 있다. 
자바스크립트 엔진이 제공하는 것이 아닌 브라우저에서 제공해주는 것이다. 
다시 말해 이들은 다른 누군가에 의해 정의되고 브라우저에 내장된 내장함수라고 생각해도 무관한데 이들은 <strong>비동기 함수</strong>이고 브라우저에 위치하고 있다. </p>
<p>다른말로는 자바스크립트 엔진이 콜스텍에 쌓고 실행을 처리하는 함수는 
<strong>우리가 자바스크립트라는 언어로 작성한 커스텀 함수다.</strong></p>
<h2 id="33-자바스크립트-엔진의-코드-처리-방식">3.3. 자바스크립트 엔진의 코드 처리 방식</h2>
<p>자바스크립트 엔진은 자바스크립트로 작성된 코드들의 실행을 담당한다.
물론 실행을 하기 위해 머신코드로 변환하는 작업을 거치긴 하지만 지금은 논외로 해보자.</p>
<h3 id="331-일반적인-코드-처리">3.3.1. 일반적인 코드 처리</h3>
<p>자바스크립트로 작성된 코드는 순차적으로 call stack에 쌓이게 된다.
call stack에 쌓이는 순간은 바로 코드가 해당 코드를 실행시키도록 작성되어있을 때 이다.
즉 자바스크립트 엔진은 call stack에 코드를 실행하라고 <strong>요청</strong>을 보내고 그 요청이 call stack에 쌓이는 것이다.
그러면 call stack에서는 해당 코드에 대한 작업을 하고 완료되면 <strong>응답</strong>을 보내 call stack에서 빼버린다. 
명심해야 할 것은 코드 작업의 실행과정은 <strong>요청</strong>과 <strong>응답</strong> 이라는 것이다.
하나의 코드 실행은 <strong>요청</strong>에 의해 작업이 시작되고 완료되어 <strong>응답</strong>이 오면 비로소 <strong>완료</strong>되어 사라지는 것이다. </p>
<h3 id="332-비동기-함수-처리">3.3.2. 비동기 함수 처리</h3>
<p>만약 우리가 Web API 작업을 포함하는 함수를 자바스크립트로 작성하고 실행시킨다고 가정해보면
call stack에 쌓고 실행 요청을 보낸다.
함수 내부를 살펴보니 Web API를 실행해야하는데 자바스크립트 엔진내에 존재하는 함수가 아니다. 
그러면 자바스크립트는 이 실행을 본인 내부에서 하지 않고 Web API가 있는곳에 그에 관련한 요청을 보낸다. 
요청에 대한 <strong>응답</strong>으로 필요한 다른 <strong>응답</strong>에 대해 다른곳에 <strong>요청</strong>을 보내는 것이다.
그 요청을 비동기 함수의 callback함수와 같이 보낸다. 
브라우저는 <strong>요청</strong>에 대한 <strong>응답</strong>으로 callback함수를 보내오는데 그 응답을 call stack에서 처리한다. 그러면 예제의 실행은 <strong>완료</strong>되는데 자바스크립트는 비동기 함수를 조금 특이하게 처리한다. </p>
<p>앞서 call stack에 요청된 Web API의 실행은 call stack에서 하지 않고 Web API에 위임한다고 했다. 
이때 call stack에서는 해당 요청을 사라진다. 즉 해당 요청에 대한 응답을 본인이 처리하지 않기에 브라우저에 요청을 보내고 해당 작업에 대한 모든 정보를, 즉 callback을 call stack에서는 Web API쪽으로 함께 보내버리는 것이다.(위임)
그렇기 때문에 같이 보내진 콜백 함수는 순서를 보장 받기도 전에 다른 곳에 위임이 되어버린다.</p>
<p>하지만 브라우저는 Web API 실행 요청에 대한 응답으로 callback 함수를 보내고 그 함수를 다시 call stack에서 처리한다고 하지 않았는가?
브라우저의 응답으로 온 callback 함수를 실행하라고 call stack에 요청하고 쌓는다. 
이때는 제대로 실행 순서를 보장받는다. </p>
<p>쉽게 말해 어린아이가 귤을 먹고 싶은데 (call stack에 요청) 껍질을 본인이 깔 수 없어 엄마한테 껍질을 까달라고 요청하고 (Web API 요청 with callback) 
그 요청의 응답으로 알맹이가 돌아오고 (콜백) 그 알맹이를 먹을 수 있게 (call stack에서 실행) 되는 것이다.</p>
<p>그렇기 때문에 call stack은 본인이 수행할 수 있는 요청이 아니기에 브라우저에 껍대기를 까달라고 요청과 함께 비동기 함수안에 정의된 callback 함수도 함께 보낸다.
(API 함수에 대한 실행요청으로 실행하려 했지만 실행을 하지도 않고 다른곳으로 위임한다. 
그리고 내부에 정의된 콜백함수는 순서를 배정받기도 전에 같이 보내지는 것이다.)
그 후 브라우저에서 껍대기를 까고 알맹이를 돌려주면 (callback 함수) 다시 call stack에서 실행을 요청하고 연산 후 응답으로 보내주면 실행을 완료하고 call stack에서 사라진다. </p>
<h3 id="333-callback-queue와-event-loop">3.3.3. callback queue와 event loop</h3>
<p>하지만 그 callback 함수가 call stack으로 들어가기전에 규칙이 있다. 
Web API가 요청으로 응답을 보내주기까지 call stack은 기다리지 않고 다른 일을 순차적으로 동기적으로 처리한다. 
아직 100개의 일이 call stack에서 처리되어야 한다고 가정해보자. 
callback함수는 그 중간에 끼어들어 순서를 바꿔버릴까?
그렇게 되면 코드 실행은 엉창진창이 되버릴 것이다. 
그래서 대신 callback queue라는 곳에서 기다린다. 일종의 유명한 식당에서 줄을 서며 기다리는 것이다. 이 callback queue에서 기다리가닥 들어온 순서대로 call stack으로 옮겨지는데
event loop라는 친구가 항상 call stack과 callback queue를 지켜보고 있다가 call stack이 비워지게 되면 callback queue에서 대기중인 함수 실행을 call stack을 보내 callback 함수를 실행하게 된다. 
결국 call stack과 callback queue는 동기적으로 작동하는데 비동기 함수는 그 순서가 밀리는 것이다. </p>
<p>말로하니 역시 어렵다. 예제 코드를 작성하고 어떤 이동이 일어나는지 살펴보자.</p>
<pre><code class="language-javascript">let someVal = 1
let API_EXAMPLE = ()=&gt; {
setTimeout(function() {
 someVal + 10
},3000)
return someVal
}

let someFinalVal = API_EXAMPLE() + 100
console.log(someFinalVal)</code></pre>
<p>콘솔창에 어떤 결과값이 찍힐까? 111? 아니면 101?
진행과정을 보고 한번 살펴보자.
<img src="https://images.velog.io/images/_jouz_ryul/post/2050ce9e-ee95-4aae-b9d5-a5d56a640c76/async%20engine.gif" alt=""></p>
<p><code>setTimeout</code>이라는 Web API는 비동기 방식으로 처리되었기 때문에 
<code>someVal</code>1에 10을 더하지 못한채 <code>API_EXAMPLE</code>함수 실행은 완료되었다.
그래서 결국 콘솔에 찍힐 <code>someFinalVal</code>의 값은 1+100인 101이 되는 것이다. </p>
<p>이렇게 자바스크립트 엔진은 비동기 함수를 실행시킬 때 그 안에 작성된 콜백 함수를 Web API를 처리하는 곳으로 보내고 비동기 함수가 실행되는 동안 call stack에 보장된 순서대로 다음 함수들을 처리한다.
그 사이 비동기 함수가 연산을 마치면 같이 보내진 콜백 함수를 callback queue로 보내고
event loop가 지켜보고 있다가 call stack이 비워지면 콜백 함수를 call stack에 다시 밀어넣고 보장된 순서대로 실행 시키는 것이 바로 자바스크립트가 비동기 함수를 처리하는 방법이다. </p>
<p>비동기 함수가 어떻게 처리되는지 알아봤는데 왜 자바스크립트 엔진은 헷갈리게 브라우저 내장 함수들을 이렇게 처리하는지 이유에 대해서 알아보자.</p>
<h2 id="34-비동기-처리-방식의-이유">3.4. 비동기 처리 방식의 이유</h2>
<p>이유는 간단하게 blocking script를 방지하기 위해서다. 
위의 예제에서 setTimeout라는 Web API를 사용했는데
이 함수는 지정된 시간이 지난 후 실행 되는 대표적인 비동기 함수다.
예제에 이 함수를 사용한 이유는 <code>fetch</code>나 <code>axios</code> 등으로 대표되는 
서버와의 통신으로 데이터를 받아오는데 사용되는 Web API를 구현하기 위해서다. 
만약 통신으로 데이터를 받아오는데 위 예제처럼 3초가 아니라 10분이 걸린다고 가정해보자.
그리고 이런 함수를 비동기가 아닌 동기로 처리한다고 가정해보자. </p>
<p>그러면 10분동안 아무것도 화면에 나오지 않을 것이다. 
만약 통신으로 뉴스의 사진을 받아온다고 가정한다면 통신 다음에 실행되어야 할 코드들이
실행을 계속 기다리게 된다.
이것이 바로 <strong>blocking script</strong>다. 
자바스크립트는 동기로 코드를 실행시키는데 한 코드에 소요 되는 시간이 너무 길기 때문에
그 코드 이후에 실행으로 순서를 부여받은 코드들은 10분을 더 기다려야 실행이 된다.</p>
<p>하지만 만약 비동기로 처리한다면 어떨까?
화면에는 사진만 나오지 않고 글은 보일 것이다. 
그리고 유저는 10분뒤 사진을 받아볼 수 있을 것이다. </p>
<p>AJAX 요청이, 대표적으로, 비동기로 처리되는 이유는 웹 페이지에 필요한 리소스들을 대부분 서버로부터 전송받아 viw에 보여주기 때문이다. 
그런데 이런 리소스들 때문에 스크립트가 막힌다면 페이지 자체를 보여줄 수 없기 때문이다. </p>
<h1 id="4-이슈-결론은-promise다">4. 이슈: 결론은 Promise다.</h1>
<p>이로 인해 발생하는 이슈는 무엇일까?
바로 위 예제와 같다. 
만약 서버와의 통신으로 데이터를 받아와서 그 값을 재연산해서 최종값으로 사용하려 한다면
위의 예제처럼 &quot;+10&quot;이라는 재연산을 하지 못한채 값을 사용하게 된다. 
그러면 어떻게 해야할까?
바로 Promise를 사용하는 것이다.
Promise는 비동기 함수를 동기적으로 처리할 수 있게 해주는 아주 대단한 친구다.
Promise에 대한 정리는 다음에 하도록 하겠다.</p>
<h1 id="5-추가-job-queue">5. 추가: Job Queue</h1>
<p>인터넷에서 재밌는 글을 읽었는데 바로 Job Queue에 관한 것이다.
먼저 다시 비동기 함수 작동방식을 살펴보면,
비동기 함수는 본인의 함수를 실행하고 콜백으로 넘겨진 콜백함수를 callback queue로 보낸다. 
그리고 event loop가 call stack을 지켜보고 있다가 다 비워지면 callback queue에서 
first-in, first-out 방식으로 call stack에 밀어 넣는다. 
즉 다른 일반 함수의 실행이 모두 끝나야 비동기 함수가 실행 순서를 배부받고 보장받는 것인데
비동기 함수는 call stack 맨 끝부분에 추가된다고 봐도 무방하다.
그런데 이 job queue라는 재밌는 녀석은 비동기 함수한테 조금 더 빠른 순서를 제공한다.
물론 조건이 필요한데 그 조건은 비동기 함수가 실행되는 현재 함수가 끝나기전에 비동기 함수의 실행이 완료되면 현재 함수의 실행이 완료된 후 바로 실행되는 순서를 제공받는다. 
다시 말해 다른 일반 함수들의 실행이 끝나 call stack이 비워지기 전에 순서를 제공받는 것이다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트와 리액트 그리고 프론트엔드]]></title>
            <link>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%99%80-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C</link>
            <guid>https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%99%80-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C</guid>
            <pubDate>Fri, 05 Jun 2020 11:02:21 GMT</pubDate>
            <description><![CDATA[<p>이 글의 결론은 자바스크립트로 무엇을 하는가에 대한 결론이다. 
솔직히 최근까지 웹 프로그래밍의 목적성이 없었던 것 같다. 
왜 자바스크립트를 공부했는지. 왜 리액트를 사용하였는지. 
결국 리액트와 자바스크립트로 무엇을 하려는지에 대한 목적이 불분명했었다.
웹페이지로 서비스를 제공하기 위해서? 그건 html이나 웹 퍼블리싱으로도 가능하지 않은가?</p>
<p>결국 자바스크립트와 리액트를 가지고 무엇을 만드는 것이 아닌 무엇을 하는건지에 대한 명확한 대답을 모르니 계속 빙글빙글 도는 느낌이였다. 
단지 프론트엔드 개발자가 되기 위해서, 웹 어플리케이션을 구현하기 위해서라는 모호한 목적만 가지고 있었다. 
그래서 그동안 자바스크립트의 개념을 파고 파도 결론은 왜 이런 개념이 있는건데? 라는 자문으로 귀결되었다.</p>
<p>프론트엔드 개발자로서 서비스를 높은 퀄리티로 구현하느 것도 중요하지만
결국 내 코드가, 지금 내가 하는 개발이 궁극적으로 어떤 일련의 과정을 거쳐 구현이 되는지 아는 것도 중요하다는 생각이 들었다. 
그래서 자바스크립트의 언어적 특성과 엔진이 코드를 해석하고 번역하는 과정 (간단하게만)
그리고 그 특징과 과정으로 인해 마주치는 대표적인 이슈들에 대해서 정리해보면서 
결론적으로 자바스크립트 코드로 무엇을 하는지에 대한 결론을 내보자.</p>
<h1 id="1-자바스크립트가-뭔데">1. 자바스크립트가 뭔데?</h1>
<p>간단하게 자바스크립트는 웹 브라우저 위에서 동작하는 언어다. 
즉 웹 브라우저에서 HTML, CSS를 동적으로 제어하기 위해 만들어진 언어다.
그럼 동적으로 제어한다는건 무엇을 말하는 것일까?</p>
<p>2000년대 초반 웹사이트와 현재 웹사이트를 비교해보자.
요즘은 뱅킹 사이트에 로그인하면 자동 로그아웃까지 남은 시간을 보여준다.
또한 회원가입시 일정 조건에 맞지 않으면, 예를 들어, &quot;비밀번호는 8글자 이상 입니다.&quot; 등의 경고를 띄워주며 동적으로 보여주면서 상호작용한다.
과거의 웹사이트는 어떠한가? 
이런 경고창이나 알림창이 전혀 없었다. 즉 상호작용이 없다고 생각해도 무방하다. </p>
<h1 id="2-자바스크립트는-왜-쓰는데">2. 자바스크립트는 왜 쓰는데?</h1>
<p>이런식으로 웹사이트에 생명을 불어넣어주는 상호작용을 자바스크립트라는 언어로 하는 것이다. 
HTML과 CSS로 웹 사이트의 구조를 잡는다면 자바스크립트는 그 구조로 정적인 상호작용을 만들어 내는 것이다. 
기억해야 할것은 바로 <strong>HTML을 변화시키거나 반응하게 하는것</strong>이라고 생각하면 된다. 
그 이유는 자바스크립트의 코드가 정적인 html을 반응하게 하거나 새롭게 추가 시켜주기까지 할 수 있기 때문이다.</p>
<p>이렇게 웹 페이지가 발전해 나가면서, 즉 자바스크립트로 웹 페이지를 동적으로 만드는일이 가능해지면서, 하나의 이슈가 생겼다. (아마도?) 
그건 바로 코드의 가독성이 떨어지는 것인데 html코드와 자바스크립트 코드가 각각 다른 파일에 위치하면서 UI에 집중하기 힘든 구조이기 때문이다. 
(별도의 자바스크립트 파일을 만들어서 html <code>&lt;script&gt;</code>라는 태그의 src로 넣어줘야 한다.)
html 태그를 직접적으로 호출 또는 조작해야하고 html에 변경이 생기면 html 전체를 다시 읽어들여야 하기 때문에 어플리케이션의 무게는 무거워지고 작동의 흐름이 복잡해질 수 밖에 없다는 이슈가 생겨났다. 
그 때 혜성같이 (아마도) 나온 라이브러리가 바로 리액트다. </p>
<h1 id="3-리액트가-뭔데">3. 리액트가 뭔데?</h1>
<p>리액트는 자바스크립트 라이브러리로서 다양한 편의성을 제공한다.
이 글에서는 가볍게만 알아보는 것이기 때문에 간단하게만 정리해보겠다. 
먼저 JSX문법을 통해 UI에 더 집중할 수 있는 구조로 프로그래밍이 가능해졌다. 
예전에 UI와 동적움직임에 관한 파일과 코드가 분리되어 있었다면
리액트에서는 JSX문법으로 인해 한 파일에서 한 UI에 대해 모두 작성할 수 있게 됐다. 
html 태그에 접근하는 방법이 매우 쉬워졌다. 
가상의 카피본을 사용하여 변경점이 생긴 부분을 (자바스크립트로 동적인 상호작용을 구현이 시작되거나 완료된 부분) 알아채서 실제의 변경된 부분만 고쳐준다. 
이 말은 즉슨, 바닐라 자바스크립트로 html 태그에 직접 접근하여 조작할 때는 html 태그 전체가 영향을 받았지만 리액트는 변경된 부분만 콕 찝어서 접근하여 조작한다. </p>
<p>정리해보자면 
자바스크립트는 정적인 웹 페이지를 동적으로 만들 수 있는 기능을 제공하여 많이 쓰이게 되었다. 
이 뿐만 아니라 홈페이지에 들어가는 각종 리소스들을 (사진, 글 또는 각종 데이터들)
웹 어플리케이션에 보관할 필요 없이 서버와의 통신으로 받아올 수 있게 되어 성능면에서도 개선이 되었다. </p>
<h1 id="4-리액트는-왜-쓰는건데">4. 리액트는 왜 쓰는건데?</h1>
<p>이런 자바스크립트의 등장으로 웹페이지들은 동적으로 변했지만 
가독성과 UI에 집중할 수 없는 어플리케이션 구조 때문에 리액트라는 라이브러리가 
각광받게 되었는데 리액트에서 사용할 수 있는 JSX 문법으로 인해 html 파일이 아니더라도 html 코드를 작성하여 같은 위치에서 자바스크립트 코드를 입힐 수 있게 되었다.
또한 예전에는 직접 html 파일의 element에 접근하여 자바스크립트 코드를 입혀야 했지만
리액트의 등장으로, UI의 세분화 즉 html element를 세분화하여 사용할 수 있게 되어 
UI에 더 집중할 수 있는 환경이 만들어 진 것이다. 
그리고 리액트가 제공하는 htmle 엘리먼트에 대한 가상본으로 인해 실제 변경된 부분에만 접근하게 되어 어플리케이션의 성능에 최적화를 이룰 수 있게 된 것이다. </p>
<p>그렇다면 결국 리액트는 자바스크립트와 html을 더 편리하게 사용할 수 있게 만들어준 라이브러리다. 
그럼 리액트를 사용하여 자바스크립트로 html에 무엇을 하는 것일까?
결국은 html element에 접근하여 무언가를 하는 것이다. 이것이 자바스크립트의 사용 목적이다. 그리고 그것이 바로 DOM에 접근하여 동적으로 변경시켜 주는 것이고 그것을 리액트가 편리하게 구현할 수 있게 해준다.</p>
<h1 id="5-dom이-뭔데">5. DOM이 뭔데?</h1>
<p>DOM은 Document Object Model의 줄임말으로서, 문서 객체 모델로 불리며 HTML 문서에 접근하기 위한 일종의 인터페이스, 즉 접점이다. 
문서 내의 모든 요소를 정의하고, 정의된 각각의 요소에 접근하는 방법을 제공 한다.</p>
<p>쉽게말해, DOM의 모습은 트리 형태로서 자바스크립트로 하여금</p>
<p>1) 새로운 HTML 요소나 속성을 추가
2) 존재하는 HTML 요소나 속성을 제거
3) HTML 문서의 모든 HTML 요소를 변경
4) HTML 문서의 모든 HTML 속성을 변경할
5) 문서의 모든 CSS 스타일을 변경
6) HTML 문서에 새로운 HTML 이벤트를 추가
7) HTML 문서의 모든 HTML 이벤트에 반응
할 수 있게 해줘 웹 페이지를 동적으로 만드는데 알아야할 중요한 개념이다. 
위 일련의 행위를 하는 것을 DOM에 접근한다 라고 흔히들 말한다. </p>
<p>리액트 같은 라이브러리나 비슷한 기능을 제공하는 프레임워크들 (Vue / Angular)이 나오기 전에 
DOM에 접근을 하려면 DOM API들인 method와 property들을 자바스크립트로 사용해서 접근해서 1~7번의 행위를 해야했는데 html 파일과 자바스크립트 파일이 분리되어 있었기 때문이다.</p>
<p>하지만 리액트의 등장으로 컴포넌트 (view에서 최소한의 UI 단위로 나눠진 블록) 단위로 html과 자바스크립트를 작성할 수 있게 되어 별로의 다른 파일이 존재할 필요가 없어진 것이다.
또한 JSX문법은 자바스크립트와 html을 함께 사용할 수 있게 해주어 DOM에 접근하기 위해 method와 property로 접근할 필요없이 직접 코딩을 하면 된다. 
마지막으로 리액트가 제공하는 가상본, 즉 가상 DOM은 실제 DOM에 접근하기 전에 바뀐 부분만 체크하여 그 부분의 실제 DOM 요소에 접근하여 조작하게 해주어 성능면에서도 장점을 보인다. </p>
<p>정리하자면 DOM은 책 한권을 한장 한장 분리 시켜서 같은 대단원별로, 그 안에서 소단원 별로 so on.. 트리 구조로 바닥에 펼쳐놓는 것이다. 
JSX문법 이전에는 그 한장 한장을 실제로 찾아서 (tree 구조 이기에 root, 최상단부터 찾아 들어가게 된다) 수정사항을 수정해야 했다면 리액트는 그 한장 한장을 각 파일로 컴퓨터에 저장할 수 있게 해줘 작성과 수정에 편리함을 준 것이다. </p>
<h1 id="7-프론트엔드-개발자의-본질은-뭔데">7. 프론트엔드 개발자의 본질은 뭔데?</h1>
<p>그럼 처음 질문으로 돌아와 자바스크립트로 무엇을 하는가에 대해 잘 생각해보면,
더 나아가 프론트엔드 개발자가 하는 일을 생각해보면 DOM을 조작하는 일이다. 
DOM을 조작하는 일은 정적인 html코드에 각종 action을 추가시키고, 반응시키고, 수정시키고 더 나아가 그들의 styling도 변경하고 삭제하고 추가하는 것이다. 
그러나 바닐라 자바스크립트로는 이슈가 발생하기에 조금 더 편리하게 개발하고 유지 보수하기 위해 리액트같은 라이브러리를 사용하는 것이다. 
그럼 결국 DOM을 조작하는 일은 html을 가지고 이리 저리 노는 것(은 아니지만)이라고 볼 수 있겠다. 
(물론 단편적인 프론트엔드가 무엇을 하는가에 대한 대답이다. 코드 성능, 어플리케이션 최적화 등 신경써야할 부분은 무수히 많다.)
궁극적으로 UI를 html로 구성을 하고 interactiv하게 유저와 상호작용을 할 수 있는 interface를 코드로서 프로그래밍 하는 것이 프론트엔드가 해야 할 일이다. 
그 안에는, 앞서 말한바와 같이, 무수히 많은 고려사항이 존재한다. 
데이터를 효율적으로 받아오고, 어플리케이션 내부에서 상태를 효율적으로 관리해야하고 에러와 버그와 끝없는 싸움 등등 너무 많다. </p>
<p>또한 SinglePageApplication 이라는 리액트의 특성도 고려해봐야 한다.
모든 페이지의 script를 DOM으로 나타내는 것이 아닌 현재 필요한 view UI에 관한 스크립트만 존재한다.
한장에 페이지를 그렸다가 지웠다가 하는 것이라고 생각하면 된다.
그럼 결국 SPA도 최적화와 관련된 있지 않을까?
그럼 결국 자바스크립트도 how가 아닌 what 목적에 조금 더 초점을 맞춰야 되겠다는 생각이 든다. </p>
<p>근본적으로 위의 행동들은 자바스크립트로 프로그래밍 하게 된다. 
그렇기 떄문에 자바스크립트의 궁극적인 목표와 목적에 대해 명확히 알고 있으면
위의 여러 고려사항들로 인해 공부해야할 자바스크립트 중급 이상의 개념들에 대해 조금 더 이해도가 높아지지 않을까 하는 개인적인 희망사항으로 정리 해 보았다. 
그리고 how에서 what으로 생각의 중점을 조금씩 옮겨봐야 겠다는 생각이 들기도 한다.</p>
<hr>
<p>다음글에서는 위에서 말한 일련의 행위들로 생겨나는 issue들을 자바스크립트의 실행 방식과 함께 정리해볼 예정이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Promise 패턴으로 계획하고 Promise한테 감시받기]]></title>
            <link>https://velog.io/@_jouz_ryul/Promise%EB%A1%9C-%EA%B3%84%ED%9A%8D%ED%95%98%EA%B3%A0-%EA%B0%90%EC%8B%9C%EB%B0%9B%EA%B8%B0</link>
            <guid>https://velog.io/@_jouz_ryul/Promise%EB%A1%9C-%EA%B3%84%ED%9A%8D%ED%95%98%EA%B3%A0-%EA%B0%90%EC%8B%9C%EB%B0%9B%EA%B8%B0</guid>
            <pubDate>Thu, 04 Jun 2020 20:07:45 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>아래 글에서 자바스크립트 코드가 어떻게 실행되는지 아주 살짝 맛만봤다.
그 맛을 보니 비동기함수를 처리하는 맛도 봤는데 그 때 발생한 이슈에 대처해서 사용할
Promise에 대해 알아보자.
<a href="https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%99%80-%EC%97%94%EC%A7%84-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%8B%A4%ED%96%89-%EB%B0%A9%EC%8B%9D">https://velog.io/@_jouz_ryul/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%99%80-%EC%97%94%EC%A7%84-%EA%B7%B8%EB%A6%AC%EA%B3%A0-%EC%8B%A4%ED%96%89-%EB%B0%A9%EC%8B%9D</a></p>
</blockquote>
<p>개발을 하다보면 API request를 통한 서버와의 교신으로 데이터를 받아와서 사용하는 경우가 많다. 처음에는 이 API request나 Web API를 사용하여 데이터를 받아 사용해야 되는 경우 많은 에러와 어려움을 마주쳤는데 이 모든게 자바스크립트가 비동기 함수를 조금 특이하게 처리하기 때문이다.</p>
<p>이에 대한 해답은 Promise 패턴을 사용하는 것인데 Promise는 하나의 약속과도 같은 개념이다. 
그럼 그 약속은 무엇이며 ECMA Scirpt 6 스펙에 정식 포함되기까지 했는지 알아보자.</p>
<hr>
<h1 id="1-비동기-함수-처리로-인한-이슈">1. 비동기 함수 처리로 인한 이슈.</h1>
<p>자바스크립트는 기본적으로 동기적으로 코드가 실행된다. 하지만 비동기 함수에 대해서는 비동기적으로 처리하는 조금 특이한 점해서 이슈가 발생한다.
대표적인 비동기 함수인 <code>fetch</code>함수로 실제로 통신을 하는 코드를 예제 삼아 알아보자. </p>
<hr>
<h2 id="11-비동기-함수-이슈">1.1. 비동기 함수 이슈.</h2>
<p>먼저 어떤 이슈가 발생하는지 알아보자.</p>
<pre><code class="language-javascript">let example = 1

let fakeFetch =() =&gt; {
  setTimeout( ()=&gt; {
    return example =5
  },3000)
}
fakeFetch()
console.log(example)
// expect example value : 5
// actual example value: 1</code></pre>
<p>우선 <code>fakeFetch</code>함수라는 서버와의 통신을 하는데 3초가 걸린다는 가정으로 만든 가짜 <code>fetch</code>함수, 즉 비동기 함수다.
이 비동기 함수로 서버와의 통신으로 5 라는 값을 가져와
<code>example</code>변수에 다시 할당하는 코드를 작성했다.
그리고 함수를 실행하고 example값이 어떻게 바뀌는지 보자.
여전히 1 이다.
그 이유는 알다시피 비동기 함수의 실행 순서가 제일 뒤로 밀렸기 때문에 5라는 값을 할당하기 전에
<code>console.log(example)</code>이 실행되어 변경될 값이 아닌 현재의 값 1을 사용한 것이기 때문이다.</p>
<p>이렇게 데이터를 실제로 서버로부터 받아서 사용할 때 시점의 문제가 생긴다. 
서버로 받은 데이터를 받아서 사용할 코드의 실행 순서는
비동기 함수를 사용해서 데이터를 받아오기 때문에 항상 먼저일 수 밖에 없는 문제가 생긴다.
그럼 어떻게 해결할까?
받아온 데이터를 사용할 코드도 비동기로 사용해야하나?
그렇지 않다. Promise를 사용하면 된다.</p>
<hr>
<h1 id="2-promise는-어머니다-promise-내부-파헤치기">2. Promise는 어머니다: Promise 내부 파헤치기</h1>
<p>Promise는 고유의 패턴을 이용해 가정 및 계획표를 세울 수 있다. 
패턴이 계획표를 세우는 것이라면 Promise는 Promise로 계획한 계획표가 지켜지는지 감시를 해준다고 (사실은 검사가 맞다) 생각하면 된다.
예를 들어 방학 생활 계획표를 Promise 패턴으로 짰다면 Promise가 어머니의 역할로서 잘 지키는지 감시하고 도와준다.
계획대로 지키지 못하면 지키지 못했다고 잔소리를 (사실상 에러를 catch해주는 아주 좋은 기능) 덧붙혀 준다.</p>
<p>말로하니 어렵다. 역시나 예제 코드와 함께 
Promise가 무엇인지
Promise 구조는 어떠한지
Promise 패턴은 무엇인지
Promise가 어떻게 감시를 하는지
하나하나 알아보자.</p>
<p>(<em>Promise와 Promise패턴을 구분해서 정리하면 이해하기 쉽다. 
Promise 패턴은 Promise를 사용하기 위한 코드 구조라고 생각하면 쉽다.</em>)</p>
<hr>
<pre><code class="language-javascript">//Promise 사용과 Promise 패턴
let someVal = 1
let API_EXAMPLE_PROMISE =() =&gt; {
  1️⃣return new Promise(
  2️⃣(resolve,reject)=&gt; {
    setTimeout(()=&gt; {
      if (someVal===1) {
 resolve(someVal + 10)
      } else {reject(console.log(&quot;Fail&quot;))}
},3000)
  })3️⃣.then(data=&gt; console.log(data))
}
API_EXAMPLE_PROMISE()
// console: 11</code></pre>
<p>1️⃣ Promise 선언.
2️⃣ resolve는 성공, 즉 조건에 성공했을 때 그리고 reject는 실패, 즉 조건에 실패했을 때 사용하는것.promise 안에서 꺼내 쓰는것이다. 다시 말해 조건에 성공했다면 resolve()안의 인수값을 
리턴한다고 일단 생각하자. </p>
<p>3️⃣ Promise chain 즉 패턴의 형식이다. <code>.then</code>을 사용하여 
Promise안에 콜백으로 작성한 코드의 응답이 들어오면 이라고 가정하는 거라고 볼 수 있다. 
promise 패턴으로 api 호출 등으로 받아오는 값을 처리할 수 있다. 
이 예제는 resolve의 예제이기 때문에 resolved가 되었고
<code>.then</code>으로 리턴된 값 11을 콘솔에 사용할 수 있었던 것이다. 
(패턴에 대해서는 밑에 다시 정리할 예정)</p>
<p>위 예제는 Promise 패턴으로 3초 뒤에 실행될 함수가 연산할 값을 사용할 수 있는 형태에 대한 예제이고 가장 기본적인 형태의 Promise 사용법이다.
지금 한줄 한줄 읽어봐도 좋지만 먼저 Promise 내부를 하나하나 살펴보고 그 다음 추가로 다시 예제와 함께 알아보자. </p>
<h2 id="21-promise-상태">2.1. Promise 상태</h2>
<p>위의 코드 형태를 살펴보면 우리가 3초뒤에 연산의 값을 실행하는, API 요청 (response값을 받아오는데까지 시간이 걸리는)에 관한 함수를 Promise의 인수로 넣어줬다. 
그 후 if 문으로 조건을 걸어 조건에 일치하면 연산을 실행하고 조건과 다르면 fail이라는 문자열을 콘솔로 보여주라고 코드를 작성했다. 이게 무슨 뜻일까?
<code>new Promise()</code>라고 Promise를 선언하고 그 안에 우리가 코드를 작성하면 
해당 조건들에 따라 Promise는 상태를 가진다. 먼저 Promise의 상태들 중 3개에 대해서 알아보자.</p>
<pre><code class="language-javascript">// pending state
let sampleVal = 1
let pendingState = () =&gt; {
  return new Promise(()=&gt; {
    return sampleVal
  })
}
console.log(pendingState())

// fulfilled or resolvesd state
let sampleVal = 1
let pendingState = () =&gt; {
  return new Promise((resolve)=&gt; {
     resolve(sampleVal)
  })
}
console.log(pendingState())
// rejected
let sampleVal = 1
let pendingState = () =&gt; {
  return new Promise((resolve, reject)=&gt; {

     reject(sampleVal)

  })
}
console.log(pendingState())</code></pre>
<p>위 코드를 한 케이스당 하나씩 콘솔에 찍어보자. 아마 다음처럼 나올 것이다.</p>
<p>pending<img src="https://images.velog.io/images/_jouz_ryul/post/d8bc381c-6c42-4414-9e68-f789d472d6ab/%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%202020-06-05%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%202.25.31.png" alt="">fulfilled or resolvesd state<img src="https://images.velog.io/images/_jouz_ryul/post/321c9804-cbf9-440c-95b8-f3792b466ee4/%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%202020-06-05%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%202.25.36.png" alt="">
rejected<img src="https://images.velog.io/images/_jouz_ryul/post/370fc73d-e773-4824-a829-e1c9aba4ad6f/%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%202020-06-05%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%202.25.43.png" alt=""></p>
<p>이 세개가 대표적인 Promise의 상태이다.</p>
<p>1) pending: 기본 Promise의 상태로서 수행하기 전의 상태이다. 즉 default 값인 것이다.
2) resolved(fulfilled): 약속이 지켜진, 즉 계획대로 된 상태이다.
3) rejected: 약속이 어겨진, 즉 계획대로 된 것이 아닌 상태이다.</p>
<p>이렇게 Promise는 Promise 패턴에 대해서 지켜지는지 지켜지지 않았는지 일일히 확인해준다. 
그리곤 알려준다. 계획대로 잘 됐는지(resolved) 아니면 계획대로 되지 않았는지. </p>
<h1 id="3-promise-패턴은-계획표다">3. Promise 패턴은 계획표다.</h1>
<p>그럼 대체 Promise 패턴 무엇일까?
말 그대로 약속이다. 다른말로 하면 <strong>가정</strong>이라고 볼 수 있다.
위에서 말한 것처럼 자바스크립트 엔진은 특정 함수들의 호출에 대한 실행을 뒤로 미룬다.
언제까지? 다른 일반 함수들의 실행이 모두 끝날 때 까지.</p>
<hr>
<p>한마디로 Promise 패턴은 계획표이자 가정이다.
초등학교 때 방학이 되면 방학 계획표를 짰던 기억이 난다.
주로 다음과 같은 계획표를 짰다.</p>
<ol>
<li>아침 9시에 일어난다.</li>
<li>일어나서 아침을 먹는다.</li>
<li>아침을 먹고 수학을 공부한다.</li>
<li>수학 공부를 하고 점심을 먹는다
...
이런식으로 (물론 지키지 못했지만) 가정을 기반으로 계획을 짰었다. 
이게 프로미스다. 무슨말일까?
다시 위의 예제 코드를 가지고 알아보자.<pre><code class="language-javascript">// API 호출 예제
let someVal = 1
let API_EXAMPLE = ()=&gt; {
setTimeout(function() {
2️⃣someVal + 10
},3000)
3️⃣return someVal
}
</code></pre>
</li>
</ol>
<p>4️⃣let someFinalVal = 1️⃣API_EXAMPLE() + 100
console.log(someFinalVal)
//expected someFinalVal = 111
// actual someFinalVal = 101</p>
<pre><code>1️⃣의 실행 결과값으로 2️⃣에서 원하는 연산을 하고 3️⃣에서 결과값으로 반환하여 4️⃣의 변수에 할당될 값의 연산값으로 사용하고 싶었는데
2️⃣의 연산값이 적용되지 않았다. 실제로는 1️⃣의 실행 결과는 11이 되게 하고 싶었지만 전역에 선언된 1을 가져와 4️⃣변수의 값은 101로 할당 된 것이다. 

그런 결과는 2️⃣의 연산을 실행할 함수가 비동기 함수여서 자바스트립트가 실행을 다른 곳에 위임했고 
콜 스택에서 쌓인 다음 연산을 실행했기 때문에 반영되지 못한것이다.

그럼 여기에 Promise 패턴을 사용하면 어떤 가정을, 어떤 계획표를 세울 수 있는 것일까?
아마 콜 스텍에 쌓이지 않은 2️⃣의 연산을 할 함수의 실행을 가정할 수 있을것 같다. 
Promise 패턴을 사용하여 가정을, 계획표를 세우면 다음과 같이 해석할 수 있다.
&quot;이거 값을 할당하는 response까지 3초가 걸리는데 그냥 값이 할당되었다고 가정하자.&quot;
혹은
&quot;이거 값이 들어올건데 그 값이 들어오면 2️⃣번 연산을 실행 할거야.&quot;
이런식으로 가정을 하거나 계획을 세우면 Promise 패턴을 사용하는 것이다. 

## 3.1. 실제로 가정해보기
그럼 실제 `fetch`함수를 사용해서 알아보자.

```json
// 실제 받아올 데이터
//https://jsonplaceholder.typicode.com/users
[
  {
    &quot;id&quot;: 1,
    &quot;name&quot;: &quot;Leanne Graham&quot;,
    &quot;username&quot;: &quot;Bret&quot;,
    &quot;email&quot;: &quot;Sincere@april.biz&quot;,
    &quot;address&quot;: {
      &quot;street&quot;: &quot;Kulas Light&quot;,
      &quot;suite&quot;: &quot;Apt. 556&quot;,
      &quot;city&quot;: &quot;Gwenborough&quot;,
      &quot;zipcode&quot;: &quot;92998-3874&quot;,
      &quot;geo&quot;: {
        &quot;lat&quot;: &quot;-37.3159&quot;,
        &quot;lng&quot;: &quot;81.1496&quot;
      }
    },
    &quot;phone&quot;: &quot;1-770-736-8031 x56442&quot;,
    &quot;website&quot;: &quot;hildegard.org&quot;,
    &quot;company&quot;: {
      &quot;name&quot;: &quot;Romaguera-Crona&quot;,
      &quot;catchPhrase&quot;: &quot;Multi-layered client-server neural-net&quot;,
      &quot;bs&quot;: &quot;harness real-time e-markets&quot;
    }
  },
  {
    &quot;id&quot;: 2,
    &quot;name&quot;: &quot;Ervin Howell&quot;,
    &quot;username&quot;: &quot;Antonette&quot;,
    &quot;email&quot;: &quot;Shanna@melissa.tv&quot;,
    &quot;address&quot;: {
      &quot;street&quot;: &quot;Victor Plains&quot;,
      &quot;suite&quot;: &quot;Suite 879&quot;,
      &quot;city&quot;: &quot;Wisokyburgh&quot;,
      &quot;zipcode&quot;: &quot;90566-7771&quot;,
      &quot;geo&quot;: {
        &quot;lat&quot;: &quot;-43.9509&quot;,
        &quot;lng&quot;: &quot;-34.4618&quot;
      }
    },
    &quot;phone&quot;: &quot;010-692-6593 x09125&quot;,
    &quot;website&quot;: &quot;anastasia.net&quot;,
    &quot;company&quot;: {
      &quot;name&quot;: &quot;Deckow-Crist&quot;,
      &quot;catchPhrase&quot;: &quot;Proactive didactic contingency&quot;,
      &quot;bs&quot;: &quot;synergize scalable supply-chains&quot;
    }
  },
  ...
  ]</code></pre><p>위 주소로 접속하면 실제 열개의 객체가 담긴 배열이 나온다. 
이 주소로 실제 서버 통신으로 우리가 값을 받아볼 수 있는데 그럼 코드를 작성해보자</p>
<pre><code class="language-javascript">let myData =&quot;&quot;
let getCollectionData = () =&gt; {
  myData = fetch(&#39;https://jsonplaceholder.typicode.com/users&#39;).then(response=&gt; response.json()).then(response=&gt; response[0])
  return myData
}
getCollectionData()

console.log(myData)
</code></pre>
<p><code>fetch</code>함수를 사용해 서버와의 통신으로 데이터를 받아와서 0번째 인덱스의 객체를 콘솔에 찍어보는 코드다. 
그냥 Promise 패턴은 <code>.then</code>이라고 알아두고 (뒤에서 다시 정리할 예정)
콘솔을 확인해보자!</p>
<p><code>Promise {&lt;pending&gt;}</code>이라는 녀석만 보일 것이다.
Promise를 사용해서 문제를 해결하려고 했는데
결과가 그냥 Promise가 찍힌다.
비동기로 처리되어 연산값을 사용할 수 없는 이슈는 해결된 것 같은데 Promise의 사용도 아니고 Promise 패턴만 사용했는데
Promise가 결과로 나오다니 무슨말인가?</p>
<p>잘 살펴보면 위의 Promise 예제와 그전의 Promise를 선언하여 사용한 예제와 다른점이있다.
이 예제에는 Promise 선언부가 없다.
재밌는점은 <code>fetch</code>는 Promise를 반환한다.
그래서 <code>.then</code>, Promise 패턴을 사용할 수 있었던 것이다.
명심할 것은 Promise에만 <code>.then</code>이 적용된다.
그럼 Promise가 리턴되는건 무슨 말일까?</p>
<h1 id="4-promise는-promise를-반환한다">4. Promise는 Promise를 반환한다?</h1>
<blockquote>
<p>The Promise returned from fetch() won’t reject on HTTP error status even if the response is an HTTP 404 or 500. Instead, it will resolve normally (with ok status set to false), and it will only reject on network failure or if anything prevented the request from completing.
출처: <a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch">https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch</a></p>
</blockquote>
<p>MDN 공식문서에 나온 내용이다. fetch함수의 실행은 Promise를 반환한다. 하지만 요청 에러 상태에 대해서 reject하지 않고 정상적으로 resolve상태로 반환되며 네트워크 연결 실패시에만 reject한다고 나와있다. 
여기서 의문점</p>
<p>1) Promise를 반환한다는것이 무슨뜻일까?
2) 왜 reject 하지 않을까?</p>
<p>그럼 Promise가 Promise를 반환한다는 것이 무슨 뜻이며 왜 그러한것일까?
다시 Promise 사용법을 상기시켜보자.</p>
<ol>
<li><code>new Promise</code>로  Promise임을 선언해준다.
즉 자바스크립트 내장 함수로 저장된 Promise 객체를 <code>new</code> 키워드를 통해인스턴스화 한것이다. </li>
<li>Promise의 인수로 실행하고자 하는 함수를 작성한다. </li>
</ol>
<p>그럼 이제 Promise 상태와 잘 연결해서 생각해보자. </p>
<ol>
<li><code>new Promsie</code>로 Promise를 선언하여 인스턴스화 한다.</li>
<li>Promise의 인수로 무명 함수를 넣어 우리가 얻고자 하는 실행을 작성한다.</li>
<li>그 결과 값이(resolve 혹은 rejected) Promise로 return되어 Promise를 인스턴스화한 함수의 반환 된다. </li>
</ol>
<p>역시나 예제를 통해 쉽게 알아보자.
<img src="https://images.velog.io/images/_jouz_ryul/post/a7b88438-c8c4-499d-850b-a4637a6206e9/%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%202020-06-05%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%202.53.21.png" alt=""><img src="https://images.velog.io/images/_jouz_ryul/post/d50a32fb-fbeb-432d-9959-824077e953ef/%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%202020-06-05%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%202.53.29.png" alt=""><img src="https://images.velog.io/images/_jouz_ryul/post/6a7d6eec-c50a-4cff-8f86-a5c8e2a07cb1/%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%202020-06-05%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%202.53.33.png" alt=""></p>
<p>순서대로 pending-resolved-rejected가 콘솔에 찍힌다. 
Promise의 대표적 상태 3가지를 다시 적어보면</p>
<ol>
<li>pending</li>
<li>resolved</li>
<li>rejected
인데</li>
</ol>
<p>1번 사진은 Promise 안에 작성한 함수의 return으로 아무것도 하지않고 값만 반환하였다.
즉 resolve 나 reject로 Promise의 상태를 변화시킬 조건이나 값이 하나도 없는것이다.
그래서 Promise는 아무것도 하지않고 태초의 default인 pending으로 유지되어 현재의 상태를 return 한것이다.</p>
<p>2번과 3번은 resolve 와 reject로 Promise 상태를 바꿀 값 혹은 조건을 넣어줬다.
그랬더니 Promise의 상태가 바뀌어 콘솔에 해당하는 상태가 찍힌것이다. </p>
<p>이렇게 Promise를 사용하면 resolve, reject로 Promise의 상태를 바꿔줘야 한다.
그 이유는 Promise 패턴으로 비동기 함수 실행에 대한 계획표를 짠다고 했는데
Promise의 상태에 따라 우리가 실행하고 싶은 일들을 계획할 수 있기 때문이다.</p>
<p>resolve를 예로 들어, resolve의 조건으로 sampleVal을 넣는다면
이로 인해 Promise 상태가 resolved인 콜백함수가 반환 될 것이고 <code>.then</code>으로 그 콜백함수에 접근할 수 있어 매개변수로서 받아서 사용이 가능해지기 떄문이다. </p>
<p>반대로 reject의 조건으로 <code>sampleVal</code>을 넣어 이에 해당할 때 실행할 일을 <code>.then</code>으로 계획한다고 코드를 짠다면 그 후의 계획은 CALL BACK 함수로써 매개변수로 <code>sampleVal</code>을 사용할 수 있게 되기 때문이다. </p>
<p>정리하자면 Promise를 인스턴스화 해서 사용하면 Promise를 반환하는데 resolve와 reject의 조건에 따른 반환값이나 할당된 값에 각각 대응하여 Promise의 상태를 resolved나 rejected로 바꿔서 콜백함수를 반환한다.
(resolve와 reject의 값이 없거나 조건이 없으면 pending 유지)
이에 Promise 패턴을 사용할 때 <code>.then</code>으로 미래의 일을 계획하며 작성을 하는데
이때 Promise의 변한 상태에 따른 각각 실행하고 싶은 코드를 작성할 것이다.
이떄 이들은 call back함수로서 반환한 Promise의 값을 매개변수로 사용할 수 있게된다. 그렇기에 Promise의 상태를 각 조건과 값에 따라 바꿔서 반환해 주는 것이다. </p>
<p>아마 눈치챘겠지만 그렇다. Promise 패턴은 결국 callback을 사용하는 것이다.
그럼 이미 callback으로 해결이 가능한 실행 처리를 왜 굳이 Promise 패턴을 사용하는 것일까?</p>
<h1 id="5-promise에게-감시받는-방법">5. Promise에게 감시받는 방법.</h1>
<p>간단하게 말하면 에러 핸들링이 편한다. 왜냐? 어머니의 감시처럼
Promise가 철저하게 에러에 대해서 지켜봐주고 있기 때문이다.</p>
<pre><code class="language-javascript">// Promise 패턴을 사용하지 않고 일을 계획하는 것

let sampleVal = 1
let callbackFunc =     (sampleVal)=&gt; {
       return sampleVal+1
     }

let pendingState = (callbackFunc) =&gt; {
  return callbackFunc(callbackFunc(callbackFunc(callbackFunc(sampleVal))))
}
console.log(pendingState(callbackFunc))

// Promise 패턴을 사용하여 일을 계획 하는 것
let sampleVal = 1
let callbackFunc =     (sampleVal)=&gt; {
       return sampleVal+1
     }
let pendingState = (callbackFunc) =&gt; {
  return new Promise((resolve, reject)=&gt; {

    resolve(callbackFunc(callbackFunc(callbackFunc(callbackFunc(sampleVal)))))



  })
}
console.log(pendingState(callbackFunc))
</code></pre>
<p>물론 이번 예제는 Promise의 감시능력에 대해 보기 위해 똑같이 callback으로 실행을 했다.
밑의 코드에서 아무 오타나 한번 내보자.
한번 첫 <code>callbackFunc</code>에 들어가는 <code>sampleVal</code>을 <code>sampleVla</code>로 바꾸고 콘솔창을 지켜보자.
Promise에서 오류가 발생하고 그 내용도 자세히 알려준다.
더 나아가 Promise 패턴은 가독성이 좋다. 지금 위의 코드들은 도대체 뭘 하고있는지 추적하기가 쉽지 않다. Promise 패턴의 <code>.then</code> 매소드를 사용해보면 가독성이 훨신 좋아진다.</p>
<pre><code class="language-javascript">let sampleVal = 1

let pendingState = () =&gt; {
  return new Promise((resolve, reject)=&gt; {

    resolve(sampleVal)



  }).then((val)=&gt; {return val+1}).then((addedVal)=&gt; {return addedVal *10}).then(multipliedVal=&gt; {return multipliedVal + 10})

}
console.log(pendingState())</code></pre>
<p>가독성이 훨신 좋아졌다. 어떤 함수가 무엇을 받아서 뭘 하는지 차례차례 잘 보인다.
콘솔창은 다음과 같을 것이다. 
<img src="https://images.velog.io/images/_jouz_ryul/post/8a39b79b-1f47-4515-ad07-88f07f346e59/%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%202020-06-05%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%203.45.20.png" alt="">
그런데 뭔가가 눈에 거슬린다.
아까는 분명 resolved였는데 <code>.then</code>메소드를 사용해서 계획하고 실제로 실행했는데도 Promise의 상태는 resolved인데 왜 console에는 pending이라고 찍히는 걸까?</p>
<h1 id="6-돌아온-싱글-settled">6. 돌아온 싱글 settled</h1>
<p>그 이유는 Promise가 fulfilled (resolved) 또는 rejected의 상태로 바뀌면 앞선 예제처럼 <code>.then</code>메소드로 다음 실행을 handle 할 수 있게 된다.
(그래서 <code>.then</code>이 handler라고도 불린다.)
그런데 Promise가 제공하는 <code>.then/catch/finally</code>등의 여러 핸드러는 
Promise가 pending 상태 일때 호출을 기다린다. 
그리고 상태가 fulfilled 나 rejected가 되면 Promise의 상태는 바로 settled라는 상태로 바뀐다. 
이는 한번 fulfilled나 rejected가 되었던 Promise의 pending 상태를 일컷는 말이다. </p>
<p>이 settled 라는 상태가 되면 <code>.then/catch/finally</code>등의 Promise가 제공하는 여러 핸드러가 즉시 실행이 가능하다. 
그 후 핸드러들의 실행이 반환되어 실행이 끝나면 Promise의 상태는 다시 pending이 되는데 처음 Promise를 인스턴스했을 떄의 pending이 아닌
한번 rejected 나 fulfilled로 상태가 바뀐 대기 상태를 말하는 settled상태 인것이다.
쉽게말해 돌싱이라는 이야기다.
그래서 콘솔에 pending이라고 찍히는 것이다.</p>
<p>정리하면 Promise의 실체는 resolve 나 reject를 통해 Promise의 상태를 바꿔준 후 
각 상황에 따라 Promise의 상태를 fulfilled(resolved)나 rejected로 바꿔준다.
이렇게 상태가 바뀐 Promise는 즉각 pending 상태로 바뀌는데 
이 떄의 pending은 돌싱이다. 즉 한번 상태가 바뀌었다, 즉 사용되었음을 인지하고 있기 때문에
<code>.then</code> 등 Promise가 제공하는 메소드 혹은 핸들러를 즉각 실행을 가능하게 해준다. </p>
<p>그럼 이제 내부를 까봤으니 생각을 머리속에 잘 조립하여 앞서 시도하던 실제 <code>fetch</code> 함수를 Promise 패턴으로 실행해보자.</p>
<h1 id="7-api-호출-실전">7. API 호출 실전</h1>
<p>자 다시 3.1의 예제코드를 실행해보자. </p>
<p>이제 원리를 알았으니 적용해서 사용해보는 일만 남았다.</p>
<pre><code class="language-json">// 실제 받아올 데이터
//https://jsonplaceholder.typicode.com/users
[
  {
    &quot;id&quot;: 1,
    &quot;name&quot;: &quot;Leanne Graham&quot;,
    &quot;username&quot;: &quot;Bret&quot;,
    &quot;email&quot;: &quot;Sincere@april.biz&quot;,
    &quot;address&quot;: {
      &quot;street&quot;: &quot;Kulas Light&quot;,
      &quot;suite&quot;: &quot;Apt. 556&quot;,
      &quot;city&quot;: &quot;Gwenborough&quot;,
      &quot;zipcode&quot;: &quot;92998-3874&quot;,
      &quot;geo&quot;: {
        &quot;lat&quot;: &quot;-37.3159&quot;,
        &quot;lng&quot;: &quot;81.1496&quot;
      }
    },
    &quot;phone&quot;: &quot;1-770-736-8031 x56442&quot;,
    &quot;website&quot;: &quot;hildegard.org&quot;,
    &quot;company&quot;: {
      &quot;name&quot;: &quot;Romaguera-Crona&quot;,
      &quot;catchPhrase&quot;: &quot;Multi-layered client-server neural-net&quot;,
      &quot;bs&quot;: &quot;harness real-time e-markets&quot;
    }
  },
  {
    &quot;id&quot;: 2,
    &quot;name&quot;: &quot;Ervin Howell&quot;,
    &quot;username&quot;: &quot;Antonette&quot;,
    &quot;email&quot;: &quot;Shanna@melissa.tv&quot;,
    &quot;address&quot;: {
      &quot;street&quot;: &quot;Victor Plains&quot;,
      &quot;suite&quot;: &quot;Suite 879&quot;,
      &quot;city&quot;: &quot;Wisokyburgh&quot;,
      &quot;zipcode&quot;: &quot;90566-7771&quot;,
      &quot;geo&quot;: {
        &quot;lat&quot;: &quot;-43.9509&quot;,
        &quot;lng&quot;: &quot;-34.4618&quot;
      }
    },
    &quot;phone&quot;: &quot;010-692-6593 x09125&quot;,
    &quot;website&quot;: &quot;anastasia.net&quot;,
    &quot;company&quot;: {
      &quot;name&quot;: &quot;Deckow-Crist&quot;,
      &quot;catchPhrase&quot;: &quot;Proactive didactic contingency&quot;,
      &quot;bs&quot;: &quot;synergize scalable supply-chains&quot;
    }
  },
  ...
  ]</code></pre>
<pre><code class="language-javascript">  let myData =&quot;&quot;
let getCollectionData = () =&gt; {
  myData = fetch(&#39;https://jsonplaceholder.typicode.com/users&#39;)
  return myData
}
getCollectionData()

console.log(myData)
</code></pre>
<p>콘솔을 확인하면 잘 찍히는 것을 알 수 있다.
이게 바로 Promise를 인스턴스화 해서 사용하고 Promise 패턴으로 가독성을 높히고 에러를 잡아내는 방법이다.</p>
<ol>
<li><p>총 정리 하면 자바스크립트 엔진이 자바스크립트 코드를 비동기 실행 방식으로 실행하는데, 
함수에 있어서, 조금 특이한 방법으로 실행한다. </p>
</li>
<li><p>대표적으로 API 요청 같은 경우에는 실행의 순서가 맨 뒤로 옮겨지기 때문에 코드들을 순서대로 작성하고 API 요청으로 변수에 값을 담으려 해도 결국 값은 담기지 않는다.</p>
</li>
<li><p>그래서 Promise를 사용하고 Promise가 제공하는 핸드러를 사용하여 계획표를 짠다.</p>
</li>
<li><p>이 곳에서는 callback으로써 값을 받아서 사용하기 때문에 에러가 발생하지 않을뿐더러 
Promise 패턴을 사용하면 가독성이 좋아져서 디버깅도 쉽고 에러를 찾아내는 것도 수월해진다.</p>
</li>
</ol>
<ul>
<li>다음 블로그에 Promise의 자주 쓰이는 핸들러인 <code>try/ catch/ async/ await</code>를 정리하도록 하고
기본 Promise 정리를 끝내도록 하겠다.</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>