<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>na0i_log</title>
        <link>https://velog.io/</link>
        <description>바닐라라떼를 사랑하는 개발자</description>
        <lastBuildDate>Thu, 06 Apr 2023 13:27:54 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. na0i_log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/na_0_i" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[모던 자바스크립트 DeepDive 13장 스코프]]></title>
            <link>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-13%EC%9E%A5-%EC%8A%A4%EC%BD%94%ED%94%84</link>
            <guid>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-13%EC%9E%A5-%EC%8A%A4%EC%BD%94%ED%94%84</guid>
            <pubDate>Thu, 06 Apr 2023 13:27:54 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글은 <strong>&#39;모던 자바스크립트 DeepDive&#39;</strong>를  참고하여 작성되었습니다.</p>
</blockquote>
<h3 id="131-스코프란">13.1 스코프란?</h3>
<p>식별자는 자신이 선언된 위치에 의해 자신을 참조할 수 있는 유효 범위가 결정된다. <strong>스코프는 식별자가 유효한 범위</strong>를 말한다.</p>
<br>

<pre><code class="language-javascript">var x = &#39;global&#39;;

function foo() {
    var x = &#39;local&#39;;
    console.log(x);
}

foo();

console.log(x);</code></pre>
<p>위 예시에서 자바스크립트는 이름이 같은 두 변수(x)에 대해 어떤 변수를 참조해야 할 지 결정(식별자 결정)한다. 바깥 영역에 선언된 x 변수는 어디서든 참조할 수 있지만, foo 함수 내부에서 선언된 x 변수는 foo 함수 내부에서만 참조할 수 있으며, 두 개의 x 변수는 식별자 이름이 동일하지만 스코프가 다른 별개의 변수다.</p>
<br>

<p>식별자는 값을 구별하여 식별해 낼 수 있는 고유한 이름을 말하기 때문에 유일해야 하지만 우리가 컴퓨터를 사용할 때 다른 폴더 내에서는 동일한 파일을 사용할 수 있듯이 프로그래밍 언어에서는 스코프를 통해 식별자인 변수 이름의 충돌을 방지하여 같은 이름의 변수를 사용할 수 있도록 한다. 즉, 스코프 내에서의 식별자는 유일해야 하지만, 다른 스코프에는 같은 이름을 사용할 수 있다.</p>
<br>

<h3 id="132-스코프의-종류">13.2 스코프의 종류</h3>
<img width="312" alt="스크린샷 2022-12-01 오전 2 03 52" src="https://user-images.githubusercontent.com/77482972/204861705-5f2e661a-379a-4644-bfc9-c9538f9a9052.png">

<h4 id="1321-전역과-전역-스코프">13.2.1 전역과 전역 스코프</h4>
<p><strong>전역이란 코드의 가장 바깥 영역</strong>을 말하며, 전역은 전역 스코프를 만든다. 따라서 전역에 선언한 변수는 전역 스코프를 갖는 전역 변수가 되어 <strong>어디서든 참조할 수 있다.</strong></p>
<br>

<h4 id="1322-지역과-지역-스코프">13.2.2 지역과 지역 스코프</h4>
<p><strong>지역이란 함수 몸체 내부</strong>를 말하며, 지역 스코프를 만든다. 따라서 지역에 선언한 변수는 지역 스코프를 갖는 지역 변수가 되어 <strong>자신이 선언된 지역과 하위 지역에서만 참조할 수 있다.</strong> 즉, 지역 변수는 <strong>자신의 지역 스코프와 하위 지역 스코프에서 유효</strong>하다.</p>
<br>

<h4 id="133-스코프-체인">13.3 스코프 체인</h4>
<p>함수는 중첩될 수 있으므로 함수의 지역 스코프도 중첩될 수 있다. 이는 <strong>스코프가 함수의 중첩에 의해 계층적 구조를 갖는다(스코프 체인)</strong>는 것을 의미한다. </p>
<img width="222" alt="스크린샷 2022-12-01 오전 2 09 10" src="https://user-images.githubusercontent.com/77482972/204862740-88872e9f-99be-482c-98bf-7b707d2683f6.png">

<ul>
<li>outer 함수: 전역에 선언</li>
<li>inner 함수: outer 함수 내부에 선언</li>
</ul>
<br>

<p>위 예시와 같이 모든 스코프는 하나의 계층적 구조로 연결되며, 최상위 스코프는 전역 스코프다. <strong>변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하면서 선언된 변수를 검색</strong>한다.</p>
<blockquote>
<p>스코프 체인은 물리적인 실체로 존재한다. 위 예시와 유사하게 <strong>렉시컬 환경</strong>을 실제로 생성해, 변수 선언이 실행되면 렉시컬 환경에 변수 식별자가 key로, 변수 할당이 실행되면 식별자에 해당하는 값을 변경한다. 변수 검색도 렉시컬 환경 상에서 일어난다.</p>
</blockquote>
<br>

<h4 id="1331-스코프-체인에-의한-변수-검색">13.3.1 스코프 체인에 의한 변수 검색</h4>
<p>자바스크립트 엔진은 스코프 체인을 따라 변수를 참조하는 코드의 스코프에서 시작해 상위 스코프 방향으로 이동하며 변수를 검색한다. 위 예시에서 y를 검색할 경우에는 inner &gt; outer &gt; 전역 순서를 따른다. 하위 스코프로 내려가면서 식별자를 검색하는 경우는 없기 때문에 <strong>상위 스코프에서 유효한 변수는 하위 스코프에서 참조할 수 있지만 하위 스코프에서 유효한 변수를 상위 스코프에서 참조할 수는 없다.</strong></p>
<br>

<h4 id="1332-스코프-체인에-의한-함수-검색">13.3.2 스코프 체인에 의한 함수 검색</h4>
<p>함수도 식별자에 할당되기 때문에 스코프를 갖는다. 따라서 변수 검색과 동일한 로직으로 함수를 검색한다.</p>
<br>

<h3 id="134-함수-레벨-스코프">13.4 함수 레벨 스코프</h3>
<p>지역은 함수 몸체 내부를 말하기 때문에 <strong>지역 스코프는 코드 블록이 아니라 함수에 의해서 생성된다.</strong> var 키워드로 선언된 변수는 함수의 코드 블록만을 지역 스코프로 인정(함수 레벨 스코프)한다.</p>
<blockquote>
<p>블록 레벨 스코프는 모든 코드블록에 대해 지역 스코프를 만든다.</p>
</blockquote>
<pre><code class="language-javascript">var x = 1;

if (true) {
    var x = 10;
}

console.log(x); // 10


var i = 10;

for (var i = 0; i &lt; 5; i++) {
    console.log(i);
}

console.log(i); // 5

// 코드 블록은 지역 스코프로 인정되지 않아
// x와 i가 중복 선언됨</code></pre>
<p>단, let과 const 키워드는 블록 레벨 스코프를 지원한다.</p>
<br>

<h3 id="135-렉시컬-스코프">13.5 렉시컬 스코프</h3>
<pre><code class="language-javascript">var x = 1;

function foo () {
    var x = 10;
    bar();
}

function bar () {
    console.log(x);
}

foo(); // 1
bar(); // 1
// bar 함수가 호출된 곳이 어디든 관계없이
// bar 함수는 자신이 정의된 스코프인 전역 스코프를 기억한다.
// → 함수의 상위 스코프는 정의된 곳에 의해 결정되므로 여기서의 상위 스코프는 전역이 되어 foo 함수 내부에서 호출되었을 지라도 전역 x를 참조</code></pre>
<p>자바스크립트는 렉시컬 스코프를 따르므로 <strong>어디서 호출했는지가 아니라 함수를 어디서 정의했는지에 따라 상위 스코프를 결정한다.</strong> 함수가 호출된 위치는 상위 스코프 결정에 어떠한 영향도 주지 않는다.</p>
<br>

<p>함수의 상위 스코프는 언제나 자신이 정의된 스코프이며 함수의 상위 스코프는 함수 정의가 실행될 때 정적으로 결정된다. 함수 정의가 실행되어 생성된 함수 객체는 이렇게 결정된 상위 스코프를 기억한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[useState 지옥에서 벗어나기(with useReducer)]]></title>
            <link>https://velog.io/@na_0_i/useState-%EC%A7%80%EC%98%A5%EC%97%90%EC%84%9C-%EB%B2%97%EC%96%B4%EB%82%98%EA%B8%B0with-useReducer</link>
            <guid>https://velog.io/@na_0_i/useState-%EC%A7%80%EC%98%A5%EC%97%90%EC%84%9C-%EB%B2%97%EC%96%B4%EB%82%98%EA%B8%B0with-useReducer</guid>
            <pubDate>Thu, 06 Apr 2023 13:25:51 GMT</pubDate>
            <description><![CDATA[<h1 id="usestate-지옥에서-벗어나기with-usereducer">useState 지옥에서 벗어나기(with useReducer)</h1>
<h3 id="usereducer란">useReducer란?</h3>
<p>리액트 상태 관리로 가장 많이 사용되는 훅은 useState일 것입니다. 하지만 상태를 관리할 때 useState를 사용하는 것 말고도 useReducer를 사용하는 방법이 있습니다.</p>
<br>

<p><code>const [state, dispatch] = useReducer(reducer, initialState);</code></p>
<ul>
<li>state는 사용할 상태, dispatch는 액션을 발생시키는 함수입니다.</li>
<li>첫번째 파라미터는 reducer 함수</li>
<li>두번째 파라미터는 초기 상태입니다.</li>
</ul>
<br>

<h3 id="usestate-남용의-문제점">useState 남용의 문제점</h3>
<p>개발을 하다보면 한 컴포넌트에 수많은 useState를 작성하게 되는 경우가 있습니다.</p>
<pre><code class="language-javascript">import { useState } from &quot;react&quot;;

function EditCalendarEvent() {
  const [startDate, setStartDate] = useState();
  const [endDate, setEndDate] = useState();
  const [title, setTitle] = useState(&quot;&quot;);
  const [description, setDescription] = useState(&quot;&quot;);
  const [location, setLocation] = useState();
  const [attendees, setAttendees] = useState([]);

  return (
    &lt;&gt;
      &lt;input value={title} onChange={(e) =&gt; setTitle(e.target.value)} /&gt;
      {/* ... */}
    &lt;/&gt;
  );
}</code></pre>
<p>위 예시는 달력 이벤트를 업데이트하는 컴포넌트입니다.
<br></p>
<p>이 컴포넌트의 문제는 아래와 같습니다.</p>
<ul>
<li>useState가 남용되어 어떤 상태를 관리하고 있는지 한 눈에 알기 어렵고</li>
<li>세이프가드가 없습니다.<ul>
<li>종료 날짜를 시작 날짜 이후로 선택할 수 있다든가</li>
<li>제목이나 설명에 글자 수 제한을 건다든가</li>
</ul>
</li>
</ul>
<br>


<h3 id="usestate를-어떻게-대체할-수-있을까">useState를 어떻게 대체할 수 있을까?</h3>
<p><code>useReducer</code> 를 사용하면 위와 같은 문제를 해결할 수 있습니다.</p>
<br>

<p>useReducer를 사용하면 A에서 B로의 변환을 제어할 수 있기 때문입니다. 위 예시 코드는 아래와 같은 형태로 개선될 수 있습니다.</p>
<pre><code class="language-javascript">import { useReducer } from &quot;react&quot;;

function EditCalendarEvent() {
  const [event, updateEvent] = useReducer(
    (prev, next) =&gt; {
    // 이벤트를 검증하고 변환하여 상태가 항상 유효할 것을 한 곳에서 관리하며 보장합니다.
      return { ...prev, ...next };
    },
    { title: &quot;&quot;, description: &quot;&quot;, attendees: [] }
  );

  return (
    &lt;&gt;
      &lt;input
        value={event.title}
        onChange={(e) =&gt; updateEvent({ title: e.target.value })}
      /&gt;
      {/* ... */}
    &lt;/&gt;
  );
}</code></pre>
<p>useReducer를 사용하면 상태를 한 곳에서 관리하며 상태 변환을 제어할 수 있는 함수를 추가함으로써 언제나 유효하다는 것을 보장한다는 이점을 갖습니다.</p>
<br>

<p>아까 언급했던 <strong>useState로 상태를 따로따로 관리할 경우 세이프 가드가 없다</strong>는 문제를 useReducer로 해결해봅시다!</p>
<br>

<pre><code class="language-javascript">import { useReducer } from &quot;react&quot;;

function EditCalendarEvent() {
  const [event, updateEvent] = useReducer(
    (prev, next) =&gt; {
      const newEvent = { ...prev, ...next };
      // 시작 날짜가 종료 날짜 이후가 될 수 없음을 보장
      if (newEvent.startDate &gt; newEvent.endDate) {
        newEvent.endDate = newEvent.startDate;
      }
      // 제목이 100자를 넘을 수 없음을 보장
      if (newEvent.title.length &gt; 100) {
        newEvent.title = newEvent.title.substring(0, 100);
      }
      return newEvent;
    },
    { title: &quot;&quot;, description: &quot;&quot;, attendees: [] }
  );

  return (
    &lt;&gt;
      &lt;input
        value={event.title}
        onChange={(e) =&gt; updateEvent({ title: e.target.value })}
      /&gt;
      {/* ... */}
    &lt;/&gt;
  );
}</code></pre>
<br>

<h3 id="언제-usestate를-usereducer로-대체해야할까">언제 useState를 useReducer로 대체해야할까?</h3>
<p>useState를 사용하는 곳 대부분은 useReducer로 대체될 수 있습니다. 하지만 보통의 경우 useState를 사용해도 괜찮기 때문에 관리하는 상태 값이 적다면 useState를, 관리하는 값이 많아지고 상태의 구조가 복잡해진다면 useReducer를 사용하는 것도 하나의 방법일 것 같습니다.</p>
<br>

<p>결국은 우리의 선택!</p>
<br>

<p>이 글은 다음 글을 참고하여 작성되었습니다.</p>
<blockquote>
<p><a href="https://react.vlpt.us/basic/20-useReducer.html">https://react.vlpt.us/basic/20-useReducer.html</a></p>
</blockquote>
<blockquote>
<p><a href="https://velog.io/@eunbinn/a-cure-for-react-useState-hell">https://velog.io/@eunbinn/a-cure-for-react-useState-hell</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Container와 Wrapper, 두 용어의 차이점은 무엇일까?]]></title>
            <link>https://velog.io/@na_0_i/Container%EC%99%80-Wrapper-%EB%91%90-%EC%9A%A9%EC%96%B4%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</link>
            <guid>https://velog.io/@na_0_i/Container%EC%99%80-Wrapper-%EB%91%90-%EC%9A%A9%EC%96%B4%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</guid>
            <pubDate>Tue, 28 Mar 2023 12:05:32 GMT</pubDate>
            <description><![CDATA[<h1 id="container와-wrapper-두-용어의-차이점은-무엇일까">Container와 Wrapper, 두 용어의 차이점은 무엇일까?</h1>
<p>나는 보통 styled-components를 사용하면서 어떤 요소를 감쌀 때 Container와 Wrapper를 혼용해서 사용하곤 했었다. 하지만 이러한 사소한 네이밍 개선이 코드 가독성을 높여준다고 생각해서 Container와 Wrapper의 네이밍 차이를 알아보았다!</p>
<br>

<h3 id="container와-wrapper를-사용하는-경우">Container와 Wrapper를 사용하는 경우</h3>
<p>일반적으로 두 용어 다 <strong>요소를 포함한다는 의미</strong>를 지니며, <strong>클래스 용어로 자주 사용</strong>된다고 한다. 기본적으로 차이를 두지 않고서 사용해도 무방하지만, 엄격하게 구분을 한다고 하면 프로그래밍 관행 상으로 container와 wrapper의 차이를 파악하는 것이 가능하다고 한다.</p>
<br>

<h3 id="원론적인-의미-구분">원론적인 의미 구분</h3>
<h4 id="container--하나-이상의-요소">container : 하나 이상의 요소</h4>
<h4 id="wrapper-하나의-요소를-포함">wrapper: 하나의 요소를 포함</h4>
<p>프로그래밍 세계에서 일반적으로</p>
<ul>
<li>container는 하나 이상의 요소를 포괄하는 개체를 지칭하는 의미를 지니며,</li>
<li>wrapper는 하나의 개체만을 포함하는 것을 뜻한다고 한다.</li>
</ul>
<br>
특히 wrapper는 소프트웨어 공학 측면의 `Adapter pattern`을 참고해 더 잘 이해할 수 있는데 간단하게 얘기해보면 하나의 요소를 다른 데 적용할 수 있도록 adapter 역할을 하는 것을 wrapper라고 한다는 것을 알 수 있다.

<br>

<h3 id="예시">예시</h3>
<pre><code class="language-html">&lt;ul class=&quot;items-container&quot;&gt;
    &lt;li class=&quot;item-wrapper&quot;&gt;
        &lt;div class=&quot;item&quot;&gt;...&lt;/div&gt;
    &lt;/li&gt;
    &lt;li class=&quot;item-wrapper&quot;&gt;
        &lt;div class=&quot;item&quot;&gt;...&lt;/div&gt;
    &lt;/li&gt;
    &lt;li class=&quot;item-wrapper&quot;&gt;
        &lt;div class=&quot;item&quot;&gt;...&lt;/div&gt;
    &lt;/li&gt;
    &lt;li class=&quot;item-wrapper&quot;&gt;
        &lt;div class=&quot;item&quot;&gt;...&lt;/div&gt;
    &lt;/li&gt;
    &lt;li class=&quot;item-wrapper&quot;&gt;
        &lt;div class=&quot;item&quot;&gt;...&lt;/div&gt;
    &lt;/li&gt;
&lt;/ul&gt;</code></pre>
<p>위 예시는 다른 글에서 가져온 예시다.</p>
<br>

<p>위 예시처럼 wrapper는 하나의 요소를 감싸며 그 요소에 padding 등의 속성을 줄 경우 사용하는 것이 좋고, container는 여러 요소를 묶을 때 사용하는 것이 좋을 것 같다.</p>
<br>

<h5 id="참고한-글">참고한 글</h5>
<blockquote>
<p><a href="https://uxdev.org/entry/CSS-%ED%81%B4%EB%9E%98%EC%8A%A4-%EB%84%A4%EC%9D%B4%EB%B0%8D-%EC%8B%9C-container-vs-wrapper-%EC%B0%A8%EC%9D%B4-%EA%B5%AC%EB%B6%84%ED%95%98%EA%B8%B0">https://uxdev.org/entry/CSS-%ED%81%B4%EB%9E%98%EC%8A%A4-%EB%84%A4%EC%9D%B4%EB%B0%8D-%EC%8B%9C-container-vs-wrapper-%EC%B0%A8%EC%9D%B4-%EA%B5%AC%EB%B6%84%ED%95%98%EA%B8%B0</a></p>
</blockquote>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[React의 useCallback과 useMemo가 진짜 필요한 순간은?]]></title>
            <link>https://velog.io/@na_0_i/React%EC%9D%98-useCallback%EA%B3%BC-useMemo%EA%B0%80-%EC%A7%84%EC%A7%9C-%ED%95%84%EC%9A%94%ED%95%9C-%EC%88%9C%EA%B0%84%EC%9D%80</link>
            <guid>https://velog.io/@na_0_i/React%EC%9D%98-useCallback%EA%B3%BC-useMemo%EA%B0%80-%EC%A7%84%EC%A7%9C-%ED%95%84%EC%9A%94%ED%95%9C-%EC%88%9C%EA%B0%84%EC%9D%80</guid>
            <pubDate>Thu, 16 Mar 2023 13:45:17 GMT</pubDate>
            <description><![CDATA[<h3 id="usecallback과-usememo란">useCallback과 useMemo란?</h3>
<p>아래는 리액트 공식문서에 나와있는 useCallback과 useMemo에 대한 설명입니다.</p>
<br>

<h4 id="usecallback-메모이제이션된-콜백을-반환합니다">useCallback: 메모이제이션된 콜백을 반환합니다.</h4>
<p>콜백의 메모이제이션된 버전을 반환할 것입니다. 그 메모이제이션된 버전은 콜백의 의존성이 변경되었을 때에만 변경됩니다. 이것은, <strong>불필요한 렌더링을 방지하기 위해 참조의 동일성에 의존적인 최적화된 자식 컴포넌트에 콜백을 전달할 때 유용</strong>합니다.</p>
<br>

<h4 id="usememo-메모이제이션된-값을-반환합니다">useMemo: 메모이제이션된 값을 반환합니다.</h4>
<p>useMemo는 의존성이 변경되었을 때에만 메모이제이션된 값만 다시 계산 할 것입니다. <strong>이 최적화는 모든 렌더링 시의 고비용 계산을 방지하게 해 줍니다.</strong> 배열이 없는 경우 매 렌더링 때마다 새 값을 계산하게 될 것입니다.</p>
<br>

<h3 id="그렇다면-usecallback과-usememo는-정말-성능-향상에-도움이-될까">그렇다면 useCallback과 useMemo는 정말 성능 향상에 도움이 될까?</h3>
<blockquote>
<p><a href="https://haragoo30.medium.com/usememo-usecallback%EC%9D%84-%EC%96%B8%EC%A0%9C-%EC%8D%A8%EC%95%BC%EB%90%98%EB%82%98-6a5e6f30f759">https://haragoo30.medium.com/usememo-usecallback%EC%9D%84-%EC%96%B8%EC%A0%9C-%EC%8D%A8%EC%95%BC%EB%90%98%EB%82%98-6a5e6f30f759</a></p>
</blockquote>
<p>위 글의 결론은 작은 규모에서 useMemo, useCallback을 사용했을 떄 성능이 오히려 나빠지거나 미미하게 좋아졌고, 규모가 커질 때는 조금씩 성능상의 이점이 늘어났지만 그 효과가 미비했습니다.</p>
<blockquote>
<p><a href="https://velog.io/@hyunjine/React-Rendering-Optimization">https://velog.io/@hyunjine/React-Rendering-Optimization</a></p>
</blockquote>
<p>또다른 예시를 보여주는 블로그에서도 useCallback으로 감싼 함수는 그렇지 않은 함수보다 더 많은 일(함수를 정의하는 일, 의존성 배열의 값을 정의하는 일)을 하기 때문에 초기 렌더링에 더 느리게 실행되며, 그 이후에는 의존성 배열의 참조 동일성 체크 때문에 함수를 새로 만드는 것과 결국엔 비슷한 시간이 걸렸습니다.</p>
<br>

<p>즉, 저희가 사용해온 대부분의 방식의 useCallback과 useMemo는 쓸모가 없습니다..!</p>
<br>

<h4 id="진짜-필요한-순간은-언제일까">진짜 필요한 순간은 언제일까?</h4>
<p>컴포넌트가 렌더링 되는 순간은 3가지입니다.</p>
<ol>
<li>state가 바뀔 때</li>
<li>props가 바뀔 때</li>
<li><strong>부모가 렌더링 될 때</strong></li>
</ol>
<br>

<p>부모 컴포넌트의 렌더링은 자식 컴포넌트의 렌더링을 초래합니다.</p>
<pre><code class="language-jsx">const App = () =&gt; {
  const [state, setState] = useState(1);

  return (
    &lt;div&gt;
      &lt;button onClick={() =&gt; setState(state + 1)}&gt;{state}&lt;/button&gt;
      &lt;Page /&gt;
    &lt;/div&gt;
  );
};

const Page = () =&gt; &lt;Item /&gt;;</code></pre>
<p>위 예시에서 Page는 state도 props도 없지만 부모 컴포넌트가 렌더링 되었다는 이유만으로 렌더링됩니다.</p>
<br>

<p>이런 순간이 <code>React.memo()</code>가 필요한 순간입니다.</p>
<pre><code class="language-jsx">const PageMemoized = React.memo(Page);

const App = () =&gt; {
  const [state, setState] = useState(1);
  const onClick = () =&gt; {
    console.log(&#39;Do something on click&#39;);
  };

  return (
    &lt;div&gt;
      &lt;PageMemoized onClick={onClick} /&gt;
    &lt;/div&gt;
  );
};</code></pre>
<p>하지만, 위 예시에서도 아쉬운 점이 있습니다. </p>
<br>

<p>아래는 부모 컴포넌트인 App이 리렌더링 될 경우의 순서입니다.</p>
<ol>
<li>App 리렌더링</li>
<li>onClick 새로 생성</li>
<li>PageMemoized 컴포넌트의 props가 바뀌었는지 체크</li>
<li>onClick은 새로 생성된 함수이므로 props가 바뀌었다고 생각하여</li>
<li>PageMemoized가 리렌더링</li>
</ol>
<br>

<p>의도한 바와 다르게 Page 컴포넌트는 리렌더링 되었습니다. 이 때 필요한 것이 <code>useCallback</code>입니다.</p>
<br>

<pre><code class="language-jsx">const PageMemoized = React.memo(Page);

const App = () =&gt; {
  const [state, setState] = useState(1);
  const onClick = useCallback(() =&gt; {
    console.log(&#39;Do something on click&#39;);
  }, []);

  return (
    &lt;PageMemoized onClick={onClick} /&gt;
  );
};</code></pre>
<p><strong>위처럼 사용했을 때가 되어서야 onClick은 새로 생성되지 않고 memo된 Page 또한 렌더링되지 않습니다.</strong></p>
<br>

<p>React에서 무거운 계산은 컴포넌트를 리렌더링하고 업데이트하는 계산입니다. 따라서 React가 의도한 useMemo는 renderTree 내부의 특정 부분을 메모할 때 사용하는 것입니다. </p>
<br>

<p>useMemo와 useCallback은 첫 렌더링 때 React가 그 값을 캐시해야 합니다. <strong>따라서, 초기 렌더링에 유리하도록 필요없는 useMemo와 useCallback을 없애고 리렌더링은 변경되어야하는 부분에만 일어나게 만드는 것이 애플리케이션을 최적화 하는 좋은 방식입니다.</strong></p>
<br>

<p>이 글은 아래 글들을 참조하여 작성되었습니다.</p>
<blockquote>
<p><a href="https://velog.io/@hyunjine/React-Rendering-Optimization">https://velog.io/@hyunjine/React-Rendering-Optimization</a></p>
</blockquote>
<blockquote>
<p><a href="https://haragoo30.medium.com/usememo-usecallback%EC%9D%84-%EC%96%B8%EC%A0%9C-%EC%8D%A8%EC%95%BC%EB%90%98%EB%82%98-6a5e6f30f759">https://haragoo30.medium.com/usememo-usecallback%EC%9D%84-%EC%96%B8%EC%A0%9C-%EC%8D%A8%EC%95%BC%EB%90%98%EB%82%98-6a5e6f30f759</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[useEffect와 useLayoutEffect]]></title>
            <link>https://velog.io/@na_0_i/useEffect%EC%99%80-useLayoutEffect</link>
            <guid>https://velog.io/@na_0_i/useEffect%EC%99%80-useLayoutEffect</guid>
            <pubDate>Thu, 09 Mar 2023 14:53:04 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글은 <strong>Kent C.Dodds의 useEffect vs useLayoutEffect</strong>와 Jaewang Lee의 <strong>useEffect 와 useLayoutEffect 의 차이는 무엇일까?</strong>를 참고하여 작성되었습니다.<br> <a href="https://kentcdodds.com/blog/useeffect-vs-uselayouteffect">https://kentcdodds.com/blog/useeffect-vs-uselayouteffect</a> <br> <a href="https://medium.com/@jnso5072/react-useeffect-%EC%99%80-uselayouteffect-%EC%9D%98-%EC%B0%A8%EC%9D%B4%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C-e1a13adf1cd5">https://medium.com/@jnso5072/react-useeffect-%EC%99%80-uselayouteffect-%EC%9D%98-%EC%B0%A8%EC%9D%B4%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C-e1a13adf1cd5</a></p>
</blockquote>
<br>

<h3 id="useeffect">useEffect</h3>
<p>대부분의 경우 <code>useEffect</code>를 사용합니다. 클래스 컴포넌트의 <code>componentDidMount</code>와 <code>componentDidUpdate</code>, <code>componentWillUnmount</code>를 대체합니다.</p>
<br>

<p>한가지 주의할 점은 componentDidMount와 componentDidUpdate는 렌더링 이후 동기적으로 실행되지만 useEffect는 React가 컴포넌트를 렌더링한 후 실행되며 effect 콜백은 브라우저 페인팅을 막지 않는다는 것입니다. 이는 성능적으로 유리하며 당신이 의도한 바와 부합할 확률이 높습니다.</p>
<br>

<p>그러나, 렌더된 시점으로부터 effect 콜백이 DOM과 상호작용하는 그 사이의 시간동안 당신의 effect 콜백이 (DOM node ref를 이용해) DOM과 상호작용을 하고 이 DOM과의 상호작용이 DOM node의 외관을 변화시킨다면 당신은 <strong>useLayoutEffect</strong>를 사용해야 합니다. 그렇지 않으면 유저는 당신의 DOM 변화가 적용될 때마다 화면이 깜빡거리는 것을 볼 수 있게 될 겁니다. 이 순간만이 당신이 useEffect가 아니라 useLayoutEffect를 써야하는 순간입니다.</p>
<br>

<p><code>state 변화 → 컴포넌트 렌더 → 페인트 → useEffect</code></p>
<br>

<h3 id="uselayouteffect">useLayoutEffect</h3>
<p>useLayoutEffect는 리액트가 모든 DOM 상호작용을 끝낸 직후 동기적으로 실행됩니다. 만약 (scroll position이나 다른 style 요소들이 필요한 순간과 같이) 당신이 DOM 측정을 수행한 다음 DOM 변경 혹은 상태 업데이트를 통해 동기적으로 재렌더링해야 하는 경우 유용할 수 있습니다.</p>
<br>

<p>스케줄링 관점에서 이는 componentDidMount와 componentDidUpdate와 동일하게 동작합니다. 당신의 코드는 DOM이 업데이트 된 직후, 그리고 브라우저가 그러한 변화를 그릴 기회를 paint하기 전에 실행될 것입니다.(사용자는 브라우저가 리페인트되기 전까지 변화를 볼 수 없습니다.)</p>
<br>

<p><code>state 변화 → 컴포넌트 렌더 → useLayoutEffect → 페인트</code></p>
<br>

<p>useLayoutEffect는 내부 코드가 모두 실행된 후 painting 작업을 하므로 로직이 복잡할 경우 사용자가 레이아웃을 보는데까지 오랜 시간이 걸릴 수 있다는 단점이 있습니다. 그래서 기본적으로는 useEffect만을 사용하기가 권장됩니다.</p>
<br>

<h3 id="요약">요약</h3>
<ul>
<li>useEffect: DOM이랑 상호작용 할 필요가 없거나 당신의 DOM 변화가 관찰 불가능할 경우(대부분의 경우에 useEffect를 사용합니다)</li>
<li>useLayoutEffect: DOM과 상호작용 해야하거나 DOM 측정을 해야 할 경우</li>
</ul>
<br>

<h4 id="참고">참고</h4>
<blockquote>
<p>Render: DOM Tree 를 구성하기 위해 각 엘리먼트의 스타일 속성을 계산하는 과정<br>Paint: 실제 스크린에 Layout을 표시하고 업데이트하는 과정</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[이벤트 핸들러 네이밍 with React]]></title>
            <link>https://velog.io/@na_0_i/%EC%9D%B4%EB%B2%A4%ED%8A%B8-%ED%95%B8%EB%93%A4%EB%9F%AC-%EB%84%A4%EC%9D%B4%EB%B0%8D-with-React</link>
            <guid>https://velog.io/@na_0_i/%EC%9D%B4%EB%B2%A4%ED%8A%B8-%ED%95%B8%EB%93%A4%EB%9F%AC-%EB%84%A4%EC%9D%B4%EB%B0%8D-with-React</guid>
            <pubDate>Wed, 01 Mar 2023 16:31:51 GMT</pubDate>
            <description><![CDATA[<h1 id="react의-이벤트-핸들러-네이밍">React의 이벤트 핸들러 네이밍</h1>
<p>개발을 하다보면 내가 생각하기에 보기 좋은 함수 이름을 정하게 되는 경우가 많다. &quot;handler나 event 이름은 이렇게 지어야해!&quot; 라는 무조건적인 규칙이 없기도 하고, 팀 내에서 팀원들끼리 이렇게 하자고 정한다 해도 앞부분만 규칙을 따라가고 뒷부분은 각자 쓰고싶은 대로 쓰게 됐는데..</p>
<br>

<p>내 눈에는 보기 좋은 함수 이름이 누군가의 눈에는 좋지 못한 이름이고, 내 눈에는 보기 좋지 않은 함수 이름이 누군가의 눈에는 좋은 이름이라니! 정확한 답이 없을 때 의견을 좁히는 건 너무나 힘든 일이다.</p>
<br>

<h4 id="티끌모아-태산">티끌모아 태..산....?</h4>
<p>이러한 의견 대립이 생길 때마다 자주 등장하는 결론은 <strong>&quot;사소한 문제니 넘어가죠&quot;</strong> 였는데, 이런 사소함이 쌓여서 프로젝트 내 전체 코드의 통일성이나 가독성을 저하시키는 게 되는건 아닐까? 라는 생각이 마음 한구석에 자리잡고 있었다. </p>
<br>

<p><strong>우연히 읽게 된 좋은 글 등장!</strong></p>
<p>Jake Trent라는 분에 의해 쓰인 글이다. 이 글의 모든 저작권은 이 분께 있음을 밝힌다.</p>
<blockquote>
<p><a href="https://jaketrent.com/">https://jaketrent.com/</a></p>
</blockquote>
<blockquote>
<p><a href="https://github.com/jaketrent">https://github.com/jaketrent</a></p>
</blockquote>
<br>

<h2 id="event-handler-naming-in-react-20170309">Event Handler Naming in React (2017.03.09)</h2>
<br>

<h3 id="for-props">FOR PROPS</h3>
<p>props 이름을 정할 때에는 보통 onClick처럼 built-in 이벤트 핸들러 컨벤션과 맞춰서 on을 prefix로 사용한다.</p>
<br>

<p>이벤트 핸들러 컨벤션과 동일하게 on을 접두사로 사용함으로써, 우리는 이벤트 핸들러 함수를 감싼 것이라고 선언하는 것이다.</p>
<br>

<h3 id="for-function-names">FOR FUNCTION NAMES</h3>
<p>함수 이름도 동일한 패턴을 따르되, prefix를 on 대신 handle을 사용한다.</p>
<br>

<h4 id="예시">예시</h4>
<pre><code class="language-html">&lt;MyComponent onAlertClick={handleAlertClick} /&gt;</code></pre>
<p>이렇게 하면<br>
<strong>on</strong>은 이벤트가 여기에 연결되어 있음을 알 수 있고,<br>
<strong>handle</strong>은 이벤트가 실행될 때 호출되는 것임을 알 수 있다.</p>
<br>

<blockquote>
<p>이 때, 다른 동사를 사용하지 않고 click이라는 동사를 사용했는데, 이는 다른 동사와 함께 쓰여도 무관하다. click 대신 handleAlertDismiss와 같이 사용해도 된다는 말인데 사용하는 동사가 실제 동작을 보여주기에 더 나은 방식이라면 꼭 click이 아닌 다른 동사를 mapping 시켜도 좋다는 뜻이다.</p>
</blockquote>
<br>

<h3 id="more-complicated-naming">MORE COMPLICATED NAMING</h3>
<p>네이밍은 더 복잡해질 수도 있다. 필자는 보통 <code>명사 &gt; 동사</code> 순으로 함수를 작성한다고 한다. 그룹화해서 보기 쉽기 때문이라고 하는데 아래 예시를 보면 더 이해가 쉽다.</p>
<h4 id="예시-1">예시</h4>
<pre><code class="language-html">&lt;MyComponent1
    onClickAlert={handleClickAlert}
    onHoverAlert={handleHoverAlert}
/&gt;

&lt;MyComponent2
    onAlertClick={handleAlertClick}
    onAlertHover={handleAlertHover}
/&gt;</code></pre>
<p>MyComponent1의 props보다 MyComponent2의 props를 보는게 alert에 관련된 props를 한 눈에 볼 수 있어서 훨씬 더 편하다. 알파벳 순으로 정렬까지 해주면 더 좋다.</p>
<br>

<h3 id="component-splitting">COMPONENT SPLITTING</h3>
<p>컴포넌트를 어디서 어떻게 자를지에 대해서는 수많은 논의를 가져올 수 있는 주제이고, 각자의 방식을 찾는 예술이다. </p>
<br>

<p>네이밍과 관련지어 생각했을 때, 만약 당신이 한 모듈 안에서 많은 이벤트 핸들러를 정의하고 있다면 당신이 추상화를 잘 했는지에 대해 다시 한번 생각해보고 더 나은 캡슐화를 위해 나눠볼 수 있겠다.</p>
<br>

<p>예를 들어, form.js라는 파일에서 onRegisterSubmit, onLoginSubmit이라는 함수를 갖게 됐을 때 이는 <br></p>
<ul>
<li>registeration-form.js의 onSubmit</li>
<li>login-form.js의 onSubmit</li>
</ul>
<p>위 예시와 같이 좀 더 단순해진 이름을 사용하는 두개의 파일로 나뉠 수 있다.</p>
<br>

<h3 id="using-built-in-handler-names">USING BUILT-IN HANDLER NAMES</h3>
<p>onClick과 onSubmit 같은 리액트 내장 이벤트 핸들러 이름을 그대로 갖다 쓰는 것은 실수를 유발할 수 있으므로 조심해야한다.</p>
<pre><code class="language-html">
// props로 onClick={handleClick}을 내려준 상황이라고 가정
const MyComponent = (props) =&gt; {
    return &lt;div {...props}&gt;&lt;button&gt;이 버튼의 onClick은 어떻게 될까..?&lt;/button&gt;&lt;/div&gt;
}</code></pre>
<p>위 예시 같은 상황에서는 onClick에 이벤트 버블링이 일어나게 되고 예기치 않은 동작이 실행될 수 있다.</p>
<br>

<h3 id="마치며">마치며</h3>
<p>내 코드를 처음 봐도 쉽게 이해할 수 있었으면 좋겠다. 유지보수가 쉬운 코드였으면 좋겠다. 가독성이 좋은 코드였으면 좋겠다. 나는 좋은 코드를 쓰는 개발자가 되었으면 좋겠다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 DeepDive 12장  함수]]></title>
            <link>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-12%EC%9E%A5-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-12%EC%9E%A5-%ED%95%A8%EC%88%98</guid>
            <pubDate>Sun, 26 Feb 2023 14:13:46 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글은 <strong>&#39;모던 자바스크립트 DeepDive&#39;</strong>를  참고하여 작성되었습니다.</p>
</blockquote>
<h3 id="121-함수란">12.1 함수란?</h3>
<p>프로그래밍에서 함수란 <strong>일련의 과정을 문으로 구현하고 코드 블록으로 감싸서 하나의 실행 단위로 정의한 것</strong>이다. 함수는 값이며, 함수를 구분하기 위해 식별자인 함수 이름을 사용할 수 있다.</p>
<img width="493" alt="스크린샷 2022-11-28 오전 9 41 20" src="https://user-images.githubusercontent.com/77482972/204169265-1bc243ed-8cb8-4279-ba48-38ab44c836a5.png">

<ul>
<li>매개변수: 함수 내부로 입력을 전달받는 변수</li>
<li>인수: 입력</li>
<li>반환값: 출력</li>
</ul>
<br>

<p>함수는 함수 정의를 통해 함수를 생성하고, 인수를 매개변수를 통해 함수에 전달하면서 명시적으로 실행(함수 호출)한다. 함수를 호출하면 코드블록을 실행하고, 실행 결과(반환값)를 반환한다.</p>
<br>

<h3 id="122-함수를-사용하는-이유">12.2 함수를 사용하는 이유</h3>
<p>함수는 <strong>코드의 재사용</strong> 측면에서 매우 유용하다.</p>
<br>

<p>함수를 사용하지 않고 같은 코드를 중복해서 작성하면 그 함수를 수정해야 할 때 중복된 횟수만큼 수정해야한다. 함수는 코드의 중복을 억제하고 재사용성을 높임으로써 유지보수의 편의성과 코드의 신뢰성을 높이는 효과가 있다.</p>
<br>

<h3 id="123-함수-리터럴">12.3 함수 리터럴</h3>
<p>함수 리터럴은 function 키워드, 함수 이름, 매개 변수 목록, 함수 몸체로 구성된다.</p>
<pre><code class="language-javascript">// 변수 f에 함수 add가 할당되었다.
// 즉, 함수 리터럴은 평가되어 값을 생성한다.
var f = function add(x, y) {
    return x + y;
}</code></pre>
<p><strong>함수 이름</strong></p>
<ul>
<li>식별자다.</li>
<li>함수 이름은 함수 몸체 내에서만 참조할 수 있는 식별자다 ???</li>
<li>함수 이름은 생략 가능하다.</li>
</ul>
<p><strong>매개변수 목록</strong></p>
<ul>
<li>소괄호로 감싸고 쉼표로 구분한다.</li>
<li>매개변수 목록은 순서에 의미가 있다.</li>
<li>매개변수는 변수와 동일하게 취급된다. → 식별자 네이밍 규칙 준수</li>
</ul>
<br>

<p>함수 리터럴도 평가되어 값을 생성하며 이 값은 객체다. 하지만 일반 객체와 달리 함수는 호출할 수 있으며 일반 객체에는 없는 함수 객체만의 고유한 프로퍼티를 갖는다.</p>
<br>

<h3 id="124-함수-정의">12.4 함수 정의</h3>
<p>함수 정의란 함수를 호출하기 전에 매개변수, 실행할 문들, 반환할 값을 지정하는 것이다.</p>
<br>

<h4 id="1241--함수-선언문">12.4.1  함수 선언문</h4>
<p>함수 선언문은 함수 리터럴과 형태가 동일하다. 단, 함수 선언문은 함수 이름을 생략할 수 없다.</p>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">function add(x, y) {
    return x + y;
}

// 불가능
function (X, y) {
    return x + y;
}</code></pre>
<br>

<p>함수 선언문은 함수 이름을 생략할 수 없다는 점을 제외하면 함수 리터럴과 형태가 동일하기 때문에 기명함수 리터럴은 함수 선언문 혹은 함수 리터럴 표현식으로 해석될 가능성이 있다. 즉, 기명 함수 리터럴은 코드 문맥(함수 리터럴을 변수에 할당하거나 피연산자로 사용하면 함수 리터럴 표현식으로 해석)에 따라 해석이 달라질 수 있다. </p>
<br>

<pre><code class="language-javascript">// 기명 함수 리터럴
// 함수 선언문으로 해석
function foo() { console.log(&#39;foo&#39;); }

foo(); // foo

// 기명 함수 리터럴
// 함수 리터럴 표현식으로 해석
(function bar() { console.log(&#39;bar&#39;}; )

bar(); // ReferenceError: bar is not defined</code></pre>
<p>위 예제에서 연산자 내에 있는 함수 리터럴 bar는 함수 리터럴 표현식으로 해석된다.</p>
<br>

<p>함수 선언문은 함수 이름을 생략할 수 없다는 점을 제외하면 함수 리터럴과 형태가 동일하지만, 함수 선언문으로 선언된 함수(foo)는 호출할 수 있으나 함수 리터럴 표현식으로 생성된 함수(bar)는 호출할 수 없다는 것에서 차이를 갖는다. 왜냐하면, <strong>함수 리터럴에서 함수 이름은 함수 몸체 내에서만 참조할 수 있는 식별자</strong>이므로 <strong>함수 몸체 외부에서는 함수 이름으로 함수를 호출할 수 없기 때문</strong>이다.</p>
<br>

<p>이와 달리, 자바스크립트 엔진은 함수 선언문으로 함수 객체를 생성할 때, <strong>함수를 호출하기 위해 함수 이름과 동일한 이름의 식별자를 암묵적으로 생성해 거기에 함수 객체를 할당</strong>한다. </p>
<p><img width="564" alt="스크린샷 2022-11-29 오후 9 51 02" src="https://user-images.githubusercontent.com/77482972/204533808-176a1e87-a8f1-4d8f-8b14-c6200f1d71b8.png"> <img width="656" alt="스크린샷 2022-11-29 오후 9 51 15" src="https://user-images.githubusercontent.com/77482972/204533852-9b57da24-9355-4bd7-9ef5-1d60c51f8645.png"></p>
<br>

<p>즉, 함수는 <strong>함수 이름으로 호출하는 것이 아니라 함수 객체를 가리키는 식별자로 호출</strong>한다.</p>
<br>

<img width="705" alt="스크린샷 2022-11-29 오후 9 52 35" src="https://user-images.githubusercontent.com/77482972/204534122-9d2f8df7-fa90-4bce-a508-20925f32764a.png">


<br>

<h4 id="1242-함수-표현식">12.4.2 함수 표현식</h4>
<p>자바스크립트의 함수는 일급 객체(값의 성질을 갖는 객체)다. 함수는 일급 객체이므로 함수 리터럴로 생성한 함수 객체를 변수에 할당할 수 있는데 이를 함수 표현식이라고 한다. 함수 표현식의 함수 리터럴은 함수 이름을 생략하는 것이 일반적이다.</p>
<pre><code class="language-javascript">var add = function foo(x, y) {
    return x + y;
}

// 함수 객체를 가리키는 식별자로 호출
console.log(add(2, 5));

// 함수 이름은 함수 몸체 내부에서만 유효한 식별자
console.log(foo(2, 5)); // ReferenceError: foo is not defined</code></pre>
<p>함수를 호출할 때는 함수 이름이 아니라 함수 객체를 가리키는 식별자를 사용해야 하므로 <strong>함수 이름으로 함수를 호출할 수 없다.</strong></p>
<br>

<p>함수 선언문과 함수 표현식은 유사하게 동작하는 것처럼 보이지만, 함수 선언문은 <strong>표현식이 아닌 문</strong>이고 함수 표현식은 <strong>표현식인 문</strong>이라는 차이가 있다.</p>
<br>

<h4 id="1243-함수-생성-시점과-함수-호이스팅">12.4.3 함수 생성 시점과 함수 호이스팅</h4>
<p>함수 선언문으로 정의한 함수와 함수 표현식으로 정의된 함수의 생성 시점은 다르다.</p>
<br>

<h5 id="함수-선언문">함수 선언문</h5>
<ul>
<li>함수 호이스팅 발생</li>
<li>런타임 이전에 자바스크립트 엔진에 의해 먼저 실행</li>
<li>함수 이름과 동일한 식별자를 암묵적으로 생성하고 생성된 함수 객체를 할당</li>
<li>함수 선언문 이전에 함수를 참조할 수 있으며 호출할 수 있다.</li>
</ul>
<h5 id="함수-표현식">함수 표현식</h5>
<ul>
<li>변수 호이스팅 발생</li>
<li>변수에 할당되는 값이 함수 리터럴인 문</li>
<li>변수 선언문과 변수 할당문을 한 번에 기술한 축약 표현과 동일하게 동작</li>
<li>변수 선언은 런타임 이전에 실행되어 undefined로 초기화되지만</li>
<li>변수 할당문은 런타임에 평가되므로, 함수 리터럴도 할당문이 실행되는 시점에 평가되어 함수 객체가 된다.</li>
</ul>
<br>

<p><strong>예시</strong></p>
<pre><code class="language-javascript">// 함수 참조
console.dir(add); // add(x, y) ← 함수 호이스팅
console.dir(sub); // undefined ← 변수 호이스팅

// 함수 호출
console.log(add(2, 5)); // 7 ← 함수 호출 가능
console.log(sub(2, 5)); TypeError: sub is not a function ← 함수 호출 불가능

// 함수 선언문
function add(x, y) {
    return x + y;
}

// 함수 표현식
function sub(x, y) {
    return x - y;
}</code></pre>
<p>따라서 <strong>함수 표현식으로 정의한 함수는 반드시 함수 표현식 이후에 참조 또는 호출</strong>해야 한다.</p>
<br>

<h4 id="1244-function-생성자-함수">12.4.4 Function 생성자 함수</h4>
<p>Function 생성자 함수로 함수를 생성하는 것은 일반적이지 않고 바람직하지 않다. 함수 선언문이나 함수 표현식으로 생성한 함수와 다르게 동작한다.</p>
<pre><code class="language-javascript">// 빌트인 함수인 Function 생성자 함수 이용
// new 연산자 생략 가능
var add = new Function(&#39;x&#39;, &#39;y&#39;, &#39;return x + y&#39;);</code></pre>
<br>

<h4 id="1245-화살표-함수">12.4.5 화살표 함수</h4>
<p>function 키워드 대신 =&gt; 를 사용해 좀 더 간략한 방법으로 함수를 선언하는 방식이다. 화살표 함수는 익명함수로 정의한다. 화살표 함수는 기존 함수보다 표현이 간략하며 내부 동작 또한 간략화되어 있다.</p>
<pre><code class="language-javascript">const add = (x, y) =&gt; x + y;</code></pre>
<br>

<h3 id="125-함수-호출">12.5 함수 호출</h3>
<p>함수를 호출하면 현재 실행 흐름을 중단하고 호출된 함수로 실행 흐름을 옮긴다.</p>
<br>

<h4 id="1251-매개변수와-인수">12.5.1 매개변수와 인수</h4>
<p>함수 외부에서 함수 내부로 값을 전달할 필요가 있는 경우 매개변수를 사용해 인수를 전달한다. </p>
<h5 id="매개변수">매개변수</h5>
<ul>
<li>함수를 정의할 때 선언</li>
<li>함수 몸체 내부에서 변수와 동일하게 취급</li>
<li>함수 호출 → 매개변수 생성 후 undefined로 초기화 → 인수 할당</li>
<li>함수 몸체 외부에서 참조할 수 없다.</li>
<li>매개변수의 개수와 인수의 개수는 다를 수 있으며, 인수가 할당되지 않은 매개변수의 값은 undefined, 초과된 인수는 무시된다.</li>
</ul>
<br>

<h4 id="1252-인수-확인">12.5.2 인수 확인</h4>
<p>ES6에서 도입된 매개변수 기본값을 사용하면 인수 체크 및 초기화를 간소화할 수 있다.</p>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">
// a, b, c에 부적절한 타입이 들어올 가능성(문자열이 들어올 가능성)
// 인수가 매개변수 개수만큼 전달되지 않을 가능성
// 두 가지를 한번에 체크 및 초기화 가능

function add(a = 0, b = 0, c = 0) {
    return a + b + c;
}</code></pre>
<br>

<h4 id="1253-매개변수의-최대-개수">12.5.3 매개변수의 최대 개수</h4>
<p>매개변수의 최대 개수에 대해 명시적으로 제한하고 있지는 않지만, 매개변수는 코드를 이해하는 데 방해되는 요소이므로 이상적인 매개변수 개수는 0개이며 적을수록 좋다.(이상적인 함수는 한 가지 일만 해야 하며 가급적 작게 만들어야 한다.) 매개변수는 최대 3개 이상을 넘지 않을 것을 권장하며 그 이상의 매개변수가 필요하다면 객체를 인수로 전달하는 것이 유리하다.</p>
<br>

<p>객체를 인수로 사용할 경우</p>
<ul>
<li>프로퍼티 키만 정확히 지정하면 매개변수 순서를 신경쓰지 않아도 된다.</li>
<li>프로퍼티 키를 통해 명시적으로 인수의 의미가 설명되므로 코드의 가독성이 좋아진다.</li>
</ul>
<br>

<h4 id="1254-반환문">12.5.4 반환문</h4>
<p>return 키워드와 표현식으로 이뤄진 반환문을 사용해 반환할 수 있다.</p>
<h5 id="반환문">반환문</h5>
<ul>
<li>함수의 실행을 중단 후 함수 몸체를 빠져나간다.</li>
<li>return 뒤의 표현식을 평가해 반환</li>
<li>함수 호출 표현식은 반환값으로 평가된다.</li>
<li>반환문이 생략될 경우 마지막 문까지 실행한 후 undefined 반환</li>
<li>함수 내부에서만 사용가능</li>
</ul>
<br>

<h3 id="126-참조에-의한-전달과-외부-상태의-변경">12.6 참조에 의한 전달과 외부 상태의 변경</h3>
<p>매개변수도 함수 몸체 내부에서 변수와 동일하게 취급되므로 매개변수 또한 타입에 따라 값에 의한 전달, 참조에 의한 전달 방식을 그대로 따른다.</p>
<br>

<p><strong>원시 타입 인수</strong></p>
<ul>
<li>값 자체가 복사되어 전달</li>
<li>원본 훼손 X</li>
</ul>
<br>

<p><strong>객체 타입 인수</strong></p>
<ul>
<li>참조 값이 복사되어 전달</li>
<li>참조 값을 통해 객체가 변경되므로 원본 훼손 ㅇ</li>
</ul>
<br>

<h3 id="127-다양한-함수의-형태">12.7 다양한 함수의 형태</h3>
<h4 id="1271-즉시-실행-함수">12.7.1 즉시 실행 함수</h4>
<p>함수 정의와 동시에 즉시 호출되는 함수를 즉시 실행 함수라고 한다. 단 한 번만 호출되며 다시 호출할 수 없다.</p>
<pre><code class="language-javascript">(function() {
    var a = 3;
    var b = 5;
    return a * b;
}())</code></pre>
<p>익명 함수를 사용하는 것이 일반적이지만 기명 즉시 실행 함수도 사용할 수 있다. 하지만 <code>그룹연산자 ()</code>내의 기명 함수는 함수 선언문이 아니라 함수 리터럴로 평가되기 때문에 함수 외부에서 식별자를 참조할 수 없으므로 즉시 실행 함수를 다시 호출할 수 없다는 것은 동일하다.</p>
<pre><code class="language-javascript">(function foo(){
    var a = 3;
    var b = 5;
    return a * b;
}());

foo(); // ReferenceError</code></pre>
<p><strong>즉시 실행 함수는 반드시 <code>그룹연산자 ()</code>로 감싸야 한다.</strong> </p>
<pre><code class="language-javascript">// 1번 케이스
function (){}()

// 함수 선언문은 함수 이름을 생략할 수 없다.


// 2번 케이스
function foo(){}()

// 위와 같이 실행할 경우
// 세미콜론 자동 삽입 기능에 의해 함수 뒤에 ; 가 붙는다
// function foo(){};(); 의 형태가 된다.
// 따라서 함수 선언문 뒤의 ()는 함수 호출 연산자가 아니라 그룹 연산자로 해석되고
// 그룹 연산자에 피연산자가 없기 때문에 에러가 발생한다.</code></pre>
<p>그룹 연산자의 피연산자는 값으로 평가되므로 함수를 그룹 연산자로 감싸면 함수 리터럴로 평가되어 함수 객체가 된다.</p>
<br>

<p>즉시 실행 함수도 일반 함수처럼 값을 반환할 수도 있고 인수를 전달할 수도 있다.</p>
<pre><code class="language-javascript">var res = (function() {
    var a = 3;
    var b = 5;
    return a * b;
}());

var res2 = (function (a, b){
    return a * b;
}(3, 5));</code></pre>
<br>

<h4 id="1272-재귀-함수">12.7.2 재귀 함수</h4>
<p>재귀 함수는 재귀 호출(함수가 자기 자신을 호출)을 수행 하는 함수를 말한다. 함수 이름은 함수 몸체 내부에서만 유효하므로 함수 이름을 사용해 자기 자신을 호출할 수도 있고, 함수 표현식의 경우 식별자로도 재귀 호출을 할 수 있다(단 외부에서 호출할 때는 반드시 식별자로 함수를 호출). 재귀 함수는 자기 자신을 무한 호출하기 때문에 재귀 호출을 멈출 수 있는 <strong>탈출 조건을 반드시 만들어야 한다.</strong></p>
<br>

<p>재귀 함수는 무한 반복에 빠질 위험이 있기 때문에 재귀 함수를 사용하는 것이 직관적으로 이해하기 쉬울 때만 한정적으로 사용한다.</p>
<br>

<h4 id="1273-중첩-함수">12.7.3 중첩 함수</h4>
<p>함수 내부에 정의된 함수를 중첩 함수 또는 내부 함수라고 한다. 중첩 함수를 포함하는 함수는 외부 함수 라고 한다. 중첩 함수는 외부 함수 내부에서만 호출할 수 있다.</p>
<br>

<h4 id="1274-콜백-함수">12.7.4 콜백 함수</h4>
<p>함수의 일부가 다르면 매번 함수를 새롭게 정의해야 한다. 해결 방법으로는 함수를 합성하는 방법이 있다. 공통 로직은 미리 정의해두고, 변경 로직은 추상화해서 전달하는 것이다. 함수는 일급 객체이므로 매개변수를 통해 함수로 전달할 수 있다.</p>
<br>

<p><strong>함수의 매개변수를 통해 다른 함수 내부로 전달되는 함수를 콜백함수</strong>라고 하며 <strong>매개변수를 통해 함수 외부에서 콜백 함수를. 전달 받은 함수를 고차함수</strong>라고 한다. 고차 함수는 콜백 함수의 호출 시점을 결정해서 호출하며, 콜백 함수에 인수를 전달할 수 있다.</p>
<br>

<p>콜백함수로 전달된 함수 리터럴은 고차 함수가 호출될 때마다 평가되어 함수 객체를 생성하므로, 콜백 함수가 자주 호출되거나 다른 곳에서 호출 될 필요가 있다면 외부에서 콜백 함수를 정의한 뒤 고차 함수에 전달하는 것이 효율적이다.</p>
<br>

<p>콜백 함수는 함수형 프로그래밍 패러다임뿐만 아니라 <strong>비동기 처리</strong>에 활용되는 중요한 패턴이다. </p>
<pre><code class="language-javascript">setTimeout(function() {
    console.log(&#39;1초 경과&#39;);
}, 1000);</code></pre>
<br>

<p>콜백 함수는 배열 고차 함수에서도 사용된다.<br>
<code>map</code>, <code>filter</code>, <code>reduce</code></p>
<br>

<h4 id="1275-순수-함수와-비순수-함수">12.7.5 순수 함수와 비순수 함수</h4>
<h5 id="순수-함수">순수 함수</h5>
<ul>
<li>어떤 외부 상태에 의존하지도 변경하지도 않는</li>
<li>부수 효과가 없는 함수</li>
<li>동일한 인수가 전달되면 언제나 동일한 값을 반환</li>
<li>오직 인수에게만 의존해 값을 생성해 반환</li>
<li>인수에 의해 반환 값이 달라지므로 일반적으로 하나 이상의 인수를 전달 받는다.</li>
</ul>
<h5 id="비순수-함수">비순수 함수</h5>
<ul>
<li>외부 상태에 의존하거나 외부 상태를 변경하는</li>
<li>부수 효과가 있는 함수</li>
</ul>
<br>

<p>함수가 외부 상태를 변경하면 상태 변화를 추적하기 어렵기 때문에, 순수 함수를 사용하는 것이 좋다.</p>
<br>

<p><strong>함수형 프로그래밍</strong>은 순수 함수와 보조 함수의 조합을 통해 <strong>외부 상태를 변경하는 부수효과를 최소화해서 불변성을 지향하는 프로그래밍 패러다임</strong>이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 DeepDive 11장 원시 값과 객체의 비교]]></title>
            <link>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-11%EC%9E%A5-%EC%9B%90%EC%8B%9C-%EA%B0%92%EA%B3%BC-%EA%B0%9D%EC%B2%B4%EC%9D%98-%EB%B9%84%EA%B5%90</link>
            <guid>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-11%EC%9E%A5-%EC%9B%90%EC%8B%9C-%EA%B0%92%EA%B3%BC-%EA%B0%9D%EC%B2%B4%EC%9D%98-%EB%B9%84%EA%B5%90</guid>
            <pubDate>Sat, 25 Feb 2023 13:29:29 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글은 <strong>&#39;모던 자바스크립트 DeepDive&#39;</strong>를  참고하여 작성되었습니다.</p>
</blockquote>
<p>자바스크립트가 제공하는 데이터 타입은 원시 타입과 객체 타입으로 구분할 수 있다.</p>
<h5 id="원시-타입과-객체-타입의-차이점">원시 타입과 객체 타입의 차이점</h5>
<ul>
<li>원시 값은 변경 불가능한 값 / 객체 타입 값은 변경 가능한 값</li>
<li>원시 값은 변수에 할당하면 변수에 실제 값이 저장된다. / 객체는 변수에 할당하면 참조 값이 저장된다.</li>
<li>원시 값을 다른 변수에 할당하면 값이 복사되어 전달 된다.(값에 의한 전달) / 객체는 원본의 참조값이 복사되어 전달(참조에 의한 전달)</li>
</ul>
<br>

<h3 id="111-원시-값">11.1 원시 값</h3>
<h4 id="1111-변경-불가능한-값">11.1.1 변경 불가능한 값</h4>
<p><strong>원시 값은 변경 불가능한 값이다.</strong><br>
즉, 원시 값을 할당한 변수에 새로운 원시 값을 재할당 하면 이전 원시값을 변경하는 것이 아니라 새로운 메모리 공간을 확보하고 재할당한 원시 값을 저장한 후 변수가 새롭게 재할당한 원시값을 가리킨다.</p>
<img width="698" alt="스크린샷 2022-11-23 오후 8 54 39" src="https://user-images.githubusercontent.com/77482972/203540601-9e3afcfd-77c3-4007-bdea-581ab3a815c9.png">

<h5 id="불변성">불변성</h5>
<p>위 그림과 같이 원시 값은 값을 직접 변경할 수가 없기 때문에 변수 값을 변경하기 위해서는 새로운 메모리 공간을 확보하고, 재할당한 값을 저장한 후, 참조하던 메모리 공간의 주소를 변경한다. 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없다.</p>
<br>

<h4 id="1112-문자열과-불변성">11.1.2 문자열과 불변성</h4>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">var str = &#39;string&#39;;
str[0] = &#39;A&#39;;

console.log(str); // string</code></pre>
<p>위 예시와 같이, 문자열은 배열과 유사하게 각 문자에 접근할 수 있지만, 이미 생성된 문자열의 일부 문자를 변경해도 반영되지 않는다. 문자열은 변경 불가능한 값, 읽기 전용 값으로서 변경할 수 없기 때문이다. 이처럼 원시 값은 예기치 못한 변경으로서 자유롭기 때문에 데이터의 신뢰성을 보장한다.</p>
<br>

<h4 id="1113-값에-의한-전달">11.1.3 값에 의한 전달</h4>
<p>변수에 원시 값을 갖는 변수를 할당하면 할당 받는 변수에는 할당 되는 변수의 원시값이 복사되어 전달되는 데 이를 값에 의한 전달이라고 한다.</p>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">var score = 80;
var copy = score;
score = 100;</code></pre>
<img width="653" alt="스크린샷 2022-11-23 오후 9 10 31" src="https://user-images.githubusercontent.com/77482972/203543645-eeedc173-7203-4f5d-9ed7-42144c16de69.png">

<p>score 변수와 copy 변수가 숫자 값 80을 갖는다는 점에서는 동일하지만 80은 <strong>각각 다른 메모리 공간에 저장된 별개의 값이다.</strong> 따라서, score 변수의 값을 변경하더라도 copy 변수의 값에는 어떠한 영향도 주지 않는다.</p>
<br>

<blockquote>
<p>엄격하게 표현하면 변수에는 값이 전달되는 것이 아니라 메모리 주소가 전달되기 때문에 값에 의한 전달이라는 용어가 적절하지 않을 수 있다. 단, 전달된 메모리 주소를 통해 메모리 공간에 접근하면 값을 참조할 수 있다.</p>
</blockquote>
<p>중요한 것은 두 변수의 원시 값은 <strong>서로 다른 메모리 공간에 저장된 별개의 값이 되어 서로 간섭할 수 없다</strong>는 것이다.</p>
<br>

<h3 id="112-객체">11.2 객체</h3>
<p>객체는 프로퍼티 개수가 정해져 있지 않고, 동적으로 추가, 삭제될 수 있다. 또한 프로퍼티 값에 제한도 없기 때문에 객체는 확보해야할 메모리 공간의 크기를 사전에 정해 둘 수 없다. 따라서 객체는 원시 값과는 다른 방식으로 동작하도록 설계되어 있다.</p>
<br>

<h4 id="1121-변경-가능한-값">11.2.1 변경 가능한 값</h4>
<p><strong>객체는 변경 가능한 값이다.</strong> 원시 값이 할당된 변수는 메모리 주소를 통해 원시 값에 접근할 수 있다. 하지만 객체가 할당된 변수는 메모리 주소를 통해 접근하면 <strong>참조 값</strong>에 접근할 수 있다. 참조 값은 메모리 공간의 주소 그 자체다.</p>
<img width="326" alt="스크린샷 2022-11-23 오후 9 20 27" src="https://user-images.githubusercontent.com/77482972/203545432-326fd647-7a05-4248-a164-f65b36e127f1.png">


<p>위 그림과 같이, 객체를 할당한 변수를 참조하면 메모리에 저장되어 있는 참조 값을 통해 실제 객체에 접근한다. &#39;변수는 객체를 참조하고 있다&#39;, &#39;변수는 객체를 가리키고 있다&#39;라고 표현하는 이유다.</p>
<br>

<p><strong>객체를 할당한 변수는 재할당 없이 객체를 직접 변경할 수 있다.</strong> 재할당 없이 프로퍼티 동적 추가, 삭제, 프로퍼티 값 갱신 등이 가능하다. 객체는 변경 가능한 값이기 때문에 메모리에 저장된 객체를 직접 수정할 수 있고, 이 때 객체를 할당한 변수에 재할당을 하지 않았기 때문에 참조 값은 변경되지 않는다.</p>
<img width="325" alt="스크린샷 2022-11-23 오후 9 24 10" src="https://user-images.githubusercontent.com/77482972/203546151-fe51b4ab-c82f-49e1-9559-60af6d72ceaf.png">

<p>위와 같이 객체를 관리하는 이유는, 객체를 변경할 때마다 이전 값을 복사해서 새로 생성하는 방식이 명확하고 신뢰성이 보장될 수는 있어도, 크기가 매우 클 수도 있고, 크기가 일정하지 않으며, 프로퍼티 값이 객체일 수도 있어서 비용이 많이 들기 때문이다. 따라서, <strong>메모리를 효율적으로 사용하기 위해</strong> 객체는 변경 가능한 값으로 설계되어 있다. </p>
<br>

<p>이러한 구조적 단점에 따른 부작용이 있다면, <strong>여러개의 식별자가 하나의 객체를 공유할 수 있다는 것이다.</strong></p>
<h4 id="1122-참조에-의한-전달">11.2.2 참조에 의한 전달</h4>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">var person = {
    name: &quot;Lee&quot;,
}

var copy = person; // 얕은 복사</code></pre>
<img width="688" alt="스크린샷 2022-11-23 오후 9 31 59" src="https://user-images.githubusercontent.com/77482972/203547734-a208d04a-0543-464e-91a9-d7621abe8e2e.png">

<p>person과 copy는 저장된 메모리 주소는 다르지만 동일한 참조 값을 갖는다.(두 개의 식별자가 하나의 객체를 공유하는 상황) 따라서, <strong>원본 또는 사본 중 어느 한쪽에서 객체를 변경하면 서로 영향을 주고 받는다.</strong></p>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">var person = {
    name: &quot;Lee&quot;,
}

var copy = person; // 얕은 복사

console.log(copy === person); // true

copy.name = &#39;Kim&#39;;
person.address = &#39;Seoul&#39;;

console.log(person); // {name: &#39;Kim&#39;, address: &quot;Seoul&quot;};
console.log(copy); // {name: &#39;Kim&#39;, address: &quot;Seoul&quot;};</code></pre>
<br>

<p><strong>값에 의한 전달과 참조에 의한 전달 모두 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 면에서는 동일하다. 다만 그 값이 원시 값이냐 참조 값이냐에 따른 차이만 있을 뿐이다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 DeepDive 10장 객체 리터럴]]></title>
            <link>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-10%EC%9E%A5-%EA%B0%9D%EC%B2%B4-%EB%A6%AC%ED%84%B0%EB%9F%B4</link>
            <guid>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-10%EC%9E%A5-%EA%B0%9D%EC%B2%B4-%EB%A6%AC%ED%84%B0%EB%9F%B4</guid>
            <pubDate>Tue, 21 Feb 2023 12:49:20 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글의 <strong>&#39;모던 자바스크립트 DeepDive&#39;</strong>를  참고하여 작성되었습니다.</p>
</blockquote>
<h3 id="101-객체란">10.1 객체란?</h3>
<p>자바스크립트는 객체 기반의 프로그래밍 언어이며, 자바스크립트를 구성하는 거의 모든 것(원시 값을 제외한 나머지 값)이 객체이다.</p>
<h5 id="원시-타입">원시 타입</h5>
<ul>
<li>단 하나의 값만 나타낸다.</li>
<li>변경 불가능한 값(immutable value)</li>
</ul>
<h5 id="객체">객체</h5>
<ul>
<li>다양한 타입의 값을 하나의 단위로 구성한 복합적인 자료구조</li>
<li>변경 가능한 값(mutable value)</li>
<li>0개 이상의 프로퍼티로 구성된 집합이며, 프로퍼티는 key와 value로 구성된다.</li>
</ul>
<p>자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값이 될 수 있다. 이 때, 프로퍼티 값으로 함수가 사용될 경우 메서드라 부른다. 이처럼 객체는 프로퍼티와 메서드로 구성된 집합체다. </p>
<img width="297" alt="스크린샷 2022-11-23 오후 7 24 08" src="https://user-images.githubusercontent.com/77482972/203523533-602afaf2-c1dd-4e4a-95c5-f8cb47ee7ad2.png">

<ul>
<li><strong>프로퍼티</strong>: 객체의 상태를 나타내는 값<br></li>
<li><strong>메서드</strong>: 프로퍼티를 참조하고 조작할 수 있는 동작</li>
<li>이처럼 객체는 프로퍼티와 메서드를 모두 포함할 수 있기 때문에 상태와 동작을 하나의 단위로 구조화할 수 있어서 유용하다.</li>
</ul>
<br>

<h3 id="102-객체-리터럴에-의한-객체-생성">10.2 객체 리터럴에 의한 객체 생성</h3>
<p>클래스 기반 객체지향 언어는 클래스를 사전에 정의하고 필요한 시점에 new 연산자와 함께 생성자를 호출해 인스턴스를 생성하는 방식으로 객체를 생성한다. 자바스크립트는 프로토타입 기반 객체지향 언어로서 다양한 객체 생성 방식(객체 리터럴, Object 생성자 함수, 생성자 함수, Object.create 메서드, 클래스)을 지원한다.</p>
<h5 id="객체-리터럴">객체 리터럴</h5>
<p>객체 생성에서 가장 일반적이고 간단한 방법으로 중괄호 내에 0개 이상의 프로퍼티를 정의한다. 객체 리터럴에 프로퍼티를 포함해 객체를 생성함과 동시에 프로퍼티를 만들 수도 있고, 객체를 생성한 이후에 프로퍼티를 동적으로 추가할 수도 있다.</p>
<br>

<h3 id="103-프로퍼티">10.3 프로퍼티</h3>
<p>객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값으로 구분된다.</p>
<h5 id="프로퍼티-키">프로퍼티 키</h5>
<ul>
<li>빈 문자열을 포함하는 모든 문자열 또는 심벌 값이 들어올 수 있으나 <strong>일반적으로 문자열을 사용</strong>한다.</li>
<li>프로퍼티 값에 접근할 수 있는 이름으로서 <strong>식별자 역할</strong>을 한다.</li>
<li>식별자 네이밍 규칙을 반드시 따를 필요는 없지만, 식별자 네이밍 규칙을 따르지 않는 이름에는 따옴표를 사용한다.(권장 X)</li>
<li>문자열 또는 문자열로 평가되는 표현식을 사용해 <strong>프로퍼티 키를 동적으로 생성 가능</strong>하다. 이 때, 사용할 프로퍼티 키를 <code>[]</code>로 묶어야 한다.</li>
<li>빈 문자열을 프로퍼티 키로 사용해도 되지만 키로서 의미를 갖지 못하므로 권장되지 않는다.</li>
<li>문자열이나 심벌 값 외의 값을 프로퍼티 키에 사용하면 암묵적 타입 변환을 통해 문자열이 된다.(프로퍼티 키로 숫자를 사용할 경우 내부적으로 문자열로 변환)</li>
<li>존재하는 <strong>키를 중복 선언하면</strong> 나중에 선언한 프로퍼티 키가 먼저 선언한 프로퍼티 키를 <strong>덮어쓴다.</strong></li>
</ul>
<br>

<h3 id="104-메서드">10.4 메서드</h3>
<p>프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해 메서드라 부른다. 즉, 메서드는 객체에 묶여 있는 함수를 의미한다. </p>
<br>

<h3 id="105-프로퍼티-접근">10.5 프로퍼티 접근</h3>
<p>프로퍼티에 접근하는 방법은 두가지이다.</p>
<ol>
<li>마침표 표기법(.): <code>객체.프로퍼티키</code></li>
<li>대괄호 표기법([...]): <code>객체[&#39;프로퍼티키&#39;]</code><ul>
<li>접근 연산자 내부에 지정하는 프로퍼티 키는 따옴표로 감싼 문자열이어야 한다.</li>
<li>식별자 네이밍을 준수하지 않는 프로퍼티 키일 경우엔 대괄호 표기법을 사용한다.</li>
</ul>
</li>
</ol>
<p>좌측에는 객체로 평가되는 표현식을 기술하고, 마침표 우측 혹은 대괄호 내부에는 프로퍼티 키를 지정해 접근한다. 이 때, 객체에 존재하지 않는 프로퍼티에 접근하면 undefined를 반환한다.</p>
<br>

<h3 id="106-프로퍼티-값-갱신">10.6 프로퍼티 값 갱신</h3>
<p>이미 존재하는 프로퍼티에 값을 할당하면 프로퍼티 값이 갱신된다.</p>
<br>

<h3 id="107-프로퍼티-동적-생성">10.7 프로퍼티 동적 생성</h3>
<p>존재하지 않는 프로퍼티에 값을 할당하면 프로퍼티가 동적으로 생성되어 추가되고 프로퍼티 값이 할당된다.</p>
<br>

<h3 id="108-프로퍼티-삭제">10.8 프로퍼티 삭제</h3>
<p><code>delete 연산자</code>는 객체의 프로퍼티를 삭제한다. 존재하지 않는 프로퍼티를 삭제하면 에러없이 무시된다.</p>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">var person ={
    name: &#39;Lee&#39;
};

person.age = 20; // 프로퍼티 동적 생성

delete person.age; // 프로퍼티 삭제
delete person.address; // 에러 발생 x</code></pre>
<br>

<h3 id="109-es6에서-추가된-객체-리터럴의-확장-기능">10.9 ES6에서 추가된 객체 리터럴의 확장 기능</h3>
<h4 id="1091-프로퍼티-축약-표현">10.9.1 프로퍼티 축약 표현</h4>
<p>프로퍼티 값으로 변수를 사용하는 경우, 변수 이름과 프로퍼티 키가 동일하다면 프로퍼티 키를 생략할 수 있다. 프로퍼티 키는 변수 이름으로 자동 생성된다.</p>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">let x = 1, y = 2;

const obj = {x, y};

console.log(obj); // {x: 1, y: 2}</code></pre>
<br>

<h4 id="1092-계산된-프로퍼티-이름">10.9.2 계산된 프로퍼티 이름</h4>
<p>ES5에서는 계산된 프로퍼티 이름으로 프로퍼티 키를 동적 생성하기 위해서는 객체 리터럴 외부에서 대괄호 표기법(<code>[...]</code>)을 사용해야 했으나, ES6에서는 객체 리터럴 내부에서도 계산된 프로퍼티 이름으로 프로퍼티 키를 동적 생성할 수 있다.</p>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">const prefix = &quot;prop&quot;;
let i = 0;

const obj = {
    [`${prefix}-${++i}`]: i,
    [`${prefix}-${++i}`]: i,
    [`${prefix}-${++i}`]: i,
};

console.log(obj); // {prop-1: 1, prop-2: 2, prop-3: 3}</code></pre>
<br>

<h4 id="1093-메서드-축약-표현">10.9.3 메서드 축약 표현</h4>
<p>ES6에서는 메서드를 정의할 때 function 키워드를 생략한 축약 표현을 쓸 수 있다.</p>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">const obj = {
    name: &#39;Lee&#39;,
    sayHi() {
        console.log(&#39;하이&#39; + this.name);
    }
};

console.log(obj.sayHi()); // 하이 Lee</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[가독성 좋은 코드를 위한 고민]]></title>
            <link>https://velog.io/@na_0_i/%EA%B0%80%EB%8F%85%EC%84%B1-%EC%A2%8B%EC%9D%80-%EC%BD%94%EB%93%9C%EB%A5%BC-%EC%9C%84%ED%95%9C-%EA%B3%A0%EB%AF%BC</link>
            <guid>https://velog.io/@na_0_i/%EA%B0%80%EB%8F%85%EC%84%B1-%EC%A2%8B%EC%9D%80-%EC%BD%94%EB%93%9C%EB%A5%BC-%EC%9C%84%ED%95%9C-%EA%B3%A0%EB%AF%BC</guid>
            <pubDate>Mon, 20 Feb 2023 13:25:38 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글은 kakaoTech의 &#39;섬세한 ISFP의 코드 가독성 개선 경험&#39; 영상을 보고 작성되었습니다. </p>
</blockquote>
<h1 id="1-정확한-단어-고르기">1. 정확한 단어 고르기</h1>
<h2 id="1-1-다른-뜻을-가진-단어와-구분하기">1-1. 다른 뜻을 가진 단어와 구분하기</h2>
<h3 id="예시-load와-fetch">예시: <code>load</code>와 <code>fetch</code></h3>
<pre><code class="language-javascript">const data = await loadData();</code></pre>
<ul>
<li>load는 가져와서 싣다</li>
<li>fetch는 가져오다</li>
</ul>
<br>

<p>즉, loadData는 가져와서 싣는 것까지 완결된 상태이다.<br>
이를 다시 data 변수에 할당하면 가져온다는 뜻이 중복된다.<br></p>
<br>

<p><strong>좋은 예시</strong></p>
<pre><code class="language-javascript">const data = await fetchData();
const success = await loadData();</code></pre>
<br>

<p><strong>react query 라는 data fetching 라이브러리 예시</strong></p>
<p>isLoading과 isFetching이라는 변수를 지원한다. 이 때, 데이터가 없을 때 최초로 한 번만 바뀌는 변수는 isLoading이다. isLoading은 가져와서 싣는 것이기 때문에 한 번 isLoading이 true가 되면 계속 true인 상태가 되는 것이다.</p>
<img width="613" alt="스크린샷 2023-02-17 오후 10 51 44" src="https://user-images.githubusercontent.com/77482972/219673293-85c6f6ec-eb3a-4fd3-80c2-47b03c2bd796.png">

<br>

<p>이처럼 용어를 제대로 알고 사용하는 것은 라이브러리 용법을 익히거나 코드를 읽을 때 수월해지도록 도와줄 수 있다.</p>
<br>

<h3 id="예시-get과-query">예시: <code>get</code>과 <code>query</code></h3>
<pre><code class="language-javascript">expect(screen.getByText(&#39;Username&#39;)).toBeInTheDocument();
expect(screen.queryByText(&#39;Username&#39;)).toBeInTheDocument();</code></pre>
<ul>
<li>get은 가져오다 </li>
<li>query는 질문하다</li>
</ul>
<br>

<p>getByText와 queryByText의 차이는 getByText는 결과가 없으면 Error를 던지고, queryByText는 결과가 없으면 null을 반환한다.</p>
<br>

<h4 id="왜일까">왜일까?</h4>
<p>가져온다는 말은 결과를 당연히 가져올 것으로 기대하지만 질문하는 것은 질문으로 그치기 때문에 결과가 없을 수도 있기 때문이다. 따라서, 결과가 없을 수도 있지만 확인만 해볼 때는 queryByText를 사용하는 것이 적절하다. get은 대상이 필히 존재한다고 가정하므로 가져온 뒤 대상을 활용하는 코드가 이어진다.</p>
<br>

<h3 id="컴포넌트-작성---ui-명칭-이해하기">컴포넌트 작성 - UI 명칭 이해하기</h3>
<img width="800" alt="스크린샷 2023-02-17 오후 11 01 07" src="https://user-images.githubusercontent.com/77482972/219675997-80510c4b-847e-48a8-9e82-8a4b74f21c69.png">

<p>App Bar와 Global Navigation Bar와 Local Navigation Bar의 차이를 이해하는 것, Card와 Box의 차이를 이해하면 컴포넌트 구성 예측이 쉬워진다.</p>
<br>

<h4 id="card">Card</h4>
<p>하나의 주제로 묶인 컨텐츠와 액션, 그 모든 것</p>
<h4 id="box">Box</h4>
<p>내용물을 감싸는 래퍼의 개념에 가깝게 사용된다.</p>
<br>

<h3 id="card-예시">Card 예시</h3>
<pre><code class="language-javascript">const FruitCard = fruit =&gt; (
    &lt;div&gt;
        &lt;span&gt;{fruit.name}&lt;/span&gt;
        &lt;img src={fruit.img} /&gt;
    &lt;/div&gt;
);</code></pre>
<p>내부 컨텐츠를 포함하므로 FruitBox라는 명칭보다 FruitCard라는 명칭이 잘 어울린다.</p>
<br>

<h3 id="box-예시">Box 예시</h3>
<pre><code class="language-javascript">const FruitBox = children =&gt; (
    &lt;div&gt;
        {children}
    &lt;/div&gt;
)</code></pre>
<p>박스라는 이름에 걸맞게 테두리를 담당하는 역할만 맡게 된다.</p>
<br>

<h3 id="select와-search-예시">Select와 Search 예시</h3>
<img width="865" alt="스크린샷 2023-02-17 오후 11 08 38" src="https://user-images.githubusercontent.com/77482972/219677616-6034ec14-506d-4ef3-8673-77a50838e163.png">

<p>Select는 선택하다<br>
Search는 찾다</p>
<br>

<p>Select는 하나의 결과를 항상 선택하고, Search는 모든 결과를 찾는 것에 그친다. 따라서, Select 컴포넌트가 하이라이팅 되는 것은 당연한 결과였다. Search 컴포넌트를 사용하면 문제도 간단히 해결되고 가독성도 높아진다.</p>
<br>

<h2 id="1-2-보다-구체적인-단어로-바꾸기">1-2. 보다 구체적인 단어로 바꾸기</h2>
<p>코드 작성은 글쓰기와 같다. 광범위한 뜻을 내포하는 단어 대신 보다 원래 의미를 잘 표현할 수 있는 단어를 선택하면 의도나 목적을 명확히 전달해줄 수 있기 때문이다.</p>
<h3 id="예시">예시</h3>
<pre><code class="language-javascript">if (expirationTime &lt; PROMOTION_END_TIME) {
    return remainTime / totalTime;
}</code></pre>
<p>위 코드가 아쉬운 점은<br></p>
<ol>
<li>조건문에서는 값을 비교하고</li>
<li>return은 값을 나누고 있다.</li>
</ol>
<br>

<h3 id="어떻게-개선할까">어떻게 개선할까?</h3>
<ol>
<li>값을 비교하는 조건문이니까 값에 가까운 단어를 사용하자.<blockquote>
<p>조건문은 값을 비교하고 있기 때문에 시간값의 비교에서는 순서가 중요하다. 시간보다는 시각이라는 단어가 더 적절할 것 같다. <br>
expirationTime, PROMOTION_END_TIME → expirationDate, PROMOTION_END_DATE</p>
</blockquote>
</li>
</ol>
<br>

<ol start="2">
<li>정량적인 값을 return 할 것이라는 것을 보여주자.<blockquote>
<p>return 값이 나누는 값이기 때문에 나눌 수 있는 양인지를 나타내면 좋겠다. 기간을 의미하는 단어인 Duration을 사용하여 양의 느낌을 명확히 줄 수 있을 것 같다.<br>
remainTime, totalTime → remainDuration, totalDuration</p>
</blockquote>
</li>
</ol>
<br>

<h3 id="주로-사용할-수-있는-대체-단어">주로 사용할 수 있는 대체 단어</h3>
<h5 id="get">get</h5>
<p>→ extract(추출하다), parse(분해하다), aggregate(합치다)</p>
<h5 id="number">number</h5>
<p>→ limit(제한이 되는 수), count(총계)</p>
<h5 id="change">change</h5>
<p>→ convert(변환하다), filter(거르다), override(덮어쓰다)</p>
<h5 id="changed">changed</h5>
<p>→ dirty(더러운 = 수정이 이루어진)</p>
<br>

<h3 id="정확하지-않은게-더-좋은-경우도-있지-않을까">정확하지 않은게 더 좋은 경우도 있지 않을까?</h3>
<p><strong>아쉬운 예시</strong></p>
<pre><code class="language-javascript">const MIN_TO_SEC = 60;
const HOUR_TO_SEC = MIN_TO_SEC * 60;
const DAY_TO_SEC = HOUR_TO_SEC * 24;

convertSecondToText(3 * DAY_TO_SEC + 12 * HOUR_TO_SEC + 30 * MIN_TO_SEC).toEqual(&#39;3.5days&#39;);</code></pre>
<p><strong>좀 더 나은 예시</strong></p>
<pre><code class="language-javascript">const MIN = 60;
const HOUR = MIN * 60;
const DAY = HOUR * 24;

convertSecondToText(3 * DAY + 12 * HOUR + 30 * MIN).toEqual(&#39;3.5days&#39;);</code></pre>
<p>MIN, HOUR, DAY가 좀 더 모호하지만 아래가 좀 더 잘 읽힌다. 따라서, 항상 정확한 표현을 찾기 보다는 문맥에 맞추어 가독성을 고민해보는 것이 효과적이다.</p>
<br>

<h1 id="2-잘-보이는-형태로-작성하기">2. 잘 보이는 형태로 작성하기</h1>
<h2 id="2-1-표">2-1. 표</h2>
<p><strong>아쉬운 예시</strong></p>
<pre><code class="language-javascript">const type = 
exception
    ? undefined
    : condA
    ? &#39;A&#39;
    : condB
    ? condC
        ? &#39;BC&#39;
        : &#39;BD&#39;
    : &#39;A&#39;; </code></pre>
<p>직관적으로 코드가 눈에 들어오지 않는다.</p>
<br>

<img width="403" alt="스크린샷 2023-02-20 오전 12 28 03" src="https://user-images.githubusercontent.com/77482972/219957803-68676c66-a255-4714-bf8f-32f640c6d31c.png">

<p>표처럼 원하는 행과 열에만 시선을 두어 인과관계를 파악하기 좋을 것이다.</p>
<br>

<p><strong>let과 if문 사용한 예시</strong></p>
<pre><code class="language-javascript">let type = &#39;A&#39;;
if (exception) type = undefined;
if (condA) type = &#39;A&#39;;
if (condB) {
    if (condC) type = &#39;BC&#39;;
    else type = &#39;BD&#39;;
}</code></pre>
<br>

<p><strong>즉시 실행함수와 early return의 활용</strong></p>
<pre><code class="language-javascript">const type = (function () {
    if (exception) return undefined;
    if (condA) return &#39;A&#39;;
    if (condB &amp;&amp; condC) return &#39;BC&#39;;
    if (condB &amp;&amp; !condC) return &#39;BD&#39;;
    return &#39;A&#39;;
})();</code></pre>
<br>

<p><strong>아쉬운 예시</strong></p>
<pre><code class="language-javascript">let str = &#39;&#39;;

switch (type) {
    case &#39;apple&#39;:
        str = &#39;사과&#39;;
        break;
    case &#39;banana&#39;:
        str = &#39;바나나&#39;;
        break;
    default:
        str = &#39;포도&#39;;
}</code></pre>
<p>직관적이긴 하나, 더 좋은 형태(표)로 개선할 수 있을 것 같다.</p>
<br>

<p><strong>대응 관계를 일직선 상에 가깝게 위치한 예시</strong></p>
<pre><code class="language-javascript">const FRUIT_MAP = {
    apple: &#39;사과&#39;,
    banana: &#39;바나나&#39;,
    DEFAULT: &#39;포도&#39;,
}

const str = FRUIT_MAP[type] || FRUIT_MAP.DEFAULT;</code></pre>
<br>

<h2 id="2-2-목차">2-2. 목차</h2>
<p><strong>예시 상황</strong><br></p>
<p>모달 A, 모달 B, 모달 C가 존재하고 z-index가 아래와 같은 상황이다.</p>
<ul>
<li>모달 A의 z-index: 100</li>
<li>모달 B의 z-index: 300</li>
<li>모달 C의 z-index: 500</li>
</ul>
<br>

<p>모달 A를 모달 B 위에 띄우기 위해 A의 z-index를 1000으로 수정하면 의도치 않게 모달 C보다 위에 위치하게 되어 버린다.</p>
<br>

<p><strong>목차 작성을 응용한다면?</strong></p>
<pre><code class="language-javascript">export const ZINDEX_USAGES = {
    HEADER_DROPDOWN: 900,
    HEADER: 1000,
    MODAL_A: 100,
    MODAB_B: 300,
    ALERT_SNACKBAR: 9999,
}</code></pre>
<p>앱 내에서 사용한 모든 z-index를 한 곳에서 확인할 수 있어 가독성이 좋아진다.</p>
<br>

<h2 id="2-3-용어-정리">2-3. 용어 정리</h2>
<p><strong>아쉬운 예시</strong></p>
<pre><code class="language-javascript">if (accessType === &#39;kakao&#39;) {
    return Array.from(data)
        .filter(item =&gt; !(item.sugar &gt; 5000))
        .sort((a, b) =&gt; a.energy - b.energy);
}</code></pre>
<p>동작 과정을 이해하는 데 문제는 없지만 다른 개발자가 의도를 이해하지 못할 수도 있지 않을까?</p>
<br>

<p><strong>개선한 예시</strong></p>
<pre><code class="language-javascript">const shouldDisplay = accessType === &#39;kakao&#39;; // 보여줘야 할지 말지의 기준이었다.

if (shouldDisplay) {
    const foods = Array.from(data); // data는 사실 foods 였다.
    const healthyFoods = foods.filter(menu =&gt; {
        const isUnhealthy = food.sugar &gt; 5000; // 5000은 사실 건강함의 척도였다는 것을 삽입
        return !isUnhealthy;
    })

    const calorieOrderedFoods = healthyFoods.sort((a, b) =&gt; a.energy - b.energy);
    return calorieOrderedFoods;
}</code></pre>
<p>코드는 길어졌을 지라도 용어를 정리하듯 의도를 명확히 함으로써 좀 더 가독성이 좋아졌다.</p>
<br>

<h2 id="2-4-각주">2-4. 각주</h2>
<p>이 부분은 HOC 기법을 사용해서 설명해주셨는데 아직 HOC를 잘 사용하지 못해 감이 오질 않는다. 나중에 다시 볼 예정이다.</p>
<br>

<blockquote>
<p>&#39;섬세한 ISFP의 코드 가독성 개선 경험&#39; 다시보기
<a href="https://www.youtube.com/watch?v=emGLxi0LvNI">https://www.youtube.com/watch?v=emGLxi0LvNI</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 DeepDive 9장 타입 변환과 단축 평가]]></title>
            <link>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-9%EC%9E%A5-%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/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-9%EC%9E%A5-%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>Mon, 20 Feb 2023 07:33:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글은 <strong>&#39;모던 자바스크립트 DeepDive&#39;</strong>를  참고하여 작성되었습니다.</p>
</blockquote>
<h3 id="91-타입-변환이란">9.1 타입 변환이란?</h3>
<h5 id="명시적-타입-변환">명시적 타입 변환</h5>
<p>자바스크립트 값의 타입은 개발자의 의도에 따라 다른 타입으로 변환할 수 있다. 이처럼 개발자가 의도적으로 타입을 변환하는 것을 명시적 타입 변환 또는 타입 캐스팅이라고 한다.</p>
<p><strong>예시</strong>: toString()</p>
<h5 id="암묵적-타입-변환">암묵적 타입 변환</h5>
<p>반대로 개발자의 의도와 상관없이 표현식을 평가하는 도중 자바스크립트 엔진에 의해 암묵적으로 타입이 변환될 때도 있는데 이를 암묵적 타입 변환 혹은 타입 강제 변환 이라고 한다.</p>
<p><strong>예시</strong>: typeof(10 + &#39;&#39;) // string </p>
<br>

<p>명시적 타입 변환과 암묵적 타입 변환 모두 <strong>기존 원시값을 변경하는 것은 아니다.</strong> 타입 변환이란 기존 원시값을 사용해 다른 타입의 원시 값을 생성하는 것이다.</p>
<ul>
<li><code>x = 10, str = x.toString()</code>일 때 x 변수의 값은 변경되지 않는다.</li>
<li><code>x = 10일 때, x + &#39;&#39;</code>의 결과로 생성된 <code>&#39;10&#39;</code>은 x에 재할당 되지 않는다.</li>
<li>즉, 암묵적 타입 변환은 표현식을 평가하기 위해 피연산자 값을 암묵적 타입 변환해 새로운 타입의 값을 만들어 단 한 번 사용하고 버린다.</li>
</ul>
<br>

<h3 id="92-암묵적-타입-변환">9.2 암묵적 타입 변환</h3>
<p>자바스크립트는 가급적 에러를 발생시키지 않도록 암묵적 타입 변환을 통해 표현식을 평가한다. 암묵적 타입 변환이 발생하면 문자열, 숫자, 불리언과 같은 원시 타입 중 하나로 타입을 자동 변환한다.</p>
<h4 id="921-문자열-타입으로-변환">9.2.1 문자열 타입으로 변환</h4>
<p>+연산자는 피연산자 중 하나 이상이 문자열이라면 문자열 연결 연산자로 동작한다. 따라서 문자열 연결 연산자의 모든 피연산자는 코드의 문맥상 모두 문자열 타입이어야 한다. 따라서, 자바스크립트 엔진은 문자열 타입이 아닌 피연산자를 문자열 타입으로 암묵적 타입 변환한다.</p>
<img width="688" alt="스크린샷 2022-11-23 오전 9 25 04" src="https://user-images.githubusercontent.com/77482972/203447332-e486cf66-e5c5-437a-9280-cb5b00885f93.png">

<br>

<h4 id="922-숫자-타입으로-변환">9.2.2 숫자 타입으로 변환</h4>
<p>산술연산자의 역할은 숫자 값을 만드는 것이고 비교 연산자의 역할은 불리언 값을 만드는 것이다. 즉, 산술연산자와 비교연산자의 모든 피연산자는 코드 문맥상 모두 숫자 타입이야 하므로 자바스크립트 엔진은 피연산자 중에서 숫자 타입이 아닌 피연산자를 숫자 타입으로 암묵적 타입 변환한다. 이 때, 산술 연산자의 경우 피연산자를 암묵적 타입 변환할 수 없는 경우에 산술 연산을 수행할 수 없기 때문에 평가결과가 NaN이 된다. + 단항 연산자는 피연산자가 숫자 타입의 값이 아니면 숫자 타입의 값으로 암묵적 타입 변환을 수행한다.</p>
<img width="718" alt="스크린샷 2022-11-23 오전 9 34 18" src="https://user-images.githubusercontent.com/77482972/203448129-308a64ad-82a5-492d-9d3d-dea7b5eef47e.png">

<ul>
<li>객체, 빈 배열이 아닌 배열, undefined는 변환되지 않는다. → NaN을 반환</li>
</ul>
<br>

<h4 id="923-불리언-타입으로-변환">9.2.3 불리언 타입으로 변환</h4>
<p>if 문이나 for 문, 삼항 조건 연산자의 조건식은 불리언 값으로 평가되어야 하는 표현식이다. 자바스크립트 엔진은 조건식의 평가 결과를 불리언 타입으로 암묵적 타입 변환한다. </p>
<img width="689" alt="스크린샷 2022-11-23 오전 9 37 26" src="https://user-images.githubusercontent.com/77482972/203448399-04184594-a8e9-46ea-854d-5d54f3c26e67.png">

<p>자바스크립트 엔진은 불리언 타입이 아닌 값을 <code>Truthy 값</code> 또는 <code>Falsy 값</code> 으로 구분한다. </p>
<h5 id="falsy-값">Falsy 값</h5>
<ul>
<li>false, undefined, null, 0, -0, NaN, &#39;&#39;</li>
</ul>
<h5 id="truthy-값">Truthy 값</h5>
<ul>
<li>Falsy 값 외의 모든 값</li>
</ul>
<br>

<h3 id="93-명시적-타입-변환">9.3 명시적 타입 변환</h3>
<p>명시적으로 타입을 변경하는 방법은 다양하다.</p>
<ol>
<li>표준 빌트인 생성자 함수를 new 연산자 없이 호출하는 방법</li>
<li>빌트인 메서드를 사용하는 방법</li>
<li>암묵적 타입 변환을 이용하는 방법</li>
</ol>
<h4 id="931-문자열-타입으로-변환">9.3.1 문자열 타입으로 변환</h4>
<ol>
<li>String 생성자 함수를 new 연산자 없이 호출</li>
</ol>
<pre><code class="language-javascript">String(1); // &#39;1&#39;
String(Infinity); // &#39;Infinity&#39;
String(true); // &#39;true&#39;</code></pre>
<ol start="2">
<li>Object.prototype.toString 메서드 사용</li>
</ol>
<pre><code class="language-javascript">(1).toString(); // &#39;1&#39;
(NaN).toString(); // &#39;NaN&#39;
(Infinity).toString(); // &#39;Infinity&#39;</code></pre>
<ol start="3">
<li>문자열 연결 연산자를 이용<pre><code class="language-javascript">1 + &#39;&#39;; // &#39;1&#39;
NaN + &#39;&#39;; // &#39;NaN&#39;
Infinity + &#39;&#39;; // &#39;Infinity&#39;</code></pre>
</li>
</ol>
<br>

<h4 id="932-숫자-타입으로-변환">9.3.2 숫자 타입으로 변환</h4>
<ol>
<li>Number 생성자 함수를 new 연산자 없이 호출</li>
</ol>
<pre><code class="language-javascript">Number(&#39;10.53&#39;);
Number(ture);</code></pre>
<ol start="2">
<li>parseInt, parseFloat 함수를 사용(문자열만 가능)</li>
</ol>
<pre><code class="language-javascript">parseInt(&#39;0&#39;);
parseInt(&#39;-1&#39;);
parseFloat(&#39;10.53&#39;);</code></pre>
<ol start="3">
<li>+단항 연산자 이용
```javascript</li>
</ol>
<p>+&#39;0&#39;; // 0
+&#39;-1&#39;; // -1
+true; // 1
+false; // 0</p>
<pre><code>
4. *산술 연산자 이용
```javascript
&#39;0&#39; * 1;
&#39;-1&#39; * 1;
&#39;10.53&#39; * 1;
true * 1;</code></pre><br>

<h4 id="933-불리언-타입으로-변환">9.3.3 불리언 타입으로 변환</h4>
<ol>
<li>Boolean 생성자 함수를 new 연산자 없이 호출</li>
</ol>
<pre><code class="language-javascript">Boolean([]); // true
Boolean({}); // true
Boolean(undefined); // false
Boolean(0); // false</code></pre>
<ol start="2">
<li>! 부정 논리 연산자를 두번 사용</li>
</ol>
<pre><code class="language-javascript">!!{}; // true
!![]; // true
!!null; // false
!!&#39;x&#39;; // true
!!Infinity; // true
!!0; // false</code></pre>
<br>

<h3 id="94-단축-평가">9.4 단축 평가</h3>
<h4 id="941-논리-연산자를-사용한-단축-평가">9.4.1 논리 연산자를 사용한 단축 평가</h4>
<p>논리합(<code>||</code>)과 논리곱(<code>&amp;&amp;</code>) 연산자 표현식은 언제나 2개의 피연산자 중 어느 한쪽으로 평가된다. </p>
<h5 id="논리곱-연산자">논리곱(<code>&amp;&amp;</code>) 연산자</h5>
<ul>
<li>두 개의 피연산자가 모두 true로 평가될 때 true를 반환</li>
<li>좌항에서 우항으로 평가가 진행</li>
</ul>
<h5 id="논리합-연산자">논리합(<code>||</code>) 연산자</h5>
<ul>
<li>두 개의 피연산자 중 하나만 true로 평가되어도 true를 반환한다.</li>
<li>좌항에서 우항으로 평가 진행</li>
</ul>
<br>

<p>위 논리곱과 논리합과 같이 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환하는 것을 <strong>단축 평가</strong>라고 한다. 단축 평가는 표현식을 평가하는 도중 결과가 확정된 경우 나머지 평가 과정을 생략한다.</p>
<br>

<p>단축 평가를 사용하면 if문을 대신할 수 있다.</p>
<pre><code class="language-javascript">var done = true;
var message = &#39;&#39;;

if (done) message = &#39;완료&#39;;

var message = done &amp;&amp; &#39;완료&#39;;</code></pre>
<pre><code class="language-javascript">var done = false;
var message = &#39;&#39;;

if (!done) message = &#39;미완료&#39;;

message = done || &#39;미완료&#39;;</code></pre>
<br>

<h5 id="단축평가가-유용하게-사용되는-경우">단축평가가 유용하게 사용되는 경우</h5>
<p><strong>1. 객체가 null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조할 때</strong></p>
<p>예시</p>
<pre><code class="language-javascript">elem &amp;&amp; elem.value</code></pre>
<p>elem이 null이어도 에러를 뱉어내지 않는다.</p>
<br>

<p><strong>2. 함수 매개변수에 기본값을 설정할 때</strong></p>
<p>예시 </p>
<pre><code class="language-javascript">// 단축 평가 사용
function Temp(str) {
    str = str || &quot;&quot;
    return str.length
}

// es6 매개변수 기본값 설정
function Temp(str = &quot;&quot;) {
    return str.length
}</code></pre>
<br>

<h4 id="942-옵셔널-체이닝-연선자">9.4.2 옵셔널 체이닝 연선자</h4>
<p>옵셔널 체이닝 연산자(<code>?.</code>)는 좌항의 피연산자가 null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조할 때 유용하다. 옵셔널 체이닝 연산자가 도입되기 전에는 논리곱 연산자를 사용했으나 약간의 차이가 있다.</p>
<pre><code class="language-javascript">var str1 = &quot;&quot;;

var length1 = str1 &amp;&amp; str1.length;

console.log(length1); // &quot;&quot;

var str2 = &quot;&quot;;

var length2 = str2?.length;

console.log(length2);</code></pre>
<p>length1의 경우 논리곱 연산자를 이용한 결과로, Falsy 값으로 평가됐기 때문에 좌항의 피연산자를 그대로 반환했다. 그러나 length2의 경우 옵셔널 체이닝 연산자를 이용한 결과로, Falsy 값일지라도 그 값이 null 또는 undefined가 아니면 우항의 프로퍼티 참조를 이어나간다.</p>
<br>

<h4 id="943-null-병합-연산자">9.4.3 null 병합 연산자</h4>
<p>null 병합 연산자(<code>??</code>)는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고 그렇지 않으면 좌항의 피연산자를 반환한다. null 병합 연산자는 변수에 기본값을 설정할 때 유용하다. null 병합 연산자가 도입되기 전에는 논리합 연산자를 사용했으나 약간의 차이가 있다.</p>
<pre><code class="language-javascript">var foo1 = &#39;&#39; ?? &#39;default string&#39;;
console.log(foo1); // &#39;&#39;


var foo2 = &#39;&#39; || &#39;default string&#39;;
console.log(foo2); // &#39;default string&#39;;</code></pre>
<p>foo1의 경우 null 병합 연산자를 이용한 결과로, Falsy 값일지라도 그 값이 null 또는 undefined가 아니면 좌항의 피연산자를 그대로 반환한다. 그러나, foo2는 논리곱 연산자를 이용한 결과로, Falsy 값으로 평가됐기 때문에 우항의 피연산자를 그대로 반환했다. 만약 기본값으로 &quot;&quot;나 0을 설정했다면 ??를 사용하는 것이 좋다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 DeepDive 8장 제어문]]></title>
            <link>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-8%EC%9E%A5-%EC%A0%9C%EC%96%B4%EB%AC%B8</link>
            <guid>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-8%EC%9E%A5-%EC%A0%9C%EC%96%B4%EB%AC%B8</guid>
            <pubDate>Thu, 16 Feb 2023 08:34:05 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글은 <strong>&#39;모던 자바스크립트 DeepDive&#39;</strong>를  참고하여 작성되었습니다.</p>
</blockquote>
<h3 id="81-블록문">8.1 블록문</h3>
<p>블록문은 0개 이상의 문을 중괄호로 묶은 것이다. 자바스크립트는 블록문을 하나의 실행 단위로 취급한다. 블록문은 자체 종결성을 갖기 때문에 블록문 끝에는 세미콜론을 붙이지 않는다.</p>
<br>

<h3 id="82-조건문">8.2 조건문</h3>
<p>조건문은 주어진 조건식의 평가 결과에 따라 코드 블록의 실행을 결정한다.</p>
<h4 id="821-if--else-문">8.2.1 if ... else 문</h4>
<p>조건식의 평가 결과가 true일 경우 if 문의 코드 블록이, false일 경우 else 문의 코드 블록이 실행된다. 실행될 코드 블록을 늘리고 싶으면 else if 문을 사용하고, else if 문과 else 문은 옵션이다.</p>
<br>

<p>if 문의 조건식은 불리언 값으로 평가되어야 한다. 불리언 값이 아니더라도 암묵적으로 불리언 값으로 강제 변환된다.</p>
<br>

<p>대부분의 if ... else 문은 삼항 조건 연산자로 바꿔 쓸 수 있다.</p>
<pre><code class="language-javascript">if (x % 2) {
    result = &#39;홀수&#39;,
} else {
    result = &#39;짝수&#39;,
}

var result = x % 2 ? &#39;홀수&#39; : &#39;짝수&#39;;</code></pre>
<pre><code class="language-javascript">var kind = num ? (num &gt; 0 ? &#39;양수&#39; : &#39;음수&#39;) : &#39;영&#39;;</code></pre>
<p>값으로 사용할 수 없는 if ... else 문과 달리 삼항 조건 연산자는 값으로 평가되기 때문에 변수에 할당할 수 있다.</p>
<br>

<h4 id="822-switch-문">8.2.2 switch 문</h4>
<p>switch 문은 주어진 표현식을 평가해 그 값과 일치하는 표현식을 갖는 case 문으로 실행 흐름을 옮긴다. switch 문의 표현식과 일치하는 case 문이 없다면 default 문으로 이동한다. default 문은 선택사항이다.</p>
<br>

<p>if ... else 문의 조건식은 불리언 값으로 평가되어야 하지만, switch 문의 표현식은 문자열이나 숫자 값인 경우가 많다.</p>
<br>

<p>올바른 switch 문은 case 뒤에 break 문을 작성해 주어야 한다. break 문을 사용하지 않으면 실행 흐름이 다음 case 문으로 이동하기 때문이다(폴 스루). default 문은 맨 마지막에 위치하므로 별도로 break 문이 필요하지 않다. break 문을 생략한 폴스루가 유용한 경우도 있다.</p>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">switch (month) {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:
        days = 31;
        break;

    case 4: case 6: case 9: case 11:
        days = 30;
        break;</code></pre>
<br>

<p>if ... else 문으로 해결할 수 있다면 if ... else 문을 사용하는 편이 좋지만 조건이 너무 많아서 switch 문을 사용했을 때 가독성이 더 좋다면 switch 문을 사용하는 편이 좋다.</p>
<br>

<h3 id="83-반복문">8.3 반복문</h3>
<p>반복문은 조건식의 평가 결과가 참인 경우 코드 블록을 실행하고 조건식이 거짓이 될 때까지 반복한다.</p>
<br>

<h4 id="831-for-문">8.3.1 for 문</h4>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">// for (변수 선언문이나 할당문; 조건식; 증감식) {
//    실행될 문
//}

for (var i = 0; i &lt; 2; i++) {
    console.log(i);
}</code></pre>
<ul>
<li>변수 선언문(var i = 0;)은 한 번만 실행된다.</li>
<li>조건식을 실행 후 코드 블록이 실행된다.</li>
<li>코드 블록 실행이 종료되면 증감식이 실행 되고</li>
<li>증감식 실행이 종료되면 조건식이 실행된다.(변수 선언문 실행 X)</li>
<li>조건식 평가 결과가 false 일 경우 종료된다.</li>
</ul>
<br>

<p>for 문의 변수 선언문, 조건식, 증감식은 모두 옵션이라서 반드시 사용할 필요는 없지만 어떤 식도 사용하지 않으면 무한루프가 된다.</p>
<br>

<h4 id="832-while-문">8.3.2 while 문</h4>
<p>while 문은 주어진 조건식의 평가 결과가 참이면 코드 블록을 반복해서 실행한다. for 문은 반복 횟수가 명확할 때 주로 사용하고, while 문은 반복 횟수가 불명확할 때 주로 사용한다. while 문도 조건문의 평가 결과가 거짓이 되면 코드 블록을 종료한다.</p>
<br>

<p>조건식의 평가 결과가 언제나 참이면 무한 루프가 되지만 코드 블록 내에 if 문으로 탈출 조건을 만들고 break 문을 사용해 코드 블록을 탈출할 수 있다.</p>
<br>

<h4 id="833-do--while-문">8.3.3 do ... while 문</h4>
<p>조건식을 먼저 평가하는 while 문과 달리 do ... while 문은 코드 블록을 먼저 실행하고 조건식을 평가한다. 따라서 코드 블록이 무조건 한 번 이상 실행된다.</p>
<pre><code class="language-javascript">do {
    console.log(count);
    count ++;
} while (count &lt; 3);</code></pre>
<br>

<h3 id="84-break-문">8.4 break 문</h3>
<p>break 문은 (레이블 문, 반복문, switch 문의) 코드 블록을 탈출하여 불필요한 실행이나 반복을 회피할 수 있도록 한다. 그 외에 사용할 경우 SyntaxError가 발생한다.</p>
<blockquote>
<h5 id="레이블문">레이블문</h5>
<p>레이블문은 프로그램 실행 순서를 제어하는 데 사용한다.<br>
레이블문은 중첩된 for문 외부로 탈출할 때 용이하긴 하지만 프로그램 흐름이 복잡해지기 때문에 일반적으로는 권장되지 않는다.</p>
<pre><code class="language-javascript">foo: {
    console.log(1);
       break foo; // foo 레이블 블록문 탈출
       console.log(2);
}</code></pre>
</blockquote>
<br>

<h3 id="85-continue-문">8.5 continue 문</h3>
<p>continue문은 반복문의 코드 블록 실행을 중단하고 반복문의 증감식으로 실행 흐름을 이동시킨다. break 문처럼 반복문을 탈출하지는 않는다.</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 DeepDive 7장 연산자]]></title>
            <link>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-7%EC%9E%A5-%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-7%EC%9E%A5-%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Mon, 13 Feb 2023 14:11:33 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글은 <strong>&#39;모던 자바스크립트 DeepDive&#39;</strong>를  참고하여 작성되었습니다.</p>
</blockquote>
<h3 id="71-산술-연산자">7.1 산술 연산자</h3>
<p>수학적 계산을 수행해 새로운 값을 만들고, 불가능할 경우 NaN 반환</p>
<h4 id="711-이항-산술-연산자">7.1.1 이항 산술 연산자</h4>
<ul>
<li>피연산자의 값을 변경하는 부수 효과 X</li>
</ul>
<img width="679" alt="스크린샷 2022-11-16 오후 9 15 58" src="https://user-images.githubusercontent.com/77482972/202178364-191eb380-56c9-4596-9b23-9af88a2af77e.png">


<br>

<h4 id="712-단항-산술-연산자">7.1.2 단항 산술 연산자</h4>
<ul>
<li>1개의 피연산자를 산술 연산하여 숫자 값을 만듦</li>
<li>증가, 감소(++ / --) 연산자는 부수효과 ㅇ(피연산자의 값을 변경하는 암묵적 할당)</li>
</ul>
<img width="801" alt="스크린샷 2022-11-16 오후 9 18 07" src="https://user-images.githubusercontent.com/77482972/202178720-743e2bdb-3489-4d10-9353-74287e51c56b.png">

<br>

<h5 id="증가감소-연산자">증가/감소 연산자</h5>
<ol>
<li>전위 증가/감소 연산자</li>
</ol>
<ul>
<li>먼저 피연산자 값을 증가/감소</li>
<li>다른 연산을 수행</li>
</ul>
<ol start="2">
<li>후위 증가/감소 연산자</li>
</ol>
<ul>
<li>다른 연산을 수행 후</li>
<li>피연산자 값을 증가/감소</li>
</ul>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">var x = 5, result;

// 후위
// result에 x(5) 할당
// x += 1
result = x++;
console.log(result, x); // 5 6

// 전위
// x += 1
// result에 x(7) 할당
result = ++x;
console.log(result, x); // 7 7</code></pre>
<h5 id="-단항-연산자">+ 단항 연산자</h5>
<ul>
<li>피연산자에 어떠한 효과도 X</li>
<li>숫자 타입이 아닌 피연산자에 사용할 경우 피연산자를 숫자 타입으로 변환한 값을 생성해 반환(마찬가지로 부수효과 X)</li>
</ul>
<h5 id="--단항-연산자">- 단항 연산자</h5>
<ul>
<li>피연산자의 부호를 반전한 값을 반환</li>
<li>숫자 타입이 아닌 피연산자에 사용할 경우 피연산자를 숫자 타입으로 변환한 값을 생성해 반환(마찬가지로 부수효과 X)</li>
</ul>
<br>

<h4 id="713-문자열-연결-연산자">7.1.3 문자열 연결 연산자</h4>
<ul>
<li>연산자는 <strong>피연산자 중 하나 이상이 문자열일 경우</strong> 문자열 연결 연산자로 동작한다.</li>
</ul>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">&#39;1&#39; + 2 // &#39;12&#39;

1 + true // 2
1 + false // 1
1 + null // 1

+undefined // NaN
1 + undefined // NaN</code></pre>
<br>

<h3 id="72-할당-연산자">7.2 할당 연산자</h3>
<ul>
<li>우항에 있는 피연산자의 평가 결과를 좌항에 있는 변수에 할당한다.</li>
<li>할당 연산자는 좌항의 변수에 값을 할당하므로 부수 효과 ㅇ</li>
</ul>
<img width="725" alt="스크린샷 2022-11-16 오후 9 30 42" src="https://user-images.githubusercontent.com/77482972/202181210-c5ac0e52-ada8-416b-a263-608284683a6a.png">

<br>

<p><code>할당문은 표현식일까?</code></p>
<p>할당문 x = 10; 은 10으로 평가되며, 할당문을 다른 변수에 할당할 수 있다.<br>
즉, 할당문은 값으로 평가되는 표현식인 문이다.</p>
<pre><code class="language-javascript">var a, b, c;


// 할당문: 우항의 평가 결과를 좌항에 할당
// c = 0의 평가 결과인 0을 b에
// a에도 마찬가지로 할당
// 즉, 표현식이다.
a = b = c = 0;

console.log(a, b, c); 0 0 0</code></pre>
<br>

<h3 id="73-비교-연산자">7.3 비교 연산자</h3>
<p>좌항과 우항의 피연산자를 비교한 다음 그 결과를 불리언 값으로 반환한다.</p>
<h4 id="731-동등일치-비교-연산자">7.3.1 동등/일치 비교 연산자</h4>
<p>동등 비교 연산자와 일치 비교 연산자는 비교하는 엄격성의 정도에 차이가 있다.</p>
<img width="860" alt="스크린샷 2022-11-16 오후 9 46 45" src="https://user-images.githubusercontent.com/77482972/202184353-33b0d740-4622-4aad-bd06-f79ee39593c2.png">


<ol>
<li>동등 비교 연산자(==)</li>
</ol>
<ul>
<li>암묵적 타입 변환을 통해 타입을 일치시킨 후 같은 값인지 비교</li>
<li>타입은 다르더라도 같은 값이라면 true를 반환</li>
<li>예측하기 어려운 결과를 만들어내므로 사용하지 않는 것이 권장된다.</li>
</ul>
<ol start="2">
<li>일치 비교 연산자(===)</li>
</ol>
<ul>
<li>피연산자가 타입도 같고 값도 같은 경우에 한하여 true를 반환</li>
<li>주의할 점<ul>
<li>NaN은 자기 자신과 일치하지 않는 유일한 값이다.</li>
<li>NaN인지 조사하려면 Number.isNaN을 사용</li>
</ul>
</li>
<li>유사한 메서드: Object.is</li>
</ul>
<h4 id="732-대소-관계-비교-연산자">7.3.2 대소 관계 비교 연산자</h4>
<p>크기를 비교하여 불리언 값을 반환한다.</p>
<img width="961" alt="스크린샷 2022-11-16 오후 9 47 27" src="https://user-images.githubusercontent.com/77482972/202184504-5835fa31-658d-45ee-96ad-828c2cd6c1fc.png">

<br>

<h3 id="74-삼항-조건-연산자">7.4 삼항 조건 연산자</h3>
<ul>
<li><code>조건식</code> ? <code>조건식 true일 때 반환할 값</code> : <code>조건식이 false일 때 반환할 값</code></li>
<li>if ...else 문과 유사하지만 삼항 조건 연산자 표현식은 값처럼 사용할 수 있다는 점이 다르다.</li>
<li>즉, 삼항 조건 연산자 표현식은 값처럼 다른 표현식의 일부가 될 수 있다.</li>
</ul>
<br>

<h3 id="75-논리-연산자">7.5 논리 연산자</h3>
<img width="638" alt="스크린샷 2022-11-16 오후 9 52 10" src="https://user-images.githubusercontent.com/77482972/202185488-5c9afc81-e771-4f5e-a785-9e522abcc8b0.png">

<h5 id="논리-부정-연산자">논리 부정 연산자(!)</h5>
<ul>
<li>언제나 불리언 값을 반환한다.</li>
<li>단, 피연산자가 불리언 값일 필요는 없다.</li>
</ul>
<h5 id="논리합-논리곱-연산자-">논리합, 논리곱 연산자(||, &amp;&amp;)</h5>
<ul>
<li>2개의 피연산자 중 어느 한쪽으로 평가받는다.</li>
</ul>
<br>

<h3 id="76-쉼표-연산자">7.6 쉼표 연산자</h3>
<pre><code class="language-javascript">var x, y, z;

x = 1, y = 2, z = 3; // 3</code></pre>
<br>

<h3 id="77-그룹-연산자">7.7 그룹 연산자</h3>
<p>소괄호로 피연산자를 감싸는 그룹 연산자<code>()</code>는 자신의 피연산자인 표현식을 가장 먼저 평가한다. 따라서, 연산자의 우선순위를 조절하는데 사용할 수 있다.(연산자 우선순위가 가장 높음)</p>
<br>

<h3 id="78-typeof-연산자">7.8 typeof 연산자</h3>
<p>typeof 연산자는 피연산자의 데이터 타입을 문자열(<code>string</code>, <code>number</code>, <code>booldean</code>, <code>undefined</code>, <code>symbol</code>, <code>object</code>, <code>function</code> 중 1개)로 반환한다. <br></p>
<p><strong>주의할 점</strong></p>
<ul>
<li>null 값을 typeof 연산을 했을 때 object를 반환한다.</li>
<li>선언하지 않은 식별자에 typeof 연산을 했을 때 참조에러가 아닌 undefined를 반환한다.</li>
</ul>
<br>

<h3 id="79-지수-연산자">7.9 지수 연산자</h3>
<p>지수 연산자는 좌항의 피연산자를 밑으로, 우항의 피연산자를 지수로 거듭제곱하여 숫자 값을 반환한다. Math.pow()의 신버전이다.</p>
<br>

<h3 id="711-연산자의-부수-효과">7.11 연산자의 부수 효과</h3>
<p>부수효과가 있는 연산자: 할당 연산자, 증가/감소 연산자, delete 연산자(객체의 프로퍼티 삭제)</p>
<br>

<h3 id="712-연산자-우선순위">7.12 연산자 우선순위</h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 DeepDive 6장 데이터 타입]]></title>
            <link>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-6%EC%9E%A5-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85</link>
            <guid>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-6%EC%9E%A5-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85</guid>
            <pubDate>Mon, 13 Feb 2023 14:09:53 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글은 <strong>&#39;모던 자바스크립트 DeepDive&#39;</strong>를  참고하여 작성되었습니다.</p>
</blockquote>
<h3 id="61-숫자-타입">6.1 숫자 타입</h3>
<ul>
<li>자바스크립트에는 하나의 숫자 타입만이 존재한다.</li>
<li>모든 수를 실수로 처리하며 2진수, 8진수, 16진수를 위한 데이터 타입은 제공하지 않기 때문에 모든 값은 10진수로 해석된다.</li>
<li>자바스크립트 숫자 타입은 모든 수를 실수로 처리한다.</li>
<li>추가적으로, Infinity, -Infinitay, Nan 이라는 값도 표현할 수 있다.</li>
</ul>
<br>

<h3 id="62-문자열-타입">6.2 문자열 타입</h3>
<ul>
<li>문자열은 <code>&#39;&#39;</code>, <code>&quot;&quot;</code>, <code>``</code> 으로 텍스트를 감싼다.</li>
<li>문자열을 따옴표로 감싸는 이유는 키워드나 식별자와 구분하기 위해서이다.</li>
</ul>
<br>

<h3 id="63-템플릿-리터럴">6.3 템플릿 리터럴</h3>
<p>템플릿 리터럴은 백틱(<code>``</code>)을 사용해 표현한다.</p>
<h4 id="631-멀티라인-문자열">6.3.1 멀티라인 문자열</h4>
<p>일반적인 문자열 내에서는 줄바꿈이 허용되지 않아서 이스케이프 시퀀스를 사용해야하지만 템플릿 리터럴 내에서는 이스케이프 시퀀스를 사용하지 않고도 줄바꿈 및 공백이 허용된다.</p>
<h4 id="632-표현식-삽입">6.3.2 표현식 삽입</h4>
<p><code>${}</code>으로 표현식을 감싸 표현식을 삽입한다. 이 때 표현식 평가 결과가 문자열이 아니더라도 문자열로 타입이 변환되어 삽입된다.</p>
<br>

<h3 id="64-불리언-타입">6.4 불리언 타입</h3>
<p>true와 false</p>
<br>

<h3 id="65-undefined-타입">6.5 undefined 타입</h3>
<ul>
<li>undefined 타입의 값은 undefined가 유일하다.</li>
<li>변수 선언에 의해 확보된 메모리 공간이 첫 할당이 이루어지기 전까지 자바스크립트 엔진이 undefined로 초기화한다.</li>
<li>즉, 자바스크립트 엔진이 변수를 초기화할 때 사용하는 값이므로</li>
<li>의도적으로 변수에 undefined를 할당하는 것은 권장되지 않음(null 할당 권장)</li>
</ul>
<br>

<h3 id="66-null-타입">6.6 null 타입</h3>
<ul>
<li>null 타입의 값은 null이 유일하다.</li>
<li>null은 변수에 값이 없다는 것을 의도적으로 명시할 때 사용</li>
</ul>
<br>

<h3 id="67-심벌-타입">6.7 심벌 타입</h3>
<ul>
<li>변경 불가능한 원시 타입 값</li>
<li>다른 값과 중복되지 않는 유일무이 값이라 주로 객체의 유일한 프로퍼티 키를 만들기 위해 사용</li>
<li>Symbol 함수를 호출해 생성</li>
</ul>
<br>

<h3 id="68-객체-타입">6.8 객체 타입</h3>
<p>자바스크립트는 객체 기반의 언어이며, 자바스크립트를 이루고 있는 거의 모든 것은 객체이다.</p>
<br>

<h3 id="69-데이터-타입의-필요성">6.9 데이터 타입의 필요성</h3>
<h4 id="691-데이터-타입에-의한-메모리-공간의-확보와-참조">6.9.1 데이터 타입에 의한 메모리 공간의 확보와 참조</h4>
<p>자바스크립트 엔진은 데이터 타입에 따라 정해진 크기의 메모리 공간을 확보한다. 즉, 데이터 타입에 따라 확보해야 할 메모리 공간의 크기가 결정된다. 또한 값을 참조 하기 위해서는 읽어들여야 할 메모리 공간의 크기를 알아야 한다. 예를 들어, score 변수에 숫자가 할당되어 있다면 자바스크립트는 score 변수를 참조할 때 숫자 타입, 8바이트 단위로 읽어들인다.</p>
<h4 id="692-데이터-타입에-의한-값의-해석">6.9.2 데이터 타입에 의한 값의 해석</h4>
<p>모든 값은 데이터 타입을 가지며, 메모리에 2진수로 저장된다. 메모리에 저장된 값은 데이터 타입에 따라 다르게 해석되기 때문에 score 변수를 참조하면 메모리 공간의 주소에서 읽어들인 2진수를 숫자로 해석한다.</p>
<br>

<h3 id="610-동적-타이핑">6.10 동적 타이핑</h3>
<h4 id="6101-동적-타입-언어와-정적-타입-언어">6.10.1 동적 타입 언어와 정적 타입 언어</h4>
<h5 id="정적-타입-언어">정적 타입 언어</h5>
<ul>
<li>변수를 선언할 때 변수의 데이터 타입을 사전에 선언(명시적 타입 선언)</li>
<li>변수의 타입을 변경할 수 없다.</li>
<li>선언한 타입에 맞는 값만 할당 가능하다.</li>
<li>컴파일 시점에 타입 체크를 수행해 타입 체크를 통과하지 못하면 프로그램 실행을 막는다.</li>
</ul>
<br>

<p>자바스크립트는 변수를 선언할 때 타입을 선언하지 않으며 어떠한 데이터 타입의 값이라도 자유롭게 할당할 수 있다. 자바스크립트는 값을 할당하는 시점에 변수의 타입이 동적으로 결정되고 변수의 타입을 자유롭게 변경할 수 있다. </p>
<br>

<p>즉, 자바스크립트는 <strong>동적 타입 언어</strong>로 동적 타이핑(할당에 의해 타입이 결정 &amp; 재할당에 의해 타입 동적으로 변경)이라는 특징을 가진다.</p>
<br>

<h4 id="6102-동적-타입-언어와-변수">6.10.2 동적 타입 언어와 변수</h4>
<p>동적 타입 언어는 편리하긴 하지만 변수 값을 추적하기 어렵다든가, 변수 값에 의해 타입이 변경된다든가 등의 위험이 존재한다.</p>
<br>

<h5 id="변수-사용-시-주의-사항">변수 사용 시 주의 사항</h5>
<ul>
<li>변수는 필요한 경우에만 사용</li>
<li>변수 스코프를 최대한 좁게</li>
<li>전역 변수 사용 자제</li>
<li>변수보다는 상수 사용</li>
<li>변수 이름은 명확하게</li>
</ul>
<br>

<hr>
<blockquote>
<p>ECMAScript 사양은 문자열과 숫자 타입 외의 데이터 타입을 명시적으로 규정하고 있지 않다. 따라서 문자열과 숫자 타입을 제외한 메모리 공간의 크기는 자바스크립트 엔진 제조사의 구현에 따라 다를 수 있다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 DeepDive 5장 표현식과 문]]></title>
            <link>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-5%EC%9E%A5-%ED%91%9C%ED%98%84%EC%8B%9D%EA%B3%BC-%EB%AC%B8</link>
            <guid>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-5%EC%9E%A5-%ED%91%9C%ED%98%84%EC%8B%9D%EA%B3%BC-%EB%AC%B8</guid>
            <pubDate>Mon, 13 Feb 2023 12:57:37 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글은 <strong>&#39;모던 자바스크립트 DeepDive&#39;</strong>를  참고하여 작성되었습니다.</p>
</blockquote>
<h3 id="51-값">5.1 값</h3>
<p>값은 식이 평가되어 생성된 결과를 말한다. 변수는 값을 저장하기 위해 확보한 메모리 공간 자체 혹은 메모리 공간을 식별하기 위해 붙인 이름이므로, 변수에 할당되는 것은 값이다.</p>
<br>

<h3 id="52-리터럴">5.2 리터럴</h3>
<p>리터럴은 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 표기법이다. 자바스크립트 엔진은 런타임에 리터럴을 평가해 값을 생성한다. </p>
<h5 id="예시">예시</h5>
<ul>
<li>객체 리터럴: {name: &#39;Park&#39;, address: &#39;Seoul&#39;}</li>
<li>배열 리터럴: [1, 2, 3]</li>
<li>함수 리터럴: function () {}</li>
</ul>
<br>

<h3 id="53-표현식">5.3 표현식</h3>
<p>표현식은 값으로 평가될 수 있는 문이다. 즉, 표현식이 평가되면 값을 생성하거나 기존 값을 참조한다.</p>
<h5 id="예시-1">예시</h5>
<pre><code class="language-javascript">var score = 100; // 1

var score = 50 + 50; // 2

score; // 3</code></pre>
<ul>
<li>1에서 100은 리터럴이다. 리터럴 100은 자바스크립트 엔진에 의해 평가되어 값을 생성하므로 그 자체로 표현식이다.</li>
<li>2에서 50+50은 리터럴과 연산자로 이루어져 있다. 50+50도 평가되어 값 100을 생성하므로 표현식이다.</li>
<li>3에서 score를 참조하면 변수 값으로 평가된다. 식별자 참조는 값을 생성하지는 않지만 값으로 평가되므로 표현식이다.</li>
<li>즉, 값으로 평가될 수 있으면 모두 표현식이다.</li>
</ul>
<br>

<p>수학에서 1+2가 3과 동치인 것처럼 표현식 1+2는 값 3과 동치이다. 따라서 표현식은 값처럼 사용할 수 있고, 값이 위치할 수 있는 자리에는 표현식도 위치할 수 있다.</p>
<br>

<h3 id="54-문">5.4 문</h3>
<p>문은 프로그램을 구성하는 기본 단위이자 최소 실행 단위이다. 문의 집합이 프로그램이고, 문을 작성하고 나열하는 것이 프로그래밍이다. </p>
<br>

<h3 id="55-세미콜론과-세미콜론-자동-삽입-기능">5.5 세미콜론과 세미콜론 자동 삽입 기능</h3>
<p>세미콜론은 문의 종료를 나타낸다. 자바스크립트 엔진은 세미콜론으로 문이 종료한 위치를 파악하고 순차적으로 하나씩 문을 실행한다. 세미콜론은 옵션이라 생략 가능하다. 자바스크립트 엔진이 ASI(세미콜론 자동 삽입 기능)을 암묵적으로 수행하기 때문이다. </p>
<br>

<h5 id="세미콜론을-붙이지-않는-경우">세미콜론을 붙이지 않는 경우</h5>
<ul>
<li>0개 이상의 문을 중괄호로 묶은 코드 블록</li>
<li>예: if 문, for 문, 함수 등</li>
<li>코드 블록은 문의 종료를 의미하는 자체 종결성을 갖기 때문</li>
</ul>
<br>

<h3 id="56-표현식인-문과-표현식이-아닌-문">5.6 표현식인 문과 표현식이 아닌 문</h3>
<p>표현식과 표현식이 아닌 문을 구별하는 가장 쉬운 방법은 변수에 할당하는 것이다. 표현식은 값으로 평가될 수 있는 문이므로 변수에 할당할 수 있기 때문이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[성실함에 관련된 면접 질문]]></title>
            <link>https://velog.io/@na_0_i/%EC%84%B1%EC%8B%A4%ED%95%A8%EC%97%90-%EA%B4%80%EB%A0%A8%EB%90%9C-%EB%A9%B4%EC%A0%91-%EC%A7%88%EB%AC%B8</link>
            <guid>https://velog.io/@na_0_i/%EC%84%B1%EC%8B%A4%ED%95%A8%EC%97%90-%EA%B4%80%EB%A0%A8%EB%90%9C-%EB%A9%B4%EC%A0%91-%EC%A7%88%EB%AC%B8</guid>
            <pubDate>Sun, 12 Feb 2023 15:52:25 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이런 점들을 염두에 두고 일하다 보면 일을 대하는 태도나 의사 결정에 있어 좀 더 신중하게 임할 수 있겠다는 생각이 들어 정리해보았습니다.</p>
</blockquote>
<h4 id="1-자신과-팀의-목표-설정에-어떻게-접근하는지">1. 자신과 팀의 목표 설정에 어떻게 접근하는지</h4>
<h4 id="2-문제-해결-및-의사-결정에-어떻게-접근하는지">2. 문제 해결 및 의사 결정에 어떻게 접근하는지</h4>
<h4 id="3-목표-달성을-위해-도전이나-장애물을-극복해야-했던-경우의-예시">3. 목표 달성을 위해 도전이나 장애물을 극복해야 했던 경우의 예시</h4>
<h4 id="4-빡빡한-기한에-맞춰-일하거나-고압적인-상황을-처리해야-했던-경우의-예시">4. 빡빡한 기한에 맞춰 일하거나 고압적인 상황을 처리해야 했던 경우의 예시</h4>
<h4 id="5-기한을-맞추거나-목표를-초과-달성하기-위해-혹은-그-이상을-달성한-경우의-예시">5. 기한을 맞추거나 목표를 초과 달성하기 위해, 혹은 그 이상을 달성한 경우의 예시</h4>
<h4 id="6-프로젝트를-완료하기-위해-변화하는-상황이나-요구-사항에-적응해야-했던-경우--새로운-것을-배우거나-새로운-기술을-습득해야-했던-경우의-예시">6. 프로젝트를 완료하기 위해 변화하는 상황이나 요구 사항에 적응해야 했던 경우 / 새로운 것을 배우거나 새로운 기술을 습득해야 했던 경우의 예시</h4>
<hr>
<h4 id="7-어렵거나-비협조적인-동료나-팀원을-상대해야-했던-상황">7. 어렵거나 비협조적인 동료나 팀원을 상대해야 했던 상황</h4>
<h4 id="8-다른-사람과-효과적으로-의사소통하기-위해-의사소통-기술을-사용해야-했던-경우의-예시">8. 다른 사람과 효과적으로 의사소통하기 위해 의사소통 기술을 사용해야 했던 경우의 예시</h4>
<h4 id="9-프로젝트를-완료하기-위해-팀과-협력해야-했던-경우를-설명">9. 프로젝트를 완료하기 위해 팀과 협력해야 했던 경우를 설명</h4>
<h4 id="10-도전이나-좌절에-직면했을-때-어떻게-의욕을-유지하고-긍정적인-태도를-유지하는지">10. 도전이나 좌절에 직면했을 때 어떻게 의욕을 유지하고 긍정적인 태도를 유지하는지</h4>
<h4 id="11-긍정적이고-부정적인-피드백을-어떻게-처리하는지">11. 긍정적이고 부정적인 피드백을 어떻게 처리하는지</h4>
<h4 id="12-어려운-결정에-직면했을-때-그-결정을-내리기-위해-어떤-노력을-기울였는지">12. 어려운 결정에 직면했을 때 그 결정을 내리기 위해 어떤 노력을 기울였는지</h4>
<hr>
<h4 id="13-직접적인-감독-없이-주도권을-잡고-상황을-처리해야-했던-경우의-예시">13. 직접적인 감독 없이 주도권을 잡고 상황을 처리해야 했던 경우의 예시</h4>
<h4 id="14-언제-리더십-역할을-맡았고-어떻게-대처하였는지">14. 언제 리더십 역할을 맡았고 어떻게 대처하였는지</h4>
<hr>
<blockquote>
<p>이 글은 황민호님의 글을 참고하여 작성되었습니다.
<a href="https://careerly.co.kr/comments/73559?utm_campaign=user-share">황민호님의 면접자가 성실한지 알 수 있는 인터뷰 질문 10가지</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 DeepDive 4장 변수]]></title>
            <link>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-4%EC%9E%A5-%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@na_0_i/%EB%AA%A8%EB%8D%98%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DeepDive-4%EC%9E%A5-%EB%B3%80%EC%88%98</guid>
            <pubDate>Sun, 12 Feb 2023 15:27:47 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이 글의 <strong>&#39;모던 자바스크립트 DeepDive&#39;</strong>를  인용하여 작성되었습니다.</p>
</blockquote>
<h3 id="41-변수란-무엇인가-왜-필요한가">4.1 변수란 무엇인가? 왜 필요한가?</h3>
<p>컴퓨터는 CPU를 사용해 연산하고, 메모리를 사용해 데이터를 기억한다.</p>
<h5 id="메모리">메모리</h5>
<ul>
<li>메모리는 데이터를 저장할 수 있는 메모리 셀(1바이트)의 집합체로</li>
<li>컴퓨터는 1바이트 단위로 데이터를 저장하고 읽어들인다.</li>
<li>이 때, 각 셀은 <strong>고유의 메모리 주소</strong>를 가진다.</li>
</ul>
<br>

<p>하지만, 자바스크립트는 개발자가 메모리 주소를 통해 값에 직접 접근하는 것을 허용하지 않으며, 값이 저장될 메모리 주소는 코드가 실행될 때 메모리 상황에 따라 임의로 결정된다. 이러한 이유로 프로그래밍 언어는 변수라는 메커니즘을 제공해 <strong>기억하고 싶은 값을 메모리에 저장, 저장된 값을 읽어 들여 재사용</strong> 할 수 있도록 한다.</p>
<h5 id="변수">변수</h5>
<ul>
<li>하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름이다.</li>
<li>값의 위치를 가리킨다고 보면 된다.(값을 저장하고 참조)</li>
<li>변수는 컴파일러나 인터프리터에 의해 메모리 공간의 주소로 치환되어 실행되기 때문에 개발자가 직접 메모리 주소에 접근할 필요 없이 안전하게 접근 할 수 있다.</li>
<li><strong>변수 이름</strong>: 메모리 공간에 저장된 값을 식별할 수 있는 고유한 이름</li>
<li><strong>변수 값</strong>: 변수에 저장된 값</li>
<li><strong>할당</strong>: 변수에 값을 저장 / <strong>참조</strong>: 변수에 저장된 값을 불러 읽어오는 것</li>
</ul>
<br>

<h3 id="42-식별자">4.2 식별자</h3>
<p>식별자는 어떤 값을 구별해서 식별할 수 있는 고유한 이름으로 변수 이름을 식별자라고도 한다. 식별자는 메모리 공간에 저장된 어떤 값을 식별해내기 위해 메모리 주소를 기억해야 한다.<br>
<br>
즉, 식별자는 <strong>값이 저장되어 있는 메모리 주소와 매핑 관계</strong>를 맺으며, 이 매핑 정보도 메모리에 저장된다. 다시 얘기해, 식별자는 값이 아니라 메모리 주소를 기억하고 있다.(식별자는 메모리 주소에 붙인 이름이나 마찬가지이다.)<br>
<br>
변수, 함수, 클래스 등은 전부 식별자로, 메모리 상에 존재하는 어떤 값을 식별할 수 있는 이름은 전부 식별자이다.</p>
<br>

<h3 id="43-변수-선언">4.3 변수 선언</h3>
<p>변수 선언이란 메모리 공간을 확보하고 변수 이름과 확보된 메모리 공간의 주소를 연결해 값을 저장할 수 있도록 하는 것(=변수를 생성)이다. 자바스크립트 엔진은 변수 선언을 2단계에 걸쳐서 수행한다.</p>
<ol>
<li>선언 단계: 변수 이름을 등록</li>
<li>초기화 단계: 메모리 공간을 확보하고 undefined를 할당해 초기화(변수 선언 이후 최초로 값을 할당하는 것)</li>
</ol>
<h5 id="예시">예시</h5>
<pre><code class="language-javascript">var score;</code></pre>
<ul>
<li>위 변수 선언문은 변수 이름을 등록하고 값을 저장할 메모리 공간을 확보한다.</li>
<li>변수를 선언한 이후, 변수에 값을 할당하지는 않았으나</li>
<li>확보된 메모리 공간엔 암묵적으로 undefined가 할당되어 초기화된다.</li>
<li>var 키워드를 사용한 변수 선언은 선언 단계와 초기화 단계가 동시에 진행되어</li>
<li>선언 단계를 통해 score를 변수 이름으로 등록하고, 초기화 단계를 통해 undefined를 할당했다.</li>
</ul>
<br>

<p>var 키워드로 선언한 변수는 어떤 값을 할당하지 않아도 undefined라는 값을 갖는다. 초기화 단계를 거치지 않으면 이전에 다른 애플리케이션이 사용했던 값이 남아 있을 수 있기 때문에, 값을 할당하지 않아도 undefined로 초기화를 수행해 이런 위험으로부터 안전하도록 한다.</p>
<br>

<h3 id="44-변수-선언의-실행-시점과-변수-호이스팅">4.4 변수 선언의 실행 시점과 변수 호이스팅</h3>
<p>자바스크립트 엔진은 소스코드 실행에 앞서 소스코드 평가 과정을 거친다. 이 평가 과정에서 자바스크립트 엔진은 모든 선언문을 찾아내어 먼저 실행한다. 따라서 소스코드 내 변수 선언 위치에 상관없이 어디서든 변수를 참조할 수 있다.</p>
<h5 id="예시-1">예시</h5>
<pre><code class="language-javascript">console.log(score); // undefined

var score;</code></pre>
<ul>
<li>참조 에러가 발생하지 않고 undefined가 출력되었다.</li>
</ul>
<br>

<h3 id="45-값의-할당">4.5 값의 할당</h3>
<p>자바스크립트 엔진은 변수 선언과 값의 할당을 하나의 문으로 단축 표현해도 변수 선언과 값의 할당을 2개의 문으로 나누어 각각 실행한다. 이 때, 변수 선언은 런타임 이전에 실행되고 값의 할당은 런타임에 실행된다.</p>
<h5 id="예시-2">예시</h5>
<pre><code class="language-javascript">console.log(score); // undefined

var score = 80;

console.log(score); // 80</code></pre>
<ul>
<li>아래 그림과 같이, 이전 값 undefined가 저장되어 있던 메모리 공간을 지우고</li>
<li>그 메모리 공간에 80을 할당하는 것이 아니라</li>
<li>새로운 공간을 확보하고 80을 저장한다.</li>
</ul>
<p><img src="https://user-images.githubusercontent.com/77482972/174205174-bbbbd31c-869a-4c47-8986-ff1e548cc9b1.png" alt="image"></p>
<br>

<h3 id="46-값의-재할당">4.6 값의 재할당</h3>
<h5 id="예시-3">예시</h5>
<pre><code class="language-javascript">var score = 80;
score = 90;</code></pre>
<ul>
<li>현재 score 변수의 값은 90</li>
<li>이전 값인 undefined와 80은 어떤 식별자와도 연결되어 있지 않다.</li>
<li>불필요한 값들은 가비지 콜렉터에 의해 메모리에서 자동 해제된다.</li>
</ul>
<br>

<h3 id="47-식별자-네이밍-규칙">4.7 식별자 네이밍 규칙</h3>
<h5 id="네이밍-컨벤션">네이밍 컨벤션</h5>
<ul>
<li>카멜 케이스<ul>
<li>변수나 함수의 이름에 사용</li>
<li>firstName</li>
</ul>
</li>
<li>파스칼 케이스<ul>
<li>생성자 함수, 클래스 이름에 사용    </li>
<li>FirstName</li>
</ul>
</li>
<li>스네이크 케이스<ul>
<li>first_name</li>
</ul>
</li>
<li>헝가리언 케이스<ul>
<li>strFirstName: type + identifier</li>
<li>$elem: DOM node</li>
</ul>
</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>