<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>멋쟁이 토마토.log</title>
        <link>https://velog.io/</link>
        <description>토마토마토</description>
        <lastBuildDate>Thu, 07 Jul 2022 07:33:31 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>멋쟁이 토마토.log</title>
            <url>https://velog.velcdn.com/images/ye-ji/profile/7cb82826-3ed9-488a-a57d-6c70395956f3/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 멋쟁이 토마토.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/ye-ji" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Typescript &  CRA 초기세팅
(ESLint, Prettier 적용)]]></title>
            <link>https://velog.io/@ye-ji/Typescript-CRA-%EC%B4%88%EA%B8%B0%EC%84%B8%ED%8C%85</link>
            <guid>https://velog.io/@ye-ji/Typescript-CRA-%EC%B4%88%EA%B8%B0%EC%84%B8%ED%8C%85</guid>
            <pubDate>Thu, 07 Jul 2022 07:33:31 GMT</pubDate>
            <description><![CDATA[<pre><code>$ npx create-react-app &quot;생성할 프로젝트 이름&quot; --template typescript</code></pre><p>이 때 &quot;생성할 프로젝트 이름&#39; 대신에 .을 입력해주면 터미널에 있는 경로에서 cra가 생성되어진다!</p>
<h1 id="eslint-설치">ESLint 설치</h1>
<h4 id="1-default-config-지우기packagejson">1. default config 지우기(package.json)</h4>
<p>CRA로 프로젝트를 생성하면 package.json에서 기본적으로 세팅되어있는 아래 부분을 지운다.</p>
<pre><code>  &quot;eslintConfig&quot;: {
    &quot;extends&quot;: [
      &quot;react-app&quot;,
      &quot;react-app/jest&quot;
    ]
  },</code></pre><h4 id="2-install-eslint">2. install eslint</h4>
<pre><code>npm install eslint --save-dev</code></pre><h4 id="3-setup-eslint">3. setup eslint</h4>
<pre><code>npx eslint --init</code></pre><p><img src="https://velog.velcdn.com/images/ye-ji/post/18dfa66d-69a3-4219-9666-6688fa023677/image.png" alt="">
<img src="https://velog.velcdn.com/images/ye-ji/post/7a74403d-b0c6-48b9-824b-5d88d994936f/image.png" alt="">
<img src="https://velog.velcdn.com/images/ye-ji/post/18e3b630-c08d-43fd-9a8c-b8803c9a5d7d/image.png" alt="">
<img src="https://velog.velcdn.com/images/ye-ji/post/7e596602-32d2-44ab-9e4c-81a80d155cbf/image.png" alt="">
<img src="https://velog.velcdn.com/images/ye-ji/post/5c28f690-df5b-4f27-b578-6f4b897b1426/image.png" alt="">
<img src="https://velog.velcdn.com/images/ye-ji/post/eddf01a4-8292-49ce-a427-ec63d23bf5aa/image.png" alt="">
<img src="https://velog.velcdn.com/images/ye-ji/post/52d96f4e-7071-4fe2-bc37-25c186a0f307/image.png" alt="">
<img src="https://velog.velcdn.com/images/ye-ji/post/948289e0-1ad7-419e-96a5-159953484c92/image.png" alt="">
<img src="https://velog.velcdn.com/images/ye-ji/post/8efa1158-8e7d-4155-bbae-892149315848/image.png" alt="">
<img src="https://velog.velcdn.com/images/ye-ji/post/fc9610df-f95d-42d3-b8de-fc00c214b1d9/image.png" alt="">
<img src="https://velog.velcdn.com/images/ye-ji/post/43330bee-0a67-4286-8737-13bf69ece0bb/image.png" alt="">
<img src="https://velog.velcdn.com/images/ye-ji/post/28ca7e88-04c9-45be-beae-03371ce5c433/image.png" alt="">
위와 같은 절차를 거치게 되면 자연스럽게 설치가 되어진다!
<img src="https://velog.velcdn.com/images/ye-ji/post/c72774fd-6eda-4182-8854-63200a51b98c/image.png" alt=""></p>
<h4 id="4-running-eslint">4. Running ESLint</h4>
<p>😀 sample: JSX not allowed in files with extension &#39;.tsx&#39;
(확장자가 &#39;.tsx&#39; 인 파일에서는 jsx가 허용되지 않습니다)
⭐ solution
<code>eslintrc.json</code></p>
<pre><code>&quot;rules&quot;:{
  &quot;react/jsx-filename-extension&quot;:[&quot;warn&quot;,{&quot;extensions&quot;:[&quot;.tsx&quot;]} }
}</code></pre><p>😀 sample: import/no-unresolved
Unable to resolve path to module &#39;./App&#39;.
(모듈 &#39;./App&#39;에 대한 경로를 확인할 수 없습니다.)
⭐ solution
<code>eslintrc.json</code></p>
<pre><code>&quot;rules&quot;: {
    ...
    &quot;import/no-unresolved&quot;: &quot;off&quot;
  }</code></pre><p>😀 sample: import/extensions
⭐ solution
<code>eslintrc.json</code></p>
<pre><code>&quot;rules&quot;: {
    ...
    &quot;import/extensions&quot;: &quot;off&quot;
  }</code></pre><p>😀 sample: react/react-in-jsx-scope
&#39;React&#39; must be in scope when using JSX 
⭐ solution
<code>eslintrc.json</code></p>
<pre><code>&quot;rules&quot;: {
    ...
    &quot;react/react-in-jsx-scope&quot;: &quot;off&quot;
  }</code></pre><p>😀 sample: react/jsx-filename-extension 
⭐ solution
<code>eslintrc.json</code></p>
<pre><code>&quot;rules&quot;:  {
  &quot;react/jsx-filename-extension&quot;: [
      2,
      { &quot;extensions&quot;: [&quot;.js&quot;, &quot;.jsx&quot;, &quot;.ts&quot;, &quot;.tsx&quot;] }
    ]
},</code></pre><h1 id="prettier">Prettier</h1>
<p>ESLint와 Prettier를 사용하다보면 충돌이 생기게 된다!
그래서 eslint-config-prettier를 설치해주어야한다.</p>
<blockquote>
<p><strong>이것을 사용하게 된다면 ESLint 는 자바스크립트 문법 관련된 것들만 관리하게 되고, 코드스타일 관련 작업은 prettier 가 담당하게된다!!</strong></p>
</blockquote>
<pre><code>npm install --save-dev eslint-config-prettier</code></pre><p><code>.prettierrc</code></p>
<pre><code>{
  &quot;singleQuote&quot;: true,
  &quot;semi&quot;: true,
  &quot;useTabs&quot;: false,
  &quot;tabWidth&quot;: 2,
  &quot;trailingComma&quot;: &quot;all&quot;,
  &quot;printWidth&quot;: 80
}</code></pre><p>규칙은 다음과 같다.</p>
<ul>
<li>문자열을 사용 할 때에는 &#39; 를 사용합니다.</li>
<li>코드는 ; 로 끝나야합니다.</li>
<li>탭 대신에 스페이스를 사용합니다.</li>
<li>들여쓰기 크기는 2칸입니다.</li>
<li>객체나 배열을 작성 할 때, 원소 혹은 key-value 의 맨 뒤에있는 것에도 쉼표를 붙입니다.</li>
<li>한 줄이 80칸이 넘지 않도록 합니다</li>
</ul>
<p><code>.eslintrc.json</code></p>
<pre><code>&quot;extends&quot;: [...,&quot;prettier&quot;],</code></pre><p>이렇게 하면 완료다!!
잘 적용이 되는지 확인하기 위해서는 
<code>App.jsx</code></p>
<pre><code>const a = () =&gt; {
  return &quot;2&quot;;
};</code></pre><p>코드를 넣고 저장하면 아래와 같이 바뀌면 대성공이다!</p>
<pre><code>const a = () =&gt; &#39;2&#39;;</code></pre><p>혹시라도 <code>ctrl + s</code>를 눌렀는데도 변경이 되지 않는다면,</p>
<p>1) VSCode 의 설정을 열어서 
2) <code>Format On Save</code> 를 검색해서 체크를 활성화해준다!
<img src="https://velog.velcdn.com/images/ye-ji/post/2376c421-f876-4302-8bae-28f6710d2924/image.png" alt=""></p>
<p>3) 그 다음엔 그 다음엔 <code>ESLint</code> 를 검색해서 Enable 체크를 활성화해주면 된다!
<img src="https://velog.velcdn.com/images/ye-ji/post/fa3c54a7-4b06-4ca5-8e23-c0d6d770fb5e/image.png" alt=""></p>
<p>끗~!</p>
<p>출처)
<a href="https://velog.io/@velopert/eslint-and-prettier-in-react">https://velog.io/@velopert/eslint-and-prettier-in-react</a>
<a href="https://velog.io/@he0_077/React-Typescript-eslint-prettier-%EC%84%A4%EC%A0%95#what-is-eslint">https://velog.io/@he0_077/React-Typescript-eslint-prettier-%EC%84%A4%EC%A0%95#what-is-eslint</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[라이브러리 없이! 평점 기능 만들기 ⭐⭐⭐⭐⭐]]></title>
            <link>https://velog.io/@ye-ji/%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-%EC%97%86%EC%9D%B4-%ED%8F%89%EC%A0%90-%EA%B8%B0%EB%8A%A5-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@ye-ji/%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC-%EC%97%86%EC%9D%B4-%ED%8F%89%EC%A0%90-%EA%B8%B0%EB%8A%A5-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Tue, 31 May 2022 06:44:30 GMT</pubDate>
            <description><![CDATA[<p>예전에 프리온보딩을 통해서 별점을 만들어놓고... 
까먹지 않기 위해서 블로그를 작성해본댜~</p>
<p><code>사실 까먹어서 지금 작성함... ㅎ</code></p>
<p>다섯 개의 별을 그리기 위해서 
<code>const starArr = [1, 2, 3, 4, 5];</code> 배열을 작성한 후
반복해서 별을 출력해주면 아래와 같이 나오게 된다.</p>
<pre><code class="language-tsx">import styled from &quot;styled-components&quot;;
import { FiStar } from &quot;react-icons/fi&quot;;

export default function App() {
  const starArr = [1, 2, 3, 4, 5];
  return (
    &lt;&gt;
      {starArr.map((idx) =&gt; (
        &lt;Star /&gt;
      ))}
    &lt;/&gt;
  );
}

const Star = styled(FiStar)`
  font-size: 50px;
`;</code></pre>
<p><img src="https://velog.velcdn.com/images/ye-ji/post/3e9aaa91-b826-402e-ae5b-e34897adbe57/image.png" alt=""></p>
<p>그리고 나서 이제 마우스가 올라갔을 때와 나갔을 때, 
별의 색이 변해지기 위해서는 <code>onMouseEnter</code>와 <code>onMouseLeave</code>를 이용해서 코드를 작성해주어야 한다.</p>
<h4 id="onmouseenter">onMouseEnter</h4>
<ul>
<li>The event occurs when the pointer is moved onto an element</li>
<li>포인터가 객체의 영역에 들어왔을 때 발생되는 이벤트</li>
</ul>
<h4 id="onmouseleave">onMouseLeave</h4>
<ul>
<li>The event occurs when the pointer is moved out of an element</li>
<li>포인터가 객체의 영역에 나갔을 때 발생되는 이벤트</li>
</ul>
<p>그래서 이 둘의 이벤트를 가지고 어떻게 색을 표현할 수 있을까?</p>
<p>1) onMouseEnter이벤트가 발생했을 때의 값을 useState의 setHover를 이용하여 저장해둔다.</p>
<p>1) onMouseLeave 이벤트가 발생했을 때 setHover가 0이 되어진다.
2) starArr 배열의 index와 hover의 값이 같거나 작다면 현재 별부터 앞의 별까지 색이 칠해진다.
즉, fill의 함수를 통해 <code>fill={idx &lt;= hover ? &quot;#000&quot; : &quot;#E5E5E5&quot;}</code> 값을 칠할 수 있다.</p>
<pre><code class="language-tsx">import styled from &quot;styled-components&quot;;
import { FiStar } from &quot;react-icons/fi&quot;;
import { useState } from &quot;react&quot;;

export default function App() {
  const starArr = [1, 2, 3, 4, 5];
  const [hover, setHover] = useState(0);
  return (
    &lt;Rating&gt;
      {starArr.map((idx) =&gt; (
        &lt;Star
          key={idx}
          onMouseEnter={() =&gt; setHover(idx)}
          onMouseLeave={() =&gt; setHover(0)}
          fill={idx &lt;= hover ? &quot;#000&quot; : &quot;#E5E5E5&quot;}
        /&gt;
      ))}
    &lt;/Rating&gt;
  );
}

const Rating = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
`;

const Star = styled(FiStar)`
  font-size: 50px;
  color: transparent;
`;</code></pre>
<p>이제 선택된 별이 칠해지기 위해서는 <code>onClick</code>이벤트를 이용하여 <code>setStarNum(idx)</code>에 값을 저장해주어야 한다. </p>
<blockquote>
<p>이 때 선택 되고 난 뒤의 별의 색은 동일해야하므로 <code>onMouseEnter</code>에 조건도 추가해주어야 한다. </p>
</blockquote>
<p>그래서 최종코드를 보면 다음과 같다.</p>
<p>!codesandbox[rating-stars-6cvlk2?fontsize=14&amp;hidenavigation=1&amp;theme=dark]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS 화면 중앙 배치 (Flexbox/Grid)]]></title>
            <link>https://velog.io/@ye-ji/CSS-%EC%A0%95-%EA%B0%80%EC%9A%B4%EB%8D%B0-%EC%A0%95%EB%A0%AC</link>
            <guid>https://velog.io/@ye-ji/CSS-%EC%A0%95-%EA%B0%80%EC%9A%B4%EB%8D%B0-%EC%A0%95%EB%A0%AC</guid>
            <pubDate>Tue, 17 May 2022 15:01:02 GMT</pubDate>
            <description><![CDATA[<p>우리는 흔히 로그인이나 어떤 페이지를 만들 때 정가운데에 주로 위치하는 경우가 많다 이때 나는 grid나 flex를 이용하여 화면 중앙에 배치할 수 있도록 코드를 작성한다.</p>
<h1 id="flexbox">Flexbox</h1>
<pre><code class="language-css">.wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
}</code></pre>
<p>!codepen[lee-ye-ji/embed/wvyJgaE?default-tab=html%2Cresult]</p>
<h1 id="grid">Grid</h1>
<pre><code class="language-css">.wrapper {
  display: grid;
  place-items: center;
}</code></pre>
<p>!codepen[lee-ye-ji/embed/vYdxgGW?default-tab=html%2Cresult]</p>
<p>출처)
<a href="https://www.daleseo.com/css-centering/">https://www.daleseo.com/css-centering/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[build만으로 배포하기 : surge를 이용]]></title>
            <link>https://velog.io/@ye-ji/build%EB%A7%8C%EC%9C%BC%EB%A1%9C-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0-surge%EB%A5%BC-%EC%9D%B4%EC%9A%A9</link>
            <guid>https://velog.io/@ye-ji/build%EB%A7%8C%EC%9C%BC%EB%A1%9C-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0-surge%EB%A5%BC-%EC%9D%B4%EC%9A%A9</guid>
            <pubDate>Thu, 12 May 2022 11:02:56 GMT</pubDate>
            <description><![CDATA[<p><a href="https://surge.sh/">surge</a>를 이용하여 배포를 한다면,
github에 코드를 올리지 않고 배포를 빠르게 할 수 있다.</p>
<p>나는 기업에서 요구하는 과제를 온라인 상에 올리지 않도록 명시되어있을 때 주로 surge를 사용했다!</p>
<p>React App을 이용하여 개발 한 뒤 배포를 하기 위해서는 build명렁어를 통해 해당 파일을 만들어 준다</p>
<pre><code>$ npm run build</code></pre><p>또는</p>
<pre><code>$ yarn run build</code></pre><p>그러고 나면 build된 파일들을 아래의 사진과 같이 확인할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/ye-ji/post/3127fd11-78cf-46fc-8ee3-ccb9b5e66a13/image.png" alt=""></p>
<p>build를 하게 되면 파일들이 js, css, html 형식으로 변환된 것을 확인할 수 있다. 그 이유는 웹 브라우저 엔진이 해당 html, css, js만 읽을 수 있도록 구성되어있기 때문이다.</p>
<p>그 후에 명령어로 아래와 같이 입력해준다.</p>
<pre><code>$  cd build</code></pre><p>여기서 cd는 build파일로 경로를 변경하겠다는 의미이다.</p>
<p>이제 배포를 하기 위해서는 <code>surge</code>를 입력해준다면,</p>
<pre><code>$ surge</code></pre><p><img src="https://velog.velcdn.com/images/ye-ji/post/58d2644b-ddb3-4cb9-bfbe-2eaeb42e693f/image.png" alt=""></p>
<p>이러한 화면이 터미널에 표시가 된다.
그 후에 enter를 누르고 난 후
<img src="https://velog.velcdn.com/images/ye-ji/post/c3559564-6baf-4d28-9a3b-d92b656cbf87/image.png" alt=""></p>
<p>도메인을 넣을 수 있는 문구가 나온다!</p>
<p>이 때 주의해야 할 점은!!!!
<code>https</code>를 넣어주어야한다는 것이다!</p>
<p>그냥 위의 사진과 같이 enter를 누르게 되면
배포 시에 <a href="http://confused-sweater.surge.sh">http://confused-sweater.surge.sh</a> 가 나오게 된다.</p>
<p>그렇기에 <a href="https://confused-sweater.surge.sh">https://confused-sweater.surge.sh</a> 로 도메인을 직접 넣어주어야 안전하게 https로 나오게 된다!
<img src="https://velog.velcdn.com/images/ye-ji/post/bb763c8e-88bc-4815-b3c7-73ea0ba48009/image.png" alt=""></p>
<p>여기서 궁금증이 생기는 사람이 있을 것이다.
이 두가지 차이가 뭔데?
간략하게 설명하자면 보안성의 대한 차이이다.
HTTP는 서버와 클라이언트간에 데이터를 주고 받는 프로토콜로,
텍스트, 이미지,영상, JSON 등등 거의 모든 형태의 데이터를 전송할 수 있다. 
반면에 HTTPS는 보안 소켓 계층을 사용함으로써, 암호화된 데이터를 주고 받기 때문에 더 안전하다.</p>
<p>이제 enter를 치게 되면 아래의 사진과 같이 배포가 된다!
<img src="https://velog.velcdn.com/images/ye-ji/post/a20ad9a3-128a-4869-a695-352d4e00ee42/image.png" alt=""></p>
<p>보라색이 배포된 주소이다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Light house를 이용하여 사이트 성능 올리기]]></title>
            <link>https://velog.io/@ye-ji/Light-house%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-%EC%82%AC%EC%9D%B4%ED%8A%B8-%EC%84%B1%EB%8A%A5-%EC%98%AC%EB%A6%AC%EA%B8%B0</link>
            <guid>https://velog.io/@ye-ji/Light-house%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-%EC%82%AC%EC%9D%B4%ED%8A%B8-%EC%84%B1%EB%8A%A5-%EC%98%AC%EB%A6%AC%EA%B8%B0</guid>
            <pubDate>Fri, 22 Apr 2022 18:05:35 GMT</pubDate>
            <description><![CDATA[<p>서비스를 이용하다보면 화면이 너무 늦게 로딩되면 화가난다...🔥🔥🔥
대부분의 사용자는 화면이 너무 늦게 로딩되면 이를 기다리지 못하고 떠나가버린다...</p>
<p><img src="https://velog.velcdn.com/images/ye-ji/post/b1cad5fd-cc1b-4bbe-98ca-28c943332786/image.png" alt=""></p>
<p>이는 수익성 창출로 이루어지기 때문에 열심히 코딩을 해서 개발을 했다하더라도 사용자들이 떠나면... 물거품이 된다는 말이다ㅜ </p>
<p>그러면 도대체 성능은 어떻게 측정하고 해결해야하는지 궁금증이 생길 것이다!</p>
<p>이는 사이트마다 다를 수 있고, 회사마다 성능 측정 방식이 다를 수 있지만 <a href="https://makeup-api.herokuapp.com/">makeup-api</a>를 통해 화장품 목록을 가져오고 이를 구글의 Light house를 이용하여 성능을 해결하고자 한다..!</p>
<p><code>하지만 해당 글을 읽어보면... 서버와 클라이언트 모두 다 성능에 집중해야한다는 사실을 알게 될 것이다..</code></p>
<h1 id="텍스트-압축">텍스트 압축</h1>
<p><code>총 네트워크 바이트를 최소화하려면 텍스트 기반 리소스를 압축(gzip, deflate, brotli)하여 제공해야 합니다.</code> </p>
<p><img src="https://velog.velcdn.com/images/ye-ji/post/8dedf610-bfa3-4e5f-88c2-01cc53507966/image.png" alt=""></p>
<pre><code class="language-jsx">  useEffect(() =&gt; {
    axios
      .get(&#39;http://makeup-api.herokuapp.com/api/v1/products.json&#39;, {
        headers: {
          &#39;Content-Type&#39;: &#39;application/json&#39;,
          &#39;Accept-Encoding&#39;: &#39;gzip&#39;,
        },
      })
      .then((res) =&gt; {
        setData(res.data.slice(0, 16));
      });
  }, []);</code></pre>
<p>위와 같이 작성하여 요청 해더에 gzip으로 보내주었더니 결과가 크게 달라지지 않는다는 것을 확인하였다. <a href="https://web.dev/uses-text-compression/?utm_source=lighthouse&amp;utm_medium=devtools">텍스트 압축 활성화</a>를 읽어보았더니 이는 서버에서 압축 시에 크게 절감효과가 일어난다는 것이었다!</p>
<h3 id="그러면-서버에서-gzip으로-어떻게-압축-시켜서-보내는-건데">그러면 서버에서 gzip으로 어떻게 압축 시켜서 보내는 건데?</h3>
<p><a href="https://gitabout.com/18">웹사이트 성능 개선을 위한 gzip 압축 적용 : Apache, Tomcat, Weblogic과 Servlet Filter</a> 해당 블로그에 자세히 나와있지만 <code>난 이해를 하지 못했다...</code>
gzip 압축이 정상적으로 적용었다면 아래와 같이 response를 보내준다고 한다.
<img src="https://velog.velcdn.com/images/ye-ji/post/45fda0f1-8bfa-4da6-9aa9-b52406ea105d/image.png" alt="">
하지만 makeup-api는 적용이 되지 않았다는 것을 확인할 수 있었다.</p>
<h1 id="효율적인-캐시-정책을-사용하여-정적인-애셋-제공하기">효율적인 캐시 정책을 사용하여 정적인 애셋 제공하기</h1>
<p><a href="https://web.dev/uses-long-cache-ttl/?utm_source=lighthouse&amp;utm_medium=devtools">효율적인 캐시 정책으로 정적 자산 제공</a>을 통해 Cache-Control 값으로 max-age값이 적으면 적을 수록 좋다고 이야기하는 것 같았다. 그래서 해당 url을 전체 product인 json형태가 아닌 page api가 있다면 그 형식으로 변경해주려고 했지만 해당 api가 category와 type으로 분류를 해서 그걸로 변경해주었더니 성능이 빠르게 올라간 것을 확인할 수 있었다.
<img src="https://velog.velcdn.com/images/ye-ji/post/3a459976-55e3-4aa8-beae-e1fe2b5c8e3e/image.png" alt=""></p>
<p>하지만 <a href="https://toss.tech/article/smart-web-service-cache">웹 서비스 캐시 똑똑하게 다루기</a> 글을 통해 HTTP 캐시를 효율적으로 관리하려면 Cache-Control 헤더를 섬세하게 조절해야한다고 한다. 웹 브라우저가 서버에서 지금까지 요청한 적이 없는 리소스(HTML, CSS, JS, 이미지, 비디오 등)을 요청할 때, 서버와 브라우저는 완전한 HTTP 요청/응답을 주고 받는다고 한다. 하지만 요청 받은 이후 HTTP응답은 헤더 <strong>Cache-Control</strong> 헤더에 따라 받은 리소스의 생명주기가 결정이 된다고 한다. 즉, 두 번째 요청을 할 때 캐시가 유효한지 재검증을 수행한다는 것이다. </p>
<p><img src="https://velog.velcdn.com/images/ye-ji/post/0b7c4bd0-dbb3-48c1-8065-a361f0aadbc5/image.png" alt="">
그래서 응답시에 <code>Cache-Control 값으로 max-age=0, s-maxage=31536000</code> 을 설정하면 이로써 브라우저는 HTML 파일을 가져올 때마다 서버에 재검증 요청을 보내고, 그 사이에 배포가 있었다면 새로운 HTML 파일을 내려받는다고 한다.</p>
<p><img src="https://velog.velcdn.com/images/ye-ji/post/47cfaa9c-ae8a-4b7d-9730-f8e8065e3d5c/image.png" alt="">
<code>makeup-api</code>에선 어떻게 적용할 수 있을까? 위에서는 리소스가 가지는 Cache-Control 헤더 값이 <code>max-age=31536000</code>이었기에 아마도 makeup-api에선 max-age가 <code>1728000</code>이기에 <code>max-age=0, s-maxage=1728000</code>
로 설정하면 되지 않을까 싶다!</p>
<p><code>그렇다면 지금 현재 내가 성능을 높일 수 있는 건 무엇이 있을까?</code></p>
<h1 id="1-비동기-처리하기">1) 비동기 처리하기</h1>
<p><code>async</code> <code>await</code>로 기존 전체 product api를 비동기 처리하니 무려 <code>6</code>이나 느는 것을 확인할 수 있었다!
<img src="https://velog.velcdn.com/images/ye-ji/post/e365d13f-6747-4a1f-bae9-e5bc50063646/image.png" alt=""></p>
<pre><code class="language-tsx">  useEffect(() =&gt; {
    const getData = async () =&gt; {
      try {
        await axios.get(&#39;http://makeup-api.herokuapp.com/api/v1/products.json&#39;).then((res) =&gt; {
          setData(res.data.slice(0, 16));
        });
      } catch (err) {
        console.log(err);
      }
    };
    getData();
  }, []);</code></pre>
<p><img src="https://velog.velcdn.com/images/ye-ji/post/07f46058-7a67-457a-a686-9524f7177430/image.png" alt="">
하지만 product_category는 conceal이고, product_type이 foundation인 json을 불러왔더니 무려 <code>10</code>이나 느는 것을 확인할 수 있었다!</p>
<pre><code class="language-tsx">  useEffect(() =&gt; {
    const getData = async () =&gt; {
      try {
        await axios
          .get(
            &#39;http://makeup-api.herokuapp.com/api/v1/products.json?product_category=concealer&amp;product_type=foundation&#39;
          )
          .then((res) =&gt; {
            setData(res.data.slice(0, 16));
          });
      } catch (err) {
        console.log(err);
      }
    };
    getData();
  }, []);</code></pre>
<h1 id="2-skeleton-적용하기">2) Skeleton 적용하기</h1>
<p><img src="https://velog.velcdn.com/images/ye-ji/post/18c60c3d-a7ef-444a-8720-2a9151286b79/image.gif" alt=""></p>
<p><code>스켈레톤 적용 전</code>
<img src="https://velog.velcdn.com/images/ye-ji/post/e84311d2-567d-430e-8d4f-1aa60e7106f6/image.png" alt="">
<code>스켈레톤 적용 후</code>
<img src="https://velog.velcdn.com/images/ye-ji/post/aec5b95a-e63f-450f-aa9c-ca27985faf41/image.png" alt=""></p>
<p>첫번째는 스켈레톤을 적용하지 않은 결과이고, 두번째는 스켈레톤을 적용한 결과이다. 스켈레톤을 적용하지 않은 결과에서 왜 다시 테스트 해보니깐 성능이 <code>73</code>으로 줄어들었는지는 모르겠다.. 우선 기존과 성능을 비교했을 때 81로 같았지만 사용자 관점에서 보았을 때 빈 화면이었을 때 보다 스켈레톤을 적용함으로써, 데이터가 불러오는 효과가 있었다. 뿐만 아니라 수치 상으로도 Total Blocking Time이 줄어들었다.</p>
<hr>
<p><code>Light house</code>를 통해 성능 측정 결과 같은 조건에서도 테스트를 돌릴 때마다 수치가 변경되는 것을 확인하여서 좋은 테스트는 아니다라는 것을 깨닫게 되었다. 좀 더 성능에 대해 공부를 해야겠다...</p>
<p><code>혹시라도 제가 잘못작성한 부분이 있다면 댓글로 달아주시면 감사하겠습니당~</code></p>
<p>출처)
<a href="https://watermelonlike.tistory.com/entry/LightHouse%5C">https://watermelonlike.tistory.com/entry/LightHouse\</a>
<a href="https://toss.tech/article/smart-web-service-cache">https://toss.tech/article/smart-web-service-cache</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[가비지 컬렉션(Garbage Collection)이란? : 클로저와 비교해서]]></title>
            <link>https://velog.io/@ye-ji/%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98Garbage-Collection%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@ye-ji/%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BB%AC%EB%A0%89%EC%85%98Garbage-Collection%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Wed, 20 Apr 2022 16:31:19 GMT</pubDate>
            <description><![CDATA[<h1 id="가비지-컬렉션이란">가비지 컬렉션이란?</h1>
<p>가비지 컬렉션을 번역해보면 쓰레기 모음집이다! 이는 더이상 사용되어지지 않는 메모리인데 아직은 방출되지 않은 메모리를 의미한다. 그러면 여기서 사용은 무엇이고, 방출은 무엇일까? 해당 내용을 살펴보면 다음과 같다!
메모리의 lifecycle은 <code>Allocate memory</code> -&gt; <code>Use memory</code> -&gt; <code>Release memory</code>의 3단계의 라이프 사이클을 가진다. 메모리가 저장되고, 사용되어진다. 그 후에 끝나게 되면 방출이 되어진다. </p>
<p>즉, 정리하자면 가비지 컬렉션은 메모리가 사용되면 방출되어져야 하는 데 이 과정이 이뤄나지 않은 것들을 모은 것을 의미한다.</p>
<p>C언어 에서는 명시적으로 메모리를 할당 해제 하지만 JS에서는 수동으로 메모리를 관리하는 대신 가비지 컬렉션이 알아서 메모리를 관리해준다. 메모리에 할당된 값이 더이상 필요하지 않다고 판단될 때 메모리를 해제시키는 과정을 가비지 컬렉션이라고 부르며 이 역할을 가비지 컬렉터가 맡고 있다.</p>
<p>가비지 컬렉터가 ‘필요없다’라고 판단하는 기준은 더 이상 &#39;객체에 닿을 수 없을 때&#39;를 말한다. 닿는다는 roots(전역 변수)를 기준으로 참조, 또는 참조의 참조의… 참조가 되는 객체들입니다. 이 알고리즘을 mark and sweep이라고 부르는데 가비지 컬렉터는 ‘root에서 닿을 수 있는’ 객체들의 reachable을 true로 표시하고, false인 객체들은 메모리에서 해제시킨다.</p>
<p>이는 클로저를 사용될 때 필요없어지면 해제가 되지 않는 문제점이 발생하게 되어진다. 즉, 가비지 컬렉터가 일어나지 않게 된다!</p>
<h1 id="클로저란">클로저란?</h1>
<p><a href="https://velog.io/@ye-ji/%ED%81%B4%EB%A1%9C%EC%A0%80Closure-%EC%99%84%EB%B2%BD%ED%9E%88-%EC%9D%B4%ED%95%B4%ED%95%B4%EB%B3%B4%EC%9E%90">클로저는 내부함수의 변수가 외부함수의 변수에 접근할 수 있는 것을 의미한다. 즉 클로저 함수 안에서는 지역변수, 외부함수의 변수, 전역변수 모두 다 접근이 가능하다. 클로저는 변경이 되지 않아야 하지만 해당 값을 읽고 싶을 때 주로 사용되어진다</a></p>
<p>하지만 클로저를 통해서 템플릿처럼 사용한다면 메모리 누수 문제가 일어나게 된다.</p>
<h1 id="메모리-누수-문제">메모리 누수 문제</h1>
<p>가비지 컬렉터는 알아서 메모리 관리를 해준다는 장점이 있지만, 반대로 수동으로 메모리 해제를 할 수 없기 때문에 발생하는 메모리 누수 문제가 있다. Closure는 Mark And Sweep 알고리즘을 이용해 실행이 끝난 함수의 Lexical Environment를 메모리에서 해제하지 않고 유지한다. 즉, Closure의 필요성을 마친 뒤에도 ‘필요없음’을 가비지 컬렉터에게 알리지 않는다면 메모리 누수가 발생하게 되는 것이다!</p>
<h1 id="해결방법">해결방법</h1>
<p>closure에서 해당 된 변수가 사용되어지고 이를 메모리에서 지우는 방법은 간단하다! Closure를 담고있는 객체를 다른 값으로 초기화 시키면 더 이상 root에서 참조되지 않는 Closure를 가비지 컬렉터가 메모리 해제하게된다!</p>
<pre><code class="language-js">function makeClosureFunc(hi) {
    const name = &quot;peter&quot;;
    return function () {
        console.log(`${hi} ${name}~!`);
    };
}

const sayHiToPeter = makeClosureFunc(&quot;Good morning!&quot;);
sayHiToPeter(); //Good morning! peter~!

// ~ 함수의 필요성이 완료됨 ~

sayHiToPeter = null;
// 가비지 컬렉터가 이전 할당 값인 Closure의 reachable이 false 된 것을 확인하고 메모리에서 해제 함
</code></pre>
<p>이렇게 closure의 메모리 누수 문제 때문에 클로저의 사용을 자제해야한다는 의견도 있다고 한다. 이러한 클로저를 대체하기 위해서는 즉시 실행함수를 이용하여 private data를 구현하는 방법도 있다!</p>
<pre><code class="language-js">(function makePrivateFunc() {
    const message = &quot;private data&quot;;
    const privateFunc = function () {
        console.log(`${message} can also implemented through the IIFE`);
    };
    privateFunc();
})();</code></pre>
<p>출처) <a href="https://blog.sessionstack.com/how-javascript-works-memory-management-how-to-handle-4-common-memory-leaks-3f28b94cfbec">https://blog.sessionstack.com/how-javascript-works-memory-management-how-to-handle-4-common-memory-leaks-3f28b94cfbec</a>
<a href="https://dkje.github.io/2020/09/18/Closure/">https://dkje.github.io/2020/09/18/Closure/</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Error] IntrinsicAttributes props in React Typescript component]]></title>
            <link>https://velog.io/@ye-ji/Error-IntrinsicAttributes-props-in-React-Typescript-component-6nak5n7m</link>
            <guid>https://velog.io/@ye-ji/Error-IntrinsicAttributes-props-in-React-Typescript-component-6nak5n7m</guid>
            <pubDate>Wed, 13 Apr 2022 13:51:05 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/ye-ji/post/bbd1fa1e-74f8-4b5b-a738-6c37b09cb38c/image.png" alt=""></p>
<p>이 오류는 map함수를 이용해서 부모 컴포넌트에서 자식 컴포넌트로 props를 보낼 때 나는 오류이다.
즉, <code>[{...}, {...}, {...}]</code> 해당되는 데이터를 map함수를 이용해서 <code>{...}</code> 객체 형식으로 props를 보낼 때 타입 오류에 해당되는 내용이다.</p>
<h1 id="해결법">해결법</h1>
<p><code>부모.tsx</code></p>
<pre><code class="language-tsx">function SearchPage(): JSX.Element {
  const repoData = [{...}, {...}, {...}]
  return (
      &lt;Container&gt;
        {repoData.map((item) =&gt; (
          &lt;Card data={item} /&gt;
        ))}
      &lt;/Container&gt;
  );
}</code></pre>
<p><code>자식.tsx</code></p>
<pre><code class="language-tsx">function Card({ data }: { data: RepositoryItem }): JSX.Element {
  return (
    &lt;Wrapper&gt;
      &lt;Profile src={data.avatar} /&gt;
      &lt;Content&gt;
        &lt;Title&gt;{data.title}&lt;/Title&gt;
        &lt;User&gt;{data.user}&lt;/User&gt;
        &lt;Desc&gt;{data.desc}&lt;/Desc&gt;
        &lt;Date&gt;{data.date}&lt;/Date&gt;
        &lt;Save&gt;저장하기&lt;/Save&gt;
      &lt;/Content&gt;
    &lt;/Wrapper&gt;
  );
}</code></pre>
<p>나는 자식 컴포넌트에서 <code>(data: RepositoryItem)</code>와 같이 데이터 타입을 지정했는데 <code>{ data }: { data: RepositoryItem }</code>처럼 작성을 해야된다!!!</p>
<hr>
<p>출처) <a href="https://stackoverflow.com/questions/71106004/intrinsicattributes-props-in-react-typescript-component">https://stackoverflow.com/questions/71106004/intrinsicattributes-props-in-react-typescript-component</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[함수 호출 방식과 관계 없이 this를 지정할 수 있는 방법 : call, apply, bind]]></title>
            <link>https://velog.io/@ye-ji/%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C-%EB%B0%A9%EC%8B%9D%EA%B3%BC-%EA%B4%80%EA%B3%84-%EC%97%86%EC%9D%B4-this%EB%A5%BC-%EC%A7%80%EC%A0%95%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8A%94-%EB%B0%A9%EB%B2%95-call-apply-bind</link>
            <guid>https://velog.io/@ye-ji/%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C-%EB%B0%A9%EC%8B%9D%EA%B3%BC-%EA%B4%80%EA%B3%84-%EC%97%86%EC%9D%B4-this%EB%A5%BC-%EC%A7%80%EC%A0%95%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8A%94-%EB%B0%A9%EB%B2%95-call-apply-bind</guid>
            <pubDate>Wed, 06 Apr 2022 06:26:14 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트에서는 일반적인 방법 외에도 함수를 어디서 어떻게 호출했느냐에 관계 없이 this가 무엇인지 지정할 수 있다. </p>
<p>그럼 여기서 this는 정확히 뭔데? 라고 의문이 들 것이다.</p>
<h1 id="this">this</h1>
<p><code>this</code>는 자바스크립트에서 다른 언어와 비교했을 때 조금 다르게 동작한다. 대부분의 경우, <strong><code>this</code>의 값은 함수를 호출하는 방법</strong>에 의해 결정이 되어진다. 자바스크립트에서는 선언하면서 결정되는 것이 있고, 호출할 때 결정되는 게 있다. 선언할 때 결정되는 것은 클로저가 있다. 선언된 위치에 따라 달라진다. <code>this</code>의 핵심은 호출하는 방법에 의해서 결정된다!!</p>
<pre><code class="language-js">const someone = {
    name: &#39;yeji&#39;,
    whoAmI: function(){
        console.log(this);
    }
};
someone.whoAmI(); // {name: &quot;yeji&quot;, whoAmI: f}

const myWhoAmI = someone.whoAmI;
myWhoAmI(); // Window {postMessage: f, blur: f, ...}</code></pre>
<p>// someone.whoAmI()와 myWhoAmI()는 서로 같은 function을 의미하지만 식을 출력해보면 값이 달라지는 것을 알 수 있다. 호출하는 방법이 달라졌기 때문이다. this를 알기 위해서는 호출을 무엇이 했는지 알아야한다. 즉, 직접 호출하는 그 코드를 살펴보아야 한다. 
첫번째 호출하는 <code>someone.whoAmI();</code>의 호출하는 직접적인 부분은 <code>someone</code>인 것이다. <code>myWhoAmI();</code>는 자바스크립트 코드를 실행하는 자체 글로벌에 있고, 글로벌은 window이기 때문에 window가 호출하는 셈인 것이다. 
*<em>즉, 자바스크립트의 this는 <code>this === 호출한 객체</code>이다!!! *</em></p>
<h1 id="call--this를-특정-값으로-지정">call : this를 특정 값으로 지정</h1>
<p><code>call()</code> 메소드는 모든 함수에서 사용할 수 있으며, this를 특정값으로 지정할 수 있다. </p>
<pre><code class="language-js">const mike = {
    name: &quot;Mike&quot;,
}
const tom = {
    name: &quot;Tom&quot;,
}
function showThisName(){
    console.log(this.name);
}

showThisName(); // 아무런 값이 뜨지 않음
showThisName().call(mike); // &quot;Mike&quot;</code></pre>
<p>mike와 tom 객체가 있고, showThisName()이라는 함수가 있다. 이 함수는 this.name을 보여준다. <code>showThisName();</code>을 호출하면 아무런 값이 뜨지 않는다. 왜냐하면 여기서 this는 window를 가르키기 때문에 window.name은 &quot;&quot; 빈 문자열 이어서 아무런 값이 뜨지 않는다. 
이 때 <code>showThisName().call();</code>을 해주고 mike를 전달해준다면 <code>Mike</code>가 나오게 된다. 함수를 호출하면서 call을 사용하고 this로 사용할 객체를 넘기면 해당 함수가 주어진 객체의 메소드 인 것처럼 사용할 수 있다. </p>
<pre><code class="language-js">const mike = {
    name: &quot;Mike&quot;,
}
const tom = {
    name: &quot;Tom&quot;,
}
function showThisName(){
    console.log(this.name);
}

function update(birthYear, occupation){
    this.birthYear = birthYear;
    this.occupation = occupation;
}

update.call(mike, 1999, &quot;singer&quot;);
console.log(mike);
// {name: &quot;mike&quot;, birthYear: 1999, occupation: &quot;singer&quot;}
update.call(tom, 2002, &quot;teacher&quot;);
console.log(tom);
// {name: &quot;tom&quot;, birthYear: 2002, occupation: &quot;teacher&quot;}</code></pre>
<p><code>call</code>의 첫번째 매개변수는 this로 사용할 값이고, 매개변수가 더 있으면 그 매개변수라는 함수로 전달되어진다. </p>
<h1 id="apply--call과-유사-매개변수를-배열로-받음">apply : call과 유사, 매개변수를 배열로 받음</h1>
<pre><code class="language-js">const mike = {
    name: &quot;Mike&quot;,
}
const tom = {
    name: &quot;Tom&quot;,
}
function showThisName(){
    console.log(this.name);
}

function update(birthYear, occupation){
    this.birthYear = birthYear;
    this.occupation = occupation;
}

update.apply(mike, [1999, &quot;singer&quot;]);
console.log(mike);
// {name: &quot;mike&quot;, birthYear: 1999, occupation: &quot;singer&quot;}
update.apply(tom, [2002, &quot;teacher&quot;]);
console.log(tom);
// {name: &quot;tom&quot;, birthYear: 2002, occupation: &quot;teacher&quot;}</code></pre>
<p><code>apply</code>는 함수 매개변수를 처리하는 방법을 제외하면 call과 완전히 같다. call은 일반적인 함수와 마찬가지로 매개변수를 직접 받지만, apply는 매개변수를 배열로 받는다. <code>[]</code> 배열로 묶어주기만 하면<code>call()</code>과 동일한 결과값을 반환한다.</p>
<pre><code class="language-js">const minNum = Math.min(3, 10, 1, 6, 4);
const maxNum = Math.max(3, 10, 1, 6, 4);

console.log(minNum); // 1
console.log(maxNum); // 10

const nums = [3, 10, 1, 6, 4];
console.log(Math.min(nums)); // NaN
console.log(Math.max(nums)); // NaN

const minNum = Math.min.apply(null, nums);
const maxNum = Math.max.apply(null, nums);
console.log(minNum) // 1
console.log(maxNum) // 10</code></pre>
<p><code>apply</code>는 배열요소를 함수 매개변수로 사용할 때 유용하다. 최댓값과 최솟값을 구하는 코드가 있다고 하면 배열로 넣었을 시에 NaN이 나오게 된다.
<code>apply()</code>는 두 번째 매개변수로 배열을 전달하게 되면 그 요소들을 차례대로 인수로 사용한다. 그러니깐 <code>(null, nums)</code>사용하면 결과값이 동일하다.</p>
<h1 id="bind--함수의-this값을-영구히-바꿈">bind : 함수의 this값을 영구히 바꿈</h1>
<pre><code class="language-js">const mike = {
    name: &quot;Mike&quot;,
}

function update(birthYear, occupation){
    this.birthYear = birthYear;
    this.occupation = occupation;
}

const updateMike = update.bind(mike);
updateMike(1980, &#39;police&#39;);
console.log(mike);
// {name: &quot;Mike&quot;, birthYear: &quot;1980&quot;, occupation: &quot;police&quot;}</code></pre>
<p>어떻게 호출되었는지 개의치 않고 설정할 수 있는 것이 <code>bind</code>메소드 이다. 즉, this를 고정시킨다는 의미이다. update함수를 이리저리 옮기면서 호출하면 this값을 &quot;Mike&quot;로 나오게 하려면 bind를 사용하며 된다. <code>const updateMike = update.bind(mike);</code> 이 bind는 새로 바인딩할 함수를 만든다. 이 함수는 항상 mike를 this로 받는다. </p>
<pre><code class="language-js">const user = {
  name: &quot;Mike&quot;,
  showName function(){
      console.log(&quot;hello&quot;, ${this.name});
  },
}

user.showName(); // hello, Mike

let fn = user.showName; 
fn(); // hello, -&gt; 아무값도 나오지 않음
fn.call(user); // hello, Mike
fn.apply(user); // hello, Mike

const boundFn = fn.bind(user);
boundFn(); // hello, Mike</code></pre>
<p><code>fn();</code>을 호출하면 아무값도 나오지 않는다. <code>fn();</code>을 할당할 때 this를 잃어버리게 되는 것이다. 메소드는 <code>.</code>앞에 있는 게 this이다. 호출할 때 <code>fn()</code>만 호출하니깐 this가 없는 것이다. 이럴 때에는 call을 사용하면 <code>fn.call(user);</code> this로 사용할 값 user를 넣어주면 된다. </p>
<p><code>정리</code>
this는 호출하는 방법에 의해서 결정되어진다. 이는 굉장히 헷갈릴 수 있기 때문에 이와 관계없이 this를 지정하기 위해서는 call, apply, bind를 사용할 수 있다!</p>
<hr>
<p>참조)
!youtube[KfuyXQLFNW4]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[setTimeout / setInterval]]></title>
            <link>https://velog.io/@ye-ji/setTimeout-setInterval</link>
            <guid>https://velog.io/@ye-ji/setTimeout-setInterval</guid>
            <pubDate>Wed, 06 Apr 2022 03:00:00 GMT</pubDate>
            <description><![CDATA[<h1 id="settimeout">setTimeout</h1>
<blockquote>
<p>일정 시간이 지난 후 함수를 실행</p>
</blockquote>
<pre><code class="language-js">function fn(){
    console.log(3)
}
setTimeout(fn, 3000);</code></pre>
<p>이 코드는 3초 후에 로그를 찍어준다. setTimeOut함수는 두 개의 매개변수를 받는다. 1번째에는 일정시간이 지난 후에 실행해주는 함수이고, 두번째는 시간이다. 3000은 3s를 의미한다. </p>
<pre><code class="language-js">setTimeout(function() {
  console.log(3);
}, 3000)</code></pre>
<p>또한 이렇게 사용할 수 있다.</p>
<pre><code class="language-js">function showName(name){
    console.log(name); // &#39;Mike&#39;
}
setTimeout(showName, 3000, &#39;Mike&#39;);
// setTimeout(함수, 시간, 인수);</code></pre>
<p>만약 인수가 필요하다면 시간 뒤에 해당 값을 넣어주면 된다.</p>
<h3 id="cleartimeout">clearTimeout()</h3>
<p>예정된 작업을 없애는 메소드이다. </p>
<pre><code class="language-js">const tId = function showName(name){
    console.log(name);
}
setTimeout(showName, 3000, &#39;Mike&#39;);
clearTimeout(tId); </code></pre>
<p>3초가 지난 후에 실행되는 코드이기 때문에 <code>clearTimeout()</code>을 사용하면 아무런 일도 일어나지 않는다</p>
<h1 id="setinterval">setInterval</h1>
<blockquote>
<p>일정 시간 간격으로 함수를 반복</p>
</blockquote>
<pre><code class="language-js">function showName(name){
    console.log(name);
}
const tId = setInterval(showName, 3000, &#39;Mike&#39;);
// &#39;Mike&#39; &#39;Mike&#39; &#39;Mike&#39;
clearInterval(tId);</code></pre>
<p><code>setInterval</code>은 <code>setTimeout</code>과 사용법이 동일하다. 한번 실행하고 끝나는 <code>setTimeout</code>달리 계속 반복해서 실행되어진다. 3초마다 &#39;Mike&#39;가 찍히게 된다.
중간에 중단하고 싶다면 <code>clearInterval()</code>을 실행하면 된다.</p>
<hr>
<pre><code class="language-js">setTimeout(function() {
  console.log(2);
}, 0)

console.log(1);</code></pre>
<p>한가지 주의사항이 있다! delayTime을 0으로 주어도 바로 실행되어지지 안않기때문에 <code>console.log(1)</code>이 실행되어진 후 <code>console.log(2)</code>가 출력되어진다.</p>
<hr>
<p>출처) 
!youtube[nwk_aNbFEEc]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[클로저(Closure) 완벽히 이해해보자! ]]></title>
            <link>https://velog.io/@ye-ji/%ED%81%B4%EB%A1%9C%EC%A0%80Closure-%EC%99%84%EB%B2%BD%ED%9E%88-%EC%9D%B4%ED%95%B4%ED%95%B4%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@ye-ji/%ED%81%B4%EB%A1%9C%EC%A0%80Closure-%EC%99%84%EB%B2%BD%ED%9E%88-%EC%9D%B4%ED%95%B4%ED%95%B4%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Wed, 06 Apr 2022 02:46:17 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트는 어휘적 환경(Lexical Environment)을 갖는다.</p>
<blockquote>
<p><strong>어휘적 환경이란...?</strong>
=&gt; 간단하게 생각하면, 정적인(변하지 않는) 환경이다!</p>
</blockquote>
<pre><code>let one;
one = 1;

function addOne(num){
    console.log(one + num);
}

addOne(5);</code></pre><p>이러한 코드가 있을 때 어떻게 동작하는 지 알아보자!</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/697cf2c0-9657-4c17-90e4-3a3d7a5db7aa/image.png" alt=""></p>
<p>코드가 실행되면 스크립트에서 선언한 변수들이 Lexical 환경에 올라가게 된다. let으로 선언된 변수도 호이스팅 되어지고, Lexical 환경으로 올라가지만 초기화가 되어있지 않은 상태이다. 초기화가 되어있지 않기 때문에 사용은 못한다. 그에 비해 함수 선언문은 변수와 달리 바로 초기화 되어진다. 저 위치에서도 사용이 가능하다. 변수에 할당한 함수 표현식은 저러한 형식으로는 되지 않는다. </p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/f801a5bd-c681-4df8-b790-89ac54cbf447/image.png" alt=""></p>
<p>이제 <code>let one</code>을 만나게 되면 아직 할당은 되어있지 않기 때문에 초기값 undefined를 얻게 된다. 이제 사용을 해도 에러가 발생하지 않는다. 값이 undefined일 뿐이다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/959dc750-3705-4746-b65f-c7d87180db38/image.png" alt=""></p>
<p>이제 one에 숫자 1이 할당되어졌다. </p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/423225a8-a6b9-4f78-9dee-cff8fe780f49/image.png" alt=""></p>
<p>함수 선언은 초기에 완료되었기에 마지막 라인으로 가서 함수가 실행되어진다. 그 순간 새로운 Lexical 환경이 만들어지게 된다. 이곳에는 함수가 넘겨받은 매개변수와 지역변수들이 저장되어진다. 함수가 호출되는 동안 함수에서 만들어진 내부 Lexical 환경과 외부에서 받은 전역 Lexical 환경 두 개를 가지게 된다. 내부 Lexical 환경은 외부 Lexical 환경에 대한 참조를 가지게 된다. 지금은 저 함수의 내부 Lexical 환경이 전역 Lexical 환경이다. 즉 코드에서 변수를 찾을 때 내부에서 찾고 없으면 외부, 거기에도 없다면 전역 Lexical 환경까지 범위를 넓혀서 찾는다. </p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/1fc20a40-89c2-4117-af11-dcc01d9d888a/image.png" alt=""></p>
<p>이 코드에서 one과 num은 내부 Lexical 환경에서 먼저 찾는다. num은 찾았지만 one은 없기에 이러한 경우 외부로 넓혀서 있는지 찾고 난 후 찾게 되면 비로소 식을<code>one + num</code> 실행할 수 있게 된다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/01e2eb42-5c2b-4d76-a43e-0c9581fd3612/image.png" alt=""></p>
<p>Add함수를 만들어주는 함수 <code>makeAdder</code> 최초 실행 시 <code>makeAdder</code>와 변수 <code>add3</code>은 전역 Lexical 환경에 들어가게 된다. <code>add3</code>은 초기화가 되지 않은 상태이고, 사용할 수 없다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/c75b7168-1191-4ac6-a2a3-991ea47acef4/image.png" alt=""></p>
<p>노란색 라인이 실행될 때 <code>makeAdder</code>가 실행되고, Lexical 환경이 만들어지게 된다. 이 때 전달받은 x의 값이 들어가게 된다. 함수의 Lexical 환경에는 넘겨받은 매개변수와 지역변수들이 저장되어진다. </p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/c2f18ec8-0cc5-46b5-a738-53be99bd22d5/image.png" alt=""></p>
<p>전역 Lexical 환경에 있던 <code>add3</code>은 함수가 실행되어서 return 하는 함수가 되어진다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/5afc4f47-8387-4158-b25a-5dd13027bd76/image.png" alt=""></p>
<p>이제 마지막 줄이 실행되어지면 빨간 줄의 함수가 실행되어진다. 이 때 또다른 Lexical 환경이 만들어지게 된다. y가 2로 들어가게 된다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/99d815d1-c052-40c1-aea0-aff38b2f66ae/image.png" alt=""></p>
<p>이제 <code>x + y</code>를 하게 된다면 </p>
<p>1) x와 y를 찾게 된다. y는 있지만 
2) x는 없으므로 참조하는 외부 Lexical 환경으로 가서 찾게 된다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/9b92271c-91ef-4c37-93d0-9ade5ec62e7c/image.png" alt=""></p>
<p>정리를 하면 이 함수는 자신이 y를 가지고 있고, 상위 함수인 makeAdder의 x에 접근할 수 있다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/8b4653f0-2155-4ece-b396-6078ff3ca75d/image.png" alt=""></p>
<p>add3함수가 생성된 이후에는 상위함수인 makeAdder의 x에 접근이 가능하다. 이것을 <strong>클로저</strong>라고 한다!!!!</p>
<blockquote>
<p>Closure</p>
</blockquote>
<ul>
<li>함수와 그 함수의 렉시컬 환경의 조합</li>
<li>함수가 생성될 당시의 외부 변수를 기억하고 </li>
<li>생성된 이후에도 계속해서 접근이 가능하다</li>
</ul>
<p>외부 함수의 실행이 끝나서 외부 함수가 소멸이 되어도 내부 함수가 외부함수에 접근할 수 있다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/39045b4e-bd11-4734-9c32-eb4098997a27/image.png" alt=""></p>
<p>여기서 <code>makeAdder(10)</code>이 호출되어지지만 <code>add3</code>은 아무런 변화가 없다. 즉 <code>add10</code>과 <code>add3</code>은 서로 다른 환경을 가지고 있는 것이다.</p>
<p><code>위의 예제를 봐도 잘 이해가 되지 않아서 다른 예제들을 가지고 왔다.</code></p>
<pre><code class="language-js">function outer(){
  const a  = 1;
  console.log(a);  // 1
}
outer();</code></pre>
<p>여기서 outer는 아래와 같은 Lexical 환경을 가지게 된다. a라는 변수는 1이 들어있다는 표를 가지게 된다. </p>
<p><code>outer</code></p>
<table>
<thead>
<tr>
<th>A</th>
<th>1</th>
</tr>
</thead>
</table>
<pre><code class="language-js">function outer(){
  const a  = 1;
  const b = &#39;B&#39;;
  function inner(){
    const c = &#39;hi&#39;;
    conosole.log(b); // B
  }
  inner();
}
outer();</code></pre>
<p><code>inner</code></p>
<table>
<thead>
<tr>
<th>c</th>
<th>hi</th>
</tr>
</thead>
</table>
<p><code>outer</code></p>
<table>
<thead>
<tr>
<th>A</th>
<th>1</th>
</tr>
</thead>
<tbody><tr>
<td>b</td>
<td>B</td>
</tr>
</tbody></table>
<p>해당 콘솔에 어떻게 b가 찍히게 되었을까?라는 의문을 가지게 된다. inner안에는 분명히 b가 없는데 말이다! inner()함수가 outer{}에 들어가있기 때문에 영향을 미치게 된다. 즉, 해당 블록<code>{}</code> 안에서 사용이 가능하다. 이 때 inner안에는 b가 없으므로 해당 값을 찾기 위에서 outer까지 범위를 넓혀서 찾게 된다. </p>
<p>이제 총 정리를 해보면 </p>
<blockquote>
<p>클로저는 내부함수의 변수가 외부함수의 변수에 접근할 수 있는 것을 의미한다. 즉 클로저 함수 안에서는 지역변수, 외부함수의 변수, 전역변수 모두 다 접근이 가능하다. 클로저는 변경이 되지 않아야 하지만 해당 값을 읽고 싶을 때 주로 사용되어진다</p>
</blockquote>
<hr>
<p>출처) 
!youtube[tpl2oXQkGZs]</p>
<p>!youtube[MbYShFxp-j0]</p>
<p><a href="https://haesoo9410.tistory.com/342">https://haesoo9410.tistory.com/342</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[나머지 매개변수, 전개 구문(Rest parameters, Spread syntax)]]></title>
            <link>https://velog.io/@ye-ji/%EB%82%98%EB%A8%B8%EC%A7%80-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EC%A0%84%EA%B0%9C-%EA%B5%AC%EB%AC%B8Rest-parameters-Spread-syntax</link>
            <guid>https://velog.io/@ye-ji/%EB%82%98%EB%A8%B8%EC%A7%80-%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98-%EC%A0%84%EA%B0%9C-%EA%B5%AC%EB%AC%B8Rest-parameters-Spread-syntax</guid>
            <pubDate>Wed, 06 Apr 2022 01:13:29 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>나머지 매개변수와 전개 구문은 <code>...</code> 로 사용되어진다.
그렇다면 이 둘의 차이점은 무엇일까?
나머지 매개변수는 함수의 인수 전달 시에 마지막으로 사용되며, 전달된 인수들의 목록을 배열로 압축할때 사용되어진다. 
전개 구문은 뭉쳐있는 여러 개의 값들을 개별적인 값들의 목록으로 만들때 사용되어진다. 즉, 나머지 매개변수는 배열로 합쳐주고, 전개 구문은 배열 또는 객체를 펼쳐주는 역할을 한다.</p>
</blockquote>
<h1 id="나머지-매개변수rest-parameters">나머지 매개변수(Rest parameters)</h1>
<h3 id="인수전달">인수전달</h3>
<pre><code class="language-js">function showName(name){
    console.log(name);
}
showName(&#39;Mike&#39;); // &#39;Mike&#39;
showName(&#39;Mike&#39;, &#39;Tom&#39;); // ?
// 에러는 발생하지 않고 &#39;Mike&#39;만 출력되어진다.
showName(); // undefined</code></pre>
<p>자바스크립트에서 함수의 넘겨주는 인수의 개수는 제한이 없다. 지금은 name하나만 사용되어져 있는데 실제 호출할 때 그 개수를 맞출 필요는 없다. <code>showName()</code>처럼 아무것도 전달하지 않아도 된다.
함수의 인수에는 접근하는 방법이 2가지 있다. 하나는 arguments로 접근하는 방법이고, 또 다른 하나는 나머지 매개변수를 쓰는 것이다! 과거에는 argument만 사용이 가능했다. 지금은 여러가지 장점이 있는 나머지 매개변수를 사용하는 추세이다. </p>
<h3 id="arguments">arguments</h3>
<ul>
<li>함수로 넘어 온 모든 인수에 접근할 수 있음</li>
<li>함수 내에서 이용 가능한 지역 변수</li>
<li>length / index가 있기 때문에 배열이라고 생각할 수 있지만 Array 형태의 객체임</li>
<li><blockquote>
<p>Array 형태의 객체는 length와 index등의 속성을 가지고 있지만 배열의 내장 메소드는 가지고 있지 않다. 그래서 forEach나 map은 사용 불가능하다.</p>
</blockquote>
</li>
<li>배열의 내장 메소드 없음(forEach, map 사용 불가)<pre><code class="language-js">function showName(name){
  console.log(arguments.length);
  console.log(arguments[0]);
  console.log(arguments[1]);
}
showName(&#39;Mike&#39;, &#39;Tom&#39;);
// 2
// &#39;Mike&#39;
// &#39;Tom&#39;</code></pre>
</li>
</ul>
<h3 id="나머지-매개변수rest-parameters-1">나머지 매개변수(Rest Parameters)</h3>
<pre><code class="language-js">function showName(...names){
    console.log(names);
}
showName(); // []
showName(&#39;Mike&#39;); // [&#39;Mike&#39;]
showNmae(&#39;Mike&#39;, &#39;Tom&#39;); // [&#39;Mike&#39;, &#39;Tom&#39;]</code></pre>
<p>ES6를 사용할 수 있는 환경이면 나머지 매개변수를 사용하는 것을 권장한다. 나머지 매개변수는 정해지지 않은 개수의 수를 배열로 나타낼 수 있게 한다. <code>...</code>를 찍고 뒤에 names라는 배열 이름을 정해준다. 그러면 names배열 안에 전달된 변수들이 들어가게 된다. 아무것도 전달하지 않으면 undefined가 아니라 빈 배열이 나타나게 된다.</p>
<pre><code class="language-js">// 전달받은 모든 수를 더해야함
function add(...numbers){
    const result = numbers.reduce((prev, cur) =&gt; prev + cur);
    return result;
}

console.log(add(1,2,3)); // 6
console.log(add(1,2,3,4,5,6,7,8,9,10)); // 55

// ----------------------------------------------------

// user 객체를 만들어 주는 생성자 함수 만들기
function User(name, age, ...skills){
    this.name = name;
    this.age = age;
    this.skills = skills;
}

const user1 = new User(&quot;Mike&quot;, 30, &quot;html&quot;, &quot;css&quot;);
const user2 = new User(&quot;Tom&quot;, 20, &quot;JS&quot;, &quot;React&quot;);
const user3 = new User(&quot;Jane&quot;, 10, &quot;English&quot;);

console.log(user1);
// {
//   name: &quot;Mike&quot;,
//   age: 30,
//   skills: [&quot;html&quot;, &quot;css&quot;]
// }
console.log(user2);
// {
//   name: &quot;Tom&quot;,
//   age: 20,
//   skills: [&quot;JS&quot;, &quot;React&quot;]
// }
console.log(user3);
// {
//   name: &quot;Jane&quot;,
//   age: 10,
//   skills: [&quot;English&quot;]
// }</code></pre>
<h1 id="전개-구문spred-syntax">전개 구문(Spred Syntax)</h1>
<h3 id="전개-구문spred-syntax--배열">전개 구문(Spred Syntax) : 배열</h3>
<pre><code class="language-js">const arr1 = [1,2,3];
const arr2 = [4,5,6];
const result = [...arr1, ...arr2];

console.log(result); // [1, 2, 3, 4, 5, 6]

const result = [0, ...arr1, ...arr2, 7, 8, 9];
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]</code></pre>
<p><code>arr.push()</code> / <code>arr.splice()</code> / <code>arr.concat()</code> 작업을  전개 구문이 한 번에 줄여줌</p>
<h3 id="전개-구문spred-syntax--객체">전개 구문(Spred Syntax) : 객체</h3>
<pre><code class="language-js">const user = {name: &#39;Mike&#39;}
const mike = {...user, age: 30}

console.lg(mike) // {name: &#39;Mike&#39;, age: 30}</code></pre>
<p><code>Object.assign()</code>을 사용할 필요도 없음!</p>
<h3 id="전개-구문spred-syntax--복제">전개 구문(Spred Syntax) : 복제</h3>
<pre><code class="language-js">const arr = [1, 2, 3];
const arr2 = [...arr]; // [1, 2, 3]

const user = {name: &#39;Mike&#39;, age: 30};
const user2 = {...user};

user2.name = &quot;Tom&quot;;

console.log(user.name); // &quot;Mike&quot;
console.log(user2.name); // &quot;Tom&quot;</code></pre>
<hr>
<p>출처 )
!youtube[tpl2oXQkGZs]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[구조 분해 할당 (Destructuring assignment)]]></title>
            <link>https://velog.io/@ye-ji/%EA%B5%AC%EC%A1%B0-%EB%B6%84%ED%95%B4-%ED%95%A0%EB%8B%B9-Destructuring-assignment</link>
            <guid>https://velog.io/@ye-ji/%EA%B5%AC%EC%A1%B0-%EB%B6%84%ED%95%B4-%ED%95%A0%EB%8B%B9-Destructuring-assignment</guid>
            <pubDate>Wed, 06 Apr 2022 00:32:04 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>구조 분해 할당 구문은 배열이나 객체의 속성을 분해해서 그 값을 변수에 담을 수 있도록 하는 표현식</p>
</blockquote>
<h1 id="배열-구조-분해">배열 구조 분해</h1>
<pre><code class="language-js">const [x, y] = [1, 2];
console.log(x); // 1
console.log(y); // 2

const users = [&#39;Mike&#39;, &#39;Tom&#39;, &#39;Jane&#39;];
const [user1, user2, user3] = users;

console.log(user1); // &#39;Mike&#39;
console.log(user2); // &#39;Tom&#39;
console.log(user3); // &#39;Jane&#39;

const str = &quot;Mike-Tom-Jane&quot;;
const [user1, user2, user3] = str.split(&#39;-&#39;);
// [&#39;Mike&#39;, &#39;Tom&#39;, &#39;Jane&#39;]

console.log(user1); // &#39;Mike&#39;
console.log(user2); // &#39;Tom&#39;
console.log(user3); // &#39;Jane&#39;</code></pre>
<h3 id="배열-구조-분해--기본값">배열 구조 분해 : 기본값</h3>
<p>만약 해당하는 값이 없다면 어떻게 될까?</p>
<pre><code class="language-js">const [a,b,c] = [1,2];</code></pre>
<p>undefined가 들어간다.
a에는 1이 들어가고, b에는 2가 들어가지만, c에는 undefined가 들어간다!</p>
<pre><code>const [a=3, b=4, c=5] = [1,2];

console.log(a); // 1
console.log(b); // 2
console.log(c); // 5</code></pre><p>이 때 기본값을 주면 에러를 방지할 수 있다.</p>
<h3 id="배열-구조-분해--일부-반환값-무시">배열 구조 분해 : 일부 반환값 무시</h3>
<pre><code class="language-js">const [user1, , user2] = [&#39;Mike&#39;, &#39;Tom&#39;, &#39;Jane&#39;, &#39;Tony&#39;];

console.log(user1); // &#39;Mike&#39;
console.log(user2); // &#39;Jane&#39;</code></pre>
<p>공백과 쉼표를 이용해서 필요하지 않는 배열을 무시할 수 있다. 첫번째 요소는 user1에 들어가고, 두번째 요소는 생략, 세번째 요소는 user2에 할당되어진다.</p>
<h3 id="배열-구조-분해--바꿔치기">배열 구조 분해 : 바꿔치기</h3>
<pre><code class="language-js">[a, b] = [b, a];</code></pre>
<p>기존에는 이미 할당 된 변수를 바꾸려면 의미없는 변수를 하나 더 만들어야 했다. </p>
<pre><code class="language-js">let a = 1;
let b = 2;

// a = b; -&gt; 기존의 a의 값이 사라짐
let c  = a;
a = b;
b = c;</code></pre>
<h1 id="객체-구조-분해">객체 구조 분해</h1>
<pre><code class="language-js">const user = {name: &#39;Mike&#39;, age: 30};
const {name, age} = user;

console.log(name); // &#39;Mike&#39;
console.log(age); // 30</code></pre>
<p>객체 구조 분해는 순서에 신경쓰지 않아도 된다. 즉, <code>const {name, age} = user;</code>나 <code>const {age, name} = user;</code>으로 해도 동일하게 동작한다.</p>
<h3 id="객체-구조-분해--새로운-변수-이름으로-할당">객체 구조 분해 : 새로운 변수 이름으로 할당</h3>
<pre><code class="language-js">const user = {name: &#39;Mike&#39;, age: 30};
const {name, age} = user;
const {name: userName, age: userAge} = user;

console.log(userName); // &#39;Mike&#39;
console.log(userAge); // 30</code></pre>
<p>프로퍼티 키로 무조건 사용해야하는 것은 아니다. <code>:</code>로 새로운 변수 이름을 할당해서 사용할 수 있다.</p>
<h3 id="객체-구조-분해--기본값">객체 구조 분해 : 기본값</h3>
<pre><code class="language-js">const user = {name: &#39;Mike&#39;, age: 30};
const {name, age, gender} = user;
console.log(gender); // undefined

---------------------------------------

const {name, age, gender = &#39;male&#39;} = user;
console.log(gedner) // &#39;male&#39;

---------------------------------------

const user = {
    name: &#39;Jane&#39;,
      age: 18,
      gender: &#39;female&#39;
}
const {name, age, gender = &#39;male&#39;} = user;
console.log(gender) // &#39;female&#39;</code></pre>
<p>배열과 마찬가지로 객체를 분해할 때에도 기본값을 줄 수 있다. 객체로 부터 받은 값이 undefined일때에만 기본값이 사용된다.</p>
<hr>
<p>출처)
!youtube[lV7ulA7R5Nk]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[배열 메소드(Array methods)]]></title>
            <link>https://velog.io/@ye-ji/%EB%B0%B0%EC%97%B4-%EB%A9%94%EC%86%8C%EB%93%9CArray-methods</link>
            <guid>https://velog.io/@ye-ji/%EB%B0%B0%EC%97%B4-%EB%A9%94%EC%86%8C%EB%93%9CArray-methods</guid>
            <pubDate>Tue, 05 Apr 2022 18:09:07 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li><code>push()</code> : 뒤에 삽입</li>
</ul>
</blockquote>
<ul>
<li><code>pop()</code> : 뒤에 삭제 </li>
<li><code>unshift()</code> : 앞에 삽입</li>
<li><code>shift()</code> : 앞에 삭제</li>
</ul>
<p>배열의 대표적인 메소드들에는 <code>push()</code>, <code>pop()</code>, <code>unshift()</code> <code>shift()</code>가 있다. 
이 외의 메소드들에는 어떤 것들이 있는지 알아보자!</p>
<h2 id="arrsplicenm--특정-요소-지움">arr.splice(n,m) : 특정 요소 지움</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/23266fd7-58f5-4b72-9bd5-03008f4625fd/image.png" alt="">
<code>arr.splice(n,m)</code>는 n번째 요소부터 m개를 지우라는 의미로 사용되어진다. 인덱스 1부터 2개를 지우게 된다면 <code>[1,4,5]</code>가 남게 된다.</p>
<h2 id="arrsplicenmx--특정-요소-지우고-추가">arr.splice(n,m,x) : 특정 요소 지우고 추가</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/0295e261-6dd0-4a61-b8ce-18072ab0e9ea/image.png" alt="">
요소들을 지우고 다른 요소로 대체를 하기 위해서는 x자리에 추가할 요소들을 적어주면 된다. 인덱스 1부터 3개를 지우게 되면 <code>2,3,4</code>가 지워지게 된다. 그 자리에 100과 200이 넣어지게 된다.</p>
<p>그렇다면 두번째 인수에 0을 넣게 되면 어떻게 되어질까?
<img src="https://velog.velcdn.com/cloudflare/ye-ji/6a34d5c5-772a-4630-8f00-8b5a6b39ad43/image.png" alt=""></p>
<p>결과는 위의 사진과 같다. 0과 1 사이에 해당 요소들이 들어가게 된다.</p>
<h2 id="arrsplice--삭제된-요소들-반환">arr.splice() : 삭제된 요소들 반환</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/80f20031-11c1-4f3e-a2e7-116a7fbd1d02/image.png" alt=""></p>
<p><code>arr.splice()</code>는 삭제된 요소들을 반환한다. 즉, 메소드들을 사용할 때 값을 반환하는 데 그 값이 삭제된 요소의 배열이다. 예를 보면 <code>arr.splice(1,2)</code> 메소드를 사용한 후 반환한 값을 result에 넣어보면 삭제된 요소들이 포함된 배열이 result의 변수로 들어가는 것을 알 수 있다. </p>
<h2 id="arrslicenm--n부터-m까지">arr.slice(n,m) : n부터 m까지</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/f488e662-4d6a-4d93-8599-def0d604af9e/image.png" alt=""></p>
<p><code>slice()</code>는 <code>splice()</code>와 비슷하게 생겼지만 보다 간단하다. 인덱스 n부터 m까지 반환한다. m은 포함하지 않고 바로 앞자리를 의미하며, 사용하지 않으면 배열 끝까지를 의미한다. 문자열의 slice요소와 동일하다. 만약 괄호안에 아무값도 넣지 않으면 배열이 복사되어진다. </p>
<h2 id="arrconcatarr2-arr3--합쳐서-새-배열-반환">arr.concat(arr2, arr3..) : 합쳐서 새 배열 반환</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/6e059a0b-6b18-4739-a21a-d7db79d3b281/image.png" alt=""></p>
<p><code>concat()</code>메소드는 인자로 주어진 값들을 기존 배열에 합쳐서 새 배열을 반환한다. 현재 배열에 [3,4]를 전달하면 하나로 모아서 배열로 만들어준다. 배열 2개를 전달해도 반환되고, 배열 1개와 인자로 전달을 해도 하나의 배열로 반환되어진다.</p>
<h2 id="arrforeachfn--배열-반복">arr.forEach(fn) : 배열 반복</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/49b3c95b-acc6-4dd6-975e-9d15dbd9560f/image.png" alt=""></p>
<p><code>forEach()</code>로도 <code>for문</code>이나 <code>for of문</code> 처럼 배열을 반복할 수 있다. <code>forEach()</code>는 함수를 인수로 받는다. 그 함수에는 3개의 매개변수가 있는데 1번째는 해당 요소이고, 2번째는 인덱스이다. 마지막 3번째는 해당 배열 자체를 의미한다. 보통 1번째와 2번째만 사용되어진다.</p>
<h2 id="arrindexof--arrlastindexof--배열에서-원하는-값의-인덱스-구하기">arr.indexOf / arr.lastIndexOf : 배열에서 원하는 값의 인덱스 구하기</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/e2c8db7f-3f5c-40e6-b84f-4560a023ab28/image.png" alt=""></p>
<p>문자열의 indexOf와 사용법이 같다. 즉, 해당 배열에서 일치하는 문자열이 있을 경우 해당 값의 위치를 반환한다. 만약 인수가 2개인 경우 2번째 인수는 시작위치를 의미한다. 끝에서 부터 탐색하고 싶으면 <code>lastIndexOf</code>를 사용하면 된다.</p>
<h2 id="arrincludes--포함하는지-확인">arr.includes() : 포함하는지 확인</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/e68de6c5-0e25-4578-8f8f-2b958cf8cd15/image.png" alt="">
<code>arr.includes()</code>는 인덱스를 구할 필요 없이 값이 포함되어있는지 아닌지를 확인할 때 사용되는 메소드이다. </p>
<h2 id="arrfindfn--arrfindindexfn--만족하는-첫번째-요소-반환">arr.find(fn) / arr.findIndex(fn) : 만족하는 첫번째 요소 반환</h2>
<p><code>find()</code>와 <code>findIndex()</code>는 찾는다는 의미는 동일하지만 보다 복잡한 연산이 가능하도록 <code>(fn)</code>함수를 연결할 수 있다. 짝수를 찾아내던지, 성인을 찾는다던지의 예제에서 많이 사용된다.</p>
<blockquote>
<p>🔥 주의해야할 점은 첫번째 true값만 반환하고 끝난다는 것이다.
만약 없으면 undefined를 반환한다.
<code>findIndex()</code>는 해당 인덱스를 반환하고 없으면 -1를 반환함</p>
</blockquote>
<pre><code class="language-js">const arr = [1,2,3,4,5,6];

// arr의 짝수 값 출력
const result = arr.find((item) =&gt; {
  return item % 2 === 0;
});

console.log(result) // 2 -&gt; 첫번째 짝수만 반환됨

// 미성년자 찾기
const userList = [
  {name: &#39;Mike&#39;, age: 30},
  {name: &#39;Jane&#39;, age: 27},
  {name: &#39;Tom&#39;, age: 10}
]
// 객체가 들어있는 배열의 경우 indexOf로는 찾기가 힘듦 : find() 사용
const ageResult = userList.find((user) =&gt; {
    if(user.age &lt; 19){
        return true;
    }
    return false;
})
console.log(ageResult); // {name: &#39;Tom&#39;, age: 10}
// findIndex()로 변경하면 2가 나옴</code></pre>
<h2 id="arrfilter--만족하는-모든-요소를-배열로-반환">arr.filter() : 만족하는 모든 요소를 배열로 반환</h2>
<p><code>find()</code>는 단 하나만 찾았지만 만약 조건을 만족하는 모든 요소를 알고 싶다면 <code>filter()</code>를 사용하면 된다!</p>
<pre><code class="language-js">const arr = [1,2,3,4,5,6];

// arr의 짝수 값 출력
const result = arr.filter((item) =&gt; {
  return item % 2 === 0;
});

console.log(result) // [2,4,6] </code></pre>
<h2 id="arrreverse--역순으로-재정렬">arr.reverse() : 역순으로 재정렬</h2>
<pre><code class="language-js">const arr = [1,2,3,4,5];
arr.reverse(); // [5,4,3,2,1];</code></pre>
<p><code>arr.reverse()</code>는 역순으로 재정렬하는 메소드이다. 최근 가입한 유저부터 보여주거나 게시판의 가장 최근에 작성된 글 순서로 정렬을 할 때 자주 사용되어진다. </p>
<h2 id="arrmapfn--함수를-받아-특정-기능을-시행하고-새로운-배열을-반환">arr.map(fn) : 함수를 받아 특정 기능을 시행하고 새로운 배열을 반환</h2>
<pre><code class="language-js">const userList = [
  {name: &#39;Mike&#39;, age: 30},
  {name: &#39;Jane&#39;, age: 27},
  {name: &#39;Tom&#39;, age: 10}
]
const newUserList = userList.map((user, index) =&gt; {
    return Object.assign({}, user, {
          id: index + 1,
        isAdult: user.age &gt; 19,
    });
});

console.log(newUserList); // [{...}, {...}, {...}]</code></pre>
<p><code>map(fn)</code>은 함수를 받아 특정 기능을 시행하고 새로운 배열을 반환하는 메소드이다. 매번 나이를 확인하기 귀찮아서 isAdult라는 프로퍼티를 추가한 새로운 배열을 만들고자 한다. <code>console.log(newUserList);</code>를 찍어보면 다음과 같다.
<img src="https://velog.velcdn.com/cloudflare/ye-ji/cff53b61-1b8e-4c99-b8dd-0493f8436f70/image.png" alt="">
또한 기존의 userList를 출력하면 기존의 값과 동일하게 나오게 된다. 즉, 해당 객체가 복사가 <code>Object.assign()</code>으로 잘 복사된 것을 확인할 수 있다.</p>
<h2 id="arrjoin--배열-합쳐서-문자열로-반환">arr.join() : 배열 합쳐서 문자열로 반환</h2>
<pre><code class="language-js">const arr = [&quot;안녕&quot;, &quot;나는&quot;, &quot;철수야&quot;];
arr.join(); // &quot;안녕,나는,철수야&quot;
arr.join(&#39; &#39;); // &quot;안녕 나는 철수야&quot;
arr.join(&#39;-&#39;); // &quot;안녕-나는-철수야&quot;</code></pre>
<p>배열을 합쳐서 문자열로 반환하기 위해서는 <code>join()</code>을 사용하면 된다.
만약 ()괄호 안에 <code>(&#39; &#39;)</code> 공백을 주어진다면 해당 쉼표 대신 공백으로 값이 반환되어진다. 다른 값을 넣으면 해당 쉼표가 다른 값으로 변경되어진다.</p>
<h2 id="arrsplit--문자열을-나눠서-배열로-반환">arr.split() : 문자열을 나눠서 배열로 반환</h2>
<pre><code class="language-js">const users = &quot;Mike,Jane,Tom,Tony&quot;;
user.split(&quot;,&quot;); // [&quot;Mike&quot;, &quot;Jane&quot;, &quot;Tom&quot;, &quot;Tony&quot;]</code></pre>
<p><code>split</code>안에 어떤 문자로 나눌 건지 정해주면 배열로 만들어진다. 즉, 예제를 보면 <code>쉼표(,)</code>를 기준으로 나누어서 배열로 만들어준 것이다.</p>
<h2 id="arrayisarray--배열인지-아닌지-확인">Array.isArray() : 배열인지 아닌지 확인</h2>
<pre><code class="language-js">const user = {
    name: &#39;Mike&#39;,
    age: 30,
}
const userList = [&quot;Mike&quot;, &quot;Jane&quot;, &quot;Tom&quot;];

console.log(typeof user); // object
console.log(typeof userList); // object

console.log(Array.isArray(user)); // false
console.log(Array.isArray(userList)); // true</code></pre>
<p>배열인지 아닌지 확인하려면 <code>Array.isArray()</code>메소드를 사용해야한다. 자바스크립트에서 배열은 객체에 속해져있기 때문에 <code>typeof</code>는 객체라고 알려준다. 그래서 배열인지 아닌지 확인하기 위해서는 <code>Array.isArray()</code>메소드를 사용해야한다.</p>
<h2 id="arrsort--배열-재정렬">arr.sort() : 배열 재정렬</h2>
<pre><code class="language-js">const arr = [1,5,4,2,3];
arr.sort(); 
console.log(arr); // [1,2,3,4,5]

const str = [&#39;a&#39;, &#39;d&#39;, &#39;c&#39;, &#39;e&#39;, &#39;b&#39;];
str.sort();
console.log(str); // [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;]</code></pre>
<p>이름대로 배열을 재정렬해준다. 하지만 배열 자체가 변경되니 주의해서 작성해야한다.</p>
<pre><code class="language-js">const arr = [27, 8, 5, 13];
arr.sort();
console.log(arr); // [13, 27, 5, 8]</code></pre>
<p>만약 위와 같이 코드를 작성하면 기존의 값이 <code>[5, 8, 13, 27]</code>로 출력되어야하는데 이상하게 <code>[13, 27, 5, 8]</code>로 출력되어진다. 그 이유는 정렬할 때 요소를 문자열로 취급하기 때문이다. 그래서 1과 2로 시작하는 13과 27이 첫번째 두번째로 나오게 된다. 그러면 우리가 알고 있는 숫자 형태로 정렬하기 위해서는 어떻게 해야할까?
<code>값을 비교할 수 있는 함수를 전달해주어야 한다.</code>
<code>sort(fn)</code>는 함수를 인수로 받는다. </p>
<pre><code class="language-js">const arr = [27, 8, 5, 13];
// function fn(a, b){
//    return a - b;
// };
// arr.sort(fn);
arr.sort((a,b) =&gt; {
    return a - b;
})
console.log(arr); // [5, 8, 13, 27]</code></pre>
<p>두 요소 a,b를 전달하고 크기를 비교해서 <code>양수, 0, 음수</code>인지만 알려주면 된다. a가 크면 양수로 리턴할 것이고, 같으면 0, a가 b보다 작으면 음수를 리턴한다. 
내부 로직은 a와 b를 비교해서 </p>
<ul>
<li>a가 작으면 a를 앞으로 보낸다. </li>
<li>0을 반환하면 가만히 있고, </li>
<li>a가 크면 b가 더 작으므로 b를 앞으로 보낸다. </li>
</ul>
<p>유용한 기능을 모아놓은 <a href="https://lodash.com/">lodash 라이브러리</a>를 이용하면 단순히 <code>_.sortBy(arr)</code>로 이용가능하다. 문자나 숫자나 상관없이 정렬해준다. </p>
<h2 id="arrreduce--실행-값을-누적하여-하나의-결과값을-반환">arr.reduce() : 실행 값을 누적하여 하나의 결과값을 반환</h2>
<pre><code class="language-js">// 배열의 모든 수 합치기
const arr = [1, 2, 3, 4, 5];

// for, for of, forEach 
const result = 0;
arr.forEach(num =&gt; {
    // result = result + num;
  result += num;
})
console.log(result) // 15

const reduceResult = arr.reduce((prev, cur) =&gt; {
    return prev + cur;
}, 0)
console.log(reduceResult) // 15
</code></pre>
<p><code>arr.reduce()</code>는 인수로 함수를 받는다. <code>(누적 계산 값, 현재 값) =&gt; {return 계산 값};</code> 
해당 코드를 분석해보면 </p>
<ul>
<li>처음에는 누산값<code>(prev)</code>이 <code>0</code>이 되어진다 -&gt; <em>초기값이 0이기 때문</em> /  <strong>누산값 : 0</strong></li>
<li>그 뒤의 현재 값<code>(cur)</code> , <code>1</code>을 더해준다. / <strong>누산값 : 1</strong></li>
<li>그 다음 한바퀴가 돌게 되고, 2가 <code>(cur)</code>에 들어오게 된다. </li>
<li>지금까지 계산된 값<code>(prev)</code>은 <code>1</code>이고,  <code>(cur)</code>이 2이어서 <code>prev + cur(1 + 2)</code>가 되어진다. / <strong>누산값 : 3</strong></li>
<li>계산된 값<code>(prev)</code> 3이고, <code>(cur)</code> 3 -&gt; 6 / <strong>누산값 : 6</strong></li>
<li><code>prev(6) + cur(4)</code> / <strong>누산값 : 10</strong></li>
<li><code>prev(10) + cur(5)</code> / <strong>누산값 : 15</strong></li>
</ul>
<p>즉, 다시 간단하게 표현하자면 다음과 같다.</p>
<blockquote>
</blockquote>
<ul>
<li><code>prev(0) + cur(0)</code> / <strong>누산값 : 0</strong></li>
<li><code>prev(0) + cur(1)</code> / <strong>누산값 : 1</strong></li>
<li><code>prev(1) + cur(2)</code> / <strong>누산값 : 3</strong></li>
<li><code>prev(3) + cur(3)</code> / <strong>누산값 : 6</strong></li>
<li><code>prev(6) + cur(4)</code> / <strong>누산값 : 10</strong></li>
<li><code>prev(10) + cur(5)</code> / <strong>누산값 : 15</strong></li>
</ul>
<p>실용적인 예제로 다시 본다면 <code>map()</code>이나 <code>filter()</code>대신에 <code>reduce()</code>를 써서 19살이상인 배열을 반환해본다면 다음과 같다.</p>
<pre><code class="language-js">const userList = [
  {name: &#39;Mike&#39;, age: 30},
  {name: &#39;Jane&#39;, age: 27},
  {name: &#39;Tom&#39;, age: 10},
  {name: &#39;Sue&#39;, age: 26},
  {name: &#39;Harry&#39;, age: 42},
  {name: &#39;Steve&#39;, age: 60},
]

const result = userList.reduce((prev, cur) =&gt; {
    if(cur.age &gt; 19){
        prev.push(cur.name);
    }
  return prev;
}, [])

console.log(result); // [&#39;Mike&#39;, &#39;Jane&#39;, &#39;Sue&#39;, &#39;Harry&#39;, &#39;Steve&#39;]</code></pre>
<ul>
<li>누산값 : []</li>
</ul>
<p>만약에 나이가 19살이상이면 배열에 push해주고, return 한다.</p>
<ul>
<li>누산값 : [&#39;Mike&#39;]</li>
</ul>
<p>만약에 19살보다 작으면 위의 if문이 실행되지 않고 그대로 지금까지 만들어진 <code>return prev</code>를 반환한다.</p>
<p>나이의 합을 구하기 위해서는 아래와 같이 작성하면 된다.</p>
<pre><code class="language-js">const userList = [
  {name: &#39;Mike&#39;, age: 30},
  {name: &#39;Jane&#39;, age: 27},
  {name: &#39;Tom&#39;, age: 10},
  {name: &#39;Sue&#39;, age: 26},
  {name: &#39;Harry&#39;, age: 42},
  {name: &#39;Steve&#39;, age: 60},
]

const result = userList.reduce((prev, cur) =&gt; {
    return prev += cur.age;
}, 0)

console.log(result); // 196</code></pre>
<hr>
<p>출처)
!youtube[pJzO6O-aWew]</p>
<p>!youtube[RW25tEAMC9w]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[문자열 메소드(String methods)]]></title>
            <link>https://velog.io/@ye-ji/%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A9%94%EC%86%8C%EB%93%9CString-methods</link>
            <guid>https://velog.io/@ye-ji/%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%A9%94%EC%86%8C%EB%93%9CString-methods</guid>
            <pubDate>Tue, 05 Apr 2022 16:05:33 GMT</pubDate>
            <description><![CDATA[<p>문자열에는 <code>작은따옴표(&#39;&#39;)</code> , <code>큰따옴표(&quot;&quot;)</code> <code>백틱기호(``)</code> 3가지가 있다.</p>
<pre><code class="language-js">const html = &#39;&lt;div class=&quot;box_title&quot;&gt;제목 영역&lt;/div&gt;&#39;</code></pre>
<p>예를 들어 html 코드 경우에는 작은 따옴표로 감싸는 게 편리하다. </p>
<pre><code class="language-js">const desc = &quot;It&#39;s 3 o&#39;clock&quot;;</code></pre>
<p>반면에 영어로 된 문장은 큰 따옴표로 감싸는 게 편리하다.</p>
<pre><code class="language-js">const name = &#39;Mike&#39;;
const result = `My name is ${name}`; // My name is Mike
const add = `2 더하기 3은 ${2 + 3}입니다.` // 2 더하기 3은 5입니다.</code></pre>
<p>백틱은 달러<code>$</code>와 중괄호<code>{}</code>를 이용해 변수를 표현하거나 표현식을 쓸 수 있다.</p>
<pre><code class="language-js">const desc = `오늘은 맑고 
화창한 날씨가 계속되겠습니다. 
내일은 비 소식이 있겠습니다.`</code></pre>
<p>또한 백틱은 여러 줄을 포함할 수 있다.</p>
<pre><code class="language-js">const desc = &#39;오늘은 맑고\n화창한 날씨가 계속되겠습니다.&#39;</code></pre>
<p>만약 따옴표로 위와 같이 표시하려면 <code>\n</code>을 사용해야한다. 그리고 꼭 한 줄로 써야한다. 줄 바꿈을 했을 시에는 error가 나오게 된다.</p>
<h2 id="length--문자열-길이">length : 문자열 길이</h2>
<pre><code class="language-js">const desc = &#39;안녕하세요.&#39;;
desc.length; // 6</code></pre>
<p>보통 가입할 때 아이디나 비밀번호를 몇 자이상 몇 자 이하로 제한할 때 체크하고는 한다. </p>
<h2 id="숫자-특정-위치에-접근">[숫자]: 특정 위치에 접근</h2>
<pre><code class="language-js">const desc = &#39;안녕하세요.&#39;;
           //0 1 2 3 4 5
desc[2] // &#39;하&#39;</code></pre>
<p>배열과 동일하게 문자열도 대괄호와 숫자로 특정 위치에 접근이 가능하다. 0부터 시작해서 &#39;하&#39;가 2가 되는 것이다.</p>
<pre><code class="language-js">const desc = &#39;안녕하세요.&#39;;
desc[4] = &#39;용&#39;
console.log(desc) // 안녕하세요.</code></pre>
<p>하지만 배열과 다르게 한 글자만 바꾸는 것은 허용되어지지 않는다!</p>
<h2 id="touppercase--tolowercase--대문자--소문자">toUpperCase() / toLowerCase() : 대문자 / 소문자</h2>
<pre><code class="language-js">const desc = &quot;Hi guys. Nice to meet you.&quot;

desc.toUpperCase(); 
&quot;HI GUYS. NICE TO MEET YOU.&quot;

desc.toLowerCase();
&quot;hi guys. nice to meet you.&quot;</code></pre>
<p>영어인 경우 <code>toUpperCase()</code>와 <code>toLowerCase()</code>로 대소문자를 바꿀 수 있다. 
<code>toUpperCase()</code> -&gt; 모든 영문을 대문자로 바꾸어줌
<code>toLowerCase()</code> -&gt; 모든 영문을 소문자로 바꾸어줌</p>
<h2 id="strindexoftext--특정-문자-위치-구하기">str.indexOf(text) : 특정 문자 위치 구하기</h2>
<pre><code class="language-js">const desc = &quot;Hi guys. Nice to meet you.&quot;
desc.indexOf(&#39;to&#39;) // 14
desc.indexOf(&#39;man&#39;) // -1

// if(desc.indexOf(&#39;Hi&#39;)){
if(desc.indexOf(&#39;Hi&#39;) &gt; -1){
    console.log(&#39;Hi가 포함된 문장입니다.&#39;);
}</code></pre>
<p><code>str.indexOf(text)</code>는 문자를 인수로 받아 몇 번째 위치하는지 알려준다. 만약 찾는 문자가 없다면 -1을 반환한다. 만약 포함된 문자가 여러 개이더라도 첫번째 위치만 반환한다. 
if문을 쓸 때 주의해야한다. 예를 들어 <code>if(desc.indexOf(&#39;Hi&#39;))</code>라고 작성하면 안에 있는 console.log메세지를 볼 수 없게 된다. 왜냐하면 Hi로 시작하는 문장이라 indexOf를 구하면 0이되기 때문이다. if에서 0은 false이고, 따라서 저 console은 찍히지 않게 된다. 그래서 <code>desc.indexOf(&#39;Hi&#39;) &gt; -1</code> 조건문을 작성해 -1보다 큰 지 판별해주어야한다. </p>
<h2 id="strslicenm--특정-범위-문자열만-뽑아보기">str.slice(n,m) : 특정 범위 문자열만 뽑아보기</h2>
<pre><code class="language-js">const desc = &quot;abcdefg&quot;;
desc.slice(2); // &quot;cdefg&quot;
desc.slice(0,5); // &quot;abcde&quot;
desc.slice(2,-2); // &quot;cde&quot; (-2 : 끝에서 2번째 자리 0부터 시작)</code></pre>
<p><code>slice</code>는 n부터 m까지의 문자열만 반환한다. 
n은 시작점이고, 
m은 </p>
<ul>
<li>없으면 문자열 끝까지</li>
<li>양수면 그 숫자까지(포함하지 않음) (ex. 5를 적으면 4까지 반환)</li>
<li>음수면 끝부터 셈 </li>
</ul>
<h2 id="strsubstringnm--n과-m-문자열-사이-반환">str.substring(n,m) : n과 m 문자열 사이 반환</h2>
<pre><code class="language-js">const desc = &quot;abcdefg&quot;;
desc.substring(2,5); // &quot;cde&quot;
desc.substring(5,2); // &quot;cde&quot;</code></pre>
<p><code>slice()</code>와 유사하지만 <code>substring()</code>은 n과 m을 바꿔도 동일하다. 즉, n부터 m까지가 아니라 n과 m사이라고 생각하면 된다! 또한 음수를 허용하지 않는다. 음수는 0으로 인식한다.</p>
<h2 id="strsubstrnm--n부터-시작하고-m개의-갯수-가져오기">str.substr(n,m) : n부터 시작하고 m개의 갯수 가져오기</h2>
<pre><code class="language-js">const desc = &quot;abcdefg&quot;;
desc.substr(2, 4); // &quot;cdef&quot;
desc.substr(-4, 2); // &quot;de&quot;</code></pre>
<p><code>substring()</code>와 유사하게 생겼지만 동작방식은 완전히 다르다. n부터 시작하고 m개의 갯수를 가져온다. </p>
<h2 id="strtrim--문자-앞-뒤-공백-제거">str.trim() : 문자 앞 뒤 공백 제거</h2>
<pre><code class="language-js">const desc = &quot; coding       &quot;;
desc.trim(); // &quot;coding&quot;</code></pre>
<p><code>trim()</code>은 문자열 앞과 끝의 공간 공백을 제거한다. 보통 사용자로부터 어떠한 값을 입력받을 때 사용되어진다.</p>
<h2 id="strrepeatn--n번-반복">str.repeat(n) : n번 반복</h2>
<pre><code class="language-js">const hello = &quot;hello!&quot;;
hello.repeat(3); // &quot;hello!hello!hello!&quot;</code></pre>
<p><code>repeat()</code>은 문자열을 n번 반복한다.</p>
<h2 id="문자열-비교">문자열 비교</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/17006a1d-147f-4877-9a91-f8f08630436b/image.png" alt=""></p>
<p>문자열도 비교가 가능하다. 당연히 1보다 3이 크듯이 아스키 코드에 의해 &quot;a&quot;보다 &quot;c&quot;가 크다. 문자의 십진법을 알기위해서는 <code>문자.codePointAt(숫자)</code>을 사용해야하며, 숫자에서 문자를 알기 위해서는 <code>String.fromCodePoint(숫자)</code>를 통해 알 수 있다.</p>
<h2 id="실생활-예제">실생활 예제</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/018f9950-54b4-4b26-af8a-2306cadccb7a/image.png" alt=""></p>
<p>어떤 책의 목차로 list가 있다고 하자. 여기서 숫자를 제외하고 글자만 찍고 싶다면 <code>for문</code>과 <code>slice()</code>를 이용하면 된다!</p>
<hr>
<p>금칙어로 &quot;콜라&quot;를 사용할 수 없다고 하면<code>indexOf()</code>와 <code>includes()</code>를 이용하여 코드를 작성하면 된다.</p>
<h4 id="indexof">indexOf()</h4>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/9ea4d884-4a68-4c26-bd5d-6f3b7a5e1889/image.png" alt=""></p>
<h4 id="includes">includes()</h4>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/221695ef-31b8-4656-9398-305992caf313/image.png" alt=""></p>
<hr>
<p>출처)
!youtube[G360D6lqrfo]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[숫자, 수학 method (Number, Math)]]></title>
            <link>https://velog.io/@ye-ji/%EC%88%AB%EC%9E%90-%EC%88%98%ED%95%99-method-Number-Math</link>
            <guid>https://velog.io/@ye-ji/%EC%88%AB%EC%9E%90-%EC%88%98%ED%95%99-method-Number-Math</guid>
            <pubDate>Tue, 05 Apr 2022 10:11:18 GMT</pubDate>
            <description><![CDATA[<h1 id="tostring--10진수---2진수-or-16진수">toString() : 10진수 -&gt; 2진수 or 16진수</h1>
<pre><code class="language-js">// 10진수 -&gt; 2진수 / 16진수
const num = 10;
num.toString(); //&quot;10&quot;
num.toString(2); //&quot;1010&quot;

const num2 = 255;
num2.toString(16); // &quot;ff&quot;</code></pre>
<p>우리가 실생활에서 사용하고 있는 숫자는 10진수이다. 개발을 하다보면 2진수나 색상표현을 위해 16진수가 필요할 때가 있다. 
이 때 10진수를 2진수나 16진수로 바꾸는 방법에 대해 알아보자
num에 10이라는 값이 들어가있고, <code>변수명.toString()</code>을 실행해보면 이름에서 알 수 있듯이 이 메소드는 숫자를 문자로 바꾸어준다!
이 때 괄호안에 숫자를 쓰면 숫자의 진법으로 변환한다. <code>(2)</code>를 사용했더니 10이 1010으로 바뀐 것을 알 수 있다. 숫자 255를 16진수로 바꾸면 ff가 된다.</p>
<h1 id="math">Math</h1>
<pre><code class="language-js">Math.PI;
// 3.141592654589795</code></pre>
<p>자바스크립트에는 수학과 관련된 property와 메소드를 가지고 있는 Math라는 내장객체가 있다. 대표적인 프로퍼티의 예로 <code>Math.PI</code>를 입력해보면 원주율을 보여준다.</p>
<h2 id="mathceil--올림">Math.ceil() : 올림</h2>
<pre><code class="language-js">const num = 4.53;
Math.ceil(num); // 5</code></pre>
<p>올림은 <code>Math.ceil()</code>메소드를 사용한다. 소수점에 상관없이 해당 값을 정수형태로 올려준다.</p>
<h2 id="mathfloor--내림">Math.floor() : 내림</h2>
<pre><code class="language-js">const num = 4.53;
Math.floor(num); // 4</code></pre>
<p>내림은 <code>Math.floor()</code>를 사용한다. 해당 값의 정수 부분만 나오는 것을 알 수 있다.</p>
<h2 id="mathround--반올림">Math.round() : 반올림</h2>
<pre><code class="language-js">const num = 4.53;
Math.round(num); // 5
const num2 = 4.4;
Math.round(num2); // 4</code></pre>
<p>반올림은 <code>Math.round()</code>를 사용한다. 첫번째 소수점<code>.5</code>이 5이상이면 해당 값을 올려주고, 4이하이면 해당 값을 반환해준다.</p>
<h2 id="소수점-자리-수">소수점 자리 수</h2>
<pre><code class="language-js">const userRate = 30.1234;
// 요구사항: 소수점 둘째자리까지 표현(셋째 자리에서 반올림)</code></pre>
<p>하지만 작업을 하다보면 소수점까지 표현해야될 때가 많다. 예를 들어 셋째 자리에서 반올림해서 둘째자리까지 표현해야한다고 하면 어떻게 해야할까?</p>
<h3 id="1-mathrounduserrate--100--100">1) Math.round(userRate * 100) / 100</h3>
<ul>
<li><code>userRate * 100</code><pre><code class="language-js">userRate * 100 // 3012.34</code></pre>
우선 해당 값에 100을 곱해준다.</li>
<li><code>Math.round(userRate * 100) / 100</code><pre><code class="language-js">Math.round(userRate * 100) / 100 // 30.12</code></pre>
그 후에 반올림을 해준 뒤 다시 100을 나누면 된다. </li>
</ul>
<h3 id="2-tofixed">2) toFixed()</h3>
<pre><code class="language-js">userRate.toFixed(2)
// &quot;30.12&quot;</code></pre>
<p>숫자를 인수로 받아 그 숫자만큼 소수점 이하의 갯수에 반환한다.</p>
<pre><code class="language-js">const userRate = 30.1234; 
userRate.toFixed(0) // &quot;30&quot;
userRate.toFixed(6) // &quot;30.123400&quot;</code></pre>
<p>만약 받는 인수가 0이거나 기존 소수의 개수보다 크면 어떻게 될까?
0은 정수의 부분만 남게된다.
소수의 개수보다 큰 부분은 0으로 채워진다.</p>
<blockquote>
<p><code>통계자료나 지표자료를 할 때 많이 사용된다!! 유용한 꿀팁 🍯</code>
하지만 단 한가지의 주의점이 있다!
바로 toFixed()는 문자열을 반환한다는 점이다!
그래서 반환받은 이후 <code>Number</code>를 이용해 숫자로 변경시켜주어야한다!</p>
</blockquote>
<pre><code class="language-js">userRate.toFixed(2); // &quot;30.12&quot;
Number(userRate.toFixed(2)); // 30.12</code></pre>
<h2 id="isnan--숫자가-아님-판별">isNaN() : 숫자가 아님 판별</h2>
<pre><code class="language-js">const x = Number(&#39;x&#39;) // NaN

x == NaN // false
x === NaN // false
NaN == NaN // false

isNaN(x) // true
isNaN(3) // false</code></pre>
<p><code>isNaN()</code>은 NaN(Not a Number)인지 아닌지 판단해준다. 즉, 숫자가 아님을 판별해준다. 여기서 x는 NaN이다. x가 NaN인지 아닌지 판별하는 방법은 <code>isNaN()</code>이 유일하다. 
NaN은 신기하게도 자기 자신과도 똑같지 않다고 판단한다. </p>
<h2 id="parseint--문자---숫자-변환">parseInt() : 문자 -&gt; 숫자 변환</h2>
<pre><code class="language-js">const margin = &#39;10px&#39;;
parseInt(margin); // 10
Number(margin); // NaN

const redColor = &#39;f3&#39;;
parseInt(redColor); // NaN</code></pre>
<p><code>parseInt()</code>는 문자를 숫자로 바꾸어준다. <code>Number()</code>와 다른 점은 문자가 혼용되어 있어도 동작을 한다는 것이다! <code>Number()</code>는 NaN을 반환하지만 <code>parseInt()</code>는 읽을 수 있는 부분까지는 읽고, 문자를 만나면 숫자를 반환한다. 그래서 숫자로 시작하지 않으면 <code>parseInt()</code>는  NaN을 반환한다. </p>
<pre><code class="language-js">const redColor = &#39;f3&#39;;
parseInt(redColor); // NaN

const redColor = &#39;f3&#39;;
parseInt(redColor, 16); // 243

parseInt(&#39;11&#39;, 2); // 3</code></pre>
<p>그런데 <code>parseInt()</code>는 두번째 인수를 받아서 인수를 지정할 수 있다.
f로 시작했지만 두번째 인수에 16을 전달해서 16진수로 바꾸어주었다.
이렇게 문자열 11을 숫자로 바꾸고, 2진수에서 10진수로 손쉽게 바꾸어줄 수 있다.</p>
<h2 id="parsefloat--문자---부동-소수점">parseFloat() : 문자 -&gt; 부동 소수점</h2>
<pre><code class="language-js">const padding = &#39;18.5%&#39;; 
parseInt(padding) // 18
parseFloat(padding) // 18.5</code></pre>
<p><code>parseFloat()</code>는 <code>parseInt()</code>와 동일하게 동작하지만 부동 소수점을 반환한다. <code>parseInt()</code>는 소수점 이하는 무시하고 정수만 반환한다.</p>
<h2 id="mathrandom--0--1사이-무작위-숫자-생성">Math.random() : 0 ~ 1사이 무작위 숫자 생성</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/8c8bb99c-5a75-4e61-90b4-59e7f992eaf6/image.png" alt=""></p>
<p><code>Math.random()</code>은 랜덤 숫자를 생성한다.
<img src="https://velog.velcdn.com/cloudflare/ye-ji/f5a18285-56ed-4f87-bd34-376386a00dd2/image.png" alt=""></p>
<p>그래서 만약 1에서 100까지 임의의 수를 뽑고 싶다면 <code>Math.floor(Math.random()*100) + 1</code> 이렇게 식을 만들어서 사용해야한다. </p>
<ul>
<li><code>Math.random()</code>으로 숫자를 생성했을 때 나오는 수가 <code>0.6789</code>라고 가정해보자. </li>
<li>거기에 100을 곱하면 우리가 뽑고 싶어하는 총 갯수가 100개 된다. 만약 이 식에서 100을 5로 바꾸면 <code>Math.random()*5</code> 0부터 4까지 즉, 5개 중 하나가 된다는 것이다. </li>
<li><code>Math.floor()</code>를 이용해서 소수점 이하를 버린다.</li>
<li>마지막으로 1을 더해주는 데 이것을 해주는 이유가 랜덤 숫자가 0.XXXX가 나올 수 있다. 버림을 했을 때 0이 나올 수 있기 때문이다. 즉, 우리가 구해주는 건 0<del>99가 아닌 1</del>100이기 때문에 최솟값 1을 더해주어야한다.</li>
</ul>
<h2 id="mathmax--최댓값">Math.max() : 최댓값</h2>
<pre><code class="language-js">Math.max(1, 4, -1, 5, 10, 9, 5, 5.54); // 10</code></pre>
<p><code>Math.max()</code>은 최댓값을 구해준다. 괄호 안에 인수들 중 최댓값인 10을 구할 수 있다.</p>
<h2 id="mathmin--최솟값">Math.min() : 최솟값</h2>
<pre><code class="language-js">Math.min(1, 4, -1, 5, 10, 9, 5, 5.54); // -1</code></pre>
<p><code>Math.min()</code>은 최솟값을 구해준다. 괄호 안에 인수들 중 가장 작은 수 -1을 구할 수 있다.</p>
<h2 id="mathabs--절댓값">Math.abs() : 절댓값</h2>
<pre><code class="language-js">Math.abs(-1); // 1</code></pre>
<p><code>Math.abs()</code>는 절댓값을 구해준다. abs는 absolute의 약자이다. -1을 넣으면 1이 나온다.</p>
<h2 id="mathpown-m-제곱">Math.pow(n, m): 제곱</h2>
<pre><code class="language-js">Math.pow(2, 10) // 1024</code></pre>
<p><code>Math.pow(n, m)</code>는 n의 m승 값을 구해준다. 즉 거듭제곱 값을 구해준다.</p>
<h2 id="mathsqrt--제곱근">Math.sqrt() : 제곱근</h2>
<pre><code class="language-js">Math.sqrt(16) // 4</code></pre>
<p><code>Math.sqrt()</code>는 제곱근을 구해준다.</p>
<hr>
<p>출처)
!youtube[ZI6TT93wggA]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[다른 개발자가 만들어 놓은 객체 활용하는 법: Symbol 이용하기]]></title>
            <link>https://velog.io/@ye-ji/%EB%8B%A4%EB%A5%B8-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EB%A7%8C%EB%93%A4%EC%96%B4-%EB%86%93%EC%9D%80-%EA%B0%9D%EC%B2%B4-%ED%99%9C%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B2%95-Symbol-%EC%9D%B4%EC%9A%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@ye-ji/%EB%8B%A4%EB%A5%B8-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EB%A7%8C%EB%93%A4%EC%96%B4-%EB%86%93%EC%9D%80-%EA%B0%9D%EC%B2%B4-%ED%99%9C%EC%9A%A9%ED%95%98%EB%8A%94-%EB%B2%95-Symbol-%EC%9D%B4%EC%9A%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 05 Apr 2022 08:47:29 GMT</pubDate>
            <description><![CDATA[<p>객체의 Property 키는 문자형으로 이루어져있다!</p>
<h1 id="property-key--문자형">Property Key : 문자형</h1>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/221a1471-e12e-4238-9396-9fcaeada9071/image.png" alt="">
숫자형이나 boolean형으로 만들어도 <code>Object.keys(obj)</code>를 통해서 <code>[&quot;1&quot;, &quot;false&quot;]</code>문자형으로 반환되는 것을 알 수 있다. 
실제로 접근할 때에도 문자 <code>&#39;1&#39;</code>이나 <code>&#39;false&#39;</code>로 접근할 수 있다.
이렇게 객체의 프로퍼티 키는 문자형으로 가능하지만 또 다른 하나는 심볼형이 있다!</p>
<h1 id="property-key--심볼형">Property Key : 심볼형</h1>
<h2 id="symbol">Symbol</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/5da56d98-e07d-4829-9246-405d977c65c6/image.png" alt=""></p>
<p>심볼은 <code>const a = Symbol()</code>로 만들어진다. 이 때 <code>new</code>는 붙이지 않는다. 심볼은 유일한 식별자를 만들 때 사용한다. 예를 들어 a와 b를 symbol로 만들어서 console.log로 찍어보면 생긴건 <code>Symbol()</code>의 형태로 동일하다. 하지만 일치 연산자로 확인해보면 <code>a === b</code>가 false로 나오게 된다!! 자료형은 달라도 내용만 일치하는 동등연산자(<code>a == b</code>)도 false가 나오게 된다. </p>
<h3 id="symbol--유일성-보장">Symbol : 유일성 보장</h3>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/963a76ff-f921-4007-8351-e2334f23366c/image.png" alt="">
심볼은 유일성이 보장된다. 즉, 전체 코드 중에 하나라는 의미이다. 심볼을 만들 때 <code>&#39;id&#39;</code>라는 설명을 붙여줄 수 있다. 설명을 붙여주면 디버깅할 때 편리하다. 문자열을 전달해주면 되는데 <strong>이 문자열은 심볼 생성에 어떠한 영향을 미치지 않는다!</strong> 
만약 설명이 똑같은 걸 또 만들게 되면 어떻게 될까?
생긴 건은 똑같지만 다르다는 것을 알 수 있다.</p>
<p>이제 심볼을 객체의 키로 사용해보자!</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/24c1d9d9-a0a1-4010-82dc-b648e9b7cf41/image.png" alt="">
id로 심볼을 만든 후에 객체를 사용해본다. 이 때 computed Property 키로 넣어준 후 해당 값을 출력해보면 심볼로 만든 키를 가진 프로퍼티가 존재하는 것을 확인할 수 있다. <code>user[id]</code>도 <code>&#39;myid&#39;</code>로 해당 값이 출력되는 것도 알 수 있다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/795101e1-063b-46bc-91d5-23206edb9c86/image.png" alt="">
그런데 여기서 <code>Object.keys(user)</code>을 하게 되면 <code>[&quot;name&quot;, &quot;age&quot;]</code> name이랑 age만 나오게 된다. 즉, Object의 메소드들은 심볼형인 형태는 건너뛰게 된다. 마찬가지로 for in을 사용해도 건너뛰게 된다.</p>
<p><code>그러면 이 심볼형은 도대체 언제 쓰일 수 있을까?</code></p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/11308103-4f46-4762-bebd-8007651c4171/image.png" alt="">
<strong>특정 객체의 원본 데이터는 건드리지 않고, 속성을 추가하고 싶을 때 사용하면 된다!</strong> 다른 사람이 만들어놓은 객체에 자신만의 속성을 추가해서 덮어씌우면 안된다. 그렇다고 해서 엄청 길고 이상한 네이밍을 쓰는 것도 좋지 않다. 원본 객체가 어디에선가 <code>Object.keys</code>나 <code>for in</code>으로 사용될 수 있기 때문이다.</p>
<h2 id="symbolfor--전역-심볼">Symbol.for() : 전역 심볼</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/c5353317-e9d3-4269-89b1-8ae6bd44beab/image.png" alt=""></p>
<p>심볼은 이름이 같더라도 다 다른 존재이다. 그런데 가끔 전역변수처럼 이름이 같으면 같은 객체를 가르켜야 할 때가 있다. 이럴 때 사용할 수 있는 것이 <code>Symbol.for()</code>이다!</p>
<ul>
<li><code>Symbol.for()</code>을 사용하면 하나의 심볼만 보장받을 수 있다.</li>
<li>없으면 만들고 있으면 가져오기 때문이다.</li>
<li><code>Symbol</code>함수는 매번 다른 Symbol 값을 생성하는 데에 비해 </li>
<li><code>Symbol.for()</code>메소드는 하나의 심볼을 생성해서 키를 통해 같은 Symbol을 공유할 수 있다.</li>
</ul>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/8f3a1cf4-6d92-446d-a688-e18d791c1ec7/image.png" alt="">
예를 들어, id1과 id2를 만들고 비교해보면 동일하다고 알려준다. <code>for</code>없이 생성한 것과 다르다. 이것을 전역심볼이라고 부르고, 코드 어디에서든 사용이 가능하다!!!
이름을 얻고 싶다면 <code>Symbol.keyFor()</code>를 사용하면 된다. <code>keyFor</code>를 이용해서 id1변수를 넣어주면 생성할 때 적어주었던 이름(id)을 알려준다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/21ff6c7d-960d-4b59-a892-8b0ba3c67779/image.png" alt=""></p>
<p>전역 심볼이 아닌 심볼은 <code>keyFor</code>을 사용할 수 없다. 대신 <code>description</code>으로 알 수 있다.</p>
<p>그렇다면 이 심볼은 어떻게 볼 수 있을까?</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/105c1691-d2bb-41c1-af53-46ec6c83d99b/image.png" alt="">
<code>Object.getOwnPropertySymbols()</code>를 사용하면 심볼들만 볼 수 있다.
또한 <code>Reflect.ownKeys()</code>는 심볼을 포함한 객체의 모든 키를 보여준다.</p>
<p>즉, 심볼을 완전히 숨길 수 있는 방법은 없다. 그런데 사실 대부분의 라이브러리 내장함수 등은 이러한 메소드들을 사용하지 않는다. 그렇기 때문에 유일한 프로퍼티를 추가하고 싶을 때 심볼을 사용하면 된다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/92a2f9e4-bc89-432b-ac9d-13eb0525001c/image.png" alt="">
*<em>위의 사진처럼 다른 개발자가 만들어 놓은 객체를 활용해서 나만의 프로퍼티를 만들 때 사용하면 된다. *</em>
이 때 user[showName]의 출력 값을 보고 싶다면 아래 해당 줄에 <code>user[ShowName]()</code>을 작성해주면 <code>Mike</code>가 출력되는 것을 볼 수 있다!</p>
<hr>
<p>출처)
!youtube[E9uCNn6BaGQ]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[계산된 프로퍼티(Computed property), 객체 메소드(Object methods)]]></title>
            <link>https://velog.io/@ye-ji/%EA%B3%84%EC%82%B0%EB%90%9C-%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0Computed-property-%EA%B0%9D%EC%B2%B4-%EB%A9%94%EC%86%8C%EB%93%9CObject-methods</link>
            <guid>https://velog.io/@ye-ji/%EA%B3%84%EC%82%B0%EB%90%9C-%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0Computed-property-%EA%B0%9D%EC%B2%B4-%EB%A9%94%EC%86%8C%EB%93%9CObject-methods</guid>
            <pubDate>Tue, 05 Apr 2022 07:44:46 GMT</pubDate>
            <description><![CDATA[<h1 id="computed-property">Computed property</h1>
<pre><code class="language-js">let a = &#39;age&#39;;
const user = {
    name: &#39;Mike&#39;,
    age: 30
}</code></pre>
<p>a라는 변수가 있고, user라는 객체가 있다. 
여기서 객체의 age라는 키 대신에 <code>[a]</code>로 사용해도 동일하다.</p>
<pre><code class="language-js">let a = &#39;age&#39;;
const user = {
    name: &#39;Mike&#39;,
    [a]: 30 // age: 30
}</code></pre>
<p>이렇게 <code>[]</code> 대괄호로 묶어주면 a라는 문자열이 아니라 변수 a에 할당된 값이 들어가게 된다. 이를 Computed property(계산된 프로퍼티)라고 부른다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/234b7ff4-74f5-44ea-8bac-b716e2c40612/image.png" alt="">
이렇게 식 자체를 넣는 것도 가능하다!!</p>
<h1 id="객체-메소드object-methods">객체 메소드(Object methods)</h1>
<h2 id="objectassign--객체-복제">Object.assign() : 객체 복제</h2>
<pre><code class="language-js">const user = {
    name: &#39;Mike&#39;,
    age: 30
}
const cloneUser = user;</code></pre>
<p>이렇게 user의 객체가 있을 때 cloneUser를 만들어서 user를 만들어주면 과연 복제가 될까? 
정답은 안된다!!!
user변수에는 객체 자체가 들어가 있는 게 아니라 <strong>객체에 저장되어 있는 메모리 주소인 객체의 참조값이 저장</strong>되어있다. 그러니깐 cloneUser를 만들어서 user를 만들면 객체가 복사되어서 들어가는 게 아니라 <strong>참조값만 복사</strong>되서 들어간다. 
<img src="https://velog.velcdn.com/cloudflare/ye-ji/1ea4eade-729a-472d-9b24-3ef57c341888/image.png" alt=""></p>
<p>즉, 위의 사진과 같이 모양을 띄게 된다. <code>cloneUser</code>의 이름을 바꾸었는데 <code>user</code>의 이름도 바뀌게 되는 것이다. 하나의 객체를 두 변수가 접근하고 있는 것이다! 
그렇다면 복제는 어떻게 하는 것일까? 아래와 같은 문법으로 사용하면 된다!</p>
<pre><code class="language-js">const newUser = Object.assign({}, user);</code></pre>
<p>여기서 <code>{}</code> 빈 객체는 초기값이다. 두번째 매개변수부터 들어온 객체들이 초기값에 병합된다. 
<img src="https://velog.velcdn.com/cloudflare/ye-ji/ce04d899-b7c4-4a18-9700-8519ac85a9be/image.png" alt="">
이렇게 하면 빈 객체에 user가 병합되므로 합체가 되어진다. 
<img src="https://velog.velcdn.com/cloudflare/ye-ji/f89ea6ca-8de1-4bd3-8634-490fe1817f5f/image.png" alt="">
이제 이름을 바꾸어도 user의 값이 바뀌지 않는다는 것을 확인할 수 있다!</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/de710348-2cd0-41c4-ac2f-aab9ee74b821/image.png" alt="">
초기값을 <code>{gender: &#39;male&#39;}</code>로 하면 총 3개의 프로퍼티가 생기게 된다. </p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/7939b29a-bc23-4e2e-b8b0-24f1d38933e8/image.png" alt="">
<strong>만약 병합을 하는데 키가 같다면 어떻게 되어질까?</strong>
덮어씌워지게 된다!!!</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/e4ef06c6-4a09-47f9-9c8e-01b0f76bd67a/image.png" alt="">
두 개 이상의 객체도 합칠 수 있다. <code>user</code>에는 이름만 있고, <code>info1</code>에는 나이, <code>info2</code>에는 성별만 있다고 할 때, 사진의 화살표 모양대로 합쳐진다!</p>
<hr>
<h2 id="objectkeys--키-배열-반환">Object.keys() : 키 배열 반환</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/53e2914e-5c82-4258-973a-6885b9afe331/image.png" alt="">
<code>Object.keys()</code> 메소드는 객체 프로퍼티의 키를 배열로 반환한다. user의 객체를 <code>Object.keys(user)</code>의 인수로 전달하게 되면 <code>[&quot;name&quot;, &quot;age&quot;, &quot;gender&quot;]</code>로 키들이 배열로 반환되어진다.</p>
<hr>
<h2 id="objectvalues--값-배열-반환">Object.values() : 값 배열 반환</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/bf8a6c96-19b1-4377-a7c2-5222d54491ac/image.png" alt="">
반대로 값들만 얻어오고 싶다면 <code>Object.values()</code> 메소드를 쓰면 된다!
객체의 value의 해당되는 부분이 <code>[&quot;Mike&quot;, 30, &quot;male&quot;]</code>배열로 반환되어진다.</p>
<h2 id="objectentries--키-값-배열-반환">Object.entries() : 키/ 값 배열 반환</h2>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/52f2930f-3194-4c1c-9bf5-0dda4e0df1a5/image.png" alt="">
키와 값을 배열로 반환하고 싶다면 <code>Object.entries()</code>메소드를 사용하면 된다. 이 메소드는 키와 값을 묶어서 배열로 반환해준다. 배열 안에 각 키와 값이 들어가 배열 3개가 들어가게 된다.</p>
<hr>
<h2 id="objectfromentries--키--값-배열-객체로">Object.fromEntries() : 키 / 값 배열 객체로</h2>
<p><code>Object.entries()</code>의 반대 기능인 <code>Object.fromEntries()</code>는 키와 값을 쌍으로 묶은 배열들을 객체로 반환해준다.
<img src="https://velog.velcdn.com/cloudflare/ye-ji/349bfdb9-d1fd-43a5-8376-5a65f3401673/image.png" alt=""></p>
<hr>
<h2 id="활용-예제">활용 예제</h2>
<pre><code class="language-js">function makeObj(key, val){
    return {
        [key]: val,
    }
}
const age = makeObj(&#39;나이&#39;, 20);
console.log(age) 
// {&#39;나이&#39;: 20}
const gender = makeObj(&#39;성별&#39;, &#39;female&#39;);
console.log(gender);
// {&#39;성별&#39;: &#39;female&#39;}</code></pre>
<p>어떠한 키가 될지 모를 때 사용되는 코드이다.</p>
<hr>
<p>출처)
!youtube[6NZpyA64ZUU]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[GitHub] We found potential security vulnerabilities in your Dependencies ]]></title>
            <link>https://velog.io/@ye-ji/GitHub-We-found-potential-security-vulnerabilities-in-your-Dependencies</link>
            <guid>https://velog.io/@ye-ji/GitHub-We-found-potential-security-vulnerabilities-in-your-Dependencies</guid>
            <pubDate>Mon, 04 Apr 2022 16:48:07 GMT</pubDate>
            <description><![CDATA[<p><img src="https://media.vlpt.us/images/ye-ji/post/1d8e5c90-408e-4f80-bcc2-0072b985a933/image.png" alt=""></p>
<p>팀 프로젝트를 하면서 내가 개발 환경을 구축하니 이러한 알림이 뜨는 것 이다! 열심히 찾아본 뒤에 해결 한 후 결과를 공유하고자 한다!
이 글을 번역해보면 다음과 같다.
<code>종속성에서 잠재적인 보안 취약성이 발견되었습니다.</code>
즉, package-lock.json에서 오류가 발생하는 것이다!</p>
<h1 id="해결-방법">해결 방법</h1>
<h2 id="1-dependency-bot-이용하기">1) dependency bot 이용하기</h2>
<p><img src="https://media.vlpt.us/images/ye-ji/post/e4fbd41c-30f8-43d0-97a8-b1fbf28a9d45/image.png" alt="">
이렇게 풀리퀘로 올라온 것을 확인할 수 있다. Merge를 하면 해당 보안 취약성을 해결할 수 있지만 부분적으로 몇 개만 적용이 된다...</p>
<h2 id="2-npm-audit-fix">2) npm audit fix</h2>
<p>처음에는 <code>npm audit fix</code>와 <code>npm audit fix --force</code>를 사용하여 몇 가지의 취약성이 사라졌지만, 결과는 동일했었다.</p>
<pre><code>npm audit fix
npm audit fix --force</code></pre><p>나의 문제는 로컬에 깔려있는 npm 패키지 문제였다. 즉, 내 컴퓨터에 깔려있는 npm 버전이 업데이트가 되지 않았기 때문이었다!</p>
<p>그래서 바로 npm과 node를 업데이트 시켜준 후 vs-code에서 <code>package-lock.json</code>과 <code>node_module</code>파일을 삭제 한 후 <code>npm i</code>를 해준뒤 레파지토리에 커밋 푸시를 해주었다! 결과는 대 성공이었다! </p>
<h3 id="npm과-node-업데이트">npm과 node 업데이트</h3>
<p>os가 windows일 경우 
<a href="https://nodejs.org/ko/download/">설치용 msi</a> 다운 받아서 그냥 설치하면 된다.</p>
<ul>
<li><p>Node.js 업데이트 하기</p>
<pre><code>1) node -v 
2) npm cache clean -f
3) npm install -g n
4) n lts</code></pre><p><em>1) Node.js 현재 버전 확인
2) npm 캐쉬 삭제 (오류발생 할 수 있음)
3) n 플러그인 설치 : 노드 버전관리 플러그인 
4) Node.js 버전 설치 (n 상세 사용법 링크 참조)
 n latest : 최신버전
 n lts : lts 버전
 n stable : 안정버전</em></p>
</li>
<li><p>npm 업데이트 하기</p>
<pre><code>1) node -v
2) npm cache clean -f
3) npm install -g n
4) n lts</code></pre><p><em>1) npm 현재 버전 확인
2) npm 업데이트 
 -g 옵션 없을 시 현재 프로젝트만 적용됨.</em></p>
</li>
</ul>
<h2 id="추후에-적용해-볼-내용🍯"><a href="https://blog.outsider.ne.kr/1323">추후에 적용해 볼 내용🍯</a></h2>
<p>npm 의존성을 실시간으로 감시하고 자동으로 업데이트할 수 있게 도와주는 라이브러리가 있다고 한다!</p>
<h3 id="1-snyk"><a href="https://snyk.io/">1. snyk</a></h3>
<p><del>원래는 greenkeeper가 있다했는데... 서비스가 중단되었다고 한다..👋</del>
<a href="https://www.wenyanet.com/opensource/ko/604c0b71f3ef3d464566569f.html">Snyk GitHub 작업</a></p>
<h3 id="2-dependency-ci"><a href="https://tidelift.com/">2. Dependency CI</a></h3>
<p><del>Greenkeeper</del>가 의존성을 최신으로 업데이트하는 데 집중한다면 Dependency CI는 의존성 모듈을 검사하는 역할을 한다. 
<img src="https://media.vlpt.us/images/ye-ji/post/3abce857-284b-43a3-9e45-b8ce40bb7662/image.png" alt="">
GitHub으로 로그인한 뒤 원하는 저장소를 활성화하면 연결이 된다
<img src="https://media.vlpt.us/images/ye-ji/post/f24def2e-c32e-498a-972d-c9778bd9d373/image.png" alt="">
CI라는 이름답게 이후에는 커밋이나 Pull Request가 올라올 때마다 해당 코드를 기준으로 검사하고 결과를 알려준다.
<img src="https://media.vlpt.us/images/ye-ji/post/c90a92e8-1af4-43cd-b813-3073b77b08d7/image.png" alt=""></p>
<p>출처: <a href="https://walldaydream.tistory.com/entry/Nodejs-npm-%EC%97%85%EB%8D%B0%EC%9D%B4%ED%8A%B8-%ED%95%98%EA%B8%B0">https://walldaydream.tistory.com/entry/Nodejs-npm-업데이트-하기</a>
<a href="https://blog.outsider.ne.kr/1323">https://blog.outsider.ne.kr/1323</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[비슷한 객체 여러 개 만들기 : 생성자 함수와 class]]></title>
            <link>https://velog.io/@ye-ji/%EB%B9%84%EC%8A%B7%ED%95%9C-%EA%B0%9D%EC%B2%B4-%EC%97%AC%EB%9F%AC-%EA%B0%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%95%A8%EC%88%98%EC%99%80-class</link>
            <guid>https://velog.io/@ye-ji/%EB%B9%84%EC%8A%B7%ED%95%9C-%EA%B0%9D%EC%B2%B4-%EC%97%AC%EB%9F%AC-%EA%B0%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0-%EC%83%9D%EC%84%B1%EC%9E%90-%ED%95%A8%EC%88%98%EC%99%80-class</guid>
            <pubDate>Mon, 04 Apr 2022 15:41:19 GMT</pubDate>
            <description><![CDATA[<p>우리는 웹사이트를 만들 때 회원의 정보, 상품의 정보등 객체를 사용하여 값이 변경되는 경우를 만들어야 할 때가 있다! 이러한 경우 생성자 함수나 class를 이용하면 좋다! es6에 class가 추가되었으므로 이를 사용하면 좋다고 한당!</p>
<h2 id="객체-리터럴">객체 리터럴</h2>
<pre><code class="language-js">let user = {
    name: &#39;Mike&#39;,
    age: 30,
}</code></pre>
<h2 id="생성자-함수">생성자 함수</h2>
<p>생성자 함수는 보통 첫 글자는 대문자로 해서 만들어준다. 이름과 나이를 인자로 받아서 this로 넣어주고 있다. 그리고 new 연산자를 사용해서 함수를 호출하고 있다.</p>
<pre><code class="language-js">function User(name, age){
// User -&gt; 대문자
  this.name = name;
  this.age = age;
}

let user1 = new User(&#39;Mike&#39;, 30);
let user2 = new User(&#39;Jane&#39;, 20);
let user3 = new User(&#39;Tom&#39;, 17);
// new 연산자를 사용해서 호출</code></pre>
<p><img src="https://media.vlpt.us/images/ye-ji/post/9bfbe2ad-9d43-4ed0-a1d7-e5dc111306f1/image.png" alt="">
이렇게 값은 다르지만 비슷한 여러 개의 객체를 만들 수 있다!
생성자 함수는 붕어빵 틀이나 와플 팬이라고 생각하면 된다. 원하는 재료들을 넣어주고, 찍어내면 되는 것이다! 지금 필요한 재료는 이름과 나이였다.</p>
<p>이제 생성자 함수가 어떻게 동작하는지 자세히 알아보자!</p>
<p><code>new 함수명</code>을 실행하면 
빈 객체<code>{}</code>를 만들고
this를 할당한다. <code>this = {}</code> 함수를 실행하면서 <code>function User(name, age){}</code> this의 프로퍼티들을 추가한다. <code>this.name = name;</code>과 <code>this.age = age;</code> 그 후에 마지막으로 this를 반환한다. (<code>return this</code>)</p>
<pre><code class="language-js">function User(name, age){
  // this = {}
  this.name = name;
  this.age = age;
  // return this
}</code></pre>
<p>이제는 메소드를 추가해보자! 모든 User에는 sayName이 있어서 자신의 이름을 말하는 메소드가 있다고 가정해보자 </p>
<pre><code class="language-js">function User(name, age){
  this.name = name;
  this.age = age;
  this.sayName = function(){
    // console.log의 this는 user5를 뜻함
      console.log(this.name);
  }
}
let user5 = new User(&#39;Han&#39;, 40);
user5.sayName(); // Han</code></pre>
<p>여기서 console.log의 this는 user5를 뜻하기 때문에 user5.sayName은 Han을 뜻한다.</p>
<p><img src="https://media.vlpt.us/images/ye-ji/post/5292d0ac-db6b-404e-b242-677e69e4e2b1/image.png" alt="">
코드를 직접 실행해보면 위의 사진과 같다. 이 때 new 생성자 함수를 이용하면 Item함수의 주석 부분이 실행되어지는 것을 알 수 있다. 꼭 new를 붙여야지만 주석 부분이 실행되어지는 것이다!</p>
<p>만약 여기서 new를 안 붙이게 되면 해당 값이 <code>undefined</code>가 뜨게 된다.
<img src="https://media.vlpt.us/images/ye-ji/post/48fe30fd-af90-4e1c-b722-5cde16c787e3/image.png" alt="">
new를 안 붙이면 함수가 실행되어지는 것이다. 사실 이 함수는 아무것도 return 해주고 있지 않기 때문에 undefined로 들어가게 되서 출력이 되는 것이다. 
<strong>즉, 생성자 함수는 잊지말고 new를 붙여주어야 한다!!!!!</strong></p>
<h2 id="상속-프로토타입prototype">상속, 프로토타입(Prototype)</h2>
<pre><code class="language-js">const user = {
    name: &#39;Mike&#39;
}
console.log(user.name); // &quot;Mike&quot;
user.hasOwnProperty(&#39;name&#39;); // true
user.hasOwnProperty(&#39;age&#39;); // false</code></pre>
<p>객체에는 자신이 프로퍼티를 가지고 있는지 확인하는 메소드인 <code>user.hasOwnProperty</code>를 사용할 수 있다. 
<img src="https://velog.velcdn.com/cloudflare/ye-ji/ab5111fb-186e-42b9-b61d-7473133ae5ae/image.png" alt="">
객체의 프로토타입은 사진과 같이 알 수 있다. 객체에서 프로토를 읽으려고 할 때 없으면 여기에서 찾게 된다. 만약 <code>hasOwnProperty</code>이 객체 안에 있다면 다음과 같이 실행되어진다.</p>
<pre><code class="language-js">const user = {
    name: &#39;Mike&#39;,
    hasOwnProperty: function(){
        console.log(&#39;haha&#39;)
    }
}
user.hasOwnProperty()
// haha</code></pre>
<p>프로토타입이 어떻게 동작하는지 알기 위해서 상속이라는 개념을 살펴보자!</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/e871c20d-200b-413a-b8e2-3b28861c39a0/image.png" alt=""></p>
<p>color, wheels, drive는 동일하게 사용된다. 객체들이 늘어나면 공통된 부분이 중복해서 사용되므로 <code>_proto_</code>로 사용할 수 있다. bmw의 wheels를 작성하면 객체의 내부에서 wheels를 찾게 된다. 찾게 되면 거기서 탐색을 멈추고 만약 없다면 <code>_proto_</code>에서 찾게 된다. </p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/22300332-cbc3-4ff9-826a-5644830c3570/image.png" alt="">
상속은 계속해서 이어질 수 있다. x5를 만들고, x5는 bmw를 상속하도록 만들었다
<img src="https://velog.velcdn.com/cloudflare/ye-ji/1f51fe59-a1a3-4eef-b8aa-a183156eb064/image.png" alt="">
그림으로 보면 x5에서 navigation이 없기 때문에 <code>_proto_</code>타입인 bmw에서 탐색을 하고, 있으니깐 멈추게 된다. drive()는 <code>_proto_</code>타입인 car까지 올라가서 사용할 수 있다. 이러한 것을 <strong>Prototype Chain</strong>이라고 한다.</p>
<pre><code class="language-js">for(p in x5){
    console.log(p);
   // color
  // name
  // navigation
  // wheels
  // drive
}
Object.keys(x5);
// [&quot;color&quot;, &quot;name&quot;]
Object.values(x5);
// [&quot;white&quot;, &quot;x5&quot;]</code></pre>
<p>for문을 통해 사용해보면 해당 값이 다 나온 다는 것을 알 수 있다. 사실 name과 color를 제외하고 프로토타입에서 정의한 프로토이다. 하지만 Object.keys나 Object.value를 하면 상속된 값들이 나오지는 않는다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/15895212-262b-411e-af53-f70d808dfe45/image.png" alt=""></p>
<p>생성자 함수를 이용하면 비슷한 객체들을 간단하게 만들 수 있다. 여기서 매개변수로 전달해준 color값 말고, wheels와 drive는 동일하기 때문에 분리할 수 있다. 여기서 <code>_proto_</code>와 <code>prototype</code>은 모습이 다르다. 생성자함수가 생성한 객체에 <code>_proto_</code>을 설정한 의미이다.</p>
<h2 id="class--es6에-추가된-스펙">class : es6에 추가된 스펙</h2>
<pre><code class="language-js">const User = function(name, age){
    this.name = name;
    this.age = age;
    this.showName = function(){
      console.log(this.name);
    }
}

const mike = new User(&quot;Mike&quot;, 30);

class User2{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
    showName(){
        console.log(this.name);
    }
}
const tom = new User2(&quot;Tom&quot;, 19);
// User2 {name: &quot;Tom&quot;, age: 19}</code></pre>
<p>어떤 게 다른지 살펴보면 new를 통해서 호출했을 때 내부에서 정의된 내용으로 객체를 생성하는 것은 동일하다. 일단 class라는 객체를 사용하고, 내부의 constructor가 있다. constructor는 객체를 만들어주는 생성자 메소드이다. new를 통해 호출하면 자동으로 실행되어진다. 객체를 초기화하기 위한 값이 저장이되고, 인수를 넘겨받을 수 있다. <code>showName()</code>처럼 class에 정의한 메소드는 User2의 프로토타입에 저장되어진다. 그래서 mike와 tom을 확인해보면 mike는 객체 내부의 showName이 있고, Tom은 protoType의 내부에 있다. 
그러면 생성자 함수에서 class와 동일하게 동작하기 위해서는 아래와 같이 작성하면 된다.</p>
<pre><code class="language-js">User.prototype.showName = function(){
    console.log(this.name);
}</code></pre>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/1d88db38-81fa-4d93-994d-0468765e6266/image.png" alt=""></p>
<p>그러면 단순히 문법의 편의성을 위해 class가 탄생한 것일까?
<code>new</code>를 빼고 실행해보면 class는 typeerror가 뜨고, 생성자 함수는 undefined가 뜬다. 이렇게 error로 인해 개발자가 코드를 잘못입력 했을 시에 알려준다.</p>
<h3 id="class-상속">class: 상속</h3>
<p>생성자의 함수 경우에는 prototype으로 상속을 구현해주었었다. class에서 상속은 <code>extends</code>키워드를 사용한다. 
<img src="https://velog.velcdn.com/cloudflare/ye-ji/b2a7ba12-8af3-430e-a601-d9369f66c4ee/image.png" alt=""></p>
<h3 id="class-메소드-오버라이딩">class: 메소드 오버라이딩</h3>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/2ae50c24-2dae-4359-934f-2adca467c8b5/image.png" alt=""></p>
<p>만약 Bmw내부에 Car에서 정의한 메소드와 동일한 이름의 메소드가 존재하면 어떨까? 동일한 이름으로 주어진다면 덮어씌워지게 된다. 부모의 메소드를 사용하면서 확장하고 싶다면 <code>super</code>라는 키워드를 사용하면 된다. </p>
<h3 id="class--오버라이딩">class : 오버라이딩</h3>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/f503f7e7-f29e-4559-a346-1899416a4849/image.png" alt=""></p>
<p>counstrutor 오버라이딩을 해보기 위해 해당 constructor를 생성해주고 this.navigation = 1로 만들어주면 error가 나게 된다. 에러 메시지를 보면 부모 생성자를 반드시 호출해야한다고 말한다. class의 constructor는 빈 객체를 만들어주고 this로 이 객체를 가르키게 된다. 반면 extends를 써서 만든 자식 class는 빈 객체를 만들어지고 this에 할당하는 이 작업을 건너뛴다. 그래서 항상 super();키워드로 부모클래스의 constructor를 실행해주어야 한다.
<img src="https://velog.velcdn.com/cloudflare/ye-ji/2e584b84-1b67-499d-adbc-ac5ad39ccd4f/image.png" alt=""></p>
<p>하지만 확인해보면 color의 값이 undefined가 뜨게 된다. 생성할 때 blue라는 값을 넣어주었지만 제대로 동작하기 위해서는 자식 클래스의 constructor에 동일한 인수를 받는 작업을 해주어야한다.</p>
<p><img src="https://velog.velcdn.com/cloudflare/ye-ji/10be7feb-18a7-4a92-bab3-aa96cd48e5ad/image.png" alt="">
만약 constructor가 없다면 아래의 코드와 같이 동작하게 된다.</p>
<pre><code class="language-js">constructor(...args){
    super(...args);
}</code></pre>
<p>자식생성자는 무조건 부모생성자를 호출해야하는 것이다. 자식 생성자의 constructor가 있으면 위의 처럼 호출되지 않기에 super()를 생성해주고,인수를 할당해주어야한다.  </p>
<hr>
<p>출처)
!youtube[8hrSkOihmBI]
!youtube[ddJcDZHBRm0]
!youtube[OpvtD7ELMQo]</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[호이스팅, TDZ, 변수의 생성과정, 스코프]]></title>
            <link>https://velog.io/@ye-ji/%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85-TDZ-%EB%B3%80%EC%88%98%EC%9D%98-%EC%83%9D%EC%84%B1%EA%B3%BC%EC%A0%95-%EC%8A%A4%EC%BD%94%ED%94%84</link>
            <guid>https://velog.io/@ye-ji/%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85-TDZ-%EB%B3%80%EC%88%98%EC%9D%98-%EC%83%9D%EC%84%B1%EA%B3%BC%EC%A0%95-%EC%8A%A4%EC%BD%94%ED%94%84</guid>
            <pubDate>Mon, 04 Apr 2022 12:22:51 GMT</pubDate>
            <description><![CDATA[<h1 id="호이스팅">호이스팅</h1>
<blockquote>
<p><strong>호이스팅</strong>
: 스코프 내부 어디서든 변수 선언은 최상위에 선언된 것처럼 행동</p>
</blockquote>
<h2 id="var">var</h2>
<p>중복 선언이 가능
즉, 한번 선언된 변수는 다시 선언할 수 있다.</p>
<pre><code class="language-js">var name = &#39;mike&#39;;
console.log(name);
// mike

var name = &#39;Jane&#39;;
console.log(name);
// Jane</code></pre>
<p>또한 선언되기 전에 사용될 수 있다.</p>
<pre><code class="language-js">var name;
console.log(name); // undefined
name = &#39;mike&#39;;</code></pre>
<p>선언은 호이스팅 되어지지만 할당은 호이스팅 되어지지 않는다.
즉, name이라는 변수만 올려지고 mike라는 값은 할당되어지지 않는다.
<img src="https://media.vlpt.us/images/ye-ji/post/658708a2-25a5-4858-9d57-5ab43db4e9d6/image.png" alt="">
할당을 하기 전에는 사용할 수 없음! 이는 코드를 예측 가능하게 하고, 잠재적인 버그를 줄일 수 있다!</p>
<p>but)  코드량이 많아졌을 때, 같은 이름의 변수명이 여러 번 선언되었다면 어디 부분에서 문제가 발생하는지 파악하기 힘들뿐더러 값이 바뀔 우려가 있다.
이를 보완하기 위해 ES6부터 추가된 변수 선언 방식이<code>let</code>, <code>const</code>이다.</p>
<h2 id="let">let</h2>
<p>재 할당이 가능</p>
<pre><code class="language-js">let name = &#39;mike&#39;;
console.log(name); // Mike
name = &#39;Jane&#39;;
console.log(name); // Jane</code></pre>
<pre><code class="language-js">console.log(name); // Reference Error
let name = &#39;mike&#39;;</code></pre>
<p>호이스팅은 스코프 단위<code>{}</code>로 일어난다. 그렇기 때문에 세 변수 모두 다 호이스팅이 일어난다.
<img src="https://media.vlpt.us/images/ye-ji/post/434a5d81-2cf1-47d4-b267-d1c530095283/image.png" alt="">
여기서 스코프는 함수 내부를 의미한다. let으로 선언한 age 2번째 변수가 호이스팅을 일으킨다! 만약 호이스팅이 되지 않았다면 함수 밖에서 선언된 age변수 30이 찍혀야한다. </p>
<h1 id="변수의-생성과정">변수의 생성과정</h1>
<p><img src="https://media.vlpt.us/images/ye-ji/post/08dbe7b1-87f5-4df5-8648-680c46319dfb/image.png" alt="">
변수는 3단계의 생성과정을 거친다. 1. 선언 단계, 2. 초기화 단계, 3. 할당 단계</p>
<p><img src="https://media.vlpt.us/images/ye-ji/post/6b601c6d-cc35-4449-af5b-378ca76cfe9d/image.png" alt="">
var는 선언과 초기화가 동시에 일어난다. 즉, var가 선언되면 undefined가 할당되어져 초기화되어진다. 그래서 할당 전에 호출하면 에러를 내지 않고 undefined가 나오게 된다.</p>
<p><img src="https://media.vlpt.us/images/ye-ji/post/b1fdec05-ac60-4165-a60a-275bad7c4e5a/image.png" alt="">
let은 선언 단계와 초기화 단계가 분리되어 이루어진다. 호이스팅 되면서 선언단계가 이루어지지만 초기화 단계는 실제 코드가 도달해질 때 되기 때문에 reference error가 발생하게 된다. </p>
<p><img src="https://media.vlpt.us/images/ye-ji/post/0925816a-051b-4257-8b63-a52d6e592fb4/image.png" alt=""> 
const는 선언과 할당이 동시에 되어야 한다. let과 var는 선언만 해두고 할당을 나중에 한다. let과 var는 값을 변경할 수 있기 때문이다! 
<img src="https://media.vlpt.us/images/ye-ji/post/d3c65909-dad2-47a0-84de-2461dae450aa/image.png" alt="">
선언하면서 할당을 해주지 않았기 때문에 syntax error가 나는 것을 확인할 수 있다.</p>
<h1 id="스코프">스코프</h1>
<p><img src="https://media.vlpt.us/images/ye-ji/post/6cf31870-27e8-42c0-9c11-4cd8b8316340/image.png" alt="">
<code>var는 함수 스코프</code>이고, <code>let과 const는 블록 스코프</code>이다! 블록 스코프에서 선언된 변수는 블록 내에서만 유효하며 외부에서는 접근할 수 없다. 즉, 블록 스코프는 지역변수이다. 여기서 말하는 코드 블록은 <code>함수</code>, <code>if문</code>, <code>for문</code>, <code>while문</code>, <code>try-catch문</code> 등을 의미한다. 반면에 함수 스코프는 함수 내에서 선언된 변수만 지역 스코프가 되는 것이다. </p>
<p><img src="https://media.vlpt.us/images/ye-ji/post/3fc534ad-698d-4910-ac9e-a9aa3f9e1e2d/image.png" alt="">
예를 들어 if문안에서 var를 선언한 변수는 if문 밖에서도 사용이 가능하다!!
하지만 let과 const는 이렇게 사용이 불가능하다. <code>{}</code>안에서만 사용이 가능하다.</p>
<p><img src="https://media.vlpt.us/images/ye-ji/post/177743ce-7733-4c72-ad71-2318c3530344/image.png" alt="">
var도 이렇게 함수 내에서 사용되면 함수 밖에서 사용이 불가능하다!
유일하게 벗어날 수 없는 스코프가 함수 스코프이다!!!</p>
<p>출처)
!youtube[ocGc-AmWSnQ?list=PLZKTXPmaJk8JZ2NAC538UzhY_UNqMdZB4]</p>
]]></description>
        </item>
    </channel>
</rss>