<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>purin_no_corin.log</title>
        <link>https://velog.io/</link>
        <description>길을 찾고 싶은 코린이 of 코린이</description>
        <lastBuildDate>Mon, 24 Oct 2022 09:10:53 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>purin_no_corin.log</title>
            <url>https://images.velog.io/images/purin_no_corin/profile/be4d5e4e-647e-4178-97bc-59c3ce4779fe/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. purin_no_corin.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/purin_no_corin" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[2022/10/24 flex로 상품카드 만들기]]></title>
            <link>https://velog.io/@purin_no_corin/20221024-flex%EB%A1%9C-%EC%83%81%ED%92%88%EC%B9%B4%EB%93%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@purin_no_corin/20221024-flex%EB%A1%9C-%EC%83%81%ED%92%88%EC%B9%B4%EB%93%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Mon, 24 Oct 2022 09:10:53 GMT</pubDate>
            <description><![CDATA[<p>✨ 목표</p>
<ol>
<li>flex 이용해서 두 줄의 상품 목록 만들기</li>
<li>3번째 상품에서 다음 줄로 넘어가도록 하기</li>
</ol>
<p>🚨 문제발생</p>
<pre><code>상품카드에 margin, padding등을 주려고 하면 
너비를 계산해서 작성해도 두줄이 아니라 여러줄로 깨짐</code></pre><p>🏋 해결과정</p>
<ol>
<li>div &gt; ul &gt; li 로 마크업</li>
<li>div의 너비는 지정 안함 : 컨텐츠 크기에 따라 정해지도록</li>
<li>ul의 너비를 제한하고 flex 지정</li>
<li>ul에 flex-wrap: wrap으로 설정, 컨텐츠의 크기가 더 크면 다음줄로 넘어가게됨</li>
<li>ul의 크기와 두줄로 넘어가는 범위를 고려해서 상품 너비와 마진 지정 : 원하는 지점부터 다음줄로 넘어감</li>
</ol>
<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/a1f5580a-7d42-46f4-b61d-bb880dadd08e/image.png" alt=""></p>
<p>✨ 목표</p>
<ol>
<li>상품의 가격과 로켓배송 이미지가 높이가 맞도록 정렬하기</li>
</ol>
<p>🚨 문제</p>
<pre><code>align-items: center 로 정렬하면 의도한대로 나오지 않음</code></pre><p>🏋 해결과정</p>
<ol>
<li>컨테이너에 높이를 주고</li>
<li>인라인 요소로 마크업된 가격과 로켓 이미지에 vertical-align:middle 로 정렬</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] 이벤트 핸들러, 리스너]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%ED%95%B8%EB%93%A4%EB%9F%AC-%EB%A6%AC%EC%8A%A4%EB%84%88</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%ED%95%B8%EB%93%A4%EB%9F%AC-%EB%A6%AC%EC%8A%A4%EB%84%88</guid>
            <pubDate>Wed, 05 Oct 2022 04:09:52 GMT</pubDate>
            <description><![CDATA[<h1 id="이벤트-event">이벤트 (event)</h1>
<p>메뉴 버튼을 클릭하면 정보가 보이거나 정보를 입력하면 서버에 저장되는 등 웹사이트는 수많은 기능을 제공한다.
이런 기능을 이용하기 위해 <strong>마우스, 키보드를 조작하는 행위를 이벤트</strong>라고 한다.</p>
<p>이벤트가 발생하면 &#39;그래서 이벤트가 생기면 어떻게 할건데?&#39; 라는 의문이 생길것이다. 이때 이벤트의 발생을 감지하고 처리하는 역할을 하는 것이 <code>이벤트 처리기</code> 이다.</p>
<p>처리기에는 <code>이벤트 핸들러</code> 와 <code>이벤트 리스너</code> 가 있다.</p>
<hr>
<h2 id="📌-이벤트-핸들러-handler">📌 이벤트 핸들러 (handler)</h2>
<h3 id="1-html-태그에-설정">1. HTML 태그에 설정</h3>
<pre><code class="language-html">&lt;button onclick=&quot;showMenu();&quot;&gt;</code></pre>
<ul>
<li><strong>HTML과 자바스크립트가 섞여</strong>서 유지보수하기 힘들다.</li>
<li>HTML 문서에 <strong>여러개의 자바스크립트 파일이 import</strong>되고 핸들러 명이 같을 경우 오류가 생길 수 있다.</li>
</ul>
<h3 id="2-dom-요소-객체에-설정">2. DOM 요소 객체에 설정</h3>
<pre><code class="language-javascript">let menu = document.getElementById(&quot;menu&quot;);
let btn = document.getElementById(&quot;btn&quot;);

btn.onclick = showMenu(); // btn DOM 요소를 가져와서 클릭되면 menu의 display 설정 바꾸기

function showMenu(){
    menu.style.display = &quot;block&quot;;
}</code></pre>
<p>HTML과 자바스크립트를 분리할 수 있지만 <strong>하나의 이벤트 핸들러만 등록</strong>할 수 있다.</p>
<hr>
<h2 id="📌-이벤트-리스너-addeventlistener">📌 이벤트 리스너 (addEventListener)</h2>
<pre><code class="language-javascript">target.addEventListener(type, listener, useCapture);</code></pre>
<ul>
<li>이벤트를 감지하고 싶은 요소를 <code>target</code>으로 설정</li>
<li>메서드 인자 : ( 이벤트 <code>type</code>, 이벤트를 처리할 <code>listener</code>, <code>캡처링</code> 여부 )</li>
</ul>
<br>

<p><em>예시를 살펴보자</em></p>
<pre><code class="language-javascript">head.addEventListener(&#39;mouseover&#39;, function(){
    head.style.color = &#39;cornflowerblue&#39;;
})

head.addEventListener(&#39;mouseout&#39;, function(){
    head.style.color = &#39;#fff&#39;;
}</code></pre>
<p><em>결과</em></p>
<div style="height: 0; padding-bottom: calc(60.10%); position:relative; width: 100%;"><iframe allow="autoplay; gyroscope;" allowfullscreen height="100%" referrerpolicy="strict-origin" src="https://www.kapwing.com/e/633d00c746c82c009e80fc0e" style="border:0; height:100%; left:0; overflow:hidden; position:absolute; top:0; width:100%" title="Embedded content made on Kapwing" width="100%"></iframe></div><p style="font-size: 12px; text-align: right;">Video edited on <a href="https://www.kapwing.com/video-editor">Kapwing</a></p>


<blockquote>
<p>리스너는 </p>
</blockquote>
<ol>
<li>같은 요소의 같은 이벤트에 <strong>여러개의 리스너 등록 가능</strong></li>
<li><strong>버블링, 캡처링</strong> 단계에서 모두 활용 가능</li>
<li>removeEventListener, stopPropagation, preventDefault 활용해서 <strong>이벤트 전파 제어 가능</strong></li>
<li>HTML 태그를 포함한 모든 DOM 노드에 이벤트 리스너 등록 가능
&nbsp;
다음 포스팅에서 이벤트의 전파, 위임에 대해 알아보자!</li>
</ol>
<hr>
<p>출처:</p>
<p><a href="https://tangoo91.tistory.com/31">[javascript] 자바스크립트 에벤트 핸들러와 리스너</a></p>
<p><a href="https://ko.javascript.info/introduction-browser-events">브라우저 이벤트 소개</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] Async, await]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Async-await</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Async-await</guid>
            <pubDate>Mon, 03 Oct 2022 05:56:08 GMT</pubDate>
            <description><![CDATA[<h1 id="비동기-작업-만들기">비동기 작업 만들기</h1>
<p><code>async</code> 키워드는 함수 선언시에 앞에 붙여준다.
<code>promise</code> 밀접한 연관이 있는데 아래 코드에서 <code>new Promise</code>를 리턴하는 함수를 <code>async</code> 함수로 바꿔보자</p>
<pre><code class="language-javascript">// 기존
// function startAsync(age) {
//  return new Promise((resolve, reject) =&gt; {
//    if (age &gt; 20) resolve(`${age} success`);    
//   else reject(new Error(&quot;Something went wrong&quot;));
//  });
// }

async function startAsync(age) {
  if (age &gt; 20) return `${age} success`;
  else throw new Error(`${age} is not over 20`);
}

setTimeout(() =&gt; {
  const promise1 = startAsync(25);
  promise1
    .then((value) =&gt; {
      console.log(value);
    })
    .catch((error) =&gt; {
      console.error(error);
    });
  const promise2 = startAsync(15);
  promise2
    .then((value) =&gt; {
      console.log(value);
    })
    .catch((error) =&gt; {
      console.error(error);
    });
}, 1000);</code></pre>
<pre><code>25 success
Error: 15 is not over 20
    at startAsync (/home/taehoon/Desktop/playground-nodejs/index.js:11:14)
    at Timeout._onTimeout (/home/taehoon/Desktop/playground-nodejs/index.js:23:20)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)</code></pre><p>이전 Promise 챕터의 코드와 완벽하게 같은 결과를 보여준다(내부적으로 다를 순 있지만)</p>
<h2 id="🚨-async-함수의-리턴값은-무조건-promise">🚨 async 함수의 리턴값은 무조건 promise</h2>
<pre><code class="language-javascript">if (age &gt; 20) return `${age} success`;
else throw new Error(`${age} is not over 20`);</code></pre>
<p>코드 자체만 보면 문자열이 리턴될 것으로 예상할 수 있지만</p>
<pre><code class="language-javascript">async function startAsync(age) {
  if (age &gt; 20) return `${age} success`;
  else throw new Error(`${age} is not over 20`);
}

const promise1 = startAsync(15)
console.log(typeof promise1); // object
console.dir(promise1) // Promise</code></pre>
<p>짠! <code>async</code> 키워드를 붙인 것만으로 Promise 객체를 리턴하고 있다.
일반 함수처럼 다룰 수 없다는 걸 깨달아 버렸다.. 이제 어떻게 할까?</p>
<p>Promise 객체처럼 <code>then</code>, <code>catch</code> 로 후속처리를 할 수 있지만
새로운 <code>await</code> 키워드를 이용해서 코드를 <code>async</code> 함수를 다뤄보자</p>
<hr>
<h1 id="await">await</h1>
<p><code>await</code>은 <code>Promise</code> 가 reject인지 fulfilled인지 상관 없이 일단 끝날 때까지 기다리는 특징을 가지고 있다.</p>
<h3 id="resolve">resolve</h3>
<img src="https://velog.velcdn.com/images/purin_no_corin/post/98e78345-5114-44e8-bdc4-c11e31734cfb/image.png" width="300px" heigth="150px">

<h3 id="reject">reject</h3>
<img src="https://velog.velcdn.com/images/purin_no_corin/post/0e0b519f-cb12-4e31-9869-c5054f69af8d/image.png" width="300px" heigth="150px">

<p><code>await</code> 은 <code>resolve</code> 함수가 호출될 때까지 기다린다.
reject 가 호출됐을 땐 <code>pending</code> 상태에 머물러 있음을 알 수 있다.</p>
<hr>
<h3 id="더-자세한-예제를-통해-await을-알아보자">더 자세한 예제를 통해 await을 알아보자</h3>
<pre><code class="language-javascript">function setTimeoutPromise(ms) {
  return new Promise((resolve, reject) =&gt; {
    setTimeout(() =&gt; resolve(), ms);
  });
}

async function startAsync(age) {
// 리턴한 값은 resolve, reject에 해당하는 값은 error 로 해결

  if (age &gt; 20) return `${age} success`;
  else throw new Error(`${age} is not over 20`);
}

async function startAsyncJobs() {
  await setTimeoutPromise(1000);

  const promise1 = startAsync(25);
  try {
    const value1 = await promise1; // *
    console.log(value1);
  } catch (e) {
    console.error(e);
  }
  const promise2 = startAsync(15);
  try {
    const value2 = await promise2; // *
    console.log(value2);
  } catch (e) {
    console.error(e);
  }
}

startAsyncJobs();</code></pre>
<ol>
<li><p>문법 : <code>await + Promise 객체</code></p>
</li>
<li><p>await은 Promise 가 <code>resolve</code> 함수를 호출하기를 기다린다.</p>
</li>
<li><p>✨ async 함수에서 <strong>리턴하는 값을 <code>resolve</code> 값으로 간주</strong>한다.</p>
<pre><code class="language-javascript">value1 // ${age} success
value2 // ${age} is not over 20</code></pre>
</li>
<li><p><code>throw error</code> 로 처리되는 값이 <code>reject</code> 값으로 간주되고
catch 절로 넘겨 예외처리한다.</p>
</li>
</ol>
<hr>
<h2 id="📌-await-의-의의">📌 await 의 의의?</h2>
<p>비동기 함수로 시작한 작업은 그로부터 파생한 모든 작업도 비동기 작업으로 간주할 수 있다.</p>
<p><em>이게 무슨 소리지??</em></p>
<p>말 그대로 <code>동기 환경</code> 에서는 비동기로 처리한 작업을 기다리지 않고 <strong>내 할 일을 하고 있기 때문에 비동기 작업 안에서 동기 작업이 발생하는지 신경쓰지 않는다.</strong></p>
<p>하지만 <code>비동기 환경</code> 에서 비동기 작업의 결과를 기다리는 건 의미가 있는데
예를 들어 &#39;이번 달에 생일인 친구들의 목록을 받아온 뒤 생일 파티를 준비&#39; 하려면 일단 이번 달 생일인 친구들을 찾아내서 결과를 받아야 한다.
무작정 아무 친구나 생일 준비를 해줄 수 없으니 말이다.</p>
<p>이럴 때 <code>await</code> 을 사용하는 것이다.</p>
<pre><code>Promise 작업 끝남 
    -&gt; 후속 조치 
       -&gt; resolve : then  
       -&gt; reject : catch

        |
        |
     await 함수
        |
        ↓

Promise 작업 진행
    -&gt; resolve를 기다림(await)
        - 원하는 코드 실행
    -&gt; reject로 error 발생
        - catch 로 예외 처리   </code></pre><p>작업이 끝나고 후속처리를 하는 방법대신
하나의 async 흐름에서 기다렸다가 다음 코드를 실행하는, 우리가 그동안 해온 느낌으로 비동기 작업을 다룰 수 있게 된다!</p>
<hr>
<p>출처:</p>
<p><a href="https://elvanov.com/2597">https://elvanov.com/2597 - [Javascript] 비동기, Promise, async, await 확실하게 이해하기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] 비동기 Promise]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B9%84%EB%8F%99%EA%B8%B0-Promise-async-await</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B9%84%EB%8F%99%EA%B8%B0-Promise-async-await</guid>
            <pubDate>Sat, 01 Oct 2022 02:38:38 GMT</pubDate>
            <description><![CDATA[<h1 id="함수와-콜백">함수와 콜백</h1>
<pre><code class="language-javascript">function str(){
    console.log(&#39;I \&#39;m string&#39;);
}

console.log(1);
str(); 
console.log(2);
console.log(3);</code></pre>
<p>본래 코드는 위에서 아래 순서로 실행된다.</p>
<p>함수 str은 코드 가장 위에 정의되어 있지만 <strong>실행되지 않고 있다가</strong>
1이 출력된 이후 <strong>호출</strong>되어 문자열을 뱉어낸다.</p>
<pre><code>1
I&#39;m string
2
3</code></pre><br>

<p><em>다음 예제도 살펴보자</em></p>
<pre><code class="language-javascript">function b() {
  console.log(&quot;b called!&quot;);
}

function a(another) {
  console.log(&quot;a started!&quot;);
  another();
  console.log(&quot;a ended!&quot;);
}

console.log(1);
a(b);
console.log(3);</code></pre>
<pre><code>1
a started!
b called!
a ended!
3</code></pre><p>a함수는 another 인자를 받아서 함수처럼 호출하고 있다
이처럼 a함수를 호출할 때 b함수를 전달하는 것을 <em>&#39;<strong>콜백함수를 전달한다</strong>&#39;</em> 고 한다.</p>
<blockquote>
<p>종합해보자면 함수는 
&nbsp;</p>
</blockquote>
<ol>
<li><strong>선언과 호출의 시점을 다르게 해서 코드의 실행 흐름을 조작</strong>하고 </li>
<li><strong>인자로 함수를 받아 실행</strong> 할 수 있다</li>
</ol>
<hr>
<pre><code class="language-javascript">let i = 0;
function decryptData(callback, wait, age) {
  let start = new Date().getTime();
  while (new Date().getTime() &lt; start + wait); 
  callback(`${age}세 은행원`);
}

fetchData(console.log, 1000, 20);
fetchData(console.log, 1000, 37);
fetchData(console.log, 1000, 59);</code></pre>
<p>자 이제부터 익명의 직원 3명의 개인정보를 가져오는 작업을 한다고 가정해보자
정보는 암호로 되어있어 하나의 정보를 해독 후에 가져오는데 <strong>시간 1초가 꼭 걸린</strong>다고 한다면 
한명의 직원 정보를 가져오는 동안 다른 직원의 정보를 동시에 가져오는 일은 할 수 없다. 즉 3초를 꽉 채워 기다려야 한다는 뜻이다.</p>
<p><em>하지만 해독을 다른 누군가가 대신 해주고 나는 <strong>답변을 기다리기만 한다면,</strong>
또 3대의 컴퓨터로 <strong>3명의 정보를 동시에 받아오면</strong> 어떨까?</em></p>
<hr>
<h1 id="비동기---동시에-여러개-작업">비동기 - 동시에 여러개 작업</h1>
<pre><code class="language-javascript">function finishJob(num) {
  console.log(`${num}번 요원의 정보를 받아왔습니다.`);
}

setTimeout(finishJob, 2000, 1);
setTimeout(finishJob, 1500, 2);
setTimeout(finishJob, 1000, 3);
console.log(&quot;정보 요청을 모두 보냈습니다.&quot;);</code></pre>
<pre><code>정보 요청을 모두 보냈습니다.
3번 요원의 정보를 받아왔습니다.
2번 요원의 정보를 받아왔습니다.
1번 요원의 정보를 받아왔습니다.</code></pre><p>위 코드는 3명의 정보를 동시에 받아서 정해진 시간 뒤에 출력하고 있다.
그런데 결과값이 조금 이상하다. 
마지막 console.log 함수 결과가 가장 먼저 출력되었다. 어떻게 된 일일까?</p>
<h3 id="settimeout---때문이지">setTimeout ( ) 때문이지</h3>
<pre><code class="language-javascript">setTimeout(기다린 후 호출할 콜백함수, 기다릴 밀리초, 콜백함수에 넘길 인자(옵션))</code></pre>
<ol>
<li><code>setTimeout</code> 은 기다리는 함수로 일정한 ms 뒤에 <strong>콜백함수를 호출</strong>한다.</li>
<li>그러나 setTimeout 함수 자체는 &#39;~~ms 뒤에 이 함수를 호출해&#39;하고 <strong>예약만 한 후에 바로 함수를 끝내버린다.</strong></li>
<li>이때 기다리지 않는 <strong>console.log는 즉식 실행되어 가장 상단에 출력</strong>되고 </li>
<li>콜백 함수들은 <strong>예약된 시간이 되면 finishJob을 호출</strong>해서 문자열을 출력하기 때문에 위와 같은 결과가 나오는 것이다.</li>
</ol>
<br>

<p><em><strong>위를 아래와 같이 표현해보면 setTimeout이 비동기 방식임을 알 수 있다.</strong></em>
-&gt; 예약이 끝나자마자 동시에 각자의 예약 시간을 기다리고, 이때 하나의 콜백함수가 다른 콜백함수의 기다림에 영향을 주지 않기 때문이다.</p>
<pre><code class="language-css">setTimeout(callback1, 1000ms, arg (옵션)) -&gt; 함수 끝 , 예약됨
setTimeout(callback2, 1500ms, arg (옵션)) -&gt; 함수 끝 , 예약됨
setTimeout(callback3, 2500ms, arg (옵션)) -&gt; 함수 끝 , 예약됨
     |              |                    |                |
 &#39;hi&#39; 출력             |              |                   |
                callback1         |                   |    
                 1000ms          callback2         |    
                                  1500ms            |
                                             callback3
                                              2500ms</code></pre>
<h2 id="📌-비동기---문제점">📌 비동기 - 문제점</h2>
<p>위에서 본 것처럼 비동기 작업은 한번에 여러 작업을 동시에 수행할 수 있는 장점이 있지만, <strong>의존성이 길게 이어져 있는 경우 일이 복잡</strong>해진다</p>
<p>왜냐하면 비동기 작업은 함수가 호출되는 시점에 시작되고 이때 다음 작업(콜백함수)도 넘겨줘야 하기 때문이다.</p>
<hr>
<h1 id="promise">Promise</h1>
<p>기본적인 형태부터 알아본 후 사용 예제까지 살펴보자.</p>
<pre><code class="language-javascript">const promise1 = new Promise((resolve,reject) =&gt; {
    // 비동기 작업
}) </code></pre>
<ul>
<li>const로 선언해서 재할당이 되지 않도록 하면 하나의 변수로 끝까지 관리하면 가독성이 좋고 유지보수에 용이하다.</li>
<li>new Promise 생성자 함수로 새로운 promise1 객체를 생성한다.</li>
<li><strong>특별한 함수</strong>(화살표 함수) 하나를 <strong>인자로 받는다.</strong></li>
</ul>
<h2 id="📌-executor">📌 executor</h2>
<ul>
<li>promise 생성자 함수가 받는 특별한 함수를 <code>executor</code> 라고 한다.</li>
<li>executor는 인자 2개를 받는데 하나는 <code>resolve</code>, 다른 하나는 <code>reject</code>이다.</li>
<li>이 두개의 인자 역시 함수이고 비동기 작업의 성공 / 실패를 표현한다.</li>
<li>resolve -&gt; 비동기 작업 성공
reject -&gt; 비동기 작업 실패</li>
</ul>
<p>비동기 작업은 언제 끝날 지 알 수 없기 때문에 성공, 실패에 따른 <strong>후작업</strong>까지
해 주어야 한다.</p>
<ul>
<li>resolve -&gt; <code>then</code> 으로 성공 후 작업 연결</li>
<li>reject -&gt; <code>catch</code> 로 오류나 실패를 잡아냄 </li>
</ul>
<h2 id="📌-then-catch">📌 then, catch</h2>
<p>Promise 작업이 끝난 뒤의 후속작업을 처리하는 메소드이다.</p>
<p><code>then</code> : 비동기 작업이 성공하면 실행할 동작 지정, 함수를 인자로 받음
<code>catch</code> : 비동기 작업이 실패하면 실행할 동작, 함수를 인자로 받음</p>
<pre><code class="language-javascript">const promise1 = new Promise((resolve, reject) =&gt; {
  resolve(); // reject();
});

promise1
  .then(() =&gt; {
    console.log(&quot;then!&quot;); 
  })
  .catch(() =&gt; {
    console.log(&quot;catch!&quot;);
  });</code></pre>
<p><em>결과</em></p>
<pre><code class="language-javascript">then! //catch!</code></pre>
<p>위에서 설명한 것처럼 resolve는 then으로 처리, reject는 catch로 
처리되는 것을 볼 수 있다.</p>
<h2 id="📌-재사용">📌 재사용</h2>
<p>비동기 작업을 수행할 때마다 <code>new Promise</code> 를 이용해 객체를 만들기는 번거롭다.
이럴땐 <code>new Promise</code> 의 결과를 바로 리턴하는 함수를 만들어 재사용하면 된다.</p>
<pre><code class="language-javascript">function startAsync(age) {
  return new Promise((resolve, reject) =&gt; {
    if (age &gt; 20) resolve();
    else reject();
  });
}

setTimeout(() =&gt; {
  const promise1 = startAsync(25);

  promise1
    .then(() =&gt; {
      console.log(&quot;1 then!&quot;);
    })
    .catch(() =&gt; {
      console.log(&quot;1 catch!&quot;);
    });

  const promise2 = startAsync(15);

  promise2
    .then(() =&gt; {
      console.log(&quot;2 then!&quot;);
    })
    .catch(() =&gt; {
      console.log(&quot;2 catch!&quot;);
    });

}, 1000);</code></pre>
<ul>
<li>setTimeout() 은 1000밀리초 뒤에 { } 안의 내용을 실행한다.</li>
<li>2개의 변수는 25, 15 인자로 보내 startAsync 함수를 호출한다.</li>
<li>호출하는 순간 <code>new Promise</code> 가 실행되어 비동기 작업이 시작된다.</li>
<li><code>then</code> 혹은 <code>catch</code> 로 후속 작업을 처리한다.</li>
</ul>
<p><em>결과</em></p>
<pre><code class="language-javascript">promise1 -&gt; resolve ( ) -&gt; then -&gt; // 1 then!
promise2 -&gt; reject ( ) -&gt; catch -&gt; // 2 catch!</code></pre>
<h2 id="📌-작업-결과-전달">📌 작업 결과 전달</h2>
<p>위에서 startAsync를 호출하여 변수를 만들 때 인자를 전달했었다.
이 인자를 <code>new Promise</code> 에서 resolve, reject 일 때 각각 다르게 
처리해 then, catch 에 전달할 수 있다.</p>
<pre><code class="language-javascript">function startAsync(age) {
  return new Promise((resolve, reject) =&gt; {
    if (age &gt; 20) resolve(`${age} success`);    
    else reject(new Error(`${age} is not over 20`));
  });
}

setTimeout(() =&gt; {
  const promise1 = startAsync(25);

  promise1
    .then((value) =&gt; {
      console.log(value);
    })
    .catch((error) =&gt; {
      console.error(error);
    });

  const promise2 = startAsync(15);

  promise2
    .then((value) =&gt; {
      console.log(value);
    })
    .catch((error) =&gt; {
      console.error(error);
    });

}, 1000);</code></pre>
<p><em>결과</em></p>
<pre><code>25 success
Error: 15 is not over 20
    at /home/taehoon/Desktop/playground-nodejs/index.js:4:17
    at new Promise (&lt;anonymous&gt;)
    at startAsync (/home/taehoon/Desktop/playground-nodejs/index.js:2:10)
    at Timeout._onTimeout (/home/taehoon/Desktop/playground-nodejs/index.js:17:20)
    at listOnTimeout (internal/timers.js:554:17)
    at processTimers (internal/timers.js:497:7)</code></pre><hr>
<h2 id="📌-기타사항">📌 기타사항</h2>
<p><code>executor</code> 를 만들 때 조금 더 알아두면 좋은 점들을 살펴보자</p>
<br>

<ol>
<li><code>executor</code> 내부에서 에러가 <code>throw</code> 되면 <code>reject</code>가 수행됨</li>
</ol>
<pre><code class="language-javascript">const throwError = new Promise((resolve, reject) =&gt; {
  throw Error(&quot;error&quot;);
});
throwError
  .then(() =&gt; console.log(&quot;throwError success&quot;))
  .catch(() =&gt; console.log(&quot;throwError catched&quot;));</code></pre>
<ol start="2">
<li><code>executor</code> 의 리턴 값은 무시된다.</li>
</ol>
<pre><code class="language-javascript">// 아무런 영향이 없습니다.
const ret = new Promise((resolve, reject) =&gt; {
  return &quot;returned&quot;;
});
ret
  .then(() =&gt; console.log(&quot;ret success&quot;))
  .catch(() =&gt; console.log(&quot;ret catched&quot;));</code></pre>
<pre><code class="language-javascript">Promise {&lt;pending&gt;} // 아직 아무 값도 받지 못함, (성공 / 실패) 여부 불확실</code></pre>
<ol start="3">
<li>첫번째 <code>reject</code> 혹은 <code>resolve</code> 만 유효하다.(throw 역시 이전 함수가 호출되면 무시됨)</li>
</ol>
<pre><code class="language-javascript">// resolve 만 실행
const several1 = new Promise((resolve, reject) =&gt; {
  resolve();
  reject();
});
several1
  .then(() =&gt; console.log(&quot;several1 success&quot;))
  .catch(() =&gt; console.log(&quot;several1 catched&quot;));

// reject 만 실행
const several2 = new Promise((resolve, reject) =&gt; {
  reject();
  resolve();
});
several2
  .then(() =&gt; console.log(&quot;several2 success&quot;))
  .catch(() =&gt; console.log(&quot;several2 catched&quot;));

// resolve 만 실행
const several3 = new Promise((resolve, reject) =&gt; {
  resolve();
  throw new Error(&quot;error&quot;);
});
several3
  .then(() =&gt; console.log(&quot;several3 success&quot;))
  .catch(() =&gt; console.log(&quot;several3 catched&quot;));</code></pre>
<p><em>결과</em></p>
<pre><code>// 위의 코드들 결과(순서대로)

throwError catched
several1 success
several2 catched
several3 success</code></pre><br>

<p>어차피 첫번째 resolve, reject만 영향을 주기 때문에 해당 함수가 호출되면 리턴해서 비동기 작업을 빠져나가는 것이 좋다.</p>
<p>위에서 봤던 <code>startAsync</code>를 조금 바꿔보자</p>
<pre><code class="language-javascript">function startAsync(age) {
  return new Promise((resolve, reject) =&gt; {

    if (age &gt; 20) {
      return resolve(`${age} success`);
    }

    return reject(new Error(`${age} is not over 20`));

    // 이 아래의 코드들은 이제 실행되지 않는다!
  });
}</code></pre>
<p><em>(위의 코드는 무언가를 기다리는 작업은 하고 있지 않다 단순예제로만 보기를!)</em></p>
<ul>
<li>비동기 작업이 성공하면 resolve가 실행되면서 then으로 정보를 보낸 후 리턴되고 다음 코드가 실행되지 않는다.</li>
<li>비동기 작업이 실패하면 reject를 실행, catch로 정보를 보낸 후 리턴되고 역시 이 다음의 코드들은 실행되지 않는다.</li>
</ul>
<hr>
<p><em>정리해보자면</em></p>
<blockquote>
</blockquote>
<ul>
<li>함수는 코드가 적힌 순서를 떠나 내가 원할때 코드 조각을 불러와 실행 할 수 있다.</li>
<li>콜백은 이런 함수를 인자로 보내 함수 실행의 권한을 다른 함수에 넘기는 것을 말한다.</li>
<li>비동기 작업은 이런 함수 여러개가 동시에 실행되고 언제 결과가 나올 지 알 수 없고</li>
<li>비동기 작업이라도 서로 의존성이 있는 경우 곤혹을 치를 수 있다.</li>
<li>이런 비동기 작업의 문제를 해결하기 위해 Promise 를 이용하고</li>
<li>언제끝날지 모르는 비동기 작업의 후속처리를 then,catch로 처리할 수 있다.</li>
</ul>
<hr>
<p>출처:</p>
<p><a href="https://elvanov.com/2597">https://elvanov.com/2597</a> <a href="https://elvanov.com/2597">- [Javascript] 비동기, Promise, async, await 확실하게 이해하기</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] 클로저 (Closure)]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%81%B4%EB%A1%9C%EC%A0%80-Closure</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%81%B4%EB%A1%9C%EC%A0%80-Closure</guid>
            <pubDate>Wed, 28 Sep 2022 14:59:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>실행 컨텍스트
Lexical scope
closure
private
비동기 </p>
</blockquote>
<h2 id="📌-실행-컨텍스트">📌 실행 컨텍스트</h2>
<p><strong>자바스크립트엔진</strong>은 스크립트를 실행하다가 함수를 <strong>만나면 실행컨텍스트를 생성</strong>한다.
이 실행컨텍스트에 함수가 <strong>실행될 때의 환경을 저장</strong>하며 이렇게 만들어진 실행컨텍스트는 <strong>자신만의 스코프(유효범위)를 갖게된다.</strong></p>
<pre><code class="language-javascript">var x = 10
var y = 20

function print(){
  var x = 5
  console.log(x, y)
}

print() // 5,20</code></pre>
<p>실행 컨텍스트 입장에서 살펴보자면 </p>
<ol>
<li>GO ( x= 10, y= 20, print= function )</li>
<li>print 함수 컨텍스트 ( x= 5 )</li>
<li>참조한 변수 : x= 5, y= 20</li>
</ol>
<p>🚥 우선 <strong>자바스크립트가 실행</strong>되면 <strong>글로벌 오브젝트(GO)를 생성</strong>한다.
GO에는 <strong>전역 변수</strong>들과 <strong>함수</strong>들이 프로퍼티로 저장된다 ( x = 10, y = 20, print = function ) </p>
<p>🚥 자바스크립트엔진이 print() <strong>함수를 실행</strong>하게되면 새로운 <strong>실행컨텍스트가 생성</strong>된다. ( print 컨텍스트는 x = 5를 속성으로 저장한다. )</p>
<p>🚥 print 컨텍스트에 y <strong>변수가 없으니</strong> 바로 <strong>상위 컨텍스트</strong>에서 y를 찾게된다. </p>
<p>🚥 만약에 GO에도 y가 선언되어있지 않다면 &#39;y is not defined&#39; 라는 컨퍼런스 에러가 발생한다.</p>
<p>즉, 변수를 참조할 땐 함수가 <strong>실행된 컨텍스트 내부를 먼저</strong> 살펴보고 <strong>없으면 상위 컨텍스트</strong>를 계속해서 찾는데 이것이 &#39;<strong>스코프 체인</strong>&#39;이다.</p>
<h2 id="📌-lexical-scope">📌 Lexical Scope</h2>
<p><strong>Lexical Scope</strong>는 함수와 변수의 Scope를 <strong>선언된 위치를 기준</strong>으로, 
<strong>Dynamic Scope</strong>는 함수나 변수의 Scope를 <strong>호출된 시점을 기준</strong>으로 사용한다.</p>
<p>자바스크립트는 Lexical Scope를 사용하는 점을 유념해서 아래 코드를 살펴보자</p>
<pre><code class="language-javascript">var x = 1;

function print() {
    console.log(x); // 1
}

function dummy() {
    var x = 999;
    print();
}

dummy();</code></pre>
<ul>
<li>dummy 함수를 호출하면 변수 x를 새롭게 선언, 할당하고 print 함수를 호출한다.</li>
<li>print 함수가 호출되면 <strong>선언된 위치를 파악</strong>하고 x가 전역 변수로 선언, 1을 할당 받은 뒤니까 <strong>전역 변수 x의 값을 출력</strong>한다.</li>
</ul>
<p><em>만약 Dynamic Scope로 스코프를 정한다면 실행 중 동적으로 변하니까 x값을 999로 출력한다.</em></p>
<pre><code class="language-javascript">var x = 1;

function outer() {
    var x = 2;
    function inner() {
        console.log(x)
    }

    inner();
}

outer();</code></pre>
<ul>
<li>inner 함수가 선언된 위치를 중심으로 x변수를 찾는다면
inner 함수 (없음) -&gt; 외부함수 outer 접근 (발견) -&gt; x = 2 출력</li>
</ul>
<pre><code class="language-javascript">function init() {
    var name = &quot;Mozilla&quot;; 

    function displayName() { 
        alert(name); 
    }

    displayName();
}

init();</code></pre>
<p>위에서본 설명들을 조합해서 코드를 살펴보자면 </p>
<ul>
<li>init 함수가 실행되면 name 변수와 displayName 함수가 선언되고 실행된다.</li>
<li>displayName 함수가 선언된 위치를 기준으로 현재 실행 컨텍스트에는 name 변수가 없으니 <strong>외부 함수(init)를 살핀 후 name을 찾아 그 값인 Mozilla를 출력</strong>한다.</li>
</ul>
<p><em>그럼 다음 예제도 같이 살펴보자</em></p>
<pre><code class="language-javascript">function makeFunc() {
    var name = &quot;Mozilla&quot;;
    function displayName() {
        console.log(name); // Mozilla
    }
    return displayName;
}

var myFunc = makeFunc();

myFunc();</code></pre>
<ul>
<li>위의 예제 코드와 같은 결과를 출력하지만 displayName을 <strong>바로 출력하지 않는다.</strong></li>
<li>대신 displayName 함수를 <strong>리턴값으로 myFunc에 저장 후</strong> myFunc를 <strong>실행한다.</strong></li>
<li>마찬가지로 displayName 함수 컨텍스트에는 name 변수가 없기 때문에 현재 함수 위치에서 외부 함수에 접근하고 name 값을 찾아 출력한다.</li>
</ul>
<h3 id="🚨-잠깐-어떻게-이미-리턴된-함수와-그-지역변수에-접근-할-수-있는거지">🚨 잠깐! 어떻게 &#39;이미 리턴된&#39; 함수와 그 지역변수에 접근 할 수 있는거지?</h3>
<blockquote>
<p>몇몇 프로그래밍 언어에서, <strong>함수 안의 지역 변수</strong> 들은 그 <strong>함수가 처리되는 동안에만 존재</strong>한다. 
따라서** makeFunc() 실행이 끝나면<strong>(displayName함수가 리턴되고 나면) **name 변수에 더 이상 접근할 수 없다고 예상</strong>하는 것이 일반적이다.
&nbsp;
그러나 위의 코드에선 이미 호출이 끝난 함수의 실행 컨텍스트에 접근해서
name 변수값을 받아와 출력할 수 있었다. 이게 어떻게 가능한 것일까?</p>
</blockquote>
<hr>
<h2 id="📌-closure">📌 closure</h2>
<p>자바스크립트는 함수를 리턴하고, <strong>리턴하는 함수가 클로저를 형성</strong>한다.
클로저는 <strong>함수와 함수가 선언된 어휘적 환경의 조합</strong>이다. 이 환경은 클로저가 <strong>생성된 시점</strong>의 <strong>유효 범위 내에 있는 모든 지역 변수로 구성</strong>된다.</p>
<p>_조금 더 쉽게 설명해보자면 _</p>
<blockquote>
<p>Closure란 자신이 <strong>생성된 시점의 환경을 기억</strong>하는 함수 즉,
Closure는 자신의 <strong>외부 함수 호출이 종료되었음에도 그 외부함수의 변수 or 인자에 접근 할 수 있는 함수이다.</strong></p>
</blockquote>
<p>다시 예제를 살펴보자</p>
<pre><code class="language-javascript">function makeFunc() {
    var name = &quot;Mozilla&quot;;
    function displayName() {
        console.log(name); // Mozilla
    }
    return displayName;
}

var myFunc = makeFunc();

myFunc();</code></pre>
<ul>
<li><strong>makeFunc가 리턴되면서 클로저가 생성</strong>되고 displayName이 생성될때의 <strong>위치를 기준</strong>으로 <strong>함수와 그 지역변수를 기억</strong>하게 된다.</li>
<li>이 클로저를 myFunc가 참조할 수 있게 되고 </li>
<li>myFunc 함수가 호출되는 순간 클로저에서 name 변수를 찾을 때까지 scope chain으로 상위 실행 컨텍스트를 살핀다.</li>
<li>makeFunc 함수의 지역변수인 name을 발견해 Mozilla를 출력한다.</li>
</ul>
<hr>
<h2 id="📌-private-흉내내기">📌 private 흉내내기</h2>
<p>자바스크립트는 클로저를 이용하여 프라이빗 메소드를 흉내내는 것이 가능하다. 프라이빗 메소드는 <strong>코드에 제한적인 접근만을 허용</strong>한다는 점 뿐만 아니라 <strong>전역 네임 스페이스를 관리</strong>하는 강력한 방법을 제공하여 <strong>불필요한 메소드가 공용 인터페이스를 혼란스럽게 만들지 않도록 한다.</strong></p>
<pre><code class="language-javascript">var counter = (function() {
    var privateCounter = 0;
    function changeBy(val) {
        privateCounter += val;
    }
    return {
        increment: function() {
            changeBy(1);
        },
        decrement: function() {
          changeBy(-1);
        },
        value: function() {
          return privateCounter;
        }
   };
})();

console.log(counter.value()); // logs 0
counter.increment();
counter.increment();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1</code></pre>
<ul>
<li>counter 변수에는 익명 함수가 즉시 실행되어 리턴값이 저장된다.</li>
<li>같은 어휘적(lexical) 환경을 공유하는 세개의 클로저가 생성된다.</li>
<li>이 어휘적 환경은 익명함수 안에서 만들어진 privateCounter 변수, changeBy 함수를 포함한다.</li>
<li>세개의 메서드에 의해서만 두 값이 조작될 수 있다.</li>
</ul>
<blockquote>
<p>✨ 클로저 역할?
세개의 메서드는 <strong>클로저 환경의 값만 조작</strong>하기 때문에 <strong>공용 공간을 더럽히지 않고</strong> private 변수나 함수에 <strong>외부에서 직접적으로 접근하여 조작할 수 없어 값을 보존</strong>할 수도 있다. </p>
</blockquote>
<p>값이 보존되는 또다른 예제를 살펴보자</p>
<pre><code class="language-javascript">var makeCounter = function() {
    var privateCounter = 0;
    function changeBy(val) {
        privateCounter += val;
    }
    return {
        increment: function() {
            changeBy(1);
         },
        decrement: function() {
            changeBy(-1);
        },
        value: function() {
            return privateCounter;
        }
    }
};

var counter1 = makeCounter();
var counter2 = makeCounter();

counter1.increment();
counter1.increment();

console.log(counter1.value()); /* 2 */
console.log(counter2.value()); /* 0 */</code></pre>
<ul>
<li>아까전의 코드와 다르게 익명함수를 <strong>즉시호출하지 않고 변수에 저장</strong>했다.</li>
<li>변수를 호출해서 counter1, counter2 등 <strong>여러 버전을 만들 수 있다</strong>.</li>
</ul>
<blockquote>
<p>✨ 독립성 유지 방법?
각 클로저는 그들 <strong>고유의 클로저에서 privateCounter 변수의 다른 버전을 참조한다.</strong> 
따라서 각 카운터가 호출될 때마다 하나의 클로저에서 변수 값을 변경해도 <strong>다른 클로저의 값에는 영향을 주지 않는다.</strong>
&nbsp;
이런 방식으로 클로저를 사용하여 객체지향 프로그래밍의 <strong>정보 은닉과 캡슐화</strong> 같은 이점들을 얻을 수 있다.</p>
</blockquote>
<hr>
<h2 id="📌-실용적-클로저">📌 실용적 클로저</h2>
<pre><code class="language-javascript">function makeSizer(size) {
    return function() {
           document.body.style.fontSize = size + &#39;px&#39;;
    };
}

var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);

document.getElementById(&#39;size-12&#39;).onclick = size12;
document.getElementById(&#39;size-14&#39;).onclick = size14;
document.getElementById(&#39;size-16&#39;).onclick = size16;</code></pre>
<ul>
<li>세개의 사이즈 변수에는 각자 다른 사이즈 값을 기억하는 클로저가 할당된다.</li>
<li>이 함수는 실행되지 않고 있다가 dom에서 onclick 이벤트를 감지하면 실행된다.</li>
</ul>
<blockquote>
<p>✨ 비동기 작동에도 사용해
이처럼 자신만의 고유한 환경을 참조하면 다른 환경에서 값이 변해도 영향을 받지 않고 인자로 받은 값을 기억하고 있기 때문에 <strong>나중에 호출 되더라도 
그 값을 유지한 채 작동된다.</strong></p>
</blockquote>
<hr>
<p>출처: </p>
<p><a href="https://medium.com/sjk5766/lexical-scope-closure-%EC%A0%95%EB%A6%AC-41f5d1c928e4">https://medium.com/sjk5766/lexical-scope-closure-%EC%A0%95%EB%A6%AC-41f5d1c928e4</a> - 클로저</p>
<p><a href="https://imki123.github.io/posts/33/">https://imki123.github.io/posts/33/</a> - 실행 컨텍스트</p>
<p><a href="https://elvanov.com/2597">https://elvanov.com/2597</a> - 비동기</p>
<p><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures">https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures</a> - 클로저</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] 클래스 (class)]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%81%B4%EB%9E%98%EC%8A%A4-class</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%81%B4%EB%9E%98%EC%8A%A4-class</guid>
            <pubDate>Wed, 28 Sep 2022 07:20:47 GMT</pubDate>
            <description><![CDATA[<p><em>들어가기 전에</em></p>
<h2 id="생성자-함수와-프로토타입">생성자 함수와 프로토타입</h2>
<pre><code class="language-javascript">function Person(name, age){
    this.name = name;
    this.age = age;
}

Person.prototype.isAdult = function(){
    if(this.age &gt; 20) return &#39;성인입니다.&#39;;
    else return &#39;청소년입니다.&#39;;
}

const mark = new Person(&#39;Mark&#39;, 23);
const bob = new Person(&#39;Bob&#39;, 14);

console.log(mark.isAdult());
console.log(bob.isAdult());</code></pre>
<ul>
<li>생성자 함수는 파스칼 케이스로 이름을 설정해 구별</li>
<li>생성자 함수로 만들어진 인스턴스에서 인자를 받아 속성 정의</li>
<li>메서드는 prototype 객체에 정의</li>
<li>생성자 함수로 만드는 인스턴스는 상위 객체에 접근해서 메서드를 사용한다.</li>
</ul>
<blockquote>
<p>생성자 함수: 데이터는 생성자 함수에서, 이를 조작하는 것은 프로토 객체에 따로 작성
class: 객체를 생성하기 위한 템플릿으로 <strong>데이터와 이를 조작하는 코드를 하나로 추상화한다.</strong> 
-&gt; 비록 자바스크립트에서 클래스는 프로토타입을 이용해서 만들어졌지만 ES5의 클래스 의미와는 다른 문법과 의미를 가진다</p>
</blockquote>
<hr>
<h1 id="-class"># class</h1>
<pre><code class="language-javascript">class Person{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }

    isAdult(){
        if(this.age &gt; 20){
            return `${this.name}은 성인입니다.`
        }else{
            return `${this.name}은 청소년입니다.`
        }
    }
}


const mark = new Person(&#39;Mark&#39;, 23);
const bob = new Person(&#39;Bob&#39;, 14);

console.log(mark.isAdult()); // &#39;mark은 성인입니다.&#39;
console.log(bob.isAdult()); // &#39;bob은 입니다.&#39;</code></pre>
<h2 id="📌-class-선언">📌 class 선언</h2>
<p>Class를 정의하는 방법 중 하나는 class 선언을 이용하는 것이다. class를 선언하기 위해서는 클래스의 이름(여기서 &quot;Rectangle&quot;)과 함께 class 키워드를 사용해야 한다.</p>
<pre><code class="language-javascript">class Rectangle {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}</code></pre>
<ul>
<li><em>인자는 constructor 메서드가 받아서 속성을 정의한다.</em></li>
<li>new 키워드로 인스턴스를 만들 수 있다.</li>
</ul>
<h2 id="📌-consturctor">📌 consturctor</h2>
<ul>
<li>constructor 메서드는 <strong>class 로 생성된 객체를 생성하고 초기화</strong>하기 위한 특수한 메서드이다. </li>
<li><strong>클래스 안에 한 개만 존재</strong>할 수 있다.</li>
<li>만약 클래스에 여러 개의 constructor 메서드가 존재하게 되면 SyntaxError가 발생한다.</li>
</ul>
<h2 id="class-확장">class 확장</h2>
<pre><code class="language-javascript">class Person{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }

    isAdult(){
        if(this.age &gt; 20){
            return `${this.name}은 성인입니다.`
        }else{
            return `${this.name}은 청소년입니다.`
        }
    }
}</code></pre>
<h3 id="생성자-함수-확장">생성자 함수 확장</h3>
<pre><code class="language-javascript">function Person2 (name, age){
    Person.call(this,name,age); // Person이 생성자 함수라고 가정    
}

Person2.prototype = Object.create(Person.prototype);
Person2.prototype.constructor = Person2;</code></pre>
<h3 id="class-확장-1">class 확장</h3>
<pre><code class="language-javascript">class Person2 extends Person {
    constructor(name, age){
        super(name, age);
    }
}


const mark = new Person2(&#39;Mark&#39;, 23);
const bob = new Person2(&#39;Bob&#39;, 14);

console.log(mark.isAdult()); // &#39;mark은 성인입니다.&#39;
console.log(bob.isAdult()); // &#39;bob은 청소년입니다.&#39;

console.log(mark instanceof Person2); // true
console.log(mark instanceof Person); // true</code></pre>
<ul>
<li>기존 Person 클래스 함수를 extends 키워드로 Person2로 확장하고</li>
<li>super 함수로 Person 클래스의 인자를 사용한다.</li>
<li>메서드까지 추가 코드 작성 없이 사용할 수 있다</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 선형 자료구조 ] 이중 연결 리스트 구현하기]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9D%B4%EC%A4%91-%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9D%B4%EC%A4%91-%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 27 Sep 2022 12:44:53 GMT</pubDate>
            <description><![CDATA[<h1 id="이중-연결-리스트">이중 연결 리스트</h1>
<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/39c6d8b3-7e84-4a73-b5da-37dea00b0195/image.jpeg" alt=""></p>
<ul>
<li>두 줄로 연결되어 있어서 pointer가 prev, next 두 개 존재한다.</li>
<li>리스트 뒤에서부터 노드에 접근할 수 있어 편하다.</li>
<li>리스트를 조작하는 경우엔 업데이트해야 하는 값이 늘어나서 주의해야 한다.<br>
```javascript
// 기본 코드
function Node(data){
  this.prev = null;
  this.data = data;
  this.next = null;
}

</li>
</ul>
<p>function DoubleLinkedList(){
    this.head = null;
    this.tail = null;
    this.length = 0;
}</p>
<p>DoubleLinkedList.prototype.size = function(){
    return this.length;
}</p>
<p>DoubleLinkedList.prototype.isEmpty = function(){
    return this.length === 0;
}</p>
<pre><code>---

## 📌 append
```javascript
// append(): 연결 리스트 가장 끝 부분에 노드 새로 생성 후 추가
DoubleLinkedList.prototype.append = function(data){
    let node = new Node(data);

    if(this.head === null){
        this.head = node;
        this.tail = node;
    }else{
        this.tail.next = node;
        node.prev = this.tail;
        this.tail = node;
    }

    this.length++;
}

let dll = new DoubleLinkedList();


dll.append(1);
dll.append(10);
dll.append(100);</code></pre><blockquote>
<p><strong>✅ 연결 리스트와 다른점?</strong>
똑같이 리스트 끝에 노드를 추가하더라도 이중연결 리스트는 끝에 tail과의 연결도 신경써야 한다.</p>
</blockquote>
<ul>
<li><strong>리스트가 비어</strong>있는 경우: this.head, this.tail <strong>모두 node를 가리킴</strong></li>
<li><strong>노드가 1개 이상</strong> 있는 경우:
this.tail.next = node -&gt; 원래 연결됐던 노드에 새 node 연결
node.prev = this.tail -&gt; node.prev로 원래 노드 가리킴(연결)
this.tail = node -&gt; this.tail랑 새 node 연결</li>
</ul>
<h2 id="📌-printnode-printnodeinverse">📌 printNode, printNodeInverse</h2>
<pre><code class="language-javascript">// printNode(): 연결 리스트 내에 노드 모두 출력
DoubleLinkedList.prototype.printNode = function(){
    process.stdout.write(&#39;head -&gt; &#39;);

    for(let node = this.head; node != null; node = node.next){
        process.stdout.write(`${node.data} -&gt; `);
    }
    console.log(&#39;null&#39;);
}

// printNodeInverse(): 연결 리스트 노드를 뒤에서부터 모두 출력
DoubleLinkedList.prototype.printNodeInverse = function(){
    let temp = []; 
    process.stdout.write(&#39;null &lt;- &#39;);
    for(let node = this.tail; node != null; node = node.prev){
        temp.push(node.data);
    }

    for(let i = temp.length-1; i &gt;= 0; i--){
        process.stdout.write(`${temp[i]} &lt;- `);
    }

    console.log(&#39;tail&#39;);
}


dll.printNode();
dll.printNodeInverse();</code></pre>
<blockquote>
</blockquote>
<pre><code class="language-javascript">head -&gt; 1 -&gt; 10 -&gt; 100 -&gt; null // printNode
null &lt;- 1 &lt;- 10 &lt;- 100 &lt;- tail // printNodeInverse</code></pre>
<p>두 결과는 거의 비슷하기 때문에 printNode 메서드를 이용한 트릭으로 tail
리스트를 출력할 수도 있지만 <strong>tail과 prev 포인터를 적극 이용해서 노드를 출력</strong> 했다.</p>
<ul>
<li><strong>빈 배열 temp</strong>를 만든다.</li>
<li>가장 <strong>마지막</strong> 값인 <strong>null</strong>을 문자열로 출력한다.</li>
<li>this.tail부터 시작 -&gt; <strong>node.prev로 업데이트</strong> 하면서 노드에 접근한다.</li>
<li>접근한 노드의 값을 <strong>빈 배열에 인덱스 0부터 차례로 push</strong>한다.</li>
<li>prev가 가리키는 <strong>노드가 빈 경우 반복문을 끝낸다</strong>.</li>
<li>출력 순서는 printNode와 같지만 화살표 방향과 시작 끝이 다르게 출력하기 위해 <strong>배열을 거꾸로 출력</strong>한다.</li>
<li>시작점인 <strong>tail</strong>을 문자열로 <strong>출력</strong>한다.</li>
</ul>
<hr>
<h2 id="📌-insert">📌 insert</h2>
<pre><code class="language-javascript">//insert(): position 위치에 노드 추가
DoubleLinkedList.prototype.insert = function(value,position = 0){
    if(position &lt; 0 || position &gt; this.length){
        return false;
    }

    let node = new Node(value),
        current = this.head,
        count = 0,
        prev;

    if(position === 0){
        if(this.head === null){
            this.head = node;
            this.tail = node;
        }else{
            node.next = current;
            current.prev = node;
            this.head = node;
        }

        this.length++;
    }else{
        if(position === this.length){
            current = this.tail;
            current.next = node;
            node.prev = current;
            this.tail = node;
        }else{
            while(count++ &lt; position){
                prev = current;
                current = current.next;
            }

            node.next = current;
            prev.next = node;

            current.prev = node;
            node.prev = prev;
        }

        this.length++;
    }

}

let dll = new DoubleLinkedList();


dll.insert(1);
dll.insert(10);
dll.insert(100);
dll.printNode(); // head -&gt; 100 -&gt; 10 -&gt; 1 -&gt; null
dll.printNodeInverse(); // null &lt;- 100 &lt;- 10 &lt;- 1 &lt;- tail

dll.insert(2,1);
dll.insert(3,3);
dll.printNode(); // head -&gt; 100 -&gt; 2 -&gt; 10 -&gt; 3 -&gt; 1 -&gt; null
dll.printNodeInverse(); // null &lt;- 100 &lt;- 2 &lt;- 10 &lt;- 3 &lt;- 1 &lt;- tail</code></pre>
<blockquote>
<p><strong>✅ 연결 리스트와 다른점?</strong>
이중 연결에서는 this.tail의 존재때문에 노드를 넣고 싶은 자리의 조건을 세세하게 나눠야 한다.
(value,position을 인자로 받고 position 값을 받지 못하면 디폴트 값 0)</p>
</blockquote>
<ul>
<li>position == 0 <pre><code>  + this.head === null : 리스트가 빈경우
  + 노드가 1개 이상 있는 경우</code></pre></li>
<li>position == this.length <pre><code>  this.tail과 연결 해야함</code></pre></li>
<li>위 둘 다 아닌 경우 <pre><code>  prev, current 이용해서 노드 중간에 연결</code></pre></li>
</ul>
<h2 id="📌-remove">📌 remove</h2>
<pre><code class="language-javascript">// remove(): value 데이터를 찾아서 노드 삭제
DoubleLinkedList.prototype.remove = function(value){
    let current = this.head,
        prev;

    while(current.data != value &amp;&amp; current.next != null){
        prev = current;
        current = current.next;
    }

    if(current.data != value) return null; //리스트에 없는 경우 null, 리스트가 텅 빈 경우도 current.next == null, current.data != value이므로 캐치

    if(current === this.head){
        this.head = current.next;

        if(this.length == 1) this.tail = null; // if(current.next == null) 보다 명시적임
        else this.head.prev = null;
    }else if(current === this.tail){ // 이미 위 조건에서 노드가 1개인 경우 캐치,
        this.tail = current.prev;
        this.tail.next = null;
    }else{
        prev.next = current.next;
        current.next.prev = prev;
    }

    this.length--;

    return current.data;
}


let dll = new DoubleLinkedList();


dll.insert(1);
dll.insert(10);
dll.insert(100);
dll.insert(2,1);
dll.insert(3,3);

console.log(dll.remove(1000));
dll.printNode();
dll.printNodeInverse();
console.log(dll.remove(1));
dll.printNode();
dll.printNodeInverse();
console.log(dll.remove(2));
dll.printNode();
dll.printNodeInverse();
console.log(dll.remove(100));
dll.printNode();
dll.printNodeInverse();</code></pre>
<ul>
<li>지우고 싶은 노드를 current에 저장하기 위해서 while문 이용</li>
<li>리스트를 모두 돌았는데 current.data != value면 null 반환</li>
<li>지우고 싶은 노드가 첫 노드인 경우 current.next 값을 this.head에 할당한다.<ul>
<li>노드가 1개만 있는 경우 -&gt; this.tail = null
+2개 이상 있는 경우 -&gt; this.head.prev = null<pre><code>this.head 는 지운 노드의 다음 값이고 이제는 첫 노드가 된다.
첫 노드의 경우 prev 값이 null 이니까 this.head.prev = null 초기화</code></pre></li>
</ul>
</li>
<li>지우고 싶은 노드가 마지막인 경우 this.tail에 current.prev값을 연결한다.<pre><code>첫 번째 조건에서 노드가 1개인 경우는 이미 해결 했으니까 this.tail은 
2개 이상인 경우만 신경쓴다.</code></pre></li>
<li>지우고 싶은 노드가 노드 중간에 있는 경우엔 while문으로 찾아낸 prev, current값을 이용해서 연결해준다.</li>
</ul>
<hr>
<h2 id="📌-removeat">📌 removeAt</h2>
<pre><code class="language-javascript">// removeAt(): position 위치 노드 삭제
DoubleLinkedList.prototype.removeAt = function(position = 0){
    if( position &lt; 0 || position &gt;= this.length) return null;

    let current = this.head,
        count = 0,
        prev;

    if(position === 0){
        this.head = current.next;

        if(this.length == 1) this.tail = null;
        else this.head.prev = null;

    }else if(position === this.length-1){
        this.tail = this.tail.prev;
        this.tail.next = null;
    }else{
        while(count++ &lt; position){
            prev = current;
            current = current.next;
        }

        prev.next = current.next;
        current.next.prev = prev;
    }

    this.length--;

    return current.data;
}</code></pre>
<ul>
<li>remove 메서드에서는 value값과 일치하는 노드를 지웠다면 removeAt은 
position으로 위치를 찾는다.</li>
<li>지울 노드가 this.head,this.tail과 연결되는 경우</li>
<li>지울 노드가 노드 중간에 있는 경우</li>
</ul>
<hr>
<h2 id="-📌-indexof-remove2"># 📌 indexOf, remove2</h2>
<pre><code class="language-javascript">// indexOf() : value 값과 일치하는 노드의 인덱스를 반환
DoubleLinkedList.prototype.indexOf = function(value){
    let current = this.head,
        count = 0;

    while(current != null){
        if(current.data === value) return count;

        current = current.next;
        count++
    }

    return -1;
}

// remove2 (): indexOf() + removeAt() = remove2()
DoubleLinkedList.prototype.remove2 = function(value){
    let index = this.indexOf(value);
    return this.removeAt(index);
}</code></pre>
<ul>
<li>current != null로 리스트가 비어있는 경우와 모든 노드를 돌고도 
찾는 값이 없는 경우 모두를 캐치할 수 있다.</li>
<li>while 문에서 리턴이 되지 않으면 무조건 -1 </li>
<li>remove2는 indexOf로 해당 값의 인덱스를 받아서 removeAt으로 인덱스의 노드를 삭제하고 삭제한 노드를 반환하는 메서드.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] This]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-This</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-This</guid>
            <pubDate>Sun, 25 Sep 2022 00:12:12 GMT</pubDate>
            <description><![CDATA[<p>javascript 에서의 this는 다른 언어와 다르게 동작한다.
<strong>this의 값은 함수를 호출한 방법에 의해 결정</strong>되기 때문에 <strong>this가 어디 묶여 있는지 파악</strong>하는 것이 가장 중요하다</p>
<h2 id="📌-암시적-바인딩">📌 암시적 바인딩</h2>
<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/3d45fbf0-7b80-426f-817c-2766aa6d8036/image.png" alt=""> chrome 브라우저에서 this는 window, this.alert(&#39;hi&#39;)가 잘 작동하고 있다.</p>
<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/fdf67ce4-43b4-4007-b5a5-6859d7949e0b/image.png" alt=""> node 환경에서 this는 존재하지만 this.alert()는 존재하지 않는다.</p>
<blockquote>
<p>전역공간 이외에도 함수에서의 this와 메서드의 this는 또 다를 수 있다.
이처럼 예상하기 어려운 this를 좀 더 안전하게 사용하는 방법을 살펴보자</p>
</blockquote>
<h2 id="📌-명시적-바인딩">📌 명시적 바인딩</h2>
<blockquote>
<p>Function.prototype.apply( )
Function.prototype.bind( )
Function.prototype.call( )</p>
</blockquote>
<h3 id="-call"># call</h3>
<pre><code class="language-javascript">const me = {
    name: &#39;suyeon&#39;,
      sayName: function(){
        return this.name + &#39; 입니다.&#39;;
    }
}

const zero = {
    name: &#39;베이스&#39;,
      sayName: function(){
        return this.name + &#39; 입니다.&#39;;
    }
}

function sayFullName(lastName){
    return lastName + this.sayName();
}

const result = sayFullName.call(me,&#39;kim&#39;);
const result2 = sayFullName.call(zero, &#39;제로&#39;);

console.log(result); // kimsuyeon 입니다.
console.log(result2); // 제로베이스 입니다.</code></pre>
<h3 id="-apply"># apply</h3>
<pre><code class="language-javascript">const me = {
    name: &#39;suyeon&#39;,
      sayName: function(){
        return this.name + &#39; 입니다.&#39;;
    }
}

const zero = {
    name: &#39;베이스&#39;,
      sayName: function(){
        return this.name + &#39; 입니다.&#39;;
    }
}

function sayFullName(lastName){
    return arguments[0] + this.sayName();
}

const result = sayFullName.apply(me,[&#39;kim&#39;,&#39;김&#39;]);
const result2 = sayFullName.apply(zero, [&#39;zero&#39;, &#39;제로&#39;]);

console.log(result); // kimsuyeon 입니다.
console.log(result2); // zero베이스 입니다.</code></pre>
<p>call과 같지만 <strong>배열을 인자로 받은 후</strong> <strong>arguments[index]</strong> 형식으로 요소를 선택할 수 있다</p>
<h3 id="bind">bind</h3>
<pre><code class="language-javascript">const me = {
    name: &#39;suyeon&#39;,
      sayName: function(){
        return this.name + &#39; 입니다.&#39;;
    }
}

const zero = {
    name: &#39;베이스&#39;,
      sayName: function(){
        return this.name + &#39; 입니다.&#39;;
    }
}

function sayFullName(lastName){
    return lastName + this.sayName();
}

const sayFullNameMe = sayFullName.bind(me);
const sayFullNameZero = sayFullName.bind(zero);

console.log(sayFullNameMe(&#39;kim&#39;)); // kimsuyeon 입니다.
console.log(sayFullNameZero(&#39;제로&#39;)); // 제로베이스 입니다.</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] Ajax]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Ajax</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Ajax</guid>
            <pubDate>Sat, 24 Sep 2022 23:27:06 GMT</pubDate>
            <description><![CDATA[<h1 id="http-통신">HTTP 통신</h1>
<p>HTTP(Hyper Text Transfer protocol)
<strong>브라우저와 서버가 통신</strong>할 수 있도록 만들어주는 여러 프로토콜 가운데 한 종류로 웹 브라우저와 웹 서버 사이에 <strong>HTML(웹 문서를 만들기 위한 언어) 문서</strong>를 주고받는데 쓰이는 <strong>통신 규약</strong>이다.</p>
<p>원래는 HTML 문서를 주고 받기 위함이었지만 지금은 <strong>이미지나 json파일</strong> 등도 주고 받는다.</p>
<hr>
<h1 id="ajax">Ajax</h1>
<p><strong>Asynchronous JavaScript and XML</strong>의 약자로
빠르게 동작하는 동적인 웹 페이지를 만들기 위한 개발 기법이다.</p>
<p>Ajax는 <strong>웹 페이지 전체를 다시 로딩하지 않고</strong>도 웹 페이지의 <strong>일부분을 갱신</strong>할 수 있다.
즉 Ajax를 이용하면 백그라운드 영역에서 서버와 통신하여, 그 결과를 웹 페이지의 일부분만 표시할 수 있다.</p>
<p><img src="https://user-images.githubusercontent.com/82014471/192119766-cfe1eb9d-c8fb-4f5c-bb28-a11fc0012862.gif" alt="ajax"><em>👀 페이지 전체를 로딩하지 않고도 검색어와 비슷한 검색어를 실시간으로 보여준다.</em></p>
<h2 id="✅-구성-요소">✅ 구성 요소</h2>
<ul>
<li><p>웹 페이지의 <strong>표현</strong>을 위한 <strong>HTML과 CSS</strong></p>
</li>
<li><p><strong>데이터에 접근</strong>하거나 화면 구성을 <strong>동적으로 조작</strong>하기 위해 사용되는 <strong>DOM 모델</strong></p>
</li>
<li><p><strong>데이터의 교환</strong>을 위한 <strong>JSON이나 XML</strong></p>
</li>
<li><p>웹 서버와의 <strong>비동기식 통신</strong>을 위한 <strong>XMLHttpRequest 객체</strong></p>
</li>
<li><p>위에서 언급한 <strong>모든 기술을 결합</strong>하여 사용자의 <strong>작업 흐름을 제어</strong>하는 데 사용되는 <strong>자바스크립트</strong></p>
</li>
</ul>
<h2 id="✅-동작-원리">✅ 동작 원리</h2>
<p>Ajax를 이용한 웹 응용 프로그램은 자바스크립트 코드를 통해 웹 서버와 통신하기 때문에 <strong>사용자의 동작에는 영향을 주지 않으면서</strong>도 백그라운드에서 <strong>지속해서 서버와 통신</strong>할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/eee62a73-0298-485c-b8c3-02ca32dc87e7/image.png" alt=""></p>
<ol>
<li><p>사용자 요청으로 <strong>이벤트가 발생</strong>한다.</p>
</li>
<li><p>이벤트가 발생하면 <strong>이벤트 핸들러</strong>에 의해 <strong>자바스크립트가 호출</strong>되고</p>
</li>
<li><p>자바스크립트는 <strong>XMLHttpRequest 객체 생성</strong> -&gt; <strong>서버로 요청</strong>을 낸다</p>
</li>
</ol>
<p>( 웹 브라우저는 요청을 보내고 나서, 서버의 응답을 기다릴 필요 없이 다른 작업 처리 가능)</p>
<ol start="4">
<li><p>서버는 전달받은 XMLHttpRequest 객체를 가지고 <strong>Ajax 요청을 처리</strong>하고</p>
</li>
<li><p>그 결과를 <strong>HTML, XML 또는 JSON 형태</strong>의 데이터로 <strong>웹 브라우저에 전달</strong>한다.</p>
</li>
</ol>
<p>( 이때 전달되는 응답은 새로운 페이지 전부 X, 필요한 데이터만 O )</p>
<ol start="7">
<li><p>서버로부터 전달받은 데이터를 가지고 <strong>웹 페이지의 일부분만을 갱신</strong>하는 자바스크립트를 호출하면</p>
</li>
<li><p>웹 페이지의 <strong>일부분만이 다시 로딩되어 표시</strong>된다.</p>
</li>
</ol>
<hr>
<h2 id="xmlhttprequest-객체">XMLHttpRequest 객체</h2>
<pre><code class="language-javascript">const xhr = new XMLHttpRequest();

xhr.onreadystatechange = function(){
    if(xhr.readyState === xhr.DONE){
        if( xhr.status === 200){
            console.log(xhr.response);
        }else{
            console.error(&#39;error&#39;);
        }
    }
}

xhr.open(&#39;GET&#39;,&#39;https://jsonplaceholder.typicode.com/todos/1&#39;);
xhr.send(); </code></pre>
<pre><code class="language-javascript">// 결과
VM597:6 {
  &quot;userId&quot;: 1,
  &quot;id&quot;: 1,
  &quot;title&quot;: &quot;delectus aut autem&quot;,
  &quot;completed&quot;: false
}</code></pre>
<p>위처럼 XMLHttpRequest 객체를 이용해서 json 형식의 정보를 불러 올 수 있다.</p>
<hr>
<h2 id="fetch-api">Fetch API</h2>
<blockquote>
<p>XMLHttpRequest의 단점을 보완해서 나온 api로 훨씬 간단하게 작성해서 사용할 수 있다.</p>
</blockquote>
<pre><code class="language-javascript">fetch(&#39;http://example.com/movies.json&#39;) // 1. URL fetch 요청
  .then((response) =&gt; response.json()) // 2. Fetch 응답 객체를 받아옴
  .then((data) =&gt; console.log(data)); // 3. 응답 객체가 JSON =&gt; 순수 JS 객체로 변환</code></pre>
<p><strong>네트워크 통신</strong>을 하고 <strong>json 형식으로 데이터를 받아오</strong>면 <strong>javascript 객체로 바꿔</strong>서 다루는 과정을 코드로 작성한 것이다.</p>
<hr>
<h2 id="json">JSON</h2>
<p><strong>Javascript</strong> 객체 문법을 <strong>따르는 문자 기반의 데이터 포맷</strong>이다.
JSON은 <strong>문자열 형태로 존재</strong>하며 네트워크를 통해 전송할 때 유용하다.</p>
<pre><code class="language-javascript">{
  &quot;squadName&quot;: &quot;Super hero squad&quot;,
  &quot;homeTown&quot;: &quot;Metro City&quot;,
  &quot;formed&quot;: 2016,
  &quot;secretBase&quot;: &quot;Super tower&quot;,
  &quot;active&quot;: true,
  &quot;members&quot;: [
    {
      &quot;name&quot;: &quot;Molecule Man&quot;,
      &quot;age&quot;: 29,
      &quot;secretIdentity&quot;: &quot;Dan Jukes&quot;,
      &quot;powers&quot;: [
        &quot;Radiation resistance&quot;,
        &quot;Turning tiny&quot;,
        &quot;Radiation blast&quot;
      ]
    },
    {
      &quot;name&quot;: &quot;Madame Uppercut&quot;,
      &quot;age&quot;: 39,
      &quot;secretIdentity&quot;: &quot;Jane Wilson&quot;,
      &quot;powers&quot;: [
        &quot;Million tonne punch&quot;,
        &quot;Damage resistance&quot;,
        &quot;Superhuman reflexes&quot;
      ]
    },
    {
      &quot;name&quot;: &quot;Eternal Flame&quot;,
      &quot;age&quot;: 1000000,
      &quot;secretIdentity&quot;: &quot;Unknown&quot;,
      &quot;powers&quot;: [
        &quot;Immortality&quot;,
        &quot;Heat Immunity&quot;,
        &quot;Inferno&quot;,
        &quot;Teleportation&quot;,
        &quot;Interdimensional travel&quot;
      ]
    }
  ]
}</code></pre>
<p>JOSN은 Javascript 객체 리터럴 문법을 따르는 문자열이다.</p>
<blockquote>
<p>데이터에 억세스하기 위해서는 네이티브 JSON 객체로 변환될 필요가 있어서 Javascript가 <strong>JSON 전역 객체를 통해 문자열과 JSON 객체의 상호변환을 지원</strong>한다.</p>
</blockquote>
<h3 id="-jsonstringify-"># JSON.stringify( )</h3>
<p>자바스크립트 객체를 JOSN 문자열로 변환하는 메서드로
서버로 데이터를 보낼 때 시용한다.</p>
<pre><code class="language-javascript">const obj = {x : 5, y: 6};

const jsonObj = JSON.stringify(obj);

console.log(jsonObj); // {&quot;x&quot;:5,&quot;y&quot;:6}</code></pre>
<h3 id="-jsonparse-"># JSON.parse( )</h3>
<p>JSON 문자열을 다시 javascript 객체로 반환하는 메서드로
서버에서 데이터를 가져올 때 사용한다</p>
<pre><code class="language-javascript">const obj = {x : 5, y: 6};

const jsonObj = JSON.stringify(obj);

const jsonParse = JSON.parse(jsonObj);

console.log(jsonParse); // { x: 5, y: 6 }</code></pre>
<blockquote>
<p>정리: 우리는 HTTP 통신을 활용하고 ajax로 통신을 하는데
사용할 수 있는 API는 XMLHttpRequest, fetch API 가 있고
주고 받는 데이터는 XML이 아니라 JSON 형식이며 자바스크립트 객체로 바꾸어 다룬다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] 객체 - 다루기]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B0%9D%EC%B2%B4-%EB%8B%A4%EB%A3%A8%EA%B8%B0</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B0%9D%EC%B2%B4-%EB%8B%A4%EB%A3%A8%EA%B8%B0</guid>
            <pubDate>Sat, 24 Sep 2022 07:35:52 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ol>
<li>Object.keys()</li>
<li>Object.values()</li>
<li>Object.entries()</li>
<li>배열 추가 / 제거 : push,unshift,pop,shift</li>
<li>배열 병합 : concat</li>
<li>배열 고차함수 : map, reduce, filter</li>
<li>배열 정렬 : sort</li>
<li>배열 검색 : includes</li>
</ol>
</blockquote>
<hr>
<h2 id="1-objectkeys">1. Object.keys()</h2>
<pre><code class="language-javascript">const object1 = {
  a: &#39;somestring&#39;,
  b: 42,
  c: false
};

console.log(Object.keys(object1));
// expected output: Array [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]</code></pre>
<p>객체의 속성들을 배열로 반환한다.</p>
<h2 id="2-objectvalues">2. Object.values()</h2>
<pre><code class="language-javascript">const object1 = {
  a: &#39;somestring&#39;,
  b: 42,
  c: false
};

console.log(Object.values(object1));
// expected output: Array [&quot;somestring&quot;, 42, false]</code></pre>
<p>객체의 값들을 배열로 반환한다.</p>
<h2 id="3-objectentries">3. Object.entries()</h2>
<pre><code class="language-javascript">const object1 = {
  a: &#39;somestring&#39;,
  b: 42
};

console.log(Object.entrie(obejct1)) 
// [ [ &#39;a&#39;, &#39;somestring&#39; ], [ &#39;b&#39;, 42 ] ]</code></pre>
<p>객체에서 각 키 : 값을 한쌍의 배열로 반환한다.
이 때 키는 string으로, 값은 자료형에 따라 반환된다.</p>
<h2 id="4-요소-추가삭제병합">4. 요소 추가/삭제/병합</h2>
<h3 id="-push-pop-unshift-shift"># push, pop, unshift, shift</h3>
<pre><code class="language-javascript">let arr = [&#39;js&#39;, &#39;css&#39;, &#39;java&#39;, &#39;python&#39;];


arr.push(&#39;Go&#39;);
console.log(arr); // [&#39;js&#39;, &#39;css&#39;, &#39;java&#39;, &#39;python&#39;, &#39;Go&#39;]

arr.pop();
console.log(arr); // [&#39;js&#39;, &#39;css&#39;, &#39;java&#39;, &#39;python&#39;]

arr.unshift(&#39;typeScript&#39;); 
console.log(arr);
// [&#39;typeScript&#39;, &#39;js&#39;, &#39;css&#39;, &#39;java&#39;, &#39;python&#39;]

arr.shift();
console.log(arr); // [&#39;js&#39;, &#39;css&#39;, &#39;java&#39;, &#39;python&#39;]</code></pre>
<p>위의 메소드는 요소를 추가 / 삭제 할 수 있지만 원본을 훼손하는 단점이 있다.</p>
<h3 id="-concat"># concat</h3>
<pre><code class="language-javascript">let arr = [&#39;js&#39;, &#39;css&#39;, &#39;java&#39;, &#39;python&#39;];

console.log(arr.concat(&#39;Go&#39;)); // [&#39;js&#39;, &#39;css&#39;, &#39;java&#39;, &#39;python&#39;, &#39;Go&#39;]

console.log(arr); // [&#39;js&#39;, &#39;css&#39;, &#39;java&#39;, &#39;python&#39;]</code></pre>
<hr>
<h2 id="5-고차-함수로-배열-다루기">5. 고차 함수로 배열 다루기</h2>
<h2 id="-map"># map</h2>
<blockquote>
<p>내가 가진 배열을 새롭게 조작해서 새로운 배열로 반환할 때 사용</p>
</blockquote>
<pre><code class="language-javascript">let langs = [&#39;js&#39;, &#39;css&#39;, &#39;java&#39;];

const newLangs = langs.map(function(lang){
    return lang.toUpperCase() + &#39; 언어&#39;;
});

console.log(newLangs); // [&#39;JS 언어&#39;, &#39;CSS 언어&#39;, &#39;JAVA 언어&#39;]</code></pre>
<h2 id="-filter"># filter</h2>
<blockquote>
<p>조건에 맞는 모든 요소를 배열로 반환</p>
</blockquote>
<pre><code class="language-javascript">let langs = [&#39;js&#39;, &#39;css&#39;, &#39;java&#39;, 1, 2];

const numbers = langs.filter(function(el){
    if(typeof el === &#39;number&#39;){
        return el;
    }
});

console.log(numbers); // [1,2]</code></pre>
<h2 id="-reduce"># reduce</h2>
<blockquote>
<p>배열의 각 요소에 대해 주어진 <strong>리듀서</strong>(reducer) 함수를 실행하고, 하나의 결과값을 반환한다.</p>
</blockquote>
<pre><code class="language-javascript">let numbers = [1, 3, 5, 7, 9];

const acc = numbers.reduce(function(accumulation, current){
    return accumulation + current;
},0); // 0 초기화 안하면 1부터 누적된 값으로 따짐

console.log(acc); // 25</code></pre>
<hr>
<h2 id="6-배열-검색">6. 배열 검색</h2>
<h2 id="-find"># find</h2>
<blockquote>
<p>배열에서 찾는 값 하나를 리턴해줌 (filter는 찾는 값 모두를 배열로 리턴) 찾는 값이 없으면 undefined</p>
</blockquote>
<pre><code class="language-javascript">const members = [&#39;도록&#39;, &#39;읻도록&#39;, &#39;제로&#39;, &#39;베이스&#39;];

const result = members.find(function(member){
    return member === &#39;제로&#39;;
});

console.log(result); // 제로 

// 없으면 undefined</code></pre>
<h2 id="-findindex"># findIndex</h2>
<blockquote>
<p>배열에서 찾는 값의 인덱스를 반환, 없는 경우 -1을 반환한다</p>
</blockquote>
<pre><code class="language-javascript">const members = [&#39;도록&#39;, &#39;읻도록&#39;, &#39;제로&#39;, &#39;베이스&#39;];

const result = members.findIndex(function(member){
    return member === &#39;제로&#39;;
});

console.log(result); // 2

// 없으면 -1</code></pre>
<h2 id="-indexof"># indexOf</h2>
<blockquote>
<p>찾는 요소만 인자로 넣어주면 해당 값의 인덱스를, 없는 경우 -1을 반환</p>
</blockquote>
<pre><code class="language-javascript">const members = [&#39;도록&#39;, &#39;제로&#39;, &#39;읻도록&#39;, &#39;제로&#39;, &#39;베이스&#39;];

const result = members.indexOf(&#39;제로&#39;);

console.log(result); // 1</code></pre>
<ul>
<li>만약 두번째로 존재하는 &#39;제로&#39;를 찾고 싶다면 찾기 시작하는 인덱스를 따로 지정해주면 된다.</li>
</ul>
<pre><code class="language-javascript">const members = [&#39;도록&#39;, &#39;제로&#39;, &#39;읻도록&#39;, &#39;제로&#39;, &#39;베이스&#39;];

const result = members.indexOf(&#39;제로&#39;,2); // 인덱스 2부터 찾음

console.log(result); // 3</code></pre>
<h2 id="-includes"># includes</h2>
<blockquote>
<p>배열에서 찾는 값이 존재하면 true, 없으면 false를 반환한다.</p>
</blockquote>
<pre><code class="language-javascript">const members = [&#39;도록&#39;, &#39;제로&#39;, &#39;읻도록&#39;, &#39;제로&#39;, &#39;베이스&#39;];

const result = members.includes(&#39;제로&#39;);

console.log(result); // true</code></pre>
<ul>
<li>includes 메서드는 배열 내에 찾는 값이 있는지를 불리언으로 반환해준다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] 객체 - 생성 ( 생성자 함수, Object.create, 인스턴스 )]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%95%A8%EC%88%98-Object.create-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%95%A8%EC%88%98-Object.create-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4</guid>
            <pubDate>Sat, 24 Sep 2022 06:30:05 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-객체-생성">📌 객체 생성</h2>
<h3 id="-싱글-리터럴-객체"># 싱글 리터럴 객체</h3>
<pre><code class="language-javascript">// 싱글 리터럴 객체 생성
const object = {
    property: &#39;value&#39;,
    method: function() {},
}</code></pre>
<h3 id="-생성자-함수로-객체-생성"># 생성자 함수로 객체 생성</h3>
<pre><code class="language-javascript">// 생성자 함수로 객체 생성
function NewObject(name,age) {
    this.name = name;
    this.age = age;
}
const newObject = new NewObject(&#39;syeon&#39;, 20);

console.log(newObject);  //NewObject { name: &#39;syeon&#39;, age: 20 }  </code></pre>
<h3 id="-objectcreate"># Object.create()</h3>
<blockquote>
<p>자바스크립트에서 제공하는 <strong>Object 함수의 내장 메서드</strong>로 객체를 생성한다.
<strong>Object.create</strong>(프로토 타입, 객체 서술자(기술자))</p>
</blockquote>
<pre><code class="language-javascript">const obj = Object.create(Object.prototype, {
    name:{
        value: &#39;syeon&#39;,
        writable: false, // 덮어쓸 수 있나
        enumerable: false, // 열거할 수 있나
        configurable: false, // 객체 서술자를 수정할 수 있나
    }
})

obj.name = &#39;kim&#39;;
console.log(obj.name); // syeon 변하지 않음

for(const key in obj){
    console.log(); // 열거 불가능
}

console.log(obj instanceof Object);</code></pre>
<p>프로토타입 객체 안에 저장될 속성값을 자세하게 서술할 수 있다.</p>
<hr>
<h2 id="📌-프로퍼티-열거">📌 프로퍼티 열거</h2>
<pre><code class="language-javascript">const obj = {
    prop1: &#39;value01&#39;,
    prop2: &#39;value02&#39;,
    prop3: &#39;value03&#39;,
    prop4: &#39;value04&#39;,
}

for(const key in obj){
    console.log(key); // prop1, prop2, prop3, prop4
}</code></pre>
<p>key는 obj 객체의 키값을 출력하고 있다. 
<strong>만약 value(값)을 출력하고 싶다면</strong> 어떻게 해야할까?</p>
<h3 id="-vs--">. vs [ ]</h3>
<p>객체에서 값을 가져오는 방법은 <strong>.(Dot notation)</strong>과 <strong>[ ](Bracket notation)</strong>이 있다.</p>
<pre><code class="language-javascript">for(const key in obj){
    console.log(obj.key); // undefined
}

for(const key in obj){
    console.log(obj[key]); // value01 value02 value03 value04
}

console.log(&#39;prop1&#39;); // value01</code></pre>
<p>key변수는 string으로 출력이 되기 때문에 dot notation은 사용할 수 없지만
[ ]안에는 표현식이 들어갈 수 있기 때문에 key값을 넣어 출력 가능하다.</p>
<h3 id="-체이닝-조심"># 체이닝 조심</h3>
<p>함수에서 체이닝이 일어나는 것처럼 <strong>객체는 프로토타입 체이닝이 일어난다</strong>.
현 객체에 값이 없으면 <strong>상위 프로토타입 객체를 살피면서</strong> 값을 찾는다.</p>
<p>만약 <strong>현재 객체에서만 값을 찾고 싶다면?</strong></p>
<pre><code class="language-javascript">for(const key in obj){
  if(obj.hasOwnProperty(&#39;syeon&#39;)){
      console.log(obj[key]); // 출력 안됨
  }
}</code></pre>
<hr>
<h2 id="📌-프로퍼티-접근자-getter-setter">📌 프로퍼티 접근자 (getter, setter)</h2>
<pre><code class="language-javascript">const person = {
    _firstName: &#39;syeon&#39;,
    lastName: &#39;kim&#39;,

    get firstName(){
        return this._firstName.toUpperCase();
    },

    set firstName(newFirstName){
        if(typeof newFirstName !== &#39;string&#39;){
            this._firstName = &#39;undefined&#39;;
            return;
        }

        this._firstName = newFirstName;
    },

    get fullName(){
        return this.lastName + &#39; &#39; + this._firstName + &#39; 입니다.&#39;
    }
}
person.firstName = &#39;it dorok&#39;;
console.log(person.firstName); // IT DOROK
console.log(person.fullName); // kim it dorok 입니다.</code></pre>
<blockquote>
</blockquote>
<pre><code class="language-javascript">person.firstName = &#39;it dorok&#39;; </code></pre>
<p>객체 속성을 설정하는 경우 setter가 실행되면서 받는 값이 string 인지 아닌지 판별후 값을 할당한다.</p>
<blockquote>
</blockquote>
<pre><code class="language-javascript">console.log(person.firstName); // IT DOROK
console.log(person.fullName); // kim it dorok 입니다.</code></pre>
<p>속성값을 불러오는 경우 gettr가 실행되면서 조건에 맞게 값을 출력한다.</p>
<hr>
<h2 id="-📌-인스턴스-instance"># 📌 인스턴스 (instance)</h2>
<pre><code class="language-javascript">const me = {
    name: &#39;syeon&#39;,
    age : 10,
    location: &#39;Korea&#39;,
}

const me2 = {
    name: &#39;syeon&#39;,
    age : 10,
    location: &#39;Korea&#39;,
}

console.log(me == me2); // false</code></pre>
<ul>
<li><p>두 객체는 속성값이 모두 같지만 비교한 결과 false를 출력하고 있다.</p>
</li>
<li><p>객체는 reference value 로서 사실상 변수가 저장된 메모리 주소가 비교되고 당연히 메모리 주소는 다르기 때문에 false가 출력된다.</p>
</li>
</ul>
<blockquote>
<p>이 때 특정 메모리에 공간을 차지하고 있는 고유한 객체 하나하나를 instance라고 한다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] DOM ]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DOM</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-DOM</guid>
            <pubDate>Fri, 23 Sep 2022 04:23:55 GMT</pubDate>
            <description><![CDATA[<h1 id="dom">DOM</h1>
<p>문서 객체 모델(DOM, Document Object Model)은 XML이나 HTML 문서에 접근하기 위한 일종의 인터페이스이다.
이 객체 모델은 문서 내의 모든 요소를 정의하고, 각각의 요소에 접근하는 방법을 제공한다.</p>
<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/7ed3e1c3-d913-486d-a52f-044110e2a004/image.png" alt=""></p>
<h2 id="📌-document-객체">📌 Document 객체</h2>
<p>Document 객체는 웹 페이지 그 자체를 의미하고 웹 페이지에 존재하는 HTML 요소에 접근하고자 할 때는 반드시 Document 객체부터 시작해야 한다.</p>
<pre><code class="language-javascript">document.querySelector(&#39;.hi&#39;);</code></pre>
<p>이 때 Document 객체는 DOM 요소와 관련된 작업을 도와주는 다양한 메소드를 제공한다.</p>
<h2 id="📌-노드-node">📌 노드 (Node)</h2>
<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/b029e497-13d6-4c87-8f89-242142722c3d/image.jpg" alt=""></p>
<ul>
<li><p>노드(node)는 계층적 단위로서 정보를 저장한다.</p>
</li>
<li><p>노드 트리 ( node tree )는 이러한 노드가 집합한 계층적 구조이다.</p>
</li>
<li><p>노드 트리는 최상위 레벨인 루트 노드(root node)로부터 시작하여, 가장 낮은 레벨인 텍스트 노드까지 뻗어 내려간다.</p>
</li>
<li><p>자바스크립트는 HTML DOM을 이용하여 노드 트리에 포함된 모든 노드에 접근할 수 있다.</p>
</li>
</ul>
<h2 id="📌-dom-요소-다루기">📌 DOM 요소 다루기</h2>
<h3 id="-dom-요소-선택"># DOM 요소 선택</h3>
<p>DOM 요소를 다루기 위해서는 우선 해당 요소를 선택해야 한다.</p>
<pre><code class="language-javascript">// 태그 이름이 li인 모든 요소 고르기
const listNode = document.getElementsByTagName(&#39;li&#39;); 

// id가 red인 요소 하나 고르기
const red = document.getElementById(&#39;red&#39;); 

// class가 blue인 모든 요소 고르기
const blue = document.getElementsByClassName(&#39;blue&#39;); 

// id가 green인 요소 고르기
const idGreen = document.querySelector(&#39;#green&#39;); 

// class가 yellow인 요소 모두 고르기
const classYellows = document.qeurySelectorAll(&#39;.yellow&#39;); </code></pre>
<h3 id="-dom-요소의-내용-변경"># DOM 요소의 내용 변경</h3>
<pre><code class="language-javascript">const listNode = document.querySelector(&#39;li&#39;);
listNode.classList.add(&#39;.hi&#39;);

console.log(listNode.classList); 
// DOMTokenList [&#39;.hi&#39;, value: &#39;.hi&#39;]</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] 함수 - 스코프 (Scope)]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%95%A8%EC%88%98-%EC%8A%A4%EC%BD%94%ED%94%84-Scope</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%95%A8%EC%88%98-%EC%8A%A4%EC%BD%94%ED%94%84-Scope</guid>
            <pubDate>Fri, 23 Sep 2022 03:58:32 GMT</pubDate>
            <description><![CDATA[<hr>
<h2 id="📌-스코프-scope">📌 스코프 (Scope)</h2>
<blockquote>
<ul>
<li>변수에 접근 가능한 범위</li>
</ul>
</blockquote>
<ul>
<li>함수 실행컨텍스트 내부의 변수 환경</li>
</ul>
<h3 id="-컨텍스트-context"># 컨텍스트 (context)</h3>
<blockquote>
<p>this 키워드 값, 함수가 선언된 환경을 의미한다.
_&#39;어떤 친구가 날 불렀는가?&#39; _</p>
</blockquote>
<pre><code class="language-javascript">function hi(){
    console.log(&#39;hi&#39;);

  function ask(){
      console.log(&#39;what is your name?&#39;);
  }

  ask() // context = function hi 
}

hi() // context = global </code></pre>
<h3 id="-함수-스코프"># 함수 스코프</h3>
<blockquote>
<p>JS는 기본적으로 <strong><em>함수 스코프를 따른다</em></strong> 
=&gt; 함수가 선언될 때마다 새로운 스코프 발생</p>
</blockquote>
<pre><code class="language-javascript">if( 5 &gt; 3){
  var num = 12345;
}

console.log(num); // 12345</code></pre>
<ul>
<li>함수가 선언되지 않았기 때문에 같은 컨텍스트 안에 존재, num에 접근 가능</li>
</ul>
<pre><code class="language-javascript">function a(){
 var num = 12345;
}

console.log(num) // ReferenceError</code></pre>
<ul>
<li>함수가 선언되면서 a의 실행 컨텍스트가 생성</li>
<li>이 실행 컨텍스트 내부에 존재하는 변수환경(variable environment)에 num 변수가 저장됨</li>
<li>따라서 함수 외부에서 num에 접근하려고 할 경우 스코프가 다르기 때문에 해당 변수에 접근이 불가능</li>
<li>함수외부는 global scope이고, 함수 내부는 a함수의 scope인데 부모스코프는 자식스코프에서 간섭할 수 없기 떄문에 접근이 불가능</li>
</ul>
<h3 id="-블록-스코프"># 블록 스코프</h3>
<blockquote>
<p>{ } 블록이 생성될 때마다 스코프가 생성됨
<strong>let, const의 등장으로 블록 스코프 생성 가능</strong></p>
</blockquote>
<pre><code class="language-javascript">function index() {
    for(var i = 0; i &lt; 5; i++) {
        console.log(i);
    }
    console.log(&#39;last&#39;,i);
}
index();
/*
0
1
2
3
4
&#39;last&#39; 5 
*/</code></pre>
<ul>
<li>var 로 변수 i를 초기화 하여 함수 스코프를 따르고 </li>
<li>for문과 console.log(&#39;last&#39;,i)은 <strong>같은 스코프에 있어서 변수에 접근 가능</strong></li>
</ul>
<pre><code class="language-javascript">function index() {
    for(let i = 0; i &lt; 5; i++) {
        console.log(i);
    }
    console.log(&#39;last&#39;,i);
}
index(); /* ReferenceError: i is not defined */</code></pre>
<ul>
<li>let으로 변수 i를 초기화 하여 블록 스코프를 생성</li>
<li>for문과 console.log(&#39;last&#39;,i)의 스코프가 달라서 변수에 접근 불가능</li>
</ul>
<p><strong>참조👀</strong> <del><a href="https://velog.io/@fromzoo/%ED%95%A8%EC%88%98%EC%8A%A4%EC%BD%94%ED%94%84-vs-%EB%B8%94%EB%A1%9D%EC%8A%A4%EC%BD%94%ED%94%84">https://velog.io/@fromzoo/%ED%95%A8%EC%88%98%EC%8A%A4%EC%BD%94%ED%94%84-vs-%EB%B8%94%EB%A1%9D%EC%8A%A4%EC%BD%94%ED%94%84</a></del></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 자바스크립트 ] 함수 - hoisting]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@purin_no_corin/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%95%A8%EC%88%98</guid>
            <pubDate>Fri, 23 Sep 2022 03:45:33 GMT</pubDate>
            <description><![CDATA[<h1 id="함수">함수</h1>
<blockquote>
<ul>
<li>특정 작업을 처리하는 코드 묶음</li>
</ul>
</blockquote>
<ul>
<li>코드를 묶어서 원하는 때에 사용 가능</li>
<li>아래처럼 다양한 방법으로 선언하고 사용할 수 있다.</li>
</ul>
<pre><code class="language-javascript">// 함수 선언문 (declaration)
function func(){

}

// 함수 표현식 (expression) 
const func = function func(){

}

// 메서드: 객체 안에 속성 값으로 있는 함수
const obj = {
    prop: function () {},
}

// 생성자 함수: 특정 instance를 만들어 낼 수 있다.
function MyObj(){

}

// 화살표 함수 
const arrowFunc = () =&gt; {}
</code></pre>
<h2 id="📌-hoisting">📌 hoisting</h2>
<p>호이스팅(Hoisting): 끌어 올리다 라는 뜻 함수 안에 있는 변수나 함수 맨위로 끌어올린다는 것이다.</p>
<p>실제로 코드가 끌어올려지는 것은 아니며, 자바스크립트 Parser가 내부적으로 끌어올려서 처리한다.</p>
<h3 id="-함수-선언문-호이스팅"># 함수 선언문 호이스팅</h3>
<pre><code class="language-javascript">func(); // 안녕하세요

function func() {
    console.log(&#39;안녕하세요&#39;);
}</code></pre>
<pre><code class="language-javascript">function func() {
    console.log(&#39;안녕못해&#39;);
}

func(); // 안녕못해</code></pre>
<p><strong>🚨 함수의 중복 선언이나 호이스팅 문제 발생</strong>
둘 다 정상 작동: 
심지어 두 함수를 동시에 선언하고 맨 마지막에 호출하면 오류는 발생하지 않으며 마지막으로 선언된 &#39;안녕못해&#39;가 출력된다.</p>
<h3 id="-함수-표현식-호이스팅"># 함수 표현식 호이스팅</h3>
<pre><code class="language-javascript">func(); 

var func = function() {
    console.log(&#39;안녕하세요&#39;);
}</code></pre>
<pre><code class="language-javascript">var func = function() {
    console.log(&#39;안녕하세요&#39;);
}

func();</code></pre>
<pre><code class="language-javascript">func();

let func = function() {
    console.log(&#39;안녕하세요&#39;);
}</code></pre>
<hr>
<h3 id="-1"># 1</h3>
<pre><code class="language-javascript">var func; // undefined

func(); // TypeError

var func = function() {
    console.log(&#39;안녕하세요&#39;);
}</code></pre>
<p>var로 선언된 변수에 함수를 저장하고 호출하면 : </p>
<p>함수가 맨 위로 끌어올려지면서 선언된다.</p>
<p>함수를 변수에 저장하기 전에 호출하면 func는 아직 변수기 때문에 TypeError가 발생한다.</p>
<h3 id="-2"># 2</h3>
<pre><code class="language-javascript">var func; // undefined

var func = function() {
    console.log(&#39;안녕하세요&#39;);
}

func(); // 안녕하세요</code></pre>
<p>변수가 맨 위로 끌어올려져 선언된다.
변수에 함수가 할당 된 후에 호출 하기 때문에 정상 작동된다.</p>
<h3 id="-3"># 3</h3>
<pre><code class="language-javascript">// 호이스팅 발생 안함

func(); // ReferenceError

let func = function() {
    console.log(&#39;안녕하세요&#39;);
}</code></pre>
<p>let, const의 경우 hoisting이 발생하지 않는다</p>
<p>선언과 할당이 동시에 이뤄지기 때문에 선언이 되기 전에 함수를 호출하려고 해서 참조 오류가 발생한다.</p>
<blockquote>
<p>변수나 함수의 표현식을 선언하는 경우 let, const 로 하는 것이 좋고 
그 중에도 값이 바뀌면 error를 내는 const로 선언하는 것이 좋다</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 선형 자료구조 ] 연결 리스트 구현 ]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EA%B5%AC%ED%98%84-1</link>
            <guid>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%97%B0%EA%B2%B0-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EA%B5%AC%ED%98%84-1</guid>
            <pubDate>Wed, 21 Sep 2022 12:50:15 GMT</pubDate>
            <description><![CDATA[<h2 id="연결-리스트-linked-list">연결 리스트 (Linked List)</h2>
<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/2a5fd877-a4d7-42f9-92fe-b8fbb73d3c97/image.jpeg" alt=""></p>
<p>Prototype Object 와 prototype 속성을 기억하면서 메서드를 직접 구현해보자</p>
<hr>
<h2 id="-node-linkedlist"># Node(), LinkedList()</h2>
<pre><code class="language-javascript">function Node(data){
    this.data = data;
      this.next = null;
}

function LinkedList(){
    this.head = null;
      this.length = 0;
}</code></pre>
<p>node: </p>
<ul>
<li>값과 포인터가 저장된 덩어리로 생각하면 된다. </li>
<li>Node 함수로 만들어지는 객체로부터 data값을 받아온다.</li>
</ul>
<p>linkedlist: </p>
<ul>
<li>노드가 연결, 연결되면서 만들어지는 리스트 </li>
<li>각 노드가 가진 포인터가 다음 노드를 가리키면서 만들어진다.</li>
<li>노드가 하나도 연결되지 않으면 head값은 null, 길이는 0이 된다.</li>
</ul>
<h2 id="-size-isempty"># size, isEmpty</h2>
<blockquote>
<p>연결리스트에 노드가 몇 개 있는지 확인하는 size메서드와 
연결리스트가 비었는지 확인하는 isEmpty메서드는 만들어 보자</p>
</blockquote>
<pre><code class="language-javascript">function Node(data){
    this.data = data;
      this.next = null;
}

function LinkedList(){
    this.head = null;
      this.length = 0;
}

// 연결리스트의 노드 개수 반환
LinkedList.prototype.size = function(){
    return this.length;
}

// 연결리스트가 비었는지 확인
LinkedList.prototype.isEmpty = function () {
    return this.length === 0;
}

let ll = new LinkedList();
console.log(ll) // LinkedList { head: null, length: 0 }

ll.head = new Node(123);
ll.length++;
console.log(ll); // LinkedList { head: Node { data: 123, next: null }, length: 1 }</code></pre>
<h2 id="-printnode-append"># printNode, append</h2>
<pre><code class="language-javascript">function Node(data){
    this.data = data;
      this.next = null;
}

function LinkedList(){
    this.head = null;
      this.length = 0;
}

LinkedList.prototype.size = function(){
    return this.length;
}

LinkedList.prototype.isEmpty = function () {
    return this.length === 0;
}

// 연결리스트의 노드를 순서대로 출력
LinkedList.prototype.printNode = function () {
    for(let node = this.head; node != null; node = node.next){
        process.stdout.write(`${node.data} -&gt; `);
    }

    console.log(&#39;null&#39;);
}

// 연결리스트의 마지막에 노드 추가
LinkedList.prototype.append = function(data){
    let node = new Node(data),
        current = this.head

    if(this.head === null){
        this.head = node;
    }else{
        while(current.next != null){
            current = current.next;
        }
        current.next = node;
    }

    this.length++;
}

let ll = new LinkedList();
ll.append(1);
ll.append(10);
ll.append(100);
ll.printNode(); /// 1 -&gt; 10 -&gt; 100 -&gt; null
console.log(ll.size()); // 3</code></pre>
<h2 id="-insert"># insert</h2>
<pre><code class="language-javascript">function Node(data){
    this.data = data;
      this.next = null;
}

function LinkedList(){
    this.head = null;
      this.length = 0;
}

LinkedList.prototype.size = function(){
    return this.length;
}

LinkedList.prototype.printNode = function () {
    for(let node = this.head; node != null; node = node.next){
        process.stdout.write(`${node.data} -&gt; `);
    }

    console.log(&#39;null&#39;);
}

// position 위치에 노드 추가
LinkedList.prototype.insert = function (data, position = 0) {
    if(position &lt; 0 || position &gt; this.length){
        return false;
    }
    let node = new Node(data),
        current = this.head,
        count = 0,
        prev;

    if(position === 0){
        node.next = current;
        this.head = node;
    }else{
        while(count++ &lt; position){
            prev = current;
            current = current.next;
        }
        node.next = current;
        prev.next = node;        
    }

    this.length++;

    return true;
}

let ll = new LinkedList();

ll.insert(1);
ll.insert(10); 
ll.insert(100);
ll.printNode();

ll.insert(2,1);
ll.insert(3,3);
ll.printNode();
console.log(ll.size());</code></pre>
<blockquote>
</blockquote>
<pre><code class="language-javascript">while(count++ &lt; position){// while(count != position), count++; 
    prev = current;
    current = current.next;
}
node.next = current;
prev.next = node;        </code></pre>
<p>주석처리한 부분처럼 나눠서 적기 보다 count++ &lt; position 으로 합쳐서 
적으면 더 보기 간편하고 좋다.</p>
<h2 id="-remove"># remove</h2>
<pre><code class="language-javascript">function Node(data){
    this.data = data;
      this.next = null;
}

function LinkedList(){
    this.head = null;
      this.length = 0;
}

LinkedList.prototype.size = function(){
    return this.length;
}

LinkedList.prototype.printNode = function () {
    for(let node = this.head; node != null; node = node.next){
        process.stdout.write(`${node.data} -&gt; `);
    }

    console.log(&#39;null&#39;);
}

// position 위치에 노드 추가
LinkedList.prototype.insert = function (data, position = 0) {
    if(position &lt; 0 || position &gt; this.length){ // 말도 안되는 경우를 false로 리턴
        return false;
    }
    let node = new Node(data),
        current = this.head,
        count = 0,
        prev;

    if(position === 0){
        node.next = current;
        this.head = node;
    }else{
        while(count++ &lt; position){
            prev = current;
            current = current.next;
        }
        node.next = current;
        prev.next = node;        
    }

    this.length++;

    return true;
}

// remove() data를 찾아서 노드 삭제 
LinkedList.prototype.remove = function (data){
    let current = this.head,
        prev;

    // 지우고 싶은 노드 찾기
    while(current.data != data &amp;&amp; current.next != null){ 
        prev = current;
        current = current.next;
    } 

    // 다 돌았는데 찾는 노드 없으면 null
    if(current.data != data){ // 다음 노드가 더이상 없어서 위의 while문이 끝났는데 여전히 현 노드의 값이 찾는 값과 같지 않으면 null 반환
        return null;
    }

    if(current == this.head){ // 첫 노드인 경우 prev = current, current = this.head 로 prev, current 둘 다 같은 값을 가리키게 되므로 오류 생김 -&gt; 따로 처리
        this.head = current.next; 
    }else{
        prev.next = current.next; 
    }

    this.length--;

    return current.data;
}

let ll = new LinkedList();

ll.insert(1);
ll.insert(10); 
ll.insert(100);
ll.insert(2,1);
ll.insert(3,3);
ll.printNode();

console.log(ll.remove(1000)); // null
ll.printNode();
console.log(ll.remove(1));
ll.printNode();
console.log(ll.remove(2));
ll.printNode();
console.log(ll.remove(100));
ll.printNode();
console.log(ll.size());</code></pre>
<p>this.head == null 이면 current.next == null 이기 때문에 따로 잡을 필요가 없다.</p>
<hr>
<p>9.22 더 추가 예정 removeAt(), indexOf() </p>
<h2 id="-removeat"># removeAt</h2>
<pre><code class="language-javascript">function Node(data){
    this.data = data;
      this.next = null;
}

function LinkedList(){
    this.head = null;
      this.length = 0;
}

LinkedList.prototype.size = function(){
    return this.length;
}

LinkedList.prototype.printNode = function () {
    for(let node = this.head; node != null; node = node.next){
        process.stdout.write(`${node.data} -&gt; `);
    }

    console.log(&#39;null&#39;);
}


LinkedList.prototype.insert = function (data, position = 0) {
    if(position &lt; 0 || position &gt; this.length){
        return false;
    }
    let node = new Node(data),
        current = this.head,
        count = 0,
        prev;

    if(position === 0){
        node.next = current;
        this.head = node;
    }else{
        while(count++ &lt; position){
            prev = current;
            current = current.next;
        }
        node.next = current;
        prev.next = node;        
    }

    this.length++;

    return true;
}

LinkedList.prototype.remove = function (data){
    let current = this.head,
        prev;

    while(current.data != data &amp;&amp; current.next != null){
        prev = current;
        current = current.next;
    } 

    if(current.data != data){ 
        return null;
    }

    if(current == this.head){
        this.head = current.next; 
    }else{
        prev.next = current.next; 
    }

    this.length--;

    return current.data;
}

//해당 인덱스의 노드 삭제
LinkedList.prototype.removeAt = function (position){
    if(position &lt; 0 || position &gt;= this.length){
        return null;
    }

    let current = this.head,
        count = 0,
        prev;

    while(count++ &lt; position){
        prev = current;
        current = current.next; 
    }

   if(current == this.head){
        this.head = current.next;
   }else{
        prev.next = current.next;
   }

   this.length--;

   return current.data;
}

let ll = new LinkedList();

ll.insert(1);
ll.insert(10); 
ll.insert(100);
ll.insert(2,1);
ll.insert(3,3);
ll.printNode();
console.log(&#39;----------------------------------&#39;);

console.log(ll.removeAt(1000));
ll.printNode();
console.log(ll.removeAt(1));
ll.printNode();
console.log(ll.removeAt(2));
ll.printNode();
console.log(ll.removeAt(100));
ll.printNode();
console.log(ll.size());</code></pre>
<blockquote>
</blockquote>
<pre><code class="language-javascript"> if(position &lt; 0 || position &gt;= this.length){
        return null;
    }</code></pre>
<ul>
<li>노드 추가 (insert)와 다르게 position == this.length인 경우도 null로 리턴:
마지막 요소 다음에 끼워넣는 경우 this.length와 값이 같지만 
기존에 있는 노드에서 삭제하는 경우 this.length를 인덱스로 갖는 노드는 없기 때문이다.</li>
</ul>
<h2 id="-indexof-remove2"># indexOf, remove2</h2>
<pre><code class="language-javascript">function Node(data){
    this.data = data;
      this.next = null;
}

function LinkedList(){
    this.head = null;
      this.length = 0;
}

LinkedList.prototype.size = function(){
    return this.length;
}

LinkedList.prototype.printNode = function () {
    for(let node = this.head; node != null; node = node.next){
        process.stdout.write(`${node.data} -&gt; `);
    }

    console.log(&#39;null&#39;);
}

LinkedList.prototype.insert = function (data, position = 0) {
    if(position &lt; 0 || position &gt; this.length){
        return false;
    }
    let node = new Node(data),
        current = this.head,
        count = 0,
        prev;

    if(position === 0){
        node.next = current;
        this.head = node;
    }else{
        while(count++ &lt; position){
            prev = current;
            current = current.next;
        }
        node.next = current;
        prev.next = node;        
    }

    this.length++;

    return true;
}

LinkedList.prototype.remove = function (data){
    let current = this.head,
        prev;

    while(current.data != data &amp;&amp; current.next != null){
        prev = current;
        current = current.next;
    } 

    if(current.data != data){
        return null;
    }

    if(current == this.head){
        this.head = current.next; 
    }else{
        prev.next = current.next; 
    }

    this.length--;

    return current.data;
}

//해당 인덱스의 노드 삭제
LinkedList.prototype.removeAt = function (position){
    if(position &lt; 0 || position &gt;= this.length){
        return null;
    }

    let current = this.head,
        count = 0,
        prev;

    while(count++ &lt; position){
        prev = current;
        current = current.next; 
    }

   if(current == this.head){
        this.head = current.next;
   }else{
        prev.next = current.next;
   }

   this.length--;

   return current.data;
}

// data 값을 갖는 노드의 인덱스 리턴 
LinkedList.prototype.indexOf = function(data){
    let current = this.head,
        count = 0;

   while(current != null){ //끝까지 돌았는데 노드가 null인 경우 -1 리턴
        if(current.data === data){
            return count;
        }

        count++;
        current = current.next;
   }

   return -1;
}

// data에 해당하는 노드의 인덱스를 이용해서 노드 지우는 메서드
LinkedList.prototype.remove2 = function (data){
    let index = this.indexOf(data);
    return this.removeAt(index);
}

let ll = new LinkedList();

ll.insert(1);
ll.insert(10); 
ll.insert(100);
ll.insert(2,1);
ll.insert(3,3);
ll.printNode();

console.log(ll.indexOf(1000)); // -1
console.log(ll.indexOf(1)); // 4
console.log(ll.indexOf(2)); // 1
console.log(ll.indexOf(100)); // 0

console.log(ll.remove2(1000)); // null
ll.printNode(); // 100 -&gt; 2 -&gt; 10 -&gt; 3 -&gt; 1 -&gt; null
console.log(ll.remove2(1)); // 1
ll.printNode(); // 100 -&gt; 2 -&gt; 10 -&gt; 3 -&gt; null
console.log(ll.remove2(2)); // 2
ll.printNode(); // 100 -&gt; 10 -&gt; 3 -&gt; null
console.log(ll.remove2(100)); // 100
ll.printNode(); // 10 -&gt; 3 -&gt; null
console.log(ll.size()); // 2</code></pre>
<ul>
<li>크게 루프안에 해당 data가 없는 경우를 while로 잡아냄</li>
<li>while 내에서 현재 노드의 값이 data와 같지 않으면 count(인덱스)와 
현 노드를 업데이트 함</li>
<li>현 노드의 값이 data와 같으면 count리턴</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로토 타입 prototype]]></title>
            <link>https://velog.io/@purin_no_corin/%ED%94%84%EB%A1%9C%ED%86%A0-%ED%83%80%EC%9E%85-prototype</link>
            <guid>https://velog.io/@purin_no_corin/%ED%94%84%EB%A1%9C%ED%86%A0-%ED%83%80%EC%9E%85-prototype</guid>
            <pubDate>Mon, 19 Sep 2022 13:47:11 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-prototype-vs-class">📌 Prototype vs Class</h2>
<blockquote>
<p>자바스크립트는 본래 <strong>클래스라는 개념이 없었다</strong>&nbsp;&nbsp; -&gt; 상속 개념 없음 <br>
대신 <strong>프로토타입이 존재</strong>한다.&nbsp;&nbsp; -&gt; <strong>상속 개념을 흉내</strong>냄<br>
최근 class가 추가 되었지만 <strong>자바스크립트는 여전히 프로토타입 기반</strong>이다.</p>
</blockquote>
<h2 id="📌-왜-있는-걸까">📌 왜 있는 걸까?</h2>
<pre><code class="language-javascript">function Person() {
  this.job = true;
  this.age = 23;
}

var kim  = new Person();
var park = new Person();

console.log(kim.job);  // =&gt; true
console.log(kim.age);  // =&gt; 23
console.log(park.job); // =&gt; true
console.log(park.age); // =&gt; 23</code></pre>
<p>kim, park은 모두 동일한 값을 가지고 있지만 메모리에는 각각 두개씩 4번 할당된다</p>
<p>이런 <strong>중복 할당을 해결하는게 프로토타입</strong>이다.</p>
<pre><code class="language-javascript">function Person() {}

Person.prototype.job = true;
Person.prototype.age = 23;

var kim  = new Person();
var park = new Person():

console.log(kim.age); // =&gt; 23
...</code></pre>
<p><strong>Person.prototype이라는 빈 Object가 어딘가에 존재</strong>하고, <strong>Person 함수로부터 생성된 객체들은</strong>(kim, park) 어딘가에 존재하는 Object에 들어있는 <strong>값을 모두 갖다쓸 수 있다.</strong></p>
<p>즉 kim, park이 <strong>같은 공간을 공유</strong>하는 개념이다.</p>
<hr>
<p>자바스크립트에는 Prototype Link 와 Prototype Object가 존재하고 이 둘을 통틀어 Prototype이라고 부른다.</p>
<h2 id="📌-prototype-object">📌 Prototype Object</h2>
<p>객체는 언제나 &#39;함수&#39;로 생성된다.</p>
<pre><code class="language-javascript">function Person() {} // =&gt; 함수
var personObject = new Person(); // =&gt; 함수로 객체를 생성</code></pre>
<p>일반적인 객체 생성도 마찬가지다</p>
<pre><code class="language-javascript">var obj = {};
</code></pre>
<p>위의 객체 생성 역시 아래의 방법으로 생성된다. Object 함수는 자바스크립트에서 기본으로 제공된다.</p>
<pre><code class="language-javascript">var obj = new Object();</code></pre>
<p>Object와 마찬가지로 Function, Array도 모두 함수로 정의되어 있다. 그런데 이게 Prototype Object와 무슨 관련이 있을까?</p>
<h3 id="-생성자-자격-constructor-부여"># 생성자 자격 (constructor) 부여</h3>
<ul>
<li><p>함수가 정의될 때 2가지 일이 동시에 일어나는데 그 중 하나가 생성자 자격이다. </p>
</li>
<li><p>생성자 자격이 부여되면 new를 통해 객체를 만들 수 있게 된다.
(함수만이 new 키워드 사용가능한 이유!)</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/5e5211e1-fdc8-4d0c-a1be-2c15afdbec21/image.png" alt=""></p>
<pre><code>obj 는 Object(생성자) 함수로 만들어진 객체일 뿐
함수가 아니기 때문에 new 키워드로 객체를 만들 수 없음</code></pre><h3 id="-해당함수의-prototype-object-생성-및-연결"># 해당함수의 Prototype Object 생성 및 연결</h3>
<p><del>드디어 Prototype Object가 등장했다</del>&#39;
<img src="https://velog.velcdn.com/images/purin_no_corin/post/19e9bf18-4ca4-4f58-b520-10a78d79de0c/image.png" alt=""></p>
<ul>
<li><p>생성자 자격 부여와 동시에 Prototype Object가 생성되고 </p>
</li>
<li><p>각각 prototype과 constructor으로 서로에게 접근 할 수 있다.</p>
</li>
<li><p>이때 생성된 Prototype 객체는 일반 객체와 같다</p>
</li>
</ul>
<hr>
<p>위에서의 예시를 다시 살펴보자</p>
<pre><code class="language-javascript">function Person() {} 

Person.prototype.job = true;
Person.prototype.age = 23;

var kim  = new Person();
var park = new Person():

console.log(kim.age); // =&gt; 23
...</code></pre>
<p>Prototype Object는 일반적인 객체이므로 속성을 마음대로 추가/삭제 할 수 있다. kim과 park은 Person 함수를 통해 생성되었으니 Person.prototype을 참조할 수 있게 된다.</p>
<p><strong>🚨 그런데 어떻게 참조할 수 있는걸까?</strong>
(나의 속마음: 아무리 kim,park이 Person함수로 생성됐다지만
kim.Person.prototype.age 가 아니라 kim.age 로 값을 바로 불러 올 수 있을까?)</p>
<hr>
<h2 id="📌-prototype-link">📌 Prototype Link</h2>
<ul>
<li><p>Person 함수가 가진 prototype 속성은 함수만 가질 수 있다면 
Person Prototype Object가 가진 __proto__는 모든 객체가 가진 속성이다.</p>
</li>
<li><p>__proto__는 객체가 생성될 때 조상이었던 함수의 Prototype Object를 가리킨다. (예시에선 Person Prototype Object을 가리킴)</p>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/8052b87a-457a-40a1-9726-5a283ce3864e/image.png" alt=""></p>
<ul>
<li><p>이때 kim객체는 eyes를 직접 가지고 있지 않기 때문에 eyes 속성을 찾을 때 까지 상위 프로토타입을 탐색한다. </p>
</li>
<li><p>이렇게 __proto__속성을 통해 상위 프로토타입과 연결되어있는 형태를 프로토타입 체인(Chain)이라고 한다.</p>
</li>
<li><p>최상위인 Object의 Prototype Object까지 도달했는데도 못찾았을 경우 undefined를 리턴한다. </p>
</li>
</ul>
<p>이런 프로토타입 체인 구조 때문에 모든 객체는 Object의 자식이라고 불리고, Object Prototype Object에 있는 모든 속성을 사용할 수 있다.</p>
<hr>
<h2 id="📌-프로토타입-확장">📌 프로토타입 확장</h2>
<h3 id="1-객체-속성-메서드-정의">1. 객체 속성, 메서드 정의</h3>
<pre><code class="language-javascript">function Animal (name, sound){
    this.name = name;
    this.sound = sound;
}

Animal.prototype.getInfo = function(){
    return this.name + &#39;가(이)&#39; + this.sound + &#39; 소리를 냅니다.&#39;;
}</code></pre>
<h3 id="2-생성자-함수-생성">2. 생성자 함수 생성</h3>
<pre><code class="language-javascript">function Friends(name, sound){
    Animal.call(this, name, sound);
}</code></pre>
<p>이때 call() 함수의 첫번째 매개변수는 <strong>다른 곳에서 정의된 함수</strong>를 현<strong>재 컨텍스트에서 실행</strong>할 수 있도록 한다.</p>
<ul>
<li>즉 이미 생성된 Animal 함수를 현재 Friends 함수의 컨텍스트에서 실행할 수 있다.</li>
</ul>
<h3 id="3-문제-발생">3. 문제 발생</h3>
<pre><code class="language-javascript">const dog = new Friends(&#39;개&#39;, &#39;멍멍&#39;);
const cat = new Friends(&#39;고양이&#39;, &#39;냥&#39;);

console.log(dog.getInfo()); // getInfo() is not a function
console.log(cat.getInfo()); // getInfo() is not a function</code></pre>
<p>그런데 왜 getInfo 메서드를 사용할 수 없을까?</p>
<pre><code class="language-javascript">const isEmptyFriends = Object.getOwnPropertyNames(Friends.prototype);
const isEmptyAnimal = Object.getOwnPropertyNames(Animal.prototype);

console.log(isEmptyFriends); // [ &#39;constructor&#39; ]
console.log(isEmptyAnimal); // [ &#39;constructor&#39;, &#39;getInfo&#39; ]</code></pre>
<p>확인 결과 Friends의 프로토타입 객체는 기본 constructor 속성 말고는
Animal 프로토타입 객체의 <strong>메서드를 상속 받지 못한 것</strong> 을 볼 수 있다.
(constructor 속성 덕분에 <strong>기본 Animal 속성은 접근 가능</strong>)</p>
<h3 id="4-문제-해결">4. 문제 해결</h3>
<p>1 ) Object.create로  Animal의 프로토타입 객체를 Friends의 프로토타입 객체로 설정한다.</p>
<pre><code class="language-javascript">Friends.prototype = Object.create(Animal.prototype);

console.log(Friends.prototype.constructor); // Animal</code></pre>
<p>2 ) 생성자 속성을 Friends로 바꾸기</p>
<pre><code class="language-javascript">Friends.prototype.constructor = Friends;</code></pre>
<ul>
<li>프로토타입을 Animal.prototype으로 설정 했기 때문에 기본 constructor 속성값이 Animal이다. </li>
<li>이 값을 Friends로 바꿔주면 Animal 메서드까지 완벽하게 상속 받게 된다.</li>
</ul>
<h3 id="6-완성">6. 완성</h3>
<pre><code class="language-javascript">function Animal (name, sound){
    this.name = name;
    this.sound = sound;
}

Animal.prototype.getInfo = function(){
    return this.name + &#39;가(이)&#39; + this.sound + &#39; 소리를 냅니다.&#39;;
}

function Friends(name, sound){
    Animal.call(this, name, sound);
}

Friends.prototype = Object.create(Animal.prototype);

Friends.prototype.constructor = Friends;

const dog = new Friends(&#39;개&#39;, &#39;멍멍&#39;);
const cat = new Friends(&#39;고양이&#39;, &#39;냥&#39;);

console.log(dog.getInfo()); // 개가(이)멍멍 소리를 냅니다.
console.log(cat.getInfo()); // 고양이가(이)냥 소리를 냅니다.</code></pre>
<blockquote>
<p>출처
<a href="https://medium.com/@bluesh55/javascript-prototype-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-f8e67c286b67">오승환 - [Javascript ] 프로토타입 이해하기 👀 (클릭!)</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 선형 자료구조 ] 배열 - 달팽이 만들기 ✅ (문풀)]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%B0%B0%EC%97%B4-%EB%8B%AC%ED%8C%BD%EC%9D%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0-%EB%AC%B8%ED%92%80</link>
            <guid>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%B0%B0%EC%97%B4-%EB%8B%AC%ED%8C%BD%EC%9D%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0-%EB%AC%B8%ED%92%80</guid>
            <pubDate>Mon, 19 Sep 2022 07:40:15 GMT</pubDate>
            <description><![CDATA[<p><del>이중 배열은 일차원 배열과 너무 달라서 생각을 전환하는 데 아주 오랜 시간이 걸린 것 같다...</del></p>
<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/004045ea-1139-43a7-8816-03d3e4fa7e52/image.jpeg" alt=""></p>
<h2 id="-문제-해석--해결책"># 문제 해석 &amp; 해결책</h2>
<pre><code>+ 첫줄을 그릴때만 정사각형의 한 변의 크기만큼 그린다.
+ 방향을 바꾸면서 길이는 -1씩 작아지고 2번씩 그린 후 방향을 바꾼다.

+ arr[y][x] 각 인덱스는 x축, y축으로 생각한다.
+ 값을 더해주면서 방향을 바꾸는 변수 선언.</code></pre><hr>
<pre><code class="language-javascript">// 달팽이 만들기
function answer(length) {
    let result = []

    // 이중 배열 만들기
    for(let i = 0; i &lt; length; i++){
        result[i] = [];
    }

      let x, y, direction, num;
     direction = 1;
      x = y = num = 0;
      x--; // x의 인덱스 0부터 시작하니까

      while(1){
        for(let i = 0; i &lt; length; i++){
             x += direction
            result[y][x] = ++num; // 1씩 누적
        }

          length--; // 길이 줄이기, x축 -&gt; y축으로 바뀜

          if(length == 0) break;

          for(let i = 0; i &lt; length; i++){
              y += direction;
            result[y][x] = ++num;
        }

        direction *= -1; // 방향 바꾸기
    }

    return result;
  }

  /* main code */
  let input = [
    // TC: 1
    3,

    // TC: 2
    5,

    // TC: 3
    6,
  ];

  for (let i = 0; i &lt; input.length; i++) {
    process.stdout.write(`#${i + 1} `);
    console.log(answer(input[i]));
  }
</code></pre>
<hr>
<pre><code class="language-javascript">direction *= -1; // 방향 바꾸기</code></pre>
<p>여기서 방향은 x,y축이 아니라 배열에서 증가 혹은 감소하면서 그리는 방향을 의미한다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 선형 자료구조 ] 배열 - 숫자 빈도수 구하기 ✅ (문풀)]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%B0%B0%EC%97%B4-%EC%88%AB%EC%9E%90-%EB%B9%88%EB%8F%84%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0-%EB%AC%B8%ED%92%80</link>
            <guid>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%B0%B0%EC%97%B4-%EC%88%AB%EC%9E%90-%EB%B9%88%EB%8F%84%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0-%EB%AC%B8%ED%92%80</guid>
            <pubDate>Mon, 19 Sep 2022 05:07:37 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/d88a97fd-5b3e-45b2-ba70-f1b0ef7cddba/image.jpeg" alt=""></p>
<h2 id="-문제-해석"># 문제 해석</h2>
<pre><code>인자로 들어온 숫자 예) 1245

각 자릿수 별 숫자 빈도수 -
&gt; 0: 0개, 1: 1개, 2: 1개, 3: 0개, 4: 1개, 5: 1개 ... 9: 0개 

위처럼 자리별 숫자의 빈도수를 배열로 반환하는데 없는 수도 포함해야 한다.

&gt; 1245 결과 : [0, 1, 1, 0, 1, 1, 0, 0, 0, 0]가 된다.</code></pre><h2 id="-해결책"># 해결책</h2>
<pre><code>+ 각 자리수에 있는 수를 알아내기

+ 인덱스와 해당 인덱스가 의미하는 값이 일치 [0, 1, 2 ...] 하니까
인덱스를 이용해서 바로 배열에 저장 가능</code></pre><hr>
<pre><code class="language-javascript">//숫자 빈도수 구하기
function answer(s, e) {
    let result = [];

      for(let i = 0; i &lt; 10; i++){
        result[i] = 0;
    }

      let num;
      for( let i = s; i &lt;= e; i++){
        num = i; // num = 129

        while(num != 0){
            result[num % 10]++; // 129 % 10 == 9, result[9] = 1
              num /= 10; // s = 12.9
              num = parseInt(s) // s = 12 
        }
    }

   return result;
}

/* main code */
let input = [
    // TC: 1
    [129, 137],

    // TC: 2
    [1412, 1918],

    // TC: 3
    [4159, 9182],
];

for (let i = 0; i &lt; input.length; i++) {
    process.stdout.write(`#${i + 1} `);
    console.log(answer(input[i][0], input[i][1]));
}</code></pre>
<h3 id="-중요-부분-해설"># 중요 부분 해설</h3>
<pre><code class="language-javascript">// 0 ~ 9 까지의 값(빈도수)을 0으로 우선 초기화 -&gt; 업데이트 용이
for(let i = 0; i &lt; 10; i++){
    result[i] = 0;
}

// 자릿수를 인덱스에 이용 
let num;
for( let i = s; i &lt;= e; i++){
    num = i;
    while( num != 0){
        result[s%10]++; //일의자리를 나머지로 얻어서 값 업데이트
          s /= 10; // 일의자리를 소수로 만듦
        s = parseInt(s) // 정수로 만드는 함수로 소수 자름, 십의 자리 -&gt; 일의자리
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 선형 자료구조 ] 배열 - 벽돌 옮기기 ✅ (문풀)]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%B0%B0%EC%97%B4-%EB%B2%BD%EB%8F%8C-%EC%98%AE%EA%B8%B0%EA%B8%B0-%EB%AC%B8%ED%92%80</link>
            <guid>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%B0%B0%EC%97%B4-%EB%B2%BD%EB%8F%8C-%EC%98%AE%EA%B8%B0%EA%B8%B0-%EB%AC%B8%ED%92%80</guid>
            <pubDate>Mon, 19 Sep 2022 04:36:15 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/374e7bb3-26b8-452e-91f3-288fbaf758dd/image.jpeg" alt=""></p>
<pre><code class="language-javascript">//벽돌 옮기기
function answer(blocks) { 
    let result = 0;

      // 옮겨야 하는 경우: 평균보다 벽돌이 넘칠 때
      let avg = 0;
      for(let i = 0; i&lt;blocks.length; i++){
        avg += blocks[i];
    }

      avg /= blocks.length;

      for(let i = 0; i &lt; blocks.length; i++){
        if(blocks[i] &gt; avg){
            result += blocks[i] - avg;
        }
    }

    return result;
  }

  /* main code */
  let input = [
    // TC: 1
    [5, 2, 4, 1, 7, 5],

    // TC: 2
    [12, 8, 10, 11, 9, 5, 8],

    // TC: 3
    [27, 14, 19, 11, 26, 25, 23, 15],
  ];

  for (let i = 0; i &lt; input.length; i++) {
    console.log(`#${i + 1} ${answer(input[i])}`);
  }
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 선형 자료구조 ] 배열 - OX 퀴즈  ✅ (문풀)]]></title>
            <link>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%B0%B0%EC%97%B4-OX-%ED%80%B4%EC%A6%88</link>
            <guid>https://velog.io/@purin_no_corin/%EC%84%A0%ED%98%95-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EB%B0%B0%EC%97%B4-OX-%ED%80%B4%EC%A6%88</guid>
            <pubDate>Mon, 19 Sep 2022 03:49:53 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/purin_no_corin/post/17fc652e-1984-488a-926b-6ffa1475b345/image.jpeg" alt=""></p>
<h2 id="-내-풀이"># 내 풀이</h2>
<pre><code class="language-javascript">// OX 퀴즈
function answer(mark) {
    let result = 0;

      // 누적되는 점수를 저장할 변수 선언
      let acc = 0;
      for(let i = 0; i &lt; mark.length; i++){
        if(mark[i] != 0){
            acc += mark[i];
        }else{
            acc = 0;
        }

           result += acc;
    }

    return result;
}

  /* main code */
  let input = [
    // TC: 1
    [1, 0, 1, 1, 1, 0, 1, 1, 0, 0],

    // TC: 2
    [1, 1, 0, 1, 1, 0, 1, 1, 1, 1],

    // TC: 3
    [1, 1, 1, 1, 1, 0, 0, 1, 1, 0],
  ];

  for (let i = 0; i &lt; input.length; i++) {
    console.log(`#${i + 1} ${answer(input[i])}`);
  }
</code></pre>
<h2 id="-강사님-풀이"># 강사님 풀이</h2>
<pre><code class="language-javascript">// OX 퀴즈
function answer(mark) {
    let result = 0;

      // 누적되는 점수를 저장할 변수 선언
      let acc = 0;
      for(let i = 0; i &lt; mark.length; i++){
        if(mark[i] != 0){
            //acc += mark[i];
            result += ++acc;
        }else{
            acc = 0;
        }
           //result += acc;
    }

    return result;
}

  /* main code */
  let input = [
    // TC: 1
    [1, 0, 1, 1, 1, 0, 1, 1, 0, 0],

    // TC: 2
    [1, 1, 0, 1, 1, 0, 1, 1, 1, 1],

    // TC: 3
    [1, 1, 1, 1, 1, 0, 0, 1, 1, 0],
  ];

  for (let i = 0; i &lt; input.length; i++) {
    console.log(`#${i + 1} ${answer(input[i])}`);
  }
</code></pre>
<h2 id="-차이점"># 차이점</h2>
<pre><code class="language-javascript">for(let i = 0; i &lt; mark.length; i++){
    if(mark[i] != 0){
        //acc += mark[i]; 
        result += ++acc;
    }else{
        acc = 0;
    }

      //result += acc;
}</code></pre>
<h3 id="-다양한-연산자를-사용--단항-연산자"># 다양한 연산자를 사용 : 단항 연산자</h3>
<ul>
<li>mark[i]값을 누적하는 대신 ++acc로 1 미리 더한 후 result 값에 할당했다.</li>
<li>value++ 와 ++value의 차이는 크기 때문에 점수를 부여받고 누적하는 경우엔 value++가 적합</li>
<li>루프를 돌면서 인덱스를 1씩 업데이트 하는 경우 ++value가 적합</li>
</ul>
]]></description>
        </item>
    </channel>
</rss>