<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>cest_pangeun.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Wed, 25 Mar 2026 00:44:26 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>cest_pangeun.log</title>
            <url>https://images.velog.io/images/cest_pangeun/profile/47eb86c6-bab4-4d40-9115-56472bbdfe8c/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. cest_pangeun.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/cest_pangeun" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[딸깍 (feat. codex, claude code)]]></title>
            <link>https://velog.io/@cest_pangeun/%EB%B0%B1%EC%97%94%EB%93%9C%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98-iOS-%EC%95%B1-%EA%B0%9C%EB%B0%9C%EA%B8%B0-feat.-codex-claude-code</link>
            <guid>https://velog.io/@cest_pangeun/%EB%B0%B1%EC%97%94%EB%93%9C%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%9D%98-iOS-%EC%95%B1-%EA%B0%9C%EB%B0%9C%EA%B8%B0-feat.-codex-claude-code</guid>
            <pubDate>Wed, 25 Mar 2026 00:44:26 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>글쓴이는 컴공을 나와서 현재 백엔드 개발자 4년차이다.
컴공을 가기 전에 중고등학교 내내 공부는 안하고 실음과를 가겠다고 기타만 치던 사람이었다.
그러나 연습을 더럽게 안 하던 나는 음악을 결국 취미로 남겨두게 되었고,
언젠가 스스로에게 악기 연습을 시키기 위해서 앱을 하나 만들기로 결심한다.
이 글은 앱 개발 과정기를 녹인 글이다.</p>
</blockquote>
<h3 id="밴드인들을-위한-연습-기록-앱-bandy-03월-21일-출시">밴드인들을 위한 연습 기록 앱 BANDY 03월 21일 출시!</h3>
<p>개발자 중 밴드 하시는 분들</p>
<ul>
<li>노래 부르고, 기타, 베이스, 드럼, 키보드 치시는 분들이 있다면 한 번씩 구경 와주세요🎉</li>
</ul>
<p><a href="https://apps.apple.com/kr/app/bandy-%EC%9D%8C%EC%95%85-%EC%97%B0%EC%8A%B5-%ED%8A%B8%EB%9E%98%EC%BB%A4/id6759210677">BANDY 앱스토어 바로가기</a></p>
<ul>
<li>2026년 03월 25일 : 안드로이드도 클로드 시켜서 조립하는 중</li>
</ul>
<h1 id="주절주절">주절주절...</h1>
<p>학부생 시절 iOS 개발을 깔짝 했었는데, 정작 취업은 백엔드로 하였다. 
음악과 악기는 애증이 되었지만 여전히 놓지 못해 방구석에서 릴스도 찍고, 지인들과 종종 공연도 한다.</p>
<p>기타는 항상 잡고 있는데, 내 연습량은 어떻게 되고 뭘 주로 연습하지? 라는 생각이 문득 들었고 기록하는 앱을 만들자는 결심만 사실 1년 했다. 1차 MVP 기획도 마치고, 밴드 플랫폼을 만들겠다는 원대한 계획만 1년을 했다. 사실 혼자 하기 벅차서 누구와 함께 하고 싶었으나 같이 할 사람을 구하지 못했다.</p>
<p>쓰레드를 매일 염탐하다 보니 codex와 claude code의 성능이 꽤나 올라왔다는 말이 자자했고, 지금이면 혼자 내가 기획한 앱을 만들어 볼 수 있지 않을까? 싶었다.
그러나 믿지 못하고 자만심에 iOS랑 api 서버를 혼자 뚝딱뚝딱 개발하다가 아차 싶더라. 이러다 평생 못만들겠다 싶었는데 그 찰나 카카오에서 chat gpt 대란이 났고, 나는 이때다 싶어서 구매해서 codex한테 일을 시키게 된다. (미련하고 바보같이 한 달치만 샀고, 현재는 클로드로 넘어감)</p>
<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/c94cc887-14b3-4b39-9a10-795c1fde8bf3/image.png" alt=""></p>
<h1 id="약-2개월-정도-개발-기간">약 2개월 정도 개발 기간</h1>
<p>2026년 1월 2일부터 개발을 시작했는데, 이 당시만 해도 프롬프트를 어떻게 작성해야하고, skill은 뭐고 이런 개념 자체가 아예 없었다. 나에게 지피티는 그저 개발 개념 물어보거나 사주 봐달라고 하는 정도가 다였다.</p>
<p>실제로 1월은 내가 모르는 개념들을 물어보며 직접 개발했다. 카카오를 통해서 얻은 chat gpt pro를 얻은 이후엔 이걸 뽕뽑고 싶다는 마음에 이것저것 알아보며 정보를 얻게 되었다. 개발 속도는 미친듯이 올라가는 것이 당연한 것이었고, 나는 그저 딸깍만 하면 됐다. (물론 검토와 조사를 충분히 시킨 다음 개발을 시켰다)</p>
<p>언제부터는 이러고 있는 내 모습이 릴스에 뜨더라
<img src="https://velog.velcdn.com/images/cest_pangeun/post/7d8d995c-c5fa-4432-aea2-f0e90304e441/image.png" alt=""></p>
<p>26년 1월은 개발하며 모르는 개념만 물어보며 수정하였는데, 2월부터는 codex를 이용하니 생산성이 말도 안 되게 늘었다. (codex 5.3을 사용하는 와중 5.4로 업데이트 되었고, 성능은 체감되게 좋아진 것을 느꼈다)</p>
<p>단순하게, <strong>&quot;이런 기능 만들어줘&quot;</strong> 라고 말하면 성능을 온전히 못 뽑는다는 것을 알아서 귀찮더라도 계속 설명해주고 학습시켰다.</p>
<h1 id="덜-멍청할-수-있도록-지시하기">덜 멍청할 수 있도록 지시하기</h1>
<p>나는 ios 앱개발은 학부생때 해본 것이 전부였고, 현재는 spring 백엔드 개발자로 일하고 있다. (학부생 때에는 UIKit으로 개발하였고, 이번엔 swiftUI로 진행했다) </p>
<p>codex, claude code한테 지시할 때, 귀찮더라도 항상 다음과 같은 규칙을 세웠다.</p>
<h3 id="1-작은-기능-단위로-지시하기">1. 작은 기능 단위로 지시하기</h3>
<ul>
<li>큰 기능 혹은 전체 기능 개발을 시킨다면 작업량이 느려져 내 온라인 월세들이 멍청해지는 기분이 들었다.</li>
</ul>
<h3 id="2-항상-개발-하기-전에-계획-세우고-철저한-조사-시키기">2. 항상 개발 하기 전에 계획 세우고 철저한 조사 시키기.</h3>
<ul>
<li>계획을 세우고 시키라는 것은 이제 어디에서나 하는 말이기에 당연한 것이 되었다.<blockquote>
<ul>
<li>계획을 세울 때 지시한 기능에 따라서 다르게 조사 시켰다.나는 이 기능이 필요한데 (내가 사용하려고 만든 앱이니까) 남들이 사용할 때에도 필요한 기능인지, 혹은 추가 기능이 필요한지 판단이 제대로 서지 않을 때에는 커뮤니티를 주로 확인하라고 했다. 주로 레딧을 많이 참조하거나 내가 모르는 해외 유명 커뮤니티, 혹은 국내의 관련 분야 유명 커뮤니티를 조사하더라.</li>
<li>내가 만든 앱은 음악 관련 앱이기에 튜너를 만들 땐 논문을 참고하라고 했다. 기타/베이스 음역대에 따른 주파수 분석, 정밀도, 핸드폰 마이크로 수음하는 소리 감지 후 분석, 캐패시터, 인덕터 등 정밀하게 분석할 수 있도록 관련 논문들을 찾아서 내 앱에 맞게 수치를 조절하며 개발하였다.</li>
<li>그리고 내가 만들려는 분야에서 실제 운영하고 서비스하는 어플, 오픈소스 등 무조건 유명한 것들을 참고해서 내 서비스에 어떻게 녹일 수 있을지 물어보았다.</li>
<li>마지막으로 위와 같은 과정을 통해 계획을 하게 되면 어떻게 개발을 할 것인지 주저리주저리 말해주는데, 해당 계획을 md 파일로 어느 순서로 개발할 것인지 Phase (혹은 step)으로 나눠서 정리해달라고 했다.</li>
</ul>
</blockquote>
</li>
</ul>
<h3 id="3-개발-시키기">3. 개발 시키기</h3>
<ul>
<li>1단계에서 내가 정한 작은 단위를 2단계에서 Phase 별로 더 작게 쪼개어 개발을 시켰다.<blockquote>
<ul>
<li>Phase 별로 개발을 시키고, 해당 개발이 끝나면 발생할 수 있는 사이드 이펙트를 항상 분석하고 당장 수정할 수 있는 것과 추후 수정해야 할 것들을 분리시켜 알려달라고 하였다.</li>
<li>그리고 하나의 Phase가 끝나면 해당 Phase에서는 어떤 개발을 진행하였고 발생한 이슈, 앞으로 수정해야 할 것들, 다음은 무엇을 개발할 것인지 md파일에 업데이트 하며 저장하라고 했다.</li>
</ul>
</blockquote>
</li>
</ul>
<h3 id="4-qa">4. QA</h3>
<ul>
<li>한 사이클 (1~3 단계)를 돌면 QA를 진행시켰다. 개발 도중 발견하지 못한 것들을 재확인하는 QA 검증을 돌렸다.<blockquote>
<ul>
<li>이슈를 잡으며 개발 했지만 더 세분화되게 QA를 진행시키니 작은 기능마다 이슈가 꽤 나오더라..</li>
<li>한 기능에 대한 QA가 종료되면 회귀 테스트, 통합 테스트를 진행시켰고, ios 같은 경우 API 연동 테스트까지 진행하며 이슈를 잡았다.</li>
<li>QA를 자세하게 하기 위해 만든 프롬프트 및 템플릿 가이드를 준수하도록 하였다.</li>
</ul>
</blockquote>
</li>
</ul>
<h3 id="5-해킹해봐">5. 해킹해봐.</h3>
<ul>
<li>무작정 해킹하라고 했다.<blockquote>
<ul>
<li>서버에 올리기 전에는 내 코드들을 풀스캔해서 보안 취약점을 찾아달라고 한 다음, 이슈 목록 리스트 만들어주고, 어떻게 수정하면 좋을지 또 다시 계획하고 수정 시켰다.</li>
<li>서버에 배포를 하고, 앱 심사를 올리기 전에 무작정 내 서버를 알려주고 해킹하라고 했다. 간단한 해킹 기법부터 랜섬웨어 등의 다양한 해킹 기법을 사용해서 해킹하고 보안취약점을 다시 찾게 시켰다. (<del>회사에서 랜섬웨어 맞은 적이 있어서 보안 이슈 터지면 PTDS 온다</del>)</li>
<li>어느 정도 되었다 싶은 시점에 앱 심사를 올렸고 앱 출시를 드디어 하게 되었다.</li>
</ul>
</blockquote>
</li>
</ul>
<h3 id="6-마무리">6. 마무리</h3>
<ul>
<li>내 앱은 밴드 음악 하는 사람들을 위한 앱이고, 서비스를 한국만 국한시키기엔 아까워서 일본어와 영어까지 처음부터 로컬라이징 해서 개발하였다. (출시하고 홍보를 적극적으로 하지 않았는데, 일본에서 다운로드가 있다는 것에 좀 놀랐다. 물론 ASO 최적화를 시키기 위해 꽤 공을 들였다.)</li>
<li>프롬프트 깎는 노인 마냥 계속 깎았다. 깎은 것을 토대로 AGENTS.md, CLAUDE.md를 맞춰서 만들었고 참고하여 개발할 수 있는 템플릿들을 만들고 수정해서 귀찮음이 많이 줄었다.</li>
<li>이슈가 나오거나 내 온라인 월세 친구들이 갑자기 멍청해져서 코드를 잘못 짤 때가 생기면 화나지만 다시 또 자세하게 설명했다. 화난다고 무작정 욕 박거나 &quot;이거 아니잖아&quot; 혹은 &quot;내가 이렇게 하라고 했는데 왜 너 마음대로 했어&quot; 라던가 &quot;왜 멍청해졌냐며 다시 수정해줘&quot; 라던가 식으로 질의하면 더 코드를 멍청하게 작성하는 거 같았다. 그렇기에 이상하게 코드를 짜와도 참고 계속해서 설명하고 나의 의도를 학습시켰다.</li>
<li>iOS를 출시한 이후 안드로이드 수요가 생각보다 많아서 위와 같은 방법으로 안드로이드를 개발 시키는 중이고, iOS 앱을 이미 만들어 놓은 상태에서 안드로이드 포팅을 시키니 딸깍 시간이 비약적으로 줄어서 iOS에 만든 큰 기능을 포팅시키는데 2일 걸렸다. QA하고 배포 준비하고 하면 시간이 꽤 걸리겠지만 4월 중순에는 어떻게든 안드로이드 1.0.0 버전을 출시할 수 있지 않을까</li>
<li>개인적인 생각이지만 Codex를 사용할 때 한국 시간 기준으로 저녁 9시부터 새벽 시간엔 급격하게 멍청해지는 기분이 들었다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] Typography]]></title>
            <link>https://velog.io/@cest_pangeun/CSS-Typography</link>
            <guid>https://velog.io/@cest_pangeun/CSS-Typography</guid>
            <pubDate>Fri, 01 Jul 2022 04:36:40 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/854eed05-520c-4339-b04b-7dee1652f9c9/image.png" alt=""></p>
<p>내가 느끼기에 웹이든 앱이든 아무리 디자인이 잘 나왔다고 해도 폰트가 그지같으면 안 예뻐보인다. 그만큼 폰트가 디자인에 차지하는 비중이 엄청 크다고 생각하는 사람 중 한 명이다. 오늘은 <strong>Typography</strong>에 대해서 공부해보자.
(이 글은 김버그의 CSS 강의를 듣고 정리한 글입니다)</p>
<h3 id="font-size"><code>font-size</code></h3>
<p>말 그대로 글씨의 크기를 설정할 수 있다. 폰트 사이즈를 설정할 수 있는 단위는 총 3가지이다.</p>
<ul>
<li><code>px</code> : [절대 단위]</li>
<li><code>em</code> : [상대 단위 ] equal to capital M의 약자로, 대문자 M 사이즈의 크기를 기준으로 한다고 한다. 이게 도대체 뭔 말일까? 내가 이해한 바로는 다음과 같다.<blockquote>
<p>일단, font-size의 값에 비례해서 결정된다. 예를 들어 <code>font-size: 20px</code>이라고 하자. 그렇다면, <strong>1em</strong>을 <strong>px</strong>로 환산하면 20px이 되고, <strong>1.5em</strong>은 <strong>30px</strong>이 된다.
그렇다면, 도대체 어디에 있는 <code>font-size</code>를 기준으로 <code>em</code>을 설정하는 걸까? 해당 단위가 사용되고 있는 요소의 <code>font-size</code>의 값이 기준이 된다.</p>
</blockquote>
</li>
</ul>
<pre><code class="language-css">div {
    font-size: 20px;
    width: 5em;
}</code></pre>
<p>다음과 같이 코드가 작성되었다고 가정하자. 그렇다면 이 <code>div</code>의 <strong>width</strong> 크기는 <strong>100px</strong>이 되는 것이다. 개념만 봐도 좀 복잡하다. 이걸 실제 코드에 쓰면 더 복잡해질 것이다. 너무 상대적이라 좀 불안정하다고 느낄 수도 있다. 그래서 사실 <code>font-size</code>를 설정할 때 <code>em</code>보단 <code>rem</code>을 사용한다.</p>
<ul>
<li><code>rem</code> : [상대 단위 ] <code>em</code>은 알아봤는데 그럼 <code>rem</code>은 또 대체 뭘까. <strong>root em</strong>이라고 생각하면 되는데, 즉, html에 적용된 <code>font-size</code>의 크기를 <strong>1rem</strong>이라고 정하는 것이다.</li>
</ul>
<pre><code class="language-css">html {
    font-size: 20px;
}

p {
    font-size: 2rem;
}</code></pre>
<p>위와 같은 코드가 있다. <strong>rem</strong>은 root. 즉, _html_에 적용된 <code>font-size</code>를 기준삼는다고 했다. 위 코드에서 우리는 <code>html</code>의 <code>font-size</code>를 <strong>20px</strong>로 정의했기 때문에, <code>p</code> 태그의 <code>font-size</code>는 <strong>40px</strong>이 된다.</p>
<hr>
<h3 id="line-height"><code>line-height</code></h3>
<p>이것도 <code>font-size</code>와 마찬가지로 이름이 직관적이다. <code>line-height</code> 즉, 줄 간격을 뜻한다. <code>line-height</code>도 px, em, rem을 사용할 수 있는데, line-height에서는 <strong>em</strong>을 많이 사용한다. 왜냐? 현재 적용된 폰트 사이즈에 비례해서 줄간격을 얼마나 띄울지를 설정해야 하기 때문이다. <strong>em</strong>이 기본 단위다.</p>
<pre><code class="language-css">p {
    font-size: 20px;
    line-height: 1.5;
}</code></pre>
<p><code>em</code>이 기본 단위이기 때문에, <code>px</code>, <code>rem</code>을 특별히 사용하는 것이 아니라면 위와 같이 단위를 생략해도 된다.
(<code>line-height</code>는 무조건 글자가 줄간격의 정 가운데에 정렬이 된다.)</p>
<hr>
<h3 id="letter-spacing"><code>letter-spacing</code></h3>
<p><code>letter-spacing</code>은 자간을 조정할 수 있다. <code>letter-spacing</code>을 사용할 때에는 <code>px</code>과 <code>em</code>을 사용하게 되는데, 이도 <code>line-height</code>와 마찬가지로 <code>em</code>을 많이 사용한다. 근데 <code>line-height</code>마냥 단위를 생략하면 안된다. 꼭 적어주어야 한다.</p>
<pre><code class="language-css">p {
    font-size: 20px;
    line-height: 1.5;
    letter-spacing: -0.01em;
}</code></pre>
<hr>
<h3 id="font-family"><code>font-family</code></h3>
<p><code>font-family</code>는 서체를 결정할 수 있다.</p>
<pre><code class="language-css">p {
    font-family: &quot;Poppins&quot;;
       font-family: &quot;Poppins&quot;, sans-serif;
    font-family: &quot;Poppins&quot;, &quot;Roboto&quot;, sans-serif;
}</code></pre>
<p>위와 같은 코드를 볼 수 있게 되는데, 어렵지 않다. 첫 번째 폰트를 사용하고, 만약 없으면 다음 폰트를 사용하라는 뜻이다.</p>
<hr>
<h3 id="font-weight"><code>font-weight</code></h3>
<p><code>font-weight</code>는 폰트의 굵기를 설정한다. 값은 100부터 900까지 100단위로 있는데, 높을수록 굵어진다.</p>
<ul>
<li>100 : thin</li>
<li>300 : Light</li>
<li><strong>400 : Regular</strong></li>
<li>500 : Medium</li>
<li><strong>700 : Bold</strong></li>
<li>900 : Black</li>
</ul>
<hr>
<h3 id="color"><code>color</code></h3>
<p>말 그대로 글씨의 색상을 조절한다.
색상을 조정할 때에는 3가지 표현 방식이 있다.</p>
<ul>
<li><code>hex</code> : #000000</li>
<li><code>rgb</code> : rgb(0, 0, 0)</li>
<li><code>rgba</code> : rgba(0, 0, 0, 1) - 마지막 인자는 alpha. 투명도이다. </li>
</ul>
<hr>
<h3 id="text-align"><code>text-align</code></h3>
<p><strong>text</strong>를 정렬할 때 사용한다. <code>left</code> <code>right</code> <code>center</code> 등 text의 정렬 방향을 정하면 된다.</p>
<hr>
<h3 id="text-indent"><code>text-indent</code></h3>
<p>텍스트를 들여쓰고 싶을 대 사용한다. </p>
<pre><code class="language-css">p {
    font-size: 20px;
    line-height: 1.5;
    letter-spacing: -0.01em;
    text-indent: 50px;
}</code></pre>
<hr>
<h3 id="text-transform">text-transform</h3>
<p>이 속성은 알파벳을 사용하는 언어들을 다룰 때 사용하면 된다.</p>
<ul>
<li><code>none</code></li>
<li><code>capitalize</code></li>
<li><code>uppercase</code></li>
<li><code>lowercase</code></li>
</ul>
<hr>
<h3 id="text-decoration">text-decoration</h3>
<p>이 속성은 텍스트에 줄을 그어버릴 때 사용한다. 밑줄이라던가.. 가운데줄이라던가..
이 속성은 주로 <code>a</code> 태그에 사용한다. 왜냐? <code>a</code> 태그를 사용하면 기본적으로 밑줄이 생기게 되는데, 이 밑줄을 지울 수 있다!</p>
<ul>
<li><code>none</code></li>
<li><code>underline</code></li>
<li><code>line-through</code></li>
<li><code>overline</code></li>
</ul>
<hr>
<h3 id="font-style"><code>font-style</code></h3>
<p>주로, 폰트를 기울이고 싶을 때 사용한다.</p>
<ul>
<li><code>normal</code></li>
<li><code>italic</code></li>
<li><code>oblique</code></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CSS] box에 관하여]]></title>
            <link>https://velog.io/@cest_pangeun/CSS-box%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC</link>
            <guid>https://velog.io/@cest_pangeun/CSS-box%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC</guid>
            <pubDate>Wed, 29 Jun 2022 04:51:56 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/1aa6dec1-168c-4a05-be66-d6f34d8250ef/image.png" alt=""></p>
<p>CSS를 작성할 때 <strong>box</strong>의 개념이 중요하다. content와 padding, border, margin에 대한 개념을 잘 알아야 하는데, 이것들에 대해 알아보자.</p>
<p>이 글은 내가 이해하면서 적은 흐름대로 적은 글이다. 공부한 것을 복기시키려고 작성한 글이기에, 남이 볼 때 글의 흐름이 이해가 전혀 안 될 수 있음을 알아두자.</p>
<h3 id="border">border</h3>
<p>border는 content를 감싸는 테두리라고 생각하면 된다.</p>
<p><code>border: 1px solid #000</code>
<strong>border</strong>에 대해 속성을 줄 때에는 위처럼 3가지 값을 주어야 한다.
순서대로 굵기, 스타일, 색상이다. 적용할 때 순서는 크게 상관 없지만, border를 표시하고 싶으면 3가지 속성을 꼭 적용시켜 주어야 한다.</p>
<pre><code class="language-css">div {
  margin: 0 auto;
  background-color: #2860E1;
  width: 100px;
  height: 100px;

  border: 5px solid black;
}</code></pre>
<p>위에 대한 결과값은 다음과 같다.
<img src="https://velog.velcdn.com/images/cest_pangeun/post/cd20a6d6-b6f6-44c7-ba88-45c810bcadb2/image.png" alt=""></p>
<p>스타일에는 다음과 같은 종류가 있다.</p>
<ul>
<li><code>solid</code></li>
<li><code>dashed</code></li>
<li><code>dotted</code></li>
</ul>
<br />

<p>이때, border값을 주고 싶지 않을 때가 있는데, 이때는 <code>border: none</code>을 사용하면 된다.</p>
<p>border에는 <code>border-radius</code>라는 속성이 있다. 이는 border를 둥글게 만들어 줄 수 있다. 이에 대한 값은 <code>px</code>로 주면 된다.</p>
<p><code>border-radius: 25px</code>를 적용시키면 다음과 같이 변한다.
<img src="https://velog.velcdn.com/images/cest_pangeun/post/8dab5beb-4284-4811-964b-f73a21d8cb14/image.png" alt=""></p>
<p>다음과 같이 테두리 중 한 부분만 <code>radius</code> 값을 줄 수도 있으며, 한 쪽만 <code>border</code>를 줄 수 있다.</p>
<pre><code class="language-css">.box {
  width: 300px;
  height: 300px;

  /* border: 1px solid #000; */
  /* border-radius: 5px; */
  border-top: 1px solid #000;
  border-top-left-radius: 10px;
  border-bottom-right-radius: 30px;

  padding-left: 30px;
  padding-top: 20px;
  background-color: hotpink;
}</code></pre>
<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/2bc36981-c005-4931-89f8-5a9ecd8e1236/image.png" alt=""></p>
<p>위와 같이 만든 <code>box</code>에 속성이 잘 먹었나 확인해보려면 브라우저의 개발자 도구를 확인하면 된다.</p>
<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/003052f3-7ec3-4e6e-98ff-b0578d765aa6/image.png" alt=""></p>
<p>가장 밑부분을 확인해보면, <code>width</code>, <code>height</code> 뿐만이 아니라 <code>padding</code>, <code>border</code> 등이 잘 적용된 것을 볼 수 있다.</p>
<h3 id="box-sizing"><code>box-sizing</code></h3>
<p><code>box-sizing</code>에 대해 생각을 해보자. 우리가 보통 <code>width</code>와 <code>height</code>를 주게 되면, 각 값에 맞추어서 <strong>content</strong>가 설정된다. 그런데 여기에서 <code>padding</code>이나 <code>margin</code> 값을 주게 되면 어떻게 될까??</p>
<p><code>div</code>에 <code>width</code>와 <code>height</code>를 각각 <code>300px</code>씩 주고, <code>padding</code>을 <code>50px</code>로 설정해보자. 그럼 이 <code>div</code>의 최종 크기는 얼마나 될까? <code>300px</code>로 생각할 수 있지만, 실제 크기는 <code>400px</code>로 설정된다. 왜일까?</p>
<p>이는 <code>box-sizing</code>이 기본 속성으로 <code>content-box</code>로 되어있기 때문이다. <code>content-box</code>는 <code>content</code> 자체만을 위한 높이와 넓이를 설정한다. 그렇기에 실질적인 최종 크기는 padding, border 대한 크기도 합산하여 나온다.</p>
<p>그런데 우리는 보통 디자인을 할 때, content만의 크기를 생각하지 않고, <strong>border</strong>까지의 크기를 생각하여 디자인한다. 그렇다면, 보통 우리가 생각하는 크기에 맞춰서 그려주려면 어떻게 해야할까? 간단하다.</p>
<p><code>box-sizing: border-box</code>를 설정해 주면 된다.
이렇게 해주면, content, padding, border를 알아서 계산해준다. 즉, 내가 원하는 크기에 맞춰서 개발할 수 있다.</p>
<p>모든 태그마다 <code>box-sizing: border-box</code>를 설정해주기엔 솔직히 너무 귀찮다.
다음과 같이 코드를 작성해 편하게 코딩하자.</p>
<pre><code class="language-css">* {
    box-sizing: border-box;
}</code></pre>
<hr>
<h2 id="box에-관하여">Box에 관하여.</h2>
<p>지금까지 Box Model에 관해서 알아봤다면, 이제 <strong>Box Type</strong>에 대해 알아보자.
Box Model에 대해서 아무리 잘 알아도, Box Type을 잘 모른다면 추후에 CSS를 작성할 때 레이아웃이 깨지게 된다. 다음에 대해서 알아볼 것이다.</p>
<ul>
<li>Block</li>
<li>Inline</li>
<li>Inline Block</li>
<li>Flex</li>
</ul>
<h3 id="block"><code>block</code></h3>
<p>block은 길막한다.
<code>block</code> type으로 <code>div</code>를 설정했다고 가정하자.
이때, <code>width</code>를 따로 설정하지 않으면 <code>width</code>는 부모 content-box의 100%이다.
이게 무슨 말일까? 다음 코드를 통해 알아보자.</p>
<pre><code class="language-html">&lt;div class=&quot;parent&quot;&gt;
  &lt;div class=&quot;child&quot;&gt;
    Child
  &lt;/div&gt;
&lt;/div&gt;</code></pre>
<pre><code class="language-css">.parent {
  background-color: #e5e9f2;
}

.child,
.other {
  height: 50px;
  color: #212529;
  line-height: 50px;
  text-indent: 20px;
}

.child {
  background-color: #ffc82c;
}

.other {
  background-color: #ff4949;
}</code></pre>
<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/0eea86e8-98a8-400b-81fd-f8aa705b9881/image.png" alt=""></p>
<p>위와 같이 코드를 작성했을 때, <code>child</code>의 <code>width</code>는 아무런 설정을 해주지 않았다. 그렇기에 child의 width는 parent의 width 100%의 영역을 차지한다.</p>
<p>그런데 여기서 child에 <code>width: 100px</code>를 적용시키면 어떻게 될까?</p>
<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/494aa651-fa0c-40be-84ff-0dd6f9fd1225/image.png" alt=""></p>
<p>다음과 같이 width에 대한 값을 설정해주더라도, block 되어 남은 공간에 other가 옆에 나란히 존재하지 못한다. 즉, child의 남은 공간에는 margin 값이 parent의 width에 맞춰서 자동으로 들어간다.</p>
<hr>
<h3 id="inline"><code>inline</code></h3>
<p><code>block</code>이 길막한다면 <code>inline</code>은 흐름에 맞추어 흘러간다.
<img src="https://velog.velcdn.com/images/cest_pangeun/post/286c2c59-fedf-4321-8391-2492f90eb46e/image.png" alt=""></p>
<p>위와 같이 공간에 맞추어 흘러간다. 근데 이때, 현재 채워가고 있는 공간이 꽉 찼으면 어떻게 할까? 당연하게 아래 줄로 내려가서 다시 흘러가며 공간을 채운다.
간단히 생각해서 우리가 velog에 글을 쓸 때 한 줄이 꽉 차면 자동으로 다음 줄로 넘어가 글이 계속 써지는 것을 생각하면 된다.</p>
<p><code>block</code>은 <strong>면(영역)</strong>이라고 생각하면 되고, <code>inline</code>은 <strong>선(흐름)</strong>이라고 생각하면 된다.</p>
<p>자연스럽게 흘러가기 때문에 다음과 같은 속성은 🚫<strong>사용이 금지</strong>🚫 된다.</p>
<ul>
<li><code>width</code>, <code>height</code></li>
<li><code>padding-top</code>, <code>padding-bottom</code></li>
<li><code>border-top</code>, <code>border-bottom</code></li>
<li><code>margin-top</code>, <code>margin-bottom</code></li>
</ul>
<p>왜냐? 이들은 흐름을 망치는 속성들이기 때문이다.</p>
<hr>
<h3 id="inline-block"><code>inline-block</code></h3>
<p><code>inline-block</code>은 뭘까. 말 그대로 <code>inline</code>과 <code>block</code>에서 각각 좋은 점들만 가져와서 만든 것이다. 짬짜면같은 느낌이랄까.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML TAG 정리]]></title>
            <link>https://velog.io/@cest_pangeun/HTML-TAG-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@cest_pangeun/HTML-TAG-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Thu, 23 Jun 2022 16:28:14 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/a037a29e-a91d-4ca7-bf00-673438a63bd9/image.png" alt=""></p>
<p>React를 공부하다가 HTML, CSS가 부족하다는걸 느껴 기초를 제대로 다져보려한다. 역시 뭐든 기초가 튼튼해야한다. 이걸 간과해서 삽질하는 시간이 너무 많다.</p>
<p>결국 기초를 제대로 잡고 싶어서 결국 김버그님의 강의를 듣게 되었다.
이 글은 내가 보기 위한 글이라 나만 알아보기 편하게 쓴 글이다.</p>
<h3 id="hn"><code>&lt;hn&gt;</code></h3>
<p>Heading tag라고 하며, <code>h1</code>부터 <code>h6</code>까지 있다. 주로 제목을 나타낼 때 사용한다.</p>
<h3 id="p"><code>&lt;p&gt;</code></h3>
<p>Pagagraph tag이다. 즉, 단락(문단)을 나타낼 때 사용한다.</p>
<h3 id="emphasis">Emphasis</h3>
<p>강조를 할 때 사용하며, <code>&lt;em&gt;</code>과 <code>&lt;strong&gt;</code> 태그가 있다.
브라우저에게 강조한다는 것을 알릴 수 있다.</p>
<p><code>&lt;em&gt;</code>는 강조할 때 기울임 꼴로 표시되며
<code>&lt;strong&gt;</code>은 진하게 표시된다.
<code>&lt;b&gt;</code>도 있는데 볼드 처리가 된다.</p>
<h3 id="br"><code>&lt;br&gt;</code></h3>
<p>줄바꿈을 할 때 사용한다.</p>
<h3 id="링크-anchor">링크 Anchor</h3>
<p><code>&lt;a&gt;</code> 태그가 있는데, 이는 꼭 속성을 넣어주어야 한다. 어떤 속성일까.
<code>&lt;a href=&quot;#&quot;&gt;</code>이다. <code>href</code>를 꼭 넣어주어야 한다. <code>href</code>는 <strong>hypertext reference</strong>를 뜻한다.</p>
<p>다른 사이트나 html 파일로 이동도 가능하지만 <code>&lt;a href=&quot;#hello&quot;&gt;</code> 등으로 <code>href</code> 안에 html 태그의 <code>id</code> 값을 입력해주어 페이지 내 이동도 가능하다.</p>
<h4 id="메일-보내기">메일 보내기</h4>
<p><code>&lt;a href=&quot;mailto:메일주소&quot;&gt;</code>와 같이 작성하면 Anchor 태그를 클릭하였을 때 해당 메일 주소로 바로 메일을 보낼 수 있다.</p>
<h4 id="전화-걸기-모바일-환경">전화 걸기 (모바일 환경)</h4>
<p><code>&lt;a href=&quot;tel:전화번호&quot;&gt;</code> 전화번호를 클릭하면 바로 전화 가능</p>
<h4 id="target_blank"><code>target=&quot;_blank&quot;</code></h4>
<p>이 속성을 사용하면 New Tab이 열린다.</p>
<h3 id="img-src-alt-"><code>&lt;img src=&quot;#&quot; alt=&quot;&quot; /&gt;</code></h3>
<p>이미지를 넣을 때 사용한다. <code>src</code>에는 내가 원하는 이미지의 경로(주소값)을 넣어주면 된다.
그럼 <code>alt</code>는 뭘까? alternative text 대체 텍스트이다. 만약 네트워크 통신이 제대로 이루어지지 않아 이미지가 엑박 뜬다면 사용자 입장에선 뭐지 싶을거다. 그때 나타나게 되는데, 이 이미지가 무얼 뜻하는지 대체로 텍스트가 나오는 것이다.</p>
<h3 id="리스트">리스트</h3>
<p>리스트에는 두 가지 종류가 있는데 <code>&lt;ol&gt;</code>과 <code>&lt;ul&gt;</code> 이다.
<code>&lt;ol&gt;</code> 태그는 순서가 중요한 목록에 대해 사용한다.
<code>&lt;ul&gt;</code> 태그는 순서가 중요치 않은 목록에 대해 사용한다.</p>
<p><code>&lt;li&gt;</code>는 list item의 약자로, 위의 두 태그 안에 자식 태그로 요소를 넣을 때 사용한다.</p>
<h3 id="정의-목록-dl">정의 목록 <code>&lt;dl&gt;</code></h3>
<p>용어를 정의할 때 사용한다. 혹은 <code>key-value</code>로 정보를 제공할 때 사용한다.</p>
<p><code>&lt;dl&gt;</code> 태그의 자식으로 <code>&lt;dt&gt;</code>와 <code>&lt;dd&gt;</code>가 있는데, <code>&lt;dt&gt;</code>는 key를, <code>&lt;dd&gt;</code>에는 value를 넣으면 된다.</p>
<p><code>&lt;dt&gt;</code>를 사용했으면 바로 뒤에 <code>&lt;dd&gt;</code>로 설명을 해주어야 한다.</p>
<h3 id="div"><code>&lt;div&gt;</code></h3>
<p>웹 개발을 하다 보면 <code>&lt;div&gt;</code>를 굉장히 많이 볼 수 있는데 딱히 의미는 없다. 그룹핑을 해주는 것이라고 생각하면 된다.</p>
<h3 id="span"><code>&lt;span&gt;</code></h3>
<p><code>&lt;div&gt;</code>와 마찬가지로 <code>&lt;span&gt;</code>도 딱히 의미는 없다. <code>&lt;div&gt;</code>는 <strong>block</strong> 형태고, <code>&lt;span&gt;</code>은 <strong>inline</strong>이라는 차이 정도?</p>
<h3 id="인용">인용</h3>
<p>말 그대로 인용구를 쓰고 싶을 때 사용한다.
<code>&lt;blockquote&gt;</code>와 <code>&lt;q&gt;</code> tag가 있다.
<code>&lt;cite&gt;</code>를 사용하면 출처를 함께 적을 수 있다.</p>
<p><code>&lt;blockquote&gt;</code>는 인용구 전체를 가져올 때 쓰면 되고,
<code>&lt;q&gt;</code>는 단락 중간에 인용을 표시할 때 사용한다.</p>
<h3 id="form">Form</h3>
<p>사용자로부터 <strong>input</strong>을 통해 값을 받아올 수 있다.
<strong>Form</strong>에는 <code>action=&quot;#&quot;</code> 값이 꼭 있어야 한다. 또한, <code>method</code> 값이 있어야 한다.</p>
<h4 id="label">Label</h4>
<p>폼 양식에 이름을 붙이는 태그
라벨을 사용할 때에는 어떤 <code>input</code>에 관련된 라벨인지 명시해 주어야 한다.
즉, <code>for=&quot;&quot;</code>을 사용하여 명시해 주어야 한다. <code>for</code>의 값에는 <code>input</code>의 <strong>id</strong>를 넣어주어야 한다.
<code>&lt;input&gt;</code>의 id와 <code>&lt;label&gt;</code>의 for 값을 같게 설정하면, <code>label</code>을 클릭했을 때, 자동으로 매칭되어 그에 맞는 <code>input</code>이 <code>focus</code>된다.</p>
<h4 id="input-"><code>&lt;input /&gt;</code></h4>
<p><code>&lt;input&gt;</code> 태그는 사용자로부터 무언가를 받을 수 있는데, <code>type=&quot;?&quot;</code>이 무조건 들어가야 한다.</p>
<ul>
<li><p><code>placeholder</code></p>
</li>
<li><p><code>minlength</code> : input의 최소 길이 설정</p>
</li>
<li><p><code>maxlength</code> : input의 최대 길이 설정</p>
</li>
<li><p><code>required</code> : 필수적으로 입력해야 하는 태그 설정</p>
</li>
<li><p><code>value</code> : placeholder말고 실질적으로 들어가는 값.</p>
</li>
<li><p><code>radio</code> : 선택지 중 하나만 선택 가능</p>
</li>
<li><p><code>checkbox</code> : 선택지 중 여러개 선택 가능</p>
<ul>
<li>위의 두 타입을 이용하여 만들 때에는 <code>name=&quot;&quot;</code>이라는 속성도 추가해 주어야 함.
<code>name</code>은 각 항목들을 그룹화 시킴. 
또한, <code>value</code>도 넣어주어야 함. <code>value</code>는 submit 됐을 때, 선택한 값을 식별할 수 있는 값을 뜻함.</li>
</ul>
</li>
</ul>
<h4 id="select"><code>&lt;select&gt;</code></h4>
<p><code>select</code>는 드롭다운 메뉴가 나온다. <code>&lt;select&gt;</code>의 자식 태그로는 <code>&lt;option&gt;</code>이 들어간다.
<code>&lt;select&gt;</code>에는 <code>name</code> 속성이, <code>&lt;option&gt;</code>에는 <code>&lt;value&gt;</code> 속성이 필수다.</p>
<h4 id="textarea"><code>&lt;Textarea&gt;</code></h4>
<p><code>&lt;textarea&gt;</code>에도 위와 같은 속성들을 사용할 수 있다.</p>
<h4 id="buttons">Buttons</h4>
<p><code>Button</code>에는 <code>type=&quot;&quot;</code>을 꼭 넣어주어야 한다.</p>
<ul>
<li><code>type=&quot;button&quot;</code> : 버튼은 버튼이다. ...?</li>
<li><code>type=&quot;submit&quot;</code> : form을 제출할 때 사용</li>
<li><code>type=&quot;reset&quot;</code> : form을 리셋하고 싶을 때 사용</li>
</ul>
<h3 id="table"><code>&lt;table&gt;</code></h3>
<p>말 그대로 table (표)를 만들 때 사용한다. 조금 찾아보니 table 태그를 싫어하는 개발자가 많다는 것을 알았다. 왜냐? 스타일을 하거나, 반응형을 만들 때 힘들다고 한다.</p>
<p><code>&lt;table&gt;</code> 의 자식 태그로는 <code>&lt;tr&gt;</code> (Table row) 태그가 들어가고, 이 태그 자식으로는 <code>&lt;th&gt;</code> (Table Header) 태그가 들어간다.
<code>&lt;tr&gt;</code>은 행, <code>&lt;th&gt;</code>는 열을 뜻한다.</p>
<p><code>&lt;td&gt;</code> 태그도 있는데, 이 태그는 Table Data를 뜻한다.
<code>&lt;th&gt;</code>를 사용할 때에는 <code>&lt;thead&gt;</code> 태그로 확실하게 헤더라는 것을 알려주는 것도 좋다.
그 밑에는 <code>&lt;tbody&gt;</code>로 묶는 것이 좋다.</p>
<h3 id="미디어-파일">미디어 파일</h3>
<ul>
<li><code>&lt;audio&gt;</code></li>
<li><code>&lt;video&gt;</code><ul>
<li><code>&lt;iframe&gt;</code></li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS 간단 정리]]></title>
            <link>https://velog.io/@cest_pangeun/CSS-%EA%B0%84%EB%8B%A8-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@cest_pangeun/CSS-%EA%B0%84%EB%8B%A8-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Thu, 23 Jun 2022 06:31:19 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/a8fefe5f-3d4e-4d46-ac76-40acf1d218f5/image.png" alt=""></p>
<p>이번에 토이 프로젝트로 크롬 확장 프로그램을 개발해 보면서 CSS로 인해 엄청 골머리 앓아서 이번 기회에 제대로 정리하면서 공부해보려 한다. 사실 잘 알고 있다고 생각했었는데, 막상 직접 해보니 아는 게 아는 것이 아니었다. iOS를 개발할 때는 화면이 작아서 그런지 어렵지 않게 금방 익혀서 활용 했는데, 웹은 화면이 크다 보니 체감상 더 어렵게만 느껴진다.</p>
<hr>
<h2 id="🎨-css-란">🎨 CSS 란?</h2>
<p>그래서 CSS가 뭘까. 웹 개발을 한다면 꼭 알아야 할 지식이며, 기초라는데 도대체 그게 뭔데?
CSS는 <strong>Cascading Style Sheets</strong>의 약자이다. 즉, <code>documents</code>가 사용자에게 어떤 스타일로 보일 수 있을지에 대해 코드를 작성한다. 여기서 말하는 <code>documents</code>는 흔히 우리가 알고 있는 <code>html</code>이라고 생각하면 된다.</p>
<p>CSS는 다음과 보통 같은 방식으로 사용된다. React에서의 <code>styled-component</code>나 <code>emotion</code>, <code>scss</code>와 같은 다른 것들은 다음에 정리할 예정이다.</p>
<pre><code class="language-html">&lt;html&gt;
  &lt;head&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot;&gt;
      &lt;style&gt;
        h1 {
            color: red;
        }
      &lt;/style&gt;
  &lt;/head&gt;

  &lt;body&gt;
    &lt;h1 style=&quot;color: red;&quot;&gt;CSS&lt;/h1&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>
<h3 id="선택자">선택자</h3>
<p>CSS는 <strong>선택자</strong>, <strong>선언</strong>, <strong>속성</strong>으로 이루어져 있다. 제일 중요한 것이니 잊지 말자.</p>
<pre><code class="language-css">p {
    color: blue
}</code></pre>
<p>위의 코드에서 <code>p</code>는 선택자(selector)이며, <code>p</code>를 기준으로 <code>{}</code>로 감싸져 있는 것이 선언 블록(Declaration block)이다. 블록 안에 <code>color</code>가 속성(property)을 뜻하며, <code>red</code>는 속성 값(property-value)를 뜻한다. </p>
<p>선택자의 종류는 3가지가 있다.</p>
<ul>
<li><p>태그 선택자 (tag) : 태그 선택자는 html 태그에 관한 것이며 노멀하게 <code>p</code> 혹은 <code>h1</code> 등으로 쓴다.</p>
</li>
<li><p>클래스 선택자 (<code>.class</code>) : 클래스 선택자는 해당 태그의 클래스에 관한 선택자이며, 클래스 이름 앞에 <code>.</code>을 붙여 <code>.class</code> 와 같이 표현한다.</p>
</li>
<li><p>아이디 선택자 (<code>#id</code>) : 아이디 선택자는 아이디에 관한 선택자이다. 이 선택자는 앞에 <code>#</code>을 붙여서 표현한다.</p>
</li>
</ul>
<hr>
<h3 id="부모-자식-선택자">부모 자식 선택자</h3>
<p>CSS 코드를 보면 여러 선택자가 함께 있는 것을 볼 수 있다. 그건 도대체 뭘까?</p>
<ul>
<li><code>부모 자식  { ... }</code> : 태그 이름 사이에 공백을 넣으면 <code>부모 태그 하위</code>에 있는 <code>자식 태그</code>에 스타일을 적용시킨다.</li>
<li><code>부모&gt;자식 { ... }</code> : 태그 사이에 <code>&gt;</code>를 넣으면 <code>부모</code> 바로 밑에 있는 <code>자식</code>에만 스타일 적용</li>
<li><code>부모,자식 { ... }</code> : 태그 사이에 <code>,</code>를 넣으면 <code>부모</code>와 <code>자식</code> 모두 스타일 적용</li>
<li><code>부모.자식 { ... }</code> : 태그 사이에 <code>.</code>을 넣으면 <code>부모</code> 안에 있는 <code>자식</code> Class만 스타일 적용</li>
</ul>
<hr>
<h3 id="가상-클래스-선택자">가상 클래스 선택자</h3>
<p>가상 클래스 선택자는 또 뭘까.. 이건 클래스 선택자는 아닌데, 클래스 선택자처럼 여러가지 <code>element</code>를 선택하는 것이다. 즉, 선택자 뒤에 <code>:가상이벤트</code>를 붙이면 특정 이벤트마다 적용 할 스타일을 설정할 수 있다. </p>
<ul>
<li><code>:link</code> - 방문한 적이 없는 링크</li>
<li><code>:visited</code> - 방문한 적 있는 링크</li>
<li><code>:hover</code> - 마우스를 위에 올렸을 때</li>
<li><code>:active</code> - 마우스를 클릭했을 때</li>
<li><code>:focus</code> - 포커스가 되었을 때 (<code>input</code> 등)</li>
<li><code>:first</code> - 첫 번째 요소</li>
<li><code>:last</code> - 마지막 요소</li>
<li><code>:first-child</code> - 첫 번째 자식</li>
<li><code>:last-child</code> - 마지막 자식</li>
<li><code>:nth-child(2n+1)</code> - 홀수 번째 자식</li>
</ul>
<hr>
<h2 id="🏷-css-필수-속성">🏷 CSS 필수 속성</h2>
<p>CSS 속성이 진짜 여간 많은게 아니다. 개인적인 생각인데 속성 이름들도 직관적이면서도 전혀 아닌거같다. 처음부터 무작정 다 외울 수는 없으니 일단은, 많이 사용되는 것들 먼저 알아보자.</p>
<h3 id="width-height">width, height</h3>
<p>각각 가로 길이와 세로 길이를 의미한다.
값을 정의할 때는 <code>100px</code> 처럼 숫자와 단위를 표시하며 적는다.</p>
<h4 id="📏-css-단위">📏 CSS 단위</h4>
<p>CSS 단위에 대해서 정리하자면 너무 길기에 이 부분은 따로 나중에 자세히 다룰 것이다. 여기선 간단하게 정의만 하자.</p>
<table>
<thead>
<tr>
<th align="left">절대 단위</th>
<th align="left">상대 단위</th>
</tr>
</thead>
<tbody><tr>
<td align="left"><code>cm</code></td>
<td align="left"><code>em</code></td>
</tr>
<tr>
<td align="left"><code>mm</code></td>
<td align="left"><code>ex</code></td>
</tr>
<tr>
<td align="left"><code>in</code></td>
<td align="left"><code>ch</code></td>
</tr>
<tr>
<td align="left"><code>pc</code></td>
<td align="left"><code>rem</code></td>
</tr>
<tr>
<td align="left"><code>pt</code></td>
<td align="left"><code>lh</code></td>
</tr>
<tr>
<td align="left"><code>px</code></td>
<td align="left"><code>vh</code></td>
</tr>
<tr>
<td align="left"></td>
<td align="left"><code>vw</code></td>
</tr>
<tr>
<td align="left"></td>
<td align="left"><code>vmin</code></td>
</tr>
<tr>
<td align="left"></td>
<td align="left"><code>vmax</code></td>
</tr>
<tr>
<td align="left"></td>
<td align="left"><code>%</code></td>
</tr>
</tbody></table>
<br>

<hr>
<h3 id="margin-padding">margin, padding</h3>
<p><code>margin</code>과 <code>padding</code>은 각각 바깥 여백과 안쪽 여백을 의미한다.
<code>width</code>, <code>height</code>와 마찬가지로 <strong>숫자 + 단위</strong>로 표시하며,
<code>margin</code>과 <code>padding</code>을 나누는 경계는 <code>border</code>이다.</p>
<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/1216902e-d078-4a84-8a38-ebf2509ad03c/image.png" alt=""></p>
<p>다 그리고 보니 너무 형편없이 그렸나 싶지만 나름 표현 잘 한 것 같기도 하다. (뿌듯)</p>
<h4 id="방향">방향</h4>
<p>방향마다 여백을 다르게 설정할 수 있다. 방향은 <strong>위</strong>에서부터 시계방향으로 회전하며 설정한다.</p>
<ul>
<li><code>margin: 20px</code> : 상하좌우 모두 20px</li>
<li><code>margin: 30px 10px</code> : 상하 30px, 좌우 10px</li>
<li><code>margin: 30px 10px 20px 50px</code> : 상 30, 우 10, 하 20, 좌 50</li>
<li><code>margin: 30px 10px 40px</code> : 상 30, 좌우 10, 하 40</li>
</ul>
<br>

<hr>
<h3 id="box-sizing">box-sizing</h3>
<p><code>element</code>의 <code>width</code>와 <code>height</code>를 지정할 때 내가 원하는대로 적용되지 않을 때가 있는데 이는 <code>border</code>나 <code>padding</code>, <code>margin</code> 때문일 것이다.</p>
<p>왜냐하면  <code>width</code>, <code>height</code>는 <code>content</code>의 크기를 정하는 것이기 때문에, <code>content-box</code>의 크기는 <code>padding</code>과 <code>border-width</code>까지 더해져서 그려진다.</p>
<p><code>box-sizing: content-box</code>가 기본값인데, <code>border</code>의 경계선까지 크기를 지정하고 싶으면 <code>box-sizing: border-box</code>로 설정하면 된다.</p>
<br>

<hr>
<h3 id="font">font</h3>
<p>말 그대로 글자의 폰트를 설정하는 속성이다.</p>
<ul>
<li><code>font-style</code> : 글꼴의 스타일 지정</li>
<li><code>fon-size</code> : 글자 크기</li>
<li><code>font-height</code> : 줄 간격</li>
<li><code>font-weight</code> : 글자 두께</li>
<li><code>font-family</code> : 글꼴 설정</li>
</ul>
<br>

<hr>
<h3 id="color">color</h3>
<p><code>color</code> 속성은 <code>text</code>의 색상을 의미한다.</p>
<ul>
<li><code>red</code>, <code>blue</code>, <code>green</code> 등과 같이 이미 정의된 색</li>
<li><code>#000</code>, <code>#FFF</code> 등 hex 색상 코드</li>
<li><code>rgb(0, 0, 0)</code> rgb 색상</li>
<li><code>rgba(0, 0, 0, 0.5)</code> alpha(투명도)가 적용된 rgba 색상</li>
</ul>
<br>

<hr>
<h3 id="display">display</h3>
<p><code>display</code>는 <code>element</code>를 어떻게 보여줄지 결정한다.</p>
<ul>
<li><code>none</code> : <code>element</code>를 렌더링하지 않는다. 즉, 영역을 차지하지 않는다.</li>
<li><code>block</code> : <code>div</code>, <code>p</code>, <code>h</code>, <code>li</code> 등이 해당되며, 기본적으로 가로 영역을 모두 채운다. 그리고 그 다음에 등장하는 태그들은 줄바꿈되어 나타난다.</li>
<li><code>inline</code> : <code>span</code>, <code>b</code>, <code>i</code>, <code>a</code> 등이 여기에 해당되고, 줄바꿈되지 않으며, <code>width</code>와 <code>height</code> 지정이 불가능하다. 줄바꿈은 되지 않고, 태그 바로 옆에 표시된다.</li>
<li><code>inline-block</code> : <code>block</code>과 <code>inline</code>의 합친 형태로 생각할 수 있다. 줄바꿈은 되지 않지만, 크기 조절은 가능하다.</li>
<li><code>flex</code> : flexible-box를 사용할 수 있는 속성이다. 각 요소들을 <code>item</code>으로 보고 이 <code>item</code>들을 효과적으로 정렬하고 배치할 수 있도록 도와준다. <em>반응형 페이지를 만든다면 이 부분은 무조건 필수적으로 잘 활용할 줄 알아야 한다고 생각한다.</em> 이 부분도 굉장히 중요하다고 생각하기에 따로 글을 정리하자.</li>
</ul>
<br>

<hr>
<h3 id="align">align</h3>
<ol>
<li><p><code>text-align</code>
 <code>block</code> 안에 존재하는<code>inline</code> 요소들을 정렬한다.</p>
<ul>
<li><code>left</code> : 왼쪽 정렬</li>
<li><code>right</code> : 오른쪽 정렬</li>
<li><code>center</code> : 중앙 정렬</li>
<li><code>justify</code> : 양쪽 정렬</li>
</ul>
</li>
<li><p><code>margin</code>
 <code>margin: 0 auto</code> 를 사용하면 상하는 <code>0px</code>, 좌우는 <code>auto</code>로 설정된다. 즉, 중앙 정렬을 할 수 있다. 생각해보면 당연하게도 <code>inline</code> 요소에는 먹히지 않는다.</p>
</li>
</ol>
<br>

<hr>
<h3 id="position">position</h3>
<p>포지션은 태그를 어떻게 위치시킬지를 정의한다.</p>
<ul>
<li><code>static</code> : 기본값이며, 다른 태그와의 관계를 통해 자동 배치된다. 그렇기에 위치를 임의로 설정할 수 없다.</li>
<li><code>absolute</code> : 절대 좌표를 이용해서 위치를 지정할 수 있다.</li>
<li><code>relative</code> : 원래 있던 위치(부모)를 기준으로 좌표를 지정한다.</li>
<li><code>fixed</code> : 스크롤과 상관없이 항상 문서의 좌측 상단을 기준으로 좌표를 고정한다. (웹 페이지를 만들 때 페이지의 <code>header</code>를 생각하면 이해하기 쉽다.</li>
<li><code>inherit</code> : 부모 태그의 속성값을 상속받는다.</li>
</ul>
<p>좌표를 지정할 때에는 <code>left</code>, <code>right</code>, <code>top</code>, <code>bottom</code>과 함께 사용된다.</p>
<p>( <code>absolute</code>나 <code>fixed</code>로 설정하면 <code>block</code>태그의 특징이 사라지니 알아두자)</p>
<br>

<hr>
<h3 id="마무리">마무리</h3>
<p>나중에 다시 정리해야 할 개념 Todo List</p>
<ul>
<li>CSS 단위</li>
<li>Flex 정리</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 크롬 확장 프로그램 만들기]]></title>
            <link>https://velog.io/@cest_pangeun/React-%ED%81%AC%EB%A1%AC-%ED%99%95%EC%9E%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EB%A7%8C%EB%93%A4%EA%B8%B0-1</link>
            <guid>https://velog.io/@cest_pangeun/React-%ED%81%AC%EB%A1%AC-%ED%99%95%EC%9E%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EB%A7%8C%EB%93%A4%EA%B8%B0-1</guid>
            <pubDate>Tue, 21 Jun 2022 06:28:15 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/5b8c2990-d615-4854-84f1-5dea2ec3164e/image.png" alt=""></p>
<p><a href="https://developer.chrome.com/docs/extensions/mv3/getstarted/">Chrome Developers</a>를 참고하며 만들고 작성한 글입니다.</p>
<h3 id="프로젝트-세팅">프로젝트 세팅</h3>
<p>리액트 개념을 훑긴 했는데 배운 개념들을 활용해 보기 위해서 간단하게 크롬 확장 프로그램을 만들어보려고 한다. 클론 코딩 말고 리액트로 처음 해보는 나의 아주 작은 프로젝트라서 코드가 조금 지저분 할 수 있지만, 그래도 만들어서 사람들에게 배포해보는 것을 목표로 한다.</p>
<p>우선, <code>yarn create react-app</code>으로 프로젝트를 만들어 주었다. (npm으로 해도 똑같다)
<code>create react-app</code>을 하면 <code>public</code> 폴더에 <code>manifest.json</code> 파일이 생긴 것을 볼 수 있다. 크롬 확장 프로그램을 만들기 위해선 먼저 이 파일을 수정해야 한다.</p>
<pre><code class="language-json">{
  &quot;name&quot;: &quot;My Lang&quot;,
  &quot;description&quot;: &quot;한국외대 학생을 위한 외국어 공부 도움 어플리케이션&quot;,
  &quot;manifest_version&quot;: 3,
  &quot;version&quot;: &quot;1.0.0&quot;
}</code></pre>
<p>다음과 같이 수정했다. 각 <code>key</code>가 의미하는 바는 다음과 같다.</p>
<ul>
<li><code>name</code> : 말 그대로 앱의 이름</li>
<li><code>description</code> : 앱의 설명</li>
<li><code>menifest_version</code> : 22년 6월 21일 기준으로 Chrome Extensions용 매니페스트 버전은 V3이다. Version 3에서는 보안이나 개인 정보 보호 및 성능 향상 등을 누릴 수 있다고 하는데 매니페스트에 관련된 내용도 꽤 많아서 이 부분은 추후에 공부해보려 한다. 지금 당장은 이렇게 하라니깐 해봐야지,,,</li>
<li><code>version</code> : 앱의 버전</li>
</ul>
<p><code>manifest.json</code> 파일을 위와 같이 수정했으면, <code>yarn build</code> 혹은 <code>npm build</code>를 해준다.</p>
<p>빌드를 한 이후에는 <code>chrome://extensions/</code>으로 이동하여 개발자 모드를 켜준다.
<img src="https://velog.velcdn.com/images/cest_pangeun/post/3c0ad650-df34-4842-aa7a-30bc334b448c/image.png" alt=""></p>
<p>개발자 모드를 켜주면 밑에 3가지 버튼이 생긴다. 우리는 첫 번째 <strong>압축해제된 확장 프로그램을 로드합니다</strong>를 선택할 것이다. 선택 후, 방금 <code>yarn build</code>를 통해 생성된 <code>build</code> 폴더를 <strong>load</strong> 해주면 내가 만든 프로젝트가 나타난다!! 즉, 설치되었다.</p>
<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/e761f64c-bb5d-4d99-bbc9-a157ff9be0e8/image.png" alt=""></p>
<p><code>manifest.json</code>에서 설정한 <code>name</code>, <code>description</code> <code>version</code> 등이 여기에 표시된다. 아이콘은 아직 설정하지 않았기에, <code>Default</code> 아이콘이 들어가있다.</p>
<p><strong>extension</strong>이 추가는 되었는데, 우리가 무엇을 할지 설정한 것이 없어서 아마 당장은 아무 것도 나타나지 않을 것이다. 이게 진짜로 작동 되는지 간단하게 확인하기 위해서 <code>manifest.json</code>으로 돌아가 <code>background</code>를 설정해보자.</p>
<pre><code class="language-json">{
  &quot;name&quot;: &quot;Getting Started Example&quot;,
  &quot;description&quot;: &quot;Build an Extension!&quot;,
  &quot;version&quot;: &quot;1.0&quot;,
  &quot;manifest_version&quot;: 3,
  &quot;background&quot;: {
    &quot;service_worker&quot;: &quot;background.js&quot;
  }
}</code></pre>
<p>위와 같이 background를 설정해 준 다음, <code>background.js</code>를 만들어서 다음과 같이 작성하자. 원래 <code>background.js</code> 파일을 <code>src</code> 폴더 안에 만든 다음, <code>service_worker</code>의 경로를 <code>../src/background.js</code>로 해주었는데 계속 에러가 나오길래, 어떻게 해결할지 몰라 그냥 <code>background.js</code> 파일을 <code>public</code> 폴더 안에 넣어놨다. 아마 <code>manifest.json</code>과 같은 위치에 있어야 <strong>Load</strong>가 되는 것같다.</p>
<pre><code class="language-js">// background.js

let color = &#39;#3aa757&#39;;

chrome.runtime.onInstalled.addListener(() =&gt; {
  chrome.storage.sync.set({ color });
  console.log(&#39;Default background color set to %cgreen&#39;, `color: ${color}`);
});</code></pre>
<p>근데, 이렇게 작성하면 <code>&#39;chrome&#39; is not defined.eslint no-undef</code> 이런 에러가 나왔다. 찾아보니 <code>env</code>의 <code>webextensions</code> 설정을 <code>true</code>로 바꿔주면 되는 것이었다.
그래서 <code>.eslintrc.json</code> 파일을 만들어 다음과 같이 설정해주었다.</p>
<pre><code class="language-json">{
  &quot;env&quot;: {
    &quot;webextensions&quot;: true
  }
}</code></pre>
<p><strong>storage API</strong>를 포함해서 대부분의 API들은 <code>permissions</code>이 있어야 한다. 그렇기에 또 다시 <code>manifest.json</code>에 가서 <code>&quot;permissions&quot;: [&quot;storage&quot;]</code>를 추가해준다.</p>
<p>위와 같은 설정들을 다 해주고 다시 크롬 익스텐션 페이지로 가면 다음과 같은 것이 생겼을 것이다.
<img src="https://velog.velcdn.com/images/cest_pangeun/post/cac1374a-0e92-4dc8-943b-857ed5c71cb3/image.png" alt="">
또한 <code>뷰 검사: 서비스워커(비활성)</code> 을 눌러보면 다음과 같은 팝업이 나타난다.</p>
<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/5c93c96a-a839-41e1-9fc7-0b09a21bd777/image.png" alt=""></p>
<p>일단, 아이콘은 생략하고 익스텐션에 View를 띄워볼 것이다.</p>
<p><code>minifest.json</code>에 다음 코드를 넣어보자.</p>
<pre><code class="language-json">&quot;action&quot;: {
    &quot;default_popup&quot;: &quot;index.html&quot;
  }</code></pre>
<p>그 다음, 내 확장 프로그램을 클릭하면 다음과 같이 아주 작고 하찮게 뷰가 나올 것이다.
<img src="https://velog.velcdn.com/images/cest_pangeun/post/6f7cf480-0c37-48c4-a3e8-a8fdad7f4693/image.png" alt=""></p>
<p><code>create react-app</code>을 한 이후 뷰를 바꾸지 않아 저 기본 뷰가 나왔다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Redux 개념 (2)]]></title>
            <link>https://velog.io/@cest_pangeun/Redux-%EA%B0%9C%EB%85%90-2</link>
            <guid>https://velog.io/@cest_pangeun/Redux-%EA%B0%9C%EB%85%90-2</guid>
            <pubDate>Sun, 19 Jun 2022 09:55:50 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/f9522ee8-699a-4c57-a76a-a9e058ba7e47/image.png" alt=""></p>
<p>리액트 프로젝트에서 <code>리덕스</code>를 사용할 때 가장 많이 사용하는 패턴은 <code>프레젠테이셔널 컴포넌트</code>와 <code>컨테이너 컴포넌트</code>를 분리하는 것이다.</p>
<ul>
<li><p>프레젠테이셔널 컴포넌트</p>
<blockquote>
<p>상태 관리가 이루어지지 않고, 그저 <code>props</code>를 받아와 화면에 UI를 보여주기만 하는 컴포넌트
즉, 오직 <code>View</code>만 담당하는 컴포넌트이다.</p>
</blockquote>
</li>
<li><p>컨테이너 컴포넌트</p>
<blockquote>
<p>리덕스와 연동되어 있는 컴포넌트.
리덕스로부터 상태를 받아 오기도 하고 리덕스 스토어에 액션을 디스패치 하기도 한다.
즉, 리덕스에 직접 접근이 가능하며, 스타일을 가지고 있지 않아야 한다. 스타일들은 모두 프레젠테이셔널 컴포넌트에 정의되어야 한다.</p>
</blockquote>
</li>
</ul>
<p>이런 패턴은 리덕스를 사용하는 데 필수 사항은 아니지만, <code>UI</code>와 <code>Data</code>가 분리되어 프로젝트를 이해하기 쉬워지며, 컴포넌트의 재사용률도 높여준다.</p>
<p align="center">
<img src="https://velog.velcdn.com/images/cest_pangeun/post/d1353ca2-4ca6-41af-810e-469071b9580f/image.png" width=60% />
</p>


<p><code>프레젠테이셔널 컴포넌트</code>는 <code>src/components</code>에 작성하고
<code>컨테이너 컴포넌트</code>는 <code>src/containers</code>에 작성하면 깔끔하게 정리할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Redux 개념 (1) - 용어 정리]]></title>
            <link>https://velog.io/@cest_pangeun/Redux-%EA%B0%9C%EB%85%90-1-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@cest_pangeun/Redux-%EA%B0%9C%EB%85%90-1-%EC%9A%A9%EC%96%B4-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 19 Jun 2022 08:16:36 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/b9175da6-c9e5-4e9a-ac33-f8b6fe6f1687/image.png" alt="">
👉 이 글은 <code>리액트를 다루는 기술</code>을 읽고 작성된 글 입니다.</p>
<p>Redux는 리액트에서 가장 많이 사용하는 상태 관리 라이브러리이다. <strong>MobX</strong>, <strong>recoil</strong> 등등 여러 상태 관리 라이브러리가 있지만, 일단 채용 공고를 볼 때에 제일 많이 보이는 <strong>Redux</strong>에 대해 공부하며 이후 프로젝트에 적용을 해 볼 예정이다.</p>
<h2 id="리덕스-개념-정리">리덕스 개념 정리</h2>
<p>리덕스에 대해 깊은 공부를 하기 전에, 리덕스를 공부할 때 알아두어야 할 몇가지 키워드에 대해 먼저 알아보자.</p>
<h3 id="액션-action">액션 Action</h3>
<p>상태에 변화가 필요하면 액션(Action)이 발생한다. 이는 하나의 객체로 표현되는데 다음과 같다.</p>
<pre><code class="language-js">{
  type: &#39;TOGGLE_VALUE&#39;
}</code></pre>
<p>액션 객체는 <code>type</code> 필드를 반드시 가지고 있어야 한다. <code>type</code>의 값이 액션의 이름이기 때문이다. 그리고 그 외의 값들은 나중에 State를 업데이트 할 때 참고해야 할 값이며, 내 마음대로 값을 넣을 수 있다.</p>
<pre><code class="language-js">{
  type: &#39;ADD_TODO&#39;,
  data: {
    id: 1,
    text: &#39;리덕스 배우기&#39;
}

{
  type: &#39;CHANGE_INPUT&#39;,
  text: &#39;안녕&#39;
}</code></pre>
<h3 id="액션-생성-함수-action-creator">액션 생성 함수 action creator</h3>
<p>액션 생성 함수(action creator)는 액션 객체를 만들어 주는 함수다.</p>
<pre><code class="language-js">function addTodo(data) {
  return {
      type: &#39;ADD_TODO&#39;,
    data
  }
}

// arrow function으로도 만들 수 있다.
const changeInput = text =&gt; ({
  type: &#39;CHANGE_INPUT&#39;,
  text
)};</code></pre>
<p>상태 변화를 일으커야 할 때마다 액션 객체를 만들어야 하는데, 매번 액션 객체를 만드는 것은 굉장히 번거로운 작업이고, 실수할 수도 있다. 그렇기에 함수로 만들어서 관리하자.</p>
<h3 id="리듀서-reducer">리듀서 Reducer</h3>
<p>리듀서(Reducer)는 변화를 일으키는 함수다.
액션을 만들어서 발생시키면 리듀서가 현재 상태와 전달받은 액션 객체를 파라미터로 받아온다. 그리고 두 값을 참고하여 새로운 상태를 만들어서 반환한다. 리듀서는 다음과 같은 형태이다.</p>
<pre><code class="language-js">const initialState = {
  counter: 1
}

function reducer(state = initialState, action) {
  switch (action.type) {
    case INCREMENT:
      return {
        counter: state.counter + 1
      }

    default:
      return state;
  }
}</code></pre>
<h3 id="스토어-store">스토어 Store</h3>
<p>프로젝트에 리덕스를 적용하기 위해 스토어를 적용시킨다. 프로젝트에는 하나의 스토어만 가질 수 있으며, 현재 애플리케이션 상태와 리듀서, 내장 함수들을 가지고 있다.</p>
<h3 id="디스패치-dispatch">디스패치 Dispatch</h3>
<p>디스패치(dispatch)는 스토어의 내장 함수 중 하나다. 액션을 발생시키는 장치로 이해하면 된다. 이 함수는 <code>dispatch(action)</code> 형태로 액션 객체를 파라미터로 넣어 호출한다.</p>
<p>디스패치가 호출되면, 스토어는 리듀서를 실행시켜 새로운 상태를 만든다.</p>
<h3 id="구독-subscribe">구독 subscribe</h3>
<p>구독(subscribe)도 디스패치처럼 스토어의 내장 함수 중 하나다. <code>subscribe</code> 함수 안에 리스너 함수를 파라미터로 넣어 호출하면, 이 리스너 함수가 액션이 디스패치 되어 상태가 업데이트 될 때마다 호출된다. </p>
<pre><code class="language-js">const listener = () =&gt; {
  console.log(&#39;상태가 업데이트 됨&#39;);
}

const unsubscribe = store.subscribe(listener);

unsubscribe();    // 추후 구독을 비활성화할 때 함수 호출</code></pre>
<p>구독 개념은 내가 ios를 공부하며 <code>MVVM 패턴</code>을 공부할 때도 이해가 잘 되지 않았던 부분이다. <strong>JS</strong>의 <code>Promise</code>나 <strong>Redux</strong>의 <code>subscribe</code>를 이해하는데 꽤 고생했다. 뭔가 한 번에 와닿지 않는 기분이 든다. 이걸 적용하려면 어떻게 해야하지? 라는 생각이 든다. 좀 더 공부하며 여러 코드에 적용시켜봐야 제대로 이해할 수 있을 것만 같다.</p>
<hr>
<h2 id="리덕스의-세-가지-규칙">리덕스의 세 가지 규칙</h2>
<p>리덕스는 다음 세 가지 규칙을 지켜야 한다.</p>
<h3 id="1-단일-스토어">1. 단일 스토어</h3>
<blockquote>
<p>하나의 애플리케이션 안에는 하나의 스토어가 있다. 여러 개의 스토어를 사용할 수는 있지만, 상태 관리가 너무 복잡해진다.
그렇기에 하나만 사용하자.</p>
</blockquote>
<h3 id="2-읽기-전용-상태">2. 읽기 전용 상태</h3>
<blockquote>
<p>리덕스 상태는 읽기 전용(<code>Read Only</code>) 이다. 상태를 업데이트할 때 기존의 객체는 건드리지 않고 새로운 객체를 생성해야 한다. <br>
리덕스에서 불변성을 유지해야 하는 이유는 내부적으로 데이터가 변경되는 것을 감지하기 위해 얕은 비교(shallow equality) 검사를 하기 때문이다.
<br>
즉, 객체의 변화를 감지할 때 객체의 깊숙한 안쪽까지 비교하는 것이 아니라 겉핥기 식으로 비교하여 좋은 성능 유지를 할 수 있다.</p>
</blockquote>
<h3 id="3-리듀서는-순수한-함수">3. 리듀서는 순수한 함수</h3>
<blockquote>
<p>변화를 일으키는 리듀서 함수는 순수한 함수여야 한다.</p>
</blockquote>
<p>순수한 함수는 다음 조건을 만족한다.</p>
<ul>
<li>리듀서 함수는 이전 상태와 액션 객체를 파라미터로 받는다.</li>
<li>파라미터 외의 값에는 의존하면 안된다.</li>
<li>이전 상태는 절대 건드리지 않고, 변화를 준 새로운 상태 객체를 만들어서 반환한다.</li>
<li>똑같은 파라미터로 호출된 리듀서 함수는 언제나 똑같은 결과를 반환해야 한다.</li>
</ul>
<p>⛔️ 리듀서를 작성할 때는 위의 4가지 사항을 주의해야 한다.
예를 들어, 리듀서 함수 내부에서 <code>랜덤 값</code>을 만들거나, <code>Date 함수</code>를 사용하여 현재 시간을 가져오거나, <code>네트워크 요청</code>을 한다면, 파라미터가 같아도 다른 결과를 만들 수 있기에 사용하면 안된다. 이런 작업들은 리듀서 밖에서 처리해야 한다.</p>
<ul>
<li>액션을 만드는 과정에서 처리해도 되고,</li>
<li>리덕스 미들웨어에서 처리해도 된다.</li>
</ul>
<p>주로 네트워크 요청과 같은 비동기 작업은 미들웨어를 통해 관리한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Deep Dive] 10장 객체 리터럴]]></title>
            <link>https://velog.io/@cest_pangeun/Deep-Dive-10%EC%9E%A5-%EA%B0%9D%EC%B2%B4-%EB%A6%AC%ED%84%B0%EB%9F%B4</link>
            <guid>https://velog.io/@cest_pangeun/Deep-Dive-10%EC%9E%A5-%EA%B0%9D%EC%B2%B4-%EB%A6%AC%ED%84%B0%EB%9F%B4</guid>
            <pubDate>Mon, 09 May 2022 08:31:46 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/c0a1feda-1c8b-4795-a285-3128aadc9a10/image.png" alt=""></p>
<h2 id="101-객체란">10.1 객체란?</h2>
<p>자바스크립트는 객체 기반의 프로그래밍 언어이다. 그렇기에 거의 모든 값들이 객체로 이루어져 있으며, 이 부분은 기본적이기에 잘 알아야 한다는 생각이 들었다.
객체의 프로퍼티는 키 key와 값 value로 구성되어 있다.</p>
<pre><code class="language-js">var person = {
  name: &#39;Jeon&#39;,
  age: 20
};</code></pre>
<p>자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값이 될 수 있으며, 자바스크립트 함수는 일급 객체이기에 값으로 취급할 수 있다. 이때, 프로퍼티 값이 함수일 경우 일반 함수와 구분하기 위해서 <strong>메서드 method</strong> 라고 부른다.</p>
<pre><code class="language-js">var counter = {
  num: 0,
  increase: function() {
    this.num++;
  }
};</code></pre>
<p>위의 코드를 보면 프로퍼티와 메서드로 구성된 것을 볼 수 있다.</p>
<blockquote>
<p><strong>프로퍼티</strong> : 객체의 상태를 나타내는 값(data)
<strong>메서드</strong> : 프로퍼티(상태 데이터)를 참조하고 조작할 수 있는 동작(behavior)</p>
</blockquote>
<hr>
<h2 id="102-객체-리터럴에-의한-객체-생성">10.2 객체 리터럴에 의한 객체 생성</h2>
<p>C++나 Java 같은 클래스 기반 객체지향 언어는 클래스를 사전에 정의하고 필요한 시점에 <code>new</code> 키워드와 함께 생성자를 호출하여 인스턴스를 생성한다.
반면에 자바스크립트는 프로토타입 기반 객체지향언어이기 때문에, 다양한 객체 생성 방법을 지원한다.</p>
<ul>
<li>객체 리터럴</li>
<li><code>Object</code> 생성자 함수</li>
<li>생성자 함수</li>
<li><code>Object.create</code> 메서드</li>
<li>클래스(ES6)</li>
</ul>
<p>가장 간단한 방법은 객체 리터럴을 사용하는 방법이다.</p>
<pre><code class="language-js">var person = {
  name: &#39;Jeon&#39;,
  sayHello: function() {
    console.log(`Hello! My name is ${this.name}.`);
  }
};

console.log(typeof person); // object
console.log(person); // { name : &quot;Jeon&quot;, sayHello: f}</code></pre>
<p>만약 중괄호 내에 프로퍼티를 정의하지 않았다면 빈 객체가 생성된다.</p>
<pre><code class="language-js">var empty = {};
console.log(typeof empty); // object</code></pre>
<hr>
<h2 id="103-프로퍼티">10.3 프로퍼티</h2>
<p>객체는 프로퍼티의 집합이며, 프로퍼티는 키와 값(<strong>key:value</strong>)로 구성된다.</p>
<pre><code class="language-js">var person = {
  name: &#39;Jeon&#39;,
  age: 20
}</code></pre>
<ul>
<li>프로퍼티 키 : 빈 문자열을 포함하는 모든 문자열 또는 심벌 값</li>
<li>프로퍼티 값 : 자바스크립트에서 사용할 수 있는 모든 값</li>
</ul>
<p>문자열 또는 문자열로 평가할 수 있는 표현식을 사용해 프로퍼티 키를 동적으로 생성할 수도 있다. 이 경우에는 <code>[...]</code>를 사용한다.</p>
<pre><code class="language-js">var obj = {};
var key = &#39;hello&#39;;

// ES5
obj[key] = &#39;world&#39;;

// ES6
// var obj = { [key] : &#39;world&#39; };

console.log(obj);</code></pre>
<p>만약 프로퍼티 키 값에 문자열이나 심벌 이외의 값(숫자 등)을 사용하면 <em>암묵적 타입 변환을 통해 문자열로 생성된다는 점을 잊지 말자.</em></p>
<p>또한, 이미 존재하는 키에 중복 선언을 하게 되면, 먼저 쓰여진 프로퍼티 값에 덮어쓴다.</p>
<pre><code class="language-js">var foo = {
  name: &#39;Lee&#39;,
  name: &#39;Kim&#39;,
};

console.log(foo);    // { name : &quot;Kim&quot; }</code></pre>
<hr>
<h2 id="104-메서드">10.4 메서드</h2>
<p>자바스크립트에서 사용할 수 있는 모든 값은 프로퍼티 값으로 사용할 수 있다. 그렇기에 함수도 프로퍼티 값으로 사용할 수 있는데, 이때 일반 함수와 구분하기 위해서 <strong>메서드 method</strong> 라 부른다.</p>
<pre><code class="language-js">var circle = {
  radius: 5,

  getDiameter: function() {
    return 2 * this.radius;
  }
};

console.log(circle.getDiameter());</code></pre>
<hr>
<h3 id="105-프로퍼티-접근">10.5 프로퍼티 접근</h3>
<p>프로퍼티에 접근하는 방법은 다음 두 가지 방법이 있다.</p>
<ul>
<li>마침표 프로퍼티 접근 연산자 (<code>.</code>)을 사용하는 마침표 표기법</li>
<li>대괄호 프로퍼티에 접근 연산자 (<code>[...]</code>)를 사용하는 대괄호 표기법</li>
</ul>
<pre><code class="language-js">var person = {
  name: &#39;Lee&#39;,
}

console.log(person.name); // Lee
console.log(person[&#39;name&#39;]); // Lee</code></pre>
<p>이때, 대괄호 표기법을 사용할 땐, <strong>대괄호 프로퍼티 접근 연산자 내부에 지정하는 프로퍼티 키는 반드시 따옴표로 감싼 문자열</strong> 이어야 한다. 만약 그렇지 않으면 JS 엔진은 식별자로 판단을 한다.</p>
<pre><code class="language-js">var person = {
  name: &#39;Lee&#39;
};

console.log(person[name]);    // ReferenceError: name is not defined</code></pre>
<p>또한, 존재하지 않은 프로퍼티에 접근하게 되면 <code>undefined</code>를 반환한다. 이때는 <code>ReferenceError</code>가 발생하지 않으니 주의하자.</p>
<pre><code class="language-js">var person = {
name: &#39;Lee&#39;
};

console.log(person.age) // undefined</code></pre>
<hr>
<h2 id="106-프로퍼티-값-갱신">10.6 프로퍼티 값 갱신</h2>
<p>위에서 말했듯 이미 존재하는 프로퍼티에 값을 할당하면 프로퍼티 값이 갱신된다.</p>
<pre><code class="language-js">var person = {
  name: &#39;Lee&#39;
};

person.name = &#39;Kim&#39;;

console.log(person);</code></pre>
<hr>
<h2 id="107-프로퍼티-동적-생성">10.7 프로퍼티 동적 생성</h2>
<p>존재하지 않는 프로퍼티에 값을 할당하면 프로퍼티가 동적으로 생성되어 추가되고 프로퍼티 값이 할당된다.</p>
<pre><code class="language-js">var person = {
  name: &#39;Lee&#39;;
}

person.age = 20;

console.log(person); // { name: &#39;Lee&#39;, age: 20 }</code></pre>
<hr>
<h2 id="108-프로퍼티-삭제">10.8 프로퍼티 삭제</h2>
<p><code>delete</code> 연산자는 객체의 프로퍼티를 삭제한다.</p>
<pre><code class="language-js">var person = {
  name: &#39;Lee&#39;;
}

person.age = 20;

// 위에서 추가된 age를 삭제한다.
delete person.age;

// address가 person 안에 없기 때문에 삭제할 수 없으며, 에러는 발생하지 않는다.
delete person.address;

console.log(person); // { name: &#39;Lee&#39;, age: 20 }</code></pre>
<hr>
<h2 id="109-es6에서-추가된-객체-리터럴의-확장-기능">10.9 ES6에서 추가된 객체 리터럴의 확장 기능</h2>
<p>ES6에서는 더욱 간편하고 표현력 있는 객체 리터럴의 확장 기능을 제공한다.</p>
<h3 id="1091-프로퍼티-축약-표현">10.9.1 프로퍼티 축약 표현</h3>
<p>👉 ES5</p>
<pre><code class="language-js">var x = 1, y = 2;

var obj = {
  x: x,
  y: y
};

console.log(obj);    // { x: 1, y: 2}</code></pre>
<p>👉 ES6</p>
<pre><code class="language-js">let x = 1, y = 2;

const obj = { x, y };

console.log(obj);    // { x: 1, y: 2}</code></pre>
<p>위의 두 코드만 비교해도 많이 간단해진 것을 볼 수 있다.</p>
<h3 id="1092-계산된-프로퍼티-이름">10.9.2 계산된 프로퍼티 이름</h3>
<p>👉 ES5</p>
<pre><code class="language-js">var prefix = &#39;prop&#39;;
var i = 0;

var obj = {};

// 계산된 프로퍼티 이름으로 프로퍼티 키 동적 생성
obj[prefix + &#39;-&#39; + ++i] = i;
obj[prefix + &#39;-&#39; + ++i] = i;
obj[prefix + &#39;-&#39; + ++i] = i;

console.log(obj);    // {prop-1: 1, prop-2: 2, prop-3: 3}</code></pre>
<p>👉 ES6</p>
<pre><code class="language-js">const prefix = &#39;prop&#39;;
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>
<h3 id="1093-메서드-축약-표현">10.9.3 메서드 축약 표현</h3>
<p>👉 ES5에서는 메서드를 정의할 때 프로퍼티 값으로 함수를 할당한다.</p>
<pre><code class="language-js">var obj = {
  name: &#39;Lee&#39;,
  sayHi: function() {
    console.log(&#39;Hi! &#39; + this.name);
  }
};

obj.sayHi();    // Hi! LEe</code></pre>
<p>👉 ES6에서는 메서드를 정의할 때 <code>function</code> 키워드를 생략한 축약 표현을 사용할 수 있다.</p>
<pre><code class="language-js">const obj = {
  name: &#39;Lee&#39;,

  sayHi() {
    console.log(&#39;Hi! &#39; + this.name);
  }
};

obj.sayHi(); // Hi! Lee</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Deep Dive] 타입 변환과 단축 변화]]></title>
            <link>https://velog.io/@cest_pangeun/Deep-Dive-%ED%83%80%EC%9E%85-%EB%B3%80%ED%99%98%EA%B3%BC-%EB%8B%A8%EC%B6%95-%EB%B3%80%ED%99%94</link>
            <guid>https://velog.io/@cest_pangeun/Deep-Dive-%ED%83%80%EC%9E%85-%EB%B3%80%ED%99%98%EA%B3%BC-%EB%8B%A8%EC%B6%95-%EB%B3%80%ED%99%94</guid>
            <pubDate>Fri, 06 May 2022 10:50:14 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/a887d40e-a2d7-42ed-9ccc-e2d789912a5d/image.png" alt=""></p>
<h2 id="91-타입-변환이란">9.1 타입 변환이란?</h2>
<p>값의 타입은 개발자의 의도에 따라 다른 타입으로 변환할 수 있는데, 개발자가 의도적으로 값의 타입을 변환하는 것을 <strong>명시적 타입 변환 explicit coercion</strong> 또는 <strong>타입 캐스팅 type casting</strong> 이라고 한다.</p>
<pre><code class="language-js">var x = 10;

var str = x.toString();
console.log(typeof str, str); // string 10

console.log(typeof x, x); // number 10</code></pre>
<p>위의 코드를 보면 알 수 있듯이 변수 <code>x</code>를 <code>toString</code> 함수를 이용하여 타입 변환해서 <code>str</code>에 저장을 하여도 <code>x</code>의 근본적인 타입은 변하지 않는 것을 볼 수 있다.</p>
<p>개발자가 의도적으로 타입을 변경하는 것 말고, 개발자의 의도와 상관 없이 표현식을 평가하는 도중에 자바스크립트 엔진에 의해서 암묵적으로 타입이 자동적으로 변환되기도 한다. 이를 <strong>암묵적 타입 변환 implicit coercion</strong> 또는 <strong>타입 강제 변환 type coercion</strong> 이라고 한다.</p>
<pre><code class="language-js">var x = 10;

var str = x + &#39;&#39;;
console.log(typeof str, str); // string 10

console.log(typeof x, x) // number 10</code></pre>
<p>위의 코드를 보면 <code>str</code>에 <code>x+&#39;&#39;</code>을 할당해 주었다. 자바스크립트 엔진은 이 표현식을 평가하기 위해서 변수 <code>x</code>의 숫자 값을 바탕으로 새로운 문자열 <code>10</code>을 생성하고, <code>10 + &#39;&#39;</code>를 평가한다. 이때, 암묵적으로 생성된 문자열 <code>10</code>은 <code>x</code> 변수에 재할당 되지 않는다. </p>
<p>명시적 타입 변환은 타입을 변경하겠다는 개발자의 의도가 코드에서 드러나 있지만, 암묵적 타입 변환은 자바스크립트 엔진해 의해 강제적으로, 그리고 암묵적으로 변환된다. 그렇기에 코드에 의도가 드러나지 않으며기에 언제 어떠한 방식으로 변환이 되는지 바로 알 수 없다. 이는 차후에 예측할 수 없는 결과나 오류, 버그를 초래하는 일이 발생하게 된다.</p>
<hr>
<h2 id="92-암묵적-타입-변환">9.2 암묵적 타입 변환</h2>
<p>암묵적 타입 변환은 개발자의 의도와는 상관 없이 코드의 문맥을 고려해서 타입을 변환시킨다. </p>
<pre><code class="language-js">&#39;10&#39; + 2 // &#39;102
5 * &#39;50&#39; // 50

!0 // true
if (1) {}</code></pre>
<p>위의 코드처럼 코드 문맥에 부합하지 않는 상황들이 발생할 수 있는데, 이때, 자바스크립트 엔진은 가급적 에러를 발생시키지 않기 위해서 암묵적 타입 변환을 통해 표현식을 평가하게 된다. 그런데 개발자 입장에서 보면 이러한 점이 오히려 추후 버그를 더 발생시키는 요소가 될 수 있을 것같다는 생각이 든다.</p>
<h3 id="921-문자열-타입으로-변환">9.2.1 문자열 타입으로 변환</h3>
<pre><code class="language-js">1 + &#39;2&#39; // &quot;12&quot;</code></pre>
<p>위의 코드의 <code>+</code> 연산자는 피연산자 중 하나 이상이 문자열이므로 문자열 연결 연산자로 동작하게 된다. 즉, 문자열 연결 연산자의 피연산자 중에서 문자열 타입이 아닌 피연산자를 문자열 타입으로 암묵적  타입 변환을 하게 된다. </p>
<p><code>toString()</code> 함수를 통해 문자열로 변환할 수도 있지만 <code>a + &#39;&#39;</code> 표현을 통해 <code>number</code>, <code>boolean</code>, <code>null</code>, <code>undefined</code>, <code>symbol</code>, <code>object</code> 타입 등 모든 타입을 <code>string</code> 타입으로 변환시킬 수 있다.</p>
<h3 id="922-숫자-타입으로-변환">9.2.2 숫자 타입으로 변환</h3>
<pre><code class="language-js">1 - &#39;1&#39; // 0
1 * &#39;10&#39; // 10
1 / &#39;one&#39; // Nan</code></pre>
<p>위 예제에서 사용한 연산자는 모두 산술 연산자이다. 산술 연산자의 역할은 숫자 값을 만드는 것이기에 표현식의 피연ㅇ산자는 모두 코드 모두 숫자 타입이어야 한다.
이때, 피연산자를 숫자 타입으로 변환할 수 없는 경우에는 산술 연술이 불가능 하기 때문에 <code>NaN</code>이 결과값으로 나오게 된다.</p>
<h3 id="923-불리언-타입으로-변환">9.2.3 불리언 타입으로 변환</h3>
<pre><code class="language-js">if (&#39;&#39;) console.log(x);</code></pre>
<p><code>if</code> 문이나 <code>for</code> 문과 같은 제어문 또는 삼항 조건 연산자의 조건식은 불리언 값으로 평가되어야 하는 표현식이다. JS 엔진은 조건식의 평가 결과를 불리언 타입으로 암묵적 타입 변환한다.</p>
<pre><code class="language-js">if (&#39;&#39;)    console.log(&#39;1&#39;);
if (true)  console.log(&#39;2&#39;);
if (0)     console.log(&#39;3&#39;);
if (&#39;str&#39;) console.log(&#39;4&#39;);
if (null)  console.log(&#39;5&#39;);

// 2 4</code></pre>
<p>이때, 자바스크립트 엔진은 불리언 타입이 아닌 Truthy 값 또는 Falsy 값으로 구분한다.
이때, 아래의 값들은 Falsy로 구분이 되는 것들이다.</p>
<ul>
<li><code>false</code></li>
<li><code>undefined</code></li>
<li><code>null</code></li>
<li><code>0</code>, <code>-0</code></li>
<li><code>NaN</code></li>
<li><code>&#39;&#39;(빈 문자열)</code></li>
</ul>
<hr>
<h2 id="93-명시적-타입-변환">9.3 명시적 타입 변환</h2>
<p>개발자의 의도에 따라 명시적으로 타입을 변경하는 방법은 다양하다.</p>
<ol>
<li>표준 빌트인 생성자 함수(<code>String</code>, <code>Number</code>, <code>Boolean</code>)를 <code>new</code> 연산자 없이 호출하는 방법</li>
<li>암묵적 타입 변환을 이용하는 방법</li>
</ol>
<blockquote>
<p>표준 빌트인 생성자 함수왕 표준 빌트인 메서드는 자바스크립트에서 기본적으로 제공하는 함수이다.</p>
</blockquote>
<h3 id="931-문자열-타입으로-변환">9.3.1 문자열 타입으로 변환</h3>
<p>문자열이 아닌 값을 문자열 타입으로 변환하는 방법은 다음과 같다.</p>
<ol>
<li><code>String</code> 생성자 함수를 <code>new</code> 연산자 없이 호출하는 방법</li>
<li><code>Object.prototype.toString</code> 메서드를 이용하는 방법</li>
<li>문자열 연결 연산자를 사용하는 방법</li>
</ol>
<pre><code class="language-js">String(1)         // &quot;1&quot;
(1).toString()     // &quot;1&quot;
1 + &#39;&#39;             // &quot;1&quot;</code></pre>
<h3 id="932-숫자-타입으로-변환">9.3.2 숫자 타입으로 변환</h3>
<p>숫자 타입으로 변환하는 방법은 다음과 같다.</p>
<ol>
<li><code>Number</code> 생성자 함수를 <code>new</code> 연산자 없이 호출하는 방법</li>
<li><code>parseInt</code>, <code>parseFloat</code> 함수를 사용하는 방법</li>
<li><code>+</code> 단항 산술 연산자를 이용하는 방법</li>
<li><code>*</code> 산술 연산자를 이용하는 방법</li>
</ol>
<pre><code class="language-js">Number(&#39;0&#39;)     // 0
parseInt(&#39;0&#39;)     // 0
+&#39;0&#39;             // 0
&#39;0&#39; * 1         // 0</code></pre>
<h3 id="933-불리언-타입으로-변환">9.3.3 불리언 타입으로 변환</h3>
<p>불리언 타입으로 변환하는 방법은 다음과 같다.</p>
<ol>
<li><code>Boolean</code> 생성자 함수를 <code>new</code> 연산자 없이 호출하는 방법</li>
<li><code>!</code> 부정 논리 연산자를 두 번 사용하는 방법</li>
</ol>
<pre><code class="language-js">Boolean(&#39;x&#39;)         // true
Boolean(&#39;&#39;)            // false
Boolean(&#39;flase&#39;)    // true

Boolean(0)            // flase
Boolean(1)            // true

!!&#39;x&#39;;                // true
!!&#39;&#39;;                // false
!!0;                // false

!!null;                // false
!!undefined;        // false
!!{};                // true
!![];                // true</code></pre>
<hr>
<h2 id="94-단축-평가">9.4 단축 평가</h2>
<h3 id="941-논리-연산자를-사용한-단축-평가">9.4.1 논리 연산자를 사용한 단축 평가</h3>
<p><code>논리합(||)</code> <code>논리곱(&amp;&amp;)</code> 연산자 표현식의 평가 결과는 <code>Boolean</code> 값이 아닐 수 있으며, 언제나 2개의 피연산자 중 어느 한쪽으로 평가된다.</p>
<pre><code class="language-js">&#39;Cat&#39; &amp;&amp; &#39;Dog&#39;    // Dog</code></pre>
<p><code>&amp;&amp;</code> 연산자는 두 개의 피연산자가 모두 <code>true</code>로 평가될 때, <code>true</code>로 반환한다. 그리고 좌항에서 우항으로 평가가 진행된다.</p>
<p>위의 코드를 보면 첫 번째 피연산자 <code>Cat</code>은 Truthy 값이기 때문에 <code>true</code>로 평가된다. 사실 첫 번째 피연산자까지만 보고서 값을 평가할 수는 없다. 두 번째까지 봐야 한다. 즉, 논리곱 연산자는 두 번째 피연산자가 평가 결과를 결정한다. 두 번째가 <code>Dog</code> 즉, Truthy 값이기 때문에 논리곱에서는 두 번째 피연산자 (문자열) <code>Dog</code>를 그대로 반환한다.</p>
<pre><code class="language-js">&#39;Cat&#39; || &#39;Dog&#39;</code></pre>
<p><code>논리합(||)</code>은 두 개의 피연산자 중 하나만 <code>true</code>로 평가되어도 <code>true</code>를 반환한다. 위의 코드를 보면 첫 번째 피연산자 <code>Cat</code>이 Truthy한 값이기 때문에 바로 <code>Cat</code>이 반환된다.</p>
<blockquote>
<p><strong>단축 평가 shot-circuit evaluation</strong> 은 논리곱이나 논리합처럼 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환한다.</p>
</blockquote>
<p>단축 평가는 다음 규칙을 따른다.</p>
<table>
<thead>
<tr>
<th>단축 평가 표현식</th>
<th>평가 결과</th>
</tr>
</thead>
<tbody><tr>
<td>true || anything</td>
<td>true</td>
</tr>
<tr>
<td>false || anything</td>
<td>anything</td>
</tr>
<tr>
<td>true &amp;&amp; anything</td>
<td>anything</td>
</tr>
<tr>
<td>false &amp;&amp; anything</td>
<td>false</td>
</tr>
</tbody></table>
<p>단축 평가를 사용하면 <code>if</code>문을 대체할 수 있다.</p>
<pre><code class="language-js">var done = true;
var message = &#39;&#39;;

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

message = done &amp;&amp; &#39;완료&#39;;
console.log(messaghe);        // 완료</code></pre>
<pre><code class="language-js">var done = true;
var message = &#39;&#39;;

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

message = done || &#39;미완료&#39;;
console.log(messaghe);        // 미완료</code></pre>
<h3 id="👉-객체를-가리키기를-기대하는-변수가-null-또는-undefined가-아닌지-확인하고-프로퍼티를-참조할-때">👉 객체를 가리키기를 기대하는 변수가 <code>null</code> 또는 <code>undefined</code>가 아닌지 확인하고 프로퍼티를 참조할 때</h3>
<p>객체는 <code>key</code> 와 <code>value</code>로 구성된 <strong>프로퍼티 property</strong> 의 집합이다. 만약 객체를 가리키기를 기대하는 변수의 값이 객체가 아니라 <code>null</code> 또는 <code>undefined</code>인 경우 객체의 프로퍼티를 참조하면 <strong>타입 에러 Type Error</strong> 가 발생한다. 에러가 발생하면 프로그램은 강제 종료된다.</p>
<pre><code class="language-js">var elem = null;
var value = elem.value; // TypeError: Cannot read property &#39;value&#39; of null</code></pre>
<p>이때, 단축 평가를 사용하면 에러 발생은 일어나지 않는다.</p>
<pre><code class="language-js">var elem = null;
var value = elem &amp;&amp; elem.value;</code></pre>
<h3 id="👉-함수-매개변수에-기본값을-설정할-때">👉 함수 매개변수에 기본값을 설정할 때</h3>
<p>함수를 호출할 때 인수를 전달하지 않으면 매개변수에는 <code>undefined</code>가 할당된다. 이때도 단축 평가를 사용하여 매개변수의 기본값을 설정하면 <code>undefined</code>로 인한 에러 발생을 방지할 수 있다.</p>
<pre><code class="language-js">// 단축 평가를 사용한 매개변수의 기본값 설정
function getStringLength(str) {
  str = str || &#39;&#39;;
  return str.length;
}

getStringLength();        // 0
getStringLength(&#39;HI&#39;);  // 2

// ES6의 매개변수 기본값 설정
function getStringLength(str = &#39;&#39;) {
  return str.length;
}

getStringLength();        // 0
getStringLength(&#39;HI&#39;);    // 2</code></pre>
<p>의도치 않은 에러를 방지하기 위해 단축 평가를 잘 사용해보자.</p>
<h3 id="942-옵셔널-체이닝-연산자">9.4.2 옵셔널 체이닝 연산자</h3>
<p><strong>ES11 (ECMAScript2020)</strong> 에서 도입된 <strong>옵셔널 체이닝 optional chaining</strong> 연산자 <code>?.</code>는 좌항의 피연산자가 <code>null</code> 또는 <code>undefined</code>인 경우 <code>undefined</code>를 반환하고, 그렇지 않으면 우항의 프로퍼티 참조를 이어간다.</p>
<pre><code class="language-js">var elem = null;

var value = elem?.value;
console.log(value); // undefined</code></pre>
<p>👉 옵셔널 체이닝 문법을 보면 위에서 말한 단축 평가가 하는 기능을 하는 것을 볼 수 있다. 이는 ES11 이후에서 사용이 가능하니 이 점 알아두자.</p>
<h3 id="943-null--병합-연산자">9.4.3 <code>null</code>  병합 연산자</h3>
<p>ES11에서 도입된 <strong>null 병합 nullish coalescing</strong> 연산자 <code>??</code>는 좌항의 피연산자가 <code>null</code> 또는 <code>undefined</code>인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환한다. <code>null</code> 병합 연산자 <code>??</code>는 변수에 기본값을 설정할 때 유용하다.</p>
<pre><code class="language-js">var foo = null ?? &#39;default string&#39;;
console.log(foo); // &quot;default string&quot;</code></pre>
<p><code>??</code>는 변수에 기본값을 설정할 때 유용하다. <code>??</code>이 도입되기 전까지는 <code>||</code>를 사용하여 변수에 기본값을 사용했었다.</p>
<p>그런데, <code>||</code>을 사용한 경우, 좌항의 피연선자가 <code>false</code>로 평가되는 <code>Falsy</code>  값이면 우항의 피연산자를 반환한다. 만약 <code>Falsy</code> 값인 <code>0</code>이나 <code>&#39;&#39;</code>도 기본값으로서 유효하다면 예기치 않은 동작이 발생할 수 있다. </p>
<pre><code class="language-js">var foo = &#39;&#39; || &#39;default string&#39;;
console.log(foo);    // &quot;default string&quot;</code></pre>
<p>하지만 <code>??</code>는 좌항의 피연산자가 <code>false</code>로 평가되는 <code>Falsy</code> 값이라도 <code>null</code> 또는 <code>undefined</code>가 아니라면 좌항의 피연산자를 그대로 반환한다.</p>
<pre><code class="language-js">var foo = &#39;&#39; ?? &#39;default string&#39;;
console.log(foo);    // &#39;&#39;</code></pre>
<hr>
<p>리액트나 Node.js를 공부할 때 이 문법을 생각보다 유용하게 사용할 수 있었다. 잘 쓸 수 있도록 더 공부해보자.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Deep Dive] 8장 제어문]]></title>
            <link>https://velog.io/@cest_pangeun/Deep-Dive-8%EC%9E%A5-%EC%A0%9C%EC%96%B4%EB%AC%B8</link>
            <guid>https://velog.io/@cest_pangeun/Deep-Dive-8%EC%9E%A5-%EC%A0%9C%EC%96%B4%EB%AC%B8</guid>
            <pubDate>Thu, 05 May 2022 07:42:02 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/dfbc923b-7b53-4b91-b9de-e4d644890bc4/image.png" alt=""></p>
<p><strong>제어문 control flow statement</strong> 은 조건에 따라 코드 블록을 실행하거나 반복할 때 사용한다. 코드는 일반적으로는 순차적으로 실행되지만, 제어문을 사용하면 코드 흐름을 인위적으로 바꿀 수 있게 된다.</p>
<h2 id="81-조건문">8.1 조건문</h2>
<p><strong>조건문 conditional statement</strong> 은 주어진 조건식의 평가 결과에 따라 실행할 코드를 결정한다. 다음과 같은 두 가지 조건문이 있다.</p>
<ul>
<li><code>if...else</code></li>
<li><code>switch</code></li>
</ul>
<h3 id="811-ifelse">8.1.1 if...else</h3>
<p><code>if...else</code> 문은 주어진 조건식의 평가 결과(논리적 참, 거짓)에 따라 실행할 코드 블록을 결정한다.</p>
<pre><code class="language-js">if (조건식) {
  // 조건이 참일 때
} else {
  // 조건이 거짓일 때
}</code></pre>
<p>👉 <code>if</code> 문의 조건식은 <strong>Boolean</strong> 값으로 평가되어야하며, 조건식을 더 늘리고 싶다면 <code>else if</code> 를 사용하면 된다. 또한 <code>else</code>와 <code>else if</code>는 옵션이기에 사용할 필요가 없다면 사용하지 않아도 된다.</p>
<h3 id="812-switch">8.1.2 switch</h3>
<p><code>switch</code> 문은 주어진 표현식을 평가하여 그 값과 일치하는 표현식을 갖는 <code>case</code> 문으로 실행 흐름을 옮긴다. 만약, 표현식과 일치하는 <code>case</code> 문이 없다면, <code>default</code> 문으로 이동하면 되고, <code>default</code>도 옵션이라 사용하지 않아도 된다. 하지만 언제든 예외가 발생하기 마련이니 사용하는 것이 좋아보인다.</p>
<pre><code class="language-js">switch(표현식) {
  case 표현식1:
    // 표현식과 표현식1이 만족하면 실행된다.
    break;
  case 표현식2:
    // 표현식과 표현식2가 만족하면 실행된다.
    break;
  default:
}</code></pre>
<p>👉 <code>switch</code> 문을 사용할 때 주의할 점은 <code>break</code>이다. <code>break</code>를 적절히 사용하지 않으면, 표현식과 일치하지 않아도 실행 흐름이 다음 flow. 즉, 다음의 <code>case</code>로 넘어가기 때문이다.</p>
<hr>
<h2 id="82-반복문">8.2 반복문</h2>
<p><strong>반복문 loop statement</strong> 은 조건식의 평가 결과가 참인 경우 코드를 실행한다. 그 후 조건식을 계속해서 평가하며, 조건식이 거짓일 때까지 반복 실행된다. JS는 세 가지 반복문을 제공한다.</p>
<ul>
<li><code>for</code></li>
<li><code>while</code></li>
<li><code>do...while</code></li>
</ul>
<h3 id="821-for">8.2.1 for</h3>
<p><code>for</code> 문은 조건식이 거짓으로 평가될 때까지 코드를 반복 실행한다.</p>
<pre><code class="language-js">for (변수 선언문 또는 할당문; 조건식; 증감식) {
  조건식이 참일 경우 반복 실행될 문
}</code></pre>
<p>👉 <code>for</code> 문은 중첩해서 사용 가능하다. 하지만, 알고리즘을 생각 했을 때, 중첩 할수록 수행 시간도 늘어나기에 반복 중첩을 하기 전에 효율을 따져보자.</p>
<h3 id="822-while">8.2.2 while</h3>
<p><code>while</code> 문 또한 주어진 조건식의 평가가 참일 때 코드를 반복해서 실행하게 되는데, <code>for</code>문은 반복 횟수가 확실하게 정해졌을 때 주로 사용하고, <code>while</code> 문은 반복 횟수가 불명확할 때 사용한다.</p>
<pre><code class="language-js">// 무한 루프
while (true) { ... }</code></pre>
<p>👉 주로 <code>while</code>문 안에 조건문을 넣어 특정 조건이 충족 되었을 때, <code>break</code>를 사용하여 종료하는 방식으로 사용한다.</p>
<h3 id="823-dowhile">8.2.3 do...while</h3>
<p><code>do...while</code> 문은 코드를 먼저 한 번 이상 실행한 다음에 조건을 평가한다.</p>
<pre><code class="language-js">var count = 0;

do {
  console.log(count);
  count++;
} while (count &lt; 3);</code></pre>
<hr>
<h2 id="83-break-문">8.3 break 문</h2>
<p><code>switch</code> 문과 <code>while</code> 문에서 봤듯, 반복되어 실행되는 코드 블럭을 탈출한다.
단, 레이블문, 반복문, switch 외에 사용하면 <code>SyntaxError</code>가 발생한다.</p>
<blockquote>
<p>👉 레이블 문 Label Statement란?
식별자가 붙은 statement를 뜻한다.</p>
</blockquote>
<pre><code class="language-js">foo: console.log(&#39;foo&#39;); // foo라는 레이블 식별자가 붙음.</code></pre>
<pre><code class="language-js">outer: for(var i = 0; i &lt; 3; i++) {
  for (var j = 0; j &lt; 3; j++) {
    if (i + j === 3) break outer;
    console.log(`inner[${i}, ${j}]`);
  }
}

console.log(&#39;Done!&#39;);</code></pre>
<p>위의 코드와 같이 레이블 문은 중첩된 <code>for</code> 문 외부로 탈출할 때 유용하지만 그 밖의 경우에는 일반적으로 권장하지 않는다. 이는 코드의 흐름이 복잡해지고, 가독성 또한 나빠진다. 결국 내가 원치 않는 결과값이나 오류를 뿜어낼 가능성이 높다.</p>
<p><code>break</code> 문은 반복문을 더 이상 진행하지 않아도 될 때 사용하도록 하자. </p>
<hr>
<h2 id="84-continue-문">8.4 continue 문</h2>
<p><code>continue</code> 는 반복문의 코드 실행을 현 시점에서 중단하고 반복문의 증감식으로 실행 흐름을 이동한다. 이 문을 만나면 코드를 현 시점에서 중단하는건 <code>break</code>와 같지만 다른 점은 반복문을 탈출하지 않는다는 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Deep Dive] 7장 연산자]]></title>
            <link>https://velog.io/@cest_pangeun/Deep-Dive-7%EC%9E%A5-%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@cest_pangeun/Deep-Dive-7%EC%9E%A5-%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Thu, 05 May 2022 05:04:41 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/1b667c84-70fb-4e11-8b61-0a0652e6d079/image.png" alt=""></p>
<p><strong>연산자 operator</strong> 는 하나 이상의 표현식을 대상으로 산술, 할당, 비교, 논리, 타입, 지수 연산 등을 수행하여 하나의 값을 만든다. 이때 연산의 대상을 <strong>피연산자 operand</strong> 라 한다.</p>
<p>자, 기본적인 용어는 뭔지 알았으니 그럼 지금부터 자바스크립트가 제공하는 다양한 연산자에 대해서 알아보자.</p>
<h2 id="71-산술-연산자">7.1 산술 연산자</h2>
<p><strong>산술 연산자 arithmetic operator</strong> 는 피연산자를 대상으로 수학적 계산을 수행해 새로운 숫자 값을 만든다. 산술 연산이 불가능한 경우 <strong>NaN</strong>을 반환한다.</p>
<h3 id="711-이항-산술-연산자">7.1.1 이항 산술 연산자</h3>
<p><strong>이항 binary 산술 연산자</strong> 는 2개의 피연산자를 산술 연산하여 숫자 값을 만든다. 흔히 우리가 더하고 뺄 때 사용하는 그 연산자 맞다.</p>
<pre><code class="language-js">5 + 2 // 7
5 - 2 // 3
5 * 2 // 10
5 / 2 // 2.5
5 % 2 // 1</code></pre>
<h3 id="712-단항-산술-연산자">7.1.2 단항 산술 연산자</h3>
<p><strong>단항 unary 산술 연산자</strong> 는 1개의 피연산자를 산술연산하여 숫자 값을 만든다.
단항 산술 연산자가 이항 산술 연산자와 다른 점은 증감 연산자(<code>++</code>, <code>--</code>)가 있다.</p>
<pre><code class="language-js">var x = 1;

x++; // x = x + 1
console.log(x) // 2

x--;
console.log(x) // 1</code></pre>
<p>증감 연산자는 위치에 따라 값이 달라지므로 사용할 때 주의하여야 한다. 이는 프로그래밍을 처음 배울 때 많이 헷갈릴 수 있는 부분이다.</p>
<pre><code class="language-js">var x = 5, result;

// 선할당 후증가
result = x++;
console.log(result, x); // 5 6

// 선증가 후할당
result = ++x;
console.log(result, x); // 7 7

// 선할당 후감소
result = x--;
console.log(result, x) // 7 6

// 선감소 후할당
result = --x;
console.log(result, x) // 5 5</code></pre>
<p><code>+</code> 단항 연산자에 대해 더 알아보자.
<code>+</code> 단항 연산자는 숫자 타입이 아닌 피연산자에 사용하면 피연산자를 숫자 타입으로 변환한다. 이때, 피연산자가 숫자 타입으로 바뀔 수 없는 타입일 경우(ex. string) <code>NaN</code>을 반환한다. <code>+</code>가 있듯 <code>-</code>도 있는데 <code>-</code> 단항 연산자는 숫자 타입으로 바꿈과 동시에 부호를 반전시킨다.</p>
<h3 id="713-문자열-연결-연산자">7.1.3 문자열 연결 연산자</h3>
<p><code>+</code> 연산자는 피연산자 중 하나 이상이 문자열인 경우 문자열 연결 연산자로 동작한다.</p>
<pre><code class="language-js">// 문자열 연결 연산자
&#39;1&#39; + 2; // &#39;12&#39;
1 + &#39;2&#39;; // &#39;12

// 산술 연산자
1 + 2; // 3

// true는 1로, false는 0으로 변환된다.
1 + true; // 2
1 _ false; // 1

// null은 0으로 반환된다.
1 + null; // 1

// undefined는 숫자로 타입 변환되지 않는다.
+undefined; // NaN
1 + undefined; // NaN</code></pre>
<p>이 예제에서 볼 수 있듯, 개발자의 의도와는 상관 없이 자바스크립트 엔진이 <strong>암묵적으로</strong> 타입을 변환시킨다. 이를 <strong>암묵적 타입 변환 implicit coercion</strong> 또는 <strong>타입 강제 변환 type coercion</strong> 이라고 한다.</p>
<hr>
<h2 id="72-할당-연산자">7.2 할당 연산자</h2>
<p><strong>할당 연산자 assignment operator</strong> 는 우항에 있는 피연산자의 평가 결과를 좌항에 있는 변수에 할당한다. </p>
<pre><code class="language-js">var x;

x = 10;

x += 5;
x -= 5;
x *= 5;
x /= 5;
x %= 5;

// 문자열 연결 연산자
var str = &#39;My name is&#39;

str += &#39;Jeon&#39;
console.log(str); // My name is Jeon</code></pre>
<hr>
<h2 id="73-비교-연산자">7.3 비교 연산자</h2>
<p><strong>비교 연산자 comparison operator</strong> 는 좌항과 우항의 피연산자를 비교한 다음 그 결과를 불리언 값으로 반환한다. 주로 <code>if</code>문이나 <code>for</code>문과 같은 제어문에서 많이 사용한다.</p>
<h3 id="731-동등일치-비교-연산자">7.3.1 동등/일치 비교 연산자</h3>
<p><strong>동등 비교 loose equality</strong> 연산자와 <strong>일치 비교 strict equality</strong> 연산자는 좌항과 우항의 피연산자가 같은 값으로 평가되는지 비교해 불리언 값을 반환하지만 비교하는 엄격성의 정도가 다르다.</p>
<table>
<thead>
<tr>
<th>비교 연산자</th>
<th>의미</th>
<th>사례</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>==</td>
<td>동등 비교</td>
<td>x == y</td>
<td>x와 y의 값이 같음</td>
</tr>
<tr>
<td>===</td>
<td>일치 비교</td>
<td>x === y</td>
<td>x와 y의 값과 타입이 같음</td>
</tr>
<tr>
<td>!=</td>
<td>동등 비교</td>
<td>x != y</td>
<td>x와 y의 값이 다름</td>
</tr>
<tr>
<td>!==</td>
<td>일치 비교</td>
<td>x !== y</td>
<td>x와 y의 값과 타입이 다름</td>
</tr>
</tbody></table>
<p>위의 표를 보면 동등과 일치 비교의 차이를 알 수 있다. 차이점은 <strong>타입 체크</strong>를 하는지 안하는지를 보게 된다.
동등 비교 <code>==</code> 같은 경우에는 단순히 값만 같으면 같다고 표시한다. 즉 <code>1 == &quot;1&quot;</code> 과 같은 상황에서도 암묵적 타입 변환을 통해 일치하는지를 확인한다. 하지만 일치 비교 <code>===</code> 같은 경우에는 좌항과 우항의 <strong>값 + 타입</strong>이 같아야 최종적으로 <code>true</code>를 반환한다.</p>
<p>타입스크립트와는 다르게 자바스크립트는 타입을 개발자가 직접 설정해 주지 않는다. 그렇기에 예측 가능한 결과를 만들어내기 위해서는 <code>==</code> 보다는 <code>===</code>을 사용하는 것이 더 좋다고 생각이 든다.</p>
<h3 id="732-대소-관계-비교-연산자">7.3.2 대소 관계 비교 연산자</h3>
<p>대소 관계 비교 연산자는 피연산자의 크기를 비교하여 불리언 값을 반환한다.</p>
<pre><code class="language-js">5 &gt; 0; // true
5 &gt; 5; // false
5 &gt;= 5; // true
t &lt;= 5; // true</code></pre>
<hr>
<h2 id="74-삼항-조건-연산자">7.4 삼항 조건 연산자</h2>
<p><strong>삼항 조건 연산자 ternary operator</strong> 는 조건식의 평가 결과에 따라 반환할 값을 정한다. 
<code>조건식 ? 조건식이 true 일 때 반환값 : 조건식이 false 일 때 반환값</code>
<code>var result = score &gt;= 60 ? &#39;pass&#39; : &#39;fail&#39;</code></p>
<p>이때, 조건식의 반환값은 Boolean 타입이어야 하며, Boolean 타입이 아닐 시에는 암묵적인 타입 변환이 발생하게 된다. 위의 조건식 <code>score &gt;= 60</code>의 결과에 따라서 변수 <code>result</code>에 할당될 값이 달라진다.</p>
<p>삼항 연산자는 <code>if</code>문을 간단하게 쓸 때 종종 사용되곤 하는데 너무 남발하게 되면 오히려 코드의 가독성이 떨어질 수 있다고 생각하여 나는 잘 쓰지 않는 편이다. 또한, <code>if...else</code> 문으로 사용할 수 없기에 생각보다 사용할 수 있는 기회가 많은 편도 아니라고 생각이 든다.</p>
<hr>
<h2 id="75-논리-연산자">7.5 논리 연산자</h2>
<p><strong>논리 연산자 logical operator</strong>는 우항과 좌항의 피연산자를 논리 연산 한다.</p>
<table>
<thead>
<tr>
<th align="left">논리 연산자</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td align="left">||</td>
<td>OR</td>
</tr>
<tr>
<td align="left">&amp;&amp;</td>
<td>AND</td>
</tr>
<tr>
<td align="left">!</td>
<td>NOT</td>
</tr>
</tbody></table>
<br />

<hr>
<h2 id="76-그-외-연산자">7.6 그 외 연산자</h2>
<p><del>다양한 연산자가 있지만, 귀찮으니 간단히 요약</del></p>
<ul>
<li><p>쉼표 연산자 <code>,</code></p>
</li>
<li><p>그룹 연산자 <code>()</code></p>
</li>
<li><p>typeof 연산자 <code>typeof</code> → 피연산자의 데이터 타입을 문자열로 반환함.</p>
<ul>
<li>단, <code>null</code> 타입인지 확인을 할 때에는 <code>===</code>를 사용하자.</li>
</ul>
</li>
<li><p>지수 연산자 <code>**</code> : 거듭 제곱을 표현할 수 있다.</p>
<ul>
<li>하지만 <code>**</code>을 사용하는 것 보다 <code>Math.pow(a, n)</code>을 사용하는 것이 더 깔끔해보인다.</li>
</ul>
</li>
<li><p>더욱 더 그 외 연산자들</p>
<ul>
<li><code>?.</code> : 옵셔널 체이닝 연산자<ul>
<li><code>??</code> : null 병합 연산자</li>
<li><code>delete</code> : 프로퍼티 삭제</li>
<li><code>new</code> : 생성자 함수를 호출할 때 사용하여 인스턴스를 생성<ul>
<li><code>instanceof</code> : 좌변의 객체가 우변의 생성자 함수와 연결된 인스턴스인지 판별</li>
</ul>
</li>
<li><code>in</code> : 프로퍼티 존재 확인</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="77-연산자-우선순위">7.7 연산자 우선순위</h2>
<ol>
<li><code>()</code></li>
<li><code>new(매개변수 존재)</code> <code>[]</code> <code>()</code> <code>?.</code></li>
<li><code>new(매개변수 미존재)</code></li>
<li><code>x++</code> <code>x--</code></li>
<li><code>!x</code> <code>+x</code> <code>-x</code> <code>++x</code> <code>--x</code> <code>typeof</code> <code>delete</code></li>
<li><code>**</code></li>
<li><code>*</code> <code>/</code> <code>%</code></li>
<li><code>+</code> <code>-</code></li>
<li><code>&lt;</code> <code>&lt;=</code> <code>&gt;</code> <code>&gt;=</code> <code>in</code> <code>instanceof</code></li>
<li><code>==</code> <code>!=</code> <code>===</code> <code>!==</code></li>
<li><code>??</code></li>
<li><code>&amp;&amp;</code></li>
<li><code>||</code></li>
<li><code>? ... : ...</code></li>
<li><code>할당 연산자</code></li>
<li><code>,</code></li>
</ol>
<p>사실 연산자 종류도 많고 순서도 많아서 다 외우긴 어렵다. 필요한 것들은 외워두고, 기억이 안난다면 괄호로 묶어버리자.</p>
<hr>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Deep Dive] 6장 데이터 타입]]></title>
            <link>https://velog.io/@cest_pangeun/Deep-Dive-6%EC%9E%A5-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85</link>
            <guid>https://velog.io/@cest_pangeun/Deep-Dive-6%EC%9E%A5-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85</guid>
            <pubDate>Wed, 04 May 2022 07:13:14 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/ab7b472b-444d-40af-92fd-36aca0ae5b6c/image.png" alt=""></p>
<p><strong>데이터 타입 Data Type</strong> 은 값의 종류를 말한다. 자바스크립트뿐만이 아니라 내가 알고 있는 모든 프로그래밍 언어는 데이터 타입을 갖는다. ES6 기준 자바스크립트는 총 7개의 데이터 타입을 제공한다.</p>
<table>
<thead>
<tr>
<th>구분</th>
<th>데이터 타입</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>원시 타입</td>
<td>number</td>
<td>숫자, 정수와 실수 구분 없이 하나의 숫자 타입만 존재</td>
</tr>
<tr>
<td></td>
<td>string</td>
<td>문자열</td>
</tr>
<tr>
<td></td>
<td>boolean</td>
<td>논리적 true와 false</td>
</tr>
<tr>
<td></td>
<td>undefined</td>
<td>var 키워드로 선언된 변수에 암묵적으로 할당되는 값</td>
</tr>
<tr>
<td></td>
<td>null</td>
<td>값이 없다는 것을 의도적으로 명시할 때 사용하는 값</td>
</tr>
<tr>
<td></td>
<td>symbol</td>
<td>ES6에서 추가된 7번째 타입</td>
</tr>
<tr>
<td>객체 타입</td>
<td></td>
<td>객체, 함수, 배열 등</td>
</tr>
</tbody></table>
<br />

<p>데이터 타입을 공부할 때에 <code>undefined</code>와 <code>null</code>이 좀 헷갈릴 수 있는데 흔히 인터넷에 돌아다니는 다음 짤을 보면 쉽게 이해가 될 것이다. 이에 대해서는 추후에 다시 다룰 예정이다.
<img src="https://velog.velcdn.com/images/cest_pangeun/post/7c0b6f04-9b39-4f0e-998c-a9f5de457469/image.png" alt=""></p>
<p>자바스크립트 타입의 예시를 보자. <code>number</code> 타입의 값 1과 <code>string</code> 타입의 &#39;1&#39;은 1이 있기에 비슷해 보이지만 전혀 다르다. JS는 동적 타입을 가진 언어이다. 그렇기에 타입에 신경써주지 않으면 추후 개발을 할 때에 꽤 골치 아플 것이다. 나는 아직 TypeScript를 공부해보진 않았지만, TS는 JS와 다르게 변수에 Type 설정을 할 수 있다고 알고 있다. 이는 타입체크로 인하여 JS보다 속도가 조금 느릴 것 같지만 그만큼 타입에 대해서 안전할 것같다는 생각이 든다.</p>
<p>JS에서도 <code>// @ts-check</code>를 통하여 타입을 설정할 수 있지만, 이 책을 공부할 때에는 바닐라 JS에 대해 공부할 것이기에 지금 당장은 다루지 않을 것이다. </p>
<hr>
<h2 id="61-숫자-타입">6.1 숫자 타입</h2>
<p>C/C++이나 Java의 경우에는 정수와 실수를 구분해서 <code>int</code>, <code>long</code>, <code>float</code>, <code>double</code> 등으로 다양하게 숫자 타입을 정의해준다. 하지만 JS는 그런 것 따위 없다. 오로지 하나이다.
<strong>ECMAScript</strong> 에 따르면 숫자 타입은 64비트 부동소수점 형식을 따른다고 한다. 즉, 모든 수를 실수로 처리하고, 정수만 표현하는 데이터 타입은 존재하지 않는다.</p>
<pre><code class="language-js">var integer = 10   // 정수
var double = 10.12 // 실수
var negative = -20 // 음의 정수

// 표기법만 다를 뿐, 모두 같은 값이다.
var binary = 0b01000001
var octal = 0o101
var hex = 0x41

console.log(binary) // 65
console.log(octal)  // 65
console.log(hex)    // 65
console.log(binary === octal) // true
console.log(octal === hex)    // true
</code></pre>
<p>위에서 JS의 숫자 타입은 모두 실수로 처리한다고 말했다. 그렇기에 다음과 같은 코드처럼 정수로 표기해도 사실 실수라는 것을 잊지 말자.</p>
<pre><code class="language-js">console.log(1 === 1.0) // true
console.log( 4/2 ) // 2
console.log( 3/2 ) // 1.5</code></pre>
<p>추가적으로 숫자 타입은 세 가지 특별한 값도 표현할 수 있다.</p>
<ul>
<li><code>Infinity</code> : 양의 무한대</li>
<li><code>-Infinity</code> : 음의 무한대</li>
<li><code>NaN</code> : 산술 연산 불가 (not-a-number)</li>
</ul>
<pre><code class="language-js">console.log (10/0)        // Infinity
console.log (10/-0)       // -Infinity
console.log(1 * &#39;String&#39;) // Nan</code></pre>
<hr>
<h2 id="62-문자열-타입">6.2 문자열 타입</h2>
<p><strong>String</strong> 타입은 텍스트 데이터를 나타내는 데 사용한다. 문자열은 0개 이상의 16비트 유니코드 문자(UTF-16)의 집합으로 전 세계 대부분의 문자를 표현할 수 있다.</p>
<pre><code class="language-js">var string
string = &#39;문자열&#39; // 작은 따옴표
string = &quot;문자열&quot; // 큰 따옴표
string = `문자열` // 백틱(ES6)</code></pre>
<hr>
<h2 id="63-템플릿-리터럴">6.3 템플릿 리터럴</h2>
<p>ES6부터 <strong>템플릿 리터럴 template literal</strong> 이라고 하는 새로운 문자열 표기법이 도입되었다. 이는 다음과 같은 기능을 제공한다</p>
<ul>
<li>멀티라인 문자열 multi-line string</li>
<li>표현식 삽입 expression interpolation</li>
<li>태그드 템플릿 tagged template</li>
</ul>
<p>👉 템플릿 리터럴은 런타임에 일반 문자열로 변환되어 처리된다.
👉 또한 <code>백틱</code>을 사용해 표현한다.</p>
<pre><code class="language-js">var template = `Template Literal`
console.log(template) // Template Listeral</code></pre>
<h3 id="631-멀티라인-문자열">6.3.1 멀티라인 문자열</h3>
<p>일반 문자열 내에서는 개행이 허용되지 않는다. 따라서 개행이나 공백 등을 표현하려면 <code>\</code>으로 시작하는 <strong>이스케이프 시퀀스 escape sequence</strong> 를 사용해야 한다.</p>
<table>
<thead>
<tr>
<th>Escape Sequence</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td><code>\0</code></td>
<td>Null</td>
</tr>
<tr>
<td><code>\b</code></td>
<td>백스페이스</td>
</tr>
<tr>
<td><code>\f</code></td>
<td>Form Feed</td>
</tr>
<tr>
<td><code>\n</code></td>
<td>개행</td>
</tr>
<tr>
<td><code>\r</code></td>
<td></td>
</tr>
<tr>
<td><code>\t</code></td>
<td></td>
</tr>
<tr>
<td><code>\v</code></td>
<td></td>
</tr>
<tr>
<td><code>\uXXXX</code></td>
<td></td>
</tr>
<tr>
<td><code>\`</code></td>
<td>작은 따옴표</td>
</tr>
<tr>
<td><code>\&quot;</code></td>
<td>큰 따옴표</td>
</tr>
<tr>
<td><code>\\</code></td>
<td>백슬래시</td>
</tr>
</tbody></table>
<p>예를 들어, 줄바꿈과 들여쓰기가 적용된 HTML 문자열은 다음과 같이 작성하면 된다.</p>
<pre><code class="language-jsx">var template = &#39;&lt;ul&gt;\n\t&lt;li&gt;&lt;a href=&quot;#&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;\n&lt;/ul&gt;&#39;;

console.log(template)</code></pre>
<p>출력한 결과는 다음과 같다.</p>
<pre><code class="language-HTML">&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;</code></pre>
<p>사실 일반 문자열과 달리 템플릿 리터럴 내에서는 이스케이프 시퀀스를 사용하지 않고 <code>백틱</code> 안에서 개행 및 공백이 허용된다.</p>
<h3 id="632-표현식-삽입">6.3.2 표현식 삽입</h3>
<p>문자열은 문자열 연산자 <code>+</code> 를 사용해 연결할 수 있다. <code>+</code> 연산자는 피연산자 중 하나 이상이 문자열인 경우 문자열 연결 연산자로 동작하게 된다.</p>
<pre><code class="language-js">var first = &#39;PanGeun&#39;
var last = &#39;Jeon&#39;

// ES5 : 문자열 연결
console.log(&#39;My name is &#39; + first + &#39; &#39; + last + &#39;.&#39;)

// ES6 표현식 삽입
console.log(&#39;My name is ${first} ${last}&#39;)</code></pre>
<p>ES6 표현식 삽입을 보면 <code>${}</code>을 통해 할 수 있다. 이때, 평가 결과가 문자열이 아니더라도 문자열로 타입이 강제로 변환되어 삽입된다.</p>
<br />

<hr>
<h2 id="64-불리언-타입">6.4 불리언 타입</h2>
<p>Boolean 타입은 <code>true</code>와 <code>false</code> 뿐이다.</p>
<pre><code class="language-js">var foo = true
console.log(foo) // true

foo = false
console.log(foo) // false</code></pre>
<br />

<hr>
<h2 id="65-undefined-타입">6.5 undefined 타입</h2>
<p><code>undefined</code> 타입이 유일한 타입이다.
<code>var</code> 키워드로 선언한 변수는 암묵적으로 <code>undefined</code>로 초기화된다. 다시 말해, 변수 선언에 의해 확보된 메모리 공간을 처음 할당이 이뤄질 때까지 빈 상태로 내버려두지 않고 자바스크립트 엔진이 <code>undefined</code>로 초기화한다. </p>
<p>즉, 변수를 참조했을 때 <code>undefined</code>가 반환된다면 참조한 변수가 선언 이후 초기화가 되지 않았다는 것을 알 수 있어야 한다.</p>
<p>👉 변수에 값이 없다는 것을 표현하고 싶으면 <code>null</code> 을 할당해 주면 된다.</p>
<br />

<hr>
<h2 id="66-null-타입">6.6 null 타입</h2>
<p><code>null</code> 타입 또한 <code>null</code>이 유일하다. 이는 변수에 값이 없다는 것을 의도적으로 명시할 때 사용하며, <code>null</code>을 할당하는 것은 변수가 이전에 참조하던 값을 더 이상 참조하지 않겠다는 의미이다.</p>
<p>함수가 유효한 값을 반환할 수 없는 경우 명시적으로 <code>null</code>을 반환하기도 한다. 예를 들어, HTML 요소를 검색해 반환하는 <code>document.querySelector</code> 메서드는 조건에 부합하는 HTML 요소를 검색할 수 없는 경우 에러 대신 <code>null</code>을 반환한다.</p>
<pre><code class="language-HTML">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;body&gt;
  &lt;script&gt;
    var element = document.querySelector(&#39;.myClass&#39;);

    // HTML 문서에 myClass 클래스를 갖는 요소가 없다면 null을 반환한다.
    console.log(element); // null
  &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<br />

<hr>
<h2 id="67-심벌-타입">6.7 심벌 타입</h2>
<p><strong>심벌 Symbol</strong> 타입은 ES6에서 7번째로 추가된 타입이다. 이는 변경 불가능한 원시 타입의 값이며, 다른 값과 중복되지 않는 유일무이한 값이다. 따라서 주로 이름이 충돌할 위험이 없는객체의 유일한 프로퍼티 키를 만들기 위해 사용한다. </p>
<p>이에 대한 자세한 사항은 나중에 다시 알아보자</p>
<hr>
<h2 id="68-객체-타입">6.8 객체 타입</h2>
<p>JS에서의 타입은 크게 원시와 객체 타입으로 나뉘어 진다고 위에서 말했다. 일단 이번 장에서는 이것만 알아두자</p>
<blockquote>
<p>자바스크립트는 객체 기반의 언어이며, 자바스크립트를 이루고 있는 거의 모든 것이 객체이다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Deep Dive] 5장 표현식과 문]]></title>
            <link>https://velog.io/@cest_pangeun/Deep-Dive-5%EC%9E%A5-%ED%91%9C%ED%98%84%EC%8B%9D%EA%B3%BC-%EB%AC%B8</link>
            <guid>https://velog.io/@cest_pangeun/Deep-Dive-5%EC%9E%A5-%ED%91%9C%ED%98%84%EC%8B%9D%EA%B3%BC-%EB%AC%B8</guid>
            <pubDate>Wed, 04 May 2022 05:09:30 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/35933f83-ffd8-4480-a623-604b4fd7c3e3/image.png" alt=""></p>
<h2 id="51-값">5.1 값</h2>
<p>값 Value은 식(표현식 expression)이 평가 evaluate되어 생성된 결과를 말한다.</p>
<p>모든 값은 데이터 타입을 가지며, 메모리에 2진수 (즉, bit의 나열)로 저장된다.</p>
<pre><code class="language-js">// 변수 sum에는 10 + 20이 평가되어 생성된 숫자 &quot;값&quot; 30이 할당된다.
var sum = 10 + 20;</code></pre>
<p>위의 예제에서는 <code>sum</code> 변수에 <code>10 + 20</code> 그 자체가 저장되는 것이 아니라, 이를 연산한 값인 <code>30</code>이 값으로 할당된다. 값은 다양한 방법으로 생성할 수 있는데 가장 기본적인 방법은 <strong>리터럴 Literal</strong>을 사용하는 것이다.</p>
<hr>
<h2 id="52-리터럴">5.2 리터럴</h2>
<p><strong>리터럴 Literal</strong>은 사람이 이해할 수 있는 문자(숫자, 알파벳 등등) 또는 약속된 기호(&#39; &#39;, &quot; &quot;, [], {}, 등등)를 사용해 값을 생성하는 <strong>표기법 notation</strong>을 뜻한다.</p>
<p>리터럴을 사용하면 다음과 같이 <strong>다양한 종류 Data Type</strong>의 값을 생성할 수 있다.</p>
<table>
<thead>
<tr>
<th>리터럴</th>
<th>예시</th>
<th>비고</th>
</tr>
</thead>
<tbody><tr>
<td>정수 리터럴</td>
<td>100</td>
<td></td>
</tr>
<tr>
<td>부동소수점 리터럴</td>
<td>10.5</td>
<td></td>
</tr>
<tr>
<td>2진수 리터럴</td>
<td>0b01000001</td>
<td>0b로 시작</td>
</tr>
<tr>
<td>8진수 리터럴</td>
<td>0o101</td>
<td>ES6에서 도입. 0o로 시작</td>
</tr>
<tr>
<td>16진수 리터럴</td>
<td>0x41</td>
<td>ES6에서 도입. 0x로 시작</td>
</tr>
<tr>
<td>문자열 리터럴</td>
<td>&#39;Hello&#39;, &quot;World&quot;</td>
<td></td>
</tr>
<tr>
<td>불리언 리터럴</td>
<td>true, false</td>
<td></td>
</tr>
<tr>
<td>null 리터럴</td>
<td>null</td>
<td></td>
</tr>
<tr>
<td>undefined 리터럴</td>
<td>undefind</td>
<td></td>
</tr>
<tr>
<td>객체 리터럴</td>
<td>{ name : &#39;Lee&#39;, address: &#39;Seoul&#39; }</td>
<td></td>
</tr>
<tr>
<td>배열 리터럴</td>
<td>[ 1, 2, 3 ]</td>
<td></td>
</tr>
<tr>
<td>함수 리터럴</td>
<td>function() {}</td>
<td></td>
</tr>
<tr>
<td>정규 표현식 리터럴</td>
<td>/[a-zA-Z0-9]+/g</td>
<td></td>
</tr>
</tbody></table>
<br />

<hr>
<h2 id="53-표현식">5.3 표현식</h2>
<p><strong>표현식 expression</strong>은 값으로 평가될 수 있는 <strong>문 statement</strong>이다. 즉, 표현식이 평가되면 새로운 값을 생성하거나 기존의 값을 참조한다. 5.2에서 본 리터럴도 값으로 평가되기에 표현식이라고 할 수 있다.
👉 즉, 값으로 평가될 수 있는 문은 모두 표현식이다.</p>
<pre><code class="language-js">// 리터럴 표현식
10
&#39;Hello&#39;

// 식별자 표현식(선언이 이미 존재한다고 가정하자)
sum
person.name
arr[1]

// 연산자 표현식
10 + 20
sum = 10
sum !== 10

// 함수 or 메서드 호출 표현식(선언이 이미 존재한다고 가정)
square()
person.getName()</code></pre>
<hr>
<h2 id="54-문">5.4 문</h2>
<p><strong>문 statement</strong>은 프로그램을 구성하는 기본 단위이자 최소 실행 단위이다. 
문은 여러 토큰으로 구성되게 되는데, <strong>토큰 token</strong>이란 문법적인 의미를 가지며, 문법적으로 더 이상 나눌 수 없는 코드의 기본 요소를 의미한다.</p>
<pre><code class="language-js">var sum = 1 + 2;</code></pre>
<p>위의 코드를 보면 <code>var</code>, <code>sum</code>, <code>=</code>, <code>1</code>, <code>+</code>, <code>2</code>, <code>;</code> 으로 세부적으로 볼 수 있다. 키워드, 식별자, 연산자, 리터럴, 세미콜론이나 마침표 등의 특수 기호는 문법적인 의미를 가지며, 문법적으로 더 이상 나눌 수 없는 코드의 기본 요소이므로 모두 토큰이다. 즉, 문을 이루는 각각의 요소가 토큰이라고 볼 수 있다.</p>
<p>문은 명령문이라고도 부르는데, 다음과 같이 구분할 수 있다.</p>
<ul>
<li>선언문 : <code>var x</code></li>
<li>할당문 : <code>x = 5</code></li>
<li>함수 선언문 : <code>function foo() {}</code></li>
<li>조건문 : <code>if (x &gt; 1) { console.log(x); }</code></li>
<li>반복문 : <code>for (var i = 0; i &lt; 2; i++) { console.log(i); }</code></li>
</ul>
<br />

<hr>
<h2 id="55-세미콜론과-세미콜론-자동-삽입-기능">5.5 세미콜론과 세미콜론 자동 삽입 기능</h2>
<p><code>세미콜론 ;</code> 은 어느 프로그래밍 언어와 마찬가지로 JS에서도 문의 종료를 뜻한다
C/C++과 같은 언어에서는 문장의 끝에는 무조건 세미콜론을 붙여야 하지만, JS에서의 세미콜론은 선택이다. 붙여도 되고 붙이지 않아도 된다. 이는 자바스크립트 엔진이 소스코드를 해석할 때 문의 끝이라고 예측되는 지점에 세미콜론을 자동으로 붙여주는 <strong>세미콜론 자동 삽입 기능(ASI automatic semicolon insertion)</strong>이 암묵적으로 수행된다.</p>
<p>JS를 이용하여 개발을 할 때에 세미콜론의 유무는 자유이기 때문에 <strong>ESLint</strong>를 통해 편한대로 설정한 뒤 개발을 하면 될 것 같다. ESLint에 관해서는 Prettier와 함께 설정하는 방법을 따로 글을 쓸 예정이다.</p>
<p>나는 이전에 swift와 python을 이용하여 개발을 많이 하였기 때문에 세미콜론을 붙이지 않는 것이 더 익숙해져있다. 그렇기에 나는 붙이지 않고 개발을 하는데, 추후 협업을 할 때에는 다른 개발자와 협의를 통해 결정을 해야 할 부분이라고 생각한다.</p>
<br />

<hr>
<h2 id="56-표현식인-문과-표현식이-아닌-문">5.6 표현식인 문과 표현식이 아닌 문</h2>
<p>표현식은 문의 일부일 수도 있고 그 자체로 문이 될 수도 있다. 이게 무슨 말일까..?
다음의 코드를 살펴보자.</p>
<pre><code class="language-js">// 변수 선언문은 값으로 평가될 수 없기에 표현식이 아니다.
var x

// 1, 2, 1 + 2, x = 1 + 2는 모두 표현식이다.
// x = 1 + 2는 표현식이면서 완전한 문이기도 하다.
x = 1 + 2</code></pre>
<p>문에는 표현식인 문과 표현식이 아닌 문이 있다. 표현식은 값으로 평가될 수 있는 문이고 표현식이 아닌 문은 값으로 평가될 수 없는 문이라고 한다. 도대체 이게 뭔 소리인가 싶다.</p>
<pre><code class="language-js">var foo = var x</code></pre>
<p>위의 코드를 살펴보면 <code>SyntaxError: Unexpected token var</code> 에러가 뿜어져 나올 것이다. 표현식인지 알 수 있는 가장 간단한 방법은 변수에 할당해 보는 것인데, 위의 코드는 <code>var x</code>가 <code>var foo</code>의 값으로 평가될 수 없다. 따라서 변수 선언문은 표현식이 아니다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Deep Dive] 04장 변수]]></title>
            <link>https://velog.io/@cest_pangeun/4%EC%9E%A5-%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@cest_pangeun/4%EC%9E%A5-%EB%B3%80%EC%88%98</guid>
            <pubDate>Mon, 02 May 2022 06:35:59 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/29e58a0e-fa1d-46ce-af34-0255c7d79de0/image.png" alt=""></p>
<h2 id="41-변수란-무엇인가">4.1 변수란 무엇인가?</h2>
<p><strong>변수(variable)</strong>는 어떤 특정 값을 저장하기 위해서 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름을 말한다.</p>
<p>프로그래밍을 할 때에 우리들은 어떤 특정 값을 필요로 한다. 우리는 이 특정 값을 추후에 사용하기 위해 저장을 하게 되는데, 메모리 공간에 저장되게 된다. 우리가 저장한 값을 꺼내어 쓰기 위해 매번 메모리 주소를 불러올 수는 없으니 변수를 사용하는 것이다.</p>
<p>간단히 말하자면 변수는 프로그래밍 언어에서 값을 저장하고 참조하는 메커니즘으로, 값의 위치를 가리키는 상징적인 이름이 되는 것이다. 변수는 컴파일러나 인터프리터에 의해 값이 저장된 메모리 공간의 주소로 치환되어서 실행된다. 즉, 개발자는 직접 메모리 주소를 통해 값을 저장하거나 참조할 필요없이 변수를 통해 보다 안전하게 접근할 수 있다는 것이다.</p>
<pre><code class="language-javascript">var result = 10 + 20;</code></pre>
<p>JS에서는 위와 같이 변수를 저장할 수 있는데, 10 + 20이라는 연산을 통해 30이라는 값이 result 변수에 <strong>할당(assignment)</strong>된다.</p>
<p>여담으로 항상 코딩하면서 느끼는 것이지만 변수 이름을 잘 짓도록 하자. 변수 이름을 대충 막 짓게 되면 추후에 리팩토링을 하거나 코드 리뷰를 할 때에 혼란스럽게 만든다. 혹시 협업을 하게 된다면 변수 네이밍 규칙을 정하는 것이 필수라고 생각한다.</p>
<hr>
<h2 id="42-식별자">4.2 식별자</h2>
<p>변수 이름을 <strong>식별자(identifier)</strong>라고도 한다. 즉, 어떤 값을 구별해서 식별할 수 있는 고유한 이름을 말한다.
우리가 변수를 선언할 때에 그 값은 메모리 공간에 저장되어 있다. 따라서 식별자는 메모리 공간에 저장되어 있는 어떤 값을 구별해서 식별할 수 있어야 하는데, 이를 위해서 식별자는 변수의 값 뿐만이 아니라 메모리 주소까지 기억을 하고 있다.</p>
<hr>
<h2 id="43-변수-선언">4.3 변수 선언</h2>
<p>변수가 어떤 뜻인지 알았으면, 이제 자바스크립트에서는 변수를 어떠한 식으로 선언하는지 알아보자.</p>
<p>자바스크립트에서 변수를 선언할 때에는 <strong>ES6</strong> 이후로 <code>var</code>, <code>let</code>, <code>const</code>를 사용한다. 이전에는 <code>var</code> 변수가 유일한 키워드였다.</p>
<h3 id="var"><code>var</code></h3>
<pre><code class="language-javascript">var score;</code></pre>
<p>위의 코드는 score라는 변수 이름을 등록하고 값을 저장할 메모리 공간을 확보한 것이다. 위의 코드는 변수를 선언했지만, 값을 할당하지 않았다. 값을 할당하지 않았기에 메모리가 비어있다고 생각할 수 있다. 하지만 자바스크립트에서는 <code>undefined</code>라는 값이 암묵적으로 초기화된다.</p>
<p>변수를 선언하지 않고, 선언하지 않은 변수(식별자)에 접근하려고 하면 <strong>ReferenceError(참조 에러)</strong>가 발생하게 되니 이 점을 알아두자.</p>
<hr>
<h2 id="44-변수-선언의-실행-시점과-변수-호이스팅">4.4 변수 선언의 실행 시점과 변수 호이스팅</h2>
<pre><code class="language-js">console.log(score); // undefined

var scroe; // 변수 선언문</code></pre>
<p>이 코드는 선언문보다 변수를 참조하는 코드가 앞에 있다. JS는 인터프리터에 의해서 한 줄씩 순차적으로 선언된다.
<code>score</code>가 선언되기 전에 <code>console.log</code>에서 score를 불렀기에 다른 언어처럼 참조 에러가 발생할 것이라고 생각할 수 있지만 참조 에러가 발생하지 않고, <code>undefind</code>가 출력된다.</p>
<h3 id="why">Why?</h3>
<p>JS 엔진은 소스코드를 한 줄씩 순차적으로 실행하기에 앞서 먼저 소스코드의 평가 과정을 거치면서 소스코드를 실행하기 위한 준비를 한다. 이 과정에서</p>
<ol>
<li>JS 엔진은 변수 선언을 포함한 모든 선언문(변수, 함수 선언문 등)을 소스코드에서 먼저 찾아서 실행시킨다. </li>
<li>소스코드의 평가 과정이 끝나면 비로소 변수 선언을 포함한 모든 선언문을 제외하고 소스코드를 한 줄씩 순차적으로 실행하게 된다..</li>
</ol>
<p>즉, 변수 선언이 소스코드의 어디에 있든 상관 없이 가장 먼저 실행되기 때문에 위의 코드는 에러를 뿜지 않고 <code>undefined</code>라는 값을 뱉게 되는 것이다.</p>
<blockquote>
<p>👉 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 <strong>변수 호이스팅(Variable Hoisting)</strong> 이라고 한다.</p>
</blockquote>
<blockquote>
<p>변수 선언 키워드 (<code>var</code>, <code>let</code>, <code>const</code>) 뿐만이 아니라 <code>function</code>, <code>function*</code>, <code>class</code> 키워드를 사용하여 선언하는 모든 식별자는 호이스팅 된다.
모든 선언문은 런타임 이전 단계에서 먼저 실행되기 때문이다.</p>
</blockquote>
<hr>
<h2 id="45-값의-할당">4.5 값의 할당</h2>
<p>변수에 값을 <strong>할당(assignment)</strong> 할 때에는 할당 연산자 <code>=</code>를 사용한다.</p>
<h3 id="예시-1">예시 1</h3>
<pre><code class="language-js">var score // 변수 선언
score = 80 // 값의 할당</code></pre>
<h3 id="예시-2">예시 2</h3>
<pre><code class="language-js">var score = 80 // 변수 선언과 값의 할당</code></pre>
<p>위의 두 예시는 결과적으로 보면 <code>score</code> 변수에 80 이라는 값이 할당되어 같다. 하지만 이때, 변수 선언과 값을 할당하는 시점이 다르다는 것을 알고 있어야 한다.</p>
<blockquote>
<p>변수 선언은 런타임 이전에 먼저 실행되지만, 값의 할당은 런타임에 실행된다.</p>
</blockquote>
<pre><code class="language-js">console.log(score)

score = 80
var score

console.log(score)</code></pre>
<p>위 코드의 실행 결과는 다음과 같다.
<img src="https://velog.velcdn.com/images/cest_pangeun/post/5dcf9463-442e-4793-8c4d-ef3334692eb4/image.png" alt=""></p>
<hr>
<h2 id="46-값의-할당">4.6 값의 할당</h2>
<p>이번에는 <code>score</code> 변수에 새로운 값을 재할당을 해볼 것이다.</p>
<pre><code class="language-js">var score = 80;
score = 90;</code></pre>
<p><code>var</code> 키워드로 선언한 변수는 값을 재할당할 수 있다. 재할당은 기존의 값을 버리고 새로운 값을 저장하는 것이다. (사실 <code>var</code> 키워드로 선언한 변수는 <code>undefined</code>로 초기화 된 뒤, 값이 할당되는 것이기에 <code>var</code>로 값을 할당하는 것 자체가 재할당이라고 볼 수 있다.)</p>
<p>재할당은 변수에 저장된 값을 다른 값으로 변경하는 것을 뜻하는데, 재할당을 할 수 없는 변수가 있다. 정확히는 변수가 아니라 <strong>상수 Constant</strong> 이다. 상수는 한 번 정해지면 이후에 변하지 않는다.</p>
<p>즉, 상수란 <strong>처음에 단 한 번 할당이 되면 이후에 바꿀 수 없는 값</strong>이다. </p>
<blockquote>
<p>ES6에 도입된 <code>const</code> 키워드를 통하여 상수를 표현할 수 있다.</p>
</blockquote>
<p><code>score</code> 변수의 값을 80에서 90으로 바꾸게 되면 최종적으로 <code>score</code> 변수의 값은 90이다. 그럼 이전의 <code>undefind</code>와 <code>80</code>은 어떻게 되었을까? 이 값들은 더이상 필요한 값이 아니다. 이들은 <strong>가비지 콜렉터</strong>에 의해서 메모리에서 자동으로 해제되게 되는데, 메모리에서 언제 해제될지는 예측이 불가능하다.</p>
<blockquote>
<p>🗑 <strong>가비지 콜렉터 garbage collector</strong>는 애플리케이션이 <strong>할당 allocate</strong>한 메모리 공간을 주기적으로 검사하여 더 이상 사용되지 않는 메모리를 <strong>해제 release</strong>하는 기능을 말한다.
가비지 콜렉터를 통해서 <strong>메모리 누수 memory leak</strong>을 방지한다.</p>
</blockquote>
<hr>
<h2 id="47-식별자-네이밍-규칙">4.7 식별자 네이밍 규칙</h2>
<p>변수를 선언할 때에는 다음과 같은 네이밍 규칙을 준수해야 한다.</p>
<ul>
<li>식별자는 특수 문자를 제외한 문자, 숫자, 언더스코어(_), 달러 기호($)를 포함할 수 있다.</li>
<li>단, 식별자는 특수문자를 제외한 문자, 언더스코어(_), 달러 기호($)로 시작해야 한다. 숫자로 시작하는 것은 허용하지 않는다.</li>
<li>예약어는 식별자로 사용할 수 없다. </li>
</ul>
<br />

<h3 id="💻-다음은-자바스크립트의-예약어이다">💻 다음은 자바스크립트의 예약어이다.</h3>
<p>| JavaScript | 예약어 | 목록 |  |  | 
| --- | --- | --- | --- | --- | --- |
| await | break | case | catch | class | const
| continue | debugger | default | delete | do | else
| enum | export | extends | false | finally | for
| function | if | implements* | import | in | instanceof
| interface* | let* | new | null | package* | private*
| protected* | public* | return | super | static* | switch
| this | throw | true | try | typeof | var
| void | while | with | yield*</p>
<br />
<br />

<h3 id="네이밍-규칙">네이밍 규칙</h3>
<ol>
<li><p>변수는 쉼표를 통해 하나의 문에서 여러 개를 한 번에 선언할 수 있지만 가독성의 문제로 추천하지 않는다.</p>
<pre><code class="language-js">     var person, $elem, _name, first_name, val1;</code></pre>
</li>
<li><p>ES5 부터 변수를 만들 때 유니코드를 허용한다. 따라서 알파벳 이외의 문자로 변수를 선언할 수 있지만 이 또한 추천하지 않는다.</p>
<pre><code class="language-js">     var 이름, 주소;</code></pre>
</li>
<li><p>자바스크립트는 대소문자를 구별한다.</p>
<pre><code class="language-js">     var firstname;
     var firstName;
     var FIRSTNAME;</code></pre>
</li>
<li><p>변수 이름은 변수의 존재 목적을 쉽게 이해할 수 있도록 의미를 명확히 표현하자.</p>
<pre><code class="language-js">     var x = 3; // x 가 무엇을 의미하는지 바로 알 수 없다.
     var score = 100; // score는 점수를 뜻하는 것을 알 수 있다.</code></pre>
</li>
<li><p>일반적으로 자바스크립트에서는 <strong>카멜 케이스 camelCase</strong>를 사용하고, 생성자 함수, 클래스의 이름에는 <strong>파스칼 케이스 PascalCase</strong>를 사용한다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript Deep Dive]]></title>
            <link>https://velog.io/@cest_pangeun/JavaScript-Deep-Dive</link>
            <guid>https://velog.io/@cest_pangeun/JavaScript-Deep-Dive</guid>
            <pubDate>Mon, 02 May 2022 04:42:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/cddfe557-a989-44ff-8a24-5878b3485cf2/image.png" alt=""></p>
<h3 id="모던-자바스크립트-deep-dive">모던 자바스크립트 Deep Dive</h3>
<p>모던 자바스크립트 Deep Dive 책(도마뱀책)을 읽고 JS에 관련해서 깊게 공부하고 정리를 할 예정이다.
꾸준히 공부하며 정리하는 것이 목표이며 5~6월 동안 다 읽는 것이 목표이다.</p>
<p>혼자 하는 스터디이기 때문에 게을러지지 않고 평일에는 1일 1포스팅을 목표로 한다.</p>
<p>관련된 소스코드는 <a href="https://github.com/Jason9789/Modern_JavaScript">내 깃허브</a>에 정리할 예정이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] DOM이란?]]></title>
            <link>https://velog.io/@cest_pangeun/React-DOM%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@cest_pangeun/React-DOM%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Thu, 10 Feb 2022 06:22:07 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/cest_pangeun/post/4f15c96e-5f30-4407-bcbc-f1140a969970/image.png" alt=""></p>
<h2 id="돔dom이란-무엇일까">돔(DOM)이란 무엇일까?</h2>
<p>DOM에 대한 개념이 무엇일까? 예전에 웹 공부를 할 때도 그렇고 지금 다시 리액트를 공부할 때에도 DOM에 대한 개념을 확실히 잡고 가야겠다는 생각이 들었기에 이번 시간에 정리해 보려고 한다.</p>
<ul>
<li>우선, DOM이 있고, VirtualDOM이 있는데 기본적인 DOM의 개념부터 잡아보자.</li>
</ul>
<h3 id="dom">DOM</h3>
<p>DOM(Document Object Model)은 <a href="https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model/Introduction">MDN</a>에 따르면 HTML, XML 문서의 프로그래밍 interface라고 한다. 쉽게 이해하면, 웹 페이지를 이루는 요소들(태그 등)을 자바스크립트가 이용을 할 수 있게 브라우저 내에서 트리 구조로 만든 객체 모델이라고 생각하면 될 것 같다.</p>
<ul>
<li>즉, DOM은 HTML, XML 등의 문서와 JavaScript를 이어준다.</li>
</ul>
<h3 id="virtualdom-가상돔">VirtualDOM (가상돔)</h3>
<p>DOM에 대한 간단한 이해는 하였다. 그렇다면 리액트에서 사용하는 ReactDOM은 도대체 또 무엇일까? ReactDOM은 VirtualDOM이라고 한다. ReactDOM에 대해 알아보기 전에 VirtualDOM이 무엇인지 먼저 알아보자.</p>
<p>Instagram이나 Facebook, YouTube같은 홈페이지를 생각해보자. 이러한 서비스들은 스크롤이 무한에 가깝게 계속 내려가며 스크롤이 될 때마다 새로운 데이터들을 서버에서 불러온다. 불러온 데이터에 따라서 UI는 계속해서 업데이트 될 것이다. 수많은 Document의 elements를 가진 서비스들이 계속해서 데이터가 실제 DOM에 직접적으로 접근하여 업데이트 된다면 이는 분명 무리가 될 것이라고 판단이 된다. 이는 곧 서비스의 이슈로 이어질 것 같다고 생각이 든다. DOM 자체는 빠르지만 페이지의 리페인트가 계속해서 발생한다면 속도가 늦춰질 것이라고 생각이 든다. (이는 더 알아본 다음에 다시 정리를 할 예정이다.)</p>
<p>실제 DOM에 접근하게 되면 위와 같은 문제가 발생한다. 이를 해결하기 위해 나타난 것이 Virtual DOM이다.</p>
<ul>
<li>실제 DOM에 직접 접근하는 대신에, 이를 자바스크립트 객체로 구성하여 DOM을 추상화하여 사용하는 방식이다.</li>
<li>React를 사용할 때에는 React가 모두 처리를 해주기 때문에, DOM API를 직접 구현하지 않아도 된다.</li>
</ul>
<h3 id="virtual-dom의-반영">Virtual DOM의 반영</h3>
<p>특정 홈페이지의 데이터가 변했다고 가정을 했을 때, Virtual DOM은 다음과 같은 플로우를 가진다.</p>
<ul>
<li>기존 페이지의 데이터 버전을 <code>v1</code>, 바뀐 페이지의 데이터 버전을 <code>v2</code>라고 하자.</li>
</ul>
<ol>
<li>데이터가 업데이트 되면, <code>v2</code>의 UI 전체를 Virtual DOM을 리렌더링한다.</li>
<li>그렇다면 기존에 Virtual DOM에 있던 <code>v1</code>과 바뀐 현재의 <code>v2</code>를 비교한다. (Virtual DOM끼리 비교를 하는 것이다.)</li>
<li>비교를 한 뒤, 바뀐 일부분만 실제 DOM에 적용이 된다.</li>
</ol>
<blockquote>
<p>이러한 과정은 결국 컴포넌트가 업데이트 될 때, 리플로우가 한 번 발생한다. (리플로우와 리페인트에 대한 개념은 이후에 다룰 예정)</p>
</blockquote>
<p>실제 DOM에서 데이터가 업데이트 될 때마다 계속해서 작은 규모로 리플로우를 여러 번 하는 것보다 VirtualDOM을 이용하여 실제 DOM에서는 크게 한 번 리플로우 되는 것이 성능을 비교 했을 때, 성능 향상을 가져오게 된다.</p>
<p>참고글
<a href="https://velog.io/@mollog/React%EC%97%90%EC%84%9C%EC%9D%98-%EA%B0%80%EC%83%81%EB%8F%94-%EA%B0%9C%EB%85%90">React에서의 가상돔 개념</a></p>
]]></description>
        </item>
    </channel>
</rss>