<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>cycling-lion-cub.log</title>
        <link>https://velog.io/</link>
        <description>풀스택 웹 개발자가 목표인 애옹이</description>
        <lastBuildDate>Sun, 11 Oct 2026 16:30:35 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>cycling-lion-cub.log</title>
            <url>https://velog.velcdn.com/images/cycling-lion-cub/profile/38876d44-0ed2-4e46-871f-714795c8a154/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. cycling-lion-cub.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/cycling-lion-cub" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[MVC (Model-View-Controller)]]></title>
            <link>https://velog.io/@cycling-lion-cub/MVC-Model-View-Controller</link>
            <guid>https://velog.io/@cycling-lion-cub/MVC-Model-View-Controller</guid>
            <pubDate>Sun, 11 Oct 2026 16:30:35 GMT</pubDate>
            <description><![CDATA[<h1 id="mvc-패턴-한-번에-정리하기">MVC 패턴, 한 번에 정리하기</h1>
<h2 id="1-mvc-패턴은-무엇인가">1. MVC 패턴은 무엇인가?</h2>
<p>MVC (Model-View-Controller)는 소프트웨어를 세 가지 역할로 나누어 설계하는 <strong>아키텍처 패턴(Architectural Pattern)</strong>이야.</p>
<p>각각의 의미는 다음과 같아.</p>
<ul>
<li><strong>Model</strong> : 데이터와 비즈니스 로직을 담당</li>
<li><strong>View</strong> : 사용자에게 보여주는 화면을 담당</li>
<li><strong>Controller</strong> : 사용자의 입력을 받아 적절한 처리를 연결하고 제어</li>
</ul>
<p>여기서 MVC의 핵심은 단순히 세 가지로 나눈다는 것이 아니야.</p>
<p>서로 다른 책임을 가진 코드들을 분리해서, 하나의 부분이 변경되더라도 다른 부분에 미치는 영향을 줄이려는 것이야.</p>
<p>이것을 <strong>관심사의 분리(Separation of Concerns)</strong> 라고 해. SOLID 원칙 중 <strong>단일 책임 원칙(SRP)</strong> 과도 취지가 통하는 부분이지.</p>
<blockquote>
<p>💡 <strong>MVC는 디자인 패턴 아닌가요?</strong></p>
<p>MVC는 원래 Smalltalk 환경에서 사용자 인터페이스의 데이터, 화면 표현, 입력 처리를 분리하기 위해 등장했어. 이후 웹 애플리케이션을 비롯한 다양한 소프트웨어 구조에 적용되면서 아키텍처 패턴으로도 널리 설명되고 있어.</p>
<p>자료에 따라 MVC를 디자인 패턴이라고 부르기도 해. &quot;반복되는 설계 해결책&quot;을 넓게 묶어 디자인 패턴이라고 부르는 경우도 많기 때문이야.</p>
<p>하지만 오늘날 웹 프레임워크에서는 MVC가 애플리케이션 전체의 구조를 결정하기 때문에, 이 글에서는 <strong>아키텍처 패턴</strong>으로 설명할게.</p>
</blockquote>
<h2 id="2-mvc의-전체-구조">2. MVC의 전체 구조</h2>
<pre><code class="language-text">사용자 ── 요청 ──▶ Controller ── 데이터 요청 ──▶ Model
                     │◀──────── 결과 반환 ────────┘
                     │
                     └── 데이터 전달 ──▶ View ── 화면 ──▶ 사용자</code></pre>
<p>예를 들어 사용자가 게시판에서 게시글 상세 페이지를 클릭했다고 해보자.</p>
<ol>
<li><strong>사용자</strong> : 게시글 상세 페이지를 요청해.</li>
<li><strong>Controller</strong> : URL의 게시글 ID를 확인하고 Model에 필요한 데이터를 요청해.</li>
<li><strong>Model</strong> : 게시글을 조회하고 필요한 비즈니스 규칙을 처리한 뒤 결과를 돌려줘.</li>
<li><strong>Controller</strong> : 조회 결과를 View에 전달해.</li>
<li><strong>View</strong> : 전달받은 게시글 데이터를 화면으로 표현해.</li>
</ol>
<p>단, MVC의 구현은 프레임워크마다 달라. 고전적인 MVC에서는 View가 Model을 직접 관찰하기도 하고, 웹 MVC에서는 Controller가 Model을 조회한 후 View에 데이터를 전달하기도 해.</p>
<p>따라서 위 그림은 MVC의 유일한 구조가 아니라 이해를 돕기 위한 <strong>대표적인 흐름</strong>이야.</p>
<h2 id="3-mvc의-구성-요소별-역할">3. MVC의 구성 요소별 역할</h2>
<h3 id="model--데이터와-비즈니스-로직">Model — 데이터와 비즈니스 로직</h3>
<p>Model은 소프트웨어가 관리하는 데이터와 그 데이터에 적용되는 비즈니스 규칙을 담당해.</p>
<p>예를 들어 게시판의 Model이라면 다음 기능을 생각할 수 있겠지.</p>
<ul>
<li>게시글 데이터 조회</li>
<li>게시글 등록 및 수정</li>
<li>게시글 삭제 권한 검증 (예: 작성자 본인만 삭제 가능)</li>
<li>게시글 데이터의 유효성 검증</li>
</ul>
<blockquote>
<p>💡 &quot;로그인한 사용자인가?&quot; 를 확인하는 <strong>인증</strong>은 보통 미들웨어가 담당해. Model이 맡는 것은 &quot;이 사용자가 이 게시글을 삭제해도 되는가?&quot; 같은 <strong>비즈니스 규칙</strong>이야.</p>
</blockquote>
<p>여기서 중요한 것은 <strong>Model이 단순히 데이터베이스 자체를 의미하는 것은 아니라는 점</strong>이야.</p>
<p>Prisma는 DB에 접근하기 위한 도구이고, Model은 그보다 넓은 개념이야. 실제 프로젝트에서는 서비스(Service)와 저장소(Repository) 계층으로 Model의 책임을 나누기도 해.</p>
<h3 id="view--사용자에게-보여주는-화면">View — 사용자에게 보여주는 화면</h3>
<p>View는 데이터를 어떤 형태로 사용자에게 보여줄지를 담당해.</p>
<p>예를 들어 게시글 상세 화면이라면 다음을 표현하겠지.</p>
<pre><code class="language-jsx">function PostView({ post }) {
  return (
    &lt;article&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;p&gt;{post.content}&lt;/p&gt;
    &lt;/article&gt;
  );
}</code></pre>
<p>이 컴포넌트는 전달받은 게시글 데이터를 화면에 표현하는 역할을 하고 있어.</p>
<p>React의 컴포넌트는 View의 역할을 수행할 수 있지만, 모든 React 컴포넌트가 순수한 View인 것은 아니야. 상태 관리, 데이터 조회, 이벤트 처리까지 함께 담당할 수도 있기 때문이지.</p>
<h3 id="controller--입력을-받아-흐름을-제어">Controller — 입력을 받아 흐름을 제어</h3>
<p>Controller는 요청이나 사용자 입력을 해석하고, 적절한 Model의 동작을 호출한 뒤 응답을 결정하는 역할이야.</p>
<p>Express를 예로 들어볼게.</p>
<pre><code class="language-js">app.get(&quot;/posts/:id&quot;, async (req, res) =&gt; {
  const id = Number(req.params.id);

  const post = await postService.findById(id);

  if (!post) {
    return res.status(404).json({ message: &quot;게시글 없음&quot; });
  }

  res.json(post);
});</code></pre>
<p>위 코드에서 Controller의 역할은 세 가지야.</p>
<ol>
<li><code>req.params.id</code>로 요청한 게시글 ID를 확인해.</li>
<li><code>postService.findById(id)</code>로 게시글 데이터를 요청해.</li>
<li>조회 결과에 따라 오류를 반환하거나 데이터를 응답해.</li>
</ol>
<p>즉, Controller는 직접 모든 일을 처리하는 존재라기보다 <strong>다른 구성 요소들이 적절한 일을 수행하도록 연결하는 조정자</strong>에 가까워.</p>
<h3 id="잠깐-그러면-view는-어디에-있을까">잠깐, 그러면 View는 어디에 있을까?</h3>
<p>위 Controller는 화면이 아니라 JSON 데이터를 응답하고 있어. 이건 서버를 어떻게 구성하느냐에 따라 달라지는 부분이야.</p>
<table>
<thead>
<tr>
<th>방식</th>
<th>Controller의 응답</th>
<th>View의 위치</th>
</tr>
</thead>
<tbody><tr>
<td>전통적인 서버 렌더링 (Express + EJS 등)</td>
<td><code>res.render(&quot;post&quot;, { post })</code></td>
<td>서버의 템플릿 파일</td>
</tr>
<tr>
<td>API 서버 + React</td>
<td><code>res.json(post)</code></td>
<td>브라우저에서 실행되는 React 컴포넌트</td>
</tr>
</tbody></table>
<p>전통적인 방식에서는 서버가 템플릿 엔진으로 HTML을 직접 만들어서 보내기 때문에 M, V, C가 모두 서버 안에 있어.</p>
<p>반면 Express를 API 서버로 쓰고 화면은 React로 만드는 구조에서는, 서버는 JSON 데이터만 보내고 실제 화면은 앞에서 본 <code>PostView</code> 같은 React 컴포넌트가 그려. View의 역할이 프론트엔드로 옮겨간 셈이지.</p>
<h2 id="4-mvc-패턴을-사용하는-이유">4. MVC 패턴을 사용하는 이유</h2>
<p>그렇다면 굳이 Model, View, Controller를 나누는 이유가 뭘까?</p>
<p>MVC를 사용하지 않고 게시글의 데이터 조회, 유효성 검증, 화면 렌더링 등을 하나의 함수에 작성했다고 생각해 보자.</p>
<p>처음에는 코드가 짧고 편리할 수 있어.</p>
<p>하지만 프로젝트가 커지면 다음과 같은 문제가 발생할 수 있어.</p>
<ul>
<li>화면 디자인을 변경하려는데 데이터 조회 코드까지 건드려야 해.</li>
<li>데이터베이스 처리 방식을 변경했더니 화면에 오류가 생겨.</li>
<li>게시글 작성 기능을 테스트하려는데 실제 화면까지 실행해야 해.</li>
<li>여러 개발자가 하나의 커다란 파일을 동시에 수정하면서 충돌이 발생해.</li>
</ul>
<p>MVC는 이런 문제를 줄이기 위해 책임을 분리하는 거야.</p>
<table>
<thead>
<tr>
<th></th>
<th>책임이 혼합된 구조</th>
<th>MVC로 분리한 구조</th>
</tr>
</thead>
<tbody><tr>
<td><strong>형태</strong></td>
<td>하나의 거대한 함수</td>
<td>Model / Controller / View</td>
</tr>
<tr>
<td><strong>담당</strong></td>
<td>DB 조회 + 입력 검증 + 로직 + 화면 렌더링</td>
<td>데이터·규칙 / 요청·제어 / 화면·표현</td>
</tr>
<tr>
<td><strong>변경할 때</strong></td>
<td>여러 책임에 영향을 주기 쉬움</td>
<td>책임을 구분해 변경 영향을 관리</td>
</tr>
</tbody></table>
<h3 id="코드로-보기">&lt; 코드로 보기 &gt;</h3>
<p>MVC 전체는 아니지만, <strong>데이터를 가져오는 책임</strong>과 <strong>화면을 그리는 책임</strong>을 나누면 어떤 점이 좋은지 작은 예시로 살펴보는 코드.</p>
<hr>
<h4 id="기존에-작성한-postsjs">기존에 작성한 posts.js</h4>
<pre><code class="language-js">export async function getPost() {
  const response = await fetch(
    &quot;https://example.com/api/post/123&quot;
  );

  const data = await response.json();

  return data;
}</code></pre>
<hr>
<h4 id="기존-pagejs-의-데이터-사용-방식">기존 page.js 의 데이터 사용 방식</h4>
<pre><code class="language-js">import { getPost } from &quot;@/lib/api/posts&quot;;

export default async function PostsPage() {
  const post = await getPost();

  return (
    &lt;div&gt;
      &lt;h1&gt;{post.post_title}&lt;/h1&gt;
      &lt;p&gt;{post.created_at}&lt;/p&gt;
    &lt;/div&gt;
  );
}</code></pre>
<hr>
<h4 id="api-응답-방식이-바뀌는-경우">API 응답 방식이 바뀌는 경우</h4>
<pre><code class="language-js">// 기존 API 응답
{
  post_id: 1,
  post_title: &quot;첫 번째 게시글&quot;
  created_at: &quot;2026-10-11&quot;
}

// 변경된 API 응답
{
  id: 1,
  title: &quot;첫 번째 게시글&quot;
  createdAt: &quot;2026-10-11&quot;
}
</code></pre>
<hr>
<h4 id="postsjs-를-이렇게-리턴한다면">posts.js 를 이렇게 리턴한다면?</h4>
<p>page.js와 posts.js 사이에 다음과 같은 약속이 있다고 생각하면 돼.
<em>&quot;getPost() 함수는 언제나 id, title, createdAt이라는 속성을 가진 게시글 객체를 반환한다.&quot;</em></p>
<pre><code class="language-js">// lib/api/posts.js

export async function getPost() {
  const response = await fetch(&quot;/api/posts/1&quot;);
  const data = await response.json();

  return {
    id: data.id,
    title: data.title,
    createdAt: data.createdAt,
  };
}</code></pre>
<hr>
<h4 id="바꿀-필요가-없는-pagejs">바꿀 필요가 없는, page.js</h4>
<p>page.js는 아무런 걱정 없이 API 호출 함수만 가져다가, 자신의 역할을 수행하면 되는 구조 탄생.</p>
<pre><code class="language-js">import { getPost } from &quot;@/lib/api/posts&quot;;

export default async function PostsPage() {
  const post = await getPost();

  return (
    &lt;div&gt;
      &lt;h1&gt;{post.title}&lt;/h1&gt;
      &lt;span&gt;{post.id}&lt;/span&gt;
      &lt;p&gt;{post.createdAt}&lt;/p&gt;
    &lt;/div&gt;
  );
}</code></pre>
<h2 id="5-mvc-패턴의-장점">5. MVC 패턴의 장점</h2>
<table>
<thead>
<tr>
<th>장점</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>유지보수성 향상</td>
<td>각 부분의 책임이 분리되어 수정할 코드의 위치를 파악하기 쉬움</td>
</tr>
<tr>
<td>재사용성 향상</td>
<td>동일한 Model을 여러 View나 Controller에서 활용 가능</td>
</tr>
<tr>
<td>테스트 용이성</td>
<td>UI와 비즈니스 로직을 분리하여 독립적으로 테스트하기 쉬움</td>
</tr>
<tr>
<td>협업 효율 향상</td>
<td>역할별로 작업 범위를 나누고 병렬 개발하기 쉬움</td>
</tr>
<tr>
<td>확장성 및 유연성</td>
<td>화면이나 데이터 처리 방식 변경 시 영향을 줄일 수 있음</td>
</tr>
</tbody></table>
<p>다만 MVC를 적용하기만 하면 모든 장점이 자동으로 생기는 건 아니야.</p>
<p>예를 들어 Controller에 모든 비즈니스 로직을 넣으면 Controller가 지나치게 비대해질 수 있어. 이를 흔히 <strong>Fat Controller</strong> 문제라고 해.</p>
<p>결국 MVC에서도 각 구성 요소의 책임을 적절히 유지하는 것이 중요하지.</p>
<h2 id="6-함께-알아두면-좋은-개념들과-mvc의-관계">6. 함께 알아두면 좋은 개념들과 MVC의 관계</h2>
<p>이제 우리가 앞에서 배웠던 개념과 연결해 보자.</p>
<table>
<thead>
<tr>
<th>개념</th>
<th>MVC와의 관계</th>
</tr>
</thead>
<tbody><tr>
<td>클린 아키텍처</td>
<td>핵심 비즈니스 로직을 DB, 프레임워크, UI 같은 외부 기술에 종속되지 않도록 분리하는 아키텍처 접근 방법. MVC와 마찬가지로 관심사를 분리하지만, 특히 의존성 방향과 비즈니스 로직의 독립성을 강조</td>
</tr>
<tr>
<td>SOLID</td>
<td>MVC의 각 요소를 설계할 때 활용할 수 있는 5가지 원칙</td>
</tr>
<tr>
<td>디자인 패턴</td>
<td>반복적으로 등장하는 설계 문제를 해결하는 재사용 가능한 설계 방식. MVC는 일반적인 객체 수준의 디자인 패턴보다 범위가 큰 아키텍처 패턴이며, 내부 구현에는 옵저버 같은 디자인 패턴이 활용되기도 함</td>
</tr>
<tr>
<td>개발 방법론</td>
<td>애자일, 폭포수 등 어떤 개발 방법론을 사용하든 MVC를 적용할 수 있음</td>
</tr>
</tbody></table>
<p>여기서 한 가지 흥미로운 점이 있어.</p>
<p>MVC는 1970년대 후반 Smalltalk 환경에서 처음 등장했고, SOLID 원칙은 2000년대 초에 정리됐어. 즉 <strong>MVC는 SOLID보다 훨씬 먼저 존재했던 패턴</strong>이야.</p>
<p>따라서 MVC가 SOLID를 기반으로 만들어졌다고 말하는 것은 정확하지 않아. 다만 MVC의 책임 분리 방식은 SRP와 같은 SOLID 원칙의 취지와 잘 맞아.</p>
<h2 id="7-nextjs에서도-mvc-패턴을-사용할-수-있을까">7. Next.js에서도 MVC 패턴을 사용할 수 있을까?</h2>
<p>가능해. 하지만 Next.js App Router는 전통적인 MVC 프레임워크가 아니기 때문에 세 구성 요소가 반드시 명확하게 나뉘는 건 아니야.</p>
<p>예를 들어 게시글 상세 페이지를 구현한다고 생각해 보자.</p>
<table>
<thead>
<tr>
<th>MVC 역할</th>
<th>Next.js에서 대응할 수 있는 부분</th>
</tr>
</thead>
<tbody><tr>
<td>Model</td>
<td>도메인 로직, Service, Repository 등</td>
</tr>
<tr>
<td>View</td>
<td>JSX를 반환하는 React 컴포넌트</td>
</tr>
<tr>
<td>Controller</td>
<td>Route Handler, Server Function 및 요청·입력을 조정하는 로직</td>
</tr>
</tbody></table>
<p>단, 이 대응은 <strong>개념적인 매핑</strong>이야. 특히 서버 컴포넌트는 데이터 조회와 UI 렌더링을 함께 담당할 수도 있기 때문에 단순히 MVC의 View로만 정의하기 어려운 경우도 있어.</p>
<p>그리고 앞에서 배웠던 <code>services</code>, <code>repositories</code>, <code>routes</code>처럼 역할을 나누는 구조와 MVC는 서로 배타적인 것이 아니야.</p>
<blockquote>
<p>Next.js에서는 서버 컴포넌트 하나가 데이터 조회와 화면 렌더링을 모두 담당할 수 있어. 따라서 MVC를 적용한다는 것은 반드시 Model, View, Controller라는 이름의 파일을 각각 만드는 것이 아니라, 프로젝트의 복잡도에 따라 각 책임을 적절하게 분리하는 것을 의미해.</p>
</blockquote>
<h2 id="8-한-가지-개념-더-구분해-보기">8. 한 가지 개념 더 구분해 보기</h2>
<p>웹 개발을 배우다 보면 다음 세 가지가 자주 등장해.</p>
<table>
<thead>
<tr>
<th>구분</th>
<th>핵심 질문</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td>개발 방법론</td>
<td>어떤 과정으로 개발할까?</td>
<td>애자일, 폭포수</td>
</tr>
<tr>
<td>소프트웨어 아키텍처</td>
<td>시스템 전체를 어떻게 구성할까?</td>
<td>계층형, 마이크로서비스</td>
</tr>
<tr>
<td>디자인 패턴</td>
<td>반복되는 설계 문제를 어떻게 해결할까?</td>
<td>팩토리, 전략, 옵저버</td>
</tr>
</tbody></table>
<p>아키텍처와 디자인 패턴은 경계가 일부 겹치기도 해. 특히 MVC처럼 시스템의 책임을 나누는 방식은 <strong>아키텍처 패턴</strong>으로 분류하는 것이 일반적이야.</p>
<blockquote>
<p>💡 <strong>마무리</strong></p>
<p>MVC의 본질은 세 개의 파일이나 폴더를 만드는 것이 아니라, 서로 다른 책임과 역할을 분리해 변경에 유연한 소프트웨어를 설계하는 것에 있어.</p>
<p>관심사의 분리는 설계 원칙이고, MVC는 <strong>그 원칙을 실현하기 위한 여러 아키텍처 패턴중에 하나</strong>인거지.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[RESTful API]]></title>
            <link>https://velog.io/@cycling-lion-cub/RESTful-API</link>
            <guid>https://velog.io/@cycling-lion-cub/RESTful-API</guid>
            <pubDate>Mon, 28 Sep 2026 00:04:54 GMT</pubDate>
            <description><![CDATA[<h2 id="rest란-무엇일까">REST란 무엇일까?</h2>
<p>Representational State Transfer(REST)는 API 작동 방식에 대한 조건을 부여하는 소프트웨어 아키텍처. 즉 클라이언트와 서버가 데이터를 주고받는 방식을 설계하는 하나의 원칙이자 스타일이에요.</p>
<p><strong>RESTful API</strong>는 이 REST 원칙을 잘 따르는 API를 말해요.</p>
<h2 id="rest의-핵심-아이디어--자원resource을-url로-표현">REST의 핵심 아이디어 : 자원(Resource)을 URL로 표현</h2>
<p>REST의 가장 중요한 개념은 <strong>모든 데이터(자원, Resource)를 URL로 표현하고, 그 자원에 대한 행동(조회/생성/수정/삭제)은 HTTP 메서드로 표현한다</strong>는 점이에요.</p>
<p><img src="https://velog.velcdn.com/images/cycling-lion-cub/post/3d8d5637-d0ce-4855-85f9-4b6b416ce8ba/image.png" alt=""></p>
<h2 id="restful한-api를-위한-설계-원칙">RESTful한 API를 위한 설계 원칙</h2>
<ol>
<li><p>클라이언트 / 서버 구조 :
클라이언트(화면을 보여주는 쪽)와 서버(데이터를 관리하는 쪽)가 명확히 분리되어 있어야 해요. 그래야만 프론트엔드가 React에서 Next.js로 바뀌어도 익스프레스 백엔드는 그대로 둘 수 있고, 반대로 백엔드 로직이 바뀌어도 프론트엔드는 <strong>API 응답 형태만 똑같다면</strong> 아무런 영향도 받지 않기 때문이에요.</p>
</li>
<li><p>무상태성 (Stateless) :
서버는 클라이언트의 이전 요청 상태를 기억하지 않아야 하고, 매 요청마다 그 요청 자체에 필요한 모든 정보가 담겨 있어야 해요. 이 조건은 서버가 매번 요청을 완전히 이해해서 이행할 수 있음을 의미해요. 무상태성이 중요한 이유는 서버 입장에서 보면, 누가 어떤 상태였는지? 계속 기억해야할 경우 서버를 여러대로 늘릴 때 스케일링이 복잡해지는 문제가 생기기 때문이에요.</p>
</li>
<li><p>캐시처리 가능성 (Cacheable) :
서버의 응답에는 이 응답을 캐시해도 되는지에 대한 정보가 명시되어 있어야 해요. 우리가 배운 <strong>revalidate</strong> 개념도 결국 이 데이터를 얼마나 오래 캐시해도 되는지에 대한 정보를 정하고 있어요.</p>
</li>
<li><p>일관된 인터페이스 (Uniform Interface) :
이게 REST의 정체성이라고 할 만큼 중요해요. 다음의 몇가지 세부 규칙으로 나뉘어요.</p>
</li>
</ol>
<ul>
<li>자원의 식별 : 모든 자원은 URL로 고유하게 식별할 수 있어요.</li>
<li>표현을 통한 자원 조작 : 클라이언트는 서버가 보내준 데이터의 표현을 통해 자원을 다뤄요. 실제 데이터베이스에 직접 접근하는게 아니라, JSON이라는 표현물을 서로 주고 받는거죠.</li>
<li>자기 서술적 메시지 : 응답 자체에 이게 뭔지 설명해주는 정보가 담거야 해요. 예를 들면 Content-Type: application/json 헤더로 이 응답은 JSON 형식이라는걸 알려주는 거에요.</li>
<li>HATEOAS : 응답 안에 다음에 할 수 있는 행동에 대한 링크가 포함되어야 한다는 원칙인데, 실무에서는 엄격하게 지켜지지 않는 경우가 많아요.</li>
</ul>
<ol start="5">
<li><p>계층화 시스템 (Layered System) :
클라이언트는 자신이 서버와 직접 통신하는지, 아니면 중간에 프록시 / 로드밸런서 같은 게 껴있는지 알 필요가 없어야 해요. 우리가 이번에 Next.js에서 배운 <strong>프록시(API Route)</strong> 라는 개념도 이 원칙과 연결돼요.</p>
</li>
<li><p>온디맨드 코드 (Code on Demand) :
REST 아키텍처 스타일에서 서버는 클라이언트에게 실행 가능한 코드를 보내서, 클라이언트의 기능을 일시적으로 확장하거나 사용자가 지정할 수 있다는 원칙이에요. 이건 유일하게 선택적인 제약이라서, 지키지 않아도 REST를 위반하는 게 아니에요.</p>
</li>
</ol>
<h2 id="restful-api를-사용하면-어떤-이점이-있을까">RESTful API를 사용하면 어떤 이점이 있을까?</h2>
<ol>
<li><p>확장성 : REST API를 구현하는 시스템은 REST가 클라이언트와 서버 상호 작용을 최적화하기 때문에 효율적으로 크기를 조정할 수 있어요. 무상태는 서버가 과거 클라이언트 요청 정보를 유지할 필요가 없기 때문에 서버 로드를 제거할 수 있어요. 그리고 잘 관리된 캐싱은 일부 클라이언트와 서버간의 상호작용을 부분적으로 또는 완전히 제거할 수도 있죠. 이러한 모든 기능은 성능을 저하시키는 통신 병목 현상을 일으키지 않으면서도 확장성을 유지하게 할 수 있다는 장점이 있어요.</p>
</li>
<li><p>유연성 : RESTful 웹 서비스는 완전하게 클라이언트와 서버 분리를 지원해요. 각 부분이 독립적으로 발전할 수 있도록 다양한 서버 구성 요소를 단순화하고 분리할 수 있어요. 서버 애플리에키션의 플랫폼과 기술 변경은 클라이언트 애플리케이션에 영향을 주지 않아요. 애플리케이션 함수를 계층화하는 기능은 유연성을 더욱 향상시키는데, 예를 들면, 개발자는 애플리케이션 로직을 다시 작성하지 않고도 데이터베이스 계층을 변경할 수도 있죠.</p>
</li>
<li><p>독립성 : REST API는 사용되는 기술과 독립적으로 작용해요. API 설계에 영향을 주지 않고 다양한 프로그래밍 언어로 클라이언트 및 서버 애플리케이션을 모두 작성할 수 있어요. 또한 통신에 영향을 주지 않고 양쪽의 기본 기술을 변경할 수도 있습니다.</p>
</li>
</ol>
<blockquote>
<p>참고자료 :  <a href="https://aws.amazon.com/ko/what-is/restful-api/">https://aws.amazon.com/ko/what-is/restful-api/</a>
<a href="https://velog.io/@somday/RESTful-API-%EC%9D%B4%EB%9E%80">https://velog.io/@somday/RESTful-API-%EC%9D%B4%EB%9E%80</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 컴포넌트]]></title>
            <link>https://velog.io/@cycling-lion-cub/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8</link>
            <guid>https://velog.io/@cycling-lion-cub/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8</guid>
            <pubDate>Mon, 17 Aug 2026 16:22:25 GMT</pubDate>
            <description><![CDATA[<h2 id="1-react-컴포넌트란">1. React 컴포넌트란?</h2>
<p>React 컴포넌트는 <strong>props를 받아서 화면에 그려질 UI(JSX)를 리턴하는, 재사용 가능한 조각</strong> 입니다. 버튼 하나, 리스트 아이템 하나처럼 작은 단위일 수도 있고, 여러 컴포넌트를 조합한 페이지 전체일 수도 있어요.</p>
<pre><code class="language-jsx">import { useState } from &quot;react&quot;;
import ReviewList from &quot;./components/ReviewList&quot;;
import Modal from &quot;./components/Modal&quot;;
import ReviewForm from &quot;./components/ReviewForm&quot;;
import Button from &quot;./components/Button&quot;;
import Layout from &quot;./components/Layout&quot;;
import mockItems from &quot;./mock.json&quot;;
import styles from &quot;./App.module.css&quot;;
import useTranslate from &quot;./hooks/useTranslate&quot;;

function App() {
  const t = useTranslate();
  const [items, setItems] = useState(mockItems);
  const [order, setOrder] = useState(&quot;createdAt&quot;);
  const [isCreateReviewOpen, setIsCreateReviewOpen] = useState(false);
  const sortedItems = [...items].sort((a, b) =&gt; b[order] - a[order]);

  const handleCreate = (data) =&gt; {
    const now = new Date();
    const newItem = {
      id: items.length + 1,
      ...data,
      createdAt: now.valueOf(),
      updatedAt: now.valueOf(),
    };
    setItems([newItem, ...items]);
    setIsCreateReviewOpen(false);
  };

  const handleUpdate = (id, data) =&gt; {
    const index = items.findIndex((item) =&gt; item.id === id);
    const now = new Date();
    const newItem = {
      ...items[index],
      ...data,
      updatedAt: now.valueOf(),
    };
    const newItems = [...items.slice(0, index), newItem, ...items.slice(index + 1)];
    setItems(newItems);
  };

  const handleDelete = (id) =&gt; {
    const nextItems = items.filter((item) =&gt; item.id !== id);
    setItems(nextItems);
  };

  return (
    &lt;Layout&gt;
      &lt;div className={styles.buttons}&gt;
        &lt;div&gt;
          &lt;Button
            className={styles.orderButton}
            variant={order === &quot;createdAt&quot; ? &quot;primary&quot; : &quot;ghost&quot;}
            onClick={() =&gt; setOrder(&quot;createdAt&quot;)}
          &gt;
            {t(&quot;sort by latest&quot;)}
          &lt;/Button&gt;
          &lt;Button
            className={styles.orderButton}
            variant={order === &quot;rating&quot; ? &quot;primary&quot; : &quot;ghost&quot;}
            onClick={() =&gt; setOrder(&quot;rating&quot;)}
          &gt;
            {t(&quot;sort by best&quot;)}
          &lt;/Button&gt;
        &lt;/div&gt;
        &lt;Button className={styles.createButton} onClick={() =&gt; setIsCreateReviewOpen(true)}&gt;
          추가하기
        &lt;/Button&gt;
        &lt;Modal isOpen={isCreateReviewOpen} onClose={() =&gt; setIsCreateReviewOpen(false)}&gt;
          &lt;h2 className={styles.modalTitle}&gt;리뷰 생성&lt;/h2&gt;
          &lt;ReviewForm onSubmit={handleCreate} /&gt;
        &lt;/Modal&gt;
      &lt;/div&gt;
      &lt;ReviewList items={sortedItems} onUpdate={handleUpdate} onDelete={handleDelete} /&gt;
    &lt;/Layout&gt;
  );
}

export default App;
</code></pre>
<p>리액트에서 컴포넌트라는 개념을 사용하는 핵심 이유는 세가지로 볼 수 있습니다.</p>
<ol>
<li><strong>재사용성</strong>: 한 번 만들어두면 <code>&lt;Layout /&gt;</code>처럼 태그 형태로 계속 가져다 쓸 수 있음</li>
<li><strong>독립성</strong>: 컴포넌트마다 자기만의 로직과 상태를 가지고, 서로 조합해서 더 큰 UI를 만들기 가능</li>
<li><strong>선언적(declarative)</strong>: &quot;DOM을 이렇게 조작해라&quot; 가 아니라 &quot;지금 상태에서 화면이 이렇게 생겨야 한다&quot;만 기술하면, 실제 반영은 React 내부에서 알아서 처리</li>
</ol>
<p><img src="https://velog.velcdn.com/images/cycling-lion-cub/post/f1eb08e1-0bd0-4206-a414-cef64ea53da2/image.png" alt="컴포넌트는 props를 받아 JSX를 리턴하고, 그게 실제 화면으로 이어지는 흐름"></p>
<hr>

<h3 id="컴포넌트의-형태">컴포넌트의 형태</h3>
<p>리액트 컴포넌트는 두개의 부분으로 나눌 수 있어요. 하나는 정의하는 부분이며, 다른 하나는 사용하는 부분입니다. <strong>정의하는 부분</strong>은 <code>function</code>으로 컴포넌트를 만들면서 어떤 props가 필요한지 매개변수 자리를 설계하는 곳이고, <strong>사용하는 부분</strong>은 그 컴포넌트를 태그처럼 갖다 쓰면서 실제 값을 채워 넣는 곳이에요.</p>
<p><img src="https://velog.velcdn.com/images/cycling-lion-cub/post/fdfbb048-8f5b-4bc2-a65a-81f884d91942/image.png" alt="리액트 컴포넌트의 두가지 형태"></p>
<hr>

<h3 id="함수형-컴포넌트">함수형 컴포넌트</h3>
<pre><code class="language-jsx">function Counter() {
  const [count, setCount] = useState(0);

  return &lt;button onClick={() =&gt; setCount(count + 1)}&gt;{count}&lt;/button&gt;;
}</code></pre>
<p>그냥 함수예요. <code>useState</code>, <code>useEffect</code> 같은 <strong>훅</strong>으로 상태와 생명주기를 관리해요. 훅은 React 16.8(2019년 2월)부터 쓸 수 있게 됐어요.</p>
<h3 id="클래스형-컴포넌트">클래스형 컴포넌트</h3>
<p>같은 기능을 클래스형으로 짜면 이렇게 만들어 볼 수 있습니다.</p>
<pre><code class="language-jsx">class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
    this.handleClick = this.handleClick.bind(this); // this 바인딩 필요
  }

  handleClick() {
    this.setState({ count: this.state.count + 1 });
  }

  render() {
    return &lt;button onClick={this.handleClick}&gt;{this.state.count}&lt;/button&gt;;
  }
}</code></pre>
<p><code>React.Component</code>를 상속받는 클래스고, 반드시 <code>render()</code>를 구현해야 해요. 상태는 <code>this.state</code>, 업데이트는 <code>this.setState()</code>로 관리해요.</p>
<p><img src="https://velog.velcdn.com/images/cycling-lion-cub/post/b07e9d9b-1fa7-42da-8af8-25a454b9cf65/image.png" alt="함수형 컴포넌트와 클래스형 컴포넌트의 핵심 차이 네 가지"></p>
<h3 id="둘의-차이-표로-정리하면">둘의 차이, 표로 정리하면</h3>
<table>
<thead>
<tr>
<th></th>
<th>함수형 컴포넌트</th>
<th>클래스형 컴포넌트</th>
</tr>
</thead>
<tbody><tr>
<td>형태</td>
<td>함수</td>
<td>클래스 (<code>React.Component</code> 상속)</td>
</tr>
<tr>
<td>상태 관리</td>
<td><code>useState</code></td>
<td><code>this.state</code>, <code>this.setState()</code></td>
</tr>
<tr>
<td>생명주기</td>
<td><code>useEffect</code> 하나로 대부분 처리</td>
<td><code>componentDidMount</code> 등 여러 메서드로 분산</td>
</tr>
<tr>
<td><code>this</code></td>
<td>신경 안 써도 됨</td>
<td>메서드마다 바인딩 필요, 실수하기 쉬움</td>
</tr>
<tr>
<td>로직 재사용</td>
<td>커스텀 훅으로 간단하게</td>
<td>HOC, render props 같은 복잡한 패턴 필요</td>
</tr>
<tr>
<td>현재 위치</td>
<td>사실상 표준</td>
<td>레거시 코드에서 주로 발견됨</td>
</tr>
</tbody></table>
<h3 id="왜-함수형이-대세가-됐나">왜 함수형이 대세가 됐나?</h3>
<p>사실 리액트 초창기엔 상태(state)를 다루려면 무조건 클래스형으로 만들어야 했어요. 그러다 2019년, React가 <strong>훅(Hook)</strong>을 새로 도입하면서 상황이 바뀌었습니다.</p>
<p>훅이 생기기 전엔, 상태 하나 다루려고 해도 <code>constructor</code>, <code>this.state</code>, <code>render()</code> 같은 클래스 문법을 통째로 알아야 했어요. 근데 훅 덕분에, 위에서 본 것처럼 함수 안에 <code>useState</code> 한 줄만 써도 똑같은 걸 훨씬 짧고 간단하게 만들 수 있게 됐어요.</p>
<p>그래서 요즘 새로 만드는 리액트 프로젝트는 대부분 함수형으로 짜여요. 클래스 문법을 몰라도 리액트를 시작할 수 있게 된 거고, 이에 따라 우리도 처음부터 자연스럽게 함수형과 훅의 형태로 배우고 있는 거예요.</p>
<h3 id="클래스형-컴포넌트의-문제">클래스형 컴포넌트의 문제!</h3>
<p>클래스형 컴포넌트의 가장 큰 문제는 <strong><code>this</code> 바인딩 문제</strong>예요. 클래스형에서는 이벤트 핸들러 안 <code>this</code>가 엉뚱한 걸 가리키는 실수가 흔해서, 매번 <code>.bind(this)</code>를 해주거나 화살표 함수로 우회해야 했어요. 또, <strong>로직 재사용</strong>이 훨씬 쉬워요. 함수형과 훅에서는 반복되는 상태 관리 로직을 그냥 <strong>커스텀 훅</strong> 하나로 뽑아내서 여러 컴포넌트가 나눠 쓸 수 있거든요.</p>
<hr>

<h2 id="한-줄-요약">한 줄 요약</h2>
<ul>
<li><strong>컴포넌트</strong>: props를 받아 UI를 리턴하는 재사용 단위. 지금은 함수형과 훅 사용이 표준.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 비동기 처리]]></title>
            <link>https://velog.io/@cycling-lion-cub/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC</link>
            <guid>https://velog.io/@cycling-lion-cub/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC</guid>
            <pubDate>Thu, 30 Jul 2026 11:31:37 GMT</pubDate>
            <description><![CDATA[<h2 id="자바스크립트-엔진은-오케스트라-지휘자다">자바스크립트 엔진은 오케스트라 지휘자다</h2>
<p><img src="https://velog.velcdn.com/images/cycling-lion-cub/post/add23357-8e38-4503-af9d-23fff3aa3b17/image.png" alt="오케스트라"></p>
<h3 id="지휘자와-연주자">지휘자와 연주자</h3>
<ul>
<li>지휘자는 딱 한 명 → <strong>자바스크립트 엔진</strong> (싱글 스레드)</li>
<li>연주자는 여러 명 → <strong>Web API, OS 커널</strong> 등</li>
<li>지휘자는 연주자에게 일을 맡기고, <strong>기다리지 않고</strong> 바로 다음으로 넘어감</li>
<li>연주자가 일을 끝내면, 지휘자가 그 결과를 순서대로 받아서 처리</li>
</ul>
<table>
<thead>
<tr>
<th>지휘자 (JS 엔진)</th>
<th>연주자 (Web API)</th>
</tr>
</thead>
<tbody><tr>
<td>코드를 한 줄씩 실행</td>
<td>시간 걸리는 일(네트워크, 타이머) 처리</td>
</tr>
<tr>
<td>한 번에 하나만 실행</td>
<td>여러 명이 동시에 각자 파트 연주</td>
</tr>
<tr>
<td>기다릴 필요 없는 일은 즉시 처리</td>
<td>일 끝나면 결과를 지휘자에게 전달</td>
</tr>
</tbody></table>
<p><strong>위임 기준: &quot;이 작업, 시간이 걸리나?&quot;</strong>
→ 시간이 걸리면 연주자에게 위임 / 그렇지 않으면 지휘자가 즉시 처리</p>
<hr>
<h2 id="실제-코드로-보면">실제 코드로 보면</h2>
<p><img src="https://velog.velcdn.com/images/cycling-lion-cub/post/5447d737-e589-419b-aae5-45a156330617/image.png" alt="코드잇"></p>
<pre><code class="language-js">printEmployees();
console.log(&#39;Task 2&#39;);
console.log(&#39;Task 3&#39;);</code></pre>
<ol>
<li><code>printEmployees()</code> 실행 → 안에서 <code>fetch(...)</code>를 만남</li>
<li><code>fetch</code>는 연주자(네트워크 담당)에게 위임 → 지휘자는 기다리지 않고 다음 줄로</li>
<li><code>console.log(&#39;Task 2&#39;)</code>, <code>console.log(&#39;Task 3&#39;)</code> → 즉시 처리</li>
<li>연주자가 네트워크 요청을 끝내면 → 그제서야 데이터 처리 실행</li>
</ol>
<p><strong>출력 순서</strong></p>
<pre><code>Task 2
Task 3
[ { id: 1, name: &#39;Jason&#39;, ... } ]</code></pre><hr>
<h2 id="시각화로-다시-정리">시각화로 다시 정리</h2>
<p><img src="https://velog.velcdn.com/images/cycling-lion-cub/post/e9f479d9-69de-4855-a1ab-9bfaca2caf54/image.png" alt="자바스크립트 런타임 시각화"></p>
<table>
<thead>
<tr>
<th>다이어그램</th>
<th>오케스트라 비유</th>
</tr>
</thead>
<tbody><tr>
<td>Call Stack</td>
<td>지휘자가 지금 실행 중인 무대</td>
</tr>
<tr>
<td>Web APIs</td>
<td>연주자들이 각자 파트 연주하는 대기실</td>
</tr>
<tr>
<td>Task / Microtask Queue</td>
<td>연주 끝낸 사람들이 줄 서서 대기하는 곳</td>
</tr>
<tr>
<td>Event Loop</td>
<td>지휘자가 &quot;무대 비었나?&quot; 계속 확인하는 것</td>
</tr>
</tbody></table>
<p><strong>흐름 요약</strong></p>
<ol>
<li>동기 코드 → Call Stack에서 바로 실행</li>
<li>비동기 작업(<code>fetch</code>, <code>setTimeout</code>) → Web APIs로 위임</li>
<li>작업이 끝나면 결과 → Task / Microtask Queue에서 대기</li>
<li>Call Stack이 비면 → Event Loop가 큐에서 꺼내서 실행</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로토타입 #2 : 프로토타입(1)]]></title>
            <link>https://velog.io/@cycling-lion-cub/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-2-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%851</link>
            <guid>https://velog.io/@cycling-lion-cub/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-2-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%851</guid>
            <pubDate>Mon, 27 Jul 2026 13:43:30 GMT</pubDate>
            <description><![CDATA[<h2 id="프로토타입-기반-언어인-자바스크립트">프로토타입 기반 언어인 자바스크립트</h2>
<h3 id="구현하는-방식이-언어마다-다르다">구현하는 방식이 언어마다 다르다</h3>
<p><strong>객체지향 프로그래밍은 실제 세상에 존재하는 사물이나 개념에 대해 속성과 동작이라는 하나의 덩어리로 묶어서 프로그래밍 세계 안에 표현하는 것</strong>을 이야기해요. 다양한 종류의 프로그래밍 언어들은 이렇게 객체지향이라는 철학 아래 같은 목표를 향해 달리고 있지만, 각 언어마다의 특징들로 인해 이를 구현하는 방식은 서로 달라요. 이 구현 방식에 따라 언어는 두개의 부류로 나눌 수 있어요.</p>
<h4 id="1-클래스-기반-언어">1. 클래스 기반 언어</h4>
<p>자바, C++, 파이썬 같은 언어는 클래스(class)라는 <strong>설계도</strong>를 먼저 정의하고, 그 설계도를 바탕으로 <strong>객체(인스턴스)</strong>를 찍어내는 방식이에요.</p>
<pre><code class="language-java">// 자바 예시
class Dog {
  String name;
  void bark() { System.out.println(&quot;멍멍!&quot;); }
}

Dog dog1 = new Dog();</code></pre>
<p>여기서 Dog라는 클래스는 실체가 없는 추상적인 틀이에요. 객체(dog1)는 이 클래스로부터 찍혀 나오는 결과물이고요. 클래스와 객체는 명확히 다른 두 가지 존재예요. 이렇게 Dog 클래스라는 추상적인 틀로부터, dog1 이라는 인스턴스가 생겨나게 되는 거죠.</p>
<h4 id="2-프로토타입-기반-언어">2. 프로토타입 기반 언어</h4>
<p>자바스크립트는 자바와 같은 클래스 기반 언어와 조금 다르게 접근해요. <strong>클래스라는 별도의 추상적인 설계도 없이, 이미 존재하는 객체를 복제하거나 참조해서 새 객체를 만드는 방식</strong>이에요.</p>
<pre><code class="language-javascript">const animal = {
  eat() { console.log(&quot;먹는다&quot;); }
};

const dog1 = Object.create(animal); // animal을 원형(prototype)으로 삼아 새 객체 생성
dog1.bark = function () { console.log(&quot;멍멍!&quot;); };

dog1.eat();  // &quot;먹는다&quot;  ← animal한테 물려받음
dog1.bark(); // &quot;멍멍!&quot;</code></pre>
<p>여기서 dog1은 클래스로부터 찍혀 나온 게 아니라, 이미 존재하는 객체(animal)를 원형(prototype)으로 삼아서 그걸 참조해요. 설계도로부터 결과물이 만들어지는 게 아니라, 이미 있는 객체와 그걸 참조하는 새 객체 관계라고 볼 수 있어요.</p>
<blockquote>
<p><strong>자바스크립트는 프로토타입 기반 언어다</strong>라는 말은, 클래스라는 별도의 추상적인 설계도 없이, 이미 존재하는 객체를 원형(Prototype) 삼아 그걸 참조 및 복제해서 새로운 객체를 만들어내는 방식으로 객체지향을 구현하는 언어라는 뜻이에요.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[getElementsByClassName 메서드]]></title>
            <link>https://velog.io/@cycling-lion-cub/getElementByClassName-%EB%A9%94%EC%84%9C%EB%93%9C</link>
            <guid>https://velog.io/@cycling-lion-cub/getElementByClassName-%EB%A9%94%EC%84%9C%EB%93%9C</guid>
            <pubDate>Mon, 27 Jul 2026 10:08:51 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>인터랙티브 자바스크립트라는 수업시간에 getElementsByClassName()이라는 메서드에 대해 배웠습니다. 이 메서드는 유사배열이라는 형태로 값을 반환한다고 하는데, 그 이유가 궁금해서 찾아본 내용입니다.</p>
</blockquote>
<h2 id="왜-배열이-아니라-배열-형태로-감싸주는-걸까">왜 배열이 아니라 배열 형태로 감싸주는 걸까?</h2>
<p>getElementsByClassName() 메서드가 유사배열이라는 형태로 값을 반환하는 이유는 getElementsByClassName()은 문서 안에서 <strong>같은 클래스를 가진 요소가 몇 개일지 미리 알 수 없기 때문</strong>입니다. 요소는 1개일 수도 있고, 100개일 수도 있지만, 결국 중요한 사실은 자바스크립트 코드를 실행하기 전에는 요소의 개수를 확인할 수 없다는 점입니다. 그래서 브라우저는 찾은 요소들을 순서대로 나열해서 담아줄 그릇을 필요로하게 됩니다. 이때 배열이 아니라 <strong>HTMLCollection</strong>이라는 걸 사용해서 반환합니다.</p>
<p>여기서 핵심은, 이 메서드는 1990년대 DOM 표준(DOM Level 1~2)이 만들어질 때부터 있던 아주 오래된 <strong>Web API</strong>라는 점입니다. 그 당시엔 지금 우리가 쓰는 Array.prototype.map, forEach 같은 배열 메서드들이 자바스크립트에 아예 존재하지 않았습니다. DOM은 사실 자바스크립트 전용으로 설계된 게 아니라 여러 언어(Java, VBScript 등)에서도 쓸 수 있게 언어 중립적으로 설계되었거든요. 그래서 <strong>배열</strong>이라는 자바스크립트 고유의 자료구조 대신, DOM 자체의 규격인 <strong>HTMLCollection</strong>이라는 형태로 정의되었습니다. 이게 지금까지 하위 호환성 때문에 그대로 유지되고 있는 거고요.</p>
<hr>
<h2 id="유사배열array-like은-진짜-배열과-무엇이-다를까">유사배열(Array-like)은 진짜 배열과 무엇이 다를까?</h2>
<p>유사배열은 이름 그대로 생김새는 배열과 같이 보이지만, 배열이 아닌 것을 의미합니다.</p>
<h4 id="공통점-배열처럼-보이는-이유">공통점 (배열처럼 보이는 이유)</h4>
<ul>
<li>요소[0], 요소[1]처럼 인덱스로 접근 가능</li>
<li>length 프로퍼티로 개수 확인 가능</li>
<li>for 반복문으로 순회 가능</li>
</ul>
<h4 id="차이점-진짜-배열이-아닌-이유">차이점 (진짜 배열이 아닌 이유)</h4>
<ul>
<li>Array.prototype을 상속받지 않았기 때문에 map(), filter(), forEach(), reduce(), push(), sort() 같은 배열 메서드를 쓸 수 없음</li>
<li>console.log()로 찍어보면 [object HTMLCollection]처럼 배열이 아닌 다른 타입으로 표시</li>
<li>Array.isArray(요소)를 해보면 false 값 반환</li>
</ul>
<pre><code class="language-javascript">const boxes = document.getElementsByClassName(&#39;box&#39;);
boxes.forEach(box =&gt; console.log(box)); // ❌ TypeError: boxes.forEach is not a function</code></pre>
<hr>
<h2 id="참고할-사항-live-collection">참고할 사항: Live Collection</h2>
<p>getElementsByClassName()이 반환하는 HTMLCollection은 살아있는(live) 컬렉션입니다. 즉, DOM이 바뀌면 이 컬렉션도 자동으로 실시간 갱신되죠. 반면 querySelectorAll()이 반환하는 NodeList는 <strong>정적(static)</strong>이라서 나중에 DOM이 바뀌어도 처음 찾은 스냅샷 그대로 유지되는 모습을 보입니다. 이 부분도 헷갈리기 쉬운 부분이니까 기억해두면 좋아요!</p>
<hr>
<h2 id="그래서-실무에서는-어떻게">그래서 실무에서는 어떻게?</h2>
<p>map, filter 같은 배열 메서드가 필요할 때는, 진짜 배열로 변환하는 방식을 통해 배열 메서드를 사용할 수 있습니다. 가장 많이 쓰는 방법 두가지를 소개해 볼게요.</p>
<pre><code class="language-javascript">const boxes = document.getElementsByClassName(&#39;box&#39;);

// 방법 1: Array.from() 사용 (가장 많이 씀)
const boxArray = Array.from(boxes);

// 방법 2: 스프레드 문법 사용
const boxArray2 = [...boxes];

// 이제 배열 메서드 다 사용 가능!
boxArray.forEach(box =&gt; console.log(box));</code></pre>
<p>참고로 실무에서 순수 HTML/CSS/JS로 작업할 때는 getElementsByClassName보다 querySelectorAll을 더 많이 쓰는 편이라고 합니다.</p>
<blockquote>
<p><strong>참고</strong>
나의 친구 클로드! 🤣</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로토타입 #1 : 객체지향 프로그래밍]]></title>
            <link>https://velog.io/@cycling-lion-cub/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-1-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</link>
            <guid>https://velog.io/@cycling-lion-cub/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85-1-%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D</guid>
            <pubDate>Sun, 26 Jul 2026 18:33:50 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><strong>자바스크립트는 객체 기반의 프로그래밍 언어입니다.</strong>
심지어 자바스크립트를 이루고 있는 <strong>거의 모든 것</strong>을 객체라고도 말할 수 있죠.</p>
</blockquote>
<p>자바스크립트를 공부하다 보면 아마 손쉽게 <strong>자바스크립트는 객체다</strong>라는 표현을 들어보셨을 거예요. 다들 왜 이런 표현이 사용되는지 궁금하시지 않은가요?
이번 시간에는 프로토타입이라는 개념을 주제로 공부하기 전에, 우선 알고 넘어가야 하는 객체지향 프로그래밍이라는 개념에 대해 간단하게 살펴볼게요.</p>
<hr>
<h2 id="객체지향-프로그래밍">객체지향 프로그래밍</h2>
<p>객체지향 프로그래밍은 절차 지향적 관점에서 벗어나 <strong>여러 개의 독립적인 단위의 집합으로 프로그램을 표현하려는 프로그래밍 패러다임</strong>을 이야기해요. 다시 말하자면, 프로그램을 명령어 또는 함수의 목록으로 보는 전통적인 방법에서 벗어나 객체라는 독립적인 집합으로 표현하는 방법인 것이죠. 여기에서 객체란, 데이터의 상태(속성)와 그 데이터를 다루는 동작(메서드)을 하나로 묶은 덩어리를 이야기해요.</p>
<p>객체지향 프로그래밍은 실제 세상에 존재하는 사물이나 개념을 프로그래밍에 접목하려는 시도에서 생겨났어요. 사물이나 개념은 각각의 특징이나 성질을 나타내는 속성을 가지고 있죠? 예를 들면 사람은 이름, 주소, 성별, 나이, 신장, 체중과 같은 다양한 속성을 가지고 있어요. 그리고 우리는 이러한 속성을 이용해서 어떠한 사람을 특정하거나, 다른 사람과 구분해 낼 수 있게 되죠.</p>
<p>이처럼 <strong>실제 세상에 존재하는 사물이나 개념에 대해 속성과 동작이라는 하나의 덩어리로 묶어서 프로그래밍 세계 안에 표현하는 것</strong>을 바로 객체지향 프로그래밍이라고 해요.</p>
<hr>
<h3 id="원이라는-개념을-객체로-표현하기">원이라는 개념을 객체로 표현하기</h3>
<pre><code class="language-javascript">const circle = {
  radius: 5, // 반지름

  // 원의 지름: 2r
  getDiameter() {
    return 2 * this.radius;
  },

  // 원의 둘레: 2πr
  getPerimeter() {
    return 2 * Math.PI * this.radius;
  },

  // 원의 넓이: πr²
  getArea() {
    return Math.PI * this.radius ** 2;
  },
};

console.log(circle); // {radius: 5, getDiameter: 𝑓, getPerimeter: 𝑓, getArea: 𝑓}

console.log(circle.getDiameter()); // 10
console.log(circle.getPerimeter()); // 31.41592653589793
console.log(circle.getArea()); // 78.53981633974483</code></pre>
<p>앞에서 서술한 내용을 바탕으로 원이라는 개념을 객체로 만들어 본다면 위와 같이 표현할 수 있어요. 원은 반지름이라는 속성을 가져요. 그리고 우리는 이 반지름을 가지고 원의 지름, 둘레, 넓이를 구할 수도 있죠. 이때 반지름은 원의 상태를 나타내는 데이터, 원의 지름과 둘레 그리고 넓이를 구하는 작업은 동작이라고 부를 수 있어요.</p>
<p>이처럼 객체지향 프로그래밍은 객체의 상태를 나타내는 데이터와 상태 데이터를 조작할 수 있는 동작을 하나의 논리적인 단위로 묶어 생각해요. 그래서 객체는 <strong>상태 데이터와 동작을 하나의 논리적인 단위로 묶은 복합적인 자료구조</strong>라고 할 수 있어요.</p>
<p>그런데 객체는 사실 혼자 독립적으로만 존재하는 게 아니에요. 각 객체는 고유의 기능을 갖는 독립적인 부품이면서 동시에, 다른 객체와 관계를 맺기도 해요. 서로 메시지를 주고받거나, 심지어 다른 객체가 가진 상태 데이터나 동작을 물려받아 사용하기도 하죠.</p>
<p>다른 객체의 기능을 물려받아 사용하는 것, 이걸 <strong>상속</strong>이라고 해요. 그런데 자바스크립트는 원래 과거에 class라는 문법이 없었는데, 어떻게 상속이라는 개념을 구현했을까요? 그 답이 바로 다음 편에서 다룰 프로토타입이에요. 다음 글에서 자세히 살펴볼게요.</p>
<blockquote>
<p><strong>참고자료</strong>
책 : <a href="https://product.kyobobook.co.kr/detail/S000001766445">모던 자바스크립트, Deep Dive</a></p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>