<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>오묘한</title>
    <link>https://5myohan.tistory.com/</link>
    <description>독특한, 쉽게 단정짓기 어려운.
(네이버 블로그에서 이사 중)</description>
    <language>ko</language>
    <pubDate>Sun, 12 Jul 2026 18:19:48 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>5묘</managingEditor>
    <image>
      <title>오묘한</title>
      <url>https://tistory1.daumcdn.net/tistory/2783578/attach/04adfe076c6843308cdf5168104a8a22</url>
      <link>https://5myohan.tistory.com</link>
    </image>
    <item>
      <title>[영어 개발문서 읽기 스터디] React 가이드: Manipulating the DOM with refs.</title>
      <link>https://5myohan.tistory.com/169</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://react.dev/learn/manipulating-the-dom-with-refs&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://react.dev/learn/manipulating-the-dom-with-refs&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1705044655552&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Manipulating the DOM with Refs &amp;ndash; React&quot; data-og-description=&quot;The library for web and native user interfaces&quot; data-og-host=&quot;react.dev&quot; data-og-source-url=&quot;https://react.dev/learn/manipulating-the-dom-with-refs&quot; data-og-url=&quot;https://react.dev/learn/manipulating-the-dom-with-refs&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/BORzL/hyU5UCrOxY/mwedj22KC1DA8XpQENTZb1/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/GO4eL/hyU5IveHmz/PAQCsBylUGwQPPtPbHagPK/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567&quot;&gt;&lt;a href=&quot;https://react.dev/learn/manipulating-the-dom-with-refs&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://react.dev/learn/manipulating-the-dom-with-refs&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/BORzL/hyU5UCrOxY/mwedj22KC1DA8XpQENTZb1/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/GO4eL/hyU5IveHmz/PAQCsBylUGwQPPtPbHagPK/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567');&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;Manipulating the DOM with Refs &amp;ndash; React&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The library for web and native user interfaces&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;react.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 디자인 시스템에서 낮은 레벨의 컴포넌트들(버튼, 인풋 등등)은 그들의 DOM nodes를 이용하는 것이 흔하다.&lt;br /&gt;그러나 높은 레벨의 컴포넌트(form, list, 페이지 section 등)은 그들의 DOM 노드를 노출하는 것을 피한다.(의도하지 않은 의존성을 피하기 위해서이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;useImperativeHandle()&lt;/span&gt;: forwardRef을 이용해 자식 컴포넌트에 있는 요소에 ref을 주기 위해 사용함.&lt;br /&gt;다음과 같이 사용한다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 전문 보기&lt;/p&gt;
&lt;pre id=&quot;code_1705045121985&quot; class=&quot;verilog&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;import {
  forwardRef, 
  useRef, 
  useImperativeHandle
} from 'react';

const MyInput = forwardRef((props, ref) =&amp;gt; {
  const realInputRef = useRef(null);
  useImperativeHandle(ref, () =&amp;gt; ({
    // Only expose focus and nothing else
    focus() {
      realInputRef.current.focus();
    },
  }));
  return &amp;lt;input {...props} ref={realInputRef} /&amp;gt;;
});

export default function Form() {
  const inputRef = useRef(null);

  function handleClick() {
    inputRef.current.focus();
  }

  return (
    &amp;lt;&amp;gt;
      &amp;lt;MyInput ref={inputRef} /&amp;gt;
      &amp;lt;button onClick={handleClick}&amp;gt;
        Focus the input
      &amp;lt;/button&amp;gt;
    &amp;lt;/&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React에서 모든 '업데이트'는 2가지 방식으로 나뉜다.&lt;br /&gt;- &lt;b&gt;render하는 동안&lt;/b&gt;, React는 당신의 컴포넌트 중 screen에 떠야 하는 것을 호출한다.&lt;br /&gt;- &lt;b&gt;commit 하는 동안&lt;/b&gt;, React는 DOM에 변화를 적용한다.&lt;br /&gt;&lt;br /&gt;일반적으로 당신은 rendering하는 동안 ref에 접근하기를 원하지 않을 것이다. ref이 DOM 노드에 붙는 행위도 마찬가지이다. &lt;br /&gt;&lt;b&gt;첫번째로 render될 때 DOM 노드들은 아직 만들어지지 않았기 때문에 ref.current는 null이다. &lt;/b&gt;DOM을 업데이트한 이후에도 , DOM nodes는 아직 업데이트되지 않았다. 아직 그들을 읽어들이기에는 너무 이른 것이다.&lt;br /&gt;&lt;b&gt;React는 ref.current를 commit 하는 동안에 읽는다. &lt;/b&gt;DOM을 업데이트 하기 전에, React는 영향을 받은 ref.current를 null로 만들고 DOM을 업데이트한 후에 React는 즉시 그들에게 적합한 DOM node를 설정한다.&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주로 당신은 ref를 event handler을 통해 접근할 것이다. 만약 당신이 ref을 갖고 무엇인가 하고 싶지만 특별히 이벤트가 그 안에 없다면, 우리는 다음 페이지에서 'effects'를 살펴보아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #9feec3; color: #404756; text-align: start;&quot;&gt;flushSync()&lt;/span&gt;: DOM update가 setState보다 빠르게 발생한다 =&amp;gt; 이를 방지하고자 flushSync로 감싼다. &lt;b&gt;flushSync로 감싸게 되면 React에게 flushSync로 감싸진 code를 실행한 바로 이후에 DOM을 업데이트하도록 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ref은 좋은 탈출구이다. 당신은 ref을 React 외에서 생각해야 할 때에 사용해야만 한다.( focusing, scroll위치, 브라우저 API 호출 등 React가 드러내지 않는 것에서 말이다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;당신이 만약 focusing이나 scrolling과 같이 비교적 변화를 덜 일으키는 액션에 집착한다면, 우리는 문제를 마주하지 않을 것이다. &quot;&lt;br /&gt;&lt;b&gt;그러나 만일 당신이 DOM을 수동으로 수정하려 하면, 당신은 React가 만들 변화와 충돌의 위험을 맞게 될 것이다.&lt;br /&gt;React에 의해 관리되는 DOM 노드를 바꾸려 하지 말자.&amp;nbsp;&lt;/b&gt;수정하거나, 자식노드를 추가하거나, 또는 리엑트로부터 관리되는 element로부터 node를 삭제하는 것은 예상치 못한 시각적 결과나 충돌을 야기할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러나 이것은 당신이 그걸 아예 해선 안된다는 말은 아니다. &lt;b&gt;React가 update할 이유가 없는 부분이라면&lt;/b&gt;, 당신은 안전하게 DOM의 일부를 바꿀 수 있다. 예를 들어, 어떤 &amp;lt;div&amp;gt;가 jsx에서 항상 비어있다면 React는 그 자식 리스트를 건드릴 이유가 없다. 따라서 , 수동으로 그곳의 요소를 추가하거나 제거하는 것은 안전하다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;복습하기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Ref은 포괄적인 개념이지만,주로 DOM 요소에 붙어 관리하기 위해 사용된다.&lt;br /&gt;- 당신은 &amp;lt;div ref={myRef}&amp;gt; 이런 식으로 DOM node에 붙여서 myRef.current를 사용할 수 있다.&lt;br /&gt;- 주로 당신은 ref을 변화를 일으키지 않는 행동(focusing, scrollinh, measuring DOM elements등)에 사용할 수 있다&lt;br /&gt;- 리액트 컴포넌트는 DOM node를 기본적으로 노출시키지 않습니다. 당신은 컴포넌트에서 DOM node를 사용하기 위해 forwardRef을 사용하고 두번째 ref 인자를 자식 컴포넌트의 노드로 보내줘야 합니다.&lt;br /&gt;- React에 의해 관리되는 DOM 노드를 바꾸지 않도록 주의합니다.&lt;br /&gt;- React에 의해 바뀔 일이 없는 DOM 노드라면, 수정해도 안전합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>5묘</author>
      <guid isPermaLink="true">https://5myohan.tistory.com/169</guid>
      <comments>https://5myohan.tistory.com/169#entry169comment</comments>
      <pubDate>Fri, 12 Jan 2024 16:32:53 +0900</pubDate>
    </item>
    <item>
      <title>[모던 자바스크립트 입문] 1-3장</title>
      <link>https://5myohan.tistory.com/167</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1장.&amp;nbsp;자바스크립트의&amp;nbsp;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 프로그래밍 언어란 컴퓨터 프로그램을 작성하기 위한, 즉 알고리즘을 설명하기 위한 언어이다.&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;3. 프로그래밍 언어는 방식에 따라 절차적 언어, 객체 지향 언어, 함수형 언어, 논리형 언어로 나뉜다. 자바스크립트는 객체 지향 언어이지만 함수형 언어의 특징도 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 자바스크립트는 인터프리터 언어이다. 실행 속도가 느릴 것 같지만 최근 웹브라우저 대부분에 실행시간에 자바스크립트 코드를 컴파일하는 JIT 컴파일러가 내장돼있어 실행 속도가 매우 빨라졌다. 이는 자바스크립틀르 활용한 고기능 웹 애플리케이션을 구현할 수 있게 된 중요한 요인 중 하나이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 자바스크립트는 C++나 Java처럼 클래스를 이용해 객체를 생성하는 클래스 기반 객체 지향 언어가 아닌, 프로토타입을 상속하는 프로토타입 기반 객체 지향 언어이다. 자바스크립트에서는 객체를 생성한 후, 프로퍼티와 메서드를 동적으로 추가하거나 삭제할 수 있다. 이것이 클래스 기반 객체 지향 언어의 객체와 다른 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 동적 타입 언어다. C++와 java는 실행되기 전 변수 타입이 결정되는 정적 타입 언어이지만 자바스크립트는 변수 타입이 없다. 따라서 프로그램을 실행하는 도중 변수에 저장되는 데이터 타입이 동적으로 바뀔 수 있다. 이러한 언어를 동적 타입 언어라 칭한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. 함수가 일급 객체이다. 자바스크립트의 함수는 객체이고, 함수에 함수를 인수로 넘길 수 있다. 이것이 자바스크립트의 함수가 일급 객체인 이유이며 이 특성을 활용하면 고차 함수를 구현할 수 있어 함수형 프로그래밍이 가능해진다.&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;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2장. 프로그램의 작성과 실행법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;토큰과 공백 문자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.토큰&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;2. 공백 문자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인접한 토큰을 공백 등에 넣지 않고 나열하기만 해서는 토큰을 판별할 수 없다. 가령 return n부분을 returnn이라 표기하면 returnn을 하나의 토큰으로 인식한다. 즉 공백문자는 토큰과 토큰 사이를 구별해주는 역할을 한다. 이때 공백을 여러개 입력해도 공백문자를 하나만 입력한 것으로 간주한다. 토큰을 구분하는 공백문자로는 스페이스와 탭만 사용하고 필요할 때만 줄 바꿈 문자를 사용한다.&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;토큰과 토큰 사이에 공백 문자가 없어도 토큰을 판별할 수 있는 경우가 있다. 이때는 공백 문자를 생략할 수 있다. 가령 다음과 같은 경우이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;a = 1 + 2 * 3&amp;nbsp; -&amp;gt; a=1+2*3&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 =, +, 1 등 산술 연산자 앞 뒤의 공백 문자, (,), {,},[, ] 와 같은 괄호 앞 뒤의 공백문자, 세미콜론, 쉼표, 콜론(:), 마침표 앞 뒤의 공백문자는 생략할 수 있다. 이러한 토큰은 토큰을 분리하기 때문에 분리자 또는 구분자라고 부릅니다.&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. 프로그램 가독성 높이기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드 가독성을 높이는 방식은 매우 다양하다. 특히 공백 문자를 코드의 어느 부분에 넣을 것인지에 대해서는 개발자 집단에 따라 의견이 크게 나눠진다. 그러나 &lt;b&gt;{ 문자 다음에는 개행 문자로 줄을 바꾸어야 하고,&lt;/b&gt;&amp;nbsp; 함수의 몸체인 { ... } 안에 작성된 코드는 앞에 탭 문자를 넣어야 하는 등의 규칙은 모두가 동의하는 내용이므로 이 규칙만큼은 지키도록 하자. 코드 가독성을 높ㄹ이는 방법은 11.1.3절의 스타일 가이드 사용하기(436페이지)를 참조하자.&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. 문장&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;영어가 단어 하나만으로 의사를 표현할 수 없어, 여러 개의 단어로 된 문장으로 의사를 표현하듯이, 자바스크입트는 토큰 하나만으로는 프로그램이 실행하려는 문장을 끝낼 수 없다. 따라서 토큰을 나열해 한 문장을 만들고, 문장을 이용해 컴퓨터에 명령을 내린다.&amp;nbsp;&lt;br /&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;console.log(i + &quot;! = &quot; + fact(j) );&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특별한 경우를 제외하고는 &lt;b&gt;문장 끝에 반드시 세미콜론을 붙이고&lt;/b&gt;, &lt;b&gt;개행문자로 줄을 바꿔라&lt;/b&gt;. 그리고&lt;b&gt; 한 줄에는 한 문장만 작성하라.&amp;nbsp;&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;6. 복합문&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문장 여러 개를 중괄호({})로 감싼 코드를 복합문 또는 블록문이라 한다.&lt;/p&gt;
&lt;pre id=&quot;code_1699254089616&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Ex.
{
    sum = sum + x;
    console.log(&quot;sum = &quot; + x);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복합문 끝에는 세미콜론을 붙이지 않는다. 복합문의 중괄호 안에 포함된 문장은 중괄호를 기준으로 들여쓰기를 할 수 있습니다.&amp;nbsp;&lt;br /&gt;들여쓰기를 하지 않아도 오류가 발생하지는 않지만, 들여쓰기를 해야 프로그램의 계층 구조를 명시할 수 있어 프로그램을 읽기가 쉬워진다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;복합문은 일반적으로 if 문이나 while 문 등의 제어 구문에 사용한다. 제어 구문은 7장에서 배운다.&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;7. 빈 문장&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;빈 문장은 실행해도 자바스크립트 인터프리터가 아무런 작업을 하지 않습니다. 그러나 빈 문장이 필요한 상황이 있는데 이를 응용하는 방법은 7장에서 배웁니다.&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;8. 세미콜론 자동 추가&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;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 코드를 살펴봅시다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3장. 변수와 값&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;1-4. 변수 끌어올림과 중복 선언&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;가령 다음의 코드를 보자. console.log(x)에서 오류가 나는 것이 아니라 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;cosnsole.log(x) // undefined&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var x;&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;이 코드에서 첫번째 줄은 아직 변수 x가 선언되지 않아 오류가 발생할 것 같지만, 실제로는 오류가 발생하지 않고 undefined가 출력된다.&lt;br /&gt;이는 프로그램 중간에서 변수를 선언하더라도 &lt;b&gt;변수가 프로그램 첫머리에 선언된 것처럼 다른 문장 앞에 생성되기 때문이다&lt;/b&gt;. 이를&lt;b&gt; 변수 선언의 끌어올림(호이스팅)&lt;/b&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;console.log(x); // -&amp;gt; undefined&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var x = 5;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;console.log(x); // -&amp;gt; 5&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;이 코드의 첫번째 줄에서는 undefined가 출력되고, 3번째 줄에서는 5가 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 선언부 var x는 끌어올려지지만 대입부 x = 5는 끌어올려지지 않기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 var 문을 사용하여 같은 이름을 가진 변수를 여러 개 선언하더라도 문제가 발생하지 않습니다.&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;1-5. 변수의 명명 규칙&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수, 함수, 라벨 이름 등 사용자가 정의하는 이름을 식별자라고 합니다. 식별자는 다음과 같은 명명 규칙을 따라야 합니다.&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1699256540446&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. 사용할 수 있는 문자는 알파벳 (a-z, A-Z), 숫자(0-9), 밑줄(_), 달러기호($)다.
2. 첫 글자로는 숫자를 사용할 수 없다. 즉 첫 글자는 위에 1번에서 언급한 문자 중 하나여야 한다.
3. 하이픈(-)은 사용할 수 없고, 예약어는 사용할 수 없다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 이름은 식별자 명명 규칙에 어긋나지만 않으면 자유롭게 지정할 수 있다. 그러나 프로그램이 커질수록 사용하는 변수 개수도 늘어나므로 변수가 뜻하는 바를 파악하기가 어려워진다. 이럴 때 일정한 표기법에 따라 변수의 의미를 알 수 있다면 좋다.&lt;br /&gt;변수 표기법에는 아래 3가지 방식이 있다.&amp;nbsp;&lt;br /&gt;1. 캐멀 표기법 = ex. newName, createLifeGame&lt;br /&gt;2. 파스칼 표기법 = ex. NewName, CreateLifeGame&lt;br /&gt;3. 밑줄 표기법 = ex. new_name, create_life_game&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;br /&gt;(ex. extends, debugger, const, else..)&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-1. 데이터 타입&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;br /&gt;자바스크립트는 변수에 타입이 없어, 변수에 모든 타입의 데이터를 저장할 수 있는 &quot;동적 타입 언어&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;3-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-2-3.숫자&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대다수의 프로그래밍 언어에는 정수 타입과 부동소수점 타입이 따로 있지만, 자바스크립트에는 타입이 없어 숫자를 모두 64 비트의 부동소수점으로 표현한다. 이는 C나 자바에서 사용하는 double 타입에 해당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프로그램에 직접 작성할 수 있는 상수 값을 리터럴이라 한다. 숫자를 표현하는 리터럴은 정수 리터럴과 부동 소수점 리터럴이 있다.&lt;br /&gt;- 가수부 e, E 사용방식과 8진수는 숫자 앞에 0o을 붙이는 것, 2진수는 0b, 16진수는 0x를 붙이는 것은 ECMAScript 6에서만 사용 가능하고 5에서는 사용 불가하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 다음의 문자열은 자바스크립트에서 특별한 숫자를 표현하기 위한 문자열로 ECMAScript에서는 모두 읽기전용이라 수정할 수 없다.&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;Infinity - 플러스 무한대&lt;br /&gt;NaN - 부정값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Number.POSITIVE_INFINITY : 플러스 무한대&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Number.NEGATIVE_INFINITY: 마이너스 무한대&lt;br /&gt;Number.MAX_VALUE: 표현할 수 있는 최댓값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Number.MIN_VALUE: 표현할 수 있는 최솟값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Number.NaN : 부정값&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Number.EPSILON : &lt;b&gt;Number.EPSILON&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;속성(property)은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;a style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot; href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Number&quot;&gt;Number&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #1b1b1b; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;형으로 표현될 수 있는 1과 1보다 큰 값 중에서 가장 작은 값의, 차이다.(아주 미세한 차이를 확인해 이것 이하이면 같은 수, 즉 차가 없다라고 본다)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Number.MIN_SAFE_INTEGER:&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Number.MAX_SAFE_INTEGER:&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;NaN은 0을 0으로 나눈 결괏값, Infinity를 Infinity로 나눈 결괏값, 음수의 제곱근 등 숫자로 표현할 수 없는 부정 값을 뜻한다.&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-2-4. 문자열&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;br /&gt;Ex. \u{1f4d6}&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-2-5 논리값&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;Ex. x == 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-2-6 특수한 값&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;undefined&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 값을 아직 할당하지 않은 변수의 값.&amp;nbsp;&lt;br /&gt;- 없는 객체의 프로퍼티를 읽으려 시도 했을 떄의 값&lt;br /&gt;- 없는 배열의 요소를 읽으려 시도했을 때의 값&lt;br /&gt;- 아무것도 반환하지 않는 함수가 반환하는 값&lt;br /&gt;- 함수를 호출했을 때 전달받지 못한 인수의 값&lt;br /&gt;&lt;br /&gt;null&lt;br /&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;3-3. ECMAScript6부터 추가된 데이터 타입&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) 심벌 (구별할 때 쉽게 만듦)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var NONE = Symbol(&quot;none&quot;);&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var BLACK = Symbol(&quot;black&quot;);&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var WHITE = Symbol(&quot;white&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;Symbol.for() 을 활용해 문자열과 연결된 심볼을 생성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var sym1 = Symbol.for(&quot;club&quot;);&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 나중에 console.log(Symbol.keyFor(sym1))로 가져올 수 있다.&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;템플릿 리터럴은 ECMAScript6 부터 추가된 문자열 표현 구문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var t = `I like pizza.`&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var v = String.raw`Man Loves to do \nsports` =&amp;gt; 이스케이프 시퀀스 문자 그대로 출력함.(String.raw를 태그함수라 한다)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보간 표현식 : 템플릿 리터럴 안에 자바스크립트 표현식의 결과값 삽입 Ex. `I want to do &lt;b&gt;${something}&lt;/b&gt;`.&amp;nbsp; &amp;nbsp;var something = sports;&lt;/p&gt;</description>
      <category>개발 공부/자바스크립트</category>
      <category>모던자바스크립트입문</category>
      <author>5묘</author>
      <guid isPermaLink="true">https://5myohan.tistory.com/167</guid>
      <comments>https://5myohan.tistory.com/167#entry167comment</comments>
      <pubDate>Mon, 6 Nov 2023 15:23:04 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 보석 쇼핑</title>
      <link>https://5myohan.tistory.com/164</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Two Pointer 알고리즘 연습용으로 선택한 문제!&lt;br /&gt;Set() 을 사용해 아래와 같이 간단하게 풀었다.&lt;/p&gt;
&lt;pre id=&quot;code_1696589225789&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(gems) {
  let answer = [];

  let allSpecies = new Set(gems); // 모든 종류의 요소가 각각 1번만 담기는 set()
  let minArr = [];
  let minLength = gems.length;
  let s = 0;
  let e = 0;

  while (e &amp;lt; gems.length) {
    let items = new Set();
    for (let i = s; i &amp;lt;= e; i++) { // 반복문을 돌며 구간 내의 요소들로 하나의 set을 만든다.
      items.add(gems[i]);
    }
    if (items.size === allSpecies.size) {  // 이 새로 만든 set이 모든 종류의 요소가 담긴 set과 크기 같으면 통과
      if (e - s &amp;lt; minLength || (e - s === minLength &amp;amp;&amp;amp; s &amp;lt; minLength[0])) {
        minLength = e - s;
        minArr = [s + 1, e + 1];
      }
    }
    if (allSpecies.size &amp;lt;= items.size) {
      s++;
    } else {
      e++;
    }
  }
  answer = minArr;
  return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 케이스를 모두 통과해서 문제 없다 생각했건만..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;548&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vGvzy/btsxh6OZuJO/9nPjW8HFbx4KeNyiZJZFQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vGvzy/btsxh6OZuJO/9nPjW8HFbx4KeNyiZJZFQ1/img.png&quot; data-alt=&quot;효율성이...!!! &quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vGvzy/btsxh6OZuJO/9nPjW8HFbx4KeNyiZJZFQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvGvzy%2Fbtsxh6OZuJO%2F9nPjW8HFbx4KeNyiZJZFQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;764&quot; height=&quot;548&quot; data-origin-width=&quot;764&quot; data-origin-height=&quot;548&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;효율성이...!!! &lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대체 내 코드의 효율성에 뭐가 문제인 것인가, 이걸 찾아보고자 고민해보고 남의 코드도 살펴보니...!&lt;br /&gt;Map 객체를 쓰면 min 비교가 필요 없었다..!&lt;/p&gt;
&lt;figure id=&quot;og_1696589484493&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;[JS] 프로그래머스 보석 쇼핑&quot; data-og-description=&quot;2020 카카오 인턴십 3번문제, 슬라이딩 윈도우, 탐욕법&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@bepyan/JS-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%B3%B4%EC%84%9D-%EC%87%BC%ED%95%91&quot; data-og-url=&quot;https://velog.io/@bepyan/JS-프로그래머스-보석-쇼핑&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ezZIYD/hyT5UEYuPn/il2IOA7MBNUClcT56922HK/img.png?width=1446&amp;amp;height=588&amp;amp;face=0_0_1446_588,https://scrap.kakaocdn.net/dn/bcfg6l/hyT9Hqsfar/NwJ1qh6YEmROxXUEJNKBx1/img.png?width=1446&amp;amp;height=588&amp;amp;face=0_0_1446_588,https://scrap.kakaocdn.net/dn/cnBqxR/hyT52bWQ3k/wdjp9I6Ccalr0uK1pSHaeK/img.jpg?width=2316&amp;amp;height=3088&amp;amp;face=0_0_2316_3088&quot;&gt;&lt;a href=&quot;https://velog.io/@bepyan/JS-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%B3%B4%EC%84%9D-%EC%87%BC%ED%95%91&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@bepyan/JS-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%B3%B4%EC%84%9D-%EC%87%BC%ED%95%91&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ezZIYD/hyT5UEYuPn/il2IOA7MBNUClcT56922HK/img.png?width=1446&amp;amp;height=588&amp;amp;face=0_0_1446_588,https://scrap.kakaocdn.net/dn/bcfg6l/hyT9Hqsfar/NwJ1qh6YEmROxXUEJNKBx1/img.png?width=1446&amp;amp;height=588&amp;amp;face=0_0_1446_588,https://scrap.kakaocdn.net/dn/cnBqxR/hyT52bWQ3k/wdjp9I6Ccalr0uK1pSHaeK/img.jpg?width=2316&amp;amp;height=3088&amp;amp;face=0_0_2316_3088');&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;[JS] 프로그래머스 보석 쇼핑&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;2020 카카오 인턴십 3번문제, 슬라이딩 윈도우, 탐욕법&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Map은 키와 값을 저장할 수 있는 객체인데, 이걸 사용하면 훨씬 더 효율적으로 풀 수 있다(아래 코드 참고)&lt;br /&gt;내가 짠 코드의 경우 구간의 요소들 구하기 위해 1) end pointer을 while문에 집어넣고, 2) 구간을 도는 for 반복문을 사용해서 s나 e가 달라질때마다 반복문을 돌아야 했었는데, &lt;br /&gt;아래의 코드는 맵을 써서 인덱스를 저장해둬서 조건을 충족하기 전까지는 r(==end pointer)을 계속 옮겨두고, 조건이 충족되면 그때 최소구간인지 여부를 따져 ans 배열에 넣고, 그 후 l( == start pointer)을 한 칸 앞으로 이동시킨다. 이때 옮기는 방식도 hit안의 r에 해당하는 값 을 delete로 없애버림으로써, 자동으로 두번째 인자가 r이 되도록 만든다.&lt;/p&gt;
&lt;pre id=&quot;code_1696589888096&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(gems) {
    const cnt = new Set(gems).size;
    var ans = [1, gems.length];

    var l = 0, r = 0;
    const hit = new Map();
    hit.set(gems[0], 1)

    while (r &amp;lt; gems.length) {
        if (hit.size === cnt) {
            if(ans[1] - ans[0] &amp;gt; r - l)
                ans = [l + 1, r + 1]

            hit.set(gems[l], hit.get(gems[l]) - 1);
            if (hit.get(gems[l]) === 0) 
                hit.delete(gems[l])

            l++;
        }
        else {
            r++;
            const right = hit.get(gems[r]);
            hit.set(gems[r], right ? right + 1 : 1);
        }
    }
    return ans;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최종적으로 내가 수정한 알고리즘은 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1696592036239&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(gems) {

  const count = new Set(gems).size; // 중복 없는 Set의 크기
  let answer = [1, gems.length]; // answer의 초기값은 1과 gems.length(0 + 1, 끝 인덱스 + 1)
  let start = 0,
    end = 0; // 시작 포인터(start), 끝 포인터(end)
  const temp = new Map(); // 구간 내의 모든 인자가 담길 temp Map 객체
  temp.set(gems[0], 1); // temp 맵 객체에 먼저 0번째 인자를 넣는다.

  while (end &amp;lt; gems.length) {
    // 끝 포인터가 인덱스 끝까지 가면 반복문 종료
    if (temp.size === count) {
      // start를 옮기는 조건 =&amp;gt; 1) 모든 요소가 배열 안에 들어왔을 경우
      if (answer[1] - answer[0] &amp;gt; end - start) {
        // 2) 최소구간이 증명되면 answer에 넣는다.
        answer = [start + 1, end + 1];
      }
      temp.set(gems[start], temp.get(gems[start]) - 1); // start를 하나씩 옮기며 중복 요소를 하나씩 제거해서 마침내 중복이 없어진 요소(값이 1인)만 ans에 남게 된다.
      if (temp.get(gems[start]) === 0) {
        // 안에 요소의 값이 0개면 아예 해당 키를 없애자.
        temp.delete(gems[start]);
      }
      start++;
    } else {
      // start를 너무 옮겨 아예 요소 자체가 MAP에서 삭제되면 end를 옮기게 된다.(temp의 size가 count와 달라질테니)
      end++;
      let endValue = temp.get(gems[end]);
      temp.set(gems[end], endValue ? endValue + 1 : 1);
    }
  }
  return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론: Map(), Set() 객체를 잘 쓰자 / 반복문을 최대한 쓰지 않고, 빈 배열도 최대한 쓰지 않아야 메모리와 시간 효율성 확보 가능하다!&lt;/p&gt;</description>
      <category>개발 공부/알고리즘 문제풀이</category>
      <category>map</category>
      <category>보석쇼핑</category>
      <category>자바스크립트 코딩테스트</category>
      <category>자바스크립트 코테</category>
      <category>카카오</category>
      <category>코딩테스트</category>
      <category>투포인터</category>
      <category>프로그래머스</category>
      <author>5묘</author>
      <guid isPermaLink="true">https://5myohan.tistory.com/164</guid>
      <comments>https://5myohan.tistory.com/164#entry164comment</comments>
      <pubDate>Fri, 6 Oct 2023 20:35:35 +0900</pubDate>
    </item>
    <item>
      <title>프로토타입을 철학적으로 이해하기 (주의: 매우 이해 쉬움)</title>
      <link>https://5myohan.tistory.com/163</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트 프로토타입은 이해하기 매우 어려운 주제이다.&lt;br /&gt;책을 읽었지만 그래도 이해하지 못했는데, 프로토타입을 철학의 맥락에서 살펴본 아래 자료를 읽고 이해를 한방에 했다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;정말 이해하기 쉽게 되어있고 문과라면 오히려 더 잘 이해할 수 있으니 꼭 읽어보시는 걸 추천!&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1696574685130&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;자바스크립트는 왜 프로토타입을 선택했을까&quot; data-og-description=&quot;프로토타입으로 검색하면 으레 나오는 서두처럼 저 또한 자바스크립트를 처음 접했을 때 가장 당황스러웠던 게 프로토타입이었습니다.&quot; data-og-host=&quot;medium.com&quot; data-og-source-url=&quot;https://medium.com/@limsungmook/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94-%EC%99%9C-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%EC%9D%84-%EC%84%A0%ED%83%9D%ED%96%88%EC%9D%84%EA%B9%8C-997f985adb42&quot; data-og-url=&quot;https://medium.com/@limsungmook/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94-%EC%99%9C-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%EC%9D%84-%EC%84%A0%ED%83%9D%ED%96%88%EC%9D%84%EA%B9%8C-997f985adb42&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/n3uuG/hyT9K1JK76/mkPMF9LZ5VFpjLSYPY1K0K/img.jpg?width=800&amp;amp;height=450&amp;amp;face=285_95_493_322&quot;&gt;&lt;a href=&quot;https://medium.com/@limsungmook/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94-%EC%99%9C-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%EC%9D%84-%EC%84%A0%ED%83%9D%ED%96%88%EC%9D%84%EA%B9%8C-997f985adb42&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://medium.com/@limsungmook/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%8A%94-%EC%99%9C-%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85%EC%9D%84-%EC%84%A0%ED%83%9D%ED%96%88%EC%9D%84%EA%B9%8C-997f985adb42&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/n3uuG/hyT9K1JK76/mkPMF9LZ5VFpjLSYPY1K0K/img.jpg?width=800&amp;amp;height=450&amp;amp;face=285_95_493_322');&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;자바스크립트는 왜 프로토타입을 선택했을까&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;프로토타입으로 검색하면 으레 나오는 서두처럼 저 또한 자바스크립트를 처음 접했을 때 가장 당황스러웠던 게 프로토타입이었습니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;medium.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;h4 data-ke-size=&quot;size20&quot;&gt;정리&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프로토타입은 이미 존재하는 객체, 즉 생성된 객체를 통해 정의하는 방식이다.&lt;br /&gt;- 그래서 &lt;b&gt;프로토타입 선언 시에 객체 선언의 과정이 포함되어 있는 것이다!&lt;br /&gt;&lt;/b&gt;- 프로토타입을 적용한 후, 적용시킨 객체가 해당 속성을 변경해도 프로토타입의 객체 속성은 변경되지 않는다! (안심하자)&lt;br /&gt;- &lt;b&gt;호이스팅&lt;/b&gt;은 &lt;b&gt;실행 컨텍스트를 생성&lt;/b&gt;했을 때,&lt;b&gt; 렉시컬 스코프 내의 선언&lt;/b&gt;이 &lt;b&gt;끌어올려지는 것&lt;/b&gt;이다. (YDJS 해당 부분을 한번 더 공부해보자)&lt;br /&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;b&gt;클래스의 메소드를 호출하는 행위&lt;/b&gt;를 &lt;b&gt;메시지&lt;/b&gt;라 한다. Js에 이 개념을 적용하면 바로 이 &lt;b&gt;메시지를 발화한 객체(Invoke)&lt;/b&gt;를 &lt;b&gt;this로 지정&lt;/b&gt;할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- This 바인딩에 대하여: 발화하는&lt;span&gt; &lt;/span&gt;객체가&lt;span&gt; this&lt;/span&gt;가&lt;span&gt; &lt;/span&gt;되므로&lt;span&gt; &amp;ldquo;&lt;/span&gt;실행&lt;span&gt; &lt;/span&gt;컨텍스트를&lt;span&gt; &lt;/span&gt;발화하는&lt;span&gt;&amp;rdquo; &lt;/span&gt;객체를&lt;span&gt; &lt;/span&gt;찾아야만&lt;span&gt; &lt;/span&gt;한다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;</description>
      <category>개발 공부/자바스크립트</category>
      <author>5묘</author>
      <guid isPermaLink="true">https://5myohan.tistory.com/163</guid>
      <comments>https://5myohan.tistory.com/163#entry163comment</comments>
      <pubDate>Fri, 6 Oct 2023 17:52:48 +0900</pubDate>
    </item>
    <item>
      <title>[LeetCode] 3. Longest Substring Without Repeating Characters</title>
      <link>https://5myohan.tistory.com/162</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/longest-substring-without-repeating-characters/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://leetcode.com/problems/longest-substring-without-repeating-characters/description/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695949859718&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;LeetCode - The World's Leading Online Programming Learning Platform&quot; data-og-description=&quot;Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.&quot; data-og-host=&quot;leetcode.com&quot; data-og-source-url=&quot;https://leetcode.com/problems/longest-substring-without-repeating-characters/description/&quot; data-og-url=&quot;https://leetcode.com/problems/longest-substring-without-repeating-characters/description/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/JRkDO/hyT2CjFpLi/043GbrrEnlVNxK6KSIo8jK/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/longest-substring-without-repeating-characters/description/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://leetcode.com/problems/longest-substring-without-repeating-characters/description/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/JRkDO/hyT2CjFpLi/043GbrrEnlVNxK6KSIo8jK/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&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;LeetCode - The World's Leading Online Programming Learning Platform&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 문제는 가장 간단하게 내가 풀 수 있었던 방법이 이중 반복문을 돌리며 범위를 잡고, {문자:0} 형태의 object를 만들어 특정 문자가 등장할 때마다 해당 키의 value값에 1씩 더해주는 식으로 중복 여부를 따졌다.&lt;/p&gt;
&lt;pre id=&quot;code_1695949960895&quot; class=&quot;haxe&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-type=&quot;codeblock&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;/**
 * @param {string} s
 * @return {number}
 */
var lengthOfLongestSubstring = function (s) {
  let numsObj = {};
  let newStr = '';
  let maxLenString = '';

  for (let i = 0; i &amp;lt; s.length; i++) {
    if (!Object.keys(numsObj).includes(s[i])) {
      let newObj = {
        [s[i]]: 0
      };
      numsObj = { ...numsObj, ...newObj };
    };
  }

  for (let i = 0; i &amp;lt; s.length; i++) {
    for (key in numsObj) {
      numsObj[key] = 0;
    }
    numsObj[s[i]] += 1
    for (let n = i; n &amp;lt; s.length; n++) {
      if (i !== n) {
        numsObj[s[n]] += 1
      }

      if (numsObj[s[i]] &amp;gt; 1) {
        break;
      }

      if (numsObj[[s[n]]] &amp;gt; 1) {
        break;
      }

      newStr = s.slice(i, n + 1);
      if (maxLenString.length &amp;lt; newStr.length) {
        maxLenString = newStr;
      }
    }
  }
  return maxLenString.length;
};&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;참고로 이걸 하면서 처음으로 ES6에서 문자열을 key로 하는 object 생성법을 알게 됐다.&lt;/p&gt;
&lt;pre id=&quot;code_1695950082307&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// https://koonsland.tistory.com/146 참고

const key = 'key';
const value = 0;

const newObject = {
	[key] : value // 이런 식으로 [] 안에 문자열 변수를 넣어주면 문자를 key로 사용가능!ES6
}

//ES5까지는 이렇게 했다.
let newObject = {} // 빈 Object를 만들고
newObject[key] = value //여기에 대입해 사용&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 당연히 제대로 된 알고리즘을 사용하지 않았기에 시간은 많이 나왔다..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1656&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GdhEw/btswaq7Rh9R/GHKLFs2wJHJmVIJ9OMQCXK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GdhEw/btswaq7Rh9R/GHKLFs2wJHJmVIJ9OMQCXK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GdhEw/btswaq7Rh9R/GHKLFs2wJHJmVIJ9OMQCXK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGdhEw%2Fbtswaq7Rh9R%2FGHKLFs2wJHJmVIJ9OMQCXK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1656&quot; height=&quot;380&quot; data-origin-width=&quot;1656&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 조금 더 빠르게 풀 수 있는(시간 복잡도가 무려 O(N)이다!) 풀이법을 확인해보았다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출처: &lt;a href=&quot;https://leetcode.com/problems/longest-substring-without-repeating-characters/solutions/2940314/javascript-true-o-n-sliding-window-with-explanation/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://leetcode.com/problems/longest-substring-without-repeating-characters/solutions/2940314/javascript-true-o-n-sliding-window-with-explanation/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695950450835&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;LeetCode - The World's Leading Online Programming Learning Platform&quot; data-og-description=&quot;Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.&quot; data-og-host=&quot;leetcode.com&quot; data-og-source-url=&quot;https://leetcode.com/problems/longest-substring-without-repeating-characters/solutions/2940314/javascript-true-o-n-sliding-window-with-explanation/&quot; data-og-url=&quot;https://leetcode.com/problems/longest-substring-without-repeating-characters/solutions/2940314/javascript-true-o-n-sliding-window-with-explanation/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cuFWaV/hyT2usng09/AkIirbkV4DkKnlXPF9DHI0/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/longest-substring-without-repeating-characters/solutions/2940314/javascript-true-o-n-sliding-window-with-explanation/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://leetcode.com/problems/longest-substring-without-repeating-characters/solutions/2940314/javascript-true-o-n-sliding-window-with-explanation/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cuFWaV/hyT2usng09/AkIirbkV4DkKnlXPF9DHI0/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&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;LeetCode - The World's Leading Online Programming Learning Platform&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;pre id=&quot;code_1695950437499&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**
 * @param {string} s
 * @return {number}
 */
function lengthOfLongestSubstring(inputString) {
    if (inputString.length == 0) return 0;

    let n = inputString.length;
    
    // starting index of current window substring
    let stCurr = 0,
        // length of the longest substring
        longest = 0,
        // length of the current substring (size of window)
        currLen = 0,
        // starting index of longest substring
        start = 0;

	// hashmap to store the element as key and index last seen as value
    let lastSeenAt = {};

    // Traverse inputString to find the longest substring
    // without repeating characters.
    for (index = 0; index &amp;lt; n; index++) {
        let val = inputString[index];

        // If the current element is not present in the hash map,
        // then store it in the hash map with the value as the current index.
        if (!(val in lastSeenAt)) lastSeenAt[val] = index;
        else {
            // If the current element is present in the hash map,
            // it means that this element may have appeared before.
            // Check if the current element occurs before or after `stCurr`.
            if (lastSeenAt[val] &amp;gt;= stCurr) {
                currLen = index - stCurr;
                if (longest &amp;lt; currLen) {
                    longest = currLen;
                    start = stCurr;
                }
                // The next substring will start after the last
                // occurence of the current element.
                stCurr = lastSeenAt[val] + 1;
            }

            // Update the last occurence of
            // the element in the hash map
            lastSeenAt[val] = index;
        }
    }

    // Update the longest substring's
    // length and starting index.
    if (longest &amp;lt; index - stCurr) {
        start = stCurr;
        longest = index - stCurr;
    }

    return longest;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 문제는 stCurr이라는 시작지점을 이용해 끝 지점을 움직이며 가장 긴 중복없는 문자열을 찾는다. 여기서 나오는 개념이 바로 sliding window와 투 포인터이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;슬라이딩 윈도우는 구간이 같을 경우, 처음 값을 빼고 끝 값을 더해주는 방식으로 합을 비교할 때 사용할 수 있다.&lt;br /&gt;투 포인터는 시작과 끝, 두 지점을 움직이며 구간의 값을 구하는데, 슬라이딩 윈도우와는 달리 구간의 넓이가 유동적이라는 차이가 있다.&lt;br /&gt;&lt;a href=&quot;https://butter-shower.tistory.com/226&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://butter-shower.tistory.com/226&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695953696704&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;[Algorithm] 투포인터(Two Pointer) 알고리즘&quot; data-og-description=&quot;알고리즘 문제를 풀다보면 종종 나오는 투포인터 알고리즘! 막 꼬여가지고 ㅋㅋㅋ 저도 중간에 제대로 못짜고 그러는 경우가 많은데요, 많은 코딩테스트 문제에 등장하는 것은 아니지만 잊을만&quot; data-og-host=&quot;butter-shower.tistory.com&quot; data-og-source-url=&quot;https://butter-shower.tistory.com/226&quot; data-og-url=&quot;https://butter-shower.tistory.com/226&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dLCP4j/hyT2tAfo8n/kkFV8FfLdecy2VgFkyGmN0/img.png?width=635&amp;amp;height=232&amp;amp;face=0_0_635_232,https://scrap.kakaocdn.net/dn/V3Ivr/hyT2uFVLis/NEuCWNLtHUw1rUtdPFh5S0/img.png?width=635&amp;amp;height=232&amp;amp;face=0_0_635_232,https://scrap.kakaocdn.net/dn/CUm4F/hyT2DW8ZTA/1cHjDKi7f2bseiYKN7PuxK/img.png?width=594&amp;amp;height=364&amp;amp;face=0_0_594_364&quot;&gt;&lt;a href=&quot;https://butter-shower.tistory.com/226&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://butter-shower.tistory.com/226&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dLCP4j/hyT2tAfo8n/kkFV8FfLdecy2VgFkyGmN0/img.png?width=635&amp;amp;height=232&amp;amp;face=0_0_635_232,https://scrap.kakaocdn.net/dn/V3Ivr/hyT2uFVLis/NEuCWNLtHUw1rUtdPFh5S0/img.png?width=635&amp;amp;height=232&amp;amp;face=0_0_635_232,https://scrap.kakaocdn.net/dn/CUm4F/hyT2DW8ZTA/1cHjDKi7f2bseiYKN7PuxK/img.png?width=594&amp;amp;height=364&amp;amp;face=0_0_594_364');&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;[Algorithm] 투포인터(Two Pointer) 알고리즘&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;알고리즘 문제를 풀다보면 종종 나오는 투포인터 알고리즘! 막 꼬여가지고 ㅋㅋㅋ 저도 중간에 제대로 못짜고 그러는 경우가 많은데요, 많은 코딩테스트 문제에 등장하는 것은 아니지만 잊을만&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;butter-shower.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ji-musclecode.tistory.com/37&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ji-musclecode.tistory.com/37&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695953710825&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;슬라이딩 윈도우 알고리즘(Sliding Window) (feat. 투 포인트)&quot; data-og-description=&quot;1. 슬라이딩 윈도우 알고리즘 (Sliding Window) ( 슬라이딩 윈도우 알고리즘 간단 예제 ) 1, 2, 3, 4, 5, 6, 7 로 이루어진 숫자 배열에서 A[i] + A[i+1] + A[i+2] 형식으로 연속적인 3개의 숫자의 합의 최댓값을 &quot; data-og-host=&quot;ji-musclecode.tistory.com&quot; data-og-source-url=&quot;https://ji-musclecode.tistory.com/37&quot; data-og-url=&quot;https://ji-musclecode.tistory.com/37&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bqoqkY/hyT2rvE9Ka/PkWMh2S6nicbHHKH34ZFfk/img.png?width=800&amp;amp;height=515&amp;amp;face=0_0_800_515,https://scrap.kakaocdn.net/dn/bjXB36/hyT2B58DiA/1bg9B20qZ6I7PnfJaB9zPk/img.png?width=800&amp;amp;height=515&amp;amp;face=0_0_800_515,https://scrap.kakaocdn.net/dn/k3HRc/hyT2u6YDI3/aAyZAO1MjWozhHM9cbZOu1/img.png?width=1280&amp;amp;height=825&amp;amp;face=0_0_1280_825&quot;&gt;&lt;a href=&quot;https://ji-musclecode.tistory.com/37&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://ji-musclecode.tistory.com/37&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bqoqkY/hyT2rvE9Ka/PkWMh2S6nicbHHKH34ZFfk/img.png?width=800&amp;amp;height=515&amp;amp;face=0_0_800_515,https://scrap.kakaocdn.net/dn/bjXB36/hyT2B58DiA/1bg9B20qZ6I7PnfJaB9zPk/img.png?width=800&amp;amp;height=515&amp;amp;face=0_0_800_515,https://scrap.kakaocdn.net/dn/k3HRc/hyT2u6YDI3/aAyZAO1MjWozhHM9cbZOu1/img.png?width=1280&amp;amp;height=825&amp;amp;face=0_0_1280_825');&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;슬라이딩 윈도우 알고리즘(Sliding Window) (feat. 투 포인트)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;1. 슬라이딩 윈도우 알고리즘 (Sliding Window) ( 슬라이딩 윈도우 알고리즘 간단 예제 ) 1, 2, 3, 4, 5, 6, 7 로 이루어진 숫자 배열에서 A[i] + A[i+1] + A[i+2] 형식으로 연속적인 3개의 숫자의 합의 최댓값을&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;ji-musclecode.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 저녁은 위 블로그에서 투포인터와 슬라이딩 윈도우 문제를 풀어봐야겠다.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
      <author>5묘</author>
      <guid isPermaLink="true">https://5myohan.tistory.com/162</guid>
      <comments>https://5myohan.tistory.com/162#entry162comment</comments>
      <pubDate>Fri, 29 Sep 2023 10:21:29 +0900</pubDate>
    </item>
    <item>
      <title>[LeetCode] Add Two Numbers</title>
      <link>https://5myohan.tistory.com/161</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/add-two-numbers/editorial/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://leetcode.com/problems/add-two-numbers/editorial/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695635799568&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;LeetCode - The World's Leading Online Programming Learning Platform&quot; data-og-description=&quot;Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.&quot; data-og-host=&quot;leetcode.com&quot; data-og-source-url=&quot;https://leetcode.com/problems/add-two-numbers/editorial/&quot; data-og-url=&quot;https://leetcode.com/problems/add-two-numbers/editorial/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ciQWuy/hyTY3ChJ1p/Ogr8Ub2lBR1vZjkfsU0vN0/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/add-two-numbers/editorial/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://leetcode.com/problems/add-two-numbers/editorial/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ciQWuy/hyTY3ChJ1p/Ogr8Ub2lBR1vZjkfsU0vN0/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&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;LeetCode - The World's Leading Online Programming Learning Platform&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 주어진 시간 내에 못 풀었다..ListNode() 라는 새로운 class의 형태를 도저히 문제에 어떻게 적용해야 할지 모르겠었다.&lt;br /&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;결국 그래서 해설을 봤는데, 우선 재귀로 푸는 방법이 하나가 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;풀이:&lt;/p&gt;
&lt;pre id=&quot;code_1695785500986&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} l1
 * @param {ListNode} l2
 * @return {ListNode}
 */
var addTwoNumbers = function(l1, l2) {
    let node = null
    const carry = arguments[2]
    if (l1 || l2) {
        const val1 = l1 ? l1.val : 0
        const val2 = l2 ? l2.val : 0
        const next1 = l1 ? l1.next : null
        const next2 = l2 ? l2.next : null
        const val = carry ? val1 + val2 + 1 : val1 + val2
        node = new ListNode(val % 10)
        node.next = addTwoNumbers(next1, next2, val &amp;gt;= 10)  
    } else if (carry) {
        node = new ListNode(1)
        node.next = null
    }
    return node
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법의 경우 재귀(recursive)를 이용해 node.next의 값을 계속 node 값으로 활용할 수 있다.(&lt;span style=&quot;background-color: #ffffff; color: #262626; text-align: start;&quot;&gt;90ms, &lt;span style=&quot;background-color: #ffffff; color: #262626; text-align: start;&quot;&gt;48.58&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;MB)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또, 재귀로 풀지 않을 경우 다음의 해설을 참고할 수 있다.&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1695806056628&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;var addTwoNumbers = function(l1, l2) {
    let sum = 0;
    let current = new ListNode(0);
    let result = current;

    while (l1 || l2) {
        if (l1) {
            sum += l1.val;
            l1 = l1.next;
        }

        if (l2) {
            sum += l2.val;
            l2 = l2.next;
        }
        current.next = new ListNode(sum % 10);
        current = current.next;

        sum = sum &amp;gt; 9 ? 1: 0;
    }
    // 0은 falsy 값이므로.
    if (sum) {
        current.next = new ListNode(sum);
    }

    return result.next;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 current라는 변수를 이용해, 더할 값이 남아있다면 current = current.next로 current에 계속 더해지도록 하고, 만약 더할 값이 남아있지 않은데 sum의 자릿수가 남았다면 해당하는 자릿수만큼을 하나 더하여 current node를 완성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;81ms, &lt;span style=&quot;background-color: #ffffff; color: #262626; text-align: start;&quot;&gt;47.71&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;MB&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <author>5묘</author>
      <guid isPermaLink="true">https://5myohan.tistory.com/161</guid>
      <comments>https://5myohan.tistory.com/161#entry161comment</comments>
      <pubDate>Wed, 27 Sep 2023 18:16:27 +0900</pubDate>
    </item>
    <item>
      <title>JavaScript 기초 - array</title>
      <link>https://5myohan.tistory.com/160</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;1. array의 Constructor :Array()&lt;br /&gt;2. array의 Property:&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1695259837747&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1) Array[@@species]
=&amp;gt; 현재 이 기능은 사라질 준비 중. toReserved() 같은 최신 배열 메서드가 새 Array 기반 클래스 인스턴스를 반환한다.
기존 배열을 변경하지 않고, 새 배열 인스턴스를 반환하는 배열 메서드(filter(), map())에서 생성자로 작용해,
반환된 생성자는 원 배열과 관련 없는 새로운 배열 메서드의 반환 값을 구성하게끔 된다.

2) Array.prototype[@@unscopables]
=&amp;gt; 이 속성이 있음으로서 ECMAScript 2015에 도입된 Array 속성이 with 문 바인딩 목적으로 무시돼
2015 이전에 작성된 코드가 중단되지 않고 예상대로 계속 작동 가능하다. 가령 아래 코드를 보자.

var keys = [];

with (Array.prototype) {
  keys.push(&quot;something&quot;);
}

ECMAScript 2015에 Array.prototype.keys() 메서드가 도입되었을 때, 
@@unscopables 데이터 속성이 함께 도입되지 않았다면, 
JavaScript 런타임이 keys를 예제 코드에 정의된 keys 배열이 아닌 
Array.prototype.keys() 메서드로 해석하기 때문에 
해당 keys.push('something') 호출이 중단될 수 있었습니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. array의 method들&lt;/p&gt;
&lt;pre id=&quot;code_1695269248103&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1) Array[@@iterator]():
[@@iterator]() 메서드는 순회가능 프로토콜(for..of 루프나 spread syntax({...elements}))을 구현하며,
이 메서드가 배열의 각 인덱스 값 산출하는 배열 순회자 객체를 반환한다.

이것은 반환된 순회자 객체의 .next() 메서드를 수동으로 호출해 순회 과정을 최대한 제어하는 것이 가능하다.
아래 예시를 보자.

const arr = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;, &quot;e&quot;];
const arrIter = arr[Symbol.iterator]();
console.log(arrIter.next().value); // a
console.log(arrIter.next().value); // b
console.log(arrIter.next().value); // c
console.log(arrIter.next().value); // d
console.log(arrIter.next().value); // e

2) Array.at()
정숫값을 받아 해당 인덱스에 있는 항목을 반환한다.
양수, 음수 사용 가능하며 음의 정수는 배열 마지막 항부터 거슬러 올라간다.
만약 index 값에 array의 length 값 넣게 되면, undefined 반환한다.

3) Array.concat()
두개 이상의 배열을 병합할 때 사용한다.
기존 배열을 변경하지 않고, 새 배열을 반환한다.

4) Array.copyWithin(target, start, end?)
배열의 일부를 같은 배열의 다른 위치로 얕게 복사한다.
배열의 길이를 수정하지 않고 변형된 배열을 반환한다.
copyWithin()은 end를 포함하지 않고 end 전 까지 복사한다.
end가 없다면 start부터 끝까지가 범위이다.

EX)
const array1 = ['a', 'b', 'c', 'd', 'e'];

// Copy to index 0 the element at index 3
console.log(array1.copyWithin(0, 3, 4));
// Expected output: Array [&quot;d&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;, &quot;e&quot;]

// Copy to index 1 all elements from index 3 to the end
console.log(array1.copyWithin(1, 3));
// Expected output: Array [&quot;d&quot;, &quot;d&quot;, &quot;e&quot;, &quot;d&quot;, &quot;e&quot;]


5) Array.entries()
배열의 각 인덱스에 대한 키/값 쌍을 포함하는 새 배열 반복자 객체를 반환한다.

EX)
const array1 = ['a', 'b', 'c'];

const iterator1 = array1.entries();

console.log(iterator1.next().value);
// Expected output: Array [0, &quot;a&quot;]

console.log(iterator1.next().value);
// Expected output: Array [1, &quot;b&quot;]


** entries()는 아래와 같은 상황에서 객체에서도 사용 가능하다
EX)
const arrayLike = {
  length: 3,
  0: &quot;a&quot;,
  1: &quot;b&quot;,
  2: &quot;c&quot;,
  3: &quot;d&quot;, // length가 3이므로 entries()에서 무시됩니다.
};
for (const entry of Array.prototype.entries.call(arrayLike)) {
  console.log(entry);
}
// [ 0, 'a' ]
// [ 1, 'b' ]
// [ 2, 'c' ]

entries() 메서드는 this의 length 속성을 읽은 다음 
키가 length보다 작은 음수가 아닌 정수 속성에 각각 접근합니다.


6) Array.every()
인자는 함수, 배열의 모든 함수가 인자인 함수를 통과하는지 테스트 시 사용, 반환값은 boolean.
(EX)
const isBelowThreshold = (currentValue) =&amp;gt; currentValue &amp;lt; 40;

const array1 = [1, 30, 39, 29, 10, 13];

console.log(array1.every(isBelowThreshold));
// Expected output: true

7) Array.fill()
인자는 (채울 값, 시작 인덱스 위치(option), 끝 인덱스 위치(option)),
배열 자체를 수정해서 return 값은 수정된 배열.end는 포함되지 않는다.

8) Array.filter()
배열의 복사본을 생성해, 제공된 함수를 통과한 요소로만 필터링.
통과한 요소 없으면 빈 배열이 반환된다.
인자는 (callbackFn, thisArg(option, 콜백함수 실행 시 this로 사용할 값))

9) Array.find()
Array 인스턴스의 find() 메서드는 배열에서 제공된 테스트 함수 만족하는 첫번째 요소를 반환한다.
만족하는 요소가 없으면 undefined 가 반환된다.
인자는 (callbackFn, thisArg(option, 콜백함수 실행 시 this로 사용할 값))

10) Array.findIndex()
Array 인스턴스의 findIndex() 메서드는 인자의 함수를 만족하는 배열의 첫번째 요소에 대한 인덱스를 반환한다.
만족하는 요소가 없으면 -1 을 반환한다.
인자는 (callbackFn, thisArg(option, 콜백함수 실행 시 this로 사용할 값))

11) Array.findLast()
배열을 역순으로 순회하며 제공된 테스트 함수를 만족하는 첫번쨰 요소의 값을 반환한다.
만족하는 요소가 없으면 undefined 가 반환된다.
인자는 (callbackFn, thisArg(option, 콜백함수 실행 시 this로 사용할 값))

12) Array.findLastIndex()
배열을 역순으로 순회하며 제공된 테스트 함수를 만족하는 첫번쨰 요소의 인덱스를 반환한다.
만족하는 요소가 없다면 배열의 첫번째 요소의 인덱스를 반환한다.
인자는 (callbackFn, thisArg(option, 콜백함수 실행 시 this로 사용할 값))

13) Array.flat()
모든 하위 배열 요소들을 하나의 배열로 합치는 것.
반환값은 하위 배열 요소가 연결된 새 배열이다.

Ex.)
const arr1 = [0, 1, 2, [3, 4]];
console.log(arr1.flat());
// expected output: Array [0, 1, 2, 3, 4]

const arr2 = [0, 1, [2, [3, [4, 5]]]];
console.log(arr2.flat());
// expected output: Array [0, 1, 2, Array [3, Array [4, 5]]]

들어갈 인자는 flat(배열, (depth,  depth는 optional. 중첩된 배열구조를 얼마나 깊이 평탄화할지 지정하는 수준, 기본값은 1이다.))

14) Array.flatMap()
.flatMap() 메서드는 배열의 각 요소에 주어진 콜백 함수를 적용한 뒤, 그 결과를 한 단계씩 평탄화해 새 배열을 반환한다.
이 메서드는 .map() 뒤에 .flat()을 붙이는 것을 한번에 수행하는 것과 동일하다.
반환값은 새 배열, 인자는 flatMap(callbackFn), flatMap(callbackFn, thisArg)이다.

EX)
const arr1 = [1, 2, 1];
const result = arr1.flatMap((num) =&amp;gt; (num === 2 ? [2, 2] : 1));
console.log(result);
// Expected output: Array [1, 2, 2, 1]

15) Array.forEach()
.forEach() 메서드는 각 배열 요소에 대해 제공된 함수를 한번씩 실행한다. 반환값은 없다.(undefined)
인자는 (callbackFn, thisArg(option, 콜백함수 실행 시 this로 사용할 값))

16) Array.from()
유사 배열 객체(array-like object)나 반복 가능한 객체(iterable object)를 얕게 복사해 새로운Array 객체를 만듭니다.
반환 값은 새로운 array, 
인자는 Array.from(arrayLike(배열로 변환하고자 하는 유사배열 객체나 반복적인 객체[, mapFn(optional, 배열의 모든 요소에 대해 호출할 매핑함수) [, thisArg(optional, mapFn 실행시 this로 사용할 값)]])

17) Array.fromAsync()
반환값: 비동기 순회객체, 유사배열 객체, 반복 가능한 순회객체로부터 얕게 복사한 배열을 반환한다.
인자는 Array.fromAsync(arrayLike, mapFn, thisArg) 위의 Array.from() 과 유사.

Ex)
const asyncIterable = (async function* () {
  for (let i = 0; i &amp;lt; 5; i++) {
    await new Promise((resolve) =&amp;gt; setTimeout(resolve, 10 * i));
    yield i;
  }
})();

Array.fromAsync(asyncIterable).then((array) =&amp;gt; console.log(array));
// [0, 1, 2, 3, 4]

18) Array.includes() 
includes() 메서드는 배열 내에 해당 요소가 있는지 확인해 true, false 값을 반환한다.

19) Array.indexOf()
indexOf() 메서드는 배열 내에 해당 요소가 발견된 가장 첫번째 인덱스를 반환한다. 
찾지 못하면 -1을 반환한다.
인자는 indexOf(searchElement, fromIndex(option, 시작 인덱스, negagtive(음수)나 fromIndex+array.length로 표현 가능하나 이때도 시작에서 끝 방향으로 가는 건 잊어선 안된다. 없으면 기본값 0))

20) Array.isArray()
인자로 들어간 요소가 Array인지 true, false 반환.

21) Array.join()
Array 안의 요소를 join의 인자로 들어간 요소를 구분자로 묶어, 하나의 string을 반환.
인자는 join(separator), 기본값은 ','이다.

Ex)
const elements = ['Fire', 'Air', 'Water'];

console.log(elements.join());
// Expected output: &quot;Fire,Air,Water&quot;

console.log(elements.join(''));
// Expected output: &quot;FireAirWater&quot;

console.log(elements.join('-'));
// Expected output: &quot;Fire-Air-Water&quot;


22) Array.keys()
keys()는 array 내의 요소들의 key(없다면 index)로 이루어진 새로운 배열을 반환한다.
인자는 없다. Object.keys와 달리 가운데 요소가 빠져 있어도 keys는 수집된다

Ex)
const arr = [&quot;a&quot;, , &quot;c&quot;];
const sparseKeys = Object.keys(arr);
const denseKeys = [...arr.keys()];
console.log(sparseKeys); // ['0', '2']
console.log(denseKeys); // [0, 1, 2]

23) Array.lastIndexOf()
인자의 요소가 배열 가장 마지막에 나타난 index를 반환한다.
없을 경우 -1을 반환한다.
lastIndexOf(searchElement,fromIndex(option, 시작 인덱스, negagtive(음수)나 fromIndex+array.length로 표현 가능하나 이때도 시작에서 끝 방향으로 가는 건 잊어선 안된다. 없으면 기본값 0))

24) Array.map()
인자로 들어간 함수를 적용한 새로운 배열을 반환한다.
인자는 map(callbackFn, thisArg(optional))

25) Array.of()
element를 인자로 받아서, 해당 element들로 배열을 만들어 반환한다.

Ex) 
console.log(Array.of('foo', 2, 'bar', true));
// Expected output: Array [&quot;foo&quot;, 2, &quot;bar&quot;, true]

console.log(Array.of());
// Expected output: Array []

Array.of(7); // [7]
Array(7); // array of 7 empty slots

Array.of(1, 2, 3); // [1, 2, 3]
Array(1, 2, 3); // [1, 2, 3]

26) Array.pop()
맨 끝의 요소를 반환 후 원 배열에서 제거한다.원래 배열을 변형시키는 작업.

26) Array.push()
맨 끝에 인자의 요소를 더한다. 원래 배열을 변형시키는 작업.

27) Array.reduce()
배열을 순회하며 callbackFn으로 인자의 요소들을 현재의 currentValue에 callbackFn 하여 반환.
인자는 reduce(callbackFn, initialValue(optional, 없으면 배열의 0번째 값))

28) Array.reduceRight()
reduce()를 오른쪽에서 왼쪽(반대)방향으로 진행.

29) Array.reverse()
배열 요소의 순서를 거꾸로 바꾼다. 거꾸로 바꾼 배열을 반환한다. 원래 배열을 변형시키는 작업.
인자는 없다.

30) Array.shift()
가장 첫번째 인자를 제거하고, 제거된 인자를 반환한다. 원래 배열을 변형시키는 작업.

31) Array.slice()
인자가 범위가 되어, 해당 범위만 자른 새로운 배열을 반환한다. 원래 배열은 변하지 않는다.
인자는 slice(start(optional, 없으면 처음부터 끝까지가 범위), end(optional, 없으면 Start부터 배열 끝까지가 범위))

32) Array.some()
특정 테스트를 통과하는 요소가 하나라도 있는지를 확인해 true, false 반환한다.
인자는 some(callbackFn, thisArg)

33) Array.sort()
uft-16 코드 규칙에 따라 오름차순 정렬. 원래 배열을 변형시키는 작업.(원래 배열 변형시키지 않으려면 .toSorted() 사용해라)

Ex)
const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// Expected output: Array [&quot;Dec&quot;, &quot;Feb&quot;, &quot;Jan&quot;, &quot;March&quot;]

const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);
// Expected output: Array [1, 100000, 21, 30, 4]


34) Array.splice()
Array의 특정 인덱스에서 deleteCount만큼을 제거하고, 새로운 아이템을 추가함. 원래 배열을 변형시키는 작업.(원래 배열 변형시키지 않으려면 .toSpliced() 사용해라)
인자는 splice(start, deleteCount(optional, 0이거나 없으면 아무 아이템도 제거하지 않는다.), item1(optional), item2(optional))

Ex)
const myFish = [&quot;angel&quot;, &quot;clown&quot;, &quot;drum&quot;, &quot;sturgeon&quot;];
const removed = myFish.splice(2, 1, &quot;trumpet&quot;);

// myFish is [&quot;angel&quot;, &quot;clown&quot;, &quot;trumpet&quot;, &quot;sturgeon&quot;]
// removed is [&quot;drum&quot;]

35) Array.toLocaleString()
locale 설정이 적용된 문자열을 반환한다.(Date나, 시간이나..)

36) Array.toReversed ~toSpliced()
원래 배열을 변환시키지 않으며, 새로운 배열을 반환한다.

37) toString()
지정된 배열을 문자열로 변환한 것을 반환한다.

Ex)
const array1 = [1, 2, 'a', '1a'];

console.log(array1.toString());
// Expected output: &quot;1,2,a,1a&quot;

38) Array.unShift()
새로운 요소를 배열의 맨 앞쪽에 추가하고, 새로운 길이(array.length)를 반환한다.원래 배열을 변형시키는 작업.

Ex)
const array1 = [1, 2, 3];

console.log(array1.unshift(4, 5));
// Expected output: 5

console.log(array1);
// Expected output: Array [4, 5, 1, 2, 3]

39) Array.values()
배열에서 각 인덱스의 값을 담은 새로운 iterator을 반환한다.

40) Array.with()
주어진 인덱스의 값을 변경하기 위해 대괄호 표기법을 사용하는 것의 복사 버전.
원 배열을 변형하지 않고, 새 배열을 반환한다.
인자는 array.with(index, value)


** 더 공부해야 하는 것 =&amp;gt; 순회 메소드의 thisArg의 역할&lt;/code&gt;&lt;/pre&gt;</description>
      <category>개발 공부/자바스크립트</category>
      <author>5묘</author>
      <guid isPermaLink="true">https://5myohan.tistory.com/160</guid>
      <comments>https://5myohan.tistory.com/160#entry160comment</comments>
      <pubDate>Thu, 21 Sep 2023 10:51:01 +0900</pubDate>
    </item>
    <item>
      <title>[LeetCode] Two Sums</title>
      <link>https://5myohan.tistory.com/159</link>
      <description>&lt;figure id=&quot;og_1695037472692&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;LeetCode - The World's Leading Online Programming Learning Platform&quot; data-og-description=&quot;Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.&quot; data-og-host=&quot;leetcode.com&quot; data-og-source-url=&quot;https://leetcode.com/problems/two-sum/editorial/?source=submission-ac&quot; data-og-url=&quot;https://leetcode.com/problems/two-sum/editorial/?source=submission-ac&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bJkMoB/hyTVZ0Q9KT/kv3KVCEkQJ9vbfMjd8mtZ0/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260&quot;&gt;&lt;a href=&quot;https://leetcode.com/problems/two-sum/editorial/?source=submission-ac&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://leetcode.com/problems/two-sum/editorial/?source=submission-ac&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bJkMoB/hyTVZ0Q9KT/kv3KVCEkQJ9vbfMjd8mtZ0/img.png?width=500&amp;amp;height=260&amp;amp;face=0_0_500_260');&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;LeetCode - The World's Leading Online Programming Learning Platform&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Level up your coding skills and quickly land a job. This is the best place to expand your knowledge and get prepared for your next interview.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;leetcode.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Two Sums:&amp;nbsp; &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px; background-color: #ffffff; color: #262626;&quot;&gt;Given an array of integers&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px; background-color: #ffffff; color: #262626;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px; background-color: #ffffff; color: #262626;&quot;&gt;nums&amp;nbsp;and an integer&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px; background-color: #ffffff; color: #262626;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px; background-color: #ffffff; color: #262626;&quot;&gt;target, return&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px; background-color: #ffffff; color: #262626;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px; background-color: #ffffff; color: #262626;&quot;&gt;indices of the two numbers such that they add up to&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px; background-color: #ffffff; color: #262626;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px; background-color: #ffffff; color: #262626;&quot;&gt;target. &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #262626; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;You may assume that each input would have&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #262626; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;exactly&amp;nbsp;one solution&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #262626; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;, and you may not use the&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #262626; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #262626; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;same&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #262626; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; color: #262626; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;element twice.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #262626; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;You can return the answer in any order.&lt;/span&gt;&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #262626; text-align: start;&quot;&gt;
&lt;div data-track-load=&quot;description_content&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;Example 1:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Example 2:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;Input: nums = [3,2,4], target = 6
Output: [1,2]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Example 3:&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000;&quot;&gt;&lt;code&gt;Input: nums = [3,3], target = 6
Output: [0,1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;내가 작성한 정답&lt;/h4&gt;
&lt;pre id=&quot;code_1695037458977&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function twoSum(nums: number[], target: number): number[] {
    let result = [];
    for (let now=0; now &amp;lt; nums.length - 1; now++) {
        for (let next=1; next &amp;lt; nums.length; next++) {
            if (nums[now] + nums[next] === target) {
                if (now !== next &amp;amp;&amp;amp; !result.includes(now) &amp;amp;&amp;amp; !result.includes(next)) {
                result.push(now, next)
                };
            }
        }
    }
    return result;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이중 반복문을 사용해 O(n^2)의 시간 복잡도로 풀었다.&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;h4 data-ke-size=&quot;size20&quot;&gt;더 좋은 방법&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HashTable을 이용한다.&lt;/p&gt;
&lt;pre id=&quot;code_1695037748772&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Solution:
    def twoSum(self, nums: List[int], target: int) -&amp;gt; List[int]:
        hashmap = {}
        for i in range(len(nums)):
            complement = target - nums[i]
            if complement in hashmap:
                return [i, hashmap[complement]]
            hashmap[nums[i]] = i&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;target에서 반복문에서 돌아가는 숫자를 뺀 값을 hashMap 상에 complement라는 key로, 인덱스는 value로 저장한다. 만약 complement가 이미 hashmap에 key 값으로 존재한다면 해당 complement에 해당하는 인덱스를 불러온다.(아마 여기서 배열의 순서는 중요하지 않은 듯하다.)&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;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;hashmap이란? : &lt;a href=&quot;https://velog.io/@taeha7b/datastructure-hashtable&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://velog.io/@taeha7b/datastructure-hashtable&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1695037945040&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;[자료구조] Dictionary / HashMap / HashTable&quot; data-og-description=&quot;HashTable(해시 테이블)은 Key 와 Value 의 쌍으로 데이터를 저장하는 자료구조 입니다. 언어에 따라서 HashMap이라고도 불리며, 파이썬의 Dictionary 또한 HashTable로 구현되어 있습니다.&quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@taeha7b/datastructure-hashtable&quot; data-og-url=&quot;https://velog.io/@taeha7b/datastructure-hashtable&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bs6D1z/hyTY6KOvLR/ZpD59iI1dVprATikRjV221/img.jpg?width=666&amp;amp;height=350&amp;amp;face=0_0_666_350,https://scrap.kakaocdn.net/dn/dmklxz/hyTVV5e0z4/J9f8dhUtFyZuVOiFB2kkJ0/img.jpg?width=666&amp;amp;height=350&amp;amp;face=0_0_666_350,https://scrap.kakaocdn.net/dn/veViy/hyTVZT5CVU/SPG1OxOXqEItpH74M2Wfqk/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675&quot;&gt;&lt;a href=&quot;https://velog.io/@taeha7b/datastructure-hashtable&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@taeha7b/datastructure-hashtable&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bs6D1z/hyTY6KOvLR/ZpD59iI1dVprATikRjV221/img.jpg?width=666&amp;amp;height=350&amp;amp;face=0_0_666_350,https://scrap.kakaocdn.net/dn/dmklxz/hyTVV5e0z4/J9f8dhUtFyZuVOiFB2kkJ0/img.jpg?width=666&amp;amp;height=350&amp;amp;face=0_0_666_350,https://scrap.kakaocdn.net/dn/veViy/hyTVZT5CVU/SPG1OxOXqEItpH74M2Wfqk/img.jpg?width=1200&amp;amp;height=675&amp;amp;face=0_0_1200_675');&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;[자료구조] Dictionary / HashMap / HashTable&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;HashTable(해시 테이블)은 Key 와 Value 의 쌍으로 데이터를 저장하는 자료구조 입니다. 언어에 따라서 HashMap이라고도 불리며, 파이썬의 Dictionary 또한 HashTable로 구현되어 있습니다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h2 id=&quot;1-hashtable&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;HashTable&lt;/b&gt;(해시 테이블)은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Key&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Value&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;의 쌍으로 데이터를 저장하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;자료구조&lt;/b&gt;다.&lt;br /&gt;언어에 따라서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;HashMap&lt;/b&gt;이라고도 불리며, 파이썬의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Dictionary&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;또한 HashTable로 구현되어 있다.&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;HashTable(HashMap, Dictionary)의 특징은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;순차적으로 데이터를 저장하지 않는다.(non-iterable)&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Key를 통해서 Value값을 얻는다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Value값은 중복가능 하지만 Key는 중복될 수 없다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;수정 가능하다.(mutable)&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;파이썬의 List나 자바스크립트의 Array와 달리 저장된 데이터를 순차적으로 찾는게 아니고,&lt;br /&gt;Key값을 통해서 Value값을 찾기 때문에 빠르다.&lt;/p&gt;</description>
      <category>개발 공부/알고리즘 문제풀이</category>
      <category>leetcode</category>
      <author>5묘</author>
      <guid isPermaLink="true">https://5myohan.tistory.com/159</guid>
      <comments>https://5myohan.tistory.com/159#entry159comment</comments>
      <pubDate>Mon, 18 Sep 2023 21:07:25 +0900</pubDate>
    </item>
    <item>
      <title>타입스크립트 핸드북 (1~4)</title>
      <link>https://5myohan.tistory.com/147</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://joshua1988.github.io/ts/guide/functions.html#this&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://joshua1988.github.io/ts/guide/functions.html#this&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1679531069124&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;함수 | 타입스크립트 핸드북&quot; data-og-description=&quot;타입스크립트에서의 함수 웹 애플리케이션을 구현할 때 자주 사용되는 함수는 타입스크립트로 크게 다음 3가지 타입을 정의할 수 있습니다. 함수의 파라미터(매개변수) 타입 함수의 반환 타입 &quot; data-og-host=&quot;joshua1988.github.io&quot; data-og-source-url=&quot;https://joshua1988.github.io/ts/guide/functions.html#this&quot; data-og-url=&quot;https://joshua1988.github.io/ts/guide/functions.html#this&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://joshua1988.github.io/ts/guide/functions.html#this&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://joshua1988.github.io/ts/guide/functions.html#this&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;함수 | 타입스크립트 핸드북&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;타입스크립트에서의 함수 웹 애플리케이션을 구현할 때 자주 사용되는 함수는 타입스크립트로 크게 다음 3가지 타입을 정의할 수 있습니다. 함수의 파라미터(매개변수) 타입 함수의 반환 타입&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;joshua1988.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 기본타입&lt;/h3&gt;
&lt;pre id=&quot;code_1679908910258&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;기본 타입은 크게 12가지가 있다.

Boolean - 타입이 진위값인 경우
let isLoggedIn : boolean = false;

Number - 타입이 숫자일 때
let num : number = 10;

String - 타입이 문자일 때
let str : string = 'hi';

Object 

Array - 타입이 배열인 경우는 아래처럼 선언
let arr: Array&amp;lt;number&amp;gt; = [1, 2, 3]

Tuple - 배열의 길이가 고정되고, 각 요소의 타입 지정되어있는 배열 형식
let arr: [string, number] = ['hi', 10];

Enum - 자바, C에서 흔히 쓰이는 타입으로 특정값(상수)들의 집합을 의미
enum Avengers {Capt, IronMan, Thor}
let hero : Avengers = Avengers.Capt;

Any - 모든 타입에 대해 허용

Void - 변수에 undefined와 null만 할당하고, 함수에는 반환값을 설정할 수 없는 타입
let unuseful : void = undefined;
function notuse() : void{
   console.log('sth');
}

Null
Undefined

Never - 함수의 끝에 절대 도달하지 않는다는 의미를 지닌 타입
// 이 함수는 절대 함수의 끝까지 실행되지 않는다는 의미
function neverEnd() : never {
	while (true) {
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 함수&lt;/h3&gt;
&lt;pre id=&quot;code_1679909401810&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;웹 애플리케이션 구현 시 자주 사용되는 함수는 타입스크립트로 크게 다음 3가지 타입 정의할 수 있다.

1. 함수의 파라미터(매개변수) 타입
2. 함수의 반환 타입
3. 함수의 구조 타입

# 함수의 기본적인 타입 선언: 
	매개변수와 합수의 반환값에 타입을 추가 (반환값 타입 정하지 않을 때는 void라도 사용)
    function sum(a: number, b: number) : number {
        retutn a + b;
    }

# 함수의 인자:
	타입스크립트에서는 함수의 인자를 모두 필수값으로 간주한다. 
    따라서, 함수의 매개변수 설정 시, undefined나 null 이라도 인자로 넘겨야 하며, 
    컴파일러에서 정의된 매개변수 값이 넘어왔는지 확인한다. 정의된 매개변수 값 외에 추가로 값을 받을 순 없다.
    
    하지만 자바스크립트에서는 매개변수 갯수만큼 인자를 넘기지 않아도 된다.
    이 특성 살리고 싶으면 ? 을 이용하다.
    
    매개변수 초기화 시에는 타입을 붙이지 않는다.
    function sum(a: number, b='100'): number {
        return a + b; 
    }

# ES6 문법에서 지원하는 REST 문법
	function sum(a: number, ...nums: number[]) : number {
    	const totalOfNums = 0;
        for (let key in nums) {
        	totalOfNums += nums[key];
        }
        return a + totalOfNums;
    }&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;cf) javascript rest 문법(&lt;a href=&quot;https://learnjs.vlpt.us/useful/07-spread-and-rest.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://learnjs.vlpt.us/useful/07-spread-and-rest.html&lt;/a&gt;)&lt;/p&gt;
&lt;pre id=&quot;code_1679532071279&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const purpleCuteSlime = {
  name: '슬라임',
  attribute: 'cute',
  color: 'purple'
};

const { color, ...rest } = purpleCuteSlime;
console.log(color);
console.log(rest);

//꼭 rest라 쓰지 않아도 됨.

const purpleCuteSlime = {
  name: '슬라임',
  attribute: 'cute',
  color: 'purple'
};

const { color, ...cuteSlime } = purpleCuteSlime;
console.log(color);
console.log(cuteSlime);

const { attribute, ...slime } = cuteSlime;
console.log(attribute);
console.log(slime);&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1679532420517&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// 함수에서 rest를 사용할 때
// 다음의 경우 파라미터가 7개라 인자 7개가 가야 하는데 6개만 오기 때문에 마지막 하나인 g가 undefined가 돼서
// 합했을 때 숫자 + undefined = NaN이 되어버린다.

function sum(a, b, c, d, e, f, g) {
  let sum = 0;
  if (a) sum += a;
  if (b) sum += b;
  if (c) sum += c;
  if (d) sum += d;
  if (e) sum += e;
  if (f) sum += f;
  if (g) sum += g;
  return sum;
}

const result = sum(1, 2, 3, 4, 5, 6);
console.log(result);

// 이를 방지하기 위해 아래와 같이 rest를 사용할 수 있다.
function sum(...rest) {
  return rest.reduce((acc, current) =&amp;gt; acc + current, 0);
}

const result = sum(1, 2, 3, 4, 5, 6);
console.log(result); // 21&lt;/code&gt;&lt;/pre&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;this가 가리키는 것 명시하려면 아래와 같은 문법 써준다.&lt;/p&gt;
&lt;pre id=&quot;code_1679531365147&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface Vue {
    el: string;
    count: number;
    init(this: Vue) : () =&amp;gt; {};
}

let vm: Vue = {
    el: '#app',
    count: 10,
    init: function(this: Vue) {
        return () =&amp;gt; {
            return this.count;
        }
    }
}

let getCount = vm.init();
let count = getCount();
console.log(count);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 콜백으로 함수가 전달되었을 때 this를 구분해줘야 하는데 이럴 땐 아래와 같이 강제할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1679532795725&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;interface UIElement {
    //아래의 함수에서 'this:void' 코드는 함수에 'this' 타입을 선언할 필요가 없다는 의미입니다.
    addClickListener(onclick: (this: void, e: Event) =&amp;gt; void) : void;
}

// class Handler {
//     info: string;
//     onClick(this: Handler, e: Event) {
//         // 위의 `UIElement` 인터페이스의 스펙에 this는 필요없다 했지만 사용했기 때문에 에러가 발생합니다.
//         this.info = e.message;
//     }
// }

class Handler {
    info: string;
    onClick(this: void, e: Event) {
        console.log('clicked')
    }
}


let handler = new Handler();
uiElement.addClickListener(handler.onClick);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 바로 클래스의 메서드 방식으로 선언하는 것과 변수에 화살표 함수를 연결하는 것의 차이점이다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 인터페이스&lt;/h3&gt;
&lt;pre id=&quot;code_1679909969844&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;인터페이스는 상호 간에 정의한 약속, 혹은 규칙을 의미한다.
타입스크립트에서 인터페이스는 보통 다음의 범주에 대해 약속을 정의한다.

- 객체의 스펙(속성과 속성의 타입)
- 함수의 파라미터
- 함수의 스펙(파라미터, 반환 타입 등)
- 배열과 객체를 접근하는 방식
- 클래스

# 인터체이스에 대해 알아볼 간단한 예제를 보자

    let person = {naem: 'Capt', age: 28};
    function logAge(obj: {age: number}) { // 인자를 받을 때 객체의 속성타입까지 정의 가능
        console.log(obj.age);
    }
    logAge(person); //28

    만약 여기에 인터페이스를 적용한다면? 
    interface personAge {
        age: number;
    }

    function logAge(obj: personAge) { //인자가 'personAge'란 이름 얻어 보다 명시적으로 바뀜
        console.log(obj.age);
    }

    let person = {name: 'Capt', age: 28};
    logAge(person);

    인터페이스를 인자로 받아 사용할 때는 '인터페이스에 정의된 속성 개수'가 '인자의 속성 개수' 보다 적어도 된다. 
    하지만 인자의 속성은 인터페이스에 정의된 속성 개수는 반드시 포함해야 한다.(옵션 속성 제외)
    또 속성 순서를 지키지 않아도 된다.

# 옵션 속성: 속성에 ? 붙이기.
    interface 인터페이스_이름 {
      속성? : 타입;
    }

# 옵션 속성의 장점
    단순히 인터페이스 사용할 때 속성 선택적으로 적용가능한 것 뿐 아님!
    인터페이스에 정의되지 않은 속성을 인지시키는 것이 가능하다는 것이다.
    
 # 읽기 전용 속성
     읽기 전용 속성은 인터페이스로 객체 처음 생성할 때만 값 할당하고, 그 이후에는 변경 불가능한 속성을 의미한다.
     문법은 다음과 같이 readOnly 속성을 앞에 붙인다.
    interface CraftBeer {
       readonly brand: string;
    }
    
# 읽기 전용 배열
    배열 선언 시 ReadonlyArray&amp;lt;T&amp;gt; 타입 사용하면 읽기 전용 배열 생성 가능하다.
    
    let arr: ReadonlyArray&amp;lt;number&amp;gt; = [1, 2, 3];
    arr.splice(0,1); //errror
    arr.push(4);  //errror
    arr[0] = 100; //errror
    
    이처럼 배열을 ReadonlyArray로 선언 시 배열의 내용 변경할 수 없다. 선언 시점에만 값 정의 가능하다.

# 객체 선언과 관련된 타입 체킹
    타입스크립트는 인터페이스를 이용해 객체를 선언할 때 좀 더 엄밀한 속성 검사를 진행한다.
    만약 까다로운 타입 추론을 무시하고 싶다면 아래와 같이 선언한다.

    let myBeer = { brandon: 'what' };
    brewBeer(myBeer as CraftBeer);

    그럼에도 불구하고 인터페이스에서 정의하지 않은 속성들을 추가로 사용하고 싶다면?
    이렇게 하면 된다.

    interface CraftBeer {
      brand?: string;
      [propName: string]: any;
    }

# 함수 타입
    인터페이스는 함수의 타입을 정의할 때도 쓸 수 있다.

    interface login {
        (username: string, password: string): boolean;
    }

    let loginUser : login;
    loginUser = function(id: string, pw: string) {
        console.log('로그인 했습니다.');
        return true;
    }
    
# 클래스 타입
    C#이나 자바처럼 타입스크립트에서도 클래스가 일정 조건을 만족하도록 타입 규칙을 정할 수 있다.
    interface CraftBeer {
        beerName: string;
        nameBeer(beer: string) : void;
    }

    class myBeer implements CraftBeer {
        beerName: string = 'Baby Guinness';
        nameBeer(b: string) {
            this.beerName = b;
        }
        constrouctor () {}
    }

    const newBeer = new myBeer();
    console.log(newBeer.beerName);
    console.log(newBeer.nameBeer('Good Shot'));
    console.log(newBeer.beerName);

# 인터페이스 확장
    클래스와 마찬가지로 인터페이스도 인터페이스 간 확장이 가능하다.
    interface Person {
        name: string;
    }

    interface Developer extends Person {
        skill : string;
    }

    let fe = {} as Developer
    fe.name = 'josh';
    fe.skill = 'TypeScript';

    혹은 아래와 같이 여러 인터페이스를 상속받아 사용할 수 있다.
    interface Person {
        name: string;
    }

    interface Drinker {
        drink: string;
    }

    interface Developer extends Person, Drinker {
        skill: string;
    }

    let fe = {} as Developer;
    fe.name = 'josh';
    fe.skill = 'TypeScript';
    fe.drink ='Beer';

# 하이브리드 타입
    인터페이스는 다음과 같이 함수 타입이면서 객체 타입을 정의할 수 있는 인터페이스처럼, 
    여러가지 타입을 조합해 만들 수 있다.

    interface CraftBeer {
        (beer: string) : string;
        brand: string;
        brew() : void;
    }

    function myBeer() : CraftBeer {
        let my = (function(beer:string) {}) as CraftBeer;
        my.brand = 'Beer Kitchen';
        my.brew =  function() {};
        return my
    }

    let brewedBeer = myBeer();
    brewedBeer('My First Beer');
    brewedBeer.brand = 'Pangyo Craft';
    brewedBeer.brew();
    
# 클래스를 상속받는 인터페이스
interface가 클래스의 상속을 받을 때 내부의 private, protected 속성들도 모두 상속받는다.
이렇게 클래스를 상속받는 interface를 implement하려면 클래스나 하위 클래스 역시 extends(상속) 받아야 한다.

class Control {
  private state: any;
}
 
interface SelectableControl extends Control {
  select(): void;
}
 
class Button extends Control implements SelectableControl {
  select() {}
}
 
class TextBox extends Control {
  select() {}
}
 
class ImageControl implements SelectableControl {
// Class 'ImageControl' incorrectly implements interface 'SelectableControl'.
// Types have separate declarations of a private property 'state'.
  private state: any;
  select() {}
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;4. 이넘&lt;/h3&gt;
&lt;pre id=&quot;code_1680488461144&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;이넘은 특정 값들의 집합을 의미하는 자료형.

1. 숫자형 이넘 선언
enum Direction {
Up = 1, //1
Down,  //2
Left,  //3
Right //4
}

숫자형 이넘에 초기값을 주면 초기값부터 차례로 1씩 증가
초기값 주지 않으면 0부터 차례로 1씩 증가

enum Direction {
Up, // 0
Down, // 1
Left, // 2
right // 3
}

숫자형 이넘은 다음처럼 사용 가능하다.

enum Response {
    No = 0,
    Yes = 1,
}

function respond(recipient: string, message: Response): void {
    // ...
}

respond(&quot;Captain Pangyo&quot;, Response.Yes);

문자형 이넘은 반드시 초기값을 줘야 한다
enum Direction {
    Up = &quot;UP&quot;,
    Down = &quot;DOWN&quot;,
    Left = &quot;LEFT&quot;,
    Right = &quot;RIGHT&quot;,
}

복합 이넘(권고X, 최대한 같은 타입으로 이루어진 이넘 사용 추천)
enum BooleanLikeHeterogeneousEnum {
    No = 0,
    Yes = &quot;YES&quot;,
}

런타임 시점에서의 이넘 =&amp;gt; 런타임 시 이넘은 실제 객체 형태로 존재한다.
가령 아래와 같은 이넘 코드 있을 때

enum E {
  X, Y, Z
}

function getX(obj: { X: number }) {
  return obj.X;
}
getX(E); // 이넘 E의 X는 숫자이기 때문에 정상 동작

컴파일 시점에서의 이넘 =&amp;gt; 런타임에서는 실제객체이지만 keyof 대신 keyof typeof를 사용해야 한다.
enum LogLevel {
    ERROR, WARN, INFO, DEBUG
}

//'ERROR' | 'WARN' | 'INFO' | 'DEBUG'
type LogLevelStrings = keyof typeof LogLevel;

function printImportant(key:LogLevelStrings, message: string) {
    const num = LogLevel[key];
    if (num &amp;lt;= LogLevel.WARN) {
        console.log('Log Level key is',key);
        console.log('Log Level value is',num);
        console.log('Log Level message is',message)
    }
}
    printImportant('ERROR', 'This is Message')
    
    리버스 매핑 =&amp;gt; 숫자형 이넘에만 존재하는 특징. 이넘의 키(key) 로 값을 얻을 수 있고 값으로 키를 얻을 수 있다.
    
enum Enum {
	A
  }

let a = Enum.A; // 키로 값을 획득
let keyName = Enum[a]; // 값으로 키를 획득&lt;/code&gt;&lt;/pre&gt;</description>
      <category>개발 공부/타입스크립트</category>
      <author>5묘</author>
      <guid isPermaLink="true">https://5myohan.tistory.com/147</guid>
      <comments>https://5myohan.tistory.com/147#entry147comment</comments>
      <pubDate>Mon, 27 Mar 2023 18:42:24 +0900</pubDate>
    </item>
    <item>
      <title>타입스크립트 가이드 읽기 - 1. The Basics</title>
      <link>https://5myohan.tistory.com/146</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. The Basics&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Typescript는 함수, string, object 등 타입을 명확하게 정의해주어, 사용할 수 없는 메서드를 사용하는 일이 없도록 방지한다. (ex. function.toLowerCase();)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;javascript는 동적 타입 검사(타입 오류를 동작 수행 전에는 알 수 없고, 코드 실행해 호출해봐야 안다)만 제공한다. 그래서 어떤 동작 결과를 보일지 &lt;b&gt;코드를 작성하는 동안&amp;nbsp;&lt;/b&gt;확인하기 위해 Typescript 사용하는 것이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;정적 타입 검사 필요한 이유&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1) JavaScript가 런타임 시 내보내는 오류는 ECMA Script 명세에 적힌 대응법 기반이다. 그런데 당연히 오류를 띄워야 할 상황에서 아래처럼 이상하게 작동할 때가 있다. 아예 정의되지 않은 속성을 불러오는데 오류가 아니라 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;undefined&lt;/span&gt;가 뜬다.&lt;/p&gt;
&lt;pre id=&quot;code_1675292438848&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const user = {
  name: &quot;Daniel&quot;,
  age: 26,
};
user.location; // undefined 를 반환&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 현재 오류 없이 유효한 자바스크립트 코드더라도, 정적 타입 시스템 내애서 오류로 간주되는 경우 오류를 발생시킨다.(타입스크립트의 장점)&lt;/p&gt;
&lt;pre id=&quot;code_1675292539177&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;const user = {
  name: &quot;Daniel&quot;,
  age: 26,
};
 
user.location;
Property 'location' does not exist on type '{ name: string; age: number; }'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 외에도 타입스크립트는 2) 오타를 잡거나, 3) 호출되지 않은 함수(괄호를 빼먹었다던지), 4) 기본적인 논리 오류를 잡아낼 때 사용 가능하다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;타입스크립트 컴파일러, TSC&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ts 파일을 컴파일 해서 js 형태로 출력한다.&amp;nbsp;&lt;br /&gt;실수에 보다 방어적으로 대응할 목적이면 &lt;span style=&quot;background-color: #f1f1fe;&quot;&gt;tsc &lt;span style=&quot;color: #000000;&quot;&gt;--noEmitOnError&amp;nbsp;&lt;/span&gt; hello.ts&lt;/span&gt; 명령어를 사용해보자. 그러면 hello.ts에 작성한 코드 중 타입 검사를 통과하지 않은 것이 js로 수정되어 출력되지 않게 된다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;명시적 타입&amp;nbsp;&lt;/h4&gt;
&lt;pre id=&quot;code_1675293388973&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function greet(person: string, date: Date) {
  console.log(`Hello ${person}, today is ${date.toDateString()}!`);
}

greet(&quot;Maddison&quot;, new Date());&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명시적인 타입 표기를 작성하지 않더라도, 타입스크립트가 알아서 타입 정보를 추론할 수도 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;186&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/x5lRs/btrXMTw1foI/vcZqcWQNA7m7dVfQNFla6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/x5lRs/btrXMTw1foI/vcZqcWQNA7m7dVfQNFla6K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/x5lRs/btrXMTw1foI/vcZqcWQNA7m7dVfQNFla6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fx5lRs%2FbtrXMTw1foI%2FvcZqcWQNA7m7dVfQNFla6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;295&quot; height=&quot;139&quot; data-origin-width=&quot;395&quot; data-origin-height=&quot;186&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;지워진 타입&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 ts 파일은 아래의 js파일로 tsc를 통해 변환된다.&lt;/p&gt;
&lt;pre id=&quot;code_1675293672060&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&quot;use strict&quot;;
function greet(person, date) {
    console.log(&quot;Hello &quot;.concat(person, &quot;, today is &quot;).concat(date.toDateString(), &quot;!&quot;));
}
greet(&quot;Maddison&quot;, new Date());&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때, person과 date에 명시해둔 타입은 지워지고, 백틱 사용한 template literal이 연결연산자(+, concat)으로 이어진 하나의 문자열로 변환되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;타입 표기는 JavaScript(ECMAScript)의 일부가 아니기 때문에 TypeScript를 수정 없이 그대로 실행할 수 있는 브라우저나 런타임은 존재하지 않는다. 그래서 컴파일러 이용해 typescript 전용 코드가 제거되고, 타입표기 또한 지워진다. 타입 표기는 프로그램의 런타임 동작을 전혀 수정하지 않고, 코드 작성 중 에러를 띄워줄 뿐이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;다운 레벨링&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 템플릿 리터럴이 연결연산자로 변환된 것을 보았다. 템플릿 문자열은 ECMA Script 2015(ES6) 버전에서 등장ㅎ란 기능이다. TypeScript는 이런 새 버전의&amp;nbsp; ECMAScript를 ECMAScript 3나 5처럼 예전 버전으로 다시 작성해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 상위 버전의 ECMAScript를 하위 버전의 것으로 바꾸는 과정을 &quot;다운레벨링&quot;이라고 부른다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TypeScript는 ES3라는 아주 구버전의 ECMAScript를 타겟으로 동작하는 것이 기본 동작이다.(&lt;span style=&quot;background-color: #f1f1fe;&quot;&gt;--target 플래그&lt;/span&gt; 설정하면 최근 버전을 타겟으로 변환할 수도 있다. ex)&lt;span style=&quot;background-color: #f1f1fe;&quot;&gt; tsc --target es2015 input.ts&lt;/span&gt;)&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(기본적인 타겟값 ES3지만, 현존하는 대다수 브라우저들이 ES2015 지원하므로 안심하고 ES2015 또는 그 이상을 컴파일러 타겟으로 정할 수 있다.)&lt;/p&gt;
&lt;h4 id=&quot;엄격도&quot; data-ke-size=&quot;size20&quot;&gt;엄격도&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 제공: 타입 검사는 선택사항, 타입 추론은 가장 느슨, 잠재적인 null / undefined 값에 대한 검사 이루어지지 않음&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;엄격도 설정을 통해 최대한도의 타입 검사 가능하다. 엄격도를 활성화하는 방법은 CLI에서 --strict 플래그를 활성화하거나 tsconfig.json에 &lt;span style=&quot;background-color: #f1f1fe; color: #000000;&quot;&gt;&quot;strict&quot;: true&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 를 추가하는 것이다. &lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;반드시 알아야 하는 두 가지 가장 주요한 옵션은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;noImplicitAny&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;와&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;strictNullChecks이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f1f1fe; color: #000000;&quot;&gt;noImplicitAny&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;몇몇 경우 Typescript는 타입을 추론하지 않고 가장 관대한 타입인 any로 간주한다. 하지만 any를 사용하면 타입스크립트 사용하는 이유 무색하기 때문에, 이 noImplicitAny 플래그를 활성화하면 타입이 any로 암묵적으로 추론되는 변수에 대해 오류 발생시킨다.&lt;span style=&quot;background-color: #f1f1fe; color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f1f1fe;&quot;&gt;strictNullChecks&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;null과 undefined와 같은 값은 다른 타입의 값에 살당할 수 있는 기본 동작이지만, 이의 처리를 잊는 것 많은 버그의 원인이 될 수 있다. strictNullChecks 플래그는 null과 undefined를 보다 명시적으로 처리하게 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a href=&quot;https://www.typescriptlang.org/ko/docs/handbook/2/basic-types.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.typescriptlang.org/ko/docs/handbook/2/basic-types.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1675294314268&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Documentation - The Basics&quot; data-og-description=&quot;TypeScript를 배우는 첫 걸음: 기본 타입.&quot; data-og-host=&quot;www.typescriptlang.org&quot; data-og-source-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/2/basic-types.html&quot; data-og-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/2/basic-types.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.typescriptlang.org/ko/docs/handbook/2/basic-types.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/2/basic-types.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&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;Documentation - The Basics&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;TypeScript를 배우는 첫 걸음: 기본 타입.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.typescriptlang.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>개발 공부/타입스크립트</category>
      <category>타입스크립트</category>
      <category>타입스크립트 공식가이드</category>
      <author>5묘</author>
      <guid isPermaLink="true">https://5myohan.tistory.com/146</guid>
      <comments>https://5myohan.tistory.com/146#entry146comment</comments>
      <pubDate>Thu, 2 Feb 2023 08:32:10 +0900</pubDate>
    </item>
  </channel>
</rss>