<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Meme's IT</title>
    <link>https://memezz.tistory.com/</link>
    <description>개발 공부하는 블로그입니다</description>
    <language>ko</language>
    <pubDate>Sun, 9 Aug 2026 07:03:58 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Memez</managingEditor>
    <image>
      <title>Meme's IT</title>
      <url>https://tistory1.daumcdn.net/tistory/6574557/attach/096efb4ad57b44afb58683361b753960</url>
      <link>https://memezz.tistory.com</link>
    </image>
    <item>
      <title>[혼공컴] 1장. 컴퓨터 구조 시작하기</title>
      <link>https://memezz.tistory.com/202</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt; &lt;b&gt;컴퓨터 구조를 왜 알아야 할까?&lt;/b&gt;&lt;u&gt;&lt;b&gt;&lt;/b&gt;&lt;/u&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;1. 성능, 용량, 비용을 고려할 줄 아는 개발자가 되기 위해서&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;이전에 프로젝트를 하면서 간단히 EC2를 활용해 띄워보려는 시도를 했었다. 하지만 우리 프로젝트의 규모에 따른 서버 용량, 사양을 가늠하기가 어려웠고 이전에 실습했을 때 골랐던 사양으로 고르니 당연히 안 띄워졌던 일이 있었다&amp;hellip; 이를 통해 개발자는 코드만 잘 짜면 되는게 아니라 &lt;b&gt;프로젝트에 따라 성능, 용량, 비용을 다 따질 수 있어야 한다&lt;/b&gt;는 걸 배웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;책에서도 같은 얘기를 한다. 프로그램을 실행할 서버 컴퓨터를 고를 때 너무 저렴한 성능의 컴퓨터를 고르면 누를때마다 한참 걸리는 사이트를 만들게 될 것이고, 그렇다고 너무 좋은 컴퓨터를 고르면 비용이 너무 늘어나는 문제가 생기므로 이를 판단하는 개발자가 되어야 한다고 설명한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;2. 문제 해결 능력을 높이기 위해서&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;가끔 분명 똑같은 코드인데 어느 환경에서는 되지만 어느 환경에서는 안될 때가 있다. 이러한 원인을 찾아보면 거의 대부분의 경우 로컬 컴퓨터 환경의 차이였다.. 이런식의 문제도 컴퓨터의 구조에 대해서 잘 이해하고 있다면 서로의 환경이 어떻게 다른지 비교하며 해결의 실마리를 찾을 수 있다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 컴퓨터가 이해할 수 있는 정보&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 컴퓨터를 뜯어보기 전에, 얘가 뭘 이해할 수 있는지를 파악하고 넘어가야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터는 익히 알듯이 0과 1만 이해할 수 있는데, 0과 1로만 이루어진 정보는 크게 &lt;b&gt;데이터&lt;/b&gt;와 &lt;b&gt;명령어&lt;/b&gt;로 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;데이터&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정적인 정보(숫자, 문자, 이미지, 동영상 등)&lt;/li&gt;
&lt;li&gt;예: 1, 2 / 사진.png&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;명령어&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터를 움직이고 컴퓨터를 작동시키는 정보&lt;/li&gt;
&lt;li&gt;예: 1과 2를 더하세요, USB로 사진.png를 옮기세요&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 컴퓨터는 그럼 뭐로 이루어져있는데?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그림과 같이 메인보드가 있고, 메인보드 안에는 시스템 버스라는 통로와 CPU, 메모리가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU와 메모리는 메인보드 안에서 시스템 버스로 연결되어있고, 보조기억장치와 입출력 장치들은 메인보드 밖에서 시스템 버스로 연결되어 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;315&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bY91Xy/btsPg0YEJFT/9q2iYrxqjFqRXUE5XQGdO0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bY91Xy/btsPg0YEJFT/9q2iYrxqjFqRXUE5XQGdO0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bY91Xy/btsPg0YEJFT/9q2iYrxqjFqRXUE5XQGdO0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbY91Xy%2FbtsPg0YEJFT%2F9q2iYrxqjFqRXUE5XQGdO0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;315&quot; height=&quot;307&quot; data-origin-width=&quot;315&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 각각에 대해서 알아보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt; 메인보드&lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;283&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/l2sTx/btsPhNRQG59/rVvHRE3NKuVfwILYIUIu3K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/l2sTx/btsPhNRQG59/rVvHRE3NKuVfwILYIUIu3K/img.png&quot; data-alt=&quot;실물은 이렇게 생겼다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/l2sTx/btsPhNRQG59/rVvHRE3NKuVfwILYIUIu3K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fl2sTx%2FbtsPhNRQG59%2FrVvHRE3NKuVfwILYIUIu3K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;339&quot; height=&quot;283&quot; data-origin-width=&quot;339&quot; data-origin-height=&quot;283&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;실물은 이렇게 생겼다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메인보드에 연결된 부품은 버스라는 통로로 서로 정보를 주고 받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템 버스는 주소를 주고 받는 &lt;b&gt;주소 버스&lt;/b&gt;, 명령어와 데이터를 주고 받는 &lt;b&gt;데이터 버스&lt;/b&gt;, 제어 신호를 주고 받는 &lt;b&gt;제어 버스&lt;/b&gt;로 이루어져있다. 예를 들어, &amp;ldquo;1번 주소에 있는 데이터를 읽어오세요&amp;rdquo; 라는 명령을 CPU에서 처리한다면 &amp;ldquo;메모리 읽기&amp;rdquo; 라는 제어신호를 제어 버스로 보내고, &amp;ldquo;1번 주소에서&amp;rdquo; 라는 주소를 주소 버스로 메모리에 전달한다. 그러면 읽은 1번 주소의 데이터를 데이터 버스를 타고 다시 CPU로 전달되는 구조이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt; CPU &lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;189&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cCJEam/btsPhtM13JM/XKKKOAKL7g75erXo9lf8pk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cCJEam/btsPhtM13JM/XKKKOAKL7g75erXo9lf8pk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cCJEam/btsPhtM13JM/XKKKOAKL7g75erXo9lf8pk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcCJEam%2FbtsPhtM13JM%2FXKKKOAKL7g75erXo9lf8pk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;245&quot; height=&quot;189&quot; data-origin-width=&quot;245&quot; data-origin-height=&quot;189&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터의 두뇌 역할을 한다. 명령어를 읽고, 해석하고 실행함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;크게 3가지로 구성되어 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;계산을 맡는 &lt;b&gt;ALU&lt;/b&gt;(산술논리연산장치)&lt;/li&gt;
&lt;li&gt;임시 저장 장치인 &lt;b&gt;레지스터&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;제어 신호를 내보내고 명령어를 해석하는 &lt;b&gt;제어 장치&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt; 메모리 &lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;183&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXaSYO/btsPiD11CPx/tLZtPkAbLkCvwY4SfdkMck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXaSYO/btsPiD11CPx/tLZtPkAbLkCvwY4SfdkMck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXaSYO/btsPiD11CPx/tLZtPkAbLkCvwY4SfdkMck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXaSYO%2FbtsPiD11CPx%2FtLZtPkAbLkCvwY4SfdkMck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;290&quot; height=&quot;183&quot; data-origin-width=&quot;290&quot; data-origin-height=&quot;183&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 실행되는 프로그램의 명령어와 데이터를 저장하는 부품&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;프로그램이 실행되려면 반드시 메모리에 저장되어 있어야 함&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리에 데이터와 명령어는 주소라는 개념을 이용해 저장됨.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt; 보조기억장치 &lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/befD1j/btsPh5SqYVj/WdxKXYnw9SEoRb05lvsb40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/befD1j/btsPh5SqYVj/WdxKXYnw9SEoRb05lvsb40/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/befD1j/btsPh5SqYVj/WdxKXYnw9SEoRb05lvsb40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbefD1j%2FbtsPh5SqYVj%2FWdxKXYnw9SEoRb05lvsb40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;256&quot; height=&quot;150&quot; data-origin-width=&quot;256&quot; data-origin-height=&quot;150&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리는 가격이 비싸서 용량이 작고, 전원이 꺼지면 내용을 잃어버림&amp;hellip;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 전원이 꺼져도 저장되는 데이터들은 보조기억장치에 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예: 하드디스크, SSD, USB, DVD, CD-ROM 등&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리가 실행되고 있는 프로그램을 저장한다면, 보조기억장치는 보관할 프로그램을 저장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt;입출력 장치&lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마이크, 스피커, 프린터, 마우스, 키보드 등 컴퓨터 외부에서 내부와 정보를 교환하는 장치&lt;/p&gt;</description>
      <category>자격증 &amp;amp; 기타/혼공컴</category>
      <category>혼공컴</category>
      <author>Memez</author>
      <guid isPermaLink="true">https://memezz.tistory.com/202</guid>
      <comments>https://memezz.tistory.com/202#entry202comment</comments>
      <pubDate>Tue, 15 Jul 2025 00:03:21 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 어드벤처 게임</title>
      <link>https://memezz.tistory.com/201</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/2310&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/2310&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백준 2310번: 어드벤처 게임&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제를 풀었던 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DFS를 사용해서 풀었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;방문처리에 대해서&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;들렀던 곳을 또 들려야 최소가 되는 경우를 고려했었기 때문에 처음에는 방문처리를 하지 않았습니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;274&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOzqdU/btsMTKcgUEO/P36zNec4nde6FchIw61aek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOzqdU/btsMTKcgUEO/P36zNec4nde6FchIw61aek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOzqdU/btsMTKcgUEO/P36zNec4nde6FchIw61aek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbOzqdU%2FbtsMTKcgUEO%2FP36zNec4nde6FchIw61aek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;414&quot; height=&quot;274&quot; data-origin-width=&quot;414&quot; data-origin-height=&quot;274&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진과 같은 경우에 빈방에서의 소지금이 0원이라면 그냥 일반적인 방문처리로는 트롤방으로 바로 가는 경우가 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 방문처리를 하지 않는다면 빈방(소지금:0) &amp;rarr; 레프(소지금:20) &amp;rarr; 빈방(소지금:20) &amp;rarr; 트롤방(소지금:10) 이런식으로 갈 수 있어서 이걸 고려했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 아예 방문처리를 안하니까 &lt;s&gt;당연히&lt;/s&gt; 시간초과가 났고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 해결하기 위해 방문처리를 할때 방문 처리 배열에 현재 가지고 있는 소지금을 저장했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr;그래서 다시 들릴때 현재 소지금 &amp;gt; 이전 들릴때 소지금이면 방문할 수 있도록 처리를 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제출 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1742802293085&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 어드벤처 게임

def dfs(rooms, n):
    stack = [[1, 0]] # 시작 room number, 가지고 있는 돈
    
    # 같은 돈을 소지하고 다시 같은 방에 가는건 막자
    visited = [None] * n
    visited[0] = 0
    
    while stack:
        [now_room_number, now_money] = stack.pop()

        if now_room_number == n:
            return 'Yes'

        for next_room_number in rooms[now_room_number - 1][2]:
            next_idx = next_room_number - 1
            room_type = rooms[next_idx][0]
            room_value = rooms[next_idx][1]

            # 룸 타입 확인
            if room_type == 'E':
                next_money = now_money
            elif room_type == 'L':
                next_money = max(now_money, room_value)
            else:
                if now_money &amp;gt;= room_value:
                    next_money = now_money - room_value
                else:
                    continue

            # 들리지 않았거나, 현재 소지금이 아까보다 많을때만 갈 수 있게
            if visited[next_idx] == None or visited[next_idx] &amp;lt; next_money:
                visited[next_idx] = next_money
                stack.append([next_room_number, next_money])

    
    return 'No'


while True:
    # n = 0이 되면 종료
    n = int(input())
    if n == 0:
        break

    rooms = []
    for _ in range(n):
        input_arr = input().split(' ')
        # rooms에 저장되는 형식 [방 타입(빈방, 레프리콘, 트롤), 돈, 다음 방 정보(list)]
        rooms.append([input_arr[0], int(input_arr[1]), list(map(int, input_arr[2:len(input_arr) - 1]))])

    print(dfs(rooms, n))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데... 다른 제출한 사람들의 실행 시간이 꽤나 차이가 나서 보니까&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방문처리를 그냥 (들림 / 안들림)으로만 해도 충분히 맞는 것 같음...&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;166&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjVlIN/btsMT2RiWsM/ax85jAlqKNhB9CL5XvlSL1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjVlIN/btsMT2RiWsM/ax85jAlqKNhB9CL5XvlSL1/img.png&quot; data-alt=&quot;그래서인가 무수한 데이터 추가 요청&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjVlIN/btsMT2RiWsM/ax85jAlqKNhB9CL5XvlSL1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbjVlIN%2FbtsMT2RiWsM%2Fax85jAlqKNhB9CL5XvlSL1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;372&quot; height=&quot;166&quot; data-origin-width=&quot;372&quot; data-origin-height=&quot;166&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;그래서인가 무수한 데이터 추가 요청&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>백준</category>
      <category>어드벤처게임</category>
      <category>파이썬</category>
      <author>Memez</author>
      <guid isPermaLink="true">https://memezz.tistory.com/201</guid>
      <comments>https://memezz.tistory.com/201#entry201comment</comments>
      <pubDate>Mon, 24 Mar 2025 16:46:36 +0900</pubDate>
    </item>
    <item>
      <title>[백준] 좋다</title>
      <link>https://memezz.tistory.com/200</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.acmicpc.net/problem/1253&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.acmicpc.net/problem/1253&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;백준 1253번: 좋다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;639&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bCo5on/btsMVHLRukt/OtHIyAjDq8kB9lgmThxex0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bCo5on/btsMVHLRukt/OtHIyAjDq8kB9lgmThxex0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bCo5on/btsMVHLRukt/OtHIyAjDq8kB9lgmThxex0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbCo5on%2FbtsMVHLRukt%2FOtHIyAjDq8kB9lgmThxex0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1156&quot; height=&quot;639&quot; data-origin-width=&quot;1156&quot; data-origin-height=&quot;639&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀었던 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 두 숫자를 더해서 하나의 숫자를 찾는거니까 투포인터를 썼습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숫자를 크기 순서대로 정렬하고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3번째 숫자부터 마지막 숫자까지 하나씩 확인을 합니다&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;포인터를 배열의 가장 처음에 하나, 마지막에 하나를 두고 각 합이 확인중인 숫자랑 같은지를 확인합니다&lt;/li&gt;
&lt;li&gt;확인중인 숫자 &amp;gt; 합이라면 처음 포인터를 뒤로 밀고,&lt;/li&gt;
&lt;li&gt;확인중인 숫자 &amp;lt; 합이라면 마지막 포인터를 앞으로 땡기면서 찾았습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;생겼던 문제&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;처음에는 숫자들이 모두 자연수인줄알고 투포인터를 이용해서 찾을때 탐색하는 범위를 탐색중인 숫자의 앞 배열만을 사용했습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1, 2, 3, 4, 5, 6, 7
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 이 방법일 때 5를 확인중이라면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;p1 = 1로 두고, p2 = 4로 둬서 확인을 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 배열이 모두 자연수가 아니므로 음수의 경우도 고려해야했습니다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;-2, 0, 2, 4
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 경우에는 2를 탐색할때 앞에 있는 배열만 사용한다면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;p1 = -2, p2 = 0이 되므로 찾을 수가 없는 문제가 발생했습니다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 그래서 초기 포인터 설정을 매번 전체 배열의 처음, 끝으로 둬서 개선했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제출 코드&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1742802073483&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 백준 1253 좋다
# 투포인터

N = int(input())
nums = list(map(int, input().split()))

nums.sort()

result = 0

for i in range(N):
    target = nums[i]

    left, right = 0, N - 1   
    
    while left &amp;lt; right:
        # 지금 확인중인 숫자는 넘어가게
        if left == i:
            left += 1
            continue
        if right == i:
            right -= 1
            continue
            
        sum_of_left_right = nums[left] + nums[right]
        
        if sum_of_left_right == target:
            result += 1
            break
        elif sum_of_left_right &amp;lt; target:
            left += 1
        else:
            right -= 1

print(result)&lt;/code&gt;&lt;/pre&gt;</description>
      <category>알고리즘/문제풀이</category>
      <category>백준</category>
      <category>좋다</category>
      <category>파이썬</category>
      <author>Memez</author>
      <guid isPermaLink="true">https://memezz.tistory.com/200</guid>
      <comments>https://memezz.tistory.com/200#entry200comment</comments>
      <pubDate>Mon, 24 Mar 2025 16:41:37 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 이벤트</title>
      <link>https://memezz.tistory.com/199</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;236&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bi99Eo/btsL7e47fM4/OfMCuvhKt5QYOpszWP2iXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bi99Eo/btsL7e47fM4/OfMCuvhKt5QYOpszWP2iXk/img.png&quot; data-alt=&quot;CH40.이벤트&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bi99Eo/btsL7e47fM4/OfMCuvhKt5QYOpszWP2iXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbi99Eo%2FbtsL7e47fM4%2FOfMCuvhKt5QYOpszWP2iXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;467&quot; height=&quot;236&quot; data-origin-width=&quot;467&quot; data-origin-height=&quot;236&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;CH40.이벤트&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;40.1 이벤트 드리븐 프로그래밍&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클릭, 키보드 입력, 마우스 이동 등의 일이 일어나면 &amp;rarr; 감지 &amp;rarr; 특정한 타입의 이벤트 발생&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 때, 이벤트가 발생하면 호출할 함수를 &lt;b&gt;이벤트 핸들러&lt;/b&gt;라고 함!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이벤트가 언제 발생할지 몰라서 개발자가 명시적으로 함수를 호출하지 못함 &amp;rarr; 브라우저한테 &amp;lsquo;너가 처리해&amp;rsquo;(= 함수 호출 위임)라 하는 게 &lt;b&gt;이벤트 핸들러 등록&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 이벤트를 중심으로 제어하는 프로그래밍 방식 == 이벤트 드리븐 프로그래밍&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;40.2 이벤트 타입&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;= 이벤트의 종류를 나타내는 문자열 (예를 들어, click, mouseenter&amp;hellip;.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;약 200개 정도가 있고 머가 있는지는 너무 많아서 책 참고하셔서 그때 그때 보시면 될듯요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마우스 이벤트(click, mouseup, mousedown, mouseleave&amp;hellip;등등)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키보드 이벤트(keydown, keypress, keyup등등&amp;hellip;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엄청 많습니다&amp;hellip;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;40.3 이벤트 핸들러 등록&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트가 발생하면 브라우저에 의해 호출될 함수 = 이벤트 핸들러&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 등록하는 방법은 세가지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(1) 이벤트 핸들러 어트리뷰트 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말하면 onclick과 같이 on + 이벤트 종류를 통해 등록하는 것&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button onclick=&quot;sayHi()&quot;&amp;gt;Click me&amp;lt;/button&amp;gt;
&amp;lt;script&amp;gt;
	function sayHi() {
		console.log('Hi')
	}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 이벤트 핸들러 어트리뷰트 값으로는 함수 참조가 아닌, 함수 호출문같은걸 할당함&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 뒤에 들어가는 sayHi() 이 값이 JS코드로 해석되어서 실행됨 그래서 이렇게도 쓸 수 있음&lt;/p&gt;
&lt;pre class=&quot;hsp&quot;&gt;&lt;code&gt;&amp;lt;button onclick=&quot;console.log(1); console.log(2);&quot;&amp;gt;Click me&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 이방식은 쓰지말라고는 함 왜냐면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTML, JavaScript를 완전히 분리된 &quot;관심사&quot;로 보았습니다&lt;/li&gt;
&lt;li&gt;따라서 HTML에 직접 JavaScript를 넣는 이벤트 핸들러 어트리뷰트 방식을 지양했죠&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 컴포넌트 기반의 개발을 하는 리액트나 뷰와 같은 라이브러리/프레임워크에서는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴포넌트라는 하나의 단위 안에 HTML, CSS, JavaScript가 모두 포함됨&lt;/li&gt;
&lt;li&gt;이들을 분리된 관심사가 아닌, &quot;하나의 컴포넌트를 구성하는 요소들&quot;로 봄&lt;/li&gt;
&lt;li&gt;따라서 이벤트 핸들러를 HTML과 비슷한 방식으로 직접 작성하는 것이 자연스러움&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라는 이유로 이벤트 핸들러 어트리뷰트 방식과 비슷하게 쓴다고 하네요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;(즉, CBD에서는 &quot;버튼 컴포넌트&quot;라는 하나의 완성된 단위를 만들 때 HTML 구조, 스타일링, 이벤트 처리가 모두 그 컴포넌트의 본질적인 부분이라고 보기 때문에, 이벤트 핸들러 어트리뷰트와 비슷한 방식을 사용하는 것이 오히려 더 적절하다는 의미입니다.)&lt;/i&gt;&lt;/p&gt;
&lt;pre class=&quot;hsp&quot;&gt;&lt;code&gt;리액트일때..
&amp;lt;button onClick={sayHi}&amp;gt;Click me&amp;lt;/button&amp;gt;
뷰일때..
&amp;lt;button v-on:click=&quot;sayHi($event)&quot;&amp;gt;click&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(2) 이벤트 핸들러 프로퍼티 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식도 위와 동일하게 onclick과 같이 on + 이벤트 종류로 이루어짐&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button&amp;gt;Click me&amp;lt;/button&amp;gt;
&amp;lt;script&amp;gt;
	const $button = document.querySelector('button')
	
	$button.onclick = function () {
		console.log('Hi')
	}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 이벤트를 발생시킬 객체인 이벤트 타깃, 이벤트 종류를 나타내는 이벤트 타입, 그리고 이벤트 핸들러를 지정해서 쓴답니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예제에서는 $button이 이벤트 타깃, onclick이 이벤트 타입, function이 이벤트 핸들러가 된다고 하네용&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식을 쓴면, HTML과 자바스크립트가 뒤섞이는 문제를 해결할 수 있지만, 이벤트 핸들러 프로퍼티에 하나의 이벤트 핸들러만 바인딩할 수 있다는 단점이 있습니다.. 즉, 하나의 버튼에 함수 두개를 못 묶음!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(3) addEventListener 메서드 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞의 두 방식은 DOM Level 0부터 제공되던 오래된 방식이고, 이건 Level2부터 도입된 방식이라고 합니다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;EventTarget.addEventListener('eventType', functionName [, useCapture])
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 방식으로 쓴다고 합니다. 여기서는 이벤트 타입에 on을 붙이지 않고 씁니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 위의 예제를 이 방식으로 바꿔본다면,.,.&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button&amp;gt;Click me&amp;lt;/button&amp;gt;
&amp;lt;script&amp;gt;
	const $button = document.querySelector('button')
	
	$button.addEventListener('click', function() {
		console.log('hi')
	})
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;얘는 위의 방식과 달리, 여러개를 달 수도 있어요&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button&amp;gt;Click me&amp;lt;/button&amp;gt;
&amp;lt;script&amp;gt;
	const $button = document.querySelector('button')
	
	$button.addEventListener('click', function() {
		console.log('one')
	}
	
	$button.addEventListener('click', function() {
		console.log('two')
	}
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 호출 순서는 등록순 = one이 먼저 찍히고 two가 찍힘&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 똑같은 함수 등록하면 한번만 등록됩니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;40.4 이벤트 핸들러 제거&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;addEventListener 방식으로 등록한 이벤트 핸들러는 EventTarget.prototype.removeEventListener 메서드를 통해 제거합니다. 이때, 인수는 addEventLister와 동일하게 사용해요&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button&amp;gt;Click me&amp;lt;/button&amp;gt;
&amp;lt;script&amp;gt;
	const $button = document.querySelector('button')
	
	const func1 = console.log('one')
	
	$button.addEventListener('click', fucn1)
	
	$button.removeEventListener('click', func2) // 안됩니다
	$button.removeEventListener('click', func1) // 이건 됩니다
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 무명함수로 등록하면 제거가 안됨..&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button&amp;gt;Click me&amp;lt;/button&amp;gt;
&amp;lt;script&amp;gt;
	const $button = document.querySelector('button')
	
	$button.addEventListener('click', function() {
		console.log('one')
	})  // 이런건 제거가 안됩니다
	
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 addEventListener말고 다른 방식으로 등록한건요?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; removeEventListener이걸로는 안되고, null을 할당해주세요&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button&amp;gt;Click me&amp;lt;/button&amp;gt;
&amp;lt;script&amp;gt;
	const $button = document.querySelector('button')
	
	$button.onclick = function () {
		console.log('Hi')
	}
	
	$button.onclick = null // 이렇게 지워주세요
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;40.5 이벤트 객체&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이벤트가 발생하면 이벤트 객체가 동적으로 생성됨 &amp;rarr; 이 이벤트 객체가 이벤트 핸들러의 첫번째 인수로 전달됨&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button id=&quot;myBtn&quot;&amp;gt;Click me&amp;lt;/button&amp;gt;

&amp;lt;script&amp;gt;
const btn = document.getElementById('myBtn');

btn.addEventListener('click', function(e) {
    console.log('이벤트 타입:', e.type);  // 'click'
    console.log('이벤트 대상:', e.target); // 버튼 요소
});
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 매개변수 e에 암묵적으로 할당이 된다. (만약 이벤트 핸들러 어트리뷰트 방식이라면 무조건 event로 써야함)&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;이벤트 객체 ?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 이벤트 객체도 생성자 함수에 의해 생성된 객체이므로, 공통 프로퍼티를 상속받음 + 이벤트 타입에 따라서 고유한 프로퍼티가 정의되어있음&lt;/p&gt;
&lt;pre class=&quot;scilab&quot;&gt;&lt;code&gt;btn.addEventListener('click', function(e) {
    console.log(e.type);    // 모든 이벤트 객체가 가진 공통 프로퍼티
    console.log(e.target);  // 모든 이벤트 객체가 가진 공통 프로퍼티
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 공통으로 가진 프로퍼티가 있고, 각 이벤트 마다 다르게 갖는 프로퍼티가 있음.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// 마우스 이벤트의 고유 프로퍼티
btn.addEventListener('click', function(e) {
    console.log(e.clientX); // 마우스 이벤트에만 있는 프로퍼티
    console.log(e.clientY); // 마우스 이벤트에만 있는 프로퍼티
});

// 키보드 이벤트의 고유 프로퍼티
input.addEventListener('keydown', function(e) {
    console.log(e.keyCode); // 키보드 이벤트에만 있는 프로퍼티
    console.log(e.key);     // 키보드 이벤트에만 있는 프로퍼티
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;더 자세하게 각 이벤트마다 뭐가 있는지 알고 싶은 사람은 책 p.775-778을 읽어보세요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;40.6 이벤트 전파&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;첫 번째 아이템&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;두 번째 아이템&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;세 번째 아이템&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 리스트가 있을 때, li중에 하나를 클릭하면 이벤트가 발생하고, 이때 생성되는 이벤트 객체는 이벤트를 발생시킨 두번째 li를 중심으로 DOM 트리를 통해 전파된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 이벤트 전파는 방향에 따라 Capturing phase, Target phase, Bubbling phase로 나뉨&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 이벤트는 이벤트를 발생시킨 이벤트 타깃 뿐만 아니라, 상위 DOM요소에서도 캐치할 수 있음!&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;40.7 이벤트 위임&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;아이템 1&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;아이템 2&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;아이템 3&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 리스트가 있고, 각 리스트마다 클릭하면 어떤게 클릭되었는지 알고 싶어요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그랬을 때 각 li태그에 하나하나 이벤트를 등록하면 이런 문제가 생겨요&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;li가 많을수록 이벤트 리스너도 그만큼 많이 생성되어 메모리가 낭비됩니다.&lt;/li&gt;
&lt;li&gt;나중에 새로운 li가 추가되면 그 요소에도 별도로 이벤트를 등록해줘야 합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 쓰는게 이벤트 위임입니다. 부모인 ul에 이벤트를 하나만 등록하고, 이벤트 버블링을 활용해서 어떤 자식이 클릭되었는지 확인하는 방식입니다&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;아이템 1&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;아이템 2&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;아이템 3&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;

&amp;lt;script&amp;gt;
document.querySelector('ul').addEventListener('click', function(e) {
  if (e.target.tagName === 'LI') {
    console.log('클릭된 아이템:', e.target.textContent);
  }
});
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 쓰면&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;이벤트 리스너가 하나만 생성됩니다.&lt;/li&gt;
&lt;li&gt;새로운 li가 추가되어도 자동으로 이벤트 처리가 가능합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;40.8 DOM 요소의 기본 동작 조작&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;**preventDefault**&amp;rArr; 이벤트 객체의 메서드로, DOM 요소의 기본 동작을 중단시킵니다. (예를 들어, a태그 클릭하면 href에 지정된 링크로 간다던가, checkbox 클릭하면 체크 or 해제되는 기능 등등)&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;구글로 이동
document.querySelector('a').addEventListener('click', function(e) {
    e.preventDefault(); // a 태그의 기본 동작(페이지 이동) 중단
    console.log('링크가 클릭됨!');
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 구글로 이동하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;**stopPropagation**&amp;rArr; 얘도 이벤트 객체의 메서드로, 이벤트 전파를 중단시킵니다.&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;div&amp;gt;
    &amp;lt;button&amp;gt;클릭&amp;lt;/button&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;script&amp;gt;
const div = document.querySelector('div');
const button = document.querySelector('button');

div.addEventListener('click', () =&amp;gt; {
    console.log('div 클릭됨');
});

button.addEventListener('click', (e) =&amp;gt; {
    e.stopPropagation(); // 이벤트 버블링 중단
    console.log('button 클릭됨');
});
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 여기서는 div에 달린 이벤트는 발생하지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;40.9 이벤트 핸들러 내부의 this&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(1) 이벤트 핸들러 어트리뷰트 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방식에서는 this = 전역 객체 window&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;(2) 이벤트 핸들러 프로퍼티 방식과 (3) addEventListener 메서드 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서는 this = 이벤트를 바인딩한 DOM 요소 = e.currentTarget과 같음&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button onclick=&quot;handleClick()&quot;&amp;gt;어트리뷰트 방식&amp;lt;/button&amp;gt;
&amp;lt;button id=&quot;propertyBtn&quot;&amp;gt;프로퍼티 방식&amp;lt;/button&amp;gt;
&amp;lt;button id=&quot;addEventBtn&quot;&amp;gt;addEventListener 방식&amp;lt;/button&amp;gt;

&amp;lt;script&amp;gt;
// 1. 어트리뷰트 방식
function handleClick() {
    console.log('어트리뷰트 방식의 this:', this);  
    // Window 

// 2. 프로퍼티 방식
document.getElementById('propertyBtn').onclick = function(e) {
    console.log('프로퍼티 방식의 this:', this);  
    // &amp;lt;button id=&quot;propertyBtn&quot;&amp;gt;프로퍼티 방식&amp;lt;/button&amp;gt;
    console.log('e.currentTarget:', e.currentTarget);  
    // &amp;lt;button id=&quot;propertyBtn&quot;&amp;gt;프로퍼티 방식&amp;lt;/button&amp;gt;
};

// 3. addEventListener 방식
document.getElementById('addEventBtn').addEventListener('click', function(e) {
    console.log('addEventListener 방식의 this:', this);  
    // &amp;lt;button id=&quot;addEventBtn&quot;&amp;gt;addEventListener 방식&amp;lt;/button&amp;gt;
    console.log('e.currentTarget:', e.currentTarget);  
    // &amp;lt;button id=&quot;addEventBtn&quot;&amp;gt;addEventListener 방식&amp;lt;/button&amp;gt;
});
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;40.10 이벤트 핸들러에 인수 전달&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까 1번 방식은 함수에 인수 전달이 가능했었음. 근데 2번과 3번 방식은 어떻게 하나요?&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button id=&quot;propertyBtn&quot;&amp;gt;프로퍼티 방식&amp;lt;/button&amp;gt;
&amp;lt;button id=&quot;addEventBtn&quot;&amp;gt;addEventListener 방식&amp;lt;/button&amp;gt;

&amp;lt;script&amp;gt;
// 이벤트 핸들러
function handleClick(name) {
   console.log(`${name}님이 클릭했습니다!`);
}

// 2. 프로퍼티 방식 - 인수 전달
document.getElementById('propertyBtn').onclick = () =&amp;gt; handleClick('Kim');

// 3. addEventListener 방식 - 인수 전달
document.getElementById('addEventBtn').addEventListener('click', () =&amp;gt; handleClick('Lee'));
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;40.11 커스텀 이벤트&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;= 개발자의 의도대로 생성된 이벤트&lt;/p&gt;
&lt;pre class=&quot;xml&quot;&gt;&lt;code&gt;&amp;lt;button id=&quot;myBtn&quot;&amp;gt;클릭하세요&amp;lt;/button&amp;gt;

&amp;lt;script&amp;gt;
// 1. 마우스 이벤트 기반의 커스텀 이벤트 생성
const customMouseEvent = new MouseEvent('customClick', {
    bubbles: true,          // 버블링 활성화
    clientX: 100,           // X 좌표 지정
    clientY: 200,           // Y 좌표 지정
    view: window
});

const btn = document.getElementById('myBtn');

// 2. 커스텀 이벤트에 대한 이벤트 핸들러 등록 -&amp;gt; 마우스가 어디에 있던 항상 100,200이 나옴
btn.addEventListener('customClick', function (e) {
    console.log('X 좌표:', e.clientX);  // 100
    console.log('Y 좌표:', e.clientY);  // 200
});

// 3. 버튼 클릭 시 커스텀 이벤트 발생
btn.addEventListener('click', function() {
    this.dispatchEvent(customMouseEvent);
});
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성한 커스텀 이벤트는 dispatchEvent를 통해 실행시킬 수 있음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스터디하면서 정리한 것들 아카이빙중..&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <category>FrontEnd/JavaScript</category>
      <category>Javascript</category>
      <category>javascript deep dive</category>
      <category>이벤트</category>
      <author>Memez</author>
      <guid isPermaLink="true">https://memezz.tistory.com/199</guid>
      <comments>https://memezz.tistory.com/199#entry199comment</comments>
      <pubDate>Tue, 4 Feb 2025 14:55:14 +0900</pubDate>
    </item>
    <item>
      <title>[JS] Set과 Map</title>
      <link>https://memezz.tistory.com/198</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Ja9tC/btsLtgiatOl/bmfAQt2jUfjFiU5lOmHBX0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Ja9tC/btsLtgiatOl/bmfAQt2jUfjFiU5lOmHBX0/img.png&quot; data-alt=&quot;Ch.37 Set과 Map&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Ja9tC/btsLtgiatOl/bmfAQt2jUfjFiU5lOmHBX0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJa9tC%2FbtsLtgiatOl%2FbmfAQt2jUfjFiU5lOmHBX0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;460&quot; height=&quot;241&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Ch.37 Set과 Map&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; Set&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;= 중복되지 않는 유일한 값들의 집합&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중복이 안됨&lt;/li&gt;
&lt;li&gt;순서에 의미가 없음&lt;/li&gt;
&lt;li&gt;인덱스로 요소 접근 불가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Set 객체 생성 = Set 생성자 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734870026415&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 빈객체 
const set = new Set()
console.log(set)   // Set(0)&amp;nbsp;{size: 0}

// 이터러블을 인수로 받음
const set1 = new Set([1, 2, 3, 4])
console.log(set1)  // Set(3) {1, 2, 3}
const set2 = new Set('hello')
console.log(set2)  // Set(4) {'h', 'e', 'l', 'o'} 중복된 l은 한개만 들어감&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중복된 요소가 인수로 들어가면 한개만 들어감 -&amp;gt; 이를 이용해서 배열에서 중복된 요소를 제거할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1734870306551&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const uniq = array =&amp;gt; [... new Set(array)]
console.log(uniq([1, 2, 2, 2, 3, 3, 4, 5]))   // [1, 2, 3, 4, 5]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Set.prototype.size = 객체의 요소 개수 확인&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734870452125&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const {size} = new Set([1, 2, 3, 3])  // set만들고 set.size로 해도 같은 값
console.log(size)  // 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Set.prototype.add = 요소 추가&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734870511572&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const set = new Set()
set.add(1)
console.log(set)   // Set(1) {1}

// 연속으로 사용가능 -&amp;gt; add가 객체를 반환하기 때문에
set.add(2).add(3)
console.log(set)  // Set(3)&amp;nbsp;{1, 2, 3}

// 중복된 요소는 무시됨
set.add(1)
console.log(set)  // Set(3)&amp;nbsp;{1, 2, 3}


// NaN의 경우..
console.log(NaN === NaN)  // false지만, set에서는 같다고 평가됨
set.add(NaN).add(NaN)  // 한개만 들어감&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Set.prototype.has = 요소 존재 여부 확인&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734870758896&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const set = new Set([1, 2, 3])
console.log(set.has(1))  // true
console.log(set.has(5))  // false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Set.prototype.delete = 요소 삭제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삭제 성공 여부를 반환함&lt;/p&gt;
&lt;pre id=&quot;code_1734870836971&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const set = new Set([1, 2, 3])
console.log(set.delete(1))  // true
console.log(set)   // Set(2)&amp;nbsp;{2, 3}

set.delete(5)  // 무시됨
set.delete(3).delete(2) // 연속으로 사용 불가능&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Set.prototype.clear = 모든 요소 삭제&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;undefined 반환&lt;/p&gt;
&lt;pre id=&quot;code_1734870947189&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const set = new Set([1, 2, 3])
console.log(set.clear())   // undefined
console.log(set)    // Set(0)&amp;nbsp;{size: 0}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Set.prototype.forEach = 요소 순회&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콜백함수의 인수&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫번째 인수: 현재 순회 중인 요소값&lt;/li&gt;
&lt;li&gt;두번째 인수: 현재 순회 중인 요소값&lt;/li&gt;
&lt;li&gt;세번째 인수: 현재 순회 중인 Set 객체 자체&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1734871145963&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const set = new Set([1, 2, 3])
set.forEach((v, v2, set) =&amp;gt; console.log(v, v2, set))
// 1 1 Set(3)&amp;nbsp;{1, 2, 3}
// 2 2 Set(3) {1, 2, 3}
// 3 3 Set(3) {1, 2, 3}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫번째랑 두번째가 똑같은데 왜 굳이 이렇게 받을까&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; Array.prototype.forEach를 따라가기 위해서.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;array의 경우도 똑같이 세개를 받는데, 두번째 인수가 순회중인 요소의 인덱스임. 근데 set는 인덱스가 없으니까 그냥 첫번째 인수랑 같은 걸로...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Set 객체는 이터러블이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 for ... of도 사용가능하고, 스프레드 문법과 배열 디스트럭처링도 가능&lt;/p&gt;
&lt;pre id=&quot;code_1734871351037&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const set = new Set([1, 2, 3])

for (const v of set) {
	console.log(v) // 1 2 3
}

console.log([...set]) // [1, 2, 3]&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Set를 활용해서 집합 연산을 만들어보자&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(1) 교집합&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734871472761&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Set.prototype.intersection = function(set) {
    return new Set([...this].filter(v =&amp;gt; set.has(v)))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(2) 합집합&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734871602395&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Set.prototype.union = function (set) { 
	return new Set([...this, ...set])
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(3) 차집합&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734871660178&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Set.prototype.difference = function (set) {
	return new Set([...this].filter(v =&amp;gt; !set.has(v))
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; Map&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;= 키와 값의 쌍으로 이루어진 컬렉션&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cbR33O/btsLtWKnUdi/XKSGqIdq9KTX0EwCVIEnyK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cbR33O/btsLtWKnUdi/XKSGqIdq9KTX0EwCVIEnyK/img.png&quot; data-alt=&quot;Map객체와 객체(object)와의 차이점&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cbR33O/btsLtWKnUdi/XKSGqIdq9KTX0EwCVIEnyK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcbR33O%2FbtsLtWKnUdi%2FXKSGqIdq9KTX0EwCVIEnyK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;746&quot; height=&quot;215&quot; data-origin-width=&quot;903&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Map객체와 객체(object)와의 차이점&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Map 객체 생성 = Map생성자 사용&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이터러블을 인수로 전달받으며, 키와 값의 쌍으로 이루어진 요소로 구성되어야 함&lt;/p&gt;
&lt;pre id=&quot;code_1734871918153&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 비었을 때
const map = new Map()
console.log(map)   // Map(0)&amp;nbsp;{size: 0}

// 이터러블을 인수로
const map1 = new Map([['key1', 'value1'], ['key2', 'value2']])
console.log(map1)   // Map(2)&amp;nbsp;{'key1' =&amp;gt; 'value1', 'key2' =&amp;gt; 'value2'}

const map2 = new Map([1, 2])  // TypeError: Iterator value 1 is not an entry object
// 무조건 [['key1', 'value1'], ['key2', 'value2']] 이런 형식으로 들어와야하는데,
// 여기선 [1, 2]로 들어옴. 그래서 1을 ['key1', 'value1']의 형식으로 해석하려다가 실패

// key가 중복되면 뒤에 들어오는 value로 덮어씌워짐
const map3 = new Map([['key1', 'value1'], ['key1', 'value2']])
console.log(map3)  // Map(1)&amp;nbsp;{'key1' =&amp;gt; 'value2'}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Map.prototype.size = 갯수 확인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Map.prototype.set = 요소 추가&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734872345634&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const map = new Map()
map.set('key1', 'value1').set('key2', 'value2')  // 연속 호출 가능
console.log(map)   // Map(2)&amp;nbsp;{'key1' =&amp;gt; 'value1', 'key2' =&amp;gt; 'value2'}

// 객체를 key로 쓰는것도 가능
const user1 = { name: '철수' }
const user2 = { name: '영희' }

const userScores = new Map()
userScores.set(user1, 90)
userScores.set(user2, 85)

console.log(userScores)   // Map(2) {{name: '철수'} =&amp;gt; 90, {name: '영희'} =&amp;gt; 85}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Map.prototype.get = 요소 가져오기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734872598862&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const map = new Map()
map.set('key1', 'value1').set('key2', 'value2')
console.log(map.get('key1'))  // value1
console.log(map.get('key6'))  // 없으면 undefined&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Map.prototype.has = 존재 여부 확인&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Map.prototype.delete = 요소 삭제&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734872690958&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const map = new Map()
map.set('key1', 'value1').set('key2', 'value2')
console.log(map.delete('key1'))  // true
console.log(map)  // Map(1) {'key2' =&amp;gt; 'value2'}

console.log(map.get('key6'))  // 없으면 undefined(무시됨)
console.log(map)  // Map(1) {'key2' =&amp;gt; 'value2'}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Map.prototype.clear = 일괄 삭제&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; Map.prototype.forEach = 요소 순회&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;콜백함수의 인수&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;첫번째 인수: 현재 순회 중인 요소값&lt;/li&gt;
&lt;li&gt;두번째 인수: 현재 순회 중인 요소키&lt;/li&gt;
&lt;li&gt;세번째 인수: 현재 순회 중인 Map 객체 자체&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1734872815494&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const fruits = new Map([
    ['사과', 500],
    ['바나나', 700],
    ['오렌지', 600]
])

fruits.forEach((value, key, map) =&amp;gt; {
    console.log(`value: ${value}`)
    console.log(`key: ${key}`)
    console.log(`전체 Map:`, map)
    console.log('---------------')
})

// 출력 결과:
// value: 500
// key: 사과
// 전체 Map: Map(3) { '사과' =&amp;gt; 500, '바나나' =&amp;gt; 700, '오렌지' =&amp;gt; 600 }
// ---------------
// value: 700
// key: 바나나
// 전체 Map: Map(3) { '사과' =&amp;gt; 500, '바나나' =&amp;gt; 700, '오렌지' =&amp;gt; 600 }
// ---------------
// value: 600
// key: 오렌지
// 전체 Map: Map(3) { '사과' =&amp;gt; 500, '바나나' =&amp;gt; 700, '오렌지' =&amp;gt; 600 }
// ---------------


// 스프레드 문법
console.log([...fruits])  // [['사과', 500], ['바나나', 700], ['오렌지', 600]]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;keys, values, entries 메서드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;-&amp;gt; 각자 Map 객체의 요소키, 요소값, 요소키 + 요소값을 이터러블이면서 이터레이터인 객체로 반환&lt;/p&gt;
&lt;pre id=&quot;code_1734873008163&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const fruits = new Map([
   ['사과', 500],
   ['바나나', 700],
   ['오렌지', 600]
])

console.log(fruits.keys())  // [Map Iterator] { '사과', '바나나', '오렌지' }
console.log(fruits.values())  // [Map Iterator] { 500, 700, 600 }
console.log(fruits.entries())  // [Map Entries] { [ '사과', 500 ], [ '바나나', 700 ], [ '오렌지', 600 ] }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>FrontEnd/JavaScript</category>
      <category>Javascript</category>
      <category>map객체</category>
      <category>Set객체</category>
      <author>Memez</author>
      <guid isPermaLink="true">https://memezz.tistory.com/198</guid>
      <comments>https://memezz.tistory.com/198#entry198comment</comments>
      <pubDate>Sun, 22 Dec 2024 22:15:27 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 정규표현식</title>
      <link>https://memezz.tistory.com/197</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpZWjN/btsLqYJJlsw/duUwLngo1sJAcoHIqkGRy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpZWjN/btsLqYJJlsw/duUwLngo1sJAcoHIqkGRy1/img.png&quot; data-alt=&quot;Ch.31 정규표현식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpZWjN/btsLqYJJlsw/duUwLngo1sJAcoHIqkGRy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpZWjN%2FbtsLqYJJlsw%2FduUwLngo1sJAcoHIqkGRy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;460&quot; height=&quot;241&quot; data-origin-width=&quot;460&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Ch.31 정규표현식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  정규 표현식이란?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자열을 대상으로 패턴 매칭 기능을 제공 = 특정 패턴과 일치하는 문자열을 &lt;b&gt;검색 or 추출 or 치환&lt;/b&gt;하는 기능&lt;/p&gt;
&lt;pre id=&quot;code_1734712970418&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const tel = 010-1234-5678;
const regExp = /^\d{3}-\d{4}-\d{4}/;

// tel이 조건에 맞는지 테스트
regExp.test(tel);  // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; 사용하는 방법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 정규표현식 리터럴&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;rarr; 패턴과 플래그로 구성&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/maE0Q/btsLs7SGBcU/v1DjkxjN8rR1fnKpOP9uqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/maE0Q/btsLs7SGBcU/v1DjkxjN8rR1fnKpOP9uqK/img.png&quot; data-alt=&quot;정규표현식 리터럴&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/maE0Q/btsLs7SGBcU/v1DjkxjN8rR1fnKpOP9uqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmaE0Q%2FbtsLs7SGBcU%2Fv1DjkxjN8rR1fnKpOP9uqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;350&quot; height=&quot;157&quot; data-origin-width=&quot;397&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정규표현식 리터럴&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;pre id=&quot;code_1734713299562&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target1 = 'Is this all there is?';
const target2 = 'Is this all?';

// 패턴: is
// 플래그: i =&amp;gt; 대소문자를 구별하지 않고 검색
const regexp = /is/i;

regexp.test(target1); // true
regexp.test(target2); // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;2. RegExp 생성자 함수&lt;/p&gt;
&lt;pre id=&quot;code_1734713361251&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;new RegExp(pattern[, flags])&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1734713390503&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// RegExp 생성자 함수 사용 예시
const target = 'Is this all there is?';
const regexp = new RegExp(/is/i);
regexp.test(target); // true

// 동적으로 사용 가능
const count = (str, char) =&amp;gt; (str.match(new RegExp(char, 'gi')) ?? []).length;  // gi는 문자열 전체에서 대소문자 구분 안하고
count('Is this all there is?', 'is') // 3 -&amp;gt; is가 Is에 하나, this에 하나, 마지막에 하나
count('Is this all there is?', 'xx') // 0 -&amp;gt; xx는 없음&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; RegExp의 메서드들&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;1. exec 메서드&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인수로 전달받은 문자열에 대해 패턴을 검색해서 매칭 결과를 배열로 반환, 없으면 null 반환&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 패턴을 검색하는 g 플래그로 해도 무조건 &lt;b&gt;첫번째 매칭 결과만을 반환함!!!&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1734713989889&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'Is this all ther is?'
const regExp = /is/i
console.log(regExp.exec(target))

// 결과값
[
  0: &quot;Is&quot;,               // 매치된 문자열 전체
  index: 0,              // 매치가 발견된 시작 인덱스 위치
  input: &quot;Is this all ther is?&quot;,  // 검색이 수행된 원본 문자열
  groups: undefined      // 정규식에서 캡처 그룹이 있을 경우 여기에 저장됨
]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;2. test 메서드&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인수로 전달받은 문자열에 대해 패턴을 검색해서 매칭 결과를 boolean으로 반환&lt;/p&gt;
&lt;pre id=&quot;code_1734714141360&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'Is this all ther is?'
const regExp = /is/i
console.log(regExp.test(target))  // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;3. match 메서드(String의 빌드인 객체 &amp;rarr; 문자열에 붙여서 써야함)&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대상 문자열과 인수로 전달받은 정규 표현식과의 매칭 결과를 배열로 반환&lt;/p&gt;
&lt;pre id=&quot;code_1734714247822&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'Is this all there is?'
const regexp = /is/
console.log(target.match(regexp))

// 결과값
[
  0: &quot;is&quot;,              // 매치된 문자열
  index: 5,             // 매치가 발견된 위치 (this의 'is')
  input: &quot;Is this all there is?&quot;,    // 원본 문자열
  groups: undefined     // 캡처 그룹 결과 (여기서는 사용하지 않음)
]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;exec 메서드와 비슷하게 반환되지만, 다른점은&lt;b&gt; g 플래그를 사용하면 모든 매칭 결과&lt;/b&gt;를 배열로 반환함&lt;/p&gt;
&lt;pre id=&quot;code_1734714328112&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const regexp = /is/g;  // g 플래그 추가
console.log(target.match(regexp));
// 결과: [&quot;is&quot;, &quot;is&quot;]  - 'this'와 마지막 'is'의 두 개가 배열로 반환&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; 플래그&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정규 표현식에서 검색 방식을 설정하기 위해 사용됨&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dWVPVu/btsLsNGW4OU/deTBxS7AiKSit2CfXmYeXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dWVPVu/btsLsNGW4OU/deTBxS7AiKSit2CfXmYeXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dWVPVu/btsLsNGW4OU/deTBxS7AiKSit2CfXmYeXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdWVPVu%2FbtsLsNGW4OU%2FdeTBxS7AiKSit2CfXmYeXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;726&quot; height=&quot;193&quot; data-origin-width=&quot;741&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;필수가 아님&lt;/li&gt;
&lt;li&gt;순서 상관 없이 여러개 사용 가능&lt;/li&gt;
&lt;li&gt;플래그가 없다면 대소문자 구별됨 + 첫번째 매칭 대상이 검색되면 종료&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; 패턴&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일정한 규칙을 표현하기 위해 사용됨&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;/로 열고 닫으며 따옴표는 생략&lt;/li&gt;
&lt;li&gt;특별한 의미를 가지는 메타문자 or 기호로 표현 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;임의의 문자열 검색&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;점 하나(.) = 임의의 문자 한개&lt;/p&gt;
&lt;pre id=&quot;code_1734715233768&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'Is this all there is?'
const regexp = /.../g
// 임의의 3개의 문자를 대소문자 구별해서 전역 검색
target.match(regexp) // ['Is ', 'thi', 's a', 'll ', 'the', 're ', 'is?']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;반복 검색&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(1) {m,n}은 앞선 패턴이 최소 m번, 최대 n번 반복되는 문자열&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여기서 {m, n}이런식으로 중간에 띄어쓰기하면 동작 안함&lt;/li&gt;
&lt;li&gt;{n} 이렇게 하나만 있으면 {n,n}과 동일&lt;/li&gt;
&lt;li&gt;{n,} 이렇게 뒤에가 생략되어 있으면 {1,&amp;infin;}와 동일 = 최소 n번&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1734715400489&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'A AA B BB Aa Bb AAA'
const regExp = /A{1,2}/g
// A가 최소 1번, 최대 2번 반복되는 문자열 전역 검색
target.match(regExp)  // ['A', 'AA', 'A', 'AA', 'A']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(2) +는 앞선 패턴이 최소 한번 이상 반복되는 문자열&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, +는 {1,}과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1734715749916&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'A AA B BB Aa Bb AAA'
const regExp = /A+/g
// A가 최소 1번 반복되는 문자열 전역 검색
target.match(regExp)   // ['A', 'AA', 'A', 'AAA']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;(3) ?는 최대 한번 반복되는 문자열&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, ?는 {0,1}과 동일함&lt;/p&gt;
&lt;pre id=&quot;code_1734715922599&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'color colour colouur'
// colo까지는 있어야하고, u는 최대 한번(없어도 됨), r이 있어야함
const regExp = /colou?r/g
target.match(regExp)  // ['color', 'colour']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;u&gt;OR 검색&lt;/u&gt;&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;| 사용&lt;/li&gt;
&lt;li&gt;[ ] 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1734716140197&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'A AA B BB Aa Bb'

// 전역에서 A 또는 B 검색
const regExp1 = /A|B/g
target.match(regExp1) // ['A', 'A', 'A', 'B', 'B', 'B', 'A', 'B']

// 분해 안하고 검색하려면 +를 함께 사용
const regExp2 = /A+|B+/g
target.match(regExp2) // ['A', 'AA', 'B', 'BB', 'A', 'B']

// 근데 2번을 []를 이용해서 이렇게도 쓸 수 있음
const regExp3 = /[AB]+/g
target.match(regExp3) // ['A', 'AA', 'B', 'BB', 'A', 'B']

// 만약 범위를 지정하고 싶으면 []안에 -를 사용
const regExp4 = /[A-Z]+/g
// 이 경우엔 대문자 알파벳 검색
target.match(regExp4)  // ['A', 'AA', 'B', 'BB', 'A', 'B']

// 대소문자 구별 안할려면 이렇게
const regExp5 = /[A-Za-z]+/g
target.match(regExp5)  // ['A', 'AA', 'B', 'BB', 'Aa', 'Bb']

// 이걸 활용해서 숫자도 가능
const newTarget = 'AA BB 12,345'
const regExp6 = /[0-9]+/g
newTarget.match(regExp6) // ['12', '345']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[A-Z], [0-9]이렇게 일일히 써주는 대신, \d, \w등을 이용해서 간단하게 쓸 수도 있음&lt;/p&gt;
&lt;pre id=&quot;code_1734716820843&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'AA BB 12,345'

// \d는 숫자
const regExp1 = /[\d,]+/g    // 숫자 또는 ','가 한번 이상 반복되는 문자열
target.match(regExp1)  // ['12,345']

// \D는 숫자가 아닌 문자
const regExp2 = /[\D,]+/g
target.match(regExp2)  // ['AA BB ', ',']

// \w는 알파벳, 숫자, 언더스코어 [A-Za-z0-9_]와 같음
const regExp3 = /[\w,]+/g
target.match(regExp3)  // ['AA', 'BB', '12,345']

// \W는 \w의 반대
const regExp4 = /[\W,]+/g
target.match(regExp4)  // [' ', ' ', ',']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;NOT검색&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ ] 안에서의&lt;/b&gt; ^는 not을 의미함(ex. [^0-9]는 숫자를 제외한 문자)&lt;/p&gt;
&lt;pre id=&quot;code_1734717233997&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'AA BB 12 Aa Bb'
// 숫자 제외 검색
const regExp = /[^0-9]+/g
target.match(regExp)  // ['AA BB ', ' Aa Bb']&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;시작 위치로 검색&lt;/b&gt;&lt;/u&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[ ] 밖에서의&lt;/b&gt; ^는 문자열의 시작&lt;/p&gt;
&lt;pre id=&quot;code_1734717128144&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'https://memezz.tistory.com'
const regExp = /^https/g
regExp.test(target)  // true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 위치로 검색&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$는 문자열의 마지막을 의미&lt;/p&gt;
&lt;pre id=&quot;code_1734717274304&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const target = 'https://memezz.tistory.com'
const regExp = /com$/g
regExp.test(target)  // true&lt;/code&gt;&lt;/pre&gt;</description>
      <category>FrontEnd/JavaScript</category>
      <category>DeepDive</category>
      <category>모던자바스크립트</category>
      <category>정규표현식</category>
      <author>Memez</author>
      <guid isPermaLink="true">https://memezz.tistory.com/197</guid>
      <comments>https://memezz.tistory.com/197#entry197comment</comments>
      <pubDate>Sat, 21 Dec 2024 02:55:41 +0900</pubDate>
    </item>
    <item>
      <title>[유데미x스나이퍼팩토리] 프론트엔드 프로젝트 캠프 - npm과 pnpm, yarn / axios와 fetch</title>
      <link>https://memezz.tistory.com/196</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ewQbS9/btsLjrkaQ4o/kWZ2k6kFr2XMk6ERUNDym1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ewQbS9/btsLjrkaQ4o/kWZ2k6kFr2XMk6ERUNDym1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ewQbS9/btsLjrkaQ4o/kWZ2k6kFr2XMk6ERUNDym1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FewQbS9%2FbtsLjrkaQ4o%2FkWZ2k6kFr2XMk6ERUNDym1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;599&quot; height=&quot;337&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;벌써 프로젝트를 시작한지 2주가 되었습니다..&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1주차는 git 컨벤션과 폴더 구조, 역할 분배등의 협업을 위한 것들을 정했는데요,,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 중에 &quot;패키지 매니저인 npm과 pnpm, yarn 중에 뭐를 쓸지&quot;와 &quot;fetch가 있는데 axios를 써야할까요?&quot;라는 회의 내용을 기반으로 각각 무엇이 다른지, 어떤걸 쓰는게 좋은지를 한 번 정리해보고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; 패키지 매니저란?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;import나 require등을 이용해서 외부 의존성을 참조할 때, 올바르게 참조할 수 있도록 보장해주는 프로그램&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 다음과 같이 import 문을 쓴다고 가정해보자&lt;/p&gt;
&lt;pre id=&quot;code_1734194306966&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import React from 'react';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 여기서 react의 버전이 뭔지를 정확하게 알수가 없다..!&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이걸 package.json 파일에 명시를 해줘서 특정 버전의 react를 참조할 수 있도록 해주는데, 그걸 도와주는 게 패키지 매니저!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 패키지 매니저는 언어별로 있는데, 예를 들어 python에서는 pip, conda / java에서는 maven, gradle이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 중 javascript에서는 주로 npm, yarn, pnpm이 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;npm&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;node.js와 함께 제공되는 기본 패키지 매니저로,&lt;br /&gt;사용자가 많고 가장 오래 사용되었음&lt;/li&gt;
&lt;li&gt;package.json파일로 의존성을 관리함&lt;/li&gt;
&lt;li&gt;대규모 프로젝트에서는 속도와 성능이 저하됨(node_modules의 크기가 매우 커짐)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;yarn&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;facebook에서 npm의 문제를 대안하기 위해 만듦&lt;/li&gt;
&lt;li&gt;npm보다 빠른 설치 속도&lt;/li&gt;
&lt;li&gt;yarn.lock으로 의존성을 관리&lt;/li&gt;
&lt;li&gt;호환성 문제가 발생할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;pnpm&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;가장 최근에 나온 패키지 매니저로 (performant)npm, 즉 퍼포먼스가 향상된 npm&lt;/li&gt;
&lt;li&gt;node_modules의 용량을 최적화해서 사용(hard link방식 = alias를 걸어서 단순히, npm은 node_modules를 복사해서 사용하지만 alias를 이용해서 바로 접근해서 의존성이 디스크에 하나만 설치됨)&lt;/li&gt;
&lt;li&gt;하지만 node_modules는 그대로 유지하기 때문에 require나 import시 파일 읽기가 여러번 발생해서 느려질 수도 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 프로젝트에서는 node_modules의 용량을 줄일 수 있고, 설치 속도가 빠른 pnpm을 선택해서 하기로 결정했다..!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두번째로 나온 이슈로는 axios를 깔아야할까? javascript에서 제공하는 fetch가 비슷한 역할을 하지 않나요? 였다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그럼 둘은 어떤 차이가 있고, axios를 많이 사용하는데 그 이유는 뭔지 알아보자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  fetch&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;fetch 는 요청을 보내고, 응답을 받아오는 javascript의 내장함수로 기본적으로 async/await와 함께 사용한다&lt;/p&gt;
&lt;pre id=&quot;code_1734196178236&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;async function getData() {
  try {
    const response = await fetch('주소');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단하게 사용할 수 있지만, .json으로 응답 데이터를 수동으로 변환하는 것과 인터셉터를 직접 구현해야한다는 단점이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 네트워크 에러일 때에만 reject를 반환하기 때문에 400, 500 대 에러는 잡을 수가 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 단점들을 보완하기 위해 axios를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  axios&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;axios는 node.js와 브라우저를 위한 promise기반 http클라이언트 라이브러리로, &lt;br /&gt;fetch의 단점이었던 json을 자동으로 변환해주고, 인터셉터도 설정을 할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1734196609986&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pnpm add axios&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;pnpm에서는 다음과 같은 명령어로 설치할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1734196672196&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import axios from 'axios';

axios.get('주소')
  .then(response =&amp;gt; console.log(response.data))
  .catch(error =&amp;gt; console.error(error));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 프로젝트에서도 아무래도 더 간단한 코드를 작성할 수 있고, 에러의 처리도 훨신 편한 axios를 사용하기로 결정했다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고한 글들&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://toss.tech/article/lightning-talks-package-manager&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://toss.tech/article/lightning-talks-package-manager&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1734196029175&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;패키지 매니저의 과거, 토스의 선택, 그리고 미래&quot; data-og-description=&quot;토스는 왜 패키지 매니저로 Yarn을 선택했을까요? 이번 라이트닝 토크에서는 JavaScript의 패키지 매니저, 동작 방식, 그리고 토스의 선택과 앞으로의 방향성에 대해 이야기해 보려고 해요.&quot; data-og-host=&quot;toss.tech&quot; data-og-source-url=&quot;https://toss.tech/article/lightning-talks-package-manager&quot; data-og-url=&quot;https://toss.tech/article/lightning-talks-package-manager&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/A4nXO/hyXKsSqQ1I/X9riS7A3rVQkOXk4qVbEb0/img.png?width=3000&amp;amp;height=1534&amp;amp;face=0_0_3000_1534,https://scrap.kakaocdn.net/dn/btZgHO/hyXKuistky/IwlibEdRlm4e8rnLiRdkX0/img.png?width=3000&amp;amp;height=1534&amp;amp;face=0_0_3000_1534,https://scrap.kakaocdn.net/dn/bCuaHI/hyXKlyX9g2/0w7qLTknEt6QQxneik8kWK/img.png?width=1340&amp;amp;height=1437&amp;amp;face=0_0_1340_1437&quot;&gt;&lt;a href=&quot;https://toss.tech/article/lightning-talks-package-manager&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://toss.tech/article/lightning-talks-package-manager&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/A4nXO/hyXKsSqQ1I/X9riS7A3rVQkOXk4qVbEb0/img.png?width=3000&amp;amp;height=1534&amp;amp;face=0_0_3000_1534,https://scrap.kakaocdn.net/dn/btZgHO/hyXKuistky/IwlibEdRlm4e8rnLiRdkX0/img.png?width=3000&amp;amp;height=1534&amp;amp;face=0_0_3000_1534,https://scrap.kakaocdn.net/dn/bCuaHI/hyXKlyX9g2/0w7qLTknEt6QQxneik8kWK/img.png?width=1340&amp;amp;height=1437&amp;amp;face=0_0_1340_1437');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;패키지 매니저의 과거, 토스의 선택, 그리고 미래&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;토스는 왜 패키지 매니저로 Yarn을 선택했을까요? 이번 라이트닝 토크에서는 JavaScript의 패키지 매니저, 동작 방식, 그리고 토스의 선택과 앞으로의 방향성에 대해 이야기해 보려고 해요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;toss.tech&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://devocean.sk.com/blog/techBoardDetail.do?ID=166592&amp;amp;boardType=techBlog&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://devocean.sk.com/blog/techBoardDetail.do?ID=166592&amp;amp;boardType=techBlog&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1734196035398&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;패키지 매니저 선택을 위한 여정: NPM에서 Yarn으로 그리고 다시 pNPM&quot; data-og-description=&quot; &quot; data-og-host=&quot;devocean.sk.com&quot; data-og-source-url=&quot;https://devocean.sk.com/blog/techBoardDetail.do?ID=166592&amp;amp;boardType=techBlog&quot; data-og-url=&quot;https://devocean.sk.com/blog/techBoardDetail.do?ID=166592&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/seOOU/hyXKxlSLgW/VcbqyVC0xyklYDVfqZoMKk/img.jpg?width=720&amp;amp;height=557&amp;amp;face=0_0_720_557,https://scrap.kakaocdn.net/dn/fi3Pj/hyXKlZ4p2D/0pb4IJk6TcglkQ8Gs8fVN0/img.jpg?width=720&amp;amp;height=557&amp;amp;face=0_0_720_557,https://scrap.kakaocdn.net/dn/l3k9h/hyXKv9uvfn/27KqlrUUfPVXHzUJDBB2m1/img.png?width=1000&amp;amp;height=448&amp;amp;face=0_0_1000_448&quot;&gt;&lt;a href=&quot;https://devocean.sk.com/blog/techBoardDetail.do?ID=166592&amp;amp;boardType=techBlog&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://devocean.sk.com/blog/techBoardDetail.do?ID=166592&amp;amp;boardType=techBlog&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/seOOU/hyXKxlSLgW/VcbqyVC0xyklYDVfqZoMKk/img.jpg?width=720&amp;amp;height=557&amp;amp;face=0_0_720_557,https://scrap.kakaocdn.net/dn/fi3Pj/hyXKlZ4p2D/0pb4IJk6TcglkQ8Gs8fVN0/img.jpg?width=720&amp;amp;height=557&amp;amp;face=0_0_720_557,https://scrap.kakaocdn.net/dn/l3k9h/hyXKv9uvfn/27KqlrUUfPVXHzUJDBB2m1/img.png?width=1000&amp;amp;height=448&amp;amp;face=0_0_1000_448');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;패키지 매니저 선택을 위한 여정: NPM에서 Yarn으로 그리고 다시 pNPM&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;devocean.sk.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;a href=&quot;https://f-lab.kr/insight/understanding-package-managers&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://f-lab.kr/insight/understanding-package-managers&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-style=&quot;style6&quot; data-ke-type=&quot;horizontalRule&quot; /&gt;
&lt;p style=&quot;color: #3a4954; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;본 후기는 본 후기는 [유데미x스나이퍼팩토리] 프론트엔드 프로젝트 캠프 과정(B-log) 리뷰로 작성 되었습니다.&lt;/p&gt;</description>
      <category>교육/프론트엔드 프로젝트 캠프</category>
      <author>Memez</author>
      <guid isPermaLink="true">https://memezz.tistory.com/196</guid>
      <comments>https://memezz.tistory.com/196#entry196comment</comments>
      <pubDate>Sun, 15 Dec 2024 02:20:37 +0900</pubDate>
    </item>
    <item>
      <title>[카카오모빌리티] 지원 후기 및 회고(~2차 코테)</title>
      <link>https://memezz.tistory.com/195</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-10-17 오후 9.07.52.png&quot; data-origin-width=&quot;2102&quot; data-origin-height=&quot;1320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cZPSMP/btsJ9mSOs7c/VC2JBJ3YFFNTU3ONn6alHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cZPSMP/btsJ9mSOs7c/VC2JBJ3YFFNTU3ONn6alHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cZPSMP/btsJ9mSOs7c/VC2JBJ3YFFNTU3ONn6alHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcZPSMP%2FbtsJ9mSOs7c%2FVC2JBJ3YFFNTU3ONn6alHK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;592&quot; height=&quot;372&quot; data-filename=&quot;스크린샷 2024-10-17 오후 9.07.52.png&quot; data-origin-width=&quot;2102&quot; data-origin-height=&quot;1320&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;카카오 모빌리티를 준비하면서 검색했던 후기들이 많이 도움이 되었기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나도 도움이 됐으면 해서 + 회고를 쓰면서 실수도 돌아볼겸 쓰는 후기..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차코테까지 밖에 못갔지만... 서류합격이 많지 않았던 나에겐 좋은 기회였어서 글로 남겨보고자 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  서류&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서류는 이력서(필수)였고, 포트폴리오는 선택&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 이력서만 간단히 정리해서 pdf로 내고 포트폴리오는 노션 링크로만 첨부했음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는 약 5일만에 나왔고 주변을 보니까 비교적 널널하게 뽑은 편인 것 같다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_스크린샷 2024-10-17 오후 9.13.15.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;910&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clKHDQ/btsKaezZA6i/AMDXG7x4GpkLS6DDXwSyQk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clKHDQ/btsKaezZA6i/AMDXG7x4GpkLS6DDXwSyQk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clKHDQ/btsKaezZA6i/AMDXG7x4GpkLS6DDXwSyQk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclKHDQ%2FbtsKaezZA6i%2FAMDXG7x4GpkLS6DDXwSyQk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;421&quot; height=&quot;261&quot; data-filename=&quot;edited_스크린샷 2024-10-17 오후 9.13.15.png&quot; data-origin-width=&quot;1466&quot; data-origin-height=&quot;910&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt; &lt;b&gt; 1차 코테&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;온라인으로 봤고, 총 3문제였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 알고리즘 2문제와 react 문제가 하나 나왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특이하게 &lt;a href=&quot;https://www.codility.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;코딜리티&lt;/a&gt;라는 사이트를 통해서 시험을 봤는데, 문제가 영어였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;번역을 지원하기는 하는데, 좀 어색한 부분이 있긴했음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캠은 없었고, 검색은 불가능했다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간에 영어 &amp;gt; 한국어 또는 한국어 &amp;gt; 영어로 바꾸면 코드가 아예 없어지는데, 다시 원래 언어로 바꾸면 돌아오긴함..(&lt;i&gt;&lt;s&gt;식겁했다 진짜)&lt;/s&gt;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알고리즘은 체감 난이도가 실버 5, 실버 3? 정도 된 것 같다. 그렇게 어렵진 않았음..!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 리액트 문제는 리액트를 평소에 써봤다면 크게 어렵지는 않았을 것 같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체적으로 무난해서 오히려 올솔이 아니었다면 통과 못했을 것 같은 난이도였음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_스크린샷 2024-11-26 오후 9.40.10.png&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;618&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7AU0a/btsKWPM7Nn9/iTu3wDD8uEs3pg2KS1N9oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7AU0a/btsKWPM7Nn9/iTu3wDD8uEs3pg2KS1N9oK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7AU0a/btsKWPM7Nn9/iTu3wDD8uEs3pg2KS1N9oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7AU0a%2FbtsKWPM7Nn9%2FiTu3wDD8uEs3pg2KS1N9oK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;659&quot; height=&quot;282&quot; data-filename=&quot;edited_스크린샷 2024-11-26 오후 9.40.10.png&quot; data-origin-width=&quot;1444&quot; data-origin-height=&quot;618&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  2차 코테&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차 코테는 특이하게 오프라인으로 봤다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한양대에서 봤고, 인원이 생각보다 그렇게 많지는 않았음... 1차에서 생각보다 많이 거른 것 같았따.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;1400&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c7VFd4/btsKYCFI8bA/P2WssWkm4SvFaVxEwtgA40/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c7VFd4/btsKYCFI8bA/P2WssWkm4SvFaVxEwtgA40/img.png&quot; data-alt=&quot;한양대 수시랑 겹쳐서 음악특기자된 기분~&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c7VFd4/btsKYCFI8bA/P2WssWkm4SvFaVxEwtgA40/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc7VFd4%2FbtsKYCFI8bA%2FP2WssWkm4SvFaVxEwtgA40%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;257&quot; height=&quot;343&quot; data-origin-width=&quot;1050&quot; data-origin-height=&quot;1400&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;한양대 수시랑 겹쳐서 음악특기자된 기분~&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;1050&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Mr6pg/btsKWH9z0ur/qx5hzHVpKP6kShV8htVqkk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Mr6pg/btsKWH9z0ur/qx5hzHVpKP6kShV8htVqkk/img.png&quot; data-alt=&quot;한양대 엄청 예쁘더라&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Mr6pg/btsKWH9z0ur/qx5hzHVpKP6kShV8htVqkk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMr6pg%2FbtsKWH9z0ur%2Fqx5hzHVpKP6kShV8htVqkk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;699&quot; height=&quot;524&quot; data-origin-width=&quot;1400&quot; data-origin-height=&quot;1050&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;한양대 엄청 예쁘더라&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시험은 동일하게 3문제( 2알고리즘, 1리액트)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;솔직히 어려울거 예상하긴했지만...&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;체감 난이도 둘 다 골드3이었는데 사람마다 다를 수도 있을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트는 크게 어렵지는 않았는데... 하다가 문제가 생겼는지 계속 코드가 내 눈에는 보이는데 업로드가 안되는지 괄호가 빠졌다는 에러가 자꾸나서 맨탈이 아웃이었따... 컴포넌트 마지막에 대괄호가 자꾸 날라가는 문제였는데 왜 계속 저장을 해도 그 전 코드로 돌아가는지 이해가 안되서 찾는 것도 한참걸리고... 끝나기 5분전 쯤에 발견해서 문의도 못하고 여튼 여러모로 아쉬웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 사실 그 문제 없었어도 알고리즘 하나를 못 풀어서 크게 아쉽지는 않다..ㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로는 2차 코테까지 밖에 못 갔었지만, 리액트를 이용한 코테는 처음이었어서 좋은 경험이었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복기하면서 리액트 기능들도 좀 더 살펴볼 수 있었고.. 시험보러 다른 학교 가는 경험도 재밌었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음이 있을지는 모르겠지만, 다시 지원하게 된다면 알고리즘은 구현위주로,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트는 좀 더 경험치를 쌓는다면 충분히 면접까진 갈 수 있지 않을까....&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>취준일기</category>
      <category>카카오모빌리티</category>
      <author>Memez</author>
      <guid isPermaLink="true">https://memezz.tistory.com/195</guid>
      <comments>https://memezz.tistory.com/195#entry195comment</comments>
      <pubDate>Tue, 26 Nov 2024 21:51:59 +0900</pubDate>
    </item>
    <item>
      <title>[유데미x스나이퍼팩토리] 프론트엔드 프로젝트 캠프 - 2주차 회고 및 배운 것</title>
      <link>https://memezz.tistory.com/194</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n7jto/btsKL1tpiNg/lgD9WWymMjhwwezNknZFH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n7jto/btsKL1tpiNg/lgD9WWymMjhwwezNknZFH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n7jto/btsKL1tpiNg/lgD9WWymMjhwwezNknZFH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn7jto%2FbtsKL1tpiNg%2FlgD9WWymMjhwwezNknZFH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;335&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &amp;zwj;♀️배운것들&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;i&gt;&lt;u&gt;supabase + Next.js&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;에 대해서 새로 배웠다..!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  Next.js 프로젝트 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, shadcn ui와 함께 Next.js를 시작하기 위해서 &lt;a href=&quot;https://ui.shadcn.com/docs/installation/next&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Shadcn ui의 getting started&lt;/a&gt;를 따라서 프로젝트를 생성해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1732621027898&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npx shadcn@latest init&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-26 오후 8.39.19.png&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/edrDlE/btsKWPl3c5Y/yrhXjCxxG86WNI0RfN1kr1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/edrDlE/btsKWPl3c5Y/yrhXjCxxG86WNI0RfN1kr1/img.png&quot; data-alt=&quot;Next.js + shadcn ui 기반의 프로젝트 만들기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/edrDlE/btsKWPl3c5Y/yrhXjCxxG86WNI0RfN1kr1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FedrDlE%2FbtsKWPl3c5Y%2FyrhXjCxxG86WNI0RfN1kr1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;612&quot; height=&quot;281&quot; data-filename=&quot;스크린샷 2024-11-26 오후 8.39.19.png&quot; data-origin-width=&quot;922&quot; data-origin-height=&quot;424&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Next.js + shadcn ui 기반의 프로젝트 만들기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 실행은 react와 동일하게 해주면된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(npm install해주고, npm run dev로 확인하기)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  supabase 연결&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 &lt;a href=&quot;https://supabase.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;supabase&lt;/a&gt;에서 계정과 프로젝트를 만들어주자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-26 오후 8.50.17.png&quot; data-origin-width=&quot;282&quot; data-origin-height=&quot;232&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9YY2W/btsKYBtfyzv/9U10tDH7onJs3m4YUPris1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9YY2W/btsKYBtfyzv/9U10tDH7onJs3m4YUPris1/img.png&quot; data-alt=&quot;프로젝트 만들기&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9YY2W/btsKYBtfyzv/9U10tDH7onJs3m4YUPris1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9YY2W%2FbtsKYBtfyzv%2F9U10tDH7onJs3m4YUPris1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;200&quot; height=&quot;165&quot; data-filename=&quot;스크린샷 2024-11-26 오후 8.50.17.png&quot; data-origin-width=&quot;282&quot; data-origin-height=&quot;232&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로젝트 만들기&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;next.js에서도 supabase를 사용하기 위해서 설치를 해주자&lt;/p&gt;
&lt;pre id=&quot;code_1732621244783&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install @supabase/supabase-js&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 연결하기 위해서 env를 설정해주자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-26 오후 8.57.58.png&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lYCBE/btsKYBz1WlE/lLNcAkkNtkP8xz7CmOkUqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lYCBE/btsKYBz1WlE/lLNcAkkNtkP8xz7CmOkUqk/img.png&quot; data-alt=&quot;connect를 선택하고,&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lYCBE/btsKYBz1WlE/lLNcAkkNtkP8xz7CmOkUqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlYCBE%2FbtsKYBz1WlE%2FlLNcAkkNtkP8xz7CmOkUqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;551&quot; height=&quot;117&quot; data-filename=&quot;스크린샷 2024-11-26 오후 8.57.58.png&quot; data-origin-width=&quot;838&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;connect를 선택하고,&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-26 오후 8.58.21.png&quot; data-origin-width=&quot;1508&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bH168I/btsKYAVriRy/W1eoVXxE1w3CI4VSMloLM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bH168I/btsKYAVriRy/W1eoVXxE1w3CI4VSMloLM0/img.png&quot; data-alt=&quot;여기 밑에 있는 env파일을 그대로 만들어주면 된당&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bH168I/btsKYAVriRy/W1eoVXxE1w3CI4VSMloLM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbH168I%2FbtsKYAVriRy%2FW1eoVXxE1w3CI4VSMloLM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;693&quot; height=&quot;182&quot; data-filename=&quot;스크린샷 2024-11-26 오후 8.58.21.png&quot; data-origin-width=&quot;1508&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;여기 밑에 있는 env파일을 그대로 만들어주면 된당&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, next.js에 supabase.ts파일을 lib폴더에 생성해주자&lt;/p&gt;
&lt;pre id=&quot;code_1732623147771&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// lib/supabase.ts

import { createClient } from &quot;@supabase/supabase-js&quot;;

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL as string;
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY as string;

export const supabase = createClient(supabaseUrl, supabaseKey);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  supabase 테이블 만들고 api로 통신하기&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;supabase는 정말 쉽게 테이블을 생성할 수 있다..!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;supabase &amp;gt; table editer에서 create table을 하면 간단히 생성할 수 있음&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-26 오후 9.00.17.png&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lIFaq/btsKVIgWDMr/zcNE9DSE86aFlBAPeiCZ6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lIFaq/btsKVIgWDMr/zcNE9DSE86aFlBAPeiCZ6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lIFaq/btsKVIgWDMr/zcNE9DSE86aFlBAPeiCZ6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlIFaq%2FbtsKVIgWDMr%2FzcNE9DSE86aFlBAPeiCZ6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;510&quot; height=&quot;248&quot; data-filename=&quot;스크린샷 2024-11-26 오후 9.00.17.png&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-26 오후 9.00.50.png&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ctCeIS/btsKX5BDKbQ/sCRYSXwHJwKH2z1gow3VqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ctCeIS/btsKX5BDKbQ/sCRYSXwHJwKH2z1gow3VqK/img.png&quot; data-alt=&quot;원하는 column 생성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ctCeIS/btsKX5BDKbQ/sCRYSXwHJwKH2z1gow3VqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FctCeIS%2FbtsKX5BDKbQ%2FsCRYSXwHJwKH2z1gow3VqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;510&quot; height=&quot;217&quot; data-filename=&quot;스크린샷 2024-11-26 오후 9.00.50.png&quot; data-origin-width=&quot;1296&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;원하는 column 생성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블을 만들면 api docs를 통해 어떻게 연결하는지 친절한 설명이 나와있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쭉 내리다 보면 Insert rows가 있는데 이걸로 간단하게 버튼을 누르면 table에 column을 추가하는 걸로 테스트를 해보자&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-26 오후 9.05.22.png&quot; data-origin-width=&quot;1394&quot; data-origin-height=&quot;618&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eptNx0/btsKWKL2IDr/IOeJfydQ39okBtF632Veak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eptNx0/btsKWKL2IDr/IOeJfydQ39okBtF632Veak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eptNx0/btsKWKL2IDr/IOeJfydQ39okBtF632Veak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeptNx0%2FbtsKWKL2IDr%2FIOeJfydQ39okBtF632Veak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;634&quot; height=&quot;281&quot; data-filename=&quot;스크린샷 2024-11-26 오후 9.05.22.png&quot; data-origin-width=&quot;1394&quot; data-origin-height=&quot;618&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 next.js 프로젝트를 생성했을 때의 화면에서 shadcn ui를 이용해서 간단한 버튼을 하나 만들어주자&lt;/p&gt;
&lt;pre id=&quot;code_1732623362781&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npx shadcn@latest add button&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-26 오후 9.16.10.png&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;714&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beZysz/btsKXXKrvoY/KkkC9DmK9BKAM2aiFRcyZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beZysz/btsKXXKrvoY/KkkC9DmK9BKAM2aiFRcyZ0/img.png&quot; data-alt=&quot;이제 이 버튼을 누르면 테이블에 column이 들어오도록 만들어보자&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beZysz/btsKXXKrvoY/KkkC9DmK9BKAM2aiFRcyZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeZysz%2FbtsKXXKrvoY%2FKkkC9DmK9BKAM2aiFRcyZ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;259&quot; height=&quot;220&quot; data-filename=&quot;스크린샷 2024-11-26 오후 9.16.10.png&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;714&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;이제 이 버튼을 누르면 테이블에 column이 들어오도록 만들어보자&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;app/page.tsx에서 button에 onClick으로 위의 예시코드를 그대로 붙여넣어서 테스트를 해보자&lt;/p&gt;
&lt;pre id=&quot;code_1732623505650&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// app/page.tsx

&quot;use client&quot;

import Image from &quot;next/image&quot;;
import { Button } from &quot;@/components/ui/button&quot;;
import { supabase } from &quot;@/lib/supabase&quot;;


export default function Home() {

  const handleTestButton = async () =&amp;gt; {
    const { data, error } = await supabase
    .from('test-table')
    .insert([
      {  },
    ])
    .select()       
  }
  
  ....
  
  &amp;lt;Button onClick={() =&amp;gt; handleTestButton()}&amp;gt;테이블 테스트!&amp;lt;/Button&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 해주고 버튼을 누르면 table에 데이터가 생성되는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-26 오후 9.26.46.png&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ds9MkZ/btsKX34SLxj/dypyj9S3cJBGQ6MmFjQh9K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ds9MkZ/btsKX34SLxj/dypyj9S3cJBGQ6MmFjQh9K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ds9MkZ/btsKX34SLxj/dypyj9S3cJBGQ6MmFjQh9K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fds9MkZ%2FbtsKX34SLxj%2Fdypyj9S3cJBGQ6MmFjQh9K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;271&quot; height=&quot;177&quot; data-filename=&quot;스크린샷 2024-11-26 오후 9.26.46.png&quot; data-origin-width=&quot;428&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; &amp;zwj;♀️ 2주차 회고&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js가 생각보다 리액트와 크게 다르지 않은 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;supabase를 좀 더 기깔나게 활용하는 방법을 3주차에 배우는 중인데,,,, 쉽지 않아서 연습이 많이 필요해보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 2주차 내내 최종면접이랑 겹쳐서 집중도 안되고 바로바로 따라가지도 못했다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 시원하게 떨어졌으니까... 열심히 해봐야지 화이팅&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막 주차인 3주차에는 바로바로 따라가는 것도 그렇고 다시 혼자서 차분히 하는 것도 해봐야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내껄로 만들어야 의미가 있는거니까!!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 후기는 본 후기는 [유데미x스나이퍼팩토리] 프론트엔드 프로젝트 캠프 과정(B-log) 리뷰로 작성 되었습니다.&lt;/p&gt;</description>
      <category>교육/프론트엔드 프로젝트 캠프</category>
      <category>Next.js</category>
      <category>react</category>
      <category>Udemy</category>
      <category>미래내일일경험</category>
      <category>부트캠프</category>
      <category>스나이퍼팩토리</category>
      <category>웅진씽크빅</category>
      <category>유데미</category>
      <category>인사이드아웃</category>
      <category>프로젝트캠프</category>
      <author>Memez</author>
      <guid isPermaLink="true">https://memezz.tistory.com/194</guid>
      <comments>https://memezz.tistory.com/194#entry194comment</comments>
      <pubDate>Tue, 26 Nov 2024 21:31:11 +0900</pubDate>
    </item>
    <item>
      <title>[유데미x스나이퍼팩토리] 프론트엔드 프로젝트 캠프 - 1주차 회고 및 배운 것</title>
      <link>https://memezz.tistory.com/193</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;540&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/n7jto/btsKL1tpiNg/lgD9WWymMjhwwezNknZFH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/n7jto/btsKL1tpiNg/lgD9WWymMjhwwezNknZFH0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/n7jto/btsKL1tpiNg/lgD9WWymMjhwwezNknZFH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fn7jto%2FbtsKL1tpiNg%2FlgD9WWymMjhwwezNknZFH0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;596&quot; height=&quot;335&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;540&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React를 공부하기 위해 혼자 프로젝트를 만들려고 할 때, 백엔드가 필요할 때가 생겨서 Next.js에 관심이 생겼다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 좋은 기회로 Next.js를 배우고, React와 Next.js를 활용해 프로젝트까지 진행하는 프론트엔드 프로젝트 캠프에 참여했다! 벌써 시작한지 일주일이 지났는데, 사실 이번주는 면접 준비 + 면접 때문에 5일 중에 3일밖에 참여하지 못했다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 그 사이에 생각보다 많은 것을 배우고 생각해 볼 수 있었다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; &amp;zwj;♀️배운것들&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;u&gt;&lt;b&gt;src 폴더 구조&lt;/b&gt;&lt;/u&gt;&lt;i&gt;(index를 곁들인..)&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 프로젝트들에서도 협업에서 가장 신경 쓰였던 부분은 폴더 구조였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 배울 때에 따라 자신만의 스타일을 갖고 있다고 생각해서 결국엔 협업과정에서 서로 설득하고 맞춰가야 하는 부분이라고 생각한다. 직전 프로젝트에서는 atomic design을 적용해서 Page, Template, Organism, Molecule, Atom... 등 단위 별로 폴더 구조를 만들었다. 추가적으로 api, hooks, assets 등도 폴더를 따로 만들어서 관리했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이번 실습에서도 비슷한 구조로 만들기는 했지만, 조금 더 폴더 구조를 명확히 해서 재사용성을 높일 수 있었다고 생각한다. 특히, &lt;b&gt;각 폴더마다 index.ts를 둬서 import할 때의 경로를 훨씬 더 보기 편하게 둔 것&lt;/b&gt;이 나중에도 사용할만한 좋은 방법인 것 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1731868864201&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// components/index.ts

/** 공통적으로 사용되는 컴포넌트 */
export { Header } from &quot;./common/header/Header&quot;;

/** HOME 페이지에서 관리하는 컴포넌트 */

export { GetTodayWidget } from &quot;./home/GetTodayWidget&quot;;
export { GetHourlyWidget } from &quot;./home/GetHourlyWidget&quot;;
export { GetKakaoMapWidget } from &quot;./home/GetKakaoMapWidget&quot;;
export { GetTodayHighlightsWidget } from &quot;./home/GetTodayHighlightsWidget&quot;;
export { GetDayItem } from &quot;./home/GetDayItem&quot;;

/** UI 기초 컴포넌트 */
export { Avatar, AvatarImage, AvatarFallback } from &quot;./ui/avatar&quot;;
export { Button, buttonVariants } from &quot;./ui/button&quot;;
export {
  Card,
  CardHeader,
  CardFooter,
  CardTitle,
  CardDescription,
  CardContent,
} from &quot;./ui/card&quot;;
export { Input } from &quot;./ui/input&quot;;
export { Separator } from &quot;./ui/separator&quot;;
export { SearchBar } from &quot;./ui/search-bar&quot;;

export { GetSunriseAndSunset } from &quot;./home/GetSunriseAndSunset&quot;;
export { GetWavesWidget } from &quot;./home/GetWavesWidget&quot;;
export { GetWeekWidget } from &quot;./home/GetWeekWidget&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 식으로 컴포넌트 폴더 안에 index.ts를 만들고 해당 폴더에서 사용되는 모든 함수를 가져와서 export를 해준다.&lt;/p&gt;
&lt;pre id=&quot;code_1731868927797&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 컴포넌트를 사용하고자할 때 경로가 직관적임

import {
  Header,
  GetTodayWidget,
  GetHourlyWidget,
  GetKakaoMapWidget,
  GetTodayHighlightsWidget,
  GetWeekWidget,
} from &quot;@/components&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 해당 컴포넌트를 사용하고자 할 때, import문이 길어지지도 않고 + 경로가 직관적이라 협업에서 더 효과적일 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;u&gt;&lt;b&gt;useState, useMemo, useEffect&lt;/b&gt;&lt;/u&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React를 쓰다 보면 자주 쓰게 되는 3 대장 같은 느낌의 리액트의 훅이다. useMemo 말고 나머지 두 개는 자주 썼는데, 막상 이게 뭔지 설명하라고 하면 하기 힘들었었다. 이번주에 리액트의 기초부터 다시 하면서 왜 쓰는지, 뭔지, 어떻게 쓰는지에 대해서 다시 생각해 볼 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  useState&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;useState는 리액트의 함수형 컴포넌트에서 상태를 관리할 수 있게 해주는 훅이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 클래스 형 컴포넌트에서는 this를 사용했지만, 함수형 컴포넌트에서는 useState를 사용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1731869388701&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const [상태값, 업데이트함수] = useState(초기값)&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;초기값은 컴포넌트가 랜더링 될 때 한 번만 사용됨&lt;/li&gt;
&lt;li&gt;상태값은 변경될 때마다 재랜더링( = 상태값이 변경되면 해당 상태를 사용하는 컴포넌트가 다시 랜더링 됨)&lt;/li&gt;
&lt;li&gt;업데이트 함수는 비동기적임!!!!&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  useMemo&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;useMemo는 리액트에서 성능 최적화를 위해 사용되는 훅으로, 계산 비용이 큰 값을 메모이제이션(캐싱)합니다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1731869589910&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const 메모이제이션된값 = useMemo(() =&amp;gt; 계산할_함수(), [의존성배열]);&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;의존성 배열의 값이 변경될 때만&lt;/b&gt; 계산할 함수가 다시 실행됨&lt;/li&gt;
&lt;li&gt;불필요한 계산을 방지하여 성능 향상&lt;/li&gt;
&lt;li&gt;주로&amp;nbsp;복잡한 계산이나 큰 객체 생성 시 사용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  useEffect&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수형 컴포넌트에서 부수효과를 처리하는 데에 사용되는 리액트의 훅, 컴포넌트가 랜더링 될 때, 상태가 업데이트될 때, 언마운트될 때 등의 시점에서 특정 작업을 수행&lt;/p&gt;
&lt;pre id=&quot;code_1731869818250&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;useEffect(() =&amp;gt; {
	실행할 함수
}, [의존성배열])&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컴포넌트가 랜더링 된 이후에 실행됨&amp;nbsp;&lt;/li&gt;
&lt;li&gt;두번째 인자인 의존성 배열의 값이 바뀌면 실행됨&lt;/li&gt;
&lt;li&gt;의존성 배열이 빈 배열이라면 컴포넌트가 마운트될 때 한 번만 실행됨&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; &amp;zwj;♀️1주차 회고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 react를 또 한다고 했을 때, 이미 프로젝트를 세 번이나 했는데 얻어가는 게 있을까? 라는 생각이 먼저들긴했다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, 막상 강의를 듣는데 useState가 뭐죠? 하면 할 대답이 없다는 걸 깨달았다. 특히 이번주에 면접이 있어서 기술면접을 대비하는데 그런 기초적인 내용과 내 언어로 풀어서 설명하는 방법을 배울 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아쉬운 점은 아무래도 인생 첫 면접에 떨려서 많이 집중을 못했다는 점..... 심지어 이틀이나 수업을 못들었다는 점이 아쉽다. 왜냐면 이틀 빠지고 다음날 수업듣는데 진도가 빨라서 그런가 따라가는 게 좀 힘들었다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2주차에는 react를 조금만 더 이렇게 저렇게 활용하는 방법을 배우고 빠르게 Next.js를 공부해보고 싶다. 그리고, 강의에 최대한 빠르게 잘 따라가는 것이 목표이다... 하다보면 종종 에러가 떠서 진도를 놓칠뻔 했적이 많다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체적으로 알찼다...!!! 첫날 마곡 한 번 가보고 1시간 반을 지하철 출근길에서 낑겨서 가보고 바로 온라인으로 도망갔다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 온라인도 강사님이 잘 챙겨주셔서 좋았다...!!!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본 후기는 본 후기는 [유데미x스나이퍼팩토리] 프론트엔드 프로젝트 캠프 과정(B-log) 리뷰로 작성 되었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;#유데미 #udemy #웅진씽크빅 #스나이퍼팩토리 #인사이드아웃 #미래내일일경험 #프로젝트캠프 #부트캠프 #React #Next.js #프론트엔드개발자양성과정 #개발자교육과정&lt;/p&gt;</description>
      <category>교육/프론트엔드 프로젝트 캠프</category>
      <author>Memez</author>
      <guid isPermaLink="true">https://memezz.tistory.com/193</guid>
      <comments>https://memezz.tistory.com/193#entry193comment</comments>
      <pubDate>Mon, 18 Nov 2024 04:07:10 +0900</pubDate>
    </item>
  </channel>
</rss>