<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>프론트엔드 공부한 거 정리하기</title>
    <link>https://frdytheme.tistory.com/</link>
    <description>노트처럼 쓰는 블로그라 정리 안 된 내용이 많습니다.</description>
    <language>ko</language>
    <pubDate>Sat, 1 Aug 2026 02:13:03 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>FRDYtheme</managingEditor>
    <item>
      <title>쿠키와 세션의 특징</title>
      <link>https://frdytheme.tistory.com/139</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;쿠키와 세션은 HTTP 프로토콜의 약점을 보완하기 위해서 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 프로토콜은 요청에 대한 응답이 완료되면 연결이 끊어지기 때문에 상태의 정보가 유지되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;고속도로에서 하이패스를 이용해봤다면 얘기가 조금 쉽다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하이패스 카드가 있으면 알아서 인식하고 결제가 되므로 별도의 동작 없이 지나가면 되지만&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;없으면 멈춰서 지갑을 꺼내 맞는 금액을 직접 지불해야하는 동작이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 요청은 후자를 말한다. 톨게이트를 만날 때마다 멈춰서 일련의 동작을 해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠키와 세션은 하이패스 카드와 비슷하다. 뺏기면 안되기 때문에 보안 또한 더욱 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쿠키(Cookie)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;쿠키는 클라이언트에 저장되며 키와 값이 들어있는 작은 데이터 파일&lt;/li&gt;
&lt;li&gt;유효 기간을 명시할 수 있으며, 유효 기간 내에서는 사용이 가능하다.&lt;/li&gt;
&lt;li&gt;상태 정보를 로컬에 저장하고 참조한다.&lt;/li&gt;
&lt;li&gt;HTTP 요청 시 헤더에 포함해서 서버로 전송할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쿠키 사용의 대표 예&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 인증 및 권한 관리&lt;/li&gt;
&lt;li&gt;장바구니 기능&lt;/li&gt;
&lt;li&gt;자동 로그인 등 사용자 설정 저장&lt;/li&gt;
&lt;li&gt;광고 타겟팅&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쿠키의 발급 과정&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;클라이언트에서 HTTP 요청&lt;/li&gt;
&lt;li&gt;서버에서 쿠키를 생성해서 클라이언트에 반환&lt;/li&gt;
&lt;li&gt;이후 HTTP 요청 시 헤더에 쿠키를 담아 요청&lt;/li&gt;
&lt;li&gt;서버에서 쿠키를 검증하고 알맞은 응답을 반환&lt;/li&gt;
&lt;li&gt;쿠키의 갱신이나 정보 변경이 필요한 경우 서버에서 변경 후 반환&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;세션(Session)&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;세션은 서버에 저장되며 쿠키에 비해 큰 용량을 저장할 수 있다.&lt;/li&gt;
&lt;li&gt;브라우저를 닫거나 세션ID가 삭제되면 세션은 종료되며 데이터가 삭제된다. 유효 기간 설정도 가능.&lt;/li&gt;
&lt;li&gt;상태 정보를 서버 메모리, 데이터베이스 또는 파일 시스템에 저장한다.&lt;/li&gt;
&lt;li&gt;사용자의 정보를 서버에 두기 때문에 쿠키보다 보안이 좋지만, 사용량이 많을 경우 서버에 무리가 감.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;세션 사용의 대표 예&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자 인증 및 권한 관리&lt;/li&gt;
&lt;li&gt;장바구니 기능&lt;/li&gt;
&lt;li&gt;웹 폼의 데이터 유지 등&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;세션의 발급 과정&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;클라이언트가 서버에 최초 요청을 보낸다.&lt;/li&gt;
&lt;li&gt;서버는 클라이언트에게 고유 세션 ID를 발급하며 쿠키로 전송한다.&lt;/li&gt;
&lt;li&gt;이후의 모든 클라이언트의 요청에 세션 ID를 포함한다.&lt;/li&gt;
&lt;li&gt;서버는 세션 ID와 세션의 상태를 체크해 데이터를 관리한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쿠키와 세션의 차이점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;쿠키와 세션은 동작 원리와 발급 과정 모두 비슷하지만, 저장되는 장소가 어딘지에 큰 차이가 있으며 용량의 차이도 있다.&lt;/li&gt;
&lt;li&gt;보안 면에서는 세션이 쿠키보다 우수하지만 요청 속도는 쿠키가 세션보다 우수하다.&lt;/li&gt;
&lt;li&gt;쿠키와 세션 모두 만료 시간을 정의할 수 있지만, 세션은 쿠키와 달리 브라우저가 종료되면 삭제된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개념정리</category>
      <author>FRDYtheme</author>
      <guid isPermaLink="true">https://frdytheme.tistory.com/139</guid>
      <comments>https://frdytheme.tistory.com/139#entry139comment</comments>
      <pubDate>Tue, 31 Oct 2023 19:10:54 +0900</pubDate>
    </item>
    <item>
      <title>attribute와 property의 차이</title>
      <link>https://frdytheme.tistory.com/138</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;어트리뷰트(attribute)는 HTML의 속성으로 Element의 id, class, type 등의 추가적인 정보를 일컫는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로퍼티(property)는 DOM의 속성으로 html의 어트리뷰트를 부르는 이름이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 같은 속성을 불러오는 이름만 다른 것.&lt;/p&gt;
&lt;pre id=&quot;code_1698744651112&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;div class=&quot;box&quot; style=&quot;color: #000;&quot;&amp;gt;&amp;lt;/div&amp;gt;
// 여기서 class와 color는 attribute

document.querySelector(&quot;.box&quot;).className; // box
document.querySelector(&quot;.box&quot;).style.color; // #000
// 여기서 className과 style.color는 Property&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트를 통해 DOM의 프로퍼티 속성으로 HTML의 어트리뷰트 속성에 접근할 수 있으며 동적으로 값을 변경하는 것이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개념정리</category>
      <author>FRDYtheme</author>
      <guid isPermaLink="true">https://frdytheme.tistory.com/138</guid>
      <comments>https://frdytheme.tistory.com/138#entry138comment</comments>
      <pubDate>Tue, 31 Oct 2023 18:37:49 +0900</pubDate>
    </item>
    <item>
      <title>CSR과 SSR의 차이점과 특징</title>
      <link>https://frdytheme.tistory.com/137</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;각 CSR(Client-Side-Rendering)과 SSR(Server-Side-Rendering)으로 웹 애플리케이션을 구축하는 두 가지 주요한 방식.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;CSR의 특징&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 클라이언트 중심 렌더링: HTML 및 JavaScript 파일을 클라이언트(브라우저)로 다운로드한 후, 브라우저에서 JavaScript를 사용하여 페이지의 렌더링을 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 초기 로딩 시간: 페이지 초기 로딩 시간이 느릴 수 있지만 로딩 이후 반응이 빠르기 때문에, 사용자 경험을 향상시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 빠른 네비게이션: 페이지가 로드된 후, 클라이언트에서 페이지 전환 또는 라우팅이 빠르다, 비동기 요청을 통해 데이터를 가져오는 방식을 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. SEO 어려움: 검색 엔진 최적화에 어려움이 있을 수 있으며, 추가적인 작업이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;SSR의 특징&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 서버 중심 렌더링: 서버에서 페이지의 HTML을 동적으로 생성하고 클라이언트에 전달하며 클라이언트는 렌더링된 HTML을 브라우저에 표시한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 초기 로딩 시간: 페이지 초기 로딩 시간이 빠르지만, JS파일이 읽히기 전이므로 기능을 이용할 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TTV(Time to View)와 TTI(Time to Interact)의 시간 간격이 존재함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. SEO 용이: 검색 엔진에서 페이지의 콘텐츠를 쉽게 파악하며, SEO에 유리하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 서버 부하: 서버가 페이지의 HTML을 동적으로 생성하므로 서버 부하가 발생할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 초기 렌더링이 완료된 HTML 제공: 첫 번째 로드 시에 이미 렌더링된 HTML이 전송되므로 클라이언트 측에서 추가 렌더링이 필요 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개념정리</category>
      <author>FRDYtheme</author>
      <guid isPermaLink="true">https://frdytheme.tistory.com/137</guid>
      <comments>https://frdytheme.tistory.com/137#entry137comment</comments>
      <pubDate>Tue, 31 Oct 2023 18:25:30 +0900</pubDate>
    </item>
    <item>
      <title>CORS? Cross-Origin-Resource-Sharing에 대해</title>
      <link>https://frdytheme.tistory.com/136</link>
      <description>&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #374151; text-align: start;&quot;&gt;웹 브라우저는&lt;span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #373e48; text-align: left;&quot;&gt;해커가 CSRF(Cross-Site Request Forgery)나 XSS(Cross-Site Scripting) 등을 이용해 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #373e48; text-align: left;&quot;&gt;개인정보를 탈취하는 상황을 막기 위해&lt;span&gt; &lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #374151; text-align: start;&quot;&gt;동일 출처 정책 (Same-Origin Policy)&lt;/span&gt;&lt;/b&gt; 을 통해 &lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;다른 출처의 스크립트나 요청이 실행되는 걸 막는다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323; text-align: start;&quot;&gt;출처(Origin) : &lt;/span&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;url의 프로토콜, 호스트, 포트를 합친 것 ( - http://localhost:3000 )&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;이 SOP에 의해 서버 요청이 차단될 때 &lt;span style=&quot;color: #374151; text-align: start;&quot;&gt;CORS 에러가 &lt;/span&gt;발생하는데 사실 에러는 아니고 CORS를 이용하면 다른 출처의 리소스를 가져올 수 있는 해결책이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #374151;&quot;&gt;그럼 웹 문서에 모든 출처 정책은 Same-Origin인가?&lt;/span&gt;&lt;span style=&quot;color: #374151;&quot;&gt;그렇지 않다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #374151;&quot;&gt;HTML태그 중 Cross-Origin을 지원하는 태그가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #374151;&quot;&gt;&amp;lt;img&amp;gt; &amp;lt;script&amp;gt; &amp;lt;link&amp;gt;의 href와 src 속성은 다른 출처의 리소스에 접근하는 것이 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;* &amp;lt;script type=&quot;module&quot;&amp;gt;은 불가능.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;하지만 자바스크립트에서의 요청은 기본적으로 SOP를 따른다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. XMLHttpRequest&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. Fetch API 요청&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;3. 웹 폰트, 이미지, 스크립트 및 스타일 시트와 같은 외부 리소스에 대한 요청&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;CORS 해결 방법&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1. 클라이언트에서 HTTP요청의 헤더에 Origin을 담아 전달&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 서버는 응답헤더에 Access-Control-Allow-Origin을 담아 클라이언트에 전달.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 클라이언트에서 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교해서 유효하다면 리소스를 받게 되고 유효하지 않다면 에러가 발생한다.&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;즉, 서버에서 헤더에 허용할 출처를 기재해주어야 리소스의 요청이 가능해진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개념정리</category>
      <author>FRDYtheme</author>
      <guid isPermaLink="true">https://frdytheme.tistory.com/136</guid>
      <comments>https://frdytheme.tistory.com/136#entry136comment</comments>
      <pubDate>Tue, 31 Oct 2023 17:57:21 +0900</pubDate>
    </item>
    <item>
      <title>브라우저의 동작 원리</title>
      <link>https://frdytheme.tistory.com/135</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;브라우저에 &quot;www.google.com&quot; 주소를 입력하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 웹 브라우저는 DNS서버에 해당 도메인의 IP주소를 요청하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. DNS 해석기는 해당 요청을 일정 기간 캐싱하여 동일한 요청에 대한 빠른 응답을 대비하기 때문에 (Time to live, TTL)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;캐싱된 데이터가 있다면 DNS서버에 요청하지 않고 바로 IP주소를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. DNS서버로부터 받은 IP주소를 이용하여 HTML, CSS, JS 문서 등을 다운로드 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 브라우저의 렌더링 엔진이 HTML문서를 파싱해 DOM트리를 구축하고 CSS문서를 파싱해 CSSOM트리를 구축한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. DOM트리와 CSSOM트리를 합쳐 렌더 트리를 구축하고 레이아웃을 통해 요소의 위치와 크기를 계산한 후에 페인팅을 통해 브라우저에 나타나게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 그 과정에서 script 태그를 만나면 JS에서 요소를 변경시킬 수 있기 때문에&amp;nbsp; 렌더링 엔진은 JS엔진에게 제어권을 넘긴고 기다린다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;그래서 DOM트리 구축 전에 JS에서 요소를 탐색하거나 변경하려하면 오류가 발생한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&amp;lt;body&amp;gt;태그 아래에 &amp;lt;script&amp;gt;태그를 쓰는 이유다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 만약 스크립트를 통해 DOM 요소의 조작이 일어나면 필요한 부분을 계산해 렌더 트리를 수정하고, 리플로우, 리페인트의 과정을 거쳐 다시 화면을 출력한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;요소의 크기나 위치의 변경 없이 background-color, visibility 등의 스타일 변화만 있는 경우에는 리페인트만 발생한다.&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;리플로우와 리페인트의 발생을 최적화하는 것이 사용자 경험을 향상시키는 데에 도움이 된다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개념정리</category>
      <author>FRDYtheme</author>
      <guid isPermaLink="true">https://frdytheme.tistory.com/135</guid>
      <comments>https://frdytheme.tistory.com/135#entry135comment</comments>
      <pubDate>Tue, 31 Oct 2023 17:12:40 +0900</pubDate>
    </item>
    <item>
      <title>[Python] 기본 자료형 - 1. 숫자형</title>
      <link>https://frdytheme.tistory.com/132</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;파이썬의 자료형 정리&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 숫자형&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숫자로 이루어진 자료형, 정수(123) / 실수(12.34) / 8진수(0o34) / 16진수(0x2A) 등&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정수형(integer)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;양의 정수와 음의 정수&lt;/p&gt;
&lt;pre id=&quot;code_1682057633132&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = 123
a = -486
a = 0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;실수형(Floating-point)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬에서 실수형은 소수점이 포함된 숫자.&lt;/p&gt;
&lt;pre id=&quot;code_1682057747817&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;b = 1.5
b = -5.25&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8진수와 16진수&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8진수는 숫자가 0o 혹은 0O로 시작&lt;/p&gt;
&lt;pre id=&quot;code_1682058817518&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;c = 0o486&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;16진수는 숫자가 0x로 시작&lt;/p&gt;
&lt;pre id=&quot;code_1682058882061&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;d = 0x6df&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style2&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;숫자형 연산자&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 더하기(+), 빼기(-), 나누기(/), 곱하기(*)&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1682058972432&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = 3
b = 4

a + b
# 7
b - a
# 1
a * b
# 12
a / b
# 0.75&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 거듭제곱 ** 연산자&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1682059116761&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = 2
b = 5
a ** b
# 32&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. 나눈 후 나머지 값을 반환하는 % 연산자&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1682059184900&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;a = 10
b = 3
a % b
# 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 나눗셈 후 몫을 반환하는 // 연산자&lt;/p&gt;
&lt;pre id=&quot;code_1682059241032&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;9 // 4
# 2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Python</category>
      <author>FRDYtheme</author>
      <guid isPermaLink="true">https://frdytheme.tistory.com/132</guid>
      <comments>https://frdytheme.tistory.com/132#entry132comment</comments>
      <pubDate>Fri, 21 Apr 2023 15:41:09 +0900</pubDate>
    </item>
    <item>
      <title>[JavaScript] 생성자 함수와 클래스</title>
      <link>https://frdytheme.tistory.com/131</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;생성자 함수는 객체를 생성하기 위한 템플릿 역할을 하는 함수다. 붕어빵 틀이나 거푸집이라고 생각하면 될 듯.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1681113769557&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Person(name, age) { // 거푸집
  this.name = name;
  this.age = age;
}

const person1 = new Person('John', 30); // 팥 붕어빵
const person2 = new Person('Jane', 25); // 슈크림 붕어빵&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이 생성자 함수를 통해 생성된 객체는 각자 다른 메모리에 저장되어 참조된다. 즉, 키나 값을 바꿔도 되는 고유한 객체가 됨&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;특징&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;생성자 함수는 첫 글자를 대문자로 쓰는 게 관례라고 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;생성자 함수를 통해 생성된 객체는 생성자 함수의 프로토타입을 상속받는데, 인스턴스 메서드를 프로토타입에 추가하면 하나의 메서드를 모두가 공유할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1681114005582&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function Person(name, age) { // 생성자 함수
  this.name = name;
  this.age = age;
}

Person.prototype.sayName = function() { // 붕어빵들이 공유하는 인스턴스 메서드1
  console.log(`My name is ${this.name}.`);
};

Person.prototype.sayAge = function() { // 붕어빵들이 공유하는 인스턴스 메서드1
  console.log(`I am ${this.age} years old.`);
};

const person1 = new Person(&quot;John&quot;, 30); // 팥 붕
const person2 = new Person(&quot;Jane&quot;, 25); // 슈 붕

person1.sayName(); // &quot;My name is John.&quot;
person1.sayAge(); // &quot;I am 30 years old.&quot;

person2.sayName(); // &quot;My name is Jane.&quot;
person2.sayAge(); // &quot;I am 25 years old.&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;생성자 함수 내부에 메서드를 프로퍼티로 추가하지 않고 .prototype을 작성해서 프로토타입에 추가하는 이유는&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;전자로 메서드를 작성하면 객체가 생성될 때마다 메서드도 중복 생성되면서 메모리가 늘어나기 때문.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;ES+6 클래스 문법&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클래스는 객체를 생성하기 위한 설계도라고 생각하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1681115134485&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class ClassName {
  constructor(parameter1, parameter2, ...) {
    // 인스턴스 생성 시 초기화할 코드 작성
  }

  method1(parameter1, parameter2, ...) {
    // 메서드 코드 작성
  }

  method2(parameter1, parameter2, ...) {
    // 메서드 코드 작성
  }

  // ...
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;생성자 함수와 마찬가지로, 클래스에는 constructor라는 특수한 메서드가 있는데, 이는 객체가 생성될 때 자동으로 호출.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;내부에 객체를 초기화하는 코드를 작성할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위에 생성자 함수는 내부에 메서드를 작성하면 생성되는 객체가 메서드를 중복 생성하면서 메모리가 비효율적이지만&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt; 클래스 문법은 내부에 메서드를 작성하면 ClassName.prototype에 저장되어 생성된 객체가 이를 공유한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;클래스를 통한 객체 생성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1681115285517&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const obj = new ClassName(arg1, arg2, ...);&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;클래스.prototype에 저장된 메서드 호출&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1681115364085&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;obj.method1(arg1, arg2, ...);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클래스는 상속을 지원하며, extends 키워드를 사용해 부모 클래스를 상속받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상속 받은 자식 클래스에서 부모 클래스의 메서드 호출 가능.&lt;/p&gt;
&lt;pre id=&quot;code_1681115421341&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class ChildClassName extends ParentClassName {
  constructor(parameter1, parameter2, ...) {
    super(parameter1, parameter2, ...);
    // 자식 클래스에서 초기화할 코드 작성
  }

  method1(parameter1, parameter2, ...) {
    super.method1(parameter1, parameter2, ...);
    // 자식 클래스에서 오버라이드한 메서드 코드 작성
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;부모 클래스를 상속한 자식 클래스에서 부모 클래스의 생성자 함수를 호출하기 위해 super 키워드를 작성해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 부모 클래스의 설정을 불러오는 키워드라고 보면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;super로 부모 클래스를 상속받아 그대로 사용하거나 내용을 추가할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681115640509&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Animal { // 부모 클래스 Animal
  constructor(name, age) { // 초기화 함수 constructor
    this.name = name;
    this.age = age;
  }

  speak() { // 부모 클래스 메서드
    console.log(`${this.name} makes a sound.`);
  }
}

class Cat extends Animal { // 자식 클래스 Cat
  constructor(name, age, breed) { // 부모 클래스의 name,age 구조 상속받고 breed 구조 추가
    super(name, age); // 부모 클래스 생성자 호출
    this.breed = breed;
  }

  meow() { // 자식 클래스의 메서드.
    console.log(`${this.name} meows.`);
  }
}

const fluffy = new Cat('Fluffy', 2, 'Persian');
fluffy.speak(); // &quot;Fluffy makes a sound.&quot; // 자식 클래스는 부모 클래스의 메서드 사용 가능.
fluffy.meow(); // &quot;Fluffy meows.&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;생성자 함수와 클래스 문법의 차이점&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 문법 : 생성자 함수는 함수 선언문으로 작성(화살표 함수 불가능), 클래스는 class 키워드로 작성하며 첫 문자는 대문자 관례.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;2. 상속 : 생성자 함수는 프로토타입 체인을 통해 상속을 구현하고, 클래스는 extends 키워드를 사용해 상속을 구현.&lt;/span&gt;&lt;span style=&quot;&quot;&gt;3. 메서드 : 생성자 함수는 프로토타입 객체에 직접 할당하며, 클래스는 클래스 본문 내부에 메서드를 정의.&lt;/span&gt;&lt;span style=&quot;&quot;&gt;4. 생성자 : 생성자 함수에서는 생성자 함수의 이름과 동일한 메서드를 정의하여 객체를 초기화, 클래스에서는 constructor 메서드를 사용해 객체를 초기화.&lt;/span&gt;&lt;span style=&quot;&quot;&gt;5. 변수 호이스팅 : 클래스는 변수 호이스팅이 발생하지 않으며, 생성자 함수는 변수 호이스팅이 발생한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1681116938778&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
	클래스가 호이스팅이 발생하지 않는 이유
    
    클래스는 호이스팅이 되지 않는 것이 아니라 클래스 선언문 자체가 호이스팅이 되기 때문.
    클래스는 let 또는 const와 마찬가지로 블록 스코프를 갖기 때문에
    해당 클래스가 선언된 블록 내에서만 유효하며 클래스 내부에서 선언된 변수나 메서드는
    해당 클래스가 인스턴스화되어야만 사용할 수 있기 때문에, 호이스팅이 발생하지 않는다.
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;6. 상수 정의 : 클래스에서는 상수를 static 키워드와 함께 정의할 수 있으며, 생성자 함수에서는 상수를 정의할 수 없다.&lt;/span&gt;&lt;span style=&quot;&quot;&gt;7. 추상화 : 클래스에서는 추상 클래스와 추상 메서드를 지원하며, 생성자 함수는 지원하지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1681117568689&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/*
	추상 클래스와 추상 메서드는 일반적인 클래스나 메서드와는 다르게
    구체적인 구현이 없이 선언만 되어 있는 것을 말한다.
    즉, 추상 클래스는 인스턴스를 생성할 수 없으며
    추상 메서드는 하위 클래스에서 구현되어야 한다.
    
	예를 들어, 동물 클래스를 추상 클래스로 선언한다면
    각 동물의 종류마다 구현이 달라지기 때문에 인스턴스를 생성할 수 없고
    하위 클래스에서 해당 종류에 맞는 메서드를 구현하도록 강제할 수 있다.
    
    추상 메서드를 사용하여 '소리를 낸다' 메서드를 강제하는 것도 가능.
    이때, 추상 메서드는 하위 클래스에서 해당 메서드를 반드시 구현해야 하므로
    동물 클래스와 같이 인스턴스를 생성할 수 없다.

	따라서 추상 클래스와 추상 메서드는 상속과 다형성을 구현하는 데 매우 유용.
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681117582345&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 추상 클래스
class Animal {
  constructor(name) {
    this.name = name;
  }

  // 추상 메서드
  makeSound() {
    throw new Error('Subclass must implement abstract method');
  }
}

// 추상 클래스를 상속받은 하위 클래스
class Dog extends Animal {
  constructor(name) {
    super(name);
  }

  // 추상 메서드를 구현
  makeSound() {
    console.log('멍멍');
  }
}

// 추상 클래스를 상속받은 다른 하위 클래스
class Cat extends Animal {
  constructor(name) {
    super(name);
  }

  // 추상 메서드를 구현
  makeSound() {
    console.log('야옹');
  }
}

// 추상 클래스의 인스턴스를 만들 수 없음
const animal = new Animal('동물'); // Error: Can't instantiate abstract class

// 추상 클래스를 상속받은 하위 클래스의 인스턴스를 생성하여 사용
const dog = new Dog('개');
dog.makeSound(); // 멍멍

const cat = new Cat('고양이');
cat.makeSound(); // 야옹&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;&quot;&gt;&lt;span style=&quot;background-color: #444654; color: #d1d5db; text-align: start;&quot;&gt;참고로 자바스크립트에서는 클래스를 직접적으로 지원하지 않으므로, 클래스 내부에 추상 메서드가 하나 이상 있다면 해당 클래스는 추상 클래스로 간주할 수 있다. 추상 메서드는 구현부가 없고 메서드 이름과 매개변수만을 선언하며, 자식 클래스에서 반드시 구현해야 한다. 따라서 자식 클래스에서 구현하지 않으면 에러가 발생.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>JavaScript</category>
      <author>FRDYtheme</author>
      <guid isPermaLink="true">https://frdytheme.tistory.com/131</guid>
      <comments>https://frdytheme.tistory.com/131#entry131comment</comments>
      <pubDate>Mon, 10 Apr 2023 18:07:17 +0900</pubDate>
    </item>
    <item>
      <title>[JavaScript] Map 객체 / new Map 생성자</title>
      <link>https://frdytheme.tistory.com/130</link>
      <description>&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Map객체&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Map 객체는 '키'와 '값'으로 이루어진 컬렉션으로 자바스크립트의 기본 객체인 Object와 달리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;키가 반드시 문자열이 아니어도 되며, 다양한 데이터 타입을 키와 값으로 활용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Map객체 생성&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1681011868785&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 빈 Map 객체 생성하기
const map = new Map();

// 이터러블 객체를 전달하여 Map 객체 생성하기
const arr = [['name', 'John'], ['age', 30]];
const map2 = new Map(arr);&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Map객체의 기본 동작&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;set(key, value) : 키-값 쌍을 추가한다. 기존에 동일한 키가 존재하면 값 대체.&lt;/p&gt;
&lt;pre id=&quot;code_1681012126133&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const map = new Map();
map.set('name', 'John'); // 요소 추가
map.set('name', 'Jane'); // 요소 갱신
map.set('age', 30); // 새로운 요소 추가&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;get(key) : 키에 해당하는 값을 반환. 키가 존재하지 않으면 undefined 반환.&lt;/p&gt;
&lt;pre id=&quot;code_1681012132955&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const map = new Map();
map.set('name', 'John');
map.set('age', 30);
console.log(map.get('name')); // 'John'
console.log(map.get('age')); // 30&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;has(key) : Map객체가 해당 키를 갖고 있는 지 확인. 존재하면 true 아니면 false 반환.&lt;/p&gt;
&lt;pre id=&quot;code_1681012141434&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const map = new Map();
map.set('name', 'John');
console.log(map.has('name')); // true
console.log(map.has('age')); // false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;delete(key) : 주어진 키와 값을 삭제. 삭제에 성공하면 true, 실패하면 false 반환.&lt;/p&gt;
&lt;pre id=&quot;code_1681012149164&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const map = new Map();
map.set('name', 'John');
map.set('age', 30);
map.delete('name'); // 요소 삭제
map.delete('gender'); // 해당 키가 없으면 실패하고 false 반환&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;clear() : Map객체의 모든 요소를 제거.&lt;/p&gt;
&lt;pre id=&quot;code_1681012155707&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const map = new Map();
map.set('name', 'John');
map.set('age', 30);
map.clear(); // 모든 요소 제거&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;size() : Map객체의 요소 크기 반환.&lt;/p&gt;
&lt;pre id=&quot;code_1681012164463&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const map = new Map();
map.set('name', 'John');
map.set('age', 30);
console.log(map.size); // 2&lt;/code&gt;&lt;/pre&gt;
&lt;div style=&quot;background-color: #000000;&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Map객체의 이터레이션&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이터레이션(iteration)이란?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컬렉션의 요소를 반복할 수 있는 기능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Map객체는 기본적으로 for...of 구문을 사용하며 for...of 구문은 Map객체 내의 키-값 쌍을 반환한다.&lt;/p&gt;
&lt;pre id=&quot;code_1681012315625&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const map = new Map();
map.set('name', 'John');
map.set('age', 30);
map.set('gender', 'male');

for (const [key, value] of map) {
  console.log(`${key}: ${value}`);
}
// 출력:
// &quot;name: John&quot;
// &quot;age: 30&quot;
// &quot;gender: male&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Map 객체는 keys(), values(), entries() 메서드를 통해 이터레이터(iterator)를 반환할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;keys() : Map 객체 내 모든 키(key)를 반환.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;values() : Map 객체 내 모든 값(value)을 반환.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;entries() : Map 객체 내 모든 키-값 쌍(key-value pair)을 각각 순회.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1681012445896&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const map = new Map();
map.set('name', 'John');
map.set('age', 30);
map.set('gender', 'male');

// 모든 키 출력
for (const key of map.keys()) {
  console.log(key);
}
// 출력:
// &quot;name&quot;
// &quot;age&quot;
// &quot;gender&quot;

// 모든 값 출력
for (const value of map.values()) {
  console.log(value);
}
// 출력:
// &quot;John&quot;
// 30
// &quot;male&quot;

// 모든 키-값 쌍 출력
for (const [key, value] of map.entries()) {
  console.log(`${key}: ${value}`);
}
// 출력:
// &quot;name: John&quot;
// &quot;age: 30&quot;
// &quot;gender: male&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Map 객체는 객체와 달리 객체(Object)를 키로 사용할 수 있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 객체의 참조값이 유일하기 때문이며 아래와 같은 코드도 작성 가능하다.&lt;/p&gt;
&lt;pre id=&quot;code_1681012663030&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const myMap = new Map();
const obj = {};
myMap.set(obj, &quot;Hello, World!&quot;);
console.log(myMap.get(obj)); // 출력: &quot;Hello, World!&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript</category>
      <author>FRDYtheme</author>
      <guid isPermaLink="true">https://frdytheme.tistory.com/130</guid>
      <comments>https://frdytheme.tistory.com/130#entry130comment</comments>
      <pubDate>Sun, 9 Apr 2023 12:57:48 +0900</pubDate>
    </item>
    <item>
      <title>[JavaScript] 소수점 오류? 0.30000000000000004</title>
      <link>https://frdytheme.tistory.com/129</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;팩토리얼을 사용해서 경우의 수를 구하는 문제를 풀다가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nCm = n! / n-m! * m!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식으로 수를 구하다보면 소수점으로 떨어지는 경우가 있을 것 같아&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Math.trunc()를 사용했는데 실패해서 찾다가 알게된 글 정리.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터는 2진법으로 계산을 하기 때문에 계산을 위해 10진법인 수를 2진법으로 변환하는 과정에서 무한소수가 생길 수 있다. 다만, 컴퓨터 메모리에는 용량 제한이 있기 때문에 컴퓨터가 알아서 무한 소수를 유한 소수로 바꿔서 저장하는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 과정에서 미세한 오류가 발생한다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수포자라 자세히는 모르겠는데 여튼 소수를 계산하다보면 의도치 않은 수가 발생할 수 있으니 아래 메서드를 사용하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;toFixed()&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;toFixed()는 입력받은 숫자를, 매개변수만큼 자리수를 반올림해 String으로 반환해주는 함수.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0 - 20까지의 자리수를 매개변수로 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*** String으로 반환하므로 숫자형으로 변환해줘야 한다. ***&lt;/p&gt;
&lt;pre id=&quot;code_1680912528410&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let result = (0.1 + 0.2).toFixed(2); // 소수점 2번째 자리까지 나타냄.
// '0.30' 
Number(result); 
// 0.3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Math.round()&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222426; text-align: start;&quot;&gt;매개변수로 받은 숫자를&amp;nbsp; 반올림 후 가장 가까운 정수 값을 반환하는 함수.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #222426; text-align: start;&quot;&gt;toFixed()의 매개변수를 0으로 지정해줬을 때처럼 정수값을 반환해준다는 점에 주의하자.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1680912644269&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Math.round(20.49); 
// 20 
Math.round((0.1 + 0.2) * 10) / 10; 
// 0.3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;[출처]&lt;/p&gt;
&lt;figure id=&quot;og_1680912267207&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Javascript 소수점 오류 원인, 해결방안&quot; data-og-description=&quot;자바스크립트에서 소수점 숫자 연산을 하면, 생각지도 못한 오류가 발생한다. 아래처럼 콘솔창에 0.1 + 0.2를 입력하면, 0.3이 아니라 0.30000000000000004 가 나오는 걸 확인해볼 수 있다. 이렇게 소수점&quot; data-og-host=&quot;joooing.tistory.com&quot; data-og-source-url=&quot;https://joooing.tistory.com/entry/Javascript-%EC%86%8C%EC%88%98%EC%A0%90floating-point-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98&quot; data-og-url=&quot;https://joooing.tistory.com/entry/Javascript-%EC%86%8C%EC%88%98%EC%A0%90floating-point-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/fUkD7/hySdpSCrUG/V9eJopsaumJRYrnk1agxL1/img.png?width=800&amp;amp;height=798&amp;amp;face=0_0_800_798,https://scrap.kakaocdn.net/dn/cBEGqV/hyScwsgRKo/IERxN15hUvcLqfxlqppcT1/img.png?width=800&amp;amp;height=798&amp;amp;face=0_0_800_798,https://scrap.kakaocdn.net/dn/yMyyo/hyScywQZgK/KYkeaz9XgJffqAs9OObjak/img.png?width=1198&amp;amp;height=209&amp;amp;face=0_0_1198_209&quot;&gt;&lt;a href=&quot;https://joooing.tistory.com/entry/Javascript-%EC%86%8C%EC%88%98%EC%A0%90floating-point-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://joooing.tistory.com/entry/Javascript-%EC%86%8C%EC%88%98%EC%A0%90floating-point-%EA%B3%84%EC%82%B0-%EC%98%A4%EB%A5%98&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/fUkD7/hySdpSCrUG/V9eJopsaumJRYrnk1agxL1/img.png?width=800&amp;amp;height=798&amp;amp;face=0_0_800_798,https://scrap.kakaocdn.net/dn/cBEGqV/hyScwsgRKo/IERxN15hUvcLqfxlqppcT1/img.png?width=800&amp;amp;height=798&amp;amp;face=0_0_800_798,https://scrap.kakaocdn.net/dn/yMyyo/hyScywQZgK/KYkeaz9XgJffqAs9OObjak/img.png?width=1198&amp;amp;height=209&amp;amp;face=0_0_1198_209');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Javascript 소수점 오류 원인, 해결방안&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트에서 소수점 숫자 연산을 하면, 생각지도 못한 오류가 발생한다. 아래처럼 콘솔창에 0.1 + 0.2를 입력하면, 0.3이 아니라 0.30000000000000004 가 나오는 걸 확인해볼 수 있다. 이렇게 소수점&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;joooing.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript</category>
      <author>FRDYtheme</author>
      <guid isPermaLink="true">https://frdytheme.tistory.com/129</guid>
      <comments>https://frdytheme.tistory.com/129#entry129comment</comments>
      <pubDate>Sat, 8 Apr 2023 09:11:06 +0900</pubDate>
    </item>
    <item>
      <title>[JavaScript] 옵셔널 체이닝 / nullish연산자(??)</title>
      <link>https://frdytheme.tistory.com/128</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;옵셔널 체이닝(optional chaining)은 자바스크립트에서 속성이나 메서드를 참조할 때&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 속성이나 메서드가 존재하지 않으면 에러를 발생시키지 않고 그냥 undefined를 반환하도록 하는 연산자입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 속성이나 메서드를 참조할 때 해당 객체가 null이나 undefined일 경우 에러가 발생했기 때문에&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해 null 체크를 작성하거나, 조건문으로 처리했지만, 옵셔널 체이닝을 사용하면 간단하게 처리 가능.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옵셔널 체이닝은 &quot;?&quot;으로 표시하며 해당 속성이나 메서드가 존재하지 않으면 undefined를 반환.&lt;/p&gt;
&lt;pre id=&quot;code_1680869554014&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const person = {
  name: 'John',
  address: {
    city: 'Seoul',
    street: '123 Main St'
  }
}

// person 객체의 address 속성 내 city를 참조
let city = person.address.city; // 'Seoul'

/*  만약 person 객체에 address가 없는 경우 위 코드는 에러가 발생하며
	그 경우를 대비해 옵셔널 체이닝으로 작성 가능하다. 
    아래 식은 person에 address가 있으면 Seoul이 되고 없으면 undefined가 된다.
*/
let city = person.address?.city; // 'Seoul'

// 옵셔널 체이닝으로 보험을 들었다면 조건식을 추가해 플랜B를 작성하면 된다.

if (!person.address?.city) { // 왼쪽의 조건은 !undefined로 true가 된다.
  city = 'Seoul';
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;nullish 연산자 (??)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;옵셔널 체이닝 ?를 연속해서 붙이면 nullish 연산자로, 피연산자가 'null 혹은 undefined'일 경우 오른쪽 피연산자를 반환.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 if문을 nullish 연산자로 줄일 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1680869982540&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const city = person.address.city ?? 'Seoul';
console.log(city); // 'Seoul'&lt;/code&gt;&lt;/pre&gt;</description>
      <category>JavaScript</category>
      <author>FRDYtheme</author>
      <guid isPermaLink="true">https://frdytheme.tistory.com/128</guid>
      <comments>https://frdytheme.tistory.com/128#entry128comment</comments>
      <pubDate>Fri, 7 Apr 2023 21:22:19 +0900</pubDate>
    </item>
  </channel>
</rss>