<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>sangmin-iam.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sat, 23 Apr 2022 08:32:14 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>sangmin-iam.log</title>
            <url>https://images.velog.io/images/sangmin-iam/profile/7893841c-6cec-4f54-9089-1b8da2c4c0ad/본다이비치.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. sangmin-iam.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/sangmin-iam" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[2022]]></title>
            <link>https://velog.io/@sangmin-iam/2022</link>
            <guid>https://velog.io/@sangmin-iam/2022</guid>
            <pubDate>Sat, 23 Apr 2022 08:32:14 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>2022년 블로그를 작성하면서 공부하고 싶은 것들 (온라인강의, 책 등)</p>
</blockquote>
<ol>
<li>자바스크립트 &amp; 브라우저<ul>
<li><input disabled="" type="checkbox"> <a href="https://academy.dream-coding.com/courses/browser101">드림코딩 브라우저101</a></li>
</ul>
</li>
<li>리액트<ul>
<li><input disabled="" type="checkbox"> <a href="https://academy.dream-coding.com/courses/react-basic">드림코딩 엘리 리액트</a></li>
<li><input disabled="" type="checkbox"> <a href="https://academy.dream-coding.com/courses/react-tdd">드림코딩 엘리 TDD와 리액트</a></li>
</ul>
</li>
<li>타입스크립트<ul>
<li><input disabled="" type="checkbox"> <a href="https://academy.dream-coding.com/courses/typescript">드림코딩 엘리 타입스크립트</a></li>
</ul>
</li>
<li>HTML/CSS<ul>
<li><input disabled="" type="checkbox"> <a href="https://edu.goorm.io/lecture/20583/%EA%B9%80%EB%B2%84%EA%B7%B8%EC%9D%98-html-css%EB%8A%94-%EC%9E%AC%EB%B0%8C%EB%8B%A4">김버그의 HTML&amp;CSS는 재밌다</a></li>
<li><input disabled="" type="checkbox"> <a href="https://edu.goorm.io/lecture/25681/%EA%B9%80%EB%B2%84%EA%B7%B8%EC%9D%98-ui-%EA%B0%9C%EB%B0%9C-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%EA%B2%BD%EB%A0%A5%EA%B0%99%EC%9D%80-%EC%8B%A0%EC%9E%85%EC%9C%BC%EB%A1%9C-%EB%A0%88%EB%B2%A8%EC%97%85">김버그의 UI 개발 부트캠프 - 경력같은 신입으로 레벨업</a></li>
</ul>
</li>
<li>CS50<ul>
<li><input disabled="" type="checkbox"> <a href="https://cs50.harvard.edu/college/2022/spring/">CS50 - Free course</a></li>
</ul>
</li>
</ol>
<p>리액트 네이티브 개발자로서 현재 일을 하고 있어서 우선 순위가 밀려났다. 위 코스들은 나중에 듣도록 하자.</p>
<ol>
<li>도서<ul>
<li><input disabled="" type="checkbox"> 리팩토링 2판</li>
</ul>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[프레임워크와 라이브러리]]></title>
            <link>https://velog.io/@sangmin-iam/%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EC%99%80-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</link>
            <guid>https://velog.io/@sangmin-iam/%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC%EC%99%80-%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC</guid>
            <pubDate>Sun, 17 Apr 2022 12:24:55 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>프레임워크와 라이브러리의 차이를 대략적으로만 알고 있지만 정리를 다시 하기 위하여 다루어 보려고 합니다.</p>
</blockquote>
<h2 id="📌-프레임워크-framework">📌 프레임워크 (Framework)</h2>
<blockquote>
<p>✔️ <strong>소프트웨어의 특정 문제를 해결하기 위해서 상호 협력하는 클래스와 인터페이스의 집합</strong></p>
</blockquote>
<ul>
<li>프레임워크는 뼈대나 기반구조를 뜻하는데, 앱 개발 시 필수적인 코드, 알고리즘, 데이터베이스 연동 등과 같은 기능들을 위해 어느정도 뼈대(구조)를 제공해준다.</li>
<li>그러므로 뼈대 위에 프로그래머가 코드를 작성하여 Applicatioln을 완성시켜야 한다.</li>
<li>뼈대를 제공해 주기 때문에 객체 지향 개발을 하면서 일관성 부족 등의 문제를 해결해준다.</li>
</ul>
<h2 id="📌-라이브러리-library">📌 라이브러리 (Library)</h2>
<blockquote>
<p>✔️ <strong>단순 활용이 가능한 도구들의 집합</strong></p>
</blockquote>
<ul>
<li>라이브러리는 특정 기능에 대한 도구 혹은 함수들을 모은 집합이다. 즉, 프로그래머가 개발하는데 필요한 것들을 모아둔 것을 말한다.</li>
</ul>
<h2 id="📌-제어의-역전-inversion-of-control">📌 제어의 역전 (Inversion of Control)</h2>
<blockquote>
<p>✔️ <strong>제어의 역전</strong>이란 어떠한 일을 하도록 만들어진 <strong>프레임워크에 제어의 권한을 넘김으로써 클라이언트 코드가 신경써야 할 것들을 줄이는 전략</strong>이다.</p>
</blockquote>
<ul>
<li><strong>프레임워크와 라이브러리의 차이</strong>는 <strong>Flow(흐름)에 대한 제어 권한이 어디에 있느냐의 차이</strong>이다.</li>
<li><strong>프레임워크</strong>는 <strong>전체적인 흐름을 자체적으로 가지고 있으며 프로그래머가 그 안에 필요한 코드를 작성</strong>한다.</li>
<li><strong>라이브러리</strong>는 <strong>사용자가 흐름에 대한 제어를 하며 필요한 상황에 가져다 쓴다.</strong></li>
<li>즉, 프레임워크에는 제어의 역전(IoC)이 적용되어있다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/4fd993f2-c7e1-40dc-b8b6-8c2b0ab35032/image.png" alt=""></p>
<ul>
<li>위 그림을 해석해보면, 사용자가 라이브러리를 호출하여 사용하므로 사용자가 제어의 권한을 가지고있다는 것을 의미한다.</li>
<li>반면, 프레임워크는 사용자가 작성한 코드를 호출하므로 제어의 권한이 프레임워크에 있다는 것을 의미한다. 이를 제어의 역전이 일어났다고 말한다.</li>
</ul>
<h2 id="reference">Reference</h2>
<ul>
<li><p><a href="https://m.blog.naver.com/dktmrorl/222121510562">https://m.blog.naver.com/dktmrorl/222121510562</a></p>
</li>
<li><p><a href="https://www.zehye.kr/etc/2020/05/21/etc_framework_library/">https://www.zehye.kr/etc/2020/05/21/etc_framework_library/</a></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[양방향 단방향 데이터 바인딩]]></title>
            <link>https://velog.io/@sangmin-iam/%EC%96%91%EB%B0%A9%ED%96%A5-%EB%8B%A8%EB%B0%A9%ED%96%A5-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B0%94%EC%9D%B8%EB%94%A9</link>
            <guid>https://velog.io/@sangmin-iam/%EC%96%91%EB%B0%A9%ED%96%A5-%EB%8B%A8%EB%B0%A9%ED%96%A5-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B0%94%EC%9D%B8%EB%94%A9</guid>
            <pubDate>Sun, 17 Apr 2022 11:55:20 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>리액트를 학습 하면서 리액트는 단방향 데이터 흐름이라는 것을 알게되었고, 양방향과 단방향의 차이가 무엇인지 알아보기 위해서 정리를 하게 되었습니다. 개선 사항이 있다면 피드백 주시면 감사드리겠습니다 :)</p>
</blockquote>
<h1 id="🌐-데이터-바인딩이란">🌐 데이터 바인딩이란?</h1>
<blockquote>
<p>✔️ 두 데이터 혹은 정보의 소스를 일치시키는 기법으로, <strong>화면에 보이는 데이터와 브라우저 메모리에 있는 데이터(자바스크립트 객체들)를 일치시키는 것</strong>을 말합니다.</p>
</blockquote>
<ul>
<li>예를 들어, MVC 모델에서 Model과 View를 묶어서 &quot;자동 동기화 시키기&quot; 라고 이해할 수 있습니다.</li>
</ul>
<h2 id="📌-양방향-데이터-바인딩">📌 양방향 데이터 바인딩</h2>
<blockquote>
<p>✔️ 양방향 데이터 바인딩은 <strong>사용자 UI의 데이터 변경을 감시하는 Watcher와 자바스크립트 데이터의 변경을 감시하는 Watcher가 UI와 자바스크립트 데이터를 자동으로 동기화 시켜주는 방식</strong>을 말합니다.</p>
</blockquote>
<ul>
<li>HTML -&gt; JS</li>
<li>JS -&gt; HTML </li>
<li>양방향 데이터 바인딩을 사용하는 대표적인 프레임워크는 <strong>Vue</strong>와 <strong>Angular</strong>가 있다. (단방향은 같게 하기위한 추가적인 코드가 필요)</li>
</ul>
<h3 id="👉-장점">👉 장점</h3>
<ul>
<li>코드 사용면에서 <strong>코드량을 크게 줄여준다.</strong></li>
</ul>
<h3 id="👉-단점">👉 단점</h3>
<ul>
<li>하나에 데이터 동기화의 두 개의 Watcher가 사용되고, <strong>데이터가 많아지게 되면 이 데이터의 동기화를 위한 수 많은 Watcher가 생성되므로, 성능 저하가 발생할 수 있다.</strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/ae545ac8-de30-4bc2-8313-8356fc8ddf2d/image.png" alt=""></p>
<h2 id="📌-단방향-데이터-바인딩">📌 단방향 데이터 바인딩</h2>
<blockquote>
<p>✔️ 단방향 데이터 바인딩은 <strong>단 하나의 Watcher가 자바스크립트의 데이터 갱신을 감지하여 사용자의 UI 데이터를 갱신</strong>한다.
✔️ 사용자가 UI를 통해 자바스크립트의 데이터를 갱신할 때는, <strong>이벤트를 통해 갱신</strong>하게 된다.</p>
</blockquote>
<ul>
<li>JS -&gt; HTML</li>
<li>단방향 데이터 바인딩을 사용하는 대표적인 라이브러리에는 <strong>React</strong>가 있다.</li>
</ul>
<h3 id="👉-장점-1">👉 장점</h3>
<ul>
<li><strong>하나의 Watcher를 사용</strong>하기 때문에 <strong>양방향 데이터 바인딩이 가지는 성능적인 이슈를 해결</strong>할 수 있다.</li>
<li>데이터가 <strong>한 방향으로 흐르기 때문에 코드 이해와 데이터 추적과 디버깅</strong>이 쉽다.</li>
</ul>
<h3 id="👉-단점-1">👉 단점</h3>
<ul>
<li><p>변화를 감지하고 <strong>화면을 업데이트하는 코드를 매 번 작성</strong>해야 한다.</p>
<ul>
<li>예를 들어, 리액트에서 Input을 변경할 때 onChange 이벤트를 감지하여 상태를 변경시킨다. 그리고, Watcher가 이 상태를 감지하여 UI를 업데이트를 하게 된다. 이 방식이 바로 단방향 데이터 바인딩이라고 볼 수 있다.</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/08f40130-7453-4f46-82de-9c685cb7a665/image.png" alt=""></p>
<h1 id="🌐-reference">🌐 Reference</h1>
<ul>
<li><a href="https://dev-yakuza.posstree.com/ko/react/create-react-app/react/">https://dev-yakuza.posstree.com/ko/react/create-react-app/react/</a></li>
<li><a href="https://velog.io/@sunaaank/data-binding">https://velog.io/@sunaaank/data-binding</a></li>
<li><a href="https://sihus.tistory.com/37">https://sihus.tistory.com/37</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[콜백 함수 (Callback)]]></title>
            <link>https://velog.io/@sangmin-iam/%EC%BD%9C%EB%B0%B1-%ED%95%A8%EC%88%98-Callback</link>
            <guid>https://velog.io/@sangmin-iam/%EC%BD%9C%EB%B0%B1-%ED%95%A8%EC%88%98-Callback</guid>
            <pubDate>Wed, 13 Apr 2022 07:12:19 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이전에 학습한 내용을 <strong>복기</strong>하고자 이 글을 작성합니다. 개선해야 할 점들을 댓글로 남겨주시면 감사드리겠습니다.</p>
</blockquote>
<h1 id="🌐-콜백-함수란">🌐 콜백 함수란?</h1>
<blockquote>
<p>✔️ 콜백 함수는 <strong>다른 코드(함수 또는 메소드)의 인자로 넘겨주는 함수</strong>를 말한다
✔️ 매개변수를 넘겨 받은 함수는 <strong>callback 함수를 필요에 따라 즉시 실행(synchronously)</strong>할 수도 있고, 아니면 <strong>나중에 (asynchronously)실행</strong>할 수도 있다.</p>
</blockquote>
<ul>
<li>다른 코드에게 인자로 넘겨줌으로써 그 제어권도 함께 위임한 함수이다.</li>
<li>콜백 함수를 위임받은 코드는 자체적인 내부 로직에 의해 이 콜백 함수를 적절한 시점에 실행한다.</li>
</ul>
<h2 id="📌-동기-콜백-호출-vs-비동기-콜백-호출">📌 동기 콜백 호출 vs 비동기 콜백 호출</h2>
<pre><code class="language-js">// 동기적으로 3초 마다 배열안에 있는 수가 출력된다. (블로킹)
[1, 2, 3].forEach((num) =&gt; {
  // 콘솔 한 번에 매 3초가 걸린다.
  // 이 함수의 콜백 함수는 동기적으로 호출된다.
  callbackFn(() =&gt; console.log(num), 3000);
});

function callbackFn(callback) {
   const start = Date.now();
   let let = start;

   while ( now - start &lt; 3000 ) {
      now = Date.now(); 
   }

    callback();
}

cosnole.log(&quot;ended&quot;);

// 콘솔 출력까지 총 수행 시간 3 * 3 = 9초
// 의도적으로 타이머의 기능이 필요하다면 동기적 콜백 호출이 필요할 수도 있다.</code></pre>
<pre><code class="language-js">// 비동기적으로 3초 이후 배열의 수가 출력된다. (논 블로킹)
[1, 2, 3].forEach((num) =&gt; {
    // 자바스크립트 런타임에 존재하는 Web API에 setTiemout 함수를 사용함으로써 3초 이후 콘솔이 모두 출력된다.
      // 이 함수의 콜백 함수는 비동기적으로 호출이 된다.
  setTimeout(() =&gt; console.log(num), 3000);
});

console.log(&quot;ended&quot;);

// 콘솔 출력까지 총 수행 시간은 3초
// 블로킹을 해결하고, 속도 개선을 위해선 비동기적 콜백 호출을 이용한다.</code></pre>
<ul>
<li>여기서, 짚고 넘어가야할 것은 콜백 함수라고 해서 모두 비동기 함수가 아니라는 것이다. </li>
<li>콜백 함수의 개념은 다른 코드의 인자로 함수를 넘겨주는 것을 의미한다는 것을 명심하자.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/ee132bdf-4adc-41b8-a339-c1fc3e855a8f/image.png" alt=""></p>
<h2 id="📌-비동기-주요-사례">📌 비동기 주요 사례</h2>
<ul>
<li>사용자의 요청에 의해 특정 시간이 경과되기 전까지 어떤 함수의 실행을 보류한다거나, 사용자의 직접적인 개입이 있을 때 비로소 어떤 함수를 실행하도록 대기한다거나, 웹브라우저 자체가 아닌 별도의 대상에 무언가를 요청하고 그에 대한 응답이 왔을 때 비로소 어떤 함수를 실행하도록 대기하는 등, <strong>별도의 요청, 실행 대기, 보류 등과 관련된 코드는 비동기적인 코드입니다.</strong></li>
</ul>
<h3 id="👉-dom-요소의-이벤트-핸들러">👉 DOM 요소의 이벤트 핸들러</h3>
<ul>
<li>마우스, 키보드 이벤트 (click, keydown 둥)</li>
<li>페이지 로딩 (DOMContentLoaded 등)</li>
</ul>
<h3 id="👉-타이머">👉 타이머</h3>
<ul>
<li>setTimeout, setInterval 등</li>
<li>애니메이션 API (requestAnimationFrame)</li>
</ul>
<h3 id="👉-서버에-자원-요청">👉 서버에 자원 요청</h3>
<ul>
<li>fetch API</li>
<li>AJAX</li>
</ul>
<h1 id="🌐-콜백-지옥과-비동기-제어">🌐 콜백 지옥과 비동기 제어</h1>
<blockquote>
<p>✔️ 콜백 지옥은 콜백 함수를 익명 함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 감당하기 힘들 정도로 깊어지는 현상이다.</p>
</blockquote>
<ul>
<li>주로 이벤트 처리나 서버 통신과 같이 비동기적인 작업을 수행하기 위해 이런 형태가 자주 등장하곤 하는데, 가독성이 떨어질뿐더러 코드를 수정하기도 어렵다.</li>
</ul>
<h2 id="📌-1-1-콜백-지옥-예시">📌 (1-1) 콜백 지옥 예시</h2>
<pre><code class="language-js">setTimeout(function (name) {
    let coffeeList = name;
    console.log(coffeeList);

     setTimeout(function (name) {
      coffeeList += &quot;, &quot; + name;
      console.log(coffeeList);

        setTimeout(function (name) {
          coffeeList += &quot;, &quot; + name;
          console.log(coffeeList);

        }, 500, &quot;아메리카노&quot;);
    }, 500, &quot;카페라떼&quot;);
}, 500, &quot;카페모카&quot;);</code></pre>
<ul>
<li>위 예제는 0.5초마다 커피 목록을 수집하고 출력한다. 기능에는 지장이 없지만 들여쓰기 수준도 과도하게 깊어지고 전달되는 매개변수의 순서도 아래에서 위로 향하고 있어 어색하게 느껴진다.</li>
<li>이를 해결하는 방법은 여러가지가 있다. 우선은 Promise, async/await을 사용하지 않은 방법을 우선 한 번 살펴보자.</li>
</ul>
<h2 id="📌-1-2-콜백-지옥-해결---기명함수로-전환">📌 (1-2) 콜백 지옥 해결 - 기명함수로 전환</h2>
<pre><code class="language-js">let coffeeList = &quot;&quot;;

const addMocha = function (name) {
    coffeeList = name;
    console.log(coffeeList);
      setTimeout(addLatte, 500, &quot;카페라떼&quot;);
}

const addLatte = function (name) {
    coffeeList = name;
    console.log(coffeeList);
    setTimeout(addAmericano, 500, &quot;아메리카노&quot;);
}

const addAmericano = function (name) {
    coffeeList = name;
    console.log(coffeeList);
}

setTimeout(addMocha, 500, &quot;카페모카&quot;);</code></pre>
<ul>
<li><p>위와 같은 방식은 가독성을 높일뿐 아니라 함수 선언과 함수 호출만 구분할 수 있다면 위에서 아래로 순서대로 읽어내려가는 데 어려움이 없다.</p>
</li>
<li><p>변수가 외부에 노출되기는 했지만 즉시 실행 함수로 감싸면 간단히 해결이 가능하다.</p>
</li>
<li><p>자바스크립트는 비동기적인 방법은 동기적으로 보이게끔 처리해주는 노력을 꾸준히 해왔다. 위 방법은 하나의 역사로 참고해주면 좋다.</p>
</li>
<li><p>최근에는, ES6에서 도입된 Promise, Generator와 ES2017에서 도입된 async/await이 가장 많이 사용된다.</p>
</li>
</ul>
<h2 id="📌-2-1-비동기-작업의-동기적-표현-promise">📌 (2-1) 비동기 작업의 동기적 표현 Promise</h2>
<pre><code class="language-js">new Promise((resolve) =&gt; {
     setTiemout(() =&gt; {
         const name = &quot;카페모카&quot;;
          console.log(name);
          resolve(name);
    }, 500);
}).then((result) =&gt; {
     return new Promise((resolve) =&gt; {
         const name = result + &quot;, 카페라떼&quot;;
          console.log(name);
          resolve(name);
    });
}).then((result) =&gt; {
       return new Promise((resolve) =&gt; {
         const name = result + &quot;, 아메리카노&quot;;
          console.log(name);
          resolve(name);
    });
});</code></pre>
<ul>
<li><p>new 연산자와 함께 호출한 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a>의 인자로 넘겨주는 콜백 함수는 호출할 때 바로 실행되지만, 그 내부에 resolve 또는 reject 함수를 호출하는 구문이 있을 경우 둘 중하나가 실행되기 전까지는 then(resolve 되었을 때) 또는 catch(reject 되었을 때) 구문으로 넘어가지 않는다.</p>
</li>
<li><p>따라서, 비동기 작업이 완료될 때 resolve 또는 reject를 호출하는 방법으로 비동기 작업의 동기적 표현이 가능하다.</p>
</li>
</ul>
<h2 id="📌-2-2-비동기-작업의-동기적-표현-promise">📌 (2-2) 비동기 작업의 동기적 표현 Promise</h2>
<pre><code class="language-js">const addCoffee = function (name) {
    return function (prevName) {
         return new Promise((resolve) =&gt; {
            setTimeout(() =&gt; {
              const newName = prevName ? (prevName + &quot;, &quot; + name) : name;
              console.log(newName);
              resolve(newName);
            }, 500) 
        }) ;
    }
}

addCoffee(&quot;카페모카&quot;)()
    .then(addCoffee(&quot;카페라떼&quot;))
    .then(addCoffee(&quot;아메리카노&quot;))</code></pre>
<ul>
<li><p>위 방법은 반복적인 내용을 함수화 해서 더욱 짧게 표현한 것이다.</p>
</li>
<li><p>2번째, 3번째줄은 클로저가 형성 되어있다.</p>
</li>
</ul>
<h2 id="📌-3-비동기-작업의-동기적-표현-generator">📌 (3) 비동기 작업의 동기적 표현 Generator</h2>
<pre><code class="language-js">const addCoffee = function (prevName, name) {
     setTimeout(() =&gt; {
        coffeeMaker.next(prevName ? `${prevName}, ${name}` : name);
    }, 500); 
};

const coffeeGenerator = function* () {
     const mocha = yield addCoffee(&quot;&quot;, &quot;카페모카&quot;);
    console.log(mocha);
      const latte = yield addCoffee(mocha, &quot;카페라떼&quot;)
    console.log(latte);
      const americano = yield addCoffee(latte, &quot;아메리카노&quot;);
  console.log(americano);
}

const coffeeMaker = coffeeGenerator();
coffeeMaker.next();</code></pre>
<ul>
<li><p>함수 뒤에 &quot;*&quot;이 붙은 함수가 바로 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator">Generator함수</a>이다.</p>
</li>
<li><p>Generator 함수를 실행하면 Iterator가 반환되는데, next라는 메소드를 가지고 있다.</p>
</li>
<li><p>next 메소드를 호출하면 Generator 함수 내부에서 가장 먼저 등장하는 yield에서 함수의 실행을 멈춘다.</p>
</li>
<li><p>이후 다시 next 메소드를 호출하면 앞서 멈췄던 부분 부터 시작해서 그 다음에 등장하는 yield에서 함수 실행을 멈춘다.</p>
</li>
<li><p>비동기 작업이 완료되는 시점마다 next 메소드를 호출하면 Gnerator 함수 내부의 소스가 위에서부터 아래로 순차적으로 진행된다.</p>
</li>
</ul>
<h2 id="📌-4-비동기-작업의-동기적-표현-promise--asyncawait">📌 (4) 비동기 작업의 동기적 표현 Promise + Async/Await</h2>
<pre><code class="language-js">const addCoffee = function (name) {
    return new Promise((resolve) =&gt; {
        setTimeout(() =&gt; {
               resolve(name);
        }, 500);
    }); 
}

const coffeeMaker = async function () {
    let coffeeList = &quot;&quot;;
      const _addCoffee = async function (name) {
        coffeeList += (coffeeList ? &quot;, &quot;: &quot;&quot;) + await addCoffee(name);
    }

    await _addCoffee(&quot;카페모카&quot;);
      console.log(coffeeList);
      await _addCoffee(&quot;카페라떼&quot;);
      console.log(coffeeList);
      await _addCoffee(&quot;아메리카노&quot;);
      console.log(coffeeList);
}

coffeeMaker();</code></pre>
<ul>
<li><p>비동기 작업을 수행하고자 하는 함수 앞에 async를 표기하고 함수 내부에서 실질적인 비동기 작업이 필요한 위치마다 await을 표기하는 것만으로 뒤의 내용을 Promise로 자동 전환하고, 해당 내용이 resolve된 이후에야 다음 다음으로 진행된다.</p>
</li>
<li><p>즉 Promise의 then과 흡사한 효과를 얻을 수 있다.</p>
</li>
</ul>
<h1 id="🌐-정리">🌐 정리</h1>
<ul>
<li><p>콜백 함수는 다른 코드에 인자로 넘겨줌으로써 그 제어권도 함께 위임한 함수이다.</p>
</li>
<li><p>제어권을 넘겨받은 코드는 다음과 같은 제어권을 가진다.</p>
<ul>
<li><p>1) 콜백 함수를 호출하는 시점을 스스로 판단해서 실행한다.</p>
</li>
<li><p>2) 콜백 함수를 호출할 때 인자로 넘겨줄 값들 및 그 순서가 정해져 있다.</p>
</li>
<li><p>3) 콜백 함수의 this가 무엇을 바라보도록 할지 정해야 하는 경우도 있다. 정해지지 않은 경우엔 전역 객체르 바라보고, 임의로 변경하고 싶다면 bind 메서드를 사용하면 된다.</p>
</li>
</ul>
</li>
<li><p>어떤 함수에 인자로 메서드를 전달하더라도 이는 결국 함수로서 실행된다.</p>
</li>
<li><p>Promise, Generator, Async/Await 등을 이용하여 콜백 지옥을 어느정도 해결할 수 있다.</p>
<h1 id="reference">Reference</h1>
</li>
<li><p><a href="https://hanamon.kr/javascript-%EC%BD%9C%EB%B0%B1-%EC%A7%80%EC%98%A5-%ED%83%88%EC%B6%9C%ED%95%98%EA%B8%B0-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC-%EB%B0%A9%EB%B2%95/">[JavaScript] 콜백 지옥 탈출하기! 비동기 처리 방법</a></p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript: 실행 컨텍스트 (Execution Context)]]></title>
            <link>https://velog.io/@sangmin-iam/%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8-Execution-Context</link>
            <guid>https://velog.io/@sangmin-iam/%EC%8B%A4%ED%96%89-%EC%BB%A8%ED%85%8D%EC%8A%A4%ED%8A%B8-Execution-Context</guid>
            <pubDate>Tue, 12 Apr 2022 08:38:17 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이전에 학습한 내용들을 <strong>복기</strong>하기 위하여 작성한 내용입니다. <strong>(업데이트: 2022년 4월 12일)</strong></p>
</blockquote>
<h1 id="🌐-실행-컨텍스트란">🌐 실행 컨텍스트란?</h1>
<blockquote>
<p>✔️ 실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체이다.</p>
</blockquote>
<ul>
<li>자바스크립트의 동적 언어로서의 성격을 가장 잘 파악할 수 있는 개념이다</li>
<li>자바스크립트는 어떤 실행 컨텍스트가 활성화되는 시점에 선언된 변수를 위로 끌어올리고(호이스팅), 외부 환경 정보를 구성하고, this 값을 설정하는 등의 동작을 수행하는데, 이로 인해 다른 언어에서는 발견할 수 없는 특이한 현상들이 발생한다.</li>
<li>실행 컨텍스트는 자바스크립트에서 가장 중요한 핵심 개념중 하나이며, 클로저를 지원하는 대부분의 언어에서 이와 유사하거나 동일한 개념이 적용되어있다.</li>
</ul>
<img src="https://velog.velcdn.com/images/sangmin-iam/post/3cfa88a4-26df-4553-8407-67b425c7ec7a/image.png" width="70%"/>

<ul>
<li>동일한 환경에 있는 코드들을 실행할 때 필요한 환경 정보들을 모아 컨텍스트를 구성하고, 이를 콜 스택(Call Stack)에 쌓아 올렸다가, 가장 위에 쌓여있는 컨텍스트와 관련있는 코드들을 실행하는 식으로 전체 코드의 환경과 순서를 보장한다.</li>
<li>여기서, &#39;동일한 환경&#39;, 즉 하나의 <strong>실행 컨텍스트를 구성할 수 있는 방법으로 1) 전역공간, 2) eval() 함수, 3) 함수 실행</strong> 등이 있습니다.
자동으로 생성되는 전역공간과, eval을 제외하면 <strong>우리가 흔히 실행 컨텍스트를 구성하는 방법은 함수를 실행하는 것뿐입니다.</strong></li>
</ul>
<h2 id="📌-예제로-살펴보기">📌 예제로 살펴보기</h2>
<pre><code class="language-javascript">// ----------------------- (1)
var a = 1;
function outer() {
    function inner() {
         console.log(a);
          var a = 3;
    }
      inner(); // ---------- (2)
      console.log(a); // 1
}
outer(); // ------------- (3)
console.log(a); // 1</code></pre>
<blockquote>
<p>✔️ 자바스크립트를 실행하는 순간 (1) 전역 컨텍스트가 콜 스택에 담긴다.
✔️ (3)에서 outer 함수를 호출하면 자바스크립트 엔진은 outer 함수에 대한 환경 정보를 수집해서 outer 실행 컨텍스트를 생성한 후 콜 스택에 담는다.
✔️ 콜스택의 <strong>맨 위에 outer 실행 컨텍스트가 놓이므로</strong> 전역 컨텍스트와 관련된 코드의 실행은 일시중단하고 대신 <strong>outer 실행 컨텍스트와 관련된 코드, 즉 outer 함수 내부의 코드들을 순차적으로 실행한다.</strong>
✔️ 다시 (2) 에서 <strong>inner 함수의 실행 컨텍스트가 콜 스택의 가장 위</strong>에 담기면 <strong>outer 컨텍스트와 관련된 코드의 실행을 중단하고 inner 함수 내부의 코드를 순서대로 진행한다.</strong>
✔️ 이렇게 inner, outer, 전역 컨텍스트가 차례대로 실행되고 종료되면서 콜스택은 아무것도 남지 않은 상태로 종료된다.</p>
</blockquote>
<ul>
<li>전역 컨텍스트라는 개념은 일반적인 실행 컨텍스트와 특별히 다를 것이 없습니다. 최상단의 공간은 코드 내부에서 별도의 실행 명령이 없어도 브라우저에서 자동으로 실행하므로 자바스크립트가 열리는 순간 전역 컨텍스트가 활성화된다고 이해하면 됩니다.</li>
<li>콜 스택의 맨 위에 쌓이는 순간이 곧 현재 실행할 코드에 관여하게 되는 시점이 됩니다.</li>
<li>이렇게 어떤 <strong>실행 컨텍스트가 활성화될 때 자바스크립트 엔진은 해당 컨텍스트에 관련된 코드들을 실행하는데 필요한 환경 정보들을 수집해서 실행 컨텍스트 객체에 저장합니다.</strong></li>
</ul>
<h1 id="🌐-활성화된-실행-컨텍스트의-수집-정보">🌐 활성화된 실행 컨텍스트의 수집 정보</h1>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/1874434f-0082-4a8a-b87b-8211e6853d5d/image.png" alt="">
사진 출처: <a href="https://velog.io/@chyoon0512/JS-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85">Velog</a> (사진에 오타가 조금 있습니다)</p>
<h2 id="📌-variable-environment">📌 Variable Environment</h2>
<blockquote>
<p>✔️ 현재 <strong>실행 컨텍스트 내의 식별자들에 대한 정보 (environmentRecord) + 외부 환경 정보 (outerEnvironmentReference)의 스냅샷(Snapshot)</strong>을 유지한다.</p>
</blockquote>
<ul>
<li><p>실행 컨텍스트를 생성할 때 Variable Environment 정보를 먼저 담은 다음, 이를 그대로 복사해서 Lexical Environment를 만들고, 이후에는 주로 Lexical Environment를 활용하게 된다.</p>
</li>
<li><p>풀어서 이야기하면, 내부 환경정보는 Environment Record에 저장하고 외부 환경 정보는 Outer Environment에 저장한다. 그리고 Lexical Environment는 Variable Environment(스냅샷)을 카피를 떠서 사용한다. 그러므로, 최초 실행시에는 사실상 완전히 동일하고 이후 코드 진행에 따라 서로 달라지게 된다.</p>
</li>
</ul>
<h2 id="📌-lexical-environment">📌 Lexical Environment</h2>
<blockquote>
<p>✔️ 렉시컬 환경은 <strong>매개 변수명(Parameter), 변수의 식별자(Identifier), 선언한 함수의 함수명(Function)</strong>등을 수집하는 <strong>&quot;environmentRecord&quot;</strong>와 <strong>바로 직전 실행 컨텍스트의 LexicalEnvironment 정보를 참조</strong>하는 <strong>&quot;outerEnvironment&quot;</strong>로 구성되어 있다. </p>
</blockquote>
<ul>
<li>백과사전에 &#39;바나나&#39;를 검색하면 &#39;칼로리가 가장 높고 당질이 많은 알칼리성 식품으로 칼륨, 카로틴, 비타민 C를 함유하고 있다&#39;라는 문구가 등장한다.</li>
<li>이와 같은 느낌으로, 현재 컨텍스트 내부에는 a, b, c와 같은 식별자들이 있고 그 외부 정보는 D를 참조하도록 구성돼있다&quot; 라는 컨텍스트를 구성하는 환경 정보들을 사전에서 접하는 느낌으로 이해하면 된다.</li>
<li>최초 실행 시점에는 VariableEnvironment와 완전히 동일하다. 그러나 코드 한줄 한줄 내려가면서 변경될 수 있다.</li>
</ul>
<h3 id="🔗-environmentrecord와-호이스팅">🔗 environmentRecord와 호이스팅</h3>
<h4 id="environmentrecord">environmentRecord</h4>
<blockquote>
<p>✔️ environmentRecord에는 현재 컨텍스트와 관련된 코드의 식별자 정보들이 저장된다.</p>
</blockquote>
<ul>
<li>매개변수, 선언된 변수의 식별자, 선언된 함수 자체가 식별자 정보에 속한다.</li>
<li>컨텍스트 내부 전체를 처음부터 끝까지 훑어나가며 순서대로 수집한다.</li>
</ul>
<h4 id="호이스팅">호이스팅</h4>
<blockquote>
<p>✔️ 호이스팅은 <strong>자바스크립트 인터프레터가 매개변수, 선언된 변수의 식별자, 선언된 함수 자체가 유효 범위(Scope)의 최상단으로 끌어올려진 것을 의미한다.</strong>
✔️ 호이스팅이란 <strong>변수의 선언을 유효 범위(Scope)의 최상단으로 끌어올리는 행위를 말합니다.</strong> (같은 의미)</p>
</blockquote>
<ul>
<li>실제로는 끌어올리지는 않지만 편의상 끌어올린 것으로 간주한다.</li>
</ul>
<h4 id="호이스팅-규칙">호이스팅 규칙</h4>
<table>
<thead>
<tr>
<th align="center">선언 방식</th>
<th align="center">Hoisted?</th>
<th align="center">Initial Value</th>
<th align="center">Scope</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><strong>함수 선언문</strong></td>
<td align="center">✅ YES</td>
<td align="center">실제 함수</td>
<td align="center">Block (in Strict Mode)</td>
</tr>
<tr>
<td align="center"><strong>var</strong></td>
<td align="center">✅ YES</td>
<td align="center">undefined</td>
<td align="center">Function</td>
</tr>
<tr>
<td align="center"><strong>let, const</strong></td>
<td align="center">✅ YES and ❌ NO</td>
<td align="center">Uninitizlied (TDZ)</td>
<td align="center">Block</td>
</tr>
<tr>
<td align="center"><strong>함수 표현식 및 화살표 함수</strong></td>
<td align="center">🤷🏻‍♂️  Depends if using var or let/const</td>
<td align="center">🤷🏻‍♂️ Depends if using var or let/const</td>
<td align="center">🤷🏻‍♂️ Depends if using var or let/const</td>
</tr>
</tbody></table>
<h4 id="호이스팅-예제-1">호이스팅 예제 (1)</h4>
<ul>
<li>아래 코드의 결과가 어떻게 나올지 우선 예상을 해봅시다.</li>
</ul>
<pre><code class="language-js">functuon a(x) {    // 수집 대상 1 (매개 변수)
    console.log(x); // (1)
    var x;             // 수집 대상 2 (변수 선언)
    console.log(x); // (2)
    var x = 2;        // 수집 대상3 (변수 선언)
    console.log(x);    // (3)
}
a(1);</code></pre>
<p>보통 예상하는답</p>
<ul>
<li>(1) 1</li>
<li>(2) undefined</li>
<li>(3) 2</li>
</ul>
<p>정답은</p>
<ul>
<li>(1) 1</li>
<li>(2) 1</li>
<li>(3) 2</li>
</ul>
<p>그럼 위의 예제를 다르게 한번 봐볼까요?</p>
<pre><code class="language-js">functuon a() {    
    var x;            // 수집 대상 1의 변수 선언 부분
      var x;            // 수집 대상 2의 변수 선언 부분
      var x;            // 수집 대상 3의 변수 선언 부분

      x = 1;
      console.log(x); // (1)
      console.log(x); // (2)
      x = 2;
      console.log(x); // (3)
}
a(1);</code></pre>
<ul>
<li>위의 코드는 호이스팅이 되었다는 것을 전제로 한 코드입니다. 이제 호이스팅의 감이 오시지 않나요?</li>
</ul>
<h4 id="호이스팅-예제-2---함수-선언식">호이스팅 예제 (2) - 함수 선언식</h4>
<ul>
<li>원본 코드<pre><code class="language-js">function a() {
   console.log(b);     // (1)
   var b = &quot;bbb&quot;;        // 수집 대상 1 (변수 선언)
    console.log(b);        // (2)
    function b () { }    // 수집 대상 2 (함수 선언) 
    console.log(b);
}
</code></pre>
</li>
</ul>
<p>a();</p>
<pre><code>- 호이스팅을 마친 상태의 코드
```js
function a() {
  var b;            // 수집 대상 1. 변수는 선언부만 끌어올린다.
  function b() { }    // 수집 대상 2. 함수 선언은 전체를 끌어올린다.

  console.log(b);    // (1)
  b = &quot;bbb&quot;;        // 변수의 할당부는 원래 자리에 남겨둔다.
  console.log(b);    // (2)
  console.log(b);    // (3)
}

a();</code></pre><p><strong>console.log의 결과</strong></p>
<ul>
<li>(1) 함수</li>
<li>(2) &quot;bbb&quot;</li>
<li>(3) &quot;bbb&quot;</li>
</ul>
<p>원본 코드만 볼때는 (1) 부분은 undefined가 나거나 오류가 날 것 같지만, 함수 선언은 함수 전체가 호이스팅이 되기 때문에 위와 같은 결과를 갖게된다.</p>
<h4 id="호이스팅-예제-3---함수-표현식">호이스팅 예제 (3) - 함수 표현식</h4>
<ul>
<li>원본 코드</li>
</ul>
<pre><code class="language-js">console.log(sum(1,2));
console.log(multiply(3, 4));

function sum(a, b) {
    return a + b; 
}

var multiply = function (a, b) {
     return a * b; 
}</code></pre>
<ul>
<li>호이스팅을 마친 코드<pre><code class="language-js">var sum = function sum (a, b) { // (1) // (3)
  return a + b; 
}
var mulitply;                // (2)
console.log(sum(1, 2)));    // (4)
console.log(multiply(3, 4));// (5)
</code></pre>
</li>
</ul>
<p>multiply = function (a, b) {
    return a * b; 
}</p>
<pre><code>
위의 코드를 메모리 관점에서도 해석을 하자면
- (1) 메모리 공간을 확보하고 확보된 공간의 주솟값을 변수 sum에 연결한다.
- (2) 또 다른 메모리 공간을 확보하고 그 공간의 주솟값을 변수 multiply에 연결한다.
- (3) sum 함수를 또 따른 메모리 공간에 저장하고, 그 주솟값을 앞서 선언한 변수 sum의 공간에 할당한다. 이로써, 변수 sum은 함수 sum을 바라보는 상태가 된다.
- (4) sum을 실행한다. 정삭적으로 실행되어 3이 나온다.
- (5) 현재 multiply는 할당되어 있지 않다. 그러므로, &#39;multiply is not a function&#39;이라는 에러 메시지가 출력된다. 그 뒤에 코드는 이 에러로 인해 실행되지 않은 채 런타임이 종료된다.

&gt; ❓ 언제 함수 선언문(Function Declaration)과 함수 표현식(Function Expression)을 사용해야 하나요?

- 일관성만 있다면 어떠한 방식을 사용해도 상관없다.
- 단, 함수 선언식을 사용할 때는 이미 같은 이름으로 정의되어있는 변수를 변경할 수도 있으니 이 점을 유의하며 사용해야한다.

### 스코프, 스코프 체인, outerEnvironmentReference

&gt; ✔️ 스코프란 식별자에 접근할 수 있는 유효범위입니다.

- 식별자의 유효범위를 안에서부터 바깥으로 차례로 검색하나가는 것을 **&quot;스코프 체인&quot;**이라고 한다.
- **이를 가능하게 하는 것이 바로 LexicalEnvironment의 두 번째 수집 자료인 outerEnvironmentReference이다.**
- outerEnvironmentReference는 **현재 호출된 함수가 선언될 당시에 LexicalEnvironment를 참조한다.**

예시를 보고 설명하는게 가장 이해하기 쉽다.

#### 스코프체인 예제 (1)
```js
var a = 1;                        // (1)
var outer = function () {        // (2)
      var inner = function () {    // (4)
          console.log(a);            // (6)
        var a = 3;                // (7)
    };
      inner();                    // (5)
      console.log(a);                // (8)
}
outer();                        // (3)
console.log(a);                    // (9)</code></pre><ul>
<li><p>(시작) 전역 컨텍스트가 활성화가 된다. 전역 컨텍스트의 environmentRecord에 { a, outer } 식별자를 저장한다. 전역 컨텍스트는 선언 시점이 없으므로 전역 컨텍스트의 outerEnvironmentReference에는 아무것도 담기지 않는다. 그리고 this는 전역 객체가 된다.</p>
</li>
<li><p>(1), (2) 변수 a에 1을 할당하고, outer에 함수를 할당한다.</p>
</li>
<li><p>(3) outer 함수를 호출한다. 이로 인해 전역 컨텍스트의 코드는 일시중단되고, outer 실행 컨텍스트가 활성화 되어 (2)로 이동한다.</p>
</li>
<li><p>(2) environmentRecord에 { inner } 식별자를 저장한다. outerEnvironmentReference에는 outer 함수가 선언될 당시의 LexicalEnvironment가 담긴다. outer 함수는 전역 컨텍스트에서 선언되었으므로 전역 컨텍스트의 LexicalEnvironment를 참조복사한다. 이를 [ GLOBAL, { a, outer } ]라고 표기한다. 첫 번째는 실행 컨텍스트의 이름, 두 번째는 environmentRecord 객체이다. this는 전역 객체가 된다.</p>
</li>
<li><p>(4) inner 변수에 함수를 할당한다.</p>
</li>
<li><p>(5) inner 함수를 호출한다. 이에 따라, outer 함수의 실행 컨텍스트는 일시중단되고 inner 실행 컨텍스트가 활성화 되어 (4)로 이동한다.</p>
</li>
<li><p>(4) inner 실행 컨텍스트의 environmentRecord에 { a } 식별자를 저장한다. outerEnvironmentReference에는 inner 함수가 선언될 당시의 LexicalEnvironment가 담긴다. inner 함수는 outer 함수 내부에서 선언되었으므로 outer 함수의 LexicalEnvironment, 즉 [ outer, { inner } ]를 참조복사한다. this는 전역 객체가 된다.</p>
</li>
<li><p>(6) 식별자 a에 접근한다. 현재 활성화 상태인 inner 컨텍스트의 environmentRecord에서 a를 검색한다. 아직 할당된 값이 없으므로 <code>undefeind</code>를 출력 하게된다.</p>
</li>
<li><p>(7) inner 스코프에 있는 변수 a에 3을 할당한다.</p>
</li>
<li><p>inner 함수 실행이 종료된다. inner 실행 컨텍스트가 콜 스택에서 제거되고, 바로 아래의 outer 실행 컨텍스트가 다시 활성화 되면서, (8)을 실행한다.</p>
<ul>
<li>(8) 식별자 a에 접근하려고 한다. 이때, 자바스크립트 엔진은 활성화된 실행 컨텍스트의 LexicalEnvironment에 접근한다.</li>
<li>첫 요소의 environmentRecord에서 a가 있는지 찾아보고 없으면 outerEnvironmentReference에 있는 environmentRecord로 넘어가는 식으로 계석해서 검색을 해나간다.</li>
<li>예제에서는 두 번째, 즉 전역 LexicalEnvironment에 a가 있으니 그 a에 저장된 값 1을 반환하여 출력한다.</li>
</ul>
</li>
<li><p>(3) outer 함수가 종료된다.</p>
</li>
<li><p>(9) 식별자 a에 접근한다. 현재 활성화 상태인 전역 컨텍스트의 environmentRecord에서 a를 검색한다. 바로 a를 찾을 수 있으므로 1을 출력한다.</p>
</li>
<li><p>전역 컨텍스트가 콜 스택에서 제거되고 종료된다.</p>
</li>
</ul>
<p>위의 내용을 정리하자면, 새로운 함수 실행문을 만나면 새로운 실행 컨텍스트가 된다. 이 함수(inner)의 environmentRecord에는 수집한 식별자 정보를 저장하고, outerEnvironmentReference에는 이 함수가 선언 되었을 당시 실행 컨텍스트(outer)의 LexicalEnvironment가 된다.</p>
<p>마치, 방 안에서 부터 변수 a를 찾는 것이라고 생각하면 된다. 안방(inner)에 변수 a가 있으면 이를 사용한다. 없다면 거실(outer)로 나가서 변수 a를 찾는다. 없다면 아예 집 밖(global)으로 나가서 변수 a를 찾는다.</p>
<h2 id="📌-thisbinding">📌 ThisBinding</h2>
<blockquote>
<p>✔️ 실행 컨텍스트의 thisBinding에는 this로 지정된 객체가 저장된다.
✔️ this는 <strong>함수를 호출하는 방식에 따라 달라진다.</strong></p>
</blockquote>
<p><strong>1. Regular Function Call</strong>
    - 일반 함수로 호출하는 경우 this는 window 객체를 가리킨다. Strict Mode인 경우에는 undefined를 리턴한다.</p>
<p><strong>2. Dot Notation</strong>
    - 메소드를 사용하는 Dot Notation인 경우, this는 Dot(.) 앞에 있는 것을 가리킨다.</p>
<p><strong>3. Call, Apply, Bind</strong>
    - 첫 번째 매개변수가 this가 무엇을 가리키는지 결정한다.
    - 두 번째 인자부터는 함수의 인자로 사용한다.
    - apply는 두 번째 인자를 배열로 받는다.
    - bind는 함수를 즉시 실행하지 않고 binding된 새로운 함수를 반환한다. 즉, 변수에 저장할 수 있게된다.</p>
<p><strong>4. &quot;new&quot; Keyword</strong>
    - 함수 앞에 new 키워드를 사용하게 되면 this가 {}를 가리킨다. 즉, 빈 객체(새 인스턴스)를 생성하고 그 객체(인스턴스)를 가리킨다.</p>
<h1 id="🌐-정리">🌐 정리</h1>
<ul>
<li><strong>실행 컨텍스트</strong>는 <strong>실행할 코드에 제공할 환경정보를 모아놓은 객체</strong>이다.</li>
<li>전역 공간에서 자동으로 생성되는 <strong>전역 컨텍스트, eval(), 함수 실행에 의한 실행 컨텍스트</strong> 등이 있다.</li>
<li><strong>실행 컨텍스트가 활성화 되는 시점</strong>에 <strong>VariableEnvironment, LexicalEnvironment, ThisBinding</strong>의 세 가지 정보를 수집한다.</li>
<li><strong>VariableEnvironment는 초기 상태를 유지</strong>하며, LexicalEnvironment는 함수 실행 도중에 변경되는 사항을 즉시 반영한다.</li>
<li>LexicalEnvironment는 <strong>매개변수명(Parameter), 변수의 식별자(Identifier), 선언언 함수의 함수명 등을 수집</strong>하는 <strong>environmentRecord</strong>와 바로 <strong>직전 컨텍스트의 LexicalEnvironment 정보를 참조</strong>하는 <strong>outerEnvironmentReference</strong>로 구성 되어있다.</li>
</ul>
<ul>
<li><strong>호이스팅</strong>은 코드 해석을 좀 더 수월하게 하기 위해 <strong>environmentRecord의 수집 과정을 추상화한 개념</strong>이다.</li>
<li><strong>스코프는 식별자에 접근할 수 있는 유효범위이다.</strong></li>
</ul>
<ul>
<li>전역 컨텍스트의 LexicalEnvironment에 담긴 변수를 <strong>전역변수</strong>라 하고, 그 밖의 함수에 의해 생성된 실행 컨테스트의 변수들은 모두 <strong>지역변수</strong>라고 한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[브라우저 렌더링 과정]]></title>
            <link>https://velog.io/@sangmin-iam/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%A0%8C%EB%8D%94%EB%A7%81-%EA%B3%BC%EC%A0%95</link>
            <guid>https://velog.io/@sangmin-iam/%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%A0%8C%EB%8D%94%EB%A7%81-%EA%B3%BC%EC%A0%95</guid>
            <pubDate>Sat, 09 Apr 2022 07:31:01 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>다른 기술 블로그를 참고하여 정리하는 용도로 작성하였습니다. 앞으로도 계속 업데이트 예정입니다. <strong>(최신 업데이트: 2022년 4월 9일)</strong></p>
</blockquote>
<h1 id="⭐️-브라우저-구조">⭐️ 브라우저 구조</h1>
<img src="https://velog.velcdn.com/images/sangmin-iam/post/0dd0cd24-1e6b-468f-8e5e-e41b02e1ee43/Untitled.png" width="800px"/>

<ul>
<li>User Interface: 주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분을 말합니다.</li>
<li>Browser Engine: User Interface와 Rendering 사이의 동작을 제어합니다.</li>
<li>Rendering Engine: 요청한 콘텐츠를 표시한다. HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시합니다.</li>
<li>Networking: HTTP 요청과 같은 네트워크 호출하는데 사용됩니다.</li>
<li>JavaScript Interpreter(또는 Engine): 자바스크립트를 코드를 해석하고 실행합니다. 크롬에서는 V8 엔진을 사용하고 있습니다.</li>
<li>Display Backend(또는 UI Backend): 기본적인 위젯(콤보 박스 등)을 그립니다.</li>
<li>Data Persistence: 로컬 스토리지, 세션 스토리지, 쿠키 등 클라이언트 사이드에서 데이터를 저장하는 영역입니다.</li>
</ul>
<p><strong>구조는 브라우저마다 다를 수 있습니다.</strong></p>
<h1 id="⭐️-렌더링-엔진">⭐️ 렌더링 엔진</h1>
<p>렌더링 엔진의 역할은 요청받은 내용을 브라우저 화면에 나타내는 일입니다. HTML, CSS, JavaScript 등의 파일을 브라우저가 화면에 표시할 수 있도록 변환하여 픽셀 단위로 나타냅니다.</p>
<p>크롬 브라우저(정확히는 크로미움)는 사파리 브라우저에서 사용하는 Webkit을 사용하다가 버전 28 이후부터 Webkit 소스를 Fork하여 Blink 라는 엔진을 만들어 사용하고 있습니다.</p>
<blockquote>
<p><strong>참고 크로미움이란?</strong></p>
</blockquote>
<p>크롬은 크로미움 기반으로 만들어진 브라우저라는 이야기를 많이 들어보셨을 것입니다. 크로미움은 오픈소스 웹 브라우저입니다. <a href="https://chromium.woolyss.com/download/ko/">https://chromium.woolyss.com/download/ko/</a> 에서 다운로드해 브라우저로 사용할 수도 있습니다.</p>
<p>크로미움은 V8 이라는 자바스크립트 엔진과 Blink라는 렌더링 엔진을 사용하는 브라우저입니다. 크롬이 크로미움 기반으로 만들어졌다는 것은 오픈 소스인 크로미움 브라우저 코드 위에 살을 덧붙여 개발되었다는 의미입니다.</p>
<p>크로미움 기반의 크롬이 절반 이상 점유율을 차지하고 있습니다(<a href="https://www.koreahtml5.kr/front/stats/browser/browserUseStats.do">브라우저 점유율</a>). 이제는 Edge 브라우저도 크로미움 기반의 브라우저가 되었습니다. Edge 브라우저가 사용하던 EdgeHTML 렌더링 엔진을 포기하고 크로미움 기반의 브라우저를 만들겠다고 발표를 했습니다. (<a href="https://blogs.windows.com/windowsexperience/2018/12/06/microsoft-edge-making-the-web-better-through-more-open-source-collaboration/">Edge 브라우저의 크로미움 도입 발표</a>)</p>
<h2 id="렌더링-동작-과정">렌더링 동작 과정</h2>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/30f5cc63-05a4-4510-8eba-24fa1ec52200/%E1%84%85%E1%85%A6%E1%86%AB%E1%84%83%E1%85%A5%E1%84%85%E1%85%B5%E1%86%BC_%E1%84%83%E1%85%A9%E1%86%BC%E1%84%8C%E1%85%A1%E1%86%A8_%E1%84%80%E1%85%AA%E1%84%8C%E1%85%A5%E1%86%BC.png" alt=""></p>
<p>위의 그림은 Webkit의 렌더링 동작 과정입니다. </p>
<ol>
<li>HTML을 파싱하여 DOM 노드를 만듭니다. 이 DOM 노드들을 병합하여 DOM 트리를 생성합니다.</li>
<li>CSS를 파싱하여 CSSOM 트리를 만듭니다. (Style Rules)</li>
<li>DOM 트리와 CSSOM 트리를 사용하여, Attachment라는 과정을 통해 Render 트리를 생성합니다.</li>
<li>Render 트리를 기반으로 Layout(reflow)과정을 거쳐 노드들의 위치 계산이 이루어집니다.</li>
<li>Paint(repaint) 실제로 픽셀로 변환하여 화면에 그리게 됩니다.</li>
</ol>
<h1 id="⭐️-parser">⭐️ Parser</h1>
<p>파싱은 서버로부터 전송받은 문서의 문자열을 브라우저가 이해할 수 있는 구조로 변환하는 과정을 파싱이라고 합니다. 파싱 결과는 문서 구조를 나타내는 노드 트리인데, 파싱 트리(parse tree) 또는 문법 트리(syntax tree)라고 합니다.</p>
<h2 id="dom-document-object-model">DOM (Document Object Model)</h2>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/21488b67-206c-4ddc-b236-bfabdec23475/DOM.png" alt=""></p>
<ol>
<li>변환 (Conversion): HTML의 원시 바이트(raw bytes)을 읽어와서 해당 파일에 지정된 인코딩(UTF-8)에 따라 문자열로 변환하는 과정입니다. <code>&lt;meta charset=”utf-8”&gt;</code></li>
<li>토큰화 (Tokenizing): 문자열을 <a href="https://html.spec.whatwg.org/multipage/">W3C HTML5 표준</a>에 따라 고유 토큰 (<code>&lt;html&gt;</code>, <code>&lt;body&gt;</code>, <code>&lt;p&gt;</code> , 태그안에 있는 텍스트)으로 변환합니다. 각 토큰은 특별한 의미와 고유한 규칙을 가집니다.</li>
<li>렉싱 (Lexing): 토큰을 해당 속성 및 규칙을 정의한 객체(Nodes)로 변환합니다.</li>
<li>DOM 생성 (DOM Construction): HTML은 상위-하위 관계로 정의할 수 있어, 트리 구조로 나타낼 수 있습니다. 렉싱 과정을 거쳐 생성된 노드들을 트리 구조로 변환합니다.</li>
</ol>
<p>위에서 이야기한 4가지 과정을 모두 거치면, 위에 그림과 같은 트리 형태의 DOM이 만들어집니다. 브라우저는 이후 모든 페이지 처리가 필요할 때 이  DOM을 사용합니다.</p>
<h2 id="cssom-css-object-model">CSSOM (CSS Object Model)</h2>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/614157ed-5f21-4e5c-899a-18328e775680/CSSOM_1.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/98ebe930-3400-4e39-9a8e-3611dc1e3857/CSSOM.png" alt=""></p>
<p>위의 그림과 같이 DOM을 생성하는 과정 그대로 CSSOM 트리를 생성합니다.</p>
<p>브라우저는 DOM을 생성하는 동안 외부 CSS를 참조하는 <code>&lt;link&gt;</code> 태그를 만나게 되면 브라우저에서 리소스를 요청합니다. CSS의 원시 바이트(raw bytes) → 문자열로 변환 → 토큰 → 노트로 변환되고 마지막으로 CSSOM(CSS Object Model)이라는 트리 구조를 만듭니다.</p>
<p>CCSOM이 트리 구조를 가지는 이유는 하향식으로 규칙을 적용하기 때문입니다. 최종 스타일을 계산할 때 브라우저는 해당 노드에 적용 가능한 가장 일반적인 규칙으로 시작해 더 구체적인 규칙을 적용하는 방식입니다.</p>
<h2 id="참고-javascript와-css">참고: JavaScript와 CSS</h2>
<p>HTML과 CSS, 자바스크립트를 파싱하여 렌더 트리를 형성하고 화면에 그리는 과정을 최적화하면 브라우저의 렌더링 속도를 높여 사용자 경험을 개선할 수 있습니다. JavaScript와 CSS가 렌더링 과정에 어떤 영향을 미치는지 살펴보도록 하겠습니다.</p>
<h3 id="javascript">JavaScript</h3>
<p>자바스크립트는 파서 차단 리소스(parser blocking resource)입니다. 브라우저는 HTML문서를 파싱 하다가 자바스크립트를 만나면 진행하던 파싱을 중지하고 자바스크립트 엔진에게 권한을 넘겨 자바스크립트를 파싱하고 실행합니다.</p>
<h3 id="css">CSS</h3>
<p>CSS는 렌더링 차단 리소스(render blocking resource)입니다. CSS는 렌더링을 할 때 반드시 필요한 리소스이기 때문에 브라우저는 빠르게  CSS를 다운로드하는 것이 좋습니다. <code>&lt;head&gt;</code> 태그 안에서 정의하여 빠르게 리소스를 받을 수 있도록 해야 합니다.</p>
<p>CSS는 DOM 트리를 변경하지 않기 때문에 HTML문서 파싱을 기다리거나 중단할 이유가 없습니다. 그러나, 자바스크립트에서 스타일 정보를 요청하는 경우, CSS가 파싱되지 않은 상태라면 스크립트 에러가 발생할 수 있습니다.</p>
<p>이런 문제를 해결하기 위해 파이어폭스는 로드 중이거나 파싱 중인 CSS가 있는 경우 모든 자바스크립트 실행을 중지합니다. 반면, Webkit은 로드되지 않은 CSS 가운데 문제가 될 만한 속성이 있을 때만 자바스크립트를 중단합니다. </p>
<h1 id="⭐️-attachment">⭐️ Attachment</h1>
<p>CSSOM트리와 DOM 트리를 결합하여, 표시해야 할 순서로 내용을 그려낼 수 있도록 하기 위해 렌더 트리를 형성합니다. 이 과정을 웹킷에서는 Attachment라고 합니다. 렌더 트리는 화면에 표시되는 각 노드의 위치를 계산하는 레이아웃에도 사용되고 픽셀을 화면에 그리는 페인트 과정에도 사용됩니다.</p>
<h2 id="렌더-트리-구축">렌더 트리 구축</h2>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/b968152f-bf5a-475a-b935-69ff330883f2/render_tree.png" alt=""></p>
<p>Attachment 과정에서, 브라우저는 DOM Tree와 CSSOM Tree를 결합하여 Render Tree를 생성합니다. 렌더 트리는 페이지에 표시되는 모든 DOM 콘텐츠와 각 노드에 대한 모든 CSSOM 스타일 정보를 가집니다.</p>
<p>렌더 트리를 생성하려면 브라우저는 대략 3가지 작업을 수행합니다.</p>
<ol>
<li><p>DOM 트리의 루트(html)에서 시작하여 화면에 표시되는 노드를 각각 탐색합니다.</p>
<ul>
<li>화면에 표시되지 않는 일부 노드들 (script, meta 태그 등)은 렌더 트리에 반영되지 않습니다.</li>
<li>CSS에 의해 화면에서 숨겨지는 노드들은 렌더 트리에 반영되지 않습니다. 위의 예시에서 <code>span</code> 노드의 경우 <code>display: none</code>이 설정되기 때문에 렌더 트리에 반영되지 않습니다.  </li>
</ul>
</li>
<li><p>화면에 표시되는 각 노드에 대해 적절하게 일치하는 CSSOM 규칙을 찾아 적용합니다.  </p>
</li>
<li><p>화면에 표시되는 노드를 콘텐츠 및 계산된 스타일과 함께 내보냅니다.</p>
</li>
</ol>
<h2 id="dom-트리와-렌더-트리의-관계">DOM 트리와 렌더 트리의 관계</h2>
<p>렌더 트리 구축의 1번에서 이야기한 것 처럼 화면에 표시되지 않는 노드들은 렌더 트리에 포함되지 않습니다. 예를 들어, <code>&lt;head&gt;</code> 태그와 같은 비시각적 DOM 노드는 렌더 트리에 추가되지 않습니다.</p>
<p>뿐만 아니라, CSS로 인해 <code>display</code> 속성에 <code>none</code> 값이 할당된 노드들은 렌더 트리에 추가 되지 않습니다. 하지만, <code>visibility:hidden</code> 은 렌더 트리에 포함됩니다. 그 이유는, 이 속성이 할당된 노드는 화면에서 공간을 차지하기 때문에 렌더 트리에 포함이 됩니다.</p>
<h1 id="⭐️-layout">⭐️ Layout</h1>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/64392d16-975c-4c2f-9a12-db781ca1fdfd/layout.png" alt=""></p>
<p>렌더 트리가 생성되고, 기기의 뷰포트 내에서 렌더 트리의 각 노드들의 정확한 위치와 크기를 계산하는 과정을 Layout(혹은 Reflow)라고 합니다. 모든 상대적인 측정값은 화면에서 절대적인 픽셀값으로 변환됩니다. 즉, CSS에 상대적인 값인 %로 할당된 값들은 절대적인 값의 px단위로 변환 됩니다.</p>
<h1 id="⭐️-painting">⭐️ Painting</h1>
<p><img src="https://velog.velcdn.com/images/sangmin-iam/post/eb4932d9-0b01-4ba4-a1f0-b54be29616e8/painting.png" alt=""></p>
<p>렌더 트리의 각 노드를 화면의 실제 픽셀로 나타내는 과정을 Painting(혹은 reasterizing)라고 합니다. Painting 과정 후 브라우저 화면에 UI가 나타나게 됩니다.</p>
<h1 id="⭐️-review">⭐️ Review</h1>
<ol>
<li>HTML 문서를 파싱하여 DOM 트리를 생성합니다. (HTML Parsing)</li>
<li>CSS를 파싱하여 CSSOM 트리를 생성합니다. (CSS Parsing)</li>
<li>DOM 트리와 CSSOM 트리를 결합하여 렌더 트리를 생성합니다. (Attachment)</li>
<li>렌더 트리에서 레이아웃을 실행하여 각 노드의 정확한 위치와 크기를 계산합니다. (Layout)</li>
<li>각 노드들을 화면에 그리게 됩니다. (Painting)</li>
</ol>
<h1 id="⭐️-reference">⭐️ Reference</h1>
<ul>
<li><a href="https://beomy.github.io/tech/browser/browser-rendering/#cssomcss-object-model">[Browser] 브라우저 렌더링</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript: Array Methods: map(), filter(), reduce()]]></title>
            <link>https://velog.io/@sangmin-iam/JavaScript-Array-Data-Transformation-map-filter-reduce</link>
            <guid>https://velog.io/@sangmin-iam/JavaScript-Array-Data-Transformation-map-filter-reduce</guid>
            <pubDate>Thu, 24 Jun 2021 12:16:50 GMT</pubDate>
            <description><![CDATA[<p><em>이번 챕터도 알고리즘을 풀다가 필요한 메소드를 발견하여 정보를 찾아보며 공부한 내용으로 포스팅하게 되었습니다. 공부는 왕도도 없고 끝도 없는 것 같네요 ㅎㅎ 여러분들 힘냅시다! 피드백은 언제나 감사히 받겠습니다 😊</em></p>
<hr>
<h1 id="array-methods-map-filter-reduce">Array Methods: map(), filter(), reduce()</h1>
<blockquote>
<p>&quot;Map, reduce, and filter are all array methods in JavaScript. Each one will iterate over an array and perform a transformation or computation. Each will return a new array based on the result of the function. &quot;</p>
</blockquote>
<blockquote>
<p>map(), filter(), reduce()는 Array 메소드이다. 각 메소드는 Array를 for문 처럼 한 차례씩 데이터를 변환(Transformation하거나 계산(Computation)을 할 수 있다. 각 메소드는 함수(Function)의 결과에 따라 새로운 Array을 반환한다.</p>
</blockquote>
<br>

<h2 id="arraymap">Array.map()</h2>
<blockquote>
<p>Map()은 기존의 배열로 부터 새로운 배열을 만들어 낸다. 기존의 배열의 각각의 Element에 Function을 적용하여 새로운 배열을 반환한다. 예시를 보면 이해가 금방 된다.</p>
</blockquote>
<h3 id="syntax">Syntax</h3>
<pre><code class="language-javascript">var new_array = arr.map(function callback(element, index, array) {
    // Return value for new_array
}[, thisArg])</code></pre>
<ul>
<li>여기서 Parameter인 Element는 생략할 수 없다. </li>
<li>만약, 생략을 원할 경우<code>function callback(_, index, array)</code> undescore를 사용하여 생략하도록 권장한다.</li>
</ul>
<br>

<h3 id="example">Example</h3>
<pre><code class="language-javascript">const numbers = [1, 2, 3, 4];
const doubled = numbers.map(item =&gt; item * 2);
console.log(doubled); // [2, 4, 6, 8]</code></pre>
<ul>
<li>다음은 Array numbers에 속해있는 Elements에 2씩 곱하여 새로운 Array을 만드는 예시이다.</li>
<li><code>const doubled = numbers.map(item =&gt; item * 2);</code>의 뜻은 무엇일까?</li>
<li>Array numbers안에서 numbers들의 Element을 하나하나씩 가져올거야. 그리고 이를 <code>item</code>이라고 부를게. 그리고 이 <strong><code>item</code>에 2를 곱해서 새로운 Array에 Element로 넣어.</strong><br>

</li>
</ul>
<h2 id="arrayfilter">Array.Filter()</h2>
<blockquote>
<p>Filter를 단어 그대로 이해하면 쉽다. 과학 시간에 실험할 때 사용하는 <strong>거름종이</strong>라고 생각하면 된다. Filter는 <strong>일정한 조건에 충족한 Element</strong>들만 가지고 새로운 Array를 생성할 수 있다.</p>
</blockquote>
<h3 id="syntax-1">Syntax</h3>
<pre><code class="language-javascript">var new_array = arr.filter(function callback(element, index, array) {
    // Return true or false
}[, thisArg])</code></pre>
<p>Filter()는 Map()와 아주 비슷하다. 그러나, <strong>Filter는 Callback Funtion안에서 <code>true</code>값 혹은 <code>false</code>을 반환해야 한다.</strong> 그렇지 않으면, 원하는 대로 메소드가 실행되지 않을 것이다.</p>
<br>

<h3 id="example-1">Example</h3>
<pre><code class="language-javascript">const numbers = [1, 2, 3, 4];
const evens = numbers.filter(item =&gt; item % 2 === 0);
console.log(evens); // [2, 4]</code></pre>
<ul>
<li>결과는 <code>[2, 4]</code>을 반환한다.</li>
<li><code>numbers.filter(item =&gt; item % 2 ===0);</code> 를 해석해보자.</li>
<li>Array numbers안에 있는 Elements을 필터링할 건데 각 Element는 <code>item</code>이라고 부를거고 조건은 <code>item</code>를 2로 나누었을 때 나머지가 0인 수들만 필터링할거야.</li>
<li>2로 나누어져 나머지(remainder)가 0인 경우는 짝수(Even)인 경우이다!</li>
</ul>
<br>

<h2 id="arrayreduce">Array.Reduce()</h2>
<blockquote>
<p>Reduce()는 Array의 Elements을 하나의 Value로 변환하기 위한 메소드이다.</p>
</blockquote>
<h3 id="syntax-2">Syntax</h3>
<pre><code class="language-javascript">// Arrow function
reduce((accumulator, currentValue) =&gt; { ... } )
reduce((accumulator, currentValue, index) =&gt; { ... } )
reduce((accumulator, currentValue, index, array) =&gt; { ... } )
reduce((accumulator, currentValue, index, array) =&gt; { ... }, initialValue)</code></pre>
<ul>
<li>여기서 accumulator, currentvalue이 두가지의 Parameter가 가장 많이 사용된다.</li>
<li>비유를 일상생활에 비교하자면 사람 햄버거게임과 같은 원리다. 내 친구 한명 한명이 쌓여갈 수록 가해지는 무게가 증가하지않는가? reduce도 똑같다.</li>
<li>acuumulator는 점점 위로 쌓여져가는 내 친구들의 몸무게고 currentValue는 다음 차례에 내 위에 올라가는 다른 친구와 같다.</li>
<li>intialValue는 처음 reduce를 실행하기 전에 초기값이다. 0이면 0부터 시작한다.</li>
</ul>
<h3 id="example-2">Example</h3>
<pre><code class="language-javascript">const weightFriends = [60, 80, 100, 70];
const sum = weightFriends.reduce(function (acc, cur) {
  return acc + cur;
}, 0);
console.log(310); // 310</code></pre>
<ul>
<li>초기값은 0이다. 그러므로 0이란 숫자에서 시작을 한다.</li>
<li><code>weightFriends</code>의 첫 Element인 60을 cur에 넣는다. 그 후에 <code>acc + cur</code>을 실행한다. 초기 값은 0이므로 acc는 0 그러므로 실행 값들은 <code>0 + 60</code> 이를 <code>return</code>하면 다음 acc값에 적용한다.</li>
<li>두 번째 Element인 80을 cur에 넣는다. 그 후에 <code>acc + cur</code>을 실행한다. acc는 첫 번째 Element 60이 더 해진<code>60 + 80</code> 이를 <code>return</code>하게 되면 다음 세 번쨰 실행에는 acc가 140이 된다.</li>
<li>이러한 똑같은 방식으로 마지막 Element까지 실행된다.<br>


</li>
</ul>
<h1 id="reference">Reference</h1>
<ul>
<li><a href="https://www.freecodecamp.org/news/javascript-map-reduce-and-filter-explained-with-examples/">JavaScript Methods: map(), filter(), reduce()</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce">Array.prototype.reduce() - MDN</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript: string.substr() vs string.substring()]]></title>
            <link>https://velog.io/@sangmin-iam/JavaScript-string.substr-vs-string.substring</link>
            <guid>https://velog.io/@sangmin-iam/JavaScript-string.substr-vs-string.substring</guid>
            <pubDate>Tue, 22 Jun 2021 12:31:51 GMT</pubDate>
            <description><![CDATA[<p><em>프로그래머스에서 알고리즘을 풀던 도중에 substr()을 알게 되었다. substr()과 substring()은 굉장히 비슷하여 문자열 메소드를 사용하던 도중에도 헷갈렸다. 이를 정리하기 위해서 이 글을 작성하게 되었다.</em></p>
<hr>
<h1 id="substr-vs-substring">substr() vs substring()</h1>
<p>👉 <strong>substr()과 substring()</strong> 둘 다 모두 string(문자열)일 때 <strong>문자열의 원하는 부분</strong>을 가지고 올 수 있다.<br>
👉 여기서 다른 점은 <strong>substr()은 원하는 index 시작 위치에서 그 위치로 부터 length만큼</strong> 가져올  수 있다는 것이며, <strong>substring()은 원하는 index 시작 위치에서 끝나는 index의 위치전까지 가져올 수 있다.</strong><br>
👉 둘 다 비슷한 기능을 하지만 방법이 다른 것이다</p>
<hr>
<h2 id="stringsubstr">string.substr()</h2>
<br>

<h3 id="syntax">Syntax</h3>
<blockquote>
<p>string.substr(start)
string.substr(start, length)</p>
</blockquote>
<h3 id="examples">Examples</h3>
<pre><code class="language-javascript">const x = &quot;012345&quot;

x.substr(3, 1)     // Output: 3
x.substr(3)        // Output: 345
x.substr(-3, 2) // Output: 34
x.substr(-3)    // Output: 345
</code></pre>
<br>

<p> <code>x.substr(3,1)</code> - 3번 Index에서 시작하여 길이 1만큼의 값을 return한다. 결과값은 <code>3</code>이다.<br>
 <code>x.substr(3)</code> - Index 3번에서 시작하여 끝까지의 값을 return한다. 결과값은 <code>345</code>이다.<br>
 <code>x.substr(-3, 2)</code> - start는 인수로 음수(negative)값도 받는다. 음수인 경우에는 Index가 끝에서 시작을 한다. -1인 경우 끝에서 첫 번째이다. 여기선 -3을 인수로 받는다.끝에서 3번째인 3부터 시작하여 길이 3을 포함한 2만큼 return한다. 결과값은 <code>34</code>이다.<br></p>
<p> <code>x.substr(-3)</code> - start가 -3이므로 끝에서 3번째부터 시작한다. length의 인수를 받지 않으므로 문자열의 끝까지의 값을 return한다. 결과값은 <code>345</code>이다.</p>
<h2 id="stringsubstring">string.substring()</h2>
<br>

<h3 id="syntax-1">Syntax</h3>
<blockquote>
<p>string.substring(indexstart)
string.substring(indexstart, indexend)</p>
</blockquote>
<h3 id="examples-1">Examples</h3>
<pre><code class="language-javascript">const x = &quot;012345&quot;

x.substring(2, 5)     // Output: 234
x.substring(2)        // Output: 2345
x.substring(-3, 2) // Output: 01
x.substring(-3)    // Output: 012345</code></pre>
<br>

<p><code>x.substring(2, 5)</code> - Index 2번에서 시작하여 5에서 1을 차감한 4번 Index까지의 값을 return한다. 결과값은 <code>234</code>이다.<br>
<code>x.substring(2)</code> - Index 2번부터 끝까지의 값을 return한다. 결과값은<code>2345</code>이다.<br>
<code>x.substring(-3, 2)</code> - substring에서도 substr과 같이 음수값을 인수로 받는지 궁금할 수 있을 것이다. substr와는 다르게 <strong>substring에서는 음수값을 0으로 생각하면 된다.</strong> 그러므로 여기서 결과값은 시작부터 2에서 1을 참가한 1번 Index까지의 값을 return한다. 결과값은 <code>01</code>이다<br>
<code>x.substring(-3)</code> - 여기서도 -3을 0으로 생각하면 0부터 Index 끝까지의 값을 return하게 된다. 결과값은 <code>012345</code>이다.</p>
<h1 id="reference">Reference</h1>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr">MDN - String.prototype.substr()</a>
<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring">MDN - String.prototype.substring()</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript: Array.slice() vs Array.splice()]]></title>
            <link>https://velog.io/@sangmin-iam/JavaScript-Array.slice-vs-Array.splice</link>
            <guid>https://velog.io/@sangmin-iam/JavaScript-Array.slice-vs-Array.splice</guid>
            <pubDate>Fri, 04 Jun 2021 05:44:48 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>개선을 위한 정보 혹은 틀린 정보가 있다면 자유롭게 코멘트를 작성해주세요 :D</p>
</blockquote>
<p><em>Array에 관한 Method가 너무 많아 항상 헷갈린다. 한국어가 아닌 영어로 되어있는 언어를 공부하다 보니까 더욱 그런 생각이 든다. 그 중에서 아주 비숫하게 생긴  slice와 splice Method에 대하여 정리를 해야 겠다는 생각이 들어 이 글을 작성하게 되었다.</em></p>
<hr>
<h1 id="arrayslice">Array.slice()</h1>
<p>👉 Slice, 단어를 직역하면 야채를 썰듯이 무언가를 썬다는 뜻이다. Array에 관련된 Method이니 Array를 Slice(썰어서) 무언가를 만든다고 생각하자.</p>
<p>👉 언제나처럼 예시를 먼저 보는게 가장 이해가 빠르다고 생각한다.</p>
<blockquote>
</blockquote>
<p>array.slice(start, end)</p>
<ul>
<li>start에서 시작하여 end-1에서 끝남</li>
</ul>
<pre><code class="language-javascript">const animals = [&#39;ant&#39;, &#39;bison&#39;, &#39;camel&#39;, &#39;duck&#39;, &#39;elephant&#39;];

const newAnimals = animals.slice();


console.log(newAnimals);
// expected output: Array [&#39;ant&#39;, &#39;bison&#39;, &#39;camel&#39;, &#39;duck&#39;, &#39;elephant&#39;]

console.log(animals.slice(2));
// expected output: Array [&quot;camel&quot;, &quot;duck&quot;, &quot;elephant&quot;]

console.log(animals.slice(2, 4));
// expected output: Array [&quot;camel&quot;, &quot;duck&quot;]

</code></pre>
<ul>
<li><p><code>animals.slice()</code>은 <strong>Shallow Copy</strong>라고도 표현한다. 직역하면 얕은 복사이다. 즉, <strong>Original Array 변형시키지 않고 Array를 복사</strong>할 수 있다. 
(<strong>Original Array의 데이터가 변경</strong>되면** Shallow Copy도 변형**됨)</p>
</li>
<li><p><code>animals.slice(2)</code>은 Array의 Index <strong>Start(2)부터 끝까지</strong> slice(썰어서) 값을 Return 한다.</p>
</li>
<li><p><code>animals.slice(2, 4)</code>은 Array Index <strong>Start(2번)</strong>부터 <strong>End(4 - 1 = 3번)</strong>까지 slice(썰어서) 값을 Return 한다. </p>
</li>
<li><p>배열의 Index는 항상 0부터 시작한다는 것을 명심해야 한다.</p>
</li>
</ul>
<h1 id="arraysplice">Array.splice()</h1>
<p>👉  Splice를 네이버에서 검색하면 (밧줄의 두 끝을 함께 꼬아서) 잇다,  (필름테이프 등의 두 끝을) 붙이다[잇다] 라는 뜻이 나온다. 필름테이프가 Array라고 생각하고 Array의 Element를 빼고 다른 값을 붙여 넣는다? 에서 오지않았을까 생각을 한다.</p>
<p>👉 Splice는 3가지 기능을 할 수 있다. </p>
<pre><code>1) Orginal Array에서 원하는 Element을 Delete만하여 그 값을 Return 하는 기능

2) Array에서 원하는 Elements을 Delete하고 원하는 Value를 삽입하는 기능 

3) 그리고 Delete는 하지 않고 원하는 값을 원하는 위치에 삽입만 하는 기능이다.</code></pre><p>👉 여기서 중요한 점은 splice()는 삭제된 Array을 Return한다는 것이다.</p>
<p>👉 Slice와 다르게 Splice는 Orginal Array에 영향을 준다.</p>
<blockquote>
<p><strong>Syntax</strong> 
splice(start)
splice(start, deleteCount)
splice(start, deleteCount, item1)
splice(start, deleteCount, item1, item2, itemN)</p>
</blockquote>
<p><strong>1.</strong> Orginal Array에서 <strong>원하는 Element을 Delete</strong>하여 <strong>그 값을 Return</strong></p>
<pre><code class="language-javascript">/* splice(start) */

let originalNumber = [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;]
let removedNumber = myFish.splice(2)

// originalNumber is [&quot;1&quot;, &quot;2&quot;]
// removedNumber is [&quot;3&quot;, &quot;4&quot;]

/* splice(start, deleteCount)*/

let originalNumber = [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;]
let removedNumber = myFish.splice(1, 3)

// originalNumber is [&#39;1&#39;]
// removedNumber is [&#39;2&#39;, &#39;3&#39;, &#39;4&#39;]
</code></pre>
<p><strong>2.</strong> Array에서 <strong>원하는 Elements을 Delete</strong>하고 <strong>원하는 Value를 삽입</strong>하는 기능 - <strong>Delete된 값은 Return</strong> 한다.</p>
<pre><code class="language-javascript">
/* splice(start, deleteCount, item1, item2, itemN..)*/

let originalLetters = [&#39;a&#39;,&#39;b&#39;,&#39;h&#39;,&#39;z&#39;, &#39;e&#39;]
let removedLetters = originalLetters.splice(2, 2, &#39;c&#39;, &#39;d&#39;)

// originalLetters is [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;, &#39;e&#39;]
// removedLetters is [&#39;h&#39;, &#39;z&#39;]
</code></pre>
<p><strong>3.</strong> <strong>Delete는 하지 않고 원하는 값을 원하는 위치에 삽입</strong>만 하는 기능</p>
<pre><code class="language-javascript">
/* splice(start, deleteCount, item1, item2, itemN..)*/

let originalLetters = [&#39;a&#39;,&#39;b&#39;,&#39;d&#39;,&#39;e&#39;]
let removedLetters = originalLetters.splice(2, 0, &#39;c&#39;)

// originalLetters is [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;, &#39;e&#39;]
// removedLetters is [];
</code></pre>
<p>👉 삭제된 값은 없으므로 빈 Array가 Return이 된다.</p>
<h1 id="summary">Summary</h1>
<p>👉 Slice는 Shallow Copy로서 Original Array에 영향을 주지 않는다.</p>
<p>👉 Slice는 Orginal Array의 부분 혹은 전체를 복사하여 Manipulate할 때 사용한다.</p>
<p>👉 Splice는 Original Array에 영향을 준다 그러므로 Original Array을 Manipulate할 때 사용한다.</p>
<h1 id="reference">Reference</h1>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice">MDN - Array.prototype.slice()</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript: call, apply, bind?]]></title>
            <link>https://velog.io/@sangmin-iam/JavaScript-call-apply-bind</link>
            <guid>https://velog.io/@sangmin-iam/JavaScript-call-apply-bind</guid>
            <pubDate>Fri, 04 Jun 2021 00:23:16 GMT</pubDate>
            <description><![CDATA[<blockquote>
</blockquote>
<p>개선을 위한 정보 혹은 틀린 정보가 있다면 자유롭게 코멘트를 작성해주세요 :D</p>
<h1 id="call-apply-bind">Call, Apply, Bind</h1>
<p>👉 Call, Apply, Bind는 Function에서 사용되는 Method들 중 하나이다. Function은 Method가 없는지 알았는데 어떻게 존재하지? 이런 질문을 던질 수 있을 것이다. 이에 대한 답변은 바로 <strong>Function도 Object들 중 하나이기 때문에 Method가 존재</strong>한다.</p>
<p>👉 위 메소드들을 이해하는데 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this">this에 대한 개념</a>을 잘 알고 있어야 쉽다.</p>
<h2 id="call-apply">Call, Apply</h2>
<p>👉 설명을 먼저 하는 것 보다 예시를 드는게 이해가 가장 빠르다.</p>
<pre><code class="language-javascript">const greeting = function(a, b){
    console.log(`Hello, You can call me ${this.name}. I am interestend 
        in ${a} and ${b}}`)
}

const person1 = {name: &#39;James&#39;}
const person2 = {name: &#39;Tom&#39;}
const person3 = {name: &#39;Lee&#39;}

greeting(&#39;Music&#39;, &#39;Movie&#39;) ;
// Hello, You can call me . I am interestend in Music and Movie

greeting.call(person2 ,&#39;Music&#39;, &#39;Movie&#39;);
// Hello, You can call me Tom. I am interestend in Music and Movie

greeting.apply(person3 ,[&#39;Music&#39;, &#39;Movie&#39;]);
// Hello, You can call me Lee. I am interestend in Music and Movie
</code></pre>
<br/>
✔️ greeting 함수를 보면 a, b 두 인수를 받아 함수를 실행하는 것을 알 수 있다. 그런데 자세히 보면 this.name 이라는 this keyword를 사용한 변수가 있다는것 을 확인 할 수 있다.

<p>✔️ this keyword는 Object에서 사용되었다. 그러므로 call, apply 혹은 bind에서 첫 번째 인수로 사용 될 변수는 Object로 이루어져 있어야 한다. </p>
<pre><code class="language-javascript">// Objects
const person1 = {name: &#39;James&#39;}
const person2 = {name: &#39;Tom&#39;}
const person3 = {name: &#39;Lee&#39;}</code></pre>
<p><br/>👉 본격적으로 call, apply Method을 분석해보자.</p>
<pre><code class="language-javascript">greeting(&#39;Music&#39;, &#39;Movie&#39;) ;
// Hello, You can call me . I am interestend in Music and Movie

greeting.call(person2 ,&#39;Music&#39;, &#39;Movie&#39;);
// Hello, You can call me Tom. I am interestend in Music and Movie

greeting.apply(person3 ,[&#39;Music&#39;, &#39;Movie&#39;]);
// Hello, You can call me Lee. I am interestend in Music and Movie</code></pre>
<p><br/>✔️ 첫 번째 호출한 함수는 Method를 사용하지 않아 this.name을 출력하지 못하였다.
✔️ 두 번째 호출한 함수는 call Method을 사용하였다. 첫 번째 인수(Parameter)로 Object(perosn2)을 받고 두 번째, 세 번째는 함수에게 인자(Argument)를 전달하였다.
✔️ 세 번째 호출한 함수는 apply Method을 사용하였다. 첫 번째 인수도 마찬가지로 Object(person3)를 인자로 사용하였다. 그러나 두 번째 인자는 Array로 받아 사용하였다.
<br/></p>
<blockquote>
<p>💡 call, apply는 Method는 <strong>각자의 Object(Method의 첫 번째 인수)에 접근하여 this.name의 value를 return</strong>한다. call과 apply의 차이점은 <strong>apply는 Array을 사용</strong>하여 함수에게 인자를 전달한다는 점이다. </p>
</blockquote>
<h2 id="bind">Bind</h2>
<p>👉 Bind란 단어를 직역하면 묶다라는 뜻이 있다. 그대로 받아들이면 이해하기 쉽다. Function과 Object의 this keyword을 묶는다고 생각하면 된다.</p>
<pre><code class="language-javascript">const greeting = function(a, b){
    console.log(`Hello, You can call me ${this.name}. I am interestend 
        in ${a} and ${b}}`)
}

const person1 = {name: &#39;James&#39;}

const greetingJames = greeting.bind(person1);

greetingJames(&#39;music&#39;, &#39;movie&#39;)
// Hello, You can call me James. I am interestend in Music and Movie</code></pre>
<blockquote>
<p>✔️ bind는 call, apply method처럼  this keyword를 연결해준다. 
✔️ bind는 call, apply와 다르게 <strong>함수를 바로 출력하지 않는다.</strong>
✔️ <code>greetingJames</code> <strong>Variable(변수)에 Bind(묶어)두어 사용</strong>한다.</p>
</blockquote>
<hr>
<h1 id="which-one-to-use">Which One To Use?</h1>
<blockquote>
<p>👉 Call, Bind를 사용하면 된다.
👉 Apply는 잘 사용되지 않는 메소드이다.</p>
</blockquote>
<hr>
<h1 id="reference">Reference</h1>
<ul>
<li><a href="https://wooooooak.github.io/javascript/2018/12/08/call,apply,bind/">https://wooooooak.github.io/javascript/2018/12/08/call,apply,bind/</a></li>
<li><a href="https://www.geeksforgeeks.org/javascript-function-binding/">https://www.geeksforgeeks.org/javascript-function-binding/</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML, CSS: a, a:link, a:visited 의 차이?]]></title>
            <link>https://velog.io/@sangmin-iam/HTML-CSS-a-alink-avisited-%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@sangmin-iam/HTML-CSS-a-alink-avisited-%EC%9D%98-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Tue, 01 Jun 2021 05:58:13 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>개선을 위한 정보 혹은 틀린 정보가 있다면 자유롭게 코멘트를 작성해주세요 :D</p>
</blockquote>
<h1 id="a">a</h1>
<pre><code>&lt;a href=&quot;http://www.naver.com&quot;&gt;네이버&lt;/a&gt;</code></pre><blockquote>
<p>a는 <strong>anchor(닻)</strong>의 약자이다.  HTML 안에서 a태그는 현재 페이지에서 다른 페이지로 연결해주는 태그이다. 다른 페이지에 정착할 수 있도록 anchor(닻)을 내린다고 생각하면 된다. a태그의 기본적인 내용은 <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a">mdn</a> 혹은 <a href="https://www.w3schools.com/tags/tag_a.asp#:~:text=The%20tag%20defines%20a,which%20indicates%20the%20link&#39;s%20destination.">w3school</a> 를 참고하면 많은 정보가 있습니다 :)</p>
</blockquote>
<h2 id="alink">a:link</h2>
<h3 id="pseudo-class">Pseudo-class?</h3>
<blockquote>
<p>a:link는 css에서 a 태그를 스타일링 할 때 사용되는 pseudo-class 이다.
그렇다면 psuedo-class는 무엇이냐? 직역을 하면 가짜 클래스, 모조의 클래스라고도 할 수 있다. 즉, 클래스는 아니지만 클래스처럼 작동한다고 생각하면 된다. 
psuedo-class는 태그뒤에 :을 붙여 사용한다. 어떤 특정한 상황에 따라서 스타일링을 하고자 할 때 사용된다.</p>
</blockquote>
<h3 id="link">:link</h3>
<blockquote>
<p>a:link는 사용자가 방문하기전 상태를 나타낸다. 인터넷을 사용해보았다면 링크를 클릭하기전 글씨가 <strong>파란색</strong>(Default)인걸 알 수 있다. 이는 <strong>a:link</strong>를 통해 글씨 색을 변경할 수 있다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/sangmin-iam/post/ec64bae5-e189-4809-b691-99cb3a586ee4/a-link.jpg" alt=""></p>
<h2 id="avisited">a:visited</h2>
<blockquote>
<p>a:visited는 방문하기 후 상태를 나타낸다. 인터넷을 사용해보았다면 링크를 클릭하기전 글씨가 <strong>보라색</strong>(Default) 알 수 있다. 이는 <strong>a:visited</strong>을 CSS에서 글씨 색을 변경할 수 있다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/sangmin-iam/post/095d19c2-0703-44e8-b762-f7a196680361/a-visited.jpg" alt=""></p>
<h2 id="which-one-to-use">Which one to use?</h2>
<blockquote>
<p>a {} 로 사용해서 스타일링 한다면 link와 visited 둘 다 모두 스타일링이 적용된다.
a:link는 방문하기 전에 변경된다.
a:visited는 방문후에 스타일링이 변경된다.
※ <strong>a만 사용</strong>하거나 <strong>a:link, a:visited 모두 사용</strong>하여 스타일링 하는 것이 보편적이다.</p>
</blockquote>
<h1 id="reference">Reference</h1>
<ul>
<li><a href="https://stackoverflow.com/questions/1922643/a-vs-alink-what-is-the-difference">https://stackoverflow.com/questions/1922643/a-vs-alink-what-is-the-difference</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[김서방 찾기 알고리즘]]></title>
            <link>https://velog.io/@sangmin-iam/%EA%B9%80%EC%84%9C%EB%B0%A9%EC%B0%BE%EA%B8%B0-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</link>
            <guid>https://velog.io/@sangmin-iam/%EA%B9%80%EC%84%9C%EB%B0%A9%EC%B0%BE%EA%B8%B0-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98</guid>
            <pubDate>Sun, 23 May 2021 23:24:48 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>개선을 위한 정보 혹은 틀린 정보가 있다면 자유롭게 코멘트를 작성해주세요 :D</p>
</blockquote>
<h1 id="김서방-찾기">김서방 찾기</h1>
<h2 id="문제">문제</h2>
<h3 id="문제-설명">문제 설명</h3>
<p>String형 배열 seoul의 element중 &quot;Kim&quot;의 위치 x를 찾아, &quot;김서방은 x에 있다&quot;는 String을 반환하는 함수, solution을 완성하세요. seoul에 &quot;Kim&quot;은 오직 한 번만 나타나며 잘못된 값이 입력되는 경우는 없습니다.</p>
<h3 id="제한-사항">제한 사항</h3>
<ul>
<li>seoul은 길이 1 이상, 1000 이하인 배열입니다.</li>
<li>seoul의 원소는 길이 1 이상, 20 이하인 문자열입니다.</li>
<li>&quot;Kim&quot;은 반드시 seoul 안에 포함되어 있습니다.</li>
</ul>
<h3 id="입출력-예">입출력 예</h3>
<table>
<thead>
<tr>
<th align="center">seoul</th>
<th align="center">return</th>
</tr>
</thead>
<tbody><tr>
<td align="center">[&quot;Jane&quot;, &quot;Kim]</td>
<td align="center">1</td>
</tr>
</tbody></table>
<h2 id="문제-풀이">문제 풀이</h2>
<h3 id="나의-풀이">나의 풀이</h3>
<pre><code class="language-scss">function solution(seoul) {
    for(let i = 0; i &lt; seoul.length; i++){
        if(&quot;Kim&quot; === seoul[i]){
            var answer = &quot;김서방은 &quot; + i + &quot;에 있다&quot;
            return answer;
        };
    };
};</code></pre>
<ul>
<li>Seoul은 배열로 이루어져 있다. 그러므로 배열을 읽을 수 있는 for문을 사용했다.</li>
<li>for(let i = 0; i &lt; seoul.length; i++): seoul의 배열의 0번째 부터 시작하여 이 배열의 길이만큼 읽는다.</li>
<li>if(&quot;Kim&quot; === seoul[i]: i 번째를 읽었을때 String &quot;Kim&quot;이 출력되면 if문을 읽고 return값을 반환하고 if문을 종료한다.</li>
</ul>
<h3 id="다른-사람의-문제-풀이">다른 사람의 문제 풀이</h3>
<pre><code class="language-scss">function solution(seoul) {
        var solution = &quot;김서방은 &quot; + seoul.indexOf(&#39;Kim&#39;) + &quot;에 있다&quot;;
    return solution
};</code></pre>
<ul>
<li>프로그래머스에 있는 다른 사람의 풀이이다.</li>
<li>Array의 Method중 하나인 indexOf()를 사용하여 문제를 해결하였다.</li>
<li>다음은 indexOf() Method의 정의이다.</li>
<li>The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.</li>
<li>예를 들어, seoul.indexOf(&#39;Kim&#39;)은 배열 안에서 처음으로 &#39;Kim&#39;이 위치한 index(배열의 위치)를 찾아 결과물을 return하게 된다. 만약, &#39;Kim&#39;이란 String이 배열 안에서 존재하지 않는다면 -1을 반환한다.</li>
</ul>
<h2 id="느낀점">느낀점</h2>
<ul>
<li>문제를 푸는 방법은 다양하다. (이 문제는 for문, indexOf() Method를 사용할 수 있었음)</li>
<li>어느 방법으로 푸는 것이 가장 효율적인지 고민을 더 해봐야 할 것 같다.</li>
<li>처음부터 완벽한 프로그래머는 없다고 생각한다. 시행착오를 거쳐 자신의 코딩을 발전시켜 나가는 것이 좋은 프로그래머라고 생각한다.</li>
<li>알고리즘 문제 풀이를 통하여 자바스크립트 언어의 Grammar와 Method들을 갈고 닦을 수 있을 것 같다.</li>
</ul>
<h1 id="reference">Reference</h1>
<ul>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/12919">https://programmers.co.kr/learn/courses/30/lessons/12919</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript: Math.trunc() vs Math.floor()]]></title>
            <link>https://velog.io/@sangmin-iam/TIL-Math.trunc-vs-Math.floor</link>
            <guid>https://velog.io/@sangmin-iam/TIL-Math.trunc-vs-Math.floor</guid>
            <pubDate>Thu, 20 May 2021 01:46:17 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>스터디 로그를 위한 글입니다.
개선을 위한 정보 혹은 틀린 정보가 있다면 자유롭게 코멘트를 작성해주세요 :D</p>
</blockquote>
<h1 id="which-should-i-use">Which should I use?</h1>
<p>십진수로 변경할 때 여러가지 방법이 있다. 하지만, 무엇을 사용해야 할지 정하는 것은 가독성과 속도와의 tradeoff를 찾아야 한다.</p>
<p>상황에 따라 무엇을 사용해야 할지 정해야 한다. 단순히 소수점만 없애고자 한다면 trunc() 를 사용하면 된다. floor() , ceil() round() 는 컨셉면에서 trunc() 와 완전히 다르다.</p>
<h2 id="math-library">Math library</h2>
<pre><code class="language-javascript">var v = 3.14; 
[Math.trunc(v), Math.round(v), Math.floor(v), Math.ceil(v)]
// prints results</code></pre>
<p>여러가지 다른 Input value와 그에 대한 결과 값이다.</p>
<pre><code class="language-javascript">v        t   r   f   c
 3.87 : [ 3,  4,  3,  4]
 3.14 : [ 3,  3,  3,  4]
-3.14 : [-3, -3, -4, -3]
-3.87 : [-3, -4, -4, -3]</code></pre>
<blockquote>
<p><strong>Math.trunc() :</strong> 소수점 이하는 버린다.
<strong>Math.round() :</strong> 반올림
<strong>Math.floor() :</strong> 내림 floor =&gt; 바닥까지 내린다고 생각 3.5 -&gt; 3 -3.5 -&gt; -4
<strong>Math.ceil() :</strong> 올림 ceiling =&gt; 천장까지 올린다고 생각 3.5 -&gt; 4 -3.5 -&gt; -3</p>
</blockquote>
<h1 id="중요한점-추가">중요한점 (추가)</h1>
<p><code>Math.trunc()</code>는 소수점 이하는 다 버리기 때문에 숫자가 -23.3 음수인 경우에도 그저 -23을 Return한다.
<code>Math.floor()</code>는 -23.3인 경우에 내림을 하기 때문에 -24를 Return하게 된다. 그러므로, 그저 소수점을 버릴 것이냐, 아니면 수학적인 계산이 필요하여 음수인 경우에도 적용할 것이냐에 따라 선택하면 될 것이다.</p>
<h2 id="reference">Reference</h2>
<ul>
<li><a href="https://stackoverflow.com/questions/38702724/math-floor-vs-math-trunc-javascript">https://stackoverflow.com/questions/38702724/math-floor-vs-math-trunc-javascript</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>