<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>strong-minsu.log</title>
        <link>https://velog.io/</link>
        <description>빙글빙글</description>
        <lastBuildDate>Wed, 30 Aug 2023 04:09:45 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>strong-minsu.log</title>
            <url>https://velog.velcdn.com/images/strong-minsu/profile/66b14e8a-3a7f-4e35-bd17-2e07f7f273c3/social_profile.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. strong-minsu.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/strong-minsu" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[PWA 세팅]]></title>
            <link>https://velog.io/@strong-minsu/PWA-%EC%84%B8%ED%8C%85</link>
            <guid>https://velog.io/@strong-minsu/PWA-%EC%84%B8%ED%8C%85</guid>
            <pubDate>Wed, 30 Aug 2023 04:09:45 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p>Progressive Web App (PWA)
vite(typescript)에서 pwa 세팅</p>
<hr>

<h2 id="📌pwa-">📌PWA ?!</h2>
<p>이번 프로젝트에서 웹 말고 사용자가 앱으로도 접근할 수 있다면 좋을 것 같다는 의견이 나와서 pwa를 찾아보게 되었습니다.!</p>
<p><img src="https://velog.velcdn.com/images/strong-minsu/post/707f890e-bb50-4ad4-abe9-b52227851a12/image.png" alt=""></p>
<p>Progressive Web App (PWA)는 웹 앱과 네이티브 앱의 장점을 결합한 형태의 웹 앱입니다. 
프로젝트가 아직은 시작 단계에 불과해서 초기 세팅 정도 진행을 했습니당..</p>
<p>더 많은 내용은 <a href="https://developer.mozilla.org/ko/docs/Web/Progressive_web_apps/Tutorials/js13kGames">pwa 관련 mdn web docs</a> 에서 확인할 수 있습니다~</p>
<hr>

<h2 id="간단하게-과정-정리">간단하게 과정 정리</h2>
<h3 id="1-vite-세팅">1. vite 세팅</h3>
<p>아래 명령어를 통해 typescript로 세팅된 react 프로젝트를 얻을 수 있습니다!</p>
<blockquote>
<p>npm create vite@latest [프로젝트 명] -- --template react-ts</p>
</blockquote>
<p> 아래 vite 명령을 통해 바로 Vite를 실행할 수 있습니다</p>
<pre><code>{
  &quot;scripts&quot;: {
    &quot;dev&quot;: &quot;vite&quot;, 
    &quot;build&quot;: &quot;vite build&quot;, 
    &quot;preview&quot;: &quot;vite preview&quot; 
  }
}</code></pre><blockquote>
</blockquote>
<ul>
<li>dev: 개발 서버를 실행합니다. (<code>vite dev</code> 또는 <code>vite serve</code>로도 시작이 가능합니다.)</li>
<li>build: 배포용 빌드 작업을 수행합니다.</li>
<li>preview: 로컬에서 배포용 빌드에 대한 프리뷰 서버를 실행합니다.</li>
</ul>
<h3 id="2-pwa-세팅">2. PWA 세팅</h3>
<h4 id="1-pwa-사용전-모바일에서-보여줄-아이콘을-준비">(1). pwa 사용전 모바일에서 보여줄 아이콘을 준비</h4>
<p>(아이콘이 없을 시.. 오류가 발생할 수 있습니다.)</p>
<ul>
<li><p>아이콘 변환 사이트에서 다양한 크기의 아이콘을 준비합니다. 
(<strong>512x512 크기 이상의 아이콘이 있어야 오류 없음!</strong>)</p>
</li>
<li><p>저는 <a href="https://favicon.io/favicon-converter/">https://favicon.io/favicon-converter/</a> 여기서 변환을 진행했습니다~ </p>
</li>
<li><p>변환된 아이콘, + 이미지 중에서 필요한 것들만 public/icons에 담아 줍니다.
<img src="https://velog.velcdn.com/images/strong-minsu/post/1b830751-9aa8-4532-9eef-7e2a7b0cc398/image.png" alt=""></p>
</li>
</ul>
<h4 id="2-manifestjson-파일-설정">(2). manifest.json 파일 설정</h4>
<ul>
<li>public 디렉토리에 manifest.json 파일 생성 후, 앱 정보를 작성합니다.</li>
</ul>
<blockquote>
<p>웹앱 매니페스트란 앱에 대한 정보를 담고 JSON 파일이입니다. 배경색은 어떠한 색인지, 앱의 이름은 무엇인지, 홈스크린 화면에 추가할 때 아이콘은 어떤 것인지 등의 정보를 담고 있습니다. 웹앱 매니페스트는 manifest.json 파일명을 대부분 사용합니다.</p>
</blockquote>
<ul>
<li>short_name : 사용자 홈 화면에서 아이콘 이름으로 사용</li>
<li>name : 웹앱 설치 배너에 사용</li>
<li>icons : 홈 화면에 추가할때 사용할 이미지</li>
<li>start_url : 웹앱 실행시 시작되는 URL 주소</li>
<li>display : 디스플레이 유형(fullscreen, standalone, browser 중 설정)</li>
<li>theme_color : 상단 툴바의 색상</li>
<li>background_color : 스플래시 화면 배경 색상</li>
<li>orientation : 특정 방향을 강제로 지정(landscape, portrait 중 설정)</li>
</ul>
<p>저는 테스트여서 간단하게 작성했어용~ 아이콘 크기를 잘 맞춰주시면 될 것 같습니당!! (512x512~~)</p>
<pre><code>{
  &quot;name&quot;: &quot;webappName&quot;,
  &quot;short_name&quot;: &quot;Name&quot;,
  &quot;start_url&quot;: &quot;&quot;,
  &quot;display&quot;: &quot;standalone&quot;,
  &quot;background_color&quot;: &quot;#FFFFFF&quot;,
  &quot;theme_color&quot;: &quot;#FFFFFF&quot;,
  &quot;description&quot;: &quot;PWA test&quot;,
  &quot;icons&quot;: [
    {
      &quot;src&quot;: &quot;icons/favicon.ico&quot;,
      &quot;sizes&quot;: &quot;64x64 32x32 24x24 16x16&quot;,
      &quot;type&quot;: &quot;image/x-icon&quot;
    },
    {
      &quot;src&quot;: &quot;icons/android-chrome-192x192.png&quot;,
      &quot;type&quot;: &quot;image/png&quot;,
      &quot;sizes&quot;: &quot;192x192&quot;
    },
    {
      &quot;src&quot;: &quot;icons/android-chrome-512x512.png&quot;,
      &quot;type&quot;: &quot;image/png&quot;,
      &quot;sizes&quot;: &quot;512x512&quot;
    },
    {
      &quot;src&quot;: &quot;icons/android-chrome-512x512.png&quot;,
      &quot;type&quot;: &quot;image/png&quot;,
      &quot;sizes&quot;: &quot;512x512&quot;,
      &quot;purpose&quot;: &quot;any maskable&quot;
    }
  ]
}</code></pre><p><img src="https://velog.velcdn.com/images/strong-minsu/post/260afc0e-b682-4def-b21a-772b54271996/image.png" alt=""></p>
<h4 id="3-swjs-파일-설정">(3) sw.js 파일 설정</h4>
<p>service worker에 대해.. 잘 모르지만, 아래와 같이 간단하게 보고 넘어가 봅니다.. ㅠㅁㅠ~ </p>
<blockquote>
<p>서비스 워커(sw.js) 파일은 웹 페이지와 별도로 브라우저가 백그라운드에서 실행되는 스크립트로, 웹 페이지나 사용자 상호 작용이 필요하지 않은 기능을 제공합니다.     </p>
</blockquote>
<ul>
<li>관련 mdn 문서 
<a href="https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers">https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers</a></li>
</ul>
<p>sw.js 파일 설정은 다음과 같이 간단하게.. 틀만 넣었습니다.! (참고블로그 보고..)</p>
<ul>
<li>루트 디렉토리에 sw.js 파일 생성 후, 아래와 같이 Service Worker 설정 코드 작성합니다.<pre><code>// sw.js
</code></pre></li>
</ul>
<p>// install event
self.addEventListener(&#39;install&#39;, e =&gt; {
  // console.log(&#39;[Service Worker] installed&#39;);
});</p>
<p>// activate event
self.addEventListener(&#39;activate&#39;, e =&gt; {
  // console.log(&#39;[Service Worker] actived&#39;, e);
});</p>
<p>// fetch event
self.addEventListener(&#39;fetch&#39;, e =&gt; {
  // console.log(&#39;[Service Worker] fetched resource &#39; + e.request.url);
});</p>
<p>// 등등 앱에 따라 pwa 기능을 추가하고 sw.js에 작성할 수 있습니다.</p>
<pre><code>

#### (4). index.html 파일 수정
- index.html 파일 내부에 메타 정보와 sw.js를 불러오는 스크립트 추가합니다.
</code></pre><!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <!-- 아이콘 link 설정 -->
    <link rel="icon" href="icons/android-chrome-192x192.png" type="image/png" />
    <link rel="alternate icon" href="/favicon.ico" type="ico" sizes="16x16" />
    <link rel="apple-touch-icon" href="icons/apple-touch-icon.png" sizes="180x180" />

<pre><code>&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
&lt;link rel=&quot;manifest&quot; href=&quot;/manifest.json&quot; /&gt;
&lt;title&gt;pwa test&lt;/title&gt;</code></pre>  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
    <!-- pwa sw.js 정보 줄러오는 스크립트 추가 -->
    <script>
      if ('serviceWorker' in navigator) {
        // Register a service worker hosted at the root of the
        // site using the default scope.
        navigator.serviceWorker
          .register('/sw.js')
          .then(registration => {
            console.log('Service worker registration succeeded:', registration);
          })
          .catch(err => {
            console.log('Service worker registration failed:', error);
          });
      } else {
        console.log('Service workers are not supported.');
      }
    </script>
  </body>
</html>

<p>```</p>
<p>이렇게 끝내고 나서 npm run dev를 통해 로컬 서버를 실행하면!?
<img src="https://velog.velcdn.com/images/strong-minsu/post/5b2c1caa-fbf1-4eb7-afb7-582821b237a3/image.png" alt="">
요롷게 번역 아이콘 옆에 모니터 다운로드 (?) 아이콘이 생깁니다..! </p>
<p>우선은 이정도로 진행을 한 상태이고 정말 세팅만 !.. 끝내서 Lighthouse를 통한 검사는 페이지 작업이 완료되면 진행해 보려고 합니당..!</p>
<p>간단한 세팅정도를 프로젝트 진입전에 진행해 보았어요~~ 뿌듯합니당.! 프로젝트가 끝나고 가능하면 검사까지 완료된 상태와 배포 상태도 업데이트 해보겠습닏낭!!! </p>
<p>아래 글 보고 거의 따라한 수준이랍니다..~ 그래도 새로운 내용을 알게 되어서 좋네요~!! ㅎㅎ 여기서 더 발전하는 글이 올라오길 기대하면서.. 총총...</p>
<blockquote>
<p>참고 
<a href="https://velog.io/@boorook/Vite-React-TypeScript-PWA-%EB%A7%8C%EB%93%A4%EA%B8%B0-AWS-Amplify-%EB%B0%B0%ED%8F%AC">https://velog.io/@boorook/Vite-React-TypeScript-PWA-%EB%A7%8C%EB%93%A4%EA%B8%B0-AWS-Amplify-%EB%B0%B0%ED%8F%AC</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[React 데이터 흐름]]></title>
            <link>https://velog.io/@strong-minsu/React-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%9D%90%EB%A6%84</link>
            <guid>https://velog.io/@strong-minsu/React-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%9D%90%EB%A6%84</guid>
            <pubDate>Thu, 29 Jun 2023 15:06:27 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p>리액트 데이터 흐름</p>
<blockquote>
<p>💡 When you have faults, do not fear to abandon them.</p>
</blockquote>
<hr>

<h2 id="📌-react-props--state">📌 React Props &amp; State</h2>
<p>간단하게 정리하면 state는 내부에서 변화하는 값, props는 외부로부터 전달 받은 값!</p>
<h3 id="🔍-props">🔍 Props</h3>
<blockquote>
<p>외부로부터 전달받은 값!</p>
</blockquote>
<p><strong>Props의 특징</strong></p>
<ul>
<li><p>컴포넌트의 속성(property)를 의미한다. 
변하지 않는 외부토부터 전달받은 값으로, 웹 애플리케이션에서 해당 컴포넌트가 가진 속성에 해당한다.</p>
</li>
<li><p>부모 컴포넌트(즉 상위 컴포넌트)로부터 전달받은 값이다.
React 컴포넌트는 JavaScript 함수와 클래스로, props를 함수의 전달인자 처럼 전달하고 전달받을 수 있다. 이를 기반으로 화면에 어떻게 표시되는지를 기술하는 React 엘리먼트를 반환한다. </p>
</li>
<li><p>객체 형태이다. {어떤 타입의 값 상관 없이 전달 할 수 있음}</p>
</li>
<li><p>Props는 읽기 전용!
외부로부터 전달받기 때문에 <strong>함부로 변경될 수 없는 읽기 전용(Read-only)</strong>이다.</p>
<blockquote>
<p>읽기 전용 객체가 아니라면 props를 전달받은 하위 컴포넌트 내에서 props를 직접 수정 시 props를 전달한 상위 컴포넌트의 값에 영향을 미칠 수 있게 됩니다. 즉, 개발자가 의도하지 않은 side effect가 생기게 되어  React의 단방향, 하향식 데이터 흐름 원칙(React is all about one-way data flow down the component hierarchy)에 위배된다.</p>
</blockquote>
</li>
</ul>
<h3 id="🔍-props-사용">🔍 Props 사용</h3>
<p>props를 사용하는 방법은 다음과 같다.</p>
<ol>
<li><p>하위 컴포넌트에 전달하고자 하는 값(data)과 속성을 정의한다.</p>
</li>
<li><p>props를 이용하여 정의된 값과 속성을 전달한다.</p>
</li>
<li><p>전달받은 props를 렌더링한다.</p>
</li>
</ol>
<pre><code class="language-javascript">function Parent() {
  return (
    &lt;div className=&quot;parent&quot;&gt;
      &lt;h1&gt;I&#39;m the parent&lt;/h1&gt;
    //Child 컴포넌트에 text Props를 전달
      &lt;Child text={&quot;I&#39;m the eldest child&quot;} /&gt;
    &lt;/div&gt;
  );
}

function Child(props) {  //props객체 안에 text 속성이 있다!
  console.log(&quot;props : &quot;, props);
  //props :  {text: &quot;I&#39;m the eldest child&quot;}
  return (
    &lt;div className=&quot;child&quot;&gt;
      &lt;p&gt;{props.text}&lt;/p&gt;
        //&quot;I&#39;m the eldest child&quot; &lt;- 화면에 출력됨
    &lt;/div&gt;
  );
}

export default Parent;
</code></pre>
<hr>

<h3 id="🔍-state">🔍 State</h3>
<p>내부에서 변하는 값</p>
<ul>
<li>컴포넌트 내부에서 변할 수 있는 값! 화면에 변화를 주는 값은 React state로 다뤄야한다.</li>
<li>useState hook 사용!</li>
</ul>
<h3 id="🔍-usestate-사용법">🔍 useState 사용법</h3>
<ul>
<li>useState를 이용하기 위해서는 React로부터 useState를 불러와야 한다. import 키워드로 useState를 불러온다</li>
</ul>
<pre><code class="language-javascript">import { useState } from &quot;react&quot;;</code></pre>
<ul>
<li><p>이후 useState를 컴포넌트 안에서 호출한다 useState를 호출한다는 것은 &quot;state&quot;라는 변수를 선언하는 것과 같다. useState는 state저장변수와 state 갱신함수를 가진 배열을 반환한다. </p>
<blockquote>
<p>(const [state 저장 변수, state 갱신 함수] = useState(초기값)</p>
</blockquote>
</li>
<li><p>일반적인 변수는 함수가 끝날 때 사라지지만, state 변수는 React에 의해 함수가 끝나도 사라지지않는다.</p>
</li>
<li><p>문법적으로 보면 아래 예시의 isChecked, setIsChecked는 useState의 리턴값을 구조 분해 할당한 변수입니다.</p>
</li>
</ul>
<pre><code class="language-javascript">function CheckboxExample() {
// 새로운 state 변수를 선언하고, 여기서는 이것을 isChecked라 부르겠습니다.
  const [isChecked, setIsChecked] = useState(false);
}</code></pre>
<ul>
<li>state를 갱신하려면 state 변수를 갱신할 수 있는 함수인 setIsChecked를 호출합니다.<pre><code class="language-javascript">setIsChecked(&quot;갱신할 값&quot;);</code></pre>
</li>
<li><em>React state는 반드시 상태 변경 함수 호출로 변경해야 한다.*</em></li>
</ul>
<hr>

<h2 id="📌-react-데이터-흐름">📌 React 데이터 흐름</h2>
<p>React의 개발 방식의 가장 큰 특징은 페이지 단위가 아닌, 컴포넌트 단위로 시작한다는 점이다.</p>
<p>컴포넌트는 컴포넌트 바깥에서(외부) props를 이용해 데이터를 마치 인자(arguments) 혹은 속성(attributes)처럼 전달받을 수 있다. 데이터를 전달하는 주체는 부모 컴포넌트가 된다. </p>
<p><strong>이는 데이터의 흐름이 하향식(top-down)임을 의미한다.</strong></p>
<blockquote>
<p>React 프로젝트의 메인 페이지를 보면, &quot;one-way reactive data flow&quot; 라고 설명이 되어 있습니다. 즉, React의 데이터 흐름은 단방향이고, Reactive하다는 특징을 가지고 있습니다. 좀 더 설명하면, 이전 글에서도 설명했듯이 데이터는 Parent로부터 Child로 흐르며, 데이터의 갱신에 반응하여 뷰 또한 갱신됩니다.</p>
</blockquote>
<hr>

<h2 id="✨-마무리">✨ 마무리</h2>
<p>프로젝트 전 복습 겸 블로깅을 하고있는 나! 제법 멋지다~</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[REST API]]></title>
            <link>https://velog.io/@strong-minsu/REST-API</link>
            <guid>https://velog.io/@strong-minsu/REST-API</guid>
            <pubDate>Mon, 05 Jun 2023 02:00:56 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p>Unit8 [HTTP/네트워크]실습</p>
<blockquote>
<p>💡 Slow and steady win the race.</p>
</blockquote>
<hr>

<h2 id="📌-rest-api">📌 REST API</h2>
<p>REST (Representational State Transfer) API는 웹 기반의 소프트웨어 아키텍처 스타일 중 하나로, 클라이언트와 서버 간의 통신을 위한 표준화된 방법을 제공하는 인터페이스이다.</p>
<p><strong>REST(Representational State Transfer) API는 웹에서 사용되는 모든 데이터나 자원(Resource)을 HTTP URI로 표현한다.</strong></p>
<blockquote>
<p>API는 클라이언트와 서버 사이에도 데이터와 리소스를 요청하고, 요청에 따른 응답을 전달하기 위해 사용된다. 이 API를 보고 클라이언트는 서버에 요구사항을 요청하고, 이에 대한 응답을 서버에서 클라이언트로 전송한다.</p>
</blockquote>
<p>HTTP 프로토콜을 기반으로 요청과 응답에 따라 리소스를 주고받기 위해서는 알아보기 쉽고 잘 작성된 API가 필요하다.</p>
<h3 id="🔍-rest-api의-구성">🔍 REST API의 구성</h3>
<table>
<thead>
<tr>
<th>구성요소</th>
<th>내용</th>
<th>표현 방법</th>
</tr>
</thead>
<tbody><tr>
<td>자원(resource)</td>
<td>자원</td>
<td>URL(엔드포인트)</td>
</tr>
<tr>
<td>행위(verb)</td>
<td>자원에 대한 행위</td>
<td>HTTP 요청메소드</td>
</tr>
<tr>
<td>표현(representations)</td>
<td>자원에 대한 행위의 구체적 내용</td>
<td>페이로드</td>
</tr>
</tbody></table>
<br>

<h3 id="🔍-rest-api의-성숙도-단계">🔍 REST API의 성숙도 단계</h3>
<ul>
<li><h4 id="✨-0-단계-http-사용-">✨ 0 단계: HTTP 사용 !</h4>
단순 HTTP 프로토콜을 사용하는 것 (요청, 응답)
→ 사실상 REST API라고 할 수 없다..</li>
</ul>
<blockquote>
<p>이 단계에서는 REST 원칙을 따르지 않는 기본적인 HTTP 기반 웹 서비스를 제공한다.
XML 기반의 SOAP(Simple Object Access Protocol)과 유사한 방식으로 데이터를 주고받는다.
HTTP 메서드와 상태 코드를 제대로 활용하지 않으며, 리소스 식별에 경로 대신 쿼리 문자열을 사용할 수도 있다.</p>
</blockquote>
<br>


<ul>
<li><h4 id="✨-1-단계-개별-리소스와-통신-준수-">✨ 1 단계: 개별 리소스와 통신 준수 !</h4>
개별 리소스(Resource)와의 통신을 준수해야 한다.
  모든 자원은 개별 리소스에 맞는 엔드포인트(Endpoint)를 사용해야 하며 요청하고 받는 자원에 대한 정보를 응답으로 전달해야한다.</li>
</ul>
<p><strong>1단계에서는 요청하는 리소스가 무엇인지에 따라 각기 다른 엔드포인트로 구분하여 사용한다.</strong></p>
<blockquote>
<p>이 단계에서는 API에 리소스 개념을 도입하여 RESTful한 아키텍처의 기본 원리를 적용한다.
리소스 개념은 클라이언트가 접근하고 조작할 수 있는 추상적인 개체를 나타낸다.
리소스에 고유한 URI를 할당하고, URI를 통해 리소스에 접근하고 조작한다.
여전히 HTTP 메서드와 상태 코드를 제대로 활용하지 않을 수 있다.</p>
</blockquote>
<p>💡 엔드포인트 작성 시에는 동사, HTTP 메서드, 혹은 어떤 행위에 대한 단어 사용은 지양하고, <strong>리소스</strong>에 집중해 명사 형태의 단어로 작성하는 것이 바람직한 방법이다.</p>
<br>


<ul>
<li><h4 id="✨-2-단계-http-메소드-원칙-준수-">✨ 2 단계: HTTP 메소드 원칙 준수 !</h4>
<p>2단계에서는 CRUD에 맞게 적절한 HTTP 메서드를 사용하는 것에 중점 (CRUD(Create, Read, Update, Delete))</p>
<p> <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods">HTTP 메서드</a>를 사용할 때 몇 가지 규칙에도 유의해야 한다.</p>
</li>
</ul>
<blockquote>
<p> 이 단계에서는 HTTP 메서드를 적절하게 활용하여 리소스를 조작한다.
HTTP GET, POST, PUT, DELETE 등의 메서드를 사용하여 리소스의 조회, 생성, 수정, 삭제 작업을 수행한다.
상태 코드를 올바르게 활용하여 작업 결과를 클라이언트에게 반환한다.
Hypermedia(하이퍼미디어) 기능을 도입하여 API에 관련 리소스 간의 탐색을 쉽게 할 수도 있다.</p>
</blockquote>
<p><span style="background-color:#FFFACD ;color:black">API를 작성할 때, REST 성숙도 모델의 2단계까지 적용하면 대체적으로 잘 작성된 API이다.</span></p>
<br>


<ul>
<li><h4 id="✨-3-단계-hateoas-원칙-준수-">✨ 3 단계: HATEOAS 원칙 준수 !</h4>
</li>
<li><em>HATEOAS(Hypermedia As The Engine Of Application State)*</em>라는 약어로 표현되는 하이퍼미디어 컨트롤을 적용한다. 3단계의 요청은 2단계와 동일하지만, 응답에는 리소스의 URI를 포함한 <strong>링크</strong> 요소를 삽입하여 작성해야 한다.</li>
</ul>
<p>응답에 들어가게 되는 링크 요소는 응답을 받은 다음에 할 수 있는 다양한 액션들을 위해 많은 하이퍼미디어 컨트롤을 포함하고 있다.</p>
<blockquote>
<p>이 단계에서는 하이퍼미디어를 최대한 활용하여 API의 탐색과 상호작용을 촉진한다.
API 응답에 링크와 같은 추가 정보를 포함시켜 클라이언트가 API를 탐색하고 사용할 수 있게 한다.
클라이언트는 링크를 따라가며 새로운 리소스를 발견하고 API와 상호작용한다.
하이퍼미디어 제공을 통해 클라이언트와 서버 간의 느슨한 결합을 달성한다.</p>
</blockquote>
<br>


<h3 id="🔍-rest-api의-설계-원칙">🔍 REST API의 설계 원칙</h3>
<ul>
<li><strong>리소스 중심 (Resource-Centric)</strong>: API는 리소스를 중심으로 설계되어야 한다. 리소스는 클라이언트가 접근하고 조작할 수 있는 추상적인 개체를 나타낸다. 각 리소스는 고유한 식별자(URI)를 가지며, 클라이언트는 URI를 사용하여 리소스에 접근하고 조작한다.<pre><code class="language-javascript">//리소스를 식별할 수 있는 이름은 동사보단 명사를 사용한다.
#Bad
GET /getTodos/1
</code></pre>
</li>
</ul>
<p>#Good
GET /todos/1</p>
<pre><code>
- **HTTP 메서드 활용 (HTTP Method Usage)**: HTTP 메서드는 API의 작업을 수행하는 데 사용된다. 가장 일반적으로 사용되는 메서드는 GET(조회), POST(생성), PUT(수정), DELETE(삭제)다. 각 메서드는 해당하는 작업을 수행하기 위해 정의된 의미를 가지고 있으며, 적절한 메서드를 사용하여 리소스를 조작해야 한다.
```javascript
//리소스에 대한 행위는 HTTP 요청 메서드를 통해 표현하며 URL에 표현하지 않는다.
#Bad
GET /todos/delete/1

#Good
DELETE /todos/1</code></pre><h3 id="🔍-rest-api의-특징">🔍 REST API의 특징</h3>
<ol>
<li><p>리소스 기반: API의 핵심 개념은 리소스이다. 리소스는 웹에서 접근 가능한 개체로써, 데이터 또는 기능을 나타낸다. 각 리소스는 고유한 식별자(URI)를 가지며, 클라이언트는 URI를 사용하여 리소스에 접근하고 조작한다.</p>
</li>
<li><p>HTTP 메서드 활용: REST API는 HTTP의 다양한 메서드를 사용하여 리소스를 조작한다. 가장 일반적으로 사용되는 메서드는 GET(조회), POST(생성), PUT(수정), DELETE(삭제)다. 각 메서드는 해당하는 작업을 수행하기 위해 정의된 의미를 가지고 있다.</p>
</li>
<li><p>상태 없음(Statelessness): REST API는 상태를 관리하지 않는다. 즉, 서버는 각 요청을 개별적으로 처리하고 클라이언트의 상태를 유지하지 않는다. 이는 서버의 확장성과 클라이언트-서버의 느슨한 결합을 가능하게 한다.</p>
</li>
<li><p>자체 서술적 메시지(Self-descriptive messages): REST API는 요청과 응답의 메시지 자체가 어떤 동작을 수행하는지 명확하게 설명할 수 있어야 한다. 이는 메시지에 포함된 헤더와 페이로드를 통해 이루어진다.</p>
</li>
</ol>
<br>

<h3 id="🔍-rest-api의-아주-간단한-예시">🔍 REST API의.. 아주 간단한! 예시</h3>
<p>아래 몇가지 REST API 예시..! 너무 추상적인 생각이 들 때! 참고..!!</p>
<ol>
<li><p>블로그 게시물 API:
◾ GET /posts: 모든 게시물 가져오기
◾ GET /posts/{id}: 특정 게시물 가져오기
◾ POST /posts: 새로운 게시물 생성
◾ PUT /posts/{id}: 특정 게시물 수정
◾ DELETE /posts/{id}: 특정 게시물 삭제</p>
</li>
<li><p>사용자 관리 API:
◾ GET /users: 모든 사용자 가져오기
◾ GET /users/{id}: 특정 사용자 가져오기
◾ POST /users: 새로운 사용자 생성
◾ PUT /users/{id}: 특정 사용자 수정
◾ DELETE /users/{id}: 특정 사용자 삭제</p>
</li>
<li><p>날씨 정보 API:
◾ GET /weather: 현재 날씨 정보 가져오기
◾ GET /weather/{city}: 특정 도시의 날씨 정보 가져오기</p>
</li>
</ol>
<hr>

<h2 id="✨-마무리">✨ 마무리</h2>
<p>오랜만에 블로깅! .. 너무 오랜만인가ㅏ~ 우하핫 열심히 복습해야지!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로토타입 체인]]></title>
            <link>https://velog.io/@strong-minsu/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-%EC%B2%B4%EC%9D%B8</link>
            <guid>https://velog.io/@strong-minsu/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-%EC%B2%B4%EC%9D%B8</guid>
            <pubDate>Fri, 12 May 2023 14:37:45 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p>이전..글에 이어서! 프로토타입 체인에 대한 내용! &lt;- 진짜 어렵다.. <a href="http://www.yes24.com/Product/Goods/92742567">모던 자바스크립트 deep dive</a> 참조</p>
<blockquote>
<p>💡 When you hace a dream, you&#39;ve got to grab it and never let go.</p>
</blockquote>
<hr>

<h2 id="📌-프로토타입-체인">📌 프로토타입 체인</h2>
<h3 id="프로토타입-체인">프로토타입 체인?!</h3>
<p>이 전의 글 마지막에 <code>__proto__</code>를 이용하여 인스턴스의 프로토타입, 그 프로토타입의 프로토타입을 체인의 끝인 Object까지 확인할 수 있다... 고 하였는데 이를 이용하여 JavaScript는 상속을 구현한다.!</p>
<blockquote>
<p>객체 지향 프로그래밍의 특성 중 상속을 JavaScript에서 구현할 때에는 프로토타입 체인을 사용한다.</p>
</blockquote>
<ul>
<li><p>JavaScrip는 특정 객체의 프로퍼티나 메소드에 접근시 객체 자신의 것뿐 아니라 <code>__proto__</code>가 가리키는 링크를 따라서 자신의 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 접근할 수 있다.</p>
</li>
<li><p>특정 객체의 프로퍼티나 메소드 접근시 만약 현재 객체의 해당 프로퍼티가 존재하지 않는다면 <code>__proto__</code>가 가리키는 링크를 따라 부모 역할을 하는 프로토타입 객체의 프로퍼티나 메소드를 차례로 검색하는 것이 바로 프로토타입 체인이다.</p>
</li>
<li><p>모든 프로토타입 체이닝의 종점은 Object.prototype이다.</p>
</li>
<li><p>하위 객체는 상위 객체의 프로퍼티나 메소드를 상속받는 것이 아니라 공유한다.</p>
</li>
<li><p>해당 객체에 없는 프로퍼티나 메소드를 접근할 때 프로토타입 체이닝이 일어난다.</p>
</li>
</ul>
<pre><code class="language-javascript">function Person(name) {
  this.name = name;
}

//프로토타입 메서드
Person.prototype.sayHello = function() {
  console.log(`Hi! my name is ${this.name}`);
};

const me = new Person(&#39;Lee&#39;);

console.log(me.hasOwnProperty(&#39;name&#39;); //true</code></pre>
<p>위의 예제에서 Person 생성자 함수에 의해 생성된 me 객체가 hasOwnProperty를 호출할 수 있는 이유는 Person.prototype뿐만 아니라 Object.prototype도 상속 받았기 때문이다. 프로토타입 체인을 그림으로 표현하면 아래와 같다. </p>
<p><img src="https://velog.velcdn.com/images/strong-minsu/post/730898ab-9717-4259-a222-1307bc837aaa/image.png" alt=""></p>
<blockquote>
<p>프로토타입 체인은 자바스크립트가 객체 지향 프로그래밍의 상속을 구현하는 메커니즘이다.</p>
</blockquote>
<br>

<h3 id="dom을-이용하여-만든-div-요소를-통해-프로토타입-체인-확인하기">DOM을 이용하여 만든 div 요소를 통해 프로토타입 체인 확인하기!</h3>
<pre><code class="language-javascript">let div = document.createElement(&#39;div&#39;);

console.log(div.__proto__)
console.log(div.__proto__.__proto__)
console.log(div.__proto__.__proto__.__proto__)
console.log(div.__proto__.__proto__.__proto__.__proto__)
console.log(div.__proto__.__proto__.__proto__.__proto__.__proto__)
console.log(div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__)
console.log(div.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__.__proto__)</code></pre>
<p><img src="https://velog.velcdn.com/images/strong-minsu/post/2be490fb-be37-4839-9d0d-0a19566dbe40/image.png" alt=""></p>
<hr>

<h2 id="✨-마무리">✨ 마무리</h2>
<p>아..~ 이해가 될랑말랑... 으으으 조금 답답한 상태지만 객체 지향의 상속을 Java와 조금 다른 방식으로 구현한다는 것을 이해한 것 같다.! 그래ㅐ도 많이 이해했다..! 깊게 들어가면 너무 어렵지만, 이 부분은 중요한 부분이기 때문에!!! 열심히 공부해봐야겟다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로토타입]]></title>
            <link>https://velog.io/@strong-minsu/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85</link>
            <guid>https://velog.io/@strong-minsu/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85</guid>
            <pubDate>Fri, 12 May 2023 13:53:38 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p>프로토타입에 대한 내용을 다뤄봅니다.! &lt;- 어렵 ㅠㅁㅠ <a href="http://www.yes24.com/Product/Goods/92742567">모던 자바스크립트 deep dive</a> 참조</p>
<blockquote>
<p>💡 I am not afraid of storms for I am learning how to sail my ship.</p>
</blockquote>
<hr>

<h2 id="📌-프로토타입">📌 프로토타입</h2>
<p>JavaScript는 프로토타입을 기반으로 상속을 구현하여 불필요한 증복을 제거할 수 있다.
중복을 제거하는 방법은 기존의 코드를 적극적으로 재사용하는 것이다. (코드를 재사용하는 것은 개발 비용을 줄일 수 있는 중요한 부분이다.)</p>
<h3 id="prototype-프로토타입">prototype 프로토타입</h3>
<p>프로토 타입은 어떤 객체의 상위(부모)객체의 역할을 하는 객체로서 다른 객체에 공유 프로퍼티(메서드 포함)을 제공한다.</p>
<p>모든 객체는 하나의 프로토 타입을 갖고 모든 프로토타입은 생성자 함수와 연결되어 있다. 
<img src="https://velog.velcdn.com/images/strong-minsu/post/98867e10-3d89-4357-814a-597fb9991f0d/image.png" alt=""></p>
<br>

<h3 id="__proto__-접근자-프로퍼티"><code>__proto__</code> 접근자 프로퍼티</h3>
<p><strong>모든 객체는 <code>__proto__</code> 접근자 프로퍼티를 통해 자신의 프로토타입, 즉 [[Prototype]] 내부 슬롯에 간접적으로 접근할 수 있다.</strong></p>
<blockquote>
<p><code>__proto__</code> 접근자 프로퍼티는 객체가 직접 소유하는 프로퍼티가 아니라 Object.prototype의 프로퍼티이다. 모든 객체는 상속을 통해 <code>Object.prototype.__proto__</code> 접근자 프로퍼티를 사용할 수 있다.</p>
</blockquote>
<p>접근자 프로퍼티를 사용하는 이유는 상호 참조에 의해 프로토타입 체인이 생성되는 것을 방지하기 위해서이다.</p>
<pre><code class="language-javascript">const parent = {};
const child = {}

child.__proto__ = parent;
parent.__proto__ = child; //&lt;- TypeError
//프로토타입 체인의 종점이 없어짐</code></pre>
<p>프로토타입 체인은 단방향 링크드 리스트로 구형되어야한다.</p>
<p>함수 객체가 소유하는 <strong>prototype 프로퍼티는 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킨다.</strong> 따라서 생성자 함수를 호출할 수 없는 non-constructor함수와 화살표 함수, 메서드 축약 표현으로 정의한 메서드는 protopype 프로퍼티를 소유하지 않으며 프로토타입도 생성하지 않는다.</p>
<table>
<thead>
<tr>
<th>구분</th>
<th>소유</th>
<th>값</th>
<th>사용 주체</th>
<th>사용 목적</th>
</tr>
</thead>
<tbody><tr>
<td><code>__proto__</code> <br>접근자 프로퍼티</td>
<td>모든 객체</td>
<td>프로토타입의 참조</td>
<td>모든 객체</td>
<td>객체가 자신의 프로토타입에 접근 또는 교체하기 위해</td>
</tr>
<tr>
<td>prototype <br>프로퍼티</td>
<td>constructor</td>
<td>프로토타입의 참조</td>
<td>생성자 함수</td>
<td>생성자 함수가 자신이 생성할 객체(인스턴스)의 프로토타입을 할당하기 위해 사용</td>
</tr>
</tbody></table>
<br>


<h3 id="클래스-인스턴스-프로토타입">클래스, 인스턴스, 프로토타입</h3>
<pre><code class="language-javascript">//클래스
class Human {
    constructor(name) {
        this.name = name;
    }
      sleep() { console.log(`${this.name} is sleeping.`) }
}

//Human으로 생성한 객체 (인스턴스)
let steve = new Human(&#39;steve&#39;);

Human.prototype.constructor === Human; // true, 클래스
Human.prototype === steve.__proto__; // true, 프로토타입
Human.prototype.sleep === steve.sleep // true, 인스턴스 - 메서드

console.log(Human.prototype);
// {constructor: class Human, ƒ sleep: sleep()}

steve.__proto__; // 스티브의 프로토타입
steve.__proto__.__proto__; // 스티브의 프로토타입의 프로토타입</code></pre>
<p>맨 아래의 코드처럼 <code>__proto__</code>를 이용하여 인스턴스의 프로토타입, 그 프로토타입의 프로토타입을 체인의 끝인 Object까지 확인할 수 있다.</p>
<h3 id="정리">정리..</h3>
<ul>
<li><p>Prototype : 프로토타입 객체이다.</p>
</li>
<li><p>[[Prototype]] : 모든 객체가 가지고 있는 내부 슬롯으로 객체가 생성되는 방식에 따라 이곳에 프로토타입이 결정된다.</p>
</li>
<li><p><code>__proto__</code> : 모든 객체가 가지고 있는 접근자 프로퍼티로 이를 통해 자신의 프로토타입([[Prototype]]) 내부 슬롯에 간접적으로 접근할 수 있다.</p>
</li>
</ul>
<hr>

<h2 id="✨-마무리">✨ 마무리</h2>
<p>내용이 너무너무 방대하고 깊어.. ㅠㅁㅠ 조금만 더 다루고 싶어도 끊을 수가 없을 거 같아서... 프로토타입 기반.. 클래스.. 객체 지향.. 지금 내 뇌 터지기 일보직전..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[객체 지향 프로그래밍]]></title>
            <link>https://velog.io/@strong-minsu/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
            <guid>https://velog.io/@strong-minsu/%EA%B0%9D%EC%B2%B4-%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</guid>
            <pubDate>Fri, 12 May 2023 03:04:49 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p>객체 지향 프로그래밍에 대한 내용을 다뤄봅니다아~</p>
<blockquote>
<p>💡 Learn as if you would live forever, live as if you would die tomorrow.</p>
</blockquote>
<hr>
객체 지향 프로그래밍에서 모든 것은 객체로 그룹화 된다.
이때 객체는 책임의 존재라고 생각할 수 있다.

<h2 id="📌-객체-지향-프로그래밍-oop">📌 객체 지향 프로그래밍 (OOP)</h2>
<p>객체 지향 프로그래밍(OOP, Object-Oriented Programming)은 객체들의 집합으로 프로그램 상호 작용을 표현하며 데이터를 <strong>객체로 취급</strong>하여 객체 내부에 선언된 메서드를 활용하는 프로그램 설계 방식 중 하나이다.</p>
<p>객체 지향으로 프로그램을 설계할 때 설계에 많은 시간이 소요되며 처리 속도가 다른 프로그래밍 설계 방식보다 상대적으로 느릴 수 있다. </p>
<br>

<h3 id="🔍-객체-지향-프로그래밍의-특징">🔍 객체 지향 프로그래밍의 특징</h3>
<p>앞에서 객체 지향 프로그래밍은 설계에 많은 시간이 소요되며 처리 속도가 상대척으로 느릴 수 있는데 사용하는 이유는 무엇일까?</p>
<p>객체 지향 프로그래밍은 <strong>추상화(Abstraction)</strong>,** 캡슐화(Encapsulation)<strong>,</strong> 상속(Inheritance)<strong>,</strong> 다형성(Polymorphism)**이라는 특징이 있다. </p>
<ul>
<li><p><strong>추상화 (Abstraction)</strong> 
추상화란 복잡한 시스템으로부터 핵심적인 개념 또는 기능을 간추려 내는 것을 의미한다.</p>
</li>
<li><p><strong>캡슐화 (Encapsulation)</strong>
캡슐화는 객체의 속성과 메서드를 하나로 묶고 일부를 외부에 감추어 은닉하는 것을 의미한다.</p>
</li>
<li><p><strong>상속 (Inheritance)</strong>
상속성은 상위 클래스의 특성을 하위 클래스가 이어받아서 재사용하거나 추가, 확장하는 것을 의미한다.</p>
</li>
<li><p>** 다형성 (Polymorphism)**
다형성은 하나의 메서드나 클래스가 다양한 방법으로 동작하는 것을 의미한다.</p>
</li>
</ul>
<blockquote>
<p>객체 지향 프로그래밍을 사용하는 이유는 이러한 객체 지향 프로그래밍의 특성을 잘 이용하여 설계를 한다면, 요구하는 기능을 완벽하게 수행하고 변경하기 쉬운 (다른 말로 이해하기 쉬운) 좋은 코드를 작성할 수 있기 때문이다.</p>
</blockquote>
<br>

<h3 id="🔍-객체-지향-프로그래밍의-설계-원칙">🔍 객체 지향 프로그래밍의 설계 원칙</h3>
<p>객체 지향 프로그래밍을 설계할 경우 SOLID원칙을 지켜야 한다.</p>
<ul>
<li><p><strong>Single Responsibility Principle(SRP, 단일 책임 원칙)</strong>
모든 클래스는 각각 하나의 책임만을 가져야하는 원칙이다.</p>
</li>
<li><p><strong>Open Closed Principle(OCP, 개방-폐쇄 원칙)</strong>
유지 보수 사항이 생긴다면 코드를 쉽게 확장할 수 있도록 하고, 수정할 때는 닫혀 있어야한다는 원칙이다. 기존의 코드는 잘 변경하지 않으면서도 확장은 쉽게 할 수 있어야한다.</p>
</li>
<li><p><strong>Liskov Substitution Principle(LSP, 리스코프 치환 원칙)</strong>
프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다는 원칙이다. 부모 객체에 자식 객체를 넣어도 시스템이 문제 없이 돌아가게 만드는 것을 의미한다.</p>
</li>
<li><p><strong>Interface Segregation Principle(ISP, 인터페이스 분리 원칙)</strong>
하나의 일반적인 인터페이스보다 구체적인 여러 개의 인터페이스를 만들어야한다는 원칙이다.</p>
</li>
<li><p><strong>Dependency Inversion Principle(DIP, 의존 역전 원칙)</strong>
자신보다 변하기 쉬운 것에 의존하던 것을 추상화된 인터페이스나 상위 클래스를 두어 변하기 쉬운 것의 변화에 영향받지 않게 하는 원칙이다. 상위 계층은 하위 계층의 변화에 대한 구현으로부터 독립해야 한다.</p>
</li>
</ul>
<hr>

<h2 id="✨마무리">✨마무리</h2>
<p>소프트웨어 공학 시간에 배운 객체, 객체 지향 프로그래밍.. 오랜만에 보니까 반갑다.ㅎㅎ</p>
<p>근데 JavaScript는 명령형, 함수형, 프로토타입 기반, 객체 지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍.. 이라는데... Java로 이해한 객체 지향 프로그래밍을 그대로 생각하고 가도 될까..?하는 의문이...🤔</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[클래스와 인스턴스]]></title>
            <link>https://velog.io/@strong-minsu/%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4</link>
            <guid>https://velog.io/@strong-minsu/%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4</guid>
            <pubDate>Thu, 11 May 2023 08:51:20 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p>객체 지향 프로그래밍의 기초가 되는 클래스와 인스턴스에 대한 내용을 다뤄봅니다.</p>
<blockquote>
<p>💡 Although the world is full of suffering it is full also of the overcoming of it.</p>
</blockquote>
<hr>

<h2 id="📌-클래스와-인스턴스">📌 클래스와 인스턴스</h2>
<p>클래스는 객체 지향 프로그래밍의 기본이 되는 객체 생성의 메커니즘으로 볼 수 있다.</p>
<blockquote>
<p>객체 지향 프로그래밍을 간단하게 설명하자면 하나의 모델이 되는 청사진을 바탕으로 한 객체를 만드는 프로그래밍 패턴</p>
</blockquote>
   <img src="https://velog.velcdn.com/images/strong-minsu/post/f8d8805f-8c0b-440f-a36d-71045bc7a449/image.png" width="850" height="100" />


<ul>
<li><p>클래스
하나의 모델이 되는 청사진 =&gt; Car</p>
</li>
<li><p>인스턴스
청사진을 바탕으로 한 객체 =&gt; Audi, Nissan Volvo </p>
</li>
</ul>
<br>

<h3 id="🔍-클래스-정의">🔍 클래스 정의</h3>
<p>함수로 정의하거나(ES5) class 키워드를 사용하여 정의하며(ES6이후), 다른 함수와 구분을 위해 클래스의 이름은 파스칼 케이스를 사용한다. </p>
<pre><code class="language-javascript">//ES5 클래스는 함수로 정의할 수 있다.
function Car(brand, name, color){
    //인스턴스가 만들어질 때 실행되는 코드
}

//ES6 class라는 키워드를 이용해 정의할 수 있다.
class Car{
    constructor(brand, name, color){
        //인스턴스가 만들어질 때 실행되는 코드
    }
}</code></pre>
<br>

<h3 id="🔍-인스턴스-생성">🔍 인스턴스 생성</h3>
<p>인스턴스를 만들 때에는 new 키워드를 사용한다. 즉시 생성자 함수가 실행되며, 변수에 클래스의 설계를 가진 새로운 객체, 즉 인스턴스가 할당된다. 각각의 인스턴스는 클래스의 고유한 속성과 메서드를 갖게 된다.</p>
<p>위의 클래스 생성에서 constructor()함수가 바로 생성자 함수이다. 인스턴스가 만들어질 때 성성된다.</p>
<pre><code class="language-javascript">let Audi_A6 = new Car(&#39;Audi&#39;, &#39;A6&#39;, &#39;siver&#39;);
let Nissan_370Z = new Car(&#39;Nissan&#39;, &#39;370Z&#39;, &#39;red&#39;);
let Volvo_S90 = new Car(&#39;Volvo&#39;, &#39;S90&#39;, &#39;black&#39;);</code></pre>
<p>new 키워드를 사용해 인스턴스를 생성할 때, 생성자 함수가 실행되고 변수에 클래스 설계를 가진 새로운 객체가 할당된다. 각각의 인스턴스는 Car라는 클래스의 고유한 속성과, 메소드를 갖는다.</p>
<br>

<h3 id="🔍-속성과-메소드">🔍 속성과 메소드</h3>
<p>클래스에서는 속성과 메소드를 정의하고, 인스턴스에서 이를 활용한다.</p>
<pre><code class="language-javascript">//ES5 클래스는 함수로 정의할 수 있다.
//클래스의 속성 정의
function Car(brand, name, color){
    //인스턴스가 만들어질 때 실행되는 코드
  this.brand = brand;
  this.name = name;
  this.color = color;
}
Car.prototype.refuel = function(){}
Car.prototype.drive = function){}

//ES6 class라는 키워드를 이용해 정의할 수 있다.
//클래스의 속성 정의
class Car{
    constructor(brand, name, color){
        //인스턴스가 만들어질 때 실행되는 코드
      this.brand = brand;
        this.name = name;
      this.color = color;
    }
  //메소드 정의
  refuel(){}
  drive(){}
}


//인스턴스에서의 사용
let Audi_A6 = new Car(&#39;Audi&#39;, &#39;A6&#39;, &#39;siver&#39;);
Audi_A6.color; //siver
Audi_A6.drive(); //A6 운전을 시작합니다.
let Nissan_370Z = new Car(&#39;Nissan&#39;, &#39;370Z&#39;, &#39;red&#39;);
Nissan_370Z.brand; //Nissan
Nissan_370Z.reduel() //360Z 연료를 공급합니다.</code></pre>
<br>


<h3 id="🔍-es5와-es6-에서의-class">🔍 ES5와 ES6 에서의 class..</h3>
<p>JavaScript는 프로토타입 기반 객체 지향 언어여서 생성자 함수와 프로토타입으로 객체 지향의 상속을 구현할 수 있다.! ES6이후에 새로운 클래스가 도입되었는데(class 키워드와 constructor를 사용한 class) 이를 더 많이 사용한다고.. !..!ㅎㅁㅎ </p>
<p>ES5(생성자 함수)와 ES6(Class) 에서의 class 비교 <a href="http://www.yes24.com/Product/Goods/92742567">모던 자바스크립트 deep dive</a> 참고</p>
<table>
<thead>
<tr>
<th>Class</th>
<th>생성자 함수</th>
</tr>
</thead>
<tbody><tr>
<td>new 연산자 없이 호출할 경우 에러가 발생한다.</td>
<td>new 연산자 없이 호출하면 인반 함수로서 호출된다.</td>
</tr>
<tr>
<td>상속을 지원하는 extends와 super 키워드를 제공한다.</td>
<td>생성자 함수는 extends와 super 키워드를 제공하지 않는다.</td>
</tr>
<tr>
<td>호이스팅이 발생하지 않는 것처럼 동작한다.</td>
<td>함수 호이스팅과 변수 호이스팅이 발생한다.</td>
</tr>
<tr>
<td>클래스 내의 모든 코드에는 암묵적으로 strict mode가 지정되어 실행되며, strict mode를 해제할 수 없다.</td>
<td>생성자 함수는 암묵적으로 strict mode가 지정되지 않는다.</td>
</tr>
</tbody></table>
<hr>

<h2 id="✨마무리">✨마무리</h2>
<p>객체 지향과 클래스 부분! 익숙한듯.,. 어려운 개념..! ^ㅇ^ 그래서 공부하고 싶었던 부분인데 드뎧ㅎ 재밌당.. 코드로 직접 만들어보고싶네<del>.</del> 객체 지향 프로그래밍에 대한 깊게 다룬 글은 다음 글에서 다룰거당! 역시 프로그래밍의 꽃.. 객체 지향! 역시 추상적인.. 개념 부분은 더 많이 읽어보고 반복 학습이 중요하다..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[내장 고차 함수]]></title>
            <link>https://velog.io/@strong-minsu/%EB%82%B4%EC%9E%A5-%EA%B3%A0%EC%B0%A8-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@strong-minsu/%EB%82%B4%EC%9E%A5-%EA%B3%A0%EC%B0%A8-%ED%95%A8%EC%88%98</guid>
            <pubDate>Thu, 11 May 2023 07:21:58 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p>이전 포스트에서 다룬 고차 함수 내용을 바탕으로 자주 사용되는 배열의 내장 고차 함수에 대한 내용을 다뤄봅니다!</p>
<blockquote>
<p>💡 Push yourself, because no one else is going to do it for you.</p>
</blockquote>
<hr>

<h3 id="🌱-함수형-프로그래밍">🌱 함수형 프로그래밍</h3>
<blockquote>
<p>함수형 프로그래밍은 순수 함수와 보조 함수의 조합을 통해 로직 내에 존재하는 조건문과 반복문을 제거하여 복잡성을 해결하고 변수의 사용을 억제하여 상태 변경을 피하려는 프로그래밍 패러다임이다.</p>
</blockquote>
<p>함수형 프로그래밍은 결국 함수를 통해 부수 효과를 억제하여 오류를 피하고 프로그램의 안정성을 높이려는 노력!</p>
<hr>

<h2 id="📌-배열-고차-함수">📌 배열 고차 함수</h2>
<p>JavaScript에는 기본적으로 내장된 고차 함수가 여럿 있다. 그중에서 배열 메서드들 중 일부가 대표적인 고차 함수에 해당하고 매우 유용하여 사용도가 높다. (사용법 익히기!)
<code>자주 사용할 것 같은 배열 고차 함수를 설명한다.! 미래의 헷갈릴 나를 위해..ㅎㅎ 간단한 예제도 포함한ㄷ</code></p>
<h3 id="🌿-arrayprototypefilter">🌿 Array.prototype.filter</h3>
<p><strong>filter는 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출한다.</strong></p>
<ul>
<li><p>콜백 함수의 <strong>반환값이 true인 요소</strong>들로 구성된 새로운 배열을 반환한다.</p>
</li>
<li><p>원본 배열은 변경되지 않는다.</p>
</li>
<li><p>filter는 자신을 호출한 배열에서 필터링 조건을 만족하는 특정 요소만 추출하여 새로운 배열을 만든다.</p>
</li>
<li><p><em>즉 새로운 배열의 length 값은 원본 배열의 length 값보다 작거나 같다.*</em></p>
</li>
</ul>
<pre><code class="language-javascript">const number = [1, 2, 3, 4];

const odd = number.filter(item =&gt; item%2);
//원본 배열은 변경하지 않고, 새로운 배열을 반환한다.
console.log(odd) //[1, 3];
console.log(number) //[1, 2, 3, 4];</code></pre>
<hr>

<h3 id="🌿-arrayprototypemap">🌿 Array.prototype.map</h3>
<p><strong>map은 자신을 호출한 배열의 모든 요소를 순화하면서 인수로 전달받은 콜백 함수를 반복 호출한다.</strong></p>
<ul>
<li><p>콜백 함수의 반환값들로 구성된 새로운 배열을 반환한다.</p>
</li>
<li><p>원본 배열은 변경되지 않는다.</p>
</li>
<li><p>map을 호출한 배열과 map이 생성하여 반환한 배열은 1:1 매핑을 이룬다.</p>
</li>
<li><p><em>즉 새로운 배열과 원본 배열의 length 값은 반드시 일치한다.*</em></p>
</li>
</ul>
<pre><code class="language-javascript">const number = [1, 2, 3, 4];

const pows = number.map(item =&gt; Math.sqrt(item));
//원본 배열은 변경하지 않고, 새로운 배열을 반환한다.
console.log(pows) //[1, 4, 9, 16];
console.log(number) //[1, 2, 3, 4];</code></pre>
<hr>

<h3 id="🌿-arrayprototypereduce">🌿 Array.prototype.reduce</h3>
<p><strong>reduce는 자신을 호출한 배열의 모든 요소를 순화하면서 인수로 전달받은 콜백 함수를 반복 호출한다.</strong></p>
<ul>
<li><p>콜백 함수의 반환값을 다음 순회 시에 콜백 함수의 첫 번째 인수로 전달하면서 콜백 함수를 호출하여 하나의 결과값을 만들어 반환한다.</p>
</li>
<li><p>원본 배열은 변경되지 않는다.</p>
</li>
<li><p>첫 번째 인수로 콜백 함수, 두 번째 인수로 초기값을 전달받는다.</p>
</li>
<li><p><em>reduce의 콜백 함수에는 4개의 인수, 초기값 또는 콜백 함수의 이전 반환값, reduce 메서드를 호출한 배열의 요소값과 인덱스, reduce를 호출한 배열 자체 (this)가 전달된다.*</em></p>
</li>
</ul>
<pre><code class="language-javascript">const number = [1, 2, 3, 4];

const sum = number.reduce((accumulator, currentValue)=&gt; accumulator + currentValue, 0);

console.log(sum) //10</code></pre>
<p>reduce는 평균, 요소의 중복 횟수, 배열 평탄화, 중복 요소 제거 등 다양한 부분에서 활용될 수 있다.!</p>
<hr>

<h3 id="🌿-arrayprototypeforeach">🌿 Array.prototype.forEach</h3>
<p><strong>forEach는 for문을 대체할 수 있는 고차 함수이다.</strong></p>
<p>forEach 메서드는 반복문을 추상화한 고차 함수로서 내부에서 반복문을 통해 <strong>자신을 호출한 배열을 순회</strong>하면서 <strong>수행해야 할 처리를 콜백 함수로 전달</strong>받아 <strong>반복 호출</strong>한다.</p>
<ul>
<li><p>원본 배열을 직접 변경하지 않는다. -
변경은 가능 -&gt; <code>array.forEach((item, index, arr)=&gt;{arr[index] = item*2;})</code></p>
</li>
<li><p>반환값은 항상 undefined</p>
</li>
<li><p>콜백함수에 인자를 전달할 수 있다. 
배열의 요소값과 인덱스 그리고 forEach를 호출한 배열자체 this 이렇게 3가지를 전달할 수 있다.</p>
</li>
<li><p>for문과 달리 break, continue문은 사용이 불가능하다.</p>
</li>
</ul>
<pre><code class="language-javascript">const number = [1, 2, 3, 4];
const pows = [];

number.forEach(item =&gt; pows.push(item*item));
console.log(pows) //[1, 4, 9, 16];</code></pre>
<hr>

<h3 id="🌿-arrayprototypesort">🌿 Array.prototype.sort</h3>
<p> <strong>sort는 배열의 요소를 정렬하는 고차 함수이다.</strong></p>
<ul>
<li><p>원본 배열을 직접 변경한다.</p>
</li>
<li><p>반환값은 정렬된 배열이다. []</p>
</li>
<li><p>기본적으로 오름차순으로 정렬한다.(한글도 가능)</p>
</li>
<li><p>내림차순 정렬은 정렬 메소드 사용 후 reverse메서드를 사용하여 순서를 뒤집을 수 있다.</p>
</li>
<li><p>숫자 요소로 이루어진 배열을 정렬할 때 정렬 순서를 정의하는 함수가 필요하다.</p>
</li>
</ul>
<pre><code class="language-javascript">const fruits = [&#39;banana&#39;, &#39;orange&#39;, &#39;apple&#39;];

//오름차순 (원본 배열을 직접 변경한다.)
fruites.sort(); //[&#39;apple&#39;, &#39;banana&#39;, &#39;orange&#39;,]

//내림차순 (reverse메서드도 원본배열 직접 변경한다.)
fruites.reverse(); //[&#39;orange&#39;, &#39;banana&#39;, &#39;apple&#39;]

//숫자 요소 배열일 경우
const points= [40, 100, 1, 2, 5, 2, 25, 10];

//숫자 배열의 오름차순. 비교 함수의 반환값이 0보다 작으면 a를 우선 정렬
points.sort((a, b)=&gt;a-b);
//숫자 배열의 오름차순. 비교 함수의 반환값이 0보다 작으면 b를 우선 정렬
points.sort((a, b)=&gt;b-a);</code></pre>
<hr>

<h3 id="🌿-arrayprototypefind">🌿 Array.prototype.find</h3>
<p>ES6에 도입된 find는 자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수의 반환값이 true인 첫 번째 <strong>요소</strong>를 반환한다. 반환값이 true인 요소가 없으면 undifiend를 반환한다.</p>
<pre><code class="language-javascript">const user = [
  {id: 1, name: &quot;Lee&quot;},
  {id: 2, name: &quot;Kim&quot;},
  {id: 3, name: &quot;Choi&quot;},
  {id: 4, name: &quot;Park&quot;}
];

//filter은 배열을 반환하지만, find는 요소를 반환함
user.find(user =&gt;user.id === 2); //{id: 2, name: &quot;Kim&quot;}</code></pre>
<hr>

<h3 id="🌿-arrayprototypefindindex">🌿 Array.prototype.findIndex</h3>
<p>ES6에 도입된 find는 자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수의 반환값이 true인 첫 번째 <strong>요소의 인덱스</strong>를 반환한다. 반환값이 true인 요소가 없으면 -1을 반환한다.</p>
<pre><code class="language-javascript">const user = [
  {id: 1, name: &quot;Lee&quot;},
  {id: 2, name: &quot;Kim&quot;},
  {id: 3, name: &quot;Choi&quot;},
  {id: 4, name: &quot;Park&quot;}
];

//filter은 배열을 반환, find는 요소를 반환, findIndes는 요소의 인덱스 반환
user.find(user =&gt;user.id === 2); //1</code></pre>
<hr>

<h2 id="✨-마무리">✨ 마무리</h2>
<p>뭔가 배열의 고차 함수를 살펴보니까 코딩할 때 유용한 메서드가 많은 거 같다.. ! 앞으로 잘 사용해서 내 코드도 함수형 프로그래밍을 추구하도록 만들어봐야겠다! </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[고차 함수]]></title>
            <link>https://velog.io/@strong-minsu/%EA%B3%A0%EC%B0%A8-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@strong-minsu/%EA%B3%A0%EC%B0%A8-%ED%95%A8%EC%88%98</guid>
            <pubDate>Thu, 11 May 2023 05:47:27 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p>함수형 프로그래밍에 기반을 둔 일급객체, 고차함수에 대한 내용을 다뤄봅니다!</p>
<blockquote>
<p>💡 The world belongs to the energetic.</p>
</blockquote>
<hr>


<h2 id="📌-일급-객체-frist-class-citize">📌 일급 객체 (Frist-Class Citize)</h2>
<p>_특별한 대우를 받는 객체_라고 할 수 있다.</p>
<p>아래 조건을 만족하는 객체를 일급 객체라고 한다.</p>
<ul>
<li>변수나 자료구조(객체, 배열)에 할당(assignment)할 수 있다.</li>
<li>함수의 전달인자(argument)로 전달될 수 있다.</li>
<li>함수의 결과로써 리턴될 수 있다.</li>
<li>무명의 리터럴로 생성할 수 있다. (런타임에서 생성이 가능하다)</li>
</ul>
<p>JavaScript의 함수는 위의 조건을 모두 만족하므로 <strong>일급 객체</strong>이다.</p>
<blockquote>
<p>가장 중요한 특징은 함수를 일반 객체와 같이 <strong>함수의 매개변수에 전달할 수 있으며</strong>, <strong>함수의 반환값으로도 사용할 수 있다</strong>는 것이다. </p>
</blockquote>
<p>함수와 일반 객체와의 차이점을 살짝 집고 넘어가자~</p>
<table>
<thead>
<tr>
<th>함수</th>
<th>일반 객체</th>
</tr>
</thead>
<tbody><tr>
<td>호출이 가능하다</td>
<td>호출이 불가능하다</td>
</tr>
<tr>
<td>고유의 프로퍼티를 소유한다</td>
<td>고유의 프로퍼티가 없다.</td>
</tr>
</tbody></table>
<hr>

<h2 id="📌-고차-함수-higher-order-function-hof">📌 고차 함수 (Higher-Order Function HOF)</h2>
<blockquote>
<p><strong>고차 함수(higher order function)</strong>는 함수를 전달인자(argument)로 받을 수 있고, 함수를 리턴할 수 있는 함수이다.</p>
</blockquote>
<p>JavaScript의 함수는 일급 객체이므로 변수에 저장할 수 있다. 그리고 함수는, 함수를 담은 변수를 전달인자로 받을 수 있다. 마찬가지로, 함수 내부에서 변수에 함수를 할당할 수 있고 함수는 이 변수를 리턴할 수 있다(여기서 변수에 할당하지 않고 함수를 바로 이용할 수 있다).</p>
<p><em>고차 함수에 함수를 전달인자로 전달하고, 고차 함수는 함수 자체를 리턴한다.</em></p>
<h3 id="🔍-콜백-함수callback-function">🔍 콜백 함수(Callback Function)</h3>
<blockquote>
<p>고차 함수에서 다른 함수(caller)의 전달인자(argument)로 전달되는 함수를 콜백 함수(callback function)라고 한다.</p>
</blockquote>
<p>콜백 함수를 전달받은 고차 함수(caller)는, 함수 내부에서 이 콜백 함수를 호출(invoke)할 수 있고, 조건에 따라 콜백 함수의 실행 여부를 결정할 수도 있다. 아예 호출하지 않을 수도 있고, 여러 번 실행할 수도 있다. 특정 작업의 완료 후에 호출하는 경우는 이후에 충분히 접할 수 있다.</p>
<h3 id="🔍-커링-함수currying-function">🔍 커링 함수(Currying Function)</h3>
<blockquote>
<p>고차 함수에서 함수의 재사용성을 높이기 위해 함수 자체를 반환(return)하는 함수를 커링 함수(currying function)이라고 한다. 함수를 하나만 사용할 때는 필요한 모든 파라미터를 한 번에 넣어야 한다.</p>
</blockquote>
<p> 따로 커링 함수라는 용어를 사용하는 경우에는, 고차 함수라는 용어를 &#39;함수를 전달인자로 받는 함수&#39;에만 한정해 사용하기도 한다. 그러나 정확하게 구분하자면, <strong>고차 함수가 커링 함수를 포함</strong>한 개념으로 생각하면 된다.</p>
<h3 id="🔍-고차-함수의-예">🔍 고차 함수의 예</h3>
<h4 id="1-다른-함수를-인자로-받는-경우-🌱">1. 다른 함수를 인자로 받는 경우 🌱</h4>
<pre><code class="language-javascript">//매개변수를 2배하여 리턴한다.
function double(num) {
  return num * 2;
}

//전달받은 매개변수 num을 전달인자로 받는 함수 func를 리턴한다.
function doubleNum(func, num) {
  return func(num);
}

//output은 doubleNum함수에 인자로 double함수와 4를 넣은 결과를 리턴 받는다.
const output = doubleNum(double, 4);
console.log(output); // -&gt; 8</code></pre>
<h4 id="2-함수를-리턴하는-경우-🌱">2. 함수를 리턴하는 경우 🌱</h4>
<pre><code class="language-javascript">//전달받은 매개변수를 리턴 함수의 매개변수와 더해서 리턴하는 고차 함수
function adder(added) {
  return function (num) {
    return num + added;
  };
}

// adder(5)는 함수이다.
// 함수 호출 연산자 &#39;()&#39;를 사용할 수 있따
let output = adder(6)(3); // -&gt; 9
console.log(output); // -&gt; 9

// // javascript에서 함수는 일급 객체이기 때문에 adder가 리턴하는 함수를 변수에 할당 가능
const add3 = adder(3); //-&gt; 3을 더하는 기능을 가진 함수를 변수에 할당
output = add3(5); //3을 더하는 함수에 매개변수로 5를 전달
console.log(output); // -&gt; 8</code></pre>
<h4 id="3-함수를-인자로-받고-함수를-리턴하는-경우-🌱">3. 함수를 인자로 받고, 함수를 리턴하는 경우 🌱</h4>
<pre><code class="language-javascript">//매개변수를 2배하여 리턴한다. (함수 doubleAdder의 콜백함수)
function double(num) {
  return num * 2;
}


 // 함수 doubleAdder의 인자 func는 함수 doubleAdder의 콜백 함수이다.
 //함수 double은 함수 doubleAdder의 콜백으로 전달되었다.
function doubleAdder(added, func) {
  const doubled = func(added); //매개변수로 전달받은 함수에 매개변수로 받은 수를 인자로 전달 하여 실행한 결과.
  return function (num) {// 매개변수로 받는 수와 앞에서 실행된 결과를 더하는 함수를 리턴
    return num + doubled;
  };
}


// doubleAdder(5, double)는 함수이므로 함수 호출 기호 &#39;()&#39;를 사용할 수 있다.
doubleAdder(5, double)(3); // -&gt; 10 + 3

// doubleAdder가 리턴하는 함수를 변수에 저장할 수 있다. (일급 객체)
const addTwice3 = doubleAdder(3, double); //3을 두 배한 수와 매개변수를 더할 함수를 할당받음
addTwice3(2); // --&gt; 8</code></pre>
<hr>

<h2 id="✨-마무리">✨ 마무리</h2>
<p>고차.. 함수.. 처음 듣는 개념..! &gt;&lt; 그래도 이해는 하고 넘어간당! 굿굿 
다음 컨텐츠에서는 자주 사용하는 배열의 고차함수에 대해..!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Web Storage]]></title>
            <link>https://velog.io/@strong-minsu/Web-Storage</link>
            <guid>https://velog.io/@strong-minsu/Web-Storage</guid>
            <pubDate>Tue, 09 May 2023 02:08:45 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe-45기">✨SEB FE 45기</h2>
<p>질문게시판 기능 구현하면서 공부하게 된 부분인 웹 스토리지, 로컬과 세션에 대한 내용을 다뤄보자!</p>
<blockquote>
<p>💡 성공은 당신이 하길 원하는 것을 할 때 따라온다. 이것이 유일한 성공의 비결이다.
&quot;Success follows doing what you want to do. There is no other way to be successful.&quot; -말콤 포브스</p>
</blockquote>
<hr>

<h2 id="📌-web-storage">📌 Web Storage</h2>
<p>HTML5 이전에는 애플리케이션 데이터를 모든 서버 요청에 포함된 쿠키에 저장해야 했다.</p>
<p>HTML Web Storage?
Web Storage란 HTML5부터 제공하는 기능으로, 해당 도메인과 관련된 특정 데이터를 서버가 아니라 클라이언트 웹브라우저에 저장할 수 있도록 제공하는 기능이다. (쿠키(cookie)와 비슷한 기능)</p>
<blockquote>
<p>Web Storage API는 브라우저가 쿠키를 사용하는 것보다 훨씬 더 직관적인 방식으로 키/값 쌍을 저장할 수 있는 메커니즘을 제공한다. <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API#web_storage_concepts_and_usage">Web Storage API</a> </p>
</blockquote>
<ul>
<li><p>웹 스토리지를 사용하면 웹 애플리케이션이 사용자의 브라우저 내에서 <code>로컬로 데이터를 저장</code>할 수 있다. </p>
</li>
<li><p>웹 저장소는 더 안전하고 웹 사이트 성능에 영향을 주지 않고 많은 양의 데이터를 로컬에 저장할 수 있다.</p>
</li>
<li><p>Web Storage의 개념은 키/값 쌍으로 데이터를 저장하고, 키를 기반으로 데이터를 조회하는 패턴이다.</p>
</li>
<li><p>쿠키와 달리 저장한도는 더 크고(최소 5MB), 정보가 서버로 전송되지 않는다.</p>
</li>
<li><p>서버에 불필요한 데이터 저장을 막을 수 있다.</p>
</li>
<li><p>문자열 외에도 자바스크립트의 모든 원시형 데이터와 객체 저장 가능하다.</p>
</li>
<li><p>도메인 단위로 접근이 제한되는 CORS 특성 덕분에 CSRF로부터 안전하다.</p>
<br>

</li>
</ul>
<h3 id="🔍-localstorage--sessionstorage">🔍 localStorage &amp; sessionStorage</h3>
<h4 id="🌱_html-웹-저장소는-클라이언트에-데이터를-저장하기-위한-두-가지-개체를-제공한다_🌱">🌱_HTML 웹 저장소는 클라이언트에 데이터를 저장하기 위한 두 가지 개체를 제공한다._🌱</h4>
<p>◽ <strong>window.localStorage</strong>- 만료 날짜가 없는 데이터 저장</p>
<ul>
<li>영구 저장소, 브라우저를 닫았다가 다시 열어도 계속 유지된다.</li>
</ul>
<p>◽ <strong>window.sessionStorage</strong>- 한 세션에 대한 데이터 저장(브라우저 탭을 닫으면 데이터가 손실됨)</p>
<ul>
<li>임시저장소, 브라우저가 열려있는 한 페이지를 Reload해도 계속 유지된다. (닫으면 데이터가 삭제됨)</li>
</ul>
<br>

<p>두 스토리지 객체는 동일한 메서드와 프로퍼티를 제공한다.</p>
<p><strong><code>setItem(key, value)</code> – 키-값 쌍을 보관</strong></p>
<pre><code class="language-javascript">//key가 &quot;test&quot;고, value가 &quot;1&quot;인 데이터 저장  
localStorage.setItem(&#39;test&#39;, 1);
sessionStorage.setItem(&#39;test&#39;, 1);</code></pre>
<br>

<p><strong><code>getItem(key)</code> – 키에 해당하는 값을 받아옴</strong></p>
<pre><code class="language-javascript">//key가 &quot;test&quot;인 데이터 불러오기
localStorage.getItem(&#39;test&#39;);
sessionStorage.getItem(&#39;test&#39;);</code></pre>
<br>

<p><strong><code>removeItem(key)</code> – 키와 해당 값을 삭제</strong></p>
<pre><code class="language-javascript">//key가 &quot;test&quot;인 데이터 삭제
localStorage.removeItem(&#39;test&#39;);
sessionStorage.removeItem(&#39;test&#39;);</code></pre>
<br>

<p><strong><code>clear()</code> – 모든 것을 삭제</strong></p>
<pre><code class="language-javascript">//key가 &quot;test&quot;인 데이터 삭제
localStorage.clear();
sessionStorage.clear();</code></pre>
<br>

<p><strong><code>key(index)</code> – 인덱스(index)에 해당하는 키를 받아옴</strong></p>
<pre><code class="language-javascript">//index에 해당하는 키를 받아온다.
localStorage.key(index);
sessionStorage.key(index);</code></pre>
<br>

<p><strong><code>length</code> – 저장된 항목의 개수를 얻음</strong></p>
<pre><code class="language-javascript">//스토리지에 있는 데이터 항목의 개수를 얻는다.
localStorage.length;
sessionStorage.length;</code></pre>
<br>

<p>키 순회 방법!
(스토리지의 길이만큼 반볷하면서 키를 넣어 순회한다.)</p>
<pre><code class="language-javascript">for(let i=0; i&lt;localStorage.length; i++) {
  let key = localStorage.key(i);
  alert(`${key}: ${localStorage.getItem(key)}`);
}</code></pre>
<br>

<blockquote>
<p>🌱<strong>localStorage &amp; sessionStorage에 데이터를 저장할 때</strong>🌱
<br>키와 값은 반드시 문자열이어야 한다.
제한 용량은 5MB 이상인데, 브라우저에 따라 다를 수 있다.
데이터가 파기되지 않는다.
오리진(도메인·포트·프로토콜)에 묶여있다.</p>
</blockquote>
<p>두 스토리지 객체는 Map과 유사하다. <code>setItem/getItem/removeItem을 지원한다.</code>하지만 인덱스를 사용해 키에 접근할 수 있다는 점(key(index))에서 차이가 있다.</p>
<h4 id="🌱-localstorage--sessionstorage-비교-🌱">🌱 localStorage &amp; sessionStorage 비교 🌱</h4>
<table>
<thead>
<tr>
<th>localStorage</th>
<th>sessionStorage</th>
</tr>
</thead>
<tbody><tr>
<td>오리진이 같은 탭, 창 전체에서 공유된다.</td>
<td>오리진이 같은 브라우저 탭, iframe에서 공유된다.</td>
</tr>
<tr>
<td>페이지를 새로 고침 해도 남아있다. 브라우저를 껐다 켜도 남아있다.</td>
<td>페이지를 새로 고침 해도 남아있다. 하지만 탭이나 브라우저를 종료하면 사라진다.</td>
</tr>
</tbody></table>
<hr>

<h2 id="✨마무리">✨마무리</h2>
<p>storage에 데이터를 넣는 기능을 구현하다가 조금 정리해 놓으면 좋을 것 같아서, 따로 글을 쓰게 되었다. 서버로 보내지 않고 클라이언트에 저장한다니..! ㅎㅎ 신기하당..👀
확실히 글을 쓰면서 정리하니까 개념이해는 확실하게 되는 기분! 다음에는 쿠키에 대해서도 한 번 공부야겠다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[스코프와 클로저]]></title>
            <link>https://velog.io/@strong-minsu/%EC%8A%A4%EC%BD%94%ED%94%84%EC%99%80-%ED%81%B4%EB%A1%9C%EC%A0%80</link>
            <guid>https://velog.io/@strong-minsu/%EC%8A%A4%EC%BD%94%ED%94%84%EC%99%80-%ED%81%B4%EB%A1%9C%EC%A0%80</guid>
            <pubDate>Mon, 01 May 2023 02:41:29 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p>Unit9 [JavaScript] 핵심 개념과 주요 문법 <strong>koans 과제..!</strong></p>
<blockquote>
<p>💡불가능해 보이는 것은 불확실한 가능성보다 항상 더 낫다.
&quot;A likely impossibility is always preferable to an unconvincing possibility.&quot;-Aristotle</p>
</blockquote>
<hr>

<h2 id="📌-unit-test">📌 Unit test</h2>
<p>_koans과제가 Unit test를 수정하며 개념을 잡는 느낌으로 진행되어서 Unit test의 정의를 살짝 잡고 가야겠다..! _</p>
<blockquote>
<p>유닛 테스트(unit test)는 컴퓨터 프로그래밍에서 소스 코드의 특정 모듈이 의도된 대로 정확히 작동하는지 검증하는 절차다. 즉, 모든 함수와 메소드에 대한 테스트 케이스(Test case)를 작성하는 절차를 말한다. <a href="https://en.wikipedia.org/wiki/Unit_testing">(Wikipedia)</a></p>
</blockquote>
<p>Unit Test(단위 테스트)를 통해서 언제라도 코드 변경으로 인해 문제가 발생할 경우, 단시간 내에 이를 파악하고 바로 잡을 수 있도록 해준다.</p>
<h4 id="사용방법">사용방법</h4>
<ol>
<li>js-unit-test 디렉터리 하위에 js디렉터리를 생성</li>
<li>js 디렉터리 안에 샘플 코드를 작성한다</li>
</ol>
<p>간단한 테스트 코드 </p>
<pre><code class="language-javascript">&#39;use strict&#39;;

var helloWorld = function() {
  return &#39;helloWorld&#39;;
};

// Test case
describe(&#39;helloWorld.js&#39;, function() {

  it(&#39;should returns string &quot;helloWorld&quot;&#39;, function() {
    expect(helloWorld()).toBe(&#39;helloWorld&#39;);
    expect(helloWorld()).not.toBe(&#39;worldHello&#39;);
  });

});</code></pre>
<ul>
<li><h4 id="describename-function">describe(name, function())</h4>
단위 테스트 명세 집합, 여러 테스팅 코드를 하나의 집합으로 묶을 때 사용</li>
<li><h4 id="itname-function">it(name, function())</h4>
단위 테스트를 위한 함수, 실제 테스팅을 실행하는 코드 인자로 들어가는 함수는 expext(테스트할 함수).(toBe,toEqual 같은 matcher)의 형태입니다.</li>
<li><h4 id="matcher-함수">matcher 함수</h4>
expect(variable).toBe(true);
expect(variable).not.toBe(true);
expect(variable).toEqual(b);
expect(stringA).toMatch(/stringB/);
expect(stringA).not.toMatch(/stringB/);
expect(object.foo).toBeDefined();
expect(variable).toBeNull();
expect(a).toContain(&quot;b&quot;); // 배열변수 a에 &quot;b&quot;라는 요소가 포함돼 있는지
expect(a).toBeGreaterThan(b); // a 변수 값이 b 변수보다 큰지</li>
</ul>
<hr>

<h2 id="📌-스코프">📌 스코프</h2>
<p>스코프(scope-유효범위) 
<code>컴퓨터 공학, 그리고 JavaScript에서의 스코프는 &quot;변수의 유효범위&quot;로 사용된다.</code>
JavaScript를 포함한 모든 프로그래밍 언어의 기본적인 개념!</p>
<h3 id="📝-스코프와-주요-규칙">📝 스코프와 주요 규칙</h3>
<blockquote>
<p>변수에 접근할 수 있는 범위가 존재한다. 중괄호(블록) 안쪽에 변수가 선언되었는가, 바깥쪽에 변수가 선언되었는가가 중요하다. 변수를 포함한 모든 식별자는 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효 범위가 결정되는데, 이를 스코프라고 한다. 즉, 스코프는 식별자가 유효한 범위!</p>
</blockquote>
<p> <strong>스코프의 정의: &quot;변수 접근 규칙에 따른 유효 범위&quot;</strong></p>
<ul>
<li>안쪽 스코프에서 바깥쪽 스코프로는 접근할 수 있지만 반대는 불가능하다. </li>
<li>스코프는 중첩이 가능하다.</li>
<li>특별히 가장 바깥쪽의 스코프는 전역 스코프(Global Scope)라고 부른다. 전역이 아닌 다른 스코프는 전부 지역 스코프(local scope)이다.</li>
<li>지역 스코프에 선언한 변수는 지역 변수, 전역 스코프에서 선언한 변수는 전역 변수</li>
<li><strong>지역 변수는 전역 변수보다 더 높은 우선순위를 가진다.</strong></li>
</ul>
<table>
<thead>
<tr>
<th>구분</th>
<th>설명</th>
<th>스코프</th>
<th>변수</th>
</tr>
</thead>
<tbody><tr>
<td>전역</td>
<td>코드의 가장 바깥 영역</td>
<td>전역 스코프</td>
<td>전역 변수</td>
</tr>
<tr>
<td>지역</td>
<td>함수 몸체 내부</td>
<td>지역 스코프</td>
<td>지역 변수</td>
</tr>
</tbody></table>
<p><em>만약 스코프의 개념이 없었다면,, 같은 이름을 갖는 변수는 충돌을 일으키기 때문에, 전체 프로그램에서 모든 변수는 다른 이름을 가져야할 것이다.</em></p>
<h3 id="📝-변수-선언과-스코프">📝 변수 선언과 스코프</h3>
<h4 id="함수-레벨-스코프과-블록-레벨-스코프">함수 레벨 스코프과 블록 레벨 스코프</h4>
<p>지역은 함수 몸체 내부를 말하고, 지역은 지역 스코프를 만든다. <code>이는 코드 블록이 아닌 함수에 의해서만 지역 스코프가 생성된다</code>는 의미이다. 
C나 Java 등을 비롯한 대부분의 프로그래밍 언어는 함수 몸체만이 아니라 모든 코드 블록(if, for, while, try/chatch 등)이 지역 스코프를 만든다. 이러한 특성을 <strong>블록 레벨 스코프</strong>라고 한다.</p>
<h4 id="let-const-var-키워드">let, const, var 키워드</h4>
<table>
<thead>
<tr>
<th></th>
<th>var</th>
<th>let</th>
<th>const</th>
</tr>
</thead>
<tbody><tr>
<td>유효 범위</td>
<td>함수 스코프</td>
<td>블록 스코프 및 함수 스코프</td>
<td>블록 스코프 및 함수 스코프</td>
</tr>
<tr>
<td>값 재할당</td>
<td>가능</td>
<td>가능</td>
<td>불가능</td>
</tr>
<tr>
<td>재선언</td>
<td>가능</td>
<td>불가능</td>
<td>불가능</td>
</tr>
</tbody></table>
<blockquote>
<p>👀 var 키워드를 <strong>지양</strong>해야하는 이유
var 키워드로 선언한 변수는 중복 선언을 허용하기 때문에 이미 있는 변수의 존재를 모르고 의도치 않게 그 값을 변경할 수 있다. 또한 함수 블록만을 지역 스코프로 인정하기 때문에 다른 코드 블록에서 선언된 변수는 모두 전역 변수로 다뤄진다. 마지막으로 변수 호이스팅에 의해 변수 선언문 이전에 변수를 참조하는 것이 가능하다.(이는 프로그래밍 흐름상에도 맞지 않고, 가독성을 떨어뜨리며 오류를 발생시킬 여지가 있다)</p>
</blockquote>
<blockquote>
<p>👀 <strong>ES6의 let과 const</strong>
let과 const는 var키워드와 달리 변수의 중복 선언이 불가능하다. 블록 레벨 스코프를 따르기 때문에 무분별한 전역 변수 사용을 줄일 수 있다. 또한 let, const 는 변수 호이스팅이 발생하지 않는 것처럼 동작한다.
let : 재할당이 가능하다
const : 재할당이 불가능하다 (불변을 의미하는 것은 아님!)</p>
</blockquote>
<h4 id="🌱-변수-선언-키워드-총-정리-🌱">🌱 변수 선언 키워드 총 정리! 🌱</h4>
<ul>
<li>ES6를 사용한다면, var 키워드는 사용하지 않는다.</li>
<li>재할당이 필요한 경우에 한정해 let 키워드를 사용한다. 이때 변수의 스코프는 최대한 좁게 만든다.</li>
<li>변경이 발생하지 않고 읽기 전용으로 사용하는 변수 즉, 재할당이 필요 없는 상수로 이용된 원시값과 객체에는 const 키워드를 사용한다. const 키워드는 재할당을 금지하므로 var, let 키워드보다 안전하다.</li>
</ul>
<p><em>변수를 선언하는 시점에는 재할당이 필요할지 잘 모르는 경우가 많다. 의외로 객체는 재할당하는 경우가 드물다. 따라서 변수 선언에는 일단 const 키워드를 사용하자! (그 뒤에 변경해도 늦지 않는다!)</em></p>
<hr>

<h2 id="📌-클로저">📌 클로저</h2>
<h3 id="📝-클로저-closure-정의">📝 클로저 (closure) 정의</h3>
<blockquote>
<p><strong>&quot;A closure is the combination of a function and the lexical environment within which that function was declared.&quot;&quot; - MDN</strong></p>
</blockquote>
<p>클로저는 함수와 그 함수가 선언된 렉시컬 환경과의 조합이다.
ㄴ 진짜 추상적인 느낌.. 이해하기가 쉽지는 않다.  </p>
<p>클로저는 JavaScript 고유의 개념이 아니라 함수를 일급 객체로 취급하는 함수형 프로그래밍언어에서 사용되는 특성이다. </p>
<blockquote>
<h4 id="렉시컬-스코프">렉시컬 스코프</h4>
<p>자바스크립트엔진은 함수를 어디서 호출했는지가 아니라 함수를 어디에 정의했는지에 따라 상위 스코프를 결정한다.(렉시컬 스코프..!)</p>
</blockquote>
<h5 id="렉시컬-환경에-대한-내용은-더-다룰-것이-많지만-자세한-내용은-공부-후에-다뤄야-할-것-같다"><em>렉시컬 환경에 대한 내용은 더 다룰 것이 많지만,.. 자세한 내용은 공부 후에 다뤄야 할 것 같다..</em></h5>
<h3 id="📝-클로저-closure-자세한-설명--예시">📝 클로저 (closure) 자세한 설명 &amp; 예시</h3>
<p><strong>🌱 클로저 🌱 **
JavaScript에서 모든 함수는 자신의 상위 스코프를 기억한다. 모든 함수가 기억하는 상위 스코프는 함수를 어디서 호출하든 상관없이 유지된다. 또 이는 함수를 어디서 호출하든 상관없이 **함수는 언제나 자신이 기억하는 상위 스코프의 식별자를 참조할 수 있으며 식별자에 바인딩된 값을 변경할 수 있다.</strong></p>
<blockquote>
<h4 id="외부-함수보다-중첩-함수가-더-오래-유지되는-경우-중첩-함수는-이미-생명-주기가-종료한-외부-함수의-변수를-참조할-수-있는데-이러한-중첩-함수를-클로저closure라고-부른다"><strong>외부 함수보다 중첩 함수가 더 오래 유지되는 경우 중첩 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있는데, 이러한 중첩 함수를 클로저(closure)라고 부른다.</strong></h4>
</blockquote>
<p>아래 예시 코드는 <a href="http://www.yes24.com/Product/Goods/92742567">모던 자바스크립트 deep dive</a>를 참조했다.</p>
<pre><code class="language-javascript">const x = 1;

function outer() {
  const x = 10;
  const inner = function(){console.log(x);};
  return inner;
}

// outer 함수를 호출하면 중첩 함수 inner를 반환한다.
// outer 함수의 실행 컨텍스트는 실행 컨텍스트 스택에서 팝되어 제거된다. (즉 생명주기 종료..)
const innerFunc = outer();
innerFunc(); //10</code></pre>
<p>클로저의 예시로 위 코드를 살펴보자, 위의 코드에서 결과는 10이 출력된다. outer함수의 지역변수의 값이다. 이미 생명주기가 종료되어 실행 컨텍스트 스택에서 제거된 outer 함수의 지역변수가 다시 부활 한 듯 동작하는 것을 볼 수 있다. </p>
<hr>

<h2 id="✨마무리">✨마무리</h2>
<p>koans과제 하면서 JavaScript의 핵심 개념, 조금 심화된 내용 등을 볼 수 있어서 의미있는 시간이었던 것 같다.! 새로운 프로그래밍 언어를 처음 배우는 것이 아니다보니 빠르게 이해할 수 있었던 것 같다!1 그래두 강의 자료보다 조금 더 심화 내용이 많았는데.. (특히 렉시컬 환경.. 이건 진짜 완벽하게 이해하려면 조금 시간을 투자해야할 것 같다.) 흐름을 이해하는 것에서 멈추지 않고,, 그냥 완벽하게 알고싶당.. 더 열심히 해야겠지?? ㅎㅎ 그래도 스코프랑 클로저 개념을 정리할 수 있을만큼 이해했다! JavaScript 마스터가 될 때까지.. 아자자자자자자자ㅏㅏ!!!!!!!!!!!!!!!!!!💃</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[원시 자료형과 참조 자료형]]></title>
            <link>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-%EC%9B%90%EC%8B%9C-%EC%9E%90%EB%A3%8C%ED%98%95%EA%B3%BC-%EC%B0%B8%EC%A1%B0-%EC%9E%90%EB%A3%8C%ED%98%95</link>
            <guid>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-%EC%9B%90%EC%8B%9C-%EC%9E%90%EB%A3%8C%ED%98%95%EA%B3%BC-%EC%B0%B8%EC%A1%B0-%EC%9E%90%EB%A3%8C%ED%98%95</guid>
            <pubDate>Thu, 27 Apr 2023 05:22:37 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p> [JavaScript] 핵심 개념과 주요 문법</p>
<blockquote>
<p>💡 Go for it now. The future is promised to no one.
&quot;지금 시작해라. 미래는 아무에게도 약속되지 않는다.&quot;</p>
</blockquote>
<hr>
JavaScript에서 자료형(type)이란 값(value)의 종류다. 각각의 자료형은 고유한 속성과 메서드를 가지고 있다. 자료형은 크게 두 가지로 구분할 수 있는데, 바로 원시 자료형(primitive type)과 참조 자료형(reference type)이다.

<h2 id="📌-원시-자료형-primitive-type">📌 원시 자료형 (primitive type)</h2>
<h3 id="📝-원시-자료형">📝 원시 자료형</h3>
<p>원시 자료형의 값, 즉 원시 값은 변경이 불가능한 값(immutable value)이다. 한 번 생성된 원시 값은 읽기 전용 값이므로 변경할 수 없다.</p>
<blockquote>
<p><strong>&quot;원시 값은 변경 불가능하다&quot;</strong> 는 말은 원시 값 자체를 변경할 수 없다는 것이지 변수 값을 변경할 수 없다는 것이 아니다. 변수는 언제든지 재할당을 통해 변수 값을 변경할 수 있다.</p>
</blockquote>
<p><strong>변수 값의 변경</strong>
 변수 값을 변경하기 위해 원시 값을 재할당하면 새로운 메모리 공간을 확보하고 재할당한 값을 저장한 후, 변수가 참조하던 메모리 공간의 주소를 변경한다.(불변성) 불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없다.</p>
<h3 id="📝-값에-의한-전달">📝 값에 의한 전달</h3>
<p>변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달된다. -&gt; 값에 의한 전달.</p>
<p>아래 예시 코드는 <a href="http://www.yes24.com/Product/Goods/92742567">모던 자바스크립트 deep dive</a>를 참조했다.</p>
<pre><code class="language-javascript">var score = 80;

//copy변수에는 score변수의 값 80이 복사되어 할당된다.
var copy = score;

console.log(scpre, copy) // 80 80
console.log(score === copy) // true

//score변수와  copy변수의 값은 다른 메모리 공간에 저장된 별개의 값
//따라서 score 변수의 값을 변경해도 copy변수의 값에는 어떠한 영향도 주지 않는다
score = 100;
console.log(scpre, copy) // 100 80
console.log(score === copy) // false</code></pre>
<hr>

<h2 id="📌-참조-자료형-reference-type">📌 참조 자료형 (reference type)</h2>
<h3 id="📝-참조-자료형">📝 참조 자료형</h3>
<p>참조 자료형의 값, 즉 참조 값은 변경 가능한 값(mutable value)이다. 원시 값은 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 원시 값에 접근할 수 있지만, 참조 값은  변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 참조 값(생성된 객체가 저장된 메모리 공간의 주소)에 접근할 수 있다.</p>
<blockquote>
<p><strong>&quot;참조 값은 변경이 가능하다&quot;</strong> 객체를 할당한 변수는 재할당 없이 객체를 직접 변경할 수 있다. 즉, 재할당 없이 프로퍼티를 동적으로 추가할 수도 있고 프로퍼티 값을 갱신할 수도 있으며 프로퍼티 자체를 삭제할 수도 있다.</p>
</blockquote>
<h3 id="📝-참조에-의한-전달">📝 참조에 의한 전달</h3>
<p>참조 자료형을 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달 된다. -&gt; 잠조에 의한 전달.
아래 예시 코드는 <a href="http://www.yes24.com/Product/Goods/92742567">모던 자바스크립트 deep dive</a>를 참조했다.</p>
<pre><code class="language-javascript">var person = {
    name: &quot;Lee&quot;
};

//참조 값을 복사. copy와 person은 동일한 참조 값을 갖는다.
var copy = person;

//copy와 person은 동일한 객체를 참조한다.
console.log(copy===person); //true

//copy를 통해 객체를 변경한다.
copy.name = &quot;Kim&quot;;

//person을 통해 객체를 변경한다.
person.address = &quot;Seoul&quot;;

//copy와 person은 동일한 객체를 가리킨다.
//어느 한쪽에서 객체를 변경하면 서로 영향을 주고받는다.
console.log(person); //{name: &quot;Kim&quot;, address: &quot;Seoul&quot;}
console.log(coyp); //{name: &quot;Kim&quot;, address: &quot;Seoul&quot;}</code></pre>
<hr>

<h2 id="📌-정리">📌 정리!</h2>
<table>
<thead>
<tr>
<th>원시</th>
<th>참조</th>
</tr>
</thead>
<tbody><tr>
<td>원시 자료형을 변수에 할당하면 메모리 공간에 값 자체가 저장된다.</td>
<td>참조 자료형을 변수에 할당하면 메모리 공간에 주소 값이 저장된다.</td>
</tr>
<tr>
<td>원시값을 갖는 변수를 다른 변수에 할당하면 원시 값 자체가 복사되어 전달된다.</td>
<td>참조값을 갖는 변수를 다른 변수에 할당하면 주소 값이 복사되어 전달된다.</td>
</tr>
<tr>
<td>원시 자료형은 변경 불가능한 값(immutable value)이다. 즉 한 번 생성된 원시 자료형은 읽기 전용이다.</td>
<td>참조 자료형은 변경이 가능한 값이다.(mutable value)</td>
</tr>
</tbody></table>
<hr>

<h2 id="✨마무리">✨마무리</h2>
<p><a href="http://www.yes24.com/Product/Goods/92742567">모던 자바스크립트 deep dive</a>이 책이 JavaScript를 이해하는데 너무너무너무 많은 정보를 주고있다! 정말 모두에게 추천하고 싶어!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Linux 터미널 기초 / Node.js 환경 설정 기초]]></title>
            <link>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-Linux-%ED%84%B0%EB%AF%B8%EB%84%90-%EA%B8%B0%EC%B4%88-Node.js-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95-%EA%B8%B0%EC%B4%88</link>
            <guid>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-Linux-%ED%84%B0%EB%AF%B8%EB%84%90-%EA%B8%B0%EC%B4%88-Node.js-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95-%EA%B8%B0%EC%B4%88</guid>
            <pubDate>Mon, 24 Apr 2023 13:04:03 GMT</pubDate>
            <description><![CDATA[<h2 id="✨seb-fe">✨SEB FE</h2>
<p>Unit7 Linux / Node.js 환경 설정</p>
<blockquote>
<p>💡 in the end, it&#39;s not the years in your life that count. it&#39;s the life in your years.
&quot;결국, 인생에서 중요한 것은 몇 년이 아니다. 당신의 나이 때의 삶이다.&quot;
-Abraham Lincoln</p>
</blockquote>
<hr>

<h2 id="📌-command-line-interface">📌 Command-Line Interface</h2>
<p>CLI : Command-Line Interface 터미널을 통해 사용자와 컴퓨터가 상호 작용하는 것! 
사용자는 키보드 등의 입력 장치를 통해 문자열 형태로 컴퓨터에게 명령을 전달하고, 컴퓨터는 그 결과를 문자열로 터미널에 출력한다.</p>
<p>단축키: <code>Ctrl</code> (컨트롤 키) + <code>Alt</code> (알트 키) + <code>t</code> (영문 t)</p>
<blockquote>
<h4 id="🧐-자주쓰는-명령어-모음">🧐 자주쓰는 명령어 모음</h4>
<p><strong>pwd</strong> : 현재 위치 확인하기
<strong>mkdir</strong> : 새로운 폴더 생성하기
<strong>ls</strong> : 특정 폴더에 포함된 파일이나 폴더 확인하기 
(- 옵션 <code>l</code>(포맷 전부 표현)과 <code>a</code>(all)가 존재한다. )
<strong>cd</strong> : 폴더에 진입하기
<strong>touch</strong> : 파일 생성하기
<strong>cat</strong> : 파일의 내용을 터미널에 출력하기
<strong>rm</strong> : 폴더나 파일 삭제하기
(- 옵션 <code>r</code>(recursive) <code>f</code>(force))
<strong>mv</strong> : 폴더나 파일의 이름을 변경, 또는 폴더나 파일의 위치 옮기기 (<code>[폴더나 파일의 이름]</code> <code>[도착 폴더의 이름]</code>를 입력)
<strong>cp</strong> : 폴더나 파일을 복사하기
<em><strong>sudo</strong></em> : 관리자 권한을 획득하는 명령어</p>
</blockquote>
<p>터미널에서 텍스트 편집하기!
 vim을 이용! <a href="https://iamfreeman.tistory.com/entry/vi-vim-%ED%8E%B8%EC%A7%91%EA%B8%B0-%EB%AA%85%EB%A0%B9%EC%96%B4-%EC%A0%95%EB%A6%AC-%EB%8B%A8%EC%B6%95%ED%82%A4-%EB%AA%A8%EC%9D%8C-%EB%AA%A9%EB%A1%9D">자세한 내용</a>
<img src="https://images-ext-2.discordapp.net/external/5dCn7LOM9WEZbB8o-i03AwHXw8X8zCqXtzaCYKwtCzw/%3Fscode%3Dmtistory2%26fname%3Dhttps%253A%252F%252Fblog.kakaocdn.net%252Fdn%252Flpc7o%252FbtqxDU9uTIy%252F8JvHLA2M1ikoUURGsdghpK%252Fimg.gif/https/img1.daumcdn.net/thumb/R800x0/?width=630&height=445"></p>
<hr>

<h2 id="📌-패키지와-패키지매니저">📌 패키지와 패키지매니저</h2>
<p>패키지는 여러 파일이 담겨있는 하나의 상자!</p>
<blockquote>
<p>패키지 안에는 하나의 프로그램이 정상적으로 설치되고 동작하기 위한 모든 파일이 압축되어 있다.</p>
</blockquote>
<p>패키지 파일의 구성</p>
<ul>
<li>프로그램 파일</li>
<li>프로그램 설치 파일</li>
<li>프로그램 설치 설명서</li>
<li>프로그램에 대한 정보를 담은 파일</li>
</ul>
<p>Ubuntu 운영체제는 apt라는 패키지 매너저가 있다.</p>
<blockquote>
<h4 id="주요-명령어">주요 명령어</h4>
</blockquote>
<ul>
<li>패키지 목록 갱신: apt update(관리자 권한 필요)<ol>
<li>패키지를 다운로드할 수 있는 여러 저장소의 최신 정보를 업데이트한다. 새로운 저장소를 추가하거나, 패키지를 설치하기 전, 최신 정보를 갱신한다.</li>
<li>설치된 프로그램이 새로운 버전으로 변경되지 않는다.</li>
</ol>
</li>
<li>업그레이드 가능한 패키지 목록을 출력: apt list -—upgradable</li>
<li>전체 패키지 업그레이드(버전 업): apt upgrade (관리자 권한 필요)</li>
<li>특정 패키지만 업그레이드(버전 업): apt --only-upgrade install 패키지 이름 (관리자 권한 필요)</li>
<li>패키지 설치: apt install 패키지 이름 (관리자 권한 필요)</li>
<li>설치된 패키지 보기: apt list --installed</li>
<li>패키지 검색: apt search 검색어</li>
<li>패키지 정보 확인: apt show 패키지 이름</li>
<li>패키지 삭제: apt remove 패키지 이름(관리자 권한 필요)</li>
</ul>
<p>** Unix 기반 운영체제에서는 <code>Ctrl</code> + <code>C</code> 키는 작업을 취소**</p>
<p><strong>복사: (Ubuntu) Ctrl + Shift + c</strong></p>
<p><strong>붙여넣기: (Ubuntu) Ctrl + Shift + v</strong></p>
<h2 id="📌-nodejs">📌 Node.js</h2>
<p>Node.js는 JavaScript가 돌아가는 환경이다. </p>
<p> 당연히 Node.js를 설치해야 한다. 별도의 프로그램으로 설치할 수도 있지만, nvm(Node Version Manager)을 사용하면 Node.js의 다양한 버전을 쉽게 설치하고, 사용할 수 있기 때문에  nvm을 설치하는 것을 권장한다.
 설치 명령
<code>wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh(버전임..! 공식문서에서 확인하고 넣기) | bash</code></p>
<p>설치 확인(버전 확인)
<code>nvm --version</code></p>
<p>Node.js 설치 (nvm 이용)
<code>nvm install --lts</code>
<code>nvm -v</code> </p>
<p>Node.js 환경에서 JavaScript 파일 실행
<code>node index.js</code></p>
<p> package.json 생성 
 <code>npm init</code></p>
<h4 id="packagejson이란">package.json이란?</h4>
<p>npm 모듈을 활용하기 위해 해당 모듈에 대한 정보를 담은 파일.</p>
<ul>
<li>package.json에는 이 프로그램을 실행시키기 위해 필요한 모듈들이 무엇인지, 프로그램을 실행시키는 방법, 프로그램을 테스트하는 방법 등이 명시되어 있다.</li>
<li>위의 이유 때문에 package.json이 포함된 프로젝트 코드를 전달할 때, 포함하고 있는 모든 모듈을 다 전달하지 않아도 된다.</li>
</ul>
<blockquote>
<p>devDependencies :프로그램 실행과 관계없는 오로지 개발을 위해 필요한 dependency (의존성 모듈)
dependencies : devDependencies와는 다르게, 이 프로젝트가 돌아가기 위해 반드시 필요한 모듈들이 무엇인지가 적혀 있다. (직접 실행과 관련 있는 dependency)</p>
</blockquote>
<hr>

<h2 id="✨마무리">✨마무리</h2>
<p>CLI 오랜만이다.. 2학년, 3학년에 가상머신에서 조금 만져본 기억이 살짝 나면서 막 어렵지 않았당.. Node.js 환경도 웹 개발 혼자 독학하ㅣ면서 봤던 부분이라 ㅎㅎ 복습 느낌이었당! 그래두 확실하게 내용 한 번 더 봐서 재밌네용~ </p>
<p>오늘이 블로그 챌린지 마지막 날이다..! 10일동안 꾸준하게 기록하면서 놓쳤던 부분을 다시 확인하고 어려웠던 부분도 한 번 더 보고 갈 수 있어서 좋았다. 블로깅은 좋은 습관이다! 아자자 챌린지는 끝났지만, 나는 계속 기록해야징~ ㅎ.ㅎ </p>
<p> (사실 오늘 깃도 했지만,, 이건 나중에 더 공부해서 !! 다시 함 정리해야...)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Pair Programming]]></title>
            <link>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-Pair-Programming-mpuidwh5</link>
            <guid>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-Pair-Programming-mpuidwh5</guid>
            <pubDate>Fri, 21 Apr 2023 09:34:14 GMT</pubDate>
            <description><![CDATA[<h2 id="✨-seb-fe">✨ SEB FE</h2>
<p>Unit6 간단한 웹앱 만들기
계산기 기능을 JavaScript로 구현하기!</p>
<hr>


<h2 id="👥-pair-programming">👥 Pair Programming</h2>
<h4 id="계산기-기능-구현-과제">계산기 기능 구현 과제</h4>
<h3 id="🌱-bare-minimum">🌱 Bare Minimum</h3>
<p>Bare Minimum Requirements는 소프트웨어가 그 역할을 하기에 필요한 최소한의 요구사항이다.</p>
<h5 id="🐣-test목록">🐣 test목록</h5>
<img src="https://velog.velcdn.com/images/strong-minsu/post/280edb03-50f7-4c74-a47c-e1a628662943/image.png" width="700">

<h4 id="🐣-코드">🐣 코드</h4>
<pre><code class="language-javascript">const calculator = document.querySelector(&quot;.calculator&quot;); // calculator 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
const buttons = calculator.querySelector(&quot;.calculator__buttons&quot;); // calculator__keys 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.

const firstOperend = document.querySelector(&quot;.calculator__operend--left&quot;); // calculator__operend--left 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
const operator = document.querySelector(&quot;.calculator__operator&quot;); // calculator__operator 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
const secondOperend = document.querySelector(&quot;.calculator__operend--right&quot;); // calculator__operend--right 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
const calculatedResult = document.querySelector(&quot;.calculator__result&quot;); // calculator__result 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.

function calculate(n1, operator, n2) {
  let result = 0;
  // TODO : n1과 n2를 operator에 따라 계산하는 함수를 만드세요.
  // ex) 입력값이 n1 : &#39;1&#39;, operator : &#39;+&#39;, n2 : &#39;2&#39; 인 경우, 3이 리턴됩니다.
  //숫자들을 정수로 전환!
  let number1 = parseFloat(n1);
  let number2 = parseFloat(n2);

  //입력받은 operator에 맞게 계산 수행
  if (operator === &quot;+&quot;) {
    result = number1 + number2;
  } else if (operator === &quot;-&quot;) {
    result = number1 - number2;
  } else if (operator === &quot;*&quot;) {
    result = number1 * number2;
  } else {
    //operator === &quot;/&quot;
    result = number1 / number2;
  }
  // console.log(result);
  //결과 string로 리턴
  return String(result);
}

let numberbtn = 1; //1인경우 첫번째 숫자, 2인경우 두번째 숫자
let isOperator = false; //연산자가 눌렸는지
let isDecimal = false; //소수점이 눌렸는지
let isResult = false; //계산이 이미 진행된 상태인지

//과제1. 계산기 구현하기
buttons.addEventListener(&quot;click&quot;, function (event) {
  // 버튼을 눌렀을 때 작동하는 함수입니다.

  const target = event.target; // 클릭된 HTML 엘리먼트의 정보가 저장되어 있습니다.
  const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보를 가져옵니다.
  const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보를 가져옵니다.
  // ! 위 코드(Line 19 - 21)는 수정하지 마세요.

  if (target.matches(&quot;button&quot;)) {
    // TODO : 계산기가 작동할 수 있도록 아래 코드를 수정하세요. 작성되어 있는 조건문과 console.log를 활용하시면 쉽게 문제를 풀 수 있습니다.
    // 클릭된 HTML 엘리먼트가 button이면
    // 계산되기 완료 전
    if (!isResult) {
      if (action === &quot;number&quot;) {
        // 그리고 버튼의 클레스가 number이면
        // 아래 코드가 작동됩니다.
        if (numberbtn === 1 &amp;&amp; !isDecimal) {
          //첫번째 숫자가 눌리는 중이고 소수점이 없을 때
          firstOperend.textContent = buttonContent;
        } else if (numberbtn === 1 &amp;&amp; isDecimal) {
          //첫번째 숫자가 눌리는 중이고 소수점이 눌렸을 때
          firstOperend.textContent += buttonContent;
        } else {
          //두번째 숫자
          if (isOperator) {
            if (!isDecimal) {
              //두번째 숫자 눌리는 중이고 소수점이 없을 때
              secondOperend.textContent = buttonContent;
            } else {
              //두번째 숫자 눌리는 중이고 소수점이 눌렸을 때
              secondOperend.textContent += buttonContent;
            }
          }
        }
      }

      if (action === &quot;operator&quot;) {
        if (!isOperator) {
          operator.textContent = buttonContent;
          isOperator = true;
          numberbtn = 2;
          isDecimal = false;
        }
      }

      if (action === &quot;decimal&quot;) {
        if (numberbtn === 1) {
          //첫번째 숫자가 소수점이 눌렀을 때
          if (!isDecimal) {
            firstOperend.textContent = firstOperend.textContent + &quot;.&quot;;
            isDecimal = true;
          }
        } else {
          //두번째 숫자가 소수점이 눌렀을 때
          if (!isDecimal) {
            secondOperend.textContent = secondOperend.textContent + &quot;.&quot;;
            isDecimal = true;
          }
        }
      }

      if (action === &quot;clear&quot;) {
        firstOperend.textContent = 0;
        operator.textContent = &quot;+&quot;;
        secondOperend.textContent = 0;
        calculatedResult.textContent = 0;
        numberbtn = 1;
        isOperator = false;
        isDecimal = false;
      }

      if (action === &quot;calculate&quot;) {
        let result = calculate(
          firstOperend.textContent,
          operator.textContent,
          secondOperend.textContent
        );
        calculatedResult.textContent = result;
        isResult = true;
      }
    }

    //계산이 완료된 상태이면서 초기화 전 (넘버 버튼은 처리 X)
    else {
      if (action === &quot;clear&quot;) {
        firstOperend.textContent = 0;
        operator.textContent = &quot;+&quot;;
        secondOperend.textContent = 0;
        calculatedResult.textContent = 0;
        numberbtn = 1;
        isOperator = false;
        isDecimal = false;
        isResult = false;
      }

      if (action === &quot;calculate&quot;) {
        let result = calculate(
          firstOperend.textContent,
          operator.textContent,
          secondOperend.textContent
        );
        calculatedResult.textContent = result;
        isResult = true;
      }
    }
  }
});</code></pre>
<hr>

<h3 id="🌿-advanced-challenge--nightmare">🌿 Advanced Challenge &amp; Nightmare</h3>
<p>Bare Minimum Requirements를 넘어 User flow에 맞게 구현하기</p>
<h4 id="🐥-test목록">🐥 test목록</h4>
<p><img src="https://velog.velcdn.com/images/strong-minsu/post/9779565b-abfc-40fd-8bfb-8295e6e98da4/image.png
" width="700">
<img src="https://velog.velcdn.com/images/strong-minsu/post/d4c4595f-86a5-45da-b1bc-4fca60fc7560/image.png
" width="700"></p>
<h4 id="🐥-코드">🐥 코드</h4>
<pre><code class="language-javascript">//과제2. User flow에  따라 기능 구현하기
const display = document.querySelector(&quot;.calculator__display--for-advanced&quot;); // calculator__display 엘리먼트와, 그 자식 엘리먼트의 정보를 모두 담고 있습니다.
let firstNum, operatorForAdvanced, previousKey, previousNum;

previousKey = false; //false:숫자버튼이 눌리면 false //true:연산자버튼이 눌리면 true
operatorForAdvanced = &quot;&quot;;
let isResult2 = false;
let isDecimal2 = false; //소수점이 눌렸는지
let continuousOperation = false; //연속 연산인지

buttons.addEventListener(&quot;click&quot;, function (event) {
  // 버튼을 눌렀을 때 작동하는 함수입니다.

  const target = event.target; // 클릭된 HTML 엘리먼트의 정보가 저장되어 있습니다.
  const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보를 가져옵니다.
  const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보를 가져옵니다.
  // ! 위 코드는 수정하지 마세요.

  // ! 여기서부터 Advanced Challenge &amp; Nightmare 과제룰 풀어주세요.
  if (target.matches(&quot;button&quot;)) {
    // TODO : 계산기가 작동할 수 있도록 아래 코드를 수정하세요. 작성되어 있는 조건문과 console.log를 활용하시면 쉽게 문제를 풀 수 있습니다.
    // 클릭된 HTML 엘리먼트가 button이면
    // 계산되기 완료 전
    if (action === &quot;number&quot;) {
      // 그리고 버튼의 클레스가 number이면
      // 아래 코드가 작동됩니다.
      if (isResult2) {
        display.textContent = &quot;0&quot;;
        isResult2 = false;
        firstNum = undefined;
        previousNum = undefined;
      }
      console.log(&quot;숫자 &quot; + buttonContent + &quot; 버튼&quot;);

      if (!previousKey) {
        if (display.textContent === &quot;0&quot;) {
          if (!isDecimal2) {
            // 처음 0인 상태 -&gt; 소수점 입력이 안된 상태
            display.textContent = buttonContent;
          } else {
            // 소수점 입력된 상태
            display.textContent += buttonContent;
          }
        } else {
          // 0이 아닌 경우 그냥 계속 옆에 추가
          display.textContent += buttonContent;
        }
      } else {
        if (!isDecimal2) {
          // 처음 0인 상태 -&gt; 소수점 입력이 안된 상태
          display.textContent = buttonContent;
        } else {
          // 소수점 입력된 상태
          display.textContent += buttonContent;
        }
      }

      previousKey = false;
    }

    if (action === &quot;operator&quot;) {
      console.log(&quot;연산자 &quot; + buttonContent + &quot; 버튼&quot;);
      if (!previousKey) {
        if (firstNum !== undefined) {
          console.log(previousNum);
          //연속 연산
          previousNum = display.textContent;
          firstNum = calculate(firstNum, operatorForAdvanced, previousNum);
          console.log(firstNum);
          continuousOperation = true;
        } else {
          //첫 연산
          firstNum = display.textContent;
        }
        previousKey = true;
        isDecimal2 = false;
      }
      operatorForAdvanced = buttonContent;
      console.log(operatorForAdvanced);
    }

    if (action === &quot;decimal&quot;) {
      console.log(&quot;소수점 버튼&quot;);
      if (!isDecimal2) {
        display.textContent += &quot;.&quot;;
        isDecimal2 = true;
      }
      if (previousKey || display.textContent === previousNum) {
        display.textContent = &quot;0.&quot;;
      }
    }

    if (action === &quot;clear&quot;) {
      console.log(&quot;초기화 버튼&quot;);

      //전부 초기화
      display.textContent = 0;
      isDecimal2 = false;
      operatorForAdvanced = &quot;&quot;;
      continuousOperation = false;
      firstNum = undefined;
      previousNum = undefined;
    }

    if (action === &quot;calculate&quot;) {
      // console.log(operatorForAdvanced);
      if (operatorForAdvanced !== &quot;&quot;) {
        if (isResult2) {
          //enter 반복
          firstNum = display.textContent;
          let result = calculate(firstNum, operatorForAdvanced, previousNum);
          display.textContent = `${result}`;
        } else {
          //enter 처음
          if (!continuousOperation) {
            //처음 enter &amp; 연속 계산이 아닐때
            console.log(&quot;계산 버튼&quot;);
            previousNum = display.textContent;
            let result = calculate(firstNum, operatorForAdvanced, previousNum);
            display.textContent = `${result}`;
          } else {
            //처음 enter &amp; 연속 계산일 때
            previousNum = display.textContent;
            let result = calculate(firstNum, operatorForAdvanced, previousNum);
            display.textContent = `${result}`;
            continuousOperation = false;
          }
          isResult2 = true;
        }
      }
    }
  }
});</code></pre>
<hr>

<h2 id="✨-마무리">✨ 마무리</h2>
<p>오늘 하루종일 이 기능만.. ㅎㅎ JavaScript에 익숙해지려고 했는데 아직 조금 부족한 느낌이다.. ㅠ_ㅠ! 그래도 test 전부 통과해서 기분이 좋다! 처음에 설명 자료 참고를 까먹고 내 맘대로 구현하다가 다 갈아버린 ... 슬픈 기록 그래도 덕분에 &#39;초심으로 돌아가기&#39; 마인드를 배웠다. 다시 처음으로 돌아가야하는 날이 있을 수 있는데 , 그 때 너무 실망하지 않게 연습하는 기분! 아자자</p>
<p>아 그리고 아직 .. 코드가 많이 더러워서 올리기 창피하지만..! 고치고 싶은ㄷ..ㅍ_ㅍ 힘들다.. 내일 다시 생각해봐야겠당!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript 기초 3]]></title>
            <link>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-JavaScript-%EA%B8%B0%EC%B4%88-3</link>
            <guid>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-JavaScript-%EA%B8%B0%EC%B4%88-3</guid>
            <pubDate>Thu, 20 Apr 2023 02:56:11 GMT</pubDate>
            <description><![CDATA[<h2 id="✨-seb-fe">✨ SEB FE</h2>
<p>Unit5 JavaScript 기초</p>
<blockquote>
<p>💡 사람들은 모든 것이 변하기를 바라는 동시에, 모든 것이 그대로 남아 있기를 바란다.
&quot;People want to change everything and, at the same time want it all to remain the same.&quot;
-파울로 코엘료(Paul Coelho)</p>
</blockquote>
<hr>

<h2 id="📌-함수">📌 함수</h2>
<h3 id="🔍-함수란">🔍 함수란?</h3>
<p>함수: 입력에 따라 그에 걸맞은 작업을 하는 하나의 작업 단위, 논리적인 일련의 작업을 하는 하나의 단위</p>
<p><strong>입력을 받아서 코드블록 내부의 코드를 실행한 후 함수의 실행결과를 반환하는 일련의 과정의 묶음이다.</strong>
<img src="https://velog.velcdn.com/images/strong-minsu/post/d062a71f-9baa-4556-b35e-6efb4201078c/image.png" width="250"></p>
<p> 함수를 사용한다는 것은 특정한 코드실행 과정을 하나의 묶음으로 묶어서 필요할 때마다 호출하여 실행한다는 것을 의미한다. 자주 사용하는 기능, 계산 등은 함수로 작성해 호출하여 사용할 수 있다.</p>
<h3 id="🔍-함수-선언-표현">🔍 함수 선언, 표현</h3>
<p>변수를 선언하듯 함수 선언 키워드인 function 키워드를 사용하여 함수를 선언하는 방식을 함수선언문, 함수 선언 키워드가 아닌 변수 선언 키워드를 사용하여 함수를 ‘표현’한 방식을 함수표현식 이렇게 두 가지가 있다.</p>
<h4 id="1-함수선언문">1. 함수선언문</h4>
<p>함 수 선언 키워드인 funcstion으로 함수를 &quot;선언&quot;</p>
<pre><code class="language-javascript">function greeting(){
  console.log(&quot;hello world&quot;);
};</code></pre>
<h4 id="2-함수표현식">2. 함수표현식</h4>
<p>변수에 함수를 할당하여 함수를 &quot;표현&quot;</p>
<pre><code class="language-javascript">let  greeting = function(){
  console.log(&quot;hello world&quot;);
};</code></pre>
<h3 id="🔍-매개변수와-전달인자">🔍 매개변수와 전달인자</h3>
<p>매개변수는 함수를 정의할 때 선언하고, 함수 코드 블록 안에서 변수처럼 취급된다. 
함수를 호출할 때 소괄호 안에 전달인자값을 넣음으로써 매개변수에 값을 할당할 수 있다.</p>
<pre><code class="language-javascript">function greeting(name){ // 매개변수: name
  console.log(&quot;hello &quot;+name);
};

greeting(&quot;minsu&quot;)    // 전달인자: &quot;minsu&quot;</code></pre>
<h3 id="🔍return">🔍return</h3>
<p><strong>함수의 반환값!</strong></p>
<blockquote>
<h4 id="return의-역할">return의 역할</h4>
</blockquote>
<ul>
<li>함수 내부의 코드가 차례대로 실행되다가 return문을 만나면 값을 반환한 후 함수는 종료된다. 다시 말해 return문 뒤에 나오는 코드는 실행되지 않는다.</li>
<li>return문에 작성된 코드를 실행한 후 결과를 함수 외부로 리턴한다. 함수 외부에서 함수를 호출하면 함수의 실행결과를 확인할 수 있다.</li>
<li>함수 호출의 결과를 변수에 할당하는 것도 가능하다.</li>
<li>함수의 호출 결과끼리의 연산도 가능하다.</li>
</ul>
<hr>

<h2 id="✨-마무리">✨ 마무리</h2>
<p>함수공부완료~ 함수 만드는 건 재밌다..(?)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript 기초 2]]></title>
            <link>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-JavaScript-%EA%B8%B0%EC%B4%88-2</link>
            <guid>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-JavaScript-%EA%B8%B0%EC%B4%88-2</guid>
            <pubDate>Wed, 19 Apr 2023 02:53:02 GMT</pubDate>
            <description><![CDATA[<h2 id="✨-seb-fe">✨ SEB FE</h2>
<p>Unit5 JavaScript 기초</p>
<blockquote>
<p>💡 꿈을 이룰 수 있다는 가능성을 믿을 때 삶이 흥미롭게 느껴지는 것이다,
&quot;It&#39;s the possibility of having a dream come true that makes life interesting.&quot; 
-파울로 코엘료(Paul Coelho)</p>
</blockquote>
<hr>

<h2 id="📌-조건문">📌 조건문</h2>
<h3 id="🔍-if-문">🔍 if 문</h3>
<p>if문은 주어진 조건식의 참(true)/거짓(false) 여부에 따라 실행이 결정된다. 참과 거짓을 판단하기 위한 JavaScript의 타입은 불린 타입이고 이를 참고하면, 조건식은 결과가 불린 타입이 되도록 작성해야 한다.</p>
<p>아래의 연산자를 사용해 조건문의 조건을 완성할 수 있다 <a href="https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-JavaScript-%EA%B8%B0%EC%B4%88">자세한 내용</a></p>
<blockquote>
<h4 id="1-">1. ===</h4>
<p>동치연산자(===)는 두 피연산자가 동일하면 true, 그렇지 않으면 false를 반환</p>
</blockquote>
<h4 id="2-">2. !==</h4>
<p>!==는 반대로 두 피연산자가 동일하지 않으면 true, 동일하면 false를 반환</p>
<h4 id="3-비교연산자">3. 비교연산자</h4>
<p>비교연산자(&gt; , &lt; , &gt;= , &lt;=) 비교연산자는 두 피연산자의 값의 크기를 비교</p>
<h4 id="4-논리연산자-">4. 논리연산자(&amp;&amp;, ||)</h4>
<p>논리합(||)과 논리곱(&amp;&amp;)을 사용하면 복수의 조건을 작성할 수 있다. </p>
<h4 id="5-부정연산자">5. 부정연산자(!)</h4>
<p>부정연산자는 조건을 부정, 조건이 true이면 false, 조건이 false이면 true를 리턴한다.</p>
<h3 id="🔍-else-문">🔍 else 문</h3>
<p>if문을 사용하여 조건식이 true일 때만 코드가 실행되도록 할 수 있었다. 그런데 조건이 true일 때, 그리고 false일 때 각각 다른 코드가 실행되도록 하기 위해서는 else문이 필요하다.
<strong>else문은 독립적으로 사용할 수 없다!</strong></p>
<p>조건이 더 필요하면 else if()문을 사용해 조건을 추가할 수 있다.</p>
<pre><code class="language-javascript">if(){}            //조건을 달 수 있음, 중복 사용 불가능
else if(){}        //또 다른 조건 달 수 있음, 중복 사용 가능
else{}            //조건을 달 수 없음, 중복 사용 불가능, 독립 사용 불가능</code></pre>
<h3 id="🔍-삼항-조건-연산자">🔍 삼항 조건 연산자</h3>
<p>if문과 else문을 삼항 조건 연산자로 바꿔 쓸 수 있다.</p>
<blockquote>
<p>삼항 조건 연산자는 조건식을 먼저 작성한 후 ?를 입력하고, ?뒤로 참/거짓일 때 실행할 코드를 각각 입력한다. 참/거짓일 때 실행할 코드는 :로 구분한다.</p>
</blockquote>
<p>예시</p>
<pre><code class="language-javascript">//if, else문
let num = 5;
if (num % 2 === 0) {
    console.log(&#39;짝수&#39;);
} else {
    console.log(&#39;홀수&#39;); // &#39;홀수&#39;
}</code></pre>
<pre><code class="language-javascript">//삼항 조건 연산자
let num = 5;
num % 2 === 0 ? console.log(&#39;짝수&#39;) : console.log(&#39;홀수&#39;); // &#39;홀수&#39;</code></pre>
<hr>

<h2 id="📌-반복문">📌 반복문</h2>
<p>반복문을 사용하면 불필요한 코드를 반복적으로 사용하지 않고 간결하게 코드를 작성할 수 있다.</p>
<h3 id="🔍-for-문">🔍 for 문</h3>
<p>for 뒤에 오는 소괄호(())에는 각각 초기값, 조건식, 증감식이 들어간다!</p>
<pre><code class="language-javascript">for (초기값; 조건식; 증감식) {
    // 실행할 코드
}</code></pre>
<ul>
<li>초기값 : 증감식 반복 횟수를 카운트하는 역할을 하는 변수이다. 초기값은 반복문의 코드블록 내부에서만 유효하고 선언은 처음에만 이루어진다.</li>
<li>조건식 : 코드블록 내부의 코드 실행 여부를 결정한다. 조건식의 결과가 true일 경우 코드를 실행하고, false일 경우 반복문이 종료된다.</li>
<li>증감식 : 코드블록 내부의 코드를 실행한 후 초기값으로 선언된 변수를 증가 또는 감소시키기 위한 표현식이다.</li>
</ul>
<h3 id="🔍-while-문">🔍 while 문</h3>
<p>초기화, 조건식, 증감식이 모두 필요한 for문과 달리 while문은 조건식만 입력한 후 조건식의 평가결과가 true인 경우 코드블록 내부의 코드를 반복하여 실행한다.</p>
<pre><code class="language-javascript">while (조건식) {
    // 실행할 코드
}</code></pre>
<h3 id="🔍-do-while-문">🔍 do while 문</h3>
<p>do…while문은 while 뒤에 오는 조건식이 true로 평가되는 동안 do 뒤에 오는 코드블록 내부의 코드를 반복하여 실행한다. 단, <strong>이 경우 do의 코드블록 내부의 코드가 최소 한 번은 실행된다.</strong></p>
<pre><code class="language-javascript">do {
    // 실행할 코드
} while(조건식)</code></pre>
<h3 id="🔍-for문과-while문">🔍 for문과 while문</h3>
<p>for문과 while문의 용도는 명확하게 구분되지 않는다. while문으로 할 수 있는 것을 for문으로 구현이 가능하고, for문으로 할 수 있는 것을 while문으로 구현이 가능하다.
아래 상황은 주로 사용하는 상황이다.</p>
<blockquote>
<h4 id="for문을-사용하는-경우">for문을 사용하는 경우</h4>
</blockquote>
<ul>
<li>반복 횟수가 비교적 명확할 때</li>
<li>배열, 문자열 내부를 순회할 때</li>
<li>반복문의 중첩이 필요할 때</li>
</ul>
<blockquote>
<h4 id="while문을-사용하는-경우">while문을 사용하는 경우</h4>
</blockquote>
<ul>
<li>반복 횟수가 명확하지 않을 때</li>
</ul>
<hr>

<h2 id="✨마무리">✨마무리</h2>
<ul>
<li><p>오늘은 평소에 알던 조건문.. 가볍게 공부하고 문제도 풀었당 js로 문제를 풀어보는 건 처음이랗ㅎ 검색을 좀 했었다.. ㅎㅎ 그래도 기본적인 로직같은건 생각이나서 은근 쉬웠다는! 아 글고 삼항 조건 연산자 나는 자주 안쓰는데, 연습을 해봐야겠다! ㅎ</p>
</li>
<li><p>20일 반복문 공부도 여기에 같이 쓰기로 했다!! ㅎ.. 마무리가 2번~ 조건, 반복은 뭔가 프로그래밍의 꽃인 느낌..🌷 연습 많이해야징!!</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript 기초 1]]></title>
            <link>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-JavaScript-%EA%B8%B0%EC%B4%88</link>
            <guid>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-JavaScript-%EA%B8%B0%EC%B4%88</guid>
            <pubDate>Tue, 18 Apr 2023 05:57:50 GMT</pubDate>
            <description><![CDATA[<h2 id="✨-seb-fe">✨ SEB FE</h2>
<p>Unit5 JavaScript 기초</p>
<blockquote>
<p>💡 당신이 가진 두려움으로 인해서 무언가를 포기하지 마라. 만약 그렇게 한다면, 당신은 당신의 마음과 진정으로 대화할 기회를 놓치게 될 것이다.
&quot;Don&#39;t give in to your fears. If you do, you won&#39;t be able to talk to your heart.&quot;
-파울로 코엘료(Paul Coelho)</p>
</blockquote>
<hr>

<h2 id="📌-javascript">📌 JavaScript?</h2>
<h3 id="🔍-javascript">🔍 JavaScript</h3>
<blockquote>
<p>JavaScript는 객체 기반의 스크립트 프로그래밍 언어이다. 이 언어는 웹 브라우저 내에서 주로 사용되며, 다른 응용 프로그램의 내장 객체에도 접근할 수 있는 기능을 가지고 있다. 또한 Node.js와 같은 런타임 환경과 같이 서버 프로그래밍에도 사용되고 있다. <a href="https://en.wikipedia.org/wiki/JavaScript">(Wikipedia)</a></p>
</blockquote>
<p>JavaScript는 원래 브라우저에서 실행하기 위해 만들어진 프로그래밍 언어이다. 따라서 HTML파일과 함께 브라우저에서 실행하거나 따로 Node.js(JavaScript 런타임)을 설치해 사용해야한다.</p>
<ul>
<li><p><a href="https://stackblitz.com/">Stack Blitz</a>
웹 애플리케이션 개발을 위한 클라우드 통합 개발 환경이다. 이곳에서 JavaScript 코드를 실행해볼 수 있다.</p>
</li>
<li><p><a href="https://stackblitz.com/">Stack Blitz</a>로 JavaScript 코드를 실행하는 두 가지 방법</p>
<ol>
<li>index.js 파일에 원하는 JavaScript 코드를 작성하고, Terminal에 node index.js를 입력하고 엔터를 누르면 작성한 코드가 실행되고 출력 결과를 확인할 수 있다.</li>
</ol>
</li>
</ul>
<ol start="2">
<li>Terminal에 node를 입력하면 REPL을 사용할 수 있다. REPL 사용을 종료하려면 .exit를 입한다.<blockquote>
<p>REPL(Read-Evaluate-Print loop): 읽고(read), 평가(evaluate)하고, 출력(print)을 반복(loop)하는 가장 간단한 개발 환경 </p>
</blockquote>
</li>
</ol>
<h3 id="🔍-javascript의-데이터-타입">🔍 JavaScript의 데이터 타입</h3>
<p>타입(type)은 값(value)의 종류이다.
<code>typeof</code> 연산자로 타입을 확인할 수 있다.</p>
<h4 id="1-number-🌱">1. Number 🌱</h4>
<p>JavaScript의 여러 데이터 타입 중 Number는 일상생활에서 흔히 접할 수 있는 숫자를 자바스크립트에서 표현하기 위한 데이터 타입이다. 정수(integer)와 실수(float)를 모두 표현할 수 있다.</p>
<blockquote>
<h5 id="math-내장-객체">Math 내장 객체</h5>
</blockquote>
<ul>
<li>Math.floor(): 괄호 안의 숫자를 내림하여 반환합니다.</li>
<li>Math.ceil(): 괄호 안의 숫자를 올림하여 반환합니다.</li>
<li>Math.round(): 괄호 안의 숫자를 반올림하여 반환합니다.</li>
<li>Math.abs(): 괄호 안의 숫자의 절대값을 반환합니다.</li>
<li>Math.sqrt(): 괄호 안의 숫자의 루트값을 반환합니다.</li>
<li>Math.pow() : 괄호 안의 첫 번째 숫자를 밑, 두 번째 숫자를 지수인 숫자를 반환합니다.</li>
</ul>
<h4 id="2-string-🌱">2. String 🌱</h4>
<p>JavaScript 데이터 타입 String(문자열)은 인간의 언어, 자연어를 JavaScript에서 표현하기 위한 데이터 타입이다. 따옴표(’), 큰따옴표(”), 백틱(`)으로 감싸면 된다. 맥북의 경우 백틱은 영어로 전환하고 물결(~)을 누르면 입력할 수 있다.</p>
<ul>
<li><p>length 속성
문자열의 length 속성을 이용하여 문자열의 길이를 확인할 수 있다. 문자열 값에 .length 를 붙이면 된다.</p>
</li>
<li><p>인덱스(Index) 
문자열의 각 문자는 순서를 가지고 있다. 각 문자가 몇 번째에 위치하는지 인덱스(Index)로 확인할 수 있다. Zero-based numbering을 따르고 있다. (시작이 0부터)</p>
</li>
</ul>
<blockquote>
<h5 id="문자열-주요-메서드">문자열 주요 메서드</h5>
</blockquote>
<ul>
<li>toLowerCase() : 문자열을 소문자로 변경합니다.</li>
<li>toUpperCase() : 문자열을 대문자로 변경합니다.</li>
<li>concat() : 문자열 연결 연산자 +처럼 문자열을 이어 붙일 수 있습니다.</li>
<li>slice() : 문자열의 일부를 자를 수 있습니다.</li>
<li>indexOf() : 문자열 내에 특정 문자가 몇 번째 위치하는지 확인합니다.</li>
<li>includes() : 문자열 내에 특정 문자가 포함되어 있는지 확인합니다.</li>
</ul>
<h4 id="3-boolean-🌱">3. Boolean 🌱</h4>
<p>JavaScript 데이터 타입 Boolean(불리언)은 사실 관계를 구분하기 위한 타입이다. 불리언 타입의 값은 <code>true</code> 혹은 <code>false</code> 둘 중 하나이다.</p>
<pre><code class="language-javascript">true;
false;</code></pre>
<blockquote>
<h5 id="falsy한-값--불리언-타입은-아니지만-자바스크립트에서-false로-여겨지는-값이-일부-있는데-이를-falsy-값이라고-한다">falsy한 값? : 불리언 타입은 아니지만, 자바스크립트에서 false로 “여겨지는” 값이 일부 있는데, 이를 falsy 값이라고 한다.</h5>
</blockquote>
<pre><code class="language-javascript">// 대표적인 falsy 값
false
0
-0
0n
&quot;&quot;
&#39;&#39;
``
null
undefined
NaN```

Boolean 타입의 연산자

1. 비교연산자(comparison operator)
&gt;```===```, ```!==``` : 엄격한 동치 연산자
```==```, ```!=``` : 느슨한 동치 연산자

2. 대소 관계 비교 연산자
&gt;```&gt;``` , ```&lt;``` , ```&gt;=``` , ```&lt;=``` 

3. 논리연산자(logical operator)
&gt;```||```: 논리합(OR)
두 값 중 하나만 ture여도 결과를 true로 판단 (모두 false면 false)
```&amp;&amp;```: 논리곱(AND)
두 값 중 하나만 false여도 결과를 false로 판단 (모두 true면 true)
```!``` : 부정(NOT)
오른쪽 피연산자와 반대의 사실을 반환, falsy, truthy의 반대 값을 반환합니다.

### 🔍 JavaScript 변수

변수 선언 방법
&gt; ```변수선언키워드``` ```변수명```;&lt;br&gt;
변수 선언 키워드 종류
```var``` : 중복선언 가능 -&gt; 사용 권장하지 않음
```let``` : 재할당 가능
```const```: 재할당 불가능

변수를 선언하고  할당하지 않으면 ```undedined```가 자동할당된다.

#### 네이밍 규칙 🌱
&gt;- 식별자는 특수문자를 제외한 문자, 숫자, 언더스코어(_), 달러 기호($)를 포함할 수 있다.
- 단, 식별자는 특수문자를 제외한 문자, 언더스코어(_), 달러 기호($)로 시작해야 한다. 숫자로 시작하는 것은 허용하지 않는다.
- 예약어는 식별자로 사용할 수 없다.

#### 네이밍 컨벤션 🌱
&gt;JavaScript에서는 일반적으로 카멜 케이스(camelCase)를 사용한다. 카멜 케이스는 낙타의 등모양에서 유래된 이름으로써, 첫 단어의 첫 문자는 소문자로, 그 이후에 연결되는 단어의 첫 문자는 대문자로 작성하는 방법
```javascript
// 🐪카멜 케이스(camelCase) &lt;- JavaScript에서 사용!
let firstName = &#39;coding&#39;; 
let lastName = &#39;kim&#39;;
// 그밖에 네이밍 컨벤션
let first_name; // 🐍스네이크 케이스(snake_case) : 단어와 단어 사이에 언더스코어(_)를 사용
let FirstName; // 📐파스칼 케이스(PascalCase) : 단어의 시작을 대문자로 작성</code></pre>
<hr>

<h2 id="✨마무리">✨마무리</h2>
<p>오늘은 JavaScript를 처음부터 살펴보았다1! 시작이 좋당<del>! 자료도 은근 깔끔하고 코플릿으로 자바스크립트를 이용해 응용 문제도 많이 풀어보았다! 넘 재밌당</del> 앞으로도 아자자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Pair Programming]]></title>
            <link>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-Pair-Programming</link>
            <guid>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-Pair-Programming</guid>
            <pubDate>Mon, 17 Apr 2023 08:15:19 GMT</pubDate>
            <description><![CDATA[<h2 id="✨-seb-fe">✨ SEB FE</h2>
<p> 페어프로그래밍
저번주 금요일에 시작했던 페어프로그래밍을 마무리하는 날!</p>
<hr>

<h2 id="👥-pair-programming">👥 Pair Programming</h2>
<p>계산기 목업(Mock-up) 만들기</p>
<p><img src="https://velog.velcdn.com/images/strong-minsu/post/a7d02efa-d08f-45df-a20f-f3b7a7f9c461/image.png" alt=""></p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Calculator&lt;/title&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot; /&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=&quot;calculator&quot;&gt;
      &lt;div class=&quot;display-container&quot;&gt;
        &lt;h3&gt;calculation formula&lt;/h3&gt;
        &lt;h3&gt;result&lt;/h3&gt;
      &lt;/div&gt;
      &lt;div class=&quot;button-container&quot;&gt;
        &lt;div class=&quot;buttons&quot;&gt;
          &lt;button class=&quot;number-button&quot;&gt;AC&lt;/button&gt;
          &lt;button class=&quot;calculate-button&quot;&gt;%&lt;/button&gt;
        &lt;/div&gt;
        &lt;div class=&quot;buttons&quot;&gt;
          &lt;button class=&quot;number-button&quot;&gt;7&lt;/button&gt;
          &lt;button class=&quot;number-button&quot;&gt;8&lt;/button&gt;
          &lt;button class=&quot;number-button&quot;&gt;9&lt;/button&gt;
          &lt;button class=&quot;calculate-button&quot;&gt;+&lt;/button&gt;
        &lt;/div&gt;
        &lt;div class=&quot;buttons&quot;&gt;
          &lt;button class=&quot;number-button&quot;&gt;4&lt;/button&gt;
          &lt;button class=&quot;number-button&quot;&gt;5&lt;/button&gt;
          &lt;button class=&quot;number-button&quot;&gt;6&lt;/button&gt;
          &lt;button class=&quot;calculate-button&quot;&gt;-&lt;/button&gt;
        &lt;/div&gt;
        &lt;div class=&quot;buttons&quot;&gt;
          &lt;button class=&quot;number-button&quot;&gt;1&lt;/button&gt;
          &lt;button class=&quot;number-button&quot;&gt;2&lt;/button&gt;
          &lt;button class=&quot;number-button&quot;&gt;3&lt;/button&gt;
          &lt;button class=&quot;calculate-button&quot;&gt;*&lt;/button&gt;
        &lt;/div&gt;
        &lt;div class=&quot;buttons&quot;&gt;
          &lt;button class=&quot;number-button&quot;&gt;0&lt;/button&gt;
          &lt;button class=&quot;enter-button&quot;&gt;=&lt;/button&gt;
          &lt;button class=&quot;calculate-button&quot;&gt;/&lt;/button&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<pre><code class="language-css">* {
  box-sizing: border-box;
}

body {
  background-image: url(&quot;./배경.jpg&quot;);
  margin: 0;
  padding: 0;
  /* 100vh -&gt; 브라우저 화면의 높이만큼의 길이 */
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.calculator {
  width: 350px;
  height: 500px;
  padding: 20px 10px;
  border: 2px solid rgb(21, 31, 31);
  border-radius: 10px;
  /* 요소 정렬 */
  text-align: center;
  background-color: rgb(115, 165, 152);
  box-shadow: 3px 3px 3px 3px gray;
}

.calculator .display-container {
  width: 300px;
  height: 25%;
  border: 2px solid rgb(21, 31, 31);
  /* text-align으로 정렬될 요소기 때문에 inline-block로 변경 */
  display: inline-block;
  margin-bottom: 10px;
  background-color: #efefef;
  box-shadow: 3px 3px 3px 3px gray;
  border-radius: 5px;
}

.calculator .button-container {
  width: 310px;
  height: 70%;
  display: inline-block;
  margin-top: 5px;
  border-radius: 5px;
}

.buttons {
  width: 100%;
  height: 20%;
  /* justify-content: left; */
  /* 버튼들 관리 위헤 부모 요소에 flex 적용 &amp; 줄바꿈 없음*/
  display: flex;
  flex-wrap: nowrap;
}

.buttons button {
  font-size: 24px;
  width: 20%;
  border-radius: 10px;
  margin: 5px 5px;
  box-shadow: 2px 2px 2px 2px gray;
}

.buttons button.number-button {
  flex-grow: 1;
}

/* 마우스 버튼 위에 올릴때 나타나는 효과 hover */
.buttons button.number-button:hover {
  background-color: #d3d3d3;
  cursor: pointer;
}

/* 버튼을 클릭할 시에 나타나는 효과 active */
.buttons button.number-button:active {
  box-shadow: 1px 1px 1px 1px gray inset;
}

.buttons:first-child button.number-button:first-child,
.buttons:last-child button.number-button {
  background-color: rgb(215, 127, 110);
}

/* 마우스 버튼 위에 올릴때 나타나는 효과 hover */
.buttons:first-child button.number-button:first-child:hover,
.buttons:last-child button.number-button:hover {
  background-color: rgb(202, 119, 103);
  cursor: pointer;
}

/* 버튼을 클릭할 시에 나타나는 효과 active */
.buttons:first-child button.number-button:first-child:active,
.buttons:last-child button.number-button:active {
  box-shadow: 1px 1px 1px 1px gray inset;
}

.buttons button.calculate-button,
button.enter-button {
  width: 90px;
  background-color: rgb(223, 154, 141);
}

/* 버튼 위에 마우스를 올릴때 나타나는 효과 hover */
.buttons button.calculate-button:hover,
button.enter-button:hover {
  background-color: rgb(204, 141, 127);
  cursor: pointer;
}

/* 버튼을 클릭할 시에 나타나는 효과 active */
.buttons button.calculate-button:active,
button.enter-button:active {
  box-shadow: 1px 1px 1px 1px gray inset;
}
</code></pre>
<hr>

<h2 id="✨-마무리">✨ 마무리</h2>
<p>모두 한 번씩 프로그래밍을 접하고 오신 분들이라 확실히 커뮤니케이션이 쉬웠다! 페어분들과 함께 끝까지 과정 마무리하고싶다..~ 화이팅이야앙</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML/CSS 활용]]></title>
            <link>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-HTMLCSS-%ED%99%9C%EC%9A%A9</link>
            <guid>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-HTMLCSS-%ED%99%9C%EC%9A%A9</guid>
            <pubDate>Fri, 14 Apr 2023 09:14:08 GMT</pubDate>
            <description><![CDATA[<h2 id="✨-seb-fe">✨ SEB FE</h2>
<p>Unit4 HTML/CSS 활용</p>
<blockquote>
<p>💡 용기를 가지고, 위험을 감수하라. 왜냐하면 이 세상에서 경험을 대신할 수 있는 것은 아무것도 없기 때문이다.
&quot;Be Brave. Take Risks. Nothing can substitute experience.&quot;
-파울로 코엘료(Paul Coelho)</p>
</blockquote>
<hr>

<h2 id="📌-레이아웃layout">📌 레이아웃(Layout)</h2>
<p>레이아웃 : 요소의 위치를 목적에 맞게 배치하는 것</p>
<h3 id="🔍-와이어프레임wireframe과-목업mock-up">🔍 와이어프레임(Wireframe)과 목업(Mock-up)</h3>
<h4 id="와이어프레임wireframe">와이어프레임(Wireframe)</h4>
<p>웹 또는 애플리케이션을 개발할 때 레이아웃의 뼈대를 그리는 단계를 와이어프레임이라고 한다. 와이어프레임은 말 그대로 &quot;와이어로 설계된 모양&quot;을 의미하며, 단순한 선이나, 도형으로 웹이나 앱의 인터페이스를 시각적으로 묘사한 것이다.</p>
<h4 id="목업mock-up">목업(Mock-up)</h4>
<p>대부분의 산업에서 목업은 실물 크기의 모형을 뜻한다. 실물 제품이 없는 무형의 웹 또는 앱을 제품이라고 할 때, 목업은 실제 제품이 작동하는 모습과 동일하게 HTML 문서를 작성한다.</p>
<h3 id="🔍-화면-나누기">🔍 화면 나누기</h3>
<p>대부분의 경우 콘텐츠의 흐름은 좌에서 우, 위에서 아래로 흐릅니다. CSS로 화면을 구분할 때는 수직 분할과 수평 분할을 차례대로 적용하여 콘텐츠의 흐름을 따라 작업을 진행한다.</p>
<ol>
<li><p>[수직 분할] 화면을 수직으로 구분하여, 콘텐츠가 가로로 배치될 수 있도록 요소를 배치하기다.</p>
</li>
<li><p>[수평 분할] 분할된 각각의 요소를 수평으로 구분하여, 내부 콘텐츠가 세로로 배치될 수 있도록 요소를 배치한다.
수평으로 구분된 요소에 height 속성을 추가하면, 수평 분할을 보다 직관적으로 할 수 있다.</p>
</li>
</ol>
<h4 id="display--flex">display : flex</h4>
<p>display: flex 는 부모 박스 요소에 적용해, 자식 박스의 방향과 크기를 결정하는 레이아웃 구성 방법</p>
<blockquote>
<h4 id="부모-요소에-적용해야하는-flexbox-속성">부모 요소에 적용해야하는 Flexbox 속성</h4>
</blockquote>
<ol>
<li>flex-direction : 정렬 축 정하기</li>
<li>flex-wrap : 줄 바꿈 설정하기</li>
<li>justify-content : 축 수평 방향 정렬</li>
<li>align-items : 축 수직 방향 정렬</li>
</ol>
<blockquote>
<h4 id="자식-요소에-적용해야하는-flexbox-속성">자식 요소에 적용해야하는 Flexbox 속성</h4>
<p>flex 속성의 값 
<code>flex: &lt;grow(팽창지수)&gt; &lt;shrink(수축 지수)&gt;    &lt;basis(기본 크기)&gt;</code></p>
</blockquote>
<h3 id="💻-화면-나누기-실습">💻 화면 나누기 실습</h3>
<p>결과
<img src="https://velog.velcdn.com/images/strong-minsu/post/585ce0a6-3691-4257-9995-cb884e64bda4/image.png" width="450" height="50"/></p>
<p>코드</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot; /&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;IE=edge&quot; /&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot; /&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=&quot;vsc&quot;&gt;
      &lt;!-- 아이콘 영역 --&gt;
      &lt;div class=&quot;icons&quot;&gt;
        &lt;div class=&quot;icon&quot;&gt;아이콘1&lt;/div&gt;
        &lt;div class=&quot;icon&quot;&gt;아이콘2&lt;/div&gt;
        &lt;div class=&quot;icon&quot;&gt;아이콘3&lt;/div&gt;
      &lt;/div&gt;

      &lt;!-- 영역 1~3 --&gt;
      &lt;div class=&quot;area-div1&quot;&gt;
        &lt;div class=&quot;area1_1&quot;&gt;영역1&lt;/div&gt;
        &lt;div class=&quot;area1_1&quot;&gt;영역2&lt;/div&gt;
        &lt;div class=&quot;area1_2&quot;&gt;영역3&lt;/div&gt;
      &lt;/div&gt;

      &lt;!-- 영역 4~5 --&gt;
      &lt;div class=&quot;area-div2&quot;&gt;
        &lt;div class=&quot;area2_1&quot;&gt;영역4&lt;/div&gt;
        &lt;div class=&quot;area2_2&quot;&gt;영역5&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<pre><code class="language-css">* {
  box-sizing: border-box;
  font-size: large;
}
body {
  margin: 0;
  padding: 0;
  height: 80vh;
  justify-content: center;
  display: flex;
  justify-content: center;
  align-items: center;
}

body .vsc {
  display: flex;
  width: 80%;
  height: 55%;
}

/* 아이콘 영역 */
.vsc div.icons {
  border: 1px solid seagreen;
  flex-grow: 1;
  margin: 1px 1px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
div.icons .icon {
  border: 3px dotted tomato;
  width: 60%;
  height: 15%;
  margin: 10px 0;
}

/* 영역 1~3 */
.vsc div.area-div1 {
  border: 1px solid seagreen;
  flex-grow: 4;
  margin: 1px 1px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.vsc div.area-div1 div {
  margin: 5px 0;
}

div.area-div1 .area1_1 {
  border: 3px dotted tomato;
  width: 80%;
  flex-grow: 2;
}

div.area-div1 .area1_2 {
  border: 3px dotted tomato;
  width: 80%;
  flex-grow: 1;
}

/* 영역 4~5 */
.vsc div.area-div2 {
  border: 1px solid seagreen;
  flex-grow: 6;
  margin: 1px 1px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.vsc div.area-div2 div {
  margin: 5px 0;
}

div.area-div2 .area2_1 {
  border: 3px dotted tomato;
  width: 80%;
  flex-grow: 4;
}

div.area-div2 .area2_2 {
  border: 3px dotted tomato;
  width: 80%;
  flex-grow: 1;
}
</code></pre>
<hr>

<h2 id="✨-마무리">✨ 마무리</h2>
<p>CSS는 여전히.. 어렵! 오늘 페어프로그래밍 처음해봤는데 좋은 페어분들 만나서 기분이가 좋다..! ㅍvㅍ 자바스크립트로 문제 푸는 스터디도 결성!!(?) 주 2일씩 아침에 시작한당ㅎ 아자아자 화이팅이닷!!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS 기초]]></title>
            <link>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-CSS-%EA%B8%B0%EC%B4%88</link>
            <guid>https://velog.io/@strong-minsu/%EC%BD%94%EB%93%9C%EC%8A%A4%ED%85%8C%EC%9D%B4%EC%B8%A0-CSS-%EA%B8%B0%EC%B4%88</guid>
            <pubDate>Thu, 13 Apr 2023 06:39:16 GMT</pubDate>
            <description><![CDATA[<h2 id="✨-seb-fe">✨ SEB FE</h2>
<p>Unit3 CSS 기초</p>
<blockquote>
<p>💡 단순한것이 가장 훌륭한 것이다. 그리고 현명한 사람만이 그런 것을 볼 수 있다.
&quot;The simple things are also the most extraordinary things, and only the wise can see them.&quot;
-파울로 코엘료(Paulo Coelho)</p>
</blockquote>
<hr>

<h2 id="📌-css">📌 CSS</h2>
<h3 id="🔍-css">🔍 CSS?</h3>
<p>CSS(Cascading Style Sheets) : 웹 페이지 스타일 및 레이아웃을 정의하는 스타일시트 언어이다. </p>
<blockquote>
<p>CSS로 HTML에서 사용자가 웹 애플리케이션에 접근할 수 있는 UI를 만들게 된다.</p>
</blockquote>
<p>사용자가 서비스를 이용하기 위해서는 꼭 UI(User Interface)가 필요하다. 이때 HTML만으로 UI를 제공하게 된다면, 좋은 UX(User Experience)를 만들 수 없다. 좋은 UX는 직관적이고 쉬운 UI에서 나온다. 
사용자에게 편리한 UI를 제공하여 좋은 UX를 만들어내는 것이 중요한데 이때 사용되는 스타일 시트 언어가 CSS이다.</p>
<p>CSS에서는 색상, 글꼴, 크기, 정렬 등의 스타일을 부여할 수 있다.
<code>전부 외울 필요 X 실습으로 css를 익히고 상황에 맞게 필요한 속성을 찾아서 사용할 수 있어야한다.</code></p>
<blockquote>
<p>💡 단위
글꼴 크기, 화면 크기 등 크기를 다룰 때는 크기의 단위가 무엇보다 중요합니다. 크기의 단위는 절대 단위와 상대 단위, 두 가지로 구분할 수 있습니다.</p>
</blockquote>
<ul>
<li>절대 단위: px, pt 등</li>
<li>상대 단위: %, em, rem, ch, vw, vh 등</li>
</ul>
<h5 id="글꼴-사이즈">글꼴 사이즈</h5>
<ol>
<li><p>기기나 브라우저 사이즈 등의 환경에 영향을 받지 않는 절대적인 크기로 정하는 경우 px(픽셀)을 사용.</p>
</li>
<li><p>상대 단위인 rem을 추천한다. root의 글자 크기, 즉 브라우저의 기본 글자 크기가 1rem이며, 두 배로 크게 하고 싶다면 2rem, 작게 하려면 0.8rem 등으로 조절해서 사용할 수 있다.</p>
</li>
</ol>
<h5 id="화면-사이즈">화면 사이즈</h5>
<ol>
<li><p>반응형 웹(responsive web)에서 기준점을 만들 때 -&gt; 디바이스 크기를 나누는 기준을 px로</p>
</li>
<li><p>화면 너비나 높이에 따른 상대적인 크기가 중요한 경우 -&gt; vw, vh를 사용</p>
<br>

</li>
</ol>
<h3 id="🔍-box-model">🔍 Box Model</h3>
<p>모든 콘텐츠는 각자의 영역을 가지고 일반적으로 하나의 콘텐츠로 묶이는 요소들이 하나의 Box가 된다. (Box는 항상 직사각형이고, 너비(width)와 높이(height)를 가짐)</p>
<blockquote>
<h4 id="줄-바꿈이-되는-boxblock-vs-옆으로-붙는-boxinline-inline-block">줄 바꿈이 되는 Box(block) vs. 옆으로 붙는 Box(inline, inline-block)</h4>
<p>Box의 종류는 줄 바꿈이 되는 Box, 줄 바꿈이 없이 옆으로 붙는 Box로 구분할 수 있다. 줄 바꿈이 되는 Box는 block Box, 줄 바꿈이 일어나지 않고, 크기 지정을 할 수 없는 Box는 inline Box라고 부른다. 그리고 이 두 가지 Box 종류의 특징이 섞인, 줄 바꿈이 일어나지 않는 동시에 block Box의 특징을 가지는 inline-block Box도 있다.</p>
</blockquote>
<table>
<thead>
<tr>
<th align="center"></th>
<th align="center">block</th>
<th align="center">inline-block</th>
<th align="center">inline</th>
</tr>
</thead>
<tbody><tr>
<td align="center">줄 바꿈 여부</td>
<td align="center">줄 바꿈이 일어남</td>
<td align="center">줄 바꿈이 일어나지 않음</td>
<td align="center">줄 바꿈이 일어나지 않음</td>
</tr>
<tr>
<td align="center">기본적으로 갖는 너비(width)</td>
<td align="center">100%</td>
<td align="center">글자가 차지하는 만큼</td>
<td align="center">글자가 차지하는 만큼</td>
</tr>
<tr>
<td align="center">width, height 사용 가능 여부</td>
<td align="center">가능</td>
<td align="center">가능</td>
<td align="center">불가능</td>
</tr>
</tbody></table>
<h4 id="box를-구성하는-요소">Box를 구성하는 요소</h4>
<p>border(테두리)를 기준으로 padding(안쪽 여백)과 margin(바깥 여백)이 있다.</p>
<p><img src="https://velog.velcdn.com/images/strong-minsu/post/ed8fd633-b5d6-4a9e-b871-d99e1a8ddf84/image.png" alt=""></p>
<p> top, right, bottom, left 순서로 영역의 크기를 조절할 수 있다.</p>
<pre><code class="language-css"> /*예시!!1*/

 p {
  border: 1px solid red;
  margin: 10px 20px 30px 40px;
  padding: 10px 20px 30px 40px;
}
/* 위치 따로 조정도 가능! */
p {
  margin-top: 10px;
  margin-right: 20px;
  margin-bottom: 30px;
  margin-left: 40px;
}</code></pre>
<blockquote>
<p>💡Box를 벗어나는 콘텐츠는 overflow 속성을 통해 다룰 수 있다
auto -&gt; 스크롤 생성
hidden -&gt; 벗어난 콘텐츠 숨기기</p>
</blockquote>
<h3 id="🔍-selecter">🔍 Selecter</h3>
<p>selecter는 css에서 스타일을 적용할 대상을 표현하는 것이다.</p>
<h4 id="기본-selecter">기본 selecter</h4>
<pre><code class="language-css">*{}         /*전체 selecter*/
div{}         /*tag selecter*/
#id{}         /*id selecter*/
.class{}     /*class selecter*/
a[href]{}    /*attribute selecter*/</code></pre>
<h4 id="자식-후손-형제-selecter">자식, 후손, 형제 selecter</h4>
<pre><code>자식 selecter: “ &gt; “ 
첫 번째로 입력한 요소의 바로 아래 자식인 요소를 선택

후손 selecter: “ “ 
첫 번째로 입력한 요소의 후손을 선택

형제 selecter: “ ~ “ 
같은 부모요소를 공유하면서, 첫 번째 입력한 요소 뒤에 오는 두 번째 입력한 요소를 모두 선택

인접 형제 selecter: “ + ” 
인접 형제 셀렉터는 같은 부모 요소를 공유하면서, 첫 번째 입력한 요소 바로 뒤에 오는 두 번째 입력한 요소를 선택</code></pre><h4 id="가상-클래스-selecter">가상 클래스 selecter</h4>
<p>가상 클래스는 요소의 상태 정보에 기반해 요소를 선택합니다.
아래 예시인 a태그말고도 button, div등 상태 변화에 기반을 둔 스타일을 설정하고 싶을 때 사용할 수 있다.</p>
<pre><code class="language-css">a:link { } /*사용자가 방문하지 않은 &lt;a&gt;요소를 선택합니다.*/
a:visited { } /*사용자가 방문한 &lt;a&gt;요소를 선택합니다. */
a:hover { } /* 마우스를 요소 위에 올렸을 때 선택합니다. */
a:active { } /* 활성화 된(클릭된) 상태일 때 선택합니다. */
a:focus { } /* 포커스가 들어와 있을 때 선택합니다. */</code></pre>
<h4 id="ui-요소-상태-selecter">UI 요소 상태 selecter</h4>
<pre><code class="language-css">input:checked + span { } /*체크 상태일 때 선택합니다. */
input:enabled + span { } /*사용 가능한 상태일 때 선택합니다. */
input:disabled + span { } /*사용 불가능한 상태일 때 선택합니다. */</code></pre>
<hr>

<h2 id="✨-마무리">✨ 마무리</h2>
<p>전부터 계속 약했던 부분이다.. css.. ㅍ_ㅍ 요소 하나하나에 속성을 넣고 부모와 자식의 관계까지 고려해서 작성해야하기 때문에, 가장 두려워한 부분이기도 했다. 확실히 실습으로 내가 원하는 부분을 꾸며보는 것이 도움이 되는 것 같다! 앞으로 꾸준히 연습하면서 css 기술 발전시켜 보자!</p>
]]></description>
        </item>
    </channel>
</rss>