<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Daniel-Q.log</title>
        <link>https://velog.io/</link>
        <description>감동을 주고픈 개발자(준비생)</description>
        <lastBuildDate>Mon, 25 Dec 2023 12:45:40 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Daniel-Q.log</title>
            <url>https://velog.velcdn.com/images/dainel-q/profile/d68704ab-01c0-4483-81a6-99f32c224812/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. Daniel-Q.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dainel-q" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Next.js 를 왜 공부해야하니?]]></title>
            <link>https://velog.io/@dainel-q/Next.js-%EB%A5%BC-%EC%99%9C-%EA%B3%B5%EB%B6%80%ED%95%B4%EC%95%BC%ED%95%98%EB%8B%88</link>
            <guid>https://velog.io/@dainel-q/Next.js-%EB%A5%BC-%EC%99%9C-%EA%B3%B5%EB%B6%80%ED%95%B4%EC%95%BC%ED%95%98%EB%8B%88</guid>
            <pubDate>Mon, 25 Dec 2023 12:45:40 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h1 id="목차">목차</h1>
</blockquote>
<h1 id="1-nextjs란-무엇인가">1. Next.js란 무엇인가?</h1>
<h1 id="2-nextjs가-제공하는-주-기능">2. Next.js가 제공하는 주 기능</h1>
<h1 id="3-nextjs를-통해-작업할-프로젝트">3. Next.js를 통해 작업할 프로젝트</h1>
<h1 id="1-nextjs란-무엇인가-1">1. Next.js란 무엇인가?</h1>
<h2 id="1-1-정의--react로-만들어진-서버-사이드-렌더링ssr-프레임-워크">1-1. 정의 : React로 만들어진 서버 사이드 렌더링(SSR) 프레임 워크</h2>
<ul>
<li>왜 서버 사이드 렌더링이 중요할까?<h2 id="1-2-ssr이란--서버측에서-브라우저에서-사용될-화면view를-제공해주는-것">1-2. SSR이란 : 서버측에서 브라우저에서 사용될 화면(view)를 제공해주는 것</h2>
</li>
<li>기존의 CSR의 경우, 서버에서 받은 데이터를 토대로 브라우저가 화면(view)을 제공함</li>
<li>즉, 서버에서는 빈 html을 제공하고, 브라우저는 그에 대한 내용을 렌더링 해야하기에, 로딩 속도가 느려질 수 밖에 없음</li>
<li>또한 별도의 SEO(검색엔진 최적화)작업이 필요함 =&gt; 포털 사이트에서 웹사이트에 대한 데이터를 제대로 수집하는데 한계가 있다는 것을 의미</li>
<li>이를 해결하기 위해, SSR을 이용 =&gt; 서버가 자바스크립트까지 완성된 html문서파일을 제공하여 <strong>로딩 속도가 향상</strong> + <strong>검색엔진최적화 가능</strong></li>
<li>이게 Next.js의 유일한 장점인가?</li>
</ul>
<h2 id="1-3-풀스택-기반의-프레임-워크">1-3. 풀스택 기반의 프레임 워크</h2>
<ul>
<li>Next.js는 API 기능과 서버 컴퍼넌트를 통한 서버측 기능 + React 컴퍼넌트를 사용한 클라이언트 기능을 동시에 수행가능</li>
<li>덕분에, 프론트 엔드에서도 백엔드의 역할을 수행할 수 있다는 장점이 있음</li>
</ul>
<br>

<h1 id="2-nextjs가-제공하는-특이점">2. Next.js가 제공하는 특이점</h1>
<h2 id="2-1-pre-rendering">2-1. pre-rendering</h2>
<ul>
<li>SSR의 최대 장점으로, 미리 데이터가 렌더링된 html 페이지를 가져올 수 있으므로, UX개선에 큰 기여를 하며, 정적 사이트 생성(SSG)도 가능해진다.</li>
</ul>
<h2 id="2-2-dynamic-route-">2-2. dynamic route ([])</h2>
<ul>
<li><code>[]</code>문법을 사용하여, 동적인 url 작성이 가능</li>
<li><code>pages/[값].tsx</code> 면 <code>{router.query.값}</code>으로 편하게 사용가능</li>
</ul>
<h2 id="2-3-code-spliting코드-분할">2-3. code spliting(코드 분할)</h2>
<ul>
<li>페이지를 렌더링 할 때, 방대한 javascript paylod(전송 데이터)를 보내는 것이 아닌 dynamic import을 통해 <strong>필요한</strong> 부분만 import하여 자바스크립트 로딩 시간이 개선됨</li>
</ul>
<br>

<h1 id="3-nextjs를-통해-작업할-프로젝트-1">3. Next.js를 통해 작업할 프로젝트</h1>
<ul>
<li>프로젝트 명 : 고민을 먹는 고래</li>
<li>프로젝트 정의: 각자의 고민들을 작성하면, 이를 깔끔하게 지워주는 효과를 구현하여 잠시나마 고민을 잊게 만들어주는 페이지</li>
</ul>
<blockquote>
<p>참고 문헌
1.youngDev 블로그 :  <a href="https://velog.io/@syoung125/Next.js-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-1-Next.js-%EB%9E%80-Next.js%EB%A5%BC-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C-Next.js%EC%9D%98-%EC%9E%A5%EC%A0%90%EC%9D%80">https://velog.io/@syoung125/Next.js-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-1-Next.js-%EB%9E%80-Next.js%EB%A5%BC-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C-Next.js%EC%9D%98-%EC%9E%A5%EC%A0%90%EC%9D%80</a>
2. kyounghwan01 블로그 : <a href="https://velog.io/@syoung125/Next.js-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-1-Next.js-%EB%9E%80-Next.js%EB%A5%BC-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C-Next.js%EC%9D%98-%EC%9E%A5%EC%A0%90%EC%9D%80!%5B%5D(https://velog.velcdn.com/images/dainel-q/post/7a07a7cb-43bd-4e25-9033-54922610733e/image.png)">https://velog.io/@syoung125/Next.js-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-1-Next.js-%EB%9E%80-Next.js%EB%A5%BC-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C-Next.js%EC%9D%98-%EC%9E%A5%EC%A0%90%EC%9D%80![](https://velog.velcdn.com/images/dainel-q/post/7a07a7cb-43bd-4e25-9033-54922610733e/image.png)</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Project_Touched_Remaster]]></title>
            <link>https://velog.io/@dainel-q/ProjectTouchedRemaster</link>
            <guid>https://velog.io/@dainel-q/ProjectTouchedRemaster</guid>
            <pubDate>Sun, 17 Dec 2023 12:40:33 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h1 id="목차">목차</h1>
</blockquote>
<h2 id="1-프로젝트-기획의도">1. 프로젝트 기획의도</h2>
<h2 id="2-프로젝트에-사용된-기술스펙">2. 프로젝트에 사용된 기술스펙</h2>
<h2 id="3-프로젝트-구성">3. 프로젝트 구성</h2>
<h3 id="3-1-common-폴더">3-1. Common 폴더</h3>
<ul>
<li>Common/Button</li>
<li>Common/Footer</li>
<li>Common/GuideSection</li>
<li>Common/Header</li>
<li>Common/Modal</li>
<li>Common/Wrapper<h3 id="3-2-pages-폴더">3-2. Pages 폴더</h3>
</li>
<li>Pages/FirstPage</li>
<li>Pages/BackgroundPage</li>
<li>Pages/InfoPage</li>
<li>Pages/WritingPage</li>
<li>Pages/ImagePage</li>
<li>Pages/BgmPage</li>
<li>Pages/CheckPage</li>
<li>Pages/TestPage<h2 id="4-프로젝트-후기">4. 프로젝트 후기</h2>
</li>
</ul>
<br>

<h1 id="1-프로젝트-기획의도-1">1. 프로젝트 기획의도</h1>
<ul>
<li>2023년 작업했던 편지작성 페이지인 &#39;Project_Touched&#39;를 Remaster함
Project_Touched 시연 링크 : <a href="https://seunggyu-jung.github.io/Project-Touched-Sample/">https://seunggyu-jung.github.io/Project-Touched-Sample/</a></li>
<li>기존 프로젝트의 경우, 편지의 내용을 <strong>직접 코드로 작성</strong>해야 작성이 가능</li>
<li>홈페이지 내에서 직접 편지를 작성할 수 있는 <code>SPA 프로젝트</code>로 Remaster를 진행</li>
</ul>
<h1 id="2-프로젝트에-사용된-기술스펙-1">2. 프로젝트에 사용된 기술스펙</h1>
<blockquote>
<h2 id="1-언어--typescript">1. 언어 : TypeScript</h2>
</blockquote>
<ul>
<li>현재 프론트 엔드 실무에 있어 객체 지향의 장점과 협업을 효율을 향상시켜주는 <code>TypeScript</code>를 주 언어로 사용하여 코드의 가독성및 에러를 최소화 시킴<h2 id="2-라이브러리--react">2. 라이브러리 : React</h2>
</li>
<li>다양한 라이브러리를 사용하여 보다 페이지를 다체롭게 꾸밀 수 있은 <code>React</code>를 사용<h2 id="3-상태관리--recoil">3. 상태관리 : Recoil</h2>
</li>
<li>React과의 호환성이 좋고 Redux보다 훨씬 가볍고 실용적인 <code>Recoil</code>을 사용하여 전역 상태 관리를 진행함</li>
</ul>
<br>

<h1 id="3-프로젝트-구조">3. 프로젝트 구조</h1>
<ul>
<li>본 프로젝트는 크게 FirstPage, BackgroundPage, InfoPage, WritingPage, ImagePage, BgmPage, CheckPage, TestPage로 총 8개의 페이지로 구성되어있는 <code>Pages 폴더</code>와 버튼, 헤더, 풋터, 모달, 레이아웃 등 공통적으로 사용할 수 있는 <code>Common 폴더</code>로 구성되어있다.</li>
</ul>
<h2 id="3-1-commonbutton">3-1. Common/Button</h2>
<ul>
<li>편지를 작성하는 순서가 정해져있으며, 순서 이전과 이후로 넘어갈 수 있게 해주는 버튼을 구현</li>
<li>해당 버튼은 작성 페이지들(5개)에서 사용하기에 공용 컴퍼넌트로 제작</li>
<li>몇몇 페이지는 편지를 작성할때 반드시 작성해야 하는 내용(기본정보, 편지내용)들을 넘기는 일이 없도록 제약을 거는 함수가 구현되어 있음</li>
<li>따라서 다음으로 넘어가는 버튼의 경우, 전달값이 함수인지 아닌지를 판별하는 로직을 구현
<img src="https://velog.velcdn.com/images/dainel-q/post/b98202d0-9508-4388-b28a-2f5866a5520a/image.png" alt="">사진과 같이 필수 조건을 충족하지 못하면
<img src="https://velog.velcdn.com/images/dainel-q/post/db2eb705-8568-40be-b0cf-c3dc6c6b8f46/image.png" alt="">팝업 경고창이 나오고 다음 단계로 넘어가지 못하게 제한함
<img src="https://velog.velcdn.com/images/dainel-q/post/eb25b286-5b61-4cc2-99f7-94343e8bf9c2/image.png" alt=""></li>
</ul>
<h2 id="3-2-commonfooter">3-2. Common/Footer</h2>
<ul>
<li>프로젝트에 대한 인적사항이나 개발자에 대한 정보를 더 알아볼 수 있는 풋터 구현</li>
<li>페이지의 height값이 낮은 경우, height값에 맞게 올라오지 않고 항상 하단에 고정 할 수 있도록 공용 레이아웃에 <code>min-height</code>와 <code>padding-bottom</code>으로 값을 조정하고 풋터에 <code>position: relative</code>와 <code>translateY(-100%)</code>을 넣음
<img src="https://velog.velcdn.com/images/dainel-q/post/55cd2ffa-7c41-4665-9fe8-1618306a87b2/image.png" alt="">공용 레이아웃에 <code>min-height</code>와 <code>padding-bottom</code>으로 값을 조정
<img src="https://velog.velcdn.com/images/dainel-q/post/2ac02944-bc11-4e2d-af60-8a00ad359e2d/image.png" alt="">풋터에 <code>position: relative</code>와 <code>translateY(-100%)</code>을 넣음
<img src="https://velog.velcdn.com/images/dainel-q/post/dd8cfc8f-eeec-49bd-aea3-e85ffb9dffd4/image.png" alt=""><strong>height 공간이 남아도 항상 하단에 고정</strong></li>
</ul>
<br>

<h2 id="3-3-commonguidesection">3-3. Common/GuideSection</h2>
<ul>
<li>편지 작성 방법을 안내해주는 section은 작성 페이지에 공통적으로 들어가기에 구현</li>
<li>페이지 명과 가이드 내용을 <code>props</code>로 전달받는 구조로 사용하여 <strong>코드의 재사용성</strong>을 높임</li>
<li>만약 가이드에 설명 내용이 한 줄로 짧은 경우는 어떻게 해야하는가?</li>
<li>2단계부터 <strong>인터페이스에 null 값도 포함</strong>하여 불필요한 곳에 null을 전달시켜 해결
<img src="https://velog.velcdn.com/images/dainel-q/post/214a7aa3-eb54-4a1b-8e2b-9f5286e7d335/image.png" alt="">가이드가 긴 경우에는 상관없지만
<img src="https://velog.velcdn.com/images/dainel-q/post/b6b4c97c-c136-4d93-8d89-89dff37ad6ee/image.png" alt="">이렇게 짧은 경우 문제가 발생한다.
<img src="https://velog.velcdn.com/images/dainel-q/post/6337139a-ac5f-473b-a42d-57a78b741490/image.png" alt="">2단계부터 <strong>인터페이스에 null 값도 포함</strong>
<img src="https://velog.velcdn.com/images/dainel-q/post/1dcbfb76-3caf-4cb7-8b9f-01e81e21b3c0/image.png" alt=""></li>
</ul>
<br>

<h2 id="3-4--commonheader">3-4 . Common/Header</h2>
<ul>
<li>작성 페이지가 어떤 페이지인지 명시해주며, 각 페이지를 이동할 수 있도록 리모컨 역할을 하는 버튼을 갖는 헤더 구현</li>
<li>PC 버전의 경우, height값이 충분히 크기 때문에 fixed된 헤더가 불필요하다 느껴 값을 고정</li>
<li>모바일 버전의 경우, heigth값이 기종마다 다르기에, max-width: 500px로 고정하여 스크롤을 따라다니는 헤더를 구현
<img src="https://velog.velcdn.com/images/dainel-q/post/59f8176e-23db-484b-9a27-e938dc64f39c/image.png" alt="">PC버전
<img src="https://velog.velcdn.com/images/dainel-q/post/2b001d1d-f878-42c7-8e4d-8cdb3878615d/image.png" alt="">모바일 버전</li>
</ul>
<br>

<ul>
<li>클릭하면 동적으로 변하는 햄버거 버튼 스타일링 구현</li>
<li>@keyframes를 통해, 자연스럽게 내려오는 ul,li태그 구현
<img src="https://velog.velcdn.com/images/dainel-q/post/8683161a-7e69-46d6-b643-ecf118d19e86/image.png" alt=""></li>
<li>슬라이더의 경우, props를 styled에서 선언하여 tsx로 전달될 수 있도록 구현</li>
<li><code>ease forwards</code>를 통해 @keyframe에서 변경된 값을 유지하도록 구현
<img src="https://velog.velcdn.com/images/dainel-q/post/2be35206-f876-4093-bf2c-10eacd3b8af5/image.png" alt=""></li>
</ul>
<br>

<h2 id="3-5-commonmodal">3-5. Common/Modal</h2>
<ul>
<li>웹에서 제공하는 alert를 사용하는 것이 단조롭고, 다양한 기능을 넣을 수 없다고 판단하여 별도의 alert역할을 하는 modal창 구현
<img src="https://velog.velcdn.com/images/dainel-q/post/4ac082c5-6461-4b4b-9841-320b796ff6e4/image.png" alt=""></li>
<li>dom트리에 직접적으로 접근하여 modal창이 열렸을때, 키보드나 마우스의 스크롤을 이동시킬 수 없도록 구현
<img src="https://velog.velcdn.com/images/dainel-q/post/6a55e489-f883-422d-8cf1-be00dc3a6677/image.png" alt=""></li>
<li>모달창이 아닌 곳을 클릭하거나, <code>useEffect</code>를 사용하여 esc키를 눌러 모달창을 끌 수 있도록 구현
<img src="https://velog.velcdn.com/images/dainel-q/post/ca4eb4c5-387b-4151-8686-5dc696cbe20e/image.png" alt=""></li>
</ul>
<br>

<h2 id="3-6-commonwrapper">3-6. Common/Wrapper</h2>
<ul>
<li>편지 작성을 담당하는 모든 페이지의 레이아웃을 공용 컴퍼넌트로 제작</li>
<li>props로 children을 전달하고 각 페이지에 필요한 태그들을 담는 로직으로 작동
<img src="https://velog.velcdn.com/images/dainel-q/post/d581d9da-f996-4e37-a280-3c28bac4c048/image.png" alt=""></li>
</ul>
<br>

<h2 id="3-7-pagesfirstpage">3-7. Pages/FirstPage</h2>
<ul>
<li>사용자가 가장 먼저 접하는 페이지</li>
<li><code>react-responsive-carousel</code>라이브러리를 사용하여 반응형에 적합한 Carousel로 여타 홈페이지의 WelcomePage와 유사한 UI를 구현함
<img src="https://velog.velcdn.com/images/dainel-q/post/e9b4d185-9277-414a-bb10-48df7812b7fb/image.png" alt="">
출처 : <a href="https://programmers.co.kr/">https://programmers.co.kr/</a>
<img src="https://velog.velcdn.com/images/dainel-q/post/72a83395-d903-4234-a93c-a74ef034fb86/image.png" alt=""></li>
<li>Carousel에서 사용한 속성 :
showArrows={false} : Carousel 양 옆의 화살표 제거
showStatus={false} : Carousel 상단의 이미지의 번호 제거
autoPlay={true} : 자동으로 이미지들을 순환
infiniteLoop={true} : 순환을 무한히 진행
interval={3000} : 이미지 전환 주기를 3초로 실행
showThumbs={false} : 이미지 미리보기를 보여주지 않음
showIndicators={false} : 이미지 전환을 할 수 있는 리모컨을 숨김
stopOnHover={false} : 호버시 이미지 전환이 멈추는 것을 제거
selectedItem={currentIndex} : currentIndex에 해당하는 화면을 보여줌</li>
<li>이미지를 배열로 전달받아 이를 <code>map</code>을 통해 순환시킴
<img src="https://velog.velcdn.com/images/dainel-q/post/52c062d2-7f62-46a7-a00d-834f02bd72c4/image.png" alt=""></li>
<li>useState를 이용하여 인덱스의 상태를 관리하고, 해당 인덱스가 곧 Carousel에 보여지는 이미지의 번호
<img src="https://velog.velcdn.com/images/dainel-q/post/dbc87429-4e51-4161-8d32-f8ddf7bc98bb/image.png" alt=""></li>
</ul>
<br>

<h2 id="3-8-pagesbackgroundpage">3-8. Pages/BackgroundPage</h2>
<ul>
<li>전송될 편지의 배경화면 색상을 선택하는 페이지</li>
<li><code>react-colorful</code>라이브러리를 사용하여 색상 팔레트를 사용</li>
<li>2가지 색의 그라데이션으로 구성되어있으며, 원하는 색을 2개 선택하여 조합하는 방식</li>
<li>색상을 선택하면, 기존의 2가지 색 중, 가장 먼저 선택한 색부터 사라지는 방식</li>
<li>색들은 배열 형태로 되어있기에, 이를 반전시킬 수 있는 기능도 구현
<img src="https://velog.velcdn.com/images/dainel-q/post/2a0525b7-1f17-4cc0-bb5f-0fa29c4b60c9/image.png" alt=""></li>
<li>이렇게 선택된 색상들은 배열 형태로 Recoil 파일에 저장
<img src="https://velog.velcdn.com/images/dainel-q/post/a2e623be-f599-498b-a75d-6ed64e4ada85/image.png" alt=""></li>
<li>배경색은 welcomePage를 제외한 나머지 페이지에 globalStyle의 <code>Before가상요소</code>로 적용
<img src="https://velog.velcdn.com/images/dainel-q/post/ba33da8c-1e2a-4d2f-a816-a0856a8acf65/image.png" alt=""></li>
</ul>
<br>

<h2 id="3-9-pagesinfopage">3-9. Pages/InfoPage</h2>
<ul>
<li><p>발신자와 수신자의 이름을 작성하는 페이지</p>
</li>
<li><p>input태그에 정보를 입력하여 전달하기에 form태그를 사용</p>
</li>
<li><p>프로젝트에서 반드시 필요한 정보이기에 input태그에 p태그를 absolute로 강조</p>
</li>
<li><p>내용을 입력하면 p태그가 민트색의 체크표시로 변경
<img src="https://velog.velcdn.com/images/dainel-q/post/5bf573e0-5203-4cc9-b053-f5b1319472cc/image.png" alt=""><img src="https://velog.velcdn.com/images/dainel-q/post/3eb07d2e-1a5d-48ca-83e9-9464ea1757cd/image.png" alt=""></p>
</li>
<li><p>조건을 충족하지 않을 경우, 그 조건을 충족시키라는 팝업창이 나타나도록 구현</p>
</li>
<li><p>내용을 작성하지 않아도, 헤더의 리모컨 버튼을 통해 다른 페이지로 넘어갈 수 있게 구현하여 사용에 대한 불쾌감 제거
<img src="https://velog.velcdn.com/images/dainel-q/post/62957c43-29ee-4ea9-bb3a-71502d80007c/image.png" alt=""></p>
</li>
<li><p>두 p태그의 로직은 같지만, 각자 참조하는 상태가 다르기 때문에 따로 분리하여 구현
<img src="https://velog.velcdn.com/images/dainel-q/post/754344d0-71c1-4c5b-a28c-ae44e37f6e52/image.png" alt=""></p>
</li>
</ul>
<br>

<h2 id="3-10-pageswritingpage">3-10. Pages/WritingPage</h2>
<ul>
<li>편지의 내용을 작성하는 페이지
<img src="https://velog.velcdn.com/images/dainel-q/post/54e862b1-c7c1-4481-a38b-8e41e793de6a/image.png" alt=""></li>
<li>편지에 담길 텍스트의 폰트, 크기, 편지 section의 배경을 선택할 수 있음</li>
<li>선택로직은 select태그와 option태그로 구현
<img src="https://velog.velcdn.com/images/dainel-q/post/2d96455e-3e41-46f0-8ffb-072e5fed74da/image.png" alt=""></li>
<li>배경이미지는 내장된 이미지를 사용(추후에 변경 예정)</li>
<li>선택로직이 구현된 section은 숨기기 버튼을 통해 사용자에게 보다 쾌적한 UI를 제공
<img src="https://velog.velcdn.com/images/dainel-q/post/dc84b7c1-ebf1-4078-89c0-6f2354a15591/image.png" alt=""></li>
<li>편지내용 또한 필요한 요소이기에 필수적으로 작성하도록 설정
<img src="https://velog.velcdn.com/images/dainel-q/post/313957a6-39b3-4999-8166-e2aa13e1ac0e/image.png" alt=""></li>
</ul>
<br>

<h2 id="3-11-pagesimagepage">3-11. Pages/ImagePage</h2>
<ul>
<li>편지에 장식할 이미지를 업로드 하는 페이지</li>
<li>업로드 전에는 별도의 section이 생기지 않고, 업로드하면 보이는 로직 적용</li>
<li>이미지의 오른쪽 상단에 삭제버튼 구현</li>
<li>&#39;파일 선택&#39;버튼을 클릭하고, 원하는 이미지를 선택하여 업로드 하는 방식</li>
<li>희망하는 경우, 한 번에 여러 사진을 함께 업로드 가능
<img src="https://velog.velcdn.com/images/dainel-q/post/f7108cd2-f08d-4a69-91c8-acc761077cd5/image.png" alt=""><img src="https://velog.velcdn.com/images/dainel-q/post/1ed4f85d-0676-4a08-9650-70f2ea9815f3/image.png" alt=""></li>
<li><code>react-responsive-carousel</code>라이브러리를 사용하여 <strong>반응형</strong>에 적합한 Carousel을 사용</li>
<li>이미지는 배열 타입이며, Carousel에 담겨 <code>map</code>으로 조회가능
<img src="https://velog.velcdn.com/images/dainel-q/post/9a4aa1d3-25ac-47df-842c-edaae6e20afb/image.png" alt=""></li>
</ul>
<br>

<h2 id="3-12-pagesbgm_page">3-12. Pages/BGM_Page</h2>
<ul>
<li>편지를 열자마자 재생될 BGM을 유튜브에서 가져와 업로드하는 페이지</li>
<li><code>react-youtube</code>라이브러리를 사용하여 유튜브 url에 해당하는 영상을 상영해주는 기능 구현</li>
<li>처음 저복할때는 설정되어있는 url이 따로 존재하지 않음
<img src="https://velog.velcdn.com/images/dainel-q/post/f210aab2-569b-4eb0-a04e-4cbab32b3248/image.png" alt=""></li>
<li>사용자가 원하는 유튜브 영상의 url을 input태그에 업로드하면 <code>recoil</code>에서 관리가 됨
<img src="https://velog.velcdn.com/images/dainel-q/post/a571c45f-7c32-4333-ad3e-63ee1c9c5279/image.png" alt=""></li>
<li>이는 모바일 사용자도 함께 사용할 수 있도록 정규표현식으로 나누어 처리함
<img src="https://velog.velcdn.com/images/dainel-q/post/7cb695f0-2d1b-4c18-93b3-e7dd64c4d412/image.png" alt=""></li>
<li>이 페이지가 편지 구성 작업의 마지막 단계라서, 기존에 작성해야했던 필수 정보들의 작성 유무를 <code>recoil</code>을 조회하여 검토해줌(수신자 정보, 발신자 정보, 편지내용)
<img src="https://velog.velcdn.com/images/dainel-q/post/28e1bd2c-8112-4778-9ac0-413ee9717ca0/image.png" alt=""></li>
<li>조건을 만족하면 수신자용 welcomePage로 이동할 수 있게 해주는 팝업창이 나타남
<img src="https://velog.velcdn.com/images/dainel-q/post/d1c348d3-3dcb-45ce-a7b7-81aff1a8b1ad/image.png" alt=""></li>
</ul>
<br>

<h2 id="3-13-pagescheckpage">3-13. Pages/CheckPage</h2>
<ul>
<li>수신자가 처음으로 접하게 될 welcomePage</li>
<li>본인이 수신자가 맞는지에 대한 진위 판단 여부를 알아야하기 때문에 CheckPage로 네이밍함
<img src="https://velog.velcdn.com/images/dainel-q/post/2c5d1579-68c6-4ecc-a9d5-42fbcb34e795/image.png" alt=""></li>
<li>&#39;맞아&#39;버튼을 클릭하면 커스텀된 편지를 확인할 수 있게 해주는 페이지로 전환
<img src="https://velog.velcdn.com/images/dainel-q/post/8466abd3-3d8f-46ea-a023-ada2f300e1bc/image.png" alt=""></li>
<li>&#39;...아닌데?&#39;버튼을 클릭하면 &#39;맞아&#39;버튼과 기능이 같은 &#39;생각해보니 맞는 것 같아&#39;버튼이 있는 페이지로 전환
<img src="https://velog.velcdn.com/images/dainel-q/post/fd70cc7c-4ae5-432d-8b1a-4159bab692a6/image.png" alt=""></li>
<li>결국 본인이 수신자가 아닐 경우, 웹페이지를 종료할 것이라 판단하여, 관심이 있다면 <strong>편지내용을 볼 수 있도록</strong> 설정함</li>
</ul>
<br>

<h2 id="3-14-pagestestpage">3-14. Pages/TestPage</h2>
<ul>
<li>수신자가 보게 될 커스텀 된 편지를 미리 확인하고, 이상이 없으면 앞의 checkPage url을 복사해주는 페이지</li>
<li>위에서 아래방향으로 자동으로 글씨가 써지는 이미지를 구현
=&gt; keyframes를 통해 스크롤 아래 방향으로 천천히 글씨가 써지는 로직
<img src="https://velog.velcdn.com/images/dainel-q/post/e3a9fc5a-4111-4ef0-977f-46057271132e/image.png" alt=""><img src="https://velog.velcdn.com/images/dainel-q/post/5778f240-34f9-4161-bbf2-34ae6c142c13/image.png" alt=""></li>
<li>이미지를 추가하고, BGM을 설정하면 보다 풍성하게 커스터마이징 가능
<img src="https://velog.velcdn.com/images/dainel-q/post/988f03d6-3eab-4b5a-b909-dd68c5531b11/image.png" alt=""></li>
<li>&#39;url 복사&#39;버튼을 클릭하면 자동으로 클립보드에 checkPage의 url이 복사가 되며, 성공완료 팝업창이 나타남
<img src="https://velog.velcdn.com/images/dainel-q/post/c6d685d0-113a-41cb-93b9-674bb3f4285f/image.png" alt=""></li>
<li>거의 가능성은 없지만, 복사에 에러가 발생하면 console창에 에러를 출력해주는 로직 구현
<img src="https://velog.velcdn.com/images/dainel-q/post/a03c3d26-0284-4eb2-ba90-19ef0c84c2ca/image.png" alt=""></li>
</ul>
<br>

<h1 id="4-프로젝트-후기-1">4. 프로젝트 후기</h1>
<h2 id="4-1-장점">4-1. 장점</h2>
<ul>
<li>타인에게 감동을 준다는 <strong><code>취지에 걸맞게</code></strong> 다양하게 커스터마이징 할 수 있는 편지 홈페이지를 만들어 <strong><code>홈페이지의 정체성을 잘 살렸다</code></strong>고 판단</li>
<li><strong><code>반응형 웹페이지로 제작</code></strong>하여, 모바일 버전에서도 쾌적하게 사용할 수 있음</li>
<li><strong><code>다양한 React 라이브러리</code></strong>를 활용하여, 기존의 메신지 시스템이 구사하지 못하는 기능들을 넣음(그라데이션 배경, 유튜브 자동재생기능...)</li>
<li><strong><code>TypeScript</code></strong>와 <strong><code>Recoil</code></strong>을 활용하여 어느정도 상업용 웹페이지의 틀을 갖춘 <strong><code>SPA</code></strong>를 개발했다고 판단</li>
<li>공통으로 사용할 수 있는 코드는 최대한 <strong><code>재사용</code></strong>하는 방향으로 작업 =&gt; 불필요한 코드가 거의 없는 <strong><code>클린 코딩을 진행</code></strong></li>
</ul>
<br>

<h2 id="4-2-아쉬운-점">4-2. 아쉬운 점</h2>
<ul>
<li><p>별도의 서버를 운영하지 않아, Recoil이 로컬에서만 저장이 됨
=&gt; 수신자에게 전송을 하면 Recoil에 담긴 내용 없이 default 값으로 전송됨
=&gt; 이는 <code>firebase</code>와 같은 백엔드 서포트 어플을 활용하여 개선할 계획</p>
</li>
<li><p>현제 이 페이지의 오류는 지속되는 새로고침과 리렌더링을 진행하면, recoil에 저장된 이미지가 렌더링 되지 않음 =&gt; 이미지 데이터는 존재하지만, 렌더링을 하지 못하는 것
=&gt; 예상되는 원인 : 임의로 생성한 이미지 url주소가 렌더링 될때마다 변경되기 때문이라 판단
=&gt; 이 부분은 주변 지인들과 상의를 해서 해결해봐야 할 듯 하다.
<img src="https://velog.velcdn.com/images/dainel-q/post/14001a55-8468-4aeb-9419-6d4bed8ed19b/image.png" alt=""></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[OG(Open Graph)]]></title>
            <link>https://velog.io/@dainel-q/OGOpen-Graph</link>
            <guid>https://velog.io/@dainel-q/OGOpen-Graph</guid>
            <pubDate>Fri, 01 Dec 2023 14:39:56 GMT</pubDate>
            <description><![CDATA[<h1 id="1-정의">1. 정의</h1>
<p>정식 명칭은 Open Graph Protocol로 Facebook(현 Meta)에서 발표한 인터넷 프로토콜의 한 종류</p>
<h1 id="2-목적">2. 목적</h1>
<p>일종의 미리보기 기능을 구현해 준다. 즉, 단순 URL만 있는 웹페이지 링크에 보다 다양한 정보들을 입력하여 소비자가 웹 페이지를 쉽게 이해하고 접근할 수 있도록 보조하려는 목적이 있다.</p>
<h1 id="3-효과">3. 효과</h1>
<ul>
<li>마케팅 효과(SEO)
다양한 웹사이트들이 넘치는 소셜 미디어에서 소비자로 하여금 웹페이지에 대한 다양한 정보들을 직관적이고, 단시간에 전달할 수 있으며, 이는 곧 소비자의 이목을 집중시켜 한 번쯤 이용하고 클릭하고 싶도록 하는 마케팅 효과가 있다.
사실 이걸 직접적인 SEO효과라고 언급하기는 어렵지만, 간접적인 도움을 준다고 할 수 있다고 생각한다.</li>
</ul>
<h1 id="4-사용-예시">4. 사용 예시</h1>
<ul>
<li>적용 전 :
<img src="https://velog.velcdn.com/images/dainel-q/post/ac4851ca-86f5-4506-bfd4-d8a53159a15d/image.png" alt=""></li>
</ul>
<ul>
<li>적용 후 :
<img src="https://velog.velcdn.com/images/dainel-q/post/e71e24b2-6347-49ef-9ec5-5c8bc20f13ab/image.png" alt=""></li>
</ul>
<p>육안으도 확인 할 수 있듯이, 후자의 경우, 좀 <strong>더 매력적</strong>으로 느껴지고, 해당 페이지가 어떤 페이지인지 <strong>정보를 전달</strong>한다는 점에서 가장 큰 차이가 있다고 할 수 있다.</p>
<h1 id="5-사용법">5. 사용법</h1>
<p>index.html 파일의 head태그 안에 meta태그로 작성을 한다.
위 예시에서 적용한 오픈 그래프 태그는 og:title og:description og:image 이렇게 3개를 사용했다.
<img src="https://velog.velcdn.com/images/dainel-q/post/3055e693-6fe4-4b78-b6b3-cae371b29e15/image.png" alt="">
meta태그의 속성 중 property에 원하는 og태그를 선택하여 작성하고, content 속성에 값을 입력하는 방식으로 사용한다.</p>
<ul>
<li><p>og:title
웹 페이지의 제목을 입력하는 구간으로, 프로젝트의 명을 작성하면 된다.
기본적으로 글씨가 bold 처리되기에 그대로 사용해도 괜찮다고 생각한다.
그리고 카카오톡으로 사용할 경우, title이 카카오톡 기준으로 2줄이 넘어가면 description이 사라지기에 되도록 한 줄로 간단하게 입력할 것을 권장한다.</p>
</li>
<li><p>og:description
웹 페이지에 대한 구현 설명을 작성하는 태그로 되도록 간단하고 명료하게 작성하는 것이 중요하다.
너무 길어지는 경우, ...으로 생략이 되는데, 이것이 미관상 좋지 않다고 생각한다.</p>
</li>
<li><p>og:image
웹 페이지를 대표하는 이미지를 입력하는 태그로, 앞서 언급한 마케팅 효과의 핵심이라 할 수 있다.
웹 페이지에 업로드 할 경우, 권장되는 이미지 크기는 1200 x 630 pixel
카카오톡에만 업로드 할 경우, 권장되는 이미지 크기는 300 x 200 pixel이다.</p>
</li>
</ul>
<h1 id="6-참고">6. 참고</h1>
<h2 id="1-open-graph-시연-사이트">1. Open Graph 시연 사이트</h2>
<p><a href="https://developers.facebook.com/tools/debug/">https://developers.facebook.com/tools/debug/</a></p>
<p>본인이 facebook 계정이 있으면, 일일이 새로 commit할 필요 없이 해당 사이트에서 오픈 그래프 작동을 확인할 수 있다.</p>
<h2 id="2-카카오톡-캐시-초기화-사이트">2. 카카오톡 캐시 초기화 사이트</h2>
<p><a href="https://developers.kakao.com/tool/debugger/sharing">https://developers.kakao.com/tool/debugger/sharing</a>
카카오톡의 경우, 한 번 업로드한 오픈 그래트 태그의 정보가 캐시에 저장되어, 수정을 해도 변하지 않기 때문에, 해당 사이트에서 삭제를 하고 진행해야한다.</p>
<hr>
<p>참고 자료
<a href="https://ogp.me/">https://ogp.me/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이미지 저장 창고]]></title>
            <link>https://velog.io/@dainel-q/%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%A0%80%EC%9E%A5-%EC%B0%BD%EA%B3%A0</link>
            <guid>https://velog.io/@dainel-q/%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%A0%80%EC%9E%A5-%EC%B0%BD%EA%B3%A0</guid>
            <pubDate>Fri, 01 Dec 2023 06:46:24 GMT</pubDate>
            <description><![CDATA[<h1 id="1-project_touched_remaster">1. Project_Touched_Remaster</h1>
<h2 id="1-1-open-graph-용-이미지">1-1. Open Graph 용 이미지</h2>
<h3 id="1-1-600315">1-1. 600*315</h3>
<p><img src="https://velog.velcdn.com/images/dainel-q/post/41c3a16f-efc5-45c5-99fd-73274d825bce/image.png" alt=""></p>
<h3 id="1-2-326305">1-2. 326*305</h3>
<p><img src="https://velog.velcdn.com/images/dainel-q/post/f9ed965f-14e3-4db6-94e4-a35269e74528/image.png" alt=""></p>
<h1 id="2-interview_summary">2. Interview_Summary</h1>
<h2 id="2-1-open-graph-용-이미지">2-1. Open Graph 용 이미지</h2>
<p><img src="https://velog.velcdn.com/images/dainel-q/post/ea428100-00ae-461c-8416-7462ab6f5f89/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[🔑React의 상태관리란 무엇인가?]]></title>
            <link>https://velog.io/@dainel-q/React%EC%9D%98-%EC%83%81%ED%83%9C%EA%B4%80%EB%A6%AC%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@dainel-q/React%EC%9D%98-%EC%83%81%ED%83%9C%EA%B4%80%EB%A6%AC%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Mon, 12 Jun 2023 04:57:07 GMT</pubDate>
            <description><![CDATA[<blockquote>
</blockquote>
<h1 id="목차">목차</h1>
<h2 id="1-주제-선정-이유">1. 주제 선정 이유</h2>
<h2 id="2-상태관리란">2. 상태관리란</h2>
<ul>
<li>상태관리의 정의</li>
<li>상태의 종류<h2 id="3-react의-상태관리">3. React의 상태관리</h2>
</li>
<li>Context API</li>
<li>Redux</li>
<li>Reacoil 라이브러리</li>
</ul>
<h1 id="1-주제-선정-이유-1">1. 주제 선정 이유</h1>
<p>React라이브러리를 사용하다보면 상태관리가 필수이며 그에 따른 각종 기능들을 숙지하고 있어야한다. 이에 대해 알지 못하면 React를 사용하지 않는 수준이며, 협업을 하는데 있어 큰 지장이 되기에 이번 기회에 상태관리에 대한 정확한 정의를 학습하고, React의 상태관리 방법에는 어떤 것들이 있는지 살펴보도록 하자.</p>
<br>

<h1 id="2-상태관리란-1">2. 상태관리란</h1>
<h2 id="2-1-상태관리의-정의">2-1. 상태관리의 정의</h2>
<ul>
<li>상태(State) : 컴퍼넌트 내부에서 관리되며 어플리케이션의 렌더에 영향을 미치는 자바스크립트 객체를 의미. 즉, <strong>변화하는 데이터</strong>라고 이해하면 된다. (ex, 쇼핑몰 사이트에서 구매할 물건의 수량을 늘리고 줄이는 행위를 상태가 변화한다고 한다.)</li>
</ul>
<ul>
<li>상태관리 : 상태는 어는 컴퍼넌트에서나 일관되어야 한다. 이를 데이터의 무결성이라 한다. 왜냐하면, 상태가 컴퍼넌트마다 다르다면, 유저나 관리자가 받아들이는 데이터에 차이가 생겨 소통에 차질이 생기기 때문이다.
따라서 상태를 일관되게 관리해야하며, React의 경우, <strong>신뢰할 수 있는 단일 출처(동일한 데이터는 항상 같은 곳에서 가져온다)</strong>라는 방법론으로 상태를 관리하고 있다.</li>
</ul>
<h2 id="2-2-상태의-종류">2-2. 상태의 종류</h2>
<ul>
<li><p>지역상태(localState) : 특정 컴퍼넌트 안에서만 관리되는 상태를 의미한다. 이는 주로 작은 프로젝트처럼 좁은 영역에서만 관리되는 데이터들이다.</p>
</li>
<li><p>컴퍼넌트 간 상태: 다수의 컴퍼넌트에서 사용되고 영향을 주는 데이터들을 의미한다. 대표적인 예시로 여러 컴퍼넌트가 동시에 사용하는 모달창 등이 있다.
2개 이상의 컴퍼넌트간에 상태를 주고 받을 경우, 상위 컴퍼넌트에서 하위 컴퍼넌트로만 상태를 전달하며, 이를 Props Driling이라 한다.</p>
</li>
<li><p>전역 상태(globalState) : 프로젝트 전체에 영향을 끼치는 데이터를 의미한다. 대표적인 예로, 모든 컴퍼넌트에서 사용되는 페이지의 헤더 컴퍼넌트 등이 있다.</p>
</li>
<li><p>상태관리가 필요한 이유: 걱 컴퍼넌트가 부모자식 관계로 되어있지 않은 이상 각 컴퍼넌트간의 직접적인 데이터 전달은 어렵우며, 구조가 복잡하여 Props Driling이 많아지면 Props의 출처를 찾기 어려워기 때문에 이를 관리해줘야 한다.</p>
</li>
</ul>
<h1 id="3-react의-상태관리-1">3. React의 상태관리</h1>
<h2 id="3-1-context-api">3-1. Context API</h2>
<ul>
<li><p>Context API : React 컴포넌트 트리 안에서 전역 상태를 공유할 수 있도록 만들어진 방법이다.
명칭은 API이기는 하지만, 실질적인 관리는 API가 아니라 useState를 통해 이루어진다.</p>
</li>
<li><p>useState() : 
<code>cosnt [state, setState] = useState()</code>의 형태로 구성되어 있다.
앞에서서부터 state라는 상태변수와 상태에 변화를 주는 setState라는 함수가 있다. useState()의 파라미터에는 초기 state값이 들어가며, 이후 setState를 통해 state의 값에 변화를 주는 방식으로 상태를 관리한다.
useState()는 상태를 새로 추가하거나 삭제하는 것이 아니라 단순 비교를 통해 상태를 업데이트 시키는 원리로 작동한다.
즉, <strong>동일한 데이터의 key값이면 키의 value값의 차이를 비교하여 최신의 value값으로 갱신하며 상태를 관리한다.</strong>
이는 중간에 있는 요소들에게 props를 넘기지 않고도 데이터를 가져다 사용할 수 있기에 props Drilling을 피할 수 있으며, 주로 전역적으로 쓰이는 데이터들을 사용할 때 자주 사용된다.</p>
</li>
<li><p>useEffect() :</p>
</li>
<li><p>context API의 구조 : context, provider, comsumer 로 구성
context : 전역상태를 저장하는 곳으로 , 내부에는 provider와 consumer로  구성되어있다.
provider : 전역상태를 제공하는 역할을 한다. 주로 Root Component(index.js / app.js)에서 정의된다.
consumer  제공받은 전역상태를 받아서 사용하는 역할을 한다.</p>
</li>
</ul>
<h2 id="3-2-redux">3-2. Redux</h2>
<ul>
<li><p>Redux : 공식 문서에 따르면 자바스크립트 앱을 위한 예측 가능한 상태 컨테이너라고 정의한다.
이를 풀어 설명하면, 전역 상태를 관리하는 도구, 즉, 어플리케이션 전체에 대한 중앙 저장소 역할을 한다고 생각하면 된다.</p>
</li>
<li><p>&#39;Store&#39;,&#39;Action&#39;, &#39;Reducer&#39;로 구성되어 있다.
Store는 전역상태를 저장하는 저장소 역할을 하며, 오직 Reducer를 통해서만 접근이 가능하다. 주로 index.js에 정의되며 Store는 오직 1개만 존재할 수 있다.
Action은 Store에 저장된 상태의 변화를 Reducer에 명령하는 자바스크립트 객체이다. 변화를 주기 위해 dispatch라는 메서드를 사용하여 Reducer에게 전달된다.
Reducer는 변화를 감지하여 상태를 변화시키는 역할을 하는 순수함수로서, 전역 상태를 변경하고 업데이트시킨다. 바닐라 자바스크립트의 &#39;이벤트리스너&#39;와 동일한 역할을 한다고 파악해도 좋다.
다만, Redux의 경우, 상태관리를 할 때, 이전상태를 변경시키는 것이 아닌 <strong>새로운 상태의 객체를 생성하여 반환한다</strong>는 점을 명시해야한다.</p>
</li>
<li><p>순수함수 :  다른 외부의 상태를 변경하지 않으면서도, 어떤 동일한 인자에 대해 항상 동일한 값을 리턴하는 함수이다.</p>
</li>
</ul>
<h2 id="3-3-recoil-라이브러리">3-3. Recoil 라이브러리</h2>
<ul>
<li><p>앞서 언급한 Redux는 단방향의 흐름에서 상태관리가 용이하지만, 이를 위한 action, reducer와 같은 초기 세팅이 상당히 번거롭고 React와 잘 맞지 않는다는 여론이 주를 이루었다.</p>
</li>
<li><p>React의 상태관리를 보다 React스럽게(hook을 전역으로 확장시킴) 하기 위해, 메타(전 페이스북)사에서 제작한 React 상태관리 라이브러리이다.</p>
</li>
<li><p>Recoil은 atom과 selector라는 객체를 사용하여 상태를 관리한다.</p>
</li>
<li><p>atom은 구독, 옵저버와 같은 개념을 생각할 필요없이 hook을 사용하듯이 사용하면 된다.
hook를 사용했던 개발자라면 쉽게 사용할 수 있다.</p>
</li>
<li><p>selector를 이용하면 리듀서 없이 복잡한 연산도 간단하게 할 수 있다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[라이브러리란 무엇인가?]]></title>
            <link>https://velog.io/@dainel-q/%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@dainel-q/%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Sat, 03 Jun 2023 17:54:59 GMT</pubDate>
            <description><![CDATA[<blockquote>
</blockquote>
<h1 id="목차">목차</h1>
<h2 id="1-주제-선정-이유">1. 주제 선정 이유</h2>
<h2 id="2-라이브러리란">2. 라이브러리란</h2>
<ul>
<li>라이브러리의 정의</li>
<li>라이브러리를 사용하는 이유</li>
<li>라이브러리의 종류<h2 id="3-라이브러리와-프레임-워크의-차이점">3. 라이브러리와 프레임 워크의 차이점</h2>
<h2 id="4-요약-정리-및-면접형-qna">4. 요약 정리 및 면접형 QnA</h2>
</li>
</ul>
<h1 id="1-주제-선정-이유-1">1. 주제 선정 이유</h1>
<p>각종 프로젝트를 준비하는 과정에서 라이브러리의 중요성을 많이 언급되며, 실제 기업에서도 특정 라이브러리를 사용하여 프로젝트를 진행한 경험을 요구하는 경우가 많다고 느꼈을 것이다. 라이브러리가 정확하게 무엇이며 어떤 종류가 있으며, 왜 사용하는지에 대해 자세히 알아보고자 준비함</p>
<br>

<h1 id="2-라이브러리란-1">2. 라이브러리란</h1>
<h2 id="2-1-라이브러리의-정의">2-1. 라이브러리의 정의</h2>
<ul>
<li>소프트웨어를 개발할 때, 컴퓨터 프로그램이 사용하는 &#39;비휘발성 자원(리소스)&#39;의 집합이다.</li>
<li>사전적 용어인 도서관(library)와 비슷하게, 특정한 코드들(책들)을 모아둔 집합이라 생각하면 된다.</li>
<li>이는 소프트웨어 개발시에 사용되는 프로그램의 구성요소로, 공통으로 사용될 수 있는 특정한 기능들을 모듈(module)화 한 것이다.</li>
<li>API와의 차이점 : API는 프로그래밍 언어에서 라이브러리를 사용할 수 있도록 소스코드 수준에서 인터페이스를 노출 시킨 것이지만, 라이브러리는 실제 실행되어 기능을 수행하는 <strong>단편화된 프로그램</strong> 이다.</li>
<li>즉, 라이브러리는 완전한 프로램이 아니라 특정한 기능만을 수행하도록 제작된 프로그램이다.</li>
</ul>
<br>

<h2 id="2-2-라이브러리를-사용하는-이유">2-2. 라이브러리를 사용하는 이유</h2>
<ul>
<li>모든 기능을 직접 코딩하지 못하며, 시간을 절약하기 위해서이다.
동일한 기능을 간단한 코드로 방법화시키는 라이브러리 코드를 본인이 직접짜기엔 너무 많은 시간을 소요되며, 실제로 정해진 기간내에 처리하기도 어렵기 때문이다.</li>
<li>즉, 라이브러리를 사용할수 있으면, 보다 복잡한 코드를 짜는데 <strong>더 빠르고, 더 편리하게</strong> 할 수 있기에, 사용이 권장된다.</li>
</ul>
<br>

<h2 id="2-3-라이브러리의-종류">2-3. 라이브러리의 종류</h2>
<ul>
<li>표준 라이브러리: 특정한 언어의 개발 환경에 기본적으로 포함된 것들로, 언어의 기본 기능을 확장시키는 역할을 담당한다.
Python의 표준 라이브러리에는 문자열 처리, 파일 조작, 네트워크 통신 등 다양한 모듈들이 포함되어 있다.
참고문헌 : <a href="https://docs.python.org/ko/3/library/index.html">https://docs.python.org/ko/3/library/index.html</a></li>
<li>웹 개발 라이브러리 : 웹 개발의 편의성을 제공하는 역할을 한다.
대표적인 예로 JavaScript의 경우, jQuery, React, Angular 등이 있다.</li>
<li>데이터베이스 라이브러리 : 데이터베이스와 상호 작용하는 역할을 수행한다.</li>
<li>그래픽스 및 시각화 라이브러리 : 데이터 시각화나 그래픽스 작업을 위해 사용하는 라이브러리
대표적인 예로 JavaScript의 D3.js가 있다.</li>
<li>상태관리 라이브러리: 애플리케이션의 상태를 보다 효과적으로 관리(상태 업데이트나 추적...)하기 위한 라이브러리
대표적인 예로 Redux와 Recoil이 있다.</li>
</ul>
<br>

<h1 id="3-라이브러리와-프레임-워크의-차이점-1">3. 라이브러리와 프레임 워크의 차이점</h1>
<ul>
<li>주도권의 차이라고 설명할 수 있다.</li>
<li>라이브러리의 경우, 개발자가 필요에 따라 선택적으로 사용할 수 있다.</li>
<li>프레임 워크의 경우, 애플리케이션의 개발을 위한 일종의 뼈대 역할을 하기에, 개발자 프레임 워크에 맞춰서 개발을 해야한다.</li>
</ul>
<h2 id="3-1-react는-라이브러리인가-프레임-워크인가">3-1. React는 라이브러리인가 프레임 워크인가?</h2>
<ul>
<li>React는 &#39;프레임 워크같은&#39; 라이브러리라 정의할 수 있다. </li>
<li>React 개발당시, UI개발을 위한 라이브러리로 개발되었으나, React Router를 통한 라우팅 기능이나, Redux와 같은 다양한 상태관리 라이브러리와의 조합으로 점차 &#39;프레임 워크화&#39;되어간 것이다.</li>
<li>즉, React는 <strong>프레임워크처럼 동작하는 라이브러리</strong>라고 소개하면 된다.</li>
</ul>
<br>

<h1 id="4-요약-정리-및-면접형-qna-1">4. 요약 정리 및 면접형 QnA</h1>
<h2 id="q1-라이브러리에-대해-설명해주세요">Q1. 라이브러리에 대해 설명해주세요</h2>
<ul>
<li>라이브러리는 재사용 가능한 코드의 집합을 의미합니다.</li>
<li>해당 코드에는 특정 기능을 수행하는 함수, 클래스, 모듈 등으로 구성되어 있습니다.</li>
<li>개발자가 필요에 따라 선택적으로 사용할 수 있다는 특징이 있습니다.</li>
<li>프런트엔드 개발자인 저희에게 가장 익숙한 라이브러리에는 웹개발 라이브러리인 React와 상태관리 라이브러리인 Recoil과 Redux가 있습니다.</li>
</ul>
<br>

<h2 id="q2-혹시-redux와-recoil의-차이에-대해-설명가능하실까요">Q2. 혹시 Redux와 Recoil의 차이에 대해 설명가능하실까요?</h2>
<ul>
<li>Redux와 Recoil은 둘 다 상태 관리를 위한 라이브러리이지만, 사용 범위나 상태 업데이트 방식, 성능면에서 차이를 보입니다.</li>
<li>Redux의 경우, JavaScript 기반의 라이브러리(React, Angular, Vue)에서 모두 사용가능합니다. 반면 Recoil의 경우, Meta에서 React만을 위해 개발한 라이브러리여서 오로지 React에서만 작동가능합니다.</li>
<li>Redux는 Reducer를 활용한 일방적인 데이터 흐름으로 상태를 업로드 하지만, Recoil은 React의 useState와 유사하게 Atom이라는 상태 단위를 활용하여 상태를 업로드 합니다.</li>
<li>Recoil은 Redux보다 간단한 API를 제공하고 성능 최적화면에서도 React의 컴포넌트 라이프사이클과 잘 맞기에 우수합니다.</li>
</ul>
<br>

<h2 id="q3-react는-라이브러리일까요-아니면-프레임워크일까요">Q3. React는 라이브러리일까요, 아니면 프레임워크일까요?</h2>
<ul>
<li>React의 개념적으로 라이브러리가 맞습니다. 개발 초창기에 웹개발을 용이하게 하기 위해 개발된 웹개발 라이브러리 였으나, 다양한 상태관리 라이브러리를 함께 사용하고, 라우터를 활용한 라우팅이 가능해져서 컴포넌트간 보다 편리한 매핑이 가능해져 더이상 라이브러리가 아닌 프레임워크로 인식되는 경우가 있습니다.</li>
<li>즉, React는 <strong>프레임워크처럼 동작하는 라이브러리</strong>라고 정의할 수 있습니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[REST API란 무엇인가?]]></title>
            <link>https://velog.io/@dainel-q/REST-API%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@dainel-q/REST-API%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Sat, 27 May 2023 18:01:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
</blockquote>
<h1 id="목차">목차</h1>
<h2 id="1-주제-선정-이유">1. 주제 선정 이유</h2>
<h2 id="2-api란-무엇인가">2. API란 무엇인가?</h2>
<h2 id="3-rest-api란-무엇인가">3. REST API란 무엇인가?</h2>
<ul>
<li>REST의 개념</li>
<li>REST의 4가지 원칙</li>
<li>REST API의 개념</li>
<li>REST API를 사용하는 이유</li>
<li>HTTP API의 개념<h2 id="4-http-메서드-정리">4. HTTP 메서드 정리</h2>
</li>
<li>GET</li>
<li>POST</li>
<li>PUT</li>
<li>PATCH</li>
<li>DELETE<h2 id="5-http-메서드-속성">5. HTTP 메서드 속성</h2>
</li>
<li>안전</li>
<li>멱등</li>
<li>캐시가능<h2 id="6-요약-정리-및-면접형-qna">6. 요약 정리 및 면접형 QnA</h2>
</li>
</ul>
<h1 id="1-주제-선정-이유-1">1. 주제 선정 이유</h1>
<p>지난 IT용어 정리에서 API에 대한 설명을 했으나, 가장 중요한 REST API에 대한 설명을 간략하게 했다고 생각해서 해당 주제에 대해 자세히 설명하고자 선정했다. 프론트 엔드뿐만 아니라 IT업계에서 가장 많이 사용하는 API 방식이기에 이에 대한 정확한 개념은 반드시 숙지해야 할 것이다.</p>
<br>

<h1 id="2-api란-무엇인가--메뉴판">2. API란 무엇인가? === 메뉴판</h1>
<ul>
<li>Application Programming Interface의 앞자리를 조합하여 만든 용어로, <strong>응용 프로그램을 프로그래밍하기 위해 서로 데이터를 주고 받는 상호작용의 방법</strong>이라고 정의할 수 있다.</li>
<li>데이터를 요청하는 클라이언트(프론트엔드)에게 서버(백엔드)가 데이터를 제공해주며, 이러한 상호작용을 가능하게 해주는 것이 API이다.</li>
</ul>
<br>

<h1 id="3-rest-api란-무엇인가-1">3. REST API란 무엇인가?</h1>
<h2 id="3-1-rest의-개념">3-1. REST의 개념</h2>
<ul>
<li>REpresentational State Transfer의 약자로, 웹 서비스를 위한 아키텍처 스타일이다.</li>
<li>HTTP URI를 통해 자원을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미</li>
<li>HTTP 프로토콜에 따르는 모든 플렛폼에서 사용이 가능</li>
</ul>
<blockquote>
<h3 id="-crud란">* CRUD란</h3>
<p>Create(생성), Read(조회), Update(갱신), Delete(삭제)의 약자로, 대부분의 컴퓨터 소프트웨어가 가지는 기본적인 데이터 처리기능들을 묶어서 일컫는 말이다.
<br>
데이터 베이스에서의 기초적인 4가지 쿼리 형식
Create  - 생성 - INSERT
Read - 조회 - SELECT
Update - 갱신 - UPDATE
Delete - 삭제 - DELETE
<br>
클라이언트 &lt;-&gt; 서버간의 HTTP프로토콜을 이용한 REST API 용어
Create  - 생성 - POST
Read - 조회 - GET
Update - 갱신 - PUT, PATCH
Delete - 삭제 - DELETE</p>
</blockquote>
<br>

<h2 id="3-2-rest의-4가지-원칙">3-2. REST의 4가지 원칙</h2>
<ul>
<li>균일한 인터페이스 : URI로 지정한 Resource에 대한 조작을 통일되고 한정적인 인터페이스(HTTP 표준 프로토콜기준)로 수행</li>
<li>무상태 : 서버가 이전의 모든 요청들을 독립적으로 처리하여 응답하는 것을 의미</li>
<li>계층화 시스템 : REST Server가 다중계층으로 이루어 질 수 있다는 것을 의미(API Server, 보안, 로드벨런싱, 암호화, 사용자 인증)</li>
<li>캐시 가능성 : 보다 효율적인 요청 처리를 위해 캐시 사용을 하며, 이를 통해 REST Server의 트랜젝션이 발생하지 않아 전체 응답시간, 성능, 서버의 자원 이용률을 줄일 수 있음</li>
</ul>
<br>

<h2 id="3-3-rest-api의-개념">3-3. REST API의 개념</h2>
<ul>
<li>어원적으로 분석하면 &#39;대표적인 상태 전달자&#39;로 API 방식 중 가장 많이 그리고 표준적으로 사용되는 <strong>방법론</strong>이다.</li>
<li>아키텍처는 시스템을 구성하는 구성요소들의 조합과 그들 간의 상호작용 방식을 <strong>설계하는 것</strong>을 의미하며, REST API에서 언급하는 웹 서비스를 위한 아키텍처는 <strong>클라이언트-서버 아키텍처</strong>를 의미한다.</li>
<li>클라이언트-서버 아키텍츠는 클라이언트와 서버가 각자의 역할을 분배하여 시스템을 구성한다. 클라이언트는 사용자 인터페이스나 요청을 처리하고, 서버는 그에 필요한 데이터를 전달 및 처리를 하는 역할을 수행한다.</li>
<li>즉, REST API는 웹 서비스를 위한 클라이언트와 서버의 시스템(아키텍처)적 스타일이라 정리 할 수 있다.</li>
<li><strong>REST API는 HTTP 프로토콜을 기반으로 동작한다.</strong></li>
<li>RESTful == REST API를 사용한 웹 서비스</li>
</ul>
<br>

<h2 id="3-4-rest-api를-사용하는-이유">3-4. REST API를 사용하는 이유</h2>
<ul>
<li>자원(Resource) 중심적: 리소스(데이터)를 중심으로 API를 설계한다. 각 리소스는 고유한 식별자(URI)를 가지기 때문에 가독성이 좋아 수정이나 변경이 용이하다.</li>
<li>표준화된 인터페이스: REST API는 일반적으로 HTTP 메서드(GET, POST, PUT, DELETE)와 HTTP 상태 코드(200 OK, 404 Not Found 등)를 사용하여 일관된 인터페이스를 제공한다. 이는 개발자가 API를 이해하고 사용하기 쉽도록 도와준다.</li>
<li>사내 시스템들도 REST 기반으로 시스템을 분산해서 확장성과 재사용성을 높여 유지보수 및 운용을 편리하게 함</li>
<li>REST API 메시지가 의도하는 바를 명확하게 나타내므로 의도하는 바를 쉽게 파악</li>
<li>REST는 HTTP 표준을 기반으로 구현하기에, HTTP를 지원하는 프로그램 언어로 클라이언트, 서버를 구현할 수 있음(java,javascript)</li>
</ul>
<blockquote>
<h3 id="-http는-무엇인가">* HTTP는 무엇인가?</h3>
</blockquote>
<ul>
<li>HyperText Transfer Protocol의 약자로, 인터넷에서 웹페이지를 전송하기 위해 사용하는 프로토콜(규칙)을 의미한다. </li>
<li>HTTP는 클라이언트가 데이터를 &#39;요청&#39;하고 서버가 이에 &#39;응답&#39;하여 데이터를 주고받는 형태로 이루어져 있다.</li>
<li>REST API는 HTTP 프로토콜을 기반으로 동작하기에, 각종 HTTP 메서드를 활용하여 사용자에게 표준화된 인터페이스를 제공한다.</li>
</ul>
<br>

<h1 id="4-http-메서드-정리-1">4. HTTP 메서드 정리</h1>
<ul>
<li><strong>GET</strong> : 요청받은 URI의 정보를 검색하여 응답한다. 주로 사용자가 클릭하는 대부분의 버튼들이 GET 메서드를 사용한다고 생각해도 무방하다.
ex). GET /index.html HTTP/1.1</li>
<li><strong>POST</strong> : 요청된 자원을 생성(create)한다. 즉, 서버에 새로운 리소스를 생성하거나, 서버에 데이터를 제출하여 처리하고자 할 때 사용한다. 주로 게시물을 작성하거나, 주문 정보를 생성하거나, 새로운 파일을 업로드 하는 등, <strong>새로운 자원을 생성</strong>할 때 사용한다.
ex). POST / request-uri/ HTTP/1.1</li>
<li><strong>PUT</strong> : 요청된 자원 전체를 수정(update)한다. 기존의 URI에 내용을 수정하는 것이기에 새로운 URI를 생성하는 POST와는 차이를 두어야 한다. 주로 리소스를 업데이트할때 PUT 메서드를 사용한다고 이해하면 된다.
ex). PUT / request-uri/ HTTP/1.1</li>
<li><strong>PATCH</strong> : 요청된 자원을 수정(update)한다. 다만, 자원 전체를 수정하는 PUT메서드와는 달리, PATCH메서드의 경우 해당자원의 일부만을 교체한다는 차이점이 있다.
ex). PATCH / request-uri/ HTTP/1.1</li>
<li><strong>DELETE</strong> : 요청된 자원을 삭제할 것을 요청한다. 하지만 안정성의 문제로 대부분의 서버에서는 비활성화 되어있으며, 주로 PATCH를 통해 수정한다고 한다.
ex). DELETE / request-uri/ HTTP/1.1</li>
</ul>
<h2 id="4-1-post와-put의-차이는-무엇인가">4-1. POST와 PUT의 차이는 무엇인가?</h2>
<ul>
<li>POST 메서드는 INSERT이며 PUT 메서드는 UPDATE이다.</li>
<li>POST메서드의 경우, 멱등하지 않아 동일한 자원을 여러번 POST하면 서버자원에 변화가 생긴다.</li>
<li>PUT메서드의 경우, 멱등하여 동일한 자원을 여러번 PUT하면 서버자원이 변화하지 않고 동일한 리소스로 응답한다. </li>
<li>즉, POST메서드는 새로운 자원을 생성하기에 여러번 요청하면 서버 리소스에 변화가 생기지만, PUT의 경우, 생성이 아닌 수정을 하며, 여러번 요청해도 서버 리소스에 변화가 없다. </li>
</ul>
<h2 id="4-2-put과-patch의-차이는-무엇인가">4-2. PUT과 PATCH의 차이는 무엇인가?</h2>
<ul>
<li>PUT은 해당 자원의 전체를 교체하지만, PATCH는 일부만 변경한다.</li>
<li>PUT은 덮어쓰기, PATCH는 업데이트.</li>
</ul>
<br>

<h1 id="5-http-메서드-속성-1">5. HTTP 메서드 속성</h1>
<h2 id="1--안전safe-methods">1.  안전(Safe Methods)</h2>
<ul>
<li>호출을 해도 리소스가 변경하지 않는다.(GET만 계속 호출해도 안전, 나머지는 불안전)</li>
</ul>
<h2 id="2-멱등idempotent-methods">2. 멱등(Idempotent Methods)</h2>
<ul>
<li>몇번 호출해도 결과가 똑같은가? (POST만 멱등이 아니다, 호출 결과가 늘 새롭기 때문)</li>
<li>활용 -&gt; 자동 복구 메커니즘 (delete 같은 경우, 서버 이슈로 정상 응답을 주지 못했다면, 멱등하기 때문에 다시해도 괜찮음)</li>
<li>멱등은 외부요인으로 중간에 리소스가 변경되는 것까진 고려하지 않는다.</li>
</ul>
<h2 id="3-캐시가능cacheable-methods">3. 캐시가능(Cacheable Methods)</h2>
<ul>
<li>*캐시 : 기록</li>
<li>응답 결과 리소스를 캐시해서 사용해도 되는가?</li>
<li>스팩상 GET,HEAD,POST,PATCH는 캐시 가능 -&gt; 하지만 실제로는 GET,HEAD 정도만 캐시로 사용</li>
</ul>
<br>

<h1 id="6-요약-정리-및-면접형-qna-1">6. 요약 정리 및 면접형 QnA</h1>
<h2 id="6-1-q-rest-api가-무엇인가요">6-1. Q. REST API가 무엇인가요?</h2>
<ul>
<li>REST API는 HTTP 프로토콜을 기반으로 동작하는, 웹 서비스를 위한 클라이언트와 서버의 시스템(아키텍처)적 스타일입니다.</li>
<li>REST API가 각광받는 이유는 각 리소스는 고유한 식별자(URI)를 가지기 때문에 가독성이 좋아 수정이나 변경이 용이하고, 일관된 HTTP 프로토콜을 따르기에 개발자로 하여금 친숙하고 편리하기에 자주 사용됩니다.</li>
</ul>
<h2 id="6-2-q-post와-put의-차이는-무엇인가">6-2. Q. POST와 PUT의 차이는 무엇인가?</h2>
<ul>
<li>POST 메서드는 INSERT이며 PUT 메서드는 UPDATE입니다.</li>
<li>POST메서드의 경우, 멱등하지 않아 동일한 자원을 여러번 POST하면 서버자원에 변화가 생깁니다.</li>
<li>PUT메서드의 경우, 멱등하여 동일한 자원을 여러번 PUT하면 서버자원이 변화하지 않고 동일한 리소스로 응답합니다. </li>
<li>즉, POST메서드는 새로운 자원을 생성하기에 여러번 요청하면 서버 리소스에 변화가 생기지만, PUT의 경우, 생성이 아닌 수정을 하며, 여러번 요청해도 서버 리소스에 변화가 없습니다. </li>
</ul>
<h2 id="6-3-q-put과-patch의-차이는-무엇인가">6-3. Q. PUT과 PATCH의 차이는 무엇인가?</h2>
<ul>
<li>PUT은 해당 자원의 전체를 교체하지만, PATCH는 일부만 변경합니다.</li>
</ul>
<h2 id="6-4-q-멱등idempotent은-무엇인가">6-4. Q. 멱등(Idempotent)은 무엇인가?</h2>
<ul>
<li>동일한 작업을 여러 번 실행하더라도 결과가 동일하게 유지되는 성질을 의미합니다.</li>
<li>즉, 동일한 요청을 여러 번 실행하더라도 처음 요청과 같은 상태와 결과를 얻을 수 있다는 것을 의미합니다.</li>
<li>이는 요청의 반복 실행이나 중복 전송이 발생해도 시스템의 상태가 변하지 않는 것을 의미합니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[📋API란 무엇인가?]]></title>
            <link>https://velog.io/@dainel-q/API%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@dainel-q/API%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Sat, 20 May 2023 13:05:22 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h1 id="목차">목차</h1>
</blockquote>
<h2 id="1-주제-선정-이유">1. 주제 선정 이유</h2>
<h2 id="2-api">2. API</h2>
<ul>
<li>API의 개념</li>
<li>API의 기능</li>
<li>API의 형태</li>
<li>REST API</li>
<li>API의 종류<h2 id="3-요약-정리-및-면접형-qna">3. 요약 정리 및 면접형 QnA</h2>
<h2 id="번외-별도의-it용어">번외. 별도의 IT용어</h2>
</li>
</ul>
<h1 id="1-주제-선정-이유-1">1. 주제 선정 이유</h1>
<p>IT업계에서 API라는 용어를 상당히 많이 사용하는 것을 목격할 수 있다. 물론 이러한 문화에 친화적인 개발자라면 당연히 이해하고 넘어갔을 것이지만, 업계에 처음 진입한 사람에게는 너무나도 낯설은 용어라고 생각한다. 특히, 필자인 내가 그랬다. 그래서 이번 기회에 API에 대한 기초적인 개념을 쉬운 비유에 빗대어 설명하고자 한다.</p>
<br>

<h1 id="2-api-1">2. API</h1>
<h2 id="2-1-api의-개념">2-1. API의 개념</h2>
<ul>
<li>API는 Application Programming Interface의 앞자리를 조합하여 만든 용어이다.</li>
<li>Application은 기능이나 응용 프로그램을 의미하며, Interface는 상호작용을 의미한다.</li>
<li>즉, API는 <strong>응용 프로그램을 프로그래밍하기 위해 서로 데이터를 주고 받는 상호작용의 방법</strong>이라고 정의할 수 있다.</li>
</ul>
<br>

<h2 id="2-2-api의-기능">2-2. API의 기능</h2>
<ul>
<li>API를 실상의 예로 설명한다면, 식당의 메뉴가 적힌 <strong>메뉴판</strong>이라고 빗대어 표현할 수 있다.</li>
<li>여기서 메뉴는 API가 제공하는 데이터 형식의 정보라고 생각하면 된다.</li>
<li>식당에 들어온 손님은 메뉴판을 보고 주방장에게 메뉴를 요청하고, 주방장은 그 메뉴에 맞는 음식을 손님에게 제공한다.</li>
<li>데이터를 요청하는 클라이언트(프론트엔드)에게 서버(백엔드)가 데이터를 제공해주며, 이러한 상호작용을 가능하게 해주는 것이 API이다.</li>
</ul>
<br>

<h2 id="2-3-api의-형태">2-3. API의 형태</h2>
<ul>
<li>웹에서 사용하는 API를 &#39;웹 API&#39;라고 부르며, 모바일에서 사용하는 API를 &#39;모바일 API&#39;라고 부르며, 프론트엔드 개발자가 주로 접하는 API는 HTTP API이다.</li>
<li>HTTP는 HyperText Transfer Protocol의 약자로, 인터넷에서 웹페이지를 전송하기 위해 사용하는 프로토콜(규칙)을 의미한다. HTTP는 클라이언트와 서버 간에 데이터를 주고받는 방식을 정의하고 있으며, 웹 브라우저와 웹 서버 간의 통신에 주로 사용한다 ex).네이버 URL : <a href="https://www.naver.com/">https://www.naver.com/</a></li>
<li>API는 요청방식, 요청자료내용, 자료요청에 필요한 추가정보 순으로 구성되어있다.
ex). 클라이언트가 서버에 영화정보를 요청하는 HTTP API: GET /movies/123456789
서버가 갖고있는 영화정보: <pre><code class="language-js">HTTP/1.1 200 OK
Content-Type: application/json
</code></pre>
</li>
</ul>
<p>{
  &quot;id&quot;: 123456789,
  &quot;title&quot;: &quot;The Shawshank Redemption&quot;,
  &quot;year&quot;: 1994,
  &quot;director&quot;: &quot;Frank Darabont&quot;,
  &quot;genres&quot;: [&quot;Drama&quot;, &quot;Crime&quot;],
  &quot;rating&quot;: 9.3
}</p>
<p>```</p>
<ul>
<li>GET /movies/123456789 : 요청방식 / 요청자료내용 / 추가정보</li>
</ul>
<br>

<h2 id="2-4-rest-api">2-4. REST API</h2>
<ul>
<li>Representational State Transfer의 약자로, 웹 서비스를 위한 아키텍처 스타일, 일종의 <strong>방법론</strong>이라 이해하면 편하다.</li>
<li>REST API는 HTTP 프로토콜을 기반으로 동작하며, 클라이언트와 서버 간의 통신을 위해 HTTP 메서드(GET, POST, PUT, DELETE 등)를 사용한다.</li>
<li>REST API의 특징:</li>
</ul>
<ol>
<li>자원(Resource) 중심적: 리소스(데이터)를 중심으로 API를 설계한다. 각 리소스는 고유한 식별자(URI)를 가지기 때문에 가독성이 좋아 수정이나 변경이 용이하다.</li>
<li>상태를 전달(Stateless): 서버는 클라이언트의 상태를 관리하지 않는다. 요청은 필요한 모든 정보를 포함하고, 서버는 각 요청을 독립적으로 처리한다. 클라이언트의 세션 상태는 서버에 저장되지 않으며, 클라이언트는 필요한 경우 인증 토큰 등을 요청에 포함시켜 식별할 수 있다.</li>
<li>표준화된 인터페이스: REST API는 일반적으로 HTTP 메서드(GET, POST, PUT, DELETE)와 HTTP 상태 코드(200 OK, 404 Not Found 등)를 사용하여 일관된 인터페이스를 제공한다. 이는 개발자가 API를 이해하고 사용하기 쉽도록 도와준다.</li>
<li>계층 구조(Layered System): RESTful 서비스는 다중 계층으로 구성될 수 있다. 중간 서버, 로드 밸런서, 캐싱 서버 등을 통해 보안, 로드 분산, 성능 향상 등을 달성할 수 있다.</li>
</ol>
<ul>
<li>정리하면, <strong>REST API는 HTTP API기반으로 개발자들이 보다 쉽게 서버와 상호작용할 수 있도록 하는 표준화된 방법으로, 단순하고 가독성이 좋다는 장점이 있다.</strong></li>
</ul>
<p>REST API에 대한 자세한 설명자료영상 : <a href="https://www.youtube.com/watch?v=lsMQRaeKNDk">https://www.youtube.com/watch?v=lsMQRaeKNDk</a></p>
<br>

<h2 id="2-5-api의-종류">2-5. API의 종류</h2>
<ul>
<li>API의 종류에는 크게 3가지가 있다.</li>
</ul>
<ol>
<li>public API(open API) : 누구나 사용가능한 공개 API (ex. 기상청 : <a href="https://www.data.go.kr/data/15095109/openapi.do#tab_layer_detail_function">https://www.data.go.kr/data/15095109/openapi.do#tab_layer_detail_function</a>)</li>
<li>private API : 사내에서만 사용하는 API</li>
<li>partner API : 미리 정해준 사용자끼리 사용하는 API</li>
</ol>
<br>

<h1 id="3-요약-정리-및-면접형-qna-1">3. 요약 정리 및 면접형 QnA</h1>
<h3 id="qna--api는-무엇인가요">QnA : API는 무엇인가요?</h3>
<ul>
<li>API는 Application Programming Interface의 약자로, 응용 프로그램을 프로그래밍하기 위해 클라이언트와 서버가 서로 데이터를 주고 받는 상호작용의 방법입니다.</li>
</ul>
<br>

<h3 id="qna--혹시-rest-api가-무엇인지-알고-계신가요">QnA : 혹시 REST API가 무엇인지 알고 계신가요?</h3>
<ul>
<li>REST API는 Representational State Transfer의 약자로, HTTP API기반하여 개발자들이 보다 쉽게 서버와 상호작용할 수 있도록 하는 표준화된 API 스타일입니다. 특히 자원중심적인 스타일이기에, 각 리소스가 고유한 URI를 가져 가독성이 좋으며, 표준화된 HTTP 메서드를 사용하기에 단순하다는 장점이 있기 때문에, 현업에서 거의 REST 방식을 사용합니다.</li>
</ul>
<h2 id="reference">Reference:</h2>
<ul>
<li>코딩애플 유튜브:<a href="https://www.youtube.com/watch?v=ckSdPNKM2pY">https://www.youtube.com/watch?v=ckSdPNKM2pY</a></li>
<li>얄팍한 코딩사전 유튜브:<a href="https://www.youtube.com/watch?v=iOueE9AXDQQ">https://www.youtube.com/watch?v=iOueE9AXDQQ</a></li>
<li>노마드 코더 유튜브 : <a href="https://www.youtube.com/watch?v=iyFHfzCRHA8">https://www.youtube.com/watch?v=iyFHfzCRHA8</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[💰상속이란 무엇인가]]></title>
            <link>https://velog.io/@dainel-q/%EC%83%81%EC%86%8D%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@dainel-q/%EC%83%81%EC%86%8D%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Sat, 06 May 2023 08:22:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
</blockquote>
<h2 id="목차">목차</h2>
<h3 id="1-주제-선정-이유">1. 주제 선정 이유</h3>
<h3 id="2-상속">2. 상속</h3>
<ul>
<li>2-1. 상속의 정의 및 종류</li>
<li>2-2. 프로토타입과 상속의 관계</li>
<li>2-3. 클래스와 상속의 관계<h3 id="3-요약-정리-및-면접형-qna">3. 요약 정리 및 면접형 QnA</h3>
<h3 id="번외-별도의-it용어">번외. 별도의 IT용어</h3>
</li>
</ul>
<h1 id="1-주제-선정-이유-1">1. 주제 선정 이유</h1>
<p>코딩을 하다보면, 종종 상속이라는 용어를 많이 들어봤을 것이다. 물론, 상속의 사전적인 개념인 &#39;하위존재가 상위존재로부터 무언가를 물림받는다.&#39; 는 것 정도는 유추할 수 있을 것이다.
하지만, 코딩이나 IT업계에서 언급하는 상속에 대해 제대로 알고 넘어가는 것이 <strong>실제로 프로젝트에 적용할 때, 보다 수월하고 익숙하게 사용할 수 있을 것이기에 선정했다</strong>.</p>
<br>

<h1 id="2-상속-1">2. 상속</h1>
<h2 id="2-1-상속의-정의-및-종류">2-1. 상속의 정의 및 종류</h2>
<ul>
<li>자바스크립트에서 사용되는 상속은 <strong>프로토타입 상속</strong>과 <strong>클래스 상속</strong> 크게 두 가지로 나뉜다.</li>
<li>프로토타입 상속 : 상속을 받든 객체가 상속을 해주는 객체의 프로퍼티나 메서드를 <strong>추가로</strong> 사용할 수 있게 해주는 체계를 의미한다.</li>
<li>클래스 상속 : 기존의 클래스를 확장시키는 개념으로 이해하면 좋다. 상속받은 기존의 클래스를 토대로 새로운 기능을 <strong>추가하는</strong> 시스템을 의미한다.</li>
</ul>
<br>

<h2 id="2-2-프로토타입과-상속의-관계">2-2. 프로토타입과 상속의 관계</h2>
<ul>
<li>프로토타입 (객체) : 다른 객체에 대한 참조 하는 대상을 의미한다. 모든 객체는 [[prototype]]이라는 내부 프로퍼티를 갖는다.</li>
<li>[[prototype]]를 저장창고라고 이해면 좋다.
예를 들어, 아래의 경우, 전부 객체로 이루어져있기에 객체의 프로토타입은, [[prototype]] : Object 즉, Object.prototype이다.그리고 상속받는 객체들이 [[prototype]]안으로 들어간다.</li>
<li><code>__proto__</code> : 객체가 자신의 프로토타입에 접근하도록 해주는 접근자 프로퍼티이다. 일종의 <strong>다리(bridge)</strong>라고 이해하면 좋을 듯하다. 
해당 프로퍼티를 사용하여 상속받을 객체가 자신의 프로토타입에 들어갈 수 있도록 연결해준다.</li>
<li>즉, <code>__proto__</code> 를 사용하여 <strong>상위(부모) 객체가 하위(자식) 객체의 프로토타입에 추가되는 과정</strong>을 <strong>상속</strong>이라고 한다.
<img src="https://velog.velcdn.com/images/dainel-q/post/0ba7368c-6a60-4f68-8da4-be69a0422c37/image.png" alt=""></li>
</ul>
<h2 id="q-그런데-왜-프로토타입-상속을-하는-것인가요">Q. 그런데 왜 프로토타입 상속을 하는 것인가요??</h2>
<ul>
<li>우선은 한 사례를 통해 살펴보자
<img src="https://velog.velcdn.com/images/dainel-q/post/7f14b541-0997-4b62-b31f-86a9e4328d7c/image.png" alt=""></li>
<li>위 예시의 경우, food를 상속받은 pasta 객체가 cook이라는 메서드를 자유롭게 사용할 수 있는 사례이다.
즉, pasta 객체에서 cook메서드를 더 만들지 않고 상속받아 편하게 사용할 수 있다는 것을 의미한다.
이는 곧, <strong>코드의 재사용성을 높이고</strong> , <strong>관리를 용이하게 해준다</strong>는 장점을 갖고 있다.</li>
</ul>
<br>

<h2 id="2-3-클래스와-상속의-관계">2-3. 클래스와 상속의 관계</h2>
<ul>
<li><p>클래스(class) : 하나의 생성자 함수를 여러개 찍어낼 수 있게 해주는 문법으로 흔히 붕어빵 틀에 비유한다.</p>
</li>
<li><p>먼저 상속을 할 부모 클래스를 생성한다.</p>
<pre><code class="language-js">class Food {
  constructor (name) {
      this.name = name;
      this.won = 0;
  }

  price(won) {
      this.won = won;
      console.log(`${this.name}의 가격은 ${this.won}원 입니다.`)
  }

  pay(){
      console.log(`${this.won}원을 지불하셨습니다.`)
  }
}
</code></pre>
</li>
</ul>
<p>const food = new Food(&quot;음식&quot;);</p>
<pre><code>
- extends : 이를 상속받을 자식 클래스를 생성할 때, 자식 클래스명 옆에 작성한다.
```js
class Pasta extends Food {
    tasty(){
        console.log(`${this.name} 맛있네요!`)
    }
}

const pasta = new Pasta(&quot;아라비따 파스타&quot;);</code></pre><ul>
<li><p>위 예시를 합치면</p>
<pre><code class="language-js">class Food {
  constructor (name) {
      this.name = name;
      this.won = 0;
  }

  price(won) {
      this.won = won;
      console.log(`${this.name}의 가격은 ${this.won}원 입니다.`)
  }

  pay(){
      console.log(`${this.won}원을 지불하셨습니다.`)
  }
}
</code></pre>
</li>
</ul>
<p>const food = new Food(&quot;음식&quot;);</p>
<p>class Pasta extends Food {
    tasty(){
        console.log(<code>${this.name} 맛있네요!</code>)
    }
}</p>
<p>const pasta = new Pasta(&quot;아라비따 파스타&quot;);</p>
<pre><code>- pasta클래스는 food 클래스를 상속받고 있다는 것을 의미한다. 그렇기에 food클래스의 메서드를 사용할 수 있다.
```js
pasta.price(12000; // 아라비따 파스타의 가격은 12000원 입니다.
pasta.pay(12000);  // 12000원을 지불하셨습니다.
pasta.tasty();  // 아라비따 파스타 맛있네요!</code></pre><h2 id="q-그런데-왜-클래스-상속을-하는-것인가요">Q. 그런데 왜 클래스 상속을 하는 것인가요??</h2>
<ul>
<li>프로토타입의 상속을 하는 이유와 유사하게, 상속을 주고 받기에, 작성해야할 코드의 양이 줄어든다. 특히, 클래스의 경우, 생성자 메서드등 작성해야할 내용이 많기에, 상속의 장점이 더욱 부각된다.</li>
<li><strong>코드의 재사용성을 높이고</strong> , <strong>관리를 용이하게 해준다</strong>는 장점이 있기 때문에 사용한다.</li>
</ul>
<br>

<h1 id="3-요약-정리-및-면접형-qna-1">3. 요약 정리 및 면접형 QnA</h1>
<h2 id="qna--자바스크립트에서-사용하는-상속은-무엇이고-그-기능이-무엇인가요">QnA : 자바스크립트에서 사용하는 상속은 무엇이고, 그 기능이 무엇인가요??</h2>
<ul>
<li>상속은 상속받는 자식요소가 상속해주는 부모요소의 프로퍼티나 메서드를 <strong>추가로</strong> 사용할 수 있도록 <strong>확장</strong>해주는 기능입니다.</li>
<li>자바스크립트의 경우, <strong>프로토타입 상속</strong>, <strong>클래스 상속</strong>, 이렇게 두 가지 유형의 상속이 있습니다.</li>
<li>프로토타입의 상속은, 객체 안의 [[prototype]]라는 내부 프로퍼티안에 <code>__proto__</code>라는 접근자 프로퍼티로 객체들을 상속받아 저장하여 사용합니다.</li>
<li>클래스 상속은, 부모 클래스를 extends라는 키워드를 사용하여 자식 클래스가 상속받아 사용합니다. </li>
<li>상속을 사용하는 이유는 코드의 재사용성을 높이고, 유지보수가 필요한 경우, 특정 부분만 수정해도 되기에 관리를 용이하다는 장점이 있기 때문입니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Diary-Project Self Cord Review]]></title>
            <link>https://velog.io/@dainel-q/Diary-Project-Self-Cord-Review</link>
            <guid>https://velog.io/@dainel-q/Diary-Project-Self-Cord-Review</guid>
            <pubDate>Thu, 04 May 2023 08:57:07 GMT</pubDate>
            <description><![CDATA[<blockquote>
</blockquote>
<h2 id="목차">목차</h2>
<h3 id="1-프로젝트의-목표">1. 프로젝트의 목표</h3>
<h3 id="2-프로젝트-1차-완성-및-코드-리뷰">2. 프로젝트 1차 완성 및 코드 리뷰</h3>
<pre><code>2-1). 프로젝트 분석
2-2). 난감하거나 어려웠던 부분
2-3). 2차 작업시 개선하거나 추가했으면 하는 부분</code></pre><h1 id="1-프로젝트의-목표-1">1. 프로젝트의 목표</h1>
<ol>
<li>수업에서 실습한 일일 기록 형식의 토이프로젝트를 <strong>재구현</strong>하는 것을 목표</li>
<li>재구현 이후, <strong>별도의 추가기능들을 추가</strong>하여 다이어리가 아닌 다른 용도로 사용할 수 있도록 <strong>커스터마이징</strong> 진행할 것을 목표</li>
</ol>
<br>

<h1 id="2-프로젝트-1차-완성-및-코드-리뷰-1">2. 프로젝트 1차 완성 및 코드 리뷰</h1>
<h2 id="2-1-1차-프로젝트-분석">2-1). 1차 프로젝트 분석</h2>
<h3 id="1-공용-css">1). 공용 CSS</h3>
<ol>
<li>프로젝트는 한개의 공용 CSS파일과 3쌍의 HTML/CSS 파일로 구성되어 있다.</li>
<li>프로젝트를 시작함에 있어, 구현할 3개의 페이지의 reset.css나 전체적인 layout, 그리고 header영역의 반응형을 공용 CSS로 구현했다.</li>
<li>공용CSS에서 header영역의 자식요소들을 top-wrap으로 감싸 max-width로 반응형을 구현했다.
<img src="https://velog.velcdn.com/images/dainel-q/post/d0bf5d2e-59f6-42f7-a79f-c713cba46cd6/image.png" alt="">
<img src="https://velog.velcdn.com/images/dainel-q/post/8e51bc9c-f8fa-4a0e-a28a-af3eac1d12a0/image.png" alt=""></li>
</ol>
<br>

<h3 id="2-로그인-및-회원가입-페이지">2). 로그인 및 회원가입 페이지</h3>
<ol>
<li>로그인 페이지와 회원가입 페이지는 폼 태그를 이용한다는 점에서 상당히 유사하여 HTML은 거의 일치하게 작성했다.</li>
<li>폼태그 안의 자식요소들은 flex를 활용하여 구성했다.</li>
<li>가운데 로고 하단의 글자의 shadow는 box-shadow로 구성했다. 글자의 반만 하이라이트 처리할 때 종종 사용하기에 익혀두는 것을 권장한다.</li>
</ol>
<ul>
<li>box-shadow : inset /<em>그림자를 밖으로 내보냄</em>/ 0 /<em>그림자 위치</em>/  0 /<em>흐림 정도</em>/ -0.6 /<em>그림자의 확산 정도(크기)</em>/
<img src="https://velog.velcdn.com/images/dainel-q/post/59640f85-ae32-4c2e-a411-ebefdf38387b/image.png" alt="">
<img src="https://velog.velcdn.com/images/dainel-q/post/42f5b736-2757-4ace-b87b-26a6a44cf094/image.png" alt=""></li>
</ul>
<br>

<h3 id="3-메인-페이지">3). 메인 페이지</h3>
<ol>
<li><p>다른 페이지와 달리 상단의 우측에 가입자 이름과 로그아웃 버튼이 함께 붙어있어, 이를 <strong>float : right</strong>로 처리했다.
float의 경우, 반응형 처리를 할 때, 별도의 작업없이 부드럽게 하단으로 이동한다는 장점이 있어서, 반응형 작업시 종종 사용하길 권장한다.</p>
</li>
<li><p>수업에서는 메인 페이지 가운데에 그려진 선을 form태그의 <strong>border-right</strong>로 처리했으나, 필자는 임의의 div태그로 처리했다. 
회고를 해보니, 전자의 경우가 코드 사용량도 적어 훨씬 효율적일 것이라 생각된다.
아마도, 메인 태그를 flex 및 justify-contents: space-between을 사용하려 그랬던것 같은데, 따로 div태그 없이도 충분히 구현 가능하다.
<img src="https://velog.velcdn.com/images/dainel-q/post/6ddde8de-1d15-437a-a21e-52841952080e/image.png" alt=""></p>
</li>
<li><p>폼태그의 width 값은 이를 감싼 wrapper에 flex-basis 값을  부여하여 틀을 잡았다. 
그 외의 자식요소들에는 width : 100%를 부여했으며, 없으면 안된다.
이와 함께, flex-shrink : 0을 사용하여 크기가 변하지 않게 고정했다.
<img src="https://velog.velcdn.com/images/dainel-q/post/8cbe4a4d-a089-4d33-a067-ec72682e5aa2/image.png" alt=""></p>
</li>
<li><p>아티클의 쉼표는 가상요소를 만들고, background 속성으로 처리했다.
여기서 핵심은 <strong>백그라운드의 배경색을 초반에 작성하면 url속성값과 함께 사용할 수 있다.</strong> 다만, url이미지의 배경색이 없어야 하며, 이미지가 들어갈 가상요소의 배경색과 같아야한다.
위치는 position : absolute를 사용하여 지정해줬다.
<img src="https://velog.velcdn.com/images/dainel-q/post/d090896e-9d47-4da6-a73e-b4219fc91ea3/image.png" alt=""></p>
</li>
<li><p>아티클의 테두리의 두 줄 처리는 각각 아티클 자체의 border와 아티클의 가상요소의 border를 함께 사용하여 구현했다.</p>
</li>
</ol>
<ul>
<li>border-width : border의 두께 값을 나타냄
<img src="https://velog.velcdn.com/images/dainel-q/post/a5899592-0260-4dba-b11c-42331230d0ad/image.png" alt=""></li>
</ul>
<br>

<ol start="6">
<li>반응형 작업</li>
</ol>
<ul>
<li>max-width: 1024px를 기준으로 메인 태그는 max-width: calc(100% - 60px); 으로 양 옆에 30px씩 여유를 갖도록 작성했다.</li>
<li>가운데 줄은 숨김처리로 깔끔하게 정리했다.</li>
<li>아티클 태그는 flex-direction: column;으로 방향을 바꿨다.
<img src="https://velog.velcdn.com/images/dainel-q/post/3878a101-076a-4ae9-a3e2-68bd9284292a/image.png" alt=""></li>
</ul>
<h2 id="2-2-난감하거나-어려웠던-부분">2-2). 난감하거나 어려웠던 부분</h2>
<h3 id="1-메인-태그-가운데의-직선">1. 메인 태그 가운데의 직선</h3>
<ul>
<li>당연히 빈 div 태그를 사용하려 했으나, 코드 자체도 복잡하지고, 반응형과 같은 사후 작업시에 불편을 주기에 수업에서 사용한 border-right를 사용하여 해결 할 것을 적극 권장한다.</li>
</ul>
<br>

<h3 id="2-메인-태그의-양식부분의-width값-지정">2. 메인 태그의 양식부분의 width값 지정</h3>
<ul>
<li>form태그의 자식요소에 특정한 width값을 주기 싫었으나, 주지 않으면 모양이 틀어져서 원본가 전혀 다른 형태가 되었다. </li>
<li>또한 추후에 반응형을 넣어야 했기에 보다 유동적인 width 값을 부여해야 하는 것이 난감했다.</li>
<li>수업에서 이를 해결하기 위해, form태그에 flex-basis과 flex-shrink : 0을 함께 이용했다.
이는 form태그의 모양도 잡아주고, 자식요소에 width:100%을 부여하여 보다 유동적인 형태로 만들어줘서 유용하다.</li>
</ul>
<br>

<h2 id="2-3-2차-작업시-개선하거나-추가했으면-하는-부분">2-3). 2차 작업시 개선하거나 추가했으면 하는 부분</h2>
<h3 id="1-main-페이지--form태그의-날짜를-현재-날짜로-반영하기">1. Main 페이지 : form태그의 날짜를 현재 날짜로 반영하기</h3>
<ul>
<li>Problom: 현재 기록된 날짜는 임의로 지정한 날짜이기에 정적인 것이 문제라고 생각한다.</li>
<li>Solution: 이를 개선하기 위해서는 자바스크립트의 <code>new Date()</code>생성자 함수를 적용할 계획이다.</li>
</ul>
<h3 id="2-main-페이지--localstorage를-활용한-실시간-컨텐츠-반영">2. Main 페이지 : localStorage를 활용한 실시간 컨텐츠 반영</h3>
<ul>
<li>Problom: 현재 기록된 내용은 임의로 작성된 내용이라 정적인 것이 문제라고 생각한다.</li>
<li>Solution: 이를 개선하기 위해서는 JQuary의 localStorage를 활용할 계획이다.</li>
</ul>
<h3 id="3-login-join-페이지--반응형-구현">3. login, join 페이지 : 반응형 구현</h3>
<ul>
<li>Problom: 현재 header태그만 반응형이 구현된 상태인 것이 문제다.</li>
<li>Solution: 남은 부분도 반응형 처리하면 된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[💽객체란 무엇인가?]]></title>
            <link>https://velog.io/@dainel-q/%EA%B0%9D%EC%B2%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@dainel-q/%EA%B0%9D%EC%B2%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Tue, 02 May 2023 13:58:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
</blockquote>
<h2 id="목차">목차</h2>
<ol>
<li>주제 선정 이유<br></li>
<li>객체란 무엇인가?
 2-1). 객체의 정의 및 구조
 2-2). 참조의 정의<br></li>
<li>객체 지향 프로그래밍
 3-1). 객체 지향 프로그래밍 언어의 특징
 3-2). 객체 지향 프로그래밍 언어의 장점<br>
번외). 함께 알아두면 좋은 용어


</li>
</ol>
<br>

<h1 id="1-주제-선정-이유">1. 주제 선정 이유:</h1>
<p>자바스크립트가 객체 지향 언어라는 것은 다들 알고 있을 것이다. 그럼 여기서 말하는 객체란 과연 무엇인가? 
우리가 알고 있는 객체는 키와 값으로 이루어진 중괄호 라고 알고있는데, 이에 대해 자세히 파악하여 <strong>수업을 하거나 협업을 할 때, 보다 더 원활하게 소통할 수 있도록 돕고자</strong> 조사해봤다.</p>
<br>

<h1 id="2-객체">2. 객체</h1>
<h2 id="2-1-객체의-정의-및-구조">2-1). 객체의 정의 및 구조</h2>
<ul>
<li><p>객체 : 프로그래밍 언어에서 데이터나 함수를 담아내는 참조 자료형으로, 프로퍼티와 메서드로 이루어져 있다.</p>
</li>
<li><p>프로퍼티 : 객체의 상태 데이터를 나타내는 값으로, 키(key)와 값(value)로 이루어져 있다. 프로퍼티와 유사한 용어로, 속성(attribute)이 있다.</p>
</li>
<li><p>메서드 : 프로퍼티 중, 값이 함수인 경우, 다른 함수와 구분하기 위해 해당 프로퍼티를 메서드라고 부른다.</p>
</li>
</ul>
<h2 id="2-2-참조의-정의-및-예시">2-2). 참조의 정의 및 예시</h2>
<p>참조 : 값이 담긴 메모리 주소를 가져온다는 것을 의미, 결국 객체는 식별자(변수)에게 값이 아닌 메모리 주소만 알려주기에 참조 자료형 이라고 한다.
※객체의 주소를 비교하면 다르지만, 객체의 속성(프로퍼티)에 접근하여 값을 비교하면 같다!</p>
<pre><code class="language-js">// 예시 1. 객체의 주소 비교와 속성 값 비교
let person1 = { age: 27,
          name : Daniel};

let person2 = { age: 27,
          name : Daniel};


person1 === person2 // 객체 person1과 person2의 주소는 다르기에 false

person1.age === person2.age // 객체 person1과 person2의 age는 27로 같기에 true</code></pre>
<br>

<h1 id="3-객체-지향-프로그래밍">3. 객체 지향 프로그래밍</h1>
<ul>
<li><p>객체 지향 프로그래밍 : 데이터나 함수를 하나의 객체 단위로 묶은 독립된 객체간의 상호작용을 하는 프로그래밍 방식 </p>
</li>
<li><p>객체 지향 프로그램 언어 : C++, Java, JavaScript...</p>
</li>
</ul>
<h2 id="q-도대체-왜-객체-지향-프로그래밍-언어를-사용하는-것인가">Q. 도대체 왜 객체 지향 프로그래밍 언어를 사용하는 것인가?</h2>
<br>

<h2 id="3-1-객체-지향-프로그래밍-언어의-특징">3-1). 객체 지향 프로그래밍 언어의 특징</h2>
<h3 id="1-상속">1). 상속</h3>
<ul>
<li>어떤 객체의 프로퍼티나 메서드를 다른 객체가 그대로 사용할 수 있게 해주는 것</li>
<li>상속을 통해 <strong>코드의 재사용성이 높아지며</strong>, 클래스 간의 계층구조를 만들어 <strong>관리하기 쉬워짐</strong><h3 id="2-캡슐화">2). 캡슐화</h3>
</li>
<li>중괄호 라는 범위 안에, 객체의 키와 값을 짝지어서 타인이 함부로 객체의 값을 수정하거나 삭제하는 것을 방지한다.<h3 id="3-다형화">3). 다형화</h3>
</li>
<li>여러 객체가 하나의 메서드를 호출해도, 실행 결과가 객체마다 다르게 나타나는 특징이 있다.</li>
<li>하나의 메서드를 메서드 오버라이딩을 통해 다양한 결과를 만들 수 있어, 코드의 재사용률을 높인다.</li>
</ul>
<br>

<p>※ 메서드 오버라이딩 : 상속 관계에서 부모 클래스의 메소드를 자식 클래스에서 <strong>재정의</strong>하여 사용하는 것</p>
<pre><code class="language-js">class Animal {  // 부모 클래스
  constructor(name) {
    this.name = name;
  }

  speak() {  // 처음 선언한 메서드
    console.log(`${this.name} makes a noise.`);
  }
}

class Dog extends Animal {  // 자식 클래스
  speak() {  // 같은 명의 클래스를 재정의 -&gt; 다형화
    console.log(`${this.name} barks.`);
  }
}

class Cat extends Animal {
  speak() { // 같은 명의 클래스를 재정의 -&gt; 다형화
    console.log(`${this.name} meows.`);
  }
}

const animals = [new Dog(&#39;Rufus&#39;), new Cat(&#39;Mittens&#39;)];

animals.forEach(animal =&gt; {
  animal.speak();
});</code></pre>
<h3 id="4-추상화">4). 추상화</h3>
<ul>
<li>객체의 핵심적인 특징을 강조하고, 불필요한 부분을 생략하는 것</li>
<li>객체를 단순화시키고, 객체가 내부적으로 어떻게 구현되었는지 숨기기 때문에 코드의 가독성과 안정성이 향상</li>
</ul>
<br>

<h2 id="3-2-객체-지향-프로그래밍-언어의-장점">3-2). 객체 지향 프로그래밍 언어의 장점</h2>
<h3 id="1-재사용성">1). 재사용성</h3>
<ul>
<li>객체간에 계층이 부여되면 상속을 할 수 있고, 그 과정에서 공통된 코드는 다시 작성할 필요가 없어 <strong>구동 시간이나 로딩 시간이 상당히 절약됨</strong></li>
</ul>
<h3 id="2-가독성">2). 가독성</h3>
<ul>
<li>객체지향 프로그래밍에서는 객체의 속성과 메서드를 <strong>명확하게 정의</strong>하고, 객체 간의 상호작용을 <strong>명확하게 표현 가능</strong></li>
<li>이를 통해 코드의 가독성이 높아지며, 코드의 이해 및 유지보수가 용이해짐</li>
</ul>
<h3 id="3-유지보수성">3). 유지보수성</h3>
<ul>
<li>객체지향 프로그래밍에서는 코드를 <strong>객체 단위로 모듈화</strong>하여 작성하기 때문에, <strong>수정이나 추가를 할 때 해당 객체만 수정</strong>하면 되기에 관리에 용이</li>
</ul>
<br>

<p>※ 모듈화 : 코드를 하나의 파일에 작성하는 것이 아니라, <strong>나누어</strong> 마치 조립하듯이 구조화시키는 것을 의미</p>
<ul>
<li>자바스크립트의 경우, ES6(ES2015)의 모듈 방식을 주로 사용하는데, 이는 import와 export를 사용하는 방식이며, 이를 위해 <strong>babel</strong>과 같은 도구를 사용하여 코드를 컴파일해야 함</li>
</ul>
<pre><code class="language-js">// myModule.js // 보내는 모듈
export const foo = function() {
  console.log(&quot;Hello, World!&quot;);
};
export const bar = function() {
  console.log(&quot;Bye, World!&quot;);
};

// app.js  // 받는 모듈
import { foo, bar } from &#39;./myModule&#39;;
foo(); // &quot;Hello, World!&quot; 출력
bar(); // &quot;Bye, World!&quot; 출력</code></pre>
<br>

<h1 id="번외-함께-알아두면-좋은-용어">번외). 함께 알아두면 좋은 용어</h1>
<h3 id="1-babel">1. Babel</h3>
<ul>
<li>자바스크립트 코드를 컴파일러로 변환해주는 오픈소스 도구</li>
<li>주로 최신 버전의 자바스크립트 코드를 예전 버전으로 변환하여, 구형 브라우저에서도 실행 가능한 코드로 변환하는데 사용</li>
</ul>
<h3 id="2-컴파일러compiler">2. 컴파일러(Compiler)</h3>
<ul>
<li>프로그래밍 언어로 작성된 소스 코드를 기계어로 변환해주는 소프트웨어</li>
<li>자바스크립트의 경우, 인터프리터 언어라서 별도의 컴파일러가 필요</li>
</ul>
<h3 id="3-인터프리터-언어">3. 인터프리터 언어</h3>
<ul>
<li>프로그램의 소스 코드를 직접 실행하는 언어로, 컴파일러와는 달리 컴파일 과정 없이 소스 코드를 바로 실행</li>
<li>대표적인 인터프리터 언어 : JavaScript, Ruby, PHP...</li>
<li>코드를 한 줄 한 줄씩 읽어 들이며 실행하기에 명령 자체의 속도는 컴파일러 언어에 비해 느리다는 단점이 있음</li>
<li>오류 발견 즉시 해결할 수 있다는 장점이 있음</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 레벨 0 Day 16]]></title>
            <link>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A8-0-Day-16</link>
            <guid>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A0%88%EB%B2%A8-0-Day-16</guid>
            <pubDate>Thu, 27 Apr 2023 08:59:59 GMT</pubDate>
            <description><![CDATA[<h1 id="1-day-16-1-편지">1. Day 16-1. 편지</h1>
<blockquote>
<p>Q. 할머니가 보시기 편하도록 글자 한 자 한 자를 가로 2cm 크기로 적으려고 하며, 편지를 가로로만 적을 때, 축하 문구 message를 적기 위해 필요한 편지지의 최소 가로길이를 return 하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h2 id="1-1-내-풀이">1-1. 내 풀이</h2>
<blockquote>
</blockquote>
<pre><code>function solution(message) {
    return message.split(&quot;&quot;).length*2;
}</code></pre><h2 id="1-2-해설">1-2. 해설</h2>
<ul>
<li>문제에서 주어진 파라미터의 값은 문자열이기에 split(&quot;&quot;)으로 문자 1개씩으로 이루어진 배열을 만든다.</li>
<li>새로 생성된 배열의 길이는 곧 문자의 개수와 같고, 글자의 크기가 2cm이므로 배열의 길이에 2를 곱하여 반환한다.</li>
</ul>
<br>


<h1 id="2-day-16-2-가장-큰-수-찾기">2. Day 16-2. 가장 큰 수 찾기</h1>
<blockquote>
<p> Q. 정수 배열 array가 매개변수로 주어질 때, 가장 큰 수와 그 수의 인덱스를 담은 배열을 return 하도록 solution 함수를 완성해보세요.</p>
</blockquote>
<h2 id="2-1-내-풀이">2-1. 내 풀이</h2>
<blockquote>
</blockquote>
<pre><code>function solution(array) {
    return [Math.max(...array), array.indexOf(Math.max(...array))];
}</code></pre><h2 id="2-2-해설">2-2. 해설</h2>
<ul>
<li>파라미터의 배열 안의 요소 중, 가장 큰 수를 찾기 위해 해당 배열을 <strong>전개구문과 Math.max()</strong>를 사용한다.</li>
<li>정답 배열의 두번째 요소에는 가장 큰 수의 인덱스가 와야하기에, <strong>indexOf()메서드</strong>로 인덱스를 찾는다.</li>
</ul>
<br>

<h1 id="3-day-16-3-문자열-계산하기">3. Day 16-3. 문자열 계산하기</h1>
<blockquote>
<p> Q. my_string은 &quot;3 + 5&quot;처럼 문자열로 된 수식입니다. 문자열 my_string이 매개변수로 주어질 때, 수식을 계산한 값을 return 하는 solution 함수를 완성해주세요.</p>
</blockquote>
<h2 id="3-1-내-풀이">3-1. 내 풀이</h2>
<blockquote>
</blockquote>
<pre><code>function solution(my_string) {
    my_string = my_string.split(&quot; &quot;)
    let answer = parseInt(my_string[0]);
    for (let i = 0; i &lt; my_string.length; i++){
        if (my_string[i] === &quot;+&quot;) {
            answer += parseInt(my_string[i+1]);
        } else if (my_string[i] === &quot;-&quot;){
            answer -= parseInt(my_string[i+1]);
        }
    }
    return  answer;
}</code></pre><h2 id="3-2-해설">3-2. 해설</h2>
<ul>
<li>파라미터의 식이 한 칸씩 띄어져 있는 다항식이므로, split(&quot; &quot;) 즉, 공백을 기준으로 나뉘어진 배열을 만든다.</li>
<li>반복문을 사용하기 전에, 정답 변수에 배열의 첫번째 요소를 <strong>사전에</strong> 넣는다.</li>
<li>연산자(+,-)를 찾는 반복문을 작성한다. 만약 요소가 &quot;+&quot;인 경우, 그 다음 요소를 정답 변수에 더하고, 반대의 경우, 그 다음 요소를 뺀다.</li>
</ul>
<br>

<h1 id="4-배열의-유사도">4. 배열의 유사도</h1>
<blockquote>
<p>Q. 두 배열이 얼마나 유사한지 확인해보려고 합니다. 문자열 배열 s1과 s2가 주어질 때 같은 원소의 개수를 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h2 id="4-1-내-풀이">4-1. 내 풀이</h2>
<blockquote>
</blockquote>
<pre><code>function solution(s1, s2) {
    return s1.filter((el) =&gt; s2.includes(el)).length;
}</code></pre><h2 id="4-2-해설">4-2. 해설</h2>
<ul>
<li>파라미터 중 한 개를 기준으로 삼아 <strong>filter와 includes</strong>를 사용하여 같은 요소가 있는지 확인한다.  </li>
<li>이후, 길이로 반환한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[멋사 4-11 TIL (DOM)]]></title>
            <link>https://velog.io/@dainel-q/%EB%A9%8B%EC%82%AC-4-11-TIL-JavaScript</link>
            <guid>https://velog.io/@dainel-q/%EB%A9%8B%EC%82%AC-4-11-TIL-JavaScript</guid>
            <pubDate>Tue, 11 Apr 2023 15:30:57 GMT</pubDate>
            <description><![CDATA[<h1 id="1-요소-제어">1. 요소 제어</h1>
<h2 id="1-1-parentelementinsertbeforetarget-location--위치-이동">1-1. parentElement.insertBefore(target, location); : 위치 이동</h2>
<ul>
<li>target요소를 parentElement의 자식인 location 위치 앞으로 이동 -&gt; 단, after은 없다</li>
</ul>
<br>

<h1 id="2-innerhtmlinnertexttextcontent">2. innerHTML/innerText/textContent</h1>
<ul>
<li>JavaScript문자열로 element, text 노드를 생성하거나 추가하는 방법</li>
</ul>
<blockquote>
</blockquote>
<ul>
<li>innerHTML는 텍스트안에 html요소가 있으면 마크업 요소로 가져온다.</li>
<li>textContnet가 innerText, innerHTML 보다 처리되는 속도가 더 최적화 되어 있다.(마크업 요소를 전혀 고려하지 않기때문)</li>
<li>innerText은 HTML은 인식하진 못한다. -&gt; 그래도 문법적인 부분을 읽어서 출력.(텍스트의 &#39;형태&#39;(텍스트 줄바꿈...)는 인식하지만, 정보(색상, 굵기)는 인식하지 못한다는 의미) -&gt;  브라우저에서는 HTML요소를 해석해주지 않는다.</li>
<li>innerText 속성은 요소의 렌더링된 텍스트 콘텐츠를 나타냅니다. (렌더링된에 주목하세요. innerText는 텍스트 내에 문법적으로 처리가 가능한 텍스트가 있으면 &quot;처리가 끝난 결과물&quot;을 텍스트로 전달합니다.)</li>
</ul>
<h1 id="3-속성-제어하기">3. 속성 제어하기</h1>
<h2 id="3-1-style-객체">3-1. style 객체</h2>
<ul>
<li>요소의 스타일을 제어 : <code>target.style.property = &quot;속성값&quot;</code> 으로 제어, 하지만 이는 인라인 스타일을 수정하는 것이기에 가중치 점수가 높다. 이로인해 추후에 스타일을 변경이 어려울 수 있음</li>
<li><blockquote>
<p>이럴 경우, classList를 통한 클래스 제어가 더 유리하다.</p>
</blockquote>
</li>
</ul>
<br>

<h2 id="3-2-attribute-메서드">3-2. Attribute 메서드</h2>
<ul>
<li>노드 객체에서 호출하여 속성을 제어 :
<code>target.getAttribute(속성)</code> : 메소드 요소의 특정 속성 값에 접근할 수 있도록 함
<code>target.setAttribute(속성,속성값)</code> : 메소드 요소의 특정 속성 위치의 속성 값에 접근하여 값을 수정함</li>
</ul>
<br>

<h2 id="3-3-data-속성">3-3. data 속성</h2>
<ul>
<li>요소에 데이터를 저장하도록 도와줌</li>
</ul>
<pre><code>const target = document.querySelector(&#39;img&#39;)
    console.log(target.dataset);  // data를 가져오는 프로퍼티
    console.log(target.dataset.shipId);  // dataset으로 data를 가져온 이후에 세부 속성들을 가져온다.</code></pre><br>

<h2 id="3-4-insertadjacenthtml">3-4. insertAdjacentHTML</h2>
<ul>
<li>요소 노드를 대상의 인접한 주변에 배치</li>
</ul>
<pre><code>target.insertAdjacentHTML(&#39;beforebegin&#39;, &#39;&lt;span&gt;안녕하세요&lt;/span&gt;&#39;);  // &lt;strong&gt;의 &lt; 앞에
        target.insertAdjacentHTML(&#39;afterbegin&#39;, &#39;&lt;span&gt;W입니다&lt;/span&gt;&#39;); // &lt;strong&gt;의 &gt; 뒤에
        target.insertAdjacentHTML(&#39;beforeend&#39;, &#39;&lt;span&gt;면접오시면&lt;/span&gt;&#39;); // &lt;/strong&gt;의 &lt; 앞에
        target.insertAdjacentHTML(&#39;afterend&#39;, &#39;&lt;span&gt;집에 가세요&lt;/span&gt;&#39;); // &lt;/strong&gt;의 &gt; 뒤에</code></pre><br>

<h1 id="4-이벤트-객체">4. 이벤트 객체</h1>
<ul>
<li>이벤트는 객체이다.<pre><code>btnFirst.addEventListener(&#39;click&#39;, (event) =&gt; {
      console.log(event);
      });  =&gt; 이벤트 객체의 정보들을 가져온다.</code></pre></li>
</ul>
<h2 id="4-1-target과-currenttarget">4-1. target과 currentTarget</h2>
<ul>
<li>찾으려는 요소를 직접 찾지 않고, 부모요소를 통해 찾는 방법</li>
</ul>
<pre><code>const parent = document.querySelector(&#39;.parent&#39;);
        parent.addEventListener(&#39;click&#39;, function (event) {
        console.log(event.target); //  이벤트가 발생한 진원지의 정보가 담겨 있습니다. // 그게 버튼1 // 이벤트를 버튼의 부모에게 줘도 target은 진원지를 찾는다. 
        console.log(event.currentTarget); // 이벤트 리스너가 연결된 요소를 전부 다 가져온다.
        })</code></pre><h2 id="4-2-이벤트-전파">4-2. 이벤트 전파</h2>
<ul>
<li><p>이벤트가 발생하면, 브라우저(윈도우)부터 도큐먼트 -&gt; 부모요소 -&gt; 요소 순으로(노드 트리순)으로 이벤트가 실행될 대상(캡처링 이벤트)을 찾는다.(캡처링 단계)</p>
<pre><code>window.addEventListener(&#39;click&#39;, () =&gt; {  // 캡처링 단계 예시
         console.log(&quot;window capture!&quot;);
     }, true); // 3번째 인자에 true가 들어옴</code></pre></li>
<li><p>이벤트 대상을 찾아 캡처링이 끝나면, 반대로, DOM트리를 요소 -&gt; 부모요소 -&gt; 도큐먼트 -&gt; 브라우저(윈도우) 역순으로 올라가며 만나는 버블링 이벤트 리스너들을 실행 시킨다.(버블링 단계)</p>
</li>
</ul>
<pre><code>window.addEventListener(&#39;click&#39;, () =&gt; {  // 버블링 단계 예시
            console.log(&quot;window bubble!&quot;);
        }); // 3번째 인자에 true가 없음</code></pre><p><img src="https://velog.velcdn.com/images/dainel-q/post/98d711c1-7e8a-47e3-8c98-123bca5f16f6/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/dainel-q/post/29941f4b-10a9-45a1-90bb-6f8c9ddcfdc1/image.png" alt=""></p>
<h1 id="5-그-외-자투리">5. 그 외 자투리</h1>
<h2 id="5-1-css">5-1. CSS</h2>
<blockquote>
</blockquote>
<pre><code>// &lt;fieldset&gt;태그 =&gt; 폼 안에서 구획을 나누어 준다.
// &lt;legend&gt;JS 스터디 모집 설문조사&lt;/legend&gt; =&gt; 필드셋의 제목
// &lt;progress max=&quot;100&quot; value=&quot;0&quot; class=&quot;bar-progress&quot;&gt;&lt;/progress&gt; =&gt; 작업의 완료 정도를 나타내는 요소입니다.</code></pre><h2 id="5-2-dom">5-2. DOM</h2>
<ul>
<li>api : 앱 프로그래밍 인터페이스</li>
<li>DOM : 브라우저 객체</li>
<li>개행 하나도 노드라고 여긴다(#text)</li>
<li>노드가 요소보다 큰 개념인것인가?? -&gt; 노드가 가장 넓은 개념이고 그 안에 요소도 포함되어 있는 것</li>
<li>validity -&gt; 유효한지 확인하는 프로퍼티 키</li>
<li>&#39;keyup&#39; -&gt; 입력되면 이라는 이벤트</li>
<li>객체 안에있는 함수가 메서드</li>
<li>속성 이름이 대쉬(-) 를 통해 여러 단어로 나눠져있는 경우는 카멜케이스로 사용합니다. (background-image ⇒  backgroundImage)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[멋사 4-6 TIL(JavaScript)]]></title>
            <link>https://velog.io/@dainel-q/%EB%A9%8B%EC%82%AC-4-6-TILJavaScript</link>
            <guid>https://velog.io/@dainel-q/%EB%A9%8B%EC%82%AC-4-6-TILJavaScript</guid>
            <pubDate>Sun, 09 Apr 2023 11:35:03 GMT</pubDate>
            <description><![CDATA[<h1 id="1-반복문">1. 반복문</h1>
<h2 id="1-1-for-in">1-1. for in</h2>
<ul>
<li>배열의 인덱스나 객체의 key값을 변수 i에 부여하는 반복문</li>
<li>IE에서도 사용가능하다는 장점이 있다.</li>
</ul>
<blockquote>
</blockquote>
<pre><code>// 배열의 인덱스를 가져오는 경우
let arr1 = [10, 20, 30, 40, 50]
for (const i in arr1) {  // i가 arr의 인덱스를 가져온다
    console.log(arr1[i])
}
// 객체의 key값을 가져오는 경우
let obj1 = {&#39;one&#39; : 10, &#39;two&#39;:20}
for (const i in obj1) {  // i가 obj의 key를 가져온다
    console.log(obj1[i])
}</code></pre><h2 id="1-2-for-of">1-2. for of</h2>
<ul>
<li>배열의 값이나 객체의 iterable(반복가능, ex 배열, 문자열...)한 값을 반환하는 반복문.</li>
<li>IE에서 사용이 불가능하다.</li>
</ul>
<blockquote>
</blockquote>
<pre><code>let arr2 = [10, 20, 30, 40, 50]
let obj2 = {&#39;one&#39; : 10, &#39;two&#39;:20}
for (const item of arr2) {
    console.log(item)   // i가 arr의 값을 가져온다.
}
for (const item of obj2) {
    console.log(item)   // error //of 뒤에 iterable한 값이 나와야 한다.
}</code></pre><h2 id="1-3-for문의-객체-활용법보충">1-3. for문의 객체 활용법(보충)</h2>
<ul>
<li>배열이 객체로 이루어진 경우, 특정 key의 value를 얻고자 할 때:
for in문은 <code>arr[i][&quot;key&quot;]</code>로 구한다.
for of문은 <code>i.key</code>로 구한다.</li>
</ul>
<br>

<ul>
<li>일정하지 않는 객체에 반복문을 사용할때, nullish연산자나 조건문을 사용하여 undefined를 넘어갈 수 있다.</li>
</ul>
<blockquote>
</blockquote>
<pre><code>// 본 배열의 마지막 객체요소 안에는 age가 없어서 나이의 평균을 구하는데 어려움이 있다.
let user = [
    {
        &quot;_id&quot;: &quot;642e3071c61a23c70ae6076b&quot;,
        &quot;index&quot;: 0,
        &quot;age&quot;: 31,
        &quot;name&quot;: &quot;Hicks Garza&quot;,
        &quot;gender&quot;: &quot;male&quot;,
    },
    {
        &quot;_id&quot;: &quot;642e3071ecd6f90a87d64731&quot;,
        &quot;index&quot;: 1,
        &quot;age&quot;: 32,
        &quot;name&quot;: &quot;Ayers Harrington&quot;,
        &quot;gender&quot;: &quot;male&quot;,
    },
    {
        &quot;_id&quot;: &quot;642e3071cef9ddc131f047fb&quot;,
        &quot;index&quot;: 2,
        &quot;age&quot;: 39,
        &quot;name&quot;: &quot;Lamb Adams&quot;,
        &quot;gender&quot;: &quot;male&quot;,
    },
    {
        &quot;_id&quot;: &quot;642e3071cef9ddc131f047fb&quot;,
        &quot;index&quot;: 2,
        &quot;name&quot;: &quot;Lamb Adams&quot;,
        &quot;gender&quot;: &quot;male&quot;,
    }
]
// solution 1 : nullish연산자
let s = 0
for (const i of user) {
    s += i.age ?? 0 // 마지막 객체요소는  undefinded이지만,  nullish 연산자로 0이된다.
}
console.log((s / user.length).toFixed(2))
// solution 2 : 조건문
let s = 0;
for (const i of user.map(v =&gt; v.age)) {
    if(!!i) {  // 조건문에 의해 마지막 객체요소는  undefinded 즉, false로 출력되어 무시된다.
        s += i 
    }
}
console.log((s/ user.length).toFixed(2))
// 모범 답안(실무용)
user
    .map(v =&gt; v.age)
    .filter(v =&gt; !!v)  // 값이 있는 경우, 즉 true인 경우만 걸러낸다.
    .reduce((a,b) =&gt; a + b, 0)</code></pre><br>

<h1 id="2-continue와-break문">2. continue와 break문</h1>
<h2 id="2-1-break문">2-1. break문</h2>
<blockquote>
<p>조건이 충족되면,자신을 감싼 반복만을 탈출함. 그 상위 반복문까지 탈출하지 않음 // 중단시킴</p>
</blockquote>
<blockquote>
</blockquote>
<pre><code>// break문 예시(구구단, 3까지만 곱해짐)
for (let i = 2; i &lt; 10; i++) {
    for(let j = 1; j &lt;10; j++){
        console.log(`${i} X  ${j} = ${i*j}`)
        if (j === 3) {
            break  // j가 3이면 for(let j = 1; j &lt;10; j++)를 탈출함
        }
    }
}</code></pre><br>

<h2 id="2-2-continue문">2-2. continue문</h2>
<blockquote>
<p>조건이 충족되면, 아래 구문을 실행시키지 않고 다음 루프로 넘어가서 다시 구문을 실행시킴. // 중단시키진 않음</p>
</blockquote>
<blockquote>
</blockquote>
<pre><code>// continue문 예시(구구단, 3배고 다 곱함)
for (let i = 2; i &lt; 10; i++) {
    for(let j = 1; j &lt;10; j++){
        if (j === 3) {
            continue  // j가 3이면, 아래 console.log(`${i} X  ${j} = ${i*j}`)실행 시키지 않고 j가 4로 넘어감
        }  
        console.log(`${i} X  ${j} = ${i*j}`)
    }
}</code></pre><br>

<h1 id="3-전개구문과-구조분해할당">3. 전개구문과 구조분해할당</h1>
<h2 id="3-1-전개구문">3-1. 전개구문</h2>
<blockquote>
<p>배열이나 객체로 묶여있던 요소들을 다시 풀거나, 나뉘어진 요소들을 하나의 배열이나 객체로 모아주는 역할을 수행</p>
</blockquote>
<ul>
<li>배열의 전개구문 : 주로 서로 다른 배열을 하나로 합칠때 사용한다.</li>
</ul>
<blockquote>
</blockquote>
<pre><code>const 과일들 = [&#39;사과&#39;, &#39;파인애플&#39;, &#39;수박&#39;];
const 생선들 = [&#39;조기&#39;, &#39;갈치&#39;, &#39;다금바리&#39;];
const 합치면 = [...과일들, ...생선들];
const 합치면2 = [과일들, 생선들];
console.log(합치면);  // [&#39;사과&#39;, &#39;파인애플&#39;, &#39;수박&#39;, &#39;조기&#39;, &#39;갈치&#39;, &#39;다금바리&#39;]
console.log(합치면2);  // [Array(3), Array(3)]</code></pre><ul>
<li>객체의 전개구문 : 주로 요소에 변경사항을 줄 때 사용한다.</li>
</ul>
<blockquote>
</blockquote>
<pre><code>const A = {ein: &#39;재직중&#39;, zwei: &#39;재직중&#39;, drei: &#39;재직중&#39;, vier : &#39;재직중&#39;, funf : &#39;재직중&#39;};
const A2 = {
    ...A,
    drei: &#39;휴가&#39;,  // 객체 요소 변경
       vier: &#39;퇴사&#39;
}
A2 //  {ein: &#39;재직중&#39;, zwei: &#39;재직중&#39;, drei: &#39;휴가&#39;, vier: &#39;퇴사&#39;, funf: &#39;재직중&#39;}</code></pre><br>


<h2 id="3-2-구조분해할당">3-2. 구조분해할당</h2>
<blockquote>
</blockquote>
<pre><code>for (const [i,j] of [[1,2], [3,4], [5,6]]) {
    console.log(i,j)
} // 1 2
     3 4
     5 6</code></pre><ul>
<li>Object.entries(): 객체의 프로퍼티들을 [key ,value] 쌍의 배열로 반환해주는 메소드</li>
</ul>
<blockquote>
</blockquote>
<pre><code>const A = {ein: &#39;재직중&#39;, zwei: &#39;재직중&#39;, drei: &#39;재직중&#39;, vier : &#39;재직중&#39;, funf : &#39;재직중&#39;};
Object.entries(A)
// 0
: 
(2) [&#39;ein&#39;, &#39;재직중&#39;]
1
: 
(2) [&#39;zwei&#39;, &#39;재직중&#39;]
2
: 
(2) [&#39;drei&#39;, &#39;재직중&#39;]
3
: 
(2) [&#39;vier&#39;, &#39;재직중&#39;]
4
: 
(2) [&#39;funf&#39;, &#39;재직중&#39;]
for (const [i,j] of Object.entries(A)) {
    console.log(i,j)
}
// ein 재직중
   zwei 재직중
   drei 재직중
   vier 재직중
   funf 재직중</code></pre><ul>
<li>구조분해할당 예시</li>
</ul>
<blockquote>
</blockquote>
<pre><code>const test2 = [
    [1, 2, [10, 20]], 
    [3, 4, [30, 40]], 
    [5, 6, [50, 60]]
]
for (const [i, j] of test2) {
    console.log(i, j);
} 
const test3 = [
    [1, 2, [10, 20]], 
    [3, 4, [30, 40]], 
    [5, 6, [50, 60]]
]
for (const [i, j, k] of test3) {
    console.log(i, j, k);
}
const test4 = [
    [1, 2, [10, 20]], 
    [3, 4, [30, 40]], 
    [5, 6, [50, 60]]
]
// 모든 요소로 나누어준다
for (const [i, j, [k, l]] of test4) {
    console.log(i, j, k, l);
}
// 중요!!
const test5 = [
    [1, 2, 10, 20], 
    [3, 4, 30, 40], 
    [5, 6, 50, 60]
]
for (const [i, j, ...k] of test5) {  // j이후의 요소들을 전부 구조분해한 배열로 묶음
    console.log(i, j, k);
}</code></pre><br>


<h1 id="4-암기코드">4. 암기코드</h1>
<h2 id="4-1-구구단">4-1. 구구단</h2>
<blockquote>
</blockquote>
<pre><code>// for문
for (let i = 2; i &lt; 10; i++) {
    for (let j = 1; j &lt; 10; j++) {
        console.log(`${i} X  ${j} = ${i*j}`)
    }
}
// while문
let i = 2
while (i &lt; 10) {
    let j = 1;  // 왜 여기서 선언하는 것인가?? -&gt; 초기화를 안했기 때문  // 위에 쓰면 j는 영원히 10이 된다 -&gt; 9까지 출력하고 탈출하기 때문
    while (j &lt; 10) {
        console.log(`${i} X  ${j} = ${i*j}`)
        j++
    }
    i++
}
// 오답
// let i = 2
// let j = 1;
// while (i &lt; 10) {
//     while (j &lt; 10) {
//         console.log(`${i} X  ${j} = ${i*j}`)
//         j++
//     }
//     i++
// }</code></pre><br>

<h2 id="4-2-문자열-뒤집기">4-2. 문자열 뒤집기</h2>
<blockquote>
</blockquote>
<pre><code>//for문
let s1 = &#39;hello world&#39;
let result = &#39;&#39;;
for (let i = 0; i &lt; s1.length; i++) {
    console.log(i)
    result = s1[i] + result
}
console.log(result)
// s1[0] + result =&gt; &#39;h&#39; + &#39;&#39; =&gt; &#39;h&#39;
// s1[1] + result =&gt; &#39;e&#39; + &#39;h&#39; =&gt; &#39;eh&#39;
// s1[2] + result =&gt; &#39;l&#39; + &#39;eh&#39; =&gt; &#39;leh&#39;
// while문
let s2 = &#39;hello world&#39;
let result2 = &#39;&#39;;
let count = 0
while (count &lt; s2.length) {
    result2 = s2[count] + result2
    count++
}
console.log(result2)</code></pre><h2 id="4-3-팩토리얼">4-3 팩토리얼</h2>
<blockquote>
</blockquote>
<pre><code>//for문
let s3 = 1;
for (let i = 1; i &lt; 6; i++) {
    s3 *= i;
}
console.log(s3)
// while문
let s = 1;
count = 1;
while (count &lt; 6) {
    s *= count;
    count++
}
console.log(s)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 4-8 TIL]]></title>
            <link>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4-8-TIL</link>
            <guid>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4-8-TIL</guid>
            <pubDate>Sat, 08 Apr 2023 13:11:19 GMT</pubDate>
            <description><![CDATA[<h1 id="1-day-15-34--영어가-싫어요">1. Day 15 3/4 : 영어가 싫어요</h1>
<blockquote>
<p> Q. 영어가 싫은 머쓱이는 영어로 표기되어있는 숫자를 수로 바꾸려고 합니다. 문자열 numbers가 매개변수로 주어질 때, numbers를 정수로 바꿔 return 하도록 solution 함수를 완성해 주세요.</p>
</blockquote>
<h2 id="1-1-내-풀이-및-해설">1-1. 내 풀이 및 해설</h2>
<blockquote>
</blockquote>
<pre><code>function solution(numbers) {
    let Num = [&quot;zero&quot;, &quot;one&quot;, &quot;two&quot;, &quot;three&quot;, &quot;four&quot;, &quot;five&quot;, &quot;six&quot;, &quot;seven&quot;, &quot;eight&quot;, &quot;nine&quot;];
    let Eng = &quot;&quot;;
    let answer = &quot;&quot;;
    numbers = numbers.split(&quot;&quot;);
    for (let i = 0; i &lt; numbers.length; i++){
        Eng += numbers[i]
        if (Num.includes(Eng)){
            answer += Num.indexOf(Eng);
            Eng = &quot;&quot;;
        }
    }
    return parseInt(answer);
}</code></pre><ul>
<li>1단계. 파라미터는 숫자가 영어로 쓰여진 파라미터로 나오기에, split(&quot;&quot;)으로 하나씩 나뉘어진 배열로 만든다.</li>
<li>2단계. 영문으로 작성된 숫자로 만들어진 배열을 만들고, 인덱스를 이용하기로 판단한다.</li>
<li>3단계. 파라미터 배열에서 조합된 단어를 숫자배열과 비교하여 아라비아 숫자를 정답에 누적시켜야하기에 빈 문자열을 만든다.</li>
<li>4단계. 파라미터 배열을 순회하면서, 숫자열의 숫자와 일치하면 그 숫자열의 인덱스를 정답 배열에 누적하도록 조건문을 작성한다.</li>
</ul>
<br>

<h1 id="2-day-15-44--약수-구하기">2. Day 15 4/4 : 약수 구하기</h1>
<blockquote>
<p>Q. 정수 n이 매개변수로 주어질 때, n의 약수를 오름차순으로 담은 배열을 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h2 id="2-1-내-풀이-및-해설">2-1. 내 풀이 및 해설</h2>
<blockquote>
</blockquote>
<pre><code>function solution(n) {
    let answer = [];
    for (let i = 1; i &lt;= n; i++){
        if (n % i === 0){
            answer.push(i)
        }
    }
    return answer;
}</code></pre><ul>
<li>1단계. n이하의 자연수를 순회해야하기에, for문으로 1부터 n까지 순회하는 반복문을 작성한다.</li>
<li>2단계. n의 약수는 n에 나누었을때, 나머지가 0이라는 메커니즘을 이용한 조건문을 작성하여, 약수만 정답 배열에 추가하는 코드를 작성한다.</li>
</ul>
<h2 id="2-2-다른-내-풀이-및-해설">2-2. 다른 내 풀이 및 해설</h2>
<blockquote>
</blockquote>
<pre><code>function solution(n) {
    return Array(n).fill(0)
                   .map((v,i) =&gt; i+1)
                   .filter((el) =&gt; n % (el) === 0);
}</code></pre><ul>
<li>1단계. 인덱스가 n이고 0으로만 구성된 배열을 만든다.</li>
<li>2단계. map메서드로, 0이 인덱스에 1씩 더한 요소들로 바뀌도록 한다.</li>
<li>3단계. filter메서드로 각 요소를 n에 나누어 나머지가 0인 요소만 남도록 한다.</li>
</ul>
<br>

<h1 id="3-마무리">3. 마무리</h1>
<ul>
<li>다른 풀이들을 살펴보니, 확실히 정규식을 알면 보다 효율적으로 풀 수 있기 때문에 부진런히 공부해야겠다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 4-7 TIL]]></title>
            <link>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4-7-TIL</link>
            <guid>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4-7-TIL</guid>
            <pubDate>Sat, 08 Apr 2023 04:35:53 GMT</pubDate>
            <description><![CDATA[<h1 id="1-day15-14--인덱스-바꾸기">1. Day15 1/4 : 인덱스 바꾸기</h1>
<blockquote>
<p> Q. 문자열 my_string과 정수 num1, num2가 매개변수로 주어질 때, my_string에서 인덱스 num1과 인덱스 num2에 해당하는 문자를 바꾼 문자열을 return 하도록 solution 함수를 완성해보세요.</p>
</blockquote>
<h2 id="1-1-내-풀이">1-1. 내 풀이</h2>
<blockquote>
<pre><code>function solution(my_string, num1, num2) {
    let answer = &#39;&#39;;
    let Dex = [...my_string]
    for (let i in Dex) {
        if( i == num1) {
            answer += Dex[num2]
        } else if (i == num2) {
            answer += Dex[num1]
        } else {
            answer += Dex[i]
        }
    }
    return answer;
}</code></pre></blockquote>
<h2 id="1-2-해설">1-2. 해설</h2>
<blockquote>
</blockquote>
<ul>
<li>1단계. 파라미터가 문자열이라는 것을 감안해서 전개구문으로 전개하여 새로운 변수에 선언한다.</li>
<li>2단계. 본 문제의 핵심은 인덱스를 바꾸는 것이기에, for in 문을 사용하여 순환시킨다.</li>
<li>3단계. for in문 안에 조건문으로 인덱스 num1과 num2를 바꾸면서 정답에 요소들이 누적되도록 코드를 작성한다.</li>
</ul>
<h2 id="1-3-다른-풀이-및-해설구조분해할당">1-3. 다른 풀이 및 해설(구조분해할당)</h2>
<blockquote>
</blockquote>
<pre><code>function solution(my_string, num1, num2) {
    my_string = my_string.split(&quot;&quot;);
    [my_string[num1],my_string[num2]] = [my_string[num2],my_string[num1]]
    return my_string.join(&quot;&quot;);
}</code></pre><ul>
<li>이 풀이가 문제의 취지를 가장 잘 파악한 문제라고 생각한다.(물론 내가 푼 것은 아님)</li>
<li>1단계. 본 문제는 요소의 인덱스를 바꾸는 것이지만, 결국 요소끼리 자리를 바꾸면 되기에, 구조분해할당을 이용하여 구조를 재설정하면 된다.</li>
<li>2단계. 파라미터가 문자열로 되어있기에 이를 split(&quot;&quot;)으로 요소들이 나뉘어진 배열로 바꾼다</li>
<li>3단계. 구조분해할당을 이용하여, 배열의 요소들의 위치를 바꾼다.</li>
<li>4단계. 파라미터가 배열이 되었기에 정답에는 join(&quot;&quot;)을 사용하여 문자열로 바꾸어 반환한다.</li>
</ul>
<h2 id="1-4-다른-풀이-및-해설map-메서드">1-4. 다른 풀이 및 해설(map 메서드)</h2>
<blockquote>
</blockquote>
<pre><code>function solution(my_string, num1, num2) {
    my_string = my_string.split(&quot;&quot;)
    return my_string.map((v,i) =&gt; i === num1 ? my_string[num2] : i === num2 ? my_string[num1] : v).join(&quot;&quot;);
}</code></pre><ul>
<li>1단계. 파라미터가 문자열로 되어있기에 이를 split(&quot;&quot;)으로 요소들이 나뉘어진 배열로 바꾼다</li>
<li>2단계. 배열 내 요소들에 변화를 주는 것이기에, map메서드를 사용하며, 주어진 인덱스 간에 요소들을 바꿀 수 있는 조건 코드를 삼항 연산자로 작성한다.</li>
<li>3단계. 파라미터가 배열이 되었기에 정답에는 join(&quot;&quot;)을 사용하여 문자열로 바꾸어 반환한다.</li>
</ul>
<br>

<h1 id="2-day15-24--한-번만-등장한-문자">2. Day15 2/4 : 한 번만 등장한 문자</h1>
<blockquote>
<p>Q. 문자열 s가 매개변수로 주어집니다. s에서 한 번만 등장하는 문자를 사전 순으로 정렬한 문자열을 return 하도록 solution 함수를 완성해보세요. 한 번만 등장하는 문자가 없을 경우 빈 문자열을 return 합니다.</p>
</blockquote>
<h2 id="2-1-내-풀이-및-해설">2-1. 내 풀이 및 해설</h2>
<blockquote>
</blockquote>
<pre><code>function solution(s) {
    let answer = &#39;&#39;;
    let STR = [...s].sort()
    if(STR[0] != STR[1]){
        answer += STR[0];
    }
    for (let i = 1; i &lt; STR.length ; i++){
        if (STR[i-1] != STR[i]) {
            if(STR[i] != STR[i+1]){
                answer += STR[i];
            }
        }
    }
    return answer;
}</code></pre><ul>
<li>1단계. 정답이 사전 순으로 나와야 하기 때문에, 파라미터에 전개구문과 sort()를 사용하여 알파벳 순으로 정렬된 배열로 만든다.</li>
<li>2단계. 사전 순으로 정렬된 배열에서 한 번만 나오는 문자는 자신의 앞뒤의 문자와 다르다는 조건을 갖고 있다는 것을 파악한다.</li>
<li>3단계. for문으로 반복문을 작성하되, 인덱스의 변수가 0부터 시작하면 자신 앞의 문자가 없기때문에 시작은 1로 진행한다.</li>
<li>4단계. 0번째 요소를 판별하지 못했기 때문에, 이를 판별하는 조건문을 for문 앞에 작성한다.</li>
</ul>
<h2 id="2-2-다른-풀이-및-해설">2-2. 다른 풀이 및 해설</h2>
<blockquote>
</blockquote>
<pre><code>function solution(s) {
    s = s.split(&quot;&quot;).sort()
    return s.filter((v,i) =&gt; s[i-1] != s[i] &amp;&amp; s[i] != s[i+1])
            .join(&quot;&quot;);
}</code></pre><ul>
<li>1단계. 정답이 사전 순으로 나와야 하기 때문에, 파라미터에 split(&quot;&quot;)과 sort()를 사용하여 알파벳 순으로 정렬된 배열로 만든다.</li>
<li>2단계. 자신의 앞뒤의 문자와 비교하는 조건을 비교연산자와 논리연산자로 작성한 filter()를 사용하여 한 번만 나온 문자를 걸러낸다.</li>
</ul>
<h1 id="3-마무리">3. 마무리</h1>
<ul>
<li>배열이나 객체 요소의 순서를 바꿔야할 때, 구조분해할당이 상당히 유용하기에 정리하여 익혀둘 것</li>
<li>한 번에 모범적인 풀이법이 나올 필요는 없으니, 다양한 풀이법을 적용해볼 것을 추천한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 4-6 TIL]]></title>
            <link>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4-6-TIL</link>
            <guid>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4-6-TIL</guid>
            <pubDate>Thu, 06 Apr 2023 14:38:42 GMT</pubDate>
            <description><![CDATA[<h1 id="1-day-14-34--암호-해독">1. Day 14 3/4 : 암호 해독</h1>
<blockquote>
<p> Q. 암호화된 문자열 cipher를 주고받습니다.
그 문자열에서 code의 배수 번째 글자만 진짜 암호입니다.
문자열 cipher와 정수 code가 매개변수로 주어질 때 해독된 암호 문자열을 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h2 id="1-1-내-풀이">1-1. 내 풀이</h2>
<blockquote>
<pre><code>function solution(cipher, code) {
    let answer = &#39;&#39;;
    for (let i = code - 1; i &lt; cipher.length; i += code){
        answer += cipher[i]
    }
    return answer;
}</code></pre></blockquote>
<br>

<h2 id="1-2-해설">1-2. 해설</h2>
<blockquote>
</blockquote>
<ul>
<li>1단계. 문제에서 code의 배수 번째 글자라고 했으나, 자바스크립트의 순서는 0부터 시작하기에 사실상 code -1 번째부터 시작한다는 것을 파악한다.</li>
<li>2단계. 첫번째 인덱스는 1을 차감했으나, 순서는 code만큼 커지기에 증감식에 code를 더한다.</li>
</ul>
<br>

<h2 id="1-3-다른-풀이-및-해설---정답참조">1-3. 다른 풀이 및 해설 -&gt; 정답참조</h2>
<blockquote>
</blockquote>
<pre><code>function solution(cipher, code) {
    return [...cipher].filter((_,i) =&gt; (i + 1) % code === 0).join(&quot;&quot;);
}</code></pre><ul>
<li>1단계. code의 배수번째인 인덱스는 code의 배수보다 1이 작기 때문에, 인덱스의 입장에서 1을 더하여 code의 배수가 되는 방법으로 인덱스를 찾는다.</li>
</ul>
<br>

<h1 id="2-day-14-44--대문자와-소문자">2. Day 14 4/4 : 대문자와 소문자</h1>
<blockquote>
<p> Q . 문자열 my_string이 매개변수로 주어질 때, 대문자는 소문자로 소문자는 대문자로 변환한 문자열을 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h2 id="2-1-나의-풀이">2-1. 나의 풀이</h2>
<blockquote>
<pre><code>function solution(my_string) {
    let answer = &#39;&#39;
    for (const i of [...my_string]) {
        if (i === i.toUpperCase()) {
            answer += i.toLowerCase()
        } else {
            answer += i.toUpperCase()
        }
    }
    return answer;
}</code></pre></blockquote>
<h2 id="2-2-해설">2-2. 해설</h2>
<blockquote>
</blockquote>
<ul>
<li>1단계. 파라미터의 타입은 문자열이기에 이를 전개구문으로 전개한다.</li>
<li>2단계. 전개된 파라미터를 for of문으로 순환하며, 각 요소가 대문자인지, 아니면 소문자인지 if else문을 사용하여 구분하고, 대소문자를 바꿔준다.</li>
</ul>
<br>

<h2 id="2-3-다른-풀이-및-해설">2-3 다른 풀이 및 해설</h2>
<blockquote>
</blockquote>
<pre><code>function solution(my_string) {
    return [...my_string].map((el) =&gt; (el) === (el).toUpperCase() ? (el).toLowerCase() : (el).toUpperCase()).join(&quot;&quot;);
}</code></pre><ul>
<li>1단계. 파라미터의 타입은 문자열이기에 이를 전개구문으로 전개한다.</li>
<li>2단계. 배열의 요소에 변화를 주어야 하기 때문에 map메서드를 사용한다.</li>
<li>3단계. map으로 순환을 할 때, 삼항연산자를 이용하여, 요소의 대소문자를 판가름한 뒤, 대소문자를 바꿔준다.</li>
</ul>
<br>

<h1 id="3-마무리">3. 마무리</h1>
<ul>
<li>반복문을 사용하지 않는 코드가 더 가독성이 좋기 때문에 2가지 방식으로 다 풀어보며 학습하도록 하자!!</li>
<li>반복문이 아닌 코드를 단 번에 이해하는 것은 무리가 있으니, 답을 보더라도 천천히 그 원리를 익히고, 주말에 직접 그 방식을 적용하여 풀 수 있도록 하자.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 4-5 TIL]]></title>
            <link>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4-5-TIL</link>
            <guid>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4-5-TIL</guid>
            <pubDate>Wed, 05 Apr 2023 07:40:17 GMT</pubDate>
            <description><![CDATA[<h1 id="day-14-14-가까운-수">Day 14 1/4: 가까운 수</h1>
<blockquote>
<p>Q. 정수 배열 array와 정수 n이 매개변수로 주어질 때, array에 들어있는 정수 중 n과 가장 가까운 수를 return 하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h2 id="내-풀이">내 풀이</h2>
<pre><code>function solution(array, n) {
    array.sort((a,b) =&gt; a - b);
    let Sm  = array.map((el) =&gt; Math.abs((el) - n));
    return array[Sm.indexOf(Math.min(...Sm))];
}</code></pre><h2 id="해설">해설</h2>
<blockquote>
</blockquote>
<ul>
<li>1단계. 파라미터로 주어진 n을 array의 전 요소들에 빼준 값의 절대값이 제일 작은 것이 n과 가장 가까운 수가 된다는 메커니즘을 파악한다.</li>
<li>2단계. 그 전에, 조건으로 가까운 수가 2개 이상일 경우, 더 작은 값을 반환하라는 조건이 있음을 파악한다.</li>
<li>3단계. 배열의 초기 요소들은 순서대로 있지 않기 때문에 sort를 사용하여 오름차순으로 바꿔주면, 가까운 수가 아무리 많아도 가장 작은 값을 반환한다는 것을 파악한다.</li>
<li>4단계. map을 이용하여 배열의 모든 요소에 n을 빼고 절대값을 씌우며, 이를 새로운 변수 Sm에 부여한다.</li>
<li>5단계. 배열인 Sm에 전개구문과 min을 사용하여 가장 가까운 값을 찾고, indexOf를 활용하여 그 수의 인덱스를 파악한다.</li>
<li>6단계. 파라미터 배열의 해당 인덱스가 n과 가장 가까운 작은 수이다.</li>
</ul>
<br>

<h1 id="day-14-24-369게임">Day 14 2/4: 369게임</h1>
<blockquote>
<p>Q. 머쓱이는 친구들과 369게임을 하고 있습니다. 369게임은 1부터 숫자를 하나씩 대며 3, 6, 9가 들어가는 숫자는 숫자 대신 3, 6, 9의 개수만큼 박수를 치는 게임입니다. 머쓱이가 말해야하는 숫자 order가 매개변수로 주어질 때, 머쓱이가 쳐야할 박수 횟수를 return 하도록 solution 함수를 완성해보세요.</p>
</blockquote>
<h2 id="내-풀이-1">내 풀이</h2>
<pre><code>function solution(order) {
    let answer = 0;
    let Turn = [...order + &quot;&quot;];
    for (let i =0 ; i &lt;= Turn.length - 1; i++) {
        if (Turn[i] === &quot;3&quot; || Turn[i] === &quot;6&quot; || Turn[i] === &quot;9&quot;){
            answer += 1;
        }
    }
    return answer;
}</code></pre><h2 id="해설-1">해설</h2>
<blockquote>
</blockquote>
<ul>
<li>1단계. 본 문제는 3,6,9를 찾는 3개의 조건식으로 풀어야 한다는 것을 파악한다.</li>
<li>2단계. 여러 방법이 있지만, 우선 풀 수 있는 반복문과 조건문을 사용하기로 결정했다.</li>
<li>3단계. 파라미터의 매개 변수는 숫자열이기에 다양한 메서드를 사용하는데 제약이 있어, 이를 문자열로 만들고 전개구문으로 낱개의 문자열로 전개한다.</li>
<li>4단계. 해당 문자열을 새로운 변수에 선언하고, 3,6,9인 요소를 찾는 반복문을 작성한다.</li>
</ul>
<br>

<h1 id="마무리">마무리</h1>
<ul>
<li>금일 풀었던 문제들은 정규식으로 상당히 간단하게 풀 수 있지만 아직 주인장이 정규식에 익숙치 않기에, 정규 수업시간에 제대로 배운 후, 3회독때 적용하여 풀어 보기로 하자.</li>
<li>초판에 어지럽게 풀어고 추후에 리팩토링 하는 것도 괜찮지만, 처음에 설계를 세밀하게 하고 바로 코드 작성에 들어가는 것이 학습에 더 도움이 될 것이라 생각된다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 4-4 TIL]]></title>
            <link>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4-4-TIL</link>
            <guid>https://velog.io/@dainel-q/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-4-4-TIL</guid>
            <pubDate>Wed, 05 Apr 2023 07:16:54 GMT</pubDate>
            <description><![CDATA[<h1 id="day-13-34--중복된-문자-제거">Day 13 3/4 : 중복된 문자 제거</h1>
<blockquote>
<p>Q. 문자열 my_string이 매개변수로 주어집니다. my_string에서 중복된 문자를 제거하고 하나의 문자만 남긴 문자열을 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h2 id="내-풀이">내 풀이:</h2>
<pre><code>function solution(my_string) {
    return [...new Set(my_string)].join(&quot;&quot;);
}</code></pre><h2 id="해설">해설:</h2>
<blockquote>
</blockquote>
<ul>
<li>new Set(arr)은 중복된 요소가 없는 객체를 반환해준다. 이를 전개구문과 새로운 배열로 감싸 배열의 형태로 만들어주며, 마지막에 join메서드로 하나의 문자열로 만들어준다.
참고로, 중복은 대소문자를 가리지 않고 동일하게 취급하여 처리한다.</li>
</ul>
<br>

<h1 id="day-13-44--삼각형의-완성조건">Day 13 4/4 : 삼각형의 완성조건</h1>
<blockquote>
<p>Q. 삼각형의 세 변의 길이가 담긴 배열 sides이 매개변수로 주어집니다. 세 변으로 삼각형을 만들 수 있다면 1, 만들 수 없다면 2를 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h2 id="내-풀이-1">내 풀이</h2>
<pre><code>function solution(sides) {
    sides.sort((a,b) =&gt; b - a)
    return sides[0] &lt; sides[1] + sides[2] ? 1 : 2;
}</code></pre><h2 id="해설-1">해설</h2>
<blockquote>
</blockquote>
<ul>
<li>1단계. 파라미터의 배열에 들어가있는 요소는 무조건 3개이며, 순서대로 정렬되어 있지 않다는 것을 파악한다.</li>
<li>2단계. 이 배열을 sort메서드를 이용하여 내림차순으로 정리하면, 가장 큰 변의 길이가 0번째 인덱스로 오게 된다.</li>
<li>3단계. 0번째 인덱스의 변과 다른 두 변의 합을 비교하는 삼항 연산자를 작성하여 마무리한다.</li>
</ul>
<br>

<h1 id="마무리">마무리</h1>
<ul>
<li>Set에 대해 자세히 알지 못해서 푸는데 상당히 고민했다. 본 내용은 정규수업에서 제대로 배운 뒤에 다시 한 번 풀어볼 것!!</li>
<li>화살표 함수를 자주 사용하여 익히도록 하자!!</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[멋사 4-4 TIL (JavaScript)]]></title>
            <link>https://velog.io/@dainel-q/%EB%A9%8B%EC%82%AC-4-4-TIL-JavaScript</link>
            <guid>https://velog.io/@dainel-q/%EB%A9%8B%EC%82%AC-4-4-TIL-JavaScript</guid>
            <pubDate>Tue, 04 Apr 2023 15:49:10 GMT</pubDate>
            <description><![CDATA[<h1 id="1-템플릿-리터럴">1. 템플릿 리터럴</h1>
<h2 id="1-1-정의">1-1. 정의</h2>
<blockquote>
<p>내장된 표현식을 허용하는 문자열 리터럴이다. 쉽게 설명해서, 문자열 내에 이전에 선언된 변수를 그자체로 사용할 수 있게 해주는 리터럴 체계라고 생각하면 편하다.</p>
</blockquote>
<h2 id="1-2-표현식">1-2. 표현식</h2>
<blockquote>
<p>``안에 문자열을 작성하고, 변수는 ${}안에 작성하면 된다.</p>
</blockquote>
<pre><code>const x =10;
const y = 20;
const result = x * y;
console.log(`x값은 ${x}이고, y값은 ${y}이고 두개의 곱은 ${result}입니다.`);</code></pre><h2 id="1-3-특징">1-3. 특징</h2>
<blockquote>
<ul>
<li>기존에 이스케이프 코드인 <code>\n</code>을 사용하지 않고도 행간 줄바꿈 처리가 가능하다는 특징이 있다. </li>
</ul>
</blockquote>
<ul>
<li>다만, 가독성이 떨어진다는 단점이 있다.<pre><code>if (true) {
  if (true) {
      if (true) {
          console.log(`h
e
l
l
o
`)
      }
  }
}</code></pre></li>
</ul>
<br>

<h1 id="2-array">2. Array</h1>
<h2 id="2-1-array의-특징">2-1. array의 특징</h2>
<ol>
<li>거의 const를 사용하여 표현한다. 여기서 변수가 가리키는 것은 배열 내부의 요소가 아닌, 배열의 틀 그 자체를 가리키기에, 내부 요소에 변화를 줄 수 있다. 이를 <strong>mutable(변형가능)</strong> 이라 한다.</li>
</ol>
<br>

<ol start="2">
<li>문자열 또한 배열의 일부로 배열처럼 표현할 수는 있으나, 배열처럼 인덱스로 호출하는 것은 불가능하다. 이는 문자열이 <strong>immutable(불변함)</strong> 이기 때문이다.<blockquote>
<pre><code>const s =&#39;hello world&#39;
console.log(s[0])
s[0] = &#39;i&#39; // error</code></pre></blockquote>
</li>
</ol>
<ol start="3">
<li><p>배열의 프로퍼티가 숫자인 경우에는 <strong>오직 대괄호만으로 호출</strong> 할 수 있지만, 그 외에는 대괄호나 .을 찍어서 호출 할 수 있다.</p>
<blockquote>
<pre><code>arr[1] // O
arr.1 // X
arr.length // O
arr[&#39;length&#39;] // O</code></pre></blockquote>
</li>
<li><p>배열은 순서가 있다. 배열의 순서를 index라고 하며, 이 순서로 호출하는 것을 indexing이라 한다. 그리고 배열안에 있는 값을 원소(element)라고 한다.</p>
</li>
<li><p>배열에 다른 원시타입과 객체타입을 포함할 수 있다. 즉, 배열안에 또다른 배열이 들어가 2차원 그 이상으로도 표현이 가능하다는 것이다.</p>
<blockquote>
<pre><code>const arr = [
 [1,2,3],
 [4,5,6],
 [7,8,9]
]
// arr[2][1]
// 8</code></pre></blockquote>
</li>
</ol>
<br>


<h2 id="2-2--pop-push-shift-unshift">2-2.  pop(), push(), shift(), unshift()</h2>
<ul>
<li>해당 메서드들은 배열의 요소들을 빼거나 더하여 배열 원형을 바꾸는 메서드로, 기능이 겹칠 수 있으나, 추가적인 기능의 유무로 용도가 나뉜다.</li>
</ul>
<ol>
<li><p>pop() : 배열의 맨 마지막 요소를 추출하고, <strong>추출한 값을 반환(return)</strong> 한다. </p>
<blockquote>
<pre><code>const arr = [1, 2, 3, 4, 5]
let lastValue = arr.pop()
arr // (4) [1, 2, 3, 4]
lastValue // 5</code></pre></blockquote>
</li>
<li><p>shift() : 배열의 맨 앞 요소를 추출하고, <strong>추출한 값을 반환(return)</strong> 한다.</p>
<blockquote>
<pre><code>const arr = [&quot;사과&quot;, &quot;바나나&quot;, &quot;수박&quot;];
let firstValue = arr.shift();
arr // (2) [&#39;바나나&#39;, &#39;수박&#39;]
firstValue // &#39;사과&#39;</code></pre></blockquote>
</li>
<li><p>push() : 배열의 맨 마지막에 요소를 추가한다.</p>
<blockquote>
<pre><code>const arr = [1, 2, 3, 4, 5]
arr.push(6)
arr  // (6) [1, 2, 3, 4, 5, 6]</code></pre></blockquote>
</li>
<li><p>unshift() : 배열의 맨 앞에 요소를 추가한다.</p>
<blockquote>
<pre><code>const arr = [&quot;사과&quot;, &quot;바나나&quot;, &quot;수박&quot;];
arr.unshift(&quot;딸기&quot;,&quot;참외&quot;)
arr // (5) [&#39;딸기&#39;, &#39;참외&#39;, &#39;사과&#39;, &#39;바나나&#39;, &#39;수박&#39;]</code></pre></blockquote>
</li>
</ol>
<h2 id="2-3--splice--slice">2-3.  splice &amp; slice</h2>
<ul>
<li>두 메서드 모두 배열의 범위를 정하여 그 범위의 요소들이 담긴 배열을 반환한다는 공통점인 기능을 하지만, <strong>splice의 경우, 원본에 영향을 주면서 작동</strong> 한다는 차이점이 있다.</li>
</ul>
<ol>
<li>arr.splice(start, deleteCount, items) : 인덱스 start 번째에서 부터 deleteCount개의 요소를 지우고, 그 자리에 items들을 넣는다.<blockquote>
<pre><code>const arr = [10, 20, 30, 40, 50]
const x = [1, 2, 3]
arr.splice(2, 2, ...x); // (2) [30, 40] // 잘려나간 것
arr // (6) [10, 20, 1, 2, 3, 50] // 배열이 바뀜
arr.splice(2, 2); // 2번째 인덱스에서 값 2개를 삭제. 삽입되는 값은 없음. //  [1, 2]
arr // [10, 20, 3, 50]</code></pre></blockquote>
</li>
</ol>
<ul>
<li>예외 : splice의 파라미터에 값이 1개만 들어갈 경우, start -1 번째 빼고 다 잘려나간다는 특이점이 있다.<blockquote>
<pre><code>const arr = [10, 20, 3, 50]
arr.splice(1);  // 0번째까지 남기고 뒤에는 다 날림  // [20, 3, 50]
arr // [10]</code></pre></blockquote>
</li>
</ul>
<ol start="2">
<li>arr.slice(start, end) : 인덱스 start 번째에서 end - 1번째 까지의 요소들을 추출한다. 단, 원본은 바뀌지 않았다.<blockquote>
<pre><code>const arr = [&quot;apple&quot;, &quot;banana&quot;, &quot;cherry&quot;, &quot;durian&quot;, &quot;elderberry&quot;];
console.log(arr.slice(1, 4)); // (3) [&#39;banana&#39;, &#39;cherry&#39;, &#39;durian&#39;]
console.log(arr)  // (5) [&#39;apple&#39;, &#39;banana&#39;, &#39;cherry&#39;, &#39;durian&#39;, &#39;elderberry&#39;]
console.log(arr.slice(0)) // 전부 출력 // (5) [&#39;apple&#39;, &#39;banana&#39;, &#39;cherry&#39;, &#39;durian&#39;, &#39;elderberry&#39;]</code></pre></blockquote>
</li>
</ol>
<br>

<h2 id="2-4--foreach--map">2-4.  forEach &amp; map</h2>
<ul>
<li>두 메서드 모두 배열의 요소들을 순환하는 기능을 하지만, <strong>map은 새로운 배열을 생성한다는 차이점이 있다.</strong></li>
</ul>
<ol>
<li><p>arr.forEach((item, index) =&gt; ) : 콜백함수에 들어가는 파라미터가 <strong>item과 index이다.</strong></p>
<blockquote>
<pre><code>// 배열안에 1~100까지 forEach로 넣는 방법
const arr1 = Array(100).fill(0)
const arr2 = []
arr1.forEach((item,index) =&gt; arr2.push(index + 1))</code></pre></blockquote>
</li>
<li><p>arr.map((v,i) =&gt; ) : 콜백함수에 들어가는 파라미터가 <strong>value와 index이다.</strong></p>
<blockquote>
<pre><code>// map으로 1~100까지인 배열 만들기
const arr = Array(100).fill(0)
arr.map((v,i) =&gt; i +1)</code></pre></blockquote>
</li>
</ol>
<br>

<h2 id="2-5--filter">2-5.  filter()</h2>
<ul>
<li>filter((v,i) =&gt; v)는 value 값에 원하는 조건을 입력하여, 해당 요소만 추출한 새로운 배열을 만들어준다. 원본 배열은 그대로 유지된다.<blockquote>
<pre><code>// 짝수 찾는 방법
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
arr.filter(function(el){
  return el % 2 === 0
}) // (5) [2, 4, 6, 8, 10]
arr // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]</code></pre></blockquote>
</li>
</ul>
<br>

<h2 id="2-6-reduceac--a--c-0">2-6. reduce((a,c) =&gt; a + c, 0)</h2>
<ul>
<li>reduce()는 보통 배열의 요소들을 더할 때 사용되는 메서드로, a는 누적된 값(accumulator), c는 현재값(currentValue)을 의미하며, 맨 뒤에 inital value 0이 반드시 들어가야한다.<blockquote>
<pre><code>const arr = [1, 2, 3, 4, 5]
arr.reduce((a,c) =&gt; a + c, 0)  // 15 // 0은 반드시 넣어라</code></pre></blockquote>
</li>
</ul>
<br>

<h2 id="2-7-includes">2-7. includes()</h2>
<ul>
<li>arr.includes(n)은 arr 배열의 요소에 n이 포함되어 있는지를 boolean 값으로 반환해주는 메서드로, 요소의 타입과 컨텐츠가 정확하게 n과 일치해야 true를 반환한다.<blockquote>
<pre><code>const arr = [&#39;hello&#39; , &#39;world&#39;, 10 , &#39;seunggyu&#39;]
arr.includes(&#39;hello&#39;) // true
arr.includes(&#39;h3l&#39;) // false
arr.includes(&#39;10&#39;)  // false</code></pre></blockquote>
</li>
</ul>
<br>

<h2 id="2-8-join">2-8. join()</h2>
<ul>
<li>arr.join(&#39;n&#39;)은 배열 arr의 문자열 요소들을 &#39;n&#39;으로 이어 하나의 문자열로 반환해준다.<blockquote>
<pre><code>const arr = [&#39;hello&#39; , &#39;world&#39;, &#39;seunggyu&#39;]
arr.join(&quot;!&quot;)  // &#39;hello!world!seunggyu&#39;</code></pre></blockquote>
</li>
</ul>
<br>

<h2 id="2-9-sort">2-9. sort()</h2>
<ul>
<li>arr.sort()는 배열 arr을 오름차순 또는 내림차순으로 정리하여 <strong>원본을 변형시키는</strong> 메서드로, 주로 sort안에 다음과 같은 화살표 함수와 함께 쓰기에 암기해주는 것이 좋다.
참고로, sort((a,b) =&gt; a - b)메서드의 작동 원리는 a,b 두 요소의 차를 구해 0보다 작거나 같으면 그대로 유지하며 양수인 경우 b가 앞으로 가면서 순서를 잡는다. 물론, 내림차순은 이의 반대원리로 작동된다. + 폴더에 실무사용코드가 있으므로 참고!!<blockquote>
<pre><code>// 오름차순
const nums = [3, 1, 11, 8, 10];
console.log(nums.sort((a, b) =&gt; a - b));
nums // (5) [1, 3, 8, 10, 11]
// 내림차순
const nums = [3, 1, 11, 8, 6];
console.log(nums.sort((a, b) =&gt; b - a));
nums // (5) [11, 8, 6, 3, 1]</code></pre></blockquote>
</li>
</ul>
<h1 id="3-object객체">3. object(객체)</h1>
<ul>
<li>유사배열객체로, 중괄호 안에 <code>key : value</code>의 형태로 요소들을 정렬하는 참조 타입이다.
이는 재할당으로만 변경이 가능한 원시타입과 달리, 변수가 참조를 하는 타입이기에 동적으로 프로퍼티를 생성 및 갱신을 할 수 있어 유지보수에 상당히 유용하다.
참고로 프로퍼티는 <code>key : value</code>를 의미한다.<blockquote>
<pre><code>// 객체 사용 예시
const test = {
  group : [&#39;ein&#39;, &#39;zwei&#39;, &#39;drei&#39;, &#39;vier&#39; ,&#39;funf&#39;],
  duty : &quot;Go Home and GEt Rest&quot;,
  trouble : function (){
      return &quot;After School Class&quot;
  }
}
// value가 함수인 경우는 key도 함수의 형태로 작성해야 호출이 가능하다.
test.trouble() // After School Class
// 1. 동적 추가
test.solution = &quot;pass_exam&quot;
test //  {group: Array(5), duty: &#39;Go Home and GEt Rest&#39;, solution: &#39;pass_exam&#39;, trouble: ƒ}
// 2. 동적 갱신
test.duty = &quot;work_hard&quot;
test.duty // &quot;work_hard&quot;
// 3. 동적 삭제
delete test.trouble;
test //  {group: Array(5), duty: &#39;work_hard&#39;, solution: &#39;pass_exam&#39;}</code></pre></blockquote>
</li>
</ul>
<br>

<h2 id="3-1-hasownproperty">3-1. hasOwnProperty</h2>
<ul>
<li>객체를 돌며 해당 프로퍼티 키의 존재 유무를 boolean값으로 반환한다. 여기서 유의할 점은 객체의 프로퍼티 키는 문자열 형태로 작성하도록 한다.
단어끼리 합쳐서 사용하는 메서드는 대부분 앞글자를 대문자로 작성하여 구별한다.(has&#39;O&#39;wn&#39;P&#39;roperty)<blockquote>
<pre><code>console.log(test.hasOwnProperty(&#39;lunch&#39;)); // false
console.log(test.hasOwnProperty(&#39;trouble&#39;)); // true</code></pre></blockquote>
</li>
</ul>
<br>

<h2 id="3-2-프로퍼티-호출방식">3-2. 프로퍼티 호출방식</h2>
<ul>
<li>aespa.keys() 와 같은 다른언어의 사용 방식이 아닌 <strong><code>Object</code></strong>를 붙여 사용한다는 것이 중요하다.</li>
</ul>
<blockquote>
<pre><code>console.log(Object.keys(test))  // (3) [&#39;group&#39;, &#39;duty&#39;, &#39;trouble&#39;]
console.log(Object.values(test))  // (3) [Array(5), &#39;Go Home and GEt Rest&#39;, ƒ]</code></pre></blockquote>
<br>

<h1 id="4-함수-function">4. 함수 function()</h1>
<h2 id="4-1-함수의-특징--왜-함수를-사용하는가">4-1. 함수의 특징 : 왜 함수를 사용하는가?</h2>
<h3 id="1-재사용성이-높아짐">1. 재사용성이 높아짐</h3>
<ul>
<li>코드를 작성하다보면 같은 명령 코드를 여러 곳에서 사용해야하는 경우가 생긴다. 그때마다 장황하게 명령코드들을 작성하면, 가독성이 현저하게 떨어지며, 부팅속도 또한 늦어질 수 밖에 없다.
함수는 반복되는 코드들을 간결하게 정리하여 재사용성을 높인다.  <blockquote>
<pre><code>function Hock(){
  console.log(&#39;hello&#39;)
  console.log(&#39;hello&#39;)
  console.log(&#39;hello&#39;)
  console.log(&#39;hello&#39;)
  console.log(&#39;hello&#39;)
  console.log(&#39;hello&#39;)
  console.log(&#39;hello&#39;)
}
Hock()  // Hock()하나만 있으면 위의 7줄의 코드가 실행된다.
Hock()
Hock()</code></pre></blockquote>
</li>
</ul>
<h3 id="2-유지보수가-용이함">2. 유지보수가 용이함</h3>
<ul>
<li>함수는 처음 선언할 때만 자세하게 기술하고, 나머지 함수들은 콜백 함수들이기에, 유지보수가 필요하면 최상단의 첫번째 함수만 수정하면 된다.<blockquote>
<pre><code>function 밥짓기() {
  코드...  // 여기만 수정하면 유지보수가 끝난다.
}
밥짓기()
밥짓기()
밥짓기()
밥짓기() * 100</code></pre></blockquote>
</li>
</ul>
<h3 id="3-구조-파악이-용이함">3. 구조 파악이 용이함</h3>
<ul>
<li>함수의 이름을 정할 때, 그 함수의 역할을 유추할 수 있는 이름을 지어주면, 협업이나 유지보수를 할 때, 해당 함수의 역할이나 전체적인 코드의 구조를 파악을 보다 수월하게 할 수 있다.<blockquote>
<pre><code>밥짓기() // 해당 함수가 밥을 짓기 위한 함수라는 것을 파악할 수 있음
국끓이기()
테이블 셋팅하기()
반찬덜기()
// 해당 코드는 식사준비를 위한 코드라는 것을 알 수 있음</code></pre></blockquote>
</li>
</ul>
<br>

<h2 id="4-2-함수의-구조-및-종류">4-2. 함수의 구조 및 종류</h2>
<h3 id="1-함수-선언문일반적인-함수형태">1. 함수 선언문(일반적인 함수형태)</h3>
<ul>
<li><p>가장 보편적인 함수의 형태로, 함수의 이름과 파라미터로 구성이 된다.</p>
</li>
<li><p><strong>파라미터(parameter)는 함수를 선언할때 사용하는 매개변수를 의미하며, 아규먼트(argument)는 함수에 입력받는 실제 값을 의미한다.</strong></p>
<blockquote>
<pre><code>function ein(a,b) {  // a와 b가 본 함수의 파라미터
  let z = a + b;
  return Z ** 2
}
console.log(ein(1,2)) // 1, 2가 해당 함수의 아규먼트</code></pre></blockquote>
<br>

</li>
</ul>
<h3 id="2-화살표-함수주로-실무에서-사용">2. 화살표 함수(주로 실무에서 사용!!)</h3>
<ul>
<li>표현방식이 간단하여 실무의 거의 모든 함수들이 화살표함수를 사용한다.</li>
<li>함수의 내부에서 한 줄 표현식만 반환하면, return 키워드 없이 한 줄로도 표현이 가능하다.<blockquote>
<pre><code>const zwei = (a,b) =&gt; (a + b) ** 2
// 만악 함수 실행시 전달하는 인자가 한 개라면 소괄호를 생략가능
const drei = a =&gt; a ** 2</code></pre></blockquote>
</li>
</ul>
<br>

<h3 id="3-익명-함수이름-없이-선언하는-함수">3. 익명 함수(이름 없이 선언하는 함수)</h3>
<ul>
<li><p>함수를 선언할 때, 따로 이름을 선언하지 않는 것을 의미한다.</p>
</li>
<li><p>이 경우, 변수명을 선언하여 사용한다.</p>
<blockquote>
<pre><code>cosnt vier = function (a,b) {
  let z = a + b;
  return Z ** 2
}
console.log(vier(1,2))  // 변수로 선언하여 다양하게 사용함</code></pre></blockquote>
<br>


</li>
</ul>
<h3 id="4-콜백함수">4. 콜백함수</h3>
<ul>
<li>외부에서 선언된 함수를 아규먼트에 작성하여 끌어오는 함수</li>
<li>함수의 순수성을 유지시키고, 코드 간결화에 큰 기여를 한다.</li>
<li>함수의 순수성은 하나의 함수에 하나의 함수만 작성되어 있는 것을 의미한다.<blockquote>
<pre><code>function funf(a,b,c) {
  let z = c(a,b) + c(a,b) // 여기서 ein(a,b)를 쓰면 함수의 순수성이 깨지는 것
  return z * 2
}
funf(7, 3, ein) // ein은 외부에서 선언된 함수명이다.</code></pre></blockquote>
</li>
</ul>
<br>

<h2 id="4-3-return과-consolelog의-차이">4-3. return과 console.log의 차이</h2>
<h3 id="1-return">1. return</h3>
<ul>
<li>return은 지시자라고 불리며, <strong>return을 만나면, 함수는 즉시 실행을 멈추고 함수를 호출하는 곳에 반환 값을 할당한다.</strong></li>
<li>return이 선언되지 않는 빈 함수는 undefined를 반환한다.</li>
<li>return만 선언되고 반환값이 없는 함수도 undefined를 반환한다.</li>
<li>return undefined도 undefined를 반환한다.<blockquote>
<pre><code>function hello1(){
  //빈 코드
}
function hello2(){
  return
}
function hello3(){
  return undefined
}
hello1() // undefined
hello2() // undefined
hello3() // undefined</code></pre></blockquote>
</li>
</ul>
<h3 id="2-consolelog">2. console.log</h3>
<ul>
<li>console은 웹 브라우저의 디버깅 콘솔에 접근 할 수 있게 하는 메서드들 제공하는 객체로, 아무전역객체에서 접근이 가능하다.</li>
<li>log는 웹 콘솔에 메시지를 출력해주는 메서드이다.</li>
<li>이 둘을 종합하면, console.log는 작성된 컨텐츠를 웹 콘솔에 출력해주는 메서드이기에, 함수내의 return과 같은 역할을 하지 못한다.<blockquote>
<pre><code>function hello4(){
  console.log(&#39;hello&#39;)
  console.log(&#39;hello&#39;)
  console.log(&#39;hello&#39;)
  return    // undefined 반환
  console.log(&#39;hello&#39;)
  console.log(&#39;hello&#39;)
  console.log(&#39;hello&#39;)
}
hello4()  // hello * 3</code></pre></blockquote>
</li>
</ul>
<br>

<h2 id="4-4-javascript-함수의-결점">4-4. JavaScript 함수의 결점</h2>
<ul>
<li>아규먼트가 파라미터보다 적거나 많아도 오류를 출력하지 않는다는 단점이 있다.<blockquote>
<pre><code>function 함수1(a, b, c){
  return a + b + c
}
함수1(10, 20, 30, 40) // 60 // error가 발생하지 않는다. 
함수1(10, 20)  // 30 // error가 발생하지 않는다.</code></pre></blockquote>
</li>
</ul>
<br>

<h2 id="4-5-함수의-특이점">4-5. 함수의 특이점</h2>
<ul>
<li>파라미터에 값을 미리 선언할 수 있다.</li>
<li>단, 아규먼트에서 값을 고정하더라도, <strong>반환값 변수의 순서대로 고정된다.</strong><blockquote>
<pre><code>function 함수1(a=10, b=20, c=30){
  return a + b + c
}
함수1(1, 1) // 32
// a와 c에 들어갈 것이라 생각했지만, a와 b에 들어감
function 함수1(a=10, b=20, c=30){
  return a + b + c
}
함수1(a=1, c=1) // 32</code></pre></blockquote>
</li>
</ul>
<br>

<h2 id="4-6-즉시-실행-함수">4-6. 즉시 실행 함수</h2>
<pre><code>(function() {
    console.log(&#39;이 함수는 만들어지자마자 바로 실행됩니다!&#39;);
  })();

function 함수(){

}

함수()</code></pre>]]></description>
        </item>
    </channel>
</rss>