<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hyobi-lim.log</title>
        <link>https://velog.io/</link>
        <description>Front-end Developer 💻🔜</description>
        <lastBuildDate>Thu, 15 May 2025 10:27:46 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>hyobi-lim.log</title>
            <url>https://velog.velcdn.com/images/hyobi-lim/profile/7afba57a-46cf-4572-bc39-8c0464deaf1f/image.JPG</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. hyobi-lim.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hyobi-lim" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[CS] API]]></title>
            <link>https://velog.io/@hyobi-lim/CS-API</link>
            <guid>https://velog.io/@hyobi-lim/CS-API</guid>
            <pubDate>Thu, 15 May 2025 10:27:46 GMT</pubDate>
            <description><![CDATA[<p>API: 둘 이상의 컴퓨터 프로그램이 서로 어떻게 통신할 것인지, 어떠한 데이터를 주고 받을 건지 등에 대한 통신하는 방법이자 컴퓨터 사이에 있는 중계 계층</p>
<p>인터페이스: 서로 다른 두 개의 시스템, 장치 사이에서 정보나 신호를 주고받는 경계면
컴퓨터의 내부서버가 어떻게 구현되어있는지는 상관없이 인터페이스를 통해 통신 가능
ex) 스마트폰</p>
<p>API의 작동방식: 사용자가 브라우저를 통해서 서버에 요청을 하게 되면 API가 중계계층역할을 하며 요청을 처리
직접 서버의 데이터베이스에 접근하는 것을 방지</p>
<p>API의 장점</p>
<ol>
<li>제공자는 서비스의 중요한 부분을 드러내지 않아도 됨</li>
<li>사용자는 해당 서비스가 어떻게 구현되는지 알 필요없이 필요한 정보만을 받을 수 있음</li>
<li>OPEN API의 경우 개발 프로세스를 단순화 시키고 시간과 비용을 절약</li>
<li>내부 프로세스가 수정되었을 때 API를 매번 수정하는 것이 아닌 API가 수정이 안되게 만들 수 있음-&gt;내부 DB, 서버의 로직이 변경이 되어도 매번 사용자가 업데이트하는 일이 줄어듦</li>
<li>이벤트 발생 시, API를 호출하게 만들면 해당 데이터를 한 곳에 모을 수 있음</li>
</ol>
<p>API의 종류</p>
<ol>
<li>private: 내부적으로 사용, 해시키를 하드코딩해놓고 이를 기반으로 서버와 서버간의 통신</li>
<li>public: 모든 사람이 사용 가능, 많은 트래픽을 방지하기 위해 하루 요청수의 제한, 계정당 몇개 등으로 관리</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[CS] JSON과 직렬화와 역직렬화, XML]]></title>
            <link>https://velog.io/@hyobi-lim/CS-JSON%EA%B3%BC-%EC%A7%81%EB%A0%AC%ED%99%94%EC%99%80-%EC%97%AD%EC%A7%81%EB%A0%AC%ED%99%94-XML</link>
            <guid>https://velog.io/@hyobi-lim/CS-JSON%EA%B3%BC-%EC%A7%81%EB%A0%AC%ED%99%94%EC%99%80-%EC%97%AD%EC%A7%81%EB%A0%AC%ED%99%94-XML</guid>
            <pubDate>Tue, 13 May 2025 07:00:25 GMT</pubDate>
            <description><![CDATA[<p>JSON: Javascript 객체 문법으로 구조화된 데이터 교환형식</p>
<p>Javascript 객체문법: 키(key)과 값(value)으로 구성
ex) {key : value}
value 접근법: .key 또는 [“key”]</p>
<p>JSON의 타입: 수(Number), 문자열(String), 참/거짓(Boolean), 배열(Array), 객체(Object), null
<strong>※ undefined, 메서드 포함 X</strong></p>
<p>JSON 직렬화: 외부의 시스템에서도 사용할 수 있도록 문자열 형태로 데이터를 변환
ex) JSON.stringify()
JSON 역직렬화: 직렬화 반대
ex) JSON.parse()</p>
<p>JSON의 활용: 프로그래밍 언어와 프레임워크 등에 독립적이므로, 서로 다른 시스템간에 데이터를
교환하기에 좋음
주로 API의 반환형태, 시스템을 구성하는 설정파일에 활용
ex) API, package.json</p>
<hr>
<p>XML: 마크업 형태를 쓰는 데이터 교환형식
ex) sitemap.xml: 서비스 내의 모든 페이지들을 리스트업한 데이터, 사이트가 매우 크거나 서로 링크가 종속적으로 연결되지 않은 경우 크롤러가 일부 페이지를 누락하는 일이 있는데 이를 sitemap.xml이 방지하고 모든 페이지들을 크롤링할 수 있도록 도움</p>
<p>마크업 형태: 태그 등을 이용하여 문서나 데이터의 구조를 나타내는 방법</p>
<p>XML 구성</p>
<ol>
<li>프롤로그 : 버전, 인코딩</li>
<li>루트요소(단 하나만)</li>
<li>하위 요소들</li>
</ol>
<p>HTML VS XML</p>
<table>
<thead>
<tr>
<th align="center"></th>
<th align="center">HTML</th>
<th align="center">XML</th>
</tr>
</thead>
<tbody><tr>
<td align="center">용도</td>
<td align="center">데이터 표시</td>
<td align="center">데이터 저장 및 전송</td>
</tr>
<tr>
<td align="center">태그</td>
<td align="center">미리 정의된 태그</td>
<td align="center">태그 정의 가능</td>
</tr>
<tr>
<td align="center">대소문자 구분</td>
<td align="center">X</td>
<td align="center">O</td>
</tr>
</tbody></table>
<p>JSON VS XML
XML은 닫힌 태그가 계속 들어가기 때문에 JSON보다 무거움
변환을 위해 더 많은 노력 필요 ex) JSON은 JSON.parse()면 변환 가능</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[MEVN] 1장 (단축키, git 명령어)]]></title>
            <link>https://velog.io/@hyobi-lim/MEVN-1%EC%9E%A5-%EB%8B%A8%EC%B6%95%ED%82%A4</link>
            <guid>https://velog.io/@hyobi-lim/MEVN-1%EC%9E%A5-%EB%8B%A8%EC%B6%95%ED%82%A4</guid>
            <pubDate>Thu, 13 Mar 2025 14:29:08 GMT</pubDate>
            <description><![CDATA[<p>&lt;VSCode 단축키&gt;
-Command+Option+S: 모두 저장
-Command+D: 반복되는 코드를 한 번에 수정
-command+/: 드래그한 텍스트 주석으로 변환 또는 해제
-shift+tab: 들여쓰기 취소</p>
<p>-Command+Option+I: 개발자 도구
-Control+Option+N: 비주얼 스튜디오에서 파일 실행</p>
<p>-Control+`: 비주얼 스튜디오에서 터미널 열기</p>
<p>&lt;git으로 repository 가져오기&gt;
-해당 git에서 Code 클릭 후 주소 복사
-비주얼 스튜디오 터미널에서 &quot;git clone [복사한 주소]&quot;
-폴더명을 다르게 구축하는 경우 &quot;git clone [레파지토리] [폴더명]&quot;</p>
<p>&lt;자주 사용하는 git 명령어&gt;
-git add: 수정/추가/삭제한 파일들을 스테이지에 올림
&quot;git add .&quot;(공백 주의)로 실행시, 현재 경로 하위 폴더 안의 모든 파일이 추가됨</p>
<p>-git commit: git add를 통해 스테이지에 올려진 기록을 git 폴더에 알려줌</p>
<p>※git add-&gt;작업 폴더가 staging area에 올라감-&gt;git commit-&gt;작업 폴더가 repository(저장소)에 올라감</p>
<p>-git push origin master: origin(git으로 호스팅하는 일종의 공유 사본)의 master 브랜치에 푸시하는 것</p>
<p>-git branch [브랜치명]: [브랜치명] 브랜치 생성</p>
<p>-git switch [브랜치명]: [브랜치명] 브랜치로 이동</p>
<p>-git checkout -b [브랜치명]: [브랜치명]을 만들고 그 브랜치로 이동
ex) git checkout -b feature/#123: 123이라는 브랜치를 만들고 123브랜치로 이동</p>
<p>-git checkout master: master 브랜치로 이동</p>
<p>-git pull origin [브랜치명]: origin의 [브랜치명] 브랜치를 끌고 오는 것
*pull은 git fetch(저장소의 내용을 가져오는 것)와 git merge(레파지토리와 로컬의 변경이력을 합치는 것)를 합친 것</p>
<p>-git status: git으로 관리하는 폴더의 상태를 알 수 있음, 커밋되지 않은 변경상태를 볼 수 있음</p>
<p>-git branch -d [브랜치명]: 해당 브랜치를 지움
만약 이 브랜치가 master 브랜치에 merged되지 않은 브랜치라면 삭제되지 않음
*merged 되지 않은 브랜치 강제 삭제: git branch -D [브랜치명]</p>
<p>-git checkout --[파일명]: 해당 파일을 이전 커밋 상태로 되돌림</p>
<p>-git log --all --oneline (--graph): git에 대한 로그(변경 사항)들을 볼 수 있음</p>
<p>-git diff: 수정한 부분이 무엇인지 알려줌(최근 commit vs 현재파일 차이점)
요즘은 git difftool 사용</p>
<p>-git merge [브랜치명]: [브랜치명]의 작업내용을 현재 브랜치에 합치기</p>
<p>-merge시 충돌 해결 방법: 충돌 발생 문구 후 나오는 화면에서 원하는 코드만 남기기-&gt;git add .-&gt;git commit</p>
<p>&lt;<strong>중요한 것</strong>&gt;
코드 수정 전에 해당 수정작업에 관한 브랜치를 만들고 그 브랜치에서 작업한 후 커밋 규칙에 따라 커밋을 하고 레파지토리의 특정 브랜치로 병합하는 과정을 통해 프로젝트를 완성해 나가는 것
브랜치 생성-&gt;해당 브랜치에서 코드 수정-&gt;커밋-&gt;병합</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이더넷 프레임과 구조, 네이글 알고리즘, HTTP의 멱등성]]></title>
            <link>https://velog.io/@hyobi-lim/%EC%9D%B4%EB%8D%94%EB%84%B7-%ED%94%84%EB%A0%88%EC%9E%84%EA%B3%BC-%EA%B5%AC%EC%A1%B0-%EB%84%A4%EC%9D%B4%EA%B8%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-HTTP%EC%9D%98-%EB%A9%B1%EB%93%B1%EC%84%B1</link>
            <guid>https://velog.io/@hyobi-lim/%EC%9D%B4%EB%8D%94%EB%84%B7-%ED%94%84%EB%A0%88%EC%9E%84%EA%B3%BC-%EA%B5%AC%EC%A1%B0-%EB%84%A4%EC%9D%B4%EA%B8%80-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-HTTP%EC%9D%98-%EB%A9%B1%EB%93%B1%EC%84%B1</guid>
            <pubDate>Wed, 05 Feb 2025 12:56:29 GMT</pubDate>
            <description><![CDATA[<p>이더넷프레임 - 데이터 링크계층의 데이터 단위, 이를 기반으로 데이터가 전달</p>
<p>이더넷프레임 필드 구성
● Preamble[7바이트] : 이더넷 프레임 시작
● SFD[1바이트] : 다음 필드부터 주소필드가 시작
● Destination Address[6바이트] : 목적지 주소
● Source Address[6바이트] : 시작지 주소
● EtherType[2바이트] : 데이터링크계층 위의 IP 프로토콜을 정의 (IPv4, Ipv6)
● Payload[가변바이트] : 가변길이 필드, 이진데이터로 구성, IEEE 표준은 최대 페이로드를 1500 바이트로 지정
● FCS[4바이트] : 수신측의 에러검출, CRC 에러검출 기법에 의해 생성된 비트배열이 담김, 비트배열을 기반으로 수신된 데이터가 손상되었는지를 확인하고 에러 확인시에는 해당 프레임을 폐기하고 송신측에 재전송을 요구</p>
<hr>
<p>네이글 알고리즘 - 네트워크의 효율성을 높이기 위해 네트워크를 통해 전송되어야 하는 패킷의 수를 줄이고 적은 양의 데이터를 자주 보내면 발생되는 대역폭 낭비를 막아주는 방법</p>
<p>네이글 알고리즘의 장점</p>
<ol>
<li>네트워크 혼잡 감소: 패킷 수가 많으면 네트워크 장비(라우터, 스위치 등)에 더 많은
처리 부담을 주고, 이는 네트워크 혼잡을 증가시킬 수 있음 -&gt; 패킷 수를 줄임으로써 네트워크의 전반적인 혼잡 상태를 개선하고, 패킷 손실률을 줄일 수 있음</li>
<li>오버헤드 감소: 네트워크 패킷은 데이터를 전송할 때 필요한 제어 정보인 헤더를 포함, 작은 패킷들이 많이 전송될 때, 각 패킷에 포함된 헤더의 총량이 상당해져 유용한 데이터 전송보다 많은 대역폭을 소모할 수 있음 -&gt; 패킷의 수를 줄이면 이러한 오버헤드를 감소시켜 더 많은 유용한 데이터를 같은 양의 대역폭으로 전송할 수 있음</li>
</ol>
<p>네이글 알고리즘의 단점 : 지연시간증가</p>
<ol>
<li>작은 패킷의 수를 줄이기 위해 데이터를 버퍼링하고, 충분한 양의 데이터가 모일때까지 패킷 전송을 지연</li>
<li>ACK를 받기전까지 데이터를 전송하지 않기 때문에 지연시간이 발생할 수 있음, 이로 인해 실시간으로 데이터를 전송해야 하는 애플리케이션(예: 온라인 게임)에서는 적합하지 않음</li>
</ol>
<hr>
<p>HTTP의 멱등성 - 하나의 요청이 아닌 여러번 동일한 요청을 보냈을 때 서버가 같은 상태를 가지는 것</p>
<p>HTTP 메서드 중 멱등성을 가지는 메서드: GET, HEAD, OPTIONS, PUT, DELETE
HTTP 메서드 중 멱등성을 가지지 않는 메서드: POST, PATCH</p>
<p>멱등성을 가지는 메서드</p>
<ol>
<li>GET: 서버에서 정보를 가져오는 데 사용, 여러 개의 동일한 GET 요청을 하는 것은 한 번의 요청을 하는 것과 같은 효과 (안전한 메서드)</li>
<li>HEAD : GET 요청이 생성하는 응답의 헤더를 검색하는 데 사용, 보통 리소스 전체를 다운로드하는 오버헤드를 피하고 어떤 유형의 데이터가 반환되는지, 해당 리소스가 있는지, 수정날짜 등을 확인하기 위해 사용, GET처럼 서버 상태를 변경하지 않음 (안전한 메서드)</li>
<li>OPTIONS : 대상 리소스의 통신 옵션(서버에서 지원하는 HTTP메서드 등)을 가져올 때 사용 (안전한 메서드)</li>
<li>PUT: 리소스를 완전히 다른 버전으로 대체, 요청이 반복되면 동일한 리소스가 다시 대체되어 첫 번째 요청 후와 동일한 상태가 됨</li>
<li>DELETE: 리소스를 삭제하는 데 사용, 리소스가 삭제되면 삭제 작업을 반복해도 시스템 상태가 더 이상 변경되지 않음</li>
</ol>
<p>멱등성을 가지지 않는 메서드</p>
<ol>
<li>POST : 일반적으로 새로운 리소스를 생성하는데 사용되며 여러 POST 요청은 여러 리소스를 생성하는 결과를 초래하기 때문에 멱등성을 가지지 않음</li>
<li>PATCH : 일반적으로 리소스를 부분적으로 업데이트하는 데 사용되며 멱등성 여부는 PATCH를 실행하는 방법에 따라 달라짐, 예를 들어 필드를 특정값으로 수정하는 것이라면 멱등성을 가지지만 특정 필드의 값을 증가시키거나 해당 배열에 요소를 추가시키는 것이라면 멱등성을 가지지 않음</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[데이터베이스와 NoSQL데이터베이스의 차이, MySQL의 innoDB, MyISAM 스토리지엔진의 차이, 자바스크립트 배열]]></title>
            <link>https://velog.io/@hyobi-lim/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%99%80-NoSQL%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4-MySQL%EC%9D%98-innoDB-MyISAM-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80%EC%97%94%EC%A7%84%EC%9D%98-%EC%B0%A8%EC%9D%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B0%B0%EC%97%B4</link>
            <guid>https://velog.io/@hyobi-lim/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%99%80-NoSQL%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4-MySQL%EC%9D%98-innoDB-MyISAM-%EC%8A%A4%ED%86%A0%EB%A6%AC%EC%A7%80%EC%97%94%EC%A7%84%EC%9D%98-%EC%B0%A8%EC%9D%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B0%B0%EC%97%B4</guid>
            <pubDate>Mon, 03 Feb 2025 12:50:06 GMT</pubDate>
            <description><![CDATA[<p>관계형데이터베이스(RDBMS)와 NoSQL데이터베이스의 차이
스키마: 엄격하고 정의되어야 함 / 유연하고 동적으로 변경 가능
쿼리 언어: SQL / JSON, API, Cypher(Neo4j) 등 다양
트랜잭션: 지원 / 지원
격리성(기본): repeatable_read(mysql) / local(독자적인 격리성 레벨을 가짐):= read_uncommited(유사) (mongodb)
스케일링: 수직 스케일링이 더 쉬움 - 서버 성능향상 (128G-&gt;256G) / 수평 스케일링이 더 쉬움 - 서버대수증가 (128G를 여러대)
종류: MySQL, Oracle, PostgreSQL / MongoDB, Redis, ElasticSearch, Neo4j</p>
<hr>
<p>데이터베이스의 스토리지 엔진 - 데이터베이스 시스템에서 데이터의 저장, 검색, 트랜잭션 관리, 동시성 제어, 캐싱 등 핵심을 담당하는 필수 구성 요소
Innodb은 MySQL 8.0의 기본 스토리지 엔진이며 MyISAM이란 스토리지엔진으로도 변경이 가능</p>
<p>MySQL의 innoDB, MyISAM 스토리지엔진의 차이
트랜잭션: 지원 / 미지원
락 및 동시성: 행 레벨 락 / 테이블 레벨 락
외래 키 제약: 지원 / 미지원
=&gt;딱 봐도 innoDB 더 좋아보임 -&gt; Innodb가 MySQL 8.0의 기본 스토리지 엔진</p>
<p>어떤 엔진을 사용하는지 확인하는 쿼리
-&gt;SHOW TABLE STATUS LIKE &#39;example_myisam&#39;;</p>
<hr>
<p>밀집 배열 - 일반적인 배열로 동일한 크기의 메모리 공간이 연속적으로 나열된 자료구조</p>
<p>자바스크립트의 배열은 지금까지 살펴본 일반적인 의미의 배열과 다름
희소 배열 - 배열의 요소를 위한 각각의 메모리 공간은 동일한 크기를 갖지 않아도 되며 연속적으로 이어져 있지 않을 수도 있음</p>
<pre><code>const arr = [&#39;string&#39;, 10, true, null, function () {}];</code></pre><p>자바스크립트의 배열은 엄밀히 말해 일반적 의미의 배열이 아님
자바스크립트의 배열은 일반적인 배열의 동작을 흉내낸 특수한 객체
자바스크립트 배열은 인덱스를 프로퍼티 키로 갖으며 배열의 요소는 프로퍼티 값
자바스크립트에서 사용할 수 있는 모든 값은 객체의 프로퍼티 값이 될 수 있으므로 어떤 타입의 값이라도 배열의 요소가 될 수 있음</p>
<p>일반적인 배열과 자바스크립트 배열의 장단점</p>
<p>일반적인 배열은 인덱스로 배열 요소에 빠르게 접근 가능 but 특정 요소를 탐색하거나 요소를 삽입 또는 삭제하는 경우에는 비효율적
자바스크립트 배열은 해시 테이블로 구현된 객체이므로 인덱스로 배열 요소에 접근하는 경우, 일반적인 배열보다 성능적인 면에서 느릴 수 밖에 없는 구조적인 단점 but 특정 요소를 탐색하거나 요소를 삽입 또는 삭제하는 경우에는 일반적인 배열보다 빠른 성능을 기대
=자바스크립트 배열은 인덱스로 배열 요소에 접근하는 경우에는 일반적인 배열보다 느리지만 특정 요소를 탐색하거나 요소를 삽입 또는 삭제하는 경우에는 일반적인 배열보다 빠름</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[데이터베이스] 보이스/코드 정규형, 관계형데이터베이스와 NoSQL데이터베이스의 차이, MySQL의 innoDB, MyISAM 스토리지엔진의 차이]]></title>
            <link>https://velog.io/@hyobi-lim/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%BD%94%EB%93%9C-%EC%A0%95%EA%B7%9C%ED%98%95-%EA%B4%80%EA%B3%84%ED%98%95%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%99%80-NoSQL%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4</link>
            <guid>https://velog.io/@hyobi-lim/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EB%B3%B4%EC%9D%B4%EC%8A%A4%EC%BD%94%EB%93%9C-%EC%A0%95%EA%B7%9C%ED%98%95-%EA%B4%80%EA%B3%84%ED%98%95%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%99%80-NoSQL%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4%EC%9D%98-%EC%B0%A8%EC%9D%B4</guid>
            <pubDate>Wed, 15 Jan 2025 01:14:33 GMT</pubDate>
            <description><![CDATA[<p>보이스/코드 정규형 - 제3정규형이고, 모든 결정자가 후보키인 상태
보통 하나의 릴레이션에 여러개의 후보키가 존재할 수 있는데 이 경우에 제 3정규형보다 엄격한 기준으로 제약을 건 것
후보키가 아니면 결정자 역할을 하면 X</p>
<p>관계형데이터베이스(RDBMS)와 NoSQL데이터베이스의 차이
스키마: 엄격하고 정의되어야 함 <strong>/</strong> 유연하고 동적으로 변경 가능
쿼리 언어: SQL <strong>/</strong> JSON, API, Cypher(Neo4j) 등 다양
트랜잭션: 지원 <strong>/</strong> 지원
격리성(기본): repeatable_read(mysql) <strong>/</strong> local(독자적인 격리성 레벨을 가짐):= read_uncommited(유사) (mongodb)
스케일링: 수직 스케일링이 더 쉬움 - 서버 성능향상 (128G-&gt;256G) <strong>/</strong> 수평 스케일링이 더 쉬움 - 서버대수증가 (128G를 여러대)
종류: MySQL, Oracle, PostgreSQL <strong>/</strong> MongoDB, Redis, ElasticSearch, Neo4j</p>
<p>데이터베이스의 스토리지 엔진 - 데이터베이스 시스템에서 데이터의 저장, 검색, 트랜잭션 관리, 동시성 제어, 캐싱 등 핵심을 담당하는 필수 구성 요소
Innodb은 MySQL 8.0의 기본 스토리지 엔진이며 MyISAM이란 스토리지엔진으로도 변경이 가능</p>
<p>MySQL의 innoDB, MyISAM 스토리지엔진의 차이
트랜잭션: 지원 <strong>/</strong> 미지원
락 및 동시성: 행 레벨 락 <strong>/</strong> 테이블 레벨 락
외래 키 제약: 지원 <strong>/</strong> 미지원
=&gt;딱 봐도 innoDB 더 좋아보이쥬? 그래서 Innodb가 MySQL 8.0의 기본 스토리지 엔진</p>
<p>어떤 엔진을 사용하는지 확인하는 쿼리
-&gt;SHOW TABLE STATUS LIKE &#39;example_myisam&#39;;</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 28 (자바스크립트 배열은 배열이 아니다)]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-28-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B0%B0%EC%97%B4%EC%9D%80-%EB%B0%B0%EC%97%B4%EC%9D%B4-%EC%95%84%EB%8B%88%EB%8B%A4</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-28-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B0%B0%EC%97%B4%EC%9D%80-%EB%B0%B0%EC%97%B4%EC%9D%B4-%EC%95%84%EB%8B%88%EB%8B%A4</guid>
            <pubDate>Sun, 12 Jan 2025 13:39:04 GMT</pubDate>
            <description><![CDATA[<p>밀집 배열 - 일반적인 배열로 동일한 크기의 메모리 공간이 연속적으로 나열된 자료구조</p>
<p>자바스크립트의 배열은 지금까지 살펴본 일반적인 의미의 배열과 다름
희소 배열 - 배열의 요소를 위한 각각의 메모리 공간은 동일한 크기를 갖지 않아도 되며 연속적으로 이어져 있지 않을 수도 있음</p>
<pre><code>const arr = [&#39;string&#39;, 10, true, null, function () {}];</code></pre><p>자바스크립트의 배열은 엄밀히 말해 일반적 의미의 배열이 아님
자바스크립트의 배열은 일반적인 배열의 동작을 흉내낸 특수한 객체
자바스크립트 배열은 인덱스를 프로퍼티 키로 갖으며 배열의 요소는 프로퍼티 값
자바스크립트에서 사용할 수 있는 모든 값은 객체의 프로퍼티 값이 될 수 있으므로 어떤 타입의 값이라도 배열의 요소가 될 수 있음</p>
<p>일반적인 배열과 자바스크립트 배열의 장단점</p>
<ul>
<li>일반적인 배열은 인덱스로 배열 요소에 빠르게 접근 가능 but 특정 요소를 탐색하거나 요소를 삽입 또는 삭제하는 경우에는 비효율적</li>
<li>자바스크립트 배열은 해시 테이블로 구현된 객체이므로 인덱스로 배열 요소에 접근하는 경우, 일반적인 배열보다 성능적인 면에서 느릴 수 밖에 없는 구조적인 단점 but 특정 요소를 탐색하거나 요소를 삽입 또는 삭제하는 경우에는 일반적인 배열보다 빠른 성능을 기대
=자바스크립트 배열은 인덱스로 배열 요소에 접근하는 경우에는 일반적인 배열보다 느리지만 특정 요소를 탐색하거나 요소를 삽입 또는 삭제하는 경우에는 일반적인 배열보다 빠름</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 27 (배열)]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-27-%EB%B0%B0%EC%97%B4</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-27-%EB%B0%B0%EC%97%B4</guid>
            <pubDate>Sun, 12 Jan 2025 13:32:51 GMT</pubDate>
            <description><![CDATA[<pre><code>const emptyArr = [];

//존재하지 않는 요소에 접근하면 undefined를 반환
console.log(emptyArr[1]); // undefined
console.log(typeof emptyArr);  // object</code></pre><p>배열 리터럴은 객체 리터럴과 달리 프로퍼티명이 없고 각 요소의 값만이 존재
객체는 프로퍼티 값에 접근하기 위해 대괄호 표기법 또는 마침표 표기법을 사용하며 프로퍼티명을 키로 사용
배열은 요소에 접근하기 위해 대괄호 표기법만을 사용하며 대괄호 내에 접근하고자 하는 요소의 인덱스를 넣어줌</p>
<p>두 객체의 근본적 차이는 배열 리터럴 arr의 프로토타입 객체는 Array.prototype이지만 객체 리터럴 obj의 프로토타입 객체는 Object.prototype이라는 것</p>
<p>대부분의 프로그래밍 언어에서 배열의 요소들은 모두 같은 데이터 타입이어야 하지만, 자바스크립트 배열은 어떤 데이터 타입의 조합이라도 포함 가능</p>
<pre><code>const misc = [
  &#39;string&#39;,
  10,
  true,
  null,
  undefined,
  NaN,
  Infinity,
  [&#39;nested array&#39;],
  { object: true },
  function () {}
];</code></pre><p>Array() 생성자 함수
매개변수가 1개이고 숫자인 경우 매개변수로 전달된 숫자를 length 값으로 가지는 빈 배열을 생성</p>
<pre><code>const arr = new Array(2);
console.log(arr); // (2) [empty × 2]</code></pre><p>그 외의 경우 매개변수로 전달된 값들을 요소로 가지는 배열을 생성</p>
<pre><code>const arr = new Array(1, 2, 3);
console.log(arr); // [1, 2, 3]</code></pre><p>배열 요소 추가 - 순서에 맞게 값을 할당할 필요는 없고 인덱스를 사용하여 필요한 위치에 값을 할당</p>
<pre><code>const arr = [];

arr[1] = 1;
arr[3] = 3;

console.log(arr); // (4) [empty, 1, empty, 3]
console.log(arr.lenth); // 4

// 값이 할당되지 않은 인덱스 위치의 요소는 생성되지 않는다.
console.log(Object.keys(arr)); // [ &#39;1&#39;, &#39;3&#39; ]

// arr[0]이 undefined를 반환한 이유는 존재하지 않는 프로퍼티에 접근했을 때 undefined를 반환하는 것과 같은 이치다.
console.log(arr[0]); // undefined</code></pre><p>배열 요소 삭제 - 배열은 객체이기 때문에 배열의 요소를 삭제하기 위해 delete 연산자를 사용 가능
이때 length에는 변함 X
해당 요소를 완전히 삭제하여 length에도 반영되게 하기 위해서는 Array.splice 메소드 사용</p>
<pre><code>onst numbersArr = [&#39;zero&#39;, &#39;one&#39;, &#39;two&#39;, &#39;three&#39;];

// 요소의 값만 삭제된다
delete numbersArr[2]; // (4) [&quot;zero&quot;, &quot;one&quot;, empty, &quot;three&quot;]

// 요소 값만이 아니라 요소를 완전히 삭제한다
// splice(시작 인덱스, 삭제할 요소 수)
numbersArr.splice(2, 1); // (3) [&quot;zero&quot;, &quot;one&quot;, &quot;three&quot;]
console.log(numbersArr);</code></pre><p>배열은 객체이므로 for…in 문을 사용 O
그러나 배열은 객체이기 때문에 프로퍼티를 가질 수 있음
for…in 문을 사용하면 배열 요소뿐만 아니라 불필요한 프로퍼티까지 출력될 수 있고 요소들의 순서를 보장하지 않으므로 배열을 순회하는데 적합 X
배열의 순회에는 forEach 메소드, for 문, for…of 문을 사용하는 것이 좋음</p>
<pre><code>const arr = [0, 1, 2, 3];
arr.foo = 10;

for (const key in arr) {
  console.log(&#39;key: &#39; + key, &#39;value: &#39; + arr[key]);
}
// key: 0 value: 0
// key: 1 value: 1
// key: 2 value: 2
// key: 3 value: 3
// key: foo value: 10 =&gt; 불필요한 프로퍼티까지 출력

arr.forEach((item, index) =&gt; console.log(index, item));

for (const item of arr) {
  console.log(item);
}</code></pre><p>Array.length</p>
<pre><code>const arr = [1, 2, 3, 4, 5];
console.log(arr.length); // 5

arr[4294967294] = 100;
console.log(arr.length); // 4294967295
console.log(arr); // (4294967295) [1, 2, 3, 4, 5, empty × 4294967289, 100]</code></pre><p>배열 요소의 개수와 length 프로퍼티의 값이 반드시 일치 X(=희소 배열)</p>
<p>length 프로퍼티의 값은 명시적으로 변경 O
만약 length 프로퍼티의 값을 현재보다 작게 변경하면 변경된 length 프로퍼티의 값보다 크거나 같은 인덱스에 해당하는 요소는 모두 삭제</p>
<pre><code>const arr = [ 1, 2, 3, 4, 5 ];

// 배열 길이의 명시적 변경
arr.length = 3;
console.log(arr); // (3) [1, 2, 3]</code></pre><p>Array Method</p>
<ol>
<li>Array.isArray() - 주어진 인수가 배열이면 true, 배열이 아니면 false를 반환</li>
<li>Array.from - 유사 배열 객체 또는 이터러블 객체를 변환하여 새로운 배열을 생성<pre><code>// 문자열은 이터러블이다.
const arr1 = Array.from(&#39;Hello&#39;);
console.log(arr1); // [ &#39;H&#39;, &#39;e&#39;, &#39;l&#39;, &#39;l&#39;, &#39;o&#39; ]
</code></pre></li>
</ol>
<p>// 유사 배열 객체를 새로운 배열을 변환하여 반환한다.
const arr2 = Array.from({ length: 2, 0: &#39;a&#39;, 1: &#39;b&#39; });
console.log(arr2); // [ &#39;a&#39;, &#39;b&#39; ]</p>
<p>// Array.from의 두번째 매개변수에게 배열의 모든 요소에 대해 호출할 함수를 전달할 수 있다.
// 이 함수는 첫번째 매개변수에게 전달된 인수로 생성된 배열의 모든 요소를 인수로 전달받아 호출된다.
const arr3 = Array.from({ length: 5 }, function (v, i) { return i; });
console.log(arr3); // [ 0, 1, 2, 3, 4 ]</p>
<pre><code>3. Array.of - 전달된 인수를 요소로 갖는 배열을 생성
Array.of는 Array 생성자 함수와 다르게 전달된 인수가 1개이고 숫자이더라도 인수를 요소로 갖는 배열을 생성</code></pre><p>// 전달된 인수가 1개이고 숫자이더라도 인수를 요소로 갖는 배열을 생성한다.
const arr1 = Array.of(1);
console.log(arr1); // // [1]</p>
<p>const arr3 = Array.of(&#39;string&#39;);
console.log(arr3); // &#39;string&#39;</p>
<pre><code>4. Array.indexOf(찾을 요소, 시작 인덱스) - 원본 배열에서 인수로 전달된 요소를 검색하여 인덱스를 반환
중복되는 요소가 있는 경우, 첫번째 인덱스를 반환
해당하는 요소가 없는 경우, -1을 반환</code></pre><p>const arr = [1, 2, 2, 3];</p>
<p>// 배열 arr에서 요소 2를 검색하여 첫번째 인덱스를 반환
arr.indexOf(2);    // -&gt; 1
// 배열 arr에서 요소 4가 없으므로 -1을 반환
arr.indexOf(4);    // -1
// 두번째 인수는 검색을 시작할 인덱스이다. 두번째 인수를 생략하면 처음부터 검색한다.
arr.indexOf(2, 2); // 2</p>
<pre><code>Array.includes 메소드를 사용하면 보다 가독성이 좋음
ex) if (foods.indexOf(&#39;orange&#39;) === -1) 대신 
    if (!foods.includes(&#39;orange&#39;))
5. Array.concat(배열 또는 값) - 인수로 전달된 값들(배열 또는 값)을 원본 배열의 마지막 요소로 추가한 새로운 배열을 반환
인수로 전달한 값이 배열인 경우, 배열을 해체하여 새로운 배열의 요소로 추가
원본 배열은 변경 X</code></pre><p>const arr1 = [1, 2];
const arr2 = [3, 4];</p>
<p>// 숫자를 원본 배열 arr1의 마지막 요소로 추가한 새로운 배열을 반환
result = arr1.concat(3);
console.log(result); // [&quot;1, 2, 3]</p>
<p>//  배열 arr2와 숫자를 원본 배열 arr1의 마지막 요소로 추가한 새로운 배열을 반환
result = arr1.concat(arr2, 5);
console.log(result); // [1, 2, 3, 4, 5]</p>
<pre><code>6. Array.join(구분자) - 원본 배열의 모든 요소를 문자열로 변환한 후, 인수로 전달받은 값, 즉 구분자로 연결한 문자열을 반환
구분자는 생략 가능하며 기본 구분자는 ,</code></pre><p>const arr = [1, 2, 3, 4];</p>
<p>// 기본 구분자는 &#39;,&#39;이다.
// 원본 배열 arr의 모든 요소를 문자열로 변환한 후, 기본 구분자 &#39;,&#39;로 연결한 문자열을 반환
let result = arr.join();
console.log(result); // &#39;1,2,3,4&#39;;</p>
<p>// 원본 배열 arr의 모든 요소를 문자열로 변환한 후, 빈문자열로 연결한 문자열을 반환
result = arr.join(&#39;&#39;);
console.log(result); // &#39;1234&#39;</p>
<pre><code>7. Array.push(값들) - 인수로 전달받은 모든 값을 원본 배열의 마지막에 요소로 추가하고 변경된 length 값을 반환
push 메소드는 원본 배열을 직접 변경</code></pre><p>const arr = [1, 2];</p>
<p>// 인수로 전달받은 모든 값을 원본 배열의 마지막에 요소로 추가하고 변경된 length 값을 반환한다.
let result = arr.push(3, 4);
console.log(result); // 4</p>
<pre><code>push 메소드와 concat 메소드의 미묘한 차이
- push 메소드는 원본 배열을 직접 변경하지만 concat 메소드는 원본 배열을 변경하지 않고 새로운 배열을 반환
- 인수로 전달받은 값이 배열인 경우, push 메소드는 배열을 그대로 원본 배열의 마지막 요소로 추가하지만 concat 메소드는 배열을 해체하여 새로운 배열의 마지막 요소로 추가</code></pre><p>const arr1 = [1, 2];
// 인수로 전달받은 배열을 그대로 원본 배열의 마지막 요소로 추가한다
arr1.push([3, 4]);
console.log(arr1); // [1, 2, [3, 4]]</p>
<p>const arr2 = [1, 2];
// 인수로 전달받은 배열을 해체하여 새로운 배열의 마지막 요소로 추가한다
const result = arr2.concat([3, 4]);
console.log(result); // [1, 2, 3, 4]</p>
<pre><code>- push 메소드는 성능면에서 좋지 않음. push 메소드는 배열의 마지막에 요소를 추가하므로 length 프로퍼티를 사용하여 직접 요소를 추가할 수도 있음. 이 방법이 push 메소드보다 빠름.
ex) arr[arr.length] = 3;    // arr.push(3)와 동일한 처리. 이 방법이 push 메소드보다 빠름.
- push 메소드는 원본 배열을 직접 변경하는 부수 효과. 따라서 push 메소드보다는 spread 문법을 사용하는 편이 좋음.
ex) // ES6 spread 문법
const newArr = [...arr, 3];
// arr.push(3);
8. Array.pop() - 원본 배열에서 마지막 요소를 제거하고 제거한 요소를 반환
원본 배열이 빈 배열이면 undefined를 반환
pop 메소드는 원본 배열을 직접 변경
+push와 함께 배열을 스택(LIFO: Last In First Out)처럼 동작
9. Array.reverse() - 배열 요소의 순서를 반대로 변경
원본 배열이 변경됨, 반환값은 변경된 배열
10. Array.shift() - 배열에서 첫요소를 제거하고 제거한 요소를 반환
만약 빈 배열일 경우 undefined를 반환, 대상 배열 자체를 변경
push와 함께 배열을 큐(FIFO: First In First Out)처럼 동작
11. Array.slice(시작 인덱스, 끝 인덱스-기본값은 length) - 인자로 지정된 배열의 부분을 복사하여 반환
원본 배열은 변경 X
첫번째 매개변수 start에 해당하는 인덱스를 갖는 요소부터 매개변수 end에 해당하는 인덱스를 가진 요소 전까지 복사
인자를 전달하지 않으면 원본 배열의 복사본을 생성하여 반</code></pre><p>const arr = [1, 2, 3];</p>
<p>// 원본 배열 arr의 새로운 복사본을 생성한다.
const copy = arr.slice();
console.log(copy, copy === arr); // [ 1, 2, 3 ] false</p>
<pre><code>원본 배열의 각 요소를 얕은 복사하여 새로운 복사본을 생성</code></pre><p>const todos = [
  { id: 1, content: &#39;HTML&#39;, completed: false }
];</p>
<p>// shallow copy
const _todos = todos.slice();
console.log(_todos === todos); // false</p>
<p>// 배열의 요소는 같다. 즉, 얕은 복사되었다.
console.log(_todos[0] === todos[0]); // true</p>
<pre><code>12. Array.splice(시작 인덱스, 제거할 요소 수(옵션), 추가될 요소들(옵션)) - 기존의 배열의 요소를 제거하고 그 위치에 새로운 요소를 추가
배열 중간에 새로운 요소를 추가할 때도 사용
시작 인덱스 만을 지정하면 배열의 시작 인덱스부터 모든 요소를 제거
반환값은 삭제한 요소들 배열
이 메소드의 가장 일반적인 사용은 배열에서 요소를 삭제할 때</code></pre><p>const items1 = [1, 2, 3, 4];</p>
<p>// items[1]부터 2개의 요소를 제거하고 제거된 요소를 배열로 반환
const res1 = items1.splice(1, 2);</p>
<p>// 원본 배열이 변경된다.
console.log(items1); // [ 1, 4 ]
// 제거한 요소가 배열로 반환된다.
console.log(res1);   // [ 2, 3 ]</p>
<p>const items = [1, 2, 3, 4];</p>
<p>// items[1]부터 2개의 요소를 제거하고 그자리에 새로운 요소를 추가한다. 제거된 요소가 반환된다.
const res = items.splice(1, 2, 20, 30);</p>
<p>// 원본 배열이 변경된다.
console.log(items); // [ 1, 20, 30, 4 ]
// 제거한 요소가 배열로 반환된다.
console.log(res);   // [ 2, 3 ]</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 26  (String 객체)]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-26</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-26</guid>
            <pubDate>Sun, 12 Jan 2025 10:43:17 GMT</pubDate>
            <description><![CDATA[<p>String 생성자 함수 - new String(value)
전달된 인자는 모두 문자열로 변환</p>
<pre><code>let strObj = new String(&#39;Lee&#39;);
console.log(strObj); // [String: &#39;Lee&#39;]</code></pre><p>new 연산자를 사용하지 않고 String 생성자 함수를 호출하면 String 객체가 아닌 문자열 리터럴을 반환</p>
<pre><code>var x = String(&#39;Lee&#39;);
console.log(typeof x, x); // string Lee</code></pre><pre><code>const str = &#39;Lee&#39;;
const strObj = new String(&#39;Lee&#39;);

console.log(str == strObj);  // true
console.log(str === strObj); // false

console.log(typeof str);    // string
console.log(typeof strObj); // object</code></pre><p>String.length
문자열 내의 문자 갯수를 반환
String 객체는 length 프로퍼티를 소유하고 있으므로 유사 배열 객체</p>
<p>String Method - String 객체의 모든 메소드는 언제나 새로운 문자열을 반환
문자열은 변경 불가능한 원시 값이기 때문</p>
<ol>
<li><p>String.charAt(index number) - index에 해당하는 위치의 문자를 반환
지정한 index가 문자열의 범위를 벗어난 경우 빈문자열 반환</p>
</li>
<li><p>String.concat(문자열 1[,문자열 2,...,문자열 N]) - 인수로 전달한 1개 이상의 문자열과 연결하여 새로운 문자열을 반환
concat 메소드를 사용하는 것보다는 +, += 할당 연산자를 사용하는 것이 성능상 유리</p>
</li>
<li><p>String.indexOf(문자열, 시작 index (생략할 경우, 0)) - 문자열을 검색하여 처음 발견된 곳의 index를 반환, 발견하지 못한 경우 -1을 반환</p>
</li>
<li><p>String.lastIndexOf(문자열, 시작 index) - 문자열을 검색하여 마지막으로 발견된 곳의 index를 반환, 발견하지 못한 경우 -1을 반환
2번째 인수가 전달되면 검색 시작 위치를 시작 Index으로 이동하여 역방향으로 검색, 검색 범위는 0 ~ fromIndex</p>
</li>
<li><p>String.replace(기존 문자열, 치환 문자열) - 첫번째 인수로 전달한 문자열을 검색하여 두번째 인수로 전달한 문자열로 대체
원본 문자열은 변경되지 않고 결과가 반영된 <strong>새로운 문자열</strong>을 반환
검색된 문자열이 여럿 존재할 경우 첫번째로 검색된 문자열만 대체</p>
<pre><code>const str = &#39;Hello world&#39;;
</code></pre></li>
</ol>
<p>// 특수한 교체 패턴을 사용할 수 있다. ($&amp; =&gt; 검색된 문자열)
console.log(str.replace(&#39;world&#39;, &#39;<strong>$&amp;</strong>&#39;)); // Hello <strong>world</strong></p>
<p>const camelCase = &#39;helloWorld&#39;;
// 두번째 인수로 치환 함수를 전달할 수 있다.
// /.[A-Z]/g =&gt; 1문자와 대문자의 조합을 문자열 전체에서 검색한다.
console.log(camelCase.replace(/.[A-Z]/g, function (match) {
  // match : oW =&gt; match[0] : o, match[1] : W
  return match[0] + &#39;_&#39; + match[1].toLowerCase();
})); // hello_world</p>
<p>// /(.)([A-Z])/g =&gt; 1문자와 대문자의 조합
// $1 =&gt; (.)
// $2 =&gt; ([A-Z])
console.log(camelCase.replace(/(.)([A-Z])/g, &#39;$1_$2&#39;).toLowerCase()); // hello_world</p>
<pre><code>6. String.split(문자열 또는 정규표현식, 반환 배열 최대 크기) - 첫번째 인수로 전달한 문자열 또는 정규표현식을 대상 문자열에서 검색하여 문자열을 구분한 후 분리된 각 문자열로 이루어진 배열을 반환
원본 문자열은 변경 X
두번째 인수가 없는 경우, 대상 문자열 전체를 단일 요소로 하는 배열을 반환</code></pre><p>const str = &#39;How are you doing?&#39;;</p>
<p>// 정규 표현식
console.log(str.split(/\s/)); // [ &#39;How&#39;, &#39;are&#39;, &#39;you&#39;, &#39;doing?&#39; ]</p>
<p>// 인수가 없는 경우, 대상 문자열 전체를 단일 요소로 하는 배열을 반환한다.
console.log(str.split()); // [ &#39;How are you doing?&#39; ]</p>
<p>// 각 문자를 모두 분리한다
console.log(str.split(&#39;&#39;)); // [ &#39;H&#39;,&#39;o&#39;,&#39;w&#39;,&#39; &#39;,&#39;a&#39;,&#39;r&#39;,&#39;e&#39;,&#39; &#39;,&#39;y&#39;,&#39;o&#39;,&#39;u&#39;,&#39; &#39;,&#39;d&#39;,&#39;o&#39;,&#39;i&#39;,&#39;n&#39;,&#39;g&#39;,&#39;?&#39; ]</p>
<p>// 공백으로 구분하여 배열로 반환한다. 단 요소수는 3개까지만 허용한다
console.log(str.split(&#39; &#39;, 3)); // [ &#39;How&#39;, &#39;are&#39;, &#39;you&#39; ]</p>
<pre><code>7. String.substring(시작 인덱스, 끝 인덱스) - 첫번째 인수로 전달한 start 인덱스에 해당하는 문자부터 두번째 인자에 전달된 end 인덱스에 해당하는 문자의 바로 이전 문자까지를 모두 반환
첫번째 인수 &gt; 두번째 인수 : 두 인수는 교환
두번째 인수가 생략된 경우 : 해당 문자열의 끝까지 반환
인수 &lt; 0 또는 NaN인 경우 : 0으로 취급
인수 &gt; 문자열의 길이(str.length) : 인수는 문자열의 길이로 취급</code></pre><p>const str = &#39;Hello World&#39;; // str.length == 11</p>
<p>// 인수 &lt; 0 또는 NaN인 경우 : 0으로 취급된다.
console.log(str.substring(-2)); // Hello World</p>
<p>// 인수 &gt; 문자열의 길이 : 인수는 문자열의 길이로 취급된다.
console.log(str.substring(1, 12)); // ello World
console.log(str.substring(20)); // &#39;&#39;</p>
<pre><code>8. String.slice(시작 인덱스, 끝 인덱스) - String.substring과 동일
String.slice는 음수의 인수를 전달할 수 있음</code></pre><p>const str = &#39;hello world&#39;;</p>
<p>// 인수 &lt; 0 또는 NaN인 경우 : 0으로 취급된다.
console.log(str.substring(-5)); // &#39;hello world&#39;
// 뒤에서 5자리를 잘라내어 반환한다.
console.log(str.slice(-5)); // &#39;world&#39;</p>
<pre><code>9. String.toLowerCase() - 대상 문자열의 모든 문자를 소문자로 변경
10. String.toUpperCase() - 대상 문자열의 모든 문자를 대문자로 변경
11. String.trim() - 대상 문자열 양쪽 끝에 있는 공백 문자를 제거한 문자열을 반환</code></pre><p>const str = &#39;   foo  &#39;;</p>
<p>console.log(str.trim()); // &#39;foo&#39;</p>
<p>// String.prototype.replace
console.log(str.replace(/^\s+/g, &#39;&#39;)); // &#39;foo  &#39;
console.log(str.replace(/\s+$/g, &#39;&#39;)); // &#39;   foo&#39;</p>
<p>// String.{trimStart,trimEnd} : Proposal stage 3
console.log(str.trimStart()); // &#39;foo  &#39;
console.log(str.trimEnd());   // &#39;   foo&#39;</p>
<pre><code>12. String.repeat(숫자) - 인수로 전달한 숫자만큼 반복해 연결한 새로운 문자열을 반환
숫자가 0이면 빈 문자열을 반환하고 음수이면 RangeError를 발생</code></pre><p>console.log(&#39;abc&#39;.repeat(0));   // &#39;&#39;
console.log(&#39;abc&#39;.repeat(2));   // &#39;abcabc&#39;
console.log(&#39;abc&#39;.repeat(2.5)); // &#39;abcabc&#39; (2.5 → 2)
console.log(&#39;abc&#39;.repeat(-1));  // RangeError: Invalid count value</p>
<pre><code>13. String.includes(문자열, 검색할 위치) - 인수로 전달한 문자열이 포함되어 있는지를 검사하고 결과를 불리언 값으로 반환
두번째 인수는 옵션으로 검색할 위치를 나타내는 정수</code></pre><p>const str = &#39;hello world&#39;;</p>
<p>console.log(str.includes(&#39; &#39;));     // true
console.log(str.includes(&#39;&#39;));      // true
console.log(str.includes());        // false
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 25 (정규표현식)]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-25-%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-25-%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D</guid>
            <pubDate>Thu, 09 Jan 2025 08:49:42 GMT</pubDate>
            <description><![CDATA[<p>정규표현식 - 문자열에서 특정 내용을 찾거나 대체 또는 발췌하는데 사용
주석이나 공백을 허용하지 않고 여러가지 기호를 혼합하여 사용하기 때문에 가독성이 좋지 않다는 문제
/패턴/플래그
ex) 전화번호가 유효성 체크</p>
<pre><code>const tel = &#39;0101234567팔&#39;;
// 정규 표현식 리터럴
const myRegExp = /^[0-9]+$/;
console.log(myRegExp.test(tel)); // false</code></pre><p>자바스크립트 메소드 - exec, test, match, replace, search, split</p>
<pre><code>const targetStr = &#39;This is a pen.&#39;;
const regexr = /is/ig;

// RegExp 객체의 메소드
console.log(regexr.exec(targetStr)); // [ &#39;is&#39;, index: 2, input: &#39;This is a pen.&#39; ]
console.log(regexr.test(targetStr)); // true

// String 객체의 메소드
console.log(targetStr.match(regexr)); // [ &#39;is&#39;, &#39;is&#39; ]
console.log(targetStr.replace(regexr, &#39;IS&#39;)); // ThIS IS a pen.
// String.prototype.search는 검색된 문자열의 첫번째 인덱스를 반환한다.
console.log(targetStr.search(regexr)); // 2 ← index
console.log(targetStr.split(regexr));  // [ &#39;Th&#39;, &#39; &#39;, &#39; a pen.&#39; ]</code></pre><p>플래그(옵션)
i - 대소문자를 구별 X
g - 문자열 내의 모든 패턴을 검색
m - 문자열의 행이 바뀌더라도 계속 검색</p>
<p>패턴 - 검색하고 싶은 문자열을 지정
문자열의 따옴표는 생략, 따옴표를 포함하면 따옴표까지도 검색
특별한 의미를 가지는 메타문자 또는 기호로 표현 가능</p>
<p>. - 임의의 문자 한 개
|, [] - or    ex) /A|B/g, /A+|B+/g=/[AB]+/g
- - 범위 지정 ex) /[A-Z]+/g - 대문자 알파벳 추출, /[A-Za-z]+/g - 대소문자를 구별하지 않고 알파벳을 추출, /[0-9]+/g - 숫자 추출
\d - 숫자를 의미 &lt;-&gt; \D - 숫자 X
\w - 알파벳과 숫자를 의미 &lt;-&gt; \W - 알파벳과 숫자 X</p>
<pre><code>const targetStr = &#39;AA BB Aa Bb 24,000&#39;;
// 알파벳과 숫자 또는 &#39;,&#39;가 한번 이상 반복되는 문자열을 반복 검색
let regexr = /[\w,]+/g;
console.log(targetStr.match(regexr)); // [ &#39;AA&#39;, &#39;BB&#39;, &#39;Aa&#39;, &#39;Bb&#39;, &#39;24,000&#39; ]
// 알파벳과 숫자가 아닌 문자 또는 &#39;,&#39;가 한번 이상 반복되는 문자열을 반복 검색
regexr = /[\W,]+/g;
console.log(targetStr.match(regexr)); // [ &#39; &#39;, &#39; &#39;, &#39; &#39;, &#39; &#39;, &#39;,&#39; ]</code></pre><p>^ - 문자열의 처음을 의미 ex) /^http/
$ - 문자열의 끝을 의미 ex) /html$/</p>
<p>[^] - 부정(not)을 의, [] 바깥의 ^는 문자열의 처음을 의미 ex) /^\d+$/</p>
<p>\s - 여러 가지 공백 문자 (스페이스, 탭 등) =&gt; [\t\r\n\v\f] ex) /^[\s]+/
{} - 자릿수 ex) {4,10}: 4 ~ 10자리, /^[A-Za-z0-9]{4,10}$/ - 알파벳 대소문자 또는 숫자로 시작하고 끝나며 4 ~10자리인지 검사</p>
<p>패턴을 최소 한번 반복하려면 앞선 패턴 뒤에 +
ex) /A+/g - A+는 A만으로 이루어진 문자열(‘A’, ‘AA’, ‘AAA’, …)를 의미</p>
<p>RegExp 객체 - new RegExp(패턴[, 플래그])</p>
<pre><code>// 정규식 리터럴
/ab+c/i;
new RegExp(&#39;ab+c&#39;, &#39;i&#39;);
new RegExp(/ab+c/, &#39;i&#39;);
new RegExp(/ab+c/i); // ES6</code></pre><p>RegExp 메소드</p>
<ol>
<li>RegExp.exec(string) - 문자열을 검색하여 매칭 결과를 반환
반환값은 배열 또는 null
g 플래그를 지정하여도 첫번째 매칭 결과만을 반환<pre><code>const target = &#39;Is this all there is?&#39;;
const regExp = /is/g;
</code></pre></li>
</ol>
<p>const res = regExp.exec(target);
console.log(res); // [ &#39;is&#39;, index: 5, input: &#39;Is this all there is?&#39; ]</p>
<p>```
2. RegExp.test(string) - 문자열을 검색하여 매칭 결과를 반환
반환값은 true 또는 false</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 24 (Date 객체)]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-24-Date-%EA%B0%9D%EC%B2%B4</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-24-Date-%EA%B0%9D%EC%B2%B4</guid>
            <pubDate>Tue, 07 Jan 2025 13:18:00 GMT</pubDate>
            <description><![CDATA[<p>Date 객체는 생성자 함수
Date 생성자 함수는 날짜와 시간을 가지는 인스턴스를 생성
생성된 인스턴스는 기본적으로 현재 날짜와 시간을 나타내는 값을 가짐
현재 날짜와 시간이 아닌 다른 날짜와 시간을 다루고 싶은 경우, Date 생성자 함수에 명시적으로 해당 날짜와 시간 정보를 인수로 지정</p>
<p>Date 생성자 함수로 객체를 생성하는 방법</p>
<ol>
<li>new Date()
인수를 전달하지 않으면 현재 날짜와 시간을 가지는 인스턴스를 반환<pre><code>const date = new Date();
console.log(date); // Thu May 16 2019 17:16:13 GMT+0900 (한국 표준시)</code></pre></li>
<li>new Date(milliseconds)
인수로 숫자 타입의 밀리초를 전달하면 1970년 1월 1일 00:00(UTC)을 기점으로 인수로 전달된 밀리초만큼 경과한 날짜와 시간을 가지는 인스턴스를 반환\<pre><code>let date = new Date(0);
console.log(date); // Thu Jan 01 1970 09:00:00 GMT+0900 (한국 표준시)
</code></pre></li>
</ol>
<p>// 1s = 1,000ms
// 86400000ms는 1day를 의미
date = new Date(86400000);
console.log(date); // FFri Jan 02 1970 09:00:00 GMT+0900 (한국 표준시)</p>
<pre><code>3. new Date(dateString)
인수로 날짜와 시간을 나타내는 문자열을 전달하면 지정된 날짜와 시간을 가지는 인스턴스를 반환</code></pre><p>let date = new Date(&#39;May 16, 2019 17:22:10&#39;);
console.log(date); // Thu May 16 2019 17:22:10 GMT+0900 (한국 표준시)</p>
<p>date = new Date(&#39;2019/05/16/17:22:10&#39;);
console.log(date); // Thu May 16 2019 17:22:10 GMT+0900 (한국 표준시)</p>
<pre><code>4. new Date(year, month[, day, hour, minute, second, millisecond])
인수로 년, 월, 일, 시, 분, 초, 밀리초를 의미하는 숫자를 전달하면 지정된 날짜와 시간을 가지는 인스턴스를 반환
때 년, 월은 반드시 지정
지정하지 않은 옵션 정보는 0 또는 1으로 초기화
년, 월을 지정하지 않은 경우 1970년 1월 1일 00:00(UTC)을 가지는 인스턴스를 반환</code></pre><p>// 월을 나타내는 4는 5월을 의미한다.
let date = new Date(2019, 4);
console.log(date); // Wed May 01 2019 00:00:00 GMT+0900 (한국 표준시)</p>
<p>date = new Date(2019, 4, 16, 17, 24, 30, 0);
console.log(date); // Thu May 16 2019 17:24:30 GMT+0900 (한국 표준시)</p>
<p>// 가독성이 훨씬 좋다.
date = new Date(&#39;2019/5/16/17:24:30:10&#39;);
console.log(date); // Thu May 16 2019 17:24:30 GMT+0900 (한국 표준시)</p>
<pre><code>5. Date()
Date 생성자 함수를 new 연산자없이 호출하면 인스턴스를 반환하지 않고 결과값을 문자열로 반환</code></pre><p>let date = Date();
console.log(typeof date, date); // string Thu May 16 2019 17:33:03 GMT+0900 (한국 표준시)</p>
<pre><code>
Date 메소드
1. Date.now
1970년 1월 1일 00:00:00(UTC)을 기점으로 현재 시간까지 경과한 밀리초를 숫자로 반환</code></pre><p>const now = Date.now();</p>
<pre><code>2. Date.parse
1970년 1월 1일 00:00:00(UTC)을 기점으로 인수로 전달된 지정 시간까지의 밀리초를 숫자로 반환</code></pre><p>let d = Date.parse(&#39;Jan 2, 1970 00:00:00 UTC&#39;); // UTC 표현1
d = Date.parse(&#39;Jan 2, 1970 09:00:00&#39;); // KST 표현2
d = Date.parse(&#39;1970/01/02/09:00:00&#39;); // KST 표현3
console.log(d); // 86400000</p>
<pre><code>3. Date.UTC(year, month[, day, hour, minute, second, millisecond])
1970년 1월 1일 00:00:00(UTC)을 기점으로 인수로 전달된 지정 시간까지의 밀리초를 숫자로 반환
인수는 local time(KST)가 아닌 UTC로 인식
month는 월을 의미하는 0~11까지의 정수, 0부터 시작하므로 주의가 필요</code></pre><p>let d = Date.UTC(1970, 0, 2);
console.log(d); // 86400000</p>
<p>d = Date.UTC(&#39;1970/1/2&#39;);    //정해진 형식만 가능
console.log(d); // NaN</p>
<pre><code>4. Date.getFullYear
년도를 나타내는 4자리 숫자를 반환</code></pre><p>const today = new Date().getFullYear();
console.log(today);  // 2019</p>
<pre><code>5. Date.setFullYear
년도를 나타내는 4자리 숫자를 설
년도 이외 월, 일도 설정 가능</code></pre><p>const today = new Date();
today.setFullYear(1900, 0, 1);  // 년도 지정
year = today.getFullYear();
console.log(year);  // 1900</p>
<pre><code>6. Date.getMonth
월을 나타내는 0 ~ 11의 정수를 반환
1월은 0, 12월은 11</code></pre><p>const month = new Date().getMonth();
// Thu May 16 2019 17:44:03 GMT+0900 (한국 표준시)
console.log(month); // 4</p>
<pre><code>7. Date.setMonth(month[, day])
월을 나타내는 0 ~ 11의 정수를 설정
1월은 0, 12월은 11, 월 이외 일도 설정 가능</code></pre><p>const today = new Date();
today.setMonth(11, 1); // 월/일을 지정, 12월 1일
console.log(today); // Sun Dec 01 2019 17:45:20 GMT+0900 (한국 표준시)</p>
<pre><code>8. Date.getDate
날짜(1 ~ 31)를 나타내는 정수를 반환</code></pre><p>const date = new Date().getDate();
console.log(date);</p>
<pre><code>9. Date.setDate
날짜(1 ~ 31)를 나타내는 정수를 설정</code></pre><p>const today = new Date();
today.setDate(1);   //일자 지정
console.log(today); // Wed May 01 2019 17:47:01 GMT+0900 (한국 표준시)</p>
<pre><code>10. Date.getDay
요일(0 ~ 6)를 나타내는 정수를 반환
0은 일요일, 6은 토요일</code></pre><p>const today = new Date();
const day = today.getDay();
console.log(day);</p>
<pre><code>11. Date.getHours
시간(0 ~ 23)를 나타내는 정수를 반환</code></pre><p>const today = new Date();
const hours = today.getHours();
console.log(hours); // 17</p>
<pre><code>12. Date.setHours(hour[, minute[, second[, ms]]])
시간(0 ~ 23)를 나타내는 정수를 설정
시간 이외 분, 초, 밀리초도 설정 가능</code></pre><p>const today = new Date();
today.setHours(11, 0, 0, 0); // 시간/분/초/밀리초 지정, 00:00:00:00
hours = today.getHours();
console.log(hours); // 11</p>
<pre><code>13. Date.getMinutes
분(0 ~ 59)를 나타내는 정수를 반환</code></pre><p>const today = new Date();
const minutes = today.getMinutes();
console.log(minutes);</p>
<pre><code>14. Date.setMinutes(minute[, second[, ms]])
분(0 ~ 59)를 나타내는 정수를 설정
분 이외 초, 밀리초도 설정 가능</code></pre><p>const today = new Date();
today.setMinutes(5, 10, 999); // 분/초/밀리초 지정, 05:10:999
minutes = today.getMinutes();
console.log(minutes); // 5</p>
<pre><code>15. Date.getSeconds
초(0 ~ 59)를 나타내는 정수를 반환</code></pre><p>const today = new Date();
const seconds = today.getSeconds();
console.log(today);
console.log(seconds);</p>
<pre><code>16. Date.setSeconds(second[, ms])
초(0 ~ 59)를 나타내는 정수를 설정
초 이외 밀리초도 설정 가능</code></pre><p>const today = new Date();
today.setSeconds(15, 0); // 초/밀리초 지정, 10:000
seconds = today.getSeconds();
console.log(seconds); // 15</p>
<pre><code>17. Date.getMilliseconds
밀리초(0 ~ 999)를 나타내는 정수를 반환</code></pre><p>const today = new Date();
const ms = today.getMilliseconds();
console.log(today);
console.log(ms);</p>
<pre><code>18. Date.setMilliseconds
밀리초(0 ~ 999)를 나타내는 정수를 설정</code></pre><p>const today = new Date();
today.setMilliseconds(123); // 밀리초 지정
const ms = today.getMilliseconds();
console.log(ms);    // 123</p>
<pre><code>19. Date.getTime
1970년 1월 1일 00:00:00(UTC)를 기점으로 현재 시간까지 경과된 밀리초를 반환</code></pre><p>const today = new Date();
const time = today.getTime();
console.log(time);  // 1557996968335</p>
<pre><code>20. Date.setTime(time)
1970년 1월 1일 00:00:00(UTC)를 기점으로 현재 시간까지 경과된 밀리초를 설정</code></pre><p>const today = new Date();
today.setTime(86400000); // 86400000 === 1day
const time = today.getTime();
console.log(today); // Fri Jan 02 1970 09:00:00 GMT+0900 (한국 표준시)
console.log(time);  // 86400000</p>
<pre><code>21. Date.getTimezoneOffset
UTC와 사용자 PC 설정 시간의 차이를 분단위로 반환</code></pre><p>const today = new Date().getTimezoneOffset() / 60;
console.log(today); // -9</p>
<pre><code>22. Date.toDateString
사람이 읽을 수 있는 형식의 문자열로 **날짜**를 반환</code></pre><p>const d = new Date(&#39;2019/5/16/18:30&#39;);
console.log(d.toDateString()); // Thu May 16 2019</p>
<pre><code>23. Date.toTimeString
사람이 읽을 수 있는 형식의 문자열로 **시간**을 반환</code></pre><p>const d = new Date(&#39;2019/5/16/18:30&#39;);
console.log(d.toTimeString()); // 18:30:00 GMT+0900 (한국 표준시)
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 23 (Math 객체)]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-23-Math-%EA%B0%9D%EC%B2%B4</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-23-Math-%EA%B0%9D%EC%B2%B4</guid>
            <pubDate>Fri, 03 Jan 2025 08:15:22 GMT</pubDate>
            <description><![CDATA[<p>Math Property</p>
<ol>
<li>Math.PI - PI 값(π ≈ 3.141592653589793)을 반환<pre><code>Math.PI; // 3.141592653589793</code></pre></li>
</ol>
<p>Math Method</p>
<ol>
<li><p>Math.abs(값) - 인수의 절댓값을 반환</p>
<pre><code>Math.abs(-1);       // 1
Math.abs(&#39;-1&#39;);     // 1
Math.abs(&#39;&#39;);       // 0
Math.abs([]);       // 0
Math.abs(null);     // 0
Math.abs(undefined);// NaN
Math.abs({});       // NaN
Math.abs(&#39;string&#39;); // NaN
Math.abs();         // NaN</code></pre></li>
<li><p>Math.round(값) - 인수의 소수점 이하를 반올림한 정수를 반환</p>
<pre><code>Math.round(1.4);  // 1
Math.round(-1.6); // -2
Math.round(1);    // 1
Math.round();     // NaN</code></pre></li>
<li><p>Math.ceil(값) - 인수의 소수점 이하를 올림한 정수를 반환</p>
<pre><code>Math.ceil(1.4);  // 2
Math.ceil(-1.6); // -1
Math.ceil(1);    // 1
Math.ceil();     // NaN</code></pre></li>
<li><p>Math.floor(값) - 인수의 소수점 이하를 내림한 정수를 반환
양수인 경우, 소수점 이하를 떼어 버린 다음 정수를 반환
음수인 경우, 소수점 이하를 떼어 버린 다음 -1을 한 정수를 반환</p>
<pre><code>Math.floor(1.9);  // 1
Math.floor(-9.1); // -10
Math.floor(1);    // 1
Math.floor();     // NaN</code></pre></li>
<li><p>Math.sqrt(값) - 인수의 제곱근을 반환</p>
<pre><code>Math.sqrt(9);  // 3
Math.sqrt(-9); // NaN
Math.sqrt(2);  // 1.414213562373095
Math.sqrt();   // NaN</code></pre></li>
<li><p>Math.random() - 임의의 부동 소수점을 반환
반환된 부동 소수점은 0부터 1 미만-&gt;0은 포함되지만 1은 포함되지 않dma</p>
<pre><code>Math.random(); // 0 ~ 1 미만의 부동 소수점 (0.8208720231391746)
</code></pre></li>
</ol>
<p>// 1 ~ 10의 랜덤 정수 취득
// 1) Math.random로 0 ~ 1 미만의 부동 소수점을 구한 다음, 10을 곱해 0 ~ 10 미만의 부동 소수점을 구한다.
// 2) 0 ~ 10 미만의 부동 소수점에 1을 더해 1 ~ 10까지의 부동 소수점을 구한다.
// 3) Math.floor으로 1 ~ 10까지의 부동 소수점의 소수점 이하를 떼어 버린 다음 정수를 반환한다.
const random = Math.floor((Math.random() * 10) + 1);
console.log(random); // 1 ~ 10까지의 정수</p>
<pre><code>
7. Math.pow(값 1, 값 2) - 첫번째 인수를 밑, 두번째 인수를 지수로하여 거듭제곱을 반환</code></pre><p>Math.pow(2, 8);  // 256
Math.pow(2, -1); // 0.5
Math.pow(2);     // NaN</p>
<pre><code>
8. Math.max(인수 1, 인수 2, ... 또는 리스트) - 인수 중에서 가장 큰 수를 반환</code></pre><p>Math.max(1, 2, 3); // 3</p>
<p>const arr = [1, 2, 3];
Math.max(...arr); // 3</p>
<pre><code>
9. Math.min(인수 1, 인수 2, ... 또는 리스트) - 인수 중에서 가장 작은 수를 반환</code></pre><p>Math.min(1, 2, 3); // 1</p>
<p>// 배열 요소 중에서 최소값 취득
const arr = [1, 2, 3];
Math.min(...arr); // 1
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 22 (Number 객체)]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-22-Number%EA%B0%9D%EC%B2%B4</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-22-Number%EA%B0%9D%EC%B2%B4</guid>
            <pubDate>Fri, 03 Jan 2025 07:49:05 GMT</pubDate>
            <description><![CDATA[<p>Number 객체 - 원시 타입 number를 다룰 때 유용한 프로퍼티와 메소드를 제공하는 레퍼(wrapper) 객체
변수 또는 객체의 프로퍼티가 숫자를 값으로 가지고 있다면 Number 객체의 별도 생성없이 Number 객체의 프로퍼티와 메소드를 사용 가능</p>
<p>원시 타입이 wrapper 객체의 메소드를 사용할 수 있는 이유 - 원시 타입으로 프로퍼티나 메소드를 호출할 때 원시 타입과 연관된 wrapper 객체로 일시적으로 변환되어 프로토타입 객체를 공유하기 때문</p>
<p>Number() 생성자 함수를 통해 Number 객체 생성</p>
<pre><code>new Number(value);</code></pre><p>인자가 숫자로 변환될 수 없다면 NaN을 반환</p>
<pre><code>var x = new Number(123);
var z = new Number(&#39;str&#39;);

console.log(x); // 123
console.log(z); // NaN</code></pre><p>new 연산자를 붙이지 않으면 Number 객체를 반환하지 않고 원시 타입 숫자를 반환
일반적으로 숫자를 사용할 때는 원시 타입 숫자를 사용</p>
<pre><code>console.log(typeof 123); // number
console.log(typeof new Number(123)); // object</code></pre><p>Number 객체 Property</p>
<ol>
<li>Number.EPSILON - JavaScript에서 표현할 수 있는 가장 작은 수
부동소수점 산술 연산 비교는 정확한 값을 기대하기 어려움-&gt;정수는 2진법으로 오차없이 저장이 가능하지만 부동소수점을 표현하는 가장 널리 쓰이는 표준인 IEEE 754은 2진법으로 변환시 무한소수가 되어 미세한 오차가 발생할 수밖에 없는 구조적 한계를 갖음-&gt;부동소수점의 비교는 Number.EPSILON을 사용하여 비교 기능을 갖는 함수를 작성<pre><code>console.log(0.1 + 0.2);        // 0.30000000000000004
console.log(0.1 + 0.2 == 0.3); // false!!!
</code></pre></li>
</ol>
<p>function isEqual(a, b){
  // 즉 a와 b의 차이가 JavaScript에서 표현할 수 있는 가장 작은 수인 Number.EPSILON보다 작으면 같은 수로 인정할 수 있다.
  return Math.abs(a - b) &lt; Number.EPSILON;
}</p>
<p>console.log(isEqual(0.1 + 0.2, 0.3));</p>
<pre><code>
2. Number.MAX_VALUE - 자바스크립트에서 사용 가능한 가장 큰 숫자
MAX_VALUE보다 큰 숫자는 Infinity

3. Number.MIN_VALUE - 자바스크립트에서 사용 가능한 가장 작은 숫자(5e-324)를 반환MIN_VALUE는 0에 가장 가까운 양수 값
MIN_VALUE보다 작은 숫자는 0으로 변환</code></pre><p>console.log(Number.MIN_VALUE &gt; 0); // true</p>
<pre><code>
4. Number.POSITIVE_INFINITY - 양의 무한대 Infinity를 반환
5. Number.NEGATIVE_INFINITY - 음의 무한대 -Infinity를 반환

6. Number.NaN(=window.NaN) - 숫자가 아님을 나타내는 숫자값</code></pre><p>console.log(Number(&#39;xyz&#39;)); // NaN
console.log(1 * &#39;string&#39;);  // NaN
console.log(typeof NaN);    // number</p>
<pre><code>
Number 객체 메소드

1. Number.isFinite(값) - 매개변수에 전달된 값이 정상적인 유한수인지를 검사하여 그 결과를 Boolean으로 반환
Number.isFinite()는 전역 함수 isFinite()와 차이 - 전역 함수 isFinite()는 인수를 숫자로 변환하여 검사를 수행하지만 Number.isFinite()는 인수를 변환하지 않음-&gt;숫자가 아닌 인수가 주어졌을 때 반환값은 언제나 false</code></pre><p>Number.isFinite(NaN)       // false
Number.isFinite(&#39;Hello&#39;)   // false</p>
<p>Number.isFinite(0)         // true
Number.isFinite(null)      // false. isFinite(null) =&gt; true</p>
<pre><code>
2. Number.isInteger(값) - 매개변수에 전달된 값이 정수인지 검사하여 그 결과를 Boolean으로 반환
검사전에 인수를 숫자로 변환하지 않음</code></pre><p>Number.isInteger(-123)  //true
Number.isInteger(5-2)   //true</p>
<p>Number.isInteger(0.5)   //false
Number.isInteger(&#39;123&#39;) //false
Number.isInteger(false) //false
Number.isInteger(-Infinity) //false</p>
<pre><code>
3. Number.isNaN(값) - 매개변수에 전달된 값이 NaN인지를 검사하여 그 결과를 Boolean으로 반환
Number.isNaN()는 전역 함수 isNaN()와 차이-&gt;전역 함수 isNaN()는 인수를 숫자로 변환하여 검사를 수행하지만 Number.isNaN()는 인수를 변환하지 않-&gt;숫자가 아닌 인수가 주어졌을 때 반환값은 언제나 false</code></pre><p>Number.isNaN(NaN)       // true
Number.isNaN(undefined) // false. undefined → NaN. isNaN(undefined) → true.
Number.isNaN({})        // false. {} → NaN.        isNaN({}) → true.
Number.isNaN(&#39;blabla&#39;)  // false. &#39;blabla&#39; → NaN.  isNaN(&#39;blabla&#39;) → true.</p>
<p>Number.isNaN(true)      // false
Number.isNaN(null)      // false
Number.isNaN(37)        // false
Number.isNaN(&#39;37.37&#39;);  // false
Number.isNaN(&#39; &#39;);      // false
Number.isNaN(new Date())             // false
Number.isNaN(new Date().toString())  // false. String → NaN. isNaN(String) → true.</p>
<pre><code>
4. Number.isSafeInteger(값) - 매개변수에 전달된 값이 안전한 정수값인지 검사하여 그 결과를 Boolean으로 반환
안전한 정수값은 -(253 - 1)와 253 - 1 사이의 정수값
검사전에 인수를 숫자로 변환하지 않음</code></pre><p>Number.isSafeInteger(-123)  //true
Number.isSafeInteger(5-2)   //true
Number.isSafeInteger(1000000000000000)  // true</p>
<p>Number.isSafeInteger(10000000000000001) // false
Number.isSafeInteger(0.5)   //false
Number.isSafeInteger(&#39;123&#39;) //false
Number.isSafeInteger(false) //false
Number.isSafeInteger(-Infinity) //false</p>
<pre><code>
5. Number.prototype.toExponential(값) - 대상을 지수 표기법으로 변환하여 문자열로 반환
(지수 표기법 - 매우 큰 숫자를 표기할 때 주로 사용하며 e(Exponent) 앞에 있는 숫자에 10의 n승이 곱하는 형식으로 수를 나타내는 방식
ex)1234 = 1.234e+3)</code></pre><p>var numObj = 77.1234;</p>
<p>console.log(numObj.toExponential());  // logs 7.71234e+1
console.log(numObj.toExponential(2)); // logs 7.71e+1
console.log(77.toExponential());      // SyntaxError: Invalid or unexpected token
console.log(77 .toExponential());     // logs 7.7e+1</p>
<pre><code>
숫자 뒤의 .은 의미가 모호
소수 구분 기호일 수도 있고 객체 프로퍼티에 접근하기 위한 마침표 표기법일 수도-&gt;따라서 자바스크립트 엔진은 숫자 뒤의 .을 부동 소수점 숫자의 일부로 해석
그러나 77.toString()은 숫자로 해석할 수 없으므로 에러(SyntaxError: Invalid or unexpected token)가 발생</code></pre><p>77.toString(); // SyntaxError: Invalid or unexpected token</p>
<pre><code>위 예제의 경우, 숫자 뒤의 첫 번째 . 뒤에는 숫자가 이어지므로 .은 명백하게 부동 소수점 숫자의 일부</code></pre><p>1.23.toString (); // &#39;1.23&#39;</p>
<pre><code>따라서 정수 리터럴과 함께 메소드를 사용할 경우, 아래의 방법을 권장</code></pre><p>(77).toString(); // &#39;77&#39;
77 .toString(); // &#39;77&#39;</p>
<pre><code>
6. Number.prototype.toFixed(값) - 매개변수로 지정된 소숫점자리를 반올림하여 문자열로 반환</code></pre><p>var numObj = 12345.6789;</p>
<p>// 소숫점 이하 반올림
console.log(numObj.toFixed());   // &#39;12346&#39;
// 소숫점 이하 2자리수 유효, 나머지 반올림
console.log(numObj.toFixed(2));  // &#39;12345.68&#39;</p>
<pre><code>
7. Number.prototype.toPrecision(값) - 매개변수로 지정된 전체 자릿수까지 유효하도록 나머지 자릿수를 반올림하여 문자열로 반환
지정된 전체 자릿수로 표현할 수 없는 경우 지수 표기법으로 결과를 반환</code></pre><p>var numObj = 12345.6789;</p>
<p>// 전체자리수 유효
console.log(numObj.toPrecision());   // &#39;12345.6789&#39;
// 전체 2자리수 유효, 나머지 반올림
console.log(numObj.toPrecision(2));  // &#39;1.2e+4&#39;
// 전체 6자리수 유효, 나머지 반올림
console.log(numObj.toPrecision(6));  // &#39;12345.7&#39;</p>
<pre><code>
8. Number.prototype.toString(값) - 숫자를 문자열로 변환하여 반환</code></pre><p>var count = 10;
console.log(count.toString());   // &#39;10&#39;
console.log((17).toString());    // &#39;17&#39;
console.log(17 .toString());     // &#39;17&#39;
console.log((17.2).toString());  // &#39;17.2&#39;</p>
<p>var x = 16;
console.log(x.toString(2));       // &#39;10000&#39;
console.log(x.toString(8));       // &#39;20&#39;
console.log(x.toString(16));      // &#39;10&#39;</p>
<p>console.log((-10).toString(2));   // &#39;-1010&#39;
console.log((-0xff).toString(2)); // &#39;-11111111&#39;</p>
<pre><code>
9. Number.prototype.valueOf() - Number 객체의 원시 타입 값을 반환</code></pre><p>var numObj = new Number(10);
console.log(typeof numObj); // object</p>
<p>var num = numObj.valueOf();
console.log(num);           // 10
console.log(typeof num);    // number
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 21]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-2122</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-2122</guid>
            <pubDate>Thu, 02 Jan 2025 08:17:19 GMT</pubDate>
            <description><![CDATA[<p>전역 객체 - 모든 객체의 유일한 최상위 객체
Browser-side에서는 window, Server-side(Node.js)에서는 global 객체를 의미</p>
<p>실행 컨텍스트 - 실행 컨텍스트는 실행할 코드에 제공할 환경 정보들을 모아놓은 객체
자바스크립트는 동일한 환경에 있는 환경 정보들을 모은 실행 컨텍스트를 콜스택에 쌓아올린 후 실행하여 코드의 환경과 순서를 보장(스택이기 때문에 FILO로 순서보장)</p>
<p>전역 프로퍼티 - 전역 객체의 프로퍼티
애플리케이션 전역에서 사용하는 값들을 나타내기 위해 사용
간단한 값이 대부분이며 다른 프로퍼티나 메소드를 가지고 있지 않음</p>
<ol>
<li>Infinity - 양/음의 무한대를 나타내는 숫자값<pre><code>console.log(3/0);  // Infinity
console.log(typeof Infinity); // number</code></pre></li>
<li>NaN(=Number.NaN) - 숫자가 아님(Not-a-Number)을 나타내는 숫자값 NaN<pre><code>console.log(Number(&#39;xyz&#39;)); // NaN
console.log(1 * &#39;string&#39;);  // NaN
console.log(typeof NaN);    // number</code></pre></li>
<li>undefined<pre><code>var foo;
console.log(foo); // undefined</code></pre></li>
</ol>
<p>전역 함수 - 애플리케이션 전역에서 호출할 수 있는 함수로서 전역 객체의 메소드</p>
<ol>
<li>eval() - 매개변수에 전달된 문자열 구문 또는 표현식을 평가 또는 실행
보안에 매우 취약하므로 가급적으로 금지<pre><code>var x = 5;
var y = 4;
console.log(eval(&#39;x * y&#39;)); // 20</code></pre></li>
<li>isFinite() - 매개변수에 전달된 값이 정상적인 유한수인지 검사하여 그 결과를 Boolean으로 반환
매개변수에 전달된 값이 숫자가 아닌 경우, 숫자로 변환한 후 검사를 수행<pre><code>console.log(isFinite(Infinity));  // false
console.log(isFinite(NaN));       // false
console.log(isFinite(&#39;Hello&#39;));   // false
console.log(isFinite(&#39;2005/12/12&#39;));   // false
</code></pre></li>
</ol>
<p>console.log(isFinite(2e64));      // true
console.log(isFinite(&#39;10&#39;));      // true: &#39;10&#39; → 10
console.log(isFinite(null));      // true: null → 0</p>
<pre><code>3. isNaN() - 매개변수에 전달된 값이 NaN인지 검사하여 그 결과를 Boolean으로 반환
매개변수에 전달된 값이 숫자가 아닌 경우, 숫자로 변환한 후 검사를 수행</code></pre><p>isNaN(NaN)       // true
isNaN(undefined) // true: undefined → NaN
isNaN({})        // true: {} → NaN
isNaN(&#39;blabla&#39;)  // true: &#39;blabla&#39; → NaN</p>
<p>isNaN(null)      // false: null → 0</p>
<p>// strings
isNaN(&#39;37.37&#39;)   // false: &#39;37.37&#39; → 37.37
isNaN(&#39; &#39;)       // false: &#39; &#39; → 0</p>
<p>// dates
isNaN(new Date())             // false: new Date() → Number
isNaN(new Date().toString())  // true:  String → NaN</p>
<pre><code>4. parseFloat() - 매개변수에 전달된 문자열을 부동소수점 숫자로 변환하여 반환
문자열의 첫 숫자만 반환되며 전후 공백은 무시
첫문자를 숫자로 변환할 수 없다면 NaN을 반환</code></pre><p>parseFloat(&#39;10.00&#39;);    // 10
parseFloat(&#39;34 45 66&#39;); // 34
parseFloat(&#39; 60 &#39;);     // 60
parseFloat(&#39;40 years&#39;); // 40
parseFloat(&#39;He was 40&#39;) // NaN</p>
<pre><code>5. parseInt(string: 파싱 대상 문자열, radix: 진법을 나타내는 기수(2 ~ 36, 기본값 or 생략시 10진수)) - 매개변수에 전달된 문자열을 정수형 숫자로 해석하여 반환
반환값은 언제나 10진수</code></pre><p>parseInt(10.123); // 10 - 첫번째 매개변수에 전달된 값이 문자열이 아니면 문자열로 변환한 후 숫자로 해석하여 반환</p>
<pre><code>두번째 매개변수에 진법을 나타내는 기수를 지정하지 않더라도 첫번째 매개변수에 전달된 문자열이 “0x” 또는 “0X”로 시작한다면 16진수로 해석하여 반환
두번째 매개변수에 진법을 나타내는 기수를 지정하지 않더라도 첫번째 매개변수에 전달된 문자열이 “0”로 시작한다면 8진수로 해석하지 않고 10진수로 해석➡️문자열을 8진수로 해석하려면 지수를 반드시 지정
첫번째 매개변수에 전달된 문자열의 첫번째 문자가 해당 지수의 숫자로 변환될 수 없다면 NaN을 반환</code></pre><p>parseInt(&#39;A0&#39;));   // NaN
parseInt(&#39;20&#39;, 2); // NaN</p>
<pre><code>첫번째 매개변수에 전달된 문자열의 두번째 문자부터 해당 진수를 나타내는 숫자가 아닌 문자(예를 들어 2진수의 경우, 2)와 마주치면 이 문자와 계속되는 문자들은 전부 무시되며 해석된 정수값만을 반환</code></pre><p>parseInt(&#39;1A0&#39;));    // 1
parseInt(&#39;58&#39;, 8);   // 5</p>
<pre><code>첫번째 매개변수에 전달된 문자열에 공백이 있다면 첫번째 문자열만 해석하여 반환하며 전후 공백은 무시
첫번째 문자열을 숫자로 파싱할 수 없는 경우, NaN을 반환</code></pre><p>parseInt(&#39;34 45 66&#39;); // 34
parseInt(&#39;He was 40&#39;) // NaN</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 19~20]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-1920</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-1920</guid>
            <pubDate>Fri, 27 Dec 2024 08:34:15 GMT</pubDate>
            <description><![CDATA[<p>객체지향 프로그래밍 - 실세계에 존재하고 인지하고 있는 객체(Object)를 소프트웨어의 세계에서 표현하기 위해 객체의 핵심적인 개념 또는 기능만을 추출하는 추상화를 통해 모델링하려는 프로그래밍 패러다임
우리가 주변의 실세계에서 사물을 인지하는 방식을 프로그래밍에 접목하려는 사상
함수들의 집합 혹은 단순한 컴퓨터의 명령어들의 목록이라는 전통적인 절차지향 프로그래밍과는 다른, 관계성있는 객체들의 집합이라는 관점으로 접근하는 소프트웨어 디자인</p>
<p>클래스 기반 언어 - 클래스로 객체의 자료구조와 기능을 정의하고 생성자를 통해 인스턴스를 생성</p>
<p>자바스크립트는 클래스 개념이 없고 별도의 객체 생성 방법이 존재</p>
<pre><code>// 1. 객체 리터럴
var obj1 = {};
obj1.name = &#39;Lee&#39;;

// 2. Object() 생성자 함수
var obj2 = new Object();
obj2.name = &#39;Lee&#39;;

// 3. 생성자 함수
function F() {}
var obj3 = new F();
obj3.name = &#39;Lee&#39;;</code></pre><p>각각의 인스턴스에 메소드 setName, getName이 중복되어 생성되는 것을 프로토타입을 이용하여 방지</p>
<pre><code>function Person(name) {
  this.name = name;
}

// 프로토타입 객체에 메소드 정의
Person.prototype.setName = function (name) {
  this.name = name;
};

// 프로토타입 객체에 메소드 정의
Person.prototype.getName = function () {
  return this.name;
};

var me  = new Person(&#39;Lee&#39;);
var you = new Person(&#39;Kim&#39;);
var him = new Person(&#39;choi&#39;);

console.log(Person.prototype);
// Person { setName: [Function], getName: [Function] }

console.log(me);  // Person { name: &#39;Lee&#39; }
console.log(you); // Person { name: &#39;Kim&#39; }
console.log(him); // Person { name: &#39;choi&#39; }</code></pre><p>상속 - 새롭게 정의할 클래스가 기존에 있는 클래스와 매우 유사하다면, 상속을 통해 다른 점만 구현
코드 재사용의 관점에서 매우 유용
자바스크립트는 기본적으로 프로토타입을 통해 상속을 구현=프로토타입을 통해 객체가 다른 객체로 직접 상속된다는 의미</p>
<p>자바스크립트 상속 구현</p>
<ol>
<li><p>의사 클래스 패턴 상속 (클래스 기반 언어의 상속 방식을 흉내 내는 것)
자식 생성자 함수의 prototype 프로퍼티를 부모 생성자 함수의 인스턴스로 교체하여 상속을 구현하는 방법
부모와 자식 모두 생성자 함수를 정의</p>
</li>
<li><p>프로토타입 패턴 상속 (프로토타입으로 상속을 구현하는 것)</p>
</li>
</ol>
<p>캡슐화(정보 은닉) - 관련있는 멤버 변수와 메소드를 클래스와 같은 하나의 틀 안에 담고 외부에 공개될 필요가 없는 정보는 숨기는 것</p>
<p>자바스크립트의 객체는 아래와 같이 크게 3가지 - 네이티브 객체, 호스트 객체, 사용자 정의 객체</p>
<p>네이티브 객체 - ECMAScript 명세에 정의된 객체를 말하며 애플리케이션 전역의 공통 기능을 제공
네이티브 객체는 애플리케이션의 환경과 관계없이 언제나 사용 가능
Object, String, Number, Function, Array, RegExp, Date, Math와 같은 객체 생성에 관계가 있는 함수 객체와 메소드로 구성</p>
<p>객체를 생성할 경우 특수한 상황이 아니라면 객체리터럴 방식을 사용하는 것이 일반적</p>
<pre><code>var o = {};</code></pre><pre><code>var x = new Boolean(false);
if (x) { // x는 객체로서 존재한다. 따라서 참으로 간주된다.
  // . . . 이 코드는 실행된다.
}</code></pre><p>호스트 객체 - 브라우저 환경에서 제공하는 window, XmlHttpRequest, HTMLElement 등의 DOM 노드 객체와 같이 호스트 환경에 정의된 객체
예를 들어 브라우저에서 동작하는 환경과 브라우저 외부에서 동작하는 환경의 자바스크립트(Node.js)는 다른 호스트 객체를 사용할 수 있음
브라우저에서 동작하는 환경의 호스트 객체는 전역 객체인 window, BOM(Browser Object Model)과 DOM(Document Object Model) 및 XMLHttpRequest 객체 등을 제공</p>
<p>전역 객체 - 모든 객체의 유일한 최상위 객체를 의미하며 일반적으로 Browser-side에서는 window, Server-side(Node.js)에서는 global 객체를 의미</p>
<p>BOM - 브라우저 객체 모델은 브라우저 탭 또는 브라우저 창의 모델을 생성
최상위 객체는 window 객체로 현재 브라우저 창 또는 탭을 표현하는 객체
이 객체의 자식 객체들은 브라우저의 다른 기능들을 표현
이 객체들은 Standard Built-in Objects가 구성된 후에 구성
<img src="https://velog.velcdn.com/images/hyobi-lim/post/f7fa7876-519d-4f6e-92a8-54297364ac62/image.png" alt=""></p>
<p>DOM - 문서 객체 모델은 현재 웹페이지의 모델을 생성
최상위 객체는 document 객체로 전체 문서를 표현
이 객체의 자식 객체들은 문서의 다른 요소들을 표현
이 객체들은 Standard Built-in Objects가 구성된 후에 구성
<img src="https://velog.velcdn.com/images/hyobi-lim/post/e410bb92-7570-4eda-9428-2206429f4823/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 17~18]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-1718</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-1718</guid>
            <pubDate>Mon, 23 Dec 2024 14:27:50 GMT</pubDate>
            <description><![CDATA[<p>클로저 - 반환된 내부함수가 자신이 선언됐을 때의 환경인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수
자신이 생성될 때의 환경을 기억하는 함수</p>
<pre><code>function outerFunc() {
  var x = 10;
  var innerFunc = function () { console.log(x); };
  return innerFunc;
}

/**
 *  함수 outerFunc를 호출하면 내부 함수 innerFunc가 반환된다.
 *  그리고 함수 outerFunc의 실행 컨텍스트는 소멸한다.
 */
var inner = outerFunc();
inner(); // 10</code></pre><p>자유변수 - 클로저에 의해 참조되는 외부함수의 변수
ex) 위 예제에서 outerFunc 함수의 변수 x</p>
<p>클로저의 활용</p>
<ul>
<li>현재 상태를 기억하고 변경된 최신 상태를 유지</li>
<li>전역 변수의 사용 억제(전역 변수는 언제든지 누구나 접근할 수 있고 변경할 수 있기 때문에 많은 부작용을 유발해 오류의 원인이 되므로 사용을 억제해야 함)</li>
<li>정보의 은닉</li>
<li></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[디자인패턴] 생성패턴, 구조패턴, 행동패턴, 라이브러리, 프레임워크, 싱글톤패턴]]></title>
            <link>https://velog.io/@hyobi-lim/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@hyobi-lim/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Tue, 17 Dec 2024 16:05:11 GMT</pubDate>
            <description><![CDATA[<p>디자인패턴 - 프로그램을 설계할 때 발생했던 문제점들을 객체 간의 상호 관계 등을 이용하여 해결할 수 있도록 하나의 ‘규약’ 형태로 만들어 놓은 것
라이브러리나 프레임워크를 만드는데 기초적인 원리가 되며 지금도 많은 라이브러리, 프레임워크가 어떠한 디자인패턴을 기반으로 만들어지고 있음</p>
<p>디자인패턴 의의 - 디자인패턴들을 미리 배워 놓는다면 이걸 기반으로 여러 문제를 해결하는데 있어서 영감을 받을 수도 있고 팀원들과 협업할 때 어떤 문제가 나타났을 때 “그 부분은 전략패턴”으로 하는게 어떤가요? 라고 했을 때 빠른 의사소통이 가능</p>
<p>디자인패턴 종류</p>
<ol>
<li>생성패턴 - 객체 생성 방법이 들어간 디자인패턴
ex) 싱글톤, 팩토리, 추상팩토리, 빌더, 프로토타입패턴</li>
<li>구조패턴 - 객체, 클래스 등으로 큰 구조를 만들 때 유연하고 효율적으로 만드는 방법이 들어간 디자인패턴
ex) 프록시, 어댑터, 브리지, 복합체, 데코레이터, 퍼사드, 플라이웨이트패턴</li>
<li>행동패턴 - 객체나 클래스 간의 알고리즘, 책임 할당에 관한 디자인패턴
ex) 이터레이터, 옵저버, 전략, 책임연쇄, 커맨드, 중재자, 메멘토, 상태, 템플릿메서드, 비지터패턴</li>
</ol>
<p>라이브러리 - 공통으로 사용될 수 있는 특정한 기능들을 모듈화한 것이며 폴더명, 파일명 등에 대한 규칙이 없고 프레임워크에 비해 자유로움
ex) 차, axios</p>
<p>프레임워크 - 프레임워크는 공통으로 사용될 수 있는 특정한 기능들을 모듈화한 것을 말합니다. 폴더명, 파일명 등에 대한 규칙이 있으며 라이브러리에 비해 좀 더 엄격함
ex) 비행기, vue.js, Django</p>
<p>싱글톤패턴 - 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴
장점: 인스턴스생성에 많은 코스트가 드는 데이터베이스 연결모듈에 많이 쓰이며 인스턴스생성을 효율적
단점: 의존성이 높아지고 TDD를 할 때 불편</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 15~16]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-1516</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-1516</guid>
            <pubDate>Thu, 12 Dec 2024 08:36:13 GMT</pubDate>
            <description><![CDATA[<p>비 블록 레벨 스코프 - 자바스크립트는 블록 레벨 스코프를 사용하지 않으므로 함수 밖에서 선언된 변수는 코드 블록 내에서 선언되었다할지라도 모두 전역 스코프을 갖게됨</p>
<pre><code>if (true) {
  var x = 5;
}
console.log(x);</code></pre><p>자바스크립트는 함수 레벨 스코프(함수 코드 블록 내에서 선언된 변수는 함수 코드 블록 내에서만 유효하고 함수 외부에서는 유효하지 않다(참조할 수 없다)는 것)를 따름
let keyword를 사용하면 블록 레벨 스코프를 사용할 수 있음</p>
<pre><code>var x = 0;
{
  var x = 1;
  console.log(x); // 1
}
console.log(x);   // 1

let y = 0;
{
  let y = 1;
  console.log(y); // 1
}
console.log(y);   // 0</code></pre><p>전역 변수의 사용은 변수 이름이 중복될 수 있고, 의도치 않은 재할당에 의한 상태 변화로 코드를 예측하기 어렵게 만드므로 사용을 억제</p>
<p>함수(지역) 영역에서 전역변수를 참조할 수 있으므로 전역변수의 값도 변경 가능
내부 함수의 경우, 전역변수는 물론 상위 함수에서 선언한 변수에 접근/변경이 가능</p>
<pre><code>var x = 10;

function foo() {
  x = 100;                // var 키워드 생략 시 전역변수 참조
  console.log(x);        // 100
}
foo();
console.log(x);         // 100</code></pre><p>중첩 스코프는 가장 인접한 지역을 우선하여 참조</p>
<pre><code>var x = 10;

function foo(){
  var x = 100;
  console.log(x);

  function bar(){   // 내부함수
    x = 1000;
    console.log(x); // 1000
  }

  bar();
  console.log(x);    // 1000
}
foo();
console.log(x); // 10</code></pre><p>동적 스코프 - 함수를 어디서 호출하였는지에 따라 상위 스코프를 결정하는 것
렉시컬 스코프 또는 정적 스코프 - 함수를 어디서 선언하였는지에 따라 상위 스코프를 결정하는 것</p>
<pre><code>var x = 1;

function foo() {
  var x = 10;
  bar();
}

function bar() {    // 함수 bar는 전역에 선언되으므로 상위 스코프는 전역 스코프
  console.log(x);
}

foo(); // 1
bar(); // 1</code></pre><p>대부분의 프로그래밍 언어는 렉시컬 스코프를 따름</p>
<p>암묵적 전역 - 선언하지 않은 식별자에 값을 할당하면 전역 객체의 프로퍼티로 동적 생성
y는 변수 선언없이 단지 전역 객체의 프로퍼티로 추가되었을 뿐-&gt;y는 변수 X-&gt;y는 변수 호이스팅이 발생 X
변수가 아니라 단지 프로퍼티인 y는 delete 연산자로 삭제할 수 있지만, 전역 변수는 프로퍼티이지만 delete 연산자로 삭제할 수 없음</p>
<pre><code>// 전역 변수 x는 호이스팅이 발생한다.
console.log(x); // undefined
// 전역 변수가 아니라 단지 전역 프로퍼티인 y는 호이스팅이 발생하지 않는다.
console.log(y); // ReferenceError: y is not defined

var x = 10; // 전역 변수

function foo () {
  // 선언하지 않은 식별자(암묵적 전역)
  y = 20;
  console.log(x + y);
}

foo(); // 30
console.log(y);    //20

delete x; // 전역 변수는 삭제되지 않는다.
delete y; // 프로퍼티는 삭제된다.

console.log(window.x); // 10
console.log(window.y); // undefined</code></pre><p>즉시실행함수를 이용한 전역변수 사용 억제 - 즉시 실행 함수는 즉시 실행되고 그 후 전역에서 바로 사라짐
전역변수를 만들지 않으므로 라이브러리 등에 자주 사용</p>
<pre><code>(function () {
  var MYAPP = {};

  MYAPP.student = {
    name: &#39;Lee&#39;,
    gender: &#39;male&#39;
  };

  console.log(MYAPP.student.name);
}());

console.log(MYAPP.student.name);</code></pre><p>strict mode - 자바스크립트 언어의 문법을 보다 엄격히 적용하여 기존에는 무시되던 오류를 발생시킬 가능성이 높거나 자바스크립트 엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적인 에러를 발생
전역의 선두 또는 함수 몸체의 선두에 &#39;use strict&#39;;를 추가하여 적용(But 전역에 적용하는 것은 바람직하지 않음)
strict mode는 즉시실행함수로 감싼 스크립트 단위로 적용하는 것이 바람직</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 13~14]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-1314</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-1314</guid>
            <pubDate>Thu, 12 Dec 2024 06:43:12 GMT</pubDate>
            <description><![CDATA[<p>typeof - 피연산자의 데이터 타입을 문자열로 반환하는 타입 연산자</p>
<pre><code>typeof NaN;             // number
typeof [];              // object
typeof new String();    // object
typeof function () {};  // function
typeof undefined;       // undefined
typeof null;            // object (설계적 결함)
typeof undeclared;      // undefined (설계적 결함)</code></pre><p>Object.prototype.toString - 모든 타입의 값의 타입을 알아낼 수 있음</p>
<pre><code>Object.prototype.toString.call(null);           // [object Null]

//타입을 반환하는 함수
function getType(target) {
  return Object.prototype.toString.call(target).slice(8, -1);
}
getType(null);       // Null</code></pre><p>instanceof - 피연산자인 객체가 우항에 명시한 타입의 인스턴스인지 여부를 알려줌
이때 타입이란 constructor를 말하며 프로토타입 체인에 존재하는 모든 constructor를 검색하여 일치하는 constructor가 있다면 true를 반환</p>
<pre><code>function Person() {}
const person = new Person();

console.log(person instanceof Person); // true
console.log(person instanceof Object); // true</code></pre><p>배열인지 체크하기 위해서는 Array.isArray 메소드를 사용</p>
<pre><code>console.log(Array.isArray([]));    // true
console.log(Array.isArray({}));    // false</code></pre><p>유사 배열 객체 - length 프로퍼티를 갖는 객체
ex) 문자열, arguments, HTMLCollection, NodeList 등
유사 배열 객체는 length 프로퍼티가 있으므로 순회할 수 있으며 call, apply 함수를 사용하여 배열의 메소드를 사용할 수도 있음</p>
<p>클래스 기반 객체지향 프로그래밍 언어 - 객체 생성 이전에 클래스를 정의하고 이를 통해 객체(인스턴스)를 생성
프로토타입 기반 객체지향 프로그래밍 언어 - 클래스 없이도 객체 생성 가능</p>
<p>Prototype
자바스크립트의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결
이것은 마치 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티 또는 메소드를 상속받아 사용할 수 있게 함
이러한 부모 객체를 Prototype(프로토타입)이라고 함</p>
<pre><code>var student = {
  name: &#39;Lee&#39;,
};

// student에는 hasOwnProperty 메소드가 없지만 아래 구문은 동작한다.
console.log(student.hasOwnProperty(&#39;name&#39;)); // true</code></pre><p>[[Prototype]]
함수를 포함한 모든 객체가 가지고 있는 인터널 슬롯
객체의 입장에서 자신의 부모 역할을 하는 프로토타입 객체를 가리키며 함수 객체의 경우 Function.prototype를 가리킴</p>
<pre><code>console.log(Person.__proto__ === Function.prototype);</code></pre><p>prototype 프로퍼티
함수 객체만 가지고 있는 프로퍼티
함수 객체가 생성자로 사용될 때 이 함수를 통해 생성될 객체의 부모 역할을 하는 객체(프로토타입 객체)를 가리킴</p>
<pre><code>console.log(Person.prototype === foo.__proto__);</code></pre><p>constructor 프로퍼티</p>
<pre><code>function Person(name) {
  this.name = name;
}

var foo = new Person(&#39;Lee&#39;);

// Person() 생성자 함수에 의해 생성된 객체를 생성한 객체는 Person() 생성자 함수이다.
console.log(Person.prototype.constructor === Person);

// foo 객체를 생성한 객체는 Person() 생성자 함수이다.
console.log(foo.constructor === Person);

// Person() 생성자 함수를 생성한 객체는 Function() 생성자 함수이다.
console.log(Person.constructor === Function);</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Poiemaweb] JavaScript 11~12]]></title>
            <link>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-111</link>
            <guid>https://velog.io/@hyobi-lim/Poiemaweb-JavaScript-111</guid>
            <pubDate>Tue, 10 Dec 2024 16:10:51 GMT</pubDate>
            <description><![CDATA[<p>변경 불가능한 값(immutable value)은 메모리 영역에서의 변경(수정)이 불가능하다는 뜻
재할당은 가능</p>
<pre><code>var str = &#39;Hello&#39;;
str = &#39;world&#39;;        //변경 X, 재할당 O, 둘 다 메모리에 존재</code></pre><pre><code>var arr = [];
console.log(arr.length); // 0

var v2 = arr.push(2);    // arr.push()는 메소드 실행 후 arr의 length를 반환
console.log(arr.length); // 1</code></pre><p>복사본을 리턴하는 문자열의 메소드 slice()와는 달리 배열(객체)의 메소드 push()는 직접 대상 배열을 변경-&gt;배열은 객체이고 객체는 immutable value가 아닌 변경 가능한 값이기 때문</p>
<p>Object.assign(target, ...sources) - 타킷 객체로 소스 객체의 프로퍼티를 복사
Shallow copy(deep copy 지원 X)</p>
<pre><code>const obj = { a: 1 };
const copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }
console.log(obj == copy); // false</code></pre><p>Object.freeze() - 불변(immutable) 객체로 변경
deep copy가 아니기 때문에 객체 내부의 객체는 변경가능</p>
<pre><code>const user = {
  name: &#39;Lee&#39;,
  address: {
    city: &#39;Seoul&#39;
  }
};
Object.freeze(user);
user.name = &#39;Kim&#39;; // 무시된다!
console.log(Object.isFrozen(user)); // true
user.address.city = &#39;Busan&#39;; // 변경된다!</code></pre><p>Immutable.js - &quot;npm install immutable&quot;으로 설치</p>
<pre><code>const { Map } = require(&#39;immutable&#39;)
const map1 = Map({ a: 1, b: 2, c: 3 })
const map2 = map1.set(&#39;b&#39;, 50)
map1.get(&#39;b&#39;) // 2        //map1.set(‘b’, 50)의 실행에도 불구하고 map1은 불변
map2.get(&#39;b&#39;) // 50        //map1.set()은 결과를 반영한 새로운 객체를 반환</code></pre><p>함수 선언문 - 자바스크립트 엔진이 내부적으로 기명 함수표현식으로 변환</p>
<pre><code>function square(number) {
  return number * number;
}

//자바스크립트 엔진이 내부적으로 기명 함수표현식으로 변환
var square = function square(number) {
  return number * number;
};</code></pre><p>함수 표현식</p>
<pre><code>// 기명 함수 표현식(named function expression)
var foo = function multiply(a, b) {
  return a * b;
};

// 익명 함수 표현식(anonymous function expression)
var bar = function(a, b) {
  return a * b;
};

console.log(foo(10, 5)); // 50
console.log(multiply(10, 5)); // Uncaught ReferenceError: multiply is not defined</code></pre><p>변수는 함수명이 아니라 할당된 함수를 가리키는 참조값을 저장
함수 호출시 함수명이 아니라 함수를 가리키는 변수명을 사용해야 함</p>
<p>=&gt;함수선언식, 함수표현식 모두 함수 리터럴 방식을 사용</p>
<p>자바스크립트는 함수 호출 시 함수 정의에 따라 인수를 전달하지 않아도 에러 발생 X
인수가 전달되지 않은 매개변수는 undefined으로 초기화, 초과된 인수는 무시
함수.length = 함수 매개변수 갯수</p>
<p>호이스팅 - 모든 선언문이 해당 Scope의 선두로 옮겨진 것처럼 동작하는 특성(선언문이 선언되기 이전에 참조 가능)
자바스크립트는 let, const를 포함하여 모든 선언(var, let, const, function, function*, class)을 호이스팅 함</p>
<p>함수 호이스팅 - 함수 선언의 위치와는 상관없이 코드 내 어느 곳에서든지 호출이 가능(<strong>함수 선언문</strong>)</p>
<p>변수 호이스팅 - 변수 생성 및 초기화와 할당이 분리되어 진행(<strong>함수 표현식</strong>)
호이스팅된 변수는 undefined로 초기화 되고 실제값의 할당은 할당문에서 이루어짐</p>
<p>함수 표현식만을 사용할 것을 권고 - 함수 호이스팅이 함수 호출 전 반드시 함수를 선언하여야 한다는 규칙을 무시하기 때문</p>
<p>일급 객체 - 생성, 대입, 연산, 인자 또는 반환값으로서의 전달 등 프로그래밍 언어의 기본적 조작을 제한없이 사용할 수 있는 대상
ex) 함수
일급 객체 조건</p>
<ol>
<li>무명의 리터럴로 표현이 가능하다.</li>
<li>변수나 자료 구조(객체, 배열 등)에 저장할 수 있다.</li>
<li>함수의 매개변수에 전달할 수 있다.</li>
<li>반환값으로 사용할 수 있다.</li>
</ol>
<p>반환값
배열 등을 이용하여 한 번에 여러 개의 값을 리턴 가능
반환 생략 가능</p>
<p>콜백 함수 - 함수를 명시적으로 호출하는 방식이 아니라 특정 이벤트가 발생했을 때 시스템에 의해 호출되는 함수
ex) 이벤트 핸들러 처리</p>
]]></description>
        </item>
    </channel>
</rss>