<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>boram_in.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 10 Feb 2022 13:23:19 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. boram_in.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/boram_in" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[0210 TIL ]]></title>
            <link>https://velog.io/@boram_in/0210-TIL</link>
            <guid>https://velog.io/@boram_in/0210-TIL</guid>
            <pubDate>Thu, 10 Feb 2022 13:23:19 GMT</pubDate>
            <description><![CDATA[<p>파이어베이스를 통해서 채팅을 할 수 있고 그룹별로 아이템을 관리할 수 있는 기본적인 어플리케이션을 구현해보려고 하고 있다.</p>
<hr/>

<h2 id="목표">목표</h2>
<ul>
<li>기존의 hook에 대해서 이해도를 높이기 위해서 최대한 재사용한다. </li>
<li>이메일, 패스워드로만 가입을 하는 이전의 프로젝트에서 사진을 추가한다. </li>
<li>온라인인 사람들을 서로 확인할 수 있도록 만들어 폐쇄적인(?) 어플리케이션이 아니라 열린(?) 어플리케이션을 지향한다. </li>
<li>TIL만 작성하는 것이 아니라 깃허브에 리드미도 작성해본다!</li>
</ul>
<hr/>

<h2 id="회원가입--로그인-hook-업데이트">회원가입 ~ 로그인 hook 업데이트</h2>
<h3 id="usesignup">useSignup</h3>
<p><img src="https://images.velog.io/images/boram_in/post/f141e8fd-7e23-403d-a482-de44cec2f3be/image.png" alt="">
변화를 전체적으로 보면 위와 같다. </p>
<h4 id="업데이트-사항">업데이트 사항</h4>
<p><img src="https://images.velog.io/images/boram_in/post/916225df-82d3-47dc-9116-372c370ee908/image.png" alt="">
우선은 넘겨받는 것에 thumbnail을 추가해준다. 이후에 createUserWithEmailAndPassword과 에러에 대한 예외처리는 그대로 둔다. 
<img src="https://images.velog.io/images/boram_in/post/dd5bd030-29a7-47ca-8372-5fbda69a3c4b/image.png" alt="">
우선 섬네일을 받기 위해서 가장 먼저 경로를 지정해준다.</p>
<pre><code>`thumbnails/${res.user.uid}/${thumbnail.name}`;</code></pre><p>전체적으로 큰 thumbnails을 모아두는 폴더를 최상위로 두고 그 아래에 회원가입을 할 때마다 자동으로 부여가 되는 uid를 통해서 개인 폴더를 만든다. 이후에 유저가 올리는 파일인 thumbnail의 name을 통해서 파일 이름으로 저장해준다. </p>
<pre><code> const img = await projectStorage.ref(uploadPath).put(thumbnail);</code></pre><p>그렇게 우선적으로 설정한 경로를 통해서 put을 통해서 thumbnail을 저장해주고 </p>
<pre><code>const imgUrl = await img.ref.getDownloadURL();</code></pre><p>updateProfile에서는 url이 필요하기 때문에 위의 이미지를 url로 받아올 수 있도록 imgUrl도 구현해준다. </p>
<pre><code>await res.user.updateProfile({ displayName, photoURL: imgUrl });</code></pre><p>이전과 동일하게 createUserWithEmailAndPassword은 이메일과 패스워드 밖에 받지 못하므로 updateProfile을 통해서 유저의 프로필을 더해준다. displayName과 photoUrl을 imgUrl로 지정해서 유저의 프로필을 업데이트 해준다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/a56ab6dd-c53d-4080-96de-f6aa93e94ef8/image.png" alt=""></p>
<p>끝으로 유저의 상태를 실시간으로 관리할 수 있도록 firestore에 컬렉션 내부에 문서를 생성해준다. 위와 유사한 방식으로 uid를 통해서 doc이 없다면 만들어주고 이후에 관리하며 set을 통해서 상태를 지정해준다. 
<img src="https://images.velog.io/images/boram_in/post/9dae7412-5f3a-4d05-9e1a-093d24c92d5a/image.png" alt="">
계속해서 이 부분에서 에러는 없이...! 컬렉션에 추가되지 않았는데 가서 users를 하나 시작해주니 이후에는 차곡차곡 쌓였다. 원래 이렇게 해야 하는 것일까..? </p>
<h3 id="uselogout">useLogout</h3>
<h4 id="업데이트-사항-1">업데이트 사항</h4>
<p><img src="https://images.velog.io/images/boram_in/post/3e121638-e952-4c29-83ff-3133113e5c0d/image.png" alt=""></p>
<p>로그아웃은 데이터를 주고 받을 일이 없기 때문에 비교적 업데이트할 사항이 많지 않다. </p>
<pre><code>
    // 로그아웃
    try {
      // online 업데이트
      const { uid } = user;
      await projectFirestore
        .collection(&quot;users&quot;)
        .doc(uid)
        .update({ online: false });

      await projectAuth.signOut();</code></pre><p>uid를 user에서 가져오고 &quot;user&quot;컬렉션에서 uid를 통해 doc을 골라낸 후에 online의 상태를 false로 다시 바꿔준다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[0205 TIL]]></title>
            <link>https://velog.io/@boram_in/0205-TIL</link>
            <guid>https://velog.io/@boram_in/0205-TIL</guid>
            <pubDate>Sat, 05 Feb 2022 14:24:03 GMT</pubDate>
            <description><![CDATA[<blockquote>
</blockquote>
<p>⚠️ TIL은 제가 이해한 내용을 바탕으로 작성되어 있으며, 쉽게 이해하기 위해서 이것저것 스스로 비유를 많이 생각하는 편이라 비약이 있을 수 있습니다. ⚠️</p>
<h2 id="1-useeffect">1. useEffect</h2>
<blockquote>
<p>✓안전한코딩✓에러검증 
우리가 매일 사용하는 useEffect.. 혹시 모르고 사용하셨나요? 
✓안전한코딩✓에러검증</p>
</blockquote>
<p>우선, useEffect에 대해서 한 번 정리해보자. </p>
<blockquote>
<h3 id="useeffect는-언제-실행되는가">useEffect는 언제 실행되는가</h3>
<p><img src="https://images.velog.io/images/boram_in/post/83583eba-5195-4e01-a6fd-6e768f3c8906/image.png" alt=""></p>
</blockquote>
<p>1) 컴포넌트가 mount되었을 때
2) 컴포넌트가 업데이트 되었을 때 
3) [ ]가 있다면 [ ] 내부의 state가 변경될 때만 </p>
<h4 id="1-컴포넌트가-mount-되었을-때--2-컴포넌트가-업데이트-되었을-때">1) 컴포넌트가 mount 되었을 때 &amp; 2) 컴포넌트가 업데이트 되었을 때</h4>
<pre><code>function 내컴포넌트(){
    useEffect(()=&gt;{
        console.log(1111)
    })
}</code></pre><p>위와 같이 useEffect를 사용하면 내컴포넌트가 mount되었을 때 console.log(1111)이 실행이 된다(1111 콘솔 출력). 이후에 내컴포넌트가 업데이트 될 때마다 console에 1111을 출력한다. 예를 들어 이후에 input을 추가해서 onChange이벤트 등을 받을 때. </p>
<p>그러나 위와 같이 console.log(1111) 정도면 다행이지만 무거운 코드라면 어떻게 될까? 업데이트가 될 때마다 내부 함수가 계속해서 실행이 될 것이다. 그렇기 때문에 useEffect는 뒤에 무언가를 추가해줄 수 있다. </p>
<h4 id="3---내부의-state가-변경될-때">3) [ ] 내부의 state가 변경될 때</h4>
<pre><code>function 내컴포넌트(){
    useEffect(()=&gt;{
        console.log(1111)
    }, [⭐])
}</code></pre><p>만약 위와 같이 코드를 써주면 이제 ⭐가 변경될 때만 console.log(1111)을 실행시켜준다. 그렇다면 요것을 이용하면? [ ]을 비어있게 처리를 하면 한 번 페이지가 로드되고 mount 될 때만 실행이 되고 이후에는 실행되지 않는다. (⭐<strong>딱 한 번만 실행!</strong>⭐)</p>
<h4 id="추가-적인-내용">+추가 적인 내용</h4>
<pre><code>useEffect (()=&gt;{

return 함수 어쩌구~~
})</code></pre><p>이렇게 return 이후에 적어주면 unmount될 때 실행된다. 요것을 이제 응용해보자! </p>
<h3 id="context-추가-공부">Context 추가 공부</h3>
<p>주중에 context 공부를 너무 후다다닥 넘긴 느낌이 있어서, 공식 사이트를 들어가서 추가적으로 Context에 대해서 공부했다. </p>
<h4 id="언제-쓸까">언제 쓸까?</h4>
<p>context는 React 컴포넌트 트리 안에서 전역(global)하게 데이터를 공유할 수 있게 만들어졌다. 그래서 로그인, 테마, 선호하는 언어 등에 사용한다. </p>
<h4 id="사용하기-전에-고려해보자">사용하기 전에 고려해보자</h4>
<p>전역! 이라고 하면 느낌이 우선 쎄하다. context는 여러 층위의 컴포넌트에 네스팅된 많은 컴포넌트에게 데이터를 전달하는 것이 목적이다. context를 사용하면 컴포넌트의 재사용성이 낮아지므로 꼭 필요한 경우에만 사용하자. </p>
<p>데이터를 트리 안 여러 층에 있는 많은 컴포넌트에 주어야 할 때도 있다. 이런 데이터 값이 변할 때마다 모든 하위 컴포넌트에게 널리 &quot;방송&quot;하는 것이 context이다. </p>
<blockquote>
<p>prop이 조선 시대 파발처럼 이곳 저곳 들리면서 모두 알려주는 느낌이라면 
<img src="https://images.velog.io/images/boram_in/post/152237be-b336-4bc6-b470-235950caa79a/image.png" alt="">
Context는 요즘 푸쉬 알림처럼 딱 푝! 하고 사용하게 하는 것인가..? </p>
</blockquote>
<h4 id="api">API</h4>
<p>** React.createContext **</p>
<pre><code>const MyContext = React.createContext(defaultValue);</code></pre><p>context 객체를 만든다고 쫄 필요 없다. 위와 같이 만들어 주면 된다. 그럼 이후에 구독! 하고 있는 컴포넌트를 렌더링 할 때 React는 컴포넌트 트리에서 가장 가까이 있는 Provider로부터 현재 값을 읽언낸다. </p>
<p>그럼 저기 defalutValue는 뭐하는 친구일까? 그렇게 트리 안에서 Provider를 찾지 못했을 때만 사용하는 값. 그래서 컴포넌트에서 얘만 테스트할 때 유용하다. </p>
<h4 id="contextprovider">context.Provider</h4>
<pre><code>&lt;MyContext.Provider value={/* 어떤 값 */}&gt;</code></pre><p>context 오브젝트 
<img src="https://images.velog.io/images/boram_in/post/6b05def8-9f4d-4f50-9824-2eeca71ae35f/image.png" alt=""></p>
<p>Context 오브젝트에 포함된 React 컴포넌트인 Provider는 Context를 구독하는 컴포넌트들에게 Context의 변화를 알려주는 알림 설정 버튼! </p>
<p>Provider 컴포넌트는 위에 value={/* 어떤 값 */}&gt; 의 value prop을 받아서 이 값을 하위의 컴포넌트에게 넘겨준다. 값을 받을 수 있는 컴포넌트의 수에는 제한이 없다. 유튜버가 유튜버를 구독하는 것처럼 Provider 하위에 Provider도 괜찮다. 다만 이 경우에는 하위의 Provider가 우선한다. </p>
<p>새로운 영상이나 커뮤니티에 글이 올라오면 파파파박 전달 되는 것처럼. Provider 하위에서 Context를 구독하는 모든 컴포넌트는 Provider의 value Prop이 바뀔 때마다 재렌더링 된다. 이러한 하위 consumer로의 전파는 shouldComponent 메서드가 적용되지 않아 업데이트를 건너뛰어도 consumer가 업데이트 된다. </p>
<p>이 때 context 값이 변경되었는지 여부는 Object.is 와 동일한 알고리즘이다. </p>
<h3 id="코드-분석">코드 분석</h3>
<pre><code>import { createContext, useReducer } from &quot;react&quot;;
🙋‍♂️ 우선은 컨텍스트를 만들기 위해서 임포트를 해준다 


export const AuthContext = createContext();
🙋‍♂️ AuthContext라는 컨텍스트를 만들어준다

export const authReducer = (state, action) =&gt; {

 🙋‍♂️ state는 state 이며, action은 dispatch이다.
 dispatch의 type에 따라서 밑의 switch가 작동


  switch (action.type) {
    default:
      return state;
  }
};

export const AuthContextProvider = ({ children }) =&gt; {
  const [state, dispatch] = useReducer(authReducer, {
    // 함수와 초기값을 인수로 받는다
    user: null,
  });

  return (
    &lt;AuthContext.Provider value={{ ...state, dispatch }}&gt;
      {children}
    &lt;/AuthContext.Provider&gt;
  );
};
</code></pre><blockquote>
<p>잠깐 useReducer는? </p>
</blockquote>
<p>###</p>
<h3 id="보완해야-할-점">보완해야 할 점</h3>
<ul>
<li>생각보다 React 공식 문서가 자세하고 친절하고 내가 모르는 부분도 많다. 라이브러리를 쓰면서 공식 문서도 모르면.. 안 되기 때문에 계속해서 모르는 부분이 있으면 그 부분과 관련된 부분들을 찾아서 읽고 전체를 정리해야겠다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[0204 TIL ]]></title>
            <link>https://velog.io/@boram_in/0204-TIL</link>
            <guid>https://velog.io/@boram_in/0204-TIL</guid>
            <pubDate>Fri, 04 Feb 2022 09:22:15 GMT</pubDate>
            <description><![CDATA[<h2 id="라우팅">라우팅</h2>
<p>이제는 눈감고도 해봅시다. 
<img src="https://images.velog.io/images/boram_in/post/ff4606e7-d74b-461a-8edf-b9bde65a6e00/image.png" alt="">
근데 진짜 눈을 감고 하면 아래와 같은 실수를 할 수도 있네요. 
<img src="https://images.velog.io/images/boram_in/post/dea25272-c6c8-41fc-b9a8-a9b4537e4216/image.png" alt="">
어색한 부분이 없으신가요? 따로 떼어놓고 보니. 잘 보인다. 회원가입으로 페이지 이동이 되지 않아서. 또 다시 라우트 페이지를 하나씩 주석처리 해보면서 찾았는데. 한참을 찾다 보니 path가 컴포넌트에 있더군요. </p>
<blockquote>
<p>이제는 익숙해진 </p>
</blockquote>
<pre><code>&lt;BrowserRouter&gt;
  &lt;Switch&gt;
    &lt;Route exact path=&quot;/&quot;&gt;</code></pre><p>  브라우저 라우터 - 스위치- 라우터s</p>
<p>눈 감은 김에 하나 더 해봅니다. 
<img src="https://images.velog.io/images/boram_in/post/57364566-7671-4d8c-9ac2-278592b53b4c/image.png" alt="">
이렇게 유저에게서 form을 통해서 정보를 받아봅시다. </p>
<pre><code>const Login = () =&gt; {
  const [email, setEmail] = useState(&quot;&quot;);
  const [password, setPassword] = useState(&quot;&quot;);

  const handleSubmit = (e) =&gt; {
    e.preventDefault();
    console.log(email, password);
  };

  return (
    &lt;form className={styles[&quot;login-form&quot;]} onSubmit={handleSubmit}&gt;
      &lt;h2&gt;로그인&lt;/h2&gt;
      &lt;label&gt;
        &lt;p&gt;이메일:&lt;/p&gt;
        &lt;input
          type=&quot;email&quot;
          required
          onChange={(e) =&gt; setEmail(e.target.value)}
          value={email}
        /&gt;
      &lt;/label&gt;
      &lt;label&gt;
        &lt;span&gt;비밀번호&lt;/span&gt;
        &lt;input type=&quot;password&quot; onChange={(e) =&gt; setPassword(e.target.value)} /&gt;
      &lt;/label&gt;

      &lt;button className=&quot;btn&quot;&gt; 로그인 &lt;/button&gt;
    &lt;/form&gt;
  );</code></pre><p>챙겨야할 부분은 value를 통해서 two-way communication이 가능하도록 하는 것과 e.preventDefault를 통해서 새로고침을 막아주는 것. 같은 방식으로 회원가입도 폼을 만들었습니다. 그렇지만 언제까지 console로 확인만 할 수 없으니 firebase로 ㄱㄱ </p>
<br>

<h2 id="어쓰-구현하기">어쓰! 구현하기</h2>
<p>예전에 스터디에서 어쓰어쓰,, 해서 잘 몰랐던...! 인증을 구현해봅시다. </p>
<blockquote>
<p>인증 vs 인가 
인증은 신원을 확인하는 과정정지! 라이트 꺼! 시동 꺼! 우리는 보통 어떤 인증요소를 증거로 제시하여 자신을 인증한다. 출입증 패스라던가. 민증이라던가.  인증과 달리 인가는  어떤 리소스에 접근할 수 있는지 또는 어떤 동작을 수행할 수 있는지를 검증하는 것으로 권한을 얻는 일. 그래서 인증은 인가로 이어질 수 있지만 인가는 인증으로 바로 이어지지 는 않는다. </p>
</blockquote>
<p><img src="https://images.velog.io/images/boram_in/post/7c5a80b3-0693-4030-b9ea-6cb021c14c19/image.png" alt=""></p>
<p>코딩하기 전부터 궁금했었는데 오늘 배워볼 수 있었다. 물론 파이어베이스를 통해서! </p>
<pre><code>const firebaseConfig = {
*******************
}</code></pre><p>콜솔로 프로젝트르 만들고 요런 파일을 어서 찾아와서 config.js로 만들고 사용할 기능들을 빨리 import하고 실행시켜주었습니다.</p>
<pre><code>import firebase from &quot;firebase/app&quot;;
import &quot;firebase/firestore&quot;;
import &quot;firebase/auth&quot;;

...

firebase.initilizeApp(firebaseConfig); //시작하겠습니다~
const projectFirestore = firebase.firestore(); // 파이어 스토어를 사용하겠다
const projectAuth = firebase.auth(); // 인증은 auth로

export { projectFirestore, projectAuth }; // 위 둘을 어디서든 사용할 수 있도록 빼내겠다.
</code></pre><p>그렇다면 이제 제대로 회원가입을 마무리해봅시다. 이를 처리할 hook을 만들어서 재사용성을 높여봅시다. </p>
<pre><code>import { useState } from &quot;react&quot;;
import { projectAuth } from &quot;../firebase/config&quot;;

export const useSignup = () =&gt; {
  const [error, setError] = useState(null);
  const [isPending, setIsPending] = useState(false);
</code></pre><p>우선은 파이어베이스에서 projectAuth를 받아오고 에러와 진행중을 띄우기 위해서 useState를 통해서 error와 isPending을 만들어주었습니다. </p>
<pre><code>const signup = async (email, password, username) =&gt; {
    setError(null);
    setIsPending(true); // 로딩 시작

    try {
      // 유저 로그인
      const res = await projectAuth.createUserWithEmailAndPassword(
        email,
        password
        // 인증을 이메일과 패스워드로 하겠다.
      );  
      console.log(res);
      console.log(res.user);
      if (!res) {
        throw new Error(&quot;유효한 이메일 혹은 비밀번호가 아닙니다&quot;);
      }
      //   성공시
      // 유저의 프로필을 업데이트하며 네임 추가하기
      await res.user.updateProfile({ displayName: username });

      setIsPending(false);
      setError(null);
    } catch (err) {
      console.log(err.message);
      setError(err.message);
      setIsPending(false); //어쨋든 로딩은 끝
    }
  };
   return { error, isPending, signup };
};</code></pre><h4 id="나를-키운-것은-팔-할이-에러다">나를 키운 것은 팔 할이 에러다.</h4>
<p><img src="https://images.velog.io/images/boram_in/post/e863885c-8106-4106-8a5f-a0ae25b8e1d6/image.png" alt=""></p>
<p>그런데 위와 같이 에러가 난다. 얼른 구글링해보자. 우선 찾아보면 예상치 못한 공백으로 인해서 .trim()을 붙여줘야 한다고 나온다. 그렇지만 그런 쉬운 것으로 해결되지 않았다. 그럴 때는 코드를 다시 보자. 다시 보니 
<img src="https://images.velog.io/images/boram_in/post/ec224ad5-dfb2-4079-9639-79703bdf7de8/image.png" alt="">
요렇게 비동기도 받아주는 부분과 또한 sign-up으로 넘겨주는 곳의 순서가 달랐다. 그래서 이후에 객체 형식으로 넘겨줄 수 있도록 {}을 넣어주니 해결이 되었다. 
<img src="https://images.velog.io/images/boram_in/post/d81c41ae-4ad0-4ede-a78f-1c05f7393fae/image.png" alt="">
그래서 이후에 테스트를 해보니 {}를 빼면, 죠렇게 순서가 맞지 않으면 에러가 났다. 
<img src="https://images.velog.io/images/boram_in/post/8090461d-8e1e-4323-af0a-3bf77aba02f8/image.png" alt="">
이후에 firebase에 들어가면 이렇게 우리가 여러 번 삽질을 한 흔적이 남아있다. </p>
<hr/>

<h3 id="로그인--로그아웃-구현하기">로그인 &amp; 로그아웃 구현하기</h3>
<p>useContext를 활용해서 전역으로 로그인과 로그아웃을 관리하고 만들어보자! </p>
<pre><code>import { createContext, useReducer } from &quot;react&quot;;

export const AuthContext = createContext();</code></pre><p>이렇게 useReducer를 불러오고 AuthContext 라는 컨텍스트를 만들어준다. </p>
<pre><code>export const authReducer = (state, action) =&gt; {
  switch (action.type) {
    case &quot;LOGIN&quot;:
      return { ...state, user: action.payload };
    case &quot;LOGOUT&quot;:
      return { ...state, user: null };
    default:
      return state;
  }
};
</code></pre><p>다음 부분에서는 state와 action을 이용해서 LOGIN과 LOGOUT 기능을 만들어준다. return 해주는 값은 현재 상태를 스프레드 형식으로 우선 받아주고 뒤에 payload를 통해서 유저의 상태를 글로벌하게 관리한다. </p>
<pre><code>export const AuthContextProvider = ({ children }) =&gt; {
  const [state, dispatch] = useReducer(authReducer, {
    user: null,
  });

  //   dispatch({type : &#39;LOG_IN&#39;})

  return (
    &lt;AuthContext.Provider value={{ ...state, dispatch }}&gt;
      {children}
      {/* 무엇이든 이후에 감쌀 모든 것을 의미 */}
    &lt;/AuthContext.Provider&gt;
  );
};</code></pre><p>위에서 children은 이후에 감쌀 모든 것을 의미하며 이 앱에서는 App을 감쌌다. </p>
<pre><code>#useAuth 

import { AuthContext } from &quot;../context/AuthContext&quot;;
import { useContext } from &quot;react&quot;;

export const useAuthContext = () =&gt; {
  const context = useContext(AuthContext);

  if (!context) {
    throw Error(&quot;useContext가 AuthProvider 내부에 있어야 합니다!&quot;);
  }

  return context;
};
</code></pre><p>그래서 위와 같은 useAuth는 지금은 App을 감쌌기 때문에 에러가 일어날 일이 없지만! 그래도 앞으로 항상 이렇게 App을 감싸는 컨텍스트만 만들 것이 아니기에 만들어주었다. </p>
<p>마지막으로 로그아웃 부분이다. 필요한 컴포넌트 어디서나 로그아웃 버튼을 눌렀을 때만 실행될 수 있도록 hook을 통해서 재사용성을 높였다. </p>
<pre><code>#useLogout
const useLogout = () =&gt; {
  const [error, setError] = useState(null);
  const [isPending, setIsPending] = useState(false);
  const { dispatch } = useAuthContext(); //dispatch the logout 기능

  //   특정 컴포넌트에서 로그아웃을 눌렀을 경우에만 로그아웃을 실행할 수 있도록
  const logout = async () =&gt; {
    setError(null);
    setIsPending(true);

    // 로그아웃
    try {
      await projectAuth.signOut();
      //   파이어 베이스의 signOut을 이용한다.
      //   projectAuth.signOut(); 가 진행된 이후에 
      이후의 것들이 실행될 수 있도록 await를 사용

      // dispatch 로그아웃
      dispatch({ type: &quot;LOGOUT&quot; });

      // 로그아웃은 별도로 유저에게 무언가 조치를 더 할 것이 
      없으므로 payload를 전달하지 않아도 된다

      setIsPending(false);
      setError(null);
    } catch (err) {
      console.log(err.message);
      setError(err.message);
      setIsPending(false);
    }
  };

  return { error, isPending, useLogout };
};
</code></pre><p>우선은 이제 익숙하게 error와 isPending을 선언해주고. dispatch하기 위해서 디스트럭처링을 통해서 구현해준다. </p>
<pre><code>const { dispatch } = useAuthContext(); //dispatch the logout 기능</code></pre><pre><code>const logout = async () =&gt; {
    setError(null);
    setIsPending(true);</code></pre><p>을 통해서 에러 스위치 내리고 isPending 스위치를 올린다
<img src="https://images.velog.io/images/boram_in/post/a418d115-0a11-4d62-9e9a-d7cc2990d770/image.png" alt=""></p>
<pre><code>try {
      await projectAuth.signOut();
        // dispatch 로그아웃
      dispatch({ type: &quot;LOGOUT&quot; });
      setIsPending(false);
      setError(null);
    } catch (err) {
      console.log(err.message);
      setError(err.message);
      setIsPending(false);
    }</code></pre><p>로그아웃은 어떻게 할까? 생각했는데 파이어 베이스의 signOut을 이용한다. 이와 더불어,  projectAuth.signOut(); 가 진행된 이후에 이후의 것들이 실행될 수 있도록 await를 사용한다. 로그아웃은 별도로 유저에게 무언가 조치를 더 할 것이 없으므로 payload를 전달하지 않아도 된다. 각 과정이 끝난 뒤에는 우선 isPending 스위치를 내리고 Error를 null 혹은 출력해준다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[0203 TIL (POST, Redirection, 검색기능)]]></title>
            <link>https://velog.io/@boram_in/0203-TIL</link>
            <guid>https://velog.io/@boram_in/0203-TIL</guid>
            <pubDate>Thu, 03 Feb 2022 12:27:44 GMT</pubDate>
            <description><![CDATA[<h2 id="post-기능-추가하기">POST 기능 추가하기</h2>
<pre><code>export const useFetch = (url, method = &quot;GET&quot;) =&gt; {
...</code></pre><p>우선은 custom hook인 useFetch에 메소드 파라미터 하나를 추가해주며, 초기값은 GET으로 설정했다. </p>
<blockquote>
<p>왜 GET?</p>
</blockquote>
<p>그리고 post될 데이터를 위해서 아래와 같이 함수를 만들어주었다. </p>
<pre><code>const postData = (postData) =&gt; {
    setOptions({
      method: &quot;POST&quot;,
      headers: {
        &quot;Content-Type&quot;: &quot;application/json&quot;,
      },
      body: JSON.stringify(postData),
    });
  };</code></pre><p>1) method: POST를 처리하기 위해서 만들었기 때문에 method는 POST이다. 
2) headers: 밑에 headers 에서는 받아올 콘텐츠의 타입에 대해서 적어준다. 이 부분에 대해서는 더 공부가 필요하겠다! 
3) body : 자바스크립트 오브젝트를 JSON의 string 형태로 바꿔줄 수 있도록 전달된 postData를 JSON.stringfy로 감쌌다. </p>
<h3 id="method-타입-신경-쓰기">method 타입 신경 쓰기!</h3>
<p>또한 아래와 같이 들어온 method의 타입에 따라서 두 가지 방향으로 실행될 수 있도록 아래 함수를 추가 해주었다. </p>
<pre><code>   if (method === &quot;GET&quot;) {
      fetchData();
    }
    if (method === &quot;POST&quot; &amp;&amp; options) {
      fetchData(options);
    }
</code></pre><p>그래서 GET이라면 바로 fetchData를 실행해주고, options가 있다면 options에 따라 실행될 수 있도록. </p>
<h3 id="create에-추가">create에 추가</h3>
<pre><code>import { useFetch } from &quot;../../hooks/useFetch&quot;;

  const { postData, data, error } = useFetch(
    &quot;http://localhost:3000/recipes&quot;,
    &quot;POST&quot;
  );</code></pre><p>위와 같이 이제 만든 hook을 불러오고 하단에서 return 해준 값 중에서 { postData, data, error }를 사용해서 POST될 데이터를 설정해주고 handleSubmit 내부에 아래와 같이 들어갈 데이터의 형식을 넣어준다. </p>
<pre><code>postData({
      title,
      ingredients,
      method,
      cookingTime: cookingTime + &quot; minutes&quot;,
    });</code></pre><p><img src="https://images.velog.io/images/boram_in/post/a5bc2fae-9c87-4314-b0c8-1e5aec4f5b78/0203_1.gif" alt=""></p>
<p><img src="https://images.velog.io/images/boram_in/post/bbeec42a-b338-43ba-85a4-fc02d27669fb/image.png" alt=""></p>
<h2 id="redirection">Redirection</h2>
<p>그렇게 submit을 하면 바로 홈페이로 돌아가게 만들 수 없을까? 우선 바로 생각해볼 것은 useHistory를 써야겠다는 생각. </p>
<pre><code>import { useHistory } from &quot;react-router-dom&quot;;

const history = useHistory();

🍔햄버거 &amp; 🍟감튀 같은 조합!
import 해보고 const 해주기</code></pre><p>그리고 data가 바뀔 때마다 리디렉션이 일어나야 하기 때문에 이 때 떠올려야 하는 것은 useEffect이다. </p>
<pre><code>  useEffect(() =&gt; {
    if (data) {
      history.push(&quot;/&quot;);
    }
  }, [data]); //useFetch로 받아온 data가 변경될 때마다 추가적으로 실행
</code></pre><p>직독직해 해보면 첨에 컴포넌트가 실행될 때 한 번 실행되었다가. 만약 data에 변경이 일어나면 안에 있는 자동적으로 내부의 함수가 실행되므로 history.push(&quot;/&quot;), 홈페이지로 돌아가게 된다. </p>
<h2 id="검색-기능-만들기">검색 기능 만들기</h2>
<h3 id="1-searchbar-구현하기">(1) searchBar 구현하기</h3>
<p>검색기능을 만들어보자! 일단 rfc ㄱㄱ! 
그리고 검색어를 받아줄 term과 setTerm을 만들어주자. </p>
<pre><code>const [term, setTerm] = useState(&quot;&quot;);</code></pre><pre><code>  &lt;div className=&quot;searchBar&quot;&gt;
      &lt;form onSubmit={handleSubmit}&gt;
        &lt;label htmlFor=&quot;search&quot;&gt; 검색: &lt;/label&gt;
        &lt;input
          type=&quot;text&quot;
          id=&quot;search&quot;
          onChange={(e) =&gt; setTerm(e.target.value)}
          required
        /&gt;
      &lt;/form&gt;
    &lt;/div&gt;</code></pre><p>그리고 생성할 컴포넌트의 핵심적인 내용은 요 부분이다. text를 받을 수 있도록 적어주고 label과 input id 를 search로, 마지막으로 검색어가 변화될 때 받을 수 있도록 e.target.value를 setTerm으로. </p>
<pre><code>const handleSubmit = (e) =&gt; {
    e.preventDefault();

    history.push(`/search?query=${term}`);
    // search로 가게끔 만들어준다.
  };</code></pre><p>위와 같이 form을 preventDefault로 기본 동작을 막아주고. 핵심은 
<code>/search?query=${term}</code> 
요 부분이다. 그래서 검색을 하면 
<img src="https://images.velog.io/images/boram_in/post/718dd14e-f695-4340-a997-de315ef82fc3/image.png" alt="">
이와 같은 곳으로 연결된다. 
<img src="https://images.velog.io/images/boram_in/post/ac72f8b2-8d04-4401-b8d7-6e19d16c589d/image.png" alt="">
아니다. 현재 그냥 서치라는 단어만 나온다. 추가적으로 search 내부에서의 동작을 구현해줘야 한다. </p>
<blockquote>
<p>배운점: 
Redirect와 같이 UX적인 부분도! 사소한 부분이지만 완성도를 높이기 위해서 신경쓰자! </p>
</blockquote>
<blockquote>
<p>더 공부해야 할 부분 : </p>
</blockquote>
<ul>
<li>왜 GET을 초기값으로 해줬을까? </li>
<li>아래와 같은 파트가 이해가 되지 않았다. 이렇게 받아오면 되는 건가..?<pre><code>const { postData, data, error } = useFetch(
 &quot;http://localhost:3000/recipes&quot;,
 &quot;POST&quot;
);</code></pre></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[0201 TIL (React Router)]]></title>
            <link>https://velog.io/@boram_in/0201-TIL</link>
            <guid>https://velog.io/@boram_in/0201-TIL</guid>
            <pubDate>Tue, 01 Feb 2022 14:33:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>오옷! 벨로그에!! 다크모드가 생겼다!!! 
바쁘신데 개발을 계속하시는 벨로퍼트님이 존경스럽다!</p>
</blockquote>
<h2 id="router">Router</h2>
<p>오늘은 리액트 라우터에 관해서 학습했다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/08666431-59b7-49ef-8ca6-02f81f87c3d7/image.png" alt=""></p>
<p>본래 서버와 브라우저의 응답은 위에 도식화된 것처럼 요청을 보내면 이에 대해서 응답을 보내준다. 그리고 바닐라 JS를 통해서 라우팅을 할 때는 HTML 페이지를 여럿 만들었다. 그러나 리액트, react-router-dom 을 사용하면 라우터를 사용하더라도 여전히 하나의 페이지를 사용한다! (놀라움!) </p>
<h4 id="react-dynamically-inject-content-from-all-componenet-into-the-dom">&quot; React dynamically inject content from all componenet into the Dom &quot;</h4>
<p>React-Dom을 사용할 때는 새로운 페이지를 렌더링하더라도 추가적인 request를 서버에 보내지 않기 때문이다. 그러한 요청을 리액트 라우터가 인터셉트한다. 그리고 이후에 동적으로 라우터에 설정된 것에 따라 페이지의 콘텐츠를 스왑한다. 그래서 페이지를 바꿀 때 더 빠르게되는 것처럼 동작.<br><img src="https://images.velog.io/images/boram_in/post/dcbc1e52-5b90-4bbf-acbb-ae568bd2d4a1/image.png" alt=""></p>
<h3 id="그래서-라우팅-그거-어떻게-하는건데">그래서 라우팅... 그거 어떻게 하는건데?</h3>
<p><img src="https://images.velog.io/images/boram_in/post/39117754-d704-4c2f-9510-af1022b83d4b/image.png" alt="">
어렵지 않다! 위와 같이 Route를 사용해주면 된다. path로 경로를 설정해준다. 그런데 한 번 쯤 겪게 되는 오류가 바로 home이 모든 페이지에 중첩되어 나타나는 오류. 이는 Route의 성질 때문인데 일치하는 모든 것을 보여준다. 그래서 /search로 이동하더라도 /이 home과 겹치기 때문에 나타난다. 그래서 그럴 때는 switch(하나만 보여줘라)로 감싸서 exact(요것과 정확히 일치할 때만)를 붙여준다. 그래서 이를 응용하면 위 사진과 같이 라우팅할 페이지를 나열하고 제일 끝에 path=&quot;*&quot;를 하면 일치한 게 하나도 없이 내려온 모든 결과값을 의미하므로 Not found에 대한 페이지도 만들어낼 수 있다. </p>
<h3 id="a-대신-link-써라">a 대신 Link 써라</h3>
<p>위처럼 인터셉트를 하여 동작하기 위해서, 내부의 링크에는 Link와 NavLink를 사용한다. 둘의 차이는 무엇일까? NavLink는 class에 active를 활성화시켜준다. 그래서 .active 등으로 스타일링과 더불어 유저가 현재 어디에 있는지 알려줄 때 유용하다. 정말 명칭 그대로 Nav에 사용하면 좋은 Link = NavLink</p>
<h3 id="route-parameters">Route Parameters</h3>
<p><img src="https://images.velog.io/images/boram_in/post/e363391f-2c1d-4ff9-b225-1c2b0d69c869/image.png" alt="">
한 두 페이지는 저렇게 하드코딩으로 할 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/a1e3ad75-4950-4d90-b34f-dc5d4c4d97a5/image.png" alt="">
근데 페이지가 위와 같이 하나 둘이 아니라 여럿일 수도 있다. 저 많은 저글링에 어떻게 넘버링을 하나하나 해줄까? 1,2,3,4 하면 손목터널증후군온다. 혼자서 공부를 할 때는 이 부분에서 엄청 고민을 했었다. 이제는 파라미터를 이용하자. 위처럼</p>
<pre><code>&quot;/articles/:id</code></pre><p>이렇게 사용하면 뒤에 :id는 리액트가 changable하다고 인식해준다. 압도적 감사! </p>
<pre><code>&lt;Link to={`/articles/${article.id}`}&gt; 그 id가 그 id 맞다. 아래에서 한 번 더 사용된다</code></pre><p>이렇게 설정을 하면 id에 따라서 라우팅을 해준다! id가 이후에도 계속 사용되기 때문에 이렇게 id를 쓰는 것처럼 나만의 방법을 설정하고 가야겠다. 그리고 저 백틱 쓰는 것은 리액트 문법이 아니라 JS문법이다. 리액트에서 리액트 문법으로 인해서 막히는 경우가 없다. catch(e) =&gt; console.err(&#39;JS를 다시 공부하세요&#39;) 이다. </p>
<h3 id="useparams-사용하기">useParams 사용하기</h3>
<p>위에서 만든 파라미터를 사용해보자</p>
<pre><code>import {useParams } from &quot;react-router-dom&quot; 으로 불러오고
const params = useParams()
params.id (위에 그 id)</code></pre><p>인데 이렇게 쓸 필요 없다. 우리는 디스트럭처링을 배웠으니. </p>
<pre><code>const {id} = useParams()
const url = url주소 + id</code></pre><p><img src="https://images.velog.io/images/boram_in/post/14884eb2-02f5-4631-b46d-980e40f5a6a7/image.png" alt="">
/를 빼먹지 말자. 오류 잡아내느라 한참 걸렸다...! </p>
<p><img src="https://images.velog.io/images/boram_in/post/017f0de8-9392-43e5-83f5-de3297a9ab92/image.png" alt=""></p>
<p>특히나 라우터 실습 중에 이러한 오류가 많이 나왔다. 라우터 page를 export할 때 잘못되어 오류가 발생한 경우가 대다수였다. 밑에 혹은 위에 export default 혹은 export를 잘 해줬는지 살펴보자. 디버깅을 할 때 결국 못 찾아 하나하나 주석처리를 해보면서 찾았다.</p>
<p><img src="https://images.velog.io/images/boram_in/post/b6488f09-77fe-4429-a6b1-12df1f8a209f/image.png" alt="">
결국 오늘 주요하게 학습한 것은 바로 </p>
<pre><code>const {id} = useParams()
const url = url주소 + id</code></pre><p>이러한 패턴이다! 또한 강의를 시작하면서 어색했던 sth &amp;&amp; sth2 이러한 패턴이 많이 익숙해졌고 자유자재로 사용할 수 있었다. 특히 map으로 처음에 못 받아와서 사용하는 이유에 대해서도 이해했다. 근데 실무에서도 많이 쓰나??는 궁금한 포인트이다. </p>
<h3 id="오늘의-잘한점">오늘의 잘한점!</h3>
<ul>
<li>아 오늘 명절이었지. 일단 공부를 했음에 감사하고 또 잘했다. </li>
<li>중간에 공부한 지 6시간 정도 지났을 때 멍~해지는 타이밍을 잘 넘겼다. 내일부터는 이럴 때 CS 과목 쓰면서 공부하면서 나도 라우팅해보려고 한다. </li>
</ul>
<h3 id="더-해볼점">더 해볼점!</h3>
<ul>
<li>Router 저거 5.1 버전 기준이다. 한창 v6가 나오면서 유튜브에서도 벨로퍼트님이 다루시기도하고 다른 분들도 다뤘는데. 추가적으로 공부하면서 업데이트 해봐야겠다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[보람찬 1월 회고 ]]></title>
            <link>https://velog.io/@boram_in/%EB%B3%B4%EB%9E%8C%EC%B0%AC-1%EC%9B%94-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@boram_in/%EB%B3%B4%EB%9E%8C%EC%B0%AC-1%EC%9B%94-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Sun, 30 Jan 2022 05:31:37 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>이제 개발한지 6개월 정도가 지났다. 
비록 학기 중에는 CS 과목을 공부했다고 해도 괜히 조급해지기도 하면서도
&#39;그래도 많이 하지 않았나?&#39; 생각을 하게 되는 시기인 것 같다. </p>
</blockquote>
<h2 id="학교-마무리">학교 마무리!</h2>
<p><img src="https://images.velog.io/images/boram_in/post/6dbd898b-6879-451c-8dbc-6e9fb89414f3/image.png" alt="">
이번 학기, 계절학기까지 포함해 23학점을 성공적으로 수강해냈다! &#39;이제 졸업만 남은 건가!&#39; 라는 생각이 들지만 졸업까지 넘어야할 산들이 많다. 이와 더불어, 거의 1년 가까이 했던 학보사 조교도 잘 마무리 했다. 이제 프로그래밍 공부에 정말 집중할 수 있는 환경이 감사하게 만들어졌다. 그래서 공부 시간도 서서히 올라가고 몰입도도 올라가고 있다. 오미크론이 걱정되기는 하지만 도서관에서 공부하고 있는데 CPA와 공무원 준비하시는 분들을 보며 더 열심히 하도록 다짐하고 있다. 
<img src="https://images.velog.io/images/boram_in/post/04c6fef5-7dd5-401e-80f7-5aac604aaf61/image.png" alt=""></p>
<h2 id="자바스크립트-딥다이브-해-해치웠나">자바스크립트 딥다이브 해.. 해치웠나?</h2>
<p><img src="https://images.velog.io/images/boram_in/post/e4a9cd84-304f-479a-a211-681b5f4cbd14/image.png" alt="">
드디어 이 도마뱀 잡았다! 근데 도마뱀처럼 내가 아해한 것은 꼬리 정도인 것 같다. 아직 몸체라고 생각되는 실행 컨텍스트, 스코프, 클로저, 프로토타입 등등은 놓친 느낌이다. 그래도 미끄러지면서도 잡은 느낌이 있으니 다시 보면 잡을 수 있으리라 생각한다. 컴퓨터 구조, 자료구조와 같은 수업을 들으면서 느꼈던 교훈은 절대 한 번만 보고 다 이해하지 못하리라는 것. 아마 CS과목, 심지어 자바스크립트도, 리액트도 한 번 쓰윽 보고 이해 못할 거다. 그렇게 되면 큰일이다. 아마 구글에서 내년 즈음에는 나를 납치해서 강제로 이직시켜버릴 수도 있따... 아님 대학원을 가버리거나. 그런 것들 바라거나 구한적 없으니 이뤄지지도 않을 듯! 2월 개강하기 전까지 한 번 정도, 중요한 파트는 한 번 더 보기로 다짐했다. </p>
<blockquote>
<p>라고 썼으나. 아마 키보드 놓는 순간까지 자바스크립트는 공부해야 할 것.</p>
</blockquote>
<h2 id="리액트-공부-시작">리액트 공부 시작!</h2>
<p>리액트 공부를 일주일 전부터 시작했다! <del>다 이루었따</del> 리액트로 공부를 하니 드드디어 도규멘트 돗 쿼리셀렉터, 겟엘레멘트바이아이디, 크리에이트~ 이러지 않아도 되니 참 좋다. 그 만큼 빠르게 자바스크립트에 대한 기억이 사라져가고 있기도 하다. !
<img src="https://images.velog.io/images/boram_in/post/9659c5df-73d3-4183-8c5f-357b9be49bab/image.png" alt="">
자바스크립트의 라이브러리여서, 그리고 로토님의 스터디 덕분에 리액트 공부가 어렵지 않다. 다만 익혀야 할 것이 많을 뿐! 특히나 리액트부터는 Udemy에서 공부하기 시작했는데 디테일하게 다뤄지는 강의들이 가격도 저렴해서 너무 좋다! 영어로 들으니, 집중도 강제로 더 해야 하고 모르는 것들은 검색도 하게 되니 속도는 느리지만 자세히 알 수 있어 좋다. 어짜피 모르면 돌아와야 한다. 프로그래밍 공부가 엄청 거창한 것이 아니라 미래에 마주할 에러에 대처할 시간을 조금 버는 것일 뿐. 그에 대한 연장선으로 에러나 버그도 공부의 일부일 뿐이다. 오히려 시간에 쫓기는 코딩을 할 때 나타지않고 지금 나타나주신 것에 대해 참 감사하다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/0c5552fa-c970-4526-95b6-5020b05bf7d2/image.png" alt=""></p>
<h3 id="잘한-점">잘한 점!</h3>
<ul>
<li>루틴을 잘 형성한 것 : 열정은 쓰레기다. 공부하는 습관도 시스템화해야 한다. 환경과의 의존성도 줄이고 테스트, 리뷰를 받을 수 있도록 해야한다!  </li>
<li>자바스크립트 마무리 해냈다: 마무리를 잘 맺는 것은 늘 중요하다. </li>
<li>백엔드 공부도 조금씩 해보려는 것 : 이것은 잘한 것일지 아닐지는 모르겠지만 프론트엔드라는 영역에 갇히지 않으려고 계속 노력하는 모습이 스스로도 가상(?)하다. </li>
<li>문학회 홈페이지를 만들고 있다! 실제 사용할 프로젝트를 만들고 배운 것을 바로바로 적용하니 학습 효율이 좋다!!
<img src="https://images.velog.io/images/boram_in/post/ccca154f-e7e7-496a-b041-16e310599560/0126.gif" alt="">
<img src="https://images.velog.io/images/boram_in/post/48d91481-2308-4ee2-8d1e-905bc0dd0565/0124_2.gif" alt=""></li>
</ul>
<h3 id="아쉬운-점">아쉬운 점!</h3>
<ul>
<li>자바스크립트를 한 번은 다 봤지만 리더님이 말씀해줬던 것 처럼 주욱 보면 코드가 주루룩 나오는 그 경지는 아니다. 근데 더 큰 문제는 자바스크립트 공부를 편리한 리액트로 인해서 스르륵 미뤄둔다는 점이다. 루틴에 자바스크립트를 넣어서 기본기를 단단히 해야겠다. 
<img src="https://images.velog.io/images/boram_in/post/d00ac22f-6fb7-4eda-bd75-d43936f5b6bf/image.png" alt=""></li>
<li>Tailwind CSS 등 CSS 프레임워크를 공부하다보니 확 느낀게 CSS에 대한 감도 많이 잃어버렸다는 점. 특히나 html을 시멘틱하게 작성해야 하는데... div와 p로 가득가득해지고 있다. html 문서를 번역(?) 해보면서 html를 등한시 하지 말아야겠다. </li>
<li>WIL 작성을 ... 거의 하지 못했다. 루틴화 하면서 동시에 루틴에서 날아가버린... 회고. 다시 붙잡아야지. 안 그럼 기록 븟새가 엉엉 울지도 모른다. 기록하지 않으면 기억에도 남지 못한다..! </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[AWS Builders Online Series]]></title>
            <link>https://velog.io/@boram_in/AWS-Builders-Online-Series</link>
            <guid>https://velog.io/@boram_in/AWS-Builders-Online-Series</guid>
            <pubDate>Thu, 20 Jan 2022 10:58:31 GMT</pubDate>
            <description><![CDATA[<h1 id="아마존-혁신의-문화-amazon-culture-of-innovation">아마존 혁신의 문화: Amazon Culture of Innovation</h1>
<h2 id="아마존의-미션">아마존의 미션</h2>
<p><img src="https://images.velog.io/images/boram_in/post/de1fa14e-c74e-4bdb-b26a-a51bf175b2b4/image.png" alt="">
아마존은 기술 기업으로 알려져있지만 고객을 중심에 두고 해결책으로 기술을 사용할 뿐이다. 
<img src="https://images.velog.io/images/boram_in/post/2dabf2f5-cb74-4cb5-ad64-1859b967ff99/image.png" alt="">
제프 베조스가 아이템으로 책을 가장 먼저 선정한 이유는 만져보지 않아도 구매가 가능하며, 이와 동시에 썩지 않는 등 보관과 배송이 용이하다는 이유도 있었지만 가장 큰 이유는 단일 품목 중에서 가장 다양한 제품이 있었기 때문이다. 즉, 고객 중심적 사고의 결과였으며 이후에 아마존 킨들 역시 이러한 맥락 상에서 구매한 책을 바로 다운로드 받아서 볼 수 있도록 출시가 된 것이다. 
<img src="https://images.velog.io/images/boram_in/post/4c0c76f1-97ea-4b85-828f-a350f56fdeb5/image.png" alt="">
flywhell 다양한 선택지를 제공. 책에서 현재 자동차까지. 다양한 옵션을 제공하면 고객의 경험치가 높아진다. AWS도 1500개가 넘는 소프트웨어 기업이 7000 개가 넘는 소프트웨어 제공. 선순환을 이루면. 규모의 경제를 통해서 다시 원가 절감. VALUE PROVISION PRICE, SELECTION(선택지), CONVINIENCE </p>
<h3 id="culture">CULTURE</h3>
<p><img src="https://images.velog.io/images/boram_in/post/a70d80a7-fe19-4be3-97f8-91cb5e86bc89/image.png" alt="">
16개의 leadership principle. 전제조건이 있다. 전 직원이라는 가정하에 이 LP가 적용된다. 왜 필요했을까? 13년 전에 24,0000명 작년에는 145만명, 폭팔적으로 성장. 하나하나 지시가 불가능해진다. 하나의 거대 기업보다는 수천 개의 start-up을 지향. 지켜야만할 행동 강령을 주어 스스로 판단하고 자율적으로 행동할 수 있도록 한 것이 LP. 
<img src="https://images.velog.io/images/boram_in/post/1717b3e2-3c1d-46af-8ef6-9588088aa565/image.png" alt="">
이러한 LP는 채용 과정에서도 매우 중요하게 다뤄지며 승진과 인사고과 평가시에도 어떤 LP를 직접적으로 보여주었는가. 또한 커뮤니케이션과 회의 시에도 사용된다.</p>
<h4 id="invent-and-simplify">Invent and Simplify</h4>
<p><img src="https://images.velog.io/images/boram_in/post/49b26629-b39b-48b5-ac10-9f05ac13d29d/image.png" alt="">
무언가 아이디어를 냈을 때 사람들이 모두 고개를 끄덕이면 혁신보다는 그냥 개선의 아이디어일 확률이 높다. 혁신적인 아이디어라고 생각하면 오래 참고 견뎌라. AWS를 시작할 때도 여론은 비슷한 평가. 낮은 이익률로 인해서 주주들에 의해 많은 challenge가 있었다. 그러나 현재는 이익의 절반 이상의 가장 많은 기여를 하는 사업부. </p>
<h4 id="working-backwards-is-a-process">Working Backwards is a process</h4>
<p><img src="https://images.velog.io/images/boram_in/post/e33d75b6-c969-4b1d-98c8-22570a6bc1b9/image.png" alt="">
거의 모든 사업모델 상품, 서비스까지 모두 이를 적용. 초기 아이디어를 만드는 것부터 고객을 위한 것인지 파악하는 것.
<img src="https://images.velog.io/images/boram_in/post/6b297f21-176c-4d40-98e0-ce8438579ccd/image.png" alt=""></p>
<ul>
<li>who is the customer =&gt; 세그멘테이션보다 페르소나 단 한 사람을 정해서 집중해 서비스를 설계 </li>
<li>painpoint를 가지고 있고 우리가 어떻게 해결해 줄 수 있는가? </li>
<li>명확한 value proposition를 가지고 있는가? </li>
<li>사용케이스를 설명할 수 있어야 한다. </li>
</ul>
<p>이와 더불어, 스스로 보도자료와 FAQs를 작성해보면서 설계한 것에 대해서 한 번 더 점검한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/dc9c6895-88a2-41b6-bebe-7ab1d6e96274/image.png" alt=""></p>
<ul>
<li>65세의 캠핑카에 사는 가상의 인물 존을 설정하고 진행 </li>
<li>painpoint : 집이 없어서 배송을 친구의 집 혹은 비싼 값을 지붛하고 오프라인에서 구매 </li>
<li>편의성의 측면에서 매우 clear하게 해결한 사례 </li>
<li>가장 많은 사용자들은 현재 여행자 혹은 출장을 다니는 사람이 현재 최대 소비자가 되었다. </li>
</ul>
<h2 id="organization">organization</h2>
<h3 id="single-threaded-ownership">single threaded ownership</h3>
<p>한 팀이 오너십을 가지고 책임을 진다. 크던 작던 하나의 문제를 해결할 수 있는 단일 팀을 만들어야 한다. 
<img src="https://images.velog.io/images/boram_in/post/37cb5869-ede0-48e8-a23a-92fec6b8a495/image.png" alt="">
2004년 제프 베조스가 고안한 아이디어로. cross-functional한 사람들로 타이트하게 이뤄진다. R&amp;D와 운영이 분리되어 있으면 책임을 전가할 가능성이 높다. 같은 팀에 two-pizza로. 프로젝트가 커지면 다시 팀을 쪼개며, 민첩성을 유지하려고 노력. </p>
<h2 id="architecture">architecture</h2>
<h3 id="loosely-coupled-system">loosely coupled System</h3>
<p>상호 의존성을 낮추며 사업을 진행. 더 빠르게 scale up을 할 수 있도록. 
<img src="https://images.velog.io/images/boram_in/post/51fb8e2a-de64-42c6-a412-041ccc2515b6/image.png" alt="">
기존의 monolitic한 &#39;Primitive&#39;하게 수정하며 MSerA를 구현. 수많은 primitive들로 구성되어 있다. amazon.com 에서 검색, 상품 이미지, 추천 모두 별도의 어플리케이션으로 구성되어 있다. 이러한 아키텍처가 제공된 것이 또 aws cloud. 필요하다면 수 천 개의 컴퓨터를 제공해주기도 했다가 또 필요가 없을 시에는 반납을 할 수 있어 실패에 대한 비용을 낮출 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/399c9fe9-5bfa-4a11-9c36-b5ca1afd4f56/image.png" alt=""></p>
<hr/>

<h1 id="알아두면-쓸모-있는-ec2-이야기">알아두면 쓸모 있는 EC2 이야기</h1>
<p><img src="https://images.velog.io/images/boram_in/post/5f711d99-fd86-476f-b684-20d7378c43c7/image.png" alt="">
수백만명의 고객들이 AWS 컴퓨터 상에서 다양한 워크로드를 제공하고 있다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/bf8e3df1-2f86-4c83-8cd8-4109a833833b/image.png" alt=""></p>
<p>M1 방식만 존재했다. 그러나 2010에는 4개의 인스턴스가 만들어졌다. 현재는 OS 종류와 다양한 환경과 비즈니스 요구에 충족할 수 있도록 다양한 옵션이 존재한다. 애플리케이션 및 워크로드에 맞는 적합한 프로세서를 제공한다. 
<img src="https://images.velog.io/images/boram_in/post/8a7d00e0-0e35-4378-81df-2ec0c0c6bd71/image.png" alt=""></p>
<h2 id="amazon-ec2-수명주기">Amazon EC2 수명주기</h2>
<p><img src="https://images.velog.io/images/boram_in/post/2cae1914-57b6-4ab3-be81-c24dedef50e6/image.png" alt="">
수명주기 이해가 필요하다. EC2가 시작하는 순간부터 종료될 때까지 다양한 상태로 전환되기 때문이다. 또한 각 상태에서 요금의 발생과 각 상태에 따라 변경되는 부분이 있다. 처음 인스턴스를 구성하여 시작하면 pending 상태로 전환이 도고 시작 시 지정한 인스턴스 유형에 따라 호스트 컴퓨터의 하드웨어가 결정된다. 또한 구성에 따라 퍼블릭 IPv4를 할당 받고, running 상태로 전환된다. 이 상태부터는 비용이 청구되기 시작한다. </p>
<blockquote>
<p>여기서 중요한 부분은 2가지 정지 상태나 최대 절전모드에서 다시 running 상태로 전환 시 다시 pending 과정을 거치기 때문에 호스팅 컴퓨팅이나 public IPv4가 변경된다.</p>
</blockquote>
<ul>
<li>만약 IP가 유지되어야 한다면 탄력적 IP를 사용할 수 있으며 또 다른 하나는 EBS 볼륨을 사용해야지 데이터가 유지된다.</li>
<li>또 다른 볼륨 방식은 인스턴스 스트어 볼륨의 경우 stop 할 수 없고 데이터 유지가 어려우므로 이 점에 유의해야 한다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/e6e6d241-ebd0-46c9-8a80-b85c9dfa682f/image.png" alt=""></p>
<p>인스턴스의 사이즈에 대한 문의가 많다고! 그런데 인스턴스는 한 번에 최적의 타입을 선택하는 것이 아니라 계속해서 모니터링하며 서비스에 맞게 수정하며 최적화 하는 것. 위와 같이 표기법을 통해서 인스턴스 유형을 제공해준다.</p>
<p><img src="https://images.velog.io/images/boram_in/post/6ed3f19e-bc35-4bb9-b7a8-131ab88ff0d8/image.png" alt=""></p>
<p>auto scaling은 인스턴스의 자동 복구와 I/O 트래픽에 따라서 EC2 인스턴스의 수를 정해 놓은 용량만큼 자동으로 늘려주고 줄여주는 기능이다. 이를 통해서 월말 등 트래픽이 늘어 날 때 유연하게 대처할 수 있다. 다만 예측이 어려울 때는 더 호율적으로 해야할 필요성. 
<img src="https://images.velog.io/images/boram_in/post/551e5022-6dbb-4a5f-8558-be5d2d6d76d4/image.png" alt="">
이러한 니즈를 충족 시킬 수 있는 것이 EC2의 spot instance이다. 경매와 비슷한 방식을 통해서 온디맨드 인스턴스와 동일하게 작동. 그러나 EC2 pool로 용량이 회수되거나 기본 가격이 높아질 경우 인스턴스 중단이 발생한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/3d92e163-1d5c-4657-9469-50e1e225e4a0/image.png" alt="">
위는 워크로드에 따른 스팟 인스턴스 사용의 예이다. </p>
<h1 id="대규모-서비스를-위한-aws의-대표적인-nosql-database-서비스-알아보기">대규모 서비스를 위한 AWS의 대표적인 NoSQL Database 서비스 알아보기</h1>
<h2 id="관계형과-nosql-데이터-베이스">관계형과 NoSQL 데이터 베이스</h2>
<p><img src="https://images.velog.io/images/boram_in/post/c6ca002f-d627-4dee-9880-ed351ef0e65f/image.png" alt="">
2021년 12월 db-engines.com의 데이터베이스 인기순위 380개가 넘는 데이터 베이스 엔진이 등록되어 있고 top10에 3개의 NoSQL 데이터베이스가 있다. 점차 많은 애플리케이션에서 NoSQL을 채택해나가고 있음을 볼 수 있다. 2000년대 초반까지만 하더라도 우리가 서비스나 시스템을 만들 때 사용할 수 있는 데이터베이스의 종류는 많지 않았다. 그러나 4차 산업혁명과 더불어 다양한 프로그래밍 언어와 런타임이 생겨났고 데이터베이스 역시 매번 새롭게 등장하고 있다.</p>
<p>현재 관계형과 NoSQL 데이터베이스는 서로의 장점을 흡수하며 발전해나가고 있다. 대표적으로 관계형 데이터베이스 중 스키마에서 자유로운 JSON 데이터타입이라는 것을 볼 수 있고 확장성을 흡수해나가고 있으며 또한 NoSQL 데이터베이스들은 관계형 데이터베이스가 갖는 주요 특징인 트랜잭션과 보조 인덱스를 흡수하며 단점을 제거해나가고 있다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[리액트를 다루는 기술] 4장 이벤트 핸들링 ]]></title>
            <link>https://velog.io/@boram_in/%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EA%B8%B0%EC%88%A0-4%EC%9E%A5-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%ED%95%B8%EB%93%A4%EB%A7%81</link>
            <guid>https://velog.io/@boram_in/%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EA%B8%B0%EC%88%A0-4%EC%9E%A5-%EC%9D%B4%EB%B2%A4%ED%8A%B8-%ED%95%B8%EB%93%A4%EB%A7%81</guid>
            <pubDate>Wed, 19 Jan 2022 07:02:27 GMT</pubDate>
            <description><![CDATA[<h2 id="41-리액트의-이벤트-시스템">4.1 리액트의 이벤트 시스템</h2>
<p>사용법은 일반 HTML에서 이벤트를 작성하는 것과 비슷한데 주의해야할 몇 가지 사항이 있다.</p>
<h3 id="411-이벤트를-사용할-때-주의-사항">4.1.1 이벤트를 사용할 때 주의 사항</h3>
<ul>
<li><p><strong>1) 이벤트 이름은 카멜 표기법으로 작성한다</strong>
예를 들어 HTML의 onclick은 리액트에서는 onClick으로 작성해야 한다. 또 onkeyup은 onKeyUp으로 작성한다 </p>
</li>
<li><p><strong>2) 이벤트에 실행한 자바스크립트 코드를 전달하는 것이 아니라 함수 형태의 값을 전달한다</strong>
HTML에서 이벤트를 설정할 때는 큰 따옴표안에 실행할 코드를 넣었지만 리액트에서는 함수 형태 객체를 전달한다. 앞서 버튼 예제에서도 화살표 함수 문법으로 함수를 만들어 전달. 이렇게 만들어서 전달해도 되고 렌더링 부분 외부에 미리 만들어서 전달해도 된다. </p>
</li>
<li><p>** 3) DOM 요소에만 이벤트를 설정할 수 있다**
즉 dic, button, input, form, span 등의 DOM 요소에는 이벤트를 설정할 수 있지만 우리가 직접 만든 컴포넌트에는 이벤트를 자체적으로 설정할 수 없다. </p>
<pre><code>&lt;MyComponent onClick = {doSomething} /&gt;</code></pre><p>예를 들어, 다음과 같이 Mycomponent에 onClick값을 설정한다면 요것을 클릭할 때 doSomething 함수를 실행하는 것이 아니라 그냥 이름인 onClick인 props를 MyComponent에게 전달해줄 뿐이다. </p>
</li>
</ul>
<p>따라서 컴포넌트에 자체적으로 이벤트를 설정할 수 없다. 하지만 전달받은 props를 컴포넌트 내부의 DOM이벤트로 설정할 수는 있다.</p>
<pre><code>&lt;div onClick = {this.props.onClick}&gt;
    { ... }
&lt;/div&gt;</code></pre><hr/>

<h2 id="42-예제로-이벤트-핸들링-익히기">4.2 예제로 이벤트 핸들링 익히기</h2>
<p><img src="https://images.velog.io/images/boram_in/post/264fefe0-271a-4de8-afb5-33b4cbbc257a/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/boram_in/post/b078832d-19c9-4545-afab-3e0da48989a4/image.png" alt=""></p>
<h3 id="422-onchange-이벤트-핸들링하기">4.2.2 onChange 이벤트 핸들링하기</h3>
<h4 id="4221-onchange-이벤트-설정">4.2.2.1 onChange 이벤트 설정</h4>
<p>EvenPractice 컴포넌트에 input 요소를 렌더링하는 코드와 해당 요소에 onChange 이벤트를 설정하는 코드. </p>
<p><img src="https://images.velog.io/images/boram_in/post/bbf37bac-4485-4a88-9e82-34e6fa226fa4/image.png" alt=""></p>
<p>e의 객체는 synthethicEvent로 웹 브라우저의 네이티브 이벤트를 감싸는 객체. 네이티브 이벤트와 인터페이스가 같으므로 순수 자바스크리브에서 HTML 이벤트를 다룰 때와 똑같이 사용하면 된다. </p>
<p>syntheticEvnet는 네이티브 이벤트와 달리 이벤트가 끝나면 이벤트가 초기화되어서 정보를 참조할 수 없다. 만약 비동기적으로 이벤트 객체를 참조할 일이 있다면 e.persist()함수를 호출해줘야 한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/70dbe39b-0428-4de5-a2dd-c5f9c9e74ce3/image.png" alt=""></p>
<p>값이 바뀔 때마다 바뀌는 값을 콘솔에 기록한다. </p>
<hr/>

<h4 id="4222-state에-input-값-담기">4.2.2.2 state에 input 값 담기</h4>
<p>state 초기값을 설정하고 이벤트 핸들링 함수 내부에서 this.setState 메서드를 호출해 state를 업데이트! 
<img src="https://images.velog.io/images/boram_in/post/35d1dcd7-5036-4b0d-a33b-3d8d6de8b868/image.png" alt=""></p>
<h4 id="4223-버튼을-누를-때-comment-값을-공백으로-설정">4.2.2.3 버튼을 누를 때 comment 값을 공백으로 설정</h4>
<p><img src="https://images.velog.io/images/boram_in/post/6ed273c5-e341-46b6-91b7-a9e743f9ca89/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/9c202984-623e-4e42-9f54-7058f7487cf3/0119_!.gif" alt=""></p>
<hr></hr>

<h3 id="423-임의-메서드-만들기">4.2.3 임의 메서드 만들기</h3>
<p>이벤트를 처리할 때 렌더링을 하는 동시에 함수를 만들어서 전달해준다. 이 방법 대신 함수를 미리 준비해 전달하는 방법도 있다. 성능상 차이는 거의 없지만 가독성은 훨씬 좋다. </p>
<pre><code>import { Component } from &#39;react&#39;;</code></pre><p>이걸 할 때 자동완성 시에 가끔 ./react라고 될 때가 있는데 그럼 다음과 같은 에러가 난다. </p>
<pre><code>Module not found: Error: Can&#39;t resolve &#39;./react&#39; in ㅇㅇㅇㅇㅇ </code></pre><p><img src="https://images.velog.io/images/boram_in/post/3166c36b-7b2b-46c7-b1cc-fc394ab36c7d/image.png" alt=""></p>
<p>함수가 호출될 때 this는 호출부에 따라 결정되므로, 클래스의 임의의 메서드가 특정 HTML 요소의 이벤트로 등록되는 과정에서 메서드와 this의 관계가 끊어져 버린다. 이로 인해서 임의 메서드가 이벤트로 등록되어도 this를 컴포넌트 자신으로 제대로 가리키기 위해서는 메서드를 this와 바인딩하는 작업이 필요. 만약 바인딩하지 않으면 this가 undefined를 가리키게 된다. </p>
<h4 id="4232-property-initializer-syntax-를-사용한-메서드-작성">4.2.3.2 Property initializer Syntax 를 사용한 메서드 작성</h4>
<p>메서드 바인딩은 생성자 메서드에서 하는 것이 정석. 하지만 이 작업이 불편할 수도. 더 간단하게 하는 방법은 바벨의 transform - class - properties 문법을 사용해 화살표 함수로 메서드를 정의하는 것</p>
<p><img src="https://images.velog.io/images/boram_in/post/ced51308-b0f9-4bc0-b445-c266859ca0e7/image.png" alt=""></p>
<blockquote>
<p>훨씬 더 깔끔하다!</p>
</blockquote>
<h3 id="424-input-여러-개-다루기">4.2.4 input 여러 개 다루기</h3>
<p>import가 여러 개일 때 어떻게 작업할까? 메서드를 여러개 만들어야 하나?? 🙋 바로 event 객체를 활용하는 것. e.target.name 값을 사용하면 된다. onChange 이벤트 핸들러에서 e.target.name은 해당 인풋의 name을 가리킨다. 지금은 message. 이런 값을 사용해 state를 설정하면 쉽게 해결할 수 있다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/ce32090e-538e-476d-a13b-abff893f2f35/image.png" alt=""></p>
<ul>
<li>이렇게 위 메서드를 세팅해 놓고. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/f566ed01-94df-4e35-811b-f9737af609b0/image.png" alt=""></p>
<ul>
<li>밑에 렌더 부분은 이렇게 하면 된다.</li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/29b36cdf-f28c-462e-8c6c-3d0e2c6f574e/0119_2.gif" alt=""></p>
<p> 위에서 핵심 코드는 요것! </p>
<pre><code>handleChange = (event) =&gt; {
    this.setState({
     ⭐ [event.target.name]: event.target.value,⭐
    });
  };</code></pre><p>객체 안에서 key를 [ ]로 감싸면 그 안에 넣은 레퍼런스가 가리키는 실제 값이 key 값으로 사용된다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/df8b2163-7431-47f5-aa6e-b5fee554da41/image.png" alt=""></p>
<hr/> 

<h3 id="425-onkeypress-이벤트-핸들링">4.2.5 onKeyPress 이벤트 핸들링</h3>
<p><img src="https://images.velog.io/images/boram_in/post/7ab11024-5308-4c80-badc-f969158fb666/image.png" alt="">
공백이 아니라면 저렇게 된다. state는 초기값이다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/ea423977-5029-4804-bd12-931263d2531a/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/boram_in/post/d1c9aec0-9328-4b80-8cf1-1e6f6579eb99/0119_3.gif" alt=""></p>
<hr/>

<h2 id="43-함수-컴포넌트로-구현해보기">4.3 함수 컴포넌트로 구현해보기</h2>
<p>함수형 컴포넌트로 바꿔보자. 
<img src="https://images.velog.io/images/boram_in/post/33d52cb1-5712-4008-af10-1e1351033c0c/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/defb0377-6a2c-4fd5-adbd-f0fbaf3c9ae5/image.png" alt=""></p>
<blockquote>
<p>위 코드에서는 e.target.name을 활용하지 않고 onChange 함수 두 개를 따로 만들어 주었다. 인풋이 두 개 밖에 없다면 이런 코드도 나쁘지 않다. 그러나 인풋의 개수가 많아지면 e.target.name을 활용하는 것이 더 좋을 수 있다. </p>
</blockquote>
<p>아래 코드는 useState를 통해 사용하는 상태에 문자열이 아닌 객체를 넣어 보자. </p>
<p><img src="https://images.velog.io/images/boram_in/post/e07c11b5-b953-4775-a6df-04f288ac6f23/image.png" alt=""></p>
<p>e.target.name 값을 활용하려면 위와 같이 useState를 쓸 때 인풋 값이 들어 있는 form 객체를 사용해주면 된다. </p>
<hr/>

<h2 id="44-정리">4.4 정리</h2>
<p>리액트에서 이벤트를 다루는 것은 순수 자바스크립트 or 제이쿼리를 사용한 웹 어플리케이션에서 이벤트를 다루는 것과 비슷. 리액트의 장점 중 하나는 자바스크립트에 익숙하다면 쉽게 활용할 수 있다. 기존 HTML DOM event를 알고 있다면 리애그의 컴포넌트 이벤트도 쉽게 다룰 수 있다. </p>
<p>이 장에서 클래스형 컴포넌트도 구현, 함수 컴포넌트로도 구현. 클래스형 컴포넌트로 할 수 있는 대부분의 기능은 함수 컴포넌트로도 구현가능. 함수 컴포넌트에서 여러 개의 인풋 상태를 관리하기 위해 useState에서 form 객체를 사용했는데 이후에 useReducer와 커스텀 Hooks를 사용하면 훨씬 더 편하게 할 수도 있다. </p>
<hr/>

]]></description>
        </item>
        <item>
            <title><![CDATA[[스터디]실무와 가까워지는 Node.js 개발(1)]]></title>
            <link>https://velog.io/@boram_in/%EC%8B%A4%EB%AC%B4%EC%99%80-%EA%B0%80%EA%B9%8C%EC%9B%8C%EC%A7%80%EB%8A%94-Node.js-%EA%B0%9C%EB%B0%9C1</link>
            <guid>https://velog.io/@boram_in/%EC%8B%A4%EB%AC%B4%EC%99%80-%EA%B0%80%EA%B9%8C%EC%9B%8C%EC%A7%80%EB%8A%94-Node.js-%EA%B0%9C%EB%B0%9C1</guid>
            <pubDate>Wed, 19 Jan 2022 01:22:34 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 포스팅은 프로그래머스의 실무와 가까워지는 Node.js 백엔드 개발 (feat. TypeScript) 스터디 내용을 기반으로 작성 되었습니다. 
<a href="https://programmers.co.kr/learn/courses/13300">https://programmers.co.kr/learn/courses/13300</a></p>
</blockquote>
<h2 id="🙋-무엇을-왜-만드시나">🙋 무엇을, 왜 만드시나?</h2>
<p>우리는 스터디 동안 커피를 주문하는 서비스를 만들 예정이다. 실생활에서의 일반적인 커피 주문은 어렵지 않다. 사람이 많지 않기 때문에. 그러나 우리 팀에 50명 - 70명의 사람이 있고 이 주문을 한꺼번에 처리해야 한다고 생각해보자. 규칙은 간단하다. </p>
<ul>
<li>자신이 원하는 메뉴가 있으면 🤚 이모지를 클릭한다.</li>
<li>없으면 자신이 메뉴명을 적고 🤚 이미지를 클릭한다.</li>
</ul>
<p>그런데 생각보다 사람이 많아지다보면 규칙이 잘 지켜지지 않는다. &#39;아아&#39;, &#39;아이스아메&#39; &#39;차가운 아메리카노&#39; 등을 모두 같은 종류로 처리를 해야 한다. 그래서 리더님이 떠올린 해결책은 다음과 같은 중국집 등에서 자주 사용하는 주문서이었다. 
<img src="https://images.velog.io/images/boram_in/post/3c6edb80-65eb-402c-a007-e64f13284bb7/image.png" alt=""></p>
<blockquote>
<h4 id="🙋-근데-꼭-만들어야-하나">🙋 근데 꼭 만들어야 하나?</h4>
<p>&#39;엑셀로도 할 수 있는거 아니야...?&#39; 사실 스터디를 하기 전에 별로 생각을 안 해봤던 고민이다. 근데 이후에 개발을 하고 혼자서 프로젝트를 할 때 꼭 이 고민을 먼저 해봐야겠다. 이 고민을 하며 동시에 어떤 툴과 라이브러리 등을 사용할지까지 생각해볼 수 있기 때문이다. </p>
</blockquote>
<hr/>

<h2 id="관계형데이터베이스-vs-nosql">관계형데이터베이스 vs NoSQL</h2>
<h3 id="관계형-데이터베이스">관계형 데이터베이스</h3>
<p><img src="https://images.velog.io/images/boram_in/post/13328fa0-e958-44ce-89f6-164947fd17b1/image.png" alt=""></p>
<ul>
<li>요렇게 표처럼 데이터를 관리하는 것이 관계형데이터베이스(RDB)이다. 정형화되어 있어서 직관적으로 이해할 수 있으며, 나온지 오래 되었기 때문에 유지보수하기가 수월하다. 또한 SQL을 사용해서 원하는 데이터만 쿼리를 할 수 있다. </li>
</ul>
<h3 id="nosql">NoSQL</h3>
<p>NoSQL은 구조가 상대적으로 덜 빡빡하다. 예를 들면, 위에서 옵션으로 아이스가 필요해서 넣었지만 NoSQL에서는 필요 없으면 아예 이 부분을 넣지 않아도 된다. 그래서 수정하거나 큰 마이그레이션을 할 때 용이하다. 또한 아래의 그림처럼 Key - Value 형태로 데이터를 저장하기도 혹은 json 같은 문서 형식으로 데이터를 저장한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/246465e7-8b58-47bb-911f-f16e6be183a2/image.png" alt=""></p>
<hr/>

<h2 id="🔥🔥-파이어-스토어-🔥🔥">🔥🔥 파이어 스토어 🔥🔥</h2>
<p>우리의 프로젝트에서는? Firebase를 사용한다. 이로 인한 장점은 자바스크립트만으로 데이터 베이스를 활용 가능하고 작은 규모는 무료라는 점! 특히나 어드민을 별도로 설정하지 않아도 파이어베이스 콘솔에 접근해 GUI(graphical user interface,그래픽 사용자 인터페이스는 사용자가 편리하게 사용할 수 있도록 입출력 등의 기능을 알기 쉬운 아이콘 따위의 그래픽으로 나타낸로 편집이 가능하다)로 편집이 가능하다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/ba41dbd3-491c-4b40-8578-29bcb47dc1d6/image.png" alt=""></p>
<h3 id="🔥-컬렉션과-문서">🔥 컬렉션과 문서</h3>
<p><img src="https://images.velog.io/images/boram_in/post/e2040262-1791-417e-b590-b2894a14db3b/image.png" alt="">
파이어스토어를 이해하기 위해서는 컬렉션과 문서(document)를 이해해야 한다. 쉽게 비유하면, 파일철이 컬렉션이고 데이터가 문서 안에 막 들어가있다. 현실 세계에서 일어날 수 없는 일이 일어난다. 파일철 안에 파일철을 넣는 것처럼 컬렉션 안에 컬렉션이 있는 nesting 구조가 나타난다. 
<img src="https://images.velog.io/images/boram_in/post/223c8da6-0424-4fff-a9ba-853396b83b18/image.png" alt=""></p>
<h3 id="🔥-일단-사용해봅시다">🔥 일단 사용해봅시다!</h3>
<p><img src="https://images.velog.io/images/boram_in/post/ada82a22-494d-4b4a-9660-322b22c13511/0119.gif" alt="">
콘솔에 들어가서 죠렇게 3가지 단계를 거쳐서 빌드를 해주면돈다. 이름이 겹치면 뒤에 해시를 자동으로 붙여준다. </p>
<h4 id="🔥-비공개-키-파일-생성">🔥 비공개 키 파일 생성</h4>
<p><img src="https://images.velog.io/images/boram_in/post/7cd8c2c2-8aa5-4592-a9b3-7ead14e6ea85/image.png" alt="">
서비스 계정을 통해서 비공개 키를 생성할 수 있다. 이후에 사용을 해야 하므로 어딘가에 저장을 해두자! </p>
<h4 id="🔥-인증-구현하기">🔥 인증 구현하기</h4>
<p><img src="https://images.velog.io/images/boram_in/post/5a256c4e-a9f8-4a97-a4d0-d00ddc12ee9d/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/4372c512-e50b-4daf-bb03-db145cee4880/image.png" alt="">
authentication으로 들어간 뒤 시작하기를 클릭. 이후에 구글을 눌러서 사용 설정을 한 뒤에 저장을 누르자! </p>
<h4 id="🔥-클라우드-파이어스토어-설정">🔥 클라우드 파이어스토어 설정</h4>
<p><img src="https://images.velog.io/images/boram_in/post/f5391648-54e1-4d5b-95cc-21744eaf52f9/image.png" alt="">
처음에는 테스트 모드로 시작해보자. 룰이 가볍기 때문에. 이후에 위치는 north-east-3로 만들면 리전이 서울이다. 그러면 조금 시간이 걸린 후에 프로비저닝을 한다. </p>
<h4 id="🔥-환경설정해주기">🔥 환경설정해주기!</h4>
<p>.env 파일을 만들어주자. </p>
<pre><code>privateKey={privateKey}
publicApiKey={apiKey}
clientEmail={clientEmail}
projectId={projectId}
databaseurl=https://{projectId}.firebaseio.com
FIREBASE_AUTH_HOST={authDomain}
PORT=4001
HOST=localhost
PROTOCOL=http</code></pre><p>위에서 다운 받은 두 개의 파일에서 찾아서 갈아 끼우면 된다. <strong>중.괄.호 남기면 안 된다!</strong></p>
<hr/>

<h2 id="서버와-http">서버와 HTTP</h2>
<h3 id="서버가-하는-일">서버가 하는 일</h3>
<p>식당에서 접객원의 server와 동일하다. 
<img src="https://images.velog.io/images/boram_in/post/81f1fc40-3276-41b4-bf8a-4884d51458cb/image.png" alt="">
Client(손님)의 경우에는 계속해서 요청을 보낸다. 예를 들면, 고르곤졸라 피자주세요~ 이렇게 하면 서버가 요 주문을 주방에 전달하고 음식이 완성되면 고객에게 전달된다. </p>
<blockquote>
<p><strong>마이크로 서비스 아키텍처는 여의도 진주집!</strong> 위에 서버는 세분화 되지 않아서 결제까지 모두 다 다담당하지만 진주집 같은 곳은 크기 때문에 김치만, 물만, 주문만 담당하는 분들이 따로 있다. 마이크로 서비스는 그렇게 세분화되어 있는 것! 추가적으로 더 공부해보자! </p>
</blockquote>
<hr>

<h3 id="http-살펴보기">HTTP 살펴보기</h3>
<p>웹서비스는 HTTP를 통해서 요청을 받는다. </p>
<pre><code>GET / HTTP/2
Host: www.google.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:89.0) Gecko/20100101 Firefox/89.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: ko-KR,ko;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1</code></pre><h4 id="스타트-라인">스타트 라인</h4>
<pre><code>GET / HTTP/2</code></pre><p>위 내용이 Start Line이다. GET, POST, PUT, DELETE 같은 메서드가 제일 먼저 위치하고 그 뒤에 어디로 요청을 보내는지 특정하는 Path가 위치합니다. 마지막으로 프로토콜 버전이 명시된다.</p>
<p>또한 패스는 쿼리 파라미터를 가질 수 있다. 얘는 가장 뒤에 물음표 기호를 넣고 시작한다. </p>
<pre><code>/users?id=123</code></pre><p>위 예시에서 쿼리 파라미터는 ?id=123이다. 2개 이상이 있다면 &amp; 기호로 연결해서 표현한다. </p>
<pre><code>/users?id=123&amp;name=test</code></pre><h4 id="헤더">헤더</h4>
<p>위 요청에서는 Start Line을 제외한 모든게 헤더이며 일반적으로 많이 쓰는건 Host, User-Agent, Accept 등의 필드</p>
<h4 id="blank-line과-body">Blank Line과 Body</h4>
<p>헤더 뒤에 Blank Line이 위치하면 그 뒤에 Body(바디)가 있다는 뜻. Body에는 주로 사용자가 제공해야하는 정보를 담는 역할을 합니다. 예를 들어 아이디(ID), 비밀번호를 입력해서 로그인을 하려고 한다면 해당 내용은 Body에 담긴다. 이미지를 포스팅하면 이미지도! HTTP는 곤충처럼 start line - Header - Body로 나뉘지만 곤충과 달리 body 부분이 없어도 전송된다. </p>
<hr/> 
]]></description>
        </item>
        <item>
            <title><![CDATA[[리액트를 다루는 기술] 3장 컴포넌트 ]]></title>
            <link>https://velog.io/@boram_in/%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EA%B8%B0%EC%88%A0-3%EC%9E%A5-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8</link>
            <guid>https://velog.io/@boram_in/%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EA%B8%B0%EC%88%A0-3%EC%9E%A5-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8</guid>
            <pubDate>Tue, 18 Jan 2022 12:22:11 GMT</pubDate>
            <description><![CDATA[<h1 id="3장-컴포넌트">3장 컴포넌트</h1>
<p>컴포넌트의 기능은 단순한 템플릿 이상. 데이터가 주어졌을 때 이에 맞추어 UI를 만들어 주는 것은 물론이고 라이프사이클 API를 이용하여 컴포넌트가 화면에서 나타날 때, 사라질 때 변화가 일어날 때 주어진 작업들을 처리할 수 있으며, 임의 메서드를 만들어 특별한 기능을 붙여줄 수 있다. </p>
<h2 id="31-클래스형-컴포넌트">3.1 클래스형 컴포넌트</h2>
<p>이전에는 함수형 컴포넌트를 봤었다. 컴포넌트를 선언하는 방식은 크게 두 가지. 하나는 하수 컴포넌트이고 또 다른 하나는 클래스형 컴포넌트이다. 
<img src="https://images.velog.io/images/boram_in/post/39a258ac-64dd-4856-bb63-49a8b6ca8f06/image.png" alt=""></p>
<blockquote>
<h4 id="클래스형-vs-함수형-컴포넌트">클래스형 vs 함수형 컴포넌트</h4>
<p><strong>[클래스형]</strong></p>
</blockquote>
<ul>
<li>state 기능 </li>
<li>라이프 사이클 기능 사용 가능 </li>
<li>임의의 메서드 정의 가능 </li>
</ul>
<p><strong>🙋 그럼 어느 상황에서 무엇을 사용할까? 🙋</strong>
함수 컴포넌트의 장점을 나열해보면 </p>
<ul>
<li>1) 선언하기가 훨씬 편하며</li>
<li>2) 메모리 자원도 클래스형 컴포넌트보다 덜 사용한다 </li>
<li>3) 배포할 때도 함수 컴포넌트를 사용하는 것이 파일 크기가 더 작다 </li>
</ul>
<p>주요한 단점은 ** state ** 와 ** 라이프사이클 API **의 사용이 불가능하다는 점. 그러나 이후에 v16.8 업데이트 이후 Hooks라는 기능이 도입되면서 해결되었다. 공식 메뉴얼에서 컴포넌트를 작성 시 함수 컴포넌트와 Hooks를 사용하도록 권장하고 있다. </p>
<h2 id="32-첫-컴포넌트-생성">3.2 첫 컴포넌트 생성</h2>
<p>첫 번째 컴포넌트를 만들어보잣! </p>
<h3 id="321-src-디렉터리에-mycomponentjs-파일-생성">3.2.1 src 디렉터리에 MyComponent.js 파일 생성</h3>
<p>컴포넌트를 만들려면 컴포넌트 코드를 선언해야 한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/719eeb82-0a41-4e88-afc4-b48492aca924/image.png" alt="">
요렇게 파일을 하나 만들어주자 </p>
<h3 id="322-코드-작성하기">3.2.2 코드 작성하기</h3>
<p><img src="https://images.velog.io/images/boram_in/post/2ee9a3b7-8f6a-487f-800e-0fbd870eff54/image.png" alt="">
화살표 문법을 통해서 생성. 함수형 컴포넌트를 선언 시 function 키워드를 사용하는 것과 화살표 함수를 사용하는 것은 큰 차이 없음. 화살표 함수가 좀 더 간결하기 때문에 사용. </p>
<h3 id="323-모듈-내보내기-및-불러오기">3.2.3 모듈 내보내기 및 불러오기</h3>
<h4 id="3231-모듈-내보내기">3.2.3.1 모듈 내보내기</h4>
<pre><code>export default Mycomponent;
</code></pre><p>이 코드는 다른 파일을 import할 때, 위에서 선언한 Mycomponent 클래스를 불러오도록 설정한다.</p>
<h4 id="3232-모듈-불러오기">3.2.3.2 모듈 불러오기</h4>
<p>이번에는 App 컴포넌트에서 Mycomponent 컴포넌트를 불러와서 사용해보자. 
<img src="https://images.velog.io/images/boram_in/post/f8cadb7d-92d6-4bc5-a597-f5f94a4b416b/image.png" alt=""></p>
<hr/>


<h2 id="33-props">3.3 props</h2>
<p>매일 프랍프랍?해서 몰랐지만 properties를 줄인 표현으로 컴포넌트의 속성을 설정할 때 사용하는 요소. props 값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서 설정할 수 있다.</p>
<hr/>

<h3 id="331-jsx-내부에서-props-렌더링">3.3.1 JSX 내부에서 props 렌더링</h3>
<p>props를 렌더링할 때 2장에서 배운 것처럼 JSX 내부에서 { } 기호로 감싸주면 된다! </p>
<p><img src="https://images.velog.io/images/boram_in/post/6f4d3a8f-c9e6-4901-af68-96e7d8bc6983/image.png" alt=""></p>
<hr/>

<h3 id="332-컴포넌트를-사용할-때-props-값-지정하기">3.3.2 컴포넌트를 사용할 때 props 값 지정하기</h3>
<p><img src="https://images.velog.io/images/boram_in/post/989c2c7f-99bd-44ce-814c-c26de46a2bc6/image.png" alt=""></p>
<ul>
<li>MyComponent의 props 값을 요렇게 지정할 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/a3036c33-2559-4432-bb1c-01dbe248d1a9/image.png" alt=""></li>
<li>요렇게 잘 표시된 것을 확인할 수 있다 </li>
</ul>
<hr/>

<h3 id="333-props-기본값-설정--defaultprops">3.3.3 props 기본값 설정 : defaultProps</h3>
<p><img src="https://images.velog.io/images/boram_in/post/65b1cba8-4211-4f9b-8bf2-c3d8eddafae1/image.png" alt="">
위와 같이 name의 값을 지정해주지 않으면 &quot;안녕, 제 이름은&quot;으로만 나온다. 그러므로 지정을 하지 않았을 때 보여줄 기본값을 설정하는 defaultProps를 알아보자. 
<img src="https://images.velog.io/images/boram_in/post/30c24080-f7bb-4a5d-a79c-2d157cef8347/image.png" alt=""></p>
<ul>
<li>Mycomponent로 돌아가서 위와 같이 작업해주면 된다! 
<img src="https://images.velog.io/images/boram_in/post/3ba44826-7521-4709-ae31-5d022de7a614/image.png" alt=""></li>
</ul>
<hr/>

<h3 id="334-태그-사이의-내용을-보여주는-children">3.3.4 태그 사이의 내용을 보여주는 Children</h3>
<p>리액트 컴포넌트를 사용할 때 컴포넌트 태그 사이의 내용을 보여주는 props가 있는데 바로 children이다. 
<img src="https://images.velog.io/images/boram_in/post/981a018f-1b68-44b1-9e08-d2365af6ac08/image.png" alt="">
위 코드에서 MyComponent 태그 사이에 작성한 문다열을 보여주려면 props.children 값을 보여주어야 한다. 
<img src="https://images.velog.io/images/boram_in/post/1a976d4b-f813-49d9-a511-f69fcf02d488/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/a9c2949d-de0a-4640-8195-1d6414939812/image.png" alt=""></p>
<blockquote>
<p>주의! 현재 MyComponent에서 작업하고 있다는 것을 까먹지 말자! app.js에서만 바꾸고 이게 왜 안 되지 하지 말고! 감싼 태그를 우선 살펴봐!!! </p>
</blockquote>
<h3 id="335-비구조화-할당-문법을-통해-props-내부-값-추출하기">3.3.5 비구조화 할당 문법을 통해 props 내부 값 추출하기</h3>
<p>현재 MyComponent에서 props 값을 조회할 때마다 props.name, props.children과 같이 props. 이라는 키워들르 앞에 붙여주고 있다. 이러한 작업을 더 편하게 하기 위해 ES6의 비구조화 할당 문법을 사용해 내부 값을 바로 추출하는 방법을 알아보자! </p>
<p><img src="https://images.velog.io/images/boram_in/post/53a746ff-d5f7-4ac9-b0bf-34b346eebf2f/image.png" alt=""></p>
<p>요렇게 const {ㅇ, ㅅ } = props 처럼 작성해주면 더 짧은 코드로 사용할 수 있으며, *<em>이렇게 객체에서 값을 추출하는 문법을 비구조화 할당(destructuring assignment)이라고 부른다. *</em>함수의 파라미터에서도 사용할 수 있으며 파라미터가 객체라면 그 값을 바로 비구조화해서 사용하는 것! 
<img src="https://images.velog.io/images/boram_in/post/ccda6a7b-9e56-45bf-8a9a-f25baf9a5459/image.png" alt="">
요렇게 props를 사용할 때 파라미터 부분에서 비구조화 할당 문법을 사용할 수 있다!! </p>
<hr/> 

<h3 id="336-proptypes를-통한-props-검증">3.3.6 propTypes를 통한 props 검증</h3>
<p>컴포넌트의 필수 props를 지정하거나 props의 타입을 지정할 때는 propTypes를 사용한다. 컴포넌트의 propTypes를 지정하는 방법은 defaultProp을 설정하는 것과 유사. 
<img src="https://images.velog.io/images/boram_in/post/f96f7a87-46a8-42ef-aec3-8b6c2c2c46e9/image.png" alt="">
이렇게 설정해주면 name 값은 무조건 문자열 현태로 전달해줘야 된다는 것을 의미한다. 값이 나타나기는 했지만 콘솔에는 경고 메세지를 출력해 경고를 출력한다. </p>
<h4 id="3361-isrequired를-사용해서-필수-proptypes-설정">3.3.6.1 isRequired를 사용해서 필수 propTypes 설정</h4>
<p>propTypes를 지정하지 않았을 때 경고 메세지를 띄워주는 작업을 해보자! propTypes를 지정할 때 뒤에 isRequired를 붙여주면 된다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/0633a42a-52b1-4aea-b98c-fbd89c2c52fc/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/07637a02-eb47-47b9-ada4-bc897f0bd782/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/ea60f4ff-ca30-49c7-83c5-bf31ad1a2c22/image.png" alt=""></p>
<hr/>

<h3 id="337-클래스형-컴포넌트에서-props-사용하기">3.3.7 클래스형 컴포넌트에서 props 사용하기</h3>
<p><img src="https://images.velog.io/images/boram_in/post/241c611d-e0a9-434c-90f3-3f482465723e/image.png" alt=""></p>
<blockquote>
<p>default와 propTypes는 필수는 아님! 그러나 프로젝트가 커질수록, 협업을 할 때 해당 컴포넌트가 어떤 props가 필요하진 쉽게 알 수 있어 능률이 올라갈 수 있다! </p>
</blockquote>
<hr/>

<h2 id="34-state">3.4 state</h2>
<p>리액트에서 state는 컴포넌트 내부에서 바뀔 수 있는 값. props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이며, 컴포넌트 자신은 해당 props를 읽기 전용으로만 사용할 수 있다. props를 바꾸려면 부모 컴포넌트에서 바꿔줘야 한다. </p>
<ul>
<li>예를 들면, 위에서 App 컴포넌트에서 MyComponent를 사용할 때 props를 바꿔 주어야 값이 변경될 수 있다. </li>
<li>반면 MyComponent에서는 전달 받은 name 값을 직접 바꿀 수 없다. </li>
</ul>
<p>🙆‍♀️ <strong>리액트에는 두 가지 종류의 state가 존재한다.</strong></p>
<ul>
<li>하나는 클래스형 컴포넌트가 지니고 있는 state이고 </li>
<li>다른 하나는 함수 컴포너느에서 useState라는 함수를 통해 사용하는 state</li>
</ul>
<h3 id="341-클래스형-컴포넌트의-state">3.4.1 클래스형 컴포넌트의 state</h3>
<p><img src="https://images.velog.io/images/boram_in/post/72b7d60f-3838-4299-8238-43f52539ca12/image.png" alt=""></p>
<p>위 파일에서 각 코드가 어떤 역할을 하는지 알아보자. 컴포넌트에 state를 설정할 때는 다음과 같이 constructor 메서드를 작성하여 설정한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/082130e4-f8e6-45bd-9e47-e8ad7c899858/image.png" alt=""></p>
<ul>
<li>컴포넌트의 생성자 메서드. 클래스형 컴포넌트에서 constructor를 작성할 때는 반드시 super(props)를 호출해주어야 한다. </li>
<li>이 함수가 호출되면 현재 클래스형 컴포넌트가 상속받고 있는 리액트의 Component 클래스가 지닌 생성자 함수를 호출해 준다. </li>
<li>그 다음 this.state 값에 초깃값을 설정. 컴포넌트의 state는 객체 형식이어야 한다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/c2108fd2-5eb7-4eec-b3c7-878c58d7743e/image.png" alt=""></p>
<ul>
<li>render 함수에서 현재 state를 조회할 때 this.state를 조회하면 된다. 그리고 button 안에 onClick이라는 값을 props로 넣어줌</li>
<li>이는 버튼이 클릭될 때 호출시킬 함수를 설정할 수 있게 해준다. </li>
<li>이를 이벤트를 설정한다고 이야기하며 화살표 함수 문법을 사용하여 넣어주어야 한다. 함수 내부에서는 this.setState라는 함수를 사용함. 이 함수가 state의 값을 바꿀 수 있게 해준다 </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/2ffe3fc9-1fa1-45a4-9ed1-b607c16768b2/image.png" alt=""></p>
<h4 id="3411-state-객체-안에-여러-값이-있을-때">3.4.1.1 state 객체 안에 여러 값이 있을 때</h4>
<p>state 객체 안에는 여러 값이 있을 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/2ec5496a-b0dd-46bf-ac0e-0710c2922ba0/image.png" alt="">
현재 state 안에 fixedNumber라는 또 다른 값을 추가. 버튼이 클릭될 때 fixedNumber 값은 그대로 두고 number 값만 변화. this.setState 함수는 인자로 전달된 객체 안에 들어 있는 값만 바꿔준다. 
<img src="https://images.velog.io/images/boram_in/post/452df6ab-d761-4cdd-a51f-6f6682d7c569/image.png" alt=""></p>
<h4 id="3412-state를-constructor에서-꺼내기">3.4.1.2 state를 constructor에서 꺼내기</h4>
<p>앞에서 state의 초깃삾을 지정하기 위해 constructor 메서드를 선언해줬다. 또 다른 방법으로 state를 지정해줄 수도 있다. 
<img src="https://images.velog.io/images/boram_in/post/d8d5036a-8aa8-41a7-bb19-df32160641e9/image.png" alt=""></p>
<p>이렇게 하면 constructor 메서드를 선언하지 않고도 state 초깃값을 설정할 수 있다! </p>
<hr/>

<h4 id="3413-thissetstate에-객체-대신-함수-인자-전달하기">3.4.1.3 this.setState에 객체 대신 함수 인자 전달하기</h4>
<p>this.setState를 사용하여 state 값을 업데이트할 때는 상태가 비동적으로 업데이트된다. 
<img src="https://images.velog.io/images/boram_in/post/885bcb1c-ef5c-4c67-8965-3b9e6fc66da1/image.png" alt="">
요렇게 두 번 호출하면 어떻게 될까? this.setState를 두 번 사용하는 것임에도 불구하고 버튼을 클릭할 때 1씩만 더해진다. this.setState를 사용한다고 해서 state 값이 바로 바뀌지 않기 때문이다. </p>
<blockquote>
<h5 id="해결책">해결책</h5>
<p>this.setState를 사용할 객체 대신에 함수를 인자로 넣어 주는 것. this.setState의 인자로 함수를 넣어 줄 때는 코드를 다음과 같은 형식으로 작성한다. 
<img src="https://images.velog.io/images/boram_in/post/3486c361-4bc0-4e8b-b545-b400095a3458/image.png" alt="">
여기서 prevState는 기존 상태이고, props는 현재 지니고 있는 props를 가리킨다. 만약 업데이트하는 과정에서 props가 필요하지 않으면 생략해도 된다. </p>
</blockquote>
<p><img src="https://images.velog.io/images/boram_in/post/00e65599-5751-4b89-9d6c-2006b03c5a59/image.png" alt=""></p>
<p>화살표 함수에서 값을 바로 반환하고 싶다면 코드 블록 {} 을 생략하면 된다. 예를 들어, 파라미터 a와 b를 받아와서 합을 구해 주는 함수를 작성하고 싶다면 다음과 같이 작성할 수 있다. </p>
<pre><code>
const sum = (a,b) =&gt; a + b; </code></pre><h4 id="3414-thissetstate가-끝난-후-특정-작업-실행하기">3.4.1.4 this.setState가 끝난 후 특정 작업 실행하기</h4>
<p>setState를 사용하여 값을 업데이트하고 난 다음에 특정 작업을 하고 싶을 때는 setState의 두 번째 파라미터로 콜백(callback)함수를 등록하여 작업을 처리할 수 있다. </p>
<hr/> 


<h3 id="342-함수-컴포넌트에서-usestate-사용하기">3.4.2 함수 컴포넌트에서 useState 사용하기</h3>
<p>리액트 16.8 이전에서는 함수 컴포넌트에서 state를 사용할 수 없었다. 그러나 16.8 이후부터는 useState라는 함수를 사요앟여 함수 컴포넌트에서도 state를 사용할 수 있게 되었다. 사용법은 조금 다르다! 이 과정에서 Hooks가 등장! </p>
<h4 id="3422-usestate-사용하기">3.4.2.2 useState 사용하기</h4>
<p>배열 비구조화를 알면 useState 사용이 쉽다. 
<img src="https://images.velog.io/images/boram_in/post/f117dad4-9e6c-4aa6-b842-9ff80ddccd53/image.png" alt="">
useState 함수의 인자에는 상태의 초기값을 넣어준다. 클래스형 커포넌트에서의 state 초깃값은 객체 형태를 넣어줘야 했지만 useState에서는 반드시 객체가 아니어도 상관 없다. 값의 형태는 자유. </p>
<p>함수를 호출하면 배열이 반환된다. 배열의 첫 번째 원소는 현재 상태이고 두 번째 원소는 상태를 바꾸어주는 함수. 이 함수를 세터(Setter)함수라고 부른다. 그리고 배열 비구조화 할당을 통해 이름을 자유롭게 정해줄 수 있다. 현재 message와 setMessage라고 이름을 설정해주었는디 text와 setText라고 이름을 바꿔줘도 된다. </p>
<h2 id="35-state를-사용할-때-주의-사항">3.5 state를 사용할 때 주의 사항</h2>
<p>클래스형 컴포넌트, 함수 컴포넌트든 state를 사용할 때는 주의해야 할 사항이 있다. state 값을 바꿔야 할 때는 setState 혹은 useState를 통해 전달 받은 세터 함수를 사용해야 한다. 
<img src="https://images.velog.io/images/boram_in/post/1d948cdd-f597-4c03-bb9a-b7d5e84ac796/image.png" alt="">
요것은 잘못된 코드이다. 배열이나 객체를 업데이트할 때는 배열이나 객체 사본을 만들고 그 사본에 값을 업데이트 한 후, 그 사본의 상태를 setState 혹은 세터 함수를 통해 업데이트 한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/aec0f951-01d9-4bf0-982f-a63be9abdef1/image.png" alt=""></p>
<hr/> 

<h2 id="36-정리">3.6 정리</h2>
<p>props와 state는 둘 다 컴포넌트에서 사용하거나 렌더링할 데이터를 담고 있으므로 비슷해 보일 수 있다. </p>
<ul>
<li>props는 부모 컴포넌트가 설정</li>
<li>state는 컴포넌트가 자체적으로 지닌 값으로 컴포넌트 내부에서 값을 업데이트 할 수 있다 </li>
</ul>
<p>props를 사용한다고 해서 값이 무조건 고정적이지 않다. 부모 컴포넌트의 state를 자식 컴포넌트의 props로 전달하고 =&gt; 자식 컴포넌트에서 특정 이벤트가 발생할 때 부모 컴포넌트의 메서드를 호출하면 props도 유동적으로 사용할 수 있다. 이후 만들어 볼 일정 관리 애플리케이션에서 이러한 구조로 프로젝트를 설계하게 된다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[리액트를 다루는 기술] 1장 리액트 시작 & 2장 JSX]]></title>
            <link>https://velog.io/@boram_in/%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EA%B8%B0%EC%88%A0-1%EC%9E%A5-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%8B%9C%EC%9E%91</link>
            <guid>https://velog.io/@boram_in/%EB%A6%AC%EC%95%A1%ED%8A%B8%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EA%B8%B0%EC%88%A0-1%EC%9E%A5-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%8B%9C%EC%9E%91</guid>
            <pubDate>Mon, 17 Jan 2022 03:39:58 GMT</pubDate>
            <description><![CDATA[<h1 id="1장-리액트-시작">1장 리액트 시작</h1>
<p><img src="https://images.velog.io/images/boram_in/post/6723f10b-74ab-42dc-b5a7-06020d704ad0/image.png" alt=""></p>
<h2 id="11-왜-리액트인가">1.1 왜 리액트인가?</h2>
<ul>
<li>이전의 프레임워크들은 주로 MVC(Model-View-Controller) 아키텍처, MVVM(Modle-View-View Model) 아키텍처를 사용. 앵귤러의 경우 MVW아키텍처로 애플리케이션을 구조화</li>
<li>여러 구조가 가진 공통점은 모델과 뷰가 있다는 것. </li>
<li>모델은 애플리케이션에서 사용하는 데이터를 관리하는 영역</li>
<li>뷰는 사용자에게 보이는 부분</li>
<li>프로그램이 사용자에게서 어떤 작업을 받으면 컨트롤러는 모델 데이터를 조회하거나 수정하고 변경된 사항을 뷰에 반영한다</li>
</ul>
<p>페이스북 개발팀은 한 가지 아이디어를 고안해냈는데 그냥 기존의 뷰를 날려버리고 처음부터 새로 렌더링 하는 방식. 이로 이해서 구조가 매우 간단하고 작성해야할 코드양도 많이 줄었다. </p>
<hr/>

<h3 id="111-리액트-이해">1.1.1 리액트 이해</h3>
<p><strong>리액트는 자바스크립트의 라이브러리</strong>로 사용자 인터페이스를 만드는데 사용한다. 구조가 MVC, MVW 등인 프레임워크와 달리** 오직 V(View)만 신경 쓰는 라이브러리. **</p>
<ul>
<li>컴포넌트 : 리액트 플젝 중 특정 부분이 어떻게 생길지 정하는 선언체. </li>
<li>템플릿 : 데이터셋이 주어지면 HTML 태그 형식을 문자열로 변환</li>
</ul>
<p>컴포넌트는 재사용이 가능한 API로 수많은 기능을 내장하고 있으며 컴포넌트 하나에서 해당 컴포넌트의 생김새와 작동 방식을 정의한다.</p>
<h3 id="1111-초기-렌더링">1.1.1.1 초기 렌더링</h3>
<p>사용자의 화면에서 뷰를 보여주는 것을 렌더링이라고 한다. 맨 처음에 어떻게 보일지 정하는 초기 렌더링이 필요. 이를 다루는 render 함수가 있다. </p>
<pre><code>render() {}</code></pre><p>얘는 컴포넌트가 어떻게 생겼는지 정의한다. 뷰가 어떻게 생겼고 어떻게 작동하는지에 대한 정보를 지닌 객체를 반환. </p>
<blockquote>
<p>컴포넌트 내부에 또 다른 컴포넌트들이 들어갈 수 있다. 이 때 render 함수를 실행하면 그 내부에 있는 컴포넌트들이 재귀적으로 렌더링. </p>
</blockquote>
<p>최상위 컴포넌트의 렌더링 작업이 끝나면 지니고 있는 정보들을 사용해 HTML 마크업을 만들고 우리가 정하는 실제 페이지의 DOM요소 안에 주입. </p>
<h3 id="1112-조화-과정">1.1.1.2 조화 과정</h3>
<p>컴포넌트에서 데이터에 변화가 있을 때 뷰가 변형되는 것처럼 보이지만 실제로는 새로운 요소로 갈아 끼우는 것. 이 작업 또한 render 함수가 맡아서 한다. 객체를 반환하므로 단순히 업데이트 값을 수정하는 것이 아니라 <strong>새로운 데이터를 가지고 render 함수를 또 다시 호출 ➡️ 데이터를 가진 뷰를 생성. ** 하지만 이 때 render 함수가 반환하는 결과를 곧바로 DOM에 반영하지 않고 이전에 render 함수가 만들었던 컴포넌트 정보와 혀내 render 함수가 만든 컴포넌트 정보를 비교. 자바스크립트를 이용해</strong> 두 가지 뷰를 최소한의 연산으로 비교한 후, 둘의 차이를 알아내 최소한의 연산으로 DOM 트리를 업데이트 **</p>
<HR/>

<h1 id="12-리액트의-특징">1.2 리액트의 특징</h1>
<h2 id="121-virtual-dom">1.2.1 Virtual DOM</h2>
<p>리액트의 주요 특징 중 하나는 Virtual DOM을 사용하는 것. DOM에는 치명적인 한 가지 문제점. 바로 동적 UI에 최적화되어 있지 않다는 것. DOM 자체는 빠르다. 단, 웹 브라우저 단에서 DOM에 변화가 일어나면 웹 브라우저가 CSS를 다시 연산, 레이아웃을 구성, 페이지를 리페인트하는 과정이 오래걸리는 것이다. </p>
<h3 id="해결법">해결법</h3>
<p>DOM을 최소한으로 조작하여 작업을 처리하는 방식으로 개선할 수 있따. 리액트는 Virtual DOM 방식을 사용해 DOM 업데이트를 추상화하여 DOM 처리 횟수를 최소화하고 효율적으로 진행한다.</p>
<h3 id="1212-virtual-dom">1.2.1.2 Virtual DOM</h3>
<p>실제 DOM에 접근해 조작하는 대신 추상화한 자바스크립트 객체를 구성하여 사용. 실제 DOM의 가벼운 사본처럼. 리액트에서 데이터가 변해 웹 브라우저에 실제 DOM을 업데이트할 때는 다음 세가지 절차를 밟는다. </p>
<blockquote>
<p>*<em>1) 데이터를 업데이트하면 전체 UI를 Virtual DOM에 리렌더링한다. 
2) 이전 Virtual DOM에 있떤 내용과 현재 내용을 비교한다 
3) 바뀐 부분만 실제 DOM에 적용한다 *</em></p>
</blockquote>
<h3 id="오해">오해</h3>
<p>virtual DOM을 사용한다고해서 사용하지 않을 때에 비해 무조건 빨라지지 않는다. 리액트 매뉴얼에서는 *<em>지속적으로 데이터가 변화하는 대규모 애플리케이션 구축하기 *</em> 라는 문장이 있다. virtual DOM이 언제나 제공할 수 있는 것은 바로 업데이트 처리 간결성. UI를 업데이트 하는 과정에서 생기는 복잡함을 모두 해소하고 더욱 쉽게 업데이트에 접근할 수 있다. </p>
<HR/>

<h2 id="122-기타-특징">1.2.2 기타 특징</h2>
<p>리액트는 오직 뷰만 담당. 리액트는 라이브러리여서 다른 웹 프레임 워크가 Ajax, 데이터 모델링, 라우팅과 같은 기능을 내장하는 반면 기타 기능을 직접 구현해 사용해야 한다. </p>
<ul>
<li>라우팅 : react- router</li>
<li>Ajax : axios, fetch </li>
<li>상태관리 : redux, MobX </li>
</ul>
<p>등을 사용한다. 자신의 취향대로 스택을 설정할 수 있다는 장점과 여러 라이브러리를 접해야 하는 단점이 존재. 
<img src="https://images.velog.io/images/boram_in/post/524647b9-ca17-4f9e-bcd4-7bc3339bdb6a/image.png" alt=""></p>
<pre><code>You are running `create-react-app` 4.0.3, which is behind the latest release (5.0.0).

We no longer support global installation of Create React App.</code></pre><p>위와 같은 오류가 났다! 리액트가 오랜만이라고 인사해주는 정도의 에러다 </p>
<blockquote>
<p>다음과 같이 해결해줄 수 있었다.</p>
</blockquote>
<ol>
<li>npm uninstall -g create-react-app</li>
<li>npm add create-react-app</li>
<li>npx create-react-app myapp</li>
</ol>
<HR/>

<h1 id="2장-jsx">2장 JSX</h1>
<h1 id="21-코드-이해하기">2.1 코드 이해하기</h1>
<pre><code>import logo from &#39;./logo.svg&#39;;
import &#39;./App.css&#39;;</code></pre><ul>
<li>여기서  import 구문이 사용됐다. 특정 파일을 불러오는 것. 이렇게 모듈을 불러와서 사용하는 거은 원래 브라우저에는 없던 기능으로 Node.js에서 지원하는 기능.</li>
<li>🙋** 웹팩이라고 들어보셨나?** : 이러한 기능을 브라우저에서도 사용하기 위해 번들러(bundler)를 사용한다. 파일읅 묶듯이 연결하는 것을 번들러 도구를 사용하면 import로 모듈을 불러왔을 때 불러온 모듈을 모두 합쳐 하나의 파일로 생성해준다. </li>
<li>웨팩을 사용하면 SVG 파일과 CSS 파일도 불러와서 사용할 수 있따. 이렇게 파일을 불러오는 것은 웹팩의 로더(loader)라는 기능이 담당. </li>
<li>babel-loader는 자바스크립트 파일들을 불러오면서 최신 자바스크립트 문법으로 작성된 코드를 바벨이라는 도구를 사용해 ES5 문법으로 변환해준다 </li>
</ul>
<blockquote>
<p>왜 변환할까? </p>
</blockquote>
<ul>
<li>구버전 웹 브라우저와 호환하기 위해서 </li>
<li>리액트 컴포넌트에서 사용하는 JSX라는 문법도 정식 자바스크립트 문법이 아니므로ES5 형태로 변환해야 한다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/427d3ad9-39d4-43f9-a61d-9455c82a385e/image.png" alt="">
이 코드는 APP이라는 컴포넌트를 만든다. function 키워드를 상요해 컴포넌트를 만들었기에 함수 컴포넌트라고 부른다. 프로젝트에서 렌더링하면 함수에서 반환하고 있는 내용을 나타낸다. 마치 HTML같은데 이런 코드를 JSX라고 부른다 </p>
<HR/>

<h2 id="22-jsx란">2.2 jsx란?</h2>
<p><img src="https://images.velog.io/images/boram_in/post/c1fb5f7e-f778-48c7-9fe6-ae2d64a1fe97/image.png" alt="">
위와 같은 JSX 코드는 다음과 같이 변환된다. 
<img src="https://images.velog.io/images/boram_in/post/f1e279d2-bb1b-46c1-89a3-3deef615c3db/image.png" alt="">
어휴 불편해! JSX를 사용하면 매우 편하게 UI를 렌더링 할 수 있다. </p>
<HR/>

<h2 id="23-jsx의-장점">2.3 JSX의 장점</h2>
<h3 id="231-보기-쉽고-익숙하다">2.3.1 보기 쉽고 익숙하다</h3>
<p>JSX를 쓰는 것이 더 편하고 가독성도 높다. 결국 HTML 코드를 작성하는 것과 비슷하므로. </p>
<h3 id="232-더욱-높은-활용도">2.3.2 더욱 높은 활용도</h3>
<p>알고 있는 div, span 같은 HTML 태그를 사용할 수 있을 뿐만 아니라 앞으로 만들 컴포넌트도 JSX 안에서 작성할 수 있다. </p>
<h2 id="24-jsx-문법">2.4 JSX 문법</h2>
<h3 id="241-감싸인-요소">2.4.1 감싸인 요소</h3>
<p>컴포넌트에 여러 요소가 있다면 반드시 부모 요소 하나로 감싸야 한다. 
<img src="https://images.velog.io/images/boram_in/post/3a4a8af2-5166-489e-bb21-8a31fa86a0c8/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/bc0a5177-3b82-475d-a9bf-c489a577a69b/image.png" alt="">
위와 같은 이유는 Virtual DOM에서 컴포넌트 변화를 감지해 낼 때 효율적으로 비교할 수 있도록 컴포넌트 내부는 하나의 DOM 트리 구조로 이뤄져야 한다는 규칙 때문</p>
<p><img src="https://images.velog.io/images/boram_in/post/55ac0e8e-4856-45fc-bdfe-2c9221921bf3/image.png" alt="">
꼭 div를 사용해야 하는 것은 아니고 v16 이상부터 도입된 Fragement라는 기능을 사용해도 된다. Fragment는 다음과 같은 형태로도 표현될 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/8d0bb298-8895-46bc-8b0c-01afd03773a9/image.png" alt=""></p>
<h3 id="242-자바스크립트-표현">2.4.2 자바스크립트 표현</h3>
<p>JSX가 단순히 DOM요소를 렌더링하는 기능만 가진 것이 아니라 자바스크립트 표현식을 쓸 수 있다. 자바스크립트 표현식을 작성하려면 코드를 {  } 로 감싸면 된다. 
<img src="https://images.velog.io/images/boram_in/post/0069e25b-df78-43e1-a662-0285cf85394a/image.png" alt=""></p>
<h3 id="243-if문-대신-조건부-연산자">2.4.3 if문 대신 조건부 연산자</h3>
<p>JSX 내부에서는 if문 사용 불가. 삼항 연산자를 사용해서 표현한다. 
<img src="https://images.velog.io/images/boram_in/post/632d6025-0a71-4b2d-9b97-8446929966b4/image.png" alt=""></p>
<h3 id="244-and-연산자를-사용한-조건부-렌더링">2.4.4 AND 연산자를 사용한 조건부 렌더링</h3>
<p>특정 조건을 만족할 때만 페이지를 보여주는 것! 
<img src="https://images.velog.io/images/boram_in/post/890a310f-9f7c-49ea-9adc-066155da0bf9/image.png" alt=""></p>
<ul>
<li>null을 위처럼 렌더링하면 아무것도 보여주지 않는다 이것을 &amp;&amp;를 사용해서 더 짧은 코드로 작업할 수 있다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/49358ef0-f76e-45a3-bed5-34e46b82091f/image.png" alt=""></p>
<ul>
<li>&amp;&amp; 연산자로 조건부 렌더링을 할 수 있는 이유는 리액트에서 false를 렌더링 시 null과 마찬가지로 아무것도 나타나지 않기 때문이다. 근데 주의해야 할 것은 falsy한 값인 0은 화면에 나타난다는 점!</li>
</ul>
<blockquote>
<h4 id="🙋-jsx-는-언제-괄호로감싸야-하나">🙋 JSX 는 언제 괄호로감싸야 하나?</h4>
<p>주로 JSX를 여러 줄로 작성할 때 괄호로 감싸고, 한 줄로 표현할 수 있으면 감싸지 않는다. 필수사항은 아니다! </p>
</blockquote>
<h3 id="245-undefined를-렌더링하지-않기">2.4.5 undefined를 렌더링하지 않기</h3>
<p>리액트 컴포넌트에서는 함수에서 undefined만 반환하여 렌더링 하는 상황을 만들면 안 된다. 예를 들어 다음과 같은 코드는 에러를 유발한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/7dc338e4-2f5f-4b2c-903b-1887153a0af7/image.png" alt=""></p>
<ul>
<li>어떤 값이 undefined일 수도 있다면 OR(||)연산자를 사용해 값을 지정할 수 있으므로 간단히 오류를 방지할 수 있다 
<img src="https://images.velog.io/images/boram_in/post/7bb63683-1efb-4940-9eac-f1466d9563dd/image.png" alt=""></li>
<li>반면 JSX 내부에서 undefined를 렌더링하는 것은 괜찮다 
<img src="https://images.velog.io/images/boram_in/post/f054ea9d-e0f8-47df-9bc6-61da883dc47c/image.png" alt=""></li>
</ul>
<p>name이 undefined일 때 보여주고 싶은 값이 있으면 위와 동일하게 {name || &#39;보람&#39;} 처럼 작성</p>
<hr>

<h3 id="246-인라인-스타일링">2.4.6 인라인 스타일링</h3>
<p>DOM에 스타일을 적용 시에 문자열 형태로 넣는 것이 아니라 객체 혀애로 넣어줘야 한다. 그리고 - 대신 camelCase로 작성해야 한다 
<img src="https://images.velog.io/images/boram_in/post/a6e37376-3397-46ee-937e-6eb1b58790c4/image.png" alt=""></p>
<ul>
<li>여는 &lt;div ㅇㅇㅇ&gt; 에서 ㅇㅇㅇ 부터 스타일을 인라인으로 작업해주면된다. 
<img src="https://images.velog.io/images/boram_in/post/73055753-5f90-4595-9a2c-e68481bdf85e/image.png" alt=""></li>
<li>npm start를 해주면 위와 같이 뽀짝한 리액트가 만들어져 있다. </li>
</ul>
<hr/>

<h3 id="247-class대신-classname">2.4.7 class대신 className</h3>
<p><img src="https://images.velog.io/images/boram_in/post/fc9977c3-6493-4bf1-9412-94f1368da9c7/image.png" alt=""></p>
<p>JSX를 작성할 때 CSS 클래스를 설정하는 과정에서 className이 아닌 class 값을 성정해도 스타일이 적용되기는 하지만 경고가 나타난다. 
<img src="https://images.velog.io/images/boram_in/post/fb95efed-ad0a-4898-b519-5e2b23a5a051/image.png" alt=""></p>
<hr/>

<h3 id="248-꼭-닫아야-하는-태그">2.4.8 꼭 닫아야 하는 태그</h3>
<p>HTML 에서는 input을 닫지 않아도 오류가 발생하지 않지만 JSX에서는 닫지 않으면 오류가 발생한다. 태그 사이에 별도의 내용이 들어가지 않는 경우에는 다음과 같이 작성할 수도. 이러한 태그를 self-closing 태그라고 부른다. 태그를 선언하면서 동시에 닫을 수 있는 태그. 
<img src="https://images.velog.io/images/boram_in/post/74f9bf91-c05a-4849-8b80-2328f30f4446/image.png" alt=""></p>
<h3 id="249-주석">2.4.9 주석</h3>
<p><img src="https://images.velog.io/images/boram_in/post/af299534-cc11-4330-8ac8-41ebf79a11c5/image.png" alt="">
주석을 작성할 때는  </p>
<pre><code>  { /* 주석은 이렇게 작성한다 */}</code></pre><p>기존의 // 혹은 /* 과 같은 주석은 페이지에 고스란히 나타난다. 
<img src="https://images.velog.io/images/boram_in/post/caeff4ec-5bdd-4761-a5da-42ab3e2db4ab/image.png" alt=""></p>
<hr/>

<h2 id="25-eslint와-prettier-적용하기">2.5 ESLint와 Prettier 적용하기</h2>
<h3 id="251-eslint">2.5.1 ESLint</h3>
<p>문법도구 </p>
<h3 id="252-prettier">2.5.2 Prettier</h3>
<p>들여쓰기가 제대로 되어 있지 않은 코드는 매우 읽기 힘들다. VScode에서 f1을 누르고 format이라고 입력한 다음 Enter을 누르면 된다! 만약 Beautify를 설치했다면 충돌이 발생할 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/54708ffa-c0f6-4fd1-9206-b3efeeebd181/image.png" alt=""></p>
<p>루트 디렉터리에서. prettierrc라는 파일을 생성하고 위 내용을 입력하면 적용이 된다! </p>
<h4 id="2521-저장할-때-자동으로-코드-정리하기">2.5.2.1 저장할 때 자동으로 코드 정리하기</h4>
<p>매번 이렇게 f1 + format은 불편하다. 
<img src="https://images.velog.io/images/boram_in/post/6e5ab046-d937-4c12-a463-14af2dc95ff4/image.png" alt=""></p>
<p>format on save를 검색하여 나타나는 체크 박스에 체크하면 된다. 이제부터 저장할 때마다 코드가 자동으로 정리된다. </p>
<hr/>
]]></description>
        </item>
        <item>
            <title><![CDATA[[타입스크립트 프로그래밍] 3장 타입의 모든 것]]></title>
            <link>https://velog.io/@boram_in/%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-3%EC%9E%A5-%ED%83%80%EC%9E%85%EC%9D%98-%EB%AA%A8%EB%93%A0-%EA%B2%83</link>
            <guid>https://velog.io/@boram_in/%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-3%EC%9E%A5-%ED%83%80%EC%9E%85%EC%9D%98-%EB%AA%A8%EB%93%A0-%EA%B2%83</guid>
            <pubDate>Sat, 15 Jan 2022 12:28:24 GMT</pubDate>
            <description><![CDATA[<h2 id="329-휴식-시간--타입-별칭-유니온-인터섹션">3.2.9 휴식 시간 : 타입 별칭, 유니온, 인터섹션</h2>
<h4 id="타입-별칭">타입 별칭</h4>
<p>(let, const, var로) 변수를 선언해서 값 대신 변수로 칭하듯 타입 별칭으로 타입을 가리킬 수 있다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/21c2bb97-2033-4dac-8a48-d7e75c5b8cfc/image.png" alt=""></p>
<p>Age는 number다. 타입 별칭을 이용하면 Person의 형태를 조금 더 이해하기 쉽게 정의할 수 있다. <strong>타입스크립트는 별칭을 추론하지는 않으므로 반드시 별칭의 타입을 명시적으로 정의해야 한다.</strong>
<img src="https://images.velog.io/images/boram_in/post/f62c84a3-e229-4678-bb25-86ce13324f78/image.png" alt=""></p>
<p>Age는 number의 별칭이므로 number에도 할당할 수 있다. 따라서 코드를 다음처럼 바꿀 수 있다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/ec4a3940-1074-4b3a-91e2-b36363a0d674/image.png" alt=""></p>
<p>타입 별칭은 프로그램의 논리에 영향을 미치지 않고 별칭이 가리키는 타입으로 대치할 수 있다. 자바스크립트 변수 선언과 마찬가지로 하나의 타입을 두 번 정의할 수는 없다. </p>
<p>타입 별칭은 복잡한 타입을 DRY(Don&#39;t Repeat Yourself)하지 않도록 해주며 변수가 어떤 목적으로 사용되었는지 쉽게 이해할 수 있게 도와준다. </p>
<hr/>

<h3 id="유니온과-인터섹션-타입">유니온과 인터섹션 타입</h3>
<ul>
<li>유니온: 둘을 합친(A나 B에 해당한는 전부) 결과가 나온다 </li>
<li>인터섹션: 둘의 공통부분(A,B 모두에 속하는 것)이 결과로 나온다 </li>
</ul>
<p>타입스크립트는 타입에 적용할 수 있는 특별한 연산자인 유니온(|)과 인터섹션(&amp;)을 제공한다. 타입은 집합과 비슷하므로 집합처럼 연산을 수행할 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/79aec3b2-e062-4766-97f0-9cd821c92e2d/image.png" alt=""></p>
<ul>
<li>CatOrDog가 있다면 어떤 사실을 알 수 있을까? 문자열 타입의 name 프로퍼티가 있다는 사실을 알 수 있다. </li>
<li>CatOrDog에 무엇을 할당할 수 있을까? cat, dog 둘 다 할당할 수 있다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/ddfc530e-1a3f-45dd-a2d6-4c9ee52700f9/image.png" alt=""></p>
<p>유니온 타입(|)에 사용된 값이 꼭 유니온을 구성하는 타입 중 하나일 필요는 없으며 양쪽 모두에 속할 수 있다. 그러면 CatAndDog과 관련해서 무엇을 알고 있는가? 얘는 name, purr, bark, wag 모두 가능하다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/428da19e-ca85-4f6a-90c1-4477a08c266c/image.png" alt=""></p>
<p>실전에서는 대개 인터섹션보다 유니온을 자주 사용한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/fe273a54-b554-4674-b2c9-7bc56c239de9/image.png" alt=""></p>
<p>이 함수는 어떤 타입의 값을 반환할까? string 또는 null을 반환할 수 있다. 이를 다음처럼 표현할 수 있다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/e7a2d859-b575-45cf-b177-9d4256552c02/image.png" alt="">
조건이 참이면 반환 타임은 string이고 그렇지 않으면 number. 즉 string | number를 반환한다. </p>
<hr>

<h3 id="3210-배열">3.2.10 배열</h3>
<p>자바스크립트처럼 타입스크립트 배열도 연결(concatenation), 푸시(pushing), 검색, 슬라이스 등을 지원하는 특별한 객체. 타입스크립트는 T[]와 Array 라는 두 가지 배열 문법을 지원한다. 성능, 의미상 두 표현은 같다. </p>
<p>대개는 배열을 동형으로 만든다. 즉 한 배열에 사과, 오렌지, 숫자를 함께 저장하지 않고 배열의 모든 항목이 같은 타입을 갖도록 설계하려 노력한다. 그렇지 않으면 타입스크립트에 배열과 관련한 작업이 안전한지 증명해야 하므로 추가 작업을 해야 한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/89c5d6c0-3c31-41c7-bbda-722850dc8f5b/image.png" alt=""></p>
<ul>
<li>위 예제를 보면 왜 동형 처리가 쉬운지 확인가능.</li>
<li>배열을 문자열 &#39;red&#39;로 초기화. 이제 타입스크립트는 문자열 값을 갖는 배열이라고 추론.</li>
<li>그리고 &#39;blue&#39;를 배열에 추가하는데 &#39;blue&#39;는 문자열이므로 아무 문제 없이 ㄱㄴ. 그러나 다시 true로 추가하려하면 에라가 발생. true는 문자열이 아니기 때문이다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/272e0d31-aaef-4535-bbb8-3515bb3269d5/image.png" alt=""></p>
<ul>
<li>반면 myArry_2는 초기화하며 number와 string을 저장했으므로 타입스크립트는 number | string으로 추론한다. <ul>
<li>각 요소는 숫자와 문자열 중 한 가지일 수 있으므로 요소를 사용하기 전에 확인해야 한다.</li>
</ul>
</li>
</ul>
<p>객체와 마찬가지로 배열을 const로 만들어도 타입스크립트는 배열의 요소 타입을 알 수 없으므로 any일 것으로 추측한다. 배열을 조작하여 요소를 추가하면 타입스크립트가 주어진 정보를 이용해 배열의 타입을 추론한다. <img src="https://images.velog.io/images/boram_in/post/26718e30-ef58-4e0d-9a14-a378aee85b99/image.png" alt=""></p>
<p>  이처럼 상황을 쉽게 만드는 any가 있으므로 너무 복잡해할 필요는 없다. </p>
<h3 id="3211-튜플">3.2.11 튜플</h3>
<p>튜플은 배열의 서브타입이다. 튜플은 길이가 고정되었고 각 인덱스의 타입이 알려진 배열의 일종이다. 다른 타입과 달리 튜플은 선언 시 타입을 명시해야 한다. 자바스크립트에서 배열과 튜플에 같은 문법을 사용하는데 타입스크립트에서는 대괄호를 배열 타입으로 추론하기 때문. </p>
<h3 id="3212-null-undefined-void-never">3.2.12 null, undefined, void, never</h3>
<ul>
<li>자바스크립트는 null, undefined 두 가지 값으로 부재를 표현. 타입스크립트도 두 가지 모두 지원.<ul>
<li>undefined : 아직 정의하지 않았음을 의미 </li>
<li>null : 값이 없다(값을 계산하려면 에러가 발생) </li>
<li>void : 명시적으로 아무것도 반환하지 않는 함수의 반환 타입 (console.log)</li>
<li>never : 절대 반환하지 않는 함수 타입(예외, 영원히 실행되는 함수) </li>
</ul>
</li>
</ul>
<h3 id="3213-열거형">3.2.13 열거형</h3>
<p>해당 타입으로 사용할 수 있는 값을 열거하는 기법. 열거형은 키를 값에 할당하는, 순서가 없는 자료구조. 키가 컴파일 타임에 고정된 객체로 특정 값(상수)들의 집합을 의미.</p>
<pre><code> enum Avengers { Capt, IronMan, Thor }
let hero: Avengers = Avengers.Capt;
</code></pre><p>이넘은 인덱스 번호로도 접근할 수 있다.</p>
<pre><code>enum Avengers { Capt, IronMan, Thor }
let hero: Avengers = Avengers[0];
</code></pre><p>만약 원한다면 이넘의 인덱스를 사용자 편의로 변경하여 사용할 수도 있다.</p>
<pre><code>enum Avengers { Capt = 2, IronMan, Thor }
let hero: Avengers = Avengers[2]; // Capt
let hero: Avengers = Avengers[4]; // Thor
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[타입스크립트 프로그래밍] 1장 & 2장 ]]></title>
            <link>https://velog.io/@boram_in/%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-1%EC%9E%A5-2%EC%9E%A5</link>
            <guid>https://velog.io/@boram_in/%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-1%EC%9E%A5-2%EC%9E%A5</guid>
            <pubDate>Sat, 15 Jan 2022 10:33:18 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="🙋-why-typescript">🙋 why typescript?</h3>
<p>자바스크립트는 언제 실수를 알려주나? 바로 프로그램을 실행할 때다. 타입스크립트가 에러를 알려준다는 사실 자체보다 더 훌륭한 것은 에러를 알려주는 시점. 개발자가 텍스트 편집기에 코드를 입력하는 순간 곧바로 에러 메세지를 발생시킨다. </p>
</blockquote>
<h1 id="2장-타입스크립트-상공에서-내려보기">2장 타입스크립트: 상공에서 내려보기</h1>
<h2 id="21-컴파일러">2.1 컴파일러</h2>
<p>프로그램은 프로그래머가 작성한 다수의 텍스트 파일로 구성.
이 텍스트를 컴파일러라는 특별한 프로그램이 파싱하여 추상 문법 트리(abstract syntax tree, AST)라는 자료구조로 변환 ➡️ AST는 공백, 주석을 완전히 무시한다 ➡️ 그리고 컴파일러는 다시 AST를 바이트코드라는 하위 수준의 표현으로 변환 ➡️ 바이트 코드가 만들어졌으면 런타임(runtime)이라는 다른 프로그램에 바이트코드를 입력해 평가하고 결과를 얻을 수 있다.</p>
<blockquote>
<p>즉 프로그램을 실행한다는 것은 컴파일러가 소스 코드를 파싱해 AST로 만들고 다시 AST를 바이트 코드로 변환한 것을 런타임이 평가하도록 지시하는 것. </p>
</blockquote>
<ul>
<li>타입스크립트가 다른 언어와 다른 점 : 컴파일러가 코드를 바이트코드 대신 자바스크립트 코드로 변환.</li>
<li>🙋 코드 안정성은 언제? : 타입스크립트 컴파일러는 AST를 만들어 결과 코드를 내놓기 전에 타입 확인을 거친다. </li>
</ul>
<blockquote>
<h3 id="타입스크립트-컴파일-및-실행">타입스크립트 컴파일 및 실행</h3>
<p><strong>TS</strong></p>
</blockquote>
<ol>
<li>타입스크립트 소스 ➡️ 타입스크립트 AST</li>
<li>타입검사기가 AST를 확인 </li>
<li>타입스크립트 AST ➡️ 자바스크립트 소스 </li>
</ol>
<p>** JS **
4. 자바스크립트 소스 ➡️ 자바스크립트 AST
5. AST ➡️ 바이트코드 
6. 런타임이 바이트코드를 평가 </p>
<p>1<del>3은 TSC가 수행하며, 과정 4</del>6은 브라우저, NodeJS, 기타 자바스크립트 엔진과 같은 런타임이 실행한다. 1~1의 과정에는 소스 코드에 사용된 타입을 이용하지만 과정 3에서는 이용하지 않는다. 다시 말해, TSC가 타입스크립트 코드를 자바스크립트 코드로 컴파일 할 때 타입확인 ❌.</p>
<p>개발자가 기입한 타입 정보는 최종적인 프로그램에는 아무런 영향을 주지 않으며 타입 확인에만 사용된다. </p>
<blockquote>
<h3 id="typechecker">typechecker</h3>
<p>코드의 타입 안정성을 검증하는 특별한 프로그램 </p>
</blockquote>
<HR/>

<h2 id="22-타입-시스템">2.2 타입 시스템</h2>
<p>최신 언어는 저마다의 타입 시스템을 갖추고 있다. </p>
<blockquote>
<h3 id="타입-시스템type-system">타입 시스템(type system)</h3>
<p>타입 검사기가 프로그램에 할당하는 데 사용하는 규칙 집합 </p>
</blockquote>
<p>타입 시스템은 보통 두 가지 종류, 즉 어떤 타임을 사용하는지를 컴파일러에 명시적으로 알려주는 타입 시스템과 자동으로 타입으로 추론하는 타입 시스템으로 구분된다. 타입스크립트는 두 가지 시스템 모두의 영향을 받았다. 즉, 개발자는 타입을 명시하거나 타입스크립트가 추론하도록 하는 방식 중에서 선택할 수 있다. </p>
<p>어노테이션을 이용하면 타입스크립트에 명시적으로 타입을 지정. 어노테이션은 &#39;value:type&#39; 형태로 쓰이며 타입 검사기에 알려주는 역할! 
<img src="https://images.velog.io/images/boram_in/post/28bd13f2-6d39-47bc-9995-36de7034ee67/image.png" alt=""></p>
<p>어노테이션을 사용하지 않으면 타입스크립트가 알아서 타입을 추론한다. 생각보다 잘함! </p>
<p><img src="https://images.velog.io/images/boram_in/post/076c847e-d8be-4b89-8c15-1a6da30d923c/image.png" alt=""></p>
<blockquote>
<p>타입스크립트가 타입을 추론하도록 두는 것이 코드를 줄일 수 있는 방법이므로 보통 어노테이션은 생략한다. </p>
</blockquote>
<hr/>

<h3 id="221-타입스크립트-vs-자바스크립트">2.2.1 타입스크립트 vs 자바스크립트</h3>
<h4 id="자바스크립트와-타입스크립트의-타입-시스템-비교">자바스크립트와 타입스크립트의 타입 시스템 비교</h4>
<table>
<thead>
<tr>
<th>타입 시스템 기능</th>
<th>자바스크립트</th>
<th>타입스크립트</th>
</tr>
</thead>
<tbody><tr>
<td>타입 결정 방식</td>
<td>동적</td>
<td>정적</td>
</tr>
<tr>
<td>타입이 자동으로 변환되는가?</td>
<td>O</td>
<td>X(대부분)</td>
</tr>
<tr>
<td>언제 타입을 확인하는가?</td>
<td>런타임</td>
<td>컴파일 타임</td>
</tr>
<tr>
<td>언제 에러를 검출하는가?</td>
<td>런타임(대부분)</td>
<td>컴파일 타임(대부분)</td>
</tr>
</tbody></table>
<h4 id="타입은-어떻게-결정되는가">타입은 어떻게 결정되는가?</h4>
<p><strong>동적 타입 바인딩이란 프로그램을 실행해야만 특정 데이터 타입을 알 수 있음을 의미</strong>. 자바스크립트는 프로그램을 실행하기 전에는 타입을 알 수 없다.(무수한console.log의 기억) ⭐** 타입스크립트는 점진적으로 타입을 확인하는(gradually typed) 언어**⭐ 타입스크립트는 타입을 지정하지 않은 프로그램이라도 그중 일부 타입을 추론해 오류를 검출할 수 있지만 모든 타입을 알지 못하는 상황에서는 많은 오류가 노출될 수 있다.</p>
<h4 id="자동으로-타입이-변환되는가">자동으로 타입이 변환되는가?</h4>
<p>자바스크립트는 약한 타입 언어. 그래서 개발자의 의도를 최대한 알아내려 노력하고 결과를 도출. 반면 타입스크립트는 유효하지 않은 작업을 발견하면 바로 에러. 
<img src="https://images.velog.io/images/boram_in/post/d6683849-7228-4e9d-a5c8-bfd4de76754d/image.png" alt=""></p>
<h4 id="언제-타입을-검사하는가">언제 타입을 검사하는가?</h4>
<p>컴파일 타임에 코드의 타입을 확인하기에 코드를 실행하지 않고도 이전 예제 코드에 에러가 있음을 바로 알 수 있다. </p>
<h4 id="에러는-언제-검출되는가">에러는 언제 검출되는가?</h4>
<p>자바스크립트는 런타임에 예외를 던지거나 암묵적 형변환 수행. 타입스크립트는 컴파일 타임에 문법 에러와 타입에러를 모두 검출. 그러나 스택 오버플로, 네트워크 등 하지 못하는 에러도 존재한다. </p>
<hr/>

<h2 id="23-코드-편집기-설정">2.3 코드 편집기 설정</h2>
<pre><code># TSC, TSLint, NodeJS용 타입 선언 설치
npm install --save-dev typescript tslint @types/node</code></pre><h3 id="231-tsconfigjson">2.3.1 tsconfig.json</h3>
<p>모든 타입스크립트 프로젝트 루트 디렉터리에 tsconfig.json파일이 존재해야 한다. 타입스크립트 프로젝트에서 어떤 파일을 컴파일하고 어떤 자바스크립트 버전으로 방출하는지를 정의. 
<img src="https://images.velog.io/images/boram_in/post/5d39b6c8-f0a0-4aa5-8824-bbba6b4c271d/image.png" alt=""></p>
<table>
<thead>
<tr>
<th align="center">옵션</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">include</td>
<td align="center">TSC가 타입스크립트 파일을 찾을 디렉터리</td>
</tr>
<tr>
<td align="center">lib</td>
<td align="center">TSC가 코드 실행환경에서 이용할 수 있다고 가정하는 API</td>
</tr>
<tr>
<td align="center">module</td>
<td align="center">TSC가 코드를 컴파일 할 때 대상 모듈 시스템(CommonJS, ES2015 등)</td>
</tr>
<tr>
<td align="center">outDir</td>
<td align="center">생성된 자바스크립트 코드를 출력할 디렉터리</td>
</tr>
<tr>
<td align="center">strict</td>
<td align="center">유효하지 않은 코드를 확인할 때 가능한 한 엄격하게 감시</td>
</tr>
<tr>
<td align="center">target</td>
<td align="center">TSC가 코드를 컴파일할 자바스크립트 버전</td>
</tr>
</tbody></table>
<hr/>

<h3 id="232-tslintjson">2.3.2 tslint.json</h3>
<p>보통 프로젝트는 TSlint 설정을 정의하는 tslint.json 파일도 포함한다. </p>
<hr/>

<h1 id="3장-타입의-모든-것">3장 타입의 모든 것</h1>
<blockquote>
<p>*<em>타입 *</em>
값과 이 값으로 할 수 있는 일의 집합</p>
</blockquote>
<p><img src="https://images.velog.io/images/boram_in/post/16d5c796-090c-430c-96b1-9c4b3ac3bcfe/image.png" alt=""></p>
<h2 id="31-타입을-이야기하다">3.1 타입을 이야기하다</h2>
<p><img src="https://images.velog.io/images/boram_in/post/06268be7-edfc-4e5b-b8f1-b6f5cee6be2d/image.png" alt="">
*<em>타입스크립트란 특정 타입만 와야할 때 이를 명시할 수 있는 언어. *</em>숫자가 아닌 타입을 건네면 타입스크립트가 바로 에러를 발생시킨다. 타입 어노테이션이 없으면 squareOfdml 매개변수에 제한이 없으므로 아무 타입이나 인수로 전달할 수 있다. 일단 타입을 제한하면 타입스크립트가 함수를 호출할 때 호환이 되는 인수로 호출했는지를 판단. </p>
<hr/>

<h2 id="32-타입의-가나다">3.2 타입의 가나다</h2>
<p>타입스크립트가 지원하는 타입을 살펴보며 무엇을 포함할 수 있는지 살펴보자. </p>
<h3 id="321-any">3.2.1 any</h3>
<ul>
<li>any는 타입의 대부</li>
<li>꼭 필요한 상황이 아니라면 사용하지 않는 것이 좋다 </li>
<li>any는 모든 값의 집합이므로 모든 것을할 수 있다. </li>
<li>이로 인해 자바스크립트처럼 동작하며 타입 검사기라는 마법이 더 이상 작동하지 않는다. </li>
</ul>
<h3 id="322-unknown">3.2.2 unknown</h3>
<ul>
<li>타입을 미리 알 수 없는 값이 있으면 any 대신 unknown을 사용하자. </li>
<li>any처럼 모든 값을 대표하지만 unknown의 타입을 검사해 정제(refine)하기 전까지는 타입스크립트가 unknown 타입의 값을 사용할 수 없게 강제한다. </li>
<li>비교연산(==, ===, ||, &amp;&amp;, ?)과 반전(!)을 지원하고 typeof, instanceof 연산자로 정제할 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/1c35e46b-95cd-46f6-a197-b9080e27eb2a/image.png" alt=""></li>
<li><ol>
<li>타입스크립트가 무언가의 타입을 unknown이라 유추하는 상황은 없다. 명시적으로 설정해줘야 한다 </li>
</ol>
</li>
<li><ol start="2">
<li>unknown 타입이 아닌 값과 unknown 타입인 값을 비교할 수 있다. </li>
</ol>
</li>
<li><ol start="3">
<li>하지만 unknown 값이 특정 타입이라고 가정하고 해당 타입에서 지원하는 동작을 수행할 수는 없다.  먼저 타입스크립트에게 해당 값이 특정 타입임을 증명해야한다.(z+10) </li>
</ol>
</li>
</ul>
<hr/>

<h3 id="323-boolean">3.2.3 boolean</h3>
<p><img src="https://images.velog.io/images/boram_in/post/18735211-b383-42f2-bcfd-438ea33abc11/image.png" alt=""></p>
<ul>
<li><ol>
<li>어떤 값이 boolean이니 타입스크립트가 추론하게 한다(a,b)</li>
</ol>
</li>
<li><ol start="2">
<li>어떤 값이 특정 boolean인지 타입스크립트가 추론(c)</li>
</ol>
</li>
<li><ol start="3">
<li>값이 boolean임을 명시적으로 전달(d)</li>
</ol>
</li>
<li><ol start="4">
<li>값이 특정 boolean임을 명시적으로 알린다 (e,f) </li>
</ol>
</li>
</ul>
<p>실제 프로그래밍에서는 보통 1,2 방법을 사용. 이렇게하면 타입 리터럴이 된다. (boolean 타입 중 특정한 하나의 값으로 한정) </p>
<hr/>


<h3 id="324-number">3.2.4 number</h3>
<p>number타입은 모든 숫자의 집합(정,소,양,음,Infinity, NaN) 
<img src="https://images.velog.io/images/boram_in/post/993bd5d9-828a-4202-9083-8605059ba1ff/image.png" alt=""></p>
<ul>
<li>boolean처럼 네 가지 방법으로 number의 타입을 지정할 수 있다 </li>
<li><ol>
<li>타입스크립트가 값이 number임을 추론하게 한다(a,b) </li>
</ol>
</li>
<li><ol start="2">
<li>const를 이용해 타입스크립트가 값이 특정 number임을 추론하게 한다(c) </li>
</ol>
</li>
<li><ol start="3">
<li>값이 number임을 명시적으로 타입스크립트에 알린다(e) </li>
</ol>
</li>
<li><ol start="4">
<li>타입스크립트에 값이 특정 number임을 명시적으로 알린다(f,g) </li>
</ol>
</li>
</ul>
<p>boolean처럼 개발자들은 대개 number 타입을 추론하도록. number 타입임을 명시해야 하는 상황은 거의 없다. </p>
<hr/>

<h3 id="325-bight">3.2.5 bight</h3>
<ul>
<li>bight는 자바스크립트와 타입스크립트에 새로 추가된 타입, 이를 이용하면 라운딩 관련 에러 걱정 없이 큰 정수를 처리할 수 있다.</li>
<li>number 253까지의 정수를 표현할 수 있지만 bight를 이용하면 이보다 큰 수도 표현 가능.</li>
<li>이 역시 가능하면 타입스크립트가 bight의 타입을 추론하게 만들자 </li>
</ul>
<hr/>

<h3 id="326-string">3.2.6 string</h3>
<ul>
<li>string은 모든 문자열의 집합으로 +, .slice 등의 연산을 수행할 수 있다. </li>
<li>boolean과 number처럼 string 타입도 네 가지 방법으로 선언할 수 있으며</li>
<li>가능하다면 타입스크립트가 string 타입을 추론하도록 두는 것이 좋다 </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/dd0edf37-afc0-4fe0-bc2a-d5c9a990017d/image.png" alt=""></p>
<hr/>

<h3 id="327-symbol">3.2.7 symbol</h3>
<p>ES2015에 새로 추가된 기능. 실무에서는 자주 사용하지 않는 편이며 객체와 맵에서 문자열 키를 대신하는 용도로 사용된다. 심벌 키를 사용하면 사람들이 잘 알려진 키만 사용하도록 강제할 수 있으므로 키를 잘못 설정하는 실수를 방지. 객체의 기본 반복자(Symbol.iterator)를 설정하거나 객체가 어떤 인스턴스인지(Symbol.hasInstance)를 런타임에 오버라이딩하는 것과 비슷한 기능을 제공. </p>
<p><img src="https://images.velog.io/images/boram_in/post/541a085f-c744-4c2b-a1d0-df61a8e1180d/image.png" alt=""></p>
<hr/>

<h3 id="328-객체">3.2.8 객체</h3>
<p>타입스크립트의 객체(object) 타입은 객체의 형태(shape)를 정의한다. 객체 타입만으로는 객체리터럴로 만든 객체와 new로 생성한 객체를 구분할 수 없다. 자바스크립트가 구조 기반 타입을 갖도록 설계되었기 때문이다. </p>
<blockquote>
<h4 id="구조-기반-타입화">구조 기반 타입화</h4>
<p>구조 기반 타입화에서는 객체의 이름에 상관없이 객체가 어떤 프로퍼티를 갖고 있는지 따진다(이름 기반 타입에서는 이름을 따진다) 일부 언어에서는 덕 타이핑(duck typing)이라고 한다(겉표지만 보고 책을 판단하지 않는 것과 같은 원리) </p>
</blockquote>
<ul>
<li>타입스크립트에서 객체를 서술하는 데 타입을 이용하는 방식은 여러가지. </li>
<li>첫 번째 방법은 값을 object로 선언하는 것이다 
<img src="https://images.velog.io/images/boram_in/post/f3478ab8-5bb1-4d71-8380-569488203f73/image.png" alt=""></li>
</ul>
<p>b에접근하면 에러가 발생. 사실 object는 any보다 조금 더 좁은 타입. object는 서술하는 값에 관한 정보를 거의 알려주지 않으며 값 자체가 자바스크립트 객체라고 말해줄 뿐이다.</p>
<p><img src="https://images.velog.io/images/boram_in/post/d7c65317-ef29-486e-b4e5-40004db5efea/image.png" alt="">
타입스크립트가 c의 형태를 추론하게 하거나 중괄호({})안에 타입을 명시적으로 묘사할 수 있다. </p>
<blockquote>
<h4 id="객체를-const로-선언할-때의-타입-추론">객체를 const로 선언할 때의 타입 추론</h4>
<p>객체를 const로 선언하면 어떻게 될까? 
<img src="https://images.velog.io/images/boram_in/post/e6b96b1c-2aa7-4404-9aa3-fa0bba443c21/image.png" alt=""></p>
</blockquote>
<ul>
<li>타입스크립트가 b를 리터럴 12가 아닌 number로 추론. 이를 통해 const를 사용하느냐 let을 사용하느냐 const를 사용하느냐에 따라 타입스크립트가 number나 string 타입을 추론. </li>
<li>하지만 지금까지 살펴본 기본 타입과 달리 객체를 const로 선언해도 타입스크립트는 더 좁은 타입으로 추론하지 않는다. 자바스크립트 객체의 값은 바뀔 수 있으며, 타입스크립트도 객체를 만든 후 필드 값을 바꾸려 할 수 있다는 사실을 알기 때문.</li>
</ul>
<p>객체 리터럴 문법은 &quot;이런 형태의 물건이 있어&quot;라고 말한다. 이 물건은 객체 리터럴 또는 클래스일 수 있다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/ac9e41a0-66ab-47f4-9d25-b3028b7c886d/image.png" alt=""></p>
<p>기본적으로 타입스크립트는 객체 프로퍼티에 엄격한 편. 예를 들어 객체에 number 타입의 b라는 프로퍼티가 있어야 한다고 정의하면 타입스크립트는 오직 b만 기대한다. b가 없거나 다른 추가 프로퍼티가 있으면 에러를 발생시킨다. </p>
<blockquote>
<p><strong>그렇다면 어떻게 예정에 없던 프로퍼티가 추가될 수 있다고 알려줄 수 있을까?</strong> </p>
</blockquote>
<p><img src="https://images.velog.io/images/boram_in/post/41eed7a2-7618-41b1-84c4-538861a51839/image.png" alt=""></p>
<ul>
<li>(1) a는 number 타입의 프로퍼티 b를 포함한다 </li>
<li>(2) a는 string 타입의 프로퍼티 c를 포함할 수도 있다. </li>
<li>(3) a는 boolean 타입의 값을 갖는 number 타입의 프로퍼티를 여러 개 포함할 수 있다. </li>
</ul>
<blockquote>
<h4 id="인덱스-시그니처index-signature">인덱스 시그니처(index signature)</h4>
<p>[key : T] : U같은 문법을 인덱스 시그니처라고 부르며 타입스크립에 어떤 객체가 여러 키를 가질 수 있음을 알려준다. &quot;이 객체에서 모든 T 타입의 키는 U 타입의 값을 갖는다&quot;라고 해석할 수 있다. 인덱스 시그니처를 이용하면 명시적으로 정의한 키 외에 다양한 키를 객체에 안전하게 추가할 수 있다. </p>
</blockquote>
<ul>
<li>인덱스 시그니처에서 기억해야 할 규칙이 하나 있다. 인덱스 시그니처의 키(T)는 반드시 number나 string 타입에 할당할 수 있는 타입이어야 한다 </li>
<li>인덱스 시그니처의 이름은 원하는 이름을 가져다 바꿔도 된다. 즉, key가 아니어도 된다. 
<img src="https://images.velog.io/images/boram_in/post/afd91aa6-9b87-4821-8fd0-9d4b7b978ba5/image.png" alt=""></li>
</ul>
<p>객체 타입을 정의할 때 선택형(?)만 사용할 수 있는 것은 아니다. 필요하면 readonly 한정자를 이용해 특정 필드를 읽기 전용으로 정의할 수 있다.( 즉, 정의한 필드에 초깃값을 할당한 다음에는 그 값을 바꿀 수 없다. 객체 프로퍼티에 const를 적용한 듯한 효과를 낸다) </p>
<p><img src="https://images.velog.io/images/boram_in/post/88dd8505-5f83-4869-a249-f24360cb6e88/image.png" alt=""></p>
<ul>
<li>firstName은 읽기 전용 프로퍼티이므로 할당할 수 없음 </li>
</ul>
<p>객체리터럴 표기법에는 빈 객체 타입({})이라는 특별한 상황이 존재. null과 undefined를 제외한 모든 타입은 빈 객체 타입에 할당할 수 있으나, 이는 사용하기 까다롭게 만든다. 따라서 가능한 한 빈 객체는 피하는 것이 좋다. </p>
<p>마지막으로 <strong>객체:Object</strong>로 객체 타입을 만드는 방법도 있다. {}과 비슷한 방법이며 마찬가지로 가능하면 사용하지 않아야 한다. 타입스크립트에서 객체를 정의하는 방법은 다음처럼 네 가지로 요약할 수 있다. </p>
<ul>
<li><ol>
<li>객체 리터럴 또는 형태라 불리는 표기법({a:string}). 객체가 어떤 필드를 포함할 수 있는지 알고 있거나 객체의 모든 값이 같은 타입을 가질 때 사용한다</li>
</ol>
</li>
<li><ol start="2">
<li>빈 객체 리터럴 표기법({}) ❌. 이 방법은 사용하지 않는 것이 좋다 ❌</li>
</ol>
</li>
<li><ol start="3">
<li>object 타입. 어떤 필드를 가지고 있는지 관심 없고 그저 객체가 필요할 때 사용</li>
</ol>
</li>
<li><ol start="4">
<li>Object 타입. ❌사용하지 않는 것이 좋다❌</li>
</ol>
</li>
</ul>
<p>🙋 타입스크립트 프로그램을 작성할 때 대부분 첫 번째나 세 번째 방법을 이용해야 한다. 두 번째와 네 번째 방법은 피해야 한다! </p>
<hr/>]]></description>
        </item>
        <item>
            <title><![CDATA[[이펙티브 타입스크립트] 1장 타입스크립트 알아보기]]></title>
            <link>https://velog.io/@boram_in/%EC%9D%B4%ED%8E%99%ED%8B%B0%EB%B8%8C-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-1%EC%9E%A5-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@boram_in/%EC%9D%B4%ED%8E%99%ED%8B%B0%EB%B8%8C-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-1%EC%9E%A5-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Sat, 15 Jan 2022 05:34:06 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="1장에서는-타입스크립트의-큰-그림들을-이해하는-데-도움이-될-내용을-공부한다">1장에서는 타입스크립트의 큰 그림들을 이해하는 데 도움이 될 내용을 공부한다!</h3>
</blockquote>
<ul>
<li>타입스크립트란?</li>
<li>자바스크립트와의 관계 </li>
<li>타입은 null이 가능한지, any 타입에서는 어떨지, duck typing이 가능한지 </li>
</ul>
<p>타입스크립트는 사용 방식 면에서 조금 독특한 언어이다. 인터프리터로 실행되는 것도 ❌, 저수준 언어로 컴파일 되는 것도 ❌ 실행 역시 타입스크립트가 아닌 자바스크립트로 이뤄진다. 그래서 관계가 밀접하고 혼란스러운일이 이로 인해 발생하기도 한다. </p>
<h2 id="아이템1-타입스크립트와-자바스크립트-관계-이해하기">아이템1 타입스크립트와 자바스크립트 관계 이해하기</h2>
<p>&quot;<strong>타입스크립트는 자바스크립트의 상위집합이다</strong>&quot; 근데 그게 무슨말? 🙋 자바스크립트 프로그램에 문법 오류가 없다면 유효한 타입스크립트 프로그램. 그런데 문법 오류가 없어도 이슈가 있다면 타입 체커에게 지적당할 가능성이 높다. 그러나 문법의 유효성과 동작의 이슈는 독립적이어서 타입스크립트는 여전히 작성된 코드를 파싱하고 자바스크립트로 변환가능 
<img src="https://images.velog.io/images/boram_in/post/d7cd0fec-72b9-4c66-b22f-8e314be6f15f/image.png" alt="">
자바스크립트 파일이 .js, jsx 확장자를 사용하는 반면 타입스크립트는 .ts, .tsx 를 사용한다. 상위 집합이므로 .js파일에 있는 코드는 이미 타입스크립트라고 할 수 있다. 이러한 특성으로 인해서 <strong>⭐ 기존에 존재하는 자바스크립트 코드를 타입스크립트로 migration 하는데 엄청난 이점 ⭐</strong>. 기존 코드를 그대로 유지하면서 일부만 타입스크립트 적용이 가능하기 때문에. </p>
<p>타입스크립트 프로그램이지만 자바스크립트가 아닌 프로그램이 존재. 이는 타입스크립트가 타입을 명시하는 추가적인 문법을 가지기 때문. 타입스크립트 컴파일러는 타입스크립트 뿐만 아니라 일반 자바스크립트 프로그램에도 유용. </p>
<p>: string은 타입스크립트에서 쓰이는 타입 구문. 타입 구문을 사용하는 순간 자바스크립트는 타입스크립트 영역으로 들어가게 된다. </p>
<p>타입시스템의 목표 중 하나는 런타임에서 오류를 발생시킬 코드를 미리 찾아 내는 것. 타입스크립트가 정적 타입 시스템이라는 것은 바로 이런 특징. 그러나 타입 체커가 모든 오류를 찾아내지는 않는다.
<img src="https://images.velog.io/images/boram_in/post/cc68f5ce-1456-4db6-b8a4-f0ef26f54c76/image.png" alt="">
위와 같은 코드는 유효한 자바스크립트(또한 타입스크립트)이며 어떠한 오류도 없이 실행된다. 그러나 state.capitol은 의도한 코드가 아니다. 이러한 경우에 타입스크립트는 추가적인 타입 구문 없이도 오류를 찾아낸다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/37be26f9-d318-429c-a7b9-7ec41f5b576a/image.png" alt=""></p>
<p>타입스크립트는 타입 구문 없이도 오류를 잡을 수 있지만, 타입 구문을 추가하면 훨씬 더 많은 오류를 찾을 수 있다. 이는 의도가 무엇인지 타입 구문을 통해 알려줄 수 있기 때문에. 
<img src="https://images.velog.io/images/boram_in/post/3a70751c-e0da-4db4-8e01-2c45c4babe79/image.png" alt=""></p>
<ul>
<li><p>객체리터럴은 알려진 속성만 지정할 수 있지만~ 과 같은 오류가 나온다. </p>
</li>
<li><p>이제 오류가 어디에서 발생했는지 찾을 수 있고 제시된 해결책도 올바르다.</p>
</li>
</ul>
<h3 id="타입스크립트-타입-시스템은-자바스트립트의-런타임-동작을-모델링한다">타입스크립트 타입 시스템은 자바스트립트의 런타임 동작을 &#39;모델링&#39;한다.</h3>
<ul>
<li>타입스크립트는 자바스크립트 런타임 동작을 모델링하는 타입 시스템을 가지고 있기 때문에 런타임 오류를 발생시키는 코드를 찾아내려 한다. 그러나 모든 오류를 찾아내리라 기대하면 안 된다. 타입 체커를 통과하면서도 런타임 오류를 발생시키는 코드는 충분히 존재할 수 있다. </li>
<li>잘못된 매개변수 개수로 함수를 호출하는 경우처럼, 자바스크립트에는 허용되지만 타입스크립틍서는 문제가 되는 경우도 있다. </li>
</ul>
<hr>

<h2 id="아이템-2-타입스크립트-설정-이해하기">아이템 2 타입스크립트 설정 이해하기</h2>
<p>현재 시점에는 설정이 거의 100개에 이른다. 이 설정은 커맨드 라인을 사용해 할 수도 있고 tsconfig.json 설정 파일을 통해서도 가능하다. 
<img src="https://images.velog.io/images/boram_in/post/e47e089b-b60a-40f8-a557-3664ecd3fe29/image.png" alt=""></p>
<p>가급적 설정파일을 이용하는 것이 좋다. 그래야 동료들이나 다른 도구들도 알 수 있기 때문. 타입스크립트는 어떻게 설정하느냐에 따라서 완전히 다른 언어처럼 느껴질 수도 있다. 설정을 제대로 사용하려면 noImplicityAny와 strictNullChecks를 이해해야한다. </p>
<hr>

<h3 id="⛳--noimplicityany">⛳  noImplicityAny</h3>
<p>변수들이 미리 정의된 타입을 가져야 하는지 여부를 제어한다. any 타입을 매개변수에 이용하면 타입 체커는 쓸모 없어진다. any는 유용하지만 매우 주의해서 사용해야한다. 
<img src="https://images.velog.io/images/boram_in/post/eee478b3-b29f-41d5-92a1-d810dd5e65d3/image.png" alt=""></p>
<ul>
<li>any를 코드에 넣지 않았지만 any 타입으로 간주되기에 이를 &#39;암시적 any&#39;라고 부른다. 그런데 같은 코드임에도 noImplicitAny를 설정하니 오류가 된다. 🙋 이러한 오류들은 명시적으로 :any라고 선언해주거나 더 분명한 타입을 사용하면 해결할 수 있다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/2f0ced56-59a1-4056-9f0b-7d33c458d14c/image.png" alt=""></p>
<ul>
<li>타입스크립트는 타입 정보를 가질 때 가장 효과적이므로, 되도록이면 noImplicitAny를 설정해야 한다. 처음부터 요것을 설정해 코드를 작성할 때마다 타입을 명시하도록 하면 문제 발견도 수월하고 가독성이 좋아지면 생산성도 좋아진다. </li>
<li>noImplicityAny 설정 해제는 자바스크립트로 되어 있는 기존 프로젝트를 타입 스크립트로 전환하는 상황에만 필요하다. </li>
</ul>
<hr/>



<h3 id="⛳-strictnullchecks">⛳ strictNullChecks</h3>
<p>null과 undefined가 모든 타입에서 허용되는지 확인하는 설정. 
<img src="https://images.velog.io/images/boram_in/post/336a62f1-b0e3-4523-908e-7caeee14519d/image.png" alt=""></p>
<ul>
<li>위 코드는 strictNullChecks가 해제되었을 때는 유효한 코드이지만 설정 후에는 오류가 난다. null대신 undefined를 써도같은 오류가 난다. 만약 null을 허용하려고 한다면, 의도를 명시적으로 드러내서 오류를 고칠 수 있다.</li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/1f71b0a7-f23d-44ca-9c67-2923f81cf16f/image.png" alt=""></p>
<ul>
<li>만약 null을 허용하지 않으려면, 이 값이 어디서부터 왔는지 찾아야 하고 null을 체크하는 코드나 단언문을 추가해야 한다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/2989a8de-aad7-43f9-be9a-0dc21716a7b4/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/boram_in/post/c2b945b1-cced-4132-a847-5cf406cc98c5/image.png" alt=""></p>
<ul>
<li><p>strictNullChecks는 null과 undefined 관련된 오류는 잡아내는데 많은 도움이 되지만, 코드 작성을 어렵게 하기도. 새 프로젝트를 시작한다면 가급적 사용하는 것이 좋지만 처음이거나 자바스크립트를 마이그레이션 중이라면 설정하지 않아도 괜찮다. 또한 strictNullChecks를 설정할면 noImplicityAny를 먼저 설정해야 한다. </p>
</li>
<li><p>언어에 의미적으로 영향을 미치는 설정들이 많지만 이 모든 체크를 설정하고 싶다면 strict 설정을 하면 된다. 타입스크립트에 strict 설정을 하면 대부분의 오류를 잡아준다. </p>
</li>
</ul>
<hr/>

<h2 id="아이템-3-코드-생성과-타입이-관계없음을-이해하기">아이템 3 코드 생성과 타입이 관계없음을 이해하기</h2>
<p>큰 그림에서 타입스크립트 컴파일러는 두 가지 역할을 수행한다. </p>
<ul>
<li>최신 타입스크립트/자바스크립트를 브라우저에서 동작할 수 있도록 구버전의 자바스크립트로 트랜스 파일한다. </li>
<li>코드의 타입 오류를 체크한다 </li>
</ul>
<blockquote>
<h4 id="트랜스파일--translate--compile-소스코드를-동일한-동작을-하는-다른-소스코드다른-버전-언어-등로-변환하는-행위를-의미-결과물이-여전히-컴파일-되어야-하는-소스코드이기-때문에-컴파일과는-구분해서-부른다"><strong>트랜스파일</strong> : translate + compile, 소스코드를 동일한 동작을 하는 다른 소스코드(다른 버전, 언어 등)로 변환하는 행위를 의미. 결과물이 여전히 컴파일 되어야 하는 소스코드이기 때문에 컴파일과는 구분해서 부른다.</h4>
</blockquote>
<p>여기서 놀라운 점은 이 두 가지가 서로 완벽히 독립적. 타입스크립트가 자바스크립트로 변환될 때 코드 내 타입에는 영향을 주지 않으며 실행 시점에도 타입은 영향을 주지 않는다. 그래서 이를 통해 할 수 있는 일과 없는 일을 짐작할 수 있다. </p>
<hr/>

<h3 id="타입-오류가-있는-코드도-컴파일이-가능하다">타입 오류가 있는 코드도 컴파일이 가능하다.</h3>
<p>컴파일은 타입 체크와 독립적으로 동작하기에 타입 오류가 있는 코드도 컴파일이 가능하다. 타입 체크와 컴파일이 동시에 이뤄지는 C나 자바와 같은 언어와 달리 경고와 비슷해 문제가 될 만한 부문을 알려 주지만 그렇다고 빌드를 멈추지는 않는다.
<img src="https://images.velog.io/images/boram_in/post/12dd8f3e-327a-49db-a28c-c0d2e2944884/image.png" alt="">
 이를통해 문제 된 오류를 수정하지 않더라도 다른 부분을 테스트할 수 있다. 만약 오류가 있을 때 컴파일 하지 않으려면 tsconfig.json에 noEmitOnError를 설정하거나 빌드 도구에 동일하게 적용하면 된다. </p>
<hr/>

<h3 id="런타임에는-타입-체크가-불가능하다">런타임에는 타입 체크가 불가능하다</h3>
<p><img src="https://images.velog.io/images/boram_in/post/0dfcc812-229b-4363-90a4-86a1e31bcf44/image.png" alt=""></p>
<ul>
<li>instanceof 체크는 런타임에 일어나지만 , Retangle은 타입이기 때문에 런타임 시점에 아무런 역할을 할 수 없다. 타입스크립트의 타입은 &#39;제거 가능&#39;하다. 실제로 자바스크립트로 컴파일 되는 과정에서 모든 인터페이스, 타입, 타입구문은 제거되어 버린다. </li>
<li>앞의 코드에서 다루고 있는 shape 타입을 명확하게 하려면, 런타임에 타입 정보를 유지하는 방법이 필요하다. 하나의 방법은 height 속성이 존재하는지 체크해보는 것. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/c7769a91-dd95-4746-967f-f47e12923945/image.png" alt=""></p>
<ul>
<li>속성 체크는 런타입에 접근 가능한 값에 관련되지만, 타입 체커 역시도 shape의 타입을 Rectangle로 보정해주기에 오류가 사라진다. </li>
<li>타입 정보를 유지하는 또 다른 방법으로는 런타임에 접근 가능한 타입 정보를 명시적으로 저장하는 &#39;태그&#39;기법이 있다. </li>
</ul>
<h4 id="태그기법">태그기법</h4>
<p><img src="https://images.velog.io/images/boram_in/post/fa6d08d5-9371-438d-a27f-b5ee42c9a470/image.png" alt=""></p>
<ul>
<li>여기서 ShapeOf 타입은 &#39;태그된 유니온&#39;의 한 예이다. 이 기법은 런타임에 타입 정보를 손쉽게 유지할 수 있기에 타입스크립트에서는 흔하게 볼 수 있다. </li>
<li>타입(런타임 접근 불가)와 값(런타임 접근 가능)을 둘 다 사용하는 기법도 있다. 타입을 클래스로 만들면 된다. Square과 Retangle을 클래스로 만들면 오류를 해결할 수 있다. </li>
</ul>
<h4 id="클래스로-해결하기">클래스로 해결하기</h4>
<p><img src="https://images.velog.io/images/boram_in/post/ae5e2d6d-8435-4691-8e61-620d4e5d5a6e/image.png" alt=""></p>
<p><strong>인터페이스는 타입으로만 사용 가능하지만</strong> 정사각형을 <strong>클래스로 선언하면 타입과 값으로 모두 사용할 수 있으므로 오류가 없다.</strong> type 모양 = 직사각형 | 정사각형 부분에서 정사각형은 타입으로 참조되지만, shape instanceof 정사각형 부분에서는 값으로 참조된다. ** ⭐ 이후에 아이템8에서 다룰 어떻게 참조되는지 구분하는 것은 매우 중요하다!**</p>
<hr/>

<h2 id="타입-연산은-런타임에-영향을-주지-않는다">타입 연산은 런타임에 영향을 주지 않는다</h2>
<p>string or number 타입인 값을 항상 number로 정제하는 경우를 가정. 다음 코드는 체커를 통과하지만 잘못된 방법을 사용했다. 
<img src="https://images.velog.io/images/boram_in/post/affe8e3d-0359-432e-a2df-6c2ccc4cde40/image.png" alt="">
변환된 자바스크립트 코드를 보면 이 함수가 실제로 어떻게 동작하는지 알 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/f914ca47-78bf-475c-bbbe-b160b2b38da5/image.png" alt="">
코드에 아무런 정제 과정이 없다. as number는 타입 연산이고 런타임 동작에는 아무런 영향을 미치지 않는다. 값을 정제하기 위해서는 런타임의 타입을 체크해야 하고 자바스크립트 연산을 통해 변환을 수행해야 한다. 
<img src="https://images.velog.io/images/boram_in/post/1ba0b38b-84fb-420a-bc7a-e00951036ba8/image.png" alt=""></p>
<ul>
<li>요것을 변환하면, </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/ab4e3c74-2472-4f5d-8128-2710bb0ec3d6/image.png" alt=""></p>
<h2 id="런타임-타입은-선언전-타입과-다를-수-있다">런타임 타입은 선언전 타입과 다를 수 있다.</h2>
<p><img src="https://images.velog.io/images/boram_in/post/7b21b4f4-0b62-4871-aaf2-4edbab497be7/image.png" alt="">
타입스크립트는 일반적으로 실행되지 못하는 죽은 코드를 찾아내지만, 여기서는 strict를 설정해도 찾아내지 못한다. :boolean이 타입 선언문이라는 것에 주목. 타입스크립트의 타입이기에 :boolean은 런타임에 제거된다. 타입 스크립트에서는 런타입 타입과 선언된 타입이 맞지 않을 수도. 타입이 달라지는 혼란스러운 상황을 가능한 한 피해야 한다. 선언된 타입이 언제든지 달라질 수 있다는 것을 명심! </p>
<hr/>

<h2 id="타입스크립트-타입으로는-함수를-오버로드-할-수-없다">타입스크립트 타입으로는 함수를 오버로드 할 수 없다</h2>
<p><img src="https://images.velog.io/images/boram_in/post/aa65e29c-1a7c-4784-a188-37c2bb3cdc16/image.png" alt="">
C++과 같은 언어는 동일한 이름에 매개변수만 다른 여러 버전의 함수를 허용. 이를 &#39;함수 오버로딩이&#39;이라고 한다. 그러나 타입스크립트에서는 타입과 런타임의 동작이 무관하므로 함수 오버로딩은 불가. 지원은 하지만 온전히 타입 수준에서만 동작한다. 하나의 함수에 대해서 여러 개의 선언문을 작성할 수 있지만 구현체(implementation)는 오직 하나 뿐. </p>
<hr/>

<h2 id="타입스크립트-타입은-런타임-성능에-영향을-주지-않는다">타입스크립트 타입은 런타임 성능에 영향을 주지 않는다</h2>
<p>타입과 타입 연산자는 자바스크립트 변환 시점에 제거가 되기에 런타임의 성능에 아무런 영향을 주지 않는다. 타입스크립트의 정적 타입은 실제로 비용이 전혀 들지 않는다.</p>
<ul>
<li><p>런타임 오버헤드가 없는 대신, 타입스크립트 컴파일러는 &#39;빌드타임&#39; 오버헤드가 존재. 타입스크립트 팀은 컴파일러 성능을 매우 중요하게 생각. 따라서 컴파일은 일반적으로 빠르며 특히 증분(incremental)빌드 시에 더욱 체감된다. 오버헤드가 커지면 빌드 도구에서 &#39;트랜스파일만(transpile)&#39;을 설정해 타입 체크를 건너뛸 수 있다.</p>
</li>
<li><p>타입스크립트가 컴파일하는 코드는 오래된 런타임 환경 지원을 위해 호환성을 노피이고 성능 오버헤드를 감안할 지, 호환성을 포기하고 성능 중심의 네이티브 구현체를 선택할 지 문데에 맞닥뜨릴 수 있다. 예를 들어 제너레이터 함수가 ES5 타깃으로 컴파일 되려면, 타임스크립트 컴파일러는 호환성을 위해 특정 헬처 코드를 추가할 것. 이런 경우가 제너레이터의 호환성을 위해 오버헤드 또는 성능을 위한 네이티브 구현체 선택의 문제. </p>
</li>
</ul>
<hr/>








<blockquote>
<p>TIL </p>
</blockquote>
<ul>
<li>완전히 다른 언어가 아니었구나! 그리고 인터프리터로 실행되거나 저수준 언어로 컴파일되지 않고 JS로 실행되는 것도 신기하다. 그래서 오히려 널리 쓰이는구나. </li>
<li>오 신기하게 대부분의 설정이 주석처리되어 있지만 tsconfig.json에 이미 존재한다. 필요한 것만 옆에 설명을 읽고 주석을 헤제하면 되는건가? </li>
<li>ㅎㅎ 이 책을 읽을 수준이 아직 아님을 깨달았다! 타입스크립트 프로그래밍을 보고 나중에 ts에 적응을 하면 이 책을 봐야지! 딥다이브를 처음볼 때랑 비교해보면 자기 수준을 알면서 책을 보는 것도 성장했다!</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 딥다이브 47장 & 48장] 에러처리 & 모듈]]></title>
            <link>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-47%EC%9E%A5-%EC%97%90%EB%9F%AC%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-47%EC%9E%A5-%EC%97%90%EB%9F%AC%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Thu, 13 Jan 2022 02:51:06 GMT</pubDate>
            <description><![CDATA[<h1 id="47장--에러처리-">47장 | 에러처리 |</h1>
<HR/>

<h2 id="471-에러-처리의-필요성">47.1 에러 처리의 필요성</h2>
<p>에러가 발생하지 않는 코드를 작성하는 것은 불가능. 따라서 에러는 언제나 발생할 수 있다. 발생한 에러에 대처하지 않고 방치해두면 프로그램은 강제 종료됨. </p>
<p>try...catch 문을 사용해 발생한 에러에 적절하게 대응하면 프로그램이 강제 종료되지 않고 계속해서 코드를 실행시킬 수 있다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/2ec38cc8-6724-457a-b2c2-e85179a47c7b/image.png" alt=""></p>
<ul>
<li>직접적으로 에러를 발생하지 않는 예외적 상황이 발생할 수도. 예외적인 상황에 적절하지게 대응하지 않으면 에러로 이어질 가능성이 크다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/2b3c9e67-abb2-4bd4-99d6-1dc045f54e2d/image.png" alt=""></p>
<ul>
<li>위 예제의 querySelector 메서드는 인수로 전달한 문자열이 CSS 선택자 문법에 맞지 않는 경우 에러를 발생시킨다. </li>
<li>하지만 querySelector 메서드는 인수로 전달한 CSS 선택자 문자열로 DOM요소 노드를 찾을 수 없는 경우 에러를 발생시키지 않고 null을 반환</li>
<li>이때 if 문으로 querySelector 메서드의 반환값을 확인하거나 단축평가 등으로 처리하지 않으면 에러로 이어질 가능성이 크다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/65c2d9c1-7f23-45df-99c1-c99b2972c965/image.png" alt=""></p>
<hr/>

<h2 id="472-trycatchfinally-문">47.2 try...catch...finally 문</h2>
<p>기본적으로 에러를 처리하는 방법은 두 가지 </p>
<ul>
<li>querySelector나 Array#find 메서드처럼 예외적인 상황에서 반환값을 if문이나 단축 평가 또는 옵셔널 체이닝 연산자를 통해 확인해서 처리하는 방법</li>
<li>에러처리: try...catch...finally처럼 에러 처리 코드를 미리 등록해 두고 에러가 발생하면 처리 코드로 점프하도록 하는 방법</li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/3b90c268-2969-477e-8b91-11f9af1f7e73/image.png" alt=""></p>
<ul>
<li>try...catch...finally 문을 실행하면 먼저 try 코드 블록이 실행된다. </li>
<li>➡️ 여기서 에러가 발생하면 에러는 catch 문의 err 변수에 전달되고 catch 코드 블록이 실행된다</li>
<li>➡️ catch문의 err변수는 try 코드 블록에 포함된 문 중에서 에러가 발생하면 생성되고 catch 코드 블록에서만 유효하다 </li>
<li>➡️ finally는 에러 발생 여부와 상관 없이 반드시 한 번은 실행된다 </li>
</ul>
<blockquote>
<p>이 역시 파이썬에서 열심히 배웠다. </p>
</blockquote>
<hr/>

<h2 id="473-error-객체">47.3 Error 객체</h2>
<p>Error 생성자 함수는 에러 객체를 생성. Error 생성자 함숭는 에러를 상세히 설명하는 에러 메세지를 인수로 전달할 수 있다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/7a55e166-485a-446c-a851-ef53e8d7f57d/image.png" alt=""></p>
<p>Error 생성자 함수가 생성한 에러 객체는 message프로퍼티와 stack 프로퍼티를 갖는다. message 프로퍼티의 값은 Error 생성자 함수에 인수로 전달한 에러 메세지이고, stack 프로퍼티의 값은 에러를 발생시킨 콜스택 호출정보를 나타내는 문자열이며 디버깅 목적으로 사용.</p>
<p>자바스크립트는 Error 생성자 함수를 포함해 7가지의 에러 객체를 생성할 수 있는 Error  생성자 함수를 제공한다. 생성자 함수가 생성한 에러 객체의 프로토타입은 모두 Error.prototype을 상속받는다. </p>
<h3 id="-생성자-함수--인스턴스-">[ 생성자 함수 / 인스턴스 ]</h3>
<ul>
<li>Error : 일반적인 에러 객체</li>
<li>SyntaxError :  자바스크립트 문법에 맞지 않은 문을 해석할 때 발생하는 에러 객체 </li>
<li>ReferenceError : 참조할 수 없는 식별자를 참조했을 때 발생하는 에러 객체 </li>
<li>TypeError : 피연산자 또는 인수의 데이터 타입이 유효하지 않을 때 발생하는 에러 객체 </li>
<li>RangeError : 숫자값의 허용 범위를 벗어났을 때 발생하는 에러 객체 </li>
<li>URIError : encodeURI 또는 decodeURI 함수에 부적절한 인수를 전달할 때 발생하는 에러 객체 </li>
<li>EvalError: eval함수에서 발생하는 에러 객체 </li>
</ul>
<hr/>

<h2 id="474-throw-문">47.4 throw 문</h2>
<ul>
<li>Error 생성자 함수로 에러 객체를 생성한다고 에러가 발생하는 것은 아니다. 즉, 에러 객체 생성과 에러 발생은 의미가 다르다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/4ccfde8c-66f3-4f69-888a-5a54ec619f9a/image.png" alt=""></p>
<ul>
<li>에러를 발생시키려면 try 코드 블록에서 throw문으로 에러 객체를 던져야 한다.<pre><code>throw 표현식;</code></pre><img src="https://images.velog.io/images/boram_in/post/db3537df-72de-43e6-bd61-e02ad12181b6/image.png" alt=""></li>
</ul>
<p>throw 문의 표현식은 어떤 값이라도 상관없지만 일반적으로 에러 객체를 지정한다. 에러를 던지면 catch 문의 에러 변수가 생성되고 던져진 에러 객체가 할당된다. 그리고 catch 코드 블록이 실행되기 시작한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/7ac0fbd0-5da8-42ed-8b26-90c44806660a/image.png" alt=""></p>
<hr/>

<h2 id="475-에러의-전파">47.5 에러의 전파</h2>
<p>콜 스택의 아래 방향(실행 중인 실랭 컨텍스트가 푸시되기 직전에 푸시된 실행 컨텍스트 방향)으로 전파된다. 
<img src="https://images.velog.io/images/boram_in/post/1e72ff7a-6755-4550-a7c2-df2dd5e6cb8d/image.png" alt=""></p>
<ul>
<li><p>(1)에서 test2 함수를 호출하면 (2)에서 test 함수가 호출되고 (3)에서 foo 함수가 호출되고 foo 함수는 (4)에서 에러를 throw한다. 이때 foo함수가 throw한 에러는 다음과 같이 호출자에게 전파되어 전역에서 캐치된다. </p>
</li>
<li><p>이처럼 throw된 에러를 캐치하지 않으면 호출자 방향으로 전파된다. 이때 throw 된 에러를 캐치하여 적절히 대응하면 프로그램을 강제 종료시키지 않고도 코드의 실행흐름을 복구할 수 있다. throw된 에러를 어디에도 캐치하지 않으면 프로그램은 강제 종료된다. </p>
</li>
</ul>
<hr/>

<h1 id="48장--모듈-">48장 | 모듈 |</h1>
<h2 id="481-모듈의-일반적인-의미">48.1 모듈의 일반적인 의미</h2>
<p>⭐<strong>모듈</strong>⭐ : 모듈이랑 애플리케이션을 구성하는 개별적 요소로서 재사용가능한 코드조각을 의미. 일반적으로 모듈은 기능을 기준으로 파일 단위로 분리. 이때 <strong>모듈이 성립하려면 모듈은 자신만의 파일 스코프(모듈 스코프)를 가질 수 있어야 한다.</strong></p>
<p>자신만의 파일 스코프를 갖는 모듈의 자산(모듈에 포함되어있는 함수, 변수, 객체 등은) 기본적으로 비공개 상태이다. (캡슐화)</p>
<p>하지만 애플리케이션과 완전히 분리되어 개별적으로 존재하는 모듈은 재사용이 불가능하므로 존재의 의미가 없다. 모듈은 애플리케이션이나 다른 모듈에 의해 재사용되어야 유의미. <strong>따라서 모듈은 공개가 필요한 자산에 한정하여 명시적으로 선택적 공개가 가능. 이를 export라고 한다.</strong></p>
<p>공개(export)된 모듈의 자산은 다른 모듈에서 재사용 가능. 이때 공개된 모듈의 자산을 사용하는 모듈을 모듈 사용자라 한다. <strong>모듈 사용자는 모듈이 공개(export)한 자산 중 일부 or 전체를 선택해 자신의 스코프 내로 불러들여 재사용 가능하며 이를 import.</strong>
<img src="https://images.velog.io/images/boram_in/post/5b076899-1a73-48d9-978d-a52c5274d06c/image.png" alt=""></p>
<h2 id="482-자바스크립트와-모듈">48.2 자바스크립트와 모듈</h2>
<p>자바스크립트 런타임 환경인 Node.js는 모듈 시스템의 사실상 표준인 CommonJS를 채택했고 독자적인 진화를 거쳐 기본적으로는 CommonJS사양을 따르고 있다. 따라서 Node.js 환경에서는 파일별로 독립적인 파일 스코프(모듈 스코프)를 갖는다. </p>
<hr/>

<h2 id="483-es6-모듈esm">48.3 ES6 모듈(ESM)</h2>
<p>이러한 상황에서 ES6에서는 클라이언트 사이드 자바스크립트에서도 동작하는 모듈 기능을 추가했다. IE제외 대부분의 브라우저에서 사용 가능. ES6모듈의 사용법은 간단. script 태그에 type =&quot;module&quot; 어트리뷰트를 추가하면 로드된 자바스크립트 파일은 모듈로서 동작한다. 일반적인 자바스크립트 파일이 아닌 ESM파일임을 명확히 하기 위해 ESM의 파일 확장자는 mjs를 사용할 것을 권장. </p>
<pre><code>&lt;script type = &quot;module&quot; scr = &quot;app.mjs&quot;&gt; &lt;/script&gt;</code></pre><p><img src="https://images.velog.io/images/boram_in/post/043a6515-bb72-45b3-bd39-087c6ccb9726/image.png" alt=""></p>
<p>ESM은 파일 자체의 독자적인 모듈 스코프를 제공한다. 따라서 모듈 내에서 var 키워드로 선언한 변수는 더는 전역 변수가 아니며 window 객체의 프로퍼티도 아니다. </p>
<hr/> 

<h3 id="4832-export-키워드">48.3.2 export 키워드</h3>
<p>모듈은 독자적인 모듈 스코프를 갖는다. 따라서 모듈 내부에서 선언한 모든 식별자는 기본적으로 해당 모듈 내부에서만 참조할 수 있다. 모듈 내부에서 선언한 식별자를 외부에 공개하여 다른 모듈들이 재사용할 수 있게 하려면 export 키워드를 사용한다. </p>
<ul>
<li>export 키워드는 선언문 앞에 사용하며 변수, 함수, 클래스 등 모든 식별자를 export할 수 있다 
<img src="https://images.velog.io/images/boram_in/post/7b7a40b3-9256-48dd-935f-3f82e60d3582/image.png" alt=""></li>
<li>선언문 앞에 매변 export 키워드를 붙이는 것이 번거롭다면 export 할 대상을 하나의 객체로 구성하여 한 번에 export 할 수도 있다. 
<img src="https://images.velog.io/images/boram_in/post/39e64da4-335c-4619-93de-cb004633aa15/image.png" alt=""></li>
</ul>
<hr/>

<h3 id="4833-import-키워드">48.3.3 import 키워드</h3>
<p>다른 모듈에서 공개(export)한 식별자를 자신의 모듈 스코프 내부로 로드하려면 import 키워드를 사용한다. 다른 모듈이 export한 식별자 이름으로 import해야 하며 ESM의 경우 파일 확장자를 생략할 수 없다 
<img src="https://images.velog.io/images/boram_in/post/3273d057-440c-4853-b6d1-85dc3611fc84/image.png" alt=""></p>
<p>위 예제의 app.mjs는 애플리케이션 집입점이므로 반드시 script 태그로 로드해야 한다. 하지만 lib.mjs는 app.mjs의 import 문에 의해 로드되는 의존성이다. 따라서 예제 48-12.mjs는 script 태그로 로드하지 않아도 된다.</p>
<p>모듈이 export한 식별자 이름을 일일이 지정하지 않고 하나의 이름으로 한 번에 import할 수도 있다. 이때 import되는 식별자는 as 뒤에 지정한 이름의 객체에 프로퍼티로 할당된다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/4d616da7-5c7a-41a5-857e-534ce8b3ec51/image.png" alt=""></p>
<ul>
<li>모듈이 export한 식별자 이름을 변경하여 import할 수도 있다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/5e66d035-303c-45e3-9123-694081272e5b/image.png" alt=""></p>
<ul>
<li>모듈에서 하나의 값만 export한다면 default 키워드를 사용할수 있다. default 키워드를 사용하는 경우 기본적으로 이름없이 하나의 값을 epxort한다. <pre><code>export default x =&gt; x * x; </code></pre></li>
</ul>
<p>default 키워드를 사용하는 경우  var, let, const 키워드는 사용할 수 없으며 default 키워드와 함께 export한 모듈은 {} 없이 임의의 이름으로 import한다 </p>
<pre><code>//app.mjs
import square from &#39;./lib.mjs&#39;

console.log(square(3)); //9</code></pre><hr/>]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 딥다이브] 44장 REST API ]]></title>
            <link>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-44%EC%9E%A5-REST-API</link>
            <guid>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-44%EC%9E%A5-REST-API</guid>
            <pubDate>Wed, 12 Jan 2022 05:11:22 GMT</pubDate>
            <description><![CDATA[<h1 id="rest-api">REST API</h1>
<blockquote>
<p>REST(REpresentational State Transfer)는 HTTP/1.0과 1.1 스펙 작성에 참여했고 아파치 HTTP 서버 프로젝트의 공동 설립자이 로이 필딩의 2000년 논문에서 처음 소개되었다. 발표 당시의 웹이 HTTP를 제대로 사용하지 못하고 있는 상황을 보고 HTTP의 장점을 최대한 활용할 수 있는 아키텍처로 REST를 소개했고 이에 맞게 디자인 하도록 유도하고 있다. ➡️ REST 원칙을 성실히 지키면 &quot;RESTful&quot;이라고 표현한다. </p>
</blockquote>
<ul>
<li>REST : HTTP를 기반으로 클라이언트가 서버의 리스소에 접근하는 방식을 규정한 아키텍터</li>
<li>REST API : REST를 기반으로 서비스 API를 구현한 것</li>
</ul>
<HR/>

<h2 id="441-rest-api의-구성">44.1 REST API의 구성</h2>
<p>REST API는 자원, 행위, 표현의 3가지 요소로 구성된다. REST는 자체 표현 구조로 구성되어 REST API만으로 HTTP 요청의 내용을 이해할 수 있다. </p>
<table>
<thead>
<tr>
<th align="center">구성 요소</th>
<th>내용</th>
<th>표현 방법</th>
</tr>
</thead>
<tbody><tr>
<td align="center">자원(RESOURCE)</td>
<td>자원</td>
<td>URI(엔드 포인트)</td>
</tr>
<tr>
<td align="center">행위(VERB)</td>
<td>자원에 대한 행위</td>
<td>HTTP 요청 메서드</td>
</tr>
<tr>
<td align="center">표현(representations)</td>
<td>자원에 대한 행위의 구체적 내용</td>
<td>페이로드</td>
</tr>
</tbody></table>
<hr/>

<h2 id="442-rest-api-설계-원칙">44.2 REST API 설계 원칙</h2>
<p>REST에서 가장 중요한 기본적 원칙은 두 가지. ⭐ <strong>URI는 리스소를 표현하는데 집중</strong>, <strong>메서드는 HTTP 요청 메서드를 통해</strong>⭐ 하는 것이 RESTful API를 설계하는 중심 규칙이다. </p>
<h3 id="1-uri는-리소스를-표현해야-한다">1. URI는 리소스를 표현해야 한다.</h3>
<p>URI는 리소스를 표현하는데 중점을 둬야. 리소스를 식별할 수 있는 이름은 동사보다 명사를 사용한다. 따라서 이름에 get 같은 행위에 대한 표현이 들어가서는 안 된다. </p>
<pre><code># bad
GET / getTodos / 1 ----(get ❌)
GET / todos / show / 1 ----(show ❌)

# good
GET / todos /1 </code></pre><h3 id="2-리소스에-대한-행위는-http-요청-메서드로-표현한다">2. 리소스에 대한 행위는 HTTP 요청 메서드로 표현한다</h3>
<p>HTTP 요청 메서드는 클라이언트가 서버에게 요청의 종류와 목적(리소스에 대한 행위)을 알리는 방법이다. 주로 5가지 요청 메서드(GET, POST, PUT, PATCH, DELETE 등)를 사용해 CRUD를 구현한다 </p>
<table>
<thead>
<tr>
<th>HTTP 요청 메서드</th>
<th>종류</th>
<th>목적</th>
<th>페이로드</th>
</tr>
</thead>
<tbody><tr>
<td>GET</td>
<td>index/retrieve</td>
<td>모든/ 특정 리스소 취득</td>
<td>❌</td>
</tr>
<tr>
<td>POST</td>
<td>create</td>
<td>리소스 생성</td>
<td>⭕</td>
</tr>
<tr>
<td>PUT</td>
<td>replace</td>
<td>리소스의 전체 교체</td>
<td>⭕</td>
</tr>
<tr>
<td>PATCH</td>
<td>modify</td>
<td>리소스의 일부 수정</td>
<td>⭕</td>
</tr>
<tr>
<td>DELETE</td>
<td>delete</td>
<td>모든/특정 리소스 삭제</td>
<td>❌</td>
</tr>
</tbody></table>
<blockquote>
<p>🙋 그래서 우리가 흔히 글을 포스팅한다고 하고 게임 등을 패치 한다고 표현하는건가? </p>
</blockquote>
<p>리소스에 대한 행위는 HTTP 요청 메서드를 통해 표현하며 URI에 표현하지 않는다. 예를 들어, 리소스를 취득하는 경우에는 GET, 리소스를 삭제하는 경우에는 DELETE를 사용하여 리소스에 대한 행위를 명확히 표현한다.</p>
<pre><code># BAD 
GET / todos / delete / 1

# GOOD
DELETE / todos / 1</code></pre><HR/>

<h2 id="443-json-sever를-이용한-rest-api-실습">44.3 JSON Sever를 이용한 REST API 실습</h2>
<p>HTTP 요청을 전송하고 응답을 받으려면 서버가 필요. JSON Sever을 사용해서 가상 REST API 서버를 구축해 HTTP 요청을 전송하고 응답을 받는 실습을 진행해보자.</p>
<p><img src="https://images.velog.io/images/boram_in/post/a5a3e41c-222c-41c5-989c-516597ac8072/image.png" alt=""></p>
<hr/>

<h3 id="4434-get-요청">44.3.4 GET 요청</h3>
<p>todos 리소스에서 모든 todo를 취득(index)한다.
<img src="https://images.velog.io/images/boram_in/post/909e5d7f-a289-4931-b2cc-836b25a8c7e7/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/66174f10-25d5-4bc6-b50a-deee513e253a/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/8b0ad51a-c573-4655-b036-020a42132885/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/boram_in/post/cef744c1-8fc9-4aef-ba6d-d446cebc32c4/image.png" alt="">
todo 리소스에서 id를 사용해 특정 todo를 취득한다. public 폴더에 다음 get_retrieve.html을 추가하고 브라우저에서 <a href="http://localhost:3000/get_retrieve.html%EB%A1%9C">http://localhost:3000/get_retrieve.html로</a> 접속한다
<img src="https://images.velog.io/images/boram_in/post/62c30716-122a-4b19-b295-3b49861198da/image.png" alt=""></p>
<h3 id="4435-post-요청">44.3.5 POST 요청</h3>
<p>todos 리소스에 새로운 todo를 생성한다. POST 요청 시에는 setRequestHeader 메서드를 사용해 요청 몸체에 담아 서버로 전송할 페이로드의 MIME 타입을 지정해야 한다. 
<img src="https://images.velog.io/images/boram_in/post/5758c228-da12-46e2-8512-8ce3b5a1e816/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/7c16ce86-64c5-4574-b9a8-244cf925a2df/image.png" alt=""></p>
<hr/> 

<h3 id="4436-put-요청">44.3.6 PUT 요청</h3>
<p>PUT은 특정 리소스 전체를 교체할 때 사용한다. 다음 예제에서는 todos리소스에서 id로 todo를 특정하여 id를 제외한 리소스 전체를 교체. PUT 요청 시에는 setRequestHeader 메서드를 사용해 요청 몸체에 담아 서버로 전송할 페이로드이 MIME 타입을 지정해야. 
<img src="https://images.velog.io/images/boram_in/post/b509cd19-df70-47c1-a70d-514702f8539e/image.png" alt=""></p>
<blockquote>
<p>💫에러났었음!💫
<img src="https://images.velog.io/images/boram_in/post/0f152fd3-6cb6-4145-bab4-d52cf613c5fc/image.png" alt="">
우선 id:4 짜리가 없기도 했구요. 교재를 그대로 타이핑한 것은 아니었고. 그리고 send에서 id:1만 바꾸면 되는게 아니라 open에서 /1로도 바꿔야 에러가 나지 않는다 </p>
</blockquote>
<hr/>

<h3 id="4437-patch-요청">44.3.7 PATCH 요청</h3>
<p>PATCH는 특정 리소스의 일부를 수정할 때 사용. PATCH 요청 시에는 setRequestHeader 메서드를 사용해 요청 몸체에 담아 서버로 전송할 페이로드의 MIME 타입을 지정해야 한다. 
<img src="https://images.velog.io/images/boram_in/post/29a56911-0485-40e7-95e3-6416d86199da/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/600ff768-1f9f-48a7-ba15-30d1bc8c0ac1/image.png" alt=""></p>
<h3 id="4438-delete-요청">44.3.8 DELETE 요청</h3>
<p>todos 리소스에서 id를 사용해 todo를 삭제한다. 
<img src="https://images.velog.io/images/boram_in/post/2a32518a-2765-4165-8250-22cb6a499a1b/image.png" alt="">
<img src="https://images.velog.io/images/boram_in/post/bdf3bf36-3c4c-422e-9e85-e49e84fd1bca/image.png" alt=""></p>
<hr/>

<blockquote>
<h2 id="til">TIL</h2>
</blockquote>
<ul>
<li>GET, POST, PUT, PATCH, DELETE 를 &#39;한 번 해봤다&#39; 정도! </li>
<li>REST API 관련한 요구가 자격요건 혹은 우대사항에서 많이 보이는데 개념을 잡을 수 있었고 이후에 노드 스터디에서 자세한 것은 직접 짜봐야겠다. </li>
<li>중간중간 코드가 되게 어렵게도? 낯설기도? 한데 복습하면서 보면 그렇게 어렵지 않다. </li>
<li>결국
  [만들기]<ul>
<li>** new **로 XMLHttpRequest를 생성해주고 (나 이제부터 시작할거야~ 선언)
[초기화]</li>
<li>** open ** 으로 열고 ( ) 안에 어떤 작업을 수행할지 적어주고 </li>
<li>** send **로 요청을 전송하고(단순 get이 아니고 내가 보내는 거면 JSON.stringfy로 페이로드 해주고)</li>
<li>** onload ** 로 성공한 경우 발생할 것 else로 실패시 발생할 것을 지정해주는 것!<ul>
<li>패턴화를 하면 순서도 일관적으로 짤 수 있고 최소한 헤메지 않고 만들 수 있더라!  </li>
</ul>
</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 딥다이브] 42장 비동기 프로그래밍]]></title>
            <link>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-42%EC%9E%A5-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
            <guid>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-42%EC%9E%A5-%EB%B9%84%EB%8F%99%EA%B8%B0-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</guid>
            <pubDate>Wed, 12 Jan 2022 01:42:11 GMT</pubDate>
            <description><![CDATA[<h1 id="42장-비동기-프로그래밍">42장 비동기 프로그래밍</h1>
<p><img src="https://images.velog.io/images/boram_in/post/5e298134-05cc-41d1-9ae9-c63b38f29184/%EB%B9%84%EB%8F%99%EA%B8%B0.gif" alt=""></p>
<blockquote>
<p>🙋 비동기 프로그래밍! 말은 엄청 많이 들어봤다. 그런데 과연 뭘까??? </p>
</blockquote>
<h2 id="421-동기-처리와-비동기-처리">42.1 동기 처리와 비동기 처리</h2>
<p>앞서 실행 컨텍스트에서 공부한 것처럼 함수를 호출하면 함수가 코드가 평가돼서 함수 실행 컨텍스트가 생성됨 ➡️ 생성된 함수 실행 컨텍스트는 실행 컨텍스트 스택(콜 스택)에 푸시되고 ➡️ 함수 코드가 실행된다 ➡️ 함수 콛으의 실행이 종료되면 함수 실행 컨텍스트는 실행 컨텍스트 스택에서 팝되어 제거된다. </p>
<p>자바스크립트 엔진은 단 하나의 실행 컨텍스트 스택을 갖는다. 이는 함수를 처리할 수 있는 창구가 단 하나이며, 동시에 2 개 이상의 함수를 동시에 실행할 수 없다. 
<img src="https://images.velog.io/images/boram_in/post/cf7f5383-bf29-4f06-afe8-b017293a12eb/image.png" alt="">
실행 컨텍스트 스택의 최상위 요소인 &quot;실행 중인 실행 컨텍스트&quot;를 제외한 모든 실행 컨텍스트는 모두 싷행을 기다리는 태스크(task)들이다. 대기 중인 task들은 현재 실행 중인 실행 컨텍스트가 팝되어 실행 컨텍스트 스택에서 제거되면, 즉 지금 실행 중인 애가 끝나면 실행된다. </p>
<p>이처럼 자바스크립트 엔진은 한 번에 하나의 태스크만 실행할 수 있는 싱글 스레드(single thread)방식으로 동작하낟. 싱글 스레든느 한 번에 하나의 태스크만 실행할 수 있으므로 시간이 걸리는 태스크를 실핼하면 ⭐<strong>블로킹(작업중단)</strong>⭐이 발생. 
<img src="https://images.velog.io/images/boram_in/post/3239f257-77b2-4b9f-9a4e-1a811f5b5cae/image.png" alt=""></p>
<blockquote>
<p>위처럼 실행 중인 태스크가 종료될 때까지 다음에 실행될 태스크가 대기하는 방식을 동기처리라고 한다. 동기는 실행 순서가 보장된다는 장점이 있지만 태스크가 종료될 때까지 이후 태스크들이 블로킹되는 단점이있다. 
<img src="https://images.velog.io/images/boram_in/post/f419e812-41cc-4c0a-81ae-352546e59aef/image.png" alt=""></p>
</blockquote>
<p>위 예제를 타이머 함수인 setTimeout을 사용해서 수정해보자 </p>
<p><img src="https://images.velog.io/images/boram_in/post/2647e60c-78d6-464f-8b25-9d649657138b/image.png" alt=""></p>
<blockquote>
<ul>
<li>setTimeout 함수는 위 lazy처럼 일정 시간 경과 후 콜백함수를 호출하지만 setTimeout 함수 이후의 태스크를 블로킹하지 않고 곧바로 실행한다. </li>
</ul>
</blockquote>
<ul>
<li>이처럼 실행 중 태스크가 종료되지 않은 상태여도 다음 태스크를 곧바로 실행하는 방식을 ⭐<strong>비동기처리</strong>⭐라고 한다.
<img src="https://images.velog.io/images/boram_in/post/f634a944-c6ef-4fd1-b416-905c91e97692/image.png" alt=""></li>
<li>비동기처리를 수행하는 함수는 전통적으로 콜백 패턴을 사용. 근데 콜백 패턴이 콜백 헬(callback hell)을 발생시켜 가독성이 구려지고 비동기 처리 중 발생한 에러의 예외처리가 곤란하며, 여러 개의 비동기 처리를 한 번에 처리하는 데도 한계가 존재. </li>
<li><strong>타이머 함수인 setTimeout과 setInterval, HTTP 요청, 이벤트 핸들러는 비동기 처리방식으로 동작하며</strong> 이벤트 루프와 태스크 큐와 관련이 있다.</li>
</ul>
<hr> 

<h2 id="422-이벤트-루프와-태스크-큐">42.2 이벤트 루프와 태스크 큐</h2>
<p>근데 싱글스레드치고는 브라우저가 동작할 때 여러가지 많은 태스크가 동시에 처리되는 것처럼 느껴진다. 예를 들어 HTML 요소가 애니메이션 효과를 통해 움직이면서 이벤트를 처리하기도, HTTP 요청을 통해 서버로부터 데이터를 가져오면서 렌더링하기도, 이처럼 자바스크립트의 동시성을 지원하는 것이 바로 *<em>⭐ 이벤트 루프 ⭐ *</em></p>
<p><img src="https://images.velog.io/images/boram_in/post/e3d6254b-5b87-47d1-8847-02b44b93ee6a/%EB%B9%84%EB%8F%99%EA%B8%B0.gif" alt=""></p>
<p>이벤트 루프는 브라우저에 내장되어 있는 기능 중 하나. 구글의 V8 자바스크립트 엔진을 비롯한 대부분의 자바스크립트 엔진은 크게 2개의 영역으로 구분할 수 있다. </p>
<blockquote>
<ul>
<li><strong>call stack</strong> 🙋 : 실행 컨텍스트에서 살펴본 바와 같이 소스코드(전역 코드나 함수 코드 등) 평가 과정에서 실행 컨텍스트가 추가되고 제거되는 스택 자료구조인 실행 컨텍스트 스택이 바로 콜 스택 </li>
</ul>
</blockquote>
<ul>
<li><strong>힙</strong> 🙋 : 힙은 객체가 저장되어 있느 메모리 공간. 콜 스택의 요소인 실행 컨텍스트는 힙에 저장된 객체를 참조한다. 메모리에 값을 저장하려면 먼저 값을 저장할 메모리 공간의 크기를 결정해야 한다. 객체는 원시 값과 달리 크기가 정해져 있지 않아 할당해야 할 메모리 공간의 크기를 런타임에 결정해야 한다. 따라서 힙은 구조화 되어 있지 않은 특징이 있다.</li>
</ul>
<p>콜 스택과 힙으로 구성되어 있는 자바스크립트 엔진은 단순히 태스크가 요청되면 콜 스택을 통해 요청된 작업을 순차적으로 실행할 뿐. </p>
<ul>
<li>*<em>비동기 처리에서 소스코드의 평가와 실행을 제외한 모든 처리는 자바스크립트 엔진을 구동하는 환경인 브라우저 또는 노드가 담당한다. *</em></li>
</ul>
<p>예를 들어, 비동기 방식으로 동작하는 setTimeout의 콜백 함수의 평가와 실행은 자바스크립트 엔진이 담당하지만 호출 스케줄링을 위한 타이머 설정과 콜백함수 등록은 브라우저 또는 노드가 담당. 이를 위해 브라우저 환경은 태스크 큐와 이벤트 루프를 제공한다. </p>
<blockquote>
<ul>
<li>*<em>태스크 큐(task queue/ event queue/ callback queue) *</em> 🙋:  setTimeout이나 setInterval과 같은 비동기 함수의 콜백함수 또는 이벤트 핸들러가 일시적으로 보관되는 영역. 태스크 큐와는 별도로 프로미스의 후속 처리 메서드의 콜백 함수가 일시적으로 보관되는 마이크로 태스크 큐도 존재.</li>
</ul>
</blockquote>
<ul>
<li><strong>이벤트 루프(event loop)</strong> 🙋 : 이벤트 루프는 콜 스택에 현재 실행 중인 실행 컨텍스트가 있는지, 그리고 태스크 큐에 대기중인 함수(콜백 함수, 이벤트 핸들러등)가 있는지 반복해서 확인한다. 만약 콜 스택이 비어 있고 태스크 큐에 대기중인 함수가 있다면 이벤트 루프는 순차적으로(FIFO)태스크 큐에 대기중인 함수를 콜 스택으로 이동시킨다. 이 때 콜스택으로 이동한 함수는 실행된다. 즉, 태스크 큐에 일시 보관된 함수들은 비동기 처리 방식으로 동작. </li>
</ul>
<p>*<em>비동기 함수인 setTimeout의 콜백함수는 태스크 큐에 푸시되어 대기하다가 콜 스택이 비게 되면, 전역 코드 및 명시적으로 호출된 함수가 모두 종료되면 비로소 콜 스택에 푸시되어 실행된다. 
*</em></p>
<p>자바스크립트는 싱글 스레드로 동작. 근데 브라우저는 아님. 만약 모든 자바스크립트 코드가 자바스크립트 엔진에서 싱글 스레드 방식으로 동작하면 비동기로 동작할 수 없다. <strong>즉, 자바스크립트 엔진은 싱글 스레드로 동작하지만 브라우저는 멀티 스레드이다.</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 딥다이브] 35장 스프레드 문법]]></title>
            <link>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-35%EC%9E%A5-%EC%8A%A4%ED%94%84%EB%A0%88%EB%93%9C-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-35%EC%9E%A5-%EC%8A%A4%ED%94%84%EB%A0%88%EB%93%9C-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Tue, 11 Jan 2022 12:25:59 GMT</pubDate>
            <description><![CDATA[<h1 id="35장-스프레드-문법">35장 스프레드 문법</h1>
<p>ES6에서 도입된 스프레드 문법spread syntax(전개 문법)은 ... 하나로 뭉쳐 있는 여러 값들의 집합을 펼쳐서 개별적인 값들의 목록으로 만든다. 스프레드 문법을 사용할 수 있는 대상은 Array, String, Map, Set, DOM 컬렉션, arguments와 같이 for...of 문으로 순회할 수 있는 이터러블에 한정된다. 
<img src="https://images.velog.io/images/boram_in/post/617fb227-68d6-4f80-976a-4593512ff07f/image.png" alt="">
위의 1 2 3 은 값이 아니라 값들의 목록. 즉, 스프레드 문법의 결과는 값이 아니다. 이는 스프레드 문법 ...이 피연산자를 연산하여 값을 생성하는 연산자가 아님을 의미. 따라서 스프레드 문법의 결과는 변수에 할당할 수 없다.
<img src="https://images.velog.io/images/boram_in/post/4a50c67e-d315-4f40-b891-0d28be66dfc2/image.png" alt="">
이처럼 스프레드 문법의 결과물을 값으로 사용할 수 없고, 다음과 같이 쉼표로 구분한 값의 목록을 사용하는 문맥에서만 사용할 수 있다. </p>
<ul>
<li>함수 호출문의 인수 목록</li>
<li>배열 리터럴의 요소 목록</li>
<li>객체 리터럴의 프로퍼티 목록</li>
</ul>
<hr> 

<h2 id="351-함수-호출문의-인수-목록에서-사용하는-경우">35.1 함수 호출문의 인수 목록에서 사용하는 경우</h2>
<p>요소들의 집합인 배열을 펼펴서 개별적인 값들의 목록으로 만든 후, 이를 함수의 인수 목록으로 전달해야 하는 경우가 있다. 
<img src="https://images.velog.io/images/boram_in/post/2ae7083c-6bfe-4856-943a-c1611c2e3e5a/image.png" alt=""></p>
<ul>
<li><p>Math.max 메서드는 매개변수 개수를 확정할 수 없는 가변 인자 함수. 다음과 같이 개수가 정해져 있지 않은 여러 개의 숫자를 인수로 전달 받아 인수 중에서 최대값을 반환. </p>
</li>
<li><p>근데 숫자s가 아닌 배열을 인수로 전달하면 최대값 못 구함. 그래서 NaN을 반환.</p>
</li>
<li><p>🙋 이 같은 문제를 해결하기 위해 배열을 펼쳐서 개별 값의 목록으로 만든 후 인수로 전달해야 한다. (1, 2, 3으로 펼쳐서) </p>
</li>
<li><p>스프레드 문법이 제공되기 이전에는 배열을 펼쳐서 요소들의 목록을 함수의 인수로 전달하고 싶은 경우 Function.prototype.apply을 사용했다. 
<img src="https://images.velog.io/images/boram_in/post/976d5d7d-33ed-4c77-925b-0d929e4d89a3/image.png" alt=""></p>
</li>
<li><p>스프레드 문법을 사용하면 더 간결하고 가독성이 좋다. 
<img src="https://images.velog.io/images/boram_in/post/40b9f86c-a812-4b8b-9c08-ed3e650a4c7e/image.png" alt=""></p>
</li>
</ul>
<p>스프레드 문법은 앞에서 살펴본 Rest 파라미터와 형태가 동일하여 혼동할 수 있으므로 주의할 필요가 있다. Rest 파라미터는 함수에 전달된 인수들의 목록을 배열로 전달 받기 위해 매개변수 이름 앞에 ...을 붙이는 것. 스프레드 문법은 여러 개의 값이 하나로 뭉쳐 있는 배열과 같은 이터러블을 펼쳐서 개별적인 값들의 목록을 만드는 것. 따라서 Rest 파라미터와 스프레드 문법은 서로 반대의 개념 
<img src="https://images.velog.io/images/boram_in/post/f101d689-602c-4f65-a048-76cf9aab3f15/image.png" alt=""></p>
<hr>

<h2 id="352-배열-리터럴-내부에서-사용하는-경우">35.2 배열 리터럴 내부에서 사용하는 경우</h2>
<h3 id="3521-concat">35.2.1 concat</h3>
<p>ES5 에서 2개의 배열을 1개의 배열로 결합하고 싶은 경우 배열 리터럴만으로 해결은 못하구 concat을 써야한다. 그러나 스프레드를 쓰면 다른 메서드를 쓰지 않아도 결합이 가능하다. 
<img src="https://images.velog.io/images/boram_in/post/0fb00878-43f5-4b1c-b276-c59a8dd4e5fa/image.png" alt=""></p>
<h3 id="3522-splice">35.2.2 splice</h3>
<p>ES5에서 어떤 배열의 중간에 다른 배열의 요소들을 추가하거나 제거하려면 splice 메서드를 사용. 이 때 splice 메서드의 세 번째 인수로 배열을 전달하면 배열 자체가 추가.
<img src="https://images.velog.io/images/boram_in/post/75dca5fe-e786-438e-8544-4567e4a49fe5/image.png" alt=""></p>
<ul>
<li>위 예제의 경우 splice 메서드의 세 번째 인수 [3,4]을 3,4로 헤체해 전달해야 한다. 그렇지 않으면 arr1에 arr2 배열 자체가 추가된다. 따라서 이러한 경우 Function.prototype.apply 메서드를 사용하여 splice 메서드를 호출해야 한다. apply 메서드의 두 번째 인수(배열) apply 메서드가 호출하는 함수에 헤체되어 전달된다.</li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/1fe36a20-319c-426d-b116-dc67f44de40c/image.png" alt=""></p>
<blockquote>
</blockquote>
<ul>
<li><p>apply 메서드의 2번째 인수(배열)은 apply 메서드가 호출한 splice 메서드의 인수 목록이다. </p>
</li>
<li><p>apply 메서드의 2번째 인수 [1,0].concat(arr2)는 [1,0,3,4]으로 평가된다.</p>
</li>
<li><p>따라서 splice 메서드에 apply 메서드의 2번째 인수 [1,0,3,4]이 헤체되어 전달된다.</p>
</li>
<li><p>즉, arr3[1]부터 0개 요소를 제거하고 그 자리에 새로운 요소(3,4)를 삽입한다. </p>
</li>
<li><p>스프레드 문법을 사용하면 다음과 같이 더욱 간결하고 가독성 좋게 표현할 수 있다</p>
</li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/0d417060-a7e2-4dbd-9495-73e177eb3191/image.png" alt=""></p>
<hr/>

<h3 id="3523-배열-복사">35.2.3 배열 복사</h3>
<p>ES5에서 배열을 복사하려면 slice 메서드를 사용한다 
<img src="https://images.velog.io/images/boram_in/post/5c325c68-6e42-4369-88ae-cfd3186740be/image.png" alt="">
스프레드 문법을 사용하면 다음과 같이 더욱 간결하고 가독성 좋게 표현할 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/4c38a634-592f-424d-a593-b7369ca3239a/image.png" alt="">
이때 false 값을 보면 알 수 있듯 얕은 복사를 하여 새로운 복사본을 형성(스프레드, slice 모두) </p>
<hr>

<h3 id="3524-이터러블을-배열로-변환">35.2.4 이터러블을 배열로 변환</h3>
<p>ES5에서 이터러블 배열로 변환하려면 Function.prototype.apply 또는 Function.prototype.call 메서드를 사용하여 slice 메서드를 호출해야 한다.
<img src="https://images.velog.io/images/boram_in/post/c1c0ee13-4e2e-4951-a727-68e4e8ef36d7/image.png" alt=""></p>
<ul>
<li>스프레드 문법을 사용하면 좀 더 간편하게 이터러블을 배열로 변환 가능. arguments 객체는 이터러블이면서 유사 배열 객체. 따라서 스프레드 문법의 대상이 될 수 있다. 근데 더 좋은 방법은 Rest 파라미터를 이용하는 것이다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/80bffc1b-ab4d-48bd-9a78-e89466da1bd9/image.png" alt=""></p>
<ul>
<li>그러나 앞서 살펴본 것처럼 이터러블이 아닌 유사 배열 객체는 스프레드 문법이 될 수 없으며 ES6에서 도임된 Array.from 메서드를 사용해서 유사 배열 객체 또는 이터러블을 인수로 전달 받아 배열로 변환하여 반환 </li>
</ul>
<hr> 

<h2 id="353-객체-리터럴-내부에서-사용하는-경우">35.3 객체 리터럴 내부에서 사용하는 경우</h2>
<p>Rest 프로퍼티와 함께 2021년 1월 현재 TS39 프로세스의 stage4(Finished) 단계에 제안되어 있는 스프레드 프로퍼티를 사용하면 객체 리터럴의 프로퍼티 목록에서도 스프레드 문법을 사용할 수 있다. 스프레드 문법의 대상은 이터러블이어야 하지만 스프레드 프로퍼티 제안은 일반 객체를 대상으로도 스프레드 문법을 허용한다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/51e19c6d-61f1-4831-84bb-20367f29bfc2/image.png" alt=""></p>
<ul>
<li>스프레드 프로퍼티가 제안되기 이전에는 ES6에서 도입된 Object.assign 메서드를 사용해 여러개의 객체를 병합하거나 특정 프로퍼티를 변경 or 추가 </li>
<li>스프레드 프로퍼티는 Object.assign 메서드를 대체할 수 있는 간편한 문법이다</li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/c490e067-9ae6-4b3f-8660-fc1f73014c82/image.png" alt=""></p>
<hr>

<h1 id="36장-디스트럭처링-할당">36장 디스트럭처링 할당</h1>
<p>디스트럭처링 할당(destructuring assginment(구조 분해 할당)은 구조화된 배열과 같은 이터러블 또는 객체를 구조 파괴하여 1개 이상의 변수에 개별적으로 할당하는 것. 필요한 값만 추출하여 변수에 할당할 때 유용한다. </p>
<h2 id="361-배열-디스트럭처링-할당">36.1 배열 디스트럭처링 할당</h2>
<p>ES5 에서 구조화된 배열을 디스트럭처링하여 1개 이상 변수에 할당하는 방법
<img src="https://images.velog.io/images/boram_in/post/cb45c9b3-925b-444a-a281-5e9ddbe95e5d/image.png" alt=""></p>
<p>ES6의 배열 디스트럭처링 할당은 배열의 각 요소를 배열로부터 추출하여 1개 이상의 변수에 할당. 이때 <strong>배열 디스트럭처링 할당의 대상(할당문의 우변)은 이터러블이어야 하며, 할당 기준은 배열의 인덱스다.</strong> 즉, 순서대로 할당된다.
<img src="https://images.velog.io/images/boram_in/post/e6dbf4cc-65b0-4a17-a9d6-664ac27531c2/image.png" alt="">
배열 디스트럭처링 할당을 위해서는 할당 연산자 왼쪽에 값을 할당받을 변수를 선언. 이때 변수를 배열 리터럴 형태로 선언하며 우변에 이터러블을 할당하지 않으면 에러가 발생.
<img src="https://images.velog.io/images/boram_in/post/e18de273-b56f-4a25-848e-d20305021d0e/image.png" alt="">
배열 디스트럭처링 할당 변수의 선언문은 다음처럼 선언과 할당을 분리할 수도 있다. 단, 이 경우 const 키워드로 변수를 선언할 수 없으므로 권장하지 않는다. </p>
<p>배열 디스트럭처링 할당의 기준은 배열의 인덱스. 즉, 순서대로 할당된다. 이때 변수의 개수와 이터러블의 요소 개수가 반드시 일치할 필요가 없다. 
<img src="https://images.velog.io/images/boram_in/post/35b37952-9725-4825-8188-8ee82e464100/image.png" alt=""></p>
<ul>
<li>배열 디스트럭처링 할당을 위한 변수에 기본값 설정할 수 있다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/36e3181b-6af3-4daa-b7f4-5d52a80967c8/image.png" alt=""></p>
<ul>
<li>기본값보다 할당된 값이 우선한다 </li>
<li>배열 디스트럭처링 할당은 배열과 같은 이터러블에서 필요한 요소만 추출하여 변수에 할당하고 싶을 때 유용. 다음 예제는 URL을 파싱하여 protocol, host, path 프로퍼티를 갖는 객체를 생성해 반환.</li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/4eef3a1e-3a4d-4c82-9b60-4a1caa6ad7c6/image.png" alt=""></p>
<ul>
<li>배열 디스트럭처링 할당을 위한 변수에 Rest 파라미터와 유사하게 Rest요소 ... 을 사용할 수 있다. Rest 요소는 Rest 파라미터와 마찬가지로 반드시 마지막에 있어야 한다</li>
</ul>
<hr> 

<h2 id="362-객체-디스트럭처링-할당">36.2 객체 디스트럭처링 할당</h2>
<p>ES5에서 객체의 각 프로퍼티를 객체로부터 디스트럭처링 해 변수에 할당하기 위해서는 프로퍼티 키를 사용해야 한다. 
<img src="https://images.velog.io/images/boram_in/post/8a7ce0e0-5a76-4f7c-bba3-614d3087457a/image.png" alt=""></p>
<ul>
<li>ES6 객체 디스트럭처링 할당은 객체의 각 프로퍼티를 객체로부터 추출하여 1개 이상의 변수에 할당. 이때 객체 디스트럭처링 할당의 대상은 객체여야 하며** 할당 기준은 프로퍼티 키다.** 즉, 순서는 의미가 없으며 선언된 변수 이름과 프로퍼티 키가 일치하면 할당된다 </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/34cdfea1-391b-4493-b076-7e773e13691d/image.png" alt=""></p>
<p>배열 디스트럭처링 할당과 마찬가지로 객체 디스트럭처링 할당을 위해서는 할당 연산자 왼쪽에서 프로퍼티 값을 할당받을 변수를 선언해야 한다. 이때 변수를 객체 리터럴 형태로 선언한다. 
<img src="https://images.velog.io/images/boram_in/post/b436926c-0c58-4b03-bdad-268d8cfc474e/image.png" alt="">
할당하지 않을 일도 업겠지만 만약 할당 안하면 에러난다. 그리고 리터럴로 선언한 변수이다. 이는 프로퍼티 축약 표현을 통해 선언한 것이다. </p>
<ul>
<li>객체 디스트럭처링 할당은 객체를 인수로 전달받는 함수의 매개변수에도 사용할 수 있다.</li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/6e035d9e-e611-406f-83a8-6641534c8b1c/image.png" alt=""></p>
<ul>
<li>위 예제에서 객체를 인수로 받는 매개변수 todo에 객체 디스트럭처링 할당을 사용하면 좀 더 가독성 좋게 표현할 수 있다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/1baa536b-969f-4571-979e-beb17976b2fa/image.png" alt="">
배열의 요소가 객체인 경우 배열 디스트럭처링 할당과 객체 디스트럭처링 할당을 혼용할 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/cbae6c19-7cd5-4e8c-b048-9943b40917f3/image.png" alt=""></p>
<ul>
<li>중첩 객체의 경우에는 다음과 같이 사용한다 </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/940e3785-ceee-4de1-896f-9cfd5c7195aa/image.png" alt=""></p>
<ul>
<li>address 프로퍼티 키로 객체를 추출하고 이 객체의 city 프로퍼티 키로 값을 추출한다</li>
<li>객체 디스트럭처링 할당은 위한 변수에 Rest 파라미터나 Rest 요소와 유사하게 Rest 프로퍼티...을 사용할 수 있다. Rest 프로퍼티는 Rest 프로퍼티는 Rest 파라미터나 Rest 요소와 마찬가지로 반드시 마지막에 위치해야 한다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/6d6d0999-423b-4403-b02b-a00b1f1fd068/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 딥다이브] 34장 이터러블]]></title>
            <link>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-34%EC%9E%A5-%EC%9D%B4%ED%84%B0%EB%9F%AC%EB%B8%94</link>
            <guid>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-34%EC%9E%A5-%EC%9D%B4%ED%84%B0%EB%9F%AC%EB%B8%94</guid>
            <pubDate>Mon, 10 Jan 2022 05:23:42 GMT</pubDate>
            <description><![CDATA[<h2 id="341-이터레이션-프로토콜">34.1 이터레이션 프로토콜</h2>
<p>iteration protocol은 순회 가능한(itrable)한 자료구조를 만들기 위해 ECMAScript 사양에 정의하여 미리 약속한 규칙이다. ES6에서는 순회 가능한 자료구조를 이터레이션 프로토콜을 준수하는 이터러블로 통일해 for...of문, 스프레드 문법, 배열 디스트럭처링 할당의 대상으로 사용할 수 있도록 일원화했다. 이터레이션 프로토콜에는 이터러블 프로토콜과 이터레이터 프로토콜이있다.</p>
<ul>
<li><h4 id="이터러블-프로토콜iterable-protocol">이터러블 프로토콜(iterable protocol)</h4>
<p>well-known Symbol인 Symbol.iterator를 프로퍼키 키로 사용한 메서드를 직접 구현하거나 프로토타입 체인을 통해 상속 받은 Symbol.iterator 메서들르 호출하면 이터레이터 프로토콜을 준수한 이터레이터를 반환한다. 이러한 규약을 이터러블 프로토콜이라고 하며, ** 이터러블 프로토콜을 준수한 객체를 이터러블이라 한다. 이터러블은 for ... of 문으로 순회할 수 있으며 스프레드 문법과 배열 디스트럭처링 할당의 대상으로 사용할 수 있다. **</p>
</li>
<li><h4 id="이터레이터-프로토콜-iterator-protocol">이터레이터 프로토콜 (iterator protocol)</h4>
<p>이터러블의 Symbol.iterator 메서드를 호출하면 이터레이터 프로토콜을 준수한 이터레이터를 반환한다. 이터레이터는 next 메서드를 소유하며 next 메서들르 호출하면 이터러블을 순회하며 value와 done 프로퍼티를 갖는 ** 이터레이터 리절트 객체** 를 반환한다. 이러한 규약을 이터레이터 프로토콜이라 하며, ** 이터레이터 프로토콜을 준수한 객체를 이터레이터라 한다. ** 이러테이터는 이터러블의 요소를 검색하기 위한 포인터 역할을 한다. 
<img src="https://images.velog.io/images/boram_in/post/3331b023-0a87-4b06-a64e-cd7138805574/image.png" alt=""></p>
</li>
</ul>
<h3 id="3411-이터러블">34.1.1 이터러블</h3>
<p>이터러블 프로토콜을 준수한 객체를 이터러블이라 한다. 즉, 이터러블은 Symbol.iterator를 프로퍼티 키로 사용한 메서드를 직접 구현하거나 프로토타입 체인을 통해 상속받은 객체를 말한다. 
<img src="https://images.velog.io/images/boram_in/post/b3615067-6e57-4599-a8b2-e4267992002b/image.png" alt=""></p>
<ul>
<li>배열은 Array.prototype의 Symbol.iterator 메서드를 상속받는 이터러블. 이터러블은 for...of 문으로 순회할 수 있으며, 스프레드 문법과 디스트럭처링 할당의 대상으로 사용할 수 있다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/000477a5-a9f8-44a3-9ca2-9570a345e271/image.png" alt=""></p>
<ul>
<li>Symbol.iterator 메서드를 직접 구현하지 않거나 상속 받지 않은 일반 객체는 이터러블 프로토콜을 준수한 이터러블이 아님. 따라서 일반 객체는 for...of 문으로 순회할 수 없으며 스프레드 문법과 배열 디스트럭처링 할당의 대상으로 사용할 수 없다. </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/b62e2636-4c35-48b9-96da-b322b2c91a9e/image.png" alt=""></p>
<p>단, 2021 현재 stage 4 단계에 제안되어 있는 스프레드 프로퍼티 제안은 일반 객체에 스프레드 문법 사용을 허용한다. 그리고 일반 객체도 이터러블 프로토콜을 준수하도록 구현하면 이터러블 가능! </p>
<h3 id="3412-이터레이터">34.1.2 이터레이터</h3>
<p>이터러블의 Symbol.iterator 메서드를 호출하면 이터레이터 프로토콜을 준수한 이터레이터를 반환, <strong>이터러블의 Symbol.iterator 메서드가 반환한 이터레이터는 next 메서드를 갖는다</strong>
<img src="https://images.velog.io/images/boram_in/post/b4428165-d68b-4a0b-99f6-93cde899aa54/image.png" alt=""></p>
<ul>
<li>이터레이터의 next 메서드는 이터러블의 각 요소를 순회하기 위한 포인터의 역할을 한다. 즉 next 메서드를 호출하면 이터러블을 순차적으로 한 단계씩 순회하면서 순회 결과를 나타내는 이털이터 리절트 객체(iterator result object)를 반환한다.</li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/5a5abe35-2f1e-416a-b557-fbde2273b372/image.png" alt=""></p>
<ul>
<li>이터레이터 next 메서드가 반환하는ㄴ 이터레이터 리절트 객체의 value 프로퍼티는 현재 순회 중인 이터러블의 값, done은 순회 완료 여부. </li>
</ul>
<hr> 


<h2 id="342-빌트인-이터러블">34.2 빌트인 이터러블</h2>
<p>자바스크립트는 이터레이션 프로토콜을 준수한 객체인 빌트인 이터러블을 제공. </p>
<blockquote>
<p>Array, String, Map, Set, TypedArray(Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array), DOM data structure(NodeList, HTMLCollection), Arguments</p>
</blockquote>
<hr> 


<h2 id="343-forof문">34.3 for...of문</h2>
<p>for...of 문은 이터러블을 순회하면서 이터러블 요소를 변수에 할당. for...of 문의 문법은 다음과 같고 for ... in 문의 형식과 매우 비슷하다. </p>
<blockquote>
</blockquote>
<pre><code>for (변수선언문 of 이터러블) { ... }</code></pre><p>for...of 문은 내부적으로 이터레이터의 next 메서드를 호출해 이터러블을 순회하며, next 메서드가 반환한 이터레이터 리절트 객체의 value 프로퍼티 값은 for...of문의 변수에 할당. 그리고 이터레이터 리절트 객체의 done 값이 false이면 이터러블 순회를 계속하고 true이면 중단. </p>
<ul>
<li>for...in 문은 객체 프로토타입 체인 상 모든 프로토타입의 프로퍼티 중 프로퍼티 어트리뷰트 [[Enumerable]]의 값이 true인 프로퍼티를 순회하며 열거. 이때 프로퍼티 키가 심벌인 것은 열거하지 않는다 </li>
</ul>
<hr/> 

<h2 id="344-이터러블과-유사배열-객체">34.4 이터러블과 유사배열 객체</h2>
<p>유사 배열 객체는 마치 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고 length 프로퍼티를 갖는 객체. 유사 배열 객체는 length 프로퍼티를 갖기 때문에 for 문으로 순회할 수 있고 인덱스를 나타내는 숫자 형식의 문자열을 프로퍼티 키로 가지므로 마치 배열처럼 프로퍼티 값에 접근할 수 있다. </p>
<p><img src="https://images.velog.io/images/boram_in/post/e31b99e3-6745-4c2e-b906-3e2a77e8a539/image.png" alt=""></p>
<p>유사 배열 객체는 이터러블이 아닌 일반 객체다. 따라서 유사 배열 객체에는 Symbol.iterator 메서드가 없어 for...of 문으로 순회 할 수 없다. </p>
<ul>
<li>단 arguments, NodeList, HTMLCollection은 유사 배열 객체면서 이터러블이다. 정확히 말하면 ES6에서 이터러블이 도입되면서 유사 배열 객체인 객체에 Symbol.iterator 메서드를 구현해 이터러블이 되었다. 하지만 이터러블이 된 이후에도 length 프로퍼티를 가지며 인덱스로 접근할 수 있기에 유사배열이면서 이터러블인 것.</li>
<li>배열도 ES6에서 이터러블이 되었다</li>
<li>하지만 모든 유사 배열 객체가 이터러블인 것은 위에서 살펴본 것처럼 아니다. 다만 Array.from 메서드를 사용해 배열로 간단하게 변환할 수 있다. </li>
</ul>
<blockquote>
<p>** 복습 **
Array.from 메서드는 유사 배열 객체, 이터러블을 인수로 받아 배열로 변환해 반환한다. </p>
</blockquote>
<hr>

<h2 id="345-이터레이션-프로토콜의-필요성">34.5 이터레이션 프로토콜의 필요성</h2>
<p>이터러블은 for...of문, 스프레드 문법, 배열 디스트럭처링 할당과 같은 데이터 소비자(data consumer)에 의해 사용되므로 데이터 공급자(data producer)의 역할을 한다고 할 수 있다. </p>
<p>만약 다양한 데이터 공급자가 각자의 순회 방식을 갖는다면 데이터 소비자는 다양한 데이터 공급자의 순회 방식을 모두 지원해야 한다. 하지만 다양한 데이터 공급자가 이터레이션 프로토콜을 준수하도록 규정하면 데이터 소비자는 이터레이션 프로토콜만 지원하도록 구현하면 된다. </p>
<p>즉 이터러블을 지원하는 소비자는 내부에서 Symbol.iterator 메서드를 호출해 이터레이터를 생성하고 이터레이터의 next 메서드를 호출하여 이터러블을 순회하며 이터레이터 리절트 객체를 반환. 그리고 이터레이터 리절트 객체의 value/done 프로퍼티 값으 취득. </p>
<p>이처럼 이터레이션 프로토콜은 다양한 데이터 공급자가 하나의 순회 방식을 갖도록 규정하여 데이터 소비자가 효율적으로 다양한 공급자를 사용할 수 있도록 *<em>데이터 소비자와 데이터 공급자를 연결하는 인터페이스 역할을 한다. *</em></p>
<p><img src="https://images.velog.io/images/boram_in/post/85389cb7-fad7-4118-be71-b936a0e00433/image.png" alt=""></p>
<blockquote>
<p>*<em>즉, 하나의 규칙을 공통적으로 만드는 것! *</em></p>
</blockquote>
<hr>

<h2 id="346-사용자-정의-이터러블">34.6 사용자 정의 이터러블</h2>
<h3 id="3461-사용자-정의-이터러블-구현">34.6.1 사용자 정의 이터러블 구현</h3>
<p>이터레이션 프로토콜을 준수하지 않는 일반 객체도 이터레이션 프로토콜을 준수하도록 구현하면 사용자 정의 이터러블. 예를 들어, 피보나치 수열(1,2,3,5,8,13 ... )을 구현한 사용자 정의 이터러블을 구현해보자. 
<img src="https://images.velog.io/images/boram_in/post/e7a2acd2-9485-4162-9a9f-c4d5283dcd5b/image.png" alt="">
사용자 정의 이터러블은 이터레이션 프로토콜을 준수하도록 Symbol.iterator 메서드를 구현하고 Symbol.iterator 메서드가 next 메서드를 갖는 이터레이터를 반환하도록 한다. 그리고 이터레이터의 next 메서드는 done과 value 프로퍼티를 가지는 이터레이터 리절트 객체를 반환. for...of 문은 done 프로퍼티가 true가 될 때까지 반복.</p>
<ul>
<li>이터러블은 스프레드 문법의 대상이 될 수 있다</li>
<li>이터러블은 배열 디스트럭처링 할당의 대상이 될 수 있다</li>
</ul>
<h3 id="3462-이터러블을-생성하는-함수">34.6.2 이터러블을 생성하는 함수</h3>
<p>앞서 살펴본 fibonacci 이터러블은 내부에 수열의 최대값 max를 가지고 있다. 이 수열의 최대값은 고정되어 있고 외부에서 전달할 수 없는 아쉬움이 있다. 수정해보잣! 
<img src="https://images.velog.io/images/boram_in/post/375d4ff2-2c5a-485f-a10a-1bada5460445/image.png" alt=""></p>
<h3 id="3463-이터러블이면서-이터레이터인-객체를-생성하는-함수">34.6.3 이터러블이면서 이터레이터인 객체를 생성하는 함수</h3>
<p>앞서 살펴본 fiboFunc 함수는 이터러블을 반환. 만약 이털레이터를 생헝하려면 이터러블의 Symbol.iterator 메서드를 호출.</p>
<p><img src="https://images.velog.io/images/boram_in/post/31f9257f-4f0f-4113-8489-286563b8749c/image.png" alt=""></p>
<ul>
<li>이터러블이면서 이터레이터인 객체를 생성하면 Symbol.iterator 메서드를 호출하지 않아도 된다. Symbol.iterator 메서드는 this를 반환하므로 next 메서드를 갖는 이터레이터를 반환</li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/71e2ae1f-e7d8-4d83-8019-e27ec64af7cc/image.png" alt=""></p>
<ul>
<li>앞에서 살펴본 fiboFunc 함수를 이터러블이면서 이터레이터인 객체를 생성하여 변환하는 함수로 변경해보자 </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/8f6ea496-5275-4fdb-afb2-47729cee86ca/image.png" alt=""></p>
<h3 id="3464-무한-이터러블과-지연-평가">34.6.4 무한 이터러블과 지연 평가</h3>
<p>무한 이터러블을 생성하는 함수를 정의해보자. 이를 통해 무한수열을 간단히 구현할 수 있다.
<img src="https://images.velog.io/images/boram_in/post/f7fc5ba8-7699-4968-bc03-cdb4927daf28/image.png" alt=""></p>
<ul>
<li>이터러블은 데이터 공급자의 역할을 한다. 배열이나 문자열 등은 모든 데이터 메모리에 미리 확보한 다음 데이터를 공급한다. 하지만 위 예제의 이터러블은 지연 평가(lazy evaluation)를 통해 데이터를 생성한다 </li>
<li>지연 평가는 데이터가 필요한 시점 이전까지는 미리 데이터를 생성하지 않다가 데이터가 필요한 시점이 되면 그때야 비로소 데이터를 생성하는 기법이다. 즉 평가 결과가 필요할 때까지 평가를 늦추는 기법이 지연평가</li>
</ul>
<p>위 예제의 fiboFunc 함수는 무한 이터러블을 생성. 하지만 fiboFunc 함수가 생성한 무한 이터러블은 데이터를 공급하는 메커니즘을 구현한 것으로 데이터 소비자인 for ... of 문이나 배열 디스트럭처링 할당 등이 실행되기 이전까지 데이터를 생성하지 않는다</p>
<p>for...of문의 경우 이터러블을 순회할 때 내부에서 이터레이터의 next 메서드를 호출하는데 바로 이때 데이터가 생성된다. next 메서드가 호출되기 이전까지는 데이터를 생성하지 않는다. 즉 데이터가 필요할 때까지 데이터 생성은을 지연하다가 필요한 순간 만든다. </p>
<p>이처럼 지연평가를 사용하면 불필요한 데이터를 미리 생성하지 않고 필요한 순간에 생성하므로 빠른 실행 속도를 기대할 수 있고 불필요한 메모리를  소비하지 않으며 무한도 표현할 수 있는 장점이 있다. </p>
<blockquote>
<h2 id="til">TIL</h2>
<p>데이터 소비자 &amp; 데이터 공급자! 용어가 거창하기는 하지만 결국에 데이터를 실제로 쓰는(소비) 단, 데이터를 쏴주는(공급) 영역으로 이해를 하니 쉬웠다. 그리고 가운데서 하나의 인터페이스로(하나의 문법)으로 여러 흩어진 문법에서 하나의 표준문법을 정한 것으로 이해를 했다. 이렇게 효율성과 공통된 규칙을 정한 부분은 자바스크립트를 깊게 공부하면서 내가 매력을 느끼는 부분이다.
<img src="https://images.velog.io/images/boram_in/post/85389cb7-fad7-4118-be71-b936a0e00433/image.png" alt="">
스프레드 문법과 디스트럭처링 문법에 대해서도 깊이는 아니지만(곧 다음장, 다다음장에서 배울 예정) 다시 한 번 점검하게 되었다. 많이 사용하니 제대로 알고 가자!</p>
</blockquote>
<ul>
<li>for...of를 사용할 때 for...in이 익숙해서 몇 번 오타를 내었는데 실제로 나중에 서로 혼동할 수도 있으니 여기에 다시 한 번 정리! </li>
<li>for...of 문은 내부적으로 이터레이터의 next 메서드를 호출해 이터러블을 순회하며, next 메서드가 반환한 이터레이터 리절트 객체의 value 프로퍼티 값은 for...of문의 변수에 할당. 그리고 이터레이터 리절트 객체의 done 값이 false이면 이터러블 순회를 계속하고 true이면 중단. </li>
<li>for...in 문은 객체 프로토타입 체인 상 모든 프로토타입의 프로퍼티 중 프로퍼티 어트리뷰트 [[Enumerable]]의 값이 true인 프로퍼티를 순회하며 열거. 이때 프로퍼티 키가 심벌인 것은 열거하지 않는다 </li>
<li>지연 평가의 경우 장점과 개념은 알겠는데 여기서만 나오나? 조그 더 깊이 공부를 해봐야겠다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[자바스크립트 딥다이브] 27장 배열(3)]]></title>
            <link>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-27%EC%9E%A5-%EB%B0%B0%EC%97%B43</link>
            <guid>https://velog.io/@boram_in/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%94%A5%EB%8B%A4%EC%9D%B4%EB%B8%8C-27%EC%9E%A5-%EB%B0%B0%EC%97%B43</guid>
            <pubDate>Sat, 08 Jan 2022 11:01:51 GMT</pubDate>
            <description><![CDATA[<h2 id="279-배열-고차-함수">27.9 배열 고차 함수</h2>
<h3 id="배열하다가-왜-갑자기-고차함수가-나와요-🙋">배열하다가 왜 갑자기 고차함수가 나와요? 🙋</h3>
<ul>
<li>고차함수(High - Order Function,HOF)는 함수를 인수로 전달받거나 함수를 반환하는 함수! 자바스크립트는 일급 객체여서 함수를 값처럼 인수로 전달할 수 있으며 반환도 가능. 고차 함수는 가변 데이터를 피하고 불변성(immutability)을 지향하는 *<em>함수형 프로그래밍에 기반을 둔다. *</em></li>
</ul>
<h4 id="함수형-프로그래밍은-또-뭐야-🙋">함수형 프로그래밍은 또 뭐야? 🙋</h4>
<p>순순 함수와 보조 함수의 조합을 통해 조건문과 반복문을 제거해 복잡성을 해결하고 변수의 사용을 억제해 상태변경을 피하려는 프로그래밍 패러다임. 그거 왜 쓰나?  </p>
<ul>
<li>조건문이나 반복문은 로직의 흐름을 이해하기 어렵고 가독성을 해치며</li>
<li>변수 역시 누군가에 의해 언제든지 변경될 수 있어 오류의 원인이 될 수 있다</li>
</ul>
<blockquote>
<p>함수형 프로그래밍은 결국 순수 함수를 통해 부수 효과를 최대한 억제하여 오류를 피하고 프로그램의 안정성을 높이려는 노력의 일환! 자바스크립트는 고차 함수를 다수 지원. </p>
</blockquote>
<h3 id="2791-arrayprototypesort">27.9.1 Array.prototype.sort</h3>
<p>sort 메서드는 원본 배열을 직접 변경하며 정렬된 배열을 반환하며 오름차순으로 요소를 정렬.
<img src="https://images.velog.io/images/boram_in/post/e52a9b94-54d5-4a68-ab76-89aed3fc3be4/image.png" alt=""></p>
<ul>
<li>흠,, 한글도 정렬이 되구요. 영어가 우선이네요. </li>
<li>sort는 오름차순으로 요소를 정리한다. 그래서 내림차순으로 정리하려면 sort를 사용해서 오름차순으로 정렬한 후 reverse 메서들르 사용해서 순서를 뒤집는다. 
<img src="https://images.velog.io/images/boram_in/post/a07cb123-f808-4d05-98c9-a18a8f9b53da/image.png" alt=""></li>
</ul>
<h4 id="숫자는-조금-다르다">숫자는 조금 다르다.</h4>
<p>🙋 문자열은 정렬에는 문제가 없다. 그러나 숫자는 주의가 필요하다. 유니코드 코드 포인트 순서를 따른다. 
<img src="https://images.velog.io/images/boram_in/post/f69698ac-fc38-44a1-ac55-b5f856c34e08/image.png" alt=""></p>
<ul>
<li>그래서 되는 것처럼 보이지만 사실 그렇지 않다. 따라서 숫자 요소를 정렬할 때는 sort 메서드에 정렬 순서를 정의하는 비교함수를 인수로 전달해야 한다.
<img src="https://images.velog.io/images/boram_in/post/258f1232-bb95-4e04-ae06-2ab6e5bba09c/image.png" alt=""></li>
</ul>
<h4 id="객체">객체</h4>
<p>객체를 요소로 갖는 배열을 정렬
<img src="https://images.velog.io/images/boram_in/post/76de2b22-f597-4cd7-b246-2378c626c923/image.png" alt=""></p>
<blockquote>
<h4 id="sort-정렬의-알고리즘">sort 정렬의 알고리즘</h4>
<p>예전에는 quicksort알고리즘을 사용하다 ES10에서 timsort 알고리즘을 사용하도록 바뀌었다</p>
</blockquote>
<hr> 

<h3 id="2792-arrayprototypeforeach">27.9.2 Array.prototype.forEach</h3>
<h4 id="for문이-왜-문제야-🙋">for문이 왜 문제야? 🙋</h4>
<ul>
<li><p>반복을 위한 변수를 선언해야 하고 조건식과 증감식으로 이뤄져있어 함수형 프로그래밍이 추구하는 바와는 안 맞는다. 이전에 스터디를 할 때도 for문은 아무도 안 쓰더랑.</p>
</li>
<li><p>forEach 메서드는 for문을 대체할 수 있다. 내부에서 반복문을 싱행하며 이를 통해 자신을 호출한 배열을 순회하며 수행해야할 처리를 콜백함수로 전달받아 반복 호출한다. 
<img src="https://images.velog.io/images/boram_in/post/6b17184d-ce72-42c6-9183-3b0debce5c0e/image.png" alt=""></p>
</li>
<li><p>forEach 메서드는 메뉴가격의 모든 요소를 순회하며 콜백함수를 반복 호출한다. 요소가 5개니 콜백함수도 5번 호출된다. 이때 호출하는 forEach 메서드는 콜백 함수에 인수를 전달할 수 있다. 
<img src="https://images.velog.io/images/boram_in/post/2e8e7733-ffe1-4c1b-a789-e27b56106076/image.png" alt=""></p>
<blockquote>
<h4 id="jsonstringfy-메서드">JSON.stringfy 메서드</h4>
<p>객체를 JSON 포맷의 문자열로 변환한다. </p>
</blockquote>
</li>
<li><p>forEach 메서드는 원본 배열(forEach 메서들르 호출한 배열 즉 this)을 변경하지 않는다. 하지만 콜백 함수를 통해 원본 배열을 변경할 수는 있다.
<img src="https://images.velog.io/images/boram_in/post/aebdbc51-6b52-4a19-904a-4b26c2a83f02/image.png" alt=""></p>
</li>
<li><p>forEach 메서드의 반환값은 언제나 undefined다. 
<img src="https://images.velog.io/images/boram_in/post/74b952e1-010d-47d2-be6f-e260a4857467/image.png" alt=""></p>
</li>
</ul>
<h4 id="왜-foreach안에서화살표함수를-사용하나">왜 forEach안에서화살표함수를 사용하나</h4>
<ul>
<li>forEach 메서드의 두 번째 인수로 forEach 메서드의 콜백 함수 내부에서 this로 사용할 객체를 전달할 수 있다. <img src="https://images.velog.io/images/boram_in/post/fc159b85-0925-4769-8956-c975ca1ef6d0/image.png" alt=""></li>
<li>forEach 메서드의 콜백함수는 일반함수로 호출되므로 콜백 함수 내부의 this는 undefined. this가 전역객체가 아닌 undefined인 이유는 클래스 내부의 모든 코드에는 암묵적으로 strict mode가 적용되기 때문이다. </li>
<li>forEach 메서드의 콜백함수 내부의 this와 multiply 내부의 this를 일치시키려면 forEach 메서드의 두번째 인수로 forEach 메섣의 콜백 함수 내부에서 this로 사용할 객체를 전달. 아례의 예제의 경우 forEach 메서드의 두 번째 인수로 multiply 내부의 this 전달 중. 
<img src="https://images.velog.io/images/boram_in/post/cb48d796-c7bc-47d0-a0d7-ace799379a9b/image.png" alt=""></li>
<li>💫 죠렇게 this를 한 번 더 적어줘야 한다! 예제 실행하다가 헤메인 부분</li>
<li>사실 더 나은 방법은 화살표 함수 쓰는 것. 자체 this 바인딩을 갖지 않으므로 this를 참조하면 상위 스코프, 즉 multiply 메서드 내부의 this를 그대로 참조한다. 
<img src="https://images.velog.io/images/boram_in/post/59116a19-9be4-4839-b42f-f5416dbb35dc/image.png" alt=""></li>
<li>forEach 메서드는 for문과 달리 breack, continue 문을 사용할 수 없다. 다시 말해, 배열의 모든 요소를 빠짐없이 순회하며 중단할 수 없다.</li>
<li>희소배열의 경우 존재하지 않는 요소는 순회 대상에서 제외된다. </li>
</ul>
<blockquote>
<h4 id="결론">결론</h4>
<p>for 문에 비해서 성능이 좋지 않지만 가독성은 더 좋아! 
따라서 대단히 많은 배열을 순회하거나 복잡하지 않은 경우라서 for 대신 forEach 메서드를 사용할 것을 권장.</p>
</blockquote>
<hr> 


<h3 id="2793-arrayprototypemap">27.9.3 Array.prototype.map</h3>
<h4 id="map은-왜-쓰나요">map은 왜 쓰나요?</h4>
<p>🙋 map 메서드는 자신을 호출한 배열의 모든 요소를 순회하며 인수로 전달받은 콜백함수를 반복 호출한다. 근데 위에 forEach랑 다르게 콜백 함수의 반환값들로 구성된 새로운 배열을 반환함. 그러나 원본 배열은 변경되지 않음. 
<img src="https://images.velog.io/images/boram_in/post/c147e46c-d4f0-4a8d-b2cf-2bba31e034a5/image.png" alt=""></p>
<h4 id="foreach와-map의-공통점과-차이점-🙋">forEach와 Map의 공통점과 차이점 🙋</h4>
<p>자신을 호출한 배열의 모든 요소 순회하며 콜백함수를 호출한다는 것! 하지만 forEach는 언제나 undefined를 반환하는 철벽이구 map은 콜백함수의 반환값들로 구성된 새로운 배열을 반환하는 미팅.</p>
<ul>
<li><p>그래서 forEach는 단순히 반목문을 대체하기 위한 고차함수이고 map은 이름대로 다른 값으로 매핑한 배열을 생성하기 위한 고차함수다. </p>
</li>
<li><p>*<em>결국 map 메서드가 생성하여 반환하는 새로운 배열의 length 프로퍼티 값은 map 메서드를 호출한 배열의 length 프로퍼티 값과 반드시 일치. 즉, map 메서드를 호출한 배열과 1:1 매핑. *</em>  </p>
</li>
<li><p>forEach와 마찬가지로 map 메서드의 콜백함수는 map 메서드를 호출한 배열의 요소값과 인덱스, map 메서드를 호출한 배열 자체(this)를 순차적으로 전달 받을 수 있다. 다시 말해, map 메서드는 콜백함수를 호출할 때  3개의 인수를 순차적으로 전달한다. 
<img src="https://images.velog.io/images/boram_in/post/d8faf25c-193f-4994-ae50-0cdf52f2894c/image.png" alt=""></p>
</li>
<li><p>forEach 메서드와 마찬가지로 map 메서드의 두번째 인수로 map메서드의 콜백 함수 내부에서 this로 사용할 객체를 전달할 수 있다. </p>
</li>
<li><p>그러나 더 나은 방법 역시 앞선 것과 마찬가지로 화살표 함수를 사용하는 것이다. 화살표함수는 자체 this 바인딩을 갖지 않는다 따라서 화살표 함수 내부 this를 참조하면 상위 스코프 즉 add 메서드 내부의 this를 그대로 참조한다. 
<img src="https://images.velog.io/images/boram_in/post/3865e7be-c709-4d26-97f0-932fa7f22f7c/image.png" alt=""></p>
</li>
</ul>
<hr>

<h3 id="2794-arrayprototypefilter">27.9.4 Array.prototype.filter</h3>
<p>filter 메서드는 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백함수를 반복 호출. 그리고 <strong>콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환.</strong> 이때 원본 배열은 변경되지 않는다. </p>
<ul>
<li>filter 메서드는 자신이 호출한 배열에서 필터링 조건을 만족하는 특정 요소만 추출하여 새로운 배열을 만들고 싶을 때 사용. </li>
<li>용돈을 아껴야 하는 상황에서, 보람카페에서 하루 커피 지출을 3500원 이하로 해야 하는 슬픈 경우
<img src="https://images.velog.io/images/boram_in/post/9d676709-b83f-4ebd-90d2-6f7b9458078c/image.png" alt=""></li>
<li>filter도 자신을 호출한 배열의 모든 요소를 순회하며 인수로 전달받은 콜백 함수를 반복 호출한다.</li>
<li>forEach : undefined, map:콜백함수의 반환값들로 구성된 새로운 배열, fiter: 콜백함수의 반환값이 true인 요소만 추출한 새로운 배열 반환 </li>
<li>얘두 동일하게 화살표  함수 쓰시구요. 특정 요소를 제거하기 위해 사용할 수도 있다. </li>
<li>filter로 민초파와 민초척사파를 구현해보자 </li>
</ul>
<p><img src="https://images.velog.io/images/boram_in/post/412e8878-5452-47c3-888d-f4a0b8a43b3c/image.png" alt="">
filter 메서드를 사용해 특정 요소를 제거할 경우 특정 요소가 중복되어 있다면 중복 요소가 모두 제거된다. 특정 요소 하나만 제거하려면 indexOf 메서드로 인덱스 취득후 splice를 씁시다! </p>
<hr>

<h3 id="2795-arrayprototypereduce">27.9.5 Array.prototype.reduce</h3>
<p>reduce 메서드는 자신을 호출한 배열의 모든 요소를 순회하여 인수로 전달 받은 콜백함수를 반복 호출한다. 근데 반환값을 다음 순회 시에 콜백 함수의 첫 번째 인수로 전달하면서 콜백 함수를 호출하여 하나의 결과값을 만들어 변환한다. 이때 원본 배열은 변경되지 않는다 
<img src="https://images.velog.io/images/boram_in/post/6a7ad0d0-f89d-40da-931a-a2d306e43a04/image.png" alt=""></p>
<ul>
<li>reduce 메서드의 콜백함수는 4개의 인수를 전달받아 배열의 length만큼 호출된다.</li>
<li>reduce는 초기값과 배열의 첫 번째 요소값을 콜백 함수에 전달하면서 호출하고 다음 순회에는 콜백 함수의 반환값과 두 번째 요소를 콜백함수의 인수로 전달하면서 호출. 이러한 과정을 반복하여 <strong>reduce는 하나의 결과값을 반환한다.</strong></li>
</ul>
<h4 id="평균-구하기">평균 구하기</h4>
<p><img src="https://images.velog.io/images/boram_in/post/973279fd-d1db-4233-970c-76f2ebc985c3/image.png" alt=""></p>
<h4 id="요소의-중복-횟수-구하기">요소의 중복 횟수 구하기</h4>
<p><img src="https://images.velog.io/images/boram_in/post/2fcc66d1-7fcf-40ea-88ec-ce3bd4926eac/image.png" alt=""></p>
<ul>
<li>최대값, 평탄화, 중복 요소 제거 등에서도 응용해서 쓸 수 있지만 각각 max, flat, filter를 쓰는 것이 더 직관적이다. </li>
<li>filter 사용
<img src="https://images.velog.io/images/boram_in/post/8db93972-c350-4b0d-9b24-d79ba6a245dc/image.png" alt=""></li>
<li>set 사용
<img src="https://images.velog.io/images/boram_in/post/5c1b84dc-1db5-4412-9fe3-af08be6b4b24/image.png" alt=""></li>
</ul>
<p>앞서 살펴본 것처럼 reduce의 메서드의 두 번째 인수로 전달하는 초기값은 첫 번째 순회에 콜백 함수의 첫 번째 인수로 전달된다. 주의할 것은 두 번째 인수로 전달하는 초기값이 옵션이라는 것. 즉, reduce의 두번째로 전달하는 값을 생략할 수 있다.</p>
<h4 id="그러나-reduce를-호출할-때는-초기값을-전달하는-것이-안전하다">그러나 reduce를 호출할 때는 초기값을 전달하는 것이 안전하다.</h4>
<p><img src="https://images.velog.io/images/boram_in/post/d889fa29-a145-4a95-959e-2edc4f33a1f7/image.png" alt=""></p>
<ul>
<li>빈 배열로 reduce 메서드를 호출하면 에러가 발생한다. 이때 reduce 메서드에 초기값을 전달하면 에러가 발생하지 않는다. 또한 객체의 값을 합산하는 경우에는 반드시 초기값을 전달해야 한다.
<img src="https://images.velog.io/images/boram_in/post/d1027633-3757-428c-9816-86318c0c8159/image.png" alt=""></li>
</ul>
<blockquote>
<p>*<em>구러니 에러 없이 좋은 말할 때 reduce는 초기값을 생략 말고 적어주자. 그리고 왜 reduce를 그 때 썼을 때 피드백을 받았는지도 알겠군. *</em></p>
</blockquote>
<h3 id="2796-arrayprototypesome">27.9.6 Array.prototype.some</h3>
<p>some 메서드는 자신을 호출한 배열의 요소를 순회하며 인수로 전달된 콜백 함수를 호출. 이때 some 메서드는 콜백 함수의 반환 값이 단 한 번이라도 참이면 true, 모두 거짓이면 false를 반환. </p>
<ul>
<li>배열 요소 중에 콜백 함수를 통해 정의한 조건을 만족하는 요소가 1개 이상 존재하면 그 결과를 불리언 타입으로 반환. </li>
<li>단 some을 호출한 배열이 빈 배열이면 언제나 false를 반환하므로 주의</li>
<li>forEach, map, filter와 마찬가지로 some도 호출한 요소값, 인덱스, some을 호출한 배열 자체(this)를 순차적으로 전달받을 수 있다
<img src="https://images.velog.io/images/boram_in/post/c36e64f0-7333-4bb6-9dec-47d076aaa423/image.png" alt=""></li>
<li>역시 위에서 본 이유와 같이 화살표 함수를 쓰자 </li>
</ul>
<hr>

<h3 id="2797-arrayprototypeevery">27.9.7 Array.prototype.every</h3>
<p>every 메서드는 자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백함수를 호출. every 메서드는 콜백 함수의 반환값이 모두 참이면 true, 단 한 번이라도 거짓이면 false.</p>
<ul>
<li>모든 요소가 콜백 함수를 통해 정의한 조건을 모두 만족하는지 확인하여 결과를 불린 타입으로</li>
<li>빈 배열인 경우 언제나 true
<img src="https://images.velog.io/images/boram_in/post/65de7d67-a5f7-4446-bed4-a28d41b88958/image.png" alt=""></li>
<li>얘두 this 참조 문제로 화살표 함수를 써라!</li>
</ul>
<hr>

<h3 id="2798-arrayprototypefind">27.9.8 Array.prototype.find</h3>
<p>find는 자신을 호출한 배열 요소를 순회하면서 인수로 전달된 콜백 함수를 호출하여 반환값이 true인 첫 번째 요소를 반환. 콜백 함수의 반환값이 true인 요소가 존재하지 않는다면 undefined를 반환. 
<img src="https://images.velog.io/images/boram_in/post/0e13ef64-3778-48dc-b71a-b7d7870ac22c/image.png" alt=""></p>
<h4 id="vs-filter">vs filter</h4>
<ul>
<li>filter 메서드는 콜백 함수의 호출 결과가 true인 요소만 추출한 새로운 배열 반환</li>
<li>하지만 finde 메서드는 콜백 함수 반환값이 true인 첫 번째 요소를 반환하므로 해당 요소값
<img src="https://images.velog.io/images/boram_in/post/6a2ee8d6-df47-493f-84cc-3917d3640671/image.png" alt=""></li>
<li>이 친구도 역시 화살표 함수를 사용하자 </li>
</ul>
<hr>

<h3 id="2799-arrayprototypefindindex">27.9.9 Array.prototype.findIndex</h3>
<p>자신을 호추한 배열의 요소를 순회하며 인수로 전달된 콜백 함수를 호출하여 반환값이 true인 첫 번째 요소의 인덱스를 반환. 콜백 함수의 반환 값이 true인 요소가 존재하지 않는다면 -1을 반환.
<img src="https://images.velog.io/images/boram_in/post/76bcf193-60bf-4781-b52c-059399d27cb1/image.png" alt=""></p>
<h3 id="2799-arrayprototypeflatmap">27.9.9 Array.prototype.flatMap</h3>
<p>ES10에서 도입된 flatMap 메서드는 map메서드를 통해 생성된 새로운 배열을 평탄화한다. 즉 map과 flat을 순차적으로 실핸한 효과. 
<img src="https://images.velog.io/images/boram_in/post/5b73ff17-c512-43c0-a3e8-136dcb0c9d53/image.png" alt=""></p>
<ul>
<li>단 flatMap 메서드는 flat 메서드처럼 인수를 전달하여 평탄화 깊이를 지정할 수는 없고 1단계만 평탄화한다. map 메서드를 통해 생성된 중첩 배열의 평탄화 깊이를 지정해야 한다면 flatMap 메서드를 사용하지 말고 map 메서드와 flat 메서드를 각각 호출한다.
<img src="https://images.velog.io/images/boram_in/post/f8d884fa-a37d-4bd6-99c6-992bff34d365/image.png" alt=""></li>
</ul>
<hr>

<blockquote>
<h2 id="til">TIL</h2>
</blockquote>
<ul>
<li>토욜에 이렇게 빡세게 공부해본 적이 없어서 그런가. 무슨 예제 코드를 조금 응용만 해도 에러가 났다. <img src="https://images.velog.io/images/boram_in/post/fbacd072-6fa5-47e7-b4ae-f2a15bbfb31c/image.png" alt=""> 그러나 코테 이전, 현업 전에 에러는 겪을 수록 <strong>오히려 좋아!</strong> 그 덕분에 오히려 forEach, map의 차이가 분명하게 느껴졌다. 특히나 return문을 저번 스터디에서 쓴 적이 없고 익숙하지 않아서 return + this는 혼돈의 카오스였는데 this를 찍어보면서 이해를 더 해보려 노력했다. </li>
<li>단순히 타이핑연습(?)하던 이전보다 더디게 나가고 있는데 그것도 <strong>오히려 좋아</strong>다. 느리면 더하면 된다. 덜 할 이유는 아니니 오히려 좋은 것이다.</li>
<li>프로그래머스 스터디를 할 때
<img src="https://images.velog.io/images/boram_in/post/561cf756-8a22-4a12-bf1e-d168c90ba6d6/image.png" alt=""></li>
<li>신문물처럼 바라보던 forEach, map(은 왜 잘 안 쓰였지?), reduce(쓰다가 피드백 받음)를 그 때는 MDN과 블로그 등을 보면서 복붙하면서 썼는데 드디어 개념을 잡았다. 인수를 하나만 받는 경우 특히 요소일 때만 예제에서 다루고 있는데 index랑 this조작도 되나? 한 번 실험해봐야지. </li>
<li>내일은 쉬는 날이니 천천히 next.js 클론 코딩하면서 담주부터 시작할 스터디를 대비해야지. </li>
<li>filter에서 민초단, 민초척사파는 10분 정도 걸렸다. true값만 반환하면 민초를 포함하지 않는 것은 어떻게 하나? not includes같은 씽크빅도 했지만 곧 true값만 반환하니까 !를 앞에 붙이면 되겠네를 떠올렸다. 기특하군 </li>
</ul>
]]></description>
        </item>
    </channel>
</rss>