<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>지속가능한 낙원</title>
        <link>https://velog.io/</link>
        <description>천천히 운영되는 개발 블로그</description>
        <lastBuildDate>Wed, 26 Jul 2023 05:43:31 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>지속가능한 낙원</title>
            <url>https://images.velog.io/images/jen_jyseo/profile/11552755-7ca2-4f22-8f2c-6fbd037a1ca8/IMG_4377.GIF</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 지속가능한 낙원. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jen_jyseo" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[useQuery 시그니처 제네릭 위주로 살펴보기 ]]></title>
            <link>https://velog.io/@jen_jyseo/useQuery-%EC%A0%9C%EB%84%A4%EB%A6%AD-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@jen_jyseo/useQuery-%EC%A0%9C%EB%84%A4%EB%A6%AD-%EC%82%B4%ED%8E%B4%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Wed, 26 Jul 2023 05:43:31 GMT</pubDate>
            <description><![CDATA[<h4 id="🌼-tmi">🌼 TMI..</h4>
<p>입사 후 회사 업무에 적응하며 지내던 삼개월, 수습 기간이 막 끝난 지금의 내가 지난 삼개월을 말하자면.. 여지껏 공부했던 내용으로 잘 버텼다..!라고 할 수 있을 것 같다..🥹</p>
<p>이제 내가 그동안 궁금했던 부분을 공부해보려 한다.
정리에 집중하지 않고 짤막하게 가벼운 마음으로 작성할 예정..!</p>
<p>오늘은 서버 상태 관리 라이브러리인 React Query에서 제공하는 useQuery훅의 시그니처를 제네릭 위주로 살펴봐야디. 👀</p>
<hr>
<h4 id="usequery의-시그니처">useQuery의 시그니처</h4>
<pre><code class="language-typescript">function useQuery&lt;TResult, TError, TQueryKey&gt;(
  queryKey: TQueryKey,
  queryFn: (queryKey: TQueryKey) =&gt; Promise&lt;TResult&gt;,
  options?: UseQueryOptions&lt;TResult, TError, TResult, TQueryKey&gt;
): UseQueryResult&lt;TResult, TError&gt;;</code></pre>
<ol>
<li>TResult: 이는 제네릭 타입 매개변수로서, queryFn 함수에서 반환되는 결과 데이터의 타입을 나타낸다.</li>
<li>TError: 이는 제네릭 타입 매개변수로서, queryFn 함수가 발생시킬 수 있는 에러 데이터의 타입을 나타낸다.</li>
<li>TQueryKey: 이는 제네릭 타입 매개변수로서, queryKey 매개변수의 데이터 타입을 나타낸다.
queryKey는 특정 쿼리를 식별하는데 사용되며, 데이터가 이미 캐시에 있는지 여부를 판단하는 데 사용된다.</li>
<li>queryKey: 이 함수의 첫 번째 매개변수로서, 쿼리를 식별하는 키 또는 식별자이다. 타입은 TQueryKey로 지정된다.</li>
<li>queryFn: 이 함수의 두 번째 매개변수로서, queryKey를 인자로 받고 TResult 타입의 값을 반환하는 Promise를 반환하는 함수이다.</li>
<li>options: 이는 선택적 매개변수로서, 쿼리에 대한 추가적인 구성 옵션을 전달할 수 있다. 
UseQueryOptions&lt;TResult, TError, TResult, TQueryKey&gt; 타입이다. 실제로 UseQueryOptions의 내용은 구현에 따라 다르며, 특정 사용 사례에 맞게 사용된다고 한다.
내일은 option에 대하여 알아봐야지.</li>
<li>UseQueryResult 객체를 반환한다. 이 객체는 결과 데이터와 쿼리에 관련된 메타데이터를 포함하고 있으며, 제네릭 타입 매개변수로 TResult는 결과 데이터의 타입을, TError는 에러 데이터의 타입을 나타낸다.</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[DOM과 Virtual DOM]]></title>
            <link>https://velog.io/@jen_jyseo/%EB%82%B4%EA%B0%80-%EA%B0%80%EC%9E%A5-%EC%8B%A0%EA%B2%BD-%EC%93%B4-%EB%B6%80%EB%B6%84%EA%B8%B0%EC%88%A0%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@jen_jyseo/%EB%82%B4%EA%B0%80-%EA%B0%80%EC%9E%A5-%EC%8B%A0%EA%B2%BD-%EC%93%B4-%EB%B6%80%EB%B6%84%EA%B8%B0%EC%88%A0%EC%97%90-%EB%8C%80%ED%95%9C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 07 Nov 2022 17:07:52 GMT</pubDate>
            <description><![CDATA[<h3 id="📍브라우저-랜더링을-위한-빌드업">📍브라우저 랜더링을 위한 빌드업</h3>
<p>User Interface: 주소 표시줄, 이전/다음 버튼, 북마크 메뉴 등. 요청한 페이지를 보여주는 창을 제외한 나머지 모든 부분
Browser Engine: User Interface와 Rendering Engine 사이의 동작을 제어
Rendering Engine: 요청한 콘텐츠를 표시, HTML을 요청하면 HTML과 CSS를 파싱 하여 화면에 표시함
Networking: HTTP 요청과 같은 네트워크 호출에 사용됨
Javascript Interpreter(또는 Engine): 자바스크립트 코드를 해석하고 실행함. 크롬에서는 V8 엔진을 사용함
Display Backend: 기본적인 위젯(콤보 박스 등..)을 그림
Data Persistence: Local Storage, 쿠키 등 클라이언트 사이드에서 데이터를 저장하는 영역</p>
<h1 id="dom의-동작-과정">DOM의 동작 과정</h1>
<p>HTML 문서 파싱해서 DOM 트리를 만들고
CSS 문서 파싱해서 CSSOM 트리 만들고
CSSOM, DOM을 이용하여 렌더 트리를 만듬
렌더 트리 생성 끝나면 → Layout(Reflow)가 만들어짐
각 노드가 화면의 정확한 위치에 표시하기 위해 위치와 크기를 계산하는 과정
paint 과정 실행됨
계산된 위치와 크기 등의 스타일들이 실제 픽셀로 표시하는 과정</p>
<h1 id="virtual-dom-의-역할">Virtual DOM 의 역할</h1>
<p>어떤 인터렉션이 발생되면,</p>
<ol>
<li>실제 DOM에 적용되기 전에 가상의 DOM에 먼저 적용시킨다.</li>
<li>그 후 최종적인 결과를 실제 DOM에 전달한다.
→ 이렇게 되면 실제 DOM은 최종 결과만 전달 받기 때문에 브라우저 내에서 발생하는 연산의 양이 줄어들고 성능이 개선된다.
DOM 관리를 Virtual DOM이 하도록 함으로써
컴포넌트가 DOM 조작 요청을 할 때 다른 컴포넌트들과 상호작용을 하지 않아도 된다. 각 변화들의 동기화 작업을 거치치 않고 모든 작업을 하나로 묶어준다.</li>
</ol>
<p>출처: <a href="https://velog.io/@devjooj/React-React-%EB%8F%99%EC%9E%91-%EB%B0%A9%EB%B2%95-Virtual-DOM">https://velog.io/@devjooj/React-React-%EB%8F%99%EC%9E%91-%EB%B0%A9%EB%B2%95-Virtual-DOM</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[axios]]></title>
            <link>https://velog.io/@jen_jyseo/axios</link>
            <guid>https://velog.io/@jen_jyseo/axios</guid>
            <pubDate>Sun, 23 Oct 2022 19:18:19 GMT</pubDate>
            <description><![CDATA[<h1 id="다양한-axios-응용-메소드">다양한 Axios 응용 메소드</h1>
<h2 id="axios-all">axios all</h2>
<p>여러 개의 요청을 동시 수행할 경우 axios.all() 메서드를 사용한다고 한다.</p>
<p>이 때 response는 axios.spred의 콜백함수의 인자로 순차적으로 들어가기 때문에 response에 대한 처리는 axios.spread의 콜백함수 내부에서 할 수 있다.</p>
<pre><code class="language-js">function getUserAccount() {
  return axios.get(&#39;/user/12345&#39;);
}

function getUserPermissions() {
  return axios.get(&#39;/user/12345/permissions&#39;);
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // Both requests are now complete
  }));</code></pre>
<hr>
<h2 id="axios-create">axios create</h2>
<p>custom 속성을 지닌 axios 만의 instance를 만들 수 있다.</p>
<pre><code class="language-js">const instance = axios.create({
  baseURL: &#39;https://some-domain.com/api/&#39;,
  timeout: 1000,
  headers: {&#39;X-Custom-Header&#39;: &#39;foobar&#39;}
});</code></pre>
<hr>
<h2 id=""></h2>
]]></description>
        </item>
        <item>
            <title><![CDATA[ 라이프사이클 - 클래스형 vs 함수형( react hooks)]]></title>
            <link>https://velog.io/@jen_jyseo/%EB%9D%BC%EC%9D%B4%ED%94%84%EC%82%AC%EC%9D%B4%ED%81%B4-%ED%81%B4%EB%9E%98%EC%8A%A4%ED%98%95-vs-%ED%95%A8%EC%88%98%ED%98%95-react-hooks</link>
            <guid>https://velog.io/@jen_jyseo/%EB%9D%BC%EC%9D%B4%ED%94%84%EC%82%AC%EC%9D%B4%ED%81%B4-%ED%81%B4%EB%9E%98%EC%8A%A4%ED%98%95-vs-%ED%95%A8%EC%88%98%ED%98%95-react-hooks</guid>
            <pubDate>Sun, 16 Oct 2022 14:54:56 GMT</pubDate>
            <description><![CDATA[<p>React의 컴포넌트는 생명주기를 가지고, 
라이프 사이클에 따라 생성되고 업데이트되고 사라진다.
컴포넌트의 수명은 보통 페이지에서 렌더링되기 전인 준비 과정에서 시작하여 페이지에서 사라질 때 끝이난다.</p>
<hr>
<h2 id="lifecycle이란">LifeCycle이란?</h2>
<p>리액트는 컴포넌트 기반의 View를 중심으로 한 라이브러리이다.
컴포넌트의 수명은 보통 페이지에서 렌더링되기 전인 준비 과정에서 시작하여 페이지에서 사라질 때 끝이난다.
<img src="https://velog.velcdn.com/images/jen_jyseo/post/d014594e-3f90-41a3-9a76-21f9e1f06878/image.png" alt=""></p>
<hr>
<h2 id="lifecycle의-큰-세가지-단계">LifeCycle의 큰 세가지 단계</h2>
<ul>
<li>Mount</li>
<li>Update</li>
<li>Unmount</li>
</ul>
<p>마운트는 DOM이 생성되고 웹 브라우저 상에서 나타나는 것을 뜻하고, 반대로 언마운트는 DOM에서 제거되는 것을 뜻한다.</p>
<hr>
<h2 id="update가-발생하는-네가지-상황">Update가 발생하는 네가지 상황</h2>
<ol>
<li>props가 바뀔 때</li>
<li>state가 바뀔 때</li>
<li>부모 컴포넌트가 리렌더링 될 때</li>
<li>this.forceUpdate로 강제로 렌더링을 트리거할 때</li>
</ol>
<hr>
<h2 id="클래스형-라이프-사이클-메서드-vs-함수형-라이프-사이클-react-hook">클래스형 라이프 사이클 메서드 vs 함수형 라이프 사이클 React Hook</h2>
<h3 id="1-constructor">1. constructor</h3>
<p>클래스형에서는 초기 state를 정할 때 constructor를 사용해야한다.</p>
<pre><code>class Example extends React.Component {
    constructor(props) {
        super(props);
        this.state = { count: 0 };
}</code></pre><h3 id="1-usestate">1. useState</h3>
<p> 훅에서는 useState hook을 사용하면 초기 상태를 쉽게 설정해줄 수 있다.</p>
<pre><code> const Example = () =&gt; {
    const [count,setCount] = useState(0);
}</code></pre><h3 id="2-shouldcomponentupdate">2. shouldComponentUpdate</h3>
<p> 이 메서드는 props나 state를 변경했을 때, 리렌더링을 할지 말지 결정하는 메서드이다.</p>
<pre><code> class Example extends React.Component {
  shouldComponentUpdate(nextProps) {
    return nextProps.value !== this.props.value
  }
}</code></pre><h3 id="2-reactmemo--usememo">2. React.memo / useMemo</h3>
<p>React Hooks 에서도 props는 React.memo, state는 useMemo를 활용하면 렌더링 성능을 개선할 수 있다고 한다.</p>
<pre><code> const Example = React.memo(() =&gt; {
      ...
  },
  (prevProps, nextProps) =&gt; {
    return nextProps.value === prevProps.value
  }
)</code></pre><h3 id="3-componentdidmount">3. componentDidMount</h3>
<p>이 메서드는 컴포넌트를 만들고 첫 렌더링을 마친 후 실행한다. </p>
<pre><code>class Example extends React.Component {
    componentDidMount() {
        ...
    }
}
</code></pre><h3 id="3-useeffect">3. useEffect</h3>
<p>함수형 Hooks 에서는 useEffect를 활용하여 다음의 기능을 구현할 수 있다.
useEffect의 [] 의존성 배열을 비워야지만 똑같은 메소드를 구현할 수 있다.</p>
<pre><code>const Example = () =&gt; {
    useEffect(() =&gt; {
        ...
    }, []);
}</code></pre><h3 id="4-componentdidupdate">4. ComponentDidUpdate</h3>
<p>이것은 리렌더링을 완료한 후 실행한다. 업데이트가 끝난 직후이므로, DOM관련 처리를 해도 무방하다.</p>
<pre><code>class Example extends React.Component {
    componentDidUpdate(prevProps, prevState) {
        ...
    }
}</code></pre><h3 id="4-useffect">4. usEffect</h3>
<pre><code>const Example = () =&gt; {
    useEffect(() =&gt; {
        ...
    });
}</code></pre><h3 id="5-componentwillunmount">5. componentWillUnmount</h3>
<p>이 메서드는 컴포넌트를 DOM에서 제거할 때 실행한다. componentDidMount에서 등록한 이벤트가 있다면 여기서 제거 작업을 해야한다. </p>
<pre><code>class Example extends React.Component {
    coomponentWillUnmount() {
        ...
    }
}</code></pre><h3 id="5-useeffect-cleanup-function">5. useEffect CleanUp Function</h3>
<p> 함수형 컴포넌트에서는 useEffect CleanUp 함수를 통해 해당 메서드를 구현할 수 있다.</p>
<pre><code>const Example = () =&gt; {
    useEffect(() =&gt; {
        return () =&gt; {
            ...
        }
    }, []);
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[props, state, 리렌더링]]></title>
            <link>https://velog.io/@jen_jyseo/props-state-%EB%A6%AC%EB%A0%8C%EB%8D%94%EB%A7%81</link>
            <guid>https://velog.io/@jen_jyseo/props-state-%EB%A6%AC%EB%A0%8C%EB%8D%94%EB%A7%81</guid>
            <pubDate>Sun, 09 Oct 2022 20:04:37 GMT</pubDate>
            <description><![CDATA[<h2 id="props란">props란?</h2>
<ul>
<li>상위 컴포넌트가 하위 컴포넌트에 값을 전달할때 사용한다.</li>
<li>단방향 데이터 흐름을 갖는다.</li>
<li>프로퍼티의 줄임말이다.</li>
<li>컴포넌트 간에 데이터를 전달할 수 있는 컴포넌트 통신 방법입니다.</li>
</ul>
<hr>
<h2 id="state-란">State 란?</h2>
<ul>
<li><p>State는 컴포넌트의 렌더링 결과물에 영향을 주는 데이터를 갖고 있는 객체이다.</p>
</li>
<li><p>props는 컴포넌트에 전달되는 반면 state는 컴포넌트 안에서 관리된다.</p>
</li>
</ul>
<hr>
<h2 id="렌더링">렌더링</h2>
<p>컴포넌트가 현재 props와 state의 상태에 기초하여 UI를 어떻게 구성할지 컴포넌트에게 요청하는 작업을 의미한다.
<a href="https://yceffort.kr/2022/04/deep-dive-in-react-rendering">https://yceffort.kr/2022/04/deep-dive-in-react-rendering</a></p>
<h2 id="리렌더링이-되는-조건">리렌더링이 되는 조건</h2>
<ol>
<li>state 변경이 있을 때</li>
<li>새로운 props이 들어올 때</li>
<li>부모 컴포넌트가 렌더링 될 때</li>
<li>forceUpdate가 실행될 때</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript의 ES/ ES5/ ES6]]></title>
            <link>https://velog.io/@jen_jyseo/JavaScript%EC%9D%98-ES-ES5-ES6</link>
            <guid>https://velog.io/@jen_jyseo/JavaScript%EC%9D%98-ES-ES5-ES6</guid>
            <pubDate>Sun, 02 Oct 2022 18:40:40 GMT</pubDate>
            <description><![CDATA[<h1 id="esecmascript란">ES(Ecmascript)란?</h1>
<p>ECMAScript는 말 그대로 Ecma라는 기관이 만든 script 언어이며, 
<a href="https://en.wikipedia.org/wiki/ECMAScript">ECMA-262 표준</a>을 따르고 있다.</p>
<p>ECMA-262는 규격이며, ECMAScript는 ECMA-262에 의해 표준화된 자바스크립트의 새로운 이름이다.</p>
<p>따라서 ECMAScript가 표준 또는 언어규격이라는 말은 옳지 않다.</p>
<p>ECMAScript(=javascript)는 엄연히 프로그래밍 언어이며, </p>
<p><strong><em>ES6 표준을 따른다</em></strong> 라는 말은 <strong><em>ECMAScript 2015가 사용중인 ECMA 규격을 따른다</em></strong>, 
<strong><em>ECMAScript 2015과 동일한 문법을 사용한다</em></strong> 와 동의어라고 볼 수 있다.</p>
<hr>
<h3 id="es6">ES6?</h3>
<p>ES6에서 추가된 문법들은 기존의 문제들을 매우 깔끔하게 해결했으며, </p>
<p>가독성 및 유지 보수성을 보강하는 문법도 대거 추가되었다.</p>
<p>ES6 표준 문법은 <a href="https://caniuse.com/?search=es6">IE에서 지원되지 않지만</a>, 트랜스파일러(Babel)를 이용해서 하위 문법을 따르는 코드로 쉽게 변경할 수 있기 때문에 호환성 문제도 없다.</p>
<p>ES6에서 추가된 기능으론 Promise, Class, Arrow function, async/await 등이 있다.</p>
<h3 id="es6-feature">ES6 feature</h3>
<ol>
<li>기본 매개 변수 (Default Parameters)</li>
<li>템플릿 리터럴 (Template Literals)</li>
<li>멀티 라인 문자열 (Multi-line Strings)</li>
<li>비구조화 할당 (Destructuring Assignment)</li>
<li>향상된 객체 리터럴 (Enhanced Object Literals)</li>
<li>화살표 함수 (Arrow Functions)</li>
<li>Promises</li>
<li>블록 범위 생성자 Let 및 Const (Block-Scoped Constructs Let and Const)</li>
<li>클래스 (Classes)</li>
<li>모듈 (Modules)</li>
</ol>
<p>기타 ES6 표준은 <a href="https://ui.toast.com/fe-guide/ko_ES5-TO-ES6">링크</a>를 참조하자!(엄청 유용하다 꼭 읽어보기)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] - 9 / 27]]></title>
            <link>https://velog.io/@jen_jyseo/TIL-9-27</link>
            <guid>https://velog.io/@jen_jyseo/TIL-9-27</guid>
            <pubDate>Mon, 26 Sep 2022 18:41:49 GMT</pubDate>
            <description><![CDATA[<h1 id="for-in">for in</h1>
<p><code>for in</code>문은 이터러블이 아닌 상속된 열거 가능한 속성들을 포함하여 객체에서 문자열로 키가 지정된 모든 열거 가능한 속성에 대해 반복한다.</p>
<p><code>for in</code>문은 모든 객체에서 사용이 가능합니다. 
 <code>for in</code>문은 객체의 key 값에 접근할 수 있지만, value 값에 접근하는 방법은 제공하지 않습니다. </p>
<p>자바스크립트에서 객체 속성들은 내부적으로 사용하는 숨겨진 속성들을 가지고 있다. </p>
<p>그 중 하나가 <code>[[Enumerable]]</code>이며, <code>for in</code> 문은 이 값이 <code>true</code> 인 속성들만 반복 가능하다.</p>
<p>객체의 모든 내장 메서드를 비롯해 각종 내장 프로퍼티들의  <code>[[Enumerable]]</code>속성은 반복되지 않는다.</p>
<h1 id="for-in과-for-of문의-차이">for in과 for of문의 차이</h1>
<h3 id="for-in-1">for in</h3>
<ul>
<li>객체의 모든 열거 가능한 속성에 대해 반복한다.</li>
</ul>
<h3 id="for-of">for of</h3>
<ul>
<li><code>[Symbol.iterator]</code> 속성을 가지는 컬렉션 전용 ⇒ 이터러블</li>
</ul>
<p><a href="https://jsdev.kr/t/for-in-vs-for-of/2938">출처</a></p>
<hr>
<h1 id="객체의-상속">객체의 상속</h1>
<h2 id="❓객체-리터럴로-생성한-객체는-어떤-객체의-프로토타입을-상속받을까">❓객체 리터럴로 생성한 객체는 어떤 객체의 프로토타입을 상속받을까?</h2>
<h3 id="객체-리터럴로-객체를-생성하는-경우"><strong>객체 리터럴로 객체를 생성하는 경우</strong></h3>
<p>⇒ <strong>그 객체의 프로토타입 객체는 Object.prototype 객체이다.</strong></p>
<h3 id="생성자-함수로-객체를-생성하는-경우"><strong>생성자 함수로 객체를 생성하는 경우</strong></h3>
<p> ⇒ <strong>그 객체의 프로토타입 객체는 생성자함수.prototype 객체이다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JWT, API]]></title>
            <link>https://velog.io/@jen_jyseo/JWT-API</link>
            <guid>https://velog.io/@jen_jyseo/JWT-API</guid>
            <pubDate>Sun, 25 Sep 2022 17:56:54 GMT</pubDate>
            <description><![CDATA[<h1 id="jwtjson-web-token">JWT(JSON Web Token)</h1>
<p>JWT는 유저를 인증하고 식별하기 위한 토큰 기반 인증이다.</p>
<p>토큰은 세션과는 달리 클라이언트에 저장되기 때문에 메모리지나 스토리지 등을 통해 세션을 관리했던 서버의 부담을 덜 수 있다.</p>
<h2 id="jwt의-특징">JWT의 특징</h2>
<p>JWT는 토큰 자체에 사용자의 권한 정보나 서비스를 사용하기 위한 정보가 포함되어있다.</p>
<p>토큰이 한 번 발듭된 이후 사용자의 정보를 바꾸더라도 토큰을 재발급하지 않는 이상 반영되지 않는다.</p>
<p>JWT와 같은 토큰을 클라이언트에 저장하고 요청시 단순히 HTTP 헤더에 토큰을 첨부하는 것만으로도 단순하게 데이터를 요청하고 응답을 받아올 수 있다.</p>
<hr>
<h1 id="apiapplication-programming-interface">API(Application Programming Interface)</h1>
<p>정의 및 프로토콜 집합을 사용하여 두 소프트웨어 구성 요소가 서로 통신할 수 있게 하는 메커니즘.</p>
<h3 id="rest-api"><strong>REST API</strong></h3>
<p>클라이언트가 서버에 요청을 데이터로 전송한다.</p>
<p>서버가 이 클라이언트 입력을 사용하여 내부 함수를 시작하고 출력 데이터를 다시 클라이언트에 반환합니다.</p>
<p><a href="https://aws.amazon.com/ko/what-is/api/">https://aws.amazon.com/ko/what-is/api/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JavaScript 문법]]></title>
            <link>https://velog.io/@jen_jyseo/JavaScript-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@jen_jyseo/JavaScript-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Fri, 23 Sep 2022 09:31:52 GMT</pubDate>
            <description><![CDATA[<p><img src="https://media.vlpt.us/images/jen_jyseo/profile/11552755-7ca2-4f22-8f2c-6fbd037a1ca8/IMG_4377.GIF?w=240" alt="https://media.vlpt.us/images/jen_jyseo/profile/11552755-7ca2-4f22-8f2c-6fbd037a1ca8/IMG_4377.GIF?w=240"></p>
<h1 id="❓javascript의-자료형과-javascript만의-특성은-무엇일까-">❓JavaScript의 자료형과 JavaScript만의 특성은 무엇일까 ?</h1>
<h2 id="javascript는-느슨한-타입의-동적-언어이다">JavaScript는 느슨한 타입의 동적 언어이다.</h2>
<p>JavaScript는 느슨한 타입(loosely typed)의 동적(dynamic) 언어이다.</p>
<p>JavaScript의 변수는 어떤 특정 타입과 연결되지 않으며, 모든 타입의 값으로 할당 (및 재할당) 가능하다.</p>
<pre><code class="language-jsx">let foo = 42 // foo가 숫자
foo = &#39;bar&#39; // foo가 이제 문자열
foo = true // foo가 이제 불리언</code></pre>
<p>JavaScript는 느슨한 타입의 동적 언어이기 때문에 변수 선언시 변수의 타입을 미리 선언하지 않아도 된다는 특징을 가지고 있다.</p>
<hr>
<h2 id="동적-언어의-문제점과-보완-방법">동적 언어의 문제점과 보완 방법</h2>
<p>이러한 특징으로 인해 변수의 타입이 변하지 않아야 하거나 변수 타입을 체크해야 하는 경우 문제에 직면할 수 있다.</p>
<p>이러한 문제는 정적 타입 체크와 강력한 문법을 추가한 TypeScript를 사용하여 보완할 수 있다.</p>
<p>정적 타입 언어는 런타임 이전에 타입이 올바른지에 대한 검사를 시행하며, 동적 타입 언어는 런타임에 프로그램의 타입이 올바른지에 대한 검사를 실행한다.</p>
<p> 만약 래퍼런스 오류를 유발하는 코드가 존재한다면 정적 언어는 컴파일하는 과정에서 오류를 출력하는 반면 동적 언어는 해당 구문이 실행되는 시점에서 오류를 출력한다.</p>
<p>TypeScript는 정적 타입 언어이기 때문에 런타임 이전(컴파일 과정)에 오류를 출력한다.</p>
<p><a href="https://jess2.xyz/typescript/javascript-vs-typescript/">참조</a></p>
<hr>
<h2 id="javascript-형변환">JavaScript 형변환</h2>
<p>자바스크립트는 변수 선언 시 타입을 지정하지 않기에 용도에 따라 개발자가 명시적으로 타입을 지정해주기도 하고, 자바스크립트 엔진 내에서 암시적으로 타입을 변환하기도 한다.</p>
<p>JavaScript 형변환에는 명시적 형변환과 암시적 형변환이 있다.</p>
<h3 id="명시적-형변환">명시적 형변환</h3>
<p><code>String()</code>, <code>Number()\</code>, <code>Boolean()</code> 등의 함수를 사용하여 명시적으로 타입을 변환하는 형변환이이다.</p>
<pre><code class="language-jsx">//String
String(22) // &quot;22&quot;</code></pre>
<h3 id="암시적-형변환">암시적 형변환</h3>
<p>비교, 산술, 논리 연산자 등을 이용시 자바스크립트 엔진이 필요에 따라 자동으로 타입을 변환하는 형변환이다.</p>
<ul>
<li><code>+</code> 연산자 사용 시 피연산자 중 문자열이 하나라도만 있으면 String Type으로 변환된다.<code>undefined</code> 나 <code>null</code>도 문자열로 변환된다.</li>
</ul>
<pre><code class="language-jsx">&#39;hi&#39; + null; // &#39;hinull&#39;
&#39;hi&#39; + &#39;world&#39;; // &#39;hiworld&#39;</code></pre>
<ul>
<li><code>+</code>  연산자를 제외한 산술 연산자(<code>-, /, *, &gt;, &lt;</code> 등) 사용시 Number Type 으로 변환된다.</li>
</ul>
<pre><code class="language-jsx">/* + 연산자를 사용할 경우 */
&quot;1&quot; + &quot;1&quot; // &#39;11&#39;

/* (-, /, *, &gt;, &lt;) 등의 산술 연산자를 사용한 경우 */
&quot;1&quot; - &quot;1&quot; //0
&quot;1&quot; * &quot;1&quot; //1
&quot;1&quot; / &quot;1&quot; //0
[0] - 1 //-1</code></pre>
<p>이 때 숫자 이외의 글자가 들어있는 문자열, 배열 및 <code>undefined</code>는 Number Type으로 변환되지 않고 <code>NaN</code>(Not a Number)을 반환한다.</p>
<pre><code class="language-jsx">&quot;hi&quot; - 1 //NaN
[&quot;hi&quot;] -1 // NaN
undefined - 1 // NaN</code></pre>
<ul>
<li>동등 비교 연산자(==)를 사용할 경우 좌항의 형이 변환되어 평가된다.</li>
</ul>
<pre><code class="language-jsx">true == 1;    // true  (true를 1로 변환) 
false == 0;   // true  (false를 0으로 변환)
&#39;1&#39; == true;  // true  (&#39;1&#39;를 true로 변환)
&#39;1&#39; == 1;     // true  (&#39;1&#39;를 1로 변환)</code></pre>
<ul>
<li>NOT 논리 연산자(!)를 두 번 사용할 경우 Boolean Type으로 변환한다.</li>
</ul>
<pre><code class="language-jsx">let string = &quot;&quot;;

!!string; // false</code></pre>
<hr>
<h2 id="동등-비교-연산자와-일치-비교-연산자의-차이">동등 비교 연산자와 일치 비교 연산자의 차이</h2>
<h3 id="동등-연산자-">동등 연산자 (==)</h3>
<p>두 피연산자의 자료형을 일치시킨 후, 엄격하게 비교를 수행</p>
<h3 id="일치-연산자-">일치 연산자 (===)</h3>
<p>자료형 변환 없이 두 피연산자가 엄격히 같은지 판별</p>
<p>동등 비교 연산자(==, !=)와 일치 비교 연산자(===, !==)의 가장 큰 차이점은 <strong>형변환의 유무이다.</strong></p>
<p>일치 비교 연산자(===, !==)는 형변환을 하지 않은 상태에서 두 피연산자가 서로 같은지 비교를 진행한다.</p>
<p>일치 비교 연산자(===, !==)는 <strong>두 피연산자의 자료형까지 모두 일치/불일치해야하는 경우에 사용이 적절하다.</strong></p>
<hr>
<h2 id="undefined와-null">undefined와 null</h2>
<h3 id="undefined">undefined</h3>
<p>undefined는 ‘아무 값도 할당받지 않은 상태’를 의미한다.</p>
<p>변수 선언에 의해 확보된 메모리 공간을 처음 할당이 이뤄질 때까지 빈 상태로 내버려두지 않고 자바스크립트 엔진이 undefined로 초기화한다.</p>
<p><strong>undefined는 개발자가 의도적으로 할당하기 위한 값이 아니라 자바스크립트 엔진이 변수를 초기화 할 때 사용하는 값이다.</strong></p>
<h3 id="null">null</h3>
<p>null은 원시 자료형 null로 분류된다.</p>
<p><strong>프로그래밍 언어에서 null은 변수에 값이 없다는 것을 의도적으로 명시할 때 사용한다.</strong></p>
<p>변수에 null을 할당하는 것은 변수가 이전에 참조하던 값을 더 이상 참조하지 않겠다는 의미이다.</p>
<p>이는 이전에 할당되어 있던 값에 대한 참조를 명시적으로 제거하는 것을 의미하며, 자바스크립트 엔진은 누구도 참조하지 않은 메모리 공간에 대해 가비지 콜렉션을 수행할 것이다.</p>
<p><a href="https://hanamon.kr/javascript-undefined-null-%EC%B0%A8%EC%9D%B4%EC%A0%90/">참조</a></p>
<hr>
<h1 id="❓javascript-객체와-불변성이란-">❓JavaScript 객체와 불변성이란 ?</h1>
<h2 id="원시값과-참조값">원시값과 참조값</h2>
<p>JavaScript 데이터 타입은 크게 원시값과 참조값으로 나뉜다.</p>
<h3 id="원시값">원시값</h3>
<p>원시값에는 <code>Numver</code>, <code>String</code>, <code>Boolean</code>, <code>null</code>, <code>undefined</code> 이 있다.</p>
<h3 id="참조값">참조값</h3>
<p>참조값에는 <code>Object</code>이 있고, 하위로 <code>Array</code>, <code>Function</code>, <code>RegExp</code>이 있고</p>
<p>ES6에사 <code>Map</code>, <code>Set</code>, <code>WeakMap</code>, <code>WeakSet</code>등도 추가되었다.</p>
<h3 id="원시값과-참조값의-차이">원시값과 참조값의 차이</h3>
<p>원시값은 값을 그대로 변수에 할당하고,
참조값은 값이 저장된 주소값을 변수에 할당(참조)한다는 차이가 있다.</p>
<p><a href="https://webclub.tistory.com/638">원시값과 참조값이 각각 어떻게 메모리에 저장되는지 알고싶다면 클릭</a></p>
<p><a href="https://curryyou.tistory.com/276">원시값과 참조값이 어떤 위치에 저장되는지 알고싶다면 클릭</a></p>
<hr>
<h2 id="불변객체를-만드는-방법">불변객체를 만드는 방법</h2>
<h3 id="불변객체immutable-object란">불변객체(<strong><strong>immutable object)</strong></strong>란?</h3>
<p>불변객체(immutable object)는 생성 후 그 상태를 바꿀 수 없는 객체를 말한다.</p>
<h3 id="생성-후-상태를-바꿀-수-없다는-것은-무슨-의미일까">생성 후 상태를 바꿀 수 없다는 것은 무슨 의미일까?</h3>
<p>이는 메모리 힙에서 그 객체가 가리키고 있는 데이터 자체의 변화가 불가능하다는 것을 의미한다!</p>
<p>(객체는 실제 데이터는 메모리에 저장하고 그 힙 영역을 가리키는 주소 값을 콜스텍에서 가지고 있다.)</p>
<h3 id="불변객체는-언제-사용할까">불변객체는 언제 사용할까?</h3>
<p>자바스크립트에서는 참조값인 객체의 내부 프로퍼티를 수정했을 때는 가변성이라는 성질로 인하여 기존의 객체도 변하게 된다.</p>
<p>객체를 복사해서, 프로퍼티를 변경하고 싶지만 원본객체는 유지하고 싶을 때 불변 객체를 만들어 사용할 수 있다.</p>
<h3 id="불변객체를-만드는-법">불변객체를 만드는 법</h3>
<p>불변 객체를 만드는 방법은 다양한데, 대표적으로 얕은 복사와 깊은 복사를 하는 방법이 있다.</p>
<p>불변객체로 만들어야 할 객체의 프로퍼티 값으로 또 다른 참조값이 들어가있다면 얕은 복사만으로는 불변 객체를 만들 수 없다.</p>
<p>깊은 복사를 할 경우 객체의 프로퍼티 값으로 들어가 있는 또 다른 참조값까지 복사할 수 있도록 재귀적으로 복사를 수행해야 완벽한 불변 객체를 만들 수 있다.</p>
<pre><code class="language-jsx">let example = {
    name : &quot;sjy&quot;,
    gender : &#39;female&#39;,
    friend : { 
        name : &quot;ldy&quot;
    }
}

let copyObject = function(target){
    let result = {};
    for(let prop in target){
        result[prop] = target[prop];
    }
    return result;
}

let example2 = copyObject(example);

example2.name = &quot;kim&quot;;
example2.friend.name = &quot;ldy2&quot;;

console.log(example === example2); // false
console.log(example.name, example2.name);// sjy kim
console.log(example.friend.name, example2.friend.name); // ldy ldy2 </code></pre>
<hr>
<h2 id="얕은-복사와-깊은-복사">얕은 복사와 깊은 복사</h2>
<h3 id="얕은-복사-shllow-copy">얕은 복사 (Shllow Copy)</h3>
<p>얕은 복사란 객체를 복사할 때 원본 객체의 프로퍼티 값과 복사된 객체의 프로퍼티 값이 같은 주소값을 가리키고있는 객체를 말한다. </p>
<p>객체의 프로퍼티 값으로 참조값이 있을 경우 이 프로퍼티가 원본 객체의 프로퍼티와 동일한 주소값을 참조하고 있다면 이를 <code>얕은 복사</code>라고 한다.</p>
<h3 id="얕은-복사-방법">얕은 복사 방법</h3>
<h3 id="⭐️-objectassign">⭐️ Object.assign()</h3>
<p>첫번째 인자로 전달한 객체에 다음인자로 들어온 객체의 프로퍼티를 복사한다.</p>
<pre><code class="language-jsx">const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = Object.assign({}, obj);

copiedObj.b.c = 3

obj === copiedObj // false
obj.b.c === copiedObj.b.c // true</code></pre>
<h3 id="⭐️-spread-연산자">⭐️ Spread 연산자</h3>
<pre><code class="language-jsx">const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = {...obj}

copiedObj.b.c = 3

obj === copiedObj // false
obj.b.c === copiedObj.b.c // true</code></pre>
<h3 id="깊은-복사-deep-copy">깊은 복사 (Deep Copy)</h3>
<p>깊은 복사란 객체를 복사할 때 원본 객체의 프로퍼티 값과 복사된 객체의 프로퍼티 값이 다른 주소값을 가리키고있는 객체를 말한다. </p>
<h3 id="⭐️-재귀함수를-이용한-복사">⭐️ 재귀함수를 이용한 복사</h3>
<pre><code>const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

function copyObj(obj) {
  const result = {};

  for (let key in obj) {
    if (typeof obj[key] === &#39;object&#39;) {
      result[key] = copyObj(obj[key]);
    } else {
      result[key] = obj[key];
    }
  }

  return result;
}

const copiedObj = copyObj(obj);

copiedObj.b.c = 3

obj.b.c === copiedObj.b.c //false</code></pre><h3 id="⭐️-jsonstringify">⭐️ JSON.stringify()</h3>
<p>JSON.stringify()는 객체를 json 문자열로 변환하는데 이과정에서 원본 객체와의 참조가 모두 끊어진다. 객체를 json 문자열로 변환후 JSON.parse()를 이용해 다시 자바스크립트 객체로 만들어주면 깊은 복사가 된다.</p>
<p>하지만 이방법은 사용하기는 쉽지만 다른 방법에비해 아주 느리다고 알려져있다.</p>
<pre><code>const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = JSON.parse(JSON.stringify(obj));

copiedObj.b.c = 3

obj.b.c === copiedObj.b.c //false</code></pre><h3 id="⭐️-라이브러리-사용">⭐️ 라이브러리 사용</h3>
<p><code>lodash</code> 라이브러리를 사용하면 깊은 복사를 더 쉽게 할 수 있다.</p>
<pre><code>const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = _.cloneDeep(obj);

copiedObj.b.c = 3

obj.b.c === copiedObj.b.c //false</code></pre><hr>
<h1 id="❓호이스팅과-tdz는-무엇일까-">❓호이스팅과 TDZ는 무엇일까 ?</h1>
<h3 id="호이스팅-tdz-스코프">호이스팅, TDZ, 스코프</h3>
<h3 id="호이스팅hoisting">호이스팅(Hoisting)</h3>
<p>호이스팅은 변수의 선언문을 유효 범위의 최상단으로 끌어올리는 행위이다!</p>
<h3 id="var-키워드로-선언한-변수는-선언-단계-와-초기화-단계-가-동시에-진행된다">v<strong>ar 키워드로 선언한 변수는 선언 단계 와 초기화 단계 가 동시에 진행된다.</strong></h3>
<p>var 키워드로 선언한 변수는 선언 단계 와 초기화 단계 가 동시에 진행된다.</p>
<p>코드 평가 시점에 환경 레코드에 식별자를 키로 등록한 다음, 암묵적으로 <code>undefined</code>를 바인딩한다.</p>
<p>이러한 이유로 <code>var</code>키워드로 선언한 변수는 코드 실행 단계에서 변수 선언문 이전에도 참조가 가능하다. 단, 변수 선언문 이전에 참조한 변수의 값은 언제나 <code>undefined</code>이다.</p>
<p><code>var</code> 키워드로 선언한 변수에 할당한 함수 표현식도 이와 동일하게 동작한다.</p>
<h3 id="함수-선언문으로-선언한-함수">함수 선언문으로 선언한 함수</h3>
<p>함수 선언문으로 정의한 함수가 평가되면 함수 이름과 동일한 이름의 식별자를 환경 레코드에 바인딩된 객체에 키로 등록하고 생성된 함수 객체를 즉시 값으로 할당한다.</p>
<p>⇒ <strong>이것이 함수 호이스팅이 발생하는 원인이다.</strong></p>
<p>함수 선언문으로 정의한 함수는 코드 실행 단계에서 함수 선언문 이전에도 호출가능하다.</p>
<h3 id="let-const-로-선언한-변수">let, const 로 선언한 변수</h3>
<p><strong><code>let</code>,<code>const</code></strong> 키워드로 선언한 전역 변수(<code>let</code>,<code>const</code> 키워드로 선언한 변수에 할당한 함수 표현식 포함)는 환경 레코드에 등록되고 관리된다.</p>
<p><code>let</code>, <code>const</code> 키워드로 선언한 변수는 전역 객체에서 선언되어도 전역 객체의 프로퍼티(Window의 프로퍼티)가 되지 않고 전역 환경 레코드의 선언적 환경 레코드에 등록되고 관리된다.</p>
<p><code>let</code>, <code>const</code> 키워드로 선언한 변수는 전역 객체의 프로퍼티가 되지 않기 때문에 전역객체의 프로퍼티로서 참조할 수 없다. </p>
<p><code>const</code> 키워드로 선언한 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.</p>
<p><code>let</code>, <code>const</code> 키워드로 선언한 변수도 변수 호이스팅이 발생하는 것은 변함이 없다.</p>
<p><code>let</code>, <code>const</code> 로 선언한 변수는 런타임에 초기화 단계, 즉 런타임에 실행 흐름이(컨트롤이) 변수 선언문에 도달하기 전까지 일시적 사각지대(TDZ[Temporal Dead Zone])에 빠지기 때문에 참조할 수 없고 참조 에러(ReferenceError)가 발생한다.</p>
<h3 id="스코프">스코프</h3>
<p><code>var</code> 키워드로 선언한 변수는 오로지 함수의 코드 블록만 지역 스코프로 인정하는 함수 레벨 스코프를 따른다.</p>
<p><code>let</code>,<code>const</code> 키워드로 선언한 변수는 모든 코드 블록(함수, if문, for문, while문, try/catch 문 등)을 지역 스코프로 인정하는 블록 레벨 스코프를 따른다.</p>
<blockquote>
<p>블록문이 실행되면 블록문의 코드 블록을 위한 블록 레벨 스코프를 생성해야 한다. 
이를 위해 선언적 환경 레코드를 갖는 렉시컬 환경을 새롭게 생성하여 기존의 전역 렉시컬 환경을 교체한다.
이때 새롭게 생성된 블록을 위한 렉시컬 환경의 외부 렉시컬 환경에 대한 참조는 블록문이 실행되기 이전의 전역 렉시컬 환경을 가리킨다.
블록문의 실행이 종료되면 블록문이 실행되기 이전의 렉시컬 환경으로 되돌린다.</p>
</blockquote>
<hr>
<h2 id="실행-컨텍스트와-콜-스택">실행 컨텍스트와 콜 스택</h2>
<h3 id="실행-컨텍스트">실행 컨텍스트</h3>
<p>실행 컨텍스트는 소스코드를 실행 하는 데 필요한 환경을 제공하고,
코드의 실행 결과를 실제로 관리하는 영역이다.</p>
<p>실행 컨텍스트는 식별자(변수, 함수, 클래스 등의 이름)를 등록하고 관리하는 스코프(렉시컬 환경)와 실행 순서 관리(실행 컨텍스트 스택)를 구현한 내부 메커니즘으로, </p>
<p>모든 코드는 실행 컨텍스트를 통해 실행되고 관리된다.</p>
<p>식별자를 찾을 때나 전역 객체의 프로퍼티를 찾을 때는 스코프 체인을 통해 스코프(실행 컨텍스트의 렉시컬 환경)를 검색하고,</p>
<p>객체의 프로퍼티를 찾을 때는 객체 생성시상속받은 프로토타입을 프로토타입 체인을 통해 검색한다.</p>
<p>생성된 실행 컨텍스트는 스택 자료구조로 관리된다. 이를 콜스텍이라 한다.</p>
<p>코드를 실행하면 코드가 실행되는 시간의 흐름에 따라 실행 컨텍스트 스택에는 실행 컨텍스트가 추가되고 제거된다.</p>
<p>콜스택은 코드의 실행 순서를 관리한다.</p>
<p>콜스택의 최상위에 존재하는 실행 컨텍스트는 언제나 현재 실행중인 코드의 실행 컨텍스트이다.</p>
<p>실행 컨텍스트 스택의 최상위에 존재하는 실행 컨텍스트를 실행 중인 실행 컨텍스트라 부른다.</p>
<hr>
<h2 id="스코프-체인-변수-은닉화">스코프 체인, 변수 은닉화</h2>
<h3 id="스코프-체인">스코프 체인</h3>
<p>자바스크립트 엔진은 코드 실행 중 식별자를 만나면 해당 함수 컴포넌트의 렉시컬 환경 컴포넌트의  환경 레코드에서 먼저 해당 식별자를 탐색하고, </p>
<p>없다면 해당 렉시컬 환경 컴포넌트의 외부 렉시컬 환경 참조 컴포넌트의 환경 레코드에서 탐색하고, 없다면  렉시컬 환경 컴포넌트의 외부 렉시컬 환경  참조 컴포넌트의 값이 null 이 될 때까지 해당 식별자를 찾는다.</p>
<p>스코프 체인의 종점인 전역 객체에서도 찾지 못해 외부 렉시컬 환경 참조 컴포넌트의 값이 null 이라면, 참조 오류를 반환한다.</p>
<h3 id="변수-은닉화">변수 은닉화</h3>
<p>직접적으로 변경되면 안 되는 변수에 대한 접근을 막는 것을 변수 은닉화라고 한다.</p>
<p>클로저를 통해 변수 은닉화를 할 수 있다.</p>
<p><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures">클로저는 무었일까?</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[ES6]]></title>
            <link>https://velog.io/@jen_jyseo/ES6</link>
            <guid>https://velog.io/@jen_jyseo/ES6</guid>
            <pubDate>Fri, 12 Aug 2022 14:45:51 GMT</pubDate>
            <description><![CDATA[<h3 id="ecmascript란">Ecmascript란?</h3>
<p>ECMAScript는 말 그대로 Ecma라는 기관이 만든 script 언어이며, <a href="https://en.wikipedia.org/wiki/ECMAScript">ECMA-262 표준</a>을 따르고 있다.</p>
<p>ECMA-262는 규격이며, ECMAScript는 ECMA-262에 의해 표준화된 자바스크립트의 새로운 이름이다.</p>
<p>따라서 ECMAScript가 표준 또는 언어규격이라는 말은 옳지 않다.</p>
<p>ECMAScript(=javascript)는 엄연히 프로그래밍 언어이며, <strong><em>ES6 표준을 따른다</em></strong> 라는 말은 <strong><em>ECMAScript 2015가 사용중인 ECMA 규격을 따른다</em></strong>, <strong><em>ECMAScript 2015과 동일한 문법을 사용한다</em></strong> 와 동의어라고 볼 수 있다.</p>
<h3 id="es6">ES6?</h3>
<p>ES6에서 추가된 문법들은 기존의 문제들을 매우 깔끔하게 해결했으며, </p>
<p>가독성 및 유지 보수성을 보강하는 문법도 대거 추가되었다.</p>
<p>ES6 표준 문법은 <a href="https://caniuse.com/?search=es6">IE에서 지원되지 않지만</a>, 트랜스파일러(Babel)를 이용해서 하위 문법을 따르는 코드로 쉽게 변경할 수 있기 때문에 호환성 문제도 없다.</p>
<p>ES6에서 추가된 기능으론 Promise, Class, Arrow function, async/await 등이 있다.</p>
<h3 id="es6-feature">ES6 feature</h3>
<ol>
<li>기본 매개 변수 (Default Parameters)</li>
<li>템플릿 리터럴 (Template Literals)</li>
<li>멀티 라인 문자열 (Multi-line Strings)</li>
<li>비구조화 할당 (Destructuring Assignment)</li>
<li>향상된 객체 리터럴 (Enhanced Object Literals)</li>
<li>화살표 함수 (Arrow Functions)</li>
<li>Promises</li>
<li>블록 범위 생성자 Let 및 Const (Block-Scoped Constructs Let and Const)</li>
<li>클래스 (Classes)</li>
<li>모듈 (Modules)</li>
</ol>
<p>참조:<a href="https://ui.toast.com/fe-guide/ko_ES5-TO-ES6">https://ui.toast.com/fe-guide/ko_ES5-TO-ES6</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Javascript 알고리즘 - 배열]]></title>
            <link>https://velog.io/@jen_jyseo/Javascript-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B0%B0%EC%97%B4</link>
            <guid>https://velog.io/@jen_jyseo/Javascript-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%B0%B0%EC%97%B4</guid>
            <pubDate>Fri, 12 Aug 2022 14:39:30 GMT</pubDate>
            <description><![CDATA[<h1 id="자바스크립트의-배열">자바스크립트의 배열</h1>
<ul>
<li><p><strong>추가</strong>와 <strong>삭제</strong>가 반복되는 로직이라면 배열 사용을 권장하지 않는다.</p>
</li>
<li><p>배열의 크기가 고정되어있지 않다.</p>
</li>
<li><p>배열의 인덱스로 숫자가 아닌 문자나 논리값이 들어갈 수 있다.</p>
<p>  (에러가 발생하지 않을 뿐... 들어갈 수는 있지만 length적용 X)</p>
<ul>
<li><p>숫자가 아닌 값을 인덱스로 대입한다면 해당 값은 자동으로 문자열로 변화된 키 값으로 평가된다.</p>
<p>  이는 자바스크립트 배열이 근본적으로 객체타입이기 때문이다.</p>
<p>  그렇지만 배열이 일반적인 객체와 다른 점은 length가 내부적으로 관리된다는 점이다.</p>
<p>  하지만 아래 코드와 같이 인덱스와 무관한 값을 인덱스로 사용한 경우 length에 영향을 미치지 않는다.</p>
</li>
</ul>
</li>
</ul>
<pre><code class="language-jsx">const arr = [];

arr[&quot;string&quot;] = 10;
arr[false] = 0;

console.log(arr.length) // 0</code></pre>
<h1 id="자바스크립트의-배열-함수">자바스크립트의 배열 함수</h1>
<h3 id="splice">splice</h3>
<ul>
<li>splice는 Big-O 표기법으로 <strong><strong>O(n):Linear Time(선형 시간)이다.</strong></strong></li>
</ul>
<h3 id="on--linear-time"><strong><strong>O(n) : Linear Time</strong></strong></h3>
<pre><code> O(n)은 입력 데이터의 크기에 비례해서 처리시간도 늘어나는 알고리즘을 표현할 때 사용합니다.</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[HTML - img (Image)]]></title>
            <link>https://velog.io/@jen_jyseo/HTML-img-Image</link>
            <guid>https://velog.io/@jen_jyseo/HTML-img-Image</guid>
            <pubDate>Fri, 12 Aug 2022 13:25:28 GMT</pubDate>
            <description><![CDATA[<h1 id="img">Img</h1>
<p>HTML 문서에 이미지를 넣고싶을 때 사용하는 태그</p>
<h2 id="반드시-함께-사용해야-할-태그">반드시 함께 사용해야 할 태그</h2>
<h3 id="1-srcsource">1. src(source)</h3>
<p>이미지 파일이 있는 상대 경로를 적거나</p>
<p>이미지가 있는 주소값(경로)를 대입한다.</p>
<h3 id="2altalternative-text대체-텍스트">2.alt(alternative text)(대체 텍스트)</h3>
<p>이미지가 HTML문서에 뜨지 않는 경우, 엑박을 보여주지 않고</p>
<p>“이 자리에는 원래 어떤 이미지가 있다” 라고 알려주는 대체 텍스트를 대입한다.</p>
<p>시각 장애가 있는 사용자들을 위해서 필수적으로 사용하는 속성이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML - em / strong / br]]></title>
            <link>https://velog.io/@jen_jyseo/HTML-em-strong-br</link>
            <guid>https://velog.io/@jen_jyseo/HTML-em-strong-br</guid>
            <pubDate>Fri, 12 Aug 2022 13:24:34 GMT</pubDate>
            <description><![CDATA[<p>태그의 디자인이 중요한 것이 아니라,</p>
<p>브라우저에게 메세지를 전달하는 것이 중요하다!</p>
<p>스타일적인 부분은 css로 바꿀 수 있다.</p>
<h2 id="속성">속성</h2>
<p>태그에 부가적인 정보를 준다.</p>
<h1 id="brbreak">br(break)</h1>
<p>한 문단 내에서 줄바꿈을 하고 싶을 때 사용하는 태그</p>
<p>남용해서는 안된다.</p>
<h1 id="em--strong">em / strong</h1>
<p>브라우저에게 이 부분이 중요하다는  의미를 전달하고 싶을 때 사용하는 태그</p>
<h1 id="aanchor">a(Anchor)</h1>
<p>현 위치에서 다른 위치로 이동하고 싶을 때 사용하는 태그</p>
<h2 id="syntax-alert">syntax alert</h2>
<p>a 태그 사용시 반드시 <strong>href 속성</strong>을 사용해야 한다.</p>
<h3 id="속성-hrefhypertext-reference">속성 href(hypertext reference)</h3>
<ul>
<li>hypertext ⇒ html 문서</li>
<li>reference ⇒ 주소 값</li>
</ul>
<hr>
<ul>
<li>href 속성에 이동하고자 하는 값을 적어줘야 링크로서 a태그를 제대로 사용할 수 있다.</li>
</ul>
<h3 id="href-주소값-표기-방법">href 주소값 표기 방법</h3>
<ol>
<li><p>웹 URL </p>
<p> → 절대 경로 혹은 상대 경로(이동하고자 하는 html문서의 위치 경로)</p>
</li>
<li><p>페이지 내 이동</p>
<p> → 페이지 내에 이동하고 싶은 부분의 id값 입력</p>
<pre><code class="language-html"> &lt;a href=&quot;#id&quot;&gt;&lt;/a&gt;</code></pre>
</li>
<li><p>메일 쓰기</p>
<p> → 메일 주소 앞에 mailto: 를 붙인 주소를 href의 값으로 입력한다.</p>
<pre><code class="language-html"> &lt;a href=&quot;mailto:jen.jyseo@gmail.com&quot;&gt;&lt;/a&gt;</code></pre>
</li>
<li><p>전화걸기</p>
<p> → 전화번호 앞에 tel: 을 붙인 주소를 href의 값으로 입력한다.</p>
<pre><code class="language-html"> &lt;a href=&quot;tel:01012345678&quot;&gt;&lt;/a&gt;</code></pre>
<hr>
</li>
</ol>
<h3 id="속성-target">속성 target</h3>
<p>기존의 페이지는 그대로 둔 상태로 새로운 탭이 열리고  새로운 탭에서 페이지로 이동하고자 할 때 target 속성의 값으로 “_blank”를 입력한다.</p>
<pre><code class="language-html">&lt;a href=&quot;&quot; target=&quot;_blank&quot;&gt;&lt;/a&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 46. 제너레이터와 async / await]]></title>
            <link>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-46.-async-await</link>
            <guid>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-46.-async-await</guid>
            <pubDate>Wed, 23 Feb 2022 15:33:32 GMT</pubDate>
            <description><![CDATA[<h1 id="async--await">async / await</h1>
<hr>
<h2 id="466-async--await">46.6 async / await</h2>
<blockquote>
<p><strong>async / await는 프로미스를 기반으로 동작한다.</strong>
<br><strong>async / await 를 사용하면 **
프로미스의 then/ catch/ finally 후속 처리 메서드에 콜백 함수를 전달해서 비동기 처리 결과를 후속 처리할 필요 없이
--&gt; 마치 동기 처리처럼 프로미스를 사용할 수 있다!
<br><span style="color:blue"></strong>다시 말해, 프로미스의 후속 처리 메서드 없이 
  --&gt; 마치 <span style="color:deeppink">동기 처리</span>처럼 프로미스가 처리 결과를 반환하도록 구현할 수 있다.</span>**</p>
</blockquote>
<hr>
<h3 id="4661-async-함수">46.6.1 async 함수</h3>
<blockquote>
<p><strong>await 키워드는 반드시 async 함수 내부에서 사용</strong>해야 한다.
<br><strong>async 함수는 async 키워드를 사용해 정의하며 언제나 프로미스를 반환</strong>한다.</p>
</blockquote>
<blockquote>
<p><strong>async함수가 명시적으로 프로미스를 반환하지 않더라도 **
**--&gt; async 함수는 암묵적으로 반환값을 resolve 하는 프로미스를 반환한다.</strong></p>
</blockquote>
<pre><code class="language-js">// async 함수 선언문
async function foo(n) {
  return n;
}

foo(1).then((v) =&gt; console.log(v));

//  async 함수 표현식
const bar = async function (n) {
  return n;
};

bar(2).then((v) =&gt; console.log(v));

// async 화살표 함수
const baz = async (n) =&gt; n;

baz(3).then((v) =&gt; console.log(v));

// async 메서드
const obj = {
  async foo(n) {
    return n;
  }
};

obj.foo(4).then((v) =&gt; console.log(v));

// async 클래스 메서드
class Myclass {
  async bar(n) {
    return n;
  }
}

const myClass = new Myclass();
myClass.bar(5).then((v) =&gt; console.log(v));
</code></pre>
<p>클래스의 constructor 메서드는 async 메서드가 될 수 없다.</p>
<p>클래스의 constructor 메서드는 인스턴스를 반환해야 하지만,
--&gt; async 함수는 언제나 프로미스를 반환해야 한다.</p>
<hr>
<h3 id="4462-await-키워드">44.6.2 await 키워드</h3>
<blockquote>
<p><strong>await 키워드</strong>는 <strong>프로미스가 settled상태(비동기 처리가 수행된 상태)가 될 때까지 대기</strong>하다가 
--&gt; <strong>settle 상태가 되면 프로미스가 resolve 한 처리 결과를 반환</strong>한다.
<br><strong>await 키워드</strong>는 반드시 <strong>프로미스 앞에서 사용</strong>해야 한다.</p>
</blockquote>
<blockquote>
<p><strong>await 키워드는 다음 실행을 중지시켰다가 
--&gt; 프로미스가 settled 상태가 되면 다시 재개한다.</strong></p>
</blockquote>
<hr>
<h3 id="4463-에러-처리">44.6.3 에러 처리</h3>
<blockquote>
<p>에러는 호출자 방향으로 전파된다.
<br>즉, 콜 스택의 아래 방향(실행중인 실행 컨텍스트가 푸시되기 직전에 푸시된 실행 컨텍스트 방향)으로 전파된다.</p>
</blockquote>
<p>하지만, 비동기 함수의 콜백 함수를 호출한 것은 비동기 함수가 아니기 때문에
--&gt; try, catch문을 사용해 에러를 캐치할 수 없다.
(비동기 함수의 콜백 함수를 호출한 것은 아마도 이벤트 루프..?)
(호출하여 콜스텍에 실행 컨텍스트가 생성된(push) 후 평가와 실행은 아마 자바스크립트 엔진이..?)</p>
<blockquote>
<p>async / await 에서 에러 처리는 
--&gt; try...catch 문을 사용할 수 있다.
<br>콜백 함수를 인수로 전달받는 비동기 함수와는 달리,
--&gt; 프로미스를 반환하는 비동기 함수는 명시적으로 호출할 수 있기 때문에 
--&gt; 호출자가 명확하다!</p>
</blockquote>
<pre><code class="language-js">const fetch = require(&quot;node-fetch&quot;);

const foo = async () =&gt; {
  try {
    const wrongUrl = &quot;https://wrong.url&quot;;

    const response = await fetch(wrongUrl);
    const data = await response.json;
    console.log(data);
  } catch (e) {
    console.error(e); // TypeError: Failed to fetch
  }
};
// foo 함수는 프로미스를 반환하는 비동기 함수인 
// async 함수로, 호출자가 명확하다!
foo(); 
</code></pre>
<p>위 예제의 foo 함수의 catch문은 HTTP통신에서 발생한 네트워크 에러뿐 아니라
--&gt;** try 코드 블록 내의 모든 문에서 발생한 일반적인 에러까지 모두 캐치**할 수 있다!</p>
<blockquote>
<p><strong>async 함수 내에서 catch 문을 사용해서 에러 처리를 하지 않으면,
async 함수는 발생한 에러를 reject하는 프로미스를 반환한다.</strong>
<br>따라서 async 함수를 호출하고 리턴된 프로미스 객체(발생한 에러를 reject하는)에
--&gt; Promise.prototype.catch 후속 처리 메서드를 사용해 에러를 캐치할 수도 있다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 45.  프로미스]]></title>
            <link>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-45.-%ED%94%84%EB%A1%9C%EB%AF%B8%EC%8A%A4</link>
            <guid>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-45.-%ED%94%84%EB%A1%9C%EB%AF%B8%EC%8A%A4</guid>
            <pubDate>Tue, 22 Feb 2022 05:38:47 GMT</pubDate>
            <description><![CDATA[<h1 id="프로미스">프로미스</h1>
<p>프로미스는 전통적인 콜백 패턴이 가진 단점을 보완하며 비동기 처리 시점을 명확하게 표현할 수 있다는 장점이 있다.</p>
<hr>
<h2 id="451-비동기-처리를-위한-콜백-패턴의-단점">45.1 비동기 처리를 위한 콜백 패턴의 단점</h2>
<h3 id="4511-콜백-헬">45.1.1 콜백 헬</h3>
<p>비동기 함수란 함수 내부에 비동기로 동작하는 코드를 포함한 함수를 말한다.</p>
<p>비동기 함수를 호출하면 함수 내부의 비동기로 동작하는 코드가 완료되지 않았다 해도 기다리지 않고 즉시 종료된다.</p>
<p><strong>즉, 비동기 함수 내부의 비동기로 동작하는 코드는 비동기 함수가 종료된 이후에 완료된다.</strong></p>
<p>비동기 함수 내부의 비동기로 동작하는 코드는 비동기 함수가 종료된 이후에 완료되기 때문에,
비동기 함수는 비동기 처리 결과를 외부에 반환할 수 없고, 상위 스코프의 변수에 할당할 수도 없다.</p>
<p>따라서 <strong><span style="color:blue">비동기 함수의 처리 결과</span>(서버의 응답(response객체) 등)에 대한</strong> 
<strong><span style="color:blue">--&gt; 후속 처리는 <span style="color:red">비동기 함수 내부</span>에서 수행</span>해야 한다.</strong></p>
<p>비동기 함수를 범용적으로 사용하기 위해 비동기 함수에 <strong>비동기 처리 결과에 대한 후속 처리를 수행하는 콜백 함수를 전달하는 것이 일반적</strong>이다.</p>
<p>하지만 콜백 함수를 통해 비동기 처리 결과에 대한 후속 처리를 수행하는 비동기 함수가 비동기 처리 결과를 가지고 또 다시 비동기 함수를 호출해야 한다면 
콜백 함수 호출이 중첩되어 복잡도가 높아지는 현상이 발생하는데,
이를** 콜백 헬**이라고 한다.</p>
<hr>
<h2 id="452-프로미스의-생성">45.2 프로미스의 생성</h2>
<p>Promise 생성자 함수를 new 연산자와 함께 호출하면 프로미스(Promise 객체)를 생성한다.</p>
<p>Promise는 <a href="https://poiemaweb.com/js-built-in-object">호스트 객체</a>가 아닌 ECMAScript 사양에 정의된 <a href="https://poiemaweb.com/js-built-in-object">표준 빌트인 객체</a>다.</p>
<p>Promise 생성자 함수는 <strong>비동기 처리를 수행할 콜백 함수를 인수로 전달</strong>받는데 이 <strong>콜백 함수는 resolve와 reject함수를 인수로 전달받는다.</strong></p>
<p>Promise 생성자 함수가 인수로 전달받은 콜백 함수 내부에서 비동기 처리를 수행한다.</p>
<p>이때 비동기 처리가 성공하면,
콜백 함수의 인수로 전달받은 resolve함수를 호출하고,</p>
<p>비동기 처리가 실패하면,
reject 함수를 호출한다.</p>
<p>비동기 처리는 Promise 생성자 함수가 인수로 전달받은 콜백 함수 내부에서 수행한다.</p>
<hr>
<p>프로미스는 다음과 같이 
현재 비동기 처리가 어떻게 진행되고 있는지를 나타내는 <strong>상태 정보</strong>를 갖는다.</p>
<table>
<thead>
<tr>
<th align="center">프로미스의 상태 정보</th>
<th align="center">의미</th>
<th align="center">상태 변경 조건</th>
</tr>
</thead>
<tbody><tr>
<td align="center">pending</td>
<td align="center">비동기 처리가 아직 수행되지 않은 상태</td>
<td align="center">프로미스가 생성된 직후 기본 상태</td>
</tr>
<tr>
<td align="center">fulfilled</td>
<td align="center">비동기 처리가 수행된 상태(성공)</td>
<td align="center">resolve 함수 호출</td>
</tr>
<tr>
<td align="center">rejected</td>
<td align="center">비동기 처리가 수행된 상태(실패)</td>
<td align="center">reject 함수 호출</td>
</tr>
</tbody></table>
<p>생성된 직후의 프로미스는 기본적으로 pending 상태다.</p>
<p>이후 비동기 처리가 수행되면 비동기 처리 결과에 따라 다음과 같이 프로미스의 상태가 변경된다.</p>
<hr>
<p><strong>생성된 직후의 프로미스는 기본적으로 pending 상태</strong>이다.</p>
<p>이후 <strong>비동기 처리가 수행되면 비동기 처리 결과에 따라 다음과 같이 프로미스의 상태가 변경</strong>된다.</p>
<blockquote>
<ul>
<li><strong>비동기 처리 성공</strong>: resolve 함수를 호출해 프로미스를 fulfilled 상태로 변경한다.</li>
</ul>
</blockquote>
<ul>
<li><strong>비동기 처리 실패</strong>: reject 함수를 호출해 프로미스를 rejected 상태로 변경한다.</li>
</ul>
<p>**<span style="color:red">--&gt; 이처럼 프로미스의 상태는 resolve 또는 reject 함수를 호출하는 것으로 결정된다!</span>
**</p>
<hr>
<p>fulfilled 또는 rejected 상태를 settled 상태라고 한다.</p>
<p><strong>setteled</strong> 상태는 fulfilled 또는 reject 상태와 상관없이 
--&gt; <strong>pending이 아닌 상태로 비동기 처리가 수행된 상태</strong>를 말한다.</p>
<p>프로미스는 pending 상태에서 fulfilled 또는 rejected상태,
즉 settled 상태가 되면 더는 다른 상태로 변화할 수 없다.</p>
<hr>
<p>프로미스는 비동기 처리 상태와 더불어 비동기 처리 결과도 상태로 갖는다.</p>
<p>비동기 처리가 성공하면 프로미스는 pending 상태에서 fulfilled상태로 변화한다.
그리고 비동기 처리 결과를 값으로 갖는다.</p>
<p>비동기 처리가 실패하면 프로미스는 pending 상태에서 rejected 상태로 변화한다.
그리고 비동기 처리 결과를 값으로 갖는다.</p>
<p>즉,** <span style="color:blue">프로미스는 비동기 처리 상태와 처리 결과를 관리하는 <span style="color:red">객체</span></span>**다.</p>
<hr>
<h2 id="453-프로미스의-후속-처리-메서드">45.3 프로미스의 후속 처리 메서드</h2>
<p>프로미스의 비동기 처리 상태가 변화하면 이에 따른 후속 처리를 해야 한다.</p>
<p>이를 위해 <strong>프로미스는 후속 메서드 then, catch, finally를 제공한다.</strong></p>
<p><strong>프로미스의 비동기 처리 상태가 변화하면 후속 처리 메서드에 인수로 전달한 콜백 함수가 선택적으로 호출된다.</strong></p>
<p>이때 <strong>후속 처리 메서드의 콜백 함수에 프로미스의 처리 결과가 인수로 전달된다.</strong></p>
<blockquote>
<p><strong>모든 후속 처리 메서드(then, catch, finally)는 <span style="color:deeppink">
  --&gt;프로미스 객체를 반환하며!
--&gt;비동기로 동작한다!</strong></span></p>
</blockquote>
<hr>
<h3 id="💡-프로미스의-후속-처리-메서드">💡 프로미스의 후속 처리 메서드</h3>
<h3 id="4531-promiseprototypethen">45.3.1 Promise.prototype.then</h3>
<p>then 메서드는 콜백 함수를 인수로 전달받는다.</p>
<blockquote>
<p><strong>첫 번째 콜백 함수</strong>는 
--&gt; <strong>비동기 처리가 성공했을 때 호출되는 성공 처리 콜백함수이다.</strong>
<br>첫 번째 콜백 함수는 <strong>프로미스가 fulfilled 상태(resolve함수가 호출된 상태)가 되면 호출된다.</strong>
<br>이때 <strong>콜백 함수는 **
--&gt; **프로미스의 비동기 처리 결과 (resolve함수의 인수로 전달된 비동기 처리 결과)를 인수로 전달받는다.</strong></p>
</blockquote>
<hr>
<p><strong><span style="color:blue">then 메서드는 언제나 프로미스를 반환한다.</span></strong>
만약 then 메서드의 콜백 함수가 프로미스를 반환하면, 
--&gt; 그 프로미스를 그대로 반환하고</p>
<p>콜백 함수가 프로미스가 아닌 값을 반환하면 
--&gt; 그 값을 암묵적으로 resolve 또는 reject 하여 프로미스를 생성해 반환한다.</p>
<h3 id="4532-promiseprototypecatch">45.3.2 Promise.prototype.catch</h3>
<p>catch 메서드는 한 개의 콜백 함수를 인수로 전달받는다.</p>
<blockquote>
<p><strong>catch 메서드의 콜백 함수는 프로미스가 rejected 상태인 경우만 호출된다.</strong>
<br>*<em>catch 메서드는 *</em>then 메서드와 마찬가지로 *<em>언제나 프로미스를 반환한다.
*</em></p>
</blockquote>
<h3 id="4533-promiseprototypefinailly">45.3.3 Promise.prototype.finailly</h3>
<p>finally 메서드는 한 개의 콜백 함수를 인수로 전달받는다.</p>
<blockquote>
<p>finally 메서드의 콜백 함수는 
<strong>--&gt; 프로미스의 성공(fulfilled)또는 실패(rejected)와 상관 없이 무조건 한 번 호출된다.</strong>
<br>finally 메서드의 콜백 함수는 <strong>프로미스의 상태와 상관없이 공통적으로 수행해야 할 처리 내용이 있을 때 유용하다.</strong>
<br>finally 메서드도 then/catch메서드와 마찬가지로 
<strong>--&gt; 언제나 프로미스를 반환한다.</strong></p>
</blockquote>
<hr>
<h3 id="454-프로미스의-에러-처리">45.4 프로미스의 에러 처리</h3>
<p>비동기 처리 결과에 대한 후속 처리는 프로미스가 제공하는 후속 처리 메서드 then, catch, finally를 사용하여 수행한다.</p>
<blockquote>
<p><strong>비동기 처리에서 발생한 에러</strong>는 
--&gt; 프로미스의 후속 처리 메서드 <strong>catch를 사용해 처리</strong>할 수 있다.</p>
</blockquote>
<blockquote>
<p>catch 메서드를 모든 then 메서드를 호출한 이후에 호출하면
--&gt; 비동기 처리에서 발생한 에러(rejected 상태)뿐만 아니라 then 메서드 내부에서 발생한 에러까지 모두 캐치할 수 있다.
<br>따라서 예외 처리는 then 메서드에서 하지 말고 
--&gt; catch 메서드에서 하는 것을 권장한다.</p>
</blockquote>
<hr>
<h3 id="455-프로미스-체이닝">45.5 프로미스 체이닝</h3>
<p>프로미스는 then, catch, finally 후속 처리 메서드를 통해 콜백 헬을 해결한다.</p>
<p>then, catch, finally 후속 처리 메서드는 언제나 프로미스를 반환하므로
--&gt; 연속적으로 호출할 수 있다.
--&gt; 이를 <span style="color:blue"><strong>프로미스 체이닝</strong></span>이라 한다.</p>
<hr>
<p>후속 처리 메서드의 콜백 함수는 프로미스의 비동기 처리 상태가 변경되면 선택적으로 호출된다.</p>
<blockquote>
<h4 id="⭐️-후속-처리-메서드의-콜백-함수가-span-stylecolorblue명시적으로-반환한-값span이-없다면">⭐️ 후속 처리 메서드의 콜백 함수가 <span style="color:blue">명시적으로 반환한 값</span>이 없다면?!</h4>
<p><strong>--&gt; 콜백 함수는 <span style="color:blue">undefined를 반환</span>한다!</strong>
<br><strong>후속 처리 메서드는 
<span style="color:deeppink">--&gt; 콜백 함수가 반환한 값인 undefined를 resolve 한 프로미스 객체를 반환한다!</span></strong></p>
</blockquote>
<pre><code class="language-js">// console.log()메서드는 값을 return을 해주는 함수가 아니기 때문에,
// undefined를 리턴한다.
.then(resolve =&gt; console.log(resolve))
.then(console.log); // undefined</code></pre>
<p>이처럼 then, catch, finally 후속 처리 메서드는 
--&gt; 콜백 함수가 반환한 프로미스를 반환한다.</p>
<blockquote>
<p>만약 <strong>콜백 함수가 <span style="color:deeppink">프로미스가 아닌 값을 반환</span>하더라도</strong>
<strong>--&gt; 그 <span style="color:blue">값을 암묵적으로 resolve 또는 reject하여 프로미스 객체를 생성해 반환</span>한다!</strong></p>
</blockquote>
<hr>
<p>프로미스는 프로미스 체이닝을 통해 비동기 처리 결과를 전달받아 후속 처리를 하므로, 콜백 헬이 발생하지 않는다.</p>
<p>다만 <strong>프로미스도 콜백 패턴을 사용하므로 콜백 함수를 사용하지 않는 것은 아니다.</strong></p>
<p><strong>async / await 를 사용하면 프로미스의 후속 처리 메서드 없이 마치 동기처럼 프로미스가 처리 결과를 반환하도록 구현할 수 있다!</strong></p>
<hr>
<h2 id="456-프로미스의-정적-메서드">45.6 프로미스의 정적 메서드</h2>
<p>Promise 는 주로 생성자 함수로 사용되지만, 
함수도 객체이므로 메서드를 가질 수 있다.</p>
<p>Promise는 5가지 정적 메서드를 제공한다.</p>
<h3 id="4561-promiseresolve--promisereject">45.6.1 Promise.resolve / Promise.reject</h3>
<blockquote>
<p>Promise.resolve 와 Promise.reject 메서드는 <strong>이미 존재하는 값을 래핑하여 프로미스를 생성하기 위해 사용</strong>한다.</p>
</blockquote>
<hr>
<blockquote>
<p><strong>Promise.resolve 메서드</strong>는 
--&gt; <strong>인수로 전달받은 값을 resolve 하는 프로미스 객체를 생성한다.</strong></p>
</blockquote>
<pre><code class="language-js">// 배열을 resolve 하는 프로미스 객체를 생성
const resolvedPromise = Promise.resolve([1, 2, 3]);
resolvedPromise.then(console.log); // [1, 2, 3]
</code></pre>
<p>위의 예제는 아래의 예제와 동일하게 동작한다.</p>
<pre><code class="language-js">// 배열을 resolve 하는 프로미스 객체를 생성
const resolvedPromise = new Promise((resolve) =&gt; resolve([1, 2, 3]));

resolvedPromise.then(console.log); // [1, 2, 3]</code></pre>
<hr>
<blockquote>
<p>Promise.reject 메서드는 인수로 전달받은 값을 reject하는 프로미스를 생성한다.</p>
</blockquote>
<pre><code class="language-js">// 에러 객체를 reject 하는 프로미스를 생성
const rejectedPromise = Promise.reject(new Error(&quot;Error!&quot;));

rejectedPromise.catch(console.log); // Error: Error!
</code></pre>
<p>위의 예제는 아래의 예제와 동일하게 동작한다.</p>
<pre><code class="language-js">// 에러 객체를 reject 하는 프로미스를 생성
const rejectedPromise = new Promise((_, reject) =&gt; reject(new Error(&quot;Error!&quot;)));

rejectedPromise.catch(console.log); // Error: Error!</code></pre>
<hr>
<h3 id="4562-promiseall">45.6.2 Promise.all</h3>
<blockquote>
<p>Promise.all 메서드는 여러 개의 비동기 처리를 모두 병렬 처리할 때 사용한다.</p>
</blockquote>
<p>앞선 비동기 처리 결과를 다음 비동기 처리가 사용하지 않는 경우 
--&gt; 비동기 처리를 순차적으로 처리할 필요가 없다!</p>
<blockquote>
<p><strong>Promise.all 메서드는 프로미스를 요소로 갖는 배열 등의 이터러블을 인수로 전달받는다.</strong>
<br>그리고 <strong>전달받은 모든 프로미스가 모두 fulfilled(resolve) 상태가 되면
--&gt; 모든 처리 결과를 배열에 저장해 새로운 프로미스 객체를 반환한다.</strong>
<br>Promise.all 메서드가 <strong>종료하는데 걸리는 시간</strong>은 
<strong>--&gt; 가장 늦게 fulfilled 상태가 되는 프로미스 객체의 처리 시간보다 조금 더 길다!</strong></p>
</blockquote>
<blockquote>
<p><strong>Promise.all의 인수로 전달된 배열의 요소인 모든 프로미스가 
fulfilled 상태가 되면,
--&gt; resolve된 처리 결과를 모두 배열에 저장해 새로운 프로미스를 반환한다.</strong>
<br>이때, 첫 번째 요소인 프로미스 객체가 가장 나중에 fulfilled 상태가 되어도
--&gt; Promise.all 메서드는 첫 번째 프로미스가 resolve한 처리 결과부터 차례대로 배열에 저장해 그 배열을 resolve하는 새로운 프로미스를 반환한다. 
<br>즉, <span style="color:deeppink"><strong>처리 순서가 보장된다!</strong></span></p>
</blockquote>
<blockquote>
<p>Promise.all 메서드는 인수로 전달받은 <strong>배열의 프로미스 객체가 하나라도 
reject 상태가 되면</strong>
<strong>--&gt; 나머지 프로미스가 fulfilled 상태가 되는 것을 기다리지 않고 즉시 종료한다.</strong></p>
</blockquote>
<p>💡 아래 예제의 경우 세 번째 프로미스가 가장 먼저 rejected 상태가 되므로 
--&gt; 세 번째 프로미스가 reject한 에러가 catch 메서드로 전달된다.</p>
<pre><code class="language-js">Promise.all([
  new Promise((_, reject) =&gt;
    setTimeout(() =&gt; reject(new Error(&quot;Error 1&quot;)), 3000)
  ),
  new Promise((_, reject) =&gt;
    setTimeout(() =&gt; reject(new Error(&quot;Error 2&quot;)), 2000)
  ),
  new Promise((_, reject) =&gt;
    setTimeout(() =&gt; reject(new Error(&quot;Error 3&quot;)), 1000)
  )
])
  .then(console.log)
  .catch(console.log); // Error: Error 3
</code></pre>
<blockquote>
<p>Promise.all 메서드는 인수로 전달받은 이터러블의 요소가 프로미스가 아닌 경우
--&gt; Promise.resolve 메서드를 통해 프로미스로 래핑한다.</p>
</blockquote>
<pre><code class="language-js">Promise.all([
  1, // -&gt; Promise.resolve(1)
  2, // -&gt; Promise.resolve(2)
  3 // -&gt; Promise.resolve(3)
])
  .then(console.log) // [1, 2, 3]
  .catch(console.log);
</code></pre>
<hr>
<h3 id="4563-promiserace">45.6.3 Promise.race</h3>
<blockquote>
<p><strong>Promise.race 메서드는</strong> Promise.all 메서드와 동일하게
<strong>프로미스를 요소로 갖는 배열 등의 이터러블을 인수로 전달받는다.</strong>
<br>Promise.race 메서드는 Promise.all 메서드처럼 모든 프로미스가 fulfilled 상태가 되는 것을 기다리는 것이 아니라,
<br><strong>--&gt; 가장 먼저 fulfilled 상태가 된 프로미스의 처리 결과를 resolve하는 
새로운 프로미스를 반환한다.</strong></p>
</blockquote>
<pre><code class="language-js">Promise.race([
  new Promise((resolve) =&gt; setTimeout(() =&gt; resolve(1), 3000)), // 1
  new Promise((resolve) =&gt; setTimeout(() =&gt; resolve(2), 2000)), // 2
  new Promise((resolve) =&gt; setTimeout(() =&gt; resolve(3), 1000)) // 3
])
  .then(console.log) // 3
  .catch(console.error);
</code></pre>
<blockquote>
<p>프로미스가 rejected 상태가 되면 Promise.all 메서드와 동일하게 처리된다.
<br>즉, Promise.race 메서드에 전달된 프로미스가 하나라도 rejected 상태가 되면
--&gt; 에러를 reject하는 새로운 프로미스를 즉시 반환한다.</p>
</blockquote>
<pre><code class="language-js">Promise.race([
  new Promise((_, reject) =&gt;
    setTimeout(() =&gt; reject(new Error(&quot;Error 1&quot;)), 3000)
  ),
  new Promise((_, reject) =&gt;
    setTimeout(() =&gt; reject(new Error(&quot;Error 2&quot;)), 2000)
  ),
  new Promise((_, reject) =&gt;
    setTimeout(() =&gt; reject(new Error(&quot;Error 3&quot;)), 1000)
  )
])
  .then(console.log)
  .catch(console.log); // Error: Error 3
</code></pre>
<hr>
<h3 id="4564-promiseallsettled">45.6.4 Promise.allSettled</h3>
<blockquote>
<p>Promise.allSettled 메서드는 
--&gt; 프로미스를 요소로 갖는 배열 등의 이터러블을 인수로 전달받는다.
<br>그리고 전달받은 프로미스가 모두 
settled 상태 --&gt; (비동기 처리가 수행된 상태, 즉 fulfilled 또는 rejected 상태) 가 되면 처리 결과를 배열로 반환한다.</p>
</blockquote>
<pre><code class="language-js">Promise.allSettled([
  new Promise((resolve) =&gt; setTimeout(() =&gt; resolve(1), 1000)),
  new Promise((_, reject) =&gt;
    setTimeout(() =&gt; reject(new Error(&quot;Error!&quot;)), 1000)
  )
]).then(console.log);
// [Object, Object]
// 0: Object
// status: &quot;fulfilled&quot;
// value: 1
// 1: Object
// status: &quot;rejected&quot;
// reason:
// Error: Error!
</code></pre>
<blockquote>
<p>Promise.allSettled 메서드가** 반환한 배열<strong>에는 
*<em>--&gt; fulfilled 또는 rejected 상태와는 상관없이 *</em>
<br></strong>Promise.allSettled 메서드가 인수로 전달받은 배열의
--&gt; 모든 프로미스 객체들의 처리 결과가 모두 담겨 있다.**</p>
</blockquote>
<blockquote>
<p><strong>프로미스의 처리 결과를 나타내는 객체</strong></p>
</blockquote>
<ul>
<li>프로미스가 fulfilled 상태인 경우 </li>
<li>-&gt; 비동기 처리 상태를 나타내는 status 프로퍼티와, 처리 결과를 나타내는 value 프로퍼티를 갖는다.</li>
<li>프로미스가 rejected 상태인 경우</li>
<li>-&gt; 비동기 처리 상태를 나타내는 status 프로퍼티와, 에러를 나타내는 reason 프로퍼티를 갖는다.</li>
</ul>
<p>💡Promise.allsettled 메서드의 인자로 전달받은 배열의 요소인 프로미스가 모두 
--&gt; settled 상태가 되면 처리 결과를 객체로 반환한 요소를 담은 배열을 반환한다.</p>
<pre><code class="language-js">[
  // 프로미스가 fulfilled 상태인 경우
  { status: &quot;fulfilled&quot;, value: 1 },
  // 프로미스가 rejected 상태인 경우
  { status: &quot;rejected&quot;, reason: &quot;Error: Error!&quot; }
]
</code></pre>
<hr>
<h2 id="457-마이크로태스크-큐">45.7 마이크로태스크 큐</h2>
<pre><code class="language-js">setTimeout(() =&gt; console.log(1), 0);
// setTimeout의 콜백이 태스크 큐에 제일 먼저 쌓여있다.
// 콜스텍이 빌 때까지 콜백은 태스크 큐에서 대기한다.

Promise.resolve()
  .then(() =&gt; console.log(2))
  .then(() =&gt; console.log(3));
// -&gt; 2, 3, 1</code></pre>
<p>프로미스의 후속 처리 메서드도 비동기로 동작하므로
--&gt;1 -&gt; 2 -&gt; 3 의 순서로 출력될 것처럼 보이지만!
--&gt; 2 -&gt; 3 -&gt; 1 의 순으로 출력된다!</p>
<p>그 이유는 <strong><span style="color:blue">프로미스의 후속 처리 메서드(then, catch, finally)의 <span style="color:deeppink">콜백 함수</span></span></strong>는
<strong>--&gt; 태스크 큐가 아니라 <span style="color:deeppink">마이크로태스크 큐에 저장되기 때문이다!</span></strong></p>
<blockquote>
<h4 id="💡-마이크로태스크-큐">💡 마이크로태스크 큐</h4>
<p>마이크로태스크 큐는 별도의 큐다.
<br>마이크로태스크 큐에는 프로미스의 후속 처리 메서드의 콜백 함수가 일시 저장된다.
<br>그 외의 비동기 함수의 콜백 함수나 이벤트 핸들러는 태스크 큐에 일시 저장된다.</p>
</blockquote>
<blockquote>
<p><strong><span style="color:deeppink">마이크로태스크 큐는 태스크 큐보다 우선순위가 높다.</span></strong>
<br>즉, 이벤트 루프는 콜 스택이 비면 
--&gt; 먼저 마이크로태스크 큐에서 대기하고 있는 함수를 가져와 실행한다.
<br>이후 마이크로태스크 큐가 비면 
--&gt; 태스크 큐에서 대기하고 있는 함수를 가져와 실행한다.</p>
</blockquote>
<hr>
<h2 id="458-fetch">45.8 fetch</h2>
<blockquote>
<p><strong>fetch 함수</strong>는 XMLHttpRequest 객체와 마찬가지로 
--&gt; <strong>HTTP 요청 전송 기능을 제공하는 클라이언트 사이드 Web API다.</strong>
<br><strong>fetch 함수</strong>는 XHLHttpRequest 객체보다 사용법이 간단하고,
<strong>프로미스를 지원</strong>하기 때문에 <strong>비동기 처리를 위한 콜백 패턴의 단점에서 자유롭다.</strong></p>
</blockquote>
<blockquote>
<p><strong>fetch 함수</strong>에는 
--&gt; <strong>HTTP 요청을 전송할 URL</strong>을 <strong>첫 번째 인자</strong>로 전달하고
--&gt; <strong>HTTP 요청 메서드, HTTP 요청 헤더, 페이로드 등을 설정한 객체</strong>를 <strong>두 번째 인자</strong>로 전달한다.(옵션)</p>
</blockquote>
<pre><code class="language-js">const promise = fetch(url[, options])</code></pre>
<hr>
<blockquote>
<p><strong>fetch 함수</strong>는 
--&gt; <strong>HTTP 응답을 나타내는 Response 객체를 래핑한 Promise 객체를 반환</strong>한다.</p>
</blockquote>
<p>fetch 함수는 HTTP 응답을 나타내는 Response 객체를 래핑한 프로미스를 반환하므로 
후속 처리 메서드 then을 통해 프로미스가 resolve한 Response 객체를 전달받을 수 있다.</p>
<p><strong><span style="color:deeppink">Response 객체는 HTTP 응답을 나타내는 다양한 프로퍼티를 제공한다.</span></strong></p>
<blockquote>
<p><strong>Resopnse.prototype 에는</strong>
--&gt; <strong>Response 객체에 포함되어 있는 HTTP 응답 몸체를 위한 다양한 메서드를 제공</strong>한다.</p>
</blockquote>
<p>예를 들어, fetch 함수가 반환한 프로미스가 래핑하고 있는 MIME 타입이 application/json인 HTTP응답 몸체를 취득하면
--&gt; Response.prototype.json 메서드를 사용한다.</p>
<blockquote>
<p><strong>Response.prototype.json 메서드</strong>는 
--&gt; <strong>Response 객체에서 HTTP 응답 몸체를 취득하여 역직렬화 한다.</strong></p>
</blockquote>
<hr>
<p>p. 866 - fetch 요청 해보기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 42.비동기 프로그래밍]]></title>
            <link>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-42.%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
            <guid>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-42.%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</guid>
            <pubDate>Mon, 21 Feb 2022 12:13:34 GMT</pubDate>
            <description><![CDATA[<h1 id="비동기-프로그래밍">비동기 프로그래밍</h1>
<hr>
<h2 id="421-동기-처리와-비동기-처리">42.1 동기 처리와 비동기 처리</h2>
<p>실행 컨텍스트 스텍에 함수 실행 컨텍스트가 푸시되는 것은 바로 함수 실행의 시작을 의미한다.
함수가 호출된 순서대로 순차적으로 실행되는 이유는
함수가 호출된 순서대로 함수 실행 컨텍스트가 실행 컨텍스트 스택에 푸시되기 때문이다.
이처럼 함수 실행 순서는 실행 컨텍스트 스택으로 관리한다.</p>
<p><strong>자바스크립트는 단 하나의 실행 컨텍스트 스택을 갖는다.</strong>
이는 함수를 실행할 수 있는 창구가 단 하나이며,
<strong>동시에 2개 이상의 함수를 실행할 수 없다는 것을 의미한다</strong>.</p>
<p>자바스크립트 엔진은 한 번에 하나의 테스크만 실행할 수 있는 싱글 스레드 방식으로 동작한다.</p>
<p>싱글 스레드 방식은 한 번에 하나의 테스크만 실행할 수 있기 때문에 처리에 시간이 걸리는 테스크를 실행하는 경우 블로킹(작업 중단)이 발생한다.</p>
<blockquote>
<p><strong>현재 실행 중인 테스크가 종료할 때까지 
다음에 실행될 태스크가 대기하는 방식을 동기(synchronous)처리 라고 한다.</strong><br>동기 처리 방식은 태스크를 순서대로 하나씩 처리하므로 실행 순서가 보장된다는 장점이 있지만,
<strong>앞선 태스크가 종료할 때까지 이후 태스크들이 블로킹되는 단점이 있다.</strong></p>
</blockquote>
<hr>
<blockquote>
<p><strong>현재 실행 중인 태스크가 종료되지 않은 상태라 해도 
 다음 태스크를 곧바로 실행하는 방식을 비동기(asynchronous) 처리</strong>라고 한다.<br><br>비동기 처리 방식은 현재 실행 중인 태스크가 종료되지 않은 상태라 해도 다음 태스크를 곧바로 실행하므로 <strong>블로킹이 발생하지 않는다는 장점</strong>이 있지만,
<br><strong>태스크의 실행 순서가 보장되지 않는다는 단점</strong>이있다.</p>
</blockquote>
<p>비동기 처리를 수행하는 비동기 함수는 전통적으로 콜백 패턴을 사용한다.
하지만 <strong>비동기 처리를 위한 콜백 패턴은 콜백 헬을 발생</strong>시켜 가독성을 나쁘게 하고,
비동기 처리 중 발생한 에러의 예외 처리가 곤란하며,
여러개의 비동기 처리를 한 번에 처리하는 데도 한계가 있다.</p>
<p><strong>타이머 함수인 setTimeout과 setInterval, HTTP요청, 이벤트 핸들러는 비동기 처리 방식으로 동작한다</strong>.</p>
<hr>
<h2 id="422-이벤트-루프와-테스크-큐">42.2 이벤트 루프와 테스크 큐</h2>
<p><strong>자바스크립트의 동시성을 지원하는 것이 바로 이벤트 루프이다.</strong></p>
<p>이벤트 루프는 브라우저에 내장되어 있는 기능 중 하나이다.</p>
<hr>
<p>대부분의 <strong>자바스크립트 엔진은 크게 2개의 영역으로 구분할 수 있다.</strong></p>
<h4 id="자바스크립트-엔진">자바스크립트 엔진</h4>
<p><strong>1.콜 스택(call stack)</strong>
소스코드(전역 코드나 함수 코드 등)평가 과정에서 생성된 실행 컨텍스트가 추가되고 제거되는 스택 자료구조인 실행 컨텍스트 스텍이 바로 콜스텍이다!

자바스크립트 엔진은 단 하나의 콜 스택을 사용하기 때문에 최상위 실행 컨텍스트(실행 중인 실행 컨텍스트)가 종료되어 콜 스택에서 제거되기 전까지는 다른 어떤 태스크도 실행되지 않는다.</p>
<blockquote>
<p><strong>원시 타입 데이터 또한 콜스텍에 저장된다.
<br>메모리 힙에 저장된 참조 데이터의 주소값도 콜스텍에 저장된다!</strong></p>
</blockquote>
<ol start="2">
<li>힙(heap)
힙은 객체(참조 데이터)가 저장되는 메모리 공간이다.</li>
</ol>
<blockquote>
<p><strong>콜 스텍의 요소인 실행 컨텍스트는 힙에 저장된 객체를 참조한다.</strong>
**<span style="color:red">(실행 컨텍스트의 렉시컬 환경의 환경 레코드에 저장된 식별자에는 
메모리 힙에 저장된 참조 값의 주소값을 값으로 담은 메모리의 주소값이 저장된다.)</span>
**</p>
</blockquote>
<ul>
<li>메모리에 값을 저장하려면, 먼저 값을 저장할 메모리 공간의 크기를 결정해야 한다.</li>
<li>객체는 원시 값과는 달리 크기가 정해져 있지 않으므로 할당해야 할 메모리 공간의 크기를 런타임에 결정(동적 할당)해야 한다.</li>
<li>따라서 객체(참조 데이터)가 저장되는 메모리 공간인 메모리 힙은 구조화 되어있지 않다는 특징이 있다.</li>
</ul>
<hr>
<p>이처럼 콜스텍과 힙으로 구성되어 있는 자바스크립트 엔진은 
단순히 태스크가 요청되면 콜 스텍을 통해 요청된 작업을 순차적으로 실행할 뿐이다.</p>
<p>비동기 처리에서 소스코드의 평가와 실행을 제외한 모든 처리는
--&gt; 자바스크립트 엔진을 구동하는 환경인 브라우저 또는 Node.js가 담당한다.</p>
<p>예를 들어, 비동기 방식으로 동작하는 setTimeout의 콜백 함수의 평가와 실행(콜스택에 올라갔을 때)은 자바스크립트 엔진이 담당하지만
-&gt; 호출 스케줄링(콜백 함수가 호출되기까지 걸리는 시간 설정)을 위한 타이머 설정과
콜백 함수의 등록은 브라우저 또는 Node.js가 담당한다.</p>
<p>이를 위해 브라우저 환경은 태스크 큐와 이벤트 루프를 제공한다.</p>
<h4 id="브라우저-환경이-제공하는-태스크-큐와-이벤트-루프">브라우저 환경이 제공하는 태스크 큐와 이벤트 루프</h4>
<p><strong>1. 태스크 큐</strong>
setTimeout과 같은 비동기 함수의 콜백 함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역이다.
<br>태스크 큐와 별도로 프로미스의 후속 처리 메서드의 콜백 함수가 일시적으로 보관되는 마이크로태스크 큐도 존재한다.</p>
<p><strong>2. 이벤트 루프</strong>
이벤트 루프는 콜 스택에 현재 실행 중인 실행 컨텍스트가 있는지,
그리고 태스크 큐에 대기 중인 함수(콜백 함수, 이벤트 핸들러 등)가 있는지 반복해서 확인한다.
<br>만약 콜 스택이 비어 있고 태스크 큐에 대기 중인 함수가 있다면,
이벤트 루프는 순차적으로 태스크 큐에 대기 중인 함수를 콜 스택으로 이동시킨다.</p>
<p>이 때 콜스택으로 이동한 함수는 실행(자바스크립트 엔진에 의해서)된다.</p>
<p>즉,** 태스크 큐에 일시 보관된 함수들은 비동기 처리 방식으로 동작한다.**</p>
<hr>
<blockquote>
<p><strong>자바스크립트 엔진은 싱글 스레드로 동작하지만</strong>, <strong><span style="color:blue">브라우저는 멀티 스레드로 동작</span>한다.</strong></p>
</blockquote>
<hr>
<p>브라우저는 자바스크립트 엔진 외에도 렌더링 엔진과 Web API를 제공한다.</p>
<p><strong>Web API는</strong> ECMAScript 사양에 정의된 함수가 아니라
<strong>브라우저에서 제공하는 API</strong>이며,
<strong>DOM API와 타이머 함수, HTTP 요청(Ajax)과 같은 비동기 처리를 포함한다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 36. 디스트럭처링 할당 (비 구조화 할당)]]></title>
            <link>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-36.-%EB%94%94%EC%8A%A4%ED%8A%B8%EB%9F%AD%EC%B2%98%EB%A7%81-%ED%95%A0%EB%8B%B9-%EB%B9%84-%EA%B5%AC%EC%A1%B0%ED%99%94-%ED%95%A0%EB%8B%B9</link>
            <guid>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-36.-%EB%94%94%EC%8A%A4%ED%8A%B8%EB%9F%AD%EC%B2%98%EB%A7%81-%ED%95%A0%EB%8B%B9-%EB%B9%84-%EA%B5%AC%EC%A1%B0%ED%99%94-%ED%95%A0%EB%8B%B9</guid>
            <pubDate>Thu, 17 Feb 2022 06:40:46 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 35. 스프레드 문법]]></title>
            <link>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-35.-%EC%8A%A4%ED%94%84%EB%A0%88%EB%93%9C-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-35.-%EC%8A%A4%ED%94%84%EB%A0%88%EB%93%9C-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Thu, 17 Feb 2022 03:17:42 GMT</pubDate>
            <description><![CDATA[<h1 id="스프레드-문법">스프레드 문법</h1>
<hr>
<blockquote>
<p>ES6에서 도입된 스프레드 문법 ... 은 <strong>하나로 뭉쳐 있는 여러 값들의 집합을 펼쳐서(spread)
개별적인 값들의 목록으로 만든다.</strong>
<br>스프레드 문법을 사용할 수 있는 대상은 Array, String, Map, Set, DOM 컬렉션(NodeList, HTMLCollection), argument 와 같이 
--&gt; for ... of 문으로 <strong>순회할 수 있는 이터러블에 한정된다.</strong></p>
<blockquote>
<p>스프레드 문법 ... 은 이터러블 객체에만 사용 가능하나, 
--&gt; 스프레드 프로퍼티 ...는 <strong>일반 객체를 대상으로도 사용이 가능하다!</strong></p>
</blockquote>
</blockquote>
<h4 id="⭐️-스프레드-문법의-결과는-값이-아닌-값들의-목록">⭐️ 스프레드 문법의 결과는 값이 아닌 값들의 목록!</h4>
<p>스프레드 문법은 이터러블을 펼쳐서 요소들을 <strong>개별적인 값들의 목록</strong>으로 만든다.</p>
<p>값이 아닌** 값들의 목록**이다.</p>
<p>즉, <span style = 'color:blue'><strong>스프레드 문법의 결과는 값이 아니다!</strong></span></p>
<p>이는 스프레드 문법 ... 이 피연산자를 연산하여 <strong>값을 생성하는 --&gt; &#39;연산자&#39; 가 아님을 의미</strong>한다!<strong>텍스트</strong></p>
<blockquote>
<p><strong>스프레드 문법의 <span style = 'color:deeppink'>결과</span></strong>는
<strong><span style = 'color:blue'>--&gt; 값이 아닌, <span style = 'color:deeppink'>값들의 목록</span> 이기 때문에 변수에 할당할 수 없다!</span></strong></p>
</blockquote>
<pre><code class="language-js">// 스프레드 문법의 결과는 값이 아닌 값들의 목록이므로
// 변수에 할당할 수 없다.
const list = ...[1, 2, 3]; // SyntaxError: /src/index.js: Unexpected token..</code></pre>
<hr>
<h4 id="💡-스프레드-문법의-결과물을-사용-가능한-문맥">💡 스프레드 문법의 결과물을 사용 가능한 문맥</h4>
<p><strong>스프레드 문법의 결과물은 값으로 사용할 수 없고,</strong>
다음과 같이 <span style = 'color:deeppink'><strong>쉼표로 구분한 값의 목록</strong></span><strong>을 사용하는 문맥에서만 사용</strong>할 수 있다!</p>
<blockquote>
<ol>
<li>함수 호출문의 인수 목록 </li>
</ol>
<p>--&gt; <span style = 'color:blue'><strong>배열이나 객체를 <span style = 'color:deeppink'>해체</span>해서 값의 목록을 인수로 전달한다!</strong></span>
2. 배열 리터럴의 요소 목록
3. 객체 리터럴의 프로퍼티 목록</p>
</blockquote>
<hr>
<h2 id="351-함수-호출문의-인수-목록에서-사용하는-경우">35.1 함수 호출문의 인수 목록에서 사용하는 경우</h2>
<h4 id="❗️스프레드-문법과-rest-파라미터">❗️스프레드 문법과 Rest 파라미터</h4>
<blockquote>
<p>스프레드 문법은 Rest 파라미터와 형태가 동일하여 혼동할 수 있으므로 주의할 필요가 있다.
<br><strong>Rest 파라미터</strong>는 
<strong><span style = 'color:green'>함수에 전달된 인수들의 목록을 배열로 전달</span></strong>받기 위해
--&gt; <strong>매개변수 이름 앞에 ... 을 붙이는 것</strong>이다.
<br><strong>스프레드 문법</strong>은 
<strong>여러 개의 값이 하나로 뭉쳐있는</strong> 배열과 같은 <strong>이터러블 객체를 펼쳐서
--&gt; <span style = 'color:deeppink'>개별적인 값들의 목록을 만드는 것</span></strong>이다.
<br>따라서 <strong>Rest 파라미터와 스프레드 문법은 서로 <span style = 'color:green'>반대의 개념</span>이다!</strong></p>
</blockquote>
<hr>
<h2 id="352-배열-리터럴-내부에서-사용하는-경우">35.2 배열 리터럴 내부에서 사용하는 경우</h2>
<hr>
<h3 id="3521-concat">35.2.1 concat</h3>
<p>✍️ 스프레드 문법을 사용하면 별도의 메서드를 사용하지 않고 
--&gt; 배열 리터럴만으로 2개의 배열을 1개의 배열로 결합할 수 있다.</p>
<pre><code class="language-js">// ES6
const arr = [...[1, 2], ...[3, 4]];
console.log(arr); // [1, 2, 3, 4]
</code></pre>
<hr>
<h3 id="3522-splice">35.2.2 splice</h3>
<p>✍️ 스프레드 문법을 사용하면 splice 메서드를 사용시, 세 번째 인수로 배열을 전달하면 배열 자체가 추가된다. 
배열을 해체해서 전달하려면 ES5까지는 apply 메서드를 사용했지만, 
ES6의 스프레드 문법을 사용하면 더욱 간결하고 가독성 좋게 배열을 해체해서 전달할 수 있다.</p>
<pre><code class="language-js">// ES6
const arr1 = [1, 4];
const arr2 = [2, 3];

arr1.splice(1, 0, ...arr2);
console.log(arr1); // [1, 2, 3, 4]
</code></pre>
<hr>
<h3 id="3523-배열-복사">35.2.3 배열 복사</h3>
<p>✍️ 스프레드 문법을 사용하면 slice 메서드를 사용한 것보다 간결하고 가독성 있게 
원본 배열의 각 요소를 얕은 복사하여 새로운 복사본을 생성할 수 있다.</p>
<pre><code class="language-js">// ES6
const origin = [1, 2];
const copy = [...origin];

console.log(copy); // [1, 2]
console.log(copy === origin); // false
</code></pre>
<hr>
<h3 id="3524-이터러블을-배열로-변환">35.2.4 이터러블을 배열로 변환</h3>
<p>✍️ 스프레드 문법을 사용하면 간편하게 이터러블을 배열로 변환할 수 있다.</p>
<pre><code class="language-js">function sum() {
  // 이터러블이면서 유사 배열 객체인 arguments를 배열로 변환
  return [...arguments].reduce((pre, cur) =&gt; pre + cur, 0);
}

console.log(sum(1, 2, 3)); // 6
</code></pre>
<p>단, <strong>이터러블이 아닌 유사 배열 객체는 스프레드 문법의 대상이 될 수 없다.</strong></p>
<p>이터러블이 아닌 유사 배열 객체를 배열로 변경하려면
ES6에서 도입된 Array.from 메서드를 사용한다.</p>
<h4 id="💡-arrayfrom">💡 Array.from</h4>
<p>Array.from 메서드는 <strong>유사 배열 객체 또는 이터러블을 인수로 전달받아
--&gt; 배열로 변환하여 반환</strong>한다.</p>
<hr>
<h2 id="353-객체-리터럴-내부에서-사용하는-경우">35.3 객체 리터럴 내부에서 사용하는 경우</h2>
<blockquote>
<p><strong>스프레드 프로퍼티</strong>를 사용하면 객체 리터럴의 프로퍼티 목록에서도 스프레드 문법을 사용할 수 있다!
<br><strong>스프레드 문법의 대상은 이터러블이어야 하지만,
--&gt; <span style = 'color:deeppink'>스프레드 프로퍼티</span>는 <span style = 'color:blue'>일반 객체를 대상으로도 스프레드 문법의 사용을 허용</span>한다!</strong></p>
</blockquote>
<pre><code class="language-js">// 스프레드 프로퍼티
// 이터러블 객체가 아닌 일반 객체 복사(얕은 복사)
const obj = { x: 1, y: 2 };
const copy = { ...obj };

console.log(copy); // {x: 1, y: 2}
console.log(obj === copy); // false
</code></pre>
<hr>
<p>✍️ 스프레트 프로퍼티가 아닌 <strong>Objec.assign 메서드를 사용</strong>해서 
--&gt; 여러 개의 <strong>객체를 병합하거나 특정 프로퍼티를 변경 또는 추가</strong>할 수 있다!</p>
<pre><code class="language-js">// 객체 병합.
// 프로퍼티가 중복되는 경우 뒤에 위치한 프로퍼티가 우선권을 갖는다.
const marged = Object.assign({}, { x: 1, y: 2 }, { y: 10, z: 3 });
console.log(marged); // {x: 1, y: 10, z: 3}

// 특정 프로퍼티 변경
const changed = Object.assign({}, { x: 1, y: 2 }, { y: 100 });
console.log(changed); // {x: 1, y: 100}

// 프로퍼티 추가
const added = Object.assign({ x: 1, y: 2 }, { z: 0 });
console.log(added); // {x: 1, y: 2, z: 0}
</code></pre>
<hr>
<p><span style = 'color:deeppink'><strong>스프레드 프로퍼티</span>는 Object.assign 메서드를 대체할 수 있는 문법이다!</strong></p>
<pre><code class="language-js">// 객체 병합.
// 프로퍼티가 중복되는 경우 뒤에 위치한 프로퍼티가 우선권을 갖는다.
const marged = { ...{ x: 1, y: 2 }, ...{ y: 10, z: 3 } };
console.log(marged); // {x: 1, y: 10, z: 3}

// 특정 프로퍼티 변경
const changed = { ...{ x: 1, y: 2 }, y: 100 };
console.log(changed); // {x: 1, y: 100}

// 프로퍼티 추가
const added = { ...{ x: 1, y: 2 }, z: 0 };
console.log(added); // {x: 1, y: 2, z: 0}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 30.Date]]></title>
            <link>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-30.Math</link>
            <guid>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-30.Math</guid>
            <pubDate>Tue, 15 Feb 2022 16:51:17 GMT</pubDate>
            <description><![CDATA[<h1 id="date">Date</h1>
<hr>
<blockquote>
<p>Date 는 날짜와 시간(연, 월, 일, 시, 분, 초, 밀리초)을 위한 메서드를 제공하는
빌트인 객체이면서 생성자 함수이다.
<br>UTC는 국제 표준시를 의미한다. 
기술적인 표기에서는 UTC가 사용된다. 
<br>KST(한국 표준시)는 UTC에 9시간을 더한 시간이다.
즉, KST는 UTC보다 9시간이 빠르다.</p>
</blockquote>
<hr>
<h2 id="301-date-생성자-함수">30.1 Date 생성자 함수</h2>
<p>Date는 생성자 함수다.
Date 생성자 함수로 생성한 Date 객체는 기본적으로 
--&gt; <strong>현재 날짜와 시간을 나타내는 정수값을 가진다.
**
현재 날짜와 시간이 아닌 *<em>다른 날짜와 시간을 다루고 싶은 경우 *</em>
--&gt; **Date 생성자 함수에 명시적으로 해당 날짜와 시간 정보를 인수로 지정</strong>한다.</p>
<hr>
<p>Date 생성자 함수를 new 연산자 없이 호출하면 
--&gt; Date 객체를 반환하지 않고** 날짜와 시간 정보를 나타내는 문자열을 반환**한다.</p>
<hr>
<p>.
.</p>
<p>** <span style ='color: orange'>자세한 내용은 30장 Date 참조</span>**
.
.</p>
<hr>
<h2 id="302-date-메서드">30.2 Date 메서드</h2>
<h3 id="3023-dateutc">30.2.3 Date.UTC</h3>
<p>**<span style ='color: deeppink'>캘린더 작업시 사용할 수 있는 메서드라고 한다.</span> **</p>
<blockquote>
<p>1970년 1월 1일 00:00:00(UTC)을 기점으로 
--&gt; <strong>인수로 전달된 지정 시간까지의 밀리초를 숫자로 반환</strong>한다.
<br>Date.UTC 메서드는 <strong>new Date(year, month[, day, hour, minute, second, millisecond])와 같은 형식의 인수를 사용</strong>해야 한다.
<br>Date.UTC 메서드의 인수는 <strong>로컬 타임(KST)가 아닌 UTC로 인식</strong>된다.
<br><strong>month는 월을 의미하는 0~11까지의 정수</strong>다.
<strong>0부터 시작하므로 주의가 필요하다.</strong>
(--&gt; 0이 1월달이다!)</p>
</blockquote>
<pre><code class="language-js">Date.UTC(1970, 0, 2); // -&gt; 86400000
Date.UTC(&quot;2970/1/2&quot;); // -&gt; NaN
</code></pre>
<hr>
<h3 id="dateprototypetodatestring">Date.prototype.toDateString</h3>
<blockquote>
<p>사람이 읽을 수 있는 형식의 문자열로 Date 객체의 날짜를 반환한다.</p>
</blockquote>
<pre><code class="language-js">const today = new Date(&quot;2020/7/24/12:30&quot;);
today.toString(); // -&gt; Fri Jul 24 2020 12:30:00 GMT+0900 (한국 표준시)
today.toDateString(); // -&gt; Fri Jul 24 2020
</code></pre>
<hr>
<h3 id="span-style-color-green30225-dateprototypetolocalstringspan"><span style ='color: green'>30.2.25 Date.prototype.toLocalString</span></h3>
<blockquote>
<p>인수로 전달한 <span style ='color: blue'><strong>로켈(국가)를 기준</strong></span>으로
<strong>--&gt; Date 객체의 날짜와 시간을 표현한 문자열을 반환</strong>하는 메서드!
<br><strong>인수를 생략한 경우 브라우저가 동작 중인 시스템의 로캘을 적용한다</strong>.</p>
</blockquote>
<pre><code class="language-js">const today = new Date(&quot;2020/7/24/12: 30&quot;);

today.toString(); // -&gt;  Fri Jul 24 2020 12:30:00 GMT+0900 (한국 표준시) 
today.toLocaleString(); // -&gt; 2020. 7. 24. 오후 12:30:00 
today.toLocaleString(&quot;ko-KR&quot;); // -&gt; 2020. 7. 24. 오후 12:30:00 
today.toLocaleString(&quot;en-US&quot;); // -&gt; 7/24/2020, 12:30:00 PM 
today.toLocaleString(&quot;ja-JP&quot;); // -&gt; 2020/7/24 12:30:00 </code></pre>
<hr>
<h3 id="30226-dateprototypetolocaletimestring">30.2.26 Date.prototype.toLocaleTimeString</h3>
<blockquote>
<p>인수로 전달한 로캘(나라)를 기준으로 
--&gt; Date 객체의 시간을 표현한 문자열을 반환한다!
<br>인수를 생략한 경우 브라우저가 동작 중인 시스템의 로캘을 적용한다.</p>
</blockquote>
<pre><code class="language-js">const today = new Date(&quot;2020/7/24/12: 30&quot;);

console.log(today.toString()); // -&gt; Fri Jul 24 2020 12:30:00 GMT+0900 (한국 표준시)
console.log(today.toLocaleTimeString()); // -&gt; 오후 12:30:00
console.log(today.toLocaleTimeString(&quot;ko-KR&quot;)); // -&gt; 오후 12:30:00
console.log(today.toLocaleTimeString(&quot;en-US&quot;)); // -&gt; 12:30:00 PM
console.log(today.toLocaleTimeString(&quot;ja-JP&quot;)); // -&gt; 12:30:00
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 29.Math
]]></title>
            <link>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-29.Math</link>
            <guid>https://velog.io/@jen_jyseo/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-29.Math</guid>
            <pubDate>Tue, 15 Feb 2022 14:24:55 GMT</pubDate>
            <description><![CDATA[<h1 id="math">Math</h1>
<hr>
<p>Math 는 수학적인 상수와 함수를 위한 프로퍼티와 메서드를 제공한다.
<br><strong>Math 는 생성자 함수가 아니다.</strong>
<br><strong>--&gt; Math 는 정적 프로퍼티와 정적 메서드만을 제공하는 표준 빌트인 객체이다!</strong></p>
<hr>
<h2 id="291-math-프로퍼티">29.1 Math 프로퍼티</h2>
<h3 id="2911-mathpi">29.1.1 Math.PI</h3>
<blockquote>
<p><strong>원주율 PI 값을 반환</strong>한다.
<br>--&gt; 그래픽 작업을 하는 경우 사용한다.</p>
</blockquote>
<hr>
<h2 id="292-math-메서드">29.2 Math 메서드</h2>
<blockquote>
<p>Math.round 메서드는 <strong>인수로 전달된 숫자의 소수점 이하를</strong>
--&gt; <strong>반올림(0<del>4면 버리고, 5</del>9면 버린다.)한 정수를 반환</strong>한다.
<br>인수를 전달하지 않으면 --&gt;  <strong>NaN을 반환한다.</strong></p>
</blockquote>
<pre><code class="language-js">Math.round(1.4); // -&gt; 1
Math.round(1.6); // -&gt; 2
Math.round(-1.4); // -&gt; -1
Math.round(-1.6); // -&gt; -2
Math.round(1); // -&gt; 1
// 인수를 전달하지 않으면 NaN을 반환하다.
Math.round(); // -&gt; NaN
</code></pre>
<hr>
<h3 id="mathceil">Math.ceil</h3>
<blockquote>
<p>인수로 전달된 숫자의 <strong>소수점 이하를 올림(구하려는 자리 미만의 수를 올린다.)한 정수를 반환한다.</strong>
<br><span style = "color:blue"><strong>소수점 이하를 올림하면 더 큰 정수가 된다!</strong></span>
<br>1.4 의 소수점 이하를 올림하면 --&gt; 2 가 되고.
<strong>-1.4 의 소수점 이하를 올림하면 --&gt; <span style = "color:blue">1</span> 이 된다!</strong></p>
</blockquote>
<pre><code class="language-js">Math.ceil(1.4); // -&gt; 2
Math.ceil(1.6); // -&gt; 2
Math.ceil(-1.4); // -&gt; -1
Math.ceil(-1.6); // -&gt; -1
Math.ceil(1); // -&gt; 1
Math.ceil(); // -&gt; NaN</code></pre>
<hr>
<h3 id="2724-mathfloor">27.2.4 Math.floor</h3>
<blockquote>
<p>인수로 전달된 숫자의 <strong>소숫점 이하를 내림한 정수를 반환한다.</strong>
<strong><br>--&gt; Math.ceil 메서드의 반대 개념이다.</strong>
<br>소수점 이하를 <strong>내림하면 더 작은 정수가 된다.</strong>
<br>예를 들어, <strong>1.9의 소수점 이하를 내림하면 1이 되고,</strong>
<strong>-1.9의 소수점 이하를 내림하면 -2가 된다.</strong></p>
</blockquote>
<pre><code class="language-js">Math.floor(1.9); // -&gt; 1
Math.floor(9.1); // -&gt; 9
Math.floor(-1.9); // -&gt; -2
Math.floor(-9.1); // -&gt; -10
Math.floor(1); // -&gt; 1
Math.floor(); // -&gt; NaN
</code></pre>
<hr>
<h3 id="2925-mathsqrt">29.2.5 Math.sqrt</h3>
<blockquote>
<p>Math.sqrt 메서드는 인수로 전달된 숫자의 --&gt; <strong>제곱근을 반환한다.</strong></p>
</blockquote>
<pre><code class="language-js">Math.sqrt(9); // -&gt; 3
Math.sqrt(-9); // -&gt; NaN
Math.sqrt(1); // -&gt; 1
Math.sqrt(0); // -&gt; NaN</code></pre>
<hr>
<h3 id="2926-mathrandom">29.2.6 Math.random</h3>
<blockquote>
<p>Math.random 메서드는 임의의 난수(랜덤 숫자)를 반환한다.
<br>Math.random 메서드가 반환한 난수는 0에서 1미만의 실수이다!
--&gt; 즉, 0은 포함되지만 1은 포함되지 않는다.
<span style = "color:blue"><br>실제로 완전히 랜덤하지는 않다고 한다!
계속 반복 하다보면 어떠한 패턴이 일정하게 반복되는 것을 확인할 수 있다.
--&gt; 따라서 완벽한 난수를 만들어 주지는 않는다!</span></p>
</blockquote>
<pre><code class="language-js">Math.random(); // 0에서 1미만의 랜덤 실수

/*
1에서 10범위의 랜덤 정수 취득
1) Math.random 으로 0에서 1미만의 랜덤 실수를 구한 다음
   10을 곱해 0에서 10 미만의 랜덤 실수를 구한다.
2) 0에서 10미만의 랜덤 실수에 1을 더해 1에서 10 범위의 랜덤 실수를 구한다.
3) Math.floor로 1에서 10 범위의 랜덤 실수의 소수점 이하를 떼어 버린 다음 정수를 반확한다.
*/
const random = Math.floor((Math.random() * 10) + 1);
console.log(random); // 1에서 10 범위의 정수</code></pre>
<hr>
<h3 id="mathpow">Math.pow</h3>
<blockquote>
<p>Math.pow 메서드는 <strong>첫 번째 인수를 밑으로, 두 번째 인수를 지수로 거듭제곱한 결과를 반환</strong>하다.
<br>--&gt; Math.pow 메서드 대신 <span style = "color:blue"><strong>지수 연산자</strong>를 사용하면 가독성이 더 좋다!</span></p>
</blockquote>
<pre><code class="language-js">// ES7 지수 연산자
console.log(2 ** (2 ** 2)); // -&gt; 16

Math.pow(Math.pow(2, 2), 2); // -&gt; 16</code></pre>
<hr>
<h3 id="2728-mathmax">27.2.8 Math.max</h3>
<blockquote>
<p>Math.max 메서드는 전달받은 인수 중에서 <strong>가장 큰 수를 반환한다.</strong>
<br><strong>--&gt; 인수가 전달되지 않으면 -Infinity를 반환한다.</strong></p>
</blockquote>
<pre><code class="language-js">Math.max(1); // -&gt; 1
Math.max(1, 2); // -&gt; 2
Math.max(1, 2, 3); // -&gt; 3
Math.max(); // -&gt; -Infinity
</code></pre>
<blockquote>
<p>*<em>배열을 인수로 전달받아 배열의 요소 중에서 최대값을 구하려면 
Function.prototype.apply 메서드 또는 스프레드 문법을 사용해야 한다.
*</em></p>
</blockquote>
<pre><code class="language-js">// 배열 요소 중에서 최대값 취득
Math.max.apply(null, [1, 2, 3]); // -&gt; 3

// ES6 스프레드 문법
Math.max(...[1, 2, 3]); // -&gt; 3
</code></pre>
<hr>
<h3 id="2929-mathmin">29.2.9 Math.min</h3>
<blockquote>
<p>Math.min 메서드는 전달받은 인수 중에서 <strong>가장 작은 수를 반환</strong>한다.
<br><strong>인수가 전달되지 않으면 Infinity 를 반환한다.</strong></p>
</blockquote>
<blockquote>
<p><br><strong>배열을 인수로 전달받아 배열의 요소 중에서 최소값을 구하려면</strong>
<strong>--&gt; Function.prototype.apply 메서드 또는 스프레드 문법을 사용해야 한다.</strong></p>
</blockquote>
<pre><code class="language-js">// 배열 요소 중에서 최소값 취득
// apply의 첫 번째 인수로 null을 전달한 이유는
// 아래의 코드에서 apply 메서드를 호출한 이유는
// min 메서드에 배열을 전달하고자 함이기 때문이다!
// 따라서 this 바인딩이 중요하지 않기에 null 을 적었다!
Math.min.apply(null, [1, 2, 3]); // -&gt; 1

// ES6 스프레드 문법
Math.min(...[1, 2, 3]); // -&gt; 1
</code></pre>
<hr>
]]></description>
        </item>
    </channel>
</rss>