<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>bgh.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Mon, 01 Apr 2024 14:40:23 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>bgh.log</title>
            <url>https://velog.velcdn.com/images/meow_tarae/profile/2bc2d7eb-0287-46f3-99a8-24bc8285e19a/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. bgh.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/meow_tarae" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Import 자동 정렬을 적용해 보셨다면, CSS 속성도 자동 정렬해 보시는 건 어떨까요 ?]]></title>
            <link>https://velog.io/@meow_tarae/Import-%EC%9E%90%EB%8F%99-%EC%A0%95%EB%A0%AC%EC%9D%84-%EC%A0%81%EC%9A%A9%ED%95%B4-%EB%B3%B4%EC%85%A8%EB%8B%A4%EB%A9%B4-CSS-%EC%86%8D%EC%84%B1%EB%8F%84-%EC%9E%90%EB%8F%99-%EC%A0%95%EB%A0%AC%ED%95%B4-%EB%B3%B4%EC%8B%9C%EB%8A%94-%EA%B1%B4-%EC%96%B4%EB%96%A8%EA%B9%8C%EC%9A%94</link>
            <guid>https://velog.io/@meow_tarae/Import-%EC%9E%90%EB%8F%99-%EC%A0%95%EB%A0%AC%EC%9D%84-%EC%A0%81%EC%9A%A9%ED%95%B4-%EB%B3%B4%EC%85%A8%EB%8B%A4%EB%A9%B4-CSS-%EC%86%8D%EC%84%B1%EB%8F%84-%EC%9E%90%EB%8F%99-%EC%A0%95%EB%A0%AC%ED%95%B4-%EB%B3%B4%EC%8B%9C%EB%8A%94-%EA%B1%B4-%EC%96%B4%EB%96%A8%EA%B9%8C%EC%9A%94</guid>
            <pubDate>Mon, 01 Apr 2024 14:40:23 GMT</pubDate>
            <description><![CDATA[<p>(vsc 기준으로 작성된 글입니다) </p>
<p>아무것도 모르던 코린이가 첫 팀 프로젝트에서 import 구문을 
저장 (ctrl + s) 한 번에 촤라락 정렬이 되는 것을 보고 &#39;와 대박!&#39;을 외쳤던 일이 생각나네요 ㅎㅎ</p>
<br>
<hr>

<h2 id="적용하게-된-계기">적용하게 된 계기</h2>
<p>데브코스에서 첫 팀 프로젝트를 경험했을 때였습니다.</p>
<p>저희는 공통 컴포넌트 제작 후 Page UI를 개발하였습니다.</p>
<p>아직 로직을 구현하지 않았기에, 중점적으로 코드 리뷰 할 사항들은 CSS 적인 부분들이었습니다.</p>
<p>이때, 아래 사진과 같이 import 구문을 정렬한 것 처럼, 
<strong>CSS 속성들도 특정 순서들로 정렬하여 작성하였다면, CSS 내용을 조금 더 빨리 이해할 수 있을 것 같았습니다.</strong></p>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/b6fcd336-efa1-415f-b866-d20166cd076a/image.png" alt="예시"></p>
<p>이는 곧 팀원들의 리뷰 속도 향상에 도움이 될 것 같다는 생각이었습니다.</p>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/b7a1ef42-ed17-4d8c-bdc5-f681ef87f442/image.png" alt=""></p>
<p>... </p>
<p>하지만 
<code>음.. 팀 컨벤션에 따라.. display:flex는 맨 위에 오게끔, 바로 아래에는 justify-content 속성이 와야 하고..</code> 처럼, 정렬 순서를 하나하나 생각하며 코드를 작성하기에는 많이 번거로울 것 같았습니다.</p>
<br>



<p>저는 위 사진처럼, 저장 한 번으로 CSS도 자동으로 정렬해 주는 기능이 있으면 좋겠다고 생각했습니다.</p>
<p>또한 데브코스 팀원분들 외에도, 많은 사람들이 이를 쉽게 사용해보실 수 있게끔 설정법을 공유해보고자 합니다.</p>
<p>(참고로, 이 글은 styled-components와 emotion같은 css-in-js를 기준으로 작성하였습니다.)</p>
<h3 id="그런데-어떻게-이런-css-정렬이-가능한-것일까">그런데, 어떻게 이런 css 정렬이 가능한 것일까?</h3>
<p>StyleLint 덕분이었습니다 (+ PostCSS)
ESLint가 JS 관련 처리를 담당해 준다면, StyleLint가 CSS 관련 처리를 담당해 주어요.</p>
<ul>
<li>ESLint : ECMASCRIPT Linter의 줄임말, 린팅 역할과 포매터 역할을 한다.
주로 JS 기반 파일에 사용됨.</li>
<li>Stylelint : ESLint와 마찬가지로 코드 스타일과 오류를 검사하며, 주로 CSS, SCSS, Less, 그리고 CSS-in-JS 기반 파일에 사용됨.</li>
</ul>
<br>

<p>PostCSS는 역할이 무엇인가요 ?
이따 말씀드릴건데, <code>.eslintrc</code> 파일에 코드 넣어서 설정하는 것 처럼 우리는 <code>.stylelintrc</code> 파일을 하나 만들거고, 거기다가 코드를 넣어줘야 해요.
이때 <code>&quot;customSyntax&quot;: &quot;postcss-styled-syntax&quot;</code> 라는 속성을 추가하는데, 여기서 PostCSS가 사용됩니다.</p>
<blockquote>
<p>PostCSS syntax for template literals CSS-in-JS.
It was built to be used as <strong><a href="https://stylelint.io/">Stylelint</a></strong> custom syntax or with <strong><a href="https://postcss.org/">PostCSS</a></strong> plugins.</p>
</blockquote>
<p>라고 하네요.</p>
<p>styled-components와 같은 <code>CSS-in-JS</code> 라이브러리를 사용할 때, 일반 CSS 파일과 다른 특별한 구문 분석이 필요합니다. 
때문에 <code>&quot;customSyntax&quot;: &quot;postcss-styled-syntax&quot;</code>를 사용합니다.</p>
<p>(아래 사진은 postcss-styled-syntax 미사용 시)
<img src="https://velog.velcdn.com/images/meow_tarae/post/efe3b23f-21c3-46a6-b9b1-bd673abea2e7/image.png" alt=""></p>
<p>(그리고 아래 사진은 postcss-styled-syntax 사용 시)
<img src="https://velog.velcdn.com/images/meow_tarae/post/e134f2d4-9f27-4a81-8bb6-137aff4a23c5/image.png" alt=""></p>
<br>
<hr>

<h2 id="적용-방법">적용 방법</h2>
<p>서론이 길었네요. 
이제 정렬 방법에 대해 말씀드려 보겠습니다.</p>
<h3 id="1-npm에서-설치할-패키지들">1. npm에서 설치할 패키지들</h3>
<pre><code class="language-js">npm i styled-components
npm i -D @types/styled-components
npm i -D stylelint
npm i -D postcss postcss-styled-syntax 

// 아래는 선택지 입니다.
// 둘 중 본인이 원하는 것을 선택하시면 됩니다.

// 많은 정렬 패키지들 방식 중 하나를 사용하는 방식 입니다.
// 4-1. 라이브러리 적용 방법에서 이어집니다.
npm i -D stylelint-config-recess-order

// css 정렬을 커스텀으로 한땀한땀 작성하기 위해 사용했던 방식입니다.
// 4-2. Custom order 적용 방법에서 이어집니다.
npm i -D stylelint-config-standard stylelint-order </code></pre>
<br>

<h3 id="2-settingjson-사용자-설정-열기">2. Setting.json (사용자 설정 열기)</h3>
<p>( vsc에서 <code>ctrl(cmd) + shift + p</code> 누르시구 setting.json 입력하시면 나오는 네모 클릭하심 됩니다. 
아래 코드를 추가해 주세요. )</p>
<pre><code class="language-js">/* 
    본인 기준 없어도 작동은 되던 애들.
    근데 작동이 잘 안되시면 추가해 보셔요.
*/
&quot;editor.formatOnSave&quot;: true,  // 코드 저장 시 설정된 포매터가 작동되게끔
&quot;stylelint.enable&quot;: true,

/* 
    반드시 있어야 작동되는 애들.
    아래 설정에 의해, editor.formatOnSave 규칙에 따라
    코드를 저장할 경우 옵션들이 자동으로 수정할 수 있습니다.    
*/
&quot;editor.codeActionsOnSave&quot;: {  
    &quot;source.fixAll.eslint&quot;: &quot;explicit&quot;,  // eslint와 stlyelint 둘 다 실행되게끔
  &quot;source.fixAll.stylelint&quot;: &quot;explicit&quot;
},

// 적용시킬 확장자 파일들을 의미합니다.
&quot;stylelint.validate&quot;: [
  &quot;css&quot;,
  &quot;scss&quot;,
  &quot;postcss&quot;,
  &quot;typescript&quot;,
  &quot;typescriptreact&quot;,    // tsx
  &quot;javascript&quot;,
  &quot;javascriptreact&quot;      // jsx
],</code></pre>
<br>

<h3 id="3-vsc-stylelint-extension">3. vsc stylelint extension</h3>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/0b9a3340-7ac8-4f76-b1b3-b908f33e29ad/image.png" alt="">
저는 요거 설치해서 사용합니다.
(다른건 사용 안해봐서 모르겠는데, 암튼 이런거 설치를 하셔야 자동 저장 기능이 작동합니다.)</p>
<br>

<h3 id="4-stylelintrc">4. .stylelintrc</h3>
<p>( 저희는 .esintrc 파일과 같은 경로 위치에, 즉 최상단에 <code>.stylelintrc</code> 라는 이름의 파일을 만들어 두었습니다. )
( 파일명 맨 앞에 &#39; . &#39; 붙이셔야 합니다~)<img src="https://velog.velcdn.com/images/meow_tarae/post/c133ca02-33f2-4908-8c7e-1ef8107194bd/image.png" alt=""></p>
<br>

<h4 id="4-1-라이브러리-적용-방법">4-1. 라이브러리 적용 방법</h4>
<pre><code class="language-js">// .stylelintrc
{
  &quot;extends&quot;: [&quot;stylelint-config-recess-order&quot;],  // 정렬에 사용될, 설치한 라이브러리
  &quot;customSyntax&quot;: &quot;postcss-styled-syntax&quot;
}</code></pre>
<p>.stylelintrc 파일에 위 코드 입력 후 저장하시면, 이제 여러분들도 css 자동 정렬이 가능 하실거에요.
( 잘 안되시면 댓글 남겨주세요! 열심히 도와드리겠습니당 )</p>
<h4 id="왜-이런-코드를-집어넣는-건가요">왜 이런 코드를 집어넣는 건가요?</h4>
<p>.stylelintrc 파일에서는 자동으로 정렬할 &#39;순서&#39;를 정해야 합니다.
예를 들어 
<code>display 속성이 맨 위에 오게끔,</code> 
<code>그 다음에는 align-items 속성이 와야하고...</code> 
<code>바로 밑에는 justify-content 속성, 다음은..</code>
등등.</p>
<p>그런데 css에는 정말 많은 속성들이 있잖아요? 그걸 일일이 한땀한땀 타이핑해서 순서를 지정하기에는... 
조금 번거로울 것 같아요.
ex ) <a href="https://velog.io/@meow_tarae/CSS-%EC%86%8D%EC%84%B1-%EC%A0%95%EB%A0%AC-%EC%88%9C%EC%84%9C%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%84%EB%9D%BC%EB%B3%B4%EC%9E%90#ordering-rules">이 링크를 확인해보시면 굉장히 많은 css 속성들을 보실 수 있어요.</a> </p>
<p>... 정렬 기능 실험을 위해서 css 속성들을 조금 모아봤었는데, 정말 많더라구요 ㅎㅎ</p>
<br>

<p>아무튼, 이런 수고로움을 조금 덜어줄 수 있는 방법이 있습니다.
npm에는 본인들의 입맛에 맞게끔 css 속성들 순서를 정렬해놓은 패키지가 있어요.
아까 저희가 npm i 커맨드로 설치한 <code>stylelint-config-recess-order</code> 이 친구도 그 중 하나죠.</p>
<br>

<p>음... 전 이 패키지 정렬 순서가 별로인데, 혹시 이거 말고 다른건 없나요?
네, 여러가지 많은데 고것도 <a href="https://velog.io/@meow_tarae/CSS-%EC%86%8D%EC%84%B1-%EC%A0%95%EB%A0%AC-%EC%88%9C%EC%84%9C%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%84%EB%9D%BC%EB%B3%B4%EC%9E%90#%EC%97%AC%EB%9F%AC-%ED%8C%A8%ED%82%A4%EC%A7%80%EB%93%A4">이 링크</a> 에서 확인해보실 수 있습니다.</p>
<br>

<h4 id="4-2-custom-order-적용-방법">4-2. Custom order 적용 방법</h4>
<p>말 그대로 정렬하고자 하는, 정말 필요한 속성들만 골라서 해당 속성들의 순서를 지정할 수 있는 방법입니다.</p>
<p>해당 내용은 아래 링크의 블로그에서 더 자세히 확인하실 수 있습니다.</p>
<p><a href="https://velog.io/@s_sangs/CSS-in-JS-Stylelint-feat.-emotion-styled-components">블로그 링크</a></p>
<p>사실 import 자동 정렬 관련 글은 정말 많은데, css 자동 정렬 글은 굉장히 적더라구요...
위 블로그 글 보면서 많이 배울 수 있었습니다. 
감사합니다 (__)</p>
<p>아아 참 그리고, 이 <a href="https://medium.com/@dlxotjde_87064/stylelint-styled-components-order-%EA%B0%9C%EB%B0%9C%EA%B8%B0-styled-components-stylelint-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0-acd0c741e58a">블로그1</a>, <a href="https://velog.io/@hajae305/stylelint%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%B4%EC%84%9C-CSS%EC%BD%94%EB%93%9C%EB%A5%BC-%ED%9A%A8%EC%9C%A8%EC%A0%81%EC%9C%BC%EB%A1%9C-%EA%B4%80%EB%A6%AC%ED%95%B4%EB%B3%B4%EC%9E%90">블로그2</a> 글도 도움이 많이 되었습니다. 감사합니다!</p>
<br>
<hr>

<h2 id="적용-시-변화">적용 시 변화</h2>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/fba6659c-047f-48b2-89d8-e117c5f67471/image.png" alt=""></p>
<p>위 사진처럼, 기존의 작성했던 css 코드에 붉은 줄이 생기는 것을 볼 수 있습니다!</p>
<p>여기서 저장을 하면</p>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/5cb36e77-d6e3-4b41-8137-d75592fedd3d/image.png" alt=""></p>
<p>위와 같이 붉은 줄은 사라지고, 설정했던 규칙에 맞게끔 css 속성들이 정렬되는 것을 볼 수 있습니다.</p>
<br>
<hr>

<h2 id="간단한-트러블-슈팅">간단한 트러블 슈팅</h2>
<p>음.. 가장 크게 어려웠던 점은, 자료가 많이 부족해서 하나하나 찾아봐야 했다는 것?</p>
<p>그리고 vsc 설정이 어디에선가 충돌이 나서? 적용이 안되었던 부분도 한 몫 했던 것 같습니다.
실제로 3차 팀과의 프로젝트에서 vsc가 고장나서 타입스크립트가 전혀 작동을 하지 않던... 문제가 있었습니다.
(TS 문제도 vsc를 싹 다 밀고 다시 설치하니까 되더라구요.. 이것도 참, 별 짓을 다해봤었는데)</p>
<p>마지막으로</p>
<pre><code class="language-js">&quot;stylelint.validate&quot;: [
    &quot;postcss&quot;,
    &quot;typescript&quot;,
    &quot;typescriptreact&quot;,
    &quot;js&quot;,
    &quot;jsx&quot;,
    &quot;tsx&quot;
],</code></pre>
<p>위와 같이 react를 사용하는 환경이라면 jsx 파일을(혹은 tsx) 만들어 사용하실텐데, 이걸 어떻게 선언해야하는지 모르겠더라구요.</p>
<br>

<pre><code class="language-js">&quot;stylelint.validate&quot;: [
  &quot;css&quot;,
  &quot;scss&quot;,
  &quot;postcss&quot;,
  &quot;typescript&quot;,
  &quot;typescriptreact&quot;,
  &quot;javascript&quot;,
  &quot;javascriptreact&quot;
]</code></pre>
<p>처럼 &quot;typescriptreact&quot;, &quot;javascriptreact&quot; 로 수정해주니 해결되었습니다.</p>
<br>
<hr>

<h2 id="마치며">마치며</h2>
<p>요기까지 간?단하게 css 자동 정렬 기능을 적용시키는 법을 적어보았습니다.</p>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/36bbb04f-1602-4688-8782-1e5a266556ba/image.png" alt="간?단">
(간?단)</p>
<p>사실 CSS 그거 뭐 정렬 좀 한다고 얼마나 도움 되겠냐, 그 시간에 로직이나 한 줄 더 수정해라...라고 하실 수 있어요.
맞는 말씀입니다. 사실 크게 중요한 부분은 아니지요.</p>
<p>하지만 이런 사소한 부분도 있으면 좋겠다고 말씀 주신 팀원분이 계셨으며, 이를 챙김으로써 팀원들의 더 나은 PR 이해, 나아가 프로젝트 진행 속도에 조금이나마 도움이 된다면 저는 몹시 기쁠 것 같아요 ㅎㅎ</p>
<p>아직 많이 부족한 제가 팀원들에게 작게나마 도움이 된 것 같아서요.
뛰어난 팀원들 속에서 제가 뭘 해서 도움이 될 수 있을까를 계속 고민했고, 모두가 잘 모르던 부분을 메꿔주었기 때문입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS 속성 정렬 순서에 대해 아라보자.]]></title>
            <link>https://velog.io/@meow_tarae/CSS-%EC%86%8D%EC%84%B1-%EC%A0%95%EB%A0%AC-%EC%88%9C%EC%84%9C%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%84%EB%9D%BC%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@meow_tarae/CSS-%EC%86%8D%EC%84%B1-%EC%A0%95%EB%A0%AC-%EC%88%9C%EC%84%9C%EC%97%90-%EB%8C%80%ED%95%B4-%EC%95%84%EB%9D%BC%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Mon, 01 Apr 2024 14:17:07 GMT</pubDate>
            <description><![CDATA[<p>데브코스에서 1, 2차 팀 프로젝트에서 styled-components, emotion 같은 css-in-js 라이브러리를 사용하여 css 코드를 작성하였습니다.</p>
<p>이 라이브러리 기준으로 css 자동 정렬 기능을 적용시켜보게 되었고, 이때 어떻게 css 정렬을 하는게 좋을까 하는 고민을 하게 되었습니다.</p>
<p>해서 다른 사람들, 회사들은 어떻게 css 속성들을 정렬하는지 조금 찾아보았습니다.</p>
<br>
<hr>

<h2 id="정렬-순서에-대하여-아라보자">정렬 순서에 대하여 아라보자</h2>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/de605ab7-15e6-4e25-8a1f-168ace624c16/image.png" alt=""></p>
<p>출처: <a href="https://css-tricks.com/poll-results-how-do-you-order-your-css-properties/">https://css-tricks.com/poll-results-how-do-you-order-your-css-properties/</a></p>
<p>그래프에서 알 수 있듯, 절반 가까운 사람들이 <code>Grouped by type</code> 방식으로 css 속성들을 정렬하는 것을 선호함을 알 수 있습니다.</p>
<p>작은 팀일수록 관련 집합끼리(e.g. Position, Color) 묶는 것을 원할 수 있습니다.</p>
<p>또한 큰 팀일수록 알파벳 순서대로 css 정렬을 원할 수 있습니다.</p>
<p>출처: <a href="https://github.com/necolas/idiomatic-css">https://github.com/necolas/idiomatic-css</a></p>
<p>( 저희 팀은 프론트 4인의 소수 팀이기도 하고, 각 속성별로 묶여있기를 원하기에 Grouped by type 방식을 선택했습니다. )</p>
<p>그래서 css에서 어떤 type들을 Group화 했을까요?</p>
<p>각 그룹들은 크게 다음과 같은 속성들을 포함하고 있습니다. 
(이는 예시이며 모든 그룹이 다음과 같지는 않을 수 있습니다.)</p>
<h2 id="ordering-rules">Ordering rules</h2>
<table>
<thead>
<tr>
<th align="center">Category</th>
<th align="center">Properties</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Position</td>
<td align="center">position, z-index, top, bottom, left, right, trasnform</td>
</tr>
<tr>
<td align="center">Layout</td>
<td align="center">float, clear</td>
</tr>
<tr>
<td align="center">Display</td>
<td align="center">display, flex-direction, flex-wrap, justify-content, align-content, align-items, order, flex-grow, flex-shrink, flex-basis, align-self</td>
</tr>
<tr>
<td align="center">Visibility</td>
<td align="center">visibility, overflow, clip</td>
</tr>
<tr>
<td align="center">Box model</td>
<td align="center">box-sizing, width, min-width, max-width, height, min-height, max-height, margin, padding</td>
</tr>
<tr>
<td align="center">Color</td>
<td align="center">color, border, border-radius, background, box-shadow, opacity</td>
</tr>
<tr>
<td align="center">Text</td>
<td align="center">font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, font-effect, font-emphasize, font-emphasize-position, font-emphasize-style, font-smooth, line-height, letter-spacing, white-space, word-break, text-overflow</td>
</tr>
<tr>
<td align="center">Animation</td>
<td align="center">transition, animation</td>
</tr>
<tr>
<td align="center">Others</td>
<td align="center">cursor, outline, outline-width, outline-style, outline-color, outline-offset</td>
</tr>
<tr>
<td align="center">Pseudo elements</td>
<td align="center">:hover, :focus, :active, :first-child, :last-child, ::before, ::after</td>
</tr>
</tbody></table>
<p>참고) 
Box model 속성들은 밖에서 안으로 향하는 순서(From outside in)로 나열합니다. 
원래대로라면 border 속성도 Box model 범주에 포함시켜야하겠지만, <strong>border 영역은 두께만 단독으로 선언하지 않고 색상(Color)을 함께 선언하는 경우가 대부분이므로 Color 범주로 포함</strong>시킵니다.</p>
<p>출처: <a href="https://shylog.com/how-do-you-order-your-CSS-properties/">https://shylog.com/how-do-you-order-your-CSS-properties/</a></p>
<br>

<p>사실, 여기서 조금 고민에 빠졌습니다.
위에 작성한 css 외에도, css 에는 수많은 속성들이 있더라구요.
<img src="https://velog.velcdn.com/images/meow_tarae/post/4d214744-61a6-4d7a-abc3-92eabe22c362/image.png" alt=""></p>
<p>( 정렬 실험을 위해 모아본 css 속성들 입니다. 되게 많네요 ㅎ )</p>
<p>이에, 이 모든 css들의 속성 순서를 커스텀하는 것 보다는, <code>이미 정렬된 패키지에 추가적으로 원하는 순서를 override 해서 사용하는 것</code>이 조금 더 시간을 아낄 수 있을 것 같았습니다.</p>
<p>찾아본 결과 <code>stylelint docs</code>에 awesome 하다는 여러 패키지들도 있고, 개인이 만든 패키지들도 많이 있었습니다.</p>
<br>

<h3 id="여러-패키지들">여러 패키지들</h3>
<table>
<thead>
<tr>
<th align="center">이름 및 링크</th>
</tr>
</thead>
<tbody><tr>
<td align="center"><a href="https://www.npmjs.com/package/stylelint-config-hudochenkov">stylelint-config-hudochenkov</a></td>
</tr>
<tr>
<td align="center"><a href="https://www.npmjs.com/package/stylelint-config-idiomatic-order">stylelint-config-idiomatic-order</a></td>
</tr>
<tr>
<td align="center"><a href="https://www.npmjs.com/package/stylelint-config-property-sort-order-smacss">stylelint-config-property-sort-order-smacss</a></td>
</tr>
<tr>
<td align="center"><a href="https://www.npmjs.com/package/stylelint-config-rational-order">stylelint-config-rational-order</a></td>
</tr>
<tr>
<td align="center"><a href="https://www.npmjs.com/package/stylelint-config-recess-order">stylelint-config-recess-order</a></td>
</tr>
<tr>
<td align="center"><a href="https://www.npmjs.com/package/stylelint-styled-components-order">stylelint-styled-components-order</a></td>
</tr>
</tbody></table>
<p>개인적으로 저는 위에 나열된 여러 패키지들 중 비교적 최신 업데이트 되었으며, 버전 수와 다운로드 수도 제일 높은 <code>stylelint-config-recess-order</code> 를 선택하게 되었습니다.</p>
<p>(무게는 16.2kb로 위 패키지들 중에서는 중간정도의 등수 인데, 대게 1<del>20kb다가 갑자기 몇몇 패키지들은 2</del>300kb까지 뛰는 것들도 있더군요.)</p>
<br>

<h3 id="각-회사별-정렬-순서들">각 회사별 정렬 순서들</h3>
<p>위 패키지 등의 기본 css 정렬 규칙에 추가로 덧붙이기에 참고해 보면 좋을 회사들만의 css 컨벤션들도 찾아보았습니다.</p>
<table>
<thead>
<tr>
<th align="center">회사명</th>
<th align="center">사진</th>
<th align="center">출처</th>
</tr>
</thead>
<tbody><tr>
<td align="center">NHN</td>
<td align="center"><img src="https://velog.velcdn.com/images/meow_tarae/post/6e27a340-2be0-467f-ba3d-b4e4473ebb4a/image.png" alt=""></td>
<td align="center"><a href="https://nuli.navercorp.com/data/convention/NHN_Coding_Conventions_for_Markup_Languages.pdf">https://nuli.navercorp.com/data/convention/NHN_Coding_Conventions_for_Markup_Languages.pdf</a></td>
</tr>
<tr>
<td align="center">Naver</td>
<td align="center"><img src="https://velog.velcdn.com/images/meow_tarae/post/ed4fc2dc-96a6-4603-a1b7-6830c97ab594/image.png" alt=""></td>
<td align="center"><a href="https://uxkm.io/publishing/css/03-cssMiddleclass/10-css_attr_rule#gsc.tab=0">https://uxkm.io/publishing/css/03-cssMiddleclass/10-css_attr_rule#gsc.tab=0</a></td>
</tr>
<tr>
<td align="center">Daum</td>
<td align="center"><img src="https://velog.velcdn.com/images/meow_tarae/post/95ddbcdd-3830-4080-9d8d-c14d895a4dcf/image.png" alt=""></td>
<td align="center"><a href="https://uxkm.io/publishing/css/03-cssMiddleclass/10-css_attr_rule#gsc.tab=0">https://uxkm.io/publishing/css/03-cssMiddleclass/10-css_attr_rule#gsc.tab=0</a></td>
</tr>
<tr>
<td align="center">Mozila Firefox</td>
<td align="center"><img src="https://velog.velcdn.com/images/meow_tarae/post/627b0988-3d36-4160-a00d-a4a3fa3ae636/image.png" alt=""></td>
<td align="center"><a href="https://milooy.github.io/TIL/CSS/css-property-order.html">https://milooy.github.io/TIL/CSS/css-property-order.html</a></td>
</tr>
<tr>
<td align="center">CSS Declaration order</td>
<td align="center"><img src="https://velog.velcdn.com/images/meow_tarae/post/e753eec4-a902-4a8f-b008-fc319b73c107/image.png" alt=""></td>
<td align="center"><a href="https://archuive.tistory.com/72">https://archuive.tistory.com/72</a></td>
</tr>
<tr>
<td align="center">GitHub</td>
<td align="center">.</td>
<td align="center"><a href="https://gist.github.com/awkale/ad46e2ade70e833fa178#file-css-order-md">https://gist.github.com/awkale/ad46e2ade70e833fa178#file-css-order-md</a></td>
</tr>
</tbody></table>
<br>

<p>보통 밖에서부터 안쪽의 순서로 선언하는 것을 알 수 있습니다.</p>
<p>이는 화면에 보일것이냐 보이지 않을것이냐가 더욱 중요한 사항이기 때문이라고 생각합니다.</p>
<br>
<hr>

<h2 id="마치며">마치며</h2>
<p>뭔가 이것저것 찾아보았는데요, 개인적인 생각으로 개인 프로젝트나 소규모 프로젝트에서의 css 속성들 정렬 방식은 
<strong>담당자 한 명을 정하고, 해당 담당자 기준으로 작성된 css 정렬 순서에서 조금 수정한 것</strong>을 사용하면 좋을 것 같아요.</p>
<p>담당자가 많이 사용하는 css 속성들을 ordering rules의 category에 맞게 쭉 나열하고, 
그것을 팀원들과의 입맛에 맞춰 조금씩 조금씩 수정하는거죠.</p>
<p>저 많은 css 속성들을 하나하나 정렬하는 것도 좀 그렇고, 각 회사마다 적용하는 방식도 전부 다 다르니... 
이거에 시간을 너무 많이 할애하면, 배보다 배꼽이 더 큰것 같아요 ㅎ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 FE 데브코스 5기 12월~1월 MIL 회고]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-FE-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-12%EC%9B%941%EC%9B%94-MIL-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-FE-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-12%EC%9B%941%EC%9B%94-MIL-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Wed, 24 Jan 2024 02:13:07 GMT</pubDate>
            <description><![CDATA[<p>이번 회고 글까지 총 4번의 MIL을 작성했지만, 기존 팀원들과 헤어지고 작성하는 MIL은 뭔가 더 무거운 느낌이 드는 것 같다.
1차팀때도 그랬지만 많이 부족한 본인을 함께 앞으로 나아갈 수 있게 도와준 팀원분들께 항상 감사한 마음을 가지고 있고, 더군다나 이번 팀 프로젝트 기간동안은 정말 정신이 하나도 없었기에 시간이 너무 빠르게 지나간 것 같다.
그래서 더욱 무거운 느낌이 드는 것 아닐까..</p>
<p>아무튼, 데브코스 2차 소인성팀과 함께한 난생 첫 팀 프로젝트 활동을 회고하고자 한다.</p>
<h2 id="팀-프로젝트-모모">팀 프로젝트 &#39;모모&#39;</h2>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/b7ffbffd-1df2-476b-93d5-ab229d872b2a/image.png" alt=""></p>
<p>&#39; 모모 &#39;란?</p>
<blockquote>
<p>모두의 모임을 위한 <code>모모</code>는, 누구나 모임을 만들고 또 참여할 수 있도록 도와주는 <strong>모임 일정 관리 앱</strong>입니다.
취미, 학습, 네트워킹 등을 함께 하기 위해 쉽고 빠르게 모일 수 있는 플랫폼을 제공합니다.</p>
</blockquote>
<p><a href="https://momo8.vercel.app/">(모모 배포 링크)</a></p>
<br>

<h2 id="진행-흐름">진행 흐름</h2>
<h3 id="주제-선정">주제 선정</h3>
<p><em>&#39;오픈 API를 활용한 검색 웹 사이트 제작 프로젝트&#39;</em> 라는 정해진 틀 안에서 아이디어를 구상하게 되었다.
제한된 범위 내에서도 팀원들과 함께 10여가지의 다양한 아이디어를 떠올렸고, 이 좋은 아이디어들 중에서도 지난번에 유용하게 활용했던 &#39;타임테이블&#39; 기능을 유저들이 조금 더 편리하게, 다양한 기능을 접할 수 있게 만들어보게 되었다.</p>
<h3 id="그라운드-룰-셋팅">그라운드 룰 셋팅</h3>
<p>팀 프로젝트를 진행하며 전반적으로 모두가 지켜야 할 규칙을 정한 부분이다.
이때 가장 좋았던 부분은 팀 회고에서도 모두 동의했던 <strong>야간 등대</strong>이다.
<img src="https://velog.velcdn.com/images/meow_tarae/post/f1136e8d-b986-45e2-852b-6a4b1f31dbd4/image.png" alt=""></p>
<p>야간등대란 9시<del>14시의 코어타임 이후에도, 팀원들 모두 자발적으로 20시</del>24시까지 디스코드에 참여하는 제 2의 코어타임이다.</p>
<p>야간등대 덕분에 프로젝트에 대한 질문 사항, 추가 요청 사항 등을 신속하게 처리할 수 있었고 진행 속도를 더욱 증진시킬 수 있었다.</p>
<p>팀원 개개인의 일정으로 매일 참여하기 힘들었을 것임에도 불구하고, 다들 참여해 주셔서 너무 감사했다.
또한 팀으로써 더욱 더 함께하고 있다는 생각이 들었던 야간등대이기에, 다음 팀에서도 적용되었으면 하는 생각이 들었다.</p>
<h3 id="sprint">sprint</h3>
<p>스프린트를 0~5 단계로 나누고, 각 단계마다 목표를 설정하고 달려나갔다.</p>
<ul>
<li>sprint 0 : 베이스 셋팅<ul>
<li>노션, 기술 스택 선정, 피그마 (와이어프레임 및 ui), draw.io (유저 스토리), 깃허브 및 코딩 컨벤션 설정, 포스트맨 (api 설정)</li>
</ul>
</li>
<li>sprint 1 : 공통 컴포넌트 제작</li>
<li>sprint 2 : 개인별 맡은 Page UI 제작</li>
<li>sprint 3 : 제작된 Page에 API 연동</li>
<li>sprint 4 : 페이지별 기능 고도화</li>
<li>sprint 5 : 마무리 및 최종 제출</li>
</ul>
<p>스프린트 목표는 크게 위와 같았다.</p>
<p>각 단계별로 task를 나누어, 함께 맡은 과제를 처리해나가는 과정 자체는 굉장히 즐거웠다.
책임감을 가져야하는 부분이기에 어깨가 가볍진 않았지만, 모두가 으쌰으쌰해서 무언가를 만들어가는 과정이 너무 행복했던 것 같다.</p>
<br>

<h2 id="회고">회고</h2>
<h3 id="팀에-별-도움이-되지-못했던-것-같다는-생각">팀에 별 도움이 되지 못했던 것 같다는 생각.</h3>
<p>사실, 크게 티는 내지 않았지만(아닌가?) sprint 0의 셋팅들때부터 심적으로 많이 힘들었던 것 같다.</p>
<p>팀 프로젝트 경험이 전무하다보니 위 셋팅들에 대한 지식도 없었다.
그러다보니 팀원들의 셋팅에 무언가 도움을 드리고 싶어도 아무것도 할 수 없는 자신이 너무 무력했다.</p>
<p>조금이나마 도움이 돼보고자 밤새 부족한 부분 찾아보고 연습하였지만, 팀원과의 간극이 그리쉽게 좁혀지진 않았다.</p>
<p>시간 적 여유가 있다면 좋았겠지만, 팀 프로젝트는 약 1달이라는 짧은 시간만이 주어졌기 때문이다.
당시에 나는 <code>아무것도, 혹은 별 도움이 되지 못했다.</code>라는 결과만을 보며 많이 힘들어했던 것 같다.</p>
<p>++ 23일 화 시니어 프론트 개발자 테오께서 데브코스에 특강을 오셨다.
내용은 피그잼의 &#39;테오의 스프린트&#39; 템플릿을 토대로 팀 프로젝트를 조금 더 좋은 방향으로 진행할 수 있게 도와주는 것이었다.</p>
<p>이때, 테오가 말씀주셨던 말이 기억에 남는다.</p>
<blockquote>
<p>팀에서 실력 편차가 있을 수 밖에 없다.
그럴  때는 잘하는 사람이 더 잘할 수 있도록 도와줄 수 있게끔,
모르는 것은 부끄러워하지 말고 계속 물어봐서 그들이 더 잘 도울 수 있게 해라.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/0e6f0137-e9c2-4443-b57e-535a9a0de615/image.png" alt="참고자료"></p>
<p>(테오 강의내용 중)</p>
<br>

<p>생각해보면 내가 100% 모르지도, 팀원이 100% 아는것도 아니었던 것 같다.
내가 모르는 부분은 당연히 있을거고, 이때 내가 어떻게 행동해야할지를 잘 몰랐던 것 같다.
(물론 대부분을 모르긴 했다..)
그럴때 나는 팀에서 해당 내용을 잘 수행할 수 있는 사람이, 그것을 잘 수행할 수 있도록 윤활제같은 역할을 했다면 어땠을까? 하는 생각이 든다.</p>
<p>예를 들어, 우리 팀은 부모 컴포넌트로부터 받아오는 인자의 개수에 따라 interface를 사용할 것인지, type 별칭을 사용할 것인지를 분리했다.
또한 코딩 컨벤션에 interface를 사용할 경우 네이밍 앞에 I를, type의 경우 맨 뒤에 Type을 붙이는 것으로 정했다.</p>
<p>하나 문제가 있었는데, 내가 Icon 공통 컴포넌트를 만들 때였다.
만약 컴포넌트 명이 Button이고, 부모로부터 여러개의 props를 받는다면</p>
<pre><code class="language-ts">interface ButtonProps {
    ~
}

interface IStWrapper {
    ~
}</code></pre>
<p>interface 네이밍은 앞에 I를 붙이기로 정했다.
다만, 컴포넌트에 대한 타입을 지정할 땐 interface임에도 앞에 I가 아닌 맨 뒤에 Props를 붙여야 한다.</p>
<p>다만, Icon의 경우</p>
<pre><code class="language-ts">interface IconProps {
    ~
}</code></pre>
<p>위와 같이 앞에 대문자 I가 붙으며 마지막에 Props가 붙는다.
팀이 정한 정규표현식으로 걸러내지 못하는 상황.</p>
<p>그렇다고 부모에게서 받는 props 갯수를 줄여, type을 사용하기에는</p>
<pre><code class="language-ts">type IconType = {
    ~
}</code></pre>
<p>type 별칭을 사용함에도, 마찬가지로 맨 앞에 I가 붙어버린다.
type 역시 맨 앞에 대문자 I가 오면 안되고, 뒤에 Type이 붙어야한다고 컨벤션을 정했기 때문.</p>
<p>위와 같은 상황에서, 본인은 어떻게든 정규표현식을 잘 작동되게끔 수정하려 노력했던 것 같다.
결국 혼자서 해결하지 못하자 팀원들에게 문제 공유만 하였고 문제 해결에는 별다른 도움은 주지 못하였다.</p>
<p>회고를 작성하며 다시금 위 상황을 돌이켜보자면, 다음과 같은 문제가 있는 것 같다.
<code>사람과의 대화를 통해 문제를 해결하지 않고, 코딩으로 문제를 해결하려 했다.</code></p>
<p>모 엘리베이터 회사에서의 예시처럼 말이다.</p>
<blockquote>
<p>A, B 두 엘리베이터 회사는 고객으로부터 엘리베이터 속도가 느린 것 같다는 컴플레인을 받는다.
이때 A 회사는 수백억을 들여 기존보다 30% 빠른 엘리베이터로 교체하였다. 그러나, 고객으로부터의 답변은 &#39;기존과 별 차이가 없는 것 같아요.&#39;
B회사는 단지 엘리베이터 앞에 큰 거울 하나를 설치하였다.
그러자 고객들은 거울을 보며 시간을 보내게되자 컴플레인이 점차 줄어들게되었다.
이 일은, 고객 컴플레인은 결국 느껴지기에 실제로 엘리베이터 속도가 느린 것이 아닌, 단지 느린 &#39;것&#39; 같아요 라는 지겨움에서 온 것이기 때문이다.</p>
</blockquote>
<p>즉슨, 이때 나는 잘 만질줄도 모르는 정규표현식을 이렇게 저렇게 수정하려 하는 것이 아닌, 팀원들과 대화의 장을 열어야 했던 것이다.
그러지않고 잘 모른다는 핑계로 결정권자의 대답을 기다리고 있었었다.</p>
<p>요약하자면</p>
<ol>
<li>사람으로 해결하지 않고 코딩으로 문제를 해결하려 했다.</li>
<li>결정권자가 조금 더 쉽게 문제를 해결할 수 있도록 윤활제 역할을 하지 못했다.</li>
</ol>
<p>다음번에 유사한 문제가 생긴다면
&#39; 코딩 컨벤션이란 결국 우리 팀원들이 코딩을 하면서 조금 더 통일되고 훗날 공통 컴포넌트 사용, 리팩토링 등에서 조금 더 코드를 통일성 있고 쉽게 읽기 위함 아닌가?
그렇다면 앞으로도 다양한 예외가 나타날 수 있으니, 통일성 있게 interface면 맨앞에 I만, Type에는 뒤에 <del>Type만 붙이자</del> &#39;
처럼, 결정권자가 조금 더 매끄럽게 문제를 해결할 수 있게 도움이 될 수 있게 행동했으면 좋았을 것 같다.</p>
<br>

<h3 id="조금-더-나은-유저-경험을-위한-삽질-textarea">조금 더 나은 유저 경험을 위한 삽질 (textarea)</h3>
<p>sprint 2에서 본인이 맡았던 Page UI는 본문 페이지.
<img src="https://velog.velcdn.com/images/meow_tarae/post/6c942ee5-b588-4f63-ae8a-de2ec88ac905/image.png" alt="">
(예시 사진)</p>
<p>처음 만들어보는 댓글창이기에, 댓글창을 input 태그로 할 지, textarea로 할 지 고민이었다.
input 태그는 개행이 되지 않았기에, textarea를 선택했다.
<img src="https://velog.velcdn.com/images/meow_tarae/post/faf9ad95-0fea-4ed3-90ec-eab9eca6168c/image.png" alt="">
(textarea를 적용시켰을 때.)</p>
<p>다만 textarea도 문제가 있었는데, 계속 개행을 하다보면 위 사진처럼 이전에 작성했던 댓글창이 보이지 않는다.</p>
<p>이에 팀원들과 얘기를 나눠봤는데, 어떤 팀원분께서 깃허브 코드리뷰 할 때 댓글창에서도 개행 기능이 없으니 상관없지않을까? 라는 의견을 주셨다.</p>
<p>물론 이는 좋은 의견이었다.
말씀처럼 크게 고려하지 않아도 되는 부분이었지만, 이번 팀 프로젝트에서 내 목표인 <code>조금 더 나은 유저 경험을 위한 코드</code>를 위해 내 의견을 조금 밀어붙였던 것 같다.</p>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/5a6014ab-0a9e-4b05-a8e7-d38b4a9b3f5c/image.png" alt="">
(..지금보니 조금 부끄럽넹)</p>
<p>여하튼 문제를 해결하기 위해, 개행을 할 때마다 textarea height 값이 점차 커지게끔 변경해야 했다.</p>
<p>우선 이를 위해 벨로그의 댓글창 기능을 분석했다.
쉽게 해결할 줄 알았지만, 조금 까다로웠던 부분이 있었다.</p>
<p>우리에게는 고정된 font-size 값이 있었다.
때문에 조금 더 안일하게 생각한 부분인데, 단순하게 현재 상황에만 딱 들어맞게 코드를 작성하면 문제가 해결될 줄 알았던 것이다.</p>
<pre><code class="language-tsx">const [text, setText] = useState(&#39;&#39;);
const [line, setLine] = useState(0);
const textareaHeight = 81.5;
const onTextareaChange = (e) =&gt; {
  setText(e.target.value);
  setLine(e.target.scrollHeight - 80);
};

return 
    &lt;textarea
          value={text}
          style={{ height: `${textareaHeight + line * 16}px` }}
          onChange={onTextareaChange}&gt;
    &lt;/textarea&gt;</code></pre>
<p>(지금은 존재하지 않는, 백업해뒀던 코드만 가져온거라 이전에 작성했던 코드인지 아닌지 확실치 않아서 조금 아쉽다..)</p>
<p>구현을 위해 다음과 같이 생각했다.</p>
<ol>
<li>유저가 댓글을 입력한다</li>
<li>유저가 입력한 댓글의 총 개행 수(라인 갯수)를 알아낸다.</li>
<li>팀이 정한 font-size 값은 16px이니까 거기에 맞춰 textarea의 height를 재설정한다.</li>
</ol>
<p>하지만 이리 쉽게 생각 할 일이 아니었다.
여러 문제가 있었기 때문..</p>
<p>처음에는 개행할 때 마다 단지 23.3333...334px씩 늘어난다고 생각했다.</p>
<pre><code>  /* 16px
    80 - 80 = 0
    86 - 80 = 6
    109 - 80 = 29
    131 - 80 = 51
    154 - 80 = 74
    177 - 80 = 97
    200 - 80 = 120
    223 - 80 = 143
    6, 23, 17, 23, 23, 23, 23, 23
   */</code></pre><p>(물론 개행이 일어날 때 마다 고정된 23.333...34px 은 아니고, 중간중간에 한 번씩 변수가 있었음 ㅠ)
다만 이는 크나큰 착오.
알고보니 border, padding, scroll 너비, 그리고 브라우저(사파리, 크롬, 브레이브...) 등등 정말 많은 요소들에 의해 개행시 늘어나는 height 값이 변경된다는 것.
즉 코드에서의 textareaHeight라는 변수는 다양한 요인에 의해 결정되어야 하는데, 고정된 이 값은 약간의 css 변화만으로도 크게 문제가 될 수 있었다.</p>
<p>게다가 관리자 도구를 열어 살펴보니, textarea의 border 값에 1px을 부여한다고 온전히 1px을 가지고있진 않더라고.
분명 나는 1px을 부여했는데 .75px을 가지고 있었다.
정말 세밀하게 소수점 단위로 css를 일일이 부여해서 문제를 잡을 순 있었겠지만, 음.. 이건 좀 아닌 것 같았다.
그리고 브라우저마다 px들이 다 달라질텐데, 그럼 모든 브라우저들을 다 고려한 코딩을 해야하는 것인가? 하는 생각도 들었다.</p>
<p>또한, 화면에 보여지는 문제 외에도 기능적으로도 문제가 있었다.
기존에 작성했던 댓글을 &#39;수정&#39; 하려한다면, textarea가 작성되었던 댓글 height만큼 늘어나있어야 하는데, default height 값만을 가지고 있고 추가적으로 입력한다던가 지운다던가 등의 변화를 가해야만 height가 댓글에 맞게끔 수정된다는 것..?</p>
<p>그리고 &#39;개행&#39; 이라는게 \n을 나타내는데, 만약 ㅁㅁㅁㅁㅁㅁ... 를 계속 입력해서 자동 줄바꿈으로 인한 개행은 어떻게 처리해야 할 것인가..?</p>
<p>인터넷에 나와 유사한 상황인 사람들과 이를 해결한 코드들이 많이 있었지만, 문제를 해결하진 못했다.
이에 &#39;프로젝트 기간 내에 완성하지 못한 결과물은 쓰레기!&#39;라는 말이 생각이 나서 더욱 불안해져갔던 것 같다.</p>
<p>... 꽤나 고민하긴 했는데, 이 문제는 되게 허무하게 해결이 되었다.
사실 나처럼 기술적 고민으로 고생하시던 팀원분이 계셨다.
해서 그 팀원분은 다른 팀원들에게 자신의 문제를 공유하셨다.
그리고 나오는 답변. 라이브러리를 사용해봐라.
내가 가진 문제 역시 라이브러리 하나면 간단하게 해결 될 문제.
실제로 textarea-autosize 라는 라이브러리를 사용하니 손쉽게 문제가 해결되었다.</p>
<p>(아래는 댓글 입력 창)
<img src="https://velog.velcdn.com/images/meow_tarae/post/921cface-530e-4e8d-9624-d9ca1e694f91/image.png" alt=""></p>
<p>...진짜 너~무 쉽게 해결되어서 어이가 없었다.</p>
<p>그렇다고 삽질한 시간이 낭비란건 아니지만, 팀 프로젝트임을 망각하고 있었던게 아쉬웠다.
혼자 무언가를 만드는게 아니라 팀원들과 함께 하는 것임에도 불구하고, 너무 혼자 고민했던 것이 아쉬움으로 남았다.</p>
<p>조금 더 팀원들과 소통하고, 잘 배울 수 있다면 팀에 더 도움이 되는 행동을 할 시간이 생기지 않았을까 하는 생각이 든다.</p>
<h3 id="조금은-성장하지-않았나">조금은 성장하지 않았나.</h3>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/8fc2f492-7274-4c65-a312-77d221d8bf40/image.png" alt=""></p>
<p>(sprint 0 이후, 하루도 빠짐없이 기록했던 흔적들)
깃허브 컨벤션, postman 셋팅 등등 전혀 손 대지 못했던 부분 이후로 생각했던 것이 있다.</p>
<p>더 이상 아무것도 하지못했던 사람이 아닌, 뭐라도 한 사람이 되겠다.
이를 위해 매일 기록을 하고 &#39;내가 무엇을 했다&#39;를 확실히 하겠다.</p>
<p>약간 TIL 느낌이 나긴 한데, TIL은 전혀 아니라고 생각한다.
내가 오늘 어떤 것을 구현 할것이고, 이 부분을 어떻게 구현할 것인지 단계를 적어놓았다.
그리고 하나하나 해결 해나가며 모르는 부분, 어려웠던 부분을 기록했다.
그리고 잘 안될때마다 약간의 욕설(...)을 포함하기에, 남에게 공개할 TIL은 아니라고 생각한다.</p>
<p>아무튼 이런 기록들 덕분에 사진 하단에있는 &#39;공부해야하는 것&#39; 페이지를 만들 수 있었다.</p>
<p>프로젝트 하면서 잘 몰랐던 부분, 더 공부하고 싶었던 부분, 적용시켜보고 싶었던 기술..</p>
<p>예를 들어, 우리 팀은 공부를 위해 상태관리 라이브러리로 Redux-toolkit을 사용하였다.
다만, 내가 맡은 본문 페이지에서는 state가 Top-Down 방식으로 흐르기에, zustand 라는 라이브러리를 사용해보면 어땠을까 하는 생각?
또한 리액트 쿼리의 필요성.
특정 상황에서 데이터가 캐싱되어야 하는데, 이를 간단히 해결할 수 있는 도구이기 때문.
데브코스 선배이신 1기분께서 조언주신 내용이다.
등등.</p>
<p>이런 기록들이 앞으로의 성장에 도움이 될 수 있겠구나를 크게 느꼈던 것 같다.</p>
<p>이런 &#39;기록&#39; 자체는 정말 좋은 것 같다.
앞으로 기록 자체는 노션이 되었든 블로그가 되었든 자주 기록 할 참이다.</p>
<br>

<p>물론 기록 및 공부 외에도, 팀 프로젝트 방법과 팀원들과의 소통 방법까지.
정말 많은 것들을 익힐 수 있었다.
물론 이는 정말 좋은 팀원분들께서 부족한 나를 잘 나아갈 수 있게 도와주신 덕임을 잊진 않는다.</p>
<p>그리고 내 테도에 대한 문제.
잘 모르더라도 적극적으로 다가가서 함께 궁리해보기.
누가보면 속된말로 나댄다라고 할 수 있다.
이를위해 무언가를 알고 있어야 한다, 지식이 곧 힘이다를 깨닫게 되었고
사실 상대방만큼 자세히 알 필요는 없되, 최소한 대화는 할 수 있을 정도로 약간의 지식을 익혀두고 이를 바탕으로 밑작업을 준비해둔 뒤 상대와 대화해보기.</p>
<p>이번 프로젝트에서 얻은 생각으로는, 우선은 최소한 이정도만이라도 해보자. 를 얻게되었다.</p>
<p>나는 아직 여전히 많이 부족하다.
그러나 무지에 자책할 필요 없고, 아무것도 할 수 없는 것도 아니더라. 
팀에 발생한 문제를 매끄럽게 해결해나갈 수 있도록 윤활제 역할 정도는 충분히 해낼 수 있겠구나를 알게 되었다.</p>
<p>그리고 태도의 중요성.
누군가가 일을 맡겼을 때 어떤 태도로 이를 받아들이느냐.
내가 조금 좋지 않은 태도를 보였고, 이는 남들이 다 알더라고.
반성하며 앞으로는 절대 이런 태도를 보이지 않을것을 다짐할 수 있었다.</p>
<h2 id="마치며">마치며.</h2>
<p>이번 2차팀은 1차팀때보다 더 빨리 헤어진 것 같다.
팀 프로젝트 기간에 너무 정신이 없어서, 시간이 정말 눈 깜짝하니 사라졌다..
다들 정말 좋은 분들이셨는데, 이렇게 빨리 헤어진 것 같아 너무 아쉬웠다.</p>
<p>그리고 2차팀 소인성 멘토님과 마지막 면담을 나누었다. 
마지막까지 정말 좋은 말씀들을 주셨고, 나도 멘토님의 가르침에 감사를 표했다.
아, 그리고 면담 다음날에 테오의 강의가 있어서 멘토님께서 테오관련 말씀도 하셨다.
그리고 실력에 대한 부족함에 많이 힘들어하던 모습을 보였었던 나지만, 지금은 좋아진 모습에</p>
<blockquote>
<p>다음에 테오 스프린트 같은거, 참여할 수 있겠니?</p>
</blockquote>
<blockquote>
<p>네!</p>
</blockquote>
<p>정말 자신있게 대답했다.
컴플렉스를 이겨내고 처음으로 내뱉었던 긍정적인 말인 것 같다.</p>
<p>아마 데브코스 4개월 중 가장 기억에 남을 순간 중 하나가 아닐까 생각된다.</p>
<br>

<p>그리고 다음 날 가진 테오의 특강에서 배웠던 것.</p>
<blockquote>
<p>마지막으로 남는 것은 &#39;사람과 추억&#39;
이걸 남기는게 성공적인 협업.</p>
</blockquote>
<p>나도 이번 팀원분들처럼, 도움을 잘 주는 사람이 되기 위해 노력해야함을 배울 수 있었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 FE 데브코스 5기 11월~12월 MIL 회고]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-FE-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-11%EC%9B%9412%EC%9B%94-MIL-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-FE-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-11%EC%9B%9412%EC%9B%94-MIL-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Sun, 24 Dec 2023 23:29:31 GMT</pubDate>
            <description><![CDATA[<p>또 회고 쓸 날이 오다니.
정말 눈 감았다 뜨면 한 달이 뚝딱 사라지는게 참 신기하다.</p>
<p>또, 그게 벌써 3번이나 일어나 데브코스 기간이 절반이나 지나갔다.
아직도 실감이 잘 안나긴 한다 ㅎㅎ</p>
<p>슬 회고를 해보자.
이번 회고는 KPT 회고법을 사용해보고자 한다.</p>
<h1 id="keep">Keep</h1>
<h2 id="현재-만족하거나-이어가고자-하는-부분">현재 만족하거나 이어가고자 하는 부분?</h2>
<ul>
<li>디지털 디톡스</li>
<li>과제 구현 및 코드리뷰</li>
<li>다이어트</li>
</ul>
<h3 id="디지털-디톡스">디지털 디톡스</h3>
<p>거창해 보이는 이름과 달리, 그냥 유튜브나 음악 듣기 등의 시간 낭비를 줄이는 행동이다.
평소 위에 쏟는 시간이 많았던 것 같다. 이게 도파민 중독이라 쉽게 떨쳐내기가 어려웠는데, 친구와 함께 하고 있는 덕에 많이 줄일 수 있었다. 
음악은 항상 잔잔하게 틀어놓고 공부 했었는데, 이마저도 완전히 차단 해버렸다.
정말 듣고 싶을때 1~2곡만 듣는걸로.</p>
<p>효과는 굉장히 좋았던 것 같다.
항상 머리속에 잡생각이나 노래 생각이 확실히 많이 줄어들어 공부에 도움이 된 것 같다.</p>
<h3 id="과제-구현-및-코드리뷰">과제 구현 및 코드리뷰</h3>
<p>이번 리액트 과제를 지난 번 멘토님께서 조언 해주신 방법대로, 태스크를 최대한 나누고 어려운 것은 넘기는 방식으로 진행해 보았다. </p>
<p>물론 태스크를 나누는 것 자체를 아직 잘 못해서 많이 해맸기도 하고, 어려운 부분은 해결하지도 못했다.</p>
<p>그래도 어떻게든 내가 처리할 수 있을만큼 쉽게 쉽게 코드를 작성하려 노력하다보니,
다른 사람이 읽을때도 조금 더 보기 좋은 코드가 나온 것 같아 기분이 좋았다.</p>
<p>코드 리뷰시간 때 팀원분께서도 좋은 말씀 해주셔서 기분이 무척 좋았다.
내가 코드로 남에게 좋은 말을 듣는 날이 올 줄이야.</p>
<p>그리고 코드리뷰.
데브코스 들어와서 팀원들의 코드들을 많이 읽어봤지만, 그래도 읽기가 쉽지 않았다.
남의 의도와 스타일 등의 이유가 있다.</p>
<p>이를 위해, 이번에는 하나의 목적을 가지고 코드를 여러번 읽는 느낌으로 접근 해보았다.
예를 들어 처음엔 props의 흐름만을, 두번째는 코드 스타일, ...
이 방법은 기존의 무지성 코드리뷰와 비교해서 많은 시간을 단축시켜 줄 수 있었다.</p>
<h1 id="problem">Problem</h1>
<h2 id="불편하게-느끼거나-개선이-필요한-부분">불편하게 느끼거나 개선이 필요한 부분</h2>
<ul>
<li>과제</li>
<li>팀플 준비</li>
</ul>
<h3 id="과제">과제</h3>
<p>윗단에서 과제 파트에서 개선된 부분이 있지만, 여전히 부족한 부분도 많이 보인다.</p>
<p>우선 처음 배웠던 Vue 과제를 할때도, 경험이 있던 react 과제때도 심리적인 압박감이 너무 심한 것 같다.</p>
<p>그리고 추가적인 기능을 구현하겠다는 생각도 압박인 것 같다.
저번 회고에서, 추후 있을 과제에서는 부가적인 기능들도 더 추가 해보겠다 하는 생각이 있었다.
하지만 정작 기본기가 부족하기에, 기본 요구사항과 비기능 요구사항을 튼튼히 쌓아놓지 못하는 상황에서, 거기에 추가 기능을 구현하려하니 쌓아놓은 탑이 와르르 무너지려하는게 눈에 보였다.
이번 vue 과제가 그러했다.</p>
<h3 id="팀플-준비">팀플 준비</h3>
<p>우선, 이번 팀원분들은 다들 팀플 경험이 있으시거나 회사에서 근무를 하신 분들이시다.
팀플이 생판 처음인 나와는 비교가 안되게 준비가 되신 분들이기에 압박감이 있었다.</p>
<p>극복하고자 많은 구글링, 서칭을 해보았지만 맨바닥에서 쌓아올리는 지식이다보니 굉장히 조악한 수준.</p>
<p>팀플 대비로 미리미리 조금 공부해둘걸 후회로 다가왔던 것 같다.</p>
<h1 id="try">Try</h1>
<h2 id="problem에-대한-해결책이나-다음-회고때-판별-가능한-것">Problem에 대한 해결책이나 다음 회고때 판별 가능한 것.</h2>
<ul>
<li>과제</li>
<li>더욱 열심히
리액트 과제할 때 처럼, task를 더욱 세분화하려 노력하고 이를 상기하려 노력하자.
어려운 부분을 맞딱뜨렸을 때, 이를 해결하기 위해 노력하느 것은 좋지만, 이에 너무 빠져들지 않도록 조심할 필요가 있는 것 같다.</li>
</ul>
<p>그리고 추가 요구사항보다는 먼저 기본을 튼실히 쌓아놓고 뭔가를 추가하려 노력해보자.</p>
<p>마지막으로.. 팀원분들께 민폐끼치지 않게끔은 해야지...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 데브코스 5기 TIL - scss와 ts를 공부하며 ]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-vsc%EB%8A%94-%EC%97%AC%EB%9F%AC%EA%B0%9C%EC%9D%98-%ED%84%B0%EB%AF%B8%EB%84%90%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8B%A4</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-vsc%EB%8A%94-%EC%97%AC%EB%9F%AC%EA%B0%9C%EC%9D%98-%ED%84%B0%EB%AF%B8%EB%84%90%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8B%A4</guid>
            <pubDate>Wed, 22 Nov 2023 23:46:11 GMT</pubDate>
            <description><![CDATA[<h3 id="scss">SCSS</h3>
<p>데브코스에서 sass 과제를 내주었다.
이를 위해 node-sass를 설치하여 진행하였다.</p>
<h3 id="node-sass란">node-sass란?</h3>
<p>LibSass (C/C++로 작성된 Sass의 구현체)에 바인딩된 Node.js 라이브러리이다.</p>
<h3 id="sass-냅두고-왜-node-sass를">sass 냅두고 왜 node-sass를?</h3>
<p>블로그에 있는 sass 셋팅 글을 읽고 그대로 따라했다.
그리고 node 환경이기 때문에, 코드를 수정하고 저장하면 별도의 새로고침 없이도 페이지를 수정 시켜주는 환경을 좋아하기 때문.</p>
<p>(나중에 알고보니, 그냥 sass 사용해도 충분히 가능하던 일이었다..)</p>
<p><br><br></p>
<p>과제를 진행하던 중, 난관에 빠졌다.</p>
<p>자동 저장을 위해 parcel을,
scss 파일 저장 시 자동 저장을 위해 </p>
<blockquote>
<p>node-sass -w -r styles/common.scss styles/common.css</p>
</blockquote>
<p>위 커맨드를 입력해야 하는데, 이때는 여러개의 커맨드를 동시에 구동시킬 수 있다는 사실을 생각해내지 못했다.</p>
<p>항상 하나의 터미널에서 프론트 파트만을 실행시키다보니 그랬던 것 같다.</p>
<br>

<p>이에, 어떤 상황에서 여러 터미널을 사용할까? 하는 궁금증이 생겼다.</p>
<p>서버와 클라이언트를 동시 실행시키거나, DB관리, 배포 및 자동화 스크립트 실행 및 테스트 및 모니터링 등에서 사용되는 것 같다.</p>
<hr>

<h3 id="ts">TS</h3>
<p>강의 수강 중</p>
<pre><code class="language-ts">const $btn = document.querySelector(&#39;btn&#39;);
$btn.classList.add(&#39;box&#39;)</code></pre>
<p>위 코드는 에러를 발생시킨다
왜? HTML에서 btn 태그가 없을 수도 있으니까.</p>
<p>해서 as를 사용해서 btn이 존재함을 단언하여 해결하는 상황이었는데,</p>
<pre><code class="language-ts">($btn as HTMLButtonElement).classList.add(&#39;box&#39;);
// 위 방식도 가능하고 아래 방식으로도 가능하더라?
($btn as Element).classList.add(&#39;box&#39;);</code></pre>
<p>두가지 방식 모두 해결이 가능하니까, 각각의 타입이 어떤 것들인지 궁금해졌다.</p>
<h3 id="두-타입에-대하여-알아보자">두 타입에 대하여 알아보자.</h3>
<p>Element를 먼저 알아보자.
<code>lib.dom.d.ts</code>를 보면 Element는 아래와 같이 정의되어 있다. </p>
<pre><code class="language-ts">interface Element extends Node, 
                          ARIAMixin, 
                            Animatable, 
                            ChildNode, 
                            InnerHTML, 
                          NonDocumentTypeChildNode,
                            ParentNode, 
                            Slottable { ~ }</code></pre>
<p>Node, ARIAMixin, InnerHTML 등등을 상속받고 있다.</p>
<br>
그렇다면 이번엔 HTMLButtonElement.

<pre><code class="language-ts">interface HTMLButtonElement extends HTMLElement,
                                    PopoverInvokerElement { ~ }</code></pre>
<p>얘는 HTMLElement를 상속받고 있다. </p>
<p>그렇다면 한번 더, HTMLElement를 찾아봐야지.</p>
<pre><code class="language-ts">interface HTMLElement extends Element,
                              ElementCSSInlineStyle,
                              ElementContentEditable,
                              GlobalEventHandlers,
                              HTMLOrSVGElement { ~ }</code></pre>
<p>아하! Element를 상속받고 있음을 알 수 있다.</p>
<p>정리하자면, Element -&gt; HTMLElement -&gt; HTMLButtonElement 순서대로 상속받는 구조의 타입들이구나~</p>
<p><br><br></p>
<p>다시 본론으로 돌아와서, </p>
<pre><code class="language-ts">($btn as 타입)</code></pre>
<p>위와 같은 상황에서 타입을 지정해줄땐, 최상위 <strong>Element</strong> 타입 보다 Button 태그만을 가르키는 하위 <strong>HTMLButtonElemnt</strong> 타입을 지정해주는게 조금 더 구체적이겠구나~를 알게되었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 FE 데브코스 5기 10월~11월 MIL 회고]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-FE-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-10%EC%9B%9411%EC%9B%94-MIL-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-FE-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-10%EC%9B%9411%EC%9B%94-MIL-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Wed, 22 Nov 2023 14:11:12 GMT</pubDate>
            <description><![CDATA[<h1 id="또-벌써-한달-">또 벌써 한달 ??</h1>
<hr>
저번 회고와 같다.
벌써 한달이 지나갔다니..

<p>정말로 눈 깜짝할 새 한달이 지나가버려서 아직도 실감이 나질 않는다.</p>
<p><br><br></p>
<h1 id="1011월에는-어떤-일이-있었나">10~11월에는 어떤 일이 있었나</h1>
<hr>
크게 기억나는 일은

<ul>
<li>노션 클로닝</li>
<li>커피맨</li>
<li>방학</li>
<li>새로운 팀</li>
</ul>
<p>위 주제들로 회고를 하려한다. </p>
<p><br><br></p>
<h1 id="노션-클로닝">노션 클로닝</h1>
<hr>
강의에서 배운 내용들을 토대로 노션을 클로닝하는 과제가 있었다.

<p>과거 타 사이트에서 JS를 공부한 경험이 있기에 쉽게 해낼 수 있을거라 생각했던 것 같다.</p>
<p>그러나 결과는 개박살.
<img src="https://velog.velcdn.com/images/meow_tarae/post/56dfac58-44ef-42c3-b950-779811596389/image.png" alt="">
(내 멘탈을 보는 것 같다.)</p>
<p>10여일의 과제 기간 중 4일을 코드에 손도 못 대고 고대~로 날려먹고 <br> 남은 6일동안 겨우 최소 조건을 만족시켜 제출했다.</p>
<p>분명 보너스 요구 사항까지 충족시켜가며 나만의 과제를 만들겠다느니 뭐니 해놓고.. 꼴이 말이 아니었다.</p>
<h3 id="왜-그렇게-손도-못-대고-있었던걸까">왜 그렇게 손도 못 대고 있었던걸까</h3>
<ul>
<li><p>코드 따라치기 전문가
이웅모 개발자님 세션에서 말씀하셨던 <code>코드 따라치기</code>에 대한 결과물이 아닐까싶다.
이전에 강의(데브코스 아님)에 나오는 강사님이 잘 짜놓으신 코드만 Ctrl + c, Ctrl + v 해놨던 것을, 마치 본인이 짠 코드인 것 마냥 착각하고 있었던 것 같다.</p>
</li>
<li><p>프로 다이소 이용자
어디서 들었던, <code>다이소에서 물건들 사 모으는 것 마냥, 쓸데없는 경험만 주구장창</code>했던 것 같다.
a-b-c 단계별로 나아가야 하는 과정에서, a도 제대로 못하는 놈이 겉멋만 잔뜩 들어서 b, c를 맛 보려 했다. </p>
</li>
</ul>
<p>그래놓고 &#39;나 이거 다 할 줄 알아요!&#39;</p>
<p>... 지금 생각해보니 어찌나 한심한지.
<img src="https://velog.velcdn.com/images/meow_tarae/post/167b12ec-8538-45b5-9770-3f8592e3f4e9/image.png" alt="">
(후회가 막심하다 따흑따흑)</p>
<p>지난 날 제대로 공부 좀 할걸, 뼈저리게 후회한다고 과제가 저절로 해결되진 않는다. 어떻게든 해결을 봐야했다.</p>
<p>4일을 날려먹고 난 다음날, 처음부터 다시 강의를 들어가며 어떻게 과제를 수행할지 생각했다.</p>
<br>

<p><strong>이때, 어떤 문제가 있을 때 이를 어떻게 해결해야할지 조금 생각을 틔게 된 것 같다.</strong></p>
<ul>
<li>만들고자 하는 과제를 <code>구조화 및 세분화</code>하자.
UML 다이어그램도 그려보고, 종이에 각 컴포넌트들마다 기능이나 상단에서부터 내려오는 props들 흐름 등을 그려보며 어떻게든 구조화 및 세분화하려고 했던 것 같다.</li>
<li><code>배운 내용을 어떻게 써먹을까?</code>
공부를.. 음.. 옛날엔 그냥 영상만 쳐다보면서 그렇구나~ 하고 넘겼던 것 같다. 그러나 과제할 땐 &#39;이 부분은 과제에서 어떻게 써먹을 수 있을까?&#39; 를 고민했던 것 같다.</li>
</ul>
<p>물론, 마지막에 과제랍시고 내놓은 결과물은 내가봐도 참 별로인 것 같다.
<img src="https://velog.velcdn.com/images/meow_tarae/post/8559274c-e36f-4cb5-931e-a888db1ce075/image.png" alt=""></p>
<p>(고슴도치도 지 새끼는 이쁘다던데, 내 코드는 이쁘질않네)</p>
<p>그래도 노션 프로젝트 덕분에 내가 얼마나 개떡같이 코딩 공부했는지, 그리고 어떻게 공부해야 할지 고민해볼 수 있는 기회가 되어준 것 같다.</p>
<br>

<p>다음 회고인 11~12월 MIL에는 조금 더 나은 공부를 하고 있기를 바란다. 
(과제에 보너스 요구사항도 좀 넣어보고 이놈아)</p>
<p><br><br></p>
<h1 id="커피맨">커피맨</h1>
<hr>

<p>팀원들과 멘토님을 만나뵙기 위해 서울에 올라가게 되었다.
우선 저녁에 멘토님을 뵙는 계획이었고, 이전에는 모각코를 했다. 
모각코 장소는 프로그래머스 강의장이었다.
원래는 강남 카페에서 모각코를 하려 했는데, 수강생들을 위해 불철주야 노력하시는 소피아 매니저님 덕분에, 운 좋게도 프로그래머스 강의장에서 편안~하게 공부했다.
강의장에는 우리 팀 외에도 10여명의 다른 팀원 분들도 뵐 수 있었다.</p>
<p>그때 정신나간 행동을 했다.</p>
<p>MBTI가 INTJ인 본인은, <strong>I 수치가 100%다.</strong>
누가 말 걸면 사시나무처럼 떠는 놈이, 갑자기 커피 마시고 싶어서 &#39;커피 마실분~ 커피 마실분~&#39; 하며 테이블 돌아다녔던 것.</p>
<p>어찌 이딴 짓을 생판 첨 보는 분들 앞에서 했었던건가, 아직도 그날의 나에 대해 이해가 잘 안간다.</p>
<p>그래도 덕분에 다른 팀원분과 얘기도 나눠봤고, 이번에 새로운 팀이 된 &#39;Lee&#39;님과도 안면을 틔게 되었다.
<img src="https://velog.velcdn.com/images/meow_tarae/post/c0df65dc-329c-4422-bbce-c52f1325cfc0/image.png" alt="">
(어.. 그때 그 커피 마실 사람?!)</p>
<p><br><br></p>
<h1 id="방학">방학</h1>
<hr>
Three.js 에 대하여 알아보았다.

<p>scene , camera , renderer 부터 카메라 종류들, 불러올 파일들 등..</p>
<p>데브코스에서 배운 것도 아니고, 팀원들과의 사이드 프로젝트도 아니고.. 갑자기 웬 Three?</p>
<p>방학 전 날, 1차팀 멘토님과 마지막 1:1 면담을 나누었다.
아직 노션의 충격이 가시질 않던 때라, 멘토님께 조언을 구했던 것.</p>
<p>Q) 멘토님은 어떻게 여가시간을 보내시나요 ?
A) 만들고 싶은 것을 만들며 시간을 보낸다. 회사나 강의나 정해진 것들을 만들어내야 하고 생각해야한다. 그런 것만 하면 재미없다.</p>
<p>프로그래밍 언어라는 것이 극과 극으로 다른 것도 아니고, 대개 유사한 면이 있기 마련이다. 멘토님 말씀처럼 &#39;내가 만들고 싶고 공부하고 싶은 것을 하나 정하고, 그것을 노션 프로젝트에서 배운 공부 방법으로 적용시켜 체화하는 것은 어떨까?&#39;라는 생각까지 닿았다.</p>
<p>이에 실천해 보았던 것. 근데 아직 재밌는진 모르겠다
..</p>
<p><br><br></p>
<h1 id="새로운-팀">새로운 팀</h1>
<hr>
정말 좋은 팀원분들과 목표점으로 바라볼 수 있었던 멘토님 덕분에 1차 팀은 데브코스가 끝나고서도 잊히지 않을 것 같다.

<p>언젠가 다시 모여 즐겁게 놀고 싶다.</p>
<p><br><br></p>
<h1 id="마치며">마치며</h1>
<hr>
어쩌다보니 회고가 아니라 일기가 된 것 같은데..

<p>음.. 다른 분들은 뛰어나신지라 공부하신 부분들로 회고를 잘 하신 것 같지만, 나는 틀어져있던 공부 방향을 다시금 바르게 고치려 노력한 것으로 회고했다 생각한다. 그리고 공부한거는 따로 정리된 것이 있으니 나중에 그거 보면 되니까.
다음 달에는 실력적으로 성장할 수 있는 것을 목표로 해보겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[fetch 실행 시 프로미스의 응답 헤더에 관하여]]></title>
            <link>https://velog.io/@meow_tarae/fetch-%EC%8B%A4%ED%96%89-%EC%8B%9C-%ED%94%84%EB%A1%9C%EB%AF%B8%EC%8A%A4%EC%9D%98-%EC%9D%91%EB%8B%B5-%ED%97%A4%EB%8D%94%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC</link>
            <guid>https://velog.io/@meow_tarae/fetch-%EC%8B%A4%ED%96%89-%EC%8B%9C-%ED%94%84%EB%A1%9C%EB%AF%B8%EC%8A%A4%EC%9D%98-%EC%9D%91%EB%8B%B5-%ED%97%A4%EB%8D%94%EC%97%90-%EA%B4%80%ED%95%98%EC%97%AC</guid>
            <pubDate>Sat, 18 Nov 2023 09:12:52 GMT</pubDate>
            <description><![CDATA[<p>노션 클로닝 과제를 진행하며 있었던 일이다.</p>
<pre><code class="language-js">const request = async (url) =&gt; {
  try {
    const res = await fetch(`${API_END_POINT}${url}`);

    if (!res.ok) {
        // 에러처리 1
    }
    return await res.json();
  } catch (e) {
    // 에러처리 2
  }
};</code></pre>
<p><code>fetch()</code>로 url에 있는 api 데이터를 가져오려는 코드이다.
에러 체크 후, res.ok 일때만 데이터를 리턴하는 코드이다.
처음에는 HTTP 에러 (400, 500번대)만 제하면 되겠지하고 안일하게 생각했다.</p>
<p>이후 멘토님의 코드리뷰 덕분에 한 번 더 생각하게 되었고, 관련된 자료를 찾아보게 되었다.
위 코드의 흐름에 맞춰 자료를 조금 더 찾아보았다.</p>
<br>

<h3 id="fetch-실행-순서">fetch 실행 순서</h3>
<p><code>fetch()</code>를 호출했을 때 부터 순서대로 나열해보자.</p>
<ul>
<li><p>fetch()를 호출하면 브라우저는 네트워크 요청을 보내고 프라미스가 반환된다. 
(위 코드에는 res에다가 반환.)</p>
</li>
<li><p>서버에서 응답 헤더를 받자마자, fetch 호출 시 반환받은 promise가 <code>내장 클래스 Response의 인스턴스</code>와 함께 <code>이행 상태</code>가 된다.</p>
<ul>
<li>이행 상태는 CORS 에러나 네트워크 요청 자체의 실패가 아닌 이상, status에 관계없이 이행된다.</li>
<li>이때 내장 클래스 Response의 인스턴스는<pre><code class="language-js">{
// 프로퍼티
&#39;status&#39; // HTTP 응답 상태 코드 (예: 200, 404, 500).
&#39;ok&#39; // 상태 코드가 200-299 범위에 있는지 여부를 나타내는 부울 값.
&#39;statusText&#39; // HTTP 상태 메시지 (예: &quot;OK&quot;, &quot;Not Found&quot;).
&#39;headers&#39; // 응답 헤더를 나타내는 Headers 객체.
&#39;url&#39; // 응답이 온 URL.
</code></pre>
</li>
</ul>
<p>// 메서드</p>
<pre><code>text() // 응답 본문을 텍스트로 반환하는 메서드.</code></pre><p>  json() // JSON으로 파싱된 응답 본문을 반환하는 메서드.
  blob() // 응답 본문을 Blob 객체로 반환하는 메서드.
  formData() // 응답 본문을 FormData 객체로 반환하는 메서드.
  arrayBuffer() // 응답 본문을 ArrayBuffer로 반환하는 메서드.
}
 ```
 등이 있다. <br>
 이 단계는 아직 본문(body)이 도착하기 전이지만, status를 통해 요청이 성공적으로 처리되었는지 아닌지를 확인할 수 있다.</p>
</li>
<li><p>이후 res에 Response 객체 ( 위 코드에서는 res.json() ) 등을 통해 응답을 반환한다.</p>
</li>
</ul>
<br>

<p><em>res.ok가 200~299 범위의 여부를 확인한 후 boolean 값을 리턴하는 프로퍼티라는 것을 알게되었
다.</em></p>
<br>

<h3 id="에러처리">에러처리</h3>
<p>이제 fetch 실행 순서에 대하여 조금 더 잘? 알게된 것 같다.
이제 남은 것은 각 상황에 맞는 에러처리를 잘 해주는 것.</p>
<p>각각의 에러 상황에 대하여 찾아보았다.</p>
<ul>
<li>에러처리 1 : status가 400번 or 500번대의 <strong>비성공</strong> 상태에 대한 에러처리</li>
<li>에러처리 2 : 아까 이행 상태에 대하여 얘기하던 부분, CORS 에러나 서버에 요청이 완전히 서버에 도달하지 못하는 경우에 대한 에러처리</li>
</ul>
<h4 id="에러처리-1">에러처리 1</h4>
<p>아까, 200~299번 사이의 범위일 때 ok가 true를 리턴한다고 했다.
번호별로 각각의 성공 사례? 가 모두 다르더라. 
현재와 같은 일반적인 상황 외에 번호별의 특수한 경우에는 status에 따라 다른 문구 혹은 동작을 수행하게끔 하면 좋겠다고 생각했다. 
<br></p>
<p>문제는 비성공 상태에 대한 처리.
<strong>400번대 갯수만 해도 29개이고 500번대도 11개이다.</strong>
(더럽게 많다. 200번대는 10개가 채 안되는데..)
그렇다면 나는 총 40여개의 status별 에러처리를 해야하는 것인가?</p>
<p>...일단은 에러코드들이 어떤 내용들일지 한번 읽어보았다.</p>
<p><strong>400번</strong>: 클라이언트의 요청이 유효하지 않아 발생하는 상태라고 한다.</p>
<ul>
<li>401: 인증과 관련된 문제, <strong>비인증</strong>.</li>
<li>402: 비표준, 결제와 관련된 문제</li>
<li>403: 클라이언트가 권한이 없을때. 
(비회원일때, 회원 전용 페이지에 접근한다거나 관리자 페이지에 접근한다거나)</li>
<li>404: 서버가 요청받은 리소스를 찾을 수 없는 상황.</li>
<li>418: 이상한 농담..?</li>
<li>... 기타 등등</li>
</ul>
<p>공식문서를 찾아보며 위 상태들에 대하여 공통점이 있을 경우, 그 상태들을 묶어서 에러에 대처하면 어떨까 하고 생각해서 찾아봤는데..
상태들마다 각각의 에러가 발생할 수 있는 상황에 대처하기 위해 존재하는 것 같아, 공통점을 찾기가 쉽지 않았다.</p>
<p>가장 좋은 에러처리는 현재 fetch()를 사용하는 코드가 인증과 관련된 코드인지, 결제에 관련한 코드인지 등을 파악한 후 거기에 맞는 status를 찾아서 끼워넣는게 좋아보인다.</p>
<p>내 노션 클론의 경우 </p>
<pre><code class="language-markdown">url이 abc/cde 처럼 존재하지 않을 경우 (존재하지 않는 경로), 
/documents/:${id} 에서 id값이 존재하지 않을 경우 (존재하지 않는 자원)
: 404 에러처리

로그인 기능을 구현 했을 경우
비회원이 회원의 글을 읽으려하면 : 401 에러처리.
다른 사람이 쓴 글을 수정하려하면 : 403 예러처리.</code></pre>
<p>등의 에러처리를 할 수 있을 것 같다.
<br></p>
<p>이 외에도 자체 에러코드를 만들거나 하는 경우도 있다고 한다.
그리고 404등 500 오류등 모든오류는 그냥 바로 오류메시지 보여주지말고 오류메시지는 절때 친절하면안된다고 한다. 해킹에 요인이 된다고.</p>
<h4 id="에러처리-2">에러처리 2</h4>
<p>보안, url 문제, CORS, 네트워크 연결 문제 등과 관련된 에러다보니, e.message로 처리하는 것이 좋아보인다.</p>
<h3 id="결론">결론</h3>
<p>HTTP status에 대한 에러처리에 대하여 살짝 알아보았다.
예전에 마광휘 개발자님께서 추천해주신 책 중에 &#39;HTTP 완벽 가이드&#39;가 있었다.
프론트도 서버에 관하여 알아야 한다고... 그 말씀이 조금 이해가 되는 것 같았다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] Styled-Components 정리]]></title>
            <link>https://velog.io/@meow_tarae/React-Styled-Components-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@meow_tarae/React-Styled-Components-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Wed, 15 Nov 2023 21:58:04 GMT</pubDate>
            <description><![CDATA[<h3 id="사용하는-이유-">사용하는 이유 ?</h3>
<p>css 모듈을 사용할 경우 가독성이 떨어지며, hover와 같은 속성을 사용할 수 없다.</p>
<br>

<h3 id="styled-components-기본-사용-방법">styled-components 기본 사용 방법</h3>
<pre><code class="language-js">import styled from &quot;styled-components&quot;;

function App() {
  const Box = styled.div`
    background-color: skyblue;
  `;
  return (
    &lt;Box&gt;
        // div와 같은 태그명 대신 styled-components로 선언한 네이밍을 사용
      &lt;h1&gt;Styled Components&lt;/h1&gt;
      &lt;p&gt;Styled Components is cool&lt;/p&gt;
    &lt;/Box&gt;
  );
}

export default App;
</code></pre>
<br>

<h3 id="props">props</h3>
<p>jsx 구문에서 props를 설정해주면 styled는 이를 받아올 수 있다.</p>
<pre><code class="language-js">import styled from &quot;styled-components&quot;;

function App() {
  const Box = styled(Box)`
    background-color: ${(props) =&gt; props.bgColor};
  `;
  return (
    &lt;Box bgColor=&quot;snow&quot;&gt;
        // props 설정
      &lt;h1&gt;Styled Components&lt;/h1&gt;
      &lt;p&gt;Styled Components is cool&lt;/p&gt;
    &lt;/Box&gt;
  );
}

export default App;
</code></pre>
<br>

<h3 id="컴포넌트-확장">컴포넌트 확장</h3>
<p>어떤 styled components를 가져와서 확장할 수 있다.</p>
<pre><code class="language-js">import styled from &quot;styled-components&quot;;

function App() {
  const Box = styled.div`
    background-color: skyblue;
  `;
  const TextBox = styled(Box)`
    // Box component를 확장
    font-weight: 800;
    color: ${(props) =&gt; props.color};
  `;
  return (
    &lt;TextBox color=&quot;snow&quot;&gt;
      &lt;h1&gt;Styled Components&lt;/h1&gt;
      &lt;p&gt;Styled Components is cool&lt;/p&gt;
    &lt;/TextBox&gt;
  );
}

export default App;</code></pre>
<br>

<h3 id="attribute-지정">attribute 지정</h3>
<p>태그 뒤에 .attrs({ }) 를 작성한 후
중괄호 안에 속성을 집어넣으면 된다.</p>
<pre><code class="language-js">  const Box = styled.input.attrs({ required: true })`
    background-color: skyblue;
  `;</code></pre>
<br>

<h3 id="animation">Animation</h3>
<pre><code class="language-js">import styled, { keyframes } from &quot;styled-components&quot;;
// import keyframes

function App() {
  // animation은 keyframes 키워드를 사용한다.
  const animation = keyframes`
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(360deg);
    }
  `;
  const Box = styled.div`
    width: 100px;
    animation: ${animation} 2s linear;
    // 앞서 선언한 animation을 ${} 로 감싸서 사용한다.
  `;

  return (
    &lt;Box color=&quot;snow&quot;&gt;
      &lt;h1&gt;Styled Components&lt;/h1&gt;
      &lt;p&gt;Styled Components is cool&lt;/p&gt;
    &lt;/Box&gt;
  );
}

export default App;</code></pre>
<br>

<h3 id="자식요소-선택">자식요소 선택</h3>
<pre><code class="language-js">function App() {
  const Box = styled.div`
    background-color: skyblue;

    // scss 문법처럼 사용할 수 있다.
    &amp;:hover { opacity: 0; }
    &gt; :hover { opacity: .1; }
    span {opacity: .2;}
    span:hover {opacity: .3;}
  `;

  return (
    &lt;Box&gt;
      &lt;span&gt;Hello&lt;/span&gt;
    &lt;/Box&gt;
  );
}</code></pre>
<p>scss에서는 자식요소를 가르킬 때, tag 외에도 클래스 명으로 자식 요소들을 선택할 수 있었다. </p>
<p>styled-components는 그런 방법이 없을까?</p>
<pre><code class="language-js">function App() {
  const Text = styled.span`
    color: snow;
  `;
  const Box = styled.div`
    background-color: skyblue;
    ${Text}:hover { opacity: 0; }
    // components를 ${ } 안에 감싸넣어 활용할 수 있다.
  `;

  return (
    &lt;Box&gt;
      &lt;Text&gt;Hello&lt;/Text&gt;
    &lt;/Box&gt;
  );
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 FE 데브코스 5기 9월~10월 MIL 회고]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-FE-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-9%EC%9B%9410%EC%9B%94-MIL-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-FE-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-9%EC%9B%9410%EC%9B%94-MIL-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Mon, 23 Oct 2023 15:27:46 GMT</pubDate>
            <description><![CDATA[<h2 id="벌써-한달-">벌써 한달 ??</h2>
<hr>
면접 후 결과 발표를 기다리던 날이 엊그제 같은데, 벌써 1달이라는 시간이 지나갔다.

<p><img src="https://velog.velcdn.com/images/meow_tarae/post/9e123230-6ea5-4b59-96fc-1359daaad493/image.png" alt=""></p>
<p>아직도 믿기질 않는다 ㅎㅎ</p>
<p>데브코스에서 매일 진행되는 코어타임, 폭풍같은 진도, <del>무급 야근</del>까지.
코딩 공부를 원없이 하고 있는 중이다.
덕분에 이렇게 시간이 후딱 지나간게 아닐지.</p>
<p><br><br></p>
<h2 id="어떤걸-배웠더라">어떤걸 배웠더라?</h2>
<hr>

<p>데브코스 초입인 JS 기초 파트에서는 모딥다에서 배운 내용과 알고리즘들을 빠르게 훑고 지나갔다.
다행히? 데브코스 합류 전에 모딥다를 한 번 봐두었던 게 큰 도움이 되었다.</p>
<p>하지만 알고리즘 부분은 상당히.. 고통스러웠다.
<img src="https://velog.velcdn.com/images/meow_tarae/post/3b8035ba-0f2a-4079-8287-e3a0964b3f94/image.png" alt=""></p>
<p>데브코스는 기초를 가르쳐 주는 곳이 아닌, 실력을 강화하는 코스인 것 같다.
때문에 알고리즘 초보인 본인은 이때 조금 많이 고통스러웠던 것 같다.</p>
<p>이후 바닐라 JS를 통한 To Do List, Notion 클로닝을 통해 JS에 대한 숙련도를 쌓았다.</p>
<p><br><br></p>
<h2 id="좋았던-경험">좋았던 경험?</h2>
<hr>
개인적으로 신선했던 경험 중 하나는, 생성자 함수(혹은 클래스)를 통해 객체지향 방식으로 구현을 한 것이다.
외부에서 클론 코딩으로 개발을 접했는데, 이때는 무지성으로 코드를 휘갈겼었다.

<p>때문에 객체지향적 코딩과 친해지기까지 너무 오랜 시간이 걸린 것 같다..
<del>(사실 지금도 안친하다)</del></p>
<br>

<p>또한 데브코스에서는 프로젝트 기간 제외하고는, 거의 매주 우수하신 강사님들, 대기업 개발자분들의 특강이 있다.
현직에서 보고 배우신 것들 중에서도 중요한 내용들을 학생들을 위해 알려주시는 시간인데, 이 시간을 통해 <code>어떻게 공부 해나가야 할지</code> 알 수 있는 좋은 기회가 되었다.
<img src="https://velog.velcdn.com/images/meow_tarae/post/db2095ab-8540-4aef-a13b-f31f6ce0574c/image.png" alt=""></p>
<p>강사님이 알려주신 내용과 유사한 글이 있어 링크 남긴다.
<a href="https://phant0m.tistory.com/23">https://phant0m.tistory.com/23</a>
( T자 공부법 )</p>
<br>

<p>그리고 팀원들과 멘토님.
같은 직종을 목표로, 함께 달릴 수 있는 곳은 그리 많지 않다고 생각한다.
혼자였으면 지쳐 쓰러졌을 수 있지만, 함께이기에 계속 나아갈 힘이 생겨나는 것 같다.
그리고 목표로 하는 IT 대기업의 멘토님과 매주 갖는 커피챗 타임과 과제에 대한 양질의 리뷰까지.</p>
<p>.. 솔직히 너무 많은 프로틴을 섭취하고 있어 다 흡수해내지 못하고 있는 것 같은 느낌이다.
<img src="https://velog.velcdn.com/images/meow_tarae/post/dc54ad6c-9b86-4027-9b8d-20039c3313e0/image.png" alt="">
말이 그렇다는 거지, 정말 분에 겨운 성장 기회를 받고 있는 것 같아 너무 행복하다. </p>
<p>몸뚱이가 여럿이었다면 정말 폭발적으로 성장했을 것 같다.</p>
<p><br><br></p>
<h2 id="마치며">마치며</h2>
<hr>

<p>데브코스에서 정말 많은 도움을 주시고 있지만, 그걸 다 받아들이지 못하고 있는 상태라고 생각한다.
과제를 보면 어떻게 해야 할지 몰라 쩔쩔매는 시간이, 정작 과제하는 시간보다 더 많다고 생각된다.</p>
<p>나중에 있을 팀플 때 팀원분들께 폐는 끼치지 말아야 할 텐데..</p>
<p>그만큼 더 열심히 하는 수 밖에 없지 뭐..</p>
<p>그리고 프로젝트 기간이 끝난다면, 규칙적인 수면패턴과 데일리 패턴을 지켜보려 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 데브코스 5기 TIL 12일차]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-12%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-12%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Wed, 04 Oct 2023 08:53:54 GMT</pubDate>
            <description><![CDATA[<h2 id="학습-내용">학습 내용</h2>
<hr>

<h1 id="js에서-this">JS에서 this</h1>
<p>JavaScript의 <code>this</code>는  함수가 어떻게 호출되었는지에 따라 달라집니다. </p>
<pre><code class="language-js">// 1. 전역 스코프
// 전역 스코프에서 this는 전역 객체를 참조합니다. 브라우저에서는 window 객체가 됩니다.
// (Node 환경에선 global, strict mode에서는 undefined.)
console.log(this === window); // true


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


// 2. 함수 호출:
// 일반 함수로서 호출될 때 this는 전역 객체를 참조합니다.
function func() {
  console.log(this);
}
func(); // window (브라우저에서)


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


// 3. 메서드 호출:
// 객체의 메서드로서 호출될 때 this는 해당 메서드를 호출한 객체를 참조합니다.
const myObj = {
  method: function() {
    console.log(this);
      // this는 myObj를 가르킴.
  }
};
myObj.method(); 


// 3-1.
const myObj = {
  outerMethod: {
      innerMethod: function(){
        console.log(this);
        // 이때 this는 outerMethod를 가르키게 됩니다.
    }
  }
};


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


// 4. 생성자 함수:
// new 키워드를 사용하여 생성자 함수를 호출하면, this는 새로 생성된 객체를 참조합니다.
function MyClass() {
  this.prop = &quot;value&quot;;
}
const instance = new MyClass();
console.log(instance.prop); // &quot;value&quot;


// 4-1.
// 다만, new 생성자 함수 없이 함수를 호출하면, 에러가 발생합니다.
function MyClass() {
  this.prop = &quot;value&quot;;
}
const instance = MyClass();
console.log(instance.prop); // TypeError: Cannot read properties of undefined

// a) MyClass 함수가 new 생성자 함수 없이 호출되었기에, 해당 함수 내부 this는 전역 window를 가르키게 됩니다.
// b) 또한 MyClass 함수는 리턴 값이 없으므로 instanc는 undefined 입니다.
//    때문에 출력문은 undefined.prop 이 되므로 TypeError를 출력하게 됩니다.


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


// 5. 화살표 함수:
// 화살표 함수는 자신만의 this 바인딩을 갖지 않습니다. 
// 때문에 상위 함수 scope를 찾아갑니다.

function OuterFunction() {
  this.value = &quot;hello&quot;;

  this.arrowFunction = () =&gt; {
    console.log(this.value); // &quot;hello&quot;
  };
}

const instance = new OuterFunction();
instance.innerFunction(); 
instance.arrowFunction();


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


// 6. call, apply, bind:
// call, apply, bind 메서드를 사용하면 함수를 호출할 때 this의 값을 명시적으로 설정할 수 있습니다.
function showThis() {
  console.log(this);
}
const obj1 = { name: &quot;obj1&quot; };
const obj2 = { name: &quot;obj2&quot; };

showThis.call(obj1); // obj1
showThis.apply(obj2); // obj2

const boundFunction = showThis.bind(obj1);
boundFunction(); // obj1


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


// 7. 이벤트 핸들러:
// 대부분의 경우, 이벤트 핸들러에서 this는 이벤트를 발생시킨 DOM 요소를 참조합니다.

</code></pre>
<hr>

<h1 id="클로저">클로저</h1>
<p>자주 보이는 예제인데, 헷갈리는 부분이 있었어서 다시 기록하려합니다.</p>
<pre><code class="language-js">for (var i = 0; i &lt; 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, i * 1000);
}
// 5, 5, 5, 5, 5
// var를 사용하면 for 루프의 반복마다 새로운 변수 인스턴스가 생성되지 않습니다. 
// 따라서 모든 setTimeout 콜백이 루프가 끝난 동일한 i 변수를 참조하게 됩니다.


for (let i = 0; i &lt; 5; i++) {
  setTimeout(function() {
    console.log(i);
  }, i * 1000);
}
// 0, 1, 2, 3, 4
// 각 setTimeout 콜백들이 for 루프의 각 반복에서의 새로운 i 인스턴스 값을 &quot;캡처&quot;했기에
// 스택 내부의 각 setTimeout들은 서로 다른 i 값을 참조하게 되었습니다.

// 물론 즉시실행함수(IIFE) 또는 forEach문을 사용해도 됩니다.</code></pre>
<hr>

<h2 id="후기">후기</h2>
<p>아직 JS가 많이 부족하구나를 느꼈습니다. 더 꼼꼼히 열심히 공부해야겠어요.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 데브코스 5기 TIL 11일차]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-11%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-11%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Tue, 03 Oct 2023 07:34:35 GMT</pubDate>
            <description><![CDATA[<h1 id="강의-내용들">강의 내용들..</h1>
<h2 id="dom">DOM</h2>
<p>오늘은 DOM에 관해 배웠습니다.
현재 데브코스를 진행하며 팀원분들과 모딥다 스터디를 진행하고 있습니다.
덕분에 복습하기 좋은 시간이었습니다.</p>
<p>정리한 내용은 <a href="https://github.com/prgrms-web-devcourse/FEDC5_I_DeepDive/blob/GeonHo/39.%20DOM/GeonHo/gh.md">깃허브 레파지토리</a>에서 확인하실 수 있습니다.</p>
<h3 id="추가">추가</h3>
<p>돔 조작은 리플로우, 리페인팅이 발생하게되어 많은 비용이 발생하게 됩니다.
따라서 loop를 돌며 많은 요소들을 생성하고 돔에 연결/삭제하면, 그만큼 엄청 많은 비용이 발생합니다.</p>
<p>이를 방지하기위해 div와 같은 컨테이너 안에 생성할 요소들을 담아, 컨테이너를 한 번만 DOM에 연결한다면 조금 더 비용을 아낄 수 있겠습니다.</p>
<p>하지만 그렇게되면 div 태그 안에 생성한 요소들이 담기게되어, 우리가 원하는 형태의 DOM 트리가 구현되지 않을 것 입니다.</p>
<p>이때 <strong>DocumentFragment</strong>를 사용하면 좋을 것 같습니다.</p>
<p><em>DocumentFragment</em> 는 실제 DOM 트리와 분리되어 메모리에서 작업을 수행하기 때문에 실제 페이지 렌더링에 영향을 주지 않습니다.
때문에 div와 비슷한 방식으로 생성할 요소들을 조각(Frgament)안에 담은 후 요소들을 원하는 노드에 연결시켜주지만, 조각 자체는 트리에 남아있지 않습니다.</p>
<p>덕분에 우리가 원하는 DOM 트리가 구현될 수 있습니다.
이는 가상 돔을 쓰지 않고 최적화하기 좋습니다.</p>
<hr>

<h2 id="가상-돔">가상 돔</h2>
<p>리액트에서도 사용되는 가상 DOM 입니다.</p>
<p>가상 DOM은 메모리 내의 DOM 트리를 표현하는 프로그래밍 개념입니다. 실제 DOM 대신 메모리에서 빠르게 변경하고 최종적으로 실제 DOM에 결과를 반영하는 방식으로 작동합니다.</p>
<p>그런데, 과연 가상 돔은 돔보다 속도가 빠를까요?</p>
<blockquote>
<p>&#39;크게 차이가 나는 것은 아니며, 개발 편의성과 대부분의 상황에서 충분히 빠르기 때문에 사용하는 것&#39; </p>
</blockquote>
<p>이라고 합니다.</p>
<p>추가적인 내용은 리액트를 공부할때 익히는 것이 좋은 것 같아, 큰 개념만 알아보고 넘어가겠습니다.</p>
<hr>

<h1 id="추가적인-내용">추가적인 내용</h1>
<br>

<h2 id="즉시-실행-함수-iife">즉시 실행 함수 (IIFE)</h2>
<p>수업에서 강사님께서 즉시 실행 함수를 사용하셔서, 이에 대해 간단히 알아보고자 합니다.</p>
<pre><code class="language-js">// 즉시 실행 함수
(function() {
    // 함수 내부의 코드
})();</code></pre>
<ul>
<li>전체 함수를 괄호 ()로 감싸고 있습니다. 이 괄호는 함수를 표현식으로 취급하게 만듭니다.</li>
<li>마지막에 있는 ()는 함수를 호출합니다. 따라서, 이 구조의 함수는 정의되자마자 바로 실행됩니다.</li>
</ul>
<p>즉시 실행 함수는 정의되자마자 바로 실행되는 JavaScript 함수입니다. 
<strong>즉시 호출하여 실행 한다는게 함수의 정의와 호출이 동시에 이루어진다는 것입니다.</strong></p>
<p>IIFE의 주요 목적은 <strong>변수와 함수를 전역 스코프로부터 격리하여 &#39;프라이빗&#39;하게 만드는 것</strong> 입니다. 
이로써 다른 코드와의 충돌 없이 코드를 모듈화하거나 라이브러리를 작성하는 데 유용하게 사용됩니다.</p>
<ul>
<li>외부 스코프에서 IIFE에 접근할 수 없습니다. 
덕분에 global namespace를 오염시키지 않고 코드를 작성할 수 있습니다.</li>
<li>하지만 인자는 받을 수 있습니다.
전역 변수를 IIFE에 받아와서 사용할 수 있습니다.</li>
</ul>
<br>

<p>좋아보이는 IIFE지만, ES6의 모듈 시스템이 도입되면서 IIFE의 사용 빈도가 줄어들었습니다. 
ES6 모듈은 기본적으로 격리된 스코프를 제공하기 때문에, 몇몇 상황에서는 IIFE 대신 모듈을 사용하는 것이 더 나을 수 있습니다.</p>
<hr>

<h2 id="깃--깃허브-브랜치-관련">깃 &amp; 깃허브 브랜치 관련</h2>
<p>스터디를 위해 깃허브에 모딥다 레파지토리를 생성했었습니다.
거기에 개인 브랜치를 파서, 해당 브랜치에 각자 공부한 내용을 작성합니다.</p>
<p>이후 작성한 내용을 메인에 머지 요청을 위해 풀 리퀘스트를 날립니다.</p>
<p>여기까지는 지난 과제를 통해 경험해보았습니다만, 본인 브랜치를 메인 브랜치 데이터로 갱신하는 방법을 몰랐습니다.</p>
<p>깃허브 데스크탑 앱에서 Fetch 버튼만 하염없이 눌렀던... ;ㅅ;</p>
<p>해서 해결 방법을 기록하고자 합니다.</p>
<ol>
<li><p>VSC - 소스제어 - etc 버튼 클릭
<img src="https://velog.velcdn.com/images/meow_tarae/post/0b9268ec-cb4e-4362-880f-8a88d92d4d44/image.png" alt=""></p>
</li>
<li><p>풀, 푸시 - 가져올 위치... 클릭
<img src="https://velog.velcdn.com/images/meow_tarae/post/0ea2e352-b1d5-4172-845e-1b0d2972d873/image.png" alt=""></p>
</li>
<li><p>갱신하고자 하는 브랜치를 선택합니다. (저는 메인 브랜치로 갱신하고 싶어, origin/main을 선택했습니다.)
<img src="https://velog.velcdn.com/images/meow_tarae/post/d4213ca0-ad28-4029-ae62-8f5aa279dd21/image.png" alt=""></p>
</li>
</ol>
<p>짜잔- VSC에 개인 브랜치 파일들은 사라지고, 메인 브랜치 파일들로 바뀌었습니다~
그런데, 잘못눌러서 기존에 작업하던 파일들이 다 날아갈 수 있다고 생각하니, 조금 무섭긴 하네요...</p>
<h2 id="후기">후기</h2>
<p>깃 &amp; 깃허브.. 아직 많이 사용해보지 않아서 낯선 존재입니다.
아시는 분이 팀플 잘못하다가 코드 싹 다 날리셨다고 하셔서.. 더욱 무서운 존재기도 합니다.
얼릉 친해지고싶다요..!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 데브코스 5기 TIL 10일차]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-6</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-6</guid>
            <pubDate>Tue, 03 Oct 2023 01:58:50 GMT</pubDate>
            <description><![CDATA[<h2 id="백트래킹">백트래킹</h2>
<ul>
<li>모든 경우의 수를 탐색하는 알고리즘이다.</li>
<li>DFS or BFS를 사용 가능하다.
(효율을 위해 탐색하지 않아도 되는 곳을 미리 막는 것이 중요한데, 이를 <strong>가지치기</strong> 라고 한다.)</li>
<li>JS는 효율성때문에 스택을 활용하는게 좋을 것 같다!</li>
<li>탐색 중 _순환_이 나타나면 BFS를 사용하자.</li>
</ul>
<hr>


<h2 id="dp">DP</h2>
<p>가장 작은 문제를 정의할 수 있다면 사용하자.</p>
<ul>
<li>작은 문제를 통해 큰 문제를 해결하는 방식</li>
<li>특정 알고리즘이 아니고, 문제 해결 방식을 의미한다.</li>
<li>메모리를 많이 사용 but 빠른 성능</li>
</ul>
<p>DP의 두가지 방법론이 있는데, 그 중 코딩테스트에 많이 사용되는 메모이제이션에 대하여 아라보자.</p>
<ul>
<li>메모이제이션<ul>
<li>하향식 접근법</li>
<li>DP에서 작은 문제들의 결과는 항상 같다.
따라서, 이 결과들을 메모리에 저장하여 필요할 때 꺼내쓰는 것이 메모이제이션이다.</li>
</ul>
</li>
</ul>
<hr>

<h2 id="후기">후기</h2>
<p>오늘은 코테 문제 2개 푸는게 전부지만, 아직 많이 부족해서인지 두 문제 모두 어떻게 풀지.. 손도 못 댔다..
꾸준히 코테 연습하다보면 괜찮아지겠지..?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 데브코스 5기 TIL 5일차]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-5%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-5%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Tue, 26 Sep 2023 17:01:32 GMT</pubDate>
            <description><![CDATA[<hr>

<h2 id="트리">트리</h2>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/53880dc7-1dca-4d90-9e79-e46da8a459ab/image.png" alt=""></p>
<ul>
<li>최하단 level의 노드를 leaf 노드라고도 부릅니다.</li>
<li>모든 노드는 하나의 부모 노드를 가집니다.</li>
</ul>
<br>

<h2 id="이진-트리">이진 트리</h2>
<p><img src="https://cdn.programiz.com/sites/tutorial2program/files/full-binary-tree_0.png" alt=""></p>
<h4 id="각-자식-노드들이-최대-2개까지-가지는-트리입니다">각 자식 노드들이 최대 2개까지 가지는 트리입니다.</h4>
<ul>
<li>마지막 레벨을 제외한 모든 노드가 채워진 <strong>완전 이진 트리</strong></li>
<li>모든 노드가 2개씩 꽉 채워진 <strong>포화 이진 트리</strong></li>
<li>한 방향으로만 나아가는 <strong>편향 트리</strong></li>
</ul>
<p>등이 있습니다.</p>
<hr>

<h2 id="우선순위-큐">우선순위 큐</h2>
<h4 id="fifo인-큐와-달리-우선순위가-높은-큐가-먼저-빠져나가는-큐-입니다">FIFO인 큐와 달리, 우선순위가 높은 큐가 먼저 빠져나가는 큐 입니다.</h4>
<p>다만, 우선순위 큐는 자료구조가 아닌 <em>개념</em> 입니다.</p>
<p>이때, 힙은 우선 순위 큐를 구현하기 굉장히 적합한 방법 중 하나입니다.</p>
<h2 id="힙">힙</h2>
<p>이진 트리 형태를 가지며, 우선순위가 높은 요소가 먼저 나가기 위해
요소가 삽입, 삭제될 때 바로 정렬되는 특징이 있습니다.</p>
<p>때문에 힙 노드 삭제시, root 노드가 먼저 빠져나갑니다.
종류는 루트가 가장 큰 값인 <strong>최대 힙</strong>, 가장 작은 값인 <strong>최소 힙</strong>이 있습니다.</p>
<hr>

<h3 id="마무리">마무리</h3>
<p>최근 코딩 테스트 문제에 상당 시간을 투자하고 있습니다.
평소 프로그래머스 lv2 문제도 겨우겨우 조금씩 해결하고 있는데, 갑자기 lv3 문제들을 해결하려니,
어려움이 없잖아 있습니다..  ;ㅅ;
언젠가는 나아지겠죠..?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 데브코스 5기 TIL 4일차]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-4%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-4%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Mon, 25 Sep 2023 13:17:42 GMT</pubDate>
            <description><![CDATA[<h1 id="queue">Queue</h1>
<h3 id="fifo-선입선출">FIFO, 선입선출.</h3>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/fe41c6a9-88aa-4453-bbdb-9f371b257e51/image.png" alt=""></p>
<p>맨 앞에 놈을 <code>Front</code>, 맨 뒤를 <code>Back (혹은 rear)</code>.
맨 앞에 값을 제거하는 것을 <code>DeQueue()</code>, 맨 뒤에 값을 추가할땐 <code>EnQueue()</code>.</p>
<p>큐를 연습해보기위해, 프로그래머스 Lv_2 문제인 [프로세스] (<a href="https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4JS-Lv-2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4">https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4JS-Lv-2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4</a>) 문제를 풀어보았습니다.</p>
<p>Linear Queue를 배열로 구현하여 풀어보았으며, Linked list로 구현하여 푸는 방법도 있었습니다.</p>
<br>

<p>Array의 경우, DeQueue()를 통한 삭제는 아래와 같은 &lt; empty item &gt;을 발생시킵니다.</p>
<pre><code class="language-js">    Queue { queue: [ &lt;1 empty item&gt;, 2, 4 ], front: 1, rear: 3 }</code></pre>
<p>때문에, 이를 없애기 위해서는 원소들을 좌측으로 이동, 즉 O(n)의 시간이 발생합니다.</p>
<p>그에 반해 Linked List는 삽입/삭제에 O(1), 상수시간만 소요되기에 배열보다는 조금 더 시간이 적게 소요됩니다.
하지만 그만큼 구현이 조금 더 복잡한 점이 있습니다.</p>
<p>+) shift() 함수는 O(n)의 시간복잡도가 소요됩니다. 
때문에 중첩 반복문에서는 사용을 지양하는 것이 좋을 것 같습니다.</p>
<hr>

<h1 id="해시-테이블">해시 테이블</h1>
<h3 id="한정된-배열-공간에-해시함수를-통해-key를-index로-변환하여-값들을-넣는-자료구조-입니다">한정된 배열 공간에, 해시함수를 통해 key를 index로 변환하여 값들을 넣는 자료구조 입니다.</h3>
<p>삽입은 O(1)이며 index를 알고있다면 삭제, 탐색도 O(1) 입니다.</p>
<h2 id="해시-함수">해시 함수</h2>
<p><code>해시 함수</code>는 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수입니다. 
이렇게 변환된 데이터를 <code>해시 값</code>이라고 합니다.</p>
<p>하지만, 서로 다른 입력값에 같은 해시 값이 나올 수 있습니다.
이러한 현상을 <code>해시 충돌</code>이라 합니다.</p>
<p>이를 해결하기위한 여러 방법들이 있습니다.</p>
<ul>
<li><p>선형 탐사법
해시 테이블에서 충돌이 발생했을 때, 충돌이 발생한 다음 빈 슬롯을 찾을 때까지 해시 테이블을 선형적으로 탐색하는 방법입니다. 즉, 충돌이 발생한 슬롯 다음부터 순차적으로 탐색하면서 빈 슬롯을 찾습니다.<br>
하지만, 선형 탐사법은 균등한 분포를 가진 해시 함수에서는 잘 동작하지만, 해시 함수의 분포가 불균등할 경우 충돌이 더 자주 발생하게 되어 해시 테이블의 성능을 저하시킬 수 있습니다. 
또한, 선형 탐사법은 클러스터링(Clustering) 현상이 발생할 가능성이 있어, 충돌이 발생한 슬롯 주변에 데이터가 밀집하게 저장되는 문제가 있습니다.</p>
</li>
<li><p>제곱 탐사법
선형 탐사법이 충돌 후 빈 슬롯을 찾기 위해 옆으로 한칸씩 움직였다면, 제곱 탐사법은 이름처럼
충돌 발생 횟수의 제곱만큼 옆으로 이동합니다.</p>
</li>
<li><p>이중 해싱
충돌이 발생하면 기존 해시 함수가 아닌, 다른 해시 함수를 사용하는 방법입니다.</p>
</li>
<li><p>분리 연결법
출돌 지점에 Linked List를 만들어, 충돌이 일어난 index에 값을 저장하게 됩니다.
다만, 이 경우 버킷이 무한히 늘어날 수 있습니다.</p>
</li>
</ul>
<hr>

<h1 id="그래프">그래프</h1>
<h3 id="비선형-자료구조로써-edge들과-node들로-이루어져-있습니다">비선형 자료구조로써, edge들과 node들로 이루어져 있습니다.</h3>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/2c87cab9-ce51-4838-907a-5537ec613579/image.png" alt=""></p>
<p>그래프의 특징으로는</p>
<ul>
<li><p>정점은 여러개의 간선을 가질 수 있습니다.</p>
</li>
<li><p>간선은 가중치를 가질 수 있습니다.
ex ) 지하철에서 
동대구역 - 동구청역은 1분이지만
동대구역 - 신천역은 2분으로, 가중치(소요 시간)가 서로 다릅니다.</p>
</li>
<li><p>사이클이 발생할 수 있습니다.
(사이클 == 탐색시 계속 루프가 가능한 구역을 뜻합니다.)</p>
</li>
</ul>
<br>

<h3 id="그래프-구현-방법">그래프 구현 방법</h3>
<ol>
<li>인접 행렬</li>
<li>인접 리스트</li>
</ol>
<hr>

<h2 id="후기">후기</h2>
<p>오늘부터 약간 코딩테스트 준비를 위한 알고리즘 수업인 것 같다.
잘 들어서 나중에 코테 때문에 발목 잡히는 일 없게끔 해야지.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 / JS] Lv 2 프로세스]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4JS-Lv-2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4JS-Lv-2-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4</guid>
            <pubDate>Mon, 25 Sep 2023 08:51:15 GMT</pubDate>
            <description><![CDATA[<h2 id="후기">후기</h2>
<p>처음 문제를 풀 땐 잘 몰랐지만, 배열에서 shift() 사용을 지양하는게 좋은 것 같다.
shift()는 선형시간이 소요되므로, 코드 실행속도에 크게 영향을 줄수도 있는 것이 그 이유이다.
풀어보진 않았지만 팀원분의 말씀으로는, 백준에는 shift()를 사용하면 실패 처리되는 문제도 있다고 한다.</p>
<p>때문에 class로 queue를 배열로 구현하는 방법으로 문제를 풀어보았다.</p>
<p>중간에 dequeue() 메서드에 의해 queue 배열 내부에서 Empty Itmes를 만들어내지만,
front와 rear를 활용했기도 하고, 크게 배열 내부 메모리에 신경쓰지않아도 된다면 괜찮은 것 같다.</p>
<hr>

<h2 id="코드">코드</h2>
<pre><code class="language-js">class Queue {
  constructor() {
    this.queue = [];
    this.front = 0;
    this.rear = 0;
  }

  enqueue(value) {
    this.queue[this.rear++] = value;
  }

  dequeue() {
    const value = this.queue[this.front];
    delete this.queue[this.front];
    this.front++;
    return value;
  }

  peek() {
    return this.queue[this.front];
  }
}

function solution(priorities, location) {
    const myQueue = new Queue();
    for (let i = 0; i &lt; priorities.length; i++) {
        myQueue.enqueue([priorities[i], i]);
    }

    priorities.sort((a, b) =&gt; b - a);

    let count = 0;

    while (1) {
        const currentValue = myQueue.dequeue();
        if (currentValue[0] &lt; priorities[count]) {
            myQueue.enqueue(currentValue);
        } else {
            count++;
            if (currentValue[1] === location) break;
        }
    }
    return count;    
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 데브코스 5기 TIL 3일차]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-3%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-3%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Sun, 24 Sep 2023 01:58:35 GMT</pubDate>
            <description><![CDATA[<h2 id="자료구조와-알고리즘">자료구조와 알고리즘</h2>
<ul>
<li>자료구조 : 빠르고 안정적으로 데이터를 처리하는 것이 궁극적인 목표!</li>
<li>알고리즘 : 문제를 효율적이고 빠르게 해결하는것이 목표이며, 정해진 방법을 공식화한 형태로 표현합니다.</li>
</ul>
<hr>

<h2 id="문제해결-능력의-핵심-3가지">문제해결 능력의 핵심 3가지</h2>
<ol>
<li>논리적 사고 : 해결 방법 절차가 말이 되는지 ?</li>
<li>전산화 능력 : 컴퓨터적 사고가 가능한지 ?</li>
<li>Edge Case Search : 예외처리를 얼마나 잘 생각 해내는지 ?</li>
</ol>
<hr>

<h2 id="자료구조">자료구조</h2>
<h3 id="자료구조는-단순-구조-선형-구조-비선형-구조가-있습니다">자료구조는 단순 구조, 선형 구조, 비선형 구조가 있습니다.</h3>
<ul>
<li><p>단순 구조 
정수, 실수, 문자열 등이 있습니다.</p>
</li>
<li><p>선형 구조 
데이터 항목 간에 하나의 선행자와 하나의 후행자가 있습니다만,
예시로는 Array, Linked List, Stack, Queue 등이 있습니다.</p>
</li>
<li><p>비선형 구조 
항목이 여러 개의 선행자 또는 후행자를 가질 수 있습니다.
예시로는 Graph, Tree 등이 있습니다.</p>
</li>
</ul>
<hr>

<h2 id="배열">배열</h2>
<p>어떤 배열에 값을 추가하려고 합니다.</p>
<pre><code class="language-js">ㅁㅁㅁㅁㅁ 
// 위 배열에 2번 index에 0 을 추가해보겠습니다.

ㅁㅁ0ㅁㅁㅁ

//이때, 2번 index부터 arr.at(-1)까지의 원소들이 모두 오른쪽으로 한 칸 이동합니다.</code></pre>
<p>이처럼 배열의 삽입은 시간복잡도 O(n)가 소요됩니다.</p>
<p>위 배열에서 0을 제거한다면, 0 이후의 모든 원소들이 이번에는 왼쪽으로 한 칸 이동합니다.
배열 요소 삭제도 마찬가지로 시간복잡도 O(n)가 소요됩니다.</p>
<p>한 번에 O(n)의 시간이 소요되니, 반복문 내부에서 배열 요소의 삽입/삭제가 일어난다면, 
많은 시간이 소요될 것 같습니다.</p>
<p>그렇기 때문에 배열보다는 다른 자료구조를 사용하는 것이 좋아보이는데요.
이때 사용하면 좋은 Linked List가 있습니다.</p>
<h2 id="linked-list">Linked List</h2>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/bec5565d-0200-48f7-9fe9-27fd104a83aa/image.jpeg" alt="">
Linked list의 경우 삽입/삭제의 시간복잡도가 O(1), 상수시간이 소요됩니다.
다만, 탐색은 O(n)입니다. </p>
<p>배열의 경우 연속적인 메모리 공간에 원소를 저장하지만,
Linked list는 연속적인 메모리 공간에 값을 저장하진 않습니다.
각 요소가 데이터와 다음 요소를 가리키는 포인터(참조)로 이루어져 있기에, 굳이 연속적으로 있지는 않습니다. <br>
때문에 배열의 경우, index를 안다면 상수시간이 소요되겠지만
Linked List의 경우, 원하는 요소를 찾기 위해 처음부터 순회해야하고, 이에 시간복잡도가 O(n)가 소요됩니다.</p>
<hr>

<h3 id="olog-n">O(log n)</h3>
<p>Big-O 에 관한 내용 중, O(log n)은 아래와 같은 상황에서~</p>
<pre><code class="language-js">    for(let i=0; i&lt;n; i *= 2) { ~ }
    // 2를 계속 곱해가는 상황.</code></pre>
<hr>


<h2 id="과제">과제</h2>
<p>Linked list 구현
<a href="https://velog.io/@meow_tarae/JS-Linked-List-%EA%B5%AC%ED%98%84-%EC%97%B0%EC%8A%B5">https://velog.io/@meow_tarae/JS-Linked-List-%EA%B5%AC%ED%98%84-%EC%97%B0%EC%8A%B5</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JS Linked List 구현 연습]]></title>
            <link>https://velog.io/@meow_tarae/JS-Linked-List-%EA%B5%AC%ED%98%84-%EC%97%B0%EC%8A%B5</link>
            <guid>https://velog.io/@meow_tarae/JS-Linked-List-%EA%B5%AC%ED%98%84-%EC%97%B0%EC%8A%B5</guid>
            <pubDate>Sun, 24 Sep 2023 01:57:14 GMT</pubDate>
            <description><![CDATA[<h2 id="linked-list란">Linked List란?</h2>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/0f426029-d4da-4cf5-b85d-a84f16436330/image.png" alt=""></p>
<p>위 사진과 같이, 노드들이 서로 연결되어있는 자료구조입니다.
<a href="https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-3%EC%9D%BC%EC%B0%A8">참고</a>
(사진 출처: GeeksforGeeks)</p>
<hr>

<h2 id="구현">구현</h2>
<p><img src="https://velog.velcdn.com/images/meow_tarae/post/c6062bfe-b3dd-4009-90af-f814cd04e6e6/image.png" alt=""></p>
<hr>

<h3 id="확인">확인</h3>
<pre><code class="language-js">const myLinkedList = new SingleLinkedList();
myLinkedList.append(1);
myLinkedList.append(2);
myLinkedList.append(3);
myLinkedList.append(5);
myLinkedList.display();
// 
┌─────────┬────────┐
│ (index) │ Values │
├─────────┼────────┤
│    0    │   1    │
│    1    │   2    │
│    2    │   3    │
│    3    │   5    │
└─────────┴────────┘

console.log(myLinkedList.find(3));
// Node { value: 3, next: Node { value: 5, next: null } }

myLinkedList.remove(3);
myLinkedList.display();
// 
┌─────────┬────────┐
│ (index) │ Values │
├─────────┼────────┤
│    0    │   1    │
│    1    │   2    │
│    2    │   5    │
└─────────┴────────┘

myLinkedList.insert(myLinkedList.find(2), 10);
myLinkedList.display();
//
┌─────────┬────────┐
│ (index) │ Values │
├─────────┼────────┤
│    0    │   1    │
│    1    │   2    │
│    2    │   10   │
│    3    │   5    │
└─────────┴────────┘</code></pre>
<hr>


<h3 id="후기">후기</h3>
<ol>
<li><p>항상 <code>console.log()</code>만 사용했는데, <code>console.error()</code>, <code>console.table()</code>등이 있다는 사실을 알게되었다.</p>
</li>
<li><p>프로퍼티인 _size와 메서드인 size, 모두 같은 이름인 size로 하면 안되는 것을 알게되었다.
<code>_size</code>와 <code>size()</code> 메서드를 모두 <code>size</code>로 이름을 변경하면, <code>size()</code> 메서드를 호출할 때 <code>this.size</code>가 <code>size()</code> 메서드를 가리키게 된다. 이는 <code>size()</code> 메서드를 무한히 재귀적으로 호출하게 되어 스택 오버플로우 에러가 발생한다.</p>
</li>
<li><p>console.log()는 값을 출력 후, <code>undefined를 리턴</code>하는 것을 알게되었다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 데브코스 5기 TIL 2일차]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-2%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-2%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Thu, 21 Sep 2023 18:26:51 GMT</pubDate>
            <description><![CDATA[<h2 id="네트워크-기초">네트워크 기초</h2>
<p>주소창에 url을 입력하면, 잠시 로딩 후 해당 페이지로 이동하게 됩니다.
이때, 잠시 로딩하는 동안 어떤 일이 일어나고 있는걸까요 ?<br></p>
<ol>
<li>URL을 해석합니다.</li>
</ol>
<ol start="2">
<li><p>DNS (Domain Name System) 조회</p>
<p>DNS는 도메인과 IP주소를 서로 변환해줍니다.</p>
<pre><code> 헷갈리는 단어인, 도메인과 IP주소에 대하여 알아보겠습니다.

 도메인 : 웹사이트의 이름과 주소입니다.
 사람이 읽을 수 있는 주소로, IP 주소를 사람이 기억하기 쉽게 만든 것입니다. 
 일반적으로 &quot;www.naver.com&quot;과 같은 형식을 가집니다.

 IP주소 : 인터넷 프로토콜 (IP)에서 컴퓨터, 서버 또는 장치를 고유하게 식별하는 숫자로 된 라벨입니다.
 일반적으로 IPv4 로써 네 개의 숫자 블록으로 구성되며, 데이터 패킷이 올바른 위치로 전송되도록 돕습니다.

</code></pre></li>
</ol>
<ol start="3">
<li>해당 IP가 존재하는 서버로 이동합니다.<br> </li>
<li>ARP을 이용해 MAC 주소 변환을 합니다.</li>
</ol>
<pre><code>    여기서 IP주소와 MAC 주소는 각각 논리주소와 물리주소 입니다.
    MAC 주소는 기계의 실제 위치를 알기위해 필요합니다.
    그리고 ARP는 논리주소를 물리주소로 변환해주는 역할을 하는 프로토콜입니다.

    여기서, 왜 논리주소와 물리주소를 구분하는 것일까요?
    청와대를 기준으로 
       - 논리주소: &#39;서울 종로구 청와대로 1&#39;
       - 물리주소: &#39;위도와 경도&#39; 등으로 나타낼 수 있습니다.

    택배를 보낸다고 가정하면, 논리주소만 봐서는 정확한 위치를 알기 어렵습니다.
    표기 체계가 바뀐다거나 하는 경우도 생길 수 있으니까요.
    그래서 물리주소가 필요합니다.

    또한 위 주소에서 각 도시들 중 서울을 먼저 선택합니다. 
    이후에 종로구, 청와대로, 1번지를 선택하듯 
    논리주소는 대역을 통해 범위를 좁혀나갑니다.</code></pre><ol start="5">
<li>TCP 통신을 통해 Socket을 열어야 합니다.</li>
<li>서버는 응답을 반환합니다.</li>
<li>브라우저는 렌더링 합니니다.</li>
</ol>
<blockquote>
</blockquote>
<p>추가적으로, HTTP가 이미 있음에도, HTTPS는 왜 탄생했는지, 왜 필요한지 알아보겠습니다.</p>
<blockquote>
</blockquote>
<p>HTTPS는 HTTP에 SSL/TLS 암호화 계층을 추가하여 통신을 보호합니다.</p>
<blockquote>
</blockquote>
<p>HTTPS를 사용함으로써</p>
<ol>
<li>데이터의 기밀성</li>
<li>데이터의 무결성</li>
<li>쿠키 및 세션 보호
등을 얻을 수 있다는 장점이 있습니다.<blockquote>
</blockquote>
또한, 클라이언트와 서버 간에 통신을 시작할 때, 암호화된 연결을 설정하기 위해 
SSL/TLS 핸드셰이크가 발생합니다.
이는 클라이언트와 서버 간의 안전한 연결을 초기화하고 설정하는 과정입니다. 
이 과정에서 양쪽 모두 통신에 사용될 암호화 알고리즘과 키를 협상하며, 서버의 신원을 검증합니다.</li>
</ol>
<hr>

<h2 id="암호화">암호화</h2>
<h3 id="단방향-암호화와-양방향-암호화">단방향 암호화와 양방향 암호화</h3>
<ul>
<li><p>단방향 암호화 ?
한 방향으로 암호화해서 보내는 방법입니다.
따라서 원본 데이터를 복구할 수 없는 방식으로 변환합니다.
이러한 특성 때문에, 주로 패스워드와 같은 민감한 데이터를 보관할 때 사용합니다. <br>
하지만 이러한 단방향 암호화는, 동일한 메시지에 동일한 다이제스트를 갖게 됩니다.
오늘 a를 해쉬해도, 내일 a를 해쉬해도 같은 결과값이 나온다는 뜻입니다.
이 경우, 해커들이 여러 값들을 대입해보면서 얻었던 다이제스트들을 모아놓은 리스트인, 
레인보우 테이블에 우리의 소중한 데이터가 해커들의 손에 넘어갈 수 있습니다. <br>
이를 방지하기 위해 salt, key stretching 방식 등으로 해시 함수를 보완하곤 합니다.</p>
<br>
</li>
<li><p>양방향 암호화 ?
암호화된 데이터에 대한 복호화가 가능한 암호화 방식.
대표적으로 대칭키, 공개키 암호화 방식이 있습니다.</p>
<ul>
<li>대칭키
대칭키는 암복호화키가 동일하며, 해당 키를 아는 사람만이 문서를 복호화해 볼 수 있게 합니다.</li>
<li>공개키
키가 공개되어있기 때문에, 키를 교환할 필요가 없어집니다.
공개키는 모든 사람이 접근 가능한 키이고, 개인 키는 각 사용자만이 가지고 있는 키 입니다.</li>
</ul>
</li>
</ul>
<hr>

<h2 id="함수형-프로그래밍">함수형 프로그래밍</h2>
<h3 id="함수형-프로그래밍-">함수형 프로그래밍 ?</h3>
<p>데이터를 한 함수에서 다음 함수로 전달하여 데이터를 가공하고, 
이러한 일련의 함수 호출을 통해 새로운 데이터를 만드는, _데이터 파이프라인 형태_로 프로그램이 작동합니다</p>
<p>객체지향에서는 추상화의 최소 단위가 객체! 함수형은 최소단위가 <strong>함수</strong>입니다. 
때문에 함수형이 재사용성이 높다는 장점이 있습니다.</p>
<p>또한, 함수형은 <strong>불변성</strong>을 지향합니다.
이에 <strong>Side Effect</strong>를 최소화하거나 제어할 수 있고, <strong>동작을 예측하기 용이</strong>합니다.</p>
<pre><code class="language-js">// 예를 들어
const str = &#39;123&#39;;
// str의 각 숫자의 합인 6을 함수형으로 구해보겠습니다.

console.log(
  str
    .split(&quot;&quot;)
    .map((v) =&gt; +v)
    .reduce((a, b) =&gt; a + b, 0)
);</code></pre>
<br>

<h4 id="물론-함수형에도-단점은-있습니다">물론 함수형에도 단점은 있습니다.</h4>
<p>데이터의 불변성 때문에, </p>
<pre><code>a = a + 1;</code></pre><p>와 같은 단순한 계산도 데이터를 변경하는 대신, 새로운 데이터를 생성하여 반환하는 방식을 사용합니다.
이는 불필요한 메모리 낭비가 발생할 수 있습니다.
또한 재사용성이 높다는 것은 함수를 잘게 쪼갠다는 뜻이고, 코드가 복잡해질 수 있다는 단점이 있습니다.</p>
<h4 id="그렇다면-둘-중-js는-어떤-방식을-사용할까요-">그렇다면 둘 중 JS는 어떤 방식을 사용할까요 ?</h4>
<p>둘 다 입니다. JS는 함수형 + 객체형인 멀티 패러다임이 가능하니, 둘 다 사용하는 것이 좋을 것 같습니다.
<br><br></p>
<h3 id="명령형-프로그래밍-vs-선언형-프로그래밍">명령형 프로그래밍 vs 선언형 프로그래밍</h3>
<ul>
<li>명령형 프로그래밍 : <strong>어떻게(How)</strong> 작업을 수행할 것인지를 명시하는 방식입니다.</li>
<li>선언형 프로그래밍 : <strong>무엇(What)</strong>을 얻고자 하는지를 명시하고, 시스템은 <strong>어떻게(How)</strong> 그 목표를 달성할지를 처리합니다.</li>
</ul>
<hr>

<h2 id="객체지향과-프로토타입">객체지향과 프로토타입</h2>
<blockquote>
</blockquote>
<h3 id="객체지향의-객체는-현실_에-있는-것을-_추상화-한-것-">객체지향의 객체는 <em>현실_에 있는 것을 _추상화</em> 한 것 !</h3>
<h3 id="이때-추상이란-사물이-지니고있는-여러-측면-중-_특정한-부분_만-보는-것">이때 추상이란, 사물이 지니고있는 여러 측면 중 _특정한 부분_만 보는 것</h3>
<p>마치 지구본을 펼친 평면지도를 보는 것 처럼 
(구체를 펼친 것이기에 손실이 있는~)</p>
<h3 id="prototype">Prototype</h3>
<p>부모 유전자를 상속받는 것과 유사하다고 생각합니다.</p>
<p>우선, 간단한 예시를 보겠습니다.</p>
<pre><code class="language-js">function Person(name, age){
    this.name = name;
    this.age = age;

     this.getName = function() {
      return this.name;
    }
       this.getAge = function() {
      return this.age;
    }
}

const me = new Person(&#39;bgh&#39;, 1);
console.log(me);
/*    
    이때, 출력된 me 값은 , 다음과 같습니다.
    Person {
      name: &#39;bgh&#39;,
      age: 1,
      getName: [Function (anonymous)],
      getAge: [Function (anonymous)]
    }
       당장 필요하지않은 메서드들까지 포함되어, 메모리 낭비가 되고 있습니다.
*/</code></pre>
<p>프로토타입은 위와 같은 문제를 해결할 수 있습니다.</p>
<pre><code class="language-js">    this.getName = function() {
      return this.name;
    }
    // 위 코드를 아래와같이

    Person.prototype.getName = function() {
      return this.name;
    }</code></pre>
<p>이제 me는 Person {name: &#39;bgh&#39;, age: 1} 값만을 가지게 됩니다.
또한 프로토타입 체인으로 연결된 하위 자식들은, 부모의 부모가 (혹은 그 이상) 가진 프로토타입을 사용할 수 있습니다.</p>
<hr>

<h2 id="쿠키와-세션-웹-스토리지">쿠키와 세션, 웹 스토리지</h2>
<p>HTTP Request는 기본적으로 상태가 존재하지 않아, 서버는 어떤 브라우저에서 온 것인지 기억을 하지 못합니다.
따라서 헤더에 쿠키를 담아 보내고 있습니다.
(이때 쿠키는 브라우저를 닫더라도 로그인 정보가 남아있는 등을 도와주는, 데이터를 유지할 수 있게끔 도와주는 역할을 합니다.)</p>
<p>사실 클라이언트가 쿠키를 서버에다 보내도, 서버는 쿠키 주인을 모릅니다...
때문에 세션을 추가해서 보냅니다.
쿠키에 HTTP Session ID를 식별자로 넣어 보냅니다.</p>
<p>이외에도 새로운 표준으로 나타난 <strong>웹 스토리지</strong>가 있습니다.
웹 스토리지는 클라이언트 사이드에서 Key-Value 형태로 데이터를 안전하게 저장할 수 있게 도와주는 웹 API로써, 쿠키 대신 로컬 데이터를 관리해줍니다.</p>
<p>웹 스토리지는 로컬 스토리지와 세션 스토리지로 구분됩니다.</p>
<ul>
<li>로컬 스토리지 : 데이터를 반영구적으로 저장하고싶을때 유용합니다.
또한 저장한 도메인과 이용하는 도메인이 다르면 접근할 수 없다는 특징이 있습니다.</li>
<li>세션 스토리지 : 새 창 or 새 탭마다 개별적으로 데이터를 관리하며, 브라우저를 닫으면 사라집니다.
또한 세션이 서로 다르다면 데이터에 접근할 수 없다는 특징이 있습니다.</li>
</ul>
<p>웹 스토리지는 쿠키보다 훨씬 큰 데이터를 저장할 수 있으며, 데이터를 클라이언트 사이드에 저장하기에 서버에 추가적인 부하를 줄일 수 있습니다. 
(쿠키와 세션의 경우 서버의 파일에 저장되는데, 수천 수만명의 접속자가 서버에 접속한다면 서버는 큰 부하를 겪게되는 단점이 있습니다.)</p>
<hr>

<h2 id="후기">후기</h2>
<p>깊게 파고들면 끝도 없는 내용들이다보니, 얕게만 공부하려해도 굉장히 오래 걸리는 것 같습니다 ;ㅅ;
주말 이용해서 조금 더 공부해보며 익숙해지기위해 노력하겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프론트엔드 데브코스 5기 TIL 1일차]]></title>
            <link>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-1%EC%9D%BC%EC%B0%A8</link>
            <guid>https://velog.io/@meow_tarae/%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-5%EA%B8%B0-TIL-1%EC%9D%BC%EC%B0%A8</guid>
            <pubDate>Wed, 20 Sep 2023 14:34:19 GMT</pubDate>
            <description><![CDATA[<h1 id="node-버전-설정">Node 버전 설정</h1>
<blockquote>
<p>강의는 LTS인 18버전으로 진행되기에, 기존에 사용하던 버전에서 업데이트 했습니다.</p>
</blockquote>
<pre><code>nvm i 원하는버젼</code></pre><p>이후 node -v를 통해 버전을 확인해보니, 자동으로 설치한 버전으로 변경되어있었습니다.</p>
<p><br><hr></p>
<h1 id="배운-내용들">배운 내용들</h1>
<br>

<h2 id="브라우저-동작-원리">브라우저 동작 원리</h2>
<blockquote>
</blockquote>
<p>간단하게 통신, 렌더링, 스크립트 실행으로 구분됩니다.</p>
<ul>
<li>통신<ul>
<li>요청 및 응답: 사용자가 주소 표시줄에 URL을 입력하거나 링크를 클릭하면, 브라우저는 해당 웹 서버에 HTTP 또는 HTTPS 요청을 보냅니다.</li>
<li>서버 처리: 요청이 웹 서버에 도달하면 서버는 필요한 자원(HTML, CSS, JavaScript, 이미지 등)을 찾거나 생성하여 응답으로 보냅니다.</li>
<li>데이터 전송: 서버는 해당 데이터를 응답으로 브라우저에 전송하며, 브라우저는 이 데이터를 받아들여 처리합니다.</li>
</ul>
</li>
<li>렌더링<ul>
<li>HTML 및 CSS 파싱: 브라우저는 받은 HTML을 파싱하여 DOM (Document Object Model) 트리를 구축하고, CSS를 파싱하여 CSSOM (CSS Object Model) 트리를 구축합니다.</li>
<li>렌더 트리 생성: DOM과 CSSOM 트리를 결합하여 렌더 트리를 만듭니다. 렌더 트리는 화면에 표시되어야 할 내용만 포함합니다.</li>
<li>레이아웃: 렌더 트리의 각 노드에 대해 그 위치와 크기를 계산하는 과정입니다. 이를 통해 각 요소의 화면에서의 정확한 위치가 결정됩니다.</li>
<li>페인팅: 레이아웃 단계에서 결정된 위치와 크기 정보를 사용하여 실제 픽셀로 화면에 그리는 과정입니다.</li>
</ul>
</li>
<li>스크립트 실행<ul>
<li>JS 파싱 및 실행: 브라우저는 HTML 파싱 중에 <script> 태그를 만나면 파싱을 일시 중지하고 JavaScript를 파싱 및 실행합니다 (이는 async 및 defer 속성의 사용으로 변경될 수 있습니다).</li>
<li>DOM 및 JavaScript 상호 작용: JavaScript는 DOM API를 사용하여 웹 페이지의 요소에 접근하고 수정할 수 있습니다. 이를 통해 동적인 웹 페이지 효과와 상호 작용이 가능합니다.</li>
<li>이벤트 리스너: 사용자의 행동(클릭, 스크롤 등)에 반응하기 위해 JavaScript에서 이벤트 리스너를 추가할 수 있습니다. 이 리스너는 특정 이벤트가 발생할 때 실행될 함수를 지정합니다. <br>
이외에도<ol>
<li><a href="https://d2.naver.com/helloworld/59361">https://d2.naver.com/helloworld/59361</a>  </li>
<li><a href="https://ko.wikipedia.org/wiki/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8">https://ko.wikipedia.org/wiki/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8</a></li>
<li><a href="https://poiemaweb.com/js-browser">https://poiemaweb.com/js-browser</a>
위 사이트에서 추가적으로 공부할 수 있는 것 같습니다!
오늘 하루만에 공부를 끝낼 수 있는 내용은 아니니, 조금씩 공부 해야겠습니다. </li>
</ol>
</li>
</ul>
</li>
</ul>
<h2 id="호이스팅">호이스팅</h2>
<blockquote>
</blockquote>
<p>  호이스팅은 JS에서 실행 컨텍스트가 생성될 때, 변수 및 함수 선언에 사용된 식별자들을, 미리 메모리에 저장하는 동작을 의미합니다. <br>
  이때, let과 const는 호이스팅되지만 다르게 동작합니다.
  let과 const로 선언된 변수도 호이스팅되지만, 얘네에겐 임시 사각 지대(Temporal Dead Zone, TDZ)라는 것이 있습니다. 이는 변수가 선언되기 전의 코드 영역을 의미하며, 이 지대에서 변수에 접근하려고 하면 ReferenceError가 발생합니다.</p>
<pre><code class="language-js">  console.log(bar); 
  // ReferenceError: Cannot access &#39;bar&#39; before initialization
let bar = 5;</code></pre>
<p>var로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어져 문제가 없지만,
  let과 const는 선언 단계와 초기화 단계가 분리되어 진행되기 때문입니다.</p>
<h2 id="메모리-관련">메모리 관련</h2>
<blockquote>
<p>JS 엔진이 가지는 가상 머신은 메모리 모델을 구현하고 있습니다.
  각각 Heap, Call Stack이며 Heap은 참조 타입을, Call Stack은 원시 타입을 관리합니다.</p>
</blockquote>
<pre><code class="language-js">  const a = 10;
  const b = 20;
  // 식별자 a, b는 메모리 주소값과 값이 순차적으로 Call Stack에 쌓이게 됩니다.
  const arr = [1,2,3];
  // 배열 그리고 객체도 마찬가지로 Call stack에 쌓이지만,
  // 값에 해당하는 부분은 Heap에 생성된 배열 영역의 메모리 주소를 참조하게 됩니다.</code></pre>
<p>  Heap의 경우, 메모리가 필요에 따라 동적으로 변경됩니다.
  때문에 const로 선언한 식별자 arr에 push()와 같은 함수로 값을 추가할 수 있습니다.
  Call Stack에 할당된 메모리는 변경할 수 없습니다.</p>
<h2 id="가비지-컬렉터">가비지 컬렉터</h2>
<blockquote>
</blockquote>
<p>  JAVA처럼, JS에도 가비지 컬렉터가 존재하여 메모리 누수와 관련된 오류를 줄여주고 있습니다. <br>
  가비지 컬렉션은 Mark & Sweep 알고리즘을 사용합니다.
최상단 Window 객체에서부터, DOM 트리를 타고 쭈욱 내려오며 참조되는 것들에 Mark를 합니다.
  이때 가지에 연결되지 않는, 즉 참조되지 않은 객체는 "접근 불가능"하다고 간주됩니다.
  이러한 접근 불가능한 객체를 메모리에서 해제하는데, 이를 Sweep 방식이라 부릅니다.<br>
  그럼 가비지 컬렉터는 언제 작동할까요?
   객체가 접근 불가능하게 되는 시점에서 즉시 실행되는 것은 아닙니다.
  주기적으로, 혹은 메모리가 부족할때 등 엔진에 따라 다양한 방식과 상황에 작동합니다.<br>
가비지 컬렉터는 한계와 문제점도 있습니다.</p>
<ul>
<li>불필요한 객체의 참조:<ul>
<li>객체가 필요 없어지더라도 그 객체에 대한 참조가 계속 유지되면 가비지 컬렉터는 그 객체를 메모리에서 제거하지 않습니다.
이는 의도치 않은 메모리 누수를 초래할 수 있습니다.</li>
</ul>
</li>
<li>가비지 컬렉션 비용:<ul>
<li>가비지 컬렉션 동작은 CPU 자원을 사용합니다. 따라서 큰 애플리케이션에서는 가비지 컬렉션의 비용이 큰 문제가 될 수 있습니다.
가비지 컬렉션이 실행되면 애플리케이션의 실행이 일시 중단될 수 있고, 이는 특히 실시간 성능이 중요한 게임이나 그래픽스 헤비 애플리케이션에서 문제가 될 수 있습니다</li>
</ul>
</li>
</ul>
<h2 id="클로저">클로저</h2>
<blockquote>
</blockquote>
<p>  외부 함수보다 중첩 함수가 더 오래 유지되는 경우, 중첩 함수는 이미 생명 주기가 종료한 외부 함수의 변수를 참조할 수 있다. 이러한 중첩 함수를 클로저(closure)라고 부른다.<br>
  사실 클로저를 til에 적기에는, 난이도도 높고 분량을 많이 잡아먹어 나중에 주제 정리할 때 자세히 기록하겠습니다. 오늘은 간단하게만 작성하고 넘어가겠습니다.<br>
아래는  클로저를 사용하여 정보 은닉을 구현한 코드입니다.
  정보 은닉은 사용자나 다른 시스템 요소로부터 특정 데이터나 구현 세부 사항을 숨기는 것을 의미합니다. </p>
<pre><code class="language-js">  // 카운트 상태 변수
let num = 0;
// 카운트 상태 변경 함수
const increase = function () {
  // 카운트 상태를 1만큼 증가 시킨다.
  return ++num;
};
console.log(increase()); // 1
console.log(increase()); // 2
console.log(increase()); // 3</code></pre>
<h2 id="자투리">자투리</h2>
<blockquote>
</blockquote>
<ol>
<li>NaN과 Infinity 모두 Number 타입이다.<ol start="2">
<li>Control Flow vs Data Flow ?</li>
</ol>
<ul>
<li>Control Flow : 조건문, 반복문, 함수 호출 등에 의해 결정되는 프로그램 내부의 실행 순서나 방향.</li>
<li>Data Flow : 프로그램 내에서 데이터가 어떻게 이동하고, 변환되며, 저장되는지를 설명.
어떤 array 변수에 filter나 forEach등을 통해 변경되기도 합니다.<br>
Control Flow은 프로그램의 로직과 실행 순서를 결정하고, Data Flow은 프로그램 내에서 정보가 어떻게 처리되는지를 결정합니다.</li>
</ul>
</li>
</ol>
<hr><br>


<h2 id="마치며">마치며</h2>
<p>  처음으로 작성하는 TIL인지라, 많이 부족한 면을 느꼈습니다.
  다른분들 TIL 작성하시는 것을 많이 보고 배우며 개선해나가겠습니다.</p>
]]></description>
        </item>
    </channel>
</rss>