<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Ginger's velog</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Tue, 12 Oct 2021 15:58:40 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Ginger's velog</title>
            <url>https://images.velog.io/images/mong-byte/profile/441072b6-77cc-4ae6-884c-53f7b229000e/20200723_000133.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Ginger's velog. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/mong-byte" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[React와 Vue]]></title>
            <link>https://velog.io/@mong-byte/React%EC%99%80-Vue</link>
            <guid>https://velog.io/@mong-byte/React%EC%99%80-Vue</guid>
            <pubDate>Tue, 12 Oct 2021 15:58:40 GMT</pubDate>
            <description><![CDATA[<h2 id="intro">Intro</h2>
<p>개발을 시작하고 난 이래로 아직까지 react만 사용하였었지만, 이번에 가고싶은 회사의 기술스택이 vue를 사용 하는 곳이라 vue를 다뤄 볼 기회가 생겼다.</p>
<p>간단하게 미니 프로젝트를 진행하면서 어떤 공통점이 있고 차이점이 있는지 정리 해 보려고 한다.
react를 먼저 배우던 입장에서 작성이 될 것이고, 기본적으로 react와 어떤 차이점이 있는지, 어떻게 다르게 느꼈는가를 위주로 작성 해 보고자 한다.</p>
<h2 id="공통점">공통점</h2>
<p>우선 어떤 부분이 같은지 먼저 살펴보도록 하자.</p>
<ul>
<li>컴포넌트 기반으로 동작한다.</li>
<li>가상돔(Virtual DOM)을 사용한다.</li>
<li>코어 라이브러리가 있고, 라우터, 전역 상태관리등은 별도의 라이브러리가 존재</li>
</ul>
<p>우선 둘다 SPA를 만들기 위한 라이브러리이기 때문에, 컴포넌트 기반으로 동작하거나, 가상돔을 사용하여
성능 향상을 도모하고 있다.</p>
<p>공통점이라 할지는 애매했지만, vue3의 compositionAPI를 사용 할 경우, <code>setup()</code>이라는 함수 안에서
react와 유사하게 코드를 짜는것이 가능했다.</p>
<pre><code class="language-js">&lt;script&gt;
  export default {
    name: &quot;App&quot;,
    data() {
      return {
        count : 0
      }
    }
    method: {
      incCount() {
        return this.count + 1;
      }
    }
}
&lt;/script&gt;

&lt;script&gt;
  import { reactive, toRefs } from &#39;vue&#39;;
  export default {
    name: &quot;App&quot;,
    setup() {
      const state = reactive({
        conut: 0
      });

      const { countValue } = toRefs(state);

      const incCount = () =&gt; {
        return countValue.value + 1
      }
      return { countValue }
    }
}
&lt;/script&gt;</code></pre>
<p>위의 코드가 기존 코드이고, 아래 코드가 compositionAPI가 적용 된 코드이다. 지금은 아래가 좀 더 길어 보이지만, life cycle등의 method도 setup안에 들어가게 되므로, 꽤나 편하게 작성 할 수 있었다.</p>
<h2 id="차이점">차이점</h2>
<h3 id="vue의-특징">vue의 특징</h3>
<h4 id="sfc">SFC</h4>
<p>우선 SFC라는 개념이 있다.
SFC란 Single File Component의 약자로서, 하나의 파일이 하나의 컴포넌트를 담당하는 .vue라는 파일을 이야기한다.
때문에, vue의 page와 component는 .js혹은 .ts가 아니고 .vue로 만들어지게 된다.</p>
<p>이때, .vue의 파일 구조는 html을 담당하는 <code>&lt;template&gt;</code>, 자바스크립트가 작성 되는 <code>&lt;script&gt;</code>, 스타일을 정의하는 <code>&lt;style&gt;</code>이 그것이다.
이처럼 한 파일 안에 해당 컴포넌트가 가지고 있는 정보를 모두 볼 수 있기에, 한눈에 보기가 편해지는 장점이 있다. 
react를 사용할 시 styled-component를 사용하지 않고 css파일이나 css전처리기를 사용하는 프로젝트라면 외부에 css파일을 만들고 왔다갔다하면서 관리해야하니 이 부분은 괜찮다고 느꼈다.</p>
<h4 id="state">State</h4>
<p>두번째로는 state와 불변성의 부재이다.
vue를 사용하면서는 <code>data()</code>안에 해당 컴포넌트에서 사용되는 값이 관리 된다. 마치 state처럼 사용 되는 값이지만, react처럼 불변성을 유지할 필요가 없다.</p>
<p>예를 들자면, state배열에 값을 추가 하기 위해서는 react에서는 불변성을 유지하는 concat을 사용해야 하지만, vue에서는 그대로 push를 사용해도 괜찮다는 것이다.
물론 불변성을 지킬때 처럼 concat등을 사용해도 문제 없다.</p>
<p>사실 처음 vue를 시작하면서 가장 혼란스러웠던 부분이 이 부분이었다.
react를 사용하면서 함수 안에 사용 되는 값이 state였는데, vue는 이 값에 대한 언급이 없었기 때문이다.
불변성을 지키며 사용하는것이 습관이 된 것도 혼란이 오는데 일조한 느낌도 없잖아 있었다.
처음부터 vue를 배웠다면, 오히려 쉽게 배우지 않았을까 하는 생각이 들었다.</p>
<h4 id="반복렌더링">반복렌더링</h4>
<p>세번째는 반복해서 렌더링을 시킬때 이다.
react의 경우 JSX안에 자바스크립트로 대상 배열에 map함수를 사용하여 컴포넌트, 혹은 JSX를 렌더링 시켜야 했지만, vue의 경우는 v-for를 사용하여 조금 더 간단하게 사용이 가능했다.
오히려 map보다는 반복문에 가깝게 사용 할 수 있다는 점이 직관적이라 느꼈다.</p>
<pre><code class="language-js">// react
&lt;ul&gt;
  {arr.map((item, index) =&gt; {
    return &lt;li key={index}&gt;{item}&lt;/li&gt;
  })}
&lt;/ul&gt;

// vue
&lt;ul&gt;
  &lt;li v-for=&quot;(item, index) in arr&quot; :key=&quot;index&quot;&gt;
    {{item}}
  &lt;/li&gt;
&lt;/ul&gt;</code></pre>
<p>위가 react에서의 사용이고, 아래가 vue에서의 사용이다.
태그 안에 반복문을 넣는다는 느낌으로 사용 할 수 있기에 직관적이다.</p>
<h4 id="조건부-렌더링">조건부 렌더링</h4>
<p>조건부 렌더링을 사용할때, react처럼 삼항연산자, 혹은 &amp;&amp;등을 사용하여 조건부 렌더링을 처리하지 않고,
v-if라는 키워드를 사용한다.
실제 조건문처럼 v-if안에 컨디션을 입력하면, 해당 컨디션이 true가 될때 렌더링하게 된다.
물론 v-else와 v-else-if도 있어서, 이런 저런 조건에 대처하기 좋고, 가독성 향상에도 도움을 줄 것 같다.
작성법은 아래와 같다.</p>
<pre><code class="language-js">// true일때 렌더링
&lt;div v-if=&quot;true&quot;/&gt;

// false일때 렌더링
&lt;div v-else /&gt;</code></pre>
<h4 id="러닝커브">러닝커브</h4>
<p>우선 직접적으로 체감한 차이는 아니지만, 이와 관련해서 조사했을때, 많은 자료에서 러닝커브에 관한 이야기가 있었기에 생각한 바를 작성하고자 한다.</p>
<p>우선 익숙하지 않았던 차이가 있었지만, 대체로 react보다 배우기 쉽다고 생각한다.
만약 개발을 처음 시작하고 접한 SPA 라이브러리가 vue였다면, 역으로 react가 어렵게 느껴졌을 것이다.
앞서 말한 state와 불변성, 자바스크립트에 관한 지식등 요구하는 것이 많기에 처음 배운다면 이해하는데 시간이 좀 걸릴 것 같다.
하지만 react를 먼저 배운 내 경우, 아무래도 react적으로 생각하는 부분이 많았기에, 자체적인 문법과 vue만의 코딩스타일을 사용해야 하는 부분에서 혼란이 왔었다.
익숙해지고 나니 큰 문제는 아니었지만, 처음엔 굉장히 여러곳에서 자료를 찾았었다.</p>
<h2 id="outro">Outro</h2>
<p>일단 가볍게 프로젝트를 하며 가능한한 직접 체감한 부분을 위주로 작성하다보니, 타 포스팅과 비교 했을때 없거나 다루지 않은 부분이 있을 수 있다.
아마 앞으로 여러 프로젝트를 하며 직접 체감하게 되지 않을까.</p>
<p>react만 사용했을때는 react말고 다른 라이브러리를 써봐야지 하다가도 크게 기회가 없었는데, 이번에 좋은 기회가 생겨서 새로운 세계에 발을 디디게 되었다.
물론 아직 굉장히 익숙하게 다루지는 않지만, 작게 프로젝트를 진행하면서 굉장히 어렵게 느껴지는 부분은 없었기에, 아주 좋은 인상을 남겼다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[What is 'this'?]]></title>
            <link>https://velog.io/@mong-byte/What-is-this</link>
            <guid>https://velog.io/@mong-byte/What-is-this</guid>
            <pubDate>Mon, 04 Oct 2021 11:41:06 GMT</pubDate>
            <description><![CDATA[<h1 id="this">This</h1>
<p>실행컨텍스트에서 나온 this 키워드에 대하여 알아 볼 차례다.
영어 단어로서 this는 모두가 알다시피 &#39;이것&#39;이라는 의미를 가진 단어이지만, 프로그램상에서는 약간 다르게 사용된다.</p>
<p>Java등 다른 프로그램 언어에서 this는 <a href="https://ko.wikipedia.org/wiki/%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)">인스턴스</a> 자신을 가리키는 의미로서 사용된다.
즉 클래스에서만 사용 할 수 있기때문에 크게 혼란을 가지지 않고 사용 할 수 있다.</p>
<p>하지만 자바스크립트에서는 그것과 다른 방식으로 작용하며, 사용된다.
여러곳에서 사용 되며, 상황에 따라 값이 달라지기에 어떤 이유로 달라지고, 어디를 바라보고 있는지 이해하기 힘든 경우가 많다.
그렇다면, 어떻게 다른지 한번 확인 해 보도록 하자.</p>
<h2 id="상황에-따라-달라지는-this">상황에 따라 달라지는 this</h2>
<p>사실 이 this는 상황에 따라 달라지기 때문에, 정확하게 어떤 값이다! 하고 한마디로 단언하기 힘들다.
왜냐하면, 이 this는 기본적으로 실행컨텍스트가 생성될 때 함께 결정 되기때문에, 일반적으로 함수가 호출될 때 결정 되게 된다.
자바스크립트가 실행 될때 가장 위에 생기는 전역컨텍스트와 각 함수가 실행될 때 함수컨텍스트가 생성 되기 때문이다. 이때 동시에, this가 함께 결정 되게 된다.</p>
<p>그럼 어떤 요인으로 값이 바뀌는지, 어떻게 바뀌는지 알아보도록 하자.</p>
<h3 id="전역에서의-this">전역에서의 this</h3>
<p>전역에서 선언 된 this는 전역객체를 가리키게 된다.
왜냐하면, 전역컨텍스트가 생성 되며 this가 함께 결정 되고, 전역컨텍스트를 생성하는 주체가 바로 전역객체이기 때문이다.</p>
<p>일반적으로 브라우저 환경에서의 this는 window, Node.js를 사용하는 환경에서는 global을 가리킨다.</p>
<pre><code class="language-js">var a = 1;
console.log(a);         // 1
console.log(window.a);  // 1
console.log(this.a);    // 1</code></pre>
<p>변수 a를 할당해서 출력했지만 어째서인지 window, this 모두 a라는 프로퍼티가 생기고, 그 값이 1로 출력이 되었다.
이 현상에 대한 이유는, 자바스크립트의 모든 변수는 특정 객체의 프로퍼티로서 동작하기 때문에, 전역에서 변수 a를 초기화 해서 1을 할당함과 동시에, 전역객체인 window에 a라는 프로퍼티가 추가 되고, a에 1이 할당 되었기 때문이다.</p>
<p>여기서 특정 객체란 실행컨텍스트의 LexicalEnvironment(이하 LE)를 뜻한다.
실행컨텍스트는 각 변수에 대한 정보를 수집하여 LE의 프로퍼티로 저장하는데, 이후 변수를 호출하면 LE의 프로퍼티를 참조하여 일치하는 값이 있으면 그 값을 반환한다.
전역컨텍스트의 경우엔 전역객체를 그대로 참조하게 된다.
(정확하게는 GlobalEnv가 전역객체를 참조하고, 전역컨텍스트의 LE가 이 GlobalEnv를 참조하게 된다.)</p>
<p>때문에, 전역에서 var등으로 변수를 선언하지 않고, window에 직접 프로퍼티를 할당해도 대부분의 경우엔 같은 동작을 하게 된다.</p>
<pre><code class="language-js">var a = 1;
window.b = 2;
console.log(a, window.a, this.a); // 1 1 1
console.log(b, window.b, this.b); // 2 2 2

window.a = 3;
b = 4
console.log(a, window.a, this.a); // 3 3 3
console.log(b, window.b, this.b); // 4 4 4</code></pre>
<p>다만 여기는 예외가 있는데, 바로 delete를 사용 할 때이다.</p>
<pre><code class="language-js">var a = 1;
delete window.a; // false
console.log(a, window.a, this.a); // 1 1 1

var b = 2;
delete b;        // false
console.log(b, window.b, this.b); // 2 2 2

window.c = 3;
delete window.c; // true
console.log(c, window.c, this.c); // Uncaught ReferenceError: c is not defined

window.d = 4;
delete window.d; // true
console.log(d, window.d, this.d); // Uncaught ReferenceError: d is not defined</code></pre>
<p>위와 같은 결과를 확인 할 수 있다.</p>
<p>여기서 흥미로운 사실은, 전역객체에 프로퍼티로서 추가한 값은 delete로 삭제가 되는데, 변수로 선언한 값은 삭제가 되지 않는 것을 알 수 있다.
이는 사용자가 의도치 않게 변수를 삭제하는것을 막는 차원에서 기능한다고 생각 되어진다.
전역변수를 선언하면 자바스크립트 엔진이 자동으로 전역객체에 프로퍼티로 할당하고, 추가적으로 해당 프로퍼티듸 configurable 속성을 false로 정의 하게 된다.</p>
<p>이처럼 일반적으로 선언한 변수와 전역객체에 직접 프로퍼티를 할당하는것은 호이스팅여부 및 configurable에서 차이를 보이게 된다.</p>
<h3 id="메서드로서의-호출-메서드-내부에서의-this">메서드로서의 호출, 메서드 내부에서의 this</h3>
<p>들어가기 전에 우선, 함수와 메서드가 어떤 차이가 있는지 알아야 할 필요가 있다.</p>
<p>어떤 함수를 실행하는 방법으로는 함수로서 호출하는 방법과, 메서드로서 호출하는 경우가 있다.
함수와 메서드는 미리 정의한 동작을 수행하는 코드뭉치라는 공통점은 존재하지만, 이 둘을 나누는 차이는 바로 <strong>독립성</strong>에 있다.</p>
<p>함수는 그 자체로 독립적으로 호출하거나 선언 할 수 있지만, 메서드는 자신을 호출한 대상 객체에 관한 동작을 수행한다.
자바스크립트는 상황별로 this 키워드에 다른 값을 부여하게 함으로써 이를 구현하였다.</p>
<p>흔히 메서드를 &#39;객체의 프로퍼티로 할당 된 함수&#39;로 이해하는 경우가 많지만, 메서드는 객체의 메서드로 호출 될 때에만 메서드로 동작하고, 그 이외는 함수로 동작하게 된다.</p>
<p>메서드로서 호출 하는 방법은 간단하다.</p>
<pre><code class="language-js">var func = function(x:number) {
  console.log(this,x)
};
func(1);          // Window {...} 1

var obj = {
  method: func
};

obj.method(1);    // { method : f } 1</code></pre>
<p>위의 예제에서 <code>func(1)</code>부분은 함수로서 호출 되었다.
반면 아래의 <code>obj.method(1)</code>부분은 메서드로 호출 되었다.</p>
<p>메서드로서 호출은 객체의 프로퍼티로 접근하는 방식으로 호출하게 된다.
예를 들어 <code>obj.prop(x)</code> 혹은 <code>obj[&#39;prop&#39;]</code>과 같은 방식으로 호출 할 수 있다.
보다 간단하게 말하자면, 앞에 해당 메서드가 소속 되어있는 객체가 명시되어 있는 경우는 메서드, 그렇지 않은 경우는 일반 함수로서 호출되었다 볼 수 있다.</p>
<p>그렇다면 메서드 내부에서 this는 어떻게 작용할까?
this는 호출한 주체에 따라 내부에 담기는 값이 변하게 된다.
메서드의 경우, 호출한 주체는 해당 메서드가 속한 객체가 된다.</p>
<p>즉 메서드에서의 this는 메서드가 속한 객체가 되는것이다.
예를 들어 위의 경우를 볼때, <code>obj.method(1)</code>에서 this는 바로 <code>obj</code>인 것이다.</p>
<h3 id="함수로서의-호출-함수-내부에서의-this">함수로서의 호출, 함수 내부에서의 this</h3>
<p>그렇다면 메서드가 아닌 경우는 어떨까?
일반 함수의 경우 위의 <code>func(1)</code>처럼 앞에 해당 함수가 어디에 속하는지 나타나 있지 않다.
그럼 일반 함수의 this는 없는것일까?</p>
<p>그렇지 않다.
실행컨텍스트에서 컨텍스트를 활성화 할 당시에, this가 정해져 있지 않다면 자동적으로 this는 전역객체를 바라보게 된다. 따라서 함수의 this는 곧 전역객체를 가리키게 된다.</p>
<p>그렇다면 메서드 내부에서 함수를 정의하고 실행하면, this는 어디를 바라보게 될까?</p>
<pre><code class="language-js">var name = &#39;lee&#39;;

var user = {
    name: &#39;kim&#39;,
    getName: function() {
        console.log(this.name);       // (1)

        var inner = function() {
        console.log(this.name);       // (2)
        }

        inner();
    }
}

user.getName();</code></pre>
<p>위와 같은 경우에서, (1)과 (2)의 this.name은 어떤 값이 나오는지 유추해 보도록 하자.</p>
<p>우선, 지금까지의 내용을 가볍게 복습해보자.</p>
<ul>
<li>메서드의 경우, this는 해당 메서드가 속한 객체가 this의 대상이 된다.</li>
<li>일반함수의 경우, 전역객체가 this의 대상이 된다.</li>
</ul>
<p>이 두가지를 생각하며 위의 예제코드를 다시 한번 읽어보자.</p>
<p>위 코드에서 (1)의 this는 메서드로서 선언된 함수의 this이다.
때문에, (1)에서 출력 되는 값은 &#39;kim&#39;이다.</p>
<p>그렇다면 (2)의 경우도 똑같이 &#39;kim&#39;일까?
(2)의 경우엔 &#39;lee&#39;가 출력 되게 된다.
메서드 안에서 선언 된 함수라도, 일반함수이기에 그 this는 전역객체를 바라보게 된다.
때문에, 전역변수 name로 선언 되어 있는 &#39;lee&#39;가 출력 되게 되는것이다.</p>
<p>그렇다면 메서드 안에서 &#39;lee&#39;가 아닌 &#39;kim&#39;을 출력 할 수는 없는걸까?
메서드 내부에 함수를 만들어도 그 this는 전역을 바라보고 있으니, 만약 메서드 내부에 정의한 함수에서 this를 사용 하고 싶을때 문제가 생길 수 있다.</p>
<p>그런 경우엔 변수를 활용하면 된다.</p>
<pre><code class="language-js">var name = &#39;lee&#39;;

var user = {
    name: &#39;kim&#39;,
    getName: function() {
        console.log(this.name);       // (1)

               var self = this;
        var inner = function() {
        console.log(self.name);       // (2)
        }

        inner();
    }
}

user.getName();</code></pre>
<p>위와 같이 self라는 변수를 사용해서 this의 값을 저장하면, (2)의 결과도 &#39;kim&#39;을 출력하도록 할 수 있다.
이 self라는 변수명은 정해진 변수명은 아니기에, 사람마다 _this, that, _등 다양한 변수명을 사용하는데, 보편적으로 self가 가장 많이 사용 된다고 알려져 있다.</p>
<h3 id="this를-바인딩하지-않는-함수">this를 바인딩하지 않는 함수</h3>
<p>우리는 메서드 내에서 선언한 함수의 this가 메서드와 상관 없는 전역객체를 바라보고 있다는 사실을 알게 되었다.
변수를 사용해서 보완 할 수는 있지만 꽤나 번거로운것도 사실이기에, ES6부터 도입된 문법중 이 문제를 해결하기 위한 요소가 추가 되었다.</p>
<p>그것이 바로 화살표 함수(Arrow function)이다.
우리가 익히 알고 있는 화살표 함수는</p>
<pre><code class="language-js">const func = (x) =&gt; console.log(x);

func(1);</code></pre>
<p>위 처럼 함수를 간단히 표시 할 수 있고, 함수표현식을 보다 간단하게 사용 할 수 있는 장점이 있는 함수이다.
이 화살표 함수와 this는 꽤나 밀접한 연관이 있다.</p>
<p>화살표 함수는 실행컨텍스트를 생성할때, this바인딩 과정 자체가 생략되어, 함수 자체에는 this가 없고, 가장 가까운 스코프체인의 this를 대상으로 지정하게 된다.</p>
<h3 id="콜백함수-호출-시-함수-내부에서의-this">콜백함수 호출 시 함수 내부에서의 this</h3>
<p>콜백함수 내부에서의 this는 기본적으로 콜백함수의 제어권을 가져가는 함수의 this를 따라가게 된다.
콜백함수에 대해 잠깐 설명하자면, 함수 A의 제어권을 다른 함수인 B에게 넘겨주는 경우, 함수 A를 콜백함수라 명명하게 된다.</p>
<p>여기서 제어권이란, 어떤 시점에서 어떤 인자를 넘길 것인지를 결정하는 것을 의미한다.
이때, 함수 A는 함수 B의 로직에 따라 실행되고, this도 함수 B의 내부로직에 따라 결정 되게 된다.
일반적으로 콜백함수로 넘겨지는 함수도 일반함수이기에, 콜백함수의 this는 전역객체를 바라보게 된다.
하지만 제어권을 받은 함수에서 콜백함수에 별도로 this를 지정한 경우, this는 그 대상을 바라보게 된다.</p>
<p>예를 들면, addEventListener 메서드는 콜백함수를 호출할때, 자신의 this를 상속시키도록 정의 되어 있다. 이처럼 특별히 this를 변경하도록 지정 되지 않은 한, 콜백함수의 this는 전역객체를 바라보게 된다.</p>
<h3 id="생성자-함수-내부에서의-this">생성자 함수 내부에서의 this</h3>
<p>객체지향 언어에서 생성자는 class, class를 통해 만들어진 대상을 instance라고 한다.
class에 대해 간단하게 설명하자면 흔히 class의 설명으로 사용 되는 붕어빵 틀을 이야기 할 수 있다.</p>
<p>간단히만 설명하고 넘어가자면, class는 붕어빵을 만드는 틀이라 볼 수 있고, instance는 붕어빵 틀로 만들어진 붕어빵에 비유 할 수 있다.</p>
<p>자바스크립트의 경우 함수에 생성자의 역할을 함께 부여하였다.
우리가 Date등을 사용하기 위해 사용하는 명령어 new와 함께 함수를 호출하면, 해당 함수는 생성자로서 동작하게 되는 것이다. 그리고, 어떤 함수가 생성자 함수로서 호출된 경우 내부에서의 this는 생성자로 인해 만들어지는 instance 자신이 된다. 즉, 새로 만들어지는 함수 자신이 this가 되는 것이다.</p>
<p>이 생성자의 호출과 this의 부여는 추후에 포스팅으로 다루도록 하겠다.</p>
<p>예시를 보며 확인을 해보자.</p>
<pre><code class="language-js">let Food = function(name,price) {
  this.name = name;
  this.price = price;
};

let pizza = new Food(&#39;Pizza&#39;,25000);

console.log(pizza); // Food {
                    //   name: &#39;Pizza&#39;,
                    //   price: 25000,
                    //   __proto__: { constructor: ƒ Food() }
                    // }</code></pre>
<p>위의 예시와 같이, 생성자 함수로 호출 된 함수 Food의 this는 pizza instance를 가리킴을 알 수 있다.</p>
<hr>
<p>해당 포스팅은 <a href="https://www.google.com/search?q=%EC%BD%94%EC%96%B4%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8&amp;oq=%EC%BD%94%EC%96%B4%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8&amp;aqs=chrome..69i57.2512j0j4&amp;sourceid=chrome&amp;ie=UTF-8">코어자바스크립트</a> 3장 this를 바탕으로 포스팅하였습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Execution Context (실행 컨텍스트)]]></title>
            <link>https://velog.io/@mong-byte/Execution-Context-%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8</link>
            <guid>https://velog.io/@mong-byte/Execution-Context-%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8</guid>
            <pubDate>Sat, 02 Oct 2021 15:09:49 GMT</pubDate>
            <description><![CDATA[<h1 id="execution-context-실행-컨텍스트">Execution Context (실행 컨텍스트)</h1>
<h2 id="들어가기-전에">들어가기 전에</h2>
<p>실행컨텍스트에 대한 설명을 하기 전에, 우선 <code>Stack</code>과 <code>Que</code>에 대해 먼저 알고 가도록 하자.
자료구조와 알고리즘을 공부했다면 이미 알고 있는 개념이겠지만, 잠깐 다루고 가자면</p>
<p><img src="https://images.velog.io/images/mong-byte/post/d54f16f5-885b-4dd1-af48-70efb7db6e83/stack.png" alt=""></p>
<ul>
<li><code>stack</code>은 먼저 들어온 처리 사항을 나중에, 후에 들어온 처리 사항을 먼저 처리하는 자료구조(후입선출)이고,</li>
</ul>
<p><img src="https://images.velog.io/images/mong-byte/post/72d6d400-8e4a-4c21-aa60-74b426d9e100/que.png" alt=""></p>
<ul>
<li><code>que</code>는 먼저 들어온 내용을 먼저 처리하는 자료구조(선입선출)이다.</li>
</ul>
<p>이 두 자료구조를 생각하면서, 실행컨텍스트에 대해 알아보도록 하자.</p>
<h2 id="실행컨텍스트란">실행컨텍스트란?</h2>
<p>실행컨텍스트는 <strong>실행할 코드에 제공할 환경 정보들을 모아놓은 객체</strong>로서, 코드가 실행되기 위해 자바스크립트가 실행하는 특정한 동작들을 의미한다.
즉 자바스크립트가 동작하는 방식이기도 하고, 앞으로 다루게 될 <code>this</code>, <code>hoisting</code>, <code>closure</code>등 여러 개념들과 연결 되는 핵심요소이다.</p>
<p>자바스크립트는 동일한 환경에 있는 코드를 실행할때 필요한 여러가지 환경 정보들을 모아 컨텍스트를 구성하고 <code>call stack</code>에 쌓아올린다. 그렇게 쌓아 올려진 컨텍스트는 위에서부터 차례대로 실행되고, <code>stack</code>의 특성상 그 순서가 보장된다.</p>
<p>여기서 <code>동일한 환경</code>이라는 말이 나왔는데, 이것이 하나하나의 실행컨텍스트를 의미하고, 그 실행컨텍스트를 구성하는 방법으로는 세가지가 있다.</p>
<ul>
<li>전역코드</li>
<li>함수코드</li>
<li>eval코드</li>
</ul>
<p>여기서 우리가 직접적으로 실행 가능한 코드는 일반적으로, 전역코드와 함수코드이다.
자바스크립트를 실행함과 동시에 생성 되는 전역코드를 제외하고, 가장 많이 사용하는 컨텍스트 구성방법은 함수코드인데, 이는 우리가 함수를 만들어서 실행시킬때 생성 된다.</p>
<p>예제를 하나 들어보자</p>
<pre><code class="language-js">var a = 1;
function outer() {
  function inner() {
    console.log(a);
    var a = 3;
  }
  inner();
  console.log(a);
}
outer();
console.log(a);</code></pre>
<p>다음과 같은 코드가 있을때 어떠한 순서로 실행컨텍스트가 <code>call stack</code>에 쌓이고, 어떤식으로 처리 될까?</p>
<p><img src="https://images.velog.io/images/mong-byte/post/a405800b-78ee-4976-87f8-b82d84cb47de/call-stack.jpeg" alt=""></p>
<p>우선 가장 처음 생성되어 <code>call stack</code>에 담기는 컨텍스트는 전역 컨텍스트이다.
전역컨텍스트는 별다른 명령이 없어도 브라우저가 자동으로 실행하기에, 자바스크립트 코드가 구동되면 가장 처음에 생기는 컨텍스트는 전역 컨텍스트이다.</p>
<p>코드를 읽기 시작한 자바스크립트 엔진은 위에서부터 순차적으로 코드를 읽어나가게 된다.
그러다 <code>outer</code> 함수를 만나게 되면, 자바스크립트는 해당 함수에 대한 환경 정보를 수집해서 함수 컨텍스트를 만들고 <code>call stack</code>에 담게 된다.</p>
<p><code>outer</code>에 대한 컨텍스트가 생성 되면, 전역 컨텍스트에서 함수를 읽던 진행을 멈추고, <code>outer</code>함수와 관련된 코드 즉 <code>outer</code> 내부의 코드들을 실행하게 된다.</p>
<p>같은 원리로, <code>outer</code>에 관한 코드를 실행하다가 <code>inner</code>를 만나게 되면, 다시 진행을 멈추고 <code>inner</code>에 관한 코드를 실행시키게 된다.</p>
<p>이때 하나의 궁금증이 생긴다.
환경 정보를 수집한다는 말이 나왔는데, 환경정보는 무엇을 의미하는것일까?</p>
<h2 id="환경-정보">환경 정보</h2>
<p>자바스크립트를 사용하면서 코드를 실행시키기 위해선, 여러가지의 정보가 필요하다.
이 정보는 자바스크립트 엔진이 활용하기 위해 생성 됮는 객체이고, 개발자가 사용 할 수는 없다.</p>
<p>여기에 담기는 정보는 세가지가 있다.</p>
<ul>
<li>Variable Environment</li>
<li>Lexical Environment</li>
<li>This Binding</li>
</ul>
<p>하나씩 알아보도록 하자.</p>
<h3 id="variable-environment">Variable Environment</h3>
<p>Variable Environment(이하 VE)에 담기는 내용은 기본적으로 Lexical Environment(이하 LE)와 같지만 최초 실행시의 <a href="https://ko.wikipedia.org/wiki/%EC%8A%A4%EB%83%85%EC%83%B7_(%EA%B8%B0%EC%96%B5_%EC%9E%A5%EC%B9%98)">스냅샷</a>을 유지한다는것에 그 차이점이 있다.</p>
<p>VE는 컨텍스트내의 식별자들에 대한 정보와 외부 환경 정보를 담고 있고, 스냅샷이기에 선언 시점의 내용에서 변경 사항은 반영 되지 않는다는 특징이 있다.</p>
<p>최초에 실행컨텍스트가 생성 될때, VE에 그 정보를 담고, 이를 복사해서 LE를 만들고, 이후에는 그대로 LE를 사용하게 된다.
여기서 VE는 변경사항을 반영하지 않기에, 초기화시에는 VE와 LE가 동일하지만, 코드 진행에 따라 달라지게 된다.</p>
<p>VE와 LE의 내부는 <code>environmentRecord</code>(이하 ER)와 <code>outerEnvironmentReference</code>(이하 OER)로 구성되어 있다.</p>
<h3 id="lexical-environment">Lexical Environment</h3>
<p>LE는 컨텍스트가 생성 되면서 같이 생성된 VE의 정보를 복사한 값을 초기값으로 가지게 되고, LE는 기본적으로 해당 함수가 어떤 변수와 매개변수를 가지고 있고, 어떤 것을 참조하는지 등에 대한 여러가지 정보를 사전에 접하는 느낌으로 모아 놓았다고 할 수 있다.</p>
<p>LE의 내부는 VE와 같이 ER와 OER로 구성되어 있다 하였다.</p>
<p>각각의 구성요소에 대하여 알아보자</p>
<h4 id="environmentrecord--hoisting">EnvironmentRecord &amp; Hoisting</h4>
<p>호이스팅에 대해서는 대부분 변수타입 var와 연관이 있다고 알고 있을 것이다.
호이스팅이란 아래에 있는 변수를 끌어올려서(hoist) 할당은 되지 않고, 선언을 시켜 놓는것을 말한다.
그럼 이 hoisting과 ER이 어떤 관련이 있는지, 왜  호이스팅이 일어나는지에 대해 알아보도록 하자.</p>
<p>ER에는 현재 컨텍스트와 관련된 코드의 식별자 정보들이 순서대로 수집되어 저장 되게 된다.</p>
<p>이때 변수에 대한 정보들을 수집하였더라도, 아직 해당 컨텍스트의 코드들은 실행 되기 전이다.
마치 시험 시작 직전에 시험지 첫페이지를 매의 눈으로 훑지만, 풀지는 않은 느낌인 것이다.
자바스크립트는 코드가 실행되기전에 코드를 한번 훑고, 해당 코드 내에서 어떤 변수가 있는지 미리 정보를 알고 있게 된다.</p>
<p><img src="https://images.velog.io/images/mong-byte/post/4ab03434-3609-4142-aa14-6788fef63b88/reading.gif" alt=""></p>
<p>즉, 우리가 보기에(실제로 그러지는 않지만) 코드에 있는 변수들을 모두 끌어올려서 해당 변수가 어떤 변수인지 알고, 코드를 시작하는 것을 보고 호이스팅이라 부르는 것이다.
당연히 실행이 되지 않았으므로 해당 변수에 값은 할당 되지 않고, 선언만 되어지게 된다.
이것이 호이스팅이 일어나는 원리이다.</p>
<h5 id="변수의-호이스팅">변수의 호이스팅</h5>
<p>그렇다면 예제와 함께 알아보도록 하자.</p>
<pre><code class="language-js">function a(x) {
  console.log(x);
  var x;
  console.log(x);
  var x = 2;
  console.log(x);
}
a(1);</code></pre>
<p>위와 같은 코드가 있을때 각 console.log는 어떻게 찍히게 될까?</p>
<p>여기서 수집대상이 되는 요소를 살펴보면</p>
<pre><code class="language-js">function a(x) {
  var x = 1;       // 수집대상 1
  console.log(x);  // (1)
  var x;           // 수집대상 2
  console.log(x);  // (2)
  var x = 2;       // 수집대상 3
  console.log(x);  // (3)
}
a();</code></pre>
<p>이라 생각 할 수 있다.
물론 실제 자바스크립트 엔진이 이렇게 처리하지는 않고, 이해를 위해 변형 시킨 것이다.
이때 ER은 각각의 어떤 변수가 존재하는지에만 관심이 있고, 각 변수가 어떤 값을 할당 받는지는 관심이 없기에 할당부분은 남겨둔 채로 선언만 수집하게 된다.</p>
<p>수집이 완료 되고 호이스팅이 완료 된 모습을 나타내자면</p>
<pre><code class="language-js">function a(x) {
  var x;           // 수집대상 1의 선언  
  var x;           // 수집대상 2의 선언
  var x;           // 수집대상 3의 선언

  x = 1;           // 수집대상 1의 할당
  console.log(x);  // (1)
  console.log(x);  // (2)
  x = 2;           // 수집대상 3의 할당
  console.log(x);  // (3)
}
a(1);</code></pre>
<p>과 같이 나타 낼 수 있다.</p>
<p>여기서 다른 요소들의 수집이 완료 되면 코드가 실행 되게 되는데, 이때 각 <code>console.log</code>에서 출력 되는 값은 (1) 1,(2) 1,(3) 2 가 나타나게 된다.</p>
<p>수집대상 2에서 <code>undifined</code>가 나오지 않고 1이 출력 되는 이유는 각 변수의 선언이 위로 끌어올려졌고, 변수의 이름이 같았기에 같은 선언으로 간주하고 무시, x에 2가 할당 되기 전까지는 1이 할당 되어 있었기 때문이다.</p>
<h5 id="변수와-함수의-호이스팅">변수와 함수의 호이스팅</h5>
<p>그렇다면 함수가 있으면 어떻게 될까?</p>
<p>코드를 보면서 확인해보자.</p>
<pre><code class="language-js">function a() {
  console.log(b);  // (1)
  var b = &#39;bbb&#39;;   // 수집대상 1
  console.log(b);  // (2)
  function b(){}   // 수집대상 2
  console.log(b);  // (3)
}
a();</code></pre>
<p>a 함수를 실행 하는 순간 a 함수의 컨텍스트가 생성 되고, 호이스팅이 일어나게 된다. 변수만 있을때의 호이스팅과는 차이점이 있는데, 변수의 경우는 선언부만 호이스팅이 일어나지만, 함수의 경우 함수 전체가 호이스팅 되게 된다.</p>
<p>즉 호이스팅이 일어나고 난 후의 모습을 보자면</p>
<pre><code class="language-js">function a() {
  var b;           // 수집대상 1의 선언
  function b(){}   // 수집대상 2 - 함수는 전체가 끌어올려진다.

  console.log(b);  // (1)
  b = &#39;bbb&#39;;       // 수집대상 1의 할당
  console.log(b);  // (2)
  console.log(b);  // (3)
}
a();</code></pre>
<p>과 같다고 볼 수 있다.</p>
<p>이 상태에서 각 <code>console.log</code>에선 어떤 값이 나오게 될까?
정답은 (1)b함수, (2)&#39;bbb&#39;, (3)&#39;bbb&#39;이다.</p>
<p>호이스팅으로 가장 위에 끌어올려지는데 함수는 전체, 선언과 할당이 동시에 올라가게 되므로 (1)의 b는 함수가 할당이 되게 된다. 그 이후엔 문자열 &#39;bbb&#39;가 할당이 되어 (2),(3)에는 &#39;bbb&#39;가 출력 되게 된다.</p>
<h4 id="outerenvironmentreference와-scope">OuterEnvironmentReference와 Scope</h4>
<p>이번엔 OER에 대해 알아볼 차례다.
이번에 관련이 있는 개념은 바로 스코프이다.</p>
<p>스코프는 식별자에 대한 유효범위를 뜻한다.
예를 들어 A라는 함수가 있을때, A외부에 선언 된 변수는 A안에서 접근 할 수 있지만, A내부에 선언 된 변수는 A외부에서 접근 할 수 없다라는 개념이다.</p>
<p>ES5까지는 자바스크립트에서 전역스코프 외에는 함수로만 스코프를 생성 할 수 있었지만, ES6부터는 함수 뿐 아니라 if등 블록({})으로 스코프를 생성 할 수 있게 되었다.</p>
<p>이러한 스코프를 안에서 바깥으로 찾아 올라가는것을 &#39;스코프 체인&#39;이라 하고, 이 스코프 체인이 가능하게 하는것이 바로 OER인 것이다.</p>
<p>OER은 호출 된 함수가 선언될 당시의 LE를 참조하게 된다.
예를 들어 A함수 내부에 B함수를 선언하고 B함수 내부에 C함수를 선언한 경우, C함수의 OER은 B함수의 LE를 참조하게 된다. 그 이후 B함수-&gt;A함수도 마찬가지로 상위의 LE를 참조하게 되는 연결리스트의 형태를 띄게 되고, 마지막에는 전역컨텍스트의 LE를 참조하게 될 것이다.</p>
<p>이렇게 자기 상위의 하나씩만 참조하여 체인을 타고 올라가기 때문에, 체인을 타고 이동하면서 가장 먼저 발견된 식별자에만 접근이 가능하게 된다.</p>
<p>다음 코드를 보며 생각해보자.</p>
<pre><code class="language-js">var a = 1;
var outer = function () {
  var inner = function () {
     console.log(a);
    var a = 3;
  }
  inner();
  console.log(a);
}
outer();
console.log(a);</code></pre>
<p>위 함수의 <code>console.log</code>는 어떻게 출력 될까?</p>
<p>우선 전역컨텍스트가 활성화 되고, ER에 a, <code>outer</code>의 식별자를 저장하게 되고, OER은 비어있게 된다.
그 다음, 코드가 실행 되면서 각 식별자에 값이 할당 되고, <code>outer</code>를 만나 실행을 멈추고, <code>outer</code>의 컨텍스트를 생성시킨다.</p>
<p><code>outer</code> 컨텍스트가 활성화 된 다음, ER에 식별자 <code>inner</code>가 저장 되고, OER에는 <code>outer</code>가 선언 될 당시의 LE가 기록 되게 된다. 이때 기록 되는 값은 전역컨텍스트의 LE를 참조 복사하게 된다. 그리고 다시 <code>inner</code>를 만나 실행을 멈추고 <code>inner</code>의 컨텍스트가 생성 되게 된다. (OER: [ {GLOBAL, { a, outer } } ])</p>
<p><code>inner</code> 컨텍스트가 활성화 되면 ER에 식별자 a가 저장 되고, OER에는 <code>inner</code>의 선언 당시의 LE가 기록된다. 이때는 <code>outer</code>의 LE가 참조 복사된다. (OER : [ { outer, { inner } } ])</p>
<p><code>inner</code>의 실행이 시작 되고, a에 접근 하고자 하였지만, 현재 <code>inner</code> 컨텍스트에 할당된 a의 값이 없기에 <code>undifined</code>가 출력된다. 그 이후 <code>inner</code> 스코프의 a에 3을 할당하게 되고 <code>inner</code> 함수가 종료된다.
이때 <code>inner</code>의 실행컨텍스트가 <code>call stack</code>에서 제거되고, 바로 아래의 <code>outer</code> 컨텍스트가 활성화 되어 <code>outer</code>가 중단 되었던 다음 줄로 이동한다.</p>
<p><code>outer</code>에서 a에 접근하고자 했을때, <code>outer</code> 안에는 a가 없었기에 체인을 타고 전역으로 이동하게 된다.
이때 전역의 LE에서 할당 되었던 a의 값을 발견하고, 해당 값이 출력 되게 된다. 그 이후 <code>outer</code>의 실행이 종료 되면서 <code>outer</code>의 실행컨텍스트가 <code>call stack</code>에서 제거 되고 전역컨텍스트가 활성화되어 중단되었던 다음줄로 이동한다.</p>
<p>전역컨텍스트의 LE에 할당된 a의 값이 있었기에 그 값이 그대로 출력 되게 된다.
이렇게 모든 코드의 실행이 종료 되고 전역컨텍스트가 <code>call stack</code>에서 제거 되고 종료되게 된다.</p>
<p>만약 <code>inner</code>에서 <code>var a = 3;</code>이라는 코드가 없었다면 <code>inner</code>에서도 1이 출력되었을것이다.
하지만 해당 코드가 존재했기때문에, 호이스팅이 발생했고, a의 선언부가 위로 끌어올려지면서 <code>undefined</code>가 출력되게 된 것이다.
이때 <code>inner</code> 안의 a는 값이 3이 할당 되었지만, 전역과 <code>outer</code>에서는 <code>inner</code>의 변수에 접근 할 수 없기 때문에 기존에 할당 되었던 1이 출력 된 것이다.</p>
<p>때문에, <code>inner</code>에서 선언한 a값때문에 <code>inner</code>에서 전역의 a에는 접근 할 수 없게 되는데, 이를 변수의 은닉화라 한다.</p>
<p><img src="https://images.velog.io/images/mong-byte/post/55e3f087-7a82-4502-9516-f8dff5fd2043/WTF.gif" alt="">
<del><em>머리가 어지럽지만 열심히 이해해 보도록 하자.</em></del></p>
<h4 id="전역변수와-지역변수">전역변수와 지역변수</h4>
<p>위의 스코프 개념을 이용한 전역변수와 지역변수라는 개념이 있다.
전역변수는 말 그대로 전역에서 생성된 변수, 그러니까 전역컨텍스트의 a 변수에 해당하고, 지역변수는 <code>inner</code> 함수 안에서 선언된 a를 이야기한다.
스코프의 특성상 외부에서 내부의 변수에 접근 할 수 없으므로 지역변수로서 선언 된 값은 해당 지역에서만 접근 가능하고, 혹시라도 전역 공간에서 변수의 이름이 겹쳐 덮어쓸(overriding)될 위험을 줄일 수 있다.
그렇기에 가능하면 전역변수가 아닌 지역변수를 사용하도록 하자.</p>
<h3 id="this">this</h3>
<p>실행컨텍스트의 thisBinding에는 this로 지정된 객체가 저장 되게 된다.
컨텍스트가 활성화 될때, this가 지정 되지 않은 경우엔 전역객체가 저장 되게 된다.
그 외에는 함수를 호출하는 방법에 따라서 this의 값이 바뀌게 된다.
this에 대해서는 다음 포스팅에서 다루도록 하겠다.</p>
<hr>
<p>해당 포스팅은 <a href="https://www.google.com/search?q=%EC%BD%94%EC%96%B4%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8&amp;oq=%EC%BD%94%EC%96%B4%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8&amp;aqs=chrome..69i57.2512j0j4&amp;sourceid=chrome&amp;ie=UTF-8">코어자바스크립트</a> 2장 실행컨텍스트를 바탕으로 포스팅하였습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL [이벤트 루프]]]></title>
            <link>https://velog.io/@mong-byte/TIL-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84</link>
            <guid>https://velog.io/@mong-byte/TIL-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%EB%A3%A8%ED%94%84</guid>
            <pubDate>Fri, 13 Aug 2021 11:53:27 GMT</pubDate>
            <description><![CDATA[<p>이번 포스팅에선 이벤트루프에 대한 이야기를 해 보려고 한다.
이벤트루프는 자바스크립트가 이벤트를 처리하는 방식이라 할 수 있는데,
우리가 사용하는 자바스크립트가 어떻게 작동하는지 어느정도는 알아야 하지 않겠는가.
비록 아는것과 모르는것의 차이가 지금 당장 보이지 않더라도, 더 나은 개발자가 되기위해 조금씩 조금씩 알아가도록 하자.</p>
<h1 id="이벤트루프">이벤트루프</h1>
<p>이벤트루프를 알기에 앞서 먼저 알아야 할 개념이 있는데,</p>
<ul>
<li>동시성(Concurrency)</li>
<li>단일쓰레드(single-thread)</li>
</ul>
<p>가 그것이다.</p>
<p>우선 각각의 개념이 어떻게 연결 되는지 확인 해 보자.</p>
<h2 id="동시성과-단일쓰레드">동시성과 단일쓰레드</h2>
<p>브라우저는 단일쓰레드에서 동작하고, 자바스크립트는 브라우저 기반 언어인 만큼 단일쓰레드 기반으로 동작한다.
단일쓰레드라는 말은 한꺼번에 여러가지 작업(task)를 처리하지 않고, 한번에 하나의 작업만을 수행하는 방식을 의미한다.
하지만 그렇다면 이상한 점이 생긴다.
웹을 보다보면 한번에 여러가지 일을 동시에 처리 하는듯이 보이기 때문이다.
바로 이것이 자바스크립트에 있어서의 동시성(Concurrency)이라는 개념이다.</p>
<p>이렇게 자바스크립트가 동시성을 가지고 동작 할 수 있게 만드는 것이 바로 이벤트루프(Event Loop)이다.</p>
<h2 id="이벤트의-처리와-이벤트루프">이벤트의 처리와 이벤트루프</h2>
<h3 id="이벤트-처리">이벤트 처리</h3>
<p><img src="https://images.velog.io/images/mong-byte/post/7add8611-ee4e-41b3-a9d5-ebc8a9cbc5d4/event-loop.png" alt="">
자바스크립트 엔진은 대부분 두개의 영역으로 나뉘어져 있는데,</p>
<ul>
<li>Heap : 동적으로 생성된 객체인스턴스가 할당 되는 영역</li>
<li>Call stack : 요청 된 작업이 쌓이는 영역</li>
</ul>
<p>Call stack의 특징은 자바스크립트의 Call stack은 하나만 존재하기 때문에 해당 스택에 쌓인 작업들은 순차적으로 실행 되고, 하나의 작업이 종료 되기 전까지 다음 작업을 수행 할 수 없다는 특징이 있다.</p>
<p>물론 상술한 특징에 따라 작업이 실행 될 경우, 순차적으로 Call stack으로 들어온 작업을 다시 순차적으로 처리 하기 때문에 동시성과는 거리가 있는 작업이 이루어진다.
이를 동시적으로 처리 하기 위해 브라우저 혹은 nodejs를 통해 비동기 요청, 처리가 이루어지게 된다.</p>
<p>Web Api는 브라우저상에서 비동기 작업들이 수행 될 수 있게 하는 api를 뜻하며, 해당되는 비동기 작업의 종류로는 Ajax, DOM Events, Timer등이 있다.</p>
<h3 id="이벤트루프-1">이벤트루프</h3>
<p>이벤트루프(event loop)는 Call stack과 Event queue를 반복적으로 확인 하여 stack 안에 작업이 존재하는가 확인한다. 만약 Call Stack이 비어있을 경우, Event Queue 내의 task가 Call Stack으로 이동하고 실행된다.</p>
<h2 id="정리">정리</h2>
<p>정리하자면 이벤트등 비동기 작업이 일어났을때 일어나는 작업 처리순서는 다음과 같다.</p>
<p><img src="https://images.velog.io/images/mong-byte/post/243115cd-f1d4-4703-9fc6-63ca0cb76b94/event-loop.gif" alt=""></p>
<ol>
<li><p>비동기처리가 발생 했을때, 해당 코드는 Call stack에 쌓이고, 자바스크립트엔진에서 web api로 비동기 처리가 위임 된다. 비동기 처리를 담당하는 곳이 web api이기 때문이다.</p>
</li>
<li><p>web api가 비동기 작업을 처리하게 되고, 해당 이벤트의 콜백함수가 이벤트루프를 통해서 Event Queue로 이동하게 된다.</p>
</li>
<li><p>이벤트루프가 Call stack에 함수가 없는 것을 확인 했을때, Event Queue에 쌓인 콜백함수를 Call stack으로 이동시킨다.</p>
</li>
<li><p>Call stack에 쌓인 함수가 실행 되고, 다시 Call stack을 비우게 된다.</p>
</li>
</ol>
<h2 id="참고">참고</h2>
<ul>
<li><a href="https://poiemaweb.com/js-event">모던 자바스크립트 Deep dive - event</a></li>
<li><a href="https://zereight.tistory.com/855">이벤트루프란?</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[TIL [브라우저의 동작원리]]]></title>
            <link>https://velog.io/@mong-byte/TIL-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC</link>
            <guid>https://velog.io/@mong-byte/TIL-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%EC%9D%98-%EB%8F%99%EC%9E%91%EC%9B%90%EB%A6%AC</guid>
            <pubDate>Thu, 12 Aug 2021 15:21:13 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/mong-byte/post/79bcbd91-17d0-49ee-be91-8e82d86fbdca/most-secure-browser-1.jpeg" alt=""></p>
<p>브라우저(Browser)에는 여러가지 종류가 있다.
최근 가장 많이 쓰이고 있는 크롬, 파이어폭스, 사파리, 크롬 엔진을 사용하고 있는 브레이브, 네이버웨일, 여러모로 모두의 관심을 받고 있는 MS사의 IE, 최근에 추가 된 엣지 외에도 굉장히 많은 수의 브라우저가 있다.</p>
<p>아마 인터넷을 사용한다고 하면 거의 필수적으로 한번쯤 거쳐 갈 이 브라우저.
하지만 우리는 정작 이 브라우저가 어떻게 움직이는지, 어떤 방법으로 인터넷을 이용하여 우리에게 웹을 표시해 주는지, 우리는 잘 모른다.</p>
<p>컴퓨터와 인터넷이 마법을 부리는걸까?
아쉽게도 그렇지 않다. 브라우저, 컴퓨터, 인터넷 모두 제대로 된 작동 원리가 있으며, 우리는 그 원리에 따라 처리 된 내용을 보고 있는 것이다.
그렇다면 그 중에서 이 브라우저는 어떤 방식으로 우리 컴퓨터에서 작동 할까?
우리는 개발자이며, 웹을 만드는 사람들이다. 때문에, 우리는 이러한 브라우저가 어떻게 작동하는지, 작동 원리를 알아야할 필요가 있을 것이다.</p>
<h1 id="브라우저의-동작">브라우저의 동작</h1>
<h2 id="브라우저란">브라우저란?</h2>
<hr>
<p>브라우저의 동작원리에 앞서, 이 브라우저라는 것이 뭔지 먼저 알아보도록 하자.
위키백과에서 발췌 하자면,</p>
<blockquote>
<p>웹 브라우저(영어: web browser) 또는 웹 탐색기(web探索機, 문화어: 열람기)는 웹 서버에서 이동하며(navigate) 쌍방향으로 통신하고 HTML 문서나 파일을 출력하는 그래픽 사용자 인터페이스 기반의 응용 소프트웨어이다. 웹 브라우저는 대표적인 HTTP 사용자 에이전트의 하나이기도 하다. - <a href="https://ko.wikipedia.org/wiki/%EC%9B%B9_%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80">위키백과</a></p>
</blockquote>
<p>과 같이 찾을 수 있는데, 요약하자면 쌍방향으로 통신(HTTP)하고 HTML문서 혹은 파일등을 우리가 볼 수 있게 출력하는 프로그램이라는 의미이다.</p>
<p>이때 쌍방향으로 통신하는 통신규약이 바로 HTTP이며, 바로 이 브라우저를 통해서 request &amp; response를 주고 받는 것이다.</p>
<h2 id="브라우저의-기능">브라우저의 기능</h2>
<hr>
<p>상술했듯이 브라우저는 사용자가 선택한 자원을 우리가 볼 수 있게 만들어 주는 역할을 한다.
여기서 자원이란 HTML문서가 될 수도 있겠지만, PDF 혹은 Image도 자원이 될 수 있다.
또한 해당 자원의 주소는 URI(Uniform Resource Identifier)에 의해 결정 된다.</p>
<p>이 URI는 흔히 아는 URL과는 다르다!
자세히 다루게 되면 이야기가 길어져 생략하겠으나, 간단히 이야기 하고 넘어가자면 URI는 인터넷상에서 어떤 리소스(자원)를 식별하기 위한 식별자(Identifier)이고, URL은 해당 리소스가 어디에 존재하는지를 알려주기 위한 주소(Locator)이다.</p>
<p>일반적으로 HTML문서는 HTML, CSS명세에 따라 해석 되며, 해당 명세는 웹 표준화 기구(W3C)에서 정해진다.
이렇게 하나의 명세를 따르는 이유는 각 브라우저가 독립적인 방향성을 가지고 개발 되었을때, 각 브라우저간의 심각한 호환성 문제가 발생하기 때문이다.</p>
<p>이러한 문제때문에 하나의 명세에 따라 개발 된 결과, 브라우저는 서로 비슷비슷한 인터페이스를 가지게 되었는데,</p>
<ul>
<li>주소 표시줄</li>
<li>이전버튼, 다음버튼</li>
<li>새로고침 버튼</li>
<li>북마크</li>
<li>홈버튼</li>
</ul>
<p>이 바로 그것이다.</p>
<h2 id="브라우저의-구성">브라우저의 구성</h2>
<hr>
<p><img src="https://images.velog.io/images/mong-byte/post/745c763b-135b-46ca-bcdc-28b3172cbdd3/helloworld-59361-1.png" alt="">
하나하나 살펴보자면,</p>
<ul>
<li>사용자 인터페이스 : 상술한 브라우저의 인터페이스, 사용자가 사용하는 서비스를 칭한다.</li>
<li>브라우저 엔진 : 사용자 인터페이스와 렌더링 엔진의 동작을 제어한다.</li>
<li>렌더링 엔진 : 사용자가 요청한 컨텐츠를 표시하는 엔진이다.</li>
<li>통신 : HTTP를 이용한 네트워크 통신을 칭한다.</li>
<li>UI 백엔드 : 플랫폼에서 명시하지 않은 일반적인 인터페이스를 칭한다.</li>
<li>자바스크립트 해석기 : 자바스크립트를 해석하고 작동시킨다.</li>
<li>자료저장소 : 쿠키, 웹스토리지등 자료를 저장하기 위한 장소를 칭한다.</li>
</ul>
<h3 id="렌더링이란">렌더링이란?</h3>
<hr>
<p>렌더링(rendering)은 웹개발을 진행하다보면 자주 보는 단어이다.
렌더링이란 요청 하고, 응답을 받은 데이터를 가지고 화면에 그려내는 것이라 이해 하면 될것이다.</p>
<p>이를 수행 하는 장치가 바로 렌더링 엔진이고, 기본적으로 HTML, XML등의 문서를 표시 할 수 있으나, 추가 플러그인등을 사용하여 PDF등 다른 유형의 파일도 표시가 가능하다.</p>
<p>이 렌더링 엔진의 종류는 대표적으로</p>
<ul>
<li>Webkit : 크롬, 사파리등에서 사용</li>
<li>Gekko : 파이어폭스에서 사용
가 있다.</li>
</ul>
<h4 id="렌더링-과정">렌더링 과정</h4>
<hr>
<p><img src="https://images.velog.io/images/mong-byte/post/08867d52-c090-4142-86c1-83620488b7a6/helloworld-59361-2.png" alt=""></p>
<p>우선 DOM에 대해 설명 하자면,
DOM(Document Object Model)은 자바스크립트를 다루면서 많이 마주쳤던 그 DOM이 맞다.
즉 HTML을 자바스크립트로 다룰 수 있도록 변환시킨 문서 객체(Document Object)이며,
브라우저가 HTML문서를 인식하는 방법인것이다.</p>
<p>렌더링은 그림과 같이 4단계로 나뉘는데,</p>
<ul>
<li>먼저 HTML을 파싱, 태그들을 모두 DOM노드로 변한 하고, css등 스타일 요소를 파싱한다.</li>
<li>파싱된 정보를 가지고 렌더 트리를 구축한다.</li>
<li>구축 된 렌더트리는 정해진 순서대로 노드가 화면에 배치된다.</li>
<li>배치 된 노드들을 UI백엔드에서 그려낸다.</li>
</ul>
<p>와 같은 단계로 컨텐츠를 그려내게 된다.
이때, 모든 요소에 대해서의 단계 진행을 기다리지 않고, 먼저 단계를 완료하고 생성 된 순서대로 화면을 그리게 된다.
때문에 우리가 봤을때는 화면에 요소가 하나씩 나타나는것 처럼 보이는 것이다.</p>
<h3 id="웹킷의-동작구조">웹킷의 동작구조</h3>
<hr>
<p><img src="https://images.velog.io/images/mong-byte/post/1cf90a64-7b24-4a45-a3f9-3b364c155585/helloworld-59361-3.png" alt="">
여기서 어태치먼트란 파싱 된 DOM트리와 스타일 정보를 연결하여 합치는 과정이다.
어태치먼트를 거쳐서 합쳐진 DOM트리와 스타일 정보는 렌더트리가 된다.</p>
<h3 id="파싱과-dom트리-구축">파싱과 DOM트리 구축</h3>
<hr>
<p>파싱(parsing)이란 브라우저가 코드를 이해 할 수 있는 구조로 변환하는 과정을 말한다.
쉽게 이야기하자면 번역 과정인데, 전송 된 HTML코드의 맞춤법을 검사하고, 맞춤법에 맞는 태그들만 통과시켜서 만들어진 노드들로 1차적으로 파서트리라는것을 구성하게 된다.</p>
<p>이후 다시 기계어로 번역하는 과정이 추가 되고, 그것이 끝나게 되면 파싱은 종료되게 된다.
하지만 이렇게 맞춤법(규칙)을 검사하는것은 굉장히 복잡한 작업이고, 최적화 시키기 힘든 작업이기에 일반적으로는 flex, bison이라 하는 파서 생성기를 사용하게 된다.</p>
<p>여기서 생성된 파서가 우리가 만든 문서를 돌면서 실수로 빠트린 태그가 있더라도 파서가 추가 시켜주는것이다.</p>
<h2 id="정리">정리</h2>
<hr>
<p>우리가 웹페이지에서 정보를 확인하기 위해 서버에 HTTP를 이용해 요청을 보내면, 서버는 데이터를 담아 응답을 한다.
이때 우리가 받은 정보는 HTML, CSS, JS등으로 우리에게 전송 되어 오는데, 우리가 사용하는 브라우저는 전송 받은 자원을 컴퓨터가 이해할 수 있도록 파싱하고, 이를 이용해 웹페이지를 그릴 수 있도록 트리를 구성하며, JS를 컴파일하여 각종 인터렉션이 가능하게 만든다.</p>
<h2 id="참고">참고</h2>
<hr>
<ul>
<li><a href="https://d2.naver.com/helloworld/59361">[네이버 D2] 브라우저는 어떻게 동작하는가</a></li>
<li><a href="https://gyoogle.dev/blog/web-knowledge/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%20%EB%8F%99%EC%9E%91%20%EB%B0%A9%EB%B2%95.html">[TECH INTERVIEW] 브라우저 동작 방법</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Pre-onboarding [2주차 회고]]]></title>
            <link>https://velog.io/@mong-byte/Pre-onboarding-2%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@mong-byte/Pre-onboarding-2%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Sat, 07 Aug 2021 13:20:11 GMT</pubDate>
            <description><![CDATA[<h1 id="회고">회고</h1>
<p>위코드 기업협업이 끝나고 곧바로 시작된 Pre-onboarding.
쉽지 않을거라 생각은 했지만 뚜껑을 열어보니 하루하루가 챌린지였다.
그러나 이 또한 지나가는 법. 어느샌가 2주가 훌쩍 지나가 버렸다.</p>
<p>어느샌가 진행 된 프로젝트는 3개, 팀원들과도 꽤나 친해지게 되었다고 생각한다.
내가 더 나은 개발자가 되었는지, 나의 역량은 확실히 올랐는지는 모르겠지만 적어도 2주 전에 비해서 10줄 칠 코드를 8줄로 줄이는것 정도로 성장하지 않았을까 하는 생각이 든다.</p>
<p>그리고 훌륭한 개발자, 남들보다 나은 개발자는 못되더라도, 어제보다 나은 개발자가 되기 위해 지난 2주의 회고를 작성하고자 한다.</p>
<h2 id="시작이-반이다">시작이 반이다</h2>
<p>위코드 기업협업이 절반가량 진행 되었을때, 슬랙에서 프론트를 위한 원티드의 Pre-onboarding이라는 코스가 개설 된다는 소식을 들었다.
당장의 프로젝트도 정신없이 바쁘긴 했지만, 당장의 내 역량에 의문점이 들기도 하였고, 아무래도 3개월이라는 시간은 너무 짧지 않은가 하는 생각에 일단 신청 하고 보기로 했다.</p>
<p>우여곡절 많았던 기업협업을 끝내고 시작된 새로운 코스 Pre-onboarding.
첫번째 과제였던 무한스크롤은 같이 짝이 되었던 우빈님과의 콤비로 꽤 무난히 해결 할 수 있었다.
100점짜리는 아니었지만, 두번째 만드는거라 여유가 있었고, 이것저것 자료를 찾다가 <code>이거 한번 잡숴봐</code>하는 식으로 찾아 적용 시켰던 Intersection Observer를 조금 더 이해하면서 만들 수 있는 기회가 되었다 생각한다.</p>
<p>이때까지는 나름 잘 해낼 수 있을것이라는 왠지 모를 자신감도 있었고, 다음 과제를 기다릴 정도의 여유가 있었다.</p>
<h2 id="시작이-반이랬는데-나머지-반이-너무-멀다">시작이 반이랬는데 나머지 반이 너무 멀다</h2>
<p>첫번째 과제를 끝내고 새롭게 받은 과제의 테마는 고객이 보고 싶은 상품.
요점은 </p>
<ul>
<li>사용자가 본 내역을 저장해 두고</li>
<li>상품 페이지에서 랜덤을 누르면 다른 상품을 랜덤으로 출력</li>
<li>관심 없음 버튼을 누르면 해당 상품은 출력하지 않음</li>
</ul>
<p>이었다.</p>
<p>이번에도 호기롭게 시작 된 프로젝트.
시작이 반이다 라는 생각으로 호기롭게 시작했더랬다.</p>
<h3 id="그러나-쉽지-않았다">그러나 쉽지 않았다</h3>
<p>내가 구현 했던 기능은 들어온 데이터의 브랜드를 모아 하나의 배열로 만든 다음, 각각의 브랜드를 눌렀을때 필터링 되게 하는 로직과 라우터 부분이었다.</p>
<p>우선 각각의 브랜드를 눌렀을때 필터링 되게 하는 로직은 엄청나게 많이 시간을 잡아 먹지는 않았으나 문제는 라우터였다.
처음 주어진 데이터를 기반으로 사용해야 하는 터라 필요한 데이터를 처음 받아오면서 1차적으로 데이터를 가공했어야 했는데, 이때 path parameter로 사용 할 id를 넣는데서 문제가 생겼다.</p>
<p>또한, 프로젝트를 진행하던중 예상치 못했지만 필요한 기능들이 나오기 시작해서 시간은 점점 잡아먹히고, 마음도 조급해지기 시작했다.</p>
<p>어찌저찌 기능 구현이 마무리 되고 제출을 하려던 순간.
상술한 path parameter의 id에서 문제가 생겼다.</p>
<p>바로 id는 바뀌지 않는 고유의 값이어야 하는데, 이걸 index로 지정해 버려 문제가 생긴것이었다.
그래서 id값이 배열 안에서 아이템이 나가거나 들어올때, id값이 바뀌어 버리는 상황이 되었다.
결국 시간 문제상 이 부분은 바꾸지 못하고 제출 하여서 상당한 아쉬움으로 남았다.</p>
<p>이런 문제 해결 과정에서, index값을 id로 사용하는것이 얼마나 위험한지를 알게 되었고,
다음 프로젝트에선 index가 아닌 다른 방법으로 id를 부여하는 방법으로 노선을 바꾸게 되었다.</p>
<p>우여곡절이 많았지만, 데드라인 안에 기능 가동은 확인 된 결과물을 제출 했다.
라우터 말고는 큰 문제가 없었기 때문에, 다른 팀원들에게 정말 고맙고도 미안한 마음이 들었다.</p>
<h2 id="이번엔-다르다">이번엔 다르다</h2>
<p>그렇게 두번째 과제도 마무리 되고 다음은 8명이 진행하는 세번째 과제.
이전 프로젝트와 인원 말고 또 다른점이라면, Git에 관련한 차이점이 존재했다.
바로 Git flow에 따라 진행하기로 한것이다.
<img src="https://images.velog.io/images/mong-byte/post/a25d11bb-2f71-45a0-b5c8-2f07f3dc8638/git-flow_overall_graph.png" alt=""></p>
<p>여기 나온것 처럼, mater는 배포 브랜치, 개발을 위한 develop 브랜치를 두고, develop을 기반으로 각 페이지별 브랜치, 거기에서 페이지의 기능별 브랜치를 만들어서 만든 순서의 역순으로 Merge를 시키는 방식으로 진행 하였다.</p>
<p>기능은 2~3명이 나누어져 프로젝트를 진행하기로 했다.
우빈님과 다시한번 콤비가 되어 구현을 진행했는데,
우리가 맡은 기능은 권한관리와 그에 대한 라우팅, 관리자의 임의계정 생성, Util 함수 작성이었다.</p>
<p>권한 관리에 사용한 방법은 HOC를 사용해서, 해당 컴포넌트가 랜더링 되기 전에 권한을 판단하고 권한이 맞지 않다면 다른 페이지로 리다이렉트를 시키는 방법을 사용하기로 하였다.</p>
<p>아무래도 각 case에 맞춰서 조건을 줘야 하다보니 처음엔 if가 6번이나<em><del>(!)</del></em> 들어가는 일도 생겼지만, 우빈님과 시간을 들여 고민하며 최대한 줄이는것에 성공 하였다.</p>
<p>로컬스토리지를 사용하는 로직이 담겼던 util쪽에서는 이번에도 새롭게 생성 되는 계정에 id를 추가하는 기능이 필요했는데, 이때는 전 프로젝트에서 생겼던 문제점을 개선하고자, 로컬스토리지에 있는 유저 리스트의 마지막 id를 불러와서 그 id에 +1을 하는 방식으로 진행 되었다.
더미 데이터에 원래부터 id가 들어있는걸 이용한 방법이었다.</p>
<p>또한 상수를 적극적으로 활용해 보았고, 상수의 사용으로 코드가 얼마나 깔끔해 지는지 알 수 있었다.</p>
<p>가장 놀랐던 점은 8명이서 3팀으로 나누어져 개발을 해서, 굉장히 많은 파일과 기능들이 추가 되었는데, 생각보다 merge시 conflict가 많이 발생 하지 않았던 점이다.
서로의 분업이 잘 되었다는 증거인것 같아 뿌듯했다.
그리고 아침에 회의와 함께 시작해서 해산이 새벽 2~3시, 혹은 5시 넘을때도 있을 정도로 고생은 많았지만, 열정 있는 사람들과 함께라 좋다고 느꼈다.
물론 그렇게 나온 결과물도 만족스러웠다.</p>
<p>한가지 아쉬운 점은, 중간 제출이 끝나고 이어진 세션에서 함수형 컴포넌트는 HOC보다는 Route를 개조해서 사용하는 방식, hooks를 사용하는 방법등을 사용한다고 하셨는데, 우리가 이미 구현한 방법은 HOC 방식이라, 이 부분은 나중에라도 다른 방법으로 구현 해 보고 싶다고 생각하였다.</p>
<h2 id="헛걸음이라도-뒷걸음-치지-말자">헛걸음이라도 뒷걸음 치지 말자</h2>
<p>분명히 내 관점에선 쉬운 과제들은 아니었다.
같은 팀이 되신 분들도 모두 잘하시는 분들이라 조급해지기도 하지만, 나는 내 페이스대로, 하나의 과제가 있으면 무조건 하나 이상은 배우고 성장해 가려 한다.
물론 가능하다면, 그때마다 블로그등에 정리해 가려 한다.
쓰는 만큼 글쓰기도 늘것이니 말이다.</p>
<p>8명이 의사소통을 하면서 공통된 과제를 완수하는것이 쉬운 일은 아니지만, 난 그래도 팀은 정말 잘 만난것 같아 다행이라고 느꼈다.</p>
<p>물론 이 팀이 영원하지는 않겠지만, 그래도 남은 기간 화이팅 해서 서로 잘 이겨 나갔으면 좋겠다.</p>
<p><img src="https://images.velog.io/images/mong-byte/post/59df447a-21c6-4bc5-8cc8-aeedb92a4230/image_(1).png" alt=""></p>
<p>7ill-resource 화이팅!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Pre-onboarding [ Infinity scroll ]]]></title>
            <link>https://velog.io/@mong-byte/Pre-onboarding-Infinity-scroll</link>
            <guid>https://velog.io/@mong-byte/Pre-onboarding-Infinity-scroll</guid>
            <pubDate>Tue, 27 Jul 2021 16:40:49 GMT</pubDate>
            <description><![CDATA[<h1 id="infinity-scroll">Infinity scroll</h1>
<p><img src="https://images.velog.io/images/mong-byte/post/dcdbef90-98ba-45d2-b164-c7a18a021090/infinify-scroll.gif" alt=""></p>
<p>최근 웹사이트에서 자주 볼 수 있는 무한 스크롤을 구현하였다.</p>
<p>흔한 기능이라 쉽게 생각 할 수 있지만, 누군가 이야기 했던가, 인간에게 어려운 일은 컴퓨터에게 쉽고, 인간에게 쉬운 일은 어려운 법이라고.</p>
<p>내용 자체가 어렵다기 보다는 처음에 감을 잡는데 시간이 오래 걸렸다는 느낌이 든다.</p>
<p>어쨋든 이번에 구현한 무한스크롤에 대해 알아보도록 하자.</p>
<h2 id="무한스크롤이란">무한스크롤이란?</h2>
<p>코드를 보기전에 우선 무한스크롤이 어떤것인지에 대해 알아야 한다.
무한스크롤이란 스크롤이 최하단에 도달했을때, 새로운 데이터를 받아와서 아래에 붙이는 데이터의
로드 방식이라 생각하면 된다.</p>
<blockquote>
<p>핵심은 스크롤이 최하단에 도달했는지 아닌지를 어떻게 코드로 인식을 시킬것인가에 있다.</p>
</blockquote>
<h3 id="무한스크롤-flow">무한스크롤 flow</h3>
<p>무한스크롤이 어떻게 작동 되는지 쪼개보자면,</p>
<ol>
<li>스크롤이 최하단에 도달한다.</li>
<li>스크롤이 최하단에 도달한것을 감지한다.</li>
<li>스크롤이 도달하였다면 데이터 요청을 보낸다.</li>
<li>불러온 데이터를 기존의 데이터에 합친다.</li>
<li>다시 스크롤을 감시한다.</li>
</ol>
<p>로 볼 수 있다.</p>
<p><strong>2번이 핵심인데, 스크롤의 위치를 감지하기 위해서는 어떤 방법이 있을까?</strong></p>
<h2 id="어떤-방법을-이용할까">어떤 방법을 이용할까?</h2>
<p>방법은 두가지다.</p>
<ol>
<li>Viewport와 스크롤 이벤트를 이용해서 계산하는 방법</li>
<li>Intersection Observer API를 사용해서 감지기(Observer)를 두는 방법</li>
</ol>
<p>이번에는 두번째 방법인 Intersection Observer를 이용한 방법에 대해 다뤄보려 한다.</p>
<h3 id="intersection-observer">Intersection Observer</h3>
<p><a href="https://developer.mozilla.org/ko/docs/Web/API/Intersection_Observer_API">Intersection Observer</a>는 쉽게 말하면, 어떤 요소를 매개로 화면상의 어떠한 변화를 감지하여, 감지 되었을때 콜백을 실행하는 API이다.</p>
<p>화면을 내리다가 어떠한 요소(target)과 교차할때 콜백을 사용하는 것이다.
이때 options를 통해서 해당 요소와 얼마나 교차 되었을때 실행 할것인지(threshold), target과 어느정도 거리가 가까워졌을때 콜백을 실행할 것인지(rootMargin)를 정할 수 있다.</p>
<p>이때 사용 된 코드를 가져와 보면,</p>
<pre><code class="language-js">  useEffect(() =&gt; {
    if (target.current) {
      const observer = new IntersectionObserver(onIntersect, option);
      observer.observe(target.current);
      return () =&gt; observer &amp;&amp; observer.disconnect();
    }
  }, [onIntersect, target]);</code></pre>
<p>target은 useRef를 이용해 문서 최하단에 빈요소 <code>div</code>에 두었고, 이 요소가 화면안에 들어왔을 경우 <code>onIntersect</code>를 실행한다.
이때, 이 <code>observer</code>는 useRef가 적용된 <code>div</code>를 보고 있고, 한번 감지가 완료 되었을때 <code>observer</code>의 감시를 종료한다.</p>
<p><code>onIntersect</code></p>
<pre><code class="language-js">  const onIntersect = useCallback(([entry]) =&gt; {
    if (entry.isIntersecting) {
      setPage((page) =&gt; page + 1);
    }
  }, []);</code></pre>
<p><code>onIntersect</code>는 배열 요소로서 여러가지의 <code>IntersectionObserverEntry</code>라는 객체의 배열을 반환하는데, 이중 <code>isIntersecting</code>은 해당 요소의 교차상태를 Boolean값으로 나타낸다.</p>
<p>그리고 <code>isIntersecting</code>이 <code>true</code>가 되면 page를 증가시키고, page를 읽고 있던 useEffect가 새 쿼리로 요청을 보내는 flow가 완성된다.</p>
<p>그렇게 불러온 새 데이터는 기존의 Data 배열에 <code>concat</code>을 이용하여 합치게 된다.</p>
<h2 id="회고">회고</h2>
<p>무한스크롤을 구현해 본것은 이번이 처음이 아니었다.
혼자 강의를 들을때 리액트 챌린지로 나온것이 무한스크롤이었고, 밤늦게 시작했던 챌린지는 새벽이 되어 해가 뜰때쯤 완료했던 기억이 난다.</p>
<p>이야기만 들었었던 무한스크롤은 처음엔 이해하기가 굉장히 어려웠지만, 그만큼 만들면서 재미가 있었다.
만들고 나서 내가 해냈다는 생각에 다음날 하루종일 기분이 좋았고, 이래서 뭔가를 구현하는것은 즐겁다라는것을 느꼈다. 밤을 새면서 졸음을 느끼지 않다가 구현이 완료 되고 제출 한 다음에야 잠이 쏟아진걸 봐서 상당히 집중도 했을테고 말이다.</p>
<p>이번에 구현할때는 페어프로그래밍으로 진행 되었기에, 다른 사람은 어떤 방식으로 구현하는지를 배울 수 있는 귀중한 기회가 되었던것 같다.</p>
<p>물론 동시에, 그때 사용했던 코드와 개념을 다시 한번 이해하는 시간이 되었다.</p>
<h4 id="참고링크">참고링크</h4>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/API/Intersection_Observer_API">MDN</a></li>
<li><a href="https://heropy.blog/2019/10/27/intersection-observer/">https://heropy.blog/2019/10/27/intersection-observer/</a></li>
<li><a href="http://blog.hyeyoonjung.com/2019/01/09/intersectionobserver-tutorial/">http://blog.hyeyoonjung.com/2019/01/09/intersectionobserver-tutorial/</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn..."기억하고 싶은 1차 프로젝트 코드"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...%EA%B8%B0%EC%96%B5%ED%95%98%EA%B3%A0-%EC%8B%B6%EC%9D%80-1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%BD%94%EB%93%9C</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...%EA%B8%B0%EC%96%B5%ED%95%98%EA%B3%A0-%EC%8B%B6%EC%9D%80-1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%BD%94%EB%93%9C</guid>
            <pubDate>Sun, 20 Jun 2021 14:36:11 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>가장 기억에 남는 코드</p>
</blockquote>
<p>이번 프로젝트에서 가장 기억에 남는 코드는 장바구니에서 선택 된 아이템을 삭제하는 코드이다.</p>
<pre><code class="language-js">  selectDelete = () =&gt; {
    const { cartData, selectedArr } = this.state;
    const checkedArr = [];
    const deletedArr = [];
    const deletedId = [];
    let idx = selectedArr.indexOf(true);
    while (idx !== -1) {
      checkedArr.push(idx);
      idx = selectedArr.indexOf(true, idx + 1);
    }
    const newCheckedArr = cartData.filter((cartItem, index) =&gt; {
      const condition = !checkedArr.includes(index);
      if (!condition) deletedArr.push(cartItem);
      return condition;
    });
    deletedArr.map(el =&gt; {
      deletedId.push(el.id);
    });
    this.deleteCart(deletedId).then(response =&gt; {
      if (response.status !== 204)
        return alert(`삭제에 실패했습니다. 에러코드 : ${response.status}`);
      return this.setState({
        cartData: newCheckedArr,
        selectedArr: Array(newCheckedArr.length).fill(false),
      });
    });
  };</code></pre>
<p>한부분 한부분씩 떼서 설명 하기 전에, 사전에 선택을 하는 방식은 하나의 리스트 안에 각각의 인덱스에 맞는 값을 <code>true</code> 혹은 <code>false</code>로 저장 하고, 거기에 맞춰서 아이템을 삭제하는 방식이다.</p>
<p>예를 들어 아이템이 3개가 있고 2번째 아이템만 선택이 되었다면, 이를 나타내는 <code>state</code>는 <code>[false,true,false]</code>가 되는 형식이다.
이를 위해 <code>selectedArr: Array(newCheckedArr.length).fill(false),</code>에서 데이터의 갯수에 맞게 배열을 만들고, 그 값을 false로 초기화 하였다.</p>
<p>첫번째로,</p>
<pre><code class="language-js">let idx = selectedArr.indexOf(true);
    while (idx !== -1) {
      checkedArr.push(idx);
      idx = selectedArr.indexOf(true, idx + 1);
    }</code></pre>
<p>이 코드는 내가 원하는 <code>selectedArr</code>에서 <code>true</code>의 값이 어느 인덱스에 있는지를 찾는 코드이다.</p>
<p>여기에 들어가는 idx는 값이 <code>true</code>인 아이템의 인덱스만을 찾기에, 어느 인덱스에 있는 아이템이 체크(<code>true</code>)되었는지 알 수 있다.</p>
<p>이 인덱스를 <code>checkedArr</code>에 넣고,</p>
<pre><code class="language-js">const newCheckedArr = cartData.filter((cartItem, index) =&gt; {
      const condition = !checkedArr.includes(index);
      if (!condition) deletedArr.push(cartItem);
      return condition;
    });</code></pre>
<p>에서 <code>checkedArr</code>에 포함 되어 있지 않는, 즉 선택 되지 않은(<code>false</code>) 아이템만을 배열로 해서 리턴 시킨다.</p>
<p>만약 이를 만족 하지 못한다면, 즉 선택된(<code>true</code>)요소는 view에서 사라지고, 아이템은 <code>deletedArr</code>로 이동한다.</p>
<pre><code class="language-js">    deletedArr.map(el =&gt; {
      deletedId.push(el.id);
    });</code></pre>
<p>이 부분은 백엔드와의 소통의 결과물인데, 원래는 삭제한 아이템 전체를 백엔드에 보냈지만, 백엔드 팀원과의 대화 후, 해당 아이템의 id만 보내기로 합의가 되었다.
그때문에 하나의 배열을 만들고, 거기에 <code>deletedArr</code>에 <code>map</code>을 사용, id만을 추출해서 </p>
<pre><code class="language-js">this.deleteCart(deletedId).then(response =&gt; {
      if (response.status !== 204)
        return alert(`삭제에 실패했습니다. 에러코드 : ${response.status}`);
      return this.setState({
        cartData: newCheckedArr,
        selectedArr: Array(newCheckedArr.length).fill(false),
      });</code></pre>
<p>백엔드에 보내는 로직으로 이어진다.</p>
<p><code>deleteCart</code>는 </p>
<pre><code class="language-js">  deleteCart = payload =&gt; {
    return fetch(`${GET_CART_LIST}`, {
      method: &#39;DELETE&#39;,
      headers: {
        Authorization: `${LOGIN_TOKEN}`,
      },
      body: JSON.stringify(payload),
    });
  };</code></pre>
<p>이와 같은 함수로, 선택 삭제뿐만 아니라 개별 삭제에도 사용 되는 함수라서, 함수의 재사용을 위해 따로 빼두었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn..."1차 프로젝트 회고록"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...1%EC%B0%A8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D</guid>
            <pubDate>Sun, 20 Jun 2021 14:15:15 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h1 id="1차-프로젝트를-돌아보며">1차 프로젝트를 돌아보며</h1>
</blockquote>
<p>말도 많고 탈도 많았고, 끝날듯 끝나지 않던 1차 프로젝트가 마침내 그 끝을 맞이했다.</p>
<p>결코 길지는 않은 시간이었지만, 이제 막 개발자를 시작하게 된 나로서는 하나를 붙잡고 진행 된 2주란 시간은 아직 짧은 시간이라 느끼지 못하는 시간이었다.</p>
<blockquote>
<p><em>어떤 프로젝트였나?</em></p>
</blockquote>
<p>우리가 담당한 클론 대상 웹사이트는 <a href="https://www.oasis.co.kr/main">오아시스 마켓</a>이라는 커머스 사이트로, 사실 눈여겨 보던 사이트는 아니었다.</p>
<p>관심이 없었다기보다는 애당초 첫 프로젝트였기에, 어떤걸 해야겠다 하는 생각 보다는, <strong>뭐라도 괜찮으니까 열심히 하자</strong>라는 생각이 더 앞섰다고 생각한다.</p>
<p>나는 프론트엔드 팀으로 참가 했기에, 리액트를 활용하여 웹사이트의 레이아웃과, 사용자가 조작할 버튼, 혹은 컨텐츠를 제작하는 역할을 맡았었다.</p>
<blockquote>
<p><em>어떤 기능을 맡았나?</em></p>
</blockquote>
<p>내가 맡은 페이지는 우선 페이지의 상단과 하단에 있는 <code>Header</code>와 <code>Footer</code>를 1차적으로 담당했고, 그 이후엔 메인 페이지에서 각각의 상품을 클릭 했을때 넘어오는 상세페이지, 그 다음엔 장바구니 페이지를 담당 했었다.</p>
<p>사실 <code>Header</code>와 <code>Footer</code> 자체는 복잡한 로직이 없었기에 꽤나 수월하게 작업을 끝마칠 수 있었고, 상세페이지쪽의 로직도 크게 복잡하지는 않았다.</p>
<p>문제는 장바구니였다.</p>
<blockquote>
<p><em>어떤 문제가 발생하였나?</em></p>
</blockquote>
<p>프로젝트가 끝난 지금 생각 해 봤을때, 생각보다 로직이 어려웠다는 생각이 가장 먼저 들었다.</p>
<p>실제로 이 부분에서 멘토님들께 여러가지 도움 요청을 했던것도 사실이고, 구현이 어려웠다 이전에, 아예 어떻게 구현 해야 할지 감도 안잡히던 부분도 있었다.</p>
<p>어찌저찌 문제를 해결하고 완성 했을때는 꽤나 뿌듯함을 느꼈다.
처음엔 막막했지만 그래도 어떻게든 해냈구나 하는 기분이 들었다.</p>
<p>물론 그렇게 어렵게 짠 코드였기에 마지막까지 로직적으로 큰 문제를 일으키지도 않고 잘 작동 되었으니, 더욱 기억에 남는 페이지가 될것 같다.</p>
<p>장바구니에 대한 코드 리뷰는 다음 포스트에서 작성 할 예정이다.</p>
<blockquote>
<p><em>이번 프로젝트에서 기억에 남는 잘한 점은?</em></p>
</blockquote>
<p>코드에 대한것보다 팀원들과의 협업에 대해 이야기 하고 싶다.
사실 팀원들이 너무 잘 해줘서 내가 잘한점 보다는 팀이 잘 한 점이 더 맞을것이다.</p>
<p>일단 첫번째로, 전반적인 팀의 분위기는 정말 좋았던것 같은 느낌이 든다.
세상에 무조건 맞는 성향의 사람이 있는것도 아니고, 언제나 같은 기분으로 있는 사람도 없다.</p>
<p>이번 프로젝트에서 우리 팀원들은 크고 작은 다툼도 없었고, 서로가 소통이 잘 되었다 라고 말할 정도로 서로에 대한 분위기나 감정은 좋은 상태였다.
이 점은 정말 운이 좋았고, 거기에 맞춰 함께 열심히 소통한 나도 잘한 점이 아닐까 한다.</p>
<p>두번째로는 여러가지 툴의 사용에 익숙해진것이다.
팀에서 <code>git</code>등을 다루는것을 대부분 내가 맡았고, 그 덕에 처음 느꼇던 <code>git</code>에 대한 두려움도 사라졌고, 프로젝트시 어떻게 <code>git</code>이 흘러가는가, 충돌이 발생 했을때 어떻게 대처해야 하는가 등에 대해 많이 익숙해진것 같다고 느꼈다.</p>
<p>그저 공지만 기다리던 <code>slack</code>도 마침내 툴처럼 활용 되어, 여러 자료를 받거나 보내거나 하고, 밤이나 주말등에 팀원들과 연락하면서 이것저것 처리 할때 유용하게 활용 되었다.</p>
<p>프론트, 백에서 각자가 맞춰야 할 사항등을 <code>Notion</code>등에 정리한것도 잘 한 일이 아닌가 싶다.</p>
<p>세번째로는 코드의 대한 점이다.
새로운 로직을 생각해내거나 솔루션 받은 패턴을 다른곳에 응용 시켜본것도 물론 좋지만, 저번 인스타그램 클론때 새롭게 배운 코드들을 이번 프로젝트에서 꽤나 자연스럽게 사용했던것이 이번 프로젝트때 코드 면에서 얻은 가장 큰 수확이라 생각한다.</p>
<p>이번에도 꽤나 많은 코드가 등장했고, 그걸 다음 프로젝트때도 잘 활용 할 수 있었으면 좋겠다.</p>
<blockquote>
<p><em>아쉬운 점, 반성할 점은 무엇인가?</em></p>
</blockquote>
<p>가장 아쉬웠던 점은 의외로 소통에 있었다.
기록 하는 습관이 들지 않아 회의때 이야기가 나오고 이미 정해진 상황에 대해 몇번인가 나중에 되물은 적이 있었기 때문이다.
그덕에 메모하는 습관이 들기 시작하였지만, 아쉬운점이 아닐 수 없다.</p>
<p>그 다음은, 디버깅에 대해서다.
발표 전날 밤에 에러를 발견한것이다. 팀원들이 모두 달라 붙어 해결 하려 노력해서 발표는 어떻게 잘 끝났지만, 이 글을 쓰고 있는 일요일 밤까지 디버깅은 계속 되었었다.</p>
<p>디버깅 자체가 시간이 걸리는건 어쩔 수 없다고 생각하지만, 앞으로는 조금 더 시간 안배를 잘 해서 디버깅에 관한 시간을 확보 해야겠다고 생각했다.</p>
<p>다음은 나 자신에 대한 반성인데,
완성품을 봤을때, 내가 처음에 만들려고 했던 기능보다 적게 구현 했다고 느꼈다.
백엔드쪽에서 먼저 구현한것도 있었는데, 내가 조금 더 빨리 기능을 구현하고 그 기능으로 넘어갔으면 충분히 구현이 가능하다고 생각 했던 것이었다.
때문에, 더 잘 할 수 있지 않았나, 정말 이게 최선이었나 하는 생각이 들었다.</p>
<p>또 느낀것은, 실무에서는 이것보다 더 복잡하게, 더 타이트하게 개발이 이루어 질 것인데, 거기에 내가 적응 할 수 있을까 하는 생각이 들었다.
그때를 위해서라도 더 많은 공부와, 체력을 키워야 겠다는 생각이 들었다.</p>
<blockquote>
<p>하고 싶은 말</p>
</blockquote>
<p>이것저것 하고 싶은 말은 프로젝트가 끝난 뒤 회식때 다 이야기 했던 기분이 든다.
내가 말하고 싶은 한마디는, 모두가 고생한 프로젝트이고, 이번 프로젝트를 발판 삼아 더 나은 개발자로 가는 길을 각자가 찾았으면 좋겠다 라는 말을 하고 싶었다.</p>
<blockquote>
<p> 총평</p>
</blockquote>
<p>칭찬할 점도, 아쉬운 점도 분명히 많은 프로젝트였고, 냉정하게 봤을때 만족스러운 프로젝트는 아니었다 생각한다.</p>
<p>하지만 다음 프로젝트를 위한 발판은 확실히 만들어졌다고 생각한다.
오히려 잘한 점도 아쉬운 점도 많은 프로젝트이기에, 이 다음 프로젝트, 그리고 더 나아가 실무에 나가서도 내가 어떻게 행동해야 하는지에 대한 하나의 실마리를 얻은 듯한 기분이 든다.</p>
<p>사람은 잘한 일보다 아쉽고 반성 할 일을 더 오래 기억하는 생물이기에, 나를 위한 더 큰 과제를 남겨주었다고 생각한다.
또한, 내가 어떤 개발자인지, 어떤 방향을 선호하고 나아가고 싶은지에 대한 과제도 받은것 같은 느낌이 든다.
그 과제를 어떻게 풀지는 앞으로의 내가 담당하게 될것이다.</p>
<p>아래는 우리가 담당했던 프로젝트의 <code>README.md</code>파일이다.</p>
<h3 id="🌽-o-jus-maket-오져스-마켓-team">🌽 O Jus Maket (오져스 마켓) <strong>Team</strong></h3>
<p><strong>개발인원 (7명)</strong></p>
<p><a href="https://github.com/wecode-bootcamp-korea/21-1st-Ojusmarket-frontend">Frontend</a> | 김명준, 김민기, 이기완</p>
<p><a href="https://github.com/wecode-bootcamp-korea/21-1st-Ojusmarket-backend">Backend</a> | 박준영, 박지우, 장동국, 현상협</p>
<blockquote>
<p><em>&quot;소통은 무조건 중요하다! 사랑해요 오저스마켓팀&quot; - ojusmarket -</em></p>
</blockquote>
<p><strong>개발기간</strong></p>
<p>2021.06.07 ~ 2021.06.18</p>
<hr>
<h3 id="✔오아시스마켓-클론-프로젝트-선정이유">✔오아시스마켓 클론 프로젝트 선정이유</h3>
<p>커머스사이트의 다양한 회원가입, 결제, 배송 서비스들이 실제 구현되어있는것에 도전의식을 느꼈고,</p>
<p>레시피가 제공 될 뿐만아니라 레시피에 사용된 제품추천 기능 모델링에 호기심을 느끼며 직접 구현 해 보고자 선정하게 되었습니다.</p>
<h3 id="✔️오저스마켓-프로젝트-소개">✔️오저스마켓 프로젝트 소개</h3>
<p>오아시스마켓의 깔끔한 디자인과 서비스를 변형하여 클론한 &quot;오저스마켓&quot; 입니다!</p>
<p>오아시스 마켓이 제공하는 판매상품들로 적용할 수 있는 레시피의 연결성에 주목하였고, 메인페이지에서 “주문도하고 요리도하고” 탭을 추가적으로 구현하여 기존 오아시스마켓과 서비스기획의 중점을 달리하여 클론하였습니다.</p>
<p>결제서비스를 제외한 영상에서 보이는 부분들은 모두 실제 사용할 수 있는 서비스 수준으로 초기세팅부터 백앤드 연결까지 구현하였습니다.</p>
<h2 id="🔎-적용-기술-및-구현-기능">🔎 적용 기술 및 구현 기능</h2>
<h3 id="적용-기술">적용 기술</h3>
<blockquote>
</blockquote>
<ul>
<li><img src="https://img.shields.io/badge/HTML5-E34F26?style=for-the-badge&logo=html5&logoColor=white" alt="HTML"></li>
<li><img src="https://img.shields.io/badge/Sass-CC6699?style=for-the-badge&logo=sass&logoColor=white" alt="SASS"></li>
<li><img src="https://img.shields.io/badge/JavaScript-F7DF1E?style=for-the-badge&logo=javascript&logoColor=black" alt="JS"></li>
<li><img src="https://img.shields.io/badge/React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB" alt="React"></li>
</ul>
<h3 id="로그인-회원가입">로그인/ 회원가입</h3>
<ul>
<li>정규표현식사용하여 유효성검사 적용</li>
<li>fetch 받은 데이터를 이용하여 아이디 중복체크검사 적용</li>
<li>카카오 POST API를 사용하여 주소창 구현</li>
</ul>
<h3 id="메인페이지">메인페이지</h3>
<ul>
<li>배너 자동 무한 슬라이더 구현</li>
<li>캐러셀 기능 추가</li>
<li>Advanced Router를 통해 카테고리 변경 (Query Parameter 사용)</li>
</ul>
<h3 id="상세페이지-제품요리레시피">상세페이지 (제품,요리레시피)</h3>
<ul>
<li>상세정보를 fetch메소드로 전달받아 상세페이지 구현</li>
<li>동적 라우팅 (Path Parameter 사용) 으로 리스트페이지와 연결</li>
</ul>
<h3 id="장바구니">장바구니</h3>
<ul>
<li>map 함수와 spread-operator를 사용, 상품 데이터의 수량 변경 기능 구현</li>
<li>spread-operator와 map, filter, Array메소드를 적절히 사용하여 물품 선택, 삭제 구현</li>
<li>filter를 사용하여 백엔드에 보낼 삭제된 물품 데이터와 view에 비출 남은 물품들의 데이터를 분류</li>
</ul>
<h3 id="배송지페이지">배송지페이지</h3>
<ul>
<li>유저의 주소정보를 fetch 받아 기본배송지 구현</li>
</ul>
<h3 id="결제페이지">결제페이지</h3>
<ul>
<li>장바구니로 부터 location.state로 데이터를 전달받아 구매 목록 구현</li>
<li>구매자의 배송지 와 총 구매가격을 구매자에게 알려주는 UI구현</li>
</ul>
<h2 id="reference">Reference</h2>
<ul>
<li>이 프로젝트는 <a href="https://www.oasis.co.kr/main">오아시스 마켓</a> 사이트를 참조하여 학습목적으로 만들었습니다.</li>
<li>실무수준의 프로젝트이지만 학습용으로 만들었기 때문에 이 코드를 활용하여 이득을 취하거나 무단 배포할 경우 법적으로 문제될 수 있습니다.</li>
<li>이 프로젝트에서 사용하고 있는 사진 대부분은 위코드에서 구매한 것이므로 해당 프로젝트 외부인이 사용할 수 없습니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn..."프로젝트 1주차 회고"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-1%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-1%EC%A3%BC%EC%B0%A8-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Sun, 13 Jun 2021 15:15:49 GMT</pubDate>
            <description><![CDATA[<p>우선, 현재 프로젝트중이기도 하고, 새로운 기술을 익혔다기보단 실제로 프로젝트를 진행함에 있어서 배웠던 것들을 정리해보고자 한다.</p>
<h1 id="어떤-프로젝트인가">어떤 프로젝트인가?</h1>
<p>지금 진행하고 있는 프로젝트는 기본적으로 클론 프로젝트이고, <a href="https://www.oasis.co.kr/main">오아시스마켓</a>이란 사이트를 클론하는 프로젝트이다.</p>
<p>이번 한주동안 맡은 일은 홈페이지의 <code>header</code>와 <code>footer</code>의 제작, 상품 상세페이지와 장바구니 페이지의 구현을 맡았다.</p>
<h2 id="지금까지와-다른-점은-무엇인가">지금까지와 다른 점은 무엇인가?</h2>
<p>지금까지 진행했던 것과는 다른 점이라 하면, 아무래도 백엔드의 존재가 가장 클것이다.
혼자 진행하거나, 프론트엔드끼리 모여서 했던 과제는 몇번인가 진행하였지만,
백엔드와 함께 팀을 짜서 진행한것은 이번이 처음이기 때문이다.</p>
<p>가장 크게 느꼈던 것은, 첫번째는 스케일의 차이이다.</p>
<p>사람도 많아졌기 때문에, 정해진 시간이 같더라도 한두 페이지에 그쳤었다면, 이번 프로젝트에선 꽤 많은 페이지를 담당하고, 또 완성하는 흐름이 되었다.</p>
<p>또한, 단순히 내가 쓸 데이터라면서 나 혼자 납득하고 만든 mock 데이터도, 백엔드와 함께 이야기 하면서 백엔드에 어떻게 데이터를 요청 해야하고, 백엔드가 선호하는 방식등에서도 알게 되었다.</p>
<p>두번째는 내가 모르는 영역에 대해 이해하려 하고, 또 상대방이 모르는 영역을 설명 하는것이다.</p>
<p>지금까지 배운 내용들은 아무래도 프론트엔드와 관련된 내용이고, 어디까지나 웹페이지의 view를 중점적으로 생각하며 구성해왔다.</p>
<p>같은 팀이나 주변 사람들과 이야기 해도, 같이 수업을 듣는 사람들이기에 단어, 개념등에서도 이미 공유가 되어 있는 경우가 많았다.</p>
<p>하지만 백엔드의 개념을 배우지는 않았기 때문에, 백엔드에서 어떻게 데이터를 처리 하는지, 어떻게 프론트로 보내는것을 선호하는지, 데이터 모델링과 테이블은 무엇인지에 대해 잘 알지 못하였다.</p>
<p>물론 백엔드도 내가 말하는 리액트의 구동 방식과 규칙, 컴포넌트와 state등은 알지 못할것이다.</p>
<p>여기서 이해의 차이가 나기에, 함께 프로젝트를 진행하기 위해서 서로가 모르는것에 대해 더 알기 쉽게 설명하기 위해 더욱 많은 궁리를 하게 되었다.</p>
<h2 id="다르게-중요하게-느낀것은-무엇인가">다르게 중요하게 느낀것은 무엇인가?</h2>
<p>함께 일한다는것은 서로의 기술적인면만 만족해서는 안된다.
대화 하는 방식과 각종 협업을 위한 툴들을 사용하여 시간을 보다 효율적으로 사용 해야 하는것이다.</p>
<p>먼저, 이번 프로젝트를 계기로 다양한 커뮤니티 툴을 사용하게 되었다.
trello, notion, slack, github등 여러가지 툴을 이용해 커뮤니케이션을 하게 되었고, 어떤 툴을 언제 써야하는지도 이제 조금씩 감이 잡히기 시작 하였다.</p>
<p>두번째는 회의이다.
평소에 회의를 그다지 좋아하지 않았지만, 그래도 역시 서로의 의견을 교환하는데엔 회의만한것이 없다고 느꼈다.
서로가 예민한 상태여도 사용하는 말에 조심하고, 행동등을 신경 써야 하는것을 다시 한번 느꼈다.
이 부분은 우리 팀의 멤버들에게 정말 감사하고 있다.
모두가 좋은 사람들이라 1주일동안 효율적으로 작업을 진행 할 수 있었다.</p>
<p>개인적으로 느낀 세번째는 메모의 중요성이다.
초반엔 회의때 메모를 하지 않고 그냥 들었으나, 시간이 지나고 바쁜 상황이 되었을때 회의때 했던 이야기를 기억 하지 못하는 상황이 생겼다.
좋지 않은 상황인것을 깨닿고, 현재는 메모를 하면서 내가 해야 하는것, 중요한 사항들을 기록하면서 회의에 임하는 습관이 생기기 시작하였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn..."데이터의 filtering"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%9D%98-filtering</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%9D%98-filtering</guid>
            <pubDate>Sun, 06 Jun 2021 15:19:03 GMT</pubDate>
            <description><![CDATA[<p>리액트나 자바스크립트가 아니더라도, 데이터를 사용하게 되면 필연적으로 필요한 데이터와 필요 없는 데이터를 걸러야 할 일이 생긴다.</p>
<p>모든 데이터를 다 로드해도, 거기서 필요한 데이터만을 추리기도 하고, 100중에 1이 필요하다고 100을 다 로드 할 수 도 없는 노릇이니 말이다.</p>
<p>아마 array에 대한 포스팅에서도 한번 있었다고 생각하지만, 다시한번 점검한다는 생각으로 <code>Array.filter()</code>에 대해 다뤄보려고 한다.</p>
<h1 id="arrayfilter">Array.filter()</h1>
<p><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">MDN</a>을 먼저 확인해보자.</p>
<blockquote>
<p>filter() 메서드는 주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환합니다.</p>
</blockquote>
<p><code>filter</code>라는 말 처럼 하나의 컨디션을 걸고, 거기에 통과하는것들로만 모아서 새로운 배열을 만드는 메서드이다.</p>
<p>보통 이 <code>filter</code>는 자바스크립트에서도 많이 사용 되지만, 리액트에서도 자주 사용된다.</p>
<p>최근 풀었던 문제중에는 이 <code>filter</code>를 응용한 문제도 있었다.</p>
<h2 id="어떤-기능이었나">어떤 기능이었나?</h2>
<p>예를 들면, 받은 데이터를 state에 저장하고, 만약 어떠한 값이 바뀌었다면, 그 값에 맞춰서 통과하는것만 표시하는 기능이다.</p>
<p>그렇다. 바로 검색기능이다.</p>
<p>여태까지 filter에 관한 기능은 몇번 구현 했었기에, 해당 메서드를 구성하는것 자체는 어렵지 않았지만, 문제는 타이밍이었다.</p>
<p>내가 생각했던 타이밍은 크게 나눠서, 처음 데이터가 fetch 되고 state에 저장 된 다음, 키 입력이 발생 했을때에 맞춰서 컨디션에 맞는 데이터가 입력 되게 하였으나,</p>
<p>키 입력이 발생하고 setState가 비동기로 처리 되는터라 타이밍을 맞추지 못하였다.
리턴문 안에서 사용했을때도 마찬가지로 잘 되지 않았고, 구글링등으로 찾아낸 해법은 바로,
render함수 안에 변수를 선언해서, 그 변수에 filter로 거른 데이터를 담은 다음, state가 아닌, 그 변수를 기준으로 컴포넌트가 렌더링 되게 만드는 방법이었다.</p>
<p>setState의 영향도 받지 않아서 반응도 훨씬 빠른 느낌이었다.</p>
<p>다만 걸리는것은, 구글링을 하다가 비슷한 내용의 소스코드를 봐버렸기에, 혼자 해결한 느낌이 들지 않는다는것이었다.</p>
<p>그리고, 과연 내가 혼자 생각했을때, 이 발상이 생각 났을까 하는 생각도 들었다.
해결 된것은 좋지만 내 힘으로 푼게 아닌것 같아서 풀고 나서도 기분이 미묘한 문제였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn..."Spread Operator"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...Spread-Operator</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...Spread-Operator</guid>
            <pubDate>Sun, 06 Jun 2021 14:46:33 GMT</pubDate>
            <description><![CDATA[<p>최근 프로젝트를 하면서 어려운 문제가 있었기에, 해결 하느라 포스팅이 뜸했다.
이번 포스팅부터는 프로젝트를 해결하면서 어려웠던 점이나, 알면서 잘 사용하지 못했던 요소들을 다룰 예정이다.</p>
<p>우선 먼저, Spread Operator(전개구문)부터 시작하겠다.</p>
<h1 id="spread-operator">Spread Operator</h1>
<p>전개구문은 아마, 자바스크립트를 위주로 공부하다가, 리액트로 넘어오게 되면 좀 생소한 개념이 될 수 있다고 생각한다.</p>
<p>자바스크립트를 깊게 공부한 사람이면 다르겠지만, 시작한지 얼마 되지 않아 심도 있는 공부 보다는 주로 사용하는, 사용 되는 기능만을 익혀온 사람에게는 꽤나 생소하게 다가 올 것이다.</p>
<p>핵심만 전달하면, array와 object등의 구조를 깨고, 안의 아이템만을 가져 오는것이다.</p>
<p>간단하게 예를 들어보자면,</p>
<pre><code class="language-js">const arr1 = [&#39;mon&#39;,&#39;tue&#39;,&#39;wed&#39;];
const arr2 = [&#39;thr&#39;, &#39;fri&#39;, &#39;sat&#39;];
const newArr1 = [...arr1];
const newArr2 = [...arr2];

console.log(...newArr1,...newArr2); // &#39;mon&#39; &#39;tue&#39; &#39;wed&#39; &#39;thr&#39; &#39;fri&#39; &#39;sat&#39; 출력</code></pre>
<p>과 같이 들 수 있는데, 이처럼 각 배열의 아이템만들 가지고 오고 싶을때도 사용되고,
다음과 같이 사용 할 수도 있다.</p>
<pre><code class="language-js">console.log([...newArr1,...newArr2]); // [ &#39;mon&#39;, &#39;tue&#39;, &#39;wed&#39;, &#39;thr&#39;, &#39;fri&#39;, &#39;sat&#39; ] 출력</code></pre>
<p>처럼 새로운 배열을 만들 수도 있고,</p>
<pre><code class="language-js">console.log([...newArr1,...newArr2].concat(&#39;sun&#39;));
console.log([...newArr1,...newArr2,&#39;sun&#39;]);
// 둘다 [&#39;mon&#39;, &#39;tue&#39;,&#39;wed&#39;, &#39;thr&#39;,&#39;fri&#39;, &#39;sat&#39;,&#39;sun&#39;] 출력</code></pre>
<p>처럼 배열에 새로운 값을 더해서 출력하는것도 가능하다.</p>
<p>물론 object에서도 새로운 요소의 추가등에 사용 할 수 있다.</p>
<pre><code class="language-js">const obj1 = {a: 1, b: 2, c : 3};

const objClone = {...obj1,z: 1};

console.log(objClone) // { a: 1, b: 2, c: 3, z: 1 }</code></pre>
<p>와 같이 나타낼 수 있다.</p>
<h2 id="어떤-문제였나">어떤 문제였나?</h2>
<p>문제가 발생한 곳은 <strong>기존에 나눠서 <code>state</code>를 관리하다가 모든 <code>state</code>를 최상위 컴포넌트로 끌어올리면서 각각의 데이터에 어떻게 접근해서 데이터를 변경하는가</strong> 였다.</p>
<p>코드중 일부를 가져와 보자면,</p>
<pre><code class="language-js">addComment = feedId =&gt; {
    const { userData, defaultInput } = this.state;
    const newComment = {
      id: userData[feedId - 1].comments.length + 1,
      userName: &#39;asdf&#39;,
      text: defaultInput[feedId - 1],
      isLiked: false,
    };
    const newFeedData = userData.map((feeds, index) =&gt; {
      return feedId !== index + 1
        ? feeds
        : { ...feeds, comments: feeds.comments.concat(newComment) };
    });</code></pre>
<p>와 같은 코드이다.</p>
<p>아래 컴포넌트에서 props로 값을 받아오고, state의 값에따라 text에 저장해서, 댓글을 추가하는 로직의 일부이다.</p>
<p>이중 Spread Opretor가 적용된 부분을 보면, </p>
<pre><code class="language-js">    const newFeedData = userData.map((feeds, index) =&gt; {
      return feedId !== index + 1
        ? feeds
        : { ...feeds, comments: feeds.comments.concat(newComment) };
    });</code></pre>
<blockquote>
<p>여기서 userData는 [ { O,O,O,[o,o,o] }, { O,O,O,[o,o,o] }, { O,O,O,[o,o,o] } ] 와 같은 구조를 가지고 있는 json 데이터를 복사한 값을 state로 가지고 있는 데이터이다.</p>
</blockquote>
<p>흐름을 해설하자면 처음 userData에 map()을 사용해 각각의 item과 index를 얻는다.
이때 얻은 값은 3개의 object이고, 이중 feedId와 index+1이 맞지 않으면 그대로 두지만, 값이 일치 한다면 안의 값을 바꾸는 로직이다.</p>
<p>지금은 이것저것 복잡하게 보이지만, 간단하게 바꾸면</p>
<pre><code class="language-js">const obj1 = {x: &#39;hello&#39;, y: &#39;goodbye&#39;}
const obj2 = {y: &#39;world&#39;}
const changed = { ...obj1, y: obj2.y };

console.log(changed); // { x: &#39;hello&#39;, y: &#39;world&#39; }</code></pre>
<p>이렇게도 간단히 나타 낼 수 있는 로직이다.
다만 데이터의 깊이가 한번에 접근하기 힘든 위치이고, 아직까지 다뤄보지 않은 사용법이라 더 어렵게 느껴졌던것 같다.</p>
<p>다만 이 로직이 처음엔 생각 나지 않았고, 멘토님에게 질문 하고 나서 알게 되었다.
그마저도 블로그를 작성하며 완전히 이해가 가는 느낌이었다.</p>
<p>리액트를 다루면서 바닐라 자바스크립트와 비교해서 가장 큰 차이점은 아마도 이런 배열이나 obj를 다루는 빈도와 심도가 점점 늘어가는것이 아닐까 하는 생각이 들었다.</p>
<p>앞으로 비슷한 문제가 나오면 해결 할 수 있을것 같은 느낌이 든다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn..."State&props"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...Stateprops</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...Stateprops</guid>
            <pubDate>Sun, 30 May 2021 16:11:59 GMT</pubDate>
            <description><![CDATA[<h1 id="state-props">State, Props</h1>
<h2 id="state">State</h2>
<p>React에서 가장 중요한것이라고 하면, 아마 state와 props일것이다.
그중, 먼저 state에 대해 알아보도록 하자.</p>
<p>state는 일반적으로, Class Component에 존재한다.(<em><del>Hook을 사용하면 함수형에서도 state를 사용 할 수 있지만 그건 다음에..</del></em>)</p>
<p>State는 단어의 뜻대로 <strong>상태값</strong>이라는 의미를 가지고 있고, 이 상태값은 바로 state가 있는 클래스 컴포넌트가 자체적으로 가지고 있는 값이라는 의미이다.</p>
<p>오히려 더 헷갈릴 수 있는 설명이기에 더 풀어서 설명하자면,</p>
<blockquote>
<p>Component는 UI를 그리기 위한 구성단위이고, State는 UI를 그리기 위한 정보를 담고 있는 정보(Object)</p>
</blockquote>
<p>라고 할 수 있을것이다.</p>
<p>기본적으로 Object의 형태를 하고 있고, 각 컴포넌트에서 어떤 데이터를 나타낼것인지를 기록하는 것이 state인것이다.</p>
<p><strong>물론 이는 고정값이 아니며, 메서드를 통해 재정의 할 수 있다.</strong></p>
<h3 id="state의-사용">State의 사용</h3>
<pre><code class="language-js">import React from &#39;react&#39;;

class State extends React.Component {
  constructor() {
    super();
    this.state = {
      color: &#39;red&#39;
    };
  }

  render() {
    return (
      &lt;div&gt;
        &lt;h1&gt;Class Component | State&lt;/h1&gt;
      &lt;/div&gt;
    );
  }
}

export default State;</code></pre>
<p>위의 코드 예시로 state가 어디에 정의 되는지 알 수 있을것이다.</p>
<p><code>return</code>은 <code>JSX</code>를 반환시키고, state는 <code>render</code>가 실행 되기 전에 선언을 해두는 방식이다.
이렇게 해야, 컴포넌트가 렌더링 될때, <code>constructor</code>가 호출 되는 동시에 <code>state</code>가 선언 되고, 여기에 저장 된 <code>state</code>의 값을 가지고 <code>render</code>메서드가 컴포넌트를 렌더링 하는 흐름이 완성 되기 때문이다.
때문에, 당연하겠지만 처음에 선언 되는 state는 <code>default</code>값이 되는것이다.</p>
<h4 id="state를-변경하려면">State를 변경하려면?</h4>
<p>당연한 이야기이겠지만, state를 선언 해 둔 값에서 변경이 불가능하다면, 큰 의미를 가지지 못했을것이다.
우리가 원하는것은 여러가지 데이터를 입력했을때, 각각의 데이터를 담아낼 프레임이지, 하나의 값만 가지는 고정형 부품이 아니기 때문이다.</p>
<p>물론, state의 값은 앞서 말한 것 처럼 변화 시킬 수 있는 값이다.
다만, 일반적인 방법을 사용해서는 변화를 반영 시킬 수 없다.</p>
<p><strong>변화를 반영 시킬 수 없다</strong> 라고 한것은, state값은 변해도, 그 값이 반영 되지 않는다는 이야</p>
<p>만약 <code>constructor</code>에서 한번 선언한 state를 다른 메서드에서</p>
<pre><code class="language-js">changeColor = () =&gt; {
  this.state = {
  color : &#39;blue&#39;;
}
}</code></pre>
<p>처럼 직접 변화시켜도, state값은 변할 지언정 렌더링 된 컴포넌트의 색은 변하지 않는다.</p>
<p>그러면 어떻게 해야할까?
react에는 이를 위해, state를 변화 시키는 메서드를 내장하고 있다.
그것이 바로 <code>setState</code>이다.</p>
<p><code>setState</code>메서드를 사용하는 방법은</p>
<pre><code class="language-js">changeColor = () =&gt; {
  this.setState({
    color : &#39;blue&#39;;
  })
}</code></pre>
<p>와 같이, <code>setState</code>의 인자로 바꿀 state의 key와 value를 전달해서 state를 바꾼다.</p>
<p>여기서 <code>setState</code>와 직접 지정하는것의 차이가 발생하는데, <code>setState</code>는 <code>render</code>메서드를 호출 해서, 다시 렌더링 한다는 차이점이 있다.</p>
<p>즉, 바뀐 state를 가지고 다시 해당 컴포넌트를 업데이트 한다는것이다.</p>
<p>여기서 하나 의문점이 생기는데,</p>
<blockquote>
<p>그렇다면, <code>render</code>도 메서드이니, 직접 state를 변경하고 <code>render</code>를 호출하면 컴포넌트가 업데이트 될까?</p>
</blockquote>
<p>하는 점이었다.</p>
<p>결과적으론 다시 렌더링 되지 않았고, 아마 setState에는 다른 로직이 있을것이라 생각했다.</p>
<h2 id="props">Props</h2>
<p>props는 properties의 약자로, 속성이라는 뜻의 영단어를 축약한 키워드이다.
props는 다른 컴포넌트가 없고, 하나의 컴포넌트만 있다면 사용할 필요가 없다.</p>
<p>하지만, 다른 컴포넌트가 있고, 컴포넌트간 데이터전달이 필요할 경우 사용된다.</p>
<p>props도 물론 object의 형식을 따르고, 전달 되는 값으로 여러가지를 넣을 수 있지만,
함수를 전달 할 수도 있다.</p>
<p>부모 컴포넌트에서 이벤트를 할당하고, 그걸 자식컴포넌트에서 사용할때, props가 사용 되는것이다.</p>
<p>부모에서 자식 컴포넌트에게 어떻게 값을 전하는지 코드로 확인해보자.</p>
<pre><code class="language-js">// Parent.js

import React from &#39;react&#39;;
import Child from &#39;../pages/Children/Children&#39;;

class Parent extends React.Component {
  constructor() {
    super();
    this.state = {
      color: &#39;red&#39;
    };
  }

  handleColor = () =&gt; {
    this.setState({
      color: &#39;blue&#39;
    })
  }

  render() {
    return (
      &lt;div&gt;
        &lt;h1&gt;Parent Component&lt;/h1&gt;
    &lt;Child titleColor={this.state.color} changeColor={this.handleColor}/&gt;
      &lt;/div&gt;
    );
  }
}

export default State;</code></pre>
<p>여기까지가 부모 컴포넌트,</p>
<pre><code class="language-js">// Child.js

import React from &#39;react&#39;;

class Child extends React.Component {
  render() {
    // console.log(this.props);

    return (
      &lt;div&gt;
        &lt;h1 style={{color : this.props.titleColor}}&gt;Child Component&lt;/h1&gt;
    &lt;button onClick={this.props.changeColor}&gt;Click&lt;/button&gt;
      &lt;/div&gt;
    );
  }
}

export default State;</code></pre>
<p>여기까지가 자식 컴포넌트라 할때,
부모 컴포넌트에선 state를 바꾸는 메서드로서 <code>handleColor</code>를 선언했다.
그리고, 이를 자식컴포넌트에 속성(properties)으로서 전달했다.(<code>&lt;Child titleColor={this.state.color} changeColor={this.handleColor}/&gt;</code>)
자식 컴포넌트에 와서, 이 props를 받게 되는데,
현재 전달 된 props에는 두가지가 있다.
하나는 자식 컴포넌트의 색을 state에 따라 바꾸는 <code>titleColor={this.state.color}</code>와, 메서드로서 정의한 <code>changeColor={this.handleColor}</code> 두가지의 props이다.</p>
<p>이를 자식 컴포넌트에서 사용 할땐, 위의 코드와 같이 this.props.Name(Name은 props의 이름)으로 해당 props를 사용할 수 있다.
이때, props를 한번만 사용 할 수 있는것은 아니며, 해당 값이 필요한곳에 넣을 수 있다.</p>
<h2 id="주의사항">주의사항</h2>
<p>이처럼 react는 state를 이용해 data를 UI에 담기는 정보로서 사용하고, 다른 컴포넌트에 props라는것을 사용해서 전달 할 수 있다.</p>
<p>하지만 유의해야 할 것은, react의 데이터 전달 방향은 위에서 아래, 즉 부모에서 자식으로만 흐른다.</p>
<p>풀어서 설명하자면, 부모는 자식에게 자신의 state를 props로서 전달 할 수 있지만, 자식은 자신의 state를 부모에게 값으로서 전달 할 수 없다.</p>
<p>이럴땐, state를 보다 상위 컴포넌트에 선언을 해두고, 그 값을 props로 전달 받을 필요가 있다.</p>
<p>물론 그렇게 되면 그 하위에 있는 컴포넌트들에게 모두 props를 전달 해야 하는 단점이 생긴다.
그리고 그걸 위해서, 상태관리가 필요해지는것이다.
이는 추후에 다시 다루도록 하겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn..."Component&JSX"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...ComponentJSX</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...ComponentJSX</guid>
            <pubDate>Tue, 25 May 2021 15:48:54 GMT</pubDate>
            <description><![CDATA[<h1 id="componentjsx">Component&amp;JSX</h1>
<h2 id="react에서-component란">React에서 Component란?</h2>
<p>Component(구성요소, 부품)은 react에서,<strong>재사용 가능한 UI단위</strong>를 뜻한다. 이름 그대로 풀이하여, 부품처럼 이곳 저곳 필요한곳에 사용 할 수 있는것이다.</p>
<p>컴포넌트의 특징으로는</p>
<ul>
<li><p>재사용 할 수 있다.</p>
</li>
<li><p>코드의 유지보수가 용이하다.</p>
</li>
<li><p>해당 페이지가 어떻게 구성 되어 있는지 알기 쉽다.</p>
</li>
<li><p>한 컴포넌트는 다른 컴포넌트를 포함할 수 있다.</p>
<p>가 있다.</p>
<h2 id="컴포넌트의-종류">컴포넌트의 종류</h2>
<p>컴포넌트에는 크게 두가지 종류가 있는데,</p>
</li>
<li><p>Class Component</p>
</li>
<li><p>Functional Component</p>
<p>로, Class Component는 Class로서 선언되어 사용 되는 컴포넌트로, </p>
<h3 id="class-component">Class Component</h3>
</li>
</ul>
<pre><code class="language-js">import React from &#39;react&#39;

class Component extends React.Component {
  render() {
    return (
    &lt;div&gt;
      &lt;h1&gt;This is Class Component!&lt;/h1&gt;
    &lt;/div&gt;
    )
  }
}

export default Component</code></pre>
<p>처럼 나타낸다.</p>
<p>컴포넌트를 처음 선언하기 위해서는, CRA로 리액트를 실행하고, js파일에 리액트를 import시킨다.</p>
<p><strong>이때, 컴포넌트가 될 Class 혹은 Function은 camelCase를 지키되, 첫 문자는 대문자로 시작한다.</strong></p>
<p>가장 큰 특징으로는 Class를 선언하고, 반드시 <code>render()</code>메서드를 포함해야 한다는것이다.
또한, <code>render()</code>메서드는 html처럼 생긴 <code>JSX</code>를 <code>return</code>한다.</p>
<p>마지막으로, <code>export default</code>를 사용해서, 다른 컴포넌트에서 이 컴포넌트를 사용할 수 있게 만든다.</p>
<h3 id="functional-component">Functional Component</h3>
<pre><code class="language-js">import React from &#39;react&#39;

const Component = () =&gt; {
  return (
    &lt;div&gt;
      &lt;h1&gt;This is Functional Component!&lt;/h1&gt;
    &lt;/div&gt;
  )
};

export default Component</code></pre>
<p>Functioal Component는 Class Component와 다르게 함수로서 선언된다.
전반적인 흐름은 Class Component와 같으나, Functional Component는 <code>render()</code>메서드를 사용하지 않고, 바로 <code>JSX</code>를 <code>return</code>한다는 특징이 있다.</p>
<p>이때문에 함수형 컴포넌트는 클래스 컴포넌트에 비해서 작성하기 쉽고, 간단한 장점이 있다.</p>
<p>하지만, 함수형 컴포넌트는 추후에 다룰 <code>state</code>를 갖지 않음으로, lifecycle메서드를 다룰 수 없다는 단점이 있다.
이는 추후에 포스팅으로 다루도록 하겠다.
<em><del>현재는 Hook의 존재로 함수형 컴포넌트도 <code>state</code>를 사용 할 수 있다.</del></em></p>
<h2 id="jsx">JSX</h2>
<p>위에서 클래스 컴포넌트와 함수형 컴포넌트의 공통점은, <code>JSX</code>를 반환하는 것이라 하였다.
이 <code>JSX</code>는 무엇일까?</p>
<p><code>JSX</code>에 대해 알아보자</p>
<h3 id="jsx의-정의">JSX의 정의</h3>
<p><code>JSX(JavaScript Syntax Extension)</code>는 자바스크립트의 확장 문법이라는 의미를 가지고 있는 요소이고,
오직 리액트에서만 사용 되는 문법이다.</p>
<p><code>JSX</code>는 html처럼 생겼지만, html도, JavaScript도 아니다.
때문에 브라우저가 바로 <code>JSX</code>를 알아 들을 수 없기 때문에, <code>Babel</code>을 이용하여 일반 자바스크립트 문법으로 컴파일 하여 사용하게 된다.</p>
<h3 id="jsx의-장점">JSX의 장점</h3>
<p><code>JSX</code>는 html과 비슷하기때문에, 보기 쉽고 익숙하다는 장점이 있다.
또한, 자바스크립트 안에서 사용되므로, html과 자바스크립트를 이용하여 동시에 사용하는것이 가능하다. 이 예로는 DOM과 event의 핸들링이 있다.</p>
<h3 id="jsx의-사용">JSX의 사용</h3>
<p><code>JSX</code>는 일반 자바스크립트가 아니기 때문에, <code>JSX</code>를 사용하면서 자바스크립트를 사용하기 위해선 좀 특별한 사용법이 필요하다.</p>
<pre><code class="language-js">const name = &quot;World&quot;;

&lt;h1&gt;Hello {name}!&lt;/h1&gt;</code></pre>
<p>와 같이, 자바스크립트를 사용할땐 <code>{}</code>안에 선언하여 사용해야 한다.</p>
<p>두번째로는, html과 다르게 <code>JSX</code>는 <code>class</code>를 사용하지 않는다.
그 이유는 자바스크립트가 가지는 <code>class</code>와 겹치기 때문이다. 같은 이유로 <code>label</code>의 <code>for</code>도 반복문과 키워드가 겹치기 때문에, 각각 <code>className</code>과 <code>htmlFor</code>로 사용한다.</p>
<p><code>JSX</code>에서 인라인으로 스타일링을 하려면,</p>
<pre><code class="language-js">&lt;div style={{color : &quot;red&quot;}}&gt;Hello React&lt;/div&gt;</code></pre>
<p>과 같이, <code>{{}}</code>를 사용하여 스타일을 선언하게 된다.</p>
<p>다음으로, <code>JSX</code>는 모든 태그가 Self Closing이 가능하며, 모든 태그는 마지막이 닫혀 있어야 한다.
<code>&lt;div /&gt;</code>와 같이 html에선 불가능 했던 태그 사용이 가능한것이다.</p>
<p>마지막으로, <code>return</code>되는 <code>JSX</code>의 최상위 요소는, 항상 <strong>형제가 없는 하나의 요소</strong>여야 한다.
때문에 등장한 개념이 바로 <code>Fragment</code>라는 개념인데,</p>
<pre><code class="language-js">&lt;&gt;
  &lt;div /&gt;
  &lt;div /&gt;
  &lt;div /&gt;
&lt;/&gt;</code></pre>
<p>처럼, <code>&lt;&gt;</code> <code>&lt;/&gt;</code>두개의 빈 태그로 감싸서, 형제가 없는 요소로 <code>return</code>해야 한다.</p>
<p>다른 특징으로는, DOM엘리먼트를 지정할 필요가 없기 때문에, <code>addEventlistener</code>보다는 해당 요소의 속성에 <code>onEvent</code>를 사용하게 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn..."React"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...React</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...React</guid>
            <pubDate>Mon, 24 May 2021 15:42:10 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/mong-byte/post/f94be79d-d810-4117-9367-79419468ca7c/react.jpg" alt=""></p>
<p>오늘은 프론트엔드 라이브러리인 <strong>React</strong>에 대해 포스팅하려 한다.</p>
<h1 id="react는-무엇인가">React는 무엇인가?</h1>
<p>React(리액트)에 대해서 알아 보기전에, 리액트가 어떤 배경에서 탄생하게 되었는지 먼저 이야기 해 보려고 한다.</p>
<p>이야기를 좀 거슬러 올라가서, 1세대 웹인 HTML과 CSS, 2세대 웹인 JavaScript를 거쳐 3세대 웹이 되었을때, 프론트엔드와 백엔드가 나눠졌다 한다.</p>
<p>이렇게 나눠지게 된 배경에는, 웹페이지를 담당하는 부분과 서버(데이터)를 담당하는 부분이 점점 다뤄야 할 정보가 많아지고, 복잡해졌으며, 보다 전문적인 방향으로 발전이 이뤄졌기 때문이라 생각한다.</p>
<p>html과 css 그리고 vanila javascript를 사용했으면 알겠지만, 요소 하나하나마다 각각의 이벤트를 만들어 처리하거나, 요소를 직접 추가 해야하는 번거로움이 있다.
또한, 페이지가 담고 있는 정보가 많아질수록, 기하급수적으로 늘어나는 html도 효율적인 구조는 아니다.</p>
<p>이런 비효율적인 처리를 해결하기 위해 frame work와 library가 생겼는데, 대표적인 frame work가 바로 <code>Angular</code>, library에는 <code>React.js</code>와 <code>Vue.js</code>가 있다.</p>
<p>frame work와 library의 차이는 <strong>주도권이 어디에 있느냐</strong>에 있으며, <img src="https://images.velog.io/images/mong-byte/post/5dab67c0-ea48-4352-98b2-e7e953ff6345/framework_library%20(1).png" alt=""></p>
<p>사용자가 정해진 틀(frame)에서 작업한다면 frmae work,사용자가 직접 책을 꺼내듯 호출해서(library) 사용한다면 library라 한다.</p>
<p>리액트는 다른 둘과 다르게, <a href="https://developer.mozilla.org/ko/docs/Glossary/MVC">MVC모델</a> 중에서 오직 V(view)만들 담당한다.
즉, 우리 눈에 보이는 부분만 담당하는것이다.</p>
<p>이때, 하나의 html에 javascript를 이용해서 페이지를 그려내고, 그걸 내부에서 바꿔가며 컨텐츠를 표시하기에, 하나의 html을 사용한다 해서 SPA(Single Page Application)이라 한다.</p>
<p>리액트는 페이스북의 지속적인 관리 덕분에 다양한 자료를 찾을 수 있는 커뮤니티가 활성화 되어 있으며, 지금도 많은 유저가 리액트를 찾고 있다.</p>
<h2 id="react는-무슨-일을-하는가">React는 무슨 일을 하는가</h2>
<p>앞서 리액트는 눈에 보이는 view, 다른 말로 사용자 인터페이스(UI)를 만들기 위한 툴이라 하였다.</p>
<p>리액트등 프레임워크나 라이브러리를 이용하는 이유는 이 UI의 상태가 바뀌었을때, 자동으로 업데이트를 하는 점일 것이다.</p>
<p>리액트는 Virtual DOM을 이용해서 UI를 빠르게 업데이트 하는데, 이전 상태의 UI를 기억하고, 비교해서 바뀐 부분만 업데이트 한다는 특징이 있다.
때문에 꼭 필요한 곳만 효율적으로 업데이트 하는것이 가능한것이다.</p>
<h2 id="어떻게-react를-사용하는가">어떻게 React를 사용하는가?</h2>
<p>리액트를 사용하려면 우선 Node.js를 설치해야 한다.
Node.js는 원래 브라우저 기반으로 작동하는 자바스크립트를 웹이 아닌 터미널 등에서도 작동하게 만드는 런타임 환경으로서, 리액트등 프론트엔드 라이브러리, 프레임워크는 이 Node.js를 기반으로 만들어져 있다.</p>
<p>이때 함께 설치 되는것이 <a href="https://www.npmjs.com/">NPM(Node Package Manager)</a>이다.</p>
<p>우리는 앞으로 이 NPM을 사용해서 다양한 패키지를 설치, 사용할것이기에, 사용법을 익혀 놓는것이 좋을 것이다.</p>
<h3 id="cra는-무엇인가">CRA는 무엇인가?</h3>
<p>CRA는 <code>create-react-app</code>의 약자로서, 리액트를 설치해서 여러가지 초기세팅을 하기 위한 패키지를 이야기한다.</p>
<p>Node.js와 NPM이 설치 된 상태에서 터미널을 열고 원하는 디렉터리로 이동한 다음,</p>
<blockquote>
<p><code>npm install create-react-app name</code></p>
</blockquote>
<p>을 입력하고 엔터를 누르면 자동으로 설치가 시작된다.</p>
<p>설치를 하고 나면, 여러가지 파일들과 함께 <img src="https://images.velog.io/images/mong-byte/post/2cbe5f56-bbff-4550-81dc-bf95759175ea/app-page.cfe4dfdb.png" alt=""></p>
<p>위와 같은 화면이 나타나게 된다.</p>
<p>이후의 기초세팅은 다음 포스팅에서 알아보도록 하자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn... "HTMLcollection"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...-HTMLcollection</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...-HTMLcollection</guid>
            <pubDate>Fri, 21 May 2021 17:01:41 GMT</pubDate>
            <description><![CDATA[<p>오늘은 htmlcollection에 대해 포스팅 해보려 한다.</p>
<h1 id="htmlcollection이란">HTMLcollection이란?</h1>
<p>htmlCollection은 자바스크립트를 사용하면서 html요소를 리턴 받을때 볼 수 있는 유사배열이다.</p>
<p>사실 이 htmlCollection은 복수의 요소를 리턴 받을때 발생하는데, 리턴 받은 html요소가 하나일 경우, htmlElement라 부르게 된다. 보통 querySelector, getElementById 혹은 ClassName으로 html을 지정하고, <code>console.log()</code>를 사용 할 경우 볼 수 있다.</p>
<p><img src="https://images.velog.io/images/mong-byte/post/2d2b1603-48c8-4191-8262-5e51f6f9756a/90b22988277255982407264eb20a49de.png" alt=""></p>
<h2 id="어떻게-사용하는가">어떻게 사용하는가?</h2>
<p>htmlCollection은 유사배열이기에, 배열에서 사용 되는 method를 사용할 수 없다.
때문에 처음 htmlCollection을 접하면 난감할 수 있다.</p>
<p>하지만 htmlCollection은 생각보다 유용하게 쓰인다.
보통 index를 지정하지 않고 getElementClassName을 사용해서 해당 className을 가지는 요소를 전부 collection으로 받고, 특정한 메서드를 사용해서 가공을 한다.</p>
<p>이때 사용 되는 메서드가 바로 <code>Array.from</code>이다.
htmlCollection은 index를 가지고 있고, <code>length</code>속성을 가지고 있기에 <code>Array.from</code>을 사용해서 배열로 만들 수 있다.</p>
<p>이전 포스팅에서 사용 된 코드를 다시 가져와보면, </p>
<pre><code class="language-js">const deleteId = () =&gt; {
  const searchedList = document.getElementsByClassName(&quot;searched-list&quot;);
  Array.from(searchedList).forEach((list) =&gt; {
    searchBox.removeChild(list);
  });
  searchBox.classList.remove(&quot;showing&quot;);
};</code></pre>
<p><code>getElementByClassName</code>으로 <code>searched-list</code>를 클래스로 가지는 요소들을 전부 지정하고, htmlCollection을 리턴 받는다.</p>
<p>리턴 받은 유사배열을 <code>Array.from</code>으로 배열로 만든 다음, forEach로 removeChild를 모든 아이템에 적용 시키는 로직이었다.</p>
<p>또 한가지의 사용법은, 해당 html의 node에 접근 할 수 있다는것이다.
htmlElement의 경우는 해당 html의 노드에 접근 할 수 없었지만, htmlCollection의 경우는 index를 지정하여 node에 접근 할 수 있었다.</p>
<p>물론 이는 배열로 만든 다음에도 접근이 가능했기 때문에, 만약 html요소의 innerText등 곧바로 접근하기 힘든 값이 필요 하다면 htmlCollection을 사용하는것도 고려해보는것이 좋을것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn... "Array Method 응용하기"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...-Array-Method-%EC%9D%91%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...-Array-Method-%EC%9D%91%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 20 May 2021 17:26:28 GMT</pubDate>
            <description><![CDATA[<p>오늘 있었던 Array Method의 응용에 대해 포스팅을 해보려 한다.</p>
<h1 id="어떤-문제를-해결하였는가">어떤 문제를 해결하였는가?</h1>
<p>우선, 오늘 막혔던 부분은 검색창의 구현이었는데, 임의의 ID를 담고 있는 배열을 가지고 있을때, input창에서 입력된 문자를 포함 하고 있는 ID를 표시하는 기능이었다.</p>
<p>조건은 for문을 사용하지 않고, Array, 배열 관련의 메서드를 사용하는 것이었고, 이때 사용 된 키워드는</p>
<ul>
<li>filter</li>
<li>forEach</li>
<li>from</li>
<li>include</li>
</ul>
<p>였다.</p>
<h2 id="어떻게-문제를-해결하였나">어떻게 문제를 해결하였나?</h2>
<p>코드를 가져와 하나씩 설명하자면,</p>
<pre><code class="language-js">function checkInput() {
  searchInput.addEventListener(&quot;keyup&quot;, isCurrectId);
}

function init() {
  checkInput();
}

init();</code></pre>
<p>첫번째로 input창에서의 키 입력을 keyup 이벤트를 통해 입력 받는다.</p>
<pre><code class="language-js">const isCurrectId = (event) =&gt; {
  deleteId();
  const toCheckId = event.target.value;
  const checkedId = checkArry.filter((el) =&gt; {
    return toCheckId !== &quot;&quot; ? el.includes(toCheckId) : false;
  });
  if (checkedId.length &gt; 0) {
    checkedId.forEach((id) =&gt; {
      paintId(id);
    });
  } else {
    deleteId();
  }
};</code></pre>
<p>다음, 입력받은 event에 event.target.value로 접근,
filter와 include를 사용해서 가지고 있는 배열중 입력 받은 문자가 존재하는지 확인하고, 만약 없다면 false, 있다면 filter를 통해 배열로 전달 받는다.</p>
<pre><code class="language-js">const paintId = (text) =&gt; {
  const searchedList = document.createElement(&quot;div&quot;);
  const searchedName = document.createElement(&quot;li&quot;);
  const searchedAvatar = document.createElement(&quot;img&quot;);
  searchedAvatar.src = `/images/avatar/${text}.jpg`;
  searchedName.innerText = text;
  if (text) {
    searchedList.classList.add(&quot;searched-list&quot;);
    searchedName.classList.add(&quot;searched-name&quot;);
    searchedAvatar.classList.add(&quot;searched-avatar&quot;);
    searchedList.appendChild(searchedAvatar);
    searchedList.appendChild(searchedName);
    searchBox.classList.add(&quot;showing&quot;);
    searchBox.appendChild(searchedList);
  }
};</code></pre>
<p>그 후, if문을 통해 배열에 값이 존재한다면 forEach를 이용, 각각의 배열 아이템으로 변환하여 paintId로 이동시킨다. paintId에서 html 요소들을 그려내고, 배열에 아무 아이템이 없다면 delete로 이동하여 paint로 생성 되었던 요소를 지운다.</p>
<pre><code class="language-js">const deleteId = () =&gt; {
  const searchedList = document.getElementsByClassName(&quot;searched-list&quot;);
  Array.from(searchedList).forEach((list) =&gt; {
    searchBox.removeChild(list);
  });
  searchBox.classList.remove(&quot;showing&quot;);
};</code></pre>
<p>delete는 <code>getElementsByClassName</code>으로 해당 클래스의 모든 요소를 전달 받지만, 전달 된 요소는 html collection이라서 바로 removeChild를 사용 할 수 없다.</p>
<p>이때 Array.from을 사용해서 유사배열로 바꿔준 다음, forEach를 통해 하나씩 아이템을 모두 없앤다.</p>
<p>이때, <code>isCurrectId</code>의 처음 시작부분에 delete를 사용한 이유는, keyup 이벤트가 일어날때마다 생성 되어있던 html 요소를 삭제해서 초기화 하기 위해 사용하였다.</p>
<h2 id="어떤-부분이-문제였나">어떤 부분이 문제였나?</h2>
<p>가장 길게 고민했던 부분은, html을 생성 할 수는 있었지만, 삭제를 어느 타이밍에, 어떻게 할지에 대한 고민이었다.</p>
<p>그러던중, <code>isCurrectId</code> 부분에서</p>
<pre><code class="language-js">const isCurrectId = (event) =&gt; {
  deleteId();
  const toCheckId = event.target.value;
  const checkedId = checkArry.filter((el) =&gt; {
    return toCheckId !== &quot;&quot; ? el.includes(toCheckId) : false;
  });
  if (checkedId) {
    checkedId.forEach((id) =&gt; {
      paintId(id);
    });
  } else {
    //deleteId();
  }
};</code></pre>
<p>과 같이 if문에서 <code>checkedId</code>에서 문제가 발견 되었는데, checkedId에서 배열이 입력 되면서 빈 배열이 들어올 경우도 마찬가지로 <code>true</code>가 출력 되기에 사실상 이 if문은 else가 나올 수 없는 구조였던것이다.</p>
<p>이에 배열에 아이템을 찾을 수 있도록 if문의 컨디션 값을 <code>checkedId.length &gt; 0</code>처럼 확실히 값을 판단 할 수 있도록 하여 해결 하였다.</p>
<p>또, 삭제를 그냥 한번에 <code>querySelectorAll</code>이나 <code>getElementByClassName</code>으로 한꺼번에 잡아 삭제 하는것이 좋다라는 조언을 듣고, delete를 완성하여 문제를 해결 할 수 있었다.</p>
<h3 id="오늘의-교훈">오늘의 교훈</h3>
<p>이전부터 true로 취급 되는 값과 false로 취급 되는 값에 대한 정보는 알고 있었지만, 아직 이해가 부족하다는것을 깨달았다.</p>
<p>이번에 확실히 알게 되었으니, 앞으로도 여기저기 응용하고, 사용해보려 한다.</p>
<p>또, 문제의 첫단추가 되는 방법을 MDN에서 실마리를 찾았기에, 앞으로도 공식문서를 자주자주 찾아보려 한다.</p>
<p>물론 배열에 관한 메서드도 공부가 되는 문제였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn... "Linux & Terminal"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...-Linux-Terminal</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...-Linux-Terminal</guid>
            <pubDate>Tue, 18 May 2021 16:26:34 GMT</pubDate>
            <description><![CDATA[<h1 id="리눅스에-대해서">리눅스에 대해서</h1>
<p>오늘은 리눅스에 대해 이야기를 해보려 한다.</p>
<p>현대에서 개발을 한다고 하면 대개 두가지의 선택을 하게 된다.
OS를 선택할때, 맥북을 사용하고 있다면 mac OS를, 윈도우OS를 사용 하고 있다면 대개 리눅스를 선택하게 될것이다.</p>
<p>그럼 여기서 한가지 의문이 떠오를것이다.</p>
<blockquote>
<p>왜 리눅스인가?</p>
</blockquote>
<p>여러 개발자들이 윈도우를 두고 mac OS 혹은 리눅스를 사용하는데에는 이유가 있을것이다.
오늘은 그중 리눅스에 대해 알아보자.</p>
<h2 id="왜-리눅스인가">왜 리눅스인가</h2>
<p>리눅스는 리누스 토발즈(Linus Benedict Torvalds)가 개발한 유닉스기반의 운영체제이다.</p>
<p>리눅스의 가장 큰 특징은 <strong>무료</strong>오픈소스라는 것이며, 이때문에 여러가지 개조가 가능하다. 구글에서 배포하는 안드로이드도 리눅스가 기반이며, 해킹쪽에서 유명한 칼리-리눅스, 웹개발에서 유명한 리눅스-우분투등 다양한 바리에이션을 지닌다.</p>
<p><img src="https://images.velog.io/images/mong-byte/post/6985f1b4-b494-4227-a58c-db112e000139/linux-timeline-sample.png" alt="">
리눅스에서 파생된 OS들을 나열한 그림인데, 이 그림만 봐도 리눅스가 얼마나 파생OS가 다양한지 알 수 있을것이다.</p>
<p>본래 CLI(Command Line Interface) 즉 커맨드를 통해 명령 하는것에 기반을 두고 있으며, 최근에는 GUI를 통해 사용 편의성을 높이는 기능도 추가 되었다 한다.</p>
<p>그럼 왜 리눅스를 사용하는지에 대해 이야기해보자.</p>
<p>리눅스를 사용하는 이유는 크게 안정성, 유연성, 그리고 무료라는 점이 아마 가장 크지 않을까 생각한다.</p>
<p>리눅스를 쉽게 찾을 수 있는곳은 여러군데인데, 개발자의 노트북을 제외하고도 안드로이드 기반의 스마트폰, 자동차등의 임베디드, 그리고 AWS등 서버등이 리눅스 기반으로 이루어져 있다.</p>
<p>하지만 아직 윈도우와 호환은 기대하기 힘든데, WSL2를 발표하긴 했지만 아직은 길이 멀어보인다.</p>
<h2 id="리눅스의-디렉터리-구조">리눅스의 디렉터리 구조</h2>
<p>FHS는 Filesystem Hierarchy Standard라는 리눅스의 디렉터리 구조의 특징으로서, <img src="https://images.velog.io/images/mong-byte/post/7ab89789-5303-4959-9a4f-8a3c027a1248/Untitled.png" alt="">
위와 같은 디렉터리 구조를 가진다.</p>
<p>여기서 보통 사용하게 되는 공간은 /(root)와 /home/이다.
루트는 OS의 최상위 경로이고, 보통 사용자가 디렉터리를 만들고 데이터를 저장하는곳이 바로 /home/이다.</p>
<p>이때 각 디렉터리를 찾기 위해 커맨드를 입력할때 경로(path)를 이용하여 디렉터리에 접근하게 되는데, /가 기준인 절대경로와, 현재 머물고 있는 위치를 기준으로한 상대경로 두가지의 종류가 있다.</p>
<p>다음은 리눅스에서 자주 쓰이는 명령어이다.
<img src="https://images.velog.io/images/mong-byte/post/9e0ce483-e0c0-4d05-9ccc-3a1681691e26/%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C%20(1).jpg" alt=""></p>
<p>물론 이 명령어들은 git bash 혹은 zsh등에서도 사용 할 수 있기에, 잘 알아둔다면 큰 도움이 될것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn... "Data Base"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...-Data-Base</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...-Data-Base</guid>
            <pubDate>Mon, 17 May 2021 15:48:18 GMT</pubDate>
            <description><![CDATA[<h1 id="data-base란">Data Base란?</h1>
<p>Data base는 일반적으로, 컴퓨터속에 저장 된 정보나 데이터를 모아둔 집합을 이야기 한다.</p>
<p>이 데이터베이스는 <a href="https://www.oracle.com/kr/database/what-is-database/#WhatIsDBMS">데이터베이스 관리 시스템(DBMS)</a>으로 제어 되는데, 데이터와 DMBS, 관련 어플리케이션들을 통칭 <code>데이터 베이스 시스템</code>, 혹은 더 줄여서 <code>데이터베이스</code>라고 통칭 되기도 한다.(<a href="https://www.oracle.com/kr/database/what-is-database/">oracle</a>)</p>
<p>데이터베이스는 크게 나누어 두종류로 나누어진다.
하나는 <strong>관계형 데이터베이스</strong>이고, 다른 하나는 <strong>비관계형 데이터베이스</strong>이다.</p>
<p>관계형 데이터베이스는 관계형 데이터모델을 기반으로 한 데이터 시스템을 말하는데, </p>
<blockquote>
<p>관계형 데이터모델이란,
데이터를이 서로 어떤 관계인지를 나타낸 데이터를 이야기한다.</p>
</blockquote>
<p>물론 비 관계형 데이터베이스는 이와 반대로, 서로간의 관계가 없는 데이터베이스이다.
관계형 데이터베이스는 mySQL등 SQL 데이터베이스가 있고,
비관계형 데이터베이스는 MongoDB등 NoSQL 데이터베이스가 있다.</p>
<p>비관계형 데이터베이스는 다음에 알아보기로 하고, 오늘은 
관계형 데이터베이스에 대해 먼저 다뤄보려 한다.</p>
<h2 id="관계형-데이터베이스는-어떻게-나타내는가">관계형 데이터베이스는 어떻게 나타내는가?</h2>
<p>관계형 데이터베이스를 나타낼때는 2차원의 테이블로 나타내게 된다.
<img src="https://images.velog.io/images/mong-byte/post/43249eae-9bba-43eb-918a-b79dc3899bc0/aa9.jpg" alt="">
이렇게 흔히 보던 엑셀시트에 데이터를 저장하는것처럼 2차원의 테이블로 저장 하게 되고, 각 테이블은 행(row)과 열(column)으로 구성된다.</p>
<p>열에는 테이블들의 각 항목들을 이야기하고, 행에는 각 항목들이 가지고 있는 실제값을 입력하게 된다.</p>
<p>이때, 각각의 행에 들어가는 항목은 저마다 고유한 key를 가지고 있는데, 이것이 <code>Primary Key</code>이다.</p>
<p>이 키는 고유한 키이기 때문에, 해당 행을 찾거나 데이터를 가져오는곳에 사용 할 수 있다.</p>
<h3 id="데이터-연결의-종류">데이터 연결의 종류</h3>
<p>데이터들은 상호관련성을 가지고 있으며, 데이터베이스 안에서 데이터들의 연결을 나타내는 종류는 3종류가 있다.</p>
<h4 id="one-to-one">one to one</h4>
<p>테이블 A와 B, 두개의 테이블이 있다고 하자.
테이블 A의 행에 있는 데이터(실제값)이 B의 행에 있는 데이터(실제값)과 일치하는 데이터 연결을 one to one의 관계라 한다.</p>
<h4 id="one-to-many">one to many</h4>
<p>아까전과 같이 2개의 테이블이 있다고 할때, one to one이 일대일로 매칭되었다 하면, one to many는 테이블 A의 데이터 하나가 여러개의 테이블 B의 데이터와 매칭 될 수 있는 관계를 나타낸다.</p>
<h4 id="many-to-many">many to many</h4>
<p>이번엔 one to many의 데이터 연결을 연상해보자.
one to many는 하나의 테이블 A의 데이터가 테이블 B의 여러 데이터와 매칭 되었다 하면, many to many는 두개의 테이블에 있는 여러 데이터가 다른 테이블의 여러 데이터와 매칭이 되는 데이터 연결을 의미한다.</p>
<p>이때는 매칭 되는 데이터들을 바로 매칭 시키지 않고, 테이블을 하나 더 둬서 정리하는것이 특징이다.</p>
<h2 id="어떻게-데이터의-관계를-나타내는가">어떻게 데이터의 관계를 나타내는가</h2>
<p>데이터간의 관계를 나타내기 위해서는 우선 <strong>Foreign key(외부키)</strong> 를 먼저 이해해야 한다.
외부키는 한 테이블의 키에서, 다른 테이블의 키를 식별가능한 키를 이야기 하는데, 외래키는 서로가 같은 데이터타입과 값을 가지고 있어야 한다.
즉, 만약 외래키가 id라고 한다면, 둘다 id에 INT타입이어야 한다는 것이다.</p>
<p>이 외부키를 사용하여, 여러 테이블을 엮어서 데이터간의 관계를 나타내는것이다.</p>
<h2 id="데이터를-연결해서-저장하는-이유는-무엇인가">데이터를 연결해서 저장하는 이유는 무엇인가</h2>
<p>만약 우리가 하나의 테이블에 모든 정보를 다 넣는다면, 동일한 정보가 들어가거나 잘못된 정보가 들어갈 가능성이 높고,
그걸 읽기위해 불필요한 메모리가 소모되게 된다.</p>
<p>이러한 일을 막기위해 정보를 여러 테이블에 나눠서 저장하고, 이를 연결해서 저장하여 중복되는 정보의 저장을 막고, 효율적으로 데이터를 처리하는것을 <strong>정규화</strong>라고 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Today I learn... "Variable"]]></title>
            <link>https://velog.io/@mong-byte/Today-I-learn...-Variable</link>
            <guid>https://velog.io/@mong-byte/Today-I-learn...-Variable</guid>
            <pubDate>Fri, 14 May 2021 15:00:07 GMT</pubDate>
            <description><![CDATA[<p>오늘은 변수에 대해 좀 더 자세하게 다루어 보려 한다.</p>
<p>변수의 종류 <code>var</code> <code>let</code> <code>const</code>중 왜 <code>let</code>과 <code>const</code>가 나오게 되었는지, 어째서 var를 사용해서는 안되는지에 대해 알아보자.</p>
<h1 id="변수의-종류">변수의 종류</h1>
<h2 id="변수의-선언과-할당">변수의 선언과 할당</h2>
<p>우선 우린 var와 let 그리고 const에 대해 알아보기 전에 변수가 어떠한 방식으로 선언 되고 할당 되는지에 대해 알아야 한다.</p>
<p>변수의 선언과 할당은 다음과 같다.</p>
<pre><code class="language-js">var a; // 변수의 선언
a = 5; // 변수의 할당

var a = 5 // 변수의 선언과 할당을 동시에 행함</code></pre>
<p>즉, 변수의 선언과 할당은 다른것이며, 우리가 평소에 사용하는 방법은 변수의 선언과 할당을 동시에 행하는것이다.</p>
<p>위의 정보를 머리 한켠에 넣어두고, 본격적으로 변수에 대해 알아보도록 하자.</p>
<h2 id="var">var</h2>
<p>var는 variable(변수)의 줄임말로, 초기 자바스크립트에서 변수를 선언할때 사용 가능한 키워드이다.</p>
<pre><code class="language-js">var a = 5;
console.log(a); // 5출력</code></pre>
<p>이런 식으로 변수를 선언하고, 할당하는것이 가능한 키워드인데, 무엇때문에 let과 const를 만들게 된것일까?</p>
<p>우리는 비슷하게 보이는것이라도 왜 나올 수 밖에 없었는지 알아 볼 필요가 있다고 생각한다.</p>
<p>var의 단점은 다음과 같다.</p>
<h3 id="var의-단점">var의 단점</h3>
<p>var가 단순히 변수를 담고 있기만 하면 문제가 되지 않을것이다.</p>
<p>var의 치명적인 단점은 바로, var에 변수를 선언하고 할당한 뒤, 다른 어떤 요인으로 인해 같은 변수명으로 다른 값을할당하게 된다면, 아무 문제 없이 재선언, 재할당이 가능하다.</p>
<pre><code class="language-js">var a = &quot;hello&quot;;
var b = &quot; world!&quot;;
console.log(a + b); // &quot;hello world!&quot;

// 약 5천줄 이상의 코드가 작성 되고 다른 사람이 입력한다.

var a = 10;
console.log(a + b); // &quot;10 world!&quot;</code></pre>
<p>이 경우, var는 에러를 발생 시키지 않는다.</p>
<blockquote>
<p>&#39;에러가 나지 않는다면 좋은거 아닌가?&#39;</p>
</blockquote>
<p>하고 생각 할 수 있지만, var로 인해 발생하는 문제는 조금 다른 양상을 띈다.</p>
<p>위에서 보았듯이, 우리는 a에 &quot;hello&quot;라는 값을 할당하고, &quot; world&quot;를 뒤에 붙여 &quot;hello world!&quot;를 출력하도록 프로그램에게 요청하였다.</p>
<p>결과엔 잘 출력 되었고, 여기까지는 아무 문제가 없었다.
누군가가 a에 다른 값을 넣기 전까지는 말이다.</p>
<p>우리는 &quot;hello world!&quot;를 원했지만, a의 값이 재선언, 재할당 되었기 때문에 결과는 &quot;10 world!&quot;라는 이상한 값이 선언 되었다.</p>
<p>물론 일부러 악의를 가지고 이렇게 작성 할 리는 없을것이다.
하지만, 실수로 이런 일이 발생한다면, 에러를 발생 시키지 않기때문에 어디서 문제가 생겼는지 5000줄 이상의 코드를 뒤져가며 찾아야 할것이다.</p>
<p>이외에도 호이스팅이라는 단점이 있지만, 아직 호이스팅에 대한 문제가 발생하여 대응한 적이 없기에.. 생략하도록 하겠다.</p>
<p>결국 이러한 단점 때문에 새로운 변수 타입인 let과 const가 나오게 되었다.</p>
<h2 id="let--const">let &amp; const</h2>
<p>먼저 let부터 살펴보자.
변수타입 let은 재할당은 가능하지만, 재선언은 불가능하다.</p>
<p>이 말은, let의 값을 바꾸는것은 가능하지만, 같은 이름의 변수를 다시 선언하는것은 불가능하다는 것이다.</p>
<pre><code class="language-js">let a = 62;
let b = 32;

console.log(a - b); // 30

a = 52;
console.log(a - b) // 20

let a = 32; // Uncaught SyntaxError: Identifier &#39;a&#39; has already been declared</code></pre>
<p>let은 var과 다르게 에러를 발생시켰다.</p>
<p>a는 이미 선언 되었으니, 다른 이름의 변수를 선언하라는 에러이다.</p>
<p>만약 var였으면 재선언이 가능하여 값이 변했을것이다.
이처럼 let은 값을 바꾸는것은 가능하지만, 재선언을 할 때엔 에러를 발생시키고, 재선언을 거부한다.</p>
<p>const는 어떨까?
const는 var와도 let과도 다르다.
const는 선언되고 값이 할당 되는 순간, 재선언과 재할당이 불가능하다.</p>
<p>한번 이렇게 사용 한 변수는 나중에 값을 바꿀 수 없는것이다.</p>
<pre><code class="language-js">const a = 5;
console.log(a); // 5

a = 6; // Uncaught SyntaxError: Identifier &#39;a&#39; has already been declared

const a; // Uncaught SyntaxError: Missing initializer in const declaration
</code></pre>
<p>이처럼, const는 재할당과 재선언을 모두 거부한다.</p>
<p>만약 바꾸고 싶지 않은 변수가 있다면 const를 사용하고, 값이 변해야 하는 변수가 있다면 let으로 바꿔서 사용하도록 하자.</p>
]]></description>
        </item>
    </channel>
</rss>