<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>just_do.log</title>
        <link>https://velog.io/</link>
        <description>안녕하세요, 프론트엔드 개발자가 될 열정적인 사람입니다.</description>
        <lastBuildDate>Mon, 11 Dec 2023 08:05:27 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>just_do.log</title>
            <url>https://velog.velcdn.com/images/just_do/profile/434bc35a-504b-4b99-a82c-d46bbeb8a596/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. just_do.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/just_do" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[프로젝트 회고] OHNOLZA 숙박 예약 서비스 - 백엔드 개발자와 첫 협업]]></title>
            <link>https://velog.io/@just_do/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0-OHNOLZA-%EC%88%99%EB%B0%95-%EC%98%88%EC%95%BD-%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%99%80-%EC%B2%AB-%ED%98%91%EC%97%85</link>
            <guid>https://velog.io/@just_do/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0-OHNOLZA-%EC%88%99%EB%B0%95-%EC%98%88%EC%95%BD-%EC%84%9C%EB%B9%84%EC%8A%A4-%EB%B0%B1%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EC%99%80-%EC%B2%AB-%ED%98%91%EC%97%85</guid>
            <pubDate>Mon, 11 Dec 2023 08:05:27 GMT</pubDate>
            <description><![CDATA[<p>배포 주소 : <a href="https://dashing-tiramisu-cbdade.netlify.app">https://dashing-tiramisu-cbdade.netlify.app</a>
깃허브 : <a href="https://github.com/TeamOHJO/Frontend">https://github.com/TeamOHJO/Frontend</a>
개발 기간 : 2023.11.20~2023.11.30</p>
<h1 id="1-개요">1. 개요</h1>
<p>벌써 [야놀자 x 패스트캠퍼스 부트캠프] 과정을 통해 진행된 세 번째 프로젝트가 끝이 났다. 이번 프로젝트는 전 프로젝트들과 다르게 백엔드 개발을 공부 중인 분들과 함께 협업을 통해 진행됐고 개발 인원은 총 <strong>프론트 5명 백엔드 4명</strong>으로 구성되었다. 짧은 기간 동안 백엔드 분들과 협업하며 배운 새로운 경험들과 지난 프로젝트의 경험들을 녹여 초기 단계부터 단단한 웹앱을 만들기 위해 노력한 내용들을 이번 글에 기록하고자 한다.
<img src="https://velog.velcdn.com/images/just_do/post/602bb989-4d2f-4848-982c-51f6e5155ce5/image.png" alt=""></p>
<h1 id="2-단단한-웹앱을-만들기-위한-노력">2. 단단한 웹앱을 만들기 위한 노력</h1>
<p>이번 프로젝트의 목표는 단단한 웹을 만드는 것이었다. </p>
<p>그럼 어떤 웹이 단단한 웹일까? 내가 생각한 단단한 웹은 사이드 이펙트를 최소화하고 부드러운 사용자 경험을 제공하는 웹이 단단한 웹이라고 생각했다. </p>
<p>팀원들도 모두 입을 모았고 단단한 웹을 만들기 위한 고민을 시작했다. 가장 먼저 기획이 탄탄해야 했으며 주어진 기간이 짧아 시간을 어떻게 분배할지도 매우 중요하게 여겨졌다. 그래서 우리는 2주의 시간 중 4일을 기획과 디자인(PM이 따로 없었기 때문에 프론트엔드 개발자들이 기획, 디자인을 맡았다) 그리고 스택 설정에 시간을 쓰고 남은 기간 동안 개발에 집중했다.</p>
<p>결론적으로 단단한 기획과 소통을 통해 개발을 하는 동안 기획이 바뀔 일이 거의 없어 개발 기간에 개발 외의 비용이 최소화 되어 오히려 개발 기간이 단축되는 효과를 봤다.</p>
<h2 id="2-1-요구사항-분석">2-1. 요구사항 분석</h2>
<p>프로젝트 시작과 함께 진행한 요구사항 분석의 일부다. 프로젝트는 숙박 예약 서비스의 필수 요구사항들이 주어졌으며 우리는 필수사항과 추가 기능들을 나열하고 <strong>우선순위</strong>를 정하였다.
<img src="https://velog.velcdn.com/images/just_do/post/a689a25e-514d-4b3c-a258-6f61cac07ab7/image.png" alt=""></p>
<h2 id="2-2-유저-플로우">2-2. 유저 플로우</h2>
<p>이번 프로젝트는 전 프로젝트들과 다르게 현업에서 사용되는 유저 플로우 컨벤션을 가져와 색깔과 모양을 구분하여 명시적이고 구체적인 유저 플로우를 만들었다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/46db5a27-9159-447d-afd0-a001e73a5c21/image.png" alt=""></p>
<h2 id="2-3-와이어프레임">2-3. 와이어프레임</h2>
<p>와이어프레임을 만들어 본 경험은 처음인데 소통을 통해 구체적인 디자인 전에 빠르게 기획한 웹사이트를 그려나갈 수 있었다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/40eb002c-36c5-4a78-80fa-f4edbc87e667/image.png" alt=""></p>
<h2 id="2-4-디자인">2-4. 디자인</h2>
<p>이번 프로젝트의 디자인을 같이 공부 중인 <strong>최재훈님</strong>께서 그동안 해주셨고 다른 팀원들은 CRA 등 프론트 개발 환경을 구축했다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/0967649c-2fdc-4d07-9f51-4d01ed93c978/image.png" alt=""></p>
<h2 id="2-5-스택-설정">2-5. 스택 설정</h2>
<p>스택은 여러가지를 고려하여 다음과 같이 설정하게 되었다. 전체적으로 짧은 개발 기간에 다양한 기능을 개발해야 했기 때문에 설정된 스택이 많다. 팀원 모두에게 익숙한 React,TypeScript 그리고 css 라이브러리 CHAKRA UI를 활용해 개발 기간을 단축시켰다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/1be2418e-20f0-44bc-9a6c-a2fdc9ecf0b6/image.png" alt=""></p>
<h2 id="2-6-cicd">2-6. CI/CD</h2>
<p>Netlify를 활용해 개발 초기에 메인 브랜치를 배포해 로컬 환경과 배포 환경을 모두 고려한 개발을 진행할 수 있었다.
<img src="https://velog.velcdn.com/images/just_do/post/bb47e985-8317-4742-a1c7-3867b210636c/image.png" alt=""></p>
<h2 id="2-7-github-flow">2-7. GitHub Flow</h2>
<p>브랜치 전략은 깃허브 플로우 전략을 따르기로 했고 이슈 단위로 브랜치를 생성해 개발을 진행하였다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/7ff1c22f-a22a-40c3-b336-8cb245c113c6/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/just_do/post/33b2d63b-84bb-4b6c-99f3-ad165f9b49d2/image.png" alt=""></p>
<h1 id="3-백엔드-개발자와-협업">3. 백엔드 개발자와 협업</h1>
<p>전 프로젝트들에서는 파이어베이스로 백엔드를 대체하거나 주어진 API를 활용한 개발을 했었다. </p>
<p>이번에 처음 백엔드 개발자분들과 협업을 하며 처음에 API를 요청한다는 게 무슨 의미인지, 프론트에서 할 일과 백엔드에서 할 일을 분업하는 과정 등 많은 게 걱정이었다.</p>
<p>걱정이 무색하게 능력있는 팀원분들을 만나 모든 과정이 재밌었고 잘 마무리 할 수 있었다. 그래서 이번 과정을 통해 배운 내용을 정리해보고 다음에도 적용해보려고 한다.</p>
<h2 id="3-1-erd">3-1. ERD</h2>
<p>프로젝트가 시작 되고 프론트에서는 기획과 디자인을 하고 있을 때 백엔드에서 ERD 초안이 도착했다.</p>
<p>다행히 데이터베이스 설계와 mySQL을 과거에 배운 적이 있어 ERD를 읽을 줄 알았으며 프론트에서 생각하고 백엔드에서 생각하는 데이터 설계의 차이점을 비교할 수 있어 소통을 통해 요구사항을 잘 전달하고 받을 수 있었다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/ca2b49f2-28fc-4ca4-94a0-a699ec2b418e/image.png" alt=""></p>
<h2 id="3-2-목업데이터">3-2. 목업데이터</h2>
<p>프론트와 백엔드가 동시에 프로젝트를 시작했을 때 프론트에서 필요한 API를 먼저 받을 수 있는 게 아니라 개발을 진행할 때 json 파일로 목업데이터를 만들어 public에 담에 GET 요청을 보내 데이터를 가져와 작업을 하는 방식으로 진행하였다.</p>
<p>이렇게 목업데이터를 만들어 놓아 API가 완성되었을 때 데이터 설계만 서로 일치하다면 바로 적용할 수 있어 프론트/백 모두가 빠르게 개발을 진행할 수 있었다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/3e4d632c-1e5f-4730-bed7-c7953ff61f4e/image.png" alt=""></p>
<h2 id="3-3-지속적인-상황-공유">3-3. 지속적인 상황 공유</h2>
<p>팀원들과 디스코드 방을 만들고 깃허브와 연동해 프론트 뿐만 아니라 백엔드 개발자 분들의 진행 상황을 커밋 내용으로 확인 가능했고 매일 정해진 시간에 짧더라도 진행 상황을 공유해 일정을 조율하고 개발의 속도를 맞췄다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/9b9ff759-0fdd-4e76-b284-41c91739ca95/image.png" alt=""></p>
<h1 id="4-마무리">4. 마무리</h1>
<p>이번 프로젝트는 전 프로젝트의 부정적인 경험을 개선하고 백엔드 개발자와의 협업 방법을 배운 프로젝트였다.</p>
<p>지금은 리팩토링을 진행하고 있으며 코드와 성능 개선을 목적으로 진행하여 2번의 글을 더 작성할 예정이다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[TIL] Array.fill()에 빈 객체([])를 전달했더니 생긴 일]]></title>
            <link>https://velog.io/@just_do/TIL-Array.fill%EC%97%90-%EB%B9%88-%EA%B0%9D%EC%B2%B4%EB%A5%BC-%EC%A0%84%EB%8B%AC%ED%96%88%EB%8D%94%EB%8B%88-%EC%83%9D%EA%B8%B4-%EC%9D%BC</link>
            <guid>https://velog.io/@just_do/TIL-Array.fill%EC%97%90-%EB%B9%88-%EA%B0%9D%EC%B2%B4%EB%A5%BC-%EC%A0%84%EB%8B%AC%ED%96%88%EB%8D%94%EB%8B%88-%EC%83%9D%EA%B8%B4-%EC%9D%BC</guid>
            <pubDate>Wed, 30 Aug 2023 16:54:54 GMT</pubDate>
            <description><![CDATA[<h2 id="📝-개요">📝 개요</h2>
<p>DFS를 공부하던 중 2차원 배열을 만들기 위해 먼저 빈 객체를 가진 N개의 배열을 만들었다.</p>
<pre><code class="language-javascript">let N = 5
let arr = new Array(N).fill([])

console.log(arr) // [[],[],[],[],[]]</code></pre>
<p>그리고 이 배열을 0의 값으로 찬 총 NxN개의 2차원 배열로 만들어주기 위해서
아래와 같이 for문과 push 메서드로 배열을 체워넣으려고 했다.</p>
<pre><code class="language-javascript">let N = 5
let arr = new Array(N).fill([])

for(let i = 0; i&lt;N; i++) {
  for(let j =0; j&lt;N; j++){
    arr[i].push(0)
  }
}

console.log(arr) </code></pre>
<p>하지만 예상한 결과와 다르게 N^2 x N개의 배열이 결과로 나왔다. <del>( 2차원 배열을 만드는 다른 좋은 방법들도 있지만 Array를 써보고 싶었다.. )</del></p>
<h2 id="❓-원인">❓ 원인</h2>
<p>왜 이런 결과가 나왔을까? 고민을 해보았는데 아마 빈 배열을 채워 넣는 과정에서 <strong>메서드 안의 빈 배열을 얕은 복사 했기 때문</strong>이라고 생각했다. </p>
<p>메서드 자체가 하나의 데이터를 모든 배열에 채워넣는 방식이니 얕은 복사를 통해 값을 할당했을 것 같다.</p>
<h2 id="🔎-분석">🔎 분석</h2>
<p>그래서 fill로 채워 넣은 값들이 얕은 복사를 통해 같은 메모리를 가리키고 있다는 것을 증명하기 위해 자바스크립트로 변수가 가리키는 메모리 주소를 찾아보려고 한다.</p>
<p>여기까지 정리하고 구글에 열심히 찾아본 결과 <strong>자바스크립트로는 메모리 주소를 찾을 수 없다</strong>고 한다.</p>
<p>자바스크립트 엔진은 자바스크립트 언어의 컴파일러 역할을 하고 자바스크립트 엔진은 C++로 만들어져 어떻게든 찾자면 찾을 수는 있다고 하나 복잡하니 넘어가려고 한다..</p>
<h2 id="😭-결론">😭 결론</h2>
<p>결론은 조금 어렵게 생각했던 탓이지 결국 얕은 복사를 하냐 깊은 복사를 하냐의 차이였고 fill 메서드는 객체 타입을 얕은 복사하여 이러한 문제가 생긴 것 같다. 그러니 fill 메서드로 2차원 배열을 만들려고 하지 말자.</p>
<p>조금 찜찜하니 다음에 더 알아보자..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[패스트캠퍼스X야놀자 : 프론트엔드 개발 부트캠프] JS 과제 설계 과정 및 해결 방법]]></title>
            <link>https://velog.io/@just_do/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4X%EC%95%BC%EB%86%80%EC%9E%90-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-JS-%EA%B3%BC%EC%A0%9C-%EC%84%A4%EA%B3%84-%EA%B3%BC%EC%A0%95-%EB%B0%8F-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@just_do/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4X%EC%95%BC%EB%86%80%EC%9E%90-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-JS-%EA%B3%BC%EC%A0%9C-%EC%84%A4%EA%B3%84-%EA%B3%BC%EC%A0%95-%EB%B0%8F-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Mon, 28 Aug 2023 03:00:23 GMT</pubDate>
            <description><![CDATA[<p>배포 주소 : <a href="https://sweet-jelly-6687d6.netlify.app">https://sweet-jelly-6687d6.netlify.app</a>
개발기간: 2023.08.08~ 2023.08.18</p>
<h2 id="📌-과제-개요">📌 과제 개요</h2>
<blockquote>
<p>JavaScript를 활용한 사진 관리 서비스 제작</p>
</blockquote>
<h3 id="필수-요구사항">[필수 요구사항]</h3>
<ul>
<li>“AWS S3 / Firebase 같은 서비스”를 이용하여 사진을 관리할 수 있는 페이지를 구현하세요.</li>
<li>프로필 페이지를 개발하세요.</li>
<li>스크롤이 가능한 형태의 리스팅 페이지를 개발하세요.</li>
<li>전체 페이지 데스크탑-모바일 반응형 페이지를 개발하세요.</li>
<li>사진을 등록, 수정, 삭제가 가능해야 합니다.</li>
<li>유저 플로우를 제작하여 리드미에 추가하세요.</li>
<li>CSS<ul>
<li>애니메이션 구현</li>
<li>상대수치 사용(rem, em)</li>
</ul>
</li>
<li>JavaScript<ul>
<li>DOM event 조작</li>
</ul>
</li>
</ul>
<h3 id="선택-요구사항">[선택 요구사항]</h3>
<ul>
<li>사진 관리 페이지와 관련된 기타 기능도 고려해 보세요.</li>
<li>페이지가 보여지기 전에 로딩 애니메이션이 보이도록 만들어보세요.</li>
<li>직원을 등록, 수정, 삭제가 가능하게 해보세요.</li>
<li>직원 검색 기능을 추가해 보세요.</li>
<li>infinity scroll 기능을 추가해 보세요.</li>
<li>사진을 편집할 수 있는 기능을 추가해 보세요.</li>
<li>LocalStorage 사용</li>
</ul>
<h2 id="📌-유저-플로우-및-페이지-구조-설계">📌 유저 플로우 및 페이지 구조 설계</h2>
<h3 id="유저-플로우">유저 플로우</h3>
<p><img src="https://velog.velcdn.com/images/just_do/post/a2a6d60b-b4c8-457d-9952-57ec11c6b43b/image.png" alt=""></p>
<h3 id="페이지-구조">페이지 구조</h3>
<p><img src="https://velog.velcdn.com/images/just_do/post/c10e27f5-46dc-4e02-9942-ffe74eee47c2/image.png" alt=""></p>
<h2 id="📌-문제-정의">📌 문제 정의</h2>
<h3 id="1-데이터베이스-연결">1. 데이터베이스 연결</h3>
<p>예전에 NextJS 프로젝트를 진행 할 때 mongoDB랑 AWS S3로 연결하여 데이터를 관리했던 경험이 있어 이번 프로젝트의 데이터베이스도 동일한 방법으로 연결하려고 했으나 Vanilla JavaSCript로 위 데이터베이스를 연결하는 방법을 찾지 못했다.</p>
<p>NextJS랑 그냥 쌩 JavaScript의 연결 방법이 왜 차이가 났고 힘들었는지 정리가 잘 되지 않아 따로 정리를 해봐야겠다.</p>
<p>그래서 결국 Firebase를 선택하게 되었는데 이유는 객체형 데이터와 이미지 관리를 동시에 할 수 있어 웹 서버 없이 서비스를 만들 수 있고, 편리한 UX로 DB관리에 익숙하지 않은 입장으로서 접근성이 좋았다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/cf00c096-59a9-464c-9fa2-deca5c7594fb/image.png" alt=""></p>
<h3 id="2-상세-페이지spa">2. 상세 페이지(SPA)</h3>
<p>이번 페이지는 Vanilla JavaScript로 SPA를 구현하여 만들었는데 굳이 SPA로 구현할 필요는 없는 과제였다. 하지만 상세 페이지를 구현하기 위해 라이브러리 없이 SPA를 구현하게 되었다.</p>
<p>그냥 MPA로 만들어 detail.html 만들고 url에 데이터 key 값을 파라미터로 전송해 구현해도 됐었다.</p>
<p>이런 쉬운 방법을 놔두고 url로 값을 전송해본 경험이 없고 오히려 NextJS로 SPA를 구현했던 경험이 떠올라 어쩌다 보니 라이브러리 없이 SPA를 구현하게 되었다. </p>
<p><img src="https://velog.velcdn.com/images/just_do/post/18ff82b2-82b3-4f50-9fac-2dcda265c3f3/image.gif" alt=""></p>
<h3 id="3-검색-기능">3. 검색 기능</h3>
<p>firebase에서 데이터를 가져올 때 where문을 사용하여 원하는 데이터를 가져올 수 있다. </p>
<p>그래서 처음엔 검색 버튼을 눌렀을 때 리스트가 변하도록 설계하였으나 검색어에 따라 실시간으로 반응하는 리스트를 만들고 싶어 다른 방법을 찾아보았다.</p>
<p>생각해낸 방법은 처음 받아온 데이터를 배열 데이터에 담아 input 태그에 keydown 이벤트가 발생할 때마다 리스트의 노드를 수정해주는 식으로 만들었다.</p>
<p>하지만 이러한 방식은 데이터의 개수가 많아질 경우 검색부터 DOM 수정까지 너무 많은 작업을 요구해 많은 데이터를 다룰 때는 적합하지 않겠다고 생각했다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/4e15d19b-af26-4707-bf4a-bc37c2d756af/image.gif" alt=""></p>
<h3 id="4-이미지-프리뷰">4. 이미지 프리뷰</h3>
<p>사진을 등록하거나 수정할 때 파일을 선택하면 어떤 파일을 선택했는지 이미지 태그를 이용해 미리 보여주는 기능을 구현하려고 했다.</p>
<p>그래서 type=&quot;file&quot;인 input 태그의 change 이벤트가 발생하면 미리 storage에 등록하고 url을 받아와 미리 만들어 놓은 img 태그의 url을 수정하는 식으로 구현했다.</p>
<p>하지만 문제는 이미지 파일을 선택만 하고 등록은 하지 않는 방식을 반복한다면 storage에 사용되지 않는 이미지들이 쌓인다는 것이다.</p>
<p>S3 같은 경우 presigned URL을 이용해 문제를 해결했었는데 firebase로는 유사한 방법을 찾지 못해 문제를 해결하지 못하고 과제를 마무리 했다.</p>
<p>그리고 리팩토링 전 찾아보니 createObjectURL이라는 방식이 있어 리팩토링 때 이용해보려고 한다.</p>
<h2 id="마무리">마무리</h2>
<p>짧지 않은 2주 간의 프로젝트 기간으로 여러 가지 스스로 공부해가며 문제를 해결해 나갔는데 저번 과제보다 확실히 성장함이 느껴지고 재미도 있었다.(힘들었지만..) 그리고 다른 조원분들과 과정을 함께 하시는 분들을 보니 부족함도 많이 느끼고 배움도 많다. 리팩토링 때 해결하지 못 했던 문제들이랑 멘토님이 남겨주신 피드백을 꼼꼼히 수정해보려고 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[ 백준 18870 ] JavaScript 풀이 ( 표준 내장 객체 Map ) ]]></title>
            <link>https://velog.io/@just_do/%EB%B0%B1%EC%A4%80-18870-JavaScript-%ED%92%80%EC%9D%B4-%ED%91%9C%EC%A4%80-%EB%82%B4%EC%9E%A5-%EA%B0%9D%EC%B2%B4-Map</link>
            <guid>https://velog.io/@just_do/%EB%B0%B1%EC%A4%80-18870-JavaScript-%ED%92%80%EC%9D%B4-%ED%91%9C%EC%A4%80-%EB%82%B4%EC%9E%A5-%EA%B0%9D%EC%B2%B4-Map</guid>
            <pubDate>Tue, 08 Aug 2023 09:15:34 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-문제">📌 문제</h2>
<p><a href="https://www.acmicpc.net/problem/18870">백준 18870 : 좌표 압축</a></p>
<p><img src="https://velog.velcdn.com/images/just_do/post/d6873ee7-211d-4123-9a44-c78bd8fcf9fc/image.png" alt=""></p>
<p>문제를 간단히 설명하면
입력받은 N개의 수를 좌표 위에 나열하고 각 입력받은 수보다 낮은 좌표계에 존재하는 수의 갯수를 하나씩 출력하는 문제다.
(ex. 첫 번째 입력 값인 2보다 낮은 좌표에 존재하는 값은 (-9, -10) 2개로 2를 출력한다.)</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/f0b92660-377c-4318-9461-47bbbdfc5cfe/image.png" alt=""></p>
<h2 id="📌-문제-접근-방법">📌 문제 접근 방법</h2>
<p>처음 문제를 접근 했을 땐 원본 배열을 유지하고 새로운 배열에 sort() 메서드로 오름차순 정렬한 뒤 indexOf()로 원본 배열과 비교하여 index를 출력하려고 했다.</p>
<p>하지만 결과는 <strong>시간 초과</strong>가 나왔고, 이유는 마지막 for of 문에서 indexOf()가 원본 배열의 전체를 최대로 탐색하여 결과적으로 O(N^2)의 시간 복잡도가 나오기 때문이라고 생각한다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/c7cab0c1-ae84-4d5e-9775-35d8cf401ba5/image.png" alt=""></p>
<pre><code class="language-javascript">let fs = require(&quot;fs&quot;);
let input = fs.readFileSync(&quot;dev/stdin&quot;).toString().trim().split(&quot;\n&quot;);

let N = Number(input[0]);
let arr = input[1].split(&quot; &quot;).map(Number);

//새로운 배열에서 중복을 제거하고 오름차순 정렬
let newArr = [...new Set(arr)]
newArr = newArr.sort((a,b) =&gt; a-b)

let answer = &quot;&quot;

// indexOf를 활용하여 입력 받은 값의 index를 출력
for(x of arr){
  answer += newArr.indexOf(x) + &quot; &quot;
}

console.log(answer)</code></pre>
<p>그래서 문제 풀이 강의를 참고하였고, 강의에서 표준 내장 객체 Map을 사용하여 이번에 문제와 함께 정리해 Map을 이해해보려고 한다.</p>
<h2 id="📌-map을-활용한-문제-풀이">📌 Map을 활용한 문제 풀이</h2>
<h3 id="표준-내장-객체-map이란">표준 내장 객체 Map이란?</h3>
<p>Map 객체는 키-값 쌍과 키의 원래 삽입 순서를 기억한다. 모든 값(객체 및 원시 값 모두)은 키 또는 값으로 사용될 수 있다.</p>
<p>set() 메서드로 값을 삽입하고, delete() 메서드로 값을 삭제하고, get() 메서드로 값을 출력한다.</p>
<pre><code class="language-javascript">const map1 = new Map();

map1.set(&#39;a&#39;, 1);
map1.set(&#39;b&#39;, 2);
map1.set(&#39;c&#39;, 3);

console.log(map1.get(&#39;a&#39;));
// Expected output: 1

map1.set(&#39;a&#39;, 97);

console.log(map1.get(&#39;a&#39;));
// Expected output: 97

console.log(map1.size);
// Expected output: 3

map1.delete(&#39;b&#39;);

console.log(map1.size);
// Expected output: 2

console.log(map1)
// Expected output : Map(2) { &#39;a&#39; =&gt; 97, &#39;c&#39; =&gt; 3 }</code></pre>
<h3 id="문제-풀이">문제 풀이</h3>
<p>indexOf 대신 Map 객체에 담긴 키 값을 바탕으로 get() 메서드를 활용해 index 값인 값을 출력한다는 차이가 있다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/69450578-1f60-43ec-b225-5a31cddea40b/image.png" alt=""></p>
<pre><code class="language-javascript">let fs = require(&quot;fs&quot;);
let input = fs.readFileSync(&quot;dev/stdin&quot;).toString().trim().split(&quot;\n&quot;);

let N = Number(input[0]);
let arr = input[1].split(&quot; &quot;).map(Number);

// 새로운 배열에서 중복을 제거하고 오름차순 정렬
let newArr = [...new Set(arr)]
newArr = newArr.sort((a,b) =&gt; a-b)

// Map 객체를 생성하고 오름차순 정렬된 배열의 값과 index를 삽입
let myMap = new Map();
for (let i = 0; i &lt; newArr.length; i++) {
  myMap.set(newArr[i], i);
}

let answer = &quot;&quot;;

// 원본 배열의 값들을 myMap 객체에서 탑색하여 출력
for (x of arr) answer += myMap.get(x) + &quot; &quot;;
console.log(answer);</code></pre>
<p>코드를 작성해보고 해석해보았을 때 indexOf()로 배열을 탐색하는 거랑 큰 차이가 없는 것 같이 느껴져 Map 객체의 get() 메서드의 원리를 알아보았다.</p>
<h2 id="📌-왜-map이-시간-복잡도가-더-낮을까">📌 왜 Map이 시간 복잡도가 더 낮을까?</h2>
<p>기본적으로 배열과 Map 객체의 데이터 저장과 검색 방식에 차이가 있다.</p>
<p>배열은 값들이 연속된 메모리 공간에 저장되어 있다. indexOf() 메서드를 사용하면 연속된 메모리 공간을 하나씩 탐색하며 해당 원소의 인덱스를 알아낸다. 그래서 시간 복잡도가 최대 O(N)까지 나올 수 있는 것이다. </p>
<p><img src="https://velog.velcdn.com/images/just_do/post/b3dbd1e4-fcd8-40c0-aa73-8571ddc7d6bd/image.png" alt=""></p>
<p>반면 Map 객체의 경우 해시 테이블 자료구조로 데이터를 관리한다.
해시 테이블이란 데이터의 특정 값을 키(key)로 매핑하여 값을 저장하고 검색하는 데 사용된다. 해시 테이블은 키-값 쌍을 저장하는데, 이를 해시 함수를 통해 고유한 해시 코드로 변환하여 내부적으로 저장한다.</p>
<p>그래서 get 메서드로 키를 검색할 때 아래 그림처럼 해시 함수로 값의 메모리 위치를 얻어 특정 메모리를 바로 참조하여 객체의 전체를 하나씩 참조하는 것이 아니라 최대 O(1)의 시간 복잡도를 만들 수 있다.</p>
<p>여기서 최대 O(1)이라고 말하는 이유는 해당 위치에 값이 존재하지 않거나 해시 충돌이 발생할 경우 최대 O(N)의 복잡도가 될 수도 있기 때문이다. 이를 해결하는 방법으로 체이닝과 개방 주소법이 있다고 하는데 나중에 알아보기로 하자..</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/cdfe62ad-e5db-4508-87cd-0494bba35acc/image.png" alt=""></p>
<h2 id="📌-마무리">📌 마무리</h2>
<p>결론적으로 indexOf() 메서드와 Map 객체의 get() 메서드는 동작 방식과 자료구조에 큰 차이가 있기 때문에 Map 객체를 사용했을 때 낮은 시간 복잡도로 문제를 해결할 수 있었던 것이다. 그리고 자바스크립트의 객체 역시 해시 테이블 자료구조를 사용한다고 하여 일반 객체로도 구현할 수 있을 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[패스트캠퍼스X야놀자 : 프론트엔드 개발 부트캠프] 클론 코딩 과제 리팩토링]]></title>
            <link>https://velog.io/@just_do/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4X%EC%95%BC%EB%86%80%EC%9E%90-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%81%B4%EB%A1%A0-%EC%BD%94%EB%94%A9-%EA%B3%BC%EC%A0%9C-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81</link>
            <guid>https://velog.io/@just_do/%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4X%EC%95%BC%EB%86%80%EC%9E%90-%ED%94%84%EB%A1%A0%ED%8A%B8%EC%97%94%EB%93%9C-%EA%B0%9C%EB%B0%9C-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-%ED%81%B4%EB%A1%A0-%EC%BD%94%EB%94%A9-%EA%B3%BC%EC%A0%9C-%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81</guid>
            <pubDate>Mon, 07 Aug 2023 17:13:42 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-과제-소개">📌 과제 소개</h2>
<p>현재 참여 중인 <strong>패스트캠퍼스 x 야놀자 : 프론트엔드 부트캠프</strong> 과정에서 원하는 사이트를 선정하여 클론 코딩하는 과제를 수행하였다.</p>
<p>내가 선정한 사이트는 <a href="fastcampus.co.kr">패스트캠퍼스</a>이고, HTML/CSS로 최대한 구현하고 일부 JavaScript를 활용해 보충해주며 <a href="https://scintillating-kleicha-014b82.netlify.app/#">클론 사이트</a>를 제작하였다.</p>
<p><a href="https://velog.io/@just_do/CSS-JavaScript-%EB%A9%94%EC%9D%B8-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%8D%94-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4-%ED%81%B4%EB%A1%A0-%EC%BD%94%EB%94%A9">이전 포스팅</a>에서는 가장 신경썼던 부분인 슬라이더를 제작하는 과정을 전/후 생각 차이를 비교하며 작성하였고, <strong>이번 포스팅</strong>에서는 과제를 완료하고 멘토님이 남겨준 리뷰와 스스로 아쉬웠던 부분들을 바탕으로 리팩트링을 하는 내용을 담을 것이다.</p>
<h2 id="📌-리팩토링-내용">📌 리팩토링 내용</h2>
<p>리팩트링의 전체적인 깃허브 커밋 내용이다. 전반적으로 코드의 오류가 많았고, 내가 작성한 코드였지만 나도 잘 해석하기 힘들게 적힌 코드도 많았고, 클론 코딩을 하며 원본 사이트의 코드의 구조와 클레스명을 많이 참고하여 스스로 작성하지 않은 코드인 것 같다는 피드백도 받았다. 그래서 코드에 주석도 달아 이해도를 높이고 불필요한 구조를 단순화시키는데 집중했다. 그렇게 진행한 리팩토링 내용은 아래와 같다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/7e2f92b7-6099-4e6a-941a-ec2ba1b37eac/image.png" alt=""></p>
<ol>
<li><p>불필요한 코드 삭제
<img src="https://velog.velcdn.com/images/just_do/post/6ef27e86-7bf6-40d3-919c-5cb27b9feffe/image.png" alt="">
top-banner가 사라지는 기능은 구현하지 않았기 때문에 input 태그를 지워주었고, svg 태그를 긁어오는 과정에서 불필요하게 들어간 코드들을 제거해주었다.</p>
</li>
<li><p>폴더 분류
<img src="https://velog.velcdn.com/images/just_do/post/8cebf552-6d32-4350-b947-f8a8c25b6dfc/image.png" alt="">
처음에 하나의 assets 폴더에 담겨 있던 이미지 파일을 분류하였다.</p>
</li>
<li><p>태그 선택자 지양하기
<img src="https://velog.velcdn.com/images/just_do/post/47260187-ae93-40b7-a8b1-60c3e251fef2/image.png" alt="">
태그 선택자를 사용한 태그에 클레스명을 새로 달아주었다.</p>
</li>
</ol>
<h2 id="📌-마무리-및-후기">📌 마무리 및 후기</h2>
<p>이번 클론 코딩 과제를 수행하며 정말 많은 걸 배웠다. 완성도에 급해 코드보단 보여지는 것에 우선 시 하여 일부 구조나 코드를 복붙해오고, 코드를 읽는 사람은 배려하지 않은 코드를 작성하였다. 그래서 사실 코드리뷰에서 좋은 평가를 받지 못하였고, 리팩토링을 하면서 멘토님의 말씀(리뷰)을 이해하게 되었다. 그래도 이번 과제를 통해서 슬라이더나 카테고리 기능을 구현하는 노하우도 많이 늘고 DOM 구조에 대해서도 참고하며 많은 도움을 받았던 것 같아 다음 번에는 이번에 부족했던 부분을 더욱 보완하여 과제를 수행해보려고 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[패스트캠퍼스X야놀자 : 프론트엔드 개발 부트캠프] 슬라이더 구현( 설계 과정 )]]></title>
            <link>https://velog.io/@just_do/CSS-JavaScript-%EB%A9%94%EC%9D%B8-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%8D%94-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4-%ED%81%B4%EB%A1%A0-%EC%BD%94%EB%94%A9</link>
            <guid>https://velog.io/@just_do/CSS-JavaScript-%EB%A9%94%EC%9D%B8-%EC%8A%AC%EB%9D%BC%EC%9D%B4%EB%8D%94-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0%ED%8C%A8%EC%8A%A4%ED%8A%B8%EC%BA%A0%ED%8D%BC%EC%8A%A4-%ED%81%B4%EB%A1%A0-%EC%BD%94%EB%94%A9</guid>
            <pubDate>Fri, 28 Jul 2023 17:09:35 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-과제-소개">📌 과제 소개</h2>
<p>야놀자x패스트캠퍼스 부트캠프 과정 첫 번째 과제로 배운 내용을 바탕하여 원하는 사이트를 선정해 클론 코딩하는 것을 받았다. 내가 선정한 사이트는 <a href="https://fastcampus.co.kr/#">패스트캠퍼스 메인 페이지</a>다. 페이지 선정은 자유였으나 패스트캠퍼스에서 진행하는 과정이니 더 재밌는 피드백이 나올 수 있을 것 같아 선정했다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/a302bf75-f77b-4bcb-b076-9b0bddb30d32/image.png" alt=""></p>
<p>사진은 클론 코딩 대상인 패스트캠퍼스 메인 페이지고 하단은 구현 중인 클론 페이지다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/65a72877-a927-4513-ba2f-f343914a4f4a/image.png" alt=""></p>
<p>아직 상단 배너와 네비게이션 바만 완성한 상태이며 현재 메인 섹션의 슬라이더를 구현하기 위해 구상 중이다.</p>
<hr>
<h2 id="📌-슬라이더-구현-접근-방식-및-설계">📌 슬라이더 구현 접근 방식 및 설계</h2>
<p>*<strong>이 단계는 페이지 구현을 마친 후가 아닌 설계 단계에서 작성되었다.</strong></p>
<h3 id="기능-정리">기능 정리</h3>
<p>페이지에 접속해 보면 슬라이더는 총 4가지의 특별한 기능이 설계되어 있다.</p>
<ol>
<li>자동으로 초단위로 FadeIn/Out 하는 슬라이드</li>
<li>FadeIn/Out 사이에 이미지를 확대시켜 이미지가 다가오는 느낌 만들기</li>
<li>슬라이드 갯수와 현재 슬라이드 순서를 나타내는 도트들</li>
<li>슬라이드를 좌우로 직접 넘기거나 슬라이드가 자동으로 넘어가는 기능을 멈추고 실행하는 버튼</li>
</ol>
<p><img src="https://velog.velcdn.com/images/just_do/post/6fa3d8c8-3a9a-40eb-a016-5abe0dd2e94b/image.png" alt=""></p>
<h3 id="구현-방법-구상">구현 방법 구상</h3>
<p><strong>1. 자동으로 초단위로 FadeIn/Out 하는 슬라이드</strong></p>
<p>FadeIn/Out하는 슬라이드는 다른 페이지들에서도 많이 사용되는 슬라이더 방식이다. 아마 이미지와 글이 담긴 여러 개의 a태그들을 position을 absolute로 하여 같은 축에 일렬로 세우고(z축이 같다고 표현해야 하나) 순서에 해당하는 a태그의 display는 block으로 설정하고 나머지는 none으로 설정한 뒤 setinterval() 함수를 이용하여 순서에 맞게 띄워주면 될 것 같다. 그리고 css 속성에 transform 속성을 넣어 적당한 시간을 주어 천천히 사라지고 나타나는 FadeIn/Out 효과를 만들 것 같다.</p>
<p><strong>2. FadeIn/Out 사이에 이미지를 확대시켜 이미지가 다가오는 느낌 만들기</strong>
이거는 매우 간단하게 전체 이미지를 감싸는 a태그를 overflow:hidden으로 설정해 안에 들어있는 요소들이 밖으로 나오지 못하게 설정하고 안에 있는 img태그를 시간을 주어 크기를 늘리면 확대되는 느낌을 줄 수 있을 것이다.</p>
<p><strong>3. 슬라이드 갯수와 현재 슬라이드 순서를 나타내는 도트들</strong>
이게 제일 어렵다고 느끼는데 클릭에도 반응해야 하고 모양도 radio의 checked 상태도 아닌 특정한 모양을 만들어야 한다. 지금 생각하는 구현 방식은 grid css를 활용하여 원 모양의 도트들을 div 박스에 border-radius 속성을 활용해 만들고 해당 순번의 grid-templete-colums를 다른 도트들보다 2배로 주면 해결되지 않을까 싶다. 아직 grid 속성을 활용해본 적이 없어 확신이 들지 않지만 한 번 시도해봐야겠다. 그리고 내가 모르는 radio 버튼의 스타일 속성을 활용한 방법일 수도 있으니 찾아봐야겠다.</p>
<blockquote>
<p>📝 추가로 위치한 도트들을 연속적으로 클릭했을 때 오류가 발생하지 않도록 일정시간의 연속 입력을 하나의 입력으로 처리하는 코드가 있는 것 같은데 <strong>이벤트를 그룹화 시켜 연속적인 이벤트 발생을 막는 디바운스</strong>를 활용한 게 아닌가 싶다. 아직 구현하기 어렵고 시간도 부족하니 다음에 사이트 기능을 향상시킬 때 도전해봐야겠다.</p>
</blockquote>
<p><strong>4. 슬라이드를 좌우로 직접 넘기거나 슬라이드가 자동으로 넘어가는 기능을 멈추고 실행하는 버튼</strong>
좌우로 넘어가는 방식은 위 도트 방식과 비슷하게 클릭 시 이벤트가 발생하는 방식으로 구현을 하고 멈추고 실행하는 버튼은 setinterval()함수를 멈추는 함수도 있기 때문에 이를 활요하면 될 것 같다.</p>
<p><strong>5. 마지막으로 예상가는 문제점</strong>
모든 기능을 구현해봐야 알겠지만 아마도 스크립트 코드들이 꼬이는 현상이 발생할 것 같다. 슬라이더가 넘어가는 방식이 총 3가지다 보니 setinterval()함수와 엉켜 넘기자 마자 넘어가거나 이상한 곳에 display 값을 none과 block을 주는 문제가 생길 것으로 예상된다.</p>
<hr>
<h2 id="📌-구현-결과">📌 구현 결과</h2>
<p>원본 사이트 : <a href="https://fastcampus.co.kr/">https://fastcampus.co.kr/</a>
클론 사이트 : <a href="https://scintillating-kleicha-014b82.netlify.app/#">https://scintillating-kleicha-014b82.netlify.app/#</a></p>
<p>깃허브 : <a href="https://github.com/KDT1-FE/Y_FE_HTML_CSS/pull/48">https://github.com/KDT1-FE/Y_FE_HTML_CSS/pull/48</a></p>
<p><img src="https://velog.velcdn.com/images/just_do/post/dafa33a7-fd73-4605-9887-5b947f9074a5/image.gif" alt=""></p>
<h3 id="1-fadeinout">1. FadeIn/Out</h3>
<p>처음엔 display 속성을 none/block으로 전환하여 구현하려고 했으나 transition 속성 값으로 display로 했을 때 잘 구현이 되지 않아 opacity 0/1로 전환하여 구현하니 깔끔하게 구현됐다.</p>
<pre><code class="language-css">.curation-section__slidelist li{
    opacity: 0;
    transition: opacity 1s ease-out;
    width: 100%;
    position: absolute;
}</code></pre>
<h3 id="2-확대-기능">2. 확대 기능</h3>
<p>확대 기능도 처음 설계한 것처럼 부모 요소에 overflow : hidden을 설정하고 해당 슬라이드가 노출 될 때 scale을 키우는 방식으로 다가오는 느낌을 구현하였다.</p>
<pre><code class="language-css">.curation-section{
    width: 100%;
    height: 450px;
    overflow: hidden;
    position: relative;
}

.curation-section__slide__img{
    width: 1280px;
    position: absolute;
    top:0;
    z-index: 1;
    transform: scale(1);
    transition: transform 2.5s ease-out;
}</code></pre>
<h3 id="3-도트들">3. 도트들</h3>
<p>이번에 처음 input radio타입과 label을 이용하여 슬라이더와 토글들을 구현해보았는데 굉장히 편하고 활용도가 높아 보였다. 예를 들어 이커머스 사이트에서 카테고리를 클릭했을 때 나열되는 상품들이 바뀌게 구현 할 수 있을 것 같다.</p>
<p>설계 단계에선 label에 관한 개념이 없어 radio 버튼을 어떻게 도트처럼 표현할지 고민했지만 label을 활용하여 생각보다 쉽게 구현하였다. flex div에 담아 checked 상태인 label의 크기만 늘려주면 됐다.</p>
<pre><code class="language-css">.curation-section__radio label{
    display: inline-block;
    width:12px;
    height: 12px;
    margin: 6px;
    border-radius: 6px;
    background-color: rgba(255,255,255,.5);
    transition: width 0.5s;
}

.curation-section [id=&quot;slide01&quot;]:checked ~ 
.curation-section__slidewrap 
.curation-section__radio 
label:nth-child(1){
    width: 50px; background-color: #fff;
}
</code></pre>
<h3 id="4-자동으로-넘기는-기능-및-문제-해결">4. 자동으로 넘기는 기능 및 문제 해결</h3>
<p>자동으로 넘어가는 기능은 간단하게 slideIndex 변수를 만들어 nth-child(변수) 안에 변수를 넣어 setinterval 함수로 자동으로 5초마다 넘어가게 하였다. 하지만 문제는 계속 slide가 바뀌다 인위적으로 바꿨을 때 slideIndex가 따라오지 못하고 setinterval을 멈췄다 실행하지 못하여 1번에 있다 10번으로 가도 2번으로 넘어가는 문제가 생겼다.</p>
<p>이를 해결하기 위해 인위적으로 checked 값을 옮길 때 slideIndex 값도 변경해야 하고 setinterval 메서드도 멈췄다 다시 실행해야 한다.</p>
<p>그래서 도트를 클릭하여 checked를 옮길 때 &#39;click&#39;이벤트를 감지하여 setInterval() 메서드를 clearInterval()을 통해 한 번 멈춰주고 index값을 다시 재조정 후 자동으로 넘어가게 setInterval()을 다시 실행해주었다.</p>
<pre><code class="language-javascript">var slideIndex = 1;

let slideCallback = function(){
  if(slideIndex === 13){
    slideIndex = 1;
  }else{
    slideIndex++;
  }

  const slide = document.querySelector(`.curation-section input:nth-child(${slideIndex})`);
  slide.checked = true;
}

slideinterval = setInterval(slideCallback,5000)


document.addEventListener(&#39;DOMContentLoaded&#39;, function() {
  var checkboxes = document.querySelectorAll(&#39;input[type=radio][name=slide]&#39;);

  for (var checkbox of checkboxes)
  {
    checkbox.addEventListener(&#39;change&#39;, function(event)
                              {
      if (event.target.checked) {
        clearInterval(slideinterval)
        slideIndex = Object.values(checkboxes).indexOf(event.target)+1;
        slideinterval = setInterval(slideCallback,5000)
      }
    });
  }
}, false);</code></pre>
<hr>
<h2 id="📌-결론">📌 결론</h2>
<p>일주일 동안 코딩을 하면서 확실히 예전보다 성장했음을 느낄 수 있었다. 전체적인 웹페이지를 만들어 본 건 그리 오래되지 않았지만 예전엔 서칭을 하면서도 코드 이해하는데 오래 걸리고 머릿속에서 코드들을 추상화 하기도 어려웠는데 확실히 더 수월해진 것 같다. </p>
<p>그리고 무작정 만들기 보다 먼저 설계 단계를 거치고 진행하여 시간도 많이 단축했던 것 같고 완성한 뒤 전의 설계의 문제점을 다시 공부할 수 있고 왜 이런 방법을 택했는지도 더욱 명확해졌다. </p>
<p>지금은 비록 작은 단위의 그리고 클론 코딩의 수준이지만 나중에 더 큰 단위의 프로젝트를 진행할 때는 더욱 설계 단계가 중요하겠다는 생각이 들었다.</p>
<p>결론 : 만족적인 결과물</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[알고리즘, 자료구조] 자바스크립트로 스택, 큐 구현하기]]></title>
            <link>https://velog.io/@just_do/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A1%9C-%EC%8A%A4%ED%83%9D-%ED%81%90-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@just_do/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A1%9C-%EC%8A%A4%ED%83%9D-%ED%81%90-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 25 Jul 2023 08:41:46 GMT</pubDate>
            <description><![CDATA[<h1 id="스택과-큐의-구현-방식과-시간-복잡도">스택과 큐의 구현 방식과 시간 복잡도</h1>
<p>자바스크립트로 자료구조에 대해 공부하다 <strong>스택(Stack)</strong>을 배열로 구현하고 <strong>큐(Queue)</strong>도 똑같이 배열로 구현했을 때 큐의 시간복잡도가 늘어나는 것을 보고 이유를 찾게 되었다.</p>
<p>자바스크립트엔 스택과 큐가 따로 내장되어 있지 않기 때문에 배열과 내장함수들을 이용하여 스택과 큐를 흉내내어 만드는데 배열로 스택과 큐를 구현하였을 때 element가 제거되는 방식에서 사용되는 두 내장함수 <strong>Array.prototype.pop() 과 Array.prototype.shift()의 차이</strong>에 의해 시간 복잡도가 달라진다.</p>
<p>그래서 시간 복잡도를 이해하고 스택과 큐에 적용하기 위해서는 스택과 큐의 구현 방식인 <strong>배열(Array) 방식과 연결리스트(Linked List) 방식의 차이</strong>를 이해해야 한다.</p>
<hr>
<h2 id="📌-스택stack">📌 스택(Stack)</h2>
<ul>
<li>LIFO(Last In, Last Out)를 원칙으로 하는 자료구조다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/just_do/post/0526d665-47ef-4c67-9a77-6893cbf86f6e/image.png" alt=""></p>
<p>속성</p>
<ul>
<li>top : 스택 맨 위의 아이템</li>
</ul>
<p>메소드</p>
<ul>
<li>push : 스택의 맨 위에 아이템을 삽입한다</li>
<li>pop : 스택 맨 위의 아이템을 제거하고 및 그 아이템을 반환한다</li>
<li>contains : 해당 아이템이 스택에 존재하는지 확인한다</li>
<li>size : 현재 스택에 있는 아이템의 총 개수를 반환한다</li>
</ul>
<p>스택 (Stack) 사용 사례</p>
<ul>
<li>재귀 알고리즘</li>
<li>재귀적으로 함수를 호출해야 하는 경우에 임시 데이터를 스택에 넣어준다.</li>
<li>재귀함수를 빠져 나와 퇴각 검색(backtrack)을 할 때는 스택에 넣어 두었던 임시 데이터를 빼 줘야 한다.</li>
<li>스택은 이런 일련의 행위를 직관적으로 가능하게 해 준다.</li>
<li>또한 스택은 재귀 알고리즘을 반복적 형태(iterative)를 통해서 구현할 수 있게 해준다.</li>
<li>웹 브라우저 방문기록 (뒤로가기)</li>
<li>실행 취소 (undo)</li>
<li>역순 문자열 만들기</li>
<li>수식의 괄호 검사 (연산자 우선순위 표현을 위한 괄호 검사)
Ex) 올바른 괄호 문자열(VPS, Valid Parenthesis String) 판단하기</li>
<li>후위 표기법 계산</li>
</ul>
<h3 id="배열로-스택stack-구현">배열로 스택(Stack) 구현</h3>
<p>처음 문제를 풀 때는 무작정 if문을 사용하여 구현하였는데 스택을 이해하고 클래스로 구현하니 코드가 더 쉽게 이해가 된다.</p>
<pre><code class="language-javascript">class Stack {
  constructor() {
    this.items = [];
  }

  push(item) {
    this.items.push(item);
  }

  pop() {
    return this.items.pop();
  }

  // pop과 달리 아이템은 유지한 채 값만 받아온다.
  peek() {
    if (this.items.length === 0) {
      return null;
    }
    return this.items[this.items.length - 1];
  }

  getSize() {
    return this.items.length;
  }

  isEmpty() {
    return this.getSize() === 0;
  }
}
</code></pre>
<h3 id="연결리스트로-스택stack-구현">연결리스트로 스택(Stack) 구현</h3>
<p>연결리스트로 구현하니 size를 어떻게 가져올지 고민이었다. 결국 stack에 index 변수를 담아 관리하기로 했다. 연결리스트에 대한 개념은 이해했으나 구상이 제대로 되지 않았는데 스택을 이해하고 이를 연결리스트로 구현하니 머릿속에서 좀 더 구체화가 된 것 같다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/a9569462-f49b-4755-bec5-3a68018b385e/image.png" alt=""></p>
<pre><code class="language-javascript">class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

class Stack {
  constructor() {
    this.top = null
    this.index = 0;
  }

  isEmpty() {
    return this.top === null;
  }

  push(data) {
    // ex) data = 13
    const newNode = new Node(data);
    // newNode.data = 13, newNode.next = null
    newNode.next = this.top;
    // stack.top = newNode {data : 13, next = null}
    this.top = newNode;
    this.index++ ;
  }

  pop() {    
    if (this.isEmpty()) return;
    let re = this.top
    this.top = this.top.next;
    this.index-- ;
    return re.data
  }

  peek() {
    if (this.isEmpty()) return false;
    return this.top.data;
  }

  size(){
    return this.index;
  }
}</code></pre>
<h3 id="두-방식의-시간-복잡도-차이">두 방식의 시간 복잡도 차이</h3>
<p>스택에서는 배열과 연결리스트에서 시간 복잡도 차이는 크게 생기지 않는다. 그 이유는 둘 다 최상단의 데이터를 삽입, 삭제하며 관리하기 때문에 모두 O(1)의 시간 복잡도를 갖는다. 하지만 큐에서는 두 방식에서 시간 복잡도의 차이가 발생한다.</p>
<hr>
<h2 id="📌-큐queue">📌 큐(Queue)</h2>
<ul>
<li>FIFO(First In, First Out)을 원칙으로 하는 자료구조다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/just_do/post/24c613f2-dca5-46f1-8f46-6f20b74513cc/image.png" alt=""></p>
<p>속성</p>
<ul>
<li>first : 큐 맨 앞의 아이템</li>
</ul>
<p>메소드</p>
<ul>
<li>dequeue : 큐 맨 앞의 아이템을 제거하고 및 그 아이템을 반환한다</li>
<li>enqueue : 큐에 아이템을 추가한다</li>
<li>contains : 해당 아이템이 큐에 존재하는지 확인한다</li>
<li>size : 현재 큐에 있는 아이템의 총 개수를 반환한다</li>
</ul>
<p>큐 (Queue) 사용 사례</p>
<blockquote>
<p>데이터가 입력된 시간 순서대로 처리해야 할 필요가 있는 상황에 이용한다.</p>
</blockquote>
<ul>
<li>너비 우선 탐색(BFS, Breadth-First Search) 구현</li>
<li>처리해야 할 노드의 리스트를 저장하는 용도로 큐(Queue)를 사용한다.</li>
<li>노드를 하나 처리할 때마다 해당 노드와 인접한 노드들을 큐에 다시 저장한다.</li>
<li>노드를 접근한 순서대로 처리할 수 있다.</li>
<li>캐시(Cache) 구현</li>
<li>우선순위가 같은 작업 예약 (인쇄 대기열)</li>
<li>선입선출이 필요한 대기열 (티켓 카운터)</li>
<li>콜센터 고객 대기시간</li>
<li>프린터의 출력 처리</li>
<li>윈도 시스템의 메시지 처리기</li>
<li>프로세스 관리</li>
</ul>
<h3 id="배열로-큐queue-구현">배열로 큐(Queue) 구현</h3>
<p>스택과 다른점은 가장 앞에 있는 element를 추출하기 위해 pop() 대신 shift() 메서드를 사용한다는 것이다. shift()는 가장 앞에 있는 요소를 추출하고 나머지 요소들을 앞으로 당겨줘야하기 때문에 O(n)의 시간복잡도를 갖게 된다. 그래서 시간복잡도를 O(1)로 하기 위해 연결리스트 방식을 사용해야 정석적인 큐(Queue)를 만들 수 있다.</p>
<pre><code class="language-javascript">export default class Queue {
  constructor() {
    this.items = [];
  }

  enqueue(item) {
    this.items.push(item);
  }

  dequeue() {
    return this.items.shift();
  }

  peek() {
    return this.items[0];
  }

  getSize() {
    return this.items.length;
  }

  isEmpty() {
    return this.getSize() === 0;
  }
}
</code></pre>
<h3 id="연결리스트로-큐queue-구현">연결리스트로 큐(Queue) 구현</h3>
<p>연결리스트로 큐를 구현하여 element를 추출하는 과정에서 shift() 메서드를 사용하지 않아 시간복잡도 O(1)을 구현할 수 있다.</p>
<pre><code class="language-javascript">class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
  }
}

class Queue {
  constructor() {
    this.front = null;
    this.rear = null;
    this.index = 0;
  }

  isEmpty() {
    return this.front == null &amp;&amp; this.rear === null;
  }
  insert(data) {
    const newNode = new Node(data);
    if (this.isEmpty()) this.front = newNode;
    else this.rear.next = newNode;

    this.rear = newNode;
    this.index++;
  }

  remove() {
    if (this.isEmpty()) return;
    this.front = this.front.next;
    if (!this.front) this.rear = null;
    this.index--;
  }

  peekFront() {
    if (this.isEmpty()) return false;
    return this.front.data;
  }

  size(){
      return this.index;
  }
}</code></pre>
<h3 id="두-방식의-시간-복잡도-차이-1">두 방식의 시간 복잡도 차이</h3>
<p>위에서 계속 언급했던 것처럼 shift() 메서드를 사용하면 뒤 요소들을 앞으로 당겨줘야 하기 때문에 시간복잡도가 O(n)이 되지만 연결리스트로 큐를 구현하면 가장 앞에 있는 요소만 제거하면 되기 때문에 O(1)의 시간복잡도를 갖는다.</p>
<hr>
<h2 id="마무리">마무리</h2>
<p>여러 가지 자료구조 중 스택과 큐에 대하여 알아보았는데 처음 개념 공부를 하고 문제를 풀 때는 어떻게 문제에 적용할지 어려웠는데 문제를 먼저 풀어서도 있겠지만 개념을 클래스로 구현하여 다시 정리해보니 확실히 이해가 더 된 느낌이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 이해하기(배열, 연결 리스트, 스택, 큐, 트리, 그래프)]]></title>
            <link>https://velog.io/@just_do/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@just_do/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 25 Jul 2023 03:12:55 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-자료구조란">📌 자료구조란?</h2>
<blockquote>
<p><strong>자료구조</strong>란 다수의 <strong>자로(data)</strong>를 효율적으로 담기 위한 구조다.</p>
</blockquote>
<ul>
<li>자료구조는 다수의 <strong>자료(data)</strong>를 담기 위한 구조다.</li>
<li>데이터의 수가 많아질수록 효율적인 자료구조가 필요하다.</li>
</ul>
<h2 id="📌-자료구조의-필요성">📌 자료구조의 필요성</h2>
<ul>
<li>데이터를 효과적으로 저장하고, 처리하는 방법에 대해 바르게 이해할 필요가 있다.</li>
<li>자료구조를 제대로 이해하지 못하면 <strong>불필요하게 메모리와 계산을 낭비할 여지</strong>가 있다.</li>
<li>대부분의 자료구조는 <strong>특정한 상황에 놓인 문제를 해결</strong>하는 데에 특화되어 있다.</li>
</ul>
<h2 id="📌-자료구조의-종류">📌 자료구조의 종류</h2>
<p><img src="https://velog.velcdn.com/images/just_do/post/ecb43688-5a7f-4dab-ac11-02c80a023bfc/image.png" alt=""></p>
<h3 id="단순-구조primitive-data-structure">단순 구조(Primitive Data Structure)</h3>
<ul>
<li>프로그래밍에서 사용되는 기본 데이터 타입</li>
<li>JS의 원시타입에는 string, number, boolean, null, undefined 가 있다.</li>
</ul>
<h3 id="비단순-구조non-primitive-data-structure">비단순 구조(Non-Primitive Data Structure)</h3>
<ul>
<li>여러 데이터를 목적에 맞게 효과적으로 저장하는 자료구조</li>
<li>JS의 참조타입에는 Object, array, function이 있다.</li>
</ul>
<h3 id="선형-구조linear-data-structure">선형 구조(Linear Data Structure)</h3>
<p>하나의 데이터 뒤에 다른 데이터가 하나 존재하는 자료구조다.
데이터가 일렬로 연속적으로(순차적으로) 연결되어 있다.
저장된 자료의 전후 관계가 1:1이다.</p>
<h4 id="✅-배열array">✅ 배열(Array)</h4>
<p>가장 일반적인 구조이며, 메모리 상에 같은 타입의 자료가 연속적으로 저장된다. 자료값을 나타내는 가장 작은 단위가 자료를 다루는 단위이다.</p>
<h4 id="✅-연결-리스트linked-list">✅ 연결 리스트(Linked List)</h4>
<p>연결 리스트는 동적 데이터 구조이다. 1) value 와 2) pointer가 한 쌍인 노드가 모여있는 자료구조형을 의미한다. 아래 푸른색 부분이 data를 저장하고 있고, 초록색 부분은 다음 오느들 가리키는 pointer 역할을 하는 address 부분이다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/75ee152b-3d42-4e45-82f0-94f9871aa519/image.png" alt=""></p>
<h4 id="✅-스택stack">✅ 스택(Stack)</h4>
<p>스택은 마지막으로 삽입된 element가 가장 먼저 제거되는 방식(LIFO, Last In First Out)의 자료구조다. </p>
<p><img src="https://velog.velcdn.com/images/just_do/post/a5cc22f6-8f80-4b1e-a8aa-40ea31d174e9/image.png" alt=""></p>
<h4 id="✅-큐queue">✅ 큐(Queue)</h4>
<p>큐는 흔히 먼저 온 사람이 먼저 들어가는 대기줄과 비교한다. 가장 먼저 삽입된 element가 가장 먼저 제거되는 방식(FIFO, First In First Out)의 자료구조다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/e60bb318-5a63-4a69-9244-adb7f7258a58/image.png" alt=""></p>
<h3 id="비선형-구조non-linear-data-structure">비선형 구조(Non-Linear Data Structure)</h3>
<p>하나의 데이터 뒤에 다른 데이터가 여러 개 올 수 있는 자료구조다.
데이터가 일직선상으로 연결되어 있지 않아도 된다
데이터 항목 사이의 관계가 1:n이다.</p>
<h4 id="✅-트리tree">✅ 트리(Tree)</h4>
<p>트리는 부모 노드 밑에 여러 자식 노드가 연결되고, 자식 노드가 다시 부모 노드가 되어 각각의 자식 노드에게 연결되는 재귀적인 형식의 자료구조다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/ca890993-b281-4c9d-9d9c-a1000416ae20/image.png" alt=""></p>
<h4 id="✅-그래프graph">✅ 그래프(Graph)</h4>
<p>그래프는 각 노드들이 서로 연결되어 있는 자료구조다. 그래프는 노드(Node)와 간선(Edge)로 표현되며 이때 노드를 정점(Vertex)이라고도 한다. 그래프는 두 가지 방식으로 구현할 수 있다.</p>
<ul>
<li>인접 행렬(adjacency matrix): 2차원 배열을 사용하는 방식</li>
</ul>
<p><img src="https://velog.velcdn.com/images/just_do/post/683d2d04-2e3f-4aa3-bee4-e3a4a1185aaf/image.png" alt=""></p>
<ul>
<li>인접 리스트(adjacency list): 연결 리스트를 이용하는 방식</li>
</ul>
<p><img src="https://velog.velcdn.com/images/just_do/post/158fcd4d-2443-4b6a-9752-67e87b8b10e2/image.png" alt=""></p>
<h2 id="📌-자료구조와-알고리즘">📌 자료구조와 알고리즘</h2>
<ol>
<li>효율적인 자료구조 설계를 위해 알고리즘 지식이 필요하다.</li>
<li>효율적인 알고리즘을 작성하기 위해서 <strong>문제 상황에 맞는 적절한 자료구조</strong>가 사용되어야 한다.</li>
<li>프로그램을 작성할 때 자료구조와 알고리즘 모두 고려해야 한다.</li>
</ol>
<h2 id="📌-자료구조를-적절히-활용하기">📌 자료구조를 적절히 활용하기</h2>
<blockquote>
<p>대부분의 자료구조는 <strong>특정한 상황에 놓인 문제를 해결</strong>하는 데에 특화되어 있기 때문에 적절한 상황에 적절한 자료구조를 선택하면 효율적인 프로그램을 작성할 수 있다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 replace(), replaceAll() 차이]]></title>
            <link>https://velog.io/@just_do/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-replace-replaceAll-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@just_do/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-replace-replaceAll-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Wed, 19 Jul 2023 16:47:55 GMT</pubDate>
            <description><![CDATA[<p>백준 문제를 풀던 중 replace() 메서드를 쓰면 풀리지 않고 replaceAll() 메서드로 수정했을 때 풀리는 문제가 있어 둘의 차이를 이해하고 왜 문제에서 오답처리가 되었는지 알아보고자 한다.</p>
<h2 id="📌-백준-2941번-크로아티아-알파벳">📌 백준 2941번 크로아티아 알파벳</h2>
<p><a href="https://www.acmicpc.net/problem/2941">https://www.acmicpc.net/problem/2941</a></p>
<p><img src="https://velog.velcdn.com/images/just_do/post/5b1aed17-57ca-417f-931e-7431f07e13e8/image.png" alt=""></p>
<p>문제는 다음과 같이 입력으로 주어진 단어를 분석하여 알파벳의 길이를 출력하면 되는 문제다.</p>
<h2 id="📌-접근-방식-및-코드">📌 접근 방식 및 코드</h2>
<ol>
<li>크로아티아 알파벳을 배열에 정리한다.</li>
<li>입력 받은 알파벳에 크로아티아 배열을 하나씩 대입하여 아무 문자열로 변환한다.(길이만 뽑으면 되기 때문)</li>
</ol>
<pre><code class="language-javascript">// 2941 크로아티아 알파벳

let fs = require(&#39;fs&#39;);
let input = fs.readFileSync(&#39;index.txt&#39;).toString().trim().split(&#39;\n&#39;);

let arr = input[0]

let cro = [&quot;c=&quot;, &quot;c-&quot;, &quot;dz=&quot;, &quot;d-&quot;, &quot;lj&quot;, &quot;nj&quot;, &quot;s=&quot;, &quot;z=&quot;]

for (let i = 0; i &lt;cro.length; i++){
  arr = arr.replaceAll(cro[i], &quot;/&quot;) // replaceAll 대신 replace 사용 시 오답
}

console.log(arr.length)
console.log(arr)</code></pre>
<p>그런데 여기서 replaceAll 메서드 대신 replace 메서드를 사용 시 오답처리 된다. 처음에는 이해가 안 갔지만 찾아보니 너무 당연한 오답이었다.</p>
<h2 id="📌-replace-replaceall-차이">📌 replace(), replaceAll() 차이</h2>
<blockquote>
<p>replace() 메서드는 해당 문자열을 <strong>한 번만</strong> 찾아 변경하고 replaceAll()은 해당하는 문자열을 <strong>모두</strong> 찾아 치환한다.</p>
</blockquote>
<h3 id="replace">replace()</h3>
<p>다른 언어에 반해 자바스크립트는 replace first 방식을 선택하여 replace() 메서드를 사용 시 첫 번째 치환 대상을 발견 시 <strong>한 번만 치환하고 메서드를 종료한다.</strong></p>
<pre><code class="language-javascript">let str = &#39;ab?c?&#39;
str = str.replace(&quot;?&quot;, &quot;@&quot;) // ab@c?</code></pre>
<h3 id="replaceall">replaceAll()</h3>
<p>ECMA-262 12th(2021) 스펙을 기준으로 replaceAll() 기능이 추가되어 최신 자바스크립트 엔진에서는 replaceAll() 메서드를 사용할 수 있다. replaceAll() 메서드는 <strong>변환 대상을 모두 찾아 치환한다.</strong></p>
<pre><code class="language-javascript">let str = &#39;ab?c?&#39;
str = str.replaceAll(&quot;?&quot;, &quot;@&quot;) // ab@c@</code></pre>
<h2 id="📝-replace-를-replaceall처럼-사용하는-법정규표현식">📝 replace() 를 replaceAll()처럼 사용하는 법(정규표현식)</h2>
<blockquote>
<p>replace() 메서드의 첫 번째 매개변수로 정규표현식을 사용할 수 있는데 이를 통해 replaceAll() 메서드처럼 사용이 가능하다.</p>
</blockquote>
<pre><code class="language-javascript">let str = &#39;ab?c?&#39;
str = str.replace(/\?/g, &quot;@&quot;) // ab@c@</code></pre>
<p>위 코드처럼 첫 번째 매개변수에 정규표현식을 사용하면 replaceAll() 메서드처럼 사용할 수 있다. 정규표현식을 해석하면 // 안에 있는 &quot;?&quot;(&quot;?&quot;를 찾고 싶은데 그냥 ?(물음표)나 &quot;(따옴표)등을 문자열 취급하기 위해 앞에 \기호를 붙여준다)를 전역에서 찾는다는 뜻이다. 정규표현식 예제는 아래있다.</p>
<h3 id="정규-표현식-예제">정규 표현식 예제</h3>
<ul>
<li>/searchvalue/ :  &#39;/ /&#39; 사이에 검색할 문자를 입력</li>
<li>searchvalue1 | searchvalue2 | ... :  여러개의 문자를 바꾸도 싶은 경우&#39; | &#39; 로 구분하여 여러 문자 입력</li>
<li>g :  발생할 모든 패턴에 대한 전역 검색 (Global search)</li>
<li>i :  대/소문자 구분을 무시 (Case-insensitive search)</li>
<li>m :  여러줄 검색 (Multi-line search)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 7장 [연산자]]]></title>
            <link>https://velog.io/@just_do/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-7%EC%9E%A5-%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@just_do/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-7%EC%9E%A5-%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Tue, 18 Jul 2023 09:56:57 GMT</pubDate>
            <description><![CDATA[<h1 id="💻-7장-연산자">💻 7장 연산자</h1>
</br>

<h2 id="1️⃣-요약">1️⃣ 요약</h2>
<blockquote>
<p> <strong>연산자[operator]</strong>는 하나 이상의 표현식을 대상으로 <strong>산술, 할당, 비교, 논리, 타입, 지수 연산 등</strong>을 수행해 하나의 값을 만든다. 이때 연산의 대상을 <strong>피연산자[operand]</strong>라 한다.</p>
</blockquote>
</br>

<h2 id="2️⃣-정리">2️⃣ 정리</h2>
<h3 id="📌-71-산술-연산자">📌 7.1 산술 연산자</h3>
<blockquote>
<p><strong>산술 연산자</strong>는 피연산자를 대상으로 수학적 계산을 수행해 새로운 숫자 값을 만든다. 산술 연산이 불가능한 경우, <strong>NaN</strong>을 반환한다.</p>
</blockquote>
<h4 id="711-이항-산술-연산자">7.1.1 이항 산술 연산자</h4>
<p>2개의 피연산자를 산술 연산하여 숫자 값을 반환한다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/38b86055-a39e-4f61-a362-14787adff6bf/image.png" alt=""></p>
<h4 id="712-단항-산술-연산자">7.1.2 단항 산술 연산자</h4>
<p>1개의 피연산자를 산술 연산하여 숫자 값을 만든다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/f6e9c8bf-ae3b-468b-930d-862604db9dad/image.png" alt=""></p>
<h4 id="713-문자열-연결-연산자">7.1.3 문자열 연결 연산자</h4>
<p><strong>+ 연산자</strong>는 피연산자 중 하나 이상이 문자열인 경우 문자열 연결 연산자로 동작한다.</p>
<pre><code class="language-javascript">// 문자열 연결 연산자
&#39;1&#39; + 2; // -&gt; &#39;12&#39;
1 + &#39;2&#39;; // -&gt; &#39;12&#39;</code></pre>
<br/>


<h3 id="📌-72-할당-연산자">📌 7.2 할당 연산자</h3>
<blockquote>
<p><strong>할당 연산자</strong>는 우항에 있는 피연산자의 평가 결과를 좌항에 있는 변수에 할당한다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/just_do/post/f19cde89-f285-4fbf-aed9-926fff69a7d0/image.png" alt=""></p>
</br>


<h3 id="📌-73-비교-연산자">📌 7.3 비교 연산자</h3>
<blockquote>
<p><strong>비교 연산자</strong>는 좌항과 우항의 피연산자를 비교한 다음 그 결과를 <strong>불리언 값</strong>으로 반환한다.</p>
</blockquote>
<h4 id="731-동등일치-비교-연산자">7.3.1 동등/일치 비교 연산자</h4>
<p>동등 비교 연산자와 일치 비교 연산자는 좌항과 우항의 피연산자가 같은 값으로 평가되는지 비교해 불리언 값을 반환한다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/32a3a917-4352-49f6-a5fa-e7167d1d5957/image.png" alt=""></p>
<ul>
<li>동등 비교(==)
좌항과 우항의 피연산자를 비교할 때 먼저 암묵적으로 반환을 통해 <strong>타입을 일치시킨 후 같은 값인지 비교한다.</strong></li>
</ul>
<pre><code class="language-javascript">// 동등 비교
5 == &#39;5&#39;; // true</code></pre>
<ul>
<li>일치 비교(===)
좌항과 우항의 피연산자가 <strong>타입도 같고 값도 같은 경우</strong>에 한하여 true를 반환한다.</li>
</ul>
<pre><code class="language-javascript">// 일치 비교
5 === &#39;5&#39;; // false</code></pre>
<h4 id="732-대소-관계-비교-연산자">7.3.2 대소 관계 비교 연산자</h4>
<p>피연산자의 크기를 비교하여 불리언 값을 반환한다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/a22f8e36-65d9-4ef9-bc10-bb8187432dd6/image.png" alt=""></p>
</br>

<h3 id="📌-74-삼항-조건-연산자">📌 7.4 삼항 조건 연산자</h3>
<blockquote>
<p>__ 조건 연산자__조건식의 평가 결과에 따라 반환할 값을 결정한다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/just_do/post/0d9ff434-6c85-4588-bdb3-84c0c7b8b4dd/image.png" alt=""></p>
<p>삼항 조건 연산자 표현식은 값으로 평가할 수 있는 표현식인 문이다. 따라서 삼항 조건 연산자 표현식은 값처럼 다른 표현식의 일부가 될 수 있어 유용하다.</p>
</br>


<h3 id="📌-75-논리-연산자">📌 7.5 논리 연산자</h3>
<blockquote>
<p><strong>논리 연산자</strong>는 좌항의 피연산자(부정 논리 연산자의 경우 우항의 피연산자)를 논리 연산한다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/just_do/post/7e5aa156-1eb9-4672-9419-4a7ba5bd7dd9/image.png" alt=""></p>
<pre><code class="language-javascript">// 논리합(||) 연산자
true || true;   // -&gt; true
true || false;  // -&gt; true
false || true;  // -&gt; true
false || false; // -&gt; false

// 논리곱(&amp;&amp;) 연산자
true &amp;&amp; true;   // -&gt; true
true &amp;&amp; false;  // -&gt; false
false &amp;&amp; true;  // -&gt; false
false &amp;&amp; false; // -&gt; false

// 논리 부정(!) 연산자
!true;  // -&gt; false
!false; // -&gt; true</code></pre>
<p>논리합(||) 또는 논리곱(&amp;&amp;) 연산자 표현식의 평가 결과는 불리언 값이 아닐 수도 있다. 논리합(||) 또는 노리곱(&amp;&amp;) 연산자 표현식은 언제나 2개의 피연사 중 어느 한쪽으로 평가된다.</p>
<pre><code class="language-javascript">// 단축 평가
&#39;Cat&#39; &amp;&amp; &#39;Dog&#39;; // -&gt; &#39;Dog&#39;</code></pre>
</br>

<h3 id="📌-76-쉼표-연산자">📌 7.6 쉼표 연산자</h3>
<blockquote>
<p><strong>쉼표(,) 연산자</strong>는 왼쪽 피연산자부터 차례대로 피연산자를 평가하고 마지막 피연산자의 평가가 끝나면 마지막 피연산자의 평가 결과를 반환한다.</p>
</blockquote>
<pre><code class="language-javascript">var x, y, z;

x = 1, y = 2, z = 3; // 3</code></pre>
</br>

<h3 id="📌-77-그룹-연산자">📌 7.7 그룹 연산자</h3>
<blockquote>
<p><strong>소괄호(&#39;()&#39;)</strong>로 연산자를 감싸는 그룹 연산자는 자신의 피연산자인 표현식을 가장 먼저 평가한다.</p>
</blockquote>
<pre><code class="language-javascript">10 * 2 + 3; // -&gt; 23

// 그룹 연산자를 사용하여 우선순위를 조절
10 * (2 + 3); // -&gt; 50</code></pre>
</br>


<h3 id="📌-78-typeof-연산자">📌 7.8 typeof 연산자</h3>
<blockquote>
<p><strong>typeof 연산자</strong>는 피연산자의 데이터 타입을 문자열로 반환한다.</p>
</blockquote>
<pre><code class="language-javascript">typeof &#39;&#39;              // -&gt; &quot;string&quot;
typeof 1               // -&gt; &quot;number&quot;
typeof NaN             // -&gt; &quot;number&quot;
typeof true            // -&gt; &quot;boolean&quot;
typeof undefined       // -&gt; &quot;undefined&quot;
typeof Symbol()        // -&gt; &quot;symbol&quot;
typeof null            // -&gt; &quot;object&quot;
typeof []              // -&gt; &quot;object&quot;
typeof {}              // -&gt; &quot;object&quot;
typeof new Date()      // -&gt; &quot;object&quot;
typeof /test/gi        // -&gt; &quot;object&quot;
typeof function () {}  // -&gt; &quot;function&quot;</code></pre>
</br>

<h3 id="📌-79-지수-연산자">📌 7.9 지수 연산자</h3>
<blockquote>
<p><strong>지수 연산자</strong>는 좌항의 피연산자를 밑으로, 우항의 피연산자를 지수로 거듭 제곱하여 숫자 값을 반환한다.</p>
</blockquote>
<pre><code class="language-javascript">2 ** 2;   // -&gt; 4
2 ** 2.5; // -&gt; 5.65685424949238
2 ** 0;   // -&gt; 1
2 ** -2;  // -&gt; 0.25</code></pre>
</br>

<h3 id="📌-710-그-외의-연산자">📌 7.10 그 외의 연산자</h3>
<p>이외에 다양한 연산자가 있으나, 다른 장에서 설명한다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/e0996d92-917b-4c88-9273-e074e22c2351/image.png" alt=""></p>
</br>

<h3 id="📌-711-연산자의-부수-효과">📌 7.11 연산자의 부수 효과</h3>
<blockquote>
<p>대부분의 연산자는 다른 코드에 영향을 주지 않는다. 하지만 <strong>할당 연산자(=), 증가/감소 연산자(++/--), delete 연산자는 부수효과가 있다.</strong></p>
</blockquote>
<pre><code class="language-javascript">var x;

// 할당 연산자는 변수 값이 변하는 부수 효과가 있다.
// 이는 x 변수를 사용하는 다른 코드에 영향을 준다.
x = 1;
console.log(x); // 1

// 증가/감소 연산자(++/--)는 피연산자의 값을 변경하는 부수 효과가 있다.
// 피연산자 x의 값이 재할당되어 변경된다. 이는 x 변수를 사용하는 다른 코드에 영향을 준다.
x++;
console.log(x); // 2

var o = { a: 1 };

// delete 연산자는 객체의 프로퍼티를 삭제하는 부수 효과가 있다.
// 이는 o 객체를 사용하는 다른 코드에 영향을 준다.
delete o.a;
console.log(o); // {}</code></pre>
</br>

<h3 id="📌-712-연산자-우선순위">📌 7.12 연산자 우선순위</h3>
<blockquote>
<p><strong>연산자 우선순위</strong>란 여러 개의 연산자로 이뤄진 문이 실행될 때 연산자가 실행되는 순서를 말한다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/just_do/post/142acd0a-5395-4975-98c8-42ed4b5bae76/image.png" alt=""></p>
<p>연산자는 종류가 많아서 연산자 우선순위를 모두 기억하기 어렵고 실수하기도 쉽다. 따라서 기억에 의존하기보다는 연산자 우선순위가 가장 높은 그룹 연산자를 사용하여 우선순위를 명시적으로 조절하는 것을 권장한다.</p>
</br>

<h3 id="📌-713-연산자-결합-순서">📌 7.13 연산자 결합 순서</h3>
<blockquote>
<p><strong>연산자 결합 순서</strong>란 연산자의 어느 쪽(좌항 또는 우항)부터 평가를 수행할 것인지를 나타내는 순서를 말한다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/just_do/post/cf26e7d3-8420-47b3-83fb-757cfa336811/image.png" alt=""></p>
<p>연산자는 종류가 많아서 연산자 우선순위를 모두 기억하기 어렵고 실수하기도 쉽다. 따라서 기억에 의존하기보다는 연산자 우선순위가 가장 높은 그룹 연산자를 사용하여 우선순위를 명시적으로 조절하는 것을 권장한다.</p>
</br>

<h2 id="3️⃣-마무리">3️⃣ 마무리</h2>
<p>새롭거나 어려운 부분은 많이 없지만 용어 정리를 하는 장이라고 생각하고, 삼항 연산자는 자주 쓸 것 같으니 기억하자</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[나는 어떤 개발자가 되고 싶은가? [벨로그 리뷰]]]></title>
            <link>https://velog.io/@just_do/%EB%82%98%EB%8A%94-%EC%96%B4%EB%96%A4-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EB%90%98%EA%B3%A0-%EC%8B%B6%EC%9D%80%EA%B0%80-%EB%B2%A8%EB%A1%9C%EA%B7%B8-%EB%A6%AC%EB%B7%B0</link>
            <guid>https://velog.io/@just_do/%EB%82%98%EB%8A%94-%EC%96%B4%EB%96%A4-%EA%B0%9C%EB%B0%9C%EC%9E%90%EA%B0%80-%EB%90%98%EA%B3%A0-%EC%8B%B6%EC%9D%80%EA%B0%80-%EB%B2%A8%EB%A1%9C%EA%B7%B8-%EB%A6%AC%EB%B7%B0</guid>
            <pubDate>Sun, 16 Jul 2023 16:04:08 GMT</pubDate>
            <description><![CDATA[<p><a href="https://velog.io/@eddy_song/problem-solver">&#39;안 돼요&#39;라고 말하지 않는다 - eddy_song</a></p>
<p>오늘 커리어리를 천천히 읽고 있다가 좋은 글을 발견해서 나의 생각을 정리하는 시간을 가져보고자 한다. 위 글의 주요 내용은 <strong>뛰어난 개발자</strong>란 어떤 사람인지 현업에서 일하시는 디자이너, PM, QA 분들께 인터뷰를 통해 알아보고 공통점을 찾아 정리한 글이다. 그래서 비전공자로 시작하는 내가 어떻게 하면 개발자로서 살아남고(?) 성장할 수 있을지 고민하던 내겐 인상깊은 글이었다.</p>
<blockquote>
<p>긴 글을 짧게 정리하자면 현직자들이 생각하는 뛰어난 개발자란 &quot;<strong>커뮤니케이션을 잘 하는 개발자</strong>&quot;라고 한다.</p>
</blockquote>
</br>

<h2 id="📌-커뮤니케이션을-잘-하는-개발자란">📌 커뮤니케이션을 잘 하는 개발자란?</h2>
<p>글에서는 개발자의 유형을 둘로 나눴다.</p>
<p><strong>문제 해결형 개발자</strong> vs <strong>스펙 구현형 개발자</strong></p>
<p><img src="https://velog.velcdn.com/images/just_do/post/447f13cd-334c-49eb-ada3-65ba56dfd7f0/image.png" alt=""></p>
<h3 id="📝-문제-해결형-개발자">📝 문제 해결형 개발자</h3>
<p>문제 해결형 개발자는 &#39;안 된다&#39;라는 말을 그냥 하지 않는 것이라고 한다.
요구 사항이 있을 때 예스맨이 되라는 것이 아닌 요구 사항이 풀려고 하는 문제가 무엇인지 더 나은 해결 방법이 없는지 고민하고 새로운 솔루션을 제안해보는 개발자를 말한다.</p>
<p>정리해보면 그냥 개발만 하는 개발자가 아닌 함께 문제를 해결해나가는 구성원이 되자는 의미로 나는 해석하였다.</p>
<h3 id="📝-스펙-구현형-개발자">📝 스펙 구현형 개발자</h3>
<p>작성자 분이 들어준 예시로 QA 분꼐서 로그랑 파라미터를 정의해 개발자에게 전달했는데 개발자의 대답은 이랬다.</p>
<blockquote>
<p>아 그거는 스트림에서 비동기로 받아 온 거라서 서버 api 구조를 바꾸지 않으면 이 화면에서 찍는 거는 안 된다</p>
</blockquote>
<p>아직 공부가 미흡한 나도 사실 무슨 말인지 잘 이해가 안 된다.(더 열심히 공부해야겠다.)</p>
<p>그래서 이 답변과 함께 쓰레드가 끝이 났다고 한다. </p>
<p>이런 개발자들의 특징은 자신은 엔지니어니까 주어진 스펙을 만들어내고 디버깅하고 테스트해서 버그가 없도록 하는 게 그들의 임무이며 요구사항을 만드는 건 기획자나 디자이너가 할 일이라고 생각한다는 것이다.</p>
<p>여기까지가 작성자 분께서 설명하시는 <strong>문제 해결형 개발자</strong>와 <strong>스펙 구현형 개발자</strong>에 관한 설명이다. 동료로서 신뢰가 쌓이고 &quot;일 잘 하는 개발자&quot; 그리고 &quot;같이 일하고 싶은 개발자&quot;로 생각되는 사람은 <strong>문제 해결형 개발자</strong>라고 한다. </p>
<p>사실 어떤 개발자가 옳고 그른지 혹은 지향해야 할 개발자인지는 아직 잘 판단이 서지 않지만 글을 읽고 평소 생각을 더해 나는 어떤 개발자가 되고 싶은지 정리를 해보려고 한다.</p>
<h2 id="📌-나는-어떤-개발자가-될-것인가">📌 나는 어떤 개발자가 될 것인가?</h2>
<h3 id="❗️-나는-비전공자다">❗️ 나는 비전공자다.</h3>
<p>나는 경영정보학부생으로서 학사과정(졸업도 아직 못 했다.) 에서 아주 간단한 언어나 데이터 분야에 관한 공부는 조금 해보았지만사실상 <strong>비전공자로서 올해부터 진지하게 개발자의 길을 걷기 시작했다.</strong> 그래서 항상 전공자보다 더 열심히 해야 한다는 마음가짐과 개발자로서 살아남을 수 있는 방법에 관한 고민을 많이 했다. </p>
<p>고민 끝에 나온 결론은 나만의 강점을 만들고 넓은 인사이트로 소통을 잘 할 수 있는 개발자가 돼야 한다는 것이다. 그래서 이 글을 읽었을 때 그냥 평범한 개발자로서 경쟁한다면 언젠가는 경험이 더 많거나 혹은 전공자에게 밀릴 확률이 높겠다는 생각이 들어 나는 <strong>문제 해결형 개발자</strong>가 되도록 더욱 노력해야겠다는 생각이 들었다. </p>
<h3 id="❓-어떻게-문제-해결형-개발자가-될-수-있는데">❓ 어떻게 문제 해결형 개발자가 될 수 있는데?</h3>
<p>일단 글을 읽고 생각한 <strong>문제 해결형 개발자</strong>란 나의 개발 역량을 활용하여 구성원과 함께 문제를 해결하는 <strong>Problem-Solver</strong>라고 생각했다.</p>
<p>그러면 문제를 해결하기 위해서는 어떤 게 필요할까? 먼저 함께 문제를 풀어나가는 과정에서 <strong>내 역할은 개발자</strong>다. 그렇기 때문에 내 개발 역량을 키우는 것이 가장 선행되어야 할 과제이다. 그리고 <strong>다양한 프로젝트 혹은 경험들을 통해 소통하는 법을 익히고 많고 새로운 시도들을 통해 문제 해결 능력</strong>을 길러야 한다.</p>
<h3 id="❗️-결론">❗️ 결론</h3>
<p>그래서 너가 되고 싶은 개발자는 뭔데?라는 질문에 대한 답은 <strong>뛰어난 개발 역량을 지니고 넓은 인사이트도 가진 Problem-Solver다.</strong></p>
<h2 id="📌-앞으로의-계획">📌 앞으로의 계획</h2>
<p>현재 진행 중인 부트캠프 <strong>&quot;야놀자X패스트캠퍼스: 프론트엔드&quot;</strong>과정을 성공적으로 마치며 과정도 꼼꼼히 기록하고 특히 진행하는 프로젝트에서 협업을 위해 노력할 것이다.</p>
<p>마직막으로 참고 글의 작성자 분의 유튜브 링크도 남깁니다.
<a href="https://www.youtube.com/watch?v=fe6_wCixJwE">https://www.youtube.com/watch?v=fe6_wCixJwE</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Node.js 이해하기 ]]></title>
            <link>https://velog.io/@just_do/NodeJS-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@just_do/NodeJS-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 14 Jul 2023 11:29:47 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-nodejs-란">📌 Node.js 란?</h2>
<blockquote>
<p>Node.js는 Chrome V8 JavaScript 엔진으로 빌드된 <strong>JavaScript 런타임</strong>이다.</p>
</blockquote>
<p>즉, 노드를 통해 다양한 자바스크립트 애플리케이션을 실행할 수 있고, 그 중 <strong>서버</strong>를 실행하는데 가장 많이 사용된다.</p>
<p>기존 웹 브라우저에서만 실행되던 <strong>JavaScript를 서버 측에서 실행할 수 있게 해줘</strong> 웹 개발을 진행할 때 웹에서 표시되는 부분은 JavaScript를 사용하여 만들어야 하고 서버는 Ruby, Java 등 다른 언어를 사용해야 했던 문제를 <strong>JavaScript 하나로 프론트와 백을 모두 개발할 수 있는 환경을 만들었다.</strong></p>
<p>노드는 비동기식 이벤트 기반 아키텍처를 사용하여 많은 수의 동시 연결을 처리할 수 있고, 확장성과 성능이 뛰어나다. 이를 통해 JavaScript를 사용하여 <strong>웹 서버, 웹 애플리케이션</strong> 등을 개발할 수 있다. 노드는 NPM(Node Package Manager)을 포함하고 있어 다양한 외부 모듈과 라이브러리를 활용할 수 있으며, 많은 개발자와 커뮤니티의 지원을 받고 있다.
<br/></p>
<h2 id="📌-nodejs-특징">📌 Node.js 특징</h2>
<h3 id="1-자바스크립트-런타임">1. 자바스크립트 런타임</h3>
<ul>
<li><strong>런타임</strong>이란 특정 언어로 만든 프로그램을 실행할 수 있는 <strong>환경</strong>을 뜻한다. </li>
<li>즉, 자바스크립트 언어로 만든 프로그램을 실행할 수 있는 환경을 <strong>자바스크립트 런타임</strong>이라 한다.</li>
<li>노드를 사용하기 위해선 JavaScript 언어를 이해해야 한다.</li>
</ul>
<h3 id="2-이벤트-기반">2. 이벤트 기반</h3>
<ul>
<li><strong>이벤트 기반</strong>이란 이벤트가 발생할 때 미리 지정해둔 작업을 수행하는 방식을 의미한다.</li>
<li>이벤트 기반 모델에서는 <strong>이벤트 루프</strong>라는 개념이 등장한다. 여러 이벤트가 동시에 발생했을 때 어떤 순서로 콜백 함수를 호출할지를 이벤트 루프가 판단한다.</li>
<li>즉, 특정 이벤트가 발생할 때 무엇을 할지 미리 등록해두고, 이벤트가 발생하면 이벤트 리스너의 콜백함수를 호출하고, 이벤트가 끝난 후 노드는 다음 이벤트를 기다린다.</li>
</ul>
<h3 id="3-이벤트-루프">3. 이벤트 루프</h3>
<ul>
<li>이벤트 루프는 여러 이벤트가 동시에 발생했을 때 어떤 순서로 콜백함수를 호출 할지를 판단한다.
<img src="https://velog.velcdn.com/images/just_do/post/a264ef9a-f724-4512-9f7d-5ac1bc06b5a0/image.png" alt=""></li>
</ul>
<h3 id="4-논-블로킹-io">4. 논 블로킹 I/O</h3>
<ul>
<li><strong>논 블로킹</strong>이란 이전 작업이 완료될 때까지 대기하지 않고 작업을 수행한다는 뜻이다.</li>
<li>반대로 <strong>블로킹</strong>이란 이전 작업이 끝나야만 다음 작업을 수행하느 것을 의미한다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/just_do/post/061a24d2-310d-4b87-beee-877e763a38b2/image.png" alt=""></p>
<h3 id="5-싱글-스레드">5. 싱글 스레드</h3>
<p>이벤트 기반, 논 블로킹 모델과 더불어 노드를 설명하는 키워드 중 하나는 싱글 스레드이다.자바스크립트 코드는 동시에 실행될 수 없는데 그 이유는 노드가 싱글 스레드 기반이기 때문이다. 스레드를 이해하기 위해선 프로세스부터 알아야 한다.</p>
<ul>
<li><strong>프로세스</strong>는 운영체제에서 할당하는 작업의 단위다. 노드나 웹 브라우저 같은 프로그램은 개별적인 프로세스다. 프로세스 간에는 메모리 등의 자원을 공유하지 않는다.</li>
<li><strong>스레드</strong>는 프로세스 내에서 실행되는 흐름의 단위다. 프로세스는 스레드를 여러 개 생성해 여러 작업을 동시에 처리할 수 있다. 스레드들은 부모 프로세스의 자원을 공유한다. 같은 주소의 메모리에 접근 가능하므로 데이터를 공휴할 수 있다.</li>
</ul>
<p>노드는 싱글 스레드, 논 블로킹 방식 모델을 사용한다.</p>
<h2 id="📌-마무리">📌 마무리</h2>
<p>Node.js는 싱글 스레드, 논 블로킹 모델을 사용하여 작성한 코드를 하나의 스레드로 실행하기 때문에 무거운 코드를 실행할 때 성능이 저하될 수 있다. 하지만 I/O 작업과 같은 가볍지만 많은 요청을 수행할 때는 적합한 모델이기 때문에 웹 서버로서 채택되어지고 있다. 웹과 실시간으로 소통하는 서버 개발에 특화되어있다.</p>
<p>결론적으로 적은 컴퓨터 자원으로 많은 I/O 요청 작업에 특화되었고, 자바스크립트 언어로 풀스택 개발을 가능하게 해준다는 장점을 가지고 있어 꾸준히 관심을 받을 모델인 것 같다. 아직 백엔드에 관한 지식이 부족해 가볍게 알아보았지만 깊게 공부한다면 나중에 활용도가 매우 높은 지식일 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 6장 [데이터 타입]]]></title>
            <link>https://velog.io/@just_do/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-6%EC%9E%A5</link>
            <guid>https://velog.io/@just_do/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-6%EC%9E%A5</guid>
            <pubDate>Thu, 13 Jul 2023 16:10:44 GMT</pubDate>
            <description><![CDATA[<h1 id="💻-6장-데이터-타입">💻 6장 데이터 타입</h1>
</br>

<h2 id="1️⃣-요약">1️⃣ 요약</h2>
<blockquote>
<p> 데이터타입(줄여서 ‘타입’이라고도 한다.)은 값의 종류를 말한다. <strong>자바스크립트(ES6)는 7개의 데이터 타입을 제공한다.</strong> 그리고 자바스크립트의 변수는 선언이 아닌 <strong>할당에 의해 타입이 결정(타입 추론)</strong>된다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/just_do/post/f160c19d-aefb-4e79-b53f-7b702f94a8fe/image.png" alt=""></p>
</br>

<h2 id="2️⃣-정리">2️⃣ 정리</h2>
<h3 id="📌-61-숫자-타입">📌 6.1 숫자 타입</h3>
<blockquote>
<p><strong>자바스크립트는</strong> C나 자바와 달리 정수와 실수를 구분해서 init, long, float, double 등과 같은 다양한 숫자 타입을 제공하지 않고 <strong>하나의 숫자 타입만 존재한다.</strong></p>
</blockquote>
<ul>
<li>2진수, 8진수 16진수를 표현하기 위한 데이터 타입을 제공하지 않기 때문에 이들 값을 참조하면 모두 10진수로 해석한다.</li>
</ul>
<pre><code class="language-javascript">var bianary = 0b01000001; // 2진수
var octal = 0o101;        // 8진수
var hex = 0x41;           // 16진수

// 표기법만 다를 뿐 모두 같은 값이다.
console.log(binary); // 65
console.log(octal); // 65
console.log(hex); // 65
console.log(binary === octal); // true
console.log(octal === hex); // true</code></pre>
<ul>
<li>숫자 타입은 모두 실수로 처리된다.</li>
</ul>
<pre><code class="language-javascript">console.log(1 === 1.0); // true</code></pre>
<ul>
<li>숫자 타입의 3가지 특별한 값</li>
</ul>
<pre><code class="language-javascript">console.log(10 / 0); // Infinity
console.log(10 / -0); // -Infinity
console.log(1 * &#39;String&#39;); // NaN</code></pre>
<br/>


<h3 id="📌-62-문자열-타입">📌 6.2 문자열 타입</h3>
<blockquote>
<p>문자열은 작은따옴표(’’), 큰따옴표(””), 백틱(``)으로 텍스트를 감싼다.</p>
</blockquote>
<ul>
<li>따옴표로 감싸지 않은 문자는 식별자로 인식한다.</li>
</ul>
<pre><code class="language-javascript">var string = hello; // ReferenceError: hello is not defined</code></pre>
</br>


<h3 id="📌-63-템플릿-리터럴">📌 6.3 템플릿 리터럴</h3>
<blockquote>
<p>템플릿 리터럴은 멀티라인 문자열, 표현식 삽입, 태그드 문자열 등 편리한 문자열 처리 기능을 제공한다. <strong>템플릿 리터럴은 백틱(``)을 사용해 표현한다</strong></p>
</blockquote>
<pre><code class="language-javascript">var first = &#39;Ung-mo&#39;;
var last = &#39;Lee&#39;;

console.log(&#39;My name is&#39; + first + &#39; &#39; + last + &#39;.&#39;); // My name is Ung-mo Lee.

console.log(`My name is ${first} ${last}.`);          // My name is Ung-mo Lee.</code></pre>
<ul>
<li>일반 문자열 내에서는 줄바꿈(개행)이 허용되지 않아 이스케이프 시퀀스를 사용한다.</li>
</ul>
<pre><code class="language-javascript">var str = `Hello
world.;
//SyntaxError: Invalid or unexpected token</code></pre>
<p><img src="https://velog.velcdn.com/images/just_do/post/5abeee75-0631-4829-ad74-84f91ba60fe1/image.png" alt=""></p>
<ul>
<li>표현식을 삽입하려면 ${}으로 표현식을 삽입한다.</li>
</ul>
<pre><code class="language-javascript">var first = &#39;Ung-mo&#39;;
var last = &#39;Lee&#39;;

// ES6: 표현식 삽입
console.log(`My name is ${first} ${last}.`); // My name is Ung-mo Lee.</code></pre>
</br>

<h3 id="📌-64-불리언-타입">📌 6.4 불리언 타입</h3>
<blockquote>
<p>논리적 참, 거짓을 나타내는 true, false 값을 말한다.</p>
</blockquote>
</br>


<h3 id="📌-65-undefined-타입">📌 6.5 undefined 타입</h3>
<blockquote>
<p>undefined 타입의 값은 undefined가 유일하다. var 키워드를 선언한 변수는 암묵적으로 undefined로 초기화된다.</p>
</blockquote>
</br>

<h3 id="📌-66-null-타입">📌 6.6 null 타입</h3>
<blockquote>
<p>null 타입은 null이 유일하다. 자바스크립트는 대소문자를 구분하므로 null은 Null, NULL 등과 다르다.</p>
</blockquote>
</br>

<h3 id="📌-67-심벌-타입">📌 6.7 심벌 타입</h3>
<blockquote>
<p>변경 불가능한 원시 타입의 값이다. 심벌 값은 다른 값과 중복되지 않는 유일무이한 값이다. </p>
</blockquote>
</br>


<h3 id="📌-68-객체-타입">📌 6.8 객체 타입</h3>
<blockquote>
<p>자바스크립트는 객체 기반의 언어이며, <strong>자바스크립트를 이루고 있는 거의 모든 것이 객체라는 것이다.</strong></p>
</blockquote>
</br>

<h3 id="📌-69-데이터-타입의-필요성">📌 6.9 데이터 타입의 필요성</h3>
<blockquote>
<p>값은 메모리에 저장하고 참조할 수 있어야 하는데 메모리에 값을 저장하려면 먼저 <strong>확보해야 할 메모리 공간의 크기를 결정</strong>해야 한다. 이 과정에서 <strong>데이터 타입이 설정</strong> 되어야 메모리 공간 낭비와 손실 없이 값을 저장할 수 있는지 알 수 있다. 또한 <strong>참조하는 과정</strong>에서 데이터 타입을 알아야 <strong>훼손되지 않은 값을 얻을 수 있다.</strong> </p>
</blockquote>
<ul>
<li>값을 저장할 때 확보해야 하는 <strong>메모리 공간의 크기</strong>를 결정하기 위해</li>
<li>값을 참조할 때 한 번에 읽어 들여야 할 <strong>메모리 공간의 크기</strong>를 결정하기 위해</li>
<li>메모리에서 읽어 들인 <strong>2진수를 어떻게 해석</strong>할지 결정하기 위해</li>
</ul>
</br>

<h3 id="📌-610-동적-타이핑">📌 6.10 동적 타이핑</h3>
<blockquote>
<p>자바스크립트의 변수는 선언이 아닌 할당에 의해 타입이 결정(타입 추론)된다. 그리고 재할당에 의해 변수의 타입은 언제든지 동적으로 변할 수 있다. 이러한 특징을 <strong>동적 타이핑</strong>이라하며 이러한 언어를 <strong>동적 타입 언어</strong>라 한다.</p>
</blockquote>
<pre><code class="language-javascript">var foo;
console.log(typeof foo);  // undefined

foo = 3;
console.log(typeof foo);  // number

foo = &#39;Hello&#39;;
console.log(typeof foo);  // string

foo = true;
console.log(typeof foo);  // boolean

foo = null;
console.log(typeof foo);  // object

foo = Symbol();
console.log(typeof foo);  // symbol</code></pre>
<ul>
<li>동적 타입 언어는 유연성이 높지만 신뢰성이 떨어진다는 단점이 있다.</li>
</ul>
</br>

<h2 id="3️⃣-마무리">3️⃣ 마무리</h2>
<p>동적 타입 언어 자바스크립트에 대해 공부하며 TypeScript의 유용성이 궁금해지기 시작했다. 머지 않아 TypeScript를 공부하게 될 텐데 타입 선언의 중요성을 인지하며 공부를 해야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Github 이해하기 3(Git Flow)]]></title>
            <link>https://velog.io/@just_do/Github-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-3Git-Flow</link>
            <guid>https://velog.io/@just_do/Github-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-3Git-Flow</guid>
            <pubDate>Thu, 13 Jul 2023 15:46:54 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-git-flow-란">📌 Git Flow 란?</h2>
<blockquote>
<p>현업에서 사용하는 <strong>브랜치 관리 전략</strong> 중 하나로 큰 규모의 팀, 퀄리티 보장이 중요한 프로젝트, release 된 프로덕트에 대한 관리 사이클이 긴 경우 유용한 전략이다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/just_do/post/8dcbb66a-85d3-4ef9-9fbd-62763e39ab3c/image.png" alt=""></p>
<p>(사진 출처: <a href="https://www.youtube.com/watch?v=w2r0oLFtXAw">https://www.youtube.com/watch?v=w2r0oLFtXAw</a>)</p>
<p>git flow는 총 5 종류의 브랜치를 활용한다.</p>
<ol>
<li><p><strong>mater(main) 브랜치</strong>
사용자에게 배포되는 브랜치다.
부모 브랜치: -
자손 브랜치 (분기해서 생성되는 브랜치): <code>hotfix</code>, <code>develop</code>
PR받는 브랜치 (pull request 받는 브랜치): <code>release</code>
PR나가는 브랜치 (pull request 보내는 브랜치): -</p>
<br/>
</li>
<li><p><strong>hotfix 브랜치</strong>
배포된 서비스에 대한 긴급 버그 수정을 하는 브랜치다.
부모 브랜치: <code>master</code>
자손 브랜치: -
PR받는 브랜치: - 
PR나가는 브랜치: <code>develop</code>, <code>master</code></p>
<br/>
</li>
<li><p><strong>release 브랜치</strong>
배포 전 테스트를 위한 브랜치다.
부모 브랜치: <code>develop</code>
자손 브랜치: -
PR받는 브랜치: -
PR나가는 브랜치: <code>develop</code>, <code>master</code></p>
<br/>
</li>
<li><p><strong>develop 브랜치</strong>
개발 단계의 코드가 있는 브랜치다.
부모 브랜치: <code>master</code>
자손 브랜치: <code>feature</code>, <code>release</code>
PR받는 브랜치: <code>feature</code>
PR나가는 브랜치: -</p>
<br/>
</li>
<li><p><strong>feature 브랜치</strong>
특정한 기능을 구현하는 브랜치다.
부모 브랜치: <code>develop</code>
자손 브랜치: -
PR받는 브랜치: -
PR나가는 브랜치: <code>develop</code></p>
<br/>

</li>
</ol>
<h3 id="📝-github-flow">📝 Github Flow</h3>
<p>중심 내용은 Git Flow이기 때문에 사진으로 대체한다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/d332c9e5-1706-4836-80cd-0d8e6ef72391/image.png" alt=""></p>
<p>(사진 출처: <a href="https://www.youtube.com/watch?v=w2r0oLFtXAw">https://www.youtube.com/watch?v=w2r0oLFtXAw</a>)</p>
<h3 id="📝-gitlab-flow">📝 Gitlab Flow</h3>
<p>중심 내용은 Git Flow이기 때문에 사진으로 대체한다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/84d1b9cc-ca04-492c-993a-fa3474c43b43/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Github 이해하기2(branch)]]></title>
            <link>https://velog.io/@just_do/GitGithub-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B02branch</link>
            <guid>https://velog.io/@just_do/GitGithub-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B02branch</guid>
            <pubDate>Thu, 13 Jul 2023 15:32:50 GMT</pubDate>
            <description><![CDATA[<h2 id="📌-branch-란">📌 branch 란?</h2>
<blockquote>
<p><strong>branch</strong>란 git의 자체적인 기능으로 <strong>분기</strong>라는 뜻으로 버전 관리의 분기점을 만드는 기능이다.</p>
</blockquote>
<p>아래 그림처럼 master(main) 브랜치를 중심으로 분기점을 나눠 프로젝트를 여러 프로젝트로 나눠 개발하고 다시 master(main) 브랜치로 merge 한다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/c7da07d8-98cb-4dbf-a802-f62c8a8593b3/image.png" alt=""></p>
<p>나중에 협업 환경에서 git flow라는 개념으로 <strong>main branch, release branch, develop branch, feature branch, hotfix branch</strong> 의 flow로 회사마다 조금씩은 다르지만 주로 이러한 flow를 통해 개발이 진행된다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/5563212a-d04e-416b-93cd-0674b0313348/image.png" alt=""></p>
<h2 id="📌-branch-생성-전환-삭제">📌 branch 생성, 전환, 삭제</h2>
<p>처음 git init 을 통해 디렉토리를 생성하면 main 혹은 master 브랜치를 통해 개발을 진행하게 된다. 여기서 추가로 branch를 생성하기 위해서는 아래 명령어를 통해서 생성한다.</p>
<ul>
<li>브랜치 생성 방법<pre><code>git branch (새 브랜치 명)</code></pre></li>
</ul>
<p>혹은</p>
<pre><code>git switch -c (새 브랜치 명)</code></pre><p>→ 새로운 브랜치를 생성함과 동시에 전환한다.
<br/></p>
<ul>
<li>브랜치 전환 방법</li>
</ul>
<pre><code>git switch (브랜치 명)</code></pre><pre><code>git checkout (브랜치 명)</code></pre><p>→ <strong>git switch</strong> 와 <strong>git checkout</strong>은 동일하게 분기의 전환을 수행한다. <strong>git switch</strong> 명령은 주로 분기 간의 개발 및 전환에 중점을 두는 반면 <strong>git checkout</strong> 명령은 완료된 작업의 커밋 대상 지정에 중점을 둔다.
<br/></p>
<ul>
<li>브랜치 삭제 방법<pre><code>git branch -D (브랜치 명)</code></pre></li>
</ul>
<h2 id="📌-branch-활용하기--merge">📌 branch 활용하기 : merge</h2>
<blockquote>
<p><strong>git merge</strong>란 서로 다른 branch의 작업 내용을 하나의 branch로 병합하기 위한 명령어다.</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/just_do/post/c7da07d8-98cb-4dbf-a802-f62c8a8593b3/image.png" alt=""></p>
<p>위 사진처럼 작업자가 새로운 branch를 만들어 master(main) 브랜치로 병합하는 과정을 merge라 하고명령어는 다음과 같다.</p>
<pre><code>git merge (병합할 브랜치 명)</code></pre><p>→ main 브랜치에서 develop 브랜치를 병합하기 위해서는 main 브랜치로 전환한 후 <strong>git merge develop</strong> 명령어를 입력하면 된다.</p>
<p>→이 과정에서 두 브랜치가 같은 파일의 같은 곳을 수정하면 <strong>merge conflict</strong> 가 발생한다.</p>
<h3 id="📝-merge-conflict">📝 merge conflict</h3>
<blockquote>
<p><strong>merge conflict</strong> 란 브랜치를 병합하는 과정에서 두 브랜치가 같은 파일의 같은 곳을 수정하여 정확히 어떻게 합쳐야 할지 결정할 수 없을 때 발생하는 개념이다.</p>
</blockquote>
<h2 id="📌-github-에서-branch-활용하기--pull-request">📌 Github 에서 branch 활용하기 : Pull Request</h2>
<blockquote>
<p><strong>Pull Request</strong> 란 github에 작업이 완료된 브랜치를 요청하는 브랜치에 병합해 달라고 요청을 보내는 것이다.</p>
</blockquote>
<p><strong>merge</strong>는 git의 자체적인 기능으로 로컬 저장소에서 병합을 하기 위한 명령어이다. 원격 저장소에 브랜치를 <strong>merge</strong> 하기 위한 과정이 <strong>pull request</strong>라고 볼 수 있다.</p>
<h3 id="📎-pull-request-하는-방법">📎 pull request 하는 방법</h3>
<ul>
<li>특정 브랜치에서 파일을 생성 혹은 수정하고 git add / commit을 한 후 병합하고자 하는 브랜치 명으로 <strong>push</strong> 한다.</li>
</ul>
<pre><code>git push origin (병합하고자 하는 브랜치 명)</code></pre><ul>
<li>그럼 github &gt; repository &gt; pull requests 에 요청한을 확인하고 병합할 수 있다.
<img src="https://velog.velcdn.com/images/just_do/post/33902695-32b4-4c1a-9dab-3fc8707564b3/image.png" alt=""></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 5장 [표현식과 문]]]></title>
            <link>https://velog.io/@just_do/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-5%EC%9E%A5-%ED%91%9C%ED%98%84%EC%8B%9D%EA%B3%BC-%EB%AC%B8</link>
            <guid>https://velog.io/@just_do/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-5%EC%9E%A5-%ED%91%9C%ED%98%84%EC%8B%9D%EA%B3%BC-%EB%AC%B8</guid>
            <pubDate>Wed, 12 Jul 2023 16:04:03 GMT</pubDate>
            <description><![CDATA[<h1 id="💻-5장-표현식과-문">💻 5장 표현식과 문</h1>
</br>

<h2 id="1️⃣-요약">1️⃣ 요약</h2>
<blockquote>
<p> <strong>문</strong>은 프로그램을 구성하는 기본 단위이자 최소 실행 단위고 <strong>표현식</strong>은 값으로 평가될 수 있는 <strong>문</strong>이다.</p>
</blockquote>
</br>

<h2 id="2️⃣-정리">2️⃣ 정리</h2>
<h3 id="📌-51-값">📌 5.1 값</h3>
<blockquote>
<p><strong>값</strong>은 <strong>식(표현식)</strong>이 <strong>평가</strong>되어 생성된 결과를 말한다.</p>
</blockquote>
<p>모든 값은 <strong>데이터 타입</strong>을 가진다. 예를 들어 메모리에 저장된 값이 2진수 0100 0001일 때 숫자로 해석하면 65지만 문자로 해석하면 &#39;A&#39;다.</p>
<h3 id="📌-52-리터럴">📌 5.2 리터럴</h3>
<blockquote>
<p><strong>리터럴</strong>은 사람이 이해할 수 있는 문자 또는 약속된 기호를 사용해 값을 생성하는 <strong>표기법</strong>을 말한다.</p>
</blockquote>
<pre><code class="language-javascript">//숫자 리터럴 3
3</code></pre>
<ul>
<li>리터럴 종류
<img src="https://velog.velcdn.com/images/just_do/post/e11eb65d-a4f9-4a05-b69a-d30ad4c4b88f/image.png" alt=""></li>
</ul>
</br>


<h3 id="📌-53-표현식">📌 5.3 표현식</h3>
<blockquote>
<p><strong>표현식</strong>은 값으로 평가될 수 있는 <strong>문</strong>이다. 즉, 표현식이 평가되면 새로운 값을 생성하거나 기존 값을 참조한다.</p>
</blockquote>
</br>

<p>값으로 평가될 수 있는 문은 모두 표현식이다.</p>
<pre><code class="language-javascript">var score = 100;
var scroe = 50 + 50;

score; // 100</code></pre>
<ul>
<li>100은 리터럴이고 자바스크립트 엔진에 의해 평가되어 값을 생성하므로 리터럴은 그 자체로 표현식이다.</li>
<li>50 +50은 리터럴과 연산자로 이루어져 있으며 평가되어 값 100을 생성하므로 표현식이다.</li>
<li>score는 변수 식별자로 참조하면 변수 값으로 평가되기 때문에 표현식이다.</li>
</ul>
</br>

<h3 id="📌-54-문">📌 5.4 문</h3>
<blockquote>
<p><strong>문</strong>은 프로그램을 구성하는 기본 단위이자 최소 실행 단위다. 문은 여러개의 <strong>토큰</strong>으로 구성되어 있으며 토큰이란 문법적인 의미를 가지며, 문법적으로 더 이상 나눌 수 없는 코드의 기본 요소를 의미한다.</p>
</blockquote>
<p>문을 명령문이라고 부르기도 한다.로 실행한다.</p>
</br>


<h3 id="📌-55-세미콜론과-세미콜론-자동-삽입-기능">📌 5.5 세미콜론과 세미콜론 자동 삽입 기능</h3>
<blockquote>
<p>세미콜론(;)은 문의 종료를 나타낸다. 자바스크립트 엔진은 소스코드를 해석할 때 문의 끝이라고 예측되는 지점에 세미콜론을 자동으로 붙여주는 기능이 암묵적으로 수행된다.</p>
</blockquote>
</br>

<h3 id="📌-56-표현식인-문과-표현식이-아닌-문">📌 5.6 표현식인 문과 표현식이 아닌 문</h3>
<blockquote>
<p>표현식인 문과 표현식이 아닌 문을 구별하는 가장 간단하고 명료한 방법은 변수에 할당해 보는 것이다. 표현식인 문은 <strong>값으로 평가</strong>되므로 변수에 할당할 수 있다.</p>
</blockquote>
<pre><code class="language-javascript">// 변수 선언문은 값으로 평가될 수 없으므로 표현식이 아니다.
var x;
// 표현식이 아닌 문은 값처럼 사용할 수 없다.
var foo = var x; // SyntaxError: Unexpected token var

//1, 2, 1+2, x = 1 + 2는 모두 표현식이다.
//x = 1 + 2는 표현식이면서 완전한 문이기도 하다.
x = 1 + 2;</code></pre>
</br>

<h2 id="3️⃣-마무리">3️⃣ 마무리</h2>
<p>표현식과 문을 이해하고 프로그래밍 용어들에 익숙해지는 과정의 장인 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Github 이해하기(push, pull, clone)]]></title>
            <link>https://velog.io/@just_do/Github-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0push-pull-clone</link>
            <guid>https://velog.io/@just_do/Github-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0push-pull-clone</guid>
            <pubDate>Wed, 12 Jul 2023 15:40:31 GMT</pubDate>
            <description><![CDATA[<h1 id="📌-github-란">📌 Github 란?</h1>
<blockquote>
<p>Github 는 Git으로 기록된 버전들을 <strong>온라인 상</strong>에 업로드하고 <strong>보관</strong>, <strong>관리</strong>할 수 있게 해주는 서비스다.</p>
</blockquote>
<h2 id="📌-github-사용법">📌 Github 사용법</h2>
<p><a href="https://github.com/JM0417">작성자 Github 링크</a></p>
<p><strong>우리 컴퓨터에 있는 Git 저장소</strong>를 우리는 <code>Local Repository</code> 라고 말하고,</p>
<p><strong>Github 상의 (온라인 상의) Git 저장소</strong>를 우리는 <code>Remote Repository</code> 라고 말한다.</p>
<p>우리가 git init을 통해 만든 저장소는 Local Repository에 생성되결 remote 명령어를 통해 온라인 저장소 Remote Repository와 연결한다.</p>
<h3 id="1-repository-생성-및-연결">1. Repository 생성 및 연결</h3>
<ol>
<li>Repository를 만드는 방법과 주소를 찾는 방법은 간단하니 넘어간다. 아래 주소가 생성된 Remote Repository 주소다.</li>
</ol>
<p><img src="https://velog.velcdn.com/images/just_do/post/8713cdb5-3b54-4ce0-8e13-98c73ce346c5/image.png" alt=""></p>
<ol start="2">
<li>위 주소와 remote 명령어를 이용해 저장소를 연결한다.</li>
</ol>
<pre><code> git remote add origin (github repo 주소)</code></pre><p> → remote repository를 추가하는데, origin 이라는 이름의 저장소로서 우리가 뒤에 명시한 github repo 를 지정하겠다는 뜻이다.</p>
<h3 id="2-원격-저장소에-업로드하기git-push">2. 원격 저장소에 업로드하기(Git push)</h3>
<ol>
<li><p><strong>git add</strong>와 <strong>commit</strong>을 통해 로컬 저장소에 파일(수정 사항)을 저장한다.</p>
</li>
<li><p><strong>push</strong> 명령어로 commit된 파일(수정 사항)을 원격 저장소에 업로드한다.</p>
</li>
</ol>
<pre><code>git push origin (branch이름)</code></pre><p> → branch 이름은 vs코드 하단에서 확인할 수 있다.</p>
<p> <img src="https://velog.velcdn.com/images/just_do/post/f99bab95-4e13-421d-b5c2-cf747dcc40ed/image.png" alt=""></p>
<h3 id="3-repository에서-파일을-내려받기pull-clone">3. Repository에서 파일을 내려받기(pull, clone)</h3>
<p>Repository에 업로드 된 파일을 내 컴퓨터로 가져올 수 있는데, 이때 사용되는 명령어가 <strong>pull</strong>과 <strong>clone</strong>이다. 두 명령어는 원격 저장소에 있는 파일을 내려받아 로컬 저장소를 최신화 및 동기화 시킨다. 아무것도 없이 처음 내려받을 때는 <strong>git clone</strong> 명령어를 사용하고 기존에 작업하던 로컬 저장소에서 원격 저장소의 수정사항과 동기화하기 위해 사용되는 명령어가 <strong>git pull</strong>이다.</p>
<ul>
<li><strong>git clone</strong></li>
</ul>
<pre><code>git clone (repo 주소)</code></pre><p> → 업로드 된 파일을 내려받으며 commit 기록과 역사까지 전부 가져와 git reset 명령어를 통해 이전 기록으로 돌아갈 수도 있고, git pull, git push 등을 통하여 실제 repo에 수정 사항을 반영할 수 있다.</p>
<ul>
<li><strong>git pull</strong><pre><code>git pull origin main</code></pre>→ push 명령어와 반대되는 개념으로 최신 버전을 내려받아 원격 저장소와 로컬 저장소의 버전을 동기화 시키는 명령어다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git 이해하기]]></title>
            <link>https://velog.io/@just_do/Git-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@just_do/Git-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 12 Jul 2023 05:36:56 GMT</pubDate>
            <description><![CDATA[<h1 id="git이란">Git이란?</h1>
<blockquote>
<p><strong>git</strong>이란 특정 폴더, 파일들의 <strong>버전 관리</strong>를 위한 프로그램이다.</p>
</blockquote>
<h2 id="cli-이해하기">CLI 이해하기</h2>
<p>CLI란 command line interface의 약자로 흔히 우리가 보는 터미널 혹은 cmd 창에서 커멘드를 기반하여 컴퓨터와 상호작용 하는 것이 CLI 방식입니다.</p>
<p><img src="https://velog.velcdn.com/images/just_do/post/f467d47c-e378-4995-a317-f34497bd23fe/image.png" alt=""></p>
<ul>
<li><p>jinjeongmin@jinjeongmin-ui-MacBookAir Desktop ~ %
  : % 앞까지의 커멘드는 directory(경로)를 의미하고, ~는 맥북/users/(유저명) 경로의 약자이다.</p>
</li>
<li><p><strong>ls</strong> : 현재 경로의 파일들을 출력</p>
</li>
<li><p><strong>mkdir velog</strong> : 현재 경로에 &#39;velog&#39;라는 폴더를 생성</p>
</li>
</ul>
<blockquote>
<p>우리가 바탕화면에서 보는 폴더들은 위와 같은 커멘드 기반의 프로그램을 그래픽으로 표현한 GUI(graphic user interface)라고 한다.</p>
</blockquote>
<h2 id="git-이해하기">Git 이해하기</h2>
<h3 id="git-설치하는-방법">Git 설치하는 방법</h3>
<p><a href="https://git-scm.com/download/mac">https://git-scm.com/download/mac</a></p>
<h3 id="git을-사용하는-이유">Git을 사용하는 이유</h3>
<p>우리가 Git을 사용하는 이유는 프로그램의 버전 관리를 위함이다. 그리고 협업 환경에서 버전 관리를 하기 위해 Github를 사용한다.</p>
<p>git을 활용한 버전 관리 단계는 총 3단계로 나뉜다.</p>
<ol>
<li>untracked: git add 를 통해 관리되기 전의 상태</li>
<li>staged : git add를 통해 관리되는 상태</li>
<li>comitted : add 이후에 commit을 통해 저장된 최종적 상태</li>
</ol>
<h3 id="git-사용법">Git 사용법</h3>
<ul>
<li><strong>git init</strong> : git 저장소를 만드는 명령어, 이 명령어를 시작으로 해당 폴더 내부의 폴더나 파일들을 관리할 수 있다.</li>
<li><strong>git add</strong> : 저장소에 파일(수정 사항)을 저장하는 명령어<ul>
<li>git add . : 해당 경로의 모던 파일(수정 사항)을 저장</li>
<li>git add -A : 해당 경로 뿐만 아니라 git으로 관리되는 모든 파일(수정사항) 저장</li>
<li>git add hello.txt : 해당 경로의 특정 파일(수정 사항)을 저장</li>
</ul>
</li>
<li><strong>git status</strong> : git add를 통해서 관리되고 있는 파일(수정 사항)을 확인 관리</li>
<li><strong>git reset</strong> : git add 한 파일을 취소</li>
</ul>
<p><img src="https://velog.velcdn.com/images/just_do/post/861cae4f-01d5-4923-91a2-bb7c87ac649b/image.png" alt=""></p>
<ul>
<li><strong>git commit</strong> : 현재 파일(수정 사항)들을 하나의 버전으로 저장<pre><code>git commit -m&quot;(커밋 메세지)&quot;
// 커밋타입 : 동작 기능이름/함수이름
//          Feat: Create hello.txt </code></pre></li>
<li><strong>git ammend</strong> : 최근 commit 메세지를 수정</li>
<li><strong>git log</strong> : commit한 기록들을 통해 버전 확인</li>
</ul>
<p><img src="https://velog.velcdn.com/images/just_do/post/ce911238-2afc-485d-980f-82656a90b5e4/image.png" alt=""></p>
<ul>
<li><strong>git revert</strong> : 현재까지의 commit 기록을 유지하면서, 특정한 commit 이전으로 되돌리는 명령어</li>
<li><strong>git reset</strong> : 특정 커밋으로 돌아가면서, 그 커밋 이후의 기록을 삭제하는 명령어</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 4장 [변수]]]></title>
            <link>https://velog.io/@just_do/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-4%EC%9E%A5-%EB%B3%80%EC%88%98</link>
            <guid>https://velog.io/@just_do/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-4%EC%9E%A5-%EB%B3%80%EC%88%98</guid>
            <pubDate>Thu, 06 Jul 2023 16:50:49 GMT</pubDate>
            <description><![CDATA[<h1 id="💻-4장-변수">💻 4장 변수</h1>
</br>

<h2 id="1️⃣-요약">1️⃣ 요약</h2>
<blockquote>
<p> 변수란 값을 저장하기 위해 확보학 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙임 이름을 말하며 변수를 선언하는 키워드로는 <code>var</code>, <code>let</code>, <code>const</code> 가 있고 <strong>var 키워드는 선언 단계와 초기화 단계를 동시에 진행하고 let, const 키워드는 선언 단계만 진행하고 초기화 단계는 런타임에 진행된다는 특징이 있다.</strong> 그리고 const 키워드는 <code>재할당이 금지</code>되어 있다. 마지막으로 자바스크립트 엔진은 런타임이 진행되기 전에 변수를 먼저 선언하는 특징이 있는데 이를 <code>변수 호이스팅</code>이라 한다.</p>
</blockquote>
</br>

<h2 id="2️⃣-정리">2️⃣ 정리</h2>
<h3 id="📌-41-변수란-무엇인가-왜-필요한가">📌 4.1 변수란 무엇인가? 왜 필요한가?</h3>
<blockquote>
<p>변수란 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름을 말한다. 값의 <code>위치</code>를 가리키는 상징적인 이름이기도 하다. 변수에 값을 저장하는 것을 <code>할당[assignment](대입, 저장)</code>이라 하고, 변수에 저장된 값을 읽어 들이는 것을 <code>참조[refefence]</code>라 한다.</p>
</blockquote>
</br>


<h3 id="📌-42-식별자">📌 4.2 식별자</h3>
<blockquote>
<p>변수 이름을 <code>식별자[identifier]</code>라고도 한다. 식별자는 어떤 값을 구별해서 식별할 수 있는 고유한 이름을 말한다. <code>“식별자는 값이 아니라 메모리 주소를 기억하고 있다.”</code></p>
</blockquote>
<p><code>변수</code>, <code>함수</code>, <code>클래스</code> 등의 이름은 모두 식별자다. 메모리 상에 존재하는 어떤 값을 식별할 수 있는 이름을 모두 식별자라한다. 그리고 이러한 식별자들은 네이밍 규칙을 준수해야 하며, <code>선언</code>에 의해 자바스크립트 엔진에 식별자의 존재를 알린다.
</br></p>
<h3 id="📌-43-변수-선언">📌 4.3 변수 선언</h3>
<blockquote>
<p>변수를 사용하려면 반드시 <code>선언[declaration]</code>이 필요하다. 변수를 선언할 대는 <code>var</code>, <code>let</code>, <code>const</code> 키워드를 사용한다.
</br></p>
</blockquote>
<ul>
<li>var 키워드를 사용한 변수 선언</li>
</ul>
<pre><code class="language-javascript">var score;</code></pre>
<p>위 변수 선언문은 다음과 같이 변수 이름을 등록하고 값을 저장할 메모리 공간을 확보한다.</p>
<img src="https://velog.velcdn.com/images/just_do/post/e80e67a5-70f1-497d-a90f-a2078ecbe54e/image.png" style="height : 350px;">

<p>그리고 확보된 메모리 공간에는 자바스크립트 엔진에 의해 <code>undefined</code>라는 값이 암묵적으로 할당된다.</p>
<hr>
<p>📝 <strong>undefined</strong>
자바스크립트에서 제공하는 원시 타입의 값이다.</p>
<hr>
<p>자바스크립트 엔진은 변수 선언을 다음과 같은 2단계를 거쳐 수행한다.</p>
<ul>
<li><strong>선언 단계</strong> : 변수 어림을 등록해서 자바스크립트 엔진에 변수의 존재를 알린다.</li>
<li><strong>초기화 단계</strong> : 값을 저장하기 위한 메모리 공간을 확보하고 암뭊거으로 undefined를 할당해 초기화 한다.</li>
</ul>
<p>var 키워드를 사용한 변수 선언은 선언 단계와 초기화 단계가 동시에 진행된다. var score;는 <code>선언 단계</code>를 통해 변수 이름 score를 등록하고, <code>초기화 단계</code>를 통해 score 변수에 암묵적으로 undefined를 할당해 초기화한다.</p>
<p>따라서 var 키워드로 선언한 변수는 어떠한 값도 할당하지 않아도 undefined라는 값을 갖는다.</p>
<hr>
<p>📝 <strong>변수 이름은 어디에 저장되는가?</strong>
<code>변수 이름을 비롯한 모든 식별자</code>는 실행 컨텍스트에 등록된다 <code>실행 컨텍스트[excution context]</code>는 자바스크립트 엔진이 소스코드를 평가하고 실행하기 위해 필요한 환경을 제공하고 코드의 실행 결과를 실제로 관리하는 영역이다. 자바스크립트 엔진은 실행 컨텍스트를 통해 <code>식별자</code>와 <code>스코프</code>를 관리한다.
변수 이름과 변수 값은 실행 컨텍스트 내에 키[key] / 값[value] 형식인 객체로 등록되어 관리한다.</p>
<hr>
<p><strong>❓ 그럼 let 키워드와 const 키워드는 변수 선언 방식이 다른가?</strong></p>
<blockquote>
<p>다음 챕터 변수 <code>호이스팅</code>에서 다룰 내용인데 호이스팅이란 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트의 특징이다. var 키워드 뿐만 아니라 let, const 키워드 역시 선두로 호이스팅 되나 <code>var 키워드와 달리 선언 단계와 동시에 초기화 단계가 동시에 이루어지지 않고 초기화 단계는 런타임에 진행된다.</code></p>
</blockquote>
</br>

<h3 id="📌-44-변수-선언의-실행-시점과-변수-호이스팅">📌 4.4 변수 선언의 실행 시점과 변수 호이스팅</h3>
<pre><code class="language-javascript">console.log(score); // undefined
var score; // 변수 선언</code></pre>
<p>자바스크립트 코드는 인터프리터에 의해 한 줄씩 순차적으로 실행되기 때문에 console.log(score);가 먼저 실행되고 var score;가 실행된다. 하지만 위 예제는 score 변수가 먼저 선언되고 undefined로 초기화된 후 실행되는 모습을 보여준다. 이는 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 엔진의 특징 때문이며 이를 <code>변수 호이스팅</code>이라 한다.</p>
<hr>
<p>📝 <strong>변수 호이스팅</strong>
자바스크립트 엔진은 소스코드를 한 줄씩 순차적으로 실행하기에 앞서 먼저 소스코드의 평가 과정을 거쳐서 소스코드를 실행하기 위한 준비를 한다. 이때 <code>소스코드 실행을 위한 준비 단계인 소스코드의 평가 과정에서 자바스크립트 엔진은 변수 선언을 포함한 모든 선언문(변수 선언문, 함수 선언문 등)을 소스코드에서 찾아내 먼저 실행한다.</code> 그리고 소스코드의 평가과정이 끝나면 비로소 변수 선언을 포함한 모든 선언문을 제외하고 소스코드를 한 줄씩 순차적으로 실행한다.</p>
<hr>
</br>


<h3 id="📌-45-값의-할당">📌 4.5 값의 할당</h3>
<p>변수의 선언과 값의 할당을 하나의 문장으로 표현해도 자바스크립트 엔진은 변수의 선언과 값의 할당을 2개의 문으로 나누어 각각 실행한다.</p>
<img src="https://velog.velcdn.com/images/just_do/post/18a6e90f-d0fa-4aa6-b641-456afa7206f0/image.png" style="height : 350px;">

<p>이때 주의할 점은 변수 선언과 값의 할당의 실행 시점이 다르다는 것이다. <strong>변수 선언은 소스코드가 순차적으로 실행되는 시점인 런타임 이전에 먼저 실행되지만 값의 할당은 소스코드가 순차적으로 실행되는 시점인 런타임에 실행된다.</strong>
</br></p>
<h3 id="📌-46-값의-재할당">📌 4.6 값의 재할당</h3>
<p>재할당은 변수에 저장된 값을 다른 값으로 변경한다. 그래서 변수라고 하는 것이다. <strong>만약 값을 재할당할 수 없어서 변수에 저장된 값을 변경할 수 없다면 변수가 아니라 상수[constant]라 한다.</strong></p>
<hr>
<p>📝 <strong>const 키워드</strong>
ES6에서 도입된 const 키워드를 사용해 선언한 변수는 재할당이 금지된다. 즉, <strong>const 키워드는 단 한 번만 할당할 수 있는 변수를 선언한다.</strong> 따라서 const 키워드를 사용하면 상수를 표현할 수 있다.</p>
<hr>
</br>

<h3 id="📌-47-식별자-네이밍-규칙">📌 4.7 식별자 네이밍 규칙</h3>
<ul>
<li>식별자는 특수문자를 제외한 문자, 숫자, 언더스코드(_), 달러 기호($)를 포함할 수 있다.</li>
<li>단, 식별자는 특수문자를 제외한 문자, 언더스코프(_), 달러 기호($)로 시작해야 한다. <strong>숫자로 시작하는 것은 허용하지 않는다.</strong></li>
<li><strong>예약어</strong>는 식별자로 사용할 수 없다.</li>
</ul>
</br>

<h2 id="3️⃣-마무리">3️⃣ 마무리</h2>
<p>변수 호이스팅을 이해하고 이를 주의하며 코드를 작성해야겠다. 그래도 이러한 특징 덕분에 에러를 줄일 수 있는 것 같으니 잘 이해하고 활용해야 한다. 추후 스코프와 블록 스코프를 이해하고 활용하면 더 좋은 코드를 작성할 수 있을 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 2장 [JS 스터디 1주차]]]></title>
            <link>https://velog.io/@just_do/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8</link>
            <guid>https://velog.io/@just_do/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8</guid>
            <pubDate>Wed, 05 Jul 2023 15:44:11 GMT</pubDate>
            <description><![CDATA[<h1 id="💻-2장-자바스크립트란">💻 2장 자바스크립트란?</h1>
</br>

<h2 id="1️⃣-요약">1️⃣ 요약</h2>
<blockquote>
<p> 자바스크립트는 명령형, 함수형, 프로토타입 기반 객체지향 프로그래밍을 지원하는 <strong><code>멀티 패러다임 프로그래밍 언이</code></strong>이며 <strong><code>프로토타입 기반의 객체지향 언어</code></strong>다.</p>
</blockquote>
</br>

<h2 id="2️⃣-정리">2️⃣ 정리</h2>
<h3 id="📌-21-자바스크립트의-탄생">📌 2.1 자바스크립트의 탄생</h3>
<p>자바스크릡트는 1996년 웹페이즈의 보조적인 기능을 수행하기 위해 브라우저에서 동작하는 경량 프로그래밍 언어를 도입하기 위해 브렌던 아이크가 개발한 언어이다.
</br></p>
<h3 id="📌-22-자바스크립트의-표준화">📌 2.2 자바스크립트의 표준화</h3>
<p>자바스크립트의 파편화를 방지하고 모든 브라우저에서 정상적으로 동작하는 표준화된 자바스크립트의 필요성을 느껴 만든 표준 사양을 ECMAScript(일명 ES)를 만들었다. 현재는 ES13(ECMAScript 2022)까지 나왔다.
</br></p>
<h3 id="📌-23-자바스크립트-성장의-역사">📌 2.3 자바스크립트 성장의 역사</h3>
<p>웹페이지의 보조적인 기능을 수행하기 위한 언어로서 웹페이지의 성능을 향상시키는 역할을 한 자바스크립트의 역사이다.</p>
<h4 id="📎-ajax">📎 Ajax</h4>
<p>1999년, 자바스크립트를 이용해 서버와 브라우저가 <code>비동기</code> 방식으로 데이터를 교환할 수 있는 통신 기능인 <code>Ajax</code>가 XMLHttpRequest라는 이름으로 등장했다.</p>
<p>기존에 웹페이지는 화면이 전환되면 화면이 순간적으로 깜박이는 현상이 발생하고, 이는 웹페이지의 어쩔 수 없는 한계로 받아들여졌다.
Ajx의 등장은 이전의 패러다임을 획기적으로 전환했다. 즉, 웹페이지에서 병경할 필요가 없는 부분은 다시 렌더링하지 않고, 서버로부터 필요한 데이터만 전송받아 변경해야 하는 부분만 한정적으로 렌더링하는 방식이 가능해진 것이다.</p>
<h4 id="📎-jqeury">📎 JQeury</h4>
<p>2006년, JQuery는 다소 번거롭고 논란이 있던 DOM을 더욱 쉽게 제어할 수 있게 해주었고 크로스 브라우징 이슈도 어느정도 해결해 주었다.</p>
<h4 id="📎-v8-자바스크립트-엔진">📎 V8 자바스크립트 엔진</h4>
<p>구글의 V8 자바스크립트 엔진은 빠른 성능을 보여주어 웹 애플리케이션을 구축하는데 큰 도움을 주어 자바스크립트가 웹 애플리케이션 프로그래밍 언어로 자리잡을 수 있게 해주었다.</p>
<h4 id="📎-nodejs">📎 Node.js</h4>
<p>Node.js는 구글 V8 자바스크립트 엔진으로 빌드된 <strong>자바스크립트 런타임 환경</strong>이다. Node.js는 브라우저의 자바스크립트 엔진에서만 동작하던 자바스크립트를 브라우저 이외의 환경에서도 동작할 수 있도록 자바스크립트 엔진을 브라우저에서 독립시킨 <strong>자바스크립트 실행 환경</strong>이다. Node.js는 다양한 플랙폼에 적용할 수 있지만 <strong>서버 사이드 애플리케이션 개발</strong>에 주로 사용되며, 이에 필요한 모듈, 파일 시스템, HTTP 등 빌트인 API를 제공한다.</p>
<h4 id="📎-spa-프레임워크">📎 SPA 프레임워크</h4>
<p>SPA란 Single Page Aplication을 말하며 CBD Component Based Development 방법론을 기반으로 만들어진 프레임워크 들을 말한다. 대표적으로 Angular, React, Vue.js, Svelte 등이 있다.
</br></p>
<h3 id="📌-24-자바스크립트와-ecmascript">📌 2.4 자바스크립트와 ECMAScript</h3>
<p>ECMAScript는 자바스크립트의 표준 사양인 ECMA-262를 말하며, 프로그래밍 언어의 값, 타입, 객체와 프로퍼티, 함수, 표준 빌트인 객체 등 핵심 문법을 규정한다. 각 브라우저 제조사는 ECMAScript 사양을 준수해서 브라우저에 내장되는 자바스크립트 엔진을 구현한다.
자바스크릡트는 일반적으로 프로그래밍 언어로서 기본 뼈대를 이루는 ECMAScript와 브라우저가 별도로 지원하는 <strong>클라이언트 사이드 Web API</strong>, 즉 DOM, BOM, Canvas, XMLHttpRequest, fetch, requestAnimationFrame, SVG, Web Storage, Web Component, Web Worker 등을 아우르는 개념이다.</p>
</br>

<h3 id="📌-25-자바스크립트의-특징">📌 2.5 자바스크립트의 특징</h3>
<p>자바스크립트는 HTML, CSS와 함께 웹을 구성하는 요소 중 하나로 <strong>웹 브라우저에서 동작하는 유일한 프로그래밍 언어다.</strong>
자바스크립트는 개발자가 별도의 컴파일 작업을 수행하지 않는 <strong>인터프리터 언어</strong>다. 
자바스크립트는 명령형, 함수형, 프로토타입 기반 객체지향 프로그래밍을 지원하는 <strong><code>멀티 패러다임 프로그래밍 언이</code></strong>이며 <strong><code>프로토타입 기반의 객체지향 언어</code></strong>다.</p>
</br>

<h3 id="📌-26-es6-브라우저-지원-현황">📌 2.6 ES6 브라우저 지원 현황</h3>
<p>인터넷 익스플로러를 제외한 모던 브라우저의 ES6 지원 비율은 96~99%로 거의 100%에 육박하지만 인터넷 익스플로러나 구형 브라우저는 ES6를 대부분 지원하지 않는다. </p>
</br>



<h2 id="3️⃣-마무리">3️⃣ 마무리</h2>
<p>자바스크립트란 무엇인지 알아보았는데 모르는 말이 굉장히 많이 나와 당황스러웠다. 사실 현재 글은 스터디 1주차를 작성하고 있지만 글을 쓰는 지금은 스터디를 진행한지 3개월이 넘어가 이 책을 거의 끝낸 상태이다. 그래서 비동기나 DOM, 프로토타입 기반 등 절반 정도는 이해가 가지만 아직 모르는 용어들이 많아 더 많이 공부해야겠다는 생각이 들고 특히 2.3에 SPA 프레임워크는 최근에 NEXT.js 프레임워크도 사용하여 SSR 구현도 해보았고 앞으로 React를 배워나갈 예정이기에 괌심을 보였다.</p>
]]></description>
        </item>
    </channel>
</rss>