<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hanl__l.log</title>
        <link>https://velog.io/</link>
        <description>개인 공부용</description>
        <lastBuildDate>Mon, 19 Feb 2024 10:43:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>hanl__l.log</title>
            <url>https://velog.velcdn.com/images/hanl__l/profile/2fc00de1-cf1f-46cd-88c1-0fcd6aff7cb2/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. hanl__l.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hanl__l" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[HTML] URI Fragment]]></title>
            <link>https://velog.io/@hanl__l/HTML-URI-Fragment</link>
            <guid>https://velog.io/@hanl__l/HTML-URI-Fragment</guid>
            <pubDate>Mon, 19 Feb 2024 10:43:00 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.codeit.kr/topics/html-core-concepts/lessons/5702">코드잇 - HTML 핵심 개념 (페이지 안에서 이동하기)</a></p>
<p><img src="https://velog.velcdn.com/images/hanl__l/post/a39f0ce2-bc34-4008-8ee2-202f31c65987/image.jpeg" alt=""></p>
<h2>프래그먼트</h2>

<p>프래그먼트는 리소스 자체의 다른 부분을 가르키는 앵커이다. 
앵커는 리소스 내에서 북마크의 한 종류를 나타내며, 브라우저에게 &#39;북마크 된&#39; 지점에 위치한 컨텐츠를 보여주기 위한 방법을 나타낸다. HTML 문서 상에서 브라우저는 앵커가 정의된 시점으로 스크롤 된다.</p>
<p>프래그먼트 사용 시 a 태그의 href에 #id 값을 적는다. (class 는 불가하다.)</p>
<h4>예시</h4>

<pre><code class="language-HTML">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta charset=&quot;utf-8&quot;&gt;
  &lt;title&gt;한국 영화&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;a href=&quot;#1950s&quot;&gt;역사 1950년대&lt;/a&gt;
  &lt;a href=&quot;#1960s&quot;&gt;역사 1960년대&lt;/a&gt;
  &lt;a href=&quot;#1970_1980s&quot;&gt;역사 1970 ~ 1980년대&lt;/a&gt;

  &lt;h2 id=&quot;1950s&quot;&gt;1950년대&lt;/h2&gt;
  &lt;div&gt;
    &lt;p&gt;
      1945년 8월 15일 광복이 되자마자 영화인들은 거의 맨주먹으로 다시금 재기하기에 안간힘을 썼다. 광복 직후인 1946년과 1947년의 영화는 광복의 감격을 표현한 작품이 대부분이었다. 한동안 동면기에 있었던 영화인들이 서서히 일어나 또다시 영화예술을 꽃피우게 되었다. 1946년에 최인규가 고려영화사(高麗映畵社)를 창립하고 《자유만세》를 만들어 흥행에 크게 성공했으며, 뒤를 이어 이구영의 《안중근 사기》 , 윤봉춘의 《윤봉길 의사》, 전창근의 《해방된 내고향》, 이규환의 《똘똘이의 모험》· 《3·1혁명기》·《해방된 내 고향》, 김소동의 《모란등기(牡丹燈記)》 등이 발표되었다. 그 뒤 1947년에 윤봉춘의 《유관순》, 신경균의 《새로운 맹세》, 최인규의 《죄없는 죄인》, 이규환의 《갈매기》가 나왔는데, 특히 《새로운 맹세》에서 최은희가 데뷔하기도 했다. 이듬해인 1948년에는 한형모가 《성벽을 뚫고》를 발표하여 크게 성공했다. 그러나 한국의 영화가 그 예술적인 면에서 크게 진전을 본 것은 1960년 이후의 일이었다. 초창기로부터 해방 당시까지 그 의욕은 왕성했지만 예술적인 차원에서는 아직도 미숙했었다. 다른 예술과 마찬가지로 영화인들은 민족의 고뇌와 분노를 간접적으로 표현하는 데 영화를 하나의 수단으로 사용한 예가 오히려 많았다고 주장되기도 한다.[5]
    &lt;/p&gt;
    &lt;p&gt;
      1950년 6·25전쟁기에 영화인들은 다시 한번 시련기에 처했지만, 각자 역경 속에서도 1952년 전창근은 《낙동강》을, 이만흥은 《애정산맥》을 발표했고, 같은 해 최인규 문하생이던 신상옥이 《악야(惡夜)》로, 정창화가 《최후의 유혹》으로 각각 등장했다. 1954년 수도로 돌아온 영화인들은 외국 영화의 홍수라는 새로운 도전 속에서도 줄기차게 영화를 만들었다. 1954년 김성민의 《북위 41도》, 윤봉춘의 《고향의 노래》, 홍성기의 《출격명령》, 신상옥의 《코리아》 등이 나왔다. 이 해의 ‘영화평론가협회상(永畵評論家協會賞)’과, 한국영화 초창기의 공로자인 이금룡을 추모하는 뜻에서 ‘금룡상(金龍賞)’이 제정되어 영화계에 활기를 주었고, 이강천의 《피아골》에서 김진규가 데뷔하기도 했다. 1955년 5월에는 전 영화인과 관객들의 여망에 따라 국산 영화에 대한 면세조치가 취해져 이후 한국영화의 전성기를 맞이하는 중대한 계기가 되기도 했다. 이 해 개봉된 이규환의 《춘향전》은 당시 개봉관에서 10만 이상의 관객을 동원하는 등 한국영화의 르네상스를 맞이하기에 이르렀다. 1957년에는 최신 영화 기재를 도입한 안양촬영소의 준공을 보게 되었다.[6]
    &lt;/p&gt;

  &lt;/div&gt;

  &lt;h2 id=&quot;1960s&quot;&gt;1960년대&lt;/h2&gt;
  &lt;div&gt;
    &lt;p&gt;중흥기는 편의상 한국영화의 시기를 3등분하여 제작편수를 비교해 본다면, 1919년 ~ 1945년의 초창기에 제작된 영화편수가 166편, 1946년 ~ 1953년 과도기에 제작된 영화수가 86편, 1954년 ~ 1970년 중흥기에 제작된 영화수가 2,021편이나 된다. 다시 말하면, 1955년 이후 국산영화 면세조치와 최신 영화 기재의 도입, 그리고 관객의 절대적인 호응이 영화인들을 크게 고무한 결과가 되어, 1954년 이래 영화 중흥기를 맞이하였다고 볼 수 있다.[6]&lt;/p&gt;
    &lt;p&gt;그러나, 그와 같은 영화 산업의 전성시기도 1968년부터 서서히 퇴조하기 시작했으니, 그것은 텔레비전이라는 새로운 전파 매체의 강력한 도전, 그리고 이른바 대중오락의 다극화시대를 맞이하여 소위 영화예술만이 대중들의 절대적인 총애를 받던 시대가 지나간 것이다. 그리고, 한국영화계는 일제말의 수난기, 6·25의 진통기를 거쳐, 제3의 시련인 불황기에 접어든 것이다. 물론 1960년대 초반부터 중반 이후까지 일종의 대유행을 형성했었던 청춘영화라든가 문예영화(文藝映畵)라는 새로운 장르의 영화들이 등장, 한때나마 활기를 띠었던 것도 인정할 수는 있다. 특히 신성일은 이 무렵 《맨발의 청춘》, 《청춘교실》, 《흑맥》 등의 영화를 통하여 한국적인 의미의 스타시스템을 구축했으며, 문예영화(文藝映畵)쪽에서는 1961년 신상옥의 《사랑방 손님과 어머니》와 유현목의 《오발탄》, 1965년 김수용의 《갯마을》, 1966년 이만희의 《만추》, 1969년 최하원의 《독짓는 늙은이》 같은 우수한 작품들이 쏟아져나와 한국 영화의 질을 높여주기도 했다.[6]&lt;/p&gt;
  &lt;/div&gt;

  &lt;h2 id=&quot;1970_1980s&quot;&gt;1970년대&lt;/h2&gt;
  &lt;div&gt;
    &lt;p&gt;1970년대에 들어와서는 또다시 참담한 불황의 벽에 부딪쳐 허덕이다가, 1974년 이장호의 《별들의 고향》, 1977년 김호선의 《겨울여자》로 차츰 돌파구를 찾기 시작했다. 영화를 제작하는 기업은 영세하고 시장은 협소하여 외화와 같이 영화제작에 충분한 시간과 경비를 투입할 수 없었고, 또한 자본주인 흥행사의 간섭 등으로 의욕있는 작품을 제작되기에는 어려운 여건에 놓여 있었다. 이와 같이 침체된 상황을 타개하기 위해 정부에서도 영화산업의 보호 육성책으로 1971년 2월에 영화진흥조합을 발족시켜 방화제작비 융자, 시나리오 창작금 지원, 영화인 복지사업 등을 추진하게 되었다.&lt;/p&gt;
    &lt;p&gt;1980년대 초에는 텔레비전 보급과 레저 산업의 성장에 의해 영화가 지녔던 대중 오락적 기능은 상대적으로 감소되어 영화산업이 사양화하고 있었지만 1986년 영화법 개정 이후 영화제작자유화로 활기를 띠기 시작했다. 1989년 제작된 방화는 1980년대 들어 가장 많은 106편에 달했다. 실제로 1989년은 방화가 물량면에서는 1980년대 들어 최다제작이 이루어졌으나 외화직배문제로 외화수입물량이 폭증하여 방화가 흥행에 성공하지 못했고, 관객의 방화외면, 외화의 선호현상이 더욱 심화된 것으로 나타났다. 또한, 외화는 방화보다도 많은 관객을 확보하고 있었다. 1980년대의 한국 영화계의 불황은 텔레비전 보급과 레저산업의 성장이라는 외적인 면보다는 내적인 면에 더 큰 원인이 있었고, 사회적·경제적·기술적인 제반 여건이 충족되지 않은 비정상적인 출발이 한국 영화를 산업으로 성장시키지 못하고 소규모의 기업에 머물게 하였다.[7]&lt;/p&gt;
    &lt;p&gt;1988년 UIP에서 직접 배급을 맡은 미국 영화 &lt;위험한 정사&gt;의 국내 첫 상영으로 위기의식을 느낀 한국영화계는 한국영화 거듭나기를 위한 한국영화법 개정을 비롯하여 UIP의 직배저지 투쟁을 전개해 전체 영화인을 심기일전시켰다. 그러나 일부 영화인의 사욕은 내분을 자초해 영화인의 치부를 드러내기도 했다. 그 결과, 한국영화 관객의 반응은 냉담했고 그 틈을 타서 미국 직배영화는 전국의 영화관을 장악했다. 서울시네마타운의 &lt;사랑과 영혼&gt;은 사대문 안에 위치한 개봉관에 첫 입성한 직배영화로, 한국영화인들은 국내영화산업은 종말이 왔다고 우려할 정도로 심각한 상황을 경고했다.&lt;/p&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[오류 해결] 인코딩 에러]]></title>
            <link>https://velog.io/@hanl__l/%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0-%EC%9D%B8%EC%BD%94%EB%94%A9-%EC%97%90%EB%9F%AC</link>
            <guid>https://velog.io/@hanl__l/%EC%98%A4%EB%A5%98-%ED%95%B4%EA%B2%B0-%EC%9D%B8%EC%BD%94%EB%94%A9-%EC%97%90%EB%9F%AC</guid>
            <pubDate>Tue, 06 Feb 2024 14:52:51 GMT</pubDate>
            <description><![CDATA[<p>최근, 파이썬으로 데이터 분석을 하려고 도서관에서 책을 빌려와서 하던 도중 인코딩 에러가 발생했다.</p>
<blockquote>
<h3 id="인코딩-에러">인코딩 에러</h3>
<p> &#39;cp949&#39; codec can&#39;t decode byte 0xeb in position 18: illegal multibyte sequence</p>
</blockquote>
<p>utf-8로 되지 않아 cp949로 진행했는데, 다시 cp949가 안되어 utf-8로 진행했고, 문제 없이 챕터를 마칠 수 있었다. 왜 번복해서 사용하게 되었는지는 모르겠으나, 일단 인코딩 에러이므로, 이에 대해 정리하고자 한다.</p>
<h3>인코딩</h3>
인코딩은 어떤 정보를 특수한 목적을 가지고, 다른 형태로 변환하는 행위를 의미한다. 즉, 여기서는 텍스트(문자)를 기계가 이해할 수 있는 언어(기계어)로 표현하는 방법을 뜻한다.

<p>예를 들면, 대문자 A는 65로, 소문자 a는 97로 나타나진다. 아래는 ASCII (American Standard Code for Information Interchange) 테이블로, 컴퓨터에 사용할 문자를 2진수로 인코딩하기 위한 7비트의 고정길이 코드 체계이다.</p>
<p><img src="https://velog.velcdn.com/images/hanl__l/post/990e8c7e-3651-4cb3-af99-0e3dcda1b1f0/image.png" alt=""></p>
<h3>한글</h3>
한글은 총 글자수가 11,172자가 존재하기 때문에, 아스키테이블과 같은 1바이트(8비트) 체계로는 불가능하다. 더불어 한글은 자음과 모음을 조합하여 (초성, 중성, 종성을 조합) 글자를 표현하기 때문에, 이를 표현하기 위해 조합형과 완성형 방식으로 나뉘게 되었다.

<h4>조합형 방식</h4>
조합형 방식은 자음 + 모음 또는 초성 + 중성 + 종성을 조합하여 글자를 만들어 내는 방식이다. 조합형은 2바이트 체계로 총 16바이트에서 앞의 1비트는 한글임을 알리는 비트로 사용하고, 나머지 15비트는 초성, 중성, 종성을 각 5비트로 구분지어서 사용한다.

<p>자음과 모음 모든 조합을 표현할 수 있지만, 중성의 첫비트가 0일 경우 다른 ASCII 코드와 충돌할 수 있다는 단점이 있다.</p>
<h4>완성형 방식</h4>
완성형 방식은 사용빈도가 낮은 글자(예 : 첣, 껽 등)들을 제외하고 한글의 모든 글자(가 ~ 힣)를 각각 숫자로 매핑한 방식이다. EUC-KR, CP949, MS949 등이 완성형 인코딩 방식이다. 자음과 모음의 조합을 해석하는데 들어가는 비용이 줄어 조합형보다는 효율적이라 할 수 있으나, 사용하지 못하는 글자가 있다는 단점이 있다.


<h3>유니코드</h3>
1991년 전 세계 모든 문자를 매핑하는 문자 집합인 유니코드가 등장하게 되었다. 유니코드는 완성형과 같이 각 글자에 숫자를 매핑한 방식으로, 문자 하나를 4바이트(32비트)로 지정하고 있다. ASCII 코드가 1바이트 공간을 차지하는데 비해, 유니코드가 4바이트를 차지하여 비효율인 점을 보완하기 위해 UTF-8, UTF-16 등이 등장하게 되었다.

<p>UTF-8(Unicode Transformation Format - 8)은 가변 길이 문자 인코딩 방식으로, ASCII 포함 전 세계의 문자를 지원하고, 한글을 표현하는데는 3바이트를 사용한다.</p>
<h3>오류 해결 </h3>
생각보다 오류 해결은 간단하다. 뒤에 encoding을 더해주기만 하면 된다.

<p><img src="https://velog.velcdn.com/images/hanl__l/post/4ea99c8d-1d70-400a-8490-df6b87274dd5/image.png" alt=""></p>
<p>utf-8로 인코딩을 하고 다시 실행했을 때, 문제 없이 진행할 수 있었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 제어 컴포넌트 / 비제어 컴포넌트]]></title>
            <link>https://velog.io/@hanl__l/React-%EC%A0%9C%EC%96%B4-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EB%B9%84%EC%A0%9C%EC%96%B4-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8</link>
            <guid>https://velog.io/@hanl__l/React-%EC%A0%9C%EC%96%B4-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8-%EB%B9%84%EC%A0%9C%EC%96%B4-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8</guid>
            <pubDate>Tue, 12 Dec 2023 05:37:44 GMT</pubDate>
            <description><![CDATA[<p><a href="https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components">리액트 공식 문서</a></p>
<h3>제어 컴포넌트 (Controlled Components)</h3>

<pre><code class="language-jsx">import React, { useState } from &#39;react&#39;;

function ControlledInput() {
  const [inputValue, setInputValue] = useState(&#39;&#39;);

  const handleChange = (event) =&gt; {
    setInputValue(event.target.value);
  };

  return (
    &lt;input type=&quot;text&quot; value={inputValue} onChange={handleChange} /&gt;
  );
}
</code></pre>
<ul>
  <li>입력 요소의 값(value)이 컴포넌트의 state에 의해 제어된다.</li>
  <li>위의 예시에서 input 요소의 값은 React state에 의해 설정되고, 변경될 때마다 state가 업데이트 된다.</li>
  <li>이 방식으로 입력 요소의 상태를 React가 완전히 제어하게 되므로, React 컴포넌트에 의해 해당 값에 접근하거나 수정할 수 있다.</li>
</ul>



<h3>비제어 컴포넌트 (Uncontrolled Components)</h3>

<pre><code class="language-jsx">import React, { useRef } from &#39;react&#39;;

function UncontrolledInput() {
  const inputRef = useRef();

  const handleButtonClick = () =&gt; {
    // input 요소에 직접 접근하여 값을 읽거나 수정
    console.log(&#39;Input value:&#39;, inputRef.current.value);
  };

  return (
    &lt;&gt;
      &lt;input type=&quot;text&quot; ref={inputRef} /&gt;
      &lt;button onClick={handleButtonClick}&gt;Get Input Value&lt;/button&gt;
    &lt;/&gt;
  );
}</code></pre>
<ul>
  <li>입력 요소의 값이 React state에의해 직접 제어되지 않는다.</li>
  <li>DOM 요소에 직접 참조를 사용하여 값을 읽거나 수정할 수 있다.</li>
  <ul>
    <li>대신 ref를 사용하여 DOM 요소에 직접 참조를 생성하고, 이를 통해 값을 접근하거나 수정할 수 있다.</li>
  </ul>
  <li>주로 외부 라이브러리와의 통합이나 기존 HTML 양식을 React로 감싸는 경우 사용된다.</li>
</ul>


<h3>요약</h3>
<Strong>제어 컴포넌트</Strong>
<ol>
  <li> 사용자 입력이 있을 때마다 state가 업데이트 되며 이로 인해, 리렌더링이 발생한다.</li>
  <li>React는 항상 현재 값에 접근 할 수 있다.</li>
</ol>

<p><Strong>비제어 컴포넌트</Strong></p>
<ol>
  <li>값이 React 컴포넌트의 state에 의해 직접 제어되지 않고, 값이 변경될 때마다 리렌더링은 발생하지 않는다.</li>
  <li>값의 변경 여부를 알기 위해서는 직접 DOM 요소에 접근하여 값을 읽거나, 사용자 이벤트를 통해 값을 가져와야한다.</li>
</ol>


<p>각각의 컴포넌트 유형을 선택하는 데 있어서는 프로젝트의 요구사항, 상태관리의 편리성, 코드의 가독성, 유지보수성 등 여러 가지 요소를 고려해야한다.</p>
<ul>
  <li>제어 컴포넌트를 사용하는 경우</li>
  <ul>
    <li>React의 상태관리가 필요한 경우 : 입력 값에 따라 동적으로 화면을 업데이트하고 이를 React state로 관리하고자 할 때</li>
    <li>Validation 및 상태 추적이 중요한 경우 : 입력 값의 유효성을 검사하거나, 입력값이 변경될 때 특정 작업을 수행하고자 할 때</li>
  </ul>
  <li>비제어 컴포넌트를 사용하는 경우</li>
  <ul>
    <li>외부 라이브러리와 통합이 필요한 경우 : 이미 외부에서 제어되고 있는 입력 요소를 React로 감싸고자 할 때</li>
    <li>React의 상태를 사용하지 않고 간편한 구현이 필요한 경우</li>
  </ul>
</ul>]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] Deque (덱) (백준 2164)]]></title>
            <link>https://velog.io/@hanl__l/JAVA-Deque-%EB%8D%B1-%EB%B0%B1%EC%A4%80-2164</link>
            <guid>https://velog.io/@hanl__l/JAVA-Deque-%EB%8D%B1-%EB%B0%B1%EC%A4%80-2164</guid>
            <pubDate>Thu, 07 Dec 2023 07:11:51 GMT</pubDate>
            <description><![CDATA[<h3>Deque (덱)</h3>

<p><img src="https://velog.velcdn.com/images/hanl__l/post/1b19cb94-3236-43ad-8eda-1536aafd5c32/image.png" alt=""></p>
<blockquote>
<p>Double-Ended Queue의 약어로, 양쪽 끝에서 삽입과 삭제가 모두 가능한 자료구조이다. 이는 큐(Queue)와 스택(Stack)의 특징을 모두 가지고 있다. 따라서 선입선출(FIFO)과 후입선출(LIFO) 개념이 모두 적용될 수 있다. <br />
Java에서 덱은 java.util 인터페이스를 이용해 구현할 수 있다.</p>
</blockquote>
<p><Strong> 주요 메서드 </Strong></p>
<ol>
  <li>삽입 메서드</li>
  <ul>
    <li>addFirst(element) : 덱의 맨 앞에 요소를 추가</li>
    <li>addLast(element) : 덱의 맨 뒤에 요소를 추가</li>
  </ul>
  <li>삭제 메서드</li>
  <ul>
    <li>removeFirst() : 덱의 맨 앞에 있는 요소를 제거하고 반환</li>
    <li>removeLast() : 덱의 맨 뒤에 있는 요소를 제거하고 반환</li>
  </ul>
  <li>조회 메서드</li>
  <ul>
    <li>getFirst() : 덱의 맨 앞의 요소를 반환하지만 제거하진 않는다.</li>
    <li>getLast() : 덱의 맨 뒤의 요소를 반환하지만 제거하진 않는다.</li>
  </ul>
  <li>기타 메서드</li>
  <ul>
    <li>offerFirst(element) : 덱의 맨 앞에 요소를 추가한다. 큐가 꽉 차있을 경우 예외를 던지지 않고, false를 반환한다.</li>
    <li>offerLast(element) : 덱의 맨 뒤에 요소를 추가한다. 큐가 꽉 차있을 경우 예외를 던지지 않고 false를 반환한다.</li>
    <li>pollFirst() : 덱의 맨 앞의 요소를 제거하고 반환한다. 덱이 비어있으면 null을 반환한다.</li>
    <li>pollLast() : 덱의 맨 뒤에 있는 요소를 제거하고 반환한다. 덱이 비어있으면 null을 반환한다.</li>
  </ul>
</ol>

<br/>

<p><Strong>예시 1. 회문(palindrome) 여부 판별 </Strong>
회문은 앞에서부터 읽으나 뒤에서부터 읽으나 동일한 문자열을 의미한다. Deque를 사용하여 문자열을 앞뒤로 모두 비교하면서 회문 여부를 판별할 수 있다.</p>
<pre><code class="language-JAVA">import java.util.Deque;
import java.util.LinkedList;

public class PalindromeChecker {
    public static boolean isPalindrome(String str) {
        // 덱 생성
        Deque&lt;Character&gt; deque = new LinkedList&lt;&gt;();

        // 문자열을 덱에 추가
        for (char c : str.toCharArray()) {
            deque.addLast(c);
        }

        // 앞뒤로 비교하면서 회문 여부 판별
        while (deque.size() &gt; 1) {
            char first = deque.removeFirst();
            char last = deque.removeLast();

            if (first != last) {
                return false; // 회문이 아님
            }
        }

        return true; // 회문임
    }

    public static void main(String[] args) {
        String palindromeStr = &quot;radar&quot;;
        String nonPalindromeStr = &quot;hello&quot;;

        System.out.println(palindromeStr + &quot; is a palindrome: &quot; + isPalindrome(palindromeStr));
        System.out.println(nonPalindromeStr + &quot; is a palindrome: &quot; + isPalindrome(nonPalindromeStr));
    }
}</code></pre>
<br />

<p><Strong>2. 최대값이나 최솟값 찾기 (슬라이딩 윈도우)</Strong></p>
<pre><code class="language-JAVA">import java.util.Deque;
import java.util.LinkedList;

public class SlidingWindowMaximum {
    public static int[] maxSlidingWindow(int[] nums, int k) {
        if (nums == null || k &lt;= 0) {
            return new int[0];
        }

        int n = nums.length;
        int[] result = new int[n - k + 1];
        int ri = 0;

        // 인덱스를 저장하는 덱
        Deque&lt;Integer&gt; deque = new LinkedList&lt;&gt;();

        for (int i = 0; i &lt; nums.length; i++) {
            // 현재 윈도우에서 벗어난 인덱스 제거
            while (!deque.isEmpty() &amp;&amp; deque.peek() &lt; i - k + 1) {
                deque.poll();
            }

            // 현재 값보다 작은 값들은 제거
            while (!deque.isEmpty() &amp;&amp; nums[deque.peekLast()] &lt; nums[i]) {
                deque.pollLast();
            }

            // 현재 인덱스 추가
            deque.offer(i);

            // 결과 배열에 최대값 추가
            if (i &gt;= k - 1) {
                result[ri++] = nums[deque.peek()];
            }
        }

        return result;
    }

    public static void main(String[] args) {
        int[] nums = {1, 3, -1, -3, 5, 3, 6, 7};
        int k = 3;
        int[] result = maxSlidingWindow(nums, k);

        System.out.print(&quot;Maximum values in sliding windows: &quot;);
        for (int val : result) {
            System.out.print(val + &quot; &quot;);
        }
    }
}
</code></pre>
<p>이를 이용해 백준 알고리즘 중 2164 카드 2를 풀어보았다.</p>
<p><Strong>백준 2164. 카드 2</Strong></p>
<p><a href="https://www.acmicpc.net/problem/2164">백준 2164 카드 2</a></p>
<pre><code class="language-Java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;

public class Main {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        Deque&lt;Integer&gt; dq = new ArrayDeque&lt;&gt;();

        int N = Integer.parseInt(br.readLine());

        for(int i = N; i &gt;= 1; i--){
            dq.offer(i);
        }

        while(dq.size() &gt; 1){
            dq.pollLast();  //가장 위에 있는 카드를 버림
            int last = dq.pollLast();    //버린 카드 중 가장 위에 있는 카드를
            dq.addFirst(last);  //가장 밑으로 내린다
        }

        System.out.print(dq.getFirst());

    }
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 브루트포스 (전체 탐색) (백준 1018)]]></title>
            <link>https://velog.io/@hanl__l/JAVA-%EB%B8%8C%EB%A3%A8%ED%8A%B8%ED%8F%AC%EC%8A%A4-%EC%A0%84%EC%B2%B4-%ED%83%90%EC%83%89-%EB%B0%B1%EC%A4%80-1018</link>
            <guid>https://velog.io/@hanl__l/JAVA-%EB%B8%8C%EB%A3%A8%ED%8A%B8%ED%8F%AC%EC%8A%A4-%EC%A0%84%EC%B2%B4-%ED%83%90%EC%83%89-%EB%B0%B1%EC%A4%80-1018</guid>
            <pubDate>Wed, 06 Dec 2023 04:18:12 GMT</pubDate>
            <description><![CDATA[<h3>브루트포스 (Brute Force)</h3>
브루트 포스를 사전적 의미로 찾아본다면 다음과 같다.
<ul>
  <li>Brute : 무식한</li>
  <li>Force : 힘</li>
</ul>

<p>즉, 발생하는 모든 경우를 무식하게 탐색한다는 뜻이다. 전체를 탐색한다는 의미에서 전체 탐색이라고도 한다.
브루트포스는 가능한 모든 경우의 수를 시도하면서 정확한 해답을 찾는 방식으로 동작한다. 이는 모든 가능성을 다 검사하기 때문에 정확한 답을 찾을 수 있지만, 경우에 따라서는 비효율적일 수도 있다.</p>
<p>브루트포스는 주로 작은 입력 크기에 대한 문제나 문제의 특성상 다른 최적화 기법들이 적용하기 어려운 겨우에 사용된다. 예를 들어, 모든 순열을 생성하거나 부분집합을 생성하면서 특정 조건을 만족하는 것을 찾는 경우에 브루트 포스가 활용될 수 있다.</p>
<p>이를 활용해 백준 1018번 체스판 다시 칠하기를 풀어보았다.</p>
<p><a href="https://www.acmicpc.net/problem/1018">백준 1018 체스판 다시 칠하기</a></p>
<pre><code class="language-JAVA">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    private static boolean[][] board;
    private static int min = 64;    //8 * 8 칸이므로 최대 64 

    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] str = br.readLine().split(&quot; &quot;);
        int N = Integer.parseInt(str[0]);
        int M = Integer.parseInt(str[1]);

        board = new boolean[N][M];

        for(int i = 0; i &lt; N; i++){
            String line = br.readLine();
            for(int j = 0; j &lt; M; j++){
                if(line.charAt(j) == &#39;W&#39;){
                    board[i][j] = true; //W이면 true
                }else{
                    board[i][j] = false;
                }
            }
        }

        for(int i = 0; i &lt; N - 7; i++){
            for(int j = 0; j &lt; M - 7; j++){
                 findBoard(i, j);
            }
        }
        System.out.println(min);
    }

    private static void findBoard(int x, int y){
        int end_x = x + 8;
        int end_y = y + 8;

        //첫번재 칸의 색
        boolean TF = board[x][y];
        int count = 0;
        for(int i = x; i &lt; end_x; i++){
            for(int j = y; j &lt; end_y; j++){
                if(board[i][j] != TF){
                    count++;
                }
                TF = (!TF);
            }
            TF = (!TF); //체스 칸의 열 또한 흰색 검은색 반복임
        }

        count = Math.min(count, 64-count);

        min = Math.min(count, min);
    }

}</code></pre>
<br />

<p><Strong>문제 풀이</Strong></p>
<p>체스판을 만들기 위해서 격자에서 8 * 8 크기의 부분의 체스판을 만들어보면서, 최소한의 색칠을 했어야했다. 주어진 체스판에서 가능한 모든 부분을 체스판으로 만들어보면서, 색칠해야하는 최소 값을 구해야했기에 이를 모든 부분에서 비교하여 최소 값을 찾았다.</p>
<p>한 줄에서 첫번째 칸이 검은색이면, 다음 칸은 하얀색, 그 다음 칸은 검은색이어야하며,
그 다음줄에서 첫번째 칸은 흰색, 그 다음 칸은 검은색, 그 다음칸은 흰색이어야한다.</p>
<p>그러므로 하얀색일 경우 true를 검은색일 경우 false로 이차원 배열을 만들고,
이를 계속 바꿔주며 다를 경우 색을 칠하는 count를 더하였다.
마찬가지로 줄이 바뀔 경우 위의 첫번째와 색이 달라야하므로 이부분도 바꿔주었다.</p>
<p>최솟값을 구해야했기에, 1칸만 바꿔야하는 경우도 생각하여야했다. 예를 들면 보드의 맨 첫번째줄 첫번째 칸만 바꾸면 되는 경우도 있기때문에, count와 64 - count 중에서 최솟값을 비교하였다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 이분탐색 (백준 1920)]]></title>
            <link>https://velog.io/@hanl__l/JAVA-%EC%9D%B4%EB%B6%84%ED%83%90%EC%83%89-%EB%B0%B1%EC%A4%80-1920</link>
            <guid>https://velog.io/@hanl__l/JAVA-%EC%9D%B4%EB%B6%84%ED%83%90%EC%83%89-%EB%B0%B1%EC%A4%80-1920</guid>
            <pubDate>Tue, 05 Dec 2023 05:59:15 GMT</pubDate>
            <description><![CDATA[<h3>이분 탐색 (Binary Search)</h3>

<blockquote>
<p>정렬된 배열 또는 리스트에서 원하는 값을 찾는데 사용되는 알고리즘 중 하나로, 배열이나 리스트가 정렬되어있다는 조건이 필요하다. 알고리즘의 핵심은 중간 값을 선택하고, 찾고자 하는 값과 중간값을 비교하여 탐색 범위를 반으로 줄여가는 것이다.</p>
</blockquote>
<p>기본적인 동작은 다음과 같다.</p>
<ol>
  <li>시작점과 끝점을 설정 : 정렬된 배열이나 리스트에서 탐색 범위의 시작점과 끝점을 설정한다.</li>
  <li>중간 값 찾기 : 시작점과 끝점의 중간에 해당하는 인덱스를 찾는다.</li>
  <li>중간 값 비교 : 중간값과 찾고자 하는 값을 비교한다</li>
  <ul>
    <li>중간 값이 찾고자하는 값과 같았다면, 찾은 것이다.</li>
    <li>중간 값이 찾고자 하는 값보다 크다면, 큰 점을 주간 값의 이전 인텍스로 설정하여 범위를 반으로 줄인다.</li>
    <li>중간 값이 찾고자 하는 값보다 작다면, 시작점을 중간 값의 다음 인덱스로 설정하여 범위를 반으로 줄인다.</li>
  </ul>
  <li>반복 : 원하는 값이 나올 때까지 위의 과정을 반복한다.</li>
</ol>

<img src = "https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FG7wHv%2FbtqV0D9Zn52%2FIrArSq3Au3Qlkd2ja1166k%2Fimg.png" />

<p><Strong>예시</Strong></p>
<pre><code class="language-JAVA">public class BinarySearch {
    public static int binarySearch(int[] array, int target) {
        int left = 0;
        int right = array.length - 1;

        while (left &lt;= right) {
            int mid = left + (right - left) / 2;

            if (array[mid] == target) {
                return mid; // 원하는 값 발견
            } else if (array[mid] &lt; target) {
                left = mid + 1; // 중간값보다 큰 부분 탐색
            } else {
                right = mid - 1; // 중간값보다 작은 부분 탐색
            }
        }

        return -1; // 원하는 값이 없음
    }

    public static void main(String[] args) {
        int[] sortedArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int targetValue = 7;

        int result = binarySearch(sortedArray, targetValue);

        if (result != -1) {
            System.out.println(&quot;원하는 값 &quot; + targetValue + &quot;의 인덱스: &quot; + result);
        } else {
            System.out.println(&quot;원하는 값 &quot; + targetValue + &quot;을 찾을 수 없습니다.&quot;);
        }
    }
}</code></pre>
<br />
<br />
<h3>수 찾기 (백준 1920)</h3>
위의 이분탐색 알고리즘을 바탕으로 풀이해본다.

<p>-&gt; <a href="https://www.acmicpc.net/problem/1920">백준 1920 수 찾기</a></p>
<pre><code class="language-JAVA">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine());
        int[] base = new int[N];
        String[] str = br.readLine().split(&quot; &quot;);
        for(int i = 0; i &lt; N; i++){
            base[i] = Integer.parseInt(str[i]);
        }

        Arrays.sort(base);

        int M = Integer.parseInt(br.readLine());
        String[] str1 = br.readLine().split(&quot; &quot;);

        StringBuilder sb = new StringBuilder();

        for(int i = 0; i &lt; M; i++){
            int target = Integer.parseInt(str1[i]);
            int result = isTrue(base, target);
            sb.append(result).append(&quot;\n&quot;);
        }

        System.out.print(sb.toString());
    }

    private static int isTrue(int[] base, int target){
        int start = 0; int end = base.length -1;

        while(start &lt;= end){
            int mid = (start + end ) / 2;   //중앙 값
            if(base[mid] == target){
                return 1;
            }else if(base[mid] &gt; target){
                end = mid -1;
            }else{
                start = mid + 1;
            }
        }

        return 0;
    }
}
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 객체 (+ 백준 10814)]]></title>
            <link>https://velog.io/@hanl__l/JAVA-%EA%B0%9D%EC%B2%B4-%EB%B0%B1%EC%A4%80-10814</link>
            <guid>https://velog.io/@hanl__l/JAVA-%EA%B0%9D%EC%B2%B4-%EB%B0%B1%EC%A4%80-10814</guid>
            <pubDate>Wed, 29 Nov 2023 07:12:49 GMT</pubDate>
            <description><![CDATA[<h3>객체</h3>
자바는 객체 지향 프로그래밍 언어로,자바에서 객체는 Class의 Instance를 의미한다. 자바에서는 클래스의 인스턴스(객체)를 생성하여 이를 활용하는 것이 중요한 개념 중 하나이며, 이로써 객체 지향 프로그래밍의 특성을 구현하게 된다.

<blockquote>
<p>클래스 (Class)</p>
</blockquote>
<ul>
  <li>클래스는 객체를 생성하기 위한 툴이나 설계도</li>
  <li>데이터 (속성, 필드)와 메서드 (동작, 함수)를 포함한다.</li>
  <li>예시</li>
</ul>

<pre><code class="language-JAVA">public class Person {
    // 속성
    String name;
    int age;

    // 메서드
    void eat() {
        System.out.println(name + &quot; is eating.&quot;);
    }

    void walk() {
        System.out.println(name + &quot; is walking.&quot;);
    }
}</code></pre>
<blockquote>
<p>객체 (Object)</p>
</blockquote>
<ul>
  <li>클래스를 기반으로 실제 메모리에 할당된 인스턴스</li>
  <li>객체는 클래스의 인스턴스화 과정을 통해 생성된다.</li>
  <li>예시</li>
</ul>

<pre><code class="language-JAVA">// Person 클래스를 기반으로 객체 생성
Person person1 = new Person();
Person person2 = new Person();</code></pre>
<p><Strong>객체의 특징</Strong></p>
<ol>
  <li>속성 (Attributes)</li>
  <ul>
    <li>객체는 데이터를 가지고 있다. 이 데이터는 객체의 속성이라고도 한다.</li>
  </ul>
  <li>메서드</li>
  <ul>
    <li>객체는 특정한 동작을 수행할 수 있는 메서드를 가지고 있다.</li>
  </ul>
  <li>캡슐화</li>
  <ul>
    <li>관련된 데이터와 기능을 하나로 묶고 외부에서 접근을 제어하는 개념</li>
    <li>클래스는 캡슐화의 대표적인 예시이며 데이터를 private로 선언하고 메서드를 통해 접근하는 것이 캡슐화를 구현하는 한 방법이다.</li>
  </ul>
</ol>
<br />
<hr />
<br />
<h3>문제</h3>
회원들의 목록이 주어졌을 때
<ol>
  <li>나이 순 (나이의 오름차순) 으로 정렬 후</li>
  <li>나이가 같을 경우 먼저 가입한 사람이 앞에 오는 순서로 정렬</li>
</ol>

<p><a href="https://www.acmicpc.net/problem/10814">백준 10814. 나이순 정렬</a></p>
<h3>풀이</h3>
<ul>
  <li>테스트 수를 입력 받는다.</li>
  <li>Member 라는 객체를 새로 생성하고, 해당 객체를 받는 리스트를 선언한다.</li>
  <li>입력 받은 테스트 수만큼 반복하면서 각각의 반복에서 나이와 이름을 입력받아 Member 객체를 생성하고 이를 리스트에 추가한다.</li>
  <li>리스트에 담긴 Member 객체들을 나이 기준으로 오름차순 정렬한다.</li>
  <li>정렬된 리스트를 순회하면서 나이와 이름을 출력한다.</li>
</ul>


<h3>코드</h3>

<pre><code class="language-JAVA">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Main {
    static class Member {
        int age;
        String name;

        public Member(int age, String name) {
            this.age = age;
            this.name = name;
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int N = Integer.parseInt(br.readLine()); // 테스트 수

        List&lt;Member&gt; list = new ArrayList&lt;&gt;();

        for (int i = 0; i &lt; N; i++) {
            String[] str = br.readLine().split(&quot; &quot;);
            int age = Integer.parseInt(str[0]);
            String name = str[1];

            list.add(new Member(age, name));
        }

        Collections.sort(list, (m1, m2) -&gt; Integer.compare(m1.age, m2.age));

        StringBuilder sb = new StringBuilder();
        for (Member mem : list) {
            sb.append(mem.age).append(&quot; &quot;).append(mem.name).append(&quot;\n&quot;);
        }

        System.out.print(sb.toString());
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React] Hook]]></title>
            <link>https://velog.io/@hanl__l/React-Hook</link>
            <guid>https://velog.io/@hanl__l/React-Hook</guid>
            <pubDate>Tue, 28 Nov 2023 04:46:18 GMT</pubDate>
            <description><![CDATA[<h2>React Hook</h2>

<blockquote>
<p>훅(Hook)은 리액트 v16.8에서부터 도입된 기능으로, 함수혀여 컴포넌트에서 상태 및 다른 리액트 기능을 사용할 수 있게 해준다.</p>
</blockquote>
<h3>훅(Hook) 사용 규칙</h3>
<ol>
  <li>최상위에서만 Hook을 호출해야한다.</li>
      <ul>
      <li>반복문이나 조건문 혹은 중첩된 함수 내에서 Hook을 호출하면 안 된다.</li>
    </ul>
  <li>컴포넌트 내에서만 Hook을 호출해야한다.</li>
      <ul>
      <li>Hook은 리액트 함수 컴포넌트 내에서만 호출되어야한다. 일반 JavaScript 함수나 비동기 함수 내에서는 호출하지 않아야한다.</li>
    </ul>
  <li>Hook 호출 순서를 유지해야한다.</li>
      <ul>
      <li>Hook은 동일한 순서로 호출되어야한다. 이는 컴포넌트 렌더링과 관련이 있다.<li>
    </ul>
</ol>

<h3>자주 사용하는 React Hook</h3>
<h3>1. useState</h3>
함수형 컴포넌트에서 상태를 추가하고 관리하기 위해서 사용한다. useState를 사용하면, 컴포넌트가 렌더링될 때 상태를 초기화하고, 이 상태를 갱신하여 컴포넌트를 업데이트할 수 있다.

<pre><code class="language-JSX">const [state, setState] = useState(initialState);</code></pre>
<ul>
  <li>state : 상태값 자체를 나타내는 변수</li>
  <li>setState : 상태를 갱신할 때 사용되는 함수로, 새로운 상태 값을 받아와서 업데이트</li>
  <li>initialState : 컴포넌트가 처음 렌더링될 때의 초기상태를 나타낸다.</li>
</ul>

<p><Strong>useState의 특징 </Strong></p>
<ol>
<li>컴포넌트 상태관리
: useState를 사용하여 컴포넌트 내에서 동적인 상태를 추가하고 관리할 수 있다. 상태가 변경되면 리액트는 해당 컴포넌트를 리렌더링한다.</li>
</ol>
<pre><code class="language-JSX">import React, { useState } from &#39;react&#39;;

function ExampleComponent() {
  const [count, setCount] = useState(0);

  return (
    &lt;div&gt;
      &lt;p&gt;You clicked {count} times&lt;/p&gt;
      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
        Click me
      &lt;/button&gt;
    &lt;/div&gt;
  );
}</code></pre>
<ol start="2">
<li>비동기적 업데이트
: setState 함수를 사용하여, 상태를 갱신할 때, 리액트는 비동기적으로 업데이트를 수행하며, 연속적으로 호출되는 경우, 최적화를 위하여 여러 업데이트를 일괄적으로 처리한다.</li>
</ol>
<pre><code class="language-JSX">function ExampleComponent() {
  const [count, setCount] = useState(0);

  const handleClick = () =&gt; {
    // 비동기적으로 업데이트
    setCount(count + 1);
    setCount(count + 1);
  };

  return (
    &lt;div&gt;
      &lt;p&gt;You clicked {count} times&lt;/p&gt;
      &lt;button onClick={handleClick}&gt;
        Click me
      &lt;/button&gt;
    &lt;/div&gt;
  );
}</code></pre>
<p>이 예제에서 count는 2가 아닌 1이 된다.</p>
<ol start="3">
<li>이전 상태 활용
: setState 함수는 이전 상태를 활용하여 업데이트할 수 있는 함수를 전달할 수 있다.</li>
</ol>
<pre><code class="language-JSX">function ExampleComponent() {
  const [count, setCount] = useState(0);

  const handleIncrement = () =&gt; {
    // 이전 상태를 활용하여 업데이트
    setCount(prevCount =&gt; prevCount + 1);
  };

  return (
    &lt;div&gt;
      &lt;p&gt;You clicked {count} times&lt;/p&gt;
      &lt;button onClick={handleIncrement}&gt;
        Increment
      &lt;/button&gt;
    &lt;/div&gt;
  );
}</code></pre>
<ol start="4">
<li><p>여러 상태 사용
: 컴포넌트에서 여러 개의 useState를 사용하여 여러 상태를 각각 독립적으로 관리할 수 있다.</p>
<pre><code class="language-JSX">function MultiStateComponent() {
const [count, setCount] = useState(0);
const [text, setText] = useState(&#39;&#39;);

return (
 &lt;div&gt;
   &lt;p&gt;Count: {count}&lt;/p&gt;
   &lt;p&gt;Text: {text}&lt;/p&gt;
   &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
     Increment
   &lt;/button&gt;
   &lt;input
     type=&quot;text&quot;
     value={text}
     onChange={(e) =&gt; setText(e.target.value)}
   /&gt;
 &lt;/div&gt;
);
}</code></pre>
</li>
</ol>
<h3>2. useEffect</h3>
 리액트 함수형 컴포넌트에서 부수 효과를 수행하고, 컴포넌트 생명주기에 특정 작업을 처리하기 위해서 사용된다. useEffect는 컴포넌트의 렌더링 결과가 화면에 반영된 후에 비동기적으로 작업을 수행하거나, 컴포넌트가 마운트(mount)되었을 때, 언마운트(unmount)되었을 때 또는 특정 상태나 props가 변경되었을 때 실행하는 함수를 정의할 수 있다.

<pre><code class="language-JSX">useEffect(() =&gt; {
  // 부수 효과 수행 또는 특정 상태/프롭스에 따라 실행될 코드
}, [/* 의존성 배열 */]);</code></pre>
<ul>
  <li>첫 번째 매개변수 : 부수 효과를 수행하는 함수를 정의</li>
  <li>두 번재 매개변수 (의존성 배열) : 언제 useEffect를 실행할지 결정한다. 배열에 포함된 값이 변경될 때만 useEffect가 실행된다. 만약 빈배열을 전달하면 컴포넌트가 마운트된 후 한 번만 실행된다.</li>
</ul>

<p><Strong>useEffect의 특징 </Strong></p>
<ol>
<li>비동기 작업 수행
: useEffect 안에서 비동기 작업을 수행할 수 있다. API 호출, 데이터 가져오기, 타이머 설정 등의 작업을 처리할 수 있다.</li>
</ol>
<pre><code class="language-JSX">useEffect(() =&gt; {
  // 비동기 작업 수행
  const fetchData = async () =&gt; {
    const result = await fetchDataFromAPI();
    // 처리된 데이터를 사용하여 상태 갱신 등의 작업 수행
  };

  fetchData();
}, [/* 의존성 배열 */]);</code></pre>
<ol start="2">
<li>클린업(clean-up) 함수 사용
: useEffect는 부수 효과가 필요없을 때, 즉 언마운트(unmount)될 때 혹은 다음 useEffect 실행 전에 정리 작업을 수행할 수 있도록 반환된 함수를 활용할 수 있다.</li>
</ol>
<pre><code class="language-JSX">useEffect(() =&gt; {
  // 컴포넌트가 마운트된 후 실행되는 코드

  return () =&gt; {
    // 언마운트 또는 다음 useEffect 실행 전에 실행되는 정리 함수
  };
}, [/* 의존성 배열 */]);</code></pre>
<ol start="3">
<li><p>의존성 배열 활용
: useEffect의 두번째 매개변수인 의존성 배열을 사용하여, 특정상태가 props가 변경될때만 useEffect가 실행되도록 설정할 수 있다.</p>
<pre><code class="language-JSX">useEffect(() =&gt; {
// 특정 상태가 변경될 때만 실행되는 코드
}, [specificState]);</code></pre>
</li>
</ol>
<p><Strong>useEffect 사용 예시</Strong></p>
<ol>
<li>컴포넌트가 마운트 되었을 때 및 언마운트 되었을 때</li>
</ol>
<pre><code class="language-JSX">import React, { useEffect } from &#39;react&#39;;

function MountedComponent() {
  useEffect(() =&gt; {
    // 컴포넌트가 마운트된 후 실행되는 코드
    console.log(&#39;Component is mounted&#39;);

    // 정리 함수 (언마운트 또는 다음 useEffect 실행 전에 실행됨)
    return () =&gt; {
      console.log(&#39;Component will unmount or next useEffect will run&#39;);
    };
  }, []); // 빈 배열은 컴포넌트가 마운트될 때 한 번만 실행됨

  return &lt;div&gt;Mounted Component&lt;/div&gt;;
}</code></pre>
<ol start="2">
<li>특정 상태가 변경될 때<pre><code class="language-JSX">import React, { useEffect, useState } from &#39;react&#39;;
</code></pre>
</li>
</ol>
<p>function StateChangeEffect() {
  const [count, setCount] = useState(0);</p>
<p>  useEffect(() =&gt; {
    // count 상태가 변경될 때 실행되는 코드
    console.log(&#39;Count is updated:&#39;, count);
  }, [count]); // count가 변경될 때마다 실행됨</p>
<p>  return (
    <div>
      <p>Count: {count}</p>
      &lt;button onClick={() =&gt; setCount(count + 1)}&gt;
        Increment Count
      </button>
    </div>
  );
}</p>
<pre><code>
 &lt;h3&gt;3. useContext&lt;/h3&gt;
 컨텍스트(Context)를 활용하여 전역 상태를 공유하고자 할 때 사용한다. 컨텍스트는 컴포넌트 트리를 횡단하는 데이터를 전달할 수 있는 메커니즘을 제공하며, useContext는 이 컨텍스트에 접근하여 값을 가져오는데 사용된다.

&lt;br /&gt;

&lt;Strong&gt;Context 란?&lt;/Strong&gt;

&gt; 일반적인 React 어플리케이션데서 데이터는 props를 통해서 부모 컴포넌트에서 자식 컴포넌트로 전달된다. 어플리케이션 안의 여러 컴포넌트들에게 props로 전달해줘야하는 경우, context를 이용하면 명시적으로 props를 넘겨주지 않아도 값을 공유할 수 있게 해준다. 즉, 데이터가 필요할 때마다 props를 통해 전달할 필요 없이 context를 이용해 공유한다. 

  &lt;ul&gt;
    &lt;li&gt;createContext : 컨텍스트를 생성한다. 이 함수는 Provider와 Consumer를 생성하는데 사용된다.&lt;/li&gt;

```JSX
const MyContext = createContext();</code></pre>  <li>Provider : 컨텍스트 값을 제공하는 역할을 한다. Provicder로 감싼 컴포넌트 내에서 하위 컴포넌트들은 해당 컨텍스트 값을 사용할 수 있다.</li>

<pre><code class="language-JSX">  &lt;MyContext.Provider value={/* 어떤 값 */}&gt;
  {/* 여기에 있는 컴포넌트들은 MyContext의 값을 사용할 수 있음 */}
&lt;/MyContext.Provider&gt;</code></pre>
  <li>Consumer : Provider로 감싼 컴포넌트 내에서 해당 컨텍스트 값을 소비하고자 할 때 사용된다. 최근 버전의 리액트에서는 useContext Hook을 사용하는 것이 일반적이다.</li>
  </ul>

<p>컨텍스트를 사용하면, 중첩된 컴포넌트 간에 데이터를 전달하는데에 용이하며, 특히 전역적인 상태나 테마, 사용자 인증 정보같은 데이터를 효율적으로 관리할 수 있다.</p>
<p><Strong>useContext 의 사용법</Strong></p>
<h5>1. 컨텍스트 생성</h5>
먼저 'React.createContext'를 사용하여 컨텍스트를 생성한다.

<pre><code class="language-JSX">// MyContext.js
import { createContext } from &#39;react&#39;;

const MyContext = createContext();

export default MyContext;</code></pre>
<h5>2. 컨텍스트 제공</h5>
컨텍스트의 값을 제공하려는 부모 컴포넌트에서 'Context.Provider'를 사용하여 값을 전달한다.

<pre><code class="language-JSX">// ParentComponent.js
import React from &#39;react&#39;;
import MyContext from &#39;./MyContext&#39;;

function ParentComponent() {
  const contextValue = &#39;Hello from Context!&#39;;

  return (
    &lt;MyContext.Provider value={contextValue}&gt;
      {/* 자식 컴포넌트들 */}
    &lt;/MyContext.Provider&gt;
  );
}

export default ParentComponent;</code></pre>
<h5>3. 컨텍스트 사용</h5>
자식 컴포넌트에서 useContext를 사용하여 컨텍스트 값을 가져온다.

<pre><code class="language-JSX">// ChildComponent.js
import React, { useContext } from &#39;react&#39;;
import MyContext from &#39;./MyContext&#39;;

function ChildComponent() {
  const contextValue = useContext(MyContext);

  return (
    &lt;div&gt;
      &lt;p&gt;{contextValue}&lt;/p&gt;
    &lt;/div&gt;
  );
}

export default ChildComponent;</code></pre>
<p><Strong>useContext 사용 시 주의 사항</Strong></p>
<ul>
  <li>useContext는 컨텍스트의 현재 값을 반환하며, 컨텍스트의 값이 변경될 때 컴포넌트를 리렌더링한다.</li>
  <li>useContext를 사용하기 위해서는 해당 컨텍스트 Provider가 상위 계층에서 제공되어야한다.</li>
  <li>여러 개의 컨텍스트를 사용해야할 경우, 각각의 useContext를 사용하여 해당 컨텍스트의 값을 가져올 수 있다.</li>
</ul>

<h3>4. useRef</h3>
함수형 컴포넌트 내에서 참조(reference)를 관리하기 위해서 사용된다. useRef를 사용하면 DOM요소에 직접 접근하거나 컴포넌트 생명주기와 관련 없는 값을 유지할 수 있다.

<p><Strong>useRef의 주요 특징</Strong></p>
<ul>
  <li>useRef로 생성한 객체는 current 속성을 통해 실제 값에 접근한다.</li>
  <li>useRef로 생성한 참조는 컴포넌트가 리렌더링되어도 이전 값이 유지된다.</li>
  <li>useRef로 생성한 참조는 변경되어도 컴포넌트가 리렌더링 되지 않는다. 따라서 값이 변경되어도 렌더링이 발생하지 않는다.</li>
</ul>

<p>useRef는 주로 DOM조작, 애니메이션 및 다른 Hook들과의 조합 등에서 사용된다.</p>
<p><Strong>useRef의 사용법</Strong></p>
<ol>
<li>DOM 요소에 접근</li>
</ol>
<pre><code class="language-JSX">import React, { useRef, useEffect } from &#39;react&#39;;

function MyComponent() {
  // useRef를 사용하여 참조 생성
  const myInputRef = useRef(null);

  useEffect(() =&gt; {
    // 컴포넌트가 마운트되면 myInputRef.current가 해당 input 요소를 참조합니다.
    myInputRef.current.focus();
  }, []);

  return &lt;input ref={myInputRef} /&gt;;
}</code></pre>
<ol start="2">
<li>컴포넌트의 생명주기과 관련없는 값 관리
렌더링 간에 값을 계속 유지하고 싶은 경우에 사용할 수 있다.</li>
</ol>
<pre><code class="language-JSX">import React, { useRef, useState } from &#39;react&#39;;

function MyComponent() {
  const renderCount = useRef(0); // 렌더링 횟수를 기록하기 위한 useRef

  useEffect(() =&gt; {
    renderCount.current += 1;
    console.log(`Component has rendered ${renderCount.current} times.`);
  });

  return &lt;div&gt;Component content&lt;/div&gt;;
}</code></pre>
<h3>5. useMemo / useCallback </h3>
두 Hook 모두 리액트에서 성능 최적화를 위해 사용되는 Hook이지만, 목적과 방법에서 차이가 있다.

<p><Strong>useMemo</Strong></p>
<ul><li>목적 : 계산 비용이 많이 드는 함수의 결과 값을 캐싱하여 같은 계산이 반복되는 것을 방지하고 성능을 최적화 한다 </li>
  <li>사용 예시 : 계산 비용이 높은 함수의 결과 값, 메모이제이션이 필요한 연산 등을 처리할 때 사용한다.</li>
</ul>

<pre><code class="language-JSX">import React, { useMemo } from &#39;react&#39;;

function ExampleComponent({ list }) {
  const total = useMemo(() =&gt; {
    console.log(&#39;Calculating total...&#39;);
    return list.reduce((acc, item) =&gt; acc + item, 0);
  }, [list]);

  return &lt;div&gt;Total: {total}&lt;/div&gt;;
}</code></pre>
<p><Strong>useCallback</Strong></p>
<ul>
  <li> 목적 : 렌더링 시마다 생성되는 함수를 메모이제이션하여, 자식 컴포넌트에 전달하는 콜백함수들이 렌더링될 때마다 새로 생성되는 것을 방지하고 성능을 최적화한다.</li>
  <li>사용 예시 : 자식 컴포넌트에 전달되는 함수, 이벤트 핸들러 등을 처리할 때 사용</li>
</ul>

<pre><code class="language-JSX">import React, { useCallback } from &#39;react&#39;;

function ChildComponent({ onClick }) {
  // onClick은 렌더링마다 새로운 콜백이 생성되는 것을 방지
  return &lt;button onClick={onClick}&gt;Click me&lt;/button&gt;;
}

function ParentComponent() {
  const handleClick = useCallback(() =&gt; {
    console.log(&#39;Button clicked&#39;);
  }, []); // 의존성 배열이 빈 배열인 경우 항상 동일한 함수를 반환

  return &lt;ChildComponent onClick={handleClick} /&gt;;
}
</code></pre>
<ul>
  <li>공통점</li>
  <ul>
    <li>둘 다 렌더링 성능 최적화를 위해 사용된다.</li>
    <li>의존성 배열을 사용하여 해당 값이 변경될 때만 다시 계산하거나 함수를 새로 생성하도록 설정할 수 있다.</li>
  </ul>
  <li>차이점</li>
  <ul>
    <li>useMemo : 주로 값(계산 결과)을 캐싱하고 반환한다.</li>
    <li>useCallback : 주로 함수를 메모이제이션을 하여 불필요한 함수 생성을 방지한다.</li>
  </ul>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 제너레이터 (Generator)]]></title>
            <link>https://velog.io/@hanl__l/JS-%EC%A0%9C%EB%84%88%EB%A0%88%EC%9D%B4%ED%84%B0-Generator</link>
            <guid>https://velog.io/@hanl__l/JS-%EC%A0%9C%EB%84%88%EB%A0%88%EC%9D%B4%ED%84%B0-Generator</guid>
            <pubDate>Wed, 22 Nov 2023 12:55:27 GMT</pubDate>
            <description><![CDATA[<h3>제너레이터 (Generator)</h3>
 : 자바스크립트의 Generator는 함수의 실행을 일시 중단하고 재개할 수 있는 특수한 종류의 함수다. Generator는 'function*' 문법을 사용하여 정의되며, 함수 내에서 'yield' 키워드를 사용하여 값을 내보내고 함수 실행을 일시 중단할 수 있다.

<p> : 제너레이터 함수는 호출되면 즉시 실행되지 않고, 대신에 이터레이터(Iterator)를 반환한다. 제너레이터는 이터레이터 프로토콜 따르므로, next 메서드를 사용하여 값을 받아올 수 있다. &#39;next&#39; 메서드를 호출할 때마다 제너레이터 함수의 실행은 일시 중단된 상태에서 시작하고, yield 키워드에서 값을 내보내거나 다음 yield까지 실행을 진행한다.</p>
<pre><code class="language-JS">function* myGenerator() {
  yield 1;
  yield 2;
  yield 3;
}

const generator = myGenerator();

console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: false }
console.log(generator.next()); // { value: undefined, done: true }</code></pre>
<p>제너레이터 함수는 순회 가능한 객체를 생성하므로 for...of 루프나 스프레드 연산자를 통해 값을 순회할 수 있다.</p>
<p>제너레이터는 주로 비동기 코드를 작성하거나 무한한 시퀀스를 생성하는데 사용된다. 예로 들어, 비동기적인 코드에서 제너레이터를 사용하면 Promise를 더 직관적으로 작성할 수 있다.</p>
<h4>제너레이터 함수와 일반 함수의 차이점</h4>

<ol>
  <li>함수 실행 방식</li>
  <ul>
    <li>일반 함수 : 일반 함수는 호출되면 함수 블록 내부의 코드를 순차적으로 실행한다. 함수 실행 중에는 다른 코드나 이벤트 처리가 중간에 끼어들지 않고, 함수의 실행이 완료될 때까지 호출자에게 제어권을 넘기지 않는다.</li>
    <li>제너레이터 함수 : 제너레이터 함수는 호출되어도 즉시 실행되지 않고, 대신 이터레이터를 반환하고, 함수의 실행은 중간에 일시 중단되고 재개될 수 있다. yield 키워드를 토해 값을 내보내며, 함수 실행 중에는 외부에서 다시 호출되지 않는다.</li>
  </ul>
  <li>함수의 반환 값</li>
  <ul>
    <li>일반 함수 : 일반 함수는 return 키워드를 사용하여 값을 반환하고, 함수가 실행을 완료하면 반환값이 호출자에게 전달된다.</li>
    <li>제너레이터 함수 : 제너레이터 함수는 yield 키워드를 사용하여 값을 내보내지만, return 키워드도 사용할수 있다. 그러나 return은 제너레이터 함수의 실행을 완전히 종료하며, 이후에 yield로 값을 내보낼 수 없다.</li>
  </ul>
  <li>이터레이터 프로토콜</li>
  <ul>
    <li>일반 함수 : 일반 함수는 이터레이터 프로토콜을 따르지 않습니다. 따라서 for...of 루프나 스프레드 연산자를 통한 순회가 불가능하다.</li>
    <li>제너레이터 함수 : 제너레이터 함수는 이터레이터 프로토콜을 따르므로, for...of 루프나 스프레드 연산자를 사용하여 값을 순회할 수 있다.</li>
  </ul>
  <li>상태 저장</li>
  <ul>
    <li>일반 함수 : 일반함수는 호출이 완료되면 지역 변수 등의 상태는 사라지지만, 클로저를 사용하면 일부 상태를 보존할 수 있다.</li>
    <li>제너레이터 함수 : 제너레이터 함수는 상태를 보존하여 일시 중단된 위치에서 실행을 재개할 수 았다. 따라서 제너레이터 함수는 루프의 상태를 유지하거나 비동기 작업의 중간 상태를 저장하는데 유용하다.</li>
  </ul>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] Promise, async, await]]></title>
            <link>https://velog.io/@hanl__l/JS-Promise-async-await</link>
            <guid>https://velog.io/@hanl__l/JS-Promise-async-await</guid>
            <pubDate>Wed, 22 Nov 2023 12:04:26 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트는 기본적으로 단일 스레드로 동작하는 언어이며, 이는 코드의 실행이 한 번에 하나의 작업만 처리된다는 것을 의미한다. 동기적으로 실행되는 코드는 한 번에 하나의 작업만 처리되며, 코드의 실행이 완료되기 전까지 다음 코드로 진행되지 않는다. 이러한 특성은 코드의 실행 흐름이 예측 가능하고, 간단하게 유지되도록 도와준다.</p>
<p>하지만 자바스크립트에서 모든 동작이 동기적으로 작동하게 되면, 특정 동작이 끝날 때까지 화면에 나타나지 않거나 다음 동작을 수행하는데 지장을 주게 된다. 그러므로 자바스크립트가 웹 사이트에 동작할 때, 비동기적으로 동작할 수 있어야한다.</p>
<h3>비동기 통신 단점</h3>
1. 콜백 지옥 (Callback Hell)
: 비동기 코드에서 연속적으로 여러 비동기 작업을 수행해야할 때, 중첩된 콜백함수들이 쌓이면 가독성이 떨어지고 코드가 복잡해질 수 있다. 이를 콜백 지옥이라고 부르며, 코드를 이해하고 유지 보수하는에 어려움을 초래할 수 있다.

<pre><code class="language-JS">asyncFunc1(function() {
  asyncFunc2(function() {
    asyncFunc3(function() {
      // ...
    });
  });
});</code></pre>
<ol start="2">
<li>에러 처리의 어려움
: 비동기 코드에서 에러처리는 동기 코드가 어려울 수 있다. 콜백 함수 내에서 에러가 발생하면, 해당 콜백 함수 내부에서 처리해야하며 이로 인해 전체 프로세스에 영향을 줄 수 있다.</li>
</ol>
<pre><code class="language-JS">asyncFunc(function(err, result) {
  if (err) {
    console.error(&#39;Error:&#39;, err);
  } else {
    // 결과 처리
  }
});</code></pre>
<ol start="3">
<li>순서 제어의 어려움
: 여러 비동기 작업이 동시에 진행되는 경우, 그들 사이의 상대적인 순서를 제어하기 어려울 수 있다. 이로 인해 예상치 못한 결과가 발생될 수 있다.</li>
</ol>
<pre><code class="language-JS">asyncFunc1(function() {
  // 작업 1 완료 후에 작업 2 시작
});

asyncFunc2(function() {
  // 작업 2 완료 후에 작업 3 시작
});</code></pre>
<h3>Promise</h3>
: 자바스크립트에서 비동기적인 작업을 처리하는 객체로, 비동기 작업이 완료되었을 때 또는 실패했을 때의 결과를 나타냅니다. Promise는 콜백 지옥을 피하고 비동기 코드를 보다 간결하고 가독성 있게 작성할 수 있도록 도와준다.

<p>Promise는 다음의 세 가지 상태를 가지고 있다.</p>
<ul>
  <li>Pending (대기 중) : 초기 상태, 비동기 작업이 완료되지 않은 상태</li>
  <li>Fulfilled (이행 됨) : 비동기 작업이 성공적으로 완료된 상태</li>
  <li>Rejected (거부 됨) : 비동기 작업이 실패한 상태 </li>
</ul>

<p>Promise 주로 new Promise(executor) 형태로 생성되며, excutor 함수는 resolve와 reject 두 개의 콜백 함수를 인자로 받는다. resolve는 작업이 성공적으로 완료되었을 때 호출되며, reject는 작업이 실패했을 때 호출된다.</p>
<pre><code class="language-JS">const myPromise = new Promise((resolve, reject) =&gt; {
  // 비동기 작업 수행
  if (작업성공) {
    resolve(결과);
  } else {
    reject(에러);
  }
});</code></pre>
<p>Promise를 사용할 때 주로 then 및 catch 메서드를 사용하여 처리한다.</p>
<ul><li>then : Promise가 성공적으로 이행되었을 때 실행하는 콜백함수를 등록한다.</li></ul>

<pre><code class="language-JS">myPromise.then(result =&gt; {
  console.log(&#39;성공:&#39;, result);
});</code></pre>
<ul><li>catch : Promise가 거부되었을 때 실행되는 콜백 함수를 등록한다.</li></ul>

<pre><code class="language-JS">myPromise.catch(error =&gt; {
  console.error(&#39;에러:&#39;, error);
});</code></pre>
<p>Promise는 체이닝(Chaining)을 통해 여러 개의 비동기 작업을 순차적으로 처리할 수 있다.</p>
<pre><code class="language-JS">myPromise.catch(error =&gt; {
  console.error(&#39;에러:&#39;, error);
});</code></pre>
<p>async와 await는 자바스크립트에서 비동기 코드를 작성하고 다루기 위한 키워드이다. 이들은 주로 Promise와 함께 사용되어 비동기 작업을 더 간결하고 동기적으로 다룰 수 있게 한다.</p>
<h3>async</h3>
: 함수를 비동기 함수로 만든다. 이 키워드가 앞에 붙으면 함수 내에서 await 키워드를 사용할 수 있게 되며, 함수의 실행이 Promise를 반환하게 된다.

<pre><code class="language-JS">async function myAsyncFunction() {
  // 비동기 작업 수행
  const result = await someAsyncOperation();
  console.log(result);
}</code></pre>
<h3>await</h3>
: await 키워드는 async 함수 내에서만 사용 가능하며, Promise가 완료될 때까지 함수의 실행을 일시 중지하고, 해당 Promise의 결과 값을 반환한다. 이를 통해 비동기적인 코드를 동기적으로 작성할 수 있다.

<pre><code class="language-JS">async function example() {
  const result1 = await someAsyncOperation1();
  const result2 = await someAsyncOperation2();
  console.log(result1, result2);</code></pre>
<p>await를 사용하면 비동기 코드를 연결된 형태로 작성할 수 있어 가독성이 향상되고, 에러 핸들링이 간편해진다.</p>
<h4>에러 핸들링 (Error Handling)</h4>
: async / await을 사용할 때 에러 핸들링은 try/catch 문으로 수행된다.

<pre><code class="language-JS">async function example() {
  try {
    const result = await someAsyncOperation();
    console.log(result);
  } catch (error) {
    console.error(&#39;에러 발생:&#39;, error);
  }
}</code></pre>
<h4>Promise.all</h4>
 : 여러 개의 Promise를 병렬로 처리할 수 있다. await와 함께 사용하면, 여러 비동기 작업을 병렬로 처리하고 모든 작업이 완료될 때까지 기다릴 수 있다.

<pre><code class="language-JS">async function example() {
  try {
    const result = await someAsyncOperation();
    console.log(result);
  } catch (error) {
    console.error(&#39;에러 발생:&#39;, error);
  }
}</code></pre>
<p>async / await 는 코드를 더 간결하게 만들어주며, 비동기 코드를 동기적으로 작성하는데 도움을 준다. 주의할 점은 await는 반드시 async 함수 내에서 사용되어야한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 상속 / prototype]]></title>
            <link>https://velog.io/@hanl__l/JS-%EC%83%81%EC%86%8D-prototype</link>
            <guid>https://velog.io/@hanl__l/JS-%EC%83%81%EC%86%8D-prototype</guid>
            <pubDate>Tue, 21 Nov 2023 13:49:01 GMT</pubDate>
            <description><![CDATA[<p>상속(Inheritance)는 객체 지향 프로그래밍에서 중요한 개념 중 하나로, 코드의 재사용성을 높이고 객체간의 계층 구조를 만들어내는 매커니즘이다. </p>
<p>즉, 상속은 기존 클래스 또는 객체(부모 또는 상위 클래스 / 객체)에서 속성과 메서드를 파생된 새로운 클래스 또는 객체 (자식 또는 하위 클래스 / 객체)에게 공유하거나 전달하는 과정을 의미한다. 이로써 코드의 중복을 최소화하고, 유지보수성을 향상 시킬 수 있다.</p>
<p>자바스크립트에서는 프로토타입을 이용하여 상속을 구현한다. 객체는 생성될 때 &#39;프로토타입 (prototype)&#39;이라는 특수한 속성을 지니게 되는데, 이 프로토타입에는 해당 객체를 생성하는데 사용된 생성자 함수의 프로토타입 객체가 할당된다. 이로 인해 객체는 해당 프로토타입 객체의 속성과 메서드를 상속받는다.</p>
<pre><code class="language-JS">// 부모 클래스
function Animal(name) {
  this.name = name;
}

// 부모 클래스의 메서드
Animal.prototype.sayHello = function() {
  console.log(`안녕하세요, 저는 ${this.name}입니다.`);
};

// 자식 클래스
function Dog(name, breed) {
  // 부모 클래스 생성자 호출
  Animal.call(this, name);

  this.breed = breed;
}

// 자식 클래스의 인스턴스 생성
var myDog = new Dog(&#39;멍멍이&#39;, &#39;진돗개&#39;);

// 자식 클래스는 부모 클래스의 메서드를 상속받음
myDog.sayHello(); // 출력: 안녕하세요, 저는 멍멍이입니다.</code></pre>
<p>Dog 클래스는 Animal 클래스를 상속받는다. Dog 클래스의 인스턴스 myDog은 Animal 클래스의 sayHello 메서드를 호출 할 수 있다.</p>
<p>이러한 상속 메커니즘을 통해 코드의 재사용성이 높아지며, 관련된 객체간의 계층 구조를 형성할 수 있다.</p>
<h3>프로토타입</h3>
<h4>프로토타입 객체 (Object.prototype)</h4>
모든 객체는 Object를 상속한다. Object는 모든 객체가 기본으로 가져야하는 속성과 매서드를 정의하는 객체이다.

<h4>프로토타입 체인</h4>
객체의 프로토타입은 체인 형태로 연결된다. 객체가 특정 속성 또는 메서드를 찾을 때, 자바스크립트는 해당 객체의 프로토타입 체인을 따라 올라가며 찾는다.

<h4>프로토타입을 이용한 상속 매커니즘</h4>

<pre><code class="language-JS">// 부모 클래스
function Animal(name) {
  this.name = name;
}

// 부모 클래스의 메서드
Animal.prototype.sayHello = function() {
  console.log(`안녕하세요, 저는 ${this.name}입니다.`);
};

// 자식 클래스
function Dog(name, breed) {
  // 부모 클래스 생성자 호출
  Animal.call(this, name);

  this.breed = breed;
}

// 자식 클래스의 프로토타입을 부모 클래스의 인스턴스로 설정
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// 자식 클래스의 메서드
Dog.prototype.bark = function() {
  console.log(&#39;멍멍!&#39;);
};

// 자식 클래스의 인스턴스 생성
var myDog = new Dog(&#39;멍멍이&#39;, &#39;진돗개&#39;);

// 자식 클래스는 부모 클래스의 메서드를 상속받음
myDog.sayHello(); // 출력: 안녕하세요, 저는 멍멍이입니다.
myDog.bark();     // 출력: 멍멍!</code></pre>
<h4>ES6에서의 클래스 문법</h4>
ES6에서는 클래스 문법이 도입되어 좀더 쉽게 객체지향 프로그래밍을 할 수 있게 되었다. 클래스를 통한 상속은 내부적으로 프로토타입을 이용하여 구현된다.

<pre><code class="language-JS">// ES6 클래스 문법
class Animal {
  constructor(name) {
    this.name = name;
  }

  sayHello() {
    console.log(`안녕하세요, 저는 ${this.name}입니다.`);
  }
}

// 상속
class Dog extends Animal {
  constructor(name, breed) {
    // 부모 클래스 생성자 호출
    super(name);

    this.breed = breed;
  }

  bark() {
    console.log(&#39;멍멍!&#39;);
  }
}

// 인스턴스 생성
var myDog = new Dog(&#39;멍멍이&#39;, &#39;진돗개&#39;);

myDog.sayHello(); // 출력: 안녕하세요, 저는 멍멍이입니다.
myDog.bark();     // 출력: 멍멍!</code></pre>
<p>extends 키워드를 사용하여 상속을 선언하고, super 키워드를 통해 부모 클래스의 생성자를 호출할 수 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 함수 호출 call, apply, bind]]></title>
            <link>https://velog.io/@hanl__l/JS-%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C-call-apply-bind</link>
            <guid>https://velog.io/@hanl__l/JS-%ED%95%A8%EC%88%98-%ED%98%B8%EC%B6%9C-call-apply-bind</guid>
            <pubDate>Mon, 20 Nov 2023 10:59:38 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트에서 this는 함수가 호출될 때 결정되며, 호출 문맥에 다라 다르게 바인딩이 된다. 일반적으로 this 바인딩 규칙은 다음과 같다.</p>
<ol>
<li>전역 객체 바인딩
: 함수가 일반적인 함수 호출로 실행되면, this는 전역 객체에 바인딩이 된다. 브라우저 환경에서 전역 객체는 window 이다.</li>
</ol>
<pre><code class="language-JS">function globalFunction() {
  console.log(this); // 전역 객체 (브라우저에서는 window)
}

globalFunction();</code></pre>
<ol start="2">
<li>매소드 호출 시 바인딩
: 객체의 메소드로 함수가 호출되면, this는 해당 객체에 바인딩 된다.</li>
</ol>
<pre><code class="language-JS">const myObject = {
  myMethod: function() {
    console.log(this); // myObject
  }
};

myObject.myMethod();</code></pre>
<ol start="3">
<li>생성자 함수에서의 바인딩
: 생성자 함수로 객체 인스턴스를 생성할 때 this는 생성된 인스턴스에 바인딩 된다.</li>
</ol>
<pre><code class="language-JS">function MyClass() {
  this.property = &quot;Hello, this is a property.&quot;;
}

const myInstance = new MyClass();
console.log(myInstance.property); // Hello, this is a property.</code></pre>
<ol start="4">
<li>화살표 함수에서의 바인딩
: 화살표 함수는 자체적인 this를 가지지 않고 외부 스코프의 this 를 그대로 사용한다.</li>
</ol>
<pre><code class="language-JS">const arrowFunction = () =&gt; {
  console.log(this); // 외부 스코프의 this를 사용
};

arrowFunction.call({}); // 외부 스코프의 this를 사용</code></pre>
<ol start="5">
<li>함수 내부에서의 call, apply 등의 메소드를 사용한 바인딩
: call 또는 apply 등의 메소드를 사용하여 명시적으로 this를 특정 값으로 설정할 수 있다.</li>
</ol>
<pre><code class="language-JS">function explicitFunction() {
  console.log(this);
}

const explicitObject = { name: &quot;Explicit Object&quot; };

explicitFunction.call(explicitObject); // explicitObject</code></pre>
<p>여기서 함수 내부에서 call, apply, bind 메소드를 사용한 바인딩에 대해서 좀더 알아보고자 한다.</p>
<h3>Function.prototype.call()</h3>

<blockquote>
<p>fun.call(thisArg, arg1, arg2, ...)</p>
</blockquote>
<p>함수를 호출하면서 특정 객체를 thisArg로 설정하고 필요한 매개 변수를 전달한다.</p>
<h3>Function.prototype.apply()</h3>

<blockquote>
<p>fun.apply(thisArg, [argsArray])</p>
</blockquote>
<p>함수를 호출하면서 특정 객체는 thisArg로 설정하고, 매개변수를 배열로 전달한다.</p>
<h3>bind</h3>

<blockquote>
<p>const newFunc = func.bind(thisArg, arg1, arg2, ...)</p>
</blockquote>
<p>특정 객체를 thisArg로 설정하고, 필요한 매개 변수를 미치 바인딩한 새로운 함수를 생성한다.</p>
<pre><code class="language-JS">function greet(name) {
  console.log(`Hello, ${name}!`);
}

greet.call(null, &#39;John&#39;);  // Hello, John!
greet.apply(null, [&#39;Jane&#39;]);  // Hello, Jane!

const greetJohn = greet.bind(null, &#39;John&#39;);
greetJohn();  // Hello, John!</code></pre>
<h3>요약</h3>
1. call, apply, bind는 함수의 this를 사용자가 원하는 대로 바인딩 할 수 있게 한다.
2. call, apply는 함수를 호출 및 적용되고, bind()는 함수를 호출하지 않고 새로운 함수를 반환한다.
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 타이머 함수]]></title>
            <link>https://velog.io/@hanl__l/JS-%ED%83%80%EC%9D%B4%EB%A8%B8-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@hanl__l/JS-%ED%83%80%EC%9D%B4%EB%A8%B8-%ED%95%A8%EC%88%98</guid>
            <pubDate>Wed, 15 Nov 2023 14:20:03 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트 내장 함수 중 타이머 함수가 있다. 타이머 함수는 아래와 같은 역할을 한다.</p>
<table style="width : 100%">
  <tr style="border : 1px solid black;">
    <th>함수 이름</th>
    <th>설명</th>
  </tr>
  <tr style="border: 1px solid black;">
    <td>setTimeOut(함수, 시간)</td>
    <td>입력 받은 시간 이후 함수를 1번 실행한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>setInterval(함수, 시간)</td>
    <td>입력 받은 시간을 간격으로 함수를 반복적으로 실행한다.</td>
  </tr>
  <tr style ="border : 1px solid black;">
    <td>clearTimeOut()</td>
    <td>실행되고 있는 setTimeOut 함수를 중단한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>clearInterval()</td>
    <td>실행되고 있는 setInterval 함수를 중단한다.</td>
  </tr>
</table>

<blockquote>
<ol>
<li>setTimeout(callback, delay);</li>
</ol>
</blockquote>
<ul>
  <li>callback : 실행할 함수</li>
  <li>delay : 밀리초 단위의 지연 시간</li>
</ul>

<p>일정 시간이 지난 후에 지정된 callback 함수를 실행한다. 비동기적으로 진행되며 주로 일정 시간 이후 특정 작업을 실행하고자 할 때 사용한다.</p>
<pre><code class="language-JS">console.log(&quot;Start&quot;);

setTimeout(function() {
  console.log(&quot;Timeout completed after 2000 milliseconds&quot;);
}, 2000);

console.log(&quot;End&quot;);
</code></pre>
<blockquote>
<ol start="2">
<li>setInterval(callback, delay);</li>
</ol>
</blockquote>
<ul>
  <li>callback : 실행할 함수</li>
  <li>delay : 밀리초 단위의 실행 간격</li>
</ul>

<pre><code class="language-JS">let count = 0;

function printCount() {
  console.log(&quot;Count:&quot;, count);
  count++;

  if (count &gt; 5) {
    clearInterval(intervalId); // 특정 조건이 만족되면 setInterval을 중지
  }
}

const intervalId = setInterval(printCount, 1000);</code></pre>
<p>타이머 함수 사용 시 메모리 누수를 방지하기 위해 반드시 clearTimeout() 혹은 clearInterval()을 사용해야한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 클로저(Closure)]]></title>
            <link>https://velog.io/@hanl__l/JS-%ED%81%B4%EB%A1%9C%EC%A0%80Closure-uzhv9yzi</link>
            <guid>https://velog.io/@hanl__l/JS-%ED%81%B4%EB%A1%9C%EC%A0%80Closure-uzhv9yzi</guid>
            <pubDate>Wed, 15 Nov 2023 13:01:28 GMT</pubDate>
            <description><![CDATA[<h3>클로저 (Closure)</h3>

<blockquote>
<p>클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수다.</p>
</blockquote>
<p>클로저는 내부함수가 유효한 상태에서 외부함수가 종료되어 외부 함수의 실행 컨텍스트가 반환되어도, 외부함수의 실행 컨텍스트 내의 확성 객체(함수 선언 등의 정보를 가지고 있음)는 내부함수에 의해 참조되는 한 유효하여 내부함수가 스코프체인을 통해 참조할 수 있는 것을 의미한다.</p>
<pre><code class="language-Javascript">function outerFunction() {
  let outerVariable = &#39;I am from the outer function&#39;;

  function innerFunction() {
    console.log(outerVariable);
  }

  return innerFunction;
}

const closureExample = outerFunction();
closureExample(); // 결과: &quot;I am from the outer function&quot;</code></pre>
<p>위의 코드에서 outerFunction은 내부에 outerVariable이라는 변수를 가지고 있다. 또한 그 안에 정의된  innerFunction은 outerVariable에 접근한다. 그리고 outerFunction이 실행되면서 반환된 innerFunction을 clouserExample에 할당한 후 closureExample()을 호출하면, 클로저가 발생해 innterFunction은 외부함수인 outerFunction의 변수에 접근 할 수 있다.</p>
<h4>클로저가 필요한 이유</h4>

<blockquote>
<ol>
<li>데이터 캡슐화</li>
</ol>
</blockquote>
<p>외부에서의 접근을 제한하고, 내부의 함수에서만 해당 데이터에 접근 할수 있게 한다.</p>
<pre><code class="language-JavaScript">function createCounter() {
  let count = 0;

  return function() {
    count++;
    console.log(count);
  };
}

const counter = createCounter();
counter(); // 출력: 1
counter(); // 출력: 2</code></pre>
<p>createCounter가 클로저를 형성하여, count 변수를 외부에서 직접 접근하는 것을 막고 내부 함수를 통해 안전하게 데이터를 증가시킨다.</p>
<blockquote>
<ol start="2">
<li>상태 유지</li>
</ol>
</blockquote>
<p>클로저는 함수가 선언될 때 환경을 기억하므로, 함수가 외부에서 호출되어도 그 상태를 유지할 수 있다.</p>
<pre><code class="language-JavaScript">function outerFunction() {
  let outerVariable = &#39;I am from the outer function&#39;;

  function innerFunction() {
    console.log(outerVariable);
  }

  return innerFunction;
}

const closureExample = outerFunction();
closureExample(); // 결과: &quot;I am from the outer function&quot;</code></pre>
<p>innerFunction은 클로저를 통해 outerVariable 변수에 접근하여 외부 함수의 형태를 기억하고, 이를 바탕으로 출력한다.</p>
<blockquote>
<ol start="3">
<li>비동기 작업과 콜백함수</li>
</ol>
</blockquote>
<pre><code class="language-JavaScript">function fetchData(url, callback) {
  // 비동기 작업
  setTimeout(function() {
    const data = &quot;Data from &quot; + url;
    callback(data);
  }, 1000);
}

fetchData(&#39;https://example.com/api/data&#39;, function(result) {
  console.log(result);
});</code></pre>
<p>setTimeout 함수 내부의 콜백 함수가 클로저를 형성하여 외부 변수인 url과 callback에 접근하여 비동기 작업을 완료하고 결과를 전달한다.</p>
<p><br/><br /></p>
<h5>마무리</h5>
일단 아직까지 자바스크립트에서 클로저를 사용해본적이 없어서 단번에 이해하긴 어렵다. 좀 더 생각하면서 코드를 짜봐야겠다.]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 구조분해할당 / 나머지 매개 변수 / 전개구문]]></title>
            <link>https://velog.io/@hanl__l/JS-%EA%B5%AC%EC%A1%B0%EB%B6%84%ED%95%B4%ED%95%A0%EB%8B%B9-%EB%82%98%EB%A8%B8%EC%A7%80-%EB%A7%A4%EA%B0%9C-%EB%B3%80%EC%88%98-%EC%A0%84%EA%B0%9C%EA%B5%AC%EB%AC%B8</link>
            <guid>https://velog.io/@hanl__l/JS-%EA%B5%AC%EC%A1%B0%EB%B6%84%ED%95%B4%ED%95%A0%EB%8B%B9-%EB%82%98%EB%A8%B8%EC%A7%80-%EB%A7%A4%EA%B0%9C-%EB%B3%80%EC%88%98-%EC%A0%84%EA%B0%9C%EA%B5%AC%EB%AC%B8</guid>
            <pubDate>Mon, 13 Nov 2023 12:55:16 GMT</pubDate>
            <description><![CDATA[<h3>구조 분해 할당</h3>
배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 자바스크립트 표현식이다. 이를 통해 코드를 더 간결하게 작성할 수 있고, 변수 할당을 효과적으로 처리할 수 있다.

<h4>배열 구조 분해 할당</h4>
할당하고자 하는 변수의 개수가 분해하고자 하는 배열의 길이보다 크더라도 에러가 발생하지 않는다. 할당할 값이 없으면 undefined가 할당된다.

<p>= (등호) 를 이용하면 할당할 값이 없을 때 기본 값을 설정할 수 있다.</p>
<pre><code class="language-JavaScript">// 기존 방식
const colors = [&#39;빨강&#39;, &#39;파랑&#39;, &#39;초록&#39;];
const red = colors[0];
const blue = colors[1];
const green = colors[2];

// 구조 분해 할당
const [red, blue, green] = colors;

console.log(red);   // &#39;빨강&#39;
console.log(blue);  // &#39;파랑&#39;
console.log(green); // &#39;초록&#39;</code></pre>
<h4>객체 구조 분해 할당</h4>
```JavaScript
// 객체 생성
const person = { name: '홍길동', age: 30, job: '개발자' };

<p>// 객체 구조 분해 할당
const { name, age, job } = person;</p>
<p>// 변수에 할당된 값 출력
console.log(name); // &#39;홍길동&#39;
console.log(age);  // 30
console.log(job);  // &#39;개발자&#39;</p>
<pre><code>
&lt;h3&gt;나머지 매개 변수&lt;/h3&gt;
여러 개의 인수를 배열로 받아들일 수 있도록 하는 자바스크립트의 기능이다. 이는 함수가 몇 개의 인수를 미리 알 수 없는 경우 유용하게 사용할 수 있다. 나머지 매개 변수는 함수 매개 변수 중 마지막에 위치해야하며, 세 개의 점(&#39;...&#39;) 뒤에 나머지 인수를 수용할 변수의 이름이 온다.

```JavaScript
// 나머지 매개 변수 사용
function sum(...numbers) {
  let result = 0;

  for (let number of numbers) {
    result += number;
  }

  return result;
}

// 함수 호출
const total = sum(1, 2, 3, 4, 5);

console.log(total); // 15</code></pre><h3>전개 구문</h3>
배열이나 객체를 펼쳐서 각 요소 또는 속성을 개별적으로 처리할 수 있게 하는 자바스크립트 문법니다. 배열이나 객체를 다르 배열이나 객체에 복사하거나, 함수 호출 시 인수로 전달할 때 유용하게 사용된다.

<h4>배열에서의 전개 구문</h4>

<pre><code class="language-JavaScript">const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5, 6];

console.log(arr2); // [1, 2, 3, 4, 5, 6]</code></pre>
<h4>객체에서의 전개구문</h4>

<pre><code class="language-JavaScript">const obj1 = { a: 1, b: 2 };
const obj2 = { ...obj1, c: 3, d: 4 };

console.log(obj2); // { a: 1, b: 2, c: 3, d: 4 }</code></pre>
<h4>함수 호출 시 인수로서의 전개 구문</h4>
``` JavaScript
function addNumbers(a, b, c) {
  return a + b + c;
}

<p>const numbers = [1, 2, 3];
const sum = addNumbers(...numbers);</p>
<p>console.log(sum); // 6
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] Number 메서드 정리 ( +  Math 메서드)]]></title>
            <link>https://velog.io/@hanl__l/JS-Number-%EB%A9%94%EC%84%9C%EB%93%9C-%EC%A0%95%EB%A6%AC-Math-%EB%A9%94%EC%84%9C%EB%93%9C</link>
            <guid>https://velog.io/@hanl__l/JS-Number-%EB%A9%94%EC%84%9C%EB%93%9C-%EC%A0%95%EB%A6%AC-Math-%EB%A9%94%EC%84%9C%EB%93%9C</guid>
            <pubDate>Thu, 09 Nov 2023 06:12:57 GMT</pubDate>
            <description><![CDATA[<h3>Number</h3>
자바스크립트에서 Number는 숫자 데이터 타입을 나타낸다. 여러 방법으로 숫자를 선언하고 사용할 수 있다.

<ul>
  <li>정수 및 소수 선언</li>
</ul>

<pre><code class="language-JavaScript">let integerNumber = 10; // 정수
let floatNumber = 3.14; // 소수 (부동소수점 수)</code></pre>
<ul>
  <li>산술 연산</li>
</ul>

<pre><code class="language-JavaScript">let num1 = 10;
let num2 = 5;

let sum = num1 + num2; // 덧셈: 15
let difference = num1 - num2; // 뺄셈: 5
let product = num1 * num2; // 곱셈: 50
let quotient = num1 / num2; // 나눗셈: 2</code></pre>
<h4>Number 메서드</h4>

<p><Strong>parseInt()</Strong></p>
<blockquote>
<p>문자열을 정수로 변화한다. 첫번째 인수는 변환하려는 문자열이고, 두번째 인수는 어떤 진수 체계로 표현되어있는지 나타낸다. 두번째 인수는 선택적이며 생략 시 10진수로 표현된 것으로 간주한다.</p>
</blockquote>
<pre><code class="language-JavaScript">let stringNumber = &quot;42&quot;;
let parsedInt = parseInt(stringNumber); // 42 (10진수로 해석됨)

let hexString = &quot;2A&quot;;
let parsedHex = parseInt(hexString, 16); // 42 (16진수로 해석됨)</code></pre>
<p><Strong>parseFloat</Strong></p>
<blockquote>
<p>문자열을 부동소숫점 수로 변환한다. 정수 또는 소숫점 이하의 숫자로 이루어진 문자열을 전달 받는다.</p>
</blockquote>
<pre><code class="language-JavaScript">let floatString = &quot;3.14&quot;;
let parsedFloat = parseFloat(floatString); // 3.14</code></pre>
<p>+) + 연산자를 사용하여 문자열을 숫자로 간단히 변환할 수 있다.</p>
<pre><code class="language-JavaScript">let stringNumber = &quot;42&quot;;
let number = +stringNumber; // 42 (정수로 변환됨)</code></pre>
<p><Strong>isNaN()</Strong></p>
<blockquote>
<p>주어진 값이 NaN(Not a Number) 인지 여부를 확인한다. NaN은 숫자가 아님을 나타내는 값이다.</p>
</blockquote>
<pre><code class="language-JavaScript">console.log(isNaN(10)); // false
console.log(isNaN(&quot;hello&quot;)); // true (숫자로 변환할 수 없는 문자열)
console.log(isNaN(NaN)); // true</code></pre>
<p><Strong>isFinite()</Strong></p>
<blockquote>
<p>주어진 값이 유한한 수인지 확인한다. Infinity나 NaN이 아닌 유한한 수를 나타내면 true를 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">console.log(isFinite(42)); // true
console.log(isFinite(Infinity)); // false
console.log(isFinite(NaN)); // false</code></pre>
<p><Strong>isInteger()</Strong></p>
<blockquote>
<p>주어진 값이 정수인지 여부를 확인한다. 정수일 경우 true를 반환하고 그렇지 않으면 false를 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">console.log(Number.isInteger(10)); // true
console.log(Number.isInteger(3.14)); // false</code></pre>
<p><Strong>isSafeInteger()</Strong></p>
<blockquote>
<p>주어진 값이 안전한 정수인지 여부를 확인한다. 안전한 정수는 -2^53 에서 2^53까지의 정수를 의미한다. 주어진 값이 안전한 정수 범위 내에 있으면 true를 반환한고, 그렇지 않으면 false를 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">console.log(Number.isSafeInteger(9007199254740992)); // false (범위를 벗어남)
console.log(Number.isSafeInteger(42)); // true (안전한 정수 범위 내)</code></pre>
<p><Strong>toExponential()</Strong></p>
<blockquote>
<p>숫자를 지수 표기법으로 변환한다. 전달받은 인수는 소숫점 뒤에 표시될 숫자의 개수를 나타낸다.</p>
</blockquote>
<pre><code class="language-JavaScript">let number = 12345;
let exponentialForm = number.toExponential(2); // &quot;1.23e+4&quot;</code></pre>
<p><Strong>toFixed()</Strong></p>
<blockquote>
<p>숫자를 고정 소숫점 표기법으로 변환한다. 전달받은 인수는 소숫점 이하에 표시될 숫자의 개수를 나타낸다.</p>
</blockquote>
<pre><code class="language-JavaScript">let number = 3.14159;
let fixedForm = number.toFixed(2); // &quot;3.14&quot;</code></pre>
<p><Strong>toPrecision()</Strong></p>
<blockquote>
<p>숫자를 주어진 정밀도로 표현한다.</p>
</blockquote>
<pre><code class="language-JavaScript">let number = 123.456789;
let precisionForm = number.toPrecision(4); // &quot;123.5&quot;</code></pre>
<p><Strong>toString()</Strong></p>
<blockquote>
<p>숫자를 문자열로 변환한다. 전달받은 인수는 변환할 진수를 나타낸다. 이는 선택적 파라미터이며, 생략하면 10진수로 변환된다.</p>
</blockquote>
<pre><code class="language-JavaScript">let number = 42;
let binaryString = number.toString(2); // &quot;101010&quot; (2진수로 변환됨)</code></pre>
<p><Strong>valueOf()</Strong></p>
<blockquote>
<p>Number 객체의 원시값을 반환한다. Number 객체를 원시값으로 변환하면 해당 숫자가 된다.</p>
</blockquote>
<pre><code class="language-JavaScript">let numberObject = new Number(42);
let primitiveValue = numberObject.valueOf(); // 42</code></pre>
<h5>Number 메서드 요약</h5>
<table>
  <tr>
    <th>메서드</th>
    <th>설명</th>
  </tr>
  <tr>
    <td>parseInt()</td>
    <td>문자열을 파싱하여, 문자열에 포함된 숫자 부분을 정수 형태로 반환</td>
  </tr>
  <tr>
    <td>parseFloat()</td>
    <td>문자열을 파싱하여, 문자열에 포함된 숫자 부분을 실수 형태로 반환</td>
  </tr>
  <tr>
    <td>isNaN()</td>
    <td>전달된 값이 NaN이 아닌지 검사함</td>
  </tr>
  <tr>
    <td>isFinite()</td>
    <td>전달된 값이 유한한 수인지 아닌지를 검사함</td>
  </tr>
  <tr>
    <td>isInteger()</td>
    <td>전달된 값이 정수인지 아닌지를 검사함</td>
  </tr>
  <tr>
    <td>isSafeInteger()</td>
    <td>전달된 값이 안전한 정수인지 아닌지를 검사함</td>
  </tr>
  <tr>
    <td>toExponential()</td>
    <td>지수 표기법으로 변환 후, 그 값을 문자열로 반환함.</td>
  </tr>
  <tr>
    <td>isFixed()</td>
    <td>소수 부분 자릿수를 전달 받은 값으로 고정한 후 그 값을 문자열로 반환함</td>
  </tr>
  <tr>
    <td>toPrecision()</td>
    <td>가수와 소수 부분의 합친 자릿수를 전달받은 값으로 고정한 후 그 값을 문자열로 반환함</td>
  </tr>
  <tr>
    <td>toString()</td>
    <td>Number 인스턴스의 값을 문자열로 반환함</td>
  </tr>
  <tr>
    <td>valueOf()</td>
    <td>Number 인스턴스가 가지고 있는 값을 반환함</td>
  </tr>
</table>


<p>숫자 연산을 위해 자바스크립트에서 제공하는 Math 메서드를 간단히 요약한다.</p>
<h5>Math 메서드 요약</h5>
<table>
  <tr>
    <th>메서드</th>
    <th>설명</th>
  </tr>
  <tr>
    <td>Math.min()</td>
    <td>인수로 전달 받은 값 중에서 가장 작은 수로 반환함</td>
  </tr>
  <tr>
    <td>Math.max()</td>
    <td>인수로 전달 받은 값 중에서 가장 큰 수를 반환함</td>
  </tr>
  <tr>
    <td>Math.random()</td>
    <td>0보다 크거나 같고 1보다 작은 랜덤 숫자를 반환함</td>
  </tr>
  <tr>
    <td>Math.round()</td>
    <td>전달 받은 값을 소숫점 첫번째 자리에서 반올림하여 그 결과를 반환함</td>
  </tr>
  <tr>
    <td>Math.floor()</td>
    <td>소숫점 이하를 버리고 주어진 숫자를 내림하여 반환</td>
  </tr>
  <tr>
    <td>Math.ceil()</td>
    <td>소숫점 이하를 버리고 주어진 숫자를 올림하여 반환</td>
  </tr>
  <tr>
    <td>Math.abs()</td>
    <td>전달 받은 수의 절댓값을 반환함</td>
  </tr>
  <tr>
    <td>Math.sqrt()</td>
    <td>전달 받은 수의 제곱근을 반환함</td>
  </tr>
  <tr>
    <td>Math.cbrt()</td>
    <td>전달 받은 수의 세제곱근을 반환함</td>
  </tr>
</table>]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] String 메서드 정리]]></title>
            <link>https://velog.io/@hanl__l/JS-String-%EB%A9%94%EC%84%9C%EB%93%9C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@hanl__l/JS-String-%EB%A9%94%EC%84%9C%EB%93%9C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Thu, 09 Nov 2023 04:47:40 GMT</pubDate>
            <description><![CDATA[<h3>String</h3>
자바스크립트에서 String(문자열)은 문자열의 나열이다. 문자열은 작은 따옴표나 큰 따옴표로 둘러쌓인 문자들의 시퀀스이다. 또한 ES6에서 도입된 백틱(\`)을 사용하여 만들 수도 있다.

<pre><code class="language-JavaScript">const singleQuotedString = &#39;Hello, World!&#39;;
const doubleQuotedString = &quot;Hello, World!&quot;;
const backtickString = `Hello, World!`;

console.log(singleQuotedString); // 출력: &quot;Hello, World!&quot;
console.log(doubleQuotedString); // 출력: &quot;Hello, World!&quot;
console.log(backtickString);      // 출력: &quot;Hello, World!&quot;</code></pre>
<p>백틱(`)과 일반 따옴표와의 차이는 다음과 같다.</p>
<ol>
  <li>다중 라인 문자열 : 백틱은 여러 줄로 이루어진 문자열을 쉽게 작성할 수 있다. 이를 템플릿 리터럴이라 부르며, 여러 줄의 문자열을 작성할 때 \n 과 같은 이스케이프 문자를 사용하지 않아도 된다.</li>
  <li>표현식 삽입 : 백틱 문자열 안에서 ${} 구문을 사용하여 변수나 표현식을 쉽게 삽입할 수 있다.</li>
  <li>이스케이프 문자 사용의 유연성 : 일반 따옴표로 문자열을 작성할 때, 특정 문자를 이스케이프 해야하는 경우가 있다. 예를 들어 작은 따옴표 안에 작은 따옴표를 표현하려면 이스케이프해야하지만, 백틱 문자열에서는 이러한 이스케이프는 필요하지 않다.</li>
</ol>

<h4>String 메서드</h4>

<p><Strong>String.fromCharCode()</Strong></p>
<blockquote>
<p>지정된 유니코드 코드 포인트에 해당하는 문자열을 생성하는 String 객체 메서드. 하나 이상의 유니코드 포인트(숫자)를 인자로 받아 해당 코드 포인트에 해당하는 문자열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">String.fromCharCode(65);    //&quot;A&quot;
String.fromCharCode(65, 66, 67);    //&quot;ABC&quot;</code></pre>
<p><Strong>String.fromCodePoint()</Strong></p>
<blockquote>
<p>하나 이상의 유니코드 코드 포인트(숫자)를 인자로 받아 해당 코드 포인트에 해당하는 문자열을 생성한다. 코드 포인트를 직접 지정하므로, 더 직관적인 방법으로 문자열을 생성할 수 있다. 또한 코드 포인트가 유효한 범위(0 에서 0x10FFF 사이의 정수) 에 있는지 검증하고 유효하지 않는 코드 포인트를 무시한다.</p>
</blockquote>
<pre><code class="language-JavaScript">//문법
String.fromCodePoint(codePoint1, codePoint2, ..., codePointN);

//예시
const char = String.fromCodePoint(72, 101, 108, 108, 111);
console.log(char); // 출력: &quot;Hello&quot;</code></pre>
<p><Strong>indexOf()</Strong></p>
<blockquote>
<p>문자열에서 특정 문자열 또는 문자의 첫번째 발생 위치(인덱스)를 반환한다. 만약 해당 문자열이나 문자를 찾지 못하면 -1을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const index = str.indexOf(&quot;World&quot;);
console.log(index); // 출력: 7 (첫 번째 &#39;World&#39;의 시작 위치)

//두 번째 인자로 시작 인덱스를 전달 -&gt; 특정위치부터 검색 시작 가능
const str = &quot;Hello, World! Hello, Universe!&quot;;
const index = str.indexOf(&quot;Hello&quot;, 10);
console.log(index); // 출력: 14 (두 번째 &#39;Hello&#39;의 시작 위치)</code></pre>
<p><Strong>lastIndexOf()</Strong></p>
<blockquote>
<p>문자열에서 특정 문자열 또는 문자의 마지막 발생 위치(인덱스)를 반환한다. 만약 해당 문자열이나 문자를 찾지 못할 경우 -1을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World! Hello, Universe!&quot;;
const lastIndex = str.lastIndexOf(&quot;Hello&quot;);
console.log(lastIndex); // 출력: 14 (마지막 &#39;Hello&#39;의 시작 위치)

//시작 인덱스 전달 (문자열의 끝에서 역으로 검색 시작)
const str = &quot;Hello, World! Hello, Universe!&quot;;
const lastIndex = str.lastIndexOf(&quot;Hello&quot;, 13);
console.log(lastIndex); // 출력: 0 (첫 번째 &#39;Hello&#39;의 시작 위치, 13번 인덱스 이전까지 역으로 검색)</code></pre>
<p><Strong>charAt()</Strong></p>
<blockquote>
<p>문자열에서 지장헌 인덱스에 해당하는 문자를 반환한다. 인덱스는 0부터 시작하며, 지정된 인덱스가 없을 경우 빈 문자열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const character = str.charAt(7);
console.log(character); // 출력: &quot;W&quot; (인덱스 7에 해당하는 문자)</code></pre>
<p><Strong>charCodeAt()</Strong></p>
<blockquote>
<p>문자열에서 지정된 인덱스에 해당하는 문자의 유니코드 코드 포인트를 반환한다. 반환값은 0부터 65535까지의 정수로 지정된 인덱스에 문자열이 없을 경우 NaN을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const charCode = str.charCodeAt(7);
console.log(charCode); // 출력: 87 (인덱스 7에 해당하는 문자 &#39;W&#39;의 유니코드 코드 포인트)</code></pre>
<p><Strong>codePointAt()</Strong></p>
<blockquote>
<p>문자열에서 지정된 위치의 유니코드 코드 포인트를 반환한다. 0부터 0x10FFFF까지의 정수를 반환하며, 대표적으로 4바이트로 표현되는 유니코드 코드 포인트를 올바르게 처리한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;😊&quot;;
const codePoint = str.codePointAt(0);
console.log(codePoint); // 출력: 128522 (지정된 위치의 유니코드 코드 포인트)</code></pre>
<p><Strong>slice()</Strong></p>
<blockquote>
<p>문자열의 지정된 부분을 추출한다. 시작인덱스부터 끝 인덱스의 이전 문자열을 반환한다. 끝 인덱스는 선택적이며, 지정하지 않을 경우 문자열의 끝까지 추출한다. 음수 값을 사용할 경우 문자열의 끝에서 역순으로 센다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const sliced = str.slice(7, 12);
console.log(sliced); // 출력: &quot;World&quot; (인덱스 7부터 11까지의 부분 문자열)

//음수값 사용시
const str = &quot;Hello, World!&quot;;
const sliced1 = str.slice(-6); // 끝에서부터 6개의 문자열을 추출
const sliced2 = str.slice(-12, -1); // 끝에서부터 -12번째부터 -2번째까지의 문자열을 추출

console.log(sliced1); // 출력: &quot;World!&quot;
console.log(sliced2); // 출력: &quot;Hello, World&quot;</code></pre>
<p><Strong>substring()</Strong></p>
<blockquote>
<p>문자열의 지정된 부분을 추출한다. 시작 인덱스부터 끝 인덱스 이전까지의 문자열을 반환한다. 시작 인덱스와 끝 인덱스가 음수일 경우 0으로 취급된다. 끝 인덱스가 음수 또는 &quot;0&quot; 인경우 시작인덱스와 끝 인덱스가 서로 뒤바뀐다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const subStringed = str.substring(7, 12);
console.log(subStringed); // 출력: &quot;World&quot; (인덱스 7부터 11까지의 부분 문자열)</code></pre>
<p><Strong>substr()</Strong></p>
<blockquote>
<p>문자열의 지정된 위치부터 시작하여 지정된 길이의 문자열은 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const subStr = str.substr(7, 5);
console.log(subStr); // 출력: &quot;World&quot; (인덱스 7부터 길이 5까지의 부분 문자열)</code></pre>
<p><Strong>split()</Strong></p>
<blockquote>
<p>문자열을 특정 구분자(separator)를 기준으로 분할하여 배열을 반환한다. 구분자가 지정되지않으면, 전체 문자열이 하나의 요소로 들어간 배열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;apple,banana,orange&quot;;
const fruits = str.split(&quot;,&quot;);
console.log(fruits); // 출력: [&quot;apple&quot;, &quot;banana&quot;, &quot;orange&quot;] (쉼표를 기준으로 분할된 배열)

//정규 표현식 사용
const str = &quot;apple ban,banana or,ange&quot;;
const fruits = str.split(/\s|, /);
console.log(fruits); // 출력: [&quot;apple&quot;, &quot;banana&quot;, &quot;orange&quot;] (공백 또는 쉼표와 공백을 기준으로 분할된 배열)</code></pre>
<p><Strong>concat()</Strong></p>
<blockquote>
<p>문자열을 합쳐서 새로운 문자열을 생성한다. 원래 문자열을 변경하지 않고, 새로운 문자열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">//기본 구문
str.concat(string1, string2, ..., stringN)

const str1 = &quot;Hello, &quot;;
const str2 = &quot;World!&quot;;
const combinedString = str1.concat(str2);
console.log(combinedString); // 출력: &quot;Hello, World!&quot;

const greeting = &quot;Hello&quot;;
const name = &quot;Alice&quot;;
const punctuation = &quot;!&quot;;
const fullGreeting = greeting.concat(&quot;, &quot;, name, punctuation);
console.log(fullGreeting); // 출력: &quot;Hello, Alice!&quot;</code></pre>
<p><Strong>toUpperCase()</Strong></p>
<blockquote>
<p>문자열의 모든 문자를 대문자로 변환한 새로운 문자열을 반환한다. 원래 문자열을 변경하지 않고, 새로운 문자열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const upperCaseStr = str.toUpperCase();
console.log(upperCaseStr); // 출력: &quot;HELLO, WORLD!&quot;</code></pre>
<p><Strong>toLowerCase()</Strong></p>
<blockquote>
<p>문자열의 무든 문자를 소문자로 변환한 새로운 문자열을 반환한다. 원래 문자열을 변경하지 않고, 새로운 문자열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const lowerCaseStr = str.toLowerCase();
console.log(lowerCaseStr); // 출력: &quot;hello, world!&quot;</code></pre>
<p><Strong>trim()</Strong></p>
<blockquote>
<p>문자열 양 끝의 공백(스페이스, 탭, 줄 바꿈 등)을 제거한 새로운 문자열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;  Hello, World!  &quot;;
const trimmedStr = str.trim();
console.log(trimmedStr); // 출력: &quot;Hello, World!&quot;</code></pre>
<p><Strong>search()</Strong></p>
<blockquote>
<p>정규 표현식과 매치되는 첫번째 문자열의 인덱스를 반환하며, 일치하는 문자열을 찾지 못할 경우 -1을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const index = str.search(/World/);
console.log(index); // 출력: 7 (일치하는 문자열 &#39;World&#39;의 시작 인덱스)</code></pre>
<p><Strong>replace()</Strong></p>
<blockquote>
<p>지정된 패턴 또는 문자열을 새로운 문자열로 대체한 결과를 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const newStr = str.replace(&quot;World&quot;, &quot;Universe&quot;);
console.log(newStr); // 출력: &quot;Hello, Universe!&quot; (기존 문자열에서 &#39;World&#39;를 &#39;Universe&#39;로 대체)</code></pre>
<p><Strong>match()</Strong></p>
<blockquote>
<p>정규표현식과 매치되는 문자열의 배열을 반환한다. 일치하는 결과가 없을 경우 &#39;null&#39;을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const matched = str.match(/o/g);
console.log(matched); // 출력: [&quot;o&quot;, &quot;o&quot;] (정규 표현식과 일치하는 &#39;o&#39; 문자열을 모두 찾아 배열로 반환)</code></pre>
<p><Strong>includes()</Strong></p>
<blockquote>
<p>문자열에 특정 문자열이 포함되어있는지 여부를 확인하여 true 또는 false를 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const includesWorld = str.includes(&quot;World&quot;);
console.log(includesWorld); // 출력: true (문자열에 &#39;World&#39;가 포함되어 있음)</code></pre>
<p><Strong>startsWith()</Strong></p>
<blockquote>
<p>주어진 문자열이 특정 문자열로 시작하는지 여부를 확인하여 true 또는 false를 반환한다. 두 번째 매개변수로 시작위치를 지정할 수 있다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const startsWithHello = str.startsWith(&quot;Hello&quot;);
console.log(startsWithHello); // 출력: true (문자열이 &#39;Hello&#39;로 시작함)

//시작 위치 지정
const str = &quot;Hello, World!&quot;;
const startsWithWorld = str.startsWith(&quot;World&quot;, 7);
console.log(startsWithWorld); // 출력: true (인덱스 7에서 시작하는 문자열이 &#39;World&#39;로 시작함)</code></pre>
<p><Strong>endsWith()</Strong></p>
<blockquote>
<p>주어진 문자열이 특정 문자열로 끝나는지 여부를 확인하여 true 또는 false를 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const endsWithWorld = str.endsWith(&quot;World!&quot;);
console.log(endsWithWorld); // 출력: true (문자열이 &#39;World!&#39;로 끝남)</code></pre>
<p><Strong>toLocaleUpperCase()</Strong></p>
<blockquote>
<p>문자열을 현재 사용중인 로케일에 따라 대문자로 변환한 새로운 문자열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const upperCaseStr = str.toLocaleUpperCase();
console.log(upperCaseStr); // 출력: &quot;HELLO, WORLD!&quot; (현재 로케일에 따라 대문자로 변환된 문자열)</code></pre>
<p><Strong>toLocaleLowerCase()</Strong></p>
<blockquote>
<p>문자열을 현재 사용중인 로케일에 따라 소문자로 변환한 새로운 문자열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, World!&quot;;
const lowerCaseStr = str.toLocaleLowerCase();
console.log(lowerCaseStr); // 출력: &quot;hello, world!&quot; (현재 로케일에 따라 소문자로 변환된 문자열)</code></pre>
<p><Strong>localeCompare()</Strong></p>
<blockquote>
<p>두 문자열을 사용 중인 로케일에 따라 비교한다. 두 문자열이 동일하면 0을 반환하고, 첫 번째 문자열이 두 번째 문자열보다 사전적으로 앞에오면 음수를, 뒤에오면 양수를 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str1 = &quot;apple&quot;;
const str2 = &quot;banana&quot;;
const result = str1.localeCompare(str2);
console.log(result); // 출력: 음수 (str1이 str2보다 사전적으로 앞에 위치함)</code></pre>
<p><Strong>normaize()</Strong></p>
<blockquote>
<p>문자열에 포함된 유니코드 정규화 형식을 지정된 형식으로 변환한다. 주로 유니코드 문자열을 정규화하여 문자열을 비교하거나 검색할 때 사용한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Café&quot;;
const normalizedStr = str.normalize(&#39;NFD&#39;); // NFD 형식으로 정규화
console.log(normalizedStr); // 출력: &quot;Café&quot; (다양한 유니코드 문자를 정규화한 문자열)</code></pre>
<p><Strong>repeat()</Strong></p>
<blockquote>
<p>문자열을 주어진 횟수반큼 반복하여 새로운 문자열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const str = &quot;Hello, &quot;;
const repeatedStr = str.repeat(3);
console.log(repeatedStr); // 출력: &quot;Hello, Hello, Hello, &quot; (원래 문자열을 3번 반복한 문자열)</code></pre>
<p><Strong>toString()</Strong></p>
<blockquote>
<p>String 객체를 문자열로 변환한 값을 반환한다. 자바스크립트의 모든 데이터 타입은 해당 데이터 타입에 대한 문자열 표현을 가지고 있으며, 객체나 숫자, 불리언 등을 문자열로 변환할 때 자주 사용된다.</p>
</blockquote>
<pre><code class="language-JavaScript">const num = 42;
const str = num.toString();
console.log(str); // 출력: &quot;42&quot; (숫자 42를 문자열 &quot;42&quot;로 변환)</code></pre>
<p><Strong>valueOf()</Strong></p>
<blockquote>
<p>String 객체를 원시 문자열 값으로 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const strObject = new String(&quot;Hello&quot;);
const primitiveStr = strObject.valueOf();
console.log(primitiveStr); // 출력: &quot;Hello&quot; (String 객체를 원시 문자열 값으로 변환)</code></pre>
<h5>요약</h5>
<table>
  <tr>
    <th>메서드</th>
    <th>설명</th>
  </tr>
  <tr>
    <td>String.fromCharCode()</td>
    <td>쉼표로 구분되는 일련의 유니코드에 해당하는 문자들로 구성된 문자열을 반환함</td>
  </tr>
  <tr>
    <td>String.fromCodePoint()</td>
    <td>쉼표로 구분되는 일련의 코드 포인트에 해당하는 문자들로 구성된 문자열을 반환함</td>
  </tr>
  <tr>
    <td>indexOf()</td>
    <td>특정 문자나 문자열이 처음으로 등장하는 위치의 인덱스를 반환함</td>
  </tr>
  <tr>
    <td>lastIndexOf()</td>
    <td>특정 문자나 문자열이 마지막으로 등장하는 위치의 인덱스를 반환함</td>
  </tr>
  <tr>
    <td>charAt()</td>
    <td>전달받은 인덱스에 위치한 문자를 반환함</td>
  </tr>
  <tr>
    <td>charCodeAt()</td>
    <td>전달받은 인덱스에 위치한 문자열의 UTF-16 코드를 반환함</td>
  </tr>
  <tr>
    <td>charPointAt()</td>
    <td>전달받은 인덱스에 위치한 문자의 유니코드 코드 포인트를 반환함</td>
  </tr>
  <tr>
    <td>slice()</td>
    <td>전달받은 시작 인덱스로부터 종료 인덱스 바로 앞까지의 문자열을 추출한 새 문자열을 반환함</td>
  </tr>
  <tr>
    <td>substring()</td>
    <td>전달받은 시작 인덱스로부터 종료 인덱스 바로 앞까지의 문자열을 추출한 새 문자열을 반환함</td>
  </tr>
  <tr>
    <td>substr</td>
    <td>전달받은 시작 인덱스로부터 길이만큼의 문자열을 추출한 새로운 문자열을 반환함</td>
  </tr>
  <tr>
    <td>split()</td>
    <td>구분자(separator)를 기준으로 나눈 후, 나뉜 문자열을 하나의 배열로 반환함</td>
  </tr>
  <tr>
    <td>concat()</td>
    <td>전달 받은 문자열을 결합한 새로운 문자열을 반환함</td>
  </tr>
  <tr>
    <td>toUpperCase()</td>
    <td>모든 문자를 대문자로 변환한 새로운 문자열을 반환함</td>
  </tr>
  <tr>
    <td>toLowerCase()</td>
    <td>모든 문자를 소문자로 변환한 새로운 문자열을 반환함</td>
  </tr>
  <tr>
    <td>trim()</td>
    <td>양 끝에 존재하는 공백과 모든 줄 바꿈 문자를 제거한 새로운 문자열을 반환함</td>
  </tr>
  <tr>
    <td>search()</td>
    <td>인수로 전달받은 정규 표현식에 맞는 문자나 문자열이 처음으로 등작하는 위치의 인덱스를 반환함</td>
  </tr>
  <tr>
    <td>replace()</td>
    <td>인수로 전달받은 패턴에 맞는 문자열을 대체 문자열로 변환한 새로운 문자열을 반환함</td>
  </tr>
  <tr>
    <td>match()</td>
    <td>인수로 전달받은 정규 표현식에 맞는 문자열을 찾아서 하나의 배열로 반환함</td>
  </tr>
  <tr>
    <td>includes()</td>
    <td>인수로 전달받은 문자나 문자열이 포함되어있는지 검사한 후 그 결과를 boolean값으로 반환함</td>
  </tr>
  <tr>
    <td>startsWith()</td>
    <td>인수로 전달받은 문자나 문자열로 시작되는 지를 검사한 후 그 결과를 boolean 값으로 반환함</td>
  </tr>
  <tr>
    <td>endsWith()</td>
    <td>인수로 전달받은 문자나 문자열로 끝나는지를 검사한 후 그 결과를 boolean 값으로 반환함</td>
  </tr>
  <tr>
    <td>toLocaleUpperCase()</td>
    <td>영문자뿐만 아니라 모든 언어의 문자를 대문자로 변환한 새로운 문자열을 반환함</td>
  </tr>
  <tr>
    <td>toLocaleLowerCase()</td>
    <td>영문자뿐만 아니라 모든 언어의 문자를 소문자로 변환한 새로운 문자열을 반환함</td>
  </tr>
  <tr>
    <td>localeCompare()</td>
    <td>인수로 전달받은 문자열과 정렬 순서로 비교하여 그 결과를 정수로 반환함</td>
  </tr>
  <tr>
    <td>normalize()</td>
    <td>해당 문자열의 유니코드 표준화 양식을 반환함</td>
  </tr>
  <tr>
    <td>repeat()</td>
    <td>해당 문자열을 인수로 전달받은 횟수만큼 반복하여 결합한 새로운 문자열을 반환함</td>
  </tr>
  <tr>
    <td>toString()</td>
    <td>String 인스턴스의 값을 문자열로 반환함</td>
  </tr>
  <tr>
    <td>valueOf</td>
    <td>String 인스턴스의 값을 문자열로 반환함</td>
  </tr>
</table>]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 나머지 연산 분배법칙 (백준 14928번)]]></title>
            <link>https://velog.io/@hanl__l/JAVA-%EB%82%98%EB%A8%B8%EC%A7%80-%EC%97%B0%EC%82%B0-%EB%B6%84%EB%B0%B0%EB%B2%95%EC%B9%99-%EB%B0%B1%EC%A4%80-14928%EB%B2%88</link>
            <guid>https://velog.io/@hanl__l/JAVA-%EB%82%98%EB%A8%B8%EC%A7%80-%EC%97%B0%EC%82%B0-%EB%B6%84%EB%B0%B0%EB%B2%95%EC%B9%99-%EB%B0%B1%EC%A4%80-14928%EB%B2%88</guid>
            <pubDate>Wed, 08 Nov 2023 04:09:21 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/14928">백준 14928 : 큰 수</a></p>
<p>단순한 문제라고 생각하고, BigInteger를 통해 접근했을 때, 시간 초과가 발생하였다. 다른 방법으로 접근할 수 밖에 없었는데, 분배법칙으로 접근하였다.</p>
<p>분배법칙에 대한 자세한 개념은 <a href="https://ko.khanacademy.org/math/pre-algebra/pre-algebra-arith-prop/pre-algebra-ditributive-property/a/distributive-property-explained">링크</a> 를 참조하였다.</p>
<pre><code class="language-Java">import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String a = sc.next();
        sc.close();
        long remain = 0;
        for(int i = 0; i &lt; a.length(); i++){
            remain = (remain * 10 + (a.charAt(i) - &#39;0&#39;)) % 20000303;
        }

        System.out.print(remain);

    }
}</code></pre>
<p>여기서 remain = (remain * 10 + (a.charAt(i) - &#39;0&#39;)) % 20000303; 이 부분이 덧셈의 분배법칙을 이용하여 풀이한 부분이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 배열 (Array) 메소드 정리]]></title>
            <link>https://velog.io/@hanl__l/JS-%EB%B0%B0%EC%97%B4-Array-%EB%A9%94%EC%86%8C%EB%93%9C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@hanl__l/JS-%EB%B0%B0%EC%97%B4-Array-%EB%A9%94%EC%86%8C%EB%93%9C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Tue, 07 Nov 2023 11:33:12 GMT</pubDate>
            <description><![CDATA[<h3>Array</h3>
 : 자바스크립트에서 Array 객체는, 다른 프로그래밍 언어의 배열과 마찬가지로, 여러 항목의 컬렉션을 단일 변수 이름 아래 저장할 수 있다. 여기서는 배열의 생성과, 접근, 그리고 주요 메소드를 정리해보려고 한다.

<h4>배열 생성하기</h4>
 : 배열은 대괄호로 감싸진 요소들의 목록으로 정의된다.

<pre><code class="language-JavaScript">let 배열이름 = [요소1, 요소2, 요소3, ...];</code></pre>
<h4>배열 요소에 접근하기</h4>
 : 배열의 각 요소에 접근하려면 인덱스를 사용한다. 인덱스는 0부터 시작하며, 배열의 길이보다 작아야한다.

<pre><code class="language-JavaScript">let numbers = [1, 2, 3, 4, 5];
console.log(numbers[0]); // 첫 번째 요소에 접근
console.log(numbers[2]); // 세 번째 요소에 접근</code></pre>
<h4>배열의 주요 메소드</h4>

<p><Strong>Array.isArray()</Strong></p>
<blockquote>
<p>주어진 값이 배열인지 여부를 확인하는 자바스크립트 내장함수로, 인자로 전달된 값이 배열인 경우 &#39;true&#39;를 그렇지 않을 경우 &#39;false&#39; 를 반환한다. 배열과 객체를 구별할 때 유용하게 사용될 수 있다.</p>
</blockquote>
<pre><code class="language-JavaScript">const arr = [1, 2, 3];
const obj = { key: &#39;value&#39; };

console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); // false</code></pre>
<p><Strong>Array.from()</Strong></p>
<blockquote>
<p>유사 배열 객체나 반복 가능한 객체를 얕게 복사하여 새로운 배열을 생성한다. 배열 형태로 변환하고자 하는 객체를 받아들이고, 배열로 변환된 새로운 객체 배열을 반환한다.</p>
</blockquote>
<ul><li>Array.from() 메소드 문법</li></ul>

<pre><code class="language-JavaScript">Array.from(arrayLike, mapFn, thisArg)</code></pre>
<ul>
  <li>arrayLike : 배열로 반환하고자 하는 유사 배열 객체나 반복 가능한 객체</li>
  <li>mapFn (옵션) : 배열의 각 요소에 대해 호출할 매핑 함수</li>
  <li>thisArg (옵션) : mapFn에서 사용될 this 값</li>
</ul>

<pre><code class="language-JavaScript">const str = &#39;hello&#39;;
const strArray = Array.from(str);

console.log(strArray); // [&#39;h&#39;, &#39;e&#39;, &#39;l&#39;, &#39;l&#39;, &#39;o&#39;]</code></pre>
<pre><code class="language-JavaScript">const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = Array.from(numbers, x =&gt; x * x);

console.log(squaredNumbers); // [1, 4, 9, 16, 25]</code></pre>
<p><Strong>Array.of()</Strong></p>
<blockquote>
<p>전달된 인자를 요소로 가지는 새로운 배열을 생성한다. 이 메소드는 전달된 값을 요소로 갖는 배열을 생성할 때 유용하게 사용할 수 있다.</p>
</blockquote>
<pre><code class="language-JavaScript">const arr1 = Array.of(1, 2, 3, 4, 5);
console.log(arr1); // [1, 2, 3, 4, 5]

const arr2 = Array.of(&#39;a&#39;, &#39;b&#39;, &#39;c&#39;);
console.log(arr2); // [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]</code></pre>
<p>Array.of() 메소드는 전달된 인자를 요소로 가지는 배열을 항상 생성한다. 이는 Array 생성자를 사용하여 배열을 생성할 때 발생할 수 있는 혼란을 방지한다.</p>
<pre><code class="language-JavaScript">const singleNumberArray = new Array(3);
console.log(singleNumberArray); // [undefined, undefined, undefined]</code></pre>
<p>위의 코드에서 new Array(3)은 길이가 3이고 요소가 &#39;undefined&#39;로 채워진 배열을 생성한다. 반면에 Array.of(3)은 값이 3인 배열을 생성한다. 즉, Array.of()는 명시적으로 원하는 값을 요소로 가지는 배열을 생성할 때 유용하게 사용된다.</p>
<p><Strong>push()</Strong></p>
<blockquote>
<p>배열의 끝에 하나 이상의 요소를 추가하고, 배열의 길이를 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const fruits = [&#39;apple&#39;, &#39;orange&#39;];
const newLength = fruits.push(&#39;banana&#39;, &#39;kiwi&#39;);

console.log(fruits); // [&#39;apple&#39;, &#39;orange&#39;, &#39;banana&#39;, &#39;kiwi&#39;]
console.log(newLength); // 4 (배열의 새로운 길이)</code></pre>
<p><Strong>pop()</Strong></p>
<blockquote>
<p>배열 마지막의 요소를 제거하고, 제거된 요소를 반환한다. 또한 배열이 비어있을 경우 undefined를 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const fruits = [&#39;apple&#39;, &#39;orange&#39;, &#39;banana&#39;, &#39;kiwi&#39;];
const removedElement = fruits.pop();

console.log(fruits); // [&#39;apple&#39;, &#39;orange&#39;, &#39;banana&#39;]
console.log(removedElement); // &#39;kiwi&#39;</code></pre>
<p>push() 메소드는 배열의 끝에 요소를 추가하고, pop 메소드는 배열의 긑에서 요소를 제거한다. 이러한 메소드들은 배열을 Stack 자료루조 사용할 때 유용하게 사용될 수 있다.</p>
<p><Strong>shift()</Strong></p>
<blockquote>
<p>배열의 첫번째 요소를 제거하고, 반환한다. 이후 배열의 모든 다른 요소들은 한 자리씩 앞으로 이동하며, 배열의 길이가 1감소한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const fruits = [&#39;apple&#39;, &#39;orange&#39;, &#39;banana&#39;];
const shiftedElement = fruits.shift();

console.log(fruits); // [&#39;orange&#39;, &#39;banana&#39;]
console.log(shiftedElement); // &#39;apple&#39;</code></pre>
<p><Strong>unshift()</Strong></p>
<blockquote>
<p>배열의 시작 부분에 하나 이상의 요소를 추가한다. 배열의 모든 다른 요소들은 한 자리씩 뒤로 이동하며, 배열의 길이가 증가한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const fruits = [&#39;orange&#39;, &#39;banana&#39;];
const newLength = fruits.unshift(&#39;apple&#39;, &#39;kiwi&#39;);

console.log(fruits); // [&#39;apple&#39;, &#39;kiwi&#39;, &#39;orange&#39;, &#39;banana&#39;]
console.log(newLength); // 4 (배열의 새로운 길이)</code></pre>
<p>shift() 메소드는 배열의 시작에서 요소를 제거하고, unshift() 메소드는 배열의 시작에 요소를 추가한다.</p>
<p><Strong>reverse()</Strong></p>
<blockquote>
<p>배열의 요소 순서를 거꾸로 뒤집는데 사용한다. 원래의 배열의 변경하며, 뒤집힌 배열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const numbers = [1, 2, 3, 4, 5];
numbers.reverse();

console.log(numbers); // [5, 4, 3, 2, 1]</code></pre>
<p>reverse() 메소드는 원본 배열을 변경하여 뒤집힌 배열을 반환하므로, 원본 배열을 변경하지 않고 새로운 배열을 얻고 싶다면, slice() 메소드나, 전개 연산자를 사용하여 원본 배열의 복사본을 만든 후 reverse() 메소드를 호출해야한다.</p>
<pre><code class="language-JavaScript">const numbers = [1, 2, 3, 4, 5];
const copiedArray = numbers.slice().reverse();

console.log(copiedArray); // [5, 4, 3, 2, 1]
console.log(numbers); // [1, 2, 3, 4, 5] (원본 배열은 변경되지 않음)</code></pre>
<pre><code class="language-JavaScript">const numbers = [1, 2, 3, 4, 5];
const copiedArray = [...numbers].reverse();

console.log(copiedArray); // [5, 4, 3, 2, 1]
console.log(numbers); // [1, 2, 3, 4, 5] (원본 배열은 변경되지 않음)</code></pre>
<p><Strong>sort()</Strong></p>
<blockquote>
<p>배열의 요소를 문자열로 변환한 후 유니코드 순서에 따라 정렬한다. 기본적으로 문자열로 변환된 요소들의 유니코드 순서에 따라 정렬되기 때문에 숫자 정렬 시 주의가 필요하다.</p>
</blockquote>
<pre><code class="language-JavaScript">const fruits = [&#39;apple&#39;, &#39;orange&#39;, &#39;banana&#39;, &#39;kiwi&#39;];
fruits.sort();

console.log(fruits); // [&#39;apple&#39;, &#39;banana&#39;, &#39;kiwi&#39;, &#39;orange&#39;]</code></pre>
<p>숫자를 정렬할 때는 비교함수를 사용하여 정렬 순서를 결정해야한다.</p>
<pre><code class="language-JavaScript">//오름차순으로 정렬 시
const numbers = [10, 2, 5, 1, 9];
numbers.sort((a, b) =&gt; a - b);

console.log(numbers); // [1, 2, 5, 9, 10]</code></pre>
<p><Strong>slice()</Strong></p>
<blockquote>
<p>배열의 특정부분응ㄹ 추출하여 새로운 배열로 반환한다. start 인덱스부터 end 인덱스 전까지의 요소를 포함하는 새로운 배열을 반환한다. 원본 배열을 변경하지 않는다.</p>
</blockquote>
<pre><code class="language-JavaScript">const numbers = [1, 2, 3, 4, 5];
const slicedArray = numbers.slice(1, 4);

console.log(slicedArray); // [2, 3, 4]
console.log(numbers); // [1, 2, 3, 4, 5] (원본 배열은 변경되지 않음)</code></pre>
<p><Strong>splice()</Strong></p>
<blockquote>
<p>벼앨에서 요소를 제거하거나 새로운 요소를 추하갈 수 있다. splice(start, deleteCount, item1, item2...)로 사용하며, start 인덱스로부터 deleteCount 개수만큼의 요소를 제거하고, 필요한 경우 새로운 요소를 추가할 수 있다. 이는 원본 배열을 변경한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const numbers = [1, 2, 3, 4, 5];
const removedElements = numbers.splice(1, 2, 6, 7);

console.log(numbers); // [1, 6, 7, 4, 5] (원본 배열이 변경됨)
console.log(removedElements); // [2, 3] (제거된 요소들)</code></pre>
<p>위의 코드에서 splice(1,2,6,7)은 인덱스 1부터 시작하여 2개의 요소를 제거하고, 그 자리에 6,7를 추가한다. splice()는 제거된 요소들을 포함하는 배열을 반환한다.</p>
<p>slice()와 splice()의 가장 중요한 차이점은 slice()는 원본 배열을 변경하지 않고 새로운 배열을 반환하며, splice()는 원본 배열을 변경하고 제거된 요소들을 반환한다.</p>
<p><Strong>fill()</Strong></p>
<blockquote>
<p>배열의 모든 요소를 특정 값으로 채워주는 메소드이다. 원본 배열을 변경하며, 배열된 배열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">// 예제 배열 생성
const numbers = [1, 2, 3, 4, 5];

// 모든 요소를 0으로 채우기
numbers.fill(0);
console.log(numbers); // 출력: [0, 0, 0, 0, 0]

// 인덱스 1부터 3 전까지의 요소를 9로 채우기
numbers.fill(9, 1, 3);
console.log(numbers); // 출력: [0, 9, 9, 0, 0]</code></pre>
<p><Strong>join()</Strong></p>
<blockquote>
<p>배열의 모든 요소를 하나의 문자열로 합쳐 반환한다 요소들은 구분자(sepearator)로 분리된다. 구분자를 지정하지 않으면 기본적으로 쉼표(,)가 사용된다.</p>
</blockquote>
<pre><code class="language-JavaScript">const fruits = [&#39;사과&#39;, &#39;바나나&#39;, &#39;오렌지&#39;];
const joinedString = fruits.join(&#39;, &#39;); // 쉼표와 공백을 구분자로 사용하여 문자열 생성
console.log(joinedString); // 출력: &#39;사과, 바나나, 오렌지&#39;</code></pre>
<p><Strong>toString()</Strong></p>
<blockquote>
<p>배열의 모든 요소를 하나의 문자열로 합쳐 반환한다. join() 메소드와 달리 구분자를 지정할수 없으며, 기본적으로 쉼표(,)로 요소들을 구분한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const fruits = [&#39;사과&#39;, &#39;바나나&#39;, &#39;오렌지&#39;];
const stringRepresentation = fruits.toString();
console.log(stringRepresentation); // 출력: &#39;사과,바나나,오렌지&#39;</code></pre>
<p><Strong>concat()</Strong></p>
<blockquote>
<p>배열에 다른 배열이나 값들을 추가하여 새로운 배열을 생성한다. 원본 배열은 변경되지 않는다.</p>
</blockquote>
<pre><code class="language-JavaScript">const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const newArray = array1.concat(array2, 7, 8);

console.log(newArray); // 출력: [1, 2, 3, 4, 5, 6, 7, 8]
console.log(array1); // 출력: [1, 2, 3] (원본 배열은 변경되지 않음)
console.log(array2); // 출력: [4, 5, 6] (원본 배열은 변경되지 않음)</code></pre>
<p><Strong>indexOf()</Strong></p>
<blockquote>
<p>배열에서 지정한 요소를 찾아 첫번째로 나타난 위치의 인덱스를 반환한다. 요소를 찾지 못할 경우 -1을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScipt">const array = [1, 2, 3, 4, 3];
const indexOfThree = array.indexOf(3);
console.log(indexOfThree); // 출력: 2</code></pre>
<p><Strong>lastIndexOf()</Strong></p>
<blockquote>
<p>배열에서 지정한 요소를 찾아, 마지막으로 나타나는 위치의 인덱스를 반환한다. 요소를 찾지 못할 경우 -1을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const array = [1, 2, 3, 4, 3];
const lastIndexOfThree = array.lastIndexOf(3);
console.log(lastIndexOfThree); // 출력: 4</code></pre>
<p><Strong>forEach()</Strong></p>
<blockquote>
<p>배열의 각 요소에 대해 함수를 실행하는 메소드이다. 배열의 각 요소에 대해 반복문을 수행하면서, 요소를 한 번씩 처리할 때 유용하다.</p>
</blockquote>
<pre><code class="language-JavaScript">array.forEach(callback(currentValue, index, array))</code></pre>
<ul>
  <li>callback : 각 요소에 대해 실행할 함수</li>
  <li>currentValue : 현재 처리 중인 요소의 값</li>
  <li>index : 현재 처리 중인 요소의 인덱스</li>
  <li>array : forEach()를 호출한 배열 자체</li>
</ul>

<pre><code class="language-JavaScript">const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = [];

numbers.forEach(function (element) {
  squaredNumbers.push(element * element);
});

console.log(squaredNumbers); // 출력: [1, 4, 9, 16, 25]

const ages = [25, 30, 18, 15, 22];
let foundAge = null;

ages.forEach(function (age) {
  if (age &gt;= 18) {
    foundAge = age;
    return; // 특정 조건을 만족하는 요소를 찾았으면 더 이상 반복을 수행하지 않음
  }
});

console.log(foundAge); // 출력: 25</code></pre>
<p><Strong>map()</Strong></p>
<blockquote>
<p>배열의 모든 요소에 대해 주어진 함수를 호출하고, 그 결과를 모아서 새로운 배열을 반환하는 메소드이다. 원본 배열을 변경하지 않으며, 각 요소에 대해 주어진 함수를 적용한 결과를 새로운 배열에 담아서 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const newArray = array.map(callback(currentValue, index, array))</code></pre>
<ul>
  <li>callback : 각 요소에 대해 실행할 함수</li>
  <li>currentValue : 현재 처리 중인 요소의 값</li>
  <li>index : 현재 처리중인 요소의 인덱스</li>
  <li>array : map()을 호출한 배열 그 자체</li>
</ul>

<pre><code class="language-JavaScript">const numbers = [1, 2, 3, 4, 5];
const squaredNumbers = numbers.map(function (element) {
  return element * element;
});
console.log(squaredNumbers); // 출력: [1, 4, 9, 16, 25]

const numbers = [1, 2, 3, 4, 5];
const stringNumbers = numbers.map(function (element) {
  return element.toString();
});
console.log(stringNumbers); // 출력: [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;, &#39;4&#39;, &#39;5&#39;]</code></pre>
<p><Strong>filter()</Strong></p>
<blockquote>
<p>배열의 요소 중에서 주어진 함수의 조건을 마족하는 요소들로 이루어진 새로운 배열을 반환</p>
</blockquote>
<pre><code class="language-JavaScript">const newArray = array.filter(callback(element, index, array))</code></pre>
<ul>
  <li>callback : 각 요소에 대해 실행할 함수, 조건을 만족하는 경우 true, 그렇지 않을경우 false를 반환</li>
  <li>element : 현재 처리 중인 요소의 값</li>
  <li>index : 현재 처리 중인 요소의 인덱스</li>
  <li>array : filter를 호출한 배열 자체</li>
</ul>

<pre><code class="language-JavaScript">const numbers = [1, 2, 3, 4, 5, 6];
const evenNumbers = numbers.filter(function (element) {
  return element % 2 === 0;
});
console.log(evenNumbers); // 출력: [2, 4, 6]</code></pre>
<p><Strong>reduce()</Strong></p>
<blockquote>
<p>배열의 모든 요소에 대해 주어진 함수를 실행하고, 이전 결과와 현재 요소를 이용하여 하나의 값으로 축약</p>
</blockquote>
<pre><code class="language-JavaScript">const result = array.reduce(callback(accumulator, currentValue, index, array), initialValue);</code></pre>
<ul>
  <li>callback : 각 요소에 대해 실행할 함수. 누산기와 현재 요소를 이용하여 계산을 수행</li>
  <li>accumulator : 누산기로서 각 단계ㅔ서 콜백 함수의 반환값을 누적</li>
  <li>currentValue : 현재 처리 중인 요소의 값</li>
  <li>index : 현재 처리 중인 요소의 인덱스</li>
  <li>array : reduce()를 호출한 배열 자체</li>
  <li>initialValue : 누산기의 초기값으로 선택적으로 전달할 수 있음</li>
</ul>

<pre><code class="language-JavaScript">const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce(function (accumulator, currentValue) {
  return accumulator + currentValue;
}, 0);
console.log(sum); // 출력: 15</code></pre>
<p><Strong>entries()</Strong></p>
<blockquote>
<p>Map 객체의 각 키-값 쌍을 나타내는 배열을 반환. 각 배열 요소는 [key, value] 형태인 배열이다.</p>
</blockquote>
<pre><code class="language-JavaScript">const map = new Map([
  [&#39;a&#39;, 1],
  [&#39;b&#39;, 2],
  [&#39;c&#39;, 3]
]);

const entries = map.entries();
console.log([...entries]); // 출력: [[&#39;a&#39;, 1], [&#39;b&#39;, 2], [&#39;c&#39;, 3]]</code></pre>
<p><Strong>keys()</Strong></p>
<blockquote>
<p>Map 객체의 모든 키를 나타내는 배열을 반환</p>
</blockquote>
<pre><code class="language-JavaScript">const map = new Map([
  [&#39;a&#39;, 1],
  [&#39;b&#39;, 2],
  [&#39;c&#39;, 3]
]);

const keys = map.keys();
console.log([...keys]); // 출력: [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;]</code></pre>
<p><Strong>values()</Strong></p>
<blockquote>
<p>Map 객체의 모든 값을 나타내는 배열을 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const map = new Map([
  [&#39;a&#39;, 1],
  [&#39;b&#39;, 2],
  [&#39;c&#39;, 3]
]);

const values = map.values();
console.log([...values]); // 출력: [1, 2, 3]</code></pre>
<p><Strong>find()</Strong></p>
<blockquote>
<p>배열에서 주어진 콜백함수의 조건을 만족하는 &#39;첫 번째&#39; 요소를 반환한다. 조건을 만족하는 요소가 없을 경우 undefined를 반환한다.</p>
</blockquote>
<pre><code class="language-JavaScript">const foundElement = array.find(callback(element, index, array))</code></pre>
<ul>
  <li>callback : 각 요소에 대해 실행할 함수로 조건을 만족하는 경우 true, 만족하지 않을 경우 false를 반환</li>
  <li>element : 현재 처리 중인 요소의 값</li>
  <li>index : 현재 처리 중인 요소의 인덱스</li>
  <li>array : find()를 호출한 배열 자체</li>
</ul>

<pre><code class="language-JavaScript">const numbers = [1, 5, 8, 10, 12];
const foundNumber = numbers.find(function (element) {
  return element &gt; 7;
});

console.log(foundNumber); // 출력: 8</code></pre>
<h5>요약</h5>
<table>
  <tr style="border : 1px solid black;">
    <th>메소드</th>
    <th>설명</th>
  </tr>
  <tr style="border : 1px solid black;">
    <td>Array.isArray()</td>
    <td>전달된 값이 배열인지 아닌지를 확인하고, boolean으로 결과를 반환한다.</<td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>Array.from()</td>
    <td>배열과 비슷한 객체와 반복할 수 있는 객체를 배열처럼 반환한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>Array.of()</td>
    <td>인수의 수나 타입에 상관없이, 인수로 전달받은 값을 요소로 가지는 배열을 항상 생성한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>push()</td>
    <td>하나 이상의 요소를 배열의 가장 마지막에 추가한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>pop()</td>
    <td>배열의 가장 마지막 요소를 제거한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>shift()</td>
    <td>배열의 가장 첫 요소를 제거한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>unshift()</td>
    <td>하나 이상의 요소를 배열의 가장 앞에 추가한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>reverse()</td>
    <td>배열 요소의 순서를 뒤집는다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>sort()</td>
    <td>배열의 요소를 유니코드 값에 따라 정렬한다.</td>
  </tr>
    <tr style="border : 1px solid black;">
    <td>slice()</td>
    <td>시작 인덱스부터 종료 인덱스 바로 앞까지의 배열 요소로 새로운 배열을 반환한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>splice()</td>
    <td>기존의 배열 요소를 제거하거나, 새로운 배열 요소를 추가하여 배열의 내용을 변경한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>fill()</td>
    <td>시작인덱스부터 종료 인덱스 바로 앞까지의 모든 배열 요소를 특정 값으로 교체한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>join()</td>
    <td>배열의 모든 요소를 하나의 문자열로 반환한다.</td>
  </tr>
    <tr style="border : 1px solid black;">
    <td>toString()</td>
    <td>해당 배열의 모든 요소를 하나의 문자열로 반환한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>concat()</td>
    <td>해당 배열의 뒤로, 전달받은 배열을 합쳐 새로운 배열을 반환한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td >indexOf()</td>
    <td>전달받은 값과 동일한 배열 요소가 '처음으로' 등장하는 위치의 인덱스를 반환한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>lastIndexOf()</td>
    <td>전달 받은 값과 동일한 배열 요소가 '마지막으로' 등장하는 위치의 인덱스를 반환한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>forEach()</td>
    <td>해당 배열의 모든 요소에 대해 명시된 콜백함수를 실행한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>map()</td>
    <td>해당 배열의 모든 요소에 대해 명시된 콜백함수를 실행하고, 그 실행 결과를 새로운 배열로 반환한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>filter()</td>
    <td>해당 배열의 모든 요소에 대해 명시된 콜백함수를 실행하고, 그 결괏값이 True인 요소들만을 새로운 배열로 반환한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>reduce()</td>
    <td>해당 배열의 모든 요소의 값을 하나로 줄이기 위해, 두 개의 인수를 전달받는 콜백 함수를 실행한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>entries()</td>
    <td>배열 요소별로 키와 값의 한 쌍으로 이루어진 새로운 배열 반복자 객체를 배열 형태로 반환한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>keys()</td>
    <td>배열 요소로 키만 포함하는 새로운 배열 반복자 객체를 배열 형태로 반환한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>values()</td>
    <td>배열 요소별로 값만 포함하는 새로운 배열 반복자 객체를 배열 형태로 반환한다.</td>
  </tr>
  <tr style="border : 1px solid black;">
    <td>find()</td>
    <td>전달받은 함수를 만족하는 배열의 요소 값을 반환하고, 없을 경우 undefined를 반환한다.</td>
  </tr>
</table>


]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] BigInteger]]></title>
            <link>https://velog.io/@hanl__l/JAVA-BigInteger</link>
            <guid>https://velog.io/@hanl__l/JAVA-BigInteger</guid>
            <pubDate>Mon, 06 Nov 2023 12:03:18 GMT</pubDate>
            <description><![CDATA[<p>Java에서 int의 메모리 크기는 4byte로 표현할 수 있는 범위는 -2,147,483,648 ~ 2,147,483,647이다. long의 메모리 크기는 8byte로 표현할 수 있는 범위는 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807이다.
이 때 이 범위를 넘어서게 되면 모두 0으로 출력이 된다. 숫자의 범위가 저 범위를 넘는 경우는 거의 없겠지만, 돈과 관련된 개발, 혹은 알고리즘 문제를 풀 때 항상 최악의 상황을 고려해야하므로 무한의 정수가 들어갈 가능성이 있는 경우 BigInteger 클래스를 활용하는 것이 좋다. BigInteger는 문자열 형태로 이루어져 있어, 숫자의 범위가 무한하기 때문에 어떠한 정수인지 담을 수 있다.</p>
<h3>BigInteger 선언</h3>
BigInteger는 java.math 안에 있고, 아래와 같이 선언될 수 있다.

<pre><code class="language-java">//문자열로부터 BigInteger 생성
BigInteger num1 = new BigInteger(&quot;12345678901234567890&quot;);
// long 값으로부터 BigInteger 생성
BigInteger num2 = BigInteger.valueOf(1234567890); </code></pre>
<p>BigInteger를 초기화 하기 위해서는 문자열을 인자값으로 넘겨줘야한다. BigInteger는 문자열로 되어있기 때문이다.</p>
<h3>사칙연산과 나머지 연산</h3>
BigInteger는 문자열이지만, 숫자를 계산하기 위해 BigInteger 클래스 내 메서드를 이용해 사칙연산과 나머지 연산을 할 수 있다.

<pre><code class="language-java">BigInteger sum = num1.add(num2); // 덧셈
BigInteger difference = num1.subtract(num2); // 뺄셈
BigInteger product = num1.multiply(num2); // 곱셈
BigInteger quotient = num1.divide(num2); // 나눗셈
BigInteger remainder = num1.remainder(num2); // 나머지</code></pre>
<h3>형 변환</h3>
BigInteger 클래스에서 기본 데이터 타입인, int, long, float, double 등과 같은 자동 형변환은 제공되지 않는다. 따라서 BigInteger 객체를 기본 데이터 타입으로 바로 변환하는 것은 불가능하다. 대신,  intValue(), longValue() 메서드를 사용하여 변환하여 반환할 수 있다.

<pre><code class="language-java">BigInteger bigInt = new BigInteger(&quot;12345678901234567890&quot;);

int intValue = bigInt.intValue(); // BigInteger를 int로 변환
long longValue = bigInt.longValue(); // BigInteger를 long으로 변환</code></pre>
<p>주의할 점은, BigInteger의 크기가 기본 데이터 타입의 허용 범위를 벗어나게 되면 데이터 손실이 발생할 가능성이 있다. 따라서 안전하게 형변환을 하기 위해서는 BigInteger 객체의 크기가 기본 데이터 타입의 허용 범위에 있는지 확인하는 것이 중요하다.</p>
<h3>비교</h3>
BigInteger 객체간의 크기를 비교할 수 있다.

<pre><code class="language-java">int result = num1.compareTo(num2);</code></pre>
<p>위의 예시에서 result가 음수이면, num1이 num2보다 작고, 양수이면 num1이 num2보다 크다. 0일 때는 두 수가 같은 것을 의미한다.</p>
<h3>기타 메서드</h3>
pow() 매서드의 경우 BigInteger의 거듭제곱을 반환한다.

<pre><code class="language-java">BigInteger result = num1.pow(2); // num1을 제곱한 결과</code></pre>
<p>BigInteger 클래스는 정수 계산에서 발생할 수 있는 오버플로우나 정밀도 손실을 피할 수 있도록 하므로, 매우 큰 정수나 정밀한 연산이 필요한 상황에서 사용할 수 있다.</p>
]]></description>
        </item>
    </channel>
</rss>