<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[LEECY's Blog]]></title><description><![CDATA[This is LEECY's Blog]]></description><link>https://lcy042000.github.io</link><image><url>https://lcy042000.github.io/logos/leecy-logo-512W.png</url><title>LEECY&apos;s Blog</title><link>https://lcy042000.github.io</link></image><generator>GatsbyJS Advanced Starter</generator><lastBuildDate>Thu, 22 Feb 2024 14:32:59 GMT</lastBuildDate><atom:link href="https://lcy042000.github.io/rss.xml" rel="self" type="application/rss+xml"/><copyright><![CDATA[© Copyright 2021]]></copyright><item><title><![CDATA[[HOW]비동기 처리는 어떻게 동작될까?]]></title><description><![CDATA[…]]></description><link>https://lcy042000.github.io/javascript-how-asynchronous</link><guid isPermaLink="false">https://lcy042000.github.io/javascript-how-asynchronous</guid><category><![CDATA[HOW]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Asynchronous]]></category><pubDate>Thu, 22 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;자바스크립트는 싱글 스레드로 동작하기 때문에 한 번에 하나의 태스크만 처리할 수 있습니다. 이는 자바스크립트가 동기적으로 코드를 실행하는 방식을 의미합니다. 그러나 우리가 브라우저에서 웹 애플리케이션을 사용할 때 여러 작업이 동시에 처리되는 것처럼 느껴집니다. 지금부터 왜 그렇게 보이는지 알아보도록 하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://lcy042000.github.io/javascript-synchronous-and-asynchronous&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;비동기 처리가 무엇인지 궁금하다면...?&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;브라우저 환경&lt;/h3&gt;&lt;p&gt;브라우저에 내장된 자바스크립트 엔진은 대부분 &lt;strong&gt;콜 스택(실행 컨텍스트 스택)&lt;/strong&gt;과 &lt;strong&gt;힙&lt;/strong&gt;으로 나뉘어 있습니다. 콜 스택은 소스 코드 평가 후 생성된 실행 컨텍스트가 추가되어 순차적으로 태스크를 수행합니다. 힙은 객체가 저장되는 공간으로 태스크 실행 도중 필요한 객체들을 포함합니다.&lt;/p&gt;&lt;p&gt;비동기 처리에서 소스 코드 평가와 실행을 제외한 모든 작업은 자바스크립트 엔진을 작동시키는 브라우저가 담당합니다. 이를 위해 브라우저에서는 &lt;strong&gt;태스크 큐&lt;/strong&gt;와 &lt;strong&gt;이벤트 루프&lt;/strong&gt;를 제공합니다.&lt;/p&gt;&lt;h3&gt;비동기 처리 동작 과정&lt;/h3&gt;&lt;p&gt;비동기 함수가 호출되면 해당 함수의 작업은 백그라운드에서 처리됩니다. 이 작업이 완료되면 콜백 함수가 이벤트 루프를 통해 콜 스택으로 이동되어 실행됩니다. 이때 콜 스택이 비어있지 않으면 콜백 함수는 태스크 큐에서 대기하게 됩니다.&lt;/p&gt;&lt;p&gt;이벤트 루프는 콜 스택과 태스크 큐를 모니터링하면서, 콜 스택이 비어있고 대기 중인 콜백 함수가 있을 때마다 해당 함수를 콜 스택으로 이동시킵니다.&lt;/p&gt;&lt;p&gt;자바스크립트 엔진의 싱글 스레드 동작은 이러한 비동기 처리를 가능케 합니다. 즉, 단일 스레드에서 비동기적으로 작업을 처리하면서도 다른 작업은 브라우저의 다른 스레드에서 동시에 처리됩니다. 이는 브라우저가 멀티 스레드로 동작하기 때문입니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 42_비동기 프로그래밍(p.812 - 815)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]동기 or 비동기?]]></title><description><![CDATA[프로그래밍을 하다 보면 종종 ‘ 동기(synchronous)' 와  '비동기(asynchronous…]]></description><link>https://lcy042000.github.io/javascript-synchronous-and-asynchronous</link><guid isPermaLink="false">https://lcy042000.github.io/javascript-synchronous-and-asynchronous</guid><category><![CDATA[WHAT]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Synchronous]]></category><category><![CDATA[Asynchronous]]></category><pubDate>Thu, 22 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;프로그래밍을 하다 보면 종종 ‘&lt;strong&gt;동기(synchronous)&amp;#x27;&lt;/strong&gt;와 &lt;strong&gt;&amp;#x27;비동기(asynchronous)&amp;#x27;&lt;/strong&gt;라는 용어를 접하게 됩니다. 동기와 비동기는 코드 실행 순서와 시간에 관련된 개념으로, 시스템의 효율성과 사용자 경험에 영향을 미칩니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;자바스크립트는 실행 컨텍스트 스택에 들어있는 실행 컨텍스트를 실행하여 순차적으로 수행합니다. 실행 컨텍스트에 함수 실행 컨텍스트가 푸시되며 스택의 상단에 위치한 컨텍스트 부터 순서대로 실행됩니다.&lt;/p&gt;&lt;p&gt;자바스크립트 엔진은 단 하나의 실행 컨텍스트 스택을 가지기 때문에, 스택의 최상단에 있는 실행 컨텍스트를 제외하고 모든 실행 컨텍스트는 대기 중인 태스크입니다. 이는 자바스크립트 엔진이 &lt;strong&gt;싱글 스레드&lt;/strong&gt; 방식으로 동작함을 의미합니다.&lt;/p&gt;&lt;p&gt;싱글 스레드 방식은 하나의 태스크만 실행 가능하기 때문에 동작 시간이 긴 태스크 실행 시, &lt;strong&gt;블로킹(작업 중단)&lt;/strong&gt;이 발생합니다.&lt;/p&gt;&lt;h3&gt;1. 동기(Synchronous)&lt;/h3&gt;&lt;p&gt;예를 들어, 일정 시간이 흐른 뒤 함수를 호출하는 코드를 실행하는 경우, 해당 코드 뒤에 위치한 작업들은 일정 시간동안 호출되지 못하고 작업 중단이 발생합니다.&lt;/p&gt;&lt;p&gt;이처럼, 현재 실행 중인 태스크 종료까지 다른 태스크들이 대기한 뒤 순서에 따라 실행되는 것을 &lt;strong&gt;동기 처리&lt;/strong&gt;라고 합니다.&lt;/p&gt;&lt;p&gt;동기 처리 방식은 태스크 순서 대로 처리되어 실행 순서가 보장된다는 장점이 존재하지만, 앞선 태스크 종료까지 블로킹된다는 단점이 존재합니다.&lt;/p&gt;&lt;h3&gt;2. 비동기(Asynchronous)&lt;/h3&gt;&lt;p&gt;반대로, &lt;strong&gt;비동기 처리&lt;/strong&gt; 방식은 실행 중인 태스크가 종료되지 않았더라도 후순위의 태스크를 실행하는 방식입니다. 이러한 방식을 &lt;strong&gt;&amp;#x27;논블로킹(non-blocking)’&lt;/strong&gt;이라고도 부릅니다.&lt;/p&gt;&lt;p&gt;현재 실행 중인 태스크가 종료되지 않더라도 다음 태스크를 실행한다는 장점이 존재하지만, 실행 순서가 보장되지 않는다는 단점도 존재합니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;동기 처리와 비동기 처리는 실행 순서와 관련되어 중요한 개념으로 이를 활용한다면 효율적인 시스템 성능을 구현할 수 있습니다. 하지만, 잘못된 방법으로 사용한다면 블로킹 현상이나, 예측하지 못한 결과를 초래하기 때문에 상황에 알맞은 방식을 사용해야 합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://lcy042000.github.io/javascript-how-asynchronous&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;브라우저에서 비동기 처리가 어떻게 동작되는지 궁금하다면…?&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 42_비동기 프로그래밍(p.809 - 812)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]Debounce & Throttle]]></title><description><![CDATA[scroll, resize, input…]]></description><link>https://lcy042000.github.io/javascript-debounce-and-throttle</link><guid isPermaLink="false">https://lcy042000.github.io/javascript-debounce-and-throttle</guid><category><![CDATA[WHAT]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Debounce]]></category><category><![CDATA[Throttle]]></category><pubDate>Tue, 20 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;scroll, resize, input과 같은 이벤트들은 짧은 시간에 연속적으로 발생할 수 있는 이벤트입니다. 이러한 이벤트들에 바인딩 된 이벤트 핸들러가 많이 호출되면 성능 저하가 발생할 수 있습니다. 디바운스와 스로틀은 이러한 문제를 방지하기 위한 기법입니다. 디바운스와 스로틀 구현에는 타이머 함수를 활용해 구현됩니다.&lt;/p&gt;&lt;h3&gt;디바운스&lt;/h3&gt;&lt;p&gt;짧은 시간 동안 같은 이벤트가 여러 번 발생하는 경우 이벤트 핸들러를 호출하지 않다가 설정된 시간이 경과된 후 이벤트 핸들러가 한 번만 호출되도록 하는 것입니다.&lt;/p&gt;&lt;p&gt;debounce 함수가 반환하는 함수는 debounce 함수에 두 번째 인수로 전달한 시간보다 짧은 간격으로 이벤트 발생 시 이전 타이머를 취소하고 새로운 타이머를 재설정합니다. 따라서 인수로 전달한 시간보다 짧은 간격으로 이벤트 연속 발생 시 debounce 함수의 첫 번째 인수로 전달된 콜백 함수는 호출되지 않다가 delay 동안 이벤트가 발생하지 않으면 한 번만 호출됩니다.&lt;/p&gt;&lt;h3&gt;스로틀&lt;/h3&gt;&lt;p&gt;짧은 시간 간격으로 이벤트 연속 발생 시 일정 시간 간격으로 이벤트 핸들러가 최대 한 번만 호출되도록 합니다.&lt;/p&gt;&lt;p&gt;스로틀 함수는 짧은 시간 간격으로 연속해서 발생하는 이벤트의 이벤트 핸들러 호출을 방지하기 위해 이벤트를 그룹화하여 일정 시간 단위로 이벤트 핸들러가 호출되도록 호출 주기를 만듭니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 41_타이머(p.803 - 808)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[HOW]웹 프로그램에서 이벤트 관리]]></title><description><![CDATA[…]]></description><link>https://lcy042000.github.io/javascript-event-manage</link><guid isPermaLink="false">https://lcy042000.github.io/javascript-event-manage</guid><category><![CDATA[HOW]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Event]]></category><pubDate>Tue, 06 Feb 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;브라우저는 특정 사건 발생 시 이벤트를 발생시킵니다. 이때 이벤트에 반응하여 특정 작업을 수행하고 싶다면 해당 타입의 이벤트가 발생했을 때 호출될 함수를 브라우저에 알려 호출을 위임합니다. 이벤트가 발생했을 때 호출될 함수를 &lt;strong&gt;이벤트 핸들러&lt;/strong&gt;라 하며, 이벤트가 발생했을 때 브라우저에 이벤트 핸들러의 호출을 위임하는 것을 &lt;strong&gt;이벤트 핸들러 등록&lt;/strong&gt;이라 합니다.&lt;/p&gt;&lt;p&gt;이처럼 이벤트 중심으로 프로그램의 흐름을 관리하는 프로그래밍 방식을 &lt;strong&gt;이벤트 드리븐 프로그래밍&lt;/strong&gt;이라 합니다.&lt;/p&gt;&lt;h2&gt;1. 이벤트 핸들러 등록&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;이벤트 핸들러 어트리뷰트 방식&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;HTML 요소의 어트리뷰트 중에 이벤트에 대응하는 이벤트 핸들러 어트리뷰트가 존재합니다. 이벤트 핸들러 어트리뷰트의 이름은 on 접두사와 이벤트 종류를 나타내는 이벤트 타입으로 이루어져 있으며 함수 호출문 등의 문을 할당하면 이벤트 핸들러가 등록됩니다. 함수 호출문 형식 같은 형태로 할당하는 이유는 이벤트 핸들러에 인수를 전달하기 위해서입니다. 이벤트 핸들러 어트리뷰트 값은 사실 암묵적으로 생성될 이벤트 핸들러의 함수 몸체를 의미합니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;이벤트 핸들러 프로퍼티 방식&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;window 객체와 Document, HTMLElement 타입의 DOM 노드 객체는 이벤트에 대응하는 이벤트 핸들러 프로퍼티를 가지고 있습니다. 이벤트 핸들러 프로퍼티의 키는 이벤트 핸들러 어트리뷰트와 마찬가지로 on 접두사와 이벤트 종류를 나타내는 이벤트 타입으로 구성되어 있습니다. 이벤트 핸들러 등록을 위해 이벤트를 발생시킬 객체인 이벤트 타깃과 이벤트의 종류를 나타내는 이벤트 타입, 이벤트 핸들러를 지정할 필요가 있습니다. 이벤트 핸들러는 이벤트 타깃 또는 전파된 이벤트를 캐치할 DOM 노드 객체에 바인딩합니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;addEventListener 메서드 방식&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;EventTarget.addEventListener 메서드를 통해 이벤트 핸들러 등록이 가능합니다. 첫 번째 매개변수로 이벤트 타입을 전달하며, 두 번째 매개변수에는 이벤트 핸들러를 전달합니다. 마지막 매개변수에는 이벤트를 캐치할 이벤트 전파 단계(캡처링 또는 버블링)를 전달하며 false를 전달하면 버블링 단계에서 이벤트 캐치하며, true를 전달하면 캡처링 단계에서 이벤트 캐치합니다.&lt;/p&gt;&lt;p&gt;동일한 HTML 요소에서 발생한 동일한 이벤트에 대해 이벤트 핸들러 프로퍼티 방식은 하나 이상의 이벤트 핸들러를 등록할 수 없지만 addEventListener 메서드는 하나 이상의 이벤트 핸들러를 등록할 수 있습니다. 이벤트 핸들러는 등록된 순서대로 동작합니다.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;2. 이벤트 핸들러 제거&lt;/h2&gt;&lt;p&gt;EventTarget.removeEventListener 메서드를 통해 이벤트 핸들러 제거가 가능합니다. addEventListener와 동일한 매개 변수를 가지며 동일한 인수를 전달하여 이벤트 핸들러를 제거합니다.&lt;/p&gt;&lt;p&gt;이벤트 핸들러 프로퍼티 방식으로 등록한 이벤트 핸들러는 EventTarget.removeEventListener 메서드로 제거할 수 없으며 이 경우에는 null을 할당하여 제거할 수 있습니다.&lt;/p&gt;&lt;h2&gt;3. 이벤트 객체&lt;/h2&gt;&lt;p&gt;웹 페이지의 이벤트 발생 시 동적으로 이벤트 객체가 생성됩니다. 이벤트 객체는 이벤트에 관한 여러 정보를 포함하고 있으며, 이벤트 핸들러의 첫 번째 인수로 전달됩니다.&lt;/p&gt;&lt;h2&gt;4. 이벤트 전파&lt;/h2&gt;&lt;p&gt;이벤트 전파는 DOM 트리 상에 존재하는 요소 노드에서 발생한 이벤트가 DOM 트리를 통해 전달되는 것을 의미합니다.&lt;/p&gt;&lt;p&gt;예를 들어 클릭 이벤트가 발생한 경우 생성된 이벤트 객체는 이벤트를 발생시킨 DOM 요소인 이벤트 타깃을 중심으로 DOM 트리를 통해 전파됩니다. 이벤트 전파 단계는 방향에 따라 3가지로 구분됩니다.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;캡처링 단계: 이벤트가 상위 요소에서 하위 요소 방향으로 전파&lt;/li&gt;&lt;li&gt;타깃 단계: 이벤트가 이벤트 타깃에 도달&lt;/li&gt;&lt;li&gt;버블링 단계: 이벤트가 하위 요소에서 상위 요소 방향으로 전파&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;클릭 이벤트가 발생하면 클릭 이벤트 객체가 생성되고 클릭 된 요소가 이벤트 타깃이 됩니다. 이벤트 객체는 이후 window에서 시작하여 이벤트 타깃 방향으로 전파되며, 이를 캡처링 단계라고 합니다. 이벤트 객체는 이벤트 타깃에 도달하며, 이는 타깃 단계입니다. 타깃에 도달한 이벤트 객체는 다시 window 방향으로 전파되며, 이를 버블링 단계라고 합니다.&lt;/p&gt;&lt;p&gt;이벤트 타깃은 DOM 트리를 통해 전파되는 경로에 위치하는 모든 DOM 요소에서 캐치할 수 있습니다.&lt;/p&gt;&lt;h2&gt;5. 이벤트 위임&lt;/h2&gt;&lt;p&gt;여러 개의 DOM 요소에 동일한 이벤트 핸들러를 등록해야 하는 경우가 있습니다. 요소 개수가 많아지는 경우 성능 저하의 원인이 되며, 유지보수 측면에서도 부적절합니다.&lt;/p&gt;&lt;p&gt;이벤트 위임은 여러 개의 DOM 요소에 이벤트 핸들러를 등록하는 대신 요소들의 상위 요소에 이벤트 핸들러를 등록하는 방법입니다.&lt;/p&gt;&lt;p&gt;이벤트 위임을 활용하는 경우 주의해야 할 점은 이벤트를 발생한 요소가 생각과 다른 DOM 요소일 수도 있다는 점입니다. 따라서, 이벤트 핸들러가 실행되기 위해 이벤트 타깃을 검사해야 할 필요가 있습니다.&lt;/p&gt;&lt;h2&gt;6. DOM 요소의 기본 동작 조작&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;DOM 요소의 기본 동작 중단&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;DOM 요소는 기본 동작을 가지고 있습니다. 이벤트 객체의 preventDefault 메서드는 DOM 요소의 기본 동작을 중단시키는 역할을 합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;이벤트 전파 방지&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이벤트 객체의 stopPropagation 메서드는 이벤트 전파를 중지시키는 역할을 수행합니다. 하위 요소에서 발생한 이벤트를 상위 요소로 전파되는 것을 막아 하위 요소의 이벤트를 개별적으로 처리하도록 합니다.&lt;/p&gt;&lt;h2&gt;7. 이벤트 핸들러에 인수 전달&lt;/h2&gt;&lt;p&gt;이벤트 핸들러 어트리뷰트 방식은 함수 호출문을 사용 가능하기 때문에 인수 전달이 가능하지만, 이벤트 핸들러 프로퍼티 방식과 addEventListener 메서드 방식은 브라우저가 호출하기 때문에 함수 자체를 등록하여 인수 전달을 부가합니다.&lt;/p&gt;&lt;p&gt;하지만, 이벤트 핸들러 내부에서 함수를 호출하는 방법을 통해 인수 전달을 수행할 수 있습니다. 또한, 이벤트 핸들러를 반환하는 함수를 호출하면서 인수를 전달하는 방법도 존재합니다.&lt;/p&gt;&lt;h2&gt;8. 커스텀 이벤트&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;커스텀 이벤트 생성&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이벤트 생성자 함수를 통해 커스텀 이벤트를 생성할 수 있습니다. 이벤트 생성자 함수를 호출하여 명시적으로 생성한 이벤트 객체는 임의의 이벤트 타입을 지정할 수 있습니다.&lt;/p&gt;&lt;p&gt;이벤트 생성자 함수는 첫 번째 인수로 이벤트 타입을 전달받습니다. 또한 bubbles와 cancelable 프로퍼티를 true로 설정하려면 두 번째 인수로 bubbles와 cancelable 프로퍼티를 갖는 객체를 전달받습니다. 더불어 이벤트 타입에 따라 가지는 이벤트 고유의 프로퍼티 값 지정을 위해 두 번째 인수로 프로퍼티를 전달할 수 있습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;커스텀 이벤트 디스패치&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;dispatchEvent 메서드를 이용해 커스텀 이벤트를 발생시키는 디스패치를 할 수 있습니다. dispatchEvent 메서드에 이벤트 객체를 인수로 전달하면서 호출하면 인수로 전달한 이벤트 타입의 이벤트가 발생합니다.&lt;/p&gt;&lt;p&gt;dispatchEvent 메서드는 이벤트 핸들러를 동기 처리 방식으로 호출합니다. 따라서, 이벤트를 디스패치 하기 전에 커스텀 이벤트를 처리할 이벤트 핸들러를 등록해야 합니다. 커스텀 이벤트는 이벤트 핸들러 어트리뷰트와 프로퍼티가 요소 노드에 존재하지 않기 때문에 addEventListener 메서드 방식으로 이벤트 핸들러를 등록해야 한다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 40_이벤트(p.754 - 799)&lt;/p&gt;&lt;p&gt;이미지 출처 - &lt;a href=&quot;https://pixabay.com/ko/photos/%EA%B2%80%EC%9D%80-%EC%83%89-%ED%84%B0%EC%A7%80%EB%8B%A4-%EC%B6%95%ED%95%98%ED%95%98%EB%8B%A4-17121/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://pixabay.com/ko/photos/검은-색-터지다-축하하다-17121/&lt;/a&gt;&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[HOW]DOM의 노드 조작 방법]]></title><description><![CDATA[웹 화면을 구성하는 HTML의 요소를 동적으로 변경하기 위해서는 어떻게 해야 할까요? 이를 위해서는 DOM의 노드 객체에 접근하여 우리가 원하는 내용과 구조로 조작해야 합니다. 지금부터 DOM…]]></description><link>https://lcy042000.github.io/dom-operate</link><guid isPermaLink="false">https://lcy042000.github.io/dom-operate</guid><category><![CDATA[HOW]]></category><category><![CDATA[DOM]]></category><pubDate>Tue, 23 Jan 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;웹 화면을 구성하는 HTML의 요소를 동적으로 변경하기 위해서는 어떻게 해야 할까요?&lt;/p&gt;&lt;p&gt;이를 위해서는 DOM의 노드 객체에 접근하여 우리가 원하는 내용과 구조로 조작해야 합니다. 지금부터 DOM의 노드 객체에 접근하여 조작하는 방법에 대해 알아보도록 하겠습니다!&lt;/p&gt;&lt;h2&gt;1. 노드 접근&lt;/h2&gt;&lt;p&gt;HTML 요소를 변경하거나 삭제하기 위해서는 우선 요소에 접근해야 합니다. 따라서, DOM은 노드에 접근하기 위한 다양한 방법을 제공합니다.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Document.getElementById()&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Document.getElementById()는 노드의 id 어트리뷰트 값으로 요소 노드를 찾아 반환하는 메서드입니다. 해당 id 값을 갖는 하나의 노드만 반환하며 id 값은 HTML 내에서 하나만 존재해야 합니다. 동일한 id를 갖는 여러 개의 노드가 존재하더라도 에러는 발생하지 않지만 이 메서드는 첫 번째 노드만 반환합니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Document.getElementsByTagName() / Element.getElementsByTagName()&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;인수로 전달된 태그 요소 노드를 반환하는 메서드입니다. 해당 HTML 내에 여러 개의 노드 객체가 존재할 경우 모든 탐색 결과를 반환하며 HTMLCollection 객체 형태로 반환됩니다. HTMLCollection 객체는 유사 배열 객체이면서 이터러블입니다.&lt;/p&gt;&lt;p&gt;Document에 정의된 메서드는 DOM 전체에서 탐색하여 결과를 반환하며 Element에 정의된 메서드는 특정 요소 노드의 자손 노드 객체를 탐색한 결과를 반환합니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Document.getElementsByClassName() / Element.getElementsByClassName()&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;인수로 전달된 class 어트리뷰트 값을 가진 노드 객체들을 HTMLCollection 객체 형태로 반환합니다. class 값은 id 값과 달리 중복된 값을 사용할 수 있기 때문에 여러 개의 노드 객체가 존재할 수 있습니다.&lt;/p&gt;&lt;p&gt;TagName을 통한 탐색과 같이 Document의 메서드는 DOM 전체, Element의 메서드 경우 특정 노드의 자손 노드에 대한 탐색 결과를 반환합니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Document.querySelector() / Element.querySelector()&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;CSS 선택자를 이용하여 노드에 접근하는 메서드로 인수로 전달된 CSS 선택자에 해당하는 노드 객체를 탐색하여 반환합니다.&lt;/p&gt;&lt;p&gt;탐색한 결과가 여러 개인 경우 첫 번째 요소를 반환하며 없는 경우 null을 반환합니다. 또한, CSS 선택자가 문법에 맞지 않는 경우 DOMException 에러가 발생합니다.&lt;/p&gt;&lt;p&gt;원하는 CSS 선택자의 여러 개의 탐색 결과를 반환받기 원하는 경우 querySelectorAll()을 통해 접근할 수 있습니다. 이 메서드는 여러 개의 노드 객체를 갖는 DOM 컬렉션 객체인 NodeList 객체를 반환하며 이 객체는 유사 배열 객체이면서 이터러블입니다.&lt;/p&gt;&lt;p&gt;CSS 선택자를 이용한 접근 메서드는 다른 접근 메서드보다 느리다는 점이 있지만, 조금 더 구체적이고 일관된 방식으로 접근할 수 있다는 장점이 존재합니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Element.matches()&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;CSS 선택자를 통해 해당 노드를 취득할 수 있는지 확인하는 메서드입니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTMLCollection / NodeList&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;HTMLCollection과 NodeList는 DOM 컬렉션 객체로 여러 개의 결괏 값을 전달하기 위한 객체입니다. 두 객체는 유사 배열 객체이며 이터러블입니다. 따라서, 간편한 순회와 스프레드 문법 사용이 가능합니다. 또한, 노드 객체의 상태 변화를 실시간으로 반영하는 살아 있는 객체로 HTMLCollection은 항상 실시간 반영되며 NodeList는 경우에 따라 반영됩니다.&lt;/p&gt;&lt;p&gt;실시간으로 반영되는 살아 있는 객체를 사용하는 경우 요소를 순회하며 상태를 변경하면 객체의 상태가 변화되어 예상대로 동작하지 않을 수 있기 때문에 주의하여야 합니다. 따라서, 대부분의 경우 살아 있지 않은 객체인 NodeList 객체를 사용하는 것을 권장하며, NodeList 객체도 childNodes 프로퍼티가 반환하는 경우 살아 있는 객체로 동작하므로 주의해야 합니다.&lt;/p&gt;&lt;p&gt;가장 안전하게 사용하는 방법은 배열로 변환하여 사용하는 방법입니다.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;2. 노드 탐색&lt;/h2&gt;&lt;p&gt;DOM API를 통해 반환받은 노드 객체를 탐색하는 방법에 대해 알아보겠습니다. 반환받은 DOM 트리의 자식, 형제, 부모 노드에 접근해야 하는 경우가 있습니다.&lt;/p&gt;&lt;p&gt;Node가 제공하는 parentNode, previousSibling, firstChild, childNodes 프로퍼티와 Element가 제공하는 previousElementSibling, nextElementSibling을 통해 접근할 수 있습니다. 노드 탐색 프로퍼티는 모두 접근자 프로퍼티로 읽기 전용 프로퍼티입니다.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;자식 노드 탐색&lt;/strong&gt;&lt;ol&gt;&lt;li&gt;Node.childNodes: 자식 노드를 탐색하여 NodeList 객체에 담아 반환. 텍스트 노드가 포함되어 있을 수 있음&lt;/li&gt;&lt;li&gt;Element.children: 자식 노드 중 요소 노드만 탐색하여 HTMLCollection 객체에 담아 반환&lt;/li&gt;&lt;li&gt;Node.firstChild: 첫 번째 자식 노드만 반환하며 텍스트 노드일 수 있음&lt;/li&gt;&lt;li&gt;Node.lastChild: 마지막 자식 노드만 반환하며 텍스트 노드일 수 있음&lt;/li&gt;&lt;li&gt;Element.firstElementChild: 첫 번째 자식 요소 노드 반환&lt;/li&gt;&lt;li&gt;Element.lastElementChild: 마지막 자식 요소 노드 반환&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;자식 노드 존재 확인&lt;/strong&gt;&lt;ol&gt;&lt;li&gt;Node.hasChildNodes: 자식 노드가 존재하면 true, 존재하지 않으면 false, 텍스트 노드를 포함&lt;/li&gt;&lt;li&gt;Element.childElementCount / Element.children.length: 텍스트 노드 제외한 자식 노드 존재 확인&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;부모 노드 탐색&lt;/strong&gt;&lt;ol&gt;&lt;li&gt;Node.parentNode: 부모 노드 탐색&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;형제 노드 탐색&lt;/strong&gt;&lt;ol&gt;&lt;li&gt;Node.previousSibling: 부모 노드가 같은 형제 노드 중 자신의 이전 노드를 반환. 텍스트 노드 포함&lt;/li&gt;&lt;li&gt;Node.nextSibling: 부모 노드가 같은 형제 노드 중 자신의 이후 노드를 반환. 텍스트 노드 포함&lt;/li&gt;&lt;li&gt;Element.previousElementSibling: 부모 노드가 같은 형제 노드 중 자신의 이전 노드 반환. 요소 노드만 반환&lt;/li&gt;&lt;li&gt;Element.nextElementSibling: 부모 노드가 같은 형제 노드 중 자신의 이후 노드 반환. 요소 노드만 반환&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;3. 노드 정보 취득&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Node.nodeType&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;노드 객체의 타입을 나타내는 상수를 반환합니다. Node.ELEMENT_NODE는 요소 노드 타입 1을 반환하며 Node.TEXT_NODE는 텍스트 노드 타입 3을 반환, Node.DOCUMENT_NODE는 문서 노드 타입 9를 반환합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Node.nodeName&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;노드의 이름을 문자열로 반환합니다. 요소 노드는 대문자 태그 이름을 반환하며, 텍스트 노드는 ‘#text’, 문서 노드는 ‘#document’를 반환합니다.&lt;/p&gt;&lt;h2&gt;4. 요소 노드의 텍스트 조작&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Node.nodeValue&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;접근과 조작이 모두 가능한 프로퍼티로 노드 객체의 값을 반환합니다. 노드 객체의 값은 텍스트 노드의 텍스트입니다. 오직 텍스트만 반환하며 nodeValue의 프로퍼티에 값을 할당하면 텍스트 값이 변경됩니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Node.textContent&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;접근과 조작이 모두 가능한 프로퍼티로 요소 노드의 텍스트 노드와 모든 자손 노드의 텍스트 노드를 조작할 수 있습니다. 요소 노드의 childNodes 프로퍼티가 반환한 모드 노드들의 텍스트 노드의 값이며, 값이 모두 텍스트로 취급되어 HTML 마크업이 포함되어 있더라도 인식되지 않습니다.&lt;/p&gt;&lt;hr/&gt;&lt;h2&gt;5. DOM 조작&lt;/h2&gt;&lt;p&gt;DOM 조작은 새로운 노드 추가나 기존 노드를 삭제 또는 교체하는 것을 의미합니다. DOM 조작 시 리플로우와 리페인트가 발생하여 성능에 영향을 미칩니다. 따라서 DOM 조작은 주의를 요구합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;innerHTML&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Element.innerHTML은 요소 노드의 HTML 마크업을 취득하거나 변경합니다. innerHTML 참조 시 요소 노드의 시작 태그와 종료 태그 사이에 존재하는 HTML 마크업을 문자열로 반환합니다. 또한, innerHTML에 문자열을 할당하면 해당 요소 노드의 자식 노드들을 제거하고 할당한 문자열의 HTML 마크업이 파싱되어 요소 노드의 자식 노드로 DOM에 반영됩니다.&lt;/p&gt;&lt;p&gt;innerHTML에 입력받은 데이터를 곧바로 할당하는 것은 크로스 사이트 스크립팅 공격(HTML 마크업 내에 자바스크립트 악성 코드를 포함시켜 파싱 과정에서 실행하는 공격)에 취약합니다.&lt;/p&gt;&lt;p&gt;또한 innerHTML은 자식 노드를 모두 삭제시키고 할당받은 문자열을 파싱하여 변경한다는 단점이 존재합니다. 이는 효율적이지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;insertAdjacentHTML&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Element.insertAdjactHTML(position, DOMString)은 기존 요소 제거 없이 위치 지정으로 새로운 요소를 삽입합니다. DOMString 인수로 전달한 문자열을 파싱하여 position 인수로 전달된 위치에 삽입하여 DOM에 반영합니다.&lt;/p&gt;&lt;p&gt;기존 요소의 영향을 주지 않고 삽입하는 요소만 파싱하여 추가하므로 효율적이고 빠르지만, 크로스 사이트 스크립팅 공격에 취약합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;노드 생성과 추가&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Document.createElement(tagName)은 요소 노드를 생성하여 반환합니다. 매개변수 tagName에는 태그 이름을 나타내는 문자열을 인수로 전달합니다. 생성된 요소 노드는 DOM에 추가하는 별도의 추가 처리가 필요합니다.&lt;/p&gt;&lt;p&gt;Document.createTextNode(text)는 텍스트 노드를 생성하여 반환합니다. 인수로 전달된 text에 텍스트 노드의 값인 문자열을 전달합니다. 이 메서드 또한, 노드 생성만 담당할 뿐 요소 노드에 추가하지 않습니다.&lt;/p&gt;&lt;p&gt;Node.appendChild(childNode)는 childNode에 전달된 노드를 호출한 노드의 마지막 자식 노드로 추가합니다.&lt;/p&gt;&lt;p&gt;DocumentFragment 노드는 노드 객체의 일종으로 자식 노드들의 부모 노드로서 별도의 서브 DOM을 구성하여 기존 DOM에 추가하기 위해 사용합니다. 기존 DOM에는 영향을 미치지 않아 자식 노드를 추가한 다음, DOM에 추가하면 자신은 제거되고 자식 노드들만 DOM에 추가합니다. Document.createDocumentFragment는 비어 있는 DocumentFragment 노드를 생성하여 반환합니다. 실제 DOM의 변경은 한 번만 이루어져 성능에 효율적입니다.&lt;/p&gt;&lt;p&gt;Node.insertBefore(newNode, childNode)는 첫 번째 인수로 전달받은 노드를 두 번째 인수로 전달받은 노드 앞에 삽입합니다. 두 번째 인수는 반드시 호출한 노드의 자식 노드이어야 하며 아닌 경우, DOMException 에러가 발생합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;노드 복사&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Node.cloneNode([deep: true | false])는 노드의 사본을 생성하여 반환하며 인수로 true를 전달하면 깊은 복사하여 모든 자손 노드를 포함하며 false로 전달하면 얕은 복사하여 자손 노드를 복사하지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;노드 교체&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Node.replaceChild(newChild, oldChild)는 자신을 호출한 노드의 자식 노드를 다른 노드로 교체합니다. newChild 인수로 교체할 새로운 노드를 전달하고, oldChild 인수로 교체될 노드를 전달하며 호출한 노드의 자식 노드이어야 합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;노드 삭제&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Node.remove(child)는 인수로 전달된 노드를 DOM에서 삭제합니다. 인수는 호출한 노드의 자식 노드이어야 합니다.&lt;/p&gt;&lt;hr/&gt;&lt;h2&gt;6. 어트리뷰트&lt;/h2&gt;&lt;p&gt;HTML 요소는 동작을 제어하기 위한 추가적인 정보를 제공하는 어트리뷰트(속성)를 가질 수 있습니다. HTML 파싱 시점에 어트리뷰트 노드로 변환되어 요소 노드와 연결됩니다. 어트리뷰트당 하나의 어트리뷰트 노드가 생성됩니다. 모든 어트리뷰트 노드는 요소 노드의 Element.attributes 프로퍼티로 취득할 수 있으며 읽기 전용 프로퍼티로 NamedNodeMap 객체를 반환합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;HTML 어트리뷰트 조작&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Element.getAttribute/setAttribute 메서드를 통해 요소 노드에서 직접 어트리뷰트 값 취득과 변경이 가능합니다. 특정 어트리뷰트 존재 확인은 Element.hasAttribute(attributeName) 메서드를 통해 가능하며, 어트리뷰트 삭제는 Element.removeAttribute(attributeName) 메서드를 사용합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;HTML 어트리뷰트 vs DOM 프로퍼티&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;DOM 프로퍼티는 HTML 어트리뷰트의 초깃값을 가지고 있습니다. DOM 프로퍼니는 setter와 getter를 가지고 있는 접근자 프로퍼티로 참조와 변경이 가능합니다. HTML 어트리뷰트의 역할은 HTML 요소의 초기 상태를 지정하는 것으로 HTML 어트리뷰트 값은 HTML 요소의 초기 상태를 의미하며 이는 변하지 않습니다. DOM 프로퍼티는 요소 노드의 초기 상태와 최신 상태 중 최신 상태를 관리하는 역할을 합니다. 대부분의 HTML 어트리뷰트는 HTML 어트리뷰트 이름과 동일한 DOM 프로퍼티와 1:1로 대응합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;data 어트리뷰트와 dataset 프로퍼티&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;data 어트리뷰트와 dataset 프로퍼티를 통해 사용자 정의 어트리뷰트와 자바스크립트 사이의 데이터를 교환할 수 있습니다.&lt;/p&gt;&lt;p&gt;data 어트리뷰트 값은 HTMLElement.dataset 프로퍼티로 취득할 수 있으며 dataset 프로퍼티는 HTML 요소의 모든 data 어트리뷰트의 정보를 제공하는DOMStringMap 객체를 반환합니다.&lt;/p&gt;&lt;h2&gt;7. 스타일&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;인라인 스타일 조작&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;HTMLElement.style 프로퍼티는 요소 노드의 인라인 스타일을 참조와 변경이 가능한 접근자 프로퍼티입니다. CSSStyleDeclaration 타입의 객체를 반환하며, CSSStyleDeclaration 객체는 CSS 프로퍼티에 대응하는 프로퍼티를 가지고 있어 값 할당 시 해당 CSS 프로퍼티가 인라인 스타일로 HTML 요소에 추가되거나 변경됩니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;클래스 조작&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Element.className 프로퍼티는 HTML 요소의 class 어트리뷰트 값을 취득하거나 변경하는 접근자 프로퍼티입니다. 참조 시에는 class 어트리뷰트 값을 문자열로 반환하고, 할당하는 경우 class 어트리뷰트 값을 할당한 문자열로 변경합니다. className 프로퍼티는 문자열을 반환하기 때문에 공백으로 구분된 여러 개의 클래스 반환 시 다루기 불편합니다.&lt;/p&gt;&lt;p&gt;Element.classList 프로퍼티는 class 어트리뷰트의 정보를 담은 DOMTokenList 객체를 반환합니다. DOMTokenList 객체는 class 어트리뷰트 정보를 나타내는 객체로 class 어트리뷰트 값을 추가, 삭제, 참조, 포함 여부, 변경, 토글 메서드를 제공합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;요소에 적용되어 있는 CSS 스타일 참조&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;style 프로퍼티는 인라인 스타일만 반환하기 때문에 HTML 요소에 적용되어 있는 CSS 스타일 참조가 필요한 경우 getComputedStyle 메서드를 사용합니다. 요소 노드에 작용되어 있는 평가된 스타일(링크 스타일, 임베딩 스타일, 인라인 스타일, 자바스크립트 적용 스타일, 상속 스타일, 기본 스타일)을 CSSStuleDeclaration 객체에 담아 반환합니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 39_DOM(p.685 - 753)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]What is DOM?]]></title><description><![CDATA[브라우저는 화면을 그리기 위해서  DOM(Document Object Model) 이라는 트리 자료구조를 생성합니다. DOM은 HTML, XML 문서의 계층적 구조와 정보를 표현하며 이를 프로그래밍 언어가 제어할 수 있는 DOM API…]]></description><link>https://lcy042000.github.io/dom</link><guid isPermaLink="false">https://lcy042000.github.io/dom</guid><category><![CDATA[WHAT]]></category><category><![CDATA[DOM]]></category><pubDate>Thu, 28 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;브라우저는 화면을 그리기 위해서 &lt;strong&gt;DOM(Document Object Model)&lt;/strong&gt;이라는 트리 자료구조를 생성합니다. DOM은 HTML, XML 문서의 계층적 구조와 정보를 표현하며 이를 프로그래밍 언어가 제어할 수 있는 DOM API를 제공합니다. &lt;/p&gt;&lt;p&gt;DOM은 node와 object로 문서를 표현하며, 이들은 웹 페이지를 프로그래밍 언어에서 사용될 수 있게 연결시켜주는 역할을 담당합니다. 또한, DOM은 웹 페이지의 객체 지향 표현입니다.&lt;/p&gt;&lt;p&gt;지금부터 DOM에 대해 알아보도록 하겠습니다.&lt;/p&gt;&lt;h2&gt;1. 노드&lt;/h2&gt;&lt;p&gt;HTML 요소는 HTML 문서를 구성하는 개별적인 요소를 의미하며 이는 렌더링 엔진에 의해 파싱 되어 DOM을 구성하는 요소 노드 객체로 변환됩니다. HTML 문서는 HTML 요소들로 구성되며 HTML 요소는 중첩 관계를 가질 수 있습니다.&lt;/p&gt;&lt;p&gt;DOM은 노드 객체의 계층적인 구조로 구성되며, 노드 객체는 12개의 종류로 상속 구조를 갖습니다. 이 중 대표적인 노드 객체는 4가지로 문서 노드, 요소 노드, 어트리뷰트 노드, 텍스트 노드가 존재합니다.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;문서 노드: DOM 트리의 최상단에 위치하며 루트 노드로서 document 객체를 가리킵니다. document 객체는 HTML 문서를 가리킵니다.&lt;/li&gt;&lt;li&gt;요소 노드: HTML 요소를 가리키는 객체로 HTML 요소 간의 중첩에 의해 부자 관계를 가지며, 정보를 구조화합니다.&lt;/li&gt;&lt;li&gt;어트리뷰트 노드: HTML 요소의 어트리뷰트를 가리키며 어트리뷰트가 지정된 요소 노드와 연결되어 있습니다. 어트리뷰트 접근이 필요한 경우 요소 노드에 접근하여야 합니다.&lt;/li&gt;&lt;li&gt;텍스트 노드: HTML 요소의 텍스트를 가리키는 객체로 문서의 정보를 표현합니다. 요소 노드의 자식 노드이며, 텍스트 노드는 자식 노드를 가질 수 없습니다.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;노드 객체는 ECMAScript 사양에 정의된 표준 빌트인 객체가 아닌 브라우저 환경에 추가적으로 제공되는 호스트 객체이지만, 노드 객체도 자바스크립트의 객체이므로 프로토타입에 의한 상속 구조를 가집니다.&lt;/p&gt;&lt;p&gt;노드 객체는 노드 종류에 상관없이 모든 노드 객체가 공통으로 갖는 기능도 있으며, 노드 종류에 따른 기능도 있습니다. 노드 객체는 공통된 기능일수록 프로토타입 체인의 상위에 위치하며, 개별적인 기능은 프로토타입 체인의 하위에 위치합니다. 따라서, DOM은 HTML 문서의 계층적 구조와 정보를 표현하며 노드 객체의 종류에 따라 필요한 기능을 프로퍼티와 메서드의 집합인 DOM API로 제공합니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 39_DOM(p.677 - 684)&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/API/Document_Object_Model/Introduction&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mdn web docs DOM 소개&lt;/a&gt;&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[HOW]브라우저는 어떻게 화면을 보여줄까?]]></title><description><![CDATA[우리는 chrom, safari, edge…]]></description><link>https://lcy042000.github.io/browser-rendering</link><guid isPermaLink="false">https://lcy042000.github.io/browser-rendering</guid><category><![CDATA[HOW]]></category><category><![CDATA[Browser]]></category><category><![CDATA[Rendering]]></category><pubDate>Wed, 27 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;우리는 chrom, safari, edge와 같은 브라우저를 사용하여 여러 웹 서비스를 이용합니다. 주소창에 우리가 사용하고자 하는 주소를 입력하면 웹 서비스가 화면에 나타납니다. 지금부터 브라우저 창에 웹 서비스 화면이 나오는 과정에 대해 알아보도록 하겠습니다!&lt;/p&gt;&lt;hr/&gt;&lt;aside&gt;💡 브라우저 렌더링  요약 과정 1. 브라우저는 HTML, CSS, 자바스크립트 등과 같은 필요한 리소스를 웹 서버에 요청하여 응답받습니다. 2. 브라우저의 렌더링 엔진은 응답받은 리소스에서 HTML과 CSS를 해석(파싱) 하여 DOM과 CSSOM을 생성한 후 이 둘의 결합으로 렌더 트리를 생성합니다. 3. 브라우저에 있는 자바스크립트 엔진은 자바스크립트 코드를 해석(파싱) 하여 Abstract Syntax Tree(AST)를 생성하고 바이트 코드로 변환한 뒤 실행합니다. 자바스크립트 코드는 DOM과 CSSOM을 DOM API를 이용하여 변경할 수 있으며 변경된 DOM과 CSSOM은 다시 렌더 트리로 결합됩니다. 4. 생성된 렌더 트리를 기반으로 HTML 요소의 레이아웃을 계산하여 화면에 HTML을 출력합니다.&lt;/aside&gt;&lt;h2&gt;1. 요청과 응답&lt;/h2&gt;&lt;p&gt;화면을 구성(렌더링) 하는 데 필요한 자원은 모두 웹 서버에 존재합니다. 따라서 이 자원(리소스)을 웹 서버에 요청하여 응답받습니다.&lt;/p&gt;&lt;p&gt;서버에 요청하기 위해 브라우저는 주소창을 제공하며 주소창에 URL을 입력하면 이는 URL의 호스트 이름이 DNS를 통해 IP 주소로 변환되고, 변환된 IP 주소를 갖는 웹 서버에 리소스를 요청합니다. 이후 웹 서버는 요청에 맞는 리소스를 브라우저(클라이언트)에 응답합니다.&lt;/p&gt;&lt;h2&gt;2. HTTP 1.1과 HTTP 2.0&lt;/h2&gt;&lt;p&gt;HTTP(HyperText Transfer Protocol)는 웹에서 브라우저와 서버가 통신하기 위한 프로토콜(규약)입니다. 1999년 발표된 HTTP 1.1과 2015년 발표된 HTTP 2.0의 차이점을 알아보도록 하겠습니다.&lt;/p&gt;&lt;p&gt;HTTP 1.0은 클라이언트와 서버 사이의 커넥션당 하나의 요청과 응답만 처리합니다. 따라서 응답받은 HTML 내에 있는 리소스 요청들은 개별적으로 전송되고 개별적으로 응답받습니다. 이는 요청할 리소스의 개수에 비례하여 응답 시간이 증가하는 단점이 존재합니다.&lt;/p&gt;&lt;p&gt;반면, HTTP 2.0은 커넥션 당 여러 개의 요청과 응답이 가능합니다. 따라서, HTTP 1.1보다 로딩 속도가 약 50% 개선되었습니다.&lt;/p&gt;&lt;h2&gt;3. HTML 파싱과 DOM 생성&lt;/h2&gt;&lt;p&gt;서버로부터 받아온 HTML은 사람들이 알아볼 수 있는 언어로 작성되어 있기 때문에, 이를 브라우저가 인식할 수 있는 객체로 변환하여 보관해야 합니다. 브라우저 렌더링 엔진은 HTML 문서를 파싱하는 과정을 거쳐 브라우저가 읽을 수 있는 DOM(Document Object Model)을 생성합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;HTML의 DOM 변환 과정&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;서버에서 요청받은 HTML 파일을 메모리에 저장한 후 메모리에 저장된 바이트를 응답&lt;/li&gt;&lt;li&gt;브라우저는 바이트 형태로 응답받아 meta 태그의 charset 어트리뷰트에 선언된 인코딩 방식을 기준으로 문자열 형태로 변환&lt;/li&gt;&lt;li&gt;변환된 HTML 문서를 토큰 단위로 분해&lt;/li&gt;&lt;li&gt;토큰들을 객체로 변환하여 노드 생성&lt;/li&gt;&lt;li&gt;HTML 요소 간의 관계를 반영한 모든 노드들을 트리 자료구조 형태로 구성하며, 이를 DOM이라고 함&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;4. CSS 파싱과 CSSOM 생성&lt;/h2&gt;&lt;p&gt;HTML을 한 줄씩 파싱 하던 렌더링 엔진은 CSS를 로드하는 태그를 만나면 파싱을 멈추고 CSS 파일을 요청합니다. 요청한 CSS 파일을 응답받으면 HTML 파싱 후 DOM 생성 과정과 동일한 방식으로 CSSOM을 생성합니다. 이후 중단되었던 위치부터 HTML을 파싱 하여 DOM 생성을 이어갑니다.&lt;/p&gt;&lt;h2&gt;5. 렌더 트리 생성&lt;/h2&gt;&lt;p&gt;생성된 DOM과 CSSOM을 결합하여 렌더 트리를 생성합니다. 렌더 트리는 렌더링을 위한 트리 구조의 자료구조로 브라우저 화면에 출력할 노드로만 구성됩니다. 렌더 트리는 HTML 요소의 레이아웃(위치, 크기)을 계산하는 데 사용되며 픽셀을 렌더링 하는 페인팅 처리에 입력됩니다.&lt;/p&gt;&lt;p&gt;브라우저의 렌더링 과정은 특정 상황(자바스크립트에 의한 수정, 뷰포트 크기 변경, 레이아웃 변경)에서 반복되어 실행될 수 있습니다. 렌더링 과정이 반복 실행되는 리렌더링 과정은 성능에 악영향을 주는 작업으로 리렌더링이 자주 발생하지 않도록 해야 합니다.&lt;/p&gt;&lt;h2&gt;6. 자바스크립트 파싱과 실행&lt;/h2&gt;&lt;p&gt;DOM은 HTML 문서의 구조와 정보뿐만 아니라 HTML 요소와 스타일 등을 변경할 수 있는 프로그래밍 인터페이스인 DOM API를 제공합니다. DOM API를 사용하여 동적으로 DOM 조작이 가능합니다.&lt;/p&gt;&lt;p&gt;HTML 파싱 과정에서 자바스크립트를 로드하는 태그를 만나면 DOM 생성을 중단하고 웹 서버에 자바스크립트 파일을 요청합니다. 자바스크립트 파일을 응답받으면 자바스크립트 코드 파싱을 위해 자바스크립트 엔진에 제어권을 넘깁니다.&lt;/p&gt;&lt;p&gt;자바스크립트 엔진은 코드를 파싱 하여 CPU가 이해할 수 있는 저수준 언어로 변환한 뒤 실행합니다. 자바스크립트 엔진은 코드를 해석하여 AST(Abstract Syntax Tree)를 생성하여, 이를 기반으로 인터프리터가 실행할 수 있는 중간 코드인 바이트 코드를 생성하여 실행합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;자바스크립트 파싱과 실행 과정&lt;/strong&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;토크나이징: 자바스크립트 소스코드를 어휘 분석하여 코드의 최소 단위인 토큰으로 분해&lt;/li&gt;&lt;li&gt;파싱: 토큰들의 집합을 구문 분석하여 AST 생성&lt;/li&gt;&lt;li&gt;바이트코드의 생성과 실행: 생성된 AST를 인터프리터가 실행할 수 있는 바이트코드로 변환하여 인터프리터에 의해 실행됩니다.&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;7. 리플로우와 리페인트&lt;/h2&gt;&lt;p&gt;리플로우는 레이아웃 재계산하는 것을 의미합니다. 노드를 추가하거나 삭제, 요소의 크기 또는 위치 변경, 윈도우 리사이징 등 레이아웃에 영향을 주는 변경이 발생하는 경우 실행됩니다.&lt;/p&gt;&lt;p&gt;리페인트는 리플로우로 인해 재결합된 렌더 트리를 기반으로 다시 페인트하는 것을 발합니다.&lt;/p&gt;&lt;h2&gt;8. 자바스크립트 파싱에 의한 HTML 파싱 중단&lt;/h2&gt;&lt;p&gt;렌더링 엔진과 자바스크립트 엔진은 병렬적으로 실행되지 않습니다. 따라서 브라우저는 동기적으로 파싱하고 실행되기 때문에 DOM 생성을 중단시키는 자바스크립트 요청을 하는 script 태그의 위치는 중요합니다.&lt;/p&gt;&lt;p&gt;HTML 파싱 중 script 태그를 만난 후 자바스크립트 코드를 파싱 하는 과정에서 DOM API를 사용할 경우 DOM과 CSSOM이 이미 생성되어 있어야 합니다. 만약 생성되지 않았다면 문제가 발생할 수 있습니다.&lt;/p&gt;&lt;p&gt;따라서, 위와 같은 문제를 방지하기 위해 HTML의 body 요소 아래에 script 태그를 위치하는 것이 좋습니다. 이는 자바스크립트 실행 시점을 렌더링 엔진이 DOM 생성을 마무리한 후로 고정하는 것으로 문제 발생이 사라지는 효과를 누릴 수 있습니다. 또한, 자바스크립트 실행 전 DOM 생성이 마무리되어 렌더링 되므로 페이지 로딩 시간이 단축되는 효과를 가져올 수 있습니다.&lt;/p&gt;&lt;h2&gt;9. script 태그의 async/defer 어트리뷰트&lt;/h2&gt;&lt;p&gt;HTML5에는 자바스크립트 파싱에 의한 중단 문제를 해결하기 위해 script 태그에 async, defer 어트리뷰트가 추가되었습니다. async와 defer 어트리뷰트는 src 어트리뷰트를 통해 외부 자바스크립트 파일 로드 시 사용할 수 있습니다. async와 defer 어트리뷰트 사용은 HTML 파싱과 자바스크립트 파일 로드가 비동기적으로 동시에 진행되지만, 자바스크립트 실행 시점에 차이가 존재합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;async 어트리뷰트&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;HTML 파싱과 자바스크립트 로드가 비동기적으로 동시에 진행되지만, 자바스크립트의 파싱과 실행은 자바스크립트 파일 로드 완료 이후 진행되며, HTML 파싱이 중단됩니다. 여러 개의 script 태그에 async 어트리뷰트를 지정하면 script 태그 순서와 상관없이 로드 완료 순서대로 파싱이 실행되어 순서가 보장되지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;defer 어트리뷰트&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;async 어트리뷰트와 마찬가지로 HTML 파싱과 자바스크립트 파일 로드가 비동기적으로 진행되지만, 자바스크립트의 파싱과 실행은 DOM 생성이 완료된 이후(DOMContentLoaded 이벤트 발생) 진행됩니다. 따라서 DOM 생성 이후 실행되어야 할 자바스크립트에 유용합니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 38_브라우저의 렌더링 과정(p.660 - 676)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]ES6에 추가된 함수 기능]]></title><description><![CDATA[ES6는 ECMAScript2015 또는 ECMAScript6로 2015년 도입된 자바스크립트 버전입니다. ES6 이전 버전들에서 문제가 있던 것들을 보완하고 해결한 자바스크립트 버전으로 많은 개발 환경들이 ES6에 맞춰지게 되었습니다. 따라서, ES…]]></description><link>https://lcy042000.github.io/es-6-new-function</link><guid isPermaLink="false">https://lcy042000.github.io/es-6-new-function</guid><category><![CDATA[WHAT]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[ES6]]></category><category><![CDATA[Function]]></category><pubDate>Fri, 15 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;ES6는 ECMAScript2015 또는 ECMAScript6로 2015년 도입된 자바스크립트 버전입니다. ES6 이전 버전들에서 문제가 있던 것들을 보완하고 해결한 자바스크립트 버전으로 많은 개발 환경들이 ES6에 맞춰지게 되었습니다. 따라서, ES6에 대해 많은 관심과 주목을 하게 되었습니다. 지금부터 ES6에 추가된 함수 기능에 대해 알아보도록 하겠습니다.&lt;/p&gt;&lt;h2&gt;함수의 구분&lt;/h2&gt;&lt;p&gt;ES6 이전까지 함수의 별다른 구분은 존재하지 않았습니다. 여러 호출 방법을 통해 함수를 사용하여 코드의 제약이 존재하지 않아 편리한 것처럼 보일 수 있지만, 이는 잘못된 코드 작성 같은 실수를 유발하여 성능 저하로 이어질 수 있습니다.&lt;/p&gt;&lt;p&gt;ES6 이전의 모든 함수는 사용 목적에 따라 명확한 구분이 없어 호출 방식에 특별한 제약이 존재하지 않고 생성자 함수로 호출되지 않아도 프로토타입 객체를 생성할 수 있었습니다. 이러한 문제를 해결하기 위해 ES6에서는 사용 목적에 따라 함수를 일반 함수, 메서드, 화살표 함수로 구분하였습니다.&lt;/p&gt;&lt;p&gt;일반 함수는 함수 선언문 또는 함수 표현식으로 정의한 함수로 ES6 이전의 함수와 큰 차이는 존재하지 않습니다.&lt;/p&gt;&lt;h2&gt;메서드&lt;/h2&gt;&lt;p&gt;ES6에서 메서드는 메서드 축약 표현으로 정의된 함수를 의미합니다.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; obj &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token literal-property property&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;메서드는 인스턴스를 생성할 수 없는 non-constructor입니다. 따라서, prototype 프로퍼티가 존재하지 않으며 프로토타입도 생성하지 않습니다. 메서드는 자신을 바인딩 한 객체를 가리키는 내부 슬롯 [[HomeObject]]를 가지며, 이를 통해 super 키워드를 사용할 수 있습니다.&lt;/p&gt;&lt;h2&gt;화살표 함수&lt;/h2&gt;&lt;p&gt;화살표 함수는 function 키워드 대신 화살표를 사용하여 간략한 함수 정의가 가능합니다. 화살표 함수는 인스턴스를 생성할 수 없어 prototype 프로퍼티가 없으며 프로토타입도 생성하지 않습니다. 또한, 중복된 매개변수 이름을 선언할 수 없고 함수 자체의 this, arguments, super, new.target 바인딩을 갖지 않습니다. 함수 내부에서 this, arguments, super, new.target을 참조하면 스코프 체인을 따라 상위 스코프의  this, arguments, super, new.target을 참조합니다.&lt;/p&gt;&lt;p&gt;화살표 함수의 this는 일반 함수의 this와 다르게 동작합니다. 콜백 함수 내부의 this와 외부 함수의 this가 서로 다른 값을 가리켜 에러를 발생시키는 문제가 존재합니다. ES6에서는 이를 해결하기 위해 &lt;strong&gt;화살표 함수 자체의 this 바인딩을 갖지 않아 this 참조 시 상위 스코프의 this를 참조&lt;/strong&gt;하게 됩니다. 이를 lexical this라고 합니다.&lt;/p&gt;&lt;p&gt;또한 화살표 함수는 super, arguments 바인딩을 갖지 않습니다. 따라서, 화살표 함수 내부에서 참조하면 counstructor 내부의 super를 참조하거나 상위 스코프의 arguments를 참조합니다.&lt;/p&gt;&lt;h2&gt;Rest 파라미터&lt;/h2&gt;&lt;p&gt;Rest 파라미터는 함수에 전달된 인수들의 목록을 배열로 전달받습니다. 매개 변수 이름 앞에 점 3개를 붙여 정의합니다. 일반적인 매개 변수와 같이 사용할 수 있으며, 함수에 전달되는 인수들은 일반 매개 변수와 Rest 파라미터에 순차적으로 할당됩니다. 함수에 전달되는 일반 매개 변수를 제외하고 나머지 인수들로 Rest 파라미터에 할당되기 때문에 Rest 파라미터는 마지막에 위치해야 하며, 한 개의 Rest 파라미터만 선언할 수 있습니다.&lt;/p&gt;&lt;p&gt;ES6 이전에는 arguments 객체를 통해 인수를 전달받아 특정 변환을 통해 배열처럼 사용할 수 있었습니다. ES6에서 Rest 파라미터가 지원된 이후 번거로운 과정이 사라져 편리하게 매개 변수를 활용 가능해졌습니다.&lt;/p&gt;&lt;h2&gt;매개 변수 기본값&lt;/h2&gt;&lt;p&gt;함수 호출 시 전달되는 인수의 개수와 매개 변수의 개수가 달라도 에러를 발생하지 않습니다. 이는 자바스크립트 엔진이 매개 변수 개수와 인수 개수를 체크하지 않기 때문입니다. 매개 변수 개수보다 적은 인수를 전달할 경우 값을 전달받지 못한 매개 변수는 undefined 값을 가지게 됩니다. 이는 의도치 않는 결과를 낳을 수 있습니다. 따라서 ES6에서는 이를 방지하기 위해 매개 변수의 기본값을 지원합니다. 매개 변수의 기본값 설정을 통해 매개변수 개수와 일치하지 않은 인수 전달 시 설정된 기본값을 사용합니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 26_ES6 함수의 추가 기능(p.469 - 491)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[HOW]클로저의 활용 방법]]></title><description><![CDATA[…]]></description><link>https://lcy042000.github.io/ho-wto-use-closure</link><guid isPermaLink="false">https://lcy042000.github.io/ho-wto-use-closure</guid><category><![CDATA[HOW]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Closure]]></category><pubDate>Thu, 14 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;클로저는 자바스크립트에서 유용하게 사용될 수 있습니다. 지금부터 어떻게 클로저를 활용할 수 있을지 알아보도록 하겠습니다.&lt;/p&gt;&lt;h2&gt;클로저의 활용&lt;/h2&gt;&lt;p&gt;클로저는 주로 상태를 안전하게 은닉하고 특정 함수에게만 상태 변경을 허용하기 위해 사용합니다. 변수의 값이 의도치 않게 변경될 수 있으면 이는 안전하지 않은 상태입니다. 클로저는 상위 스코프에서 필요한 식별자만 참조하며, 이 식별자는 은닉된 private 변수로 의도치 않은 변경을 방지할 수 있습니다.&lt;/p&gt;&lt;p&gt;변수 값이 언제 어디서나 변경될 수 있다면, 이는 시스템의 근본적인 오류 발생 원인이 될 수 있습니다. 따라서, 클로저의 활용을 통해 외부 상태 변경이나 가변 데이터를 피하고 불변성을 지향하는 함수형 프로그래밍 특성에 맞춰 코드의 안정성을 향상할 수 있습니다.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 클로저 활용의 예시&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; counter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; counter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;aux&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		counter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;aux&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; counter&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;increase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;decrease&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;increase&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1&lt;/span&gt;
console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;counter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;decrease&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 24_클로저(p.401 - 409)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]What is Closure?]]></title><description><![CDATA[자바스크립트에 대해 공부하다 보면 클로저에 대해 한 번쯤 들어본 경험이 있을 것입니다. 클로저는 함수형 프로그래밍 언어에서 등장하는 중요한 특성입니다. 클로저에 대해 알기 전, 렉시컬 스코프와 함수 객체의 내부 슬롯인 [ Environment…]]></description><link>https://lcy042000.github.io/what-closure</link><guid isPermaLink="false">https://lcy042000.github.io/what-closure</guid><category><![CDATA[WHAT]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Closure]]></category><pubDate>Thu, 14 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;&lt;/h1&gt;&lt;p&gt;자바스크립트에 대해 공부하다 보면 클로저에 대해 한 번쯤 들어본 경험이 있을 것입니다. 클로저는 함수형 프로그래밍 언어에서 등장하는 중요한 특성입니다. 클로저에 대해 알기 전, 렉시컬 스코프와 함수 객체의 내부 슬롯인 [[Environment]]의 동작에 대해 알아야 합니다. 지금부터, 렉시컬 스코프와 [[Environment]] 슬롯에 대해 보고 나서 클로저에 대해 알아보도록 하겠습니다.&lt;/p&gt;&lt;h2&gt;렉시컬 스코프와 [[Environment]] 슬롯&lt;/h2&gt;&lt;p&gt;자바스크립트 엔진이 함수 정의 위치에 따라 상위 스코프를 정하는 것을 렉시컬 스코프라고 합니다. 함수의 상위 스코프를 정하는 것은 렉시컬 환경의 외부 렉시컬 환경에 대한 참조에 저장한 참조 값을 결정하는 것과 동일한 작업으로 함수 정의가 평가되는 시점에 정의된 환경(위치)이 상위 스코프로 결정됩니다.&lt;/p&gt;&lt;p&gt;함수가 선언되는 위치와 호출되는 위치가 다를 수 있으므로 렉시컬 스코프를 위해서 상위 스코프를 기억해야 합니다. 함수는 상위 스코프 기억을 위해 내부 슬롯 [[Environment]]에 상위 스코프 참조(함수가 정의된 위치)를 저장합니다. 이때 저장된 값은 함수가 호출되었을 때 생성될 함수 렉시컬 환경의 외부 렉시컬 환경에 대한 참조에 저장될 값이기도 합니다.&lt;/p&gt;&lt;h2&gt;클로저와 렉시컬 환경&lt;/h2&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;outer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;inner&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; inner&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; innerFunc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;outer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;innerFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;위 코드의 실행 결과는 무엇일까요? 정답은 바로 10입니다!&lt;/p&gt;&lt;p&gt;outer 함수의 실행은 inner 함수를 반환하고 종료하기 때문에 outer 함수의 실행 컨텍스트와 x 변수는 사라졌다고 생각할 수 있지만 inner 함수의 내부 슬롯 [[Environment]]에 저장된 상위 스코프 참조로 인해 outer 함수의 렉시컬 환경은 남아있습니다.&lt;/p&gt;&lt;p&gt;이처럼 외부 함수보다 중첩 함수가 더 오래 남아있고 외부 함수의 변수를 참조하는 것을 &lt;strong&gt;클로저&lt;/strong&gt;라고 합니다.&lt;/p&gt;&lt;p&gt;클로저는 중첩 함수가 상위 스코프의 식별자를 참조하고 있고 중첩 함수가 외부 함수보다 더 오래 유지되는 경우에만 한정하는 것이 일반적입니다. 또한, 클로저에 의해 참조되는 상위 스코프의 변수를 &lt;strong&gt;자유 변수&lt;/strong&gt;라고 부릅니다.&lt;/p&gt;&lt;p&gt;자바스크립트 엔진은 클로저가 참조하고 있는 식별자만 기억하고 나머지는 가비지 컬렉션을 통해 메모리 점유를 하지 않도록 처리합니다. 이를 통해 메모리 누수를 줄입니다.&lt;/p&gt;&lt;p&gt;클로저는 자바스크립트에서 중요 기능으로 클로저를 통해 효율적인 코드 작성을 할 수 있습니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 24_클로저(p.388 - 401)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[HOW]실행 컨텍스트는 어떻게 동작할까?]]></title><description><![CDATA[…]]></description><link>https://lcy042000.github.io/java-script-execution-context-operate</link><guid isPermaLink="false">https://lcy042000.github.io/java-script-execution-context-operate</guid><category><![CDATA[HOW]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Execution Context]]></category><pubDate>Wed, 13 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;자바스크립트의 실행 컨텍스트는 소스코드를 실행하고 관리하는 중요한 요소입니다. 실행 컨텍스트가 어떻게 생성되며 동작하는지 안다면 자바스크립트의 동작 과정에 대해 파악할 수 있습니다. 지금부터 자바스크립트의 실행 컨텍스트 생성과 동작 과정에 대해 알아보도록 하겠습니다.&lt;/p&gt;&lt;h2&gt;1. 전역 객체 생성&lt;/h2&gt;&lt;p&gt;전역 객체는 전역 코드가 평가되기 전에 생성됩니다. 전역 객체 또한 Object의 상속으로 생성되며 프로토타입 체인 중 하나입니다.&lt;/p&gt;&lt;h2&gt;2. 전역 코드 평가&lt;/h2&gt;&lt;p&gt;전역 객체 생성 후 소스코드를 로드하여 전역 코드를 평가합니다. 전역 코드의 평가 순서는 다음과 같습니다.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;전역 실행 컨텍스트 생성&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;전역 실행 컨텍스트를 생성하여 실행 컨텍스트 스택에 담습니다. 실행 컨텍스트 스택은 비어있었기 때문에 전역 실행 컨텍스트는 곧바로 실행 중인 실행 컨텍스트가 됩니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;전역 렉시컬 환경 생성&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;전역 렉시컬 환경을 생성하여 전역 실행 컨텍스트에 바인딩 합니다.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;전역 환경 레코드 생성&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;전역 렉시컬 환경을 구성하는 전역 환경 레코드는 전역 변수를 관리하는 전역 스코프와 전역 객체의 빌트인 전역 프로퍼티, 빌트인 전역 함수, 표준 빌트인 객체를 제공합니다. var 키워드로 선언한 전역 변수와 let, const로 선언한 전역 변수의 구분하여 관리하기 위해 전역 스코프 역할을 담당하는 전역 환경 레코드는 &lt;strong&gt;객체 환경 레코드&lt;/strong&gt;와 &lt;strong&gt;선언적 환경 레코드&lt;/strong&gt;로 구성되어 있습니다. 객체 환경 레코드와 선언적 환경 레코드는 협력을 통해 전역 스코프와 전역 객체를 관리합니다.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;객체 환경 레코드 생성&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;객체 환경 레코드는 var 키워드로 선언한 전역 변수와 함수 선언문으로 정의한 전역 함수, 빌트인 전역 프로퍼티와 빌트인 전역 함수, 표준 빌트인 객체를 관리합니다. 객체 환경 레코드는 전역 객체인 BindingObject와 연결됩니다. &lt;strong&gt;전역 코드 평가 과정에서 var 키워드의 전역 변수와 함수 선언문으로 정의된 전역 함수는 BindingObject를 통해 전역 객체의 프로퍼티와 메서드가 됩니다.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;var 키워드로 선언한 변수는 선언과 초기화가 동시에 이루어져 변수 선언문 이전에도 참조할 수 있습니다. 하지만 암묵적으로 undefined를 바인딩하기 때문에 선언문 이전 참조 시 undefined를 반환한다. 이 동작은 변수 호이스팅이 발생하는 원인이기도 합니다.&lt;/p&gt;&lt;p&gt;함수 선언문으로 정의한 함수 평가 후 BindingObject를 통해 전역 객체에 함수 이름과 동일한 이름의 key로 등록하고 생성된 함수 객체를 할당합니다. 따라서, 함수 선언문으로 정의한 함수는 함수 선언문 이전에 호출할 수 있으며 이는 변수 호이스팅과 함수 호이스팅의 차이점이기도 합니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;선언적 환경 레코드 생성&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;선언적 환경 레코드는 let, const 키워드로 선언한 전역 변수를 관리합니다. let과 const로 선언된 변수는 전역 객체의 프로퍼티에 등록되지 않고 개념적인 블록에 존재하게 되는데 개념적인 블록이 바로 선언적 환경 레코드입니다.&lt;/p&gt;&lt;p&gt;const 키워드의 변수의 경우 선언과 초기화가 분리되어 진행되기 때문에 변수 선언문에 도달하기 전까지 &lt;strong&gt;일시적 사각지대(Temporal Dead Zone; TDZ)&lt;/strong&gt;에 빠지게 됩니다. let, const 키워드도 변수 호이스팅이 발생하기는 하지만, 변수 선언문 도달 전까지 일시적 사각지대에 빠지기 때문에 참조할 수 없습니다.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;this 바인딩&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;전역 환경 레코드의 [[GlobalThisValue]] 내부 슬롯에 전역 객체를 가리키는 this가 바인딩 됩니다. &lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;외부 렉시컬 환경에 대한 참조 결정&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;외부 렉시컬 환경에 대한 참조는 현재 평가 중인 소스코드를 포함하는 외부 소스코드의 렉시컬 환경인 상위 스코프를 가리킵니다. 상위 스코프를 가리킴으로써 단방향 링크드 리스트인 스코프 체인을 구현합니다.&lt;/p&gt;&lt;p&gt;전역 코드를 포함하는 소스코드가 존재하지 않기 때문에 현재의 상황에서는 null이 할당되게 됩니다. 이는 전역 렉시컬 환경이 스코프 체인의 종점임을 뜻합니다.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;3. 전역 코드 실행&lt;/h2&gt;&lt;p&gt;전역 코드가 실행되며 전역 변수의 값이 할당되고 함수가 호출됩니다. 변수 할당문이나 함수 호출문을 실행하기 위해서는 이들이 선언된 식별자인지 확인해야 합니다. 동일한 이름의 식별자가 여러 스코프에 존재할 수 있기 때문에 어느 스코프의 식별자를 참조해야 하는지 결정하는 것을 &lt;strong&gt;식별자 결정&lt;/strong&gt;이라고 합니다.&lt;/p&gt;&lt;p&gt;식별자 결정을 위해서 실행 중인 실행 컨텍스트에서 식별자를 검색하여 해당 실행 컨텍스트의 렉시컬 환경에 존재하지 않는 경우 외부 렉시컬 환경이 가리키는 상위 스코프로 이동하여 검색합니다. 이는 스코프 체인의 동작 원리입니다.&lt;/p&gt;&lt;h2&gt;4. 함수 코드 평가&lt;/h2&gt;&lt;p&gt;함수가 호출되면 전역 코드의 실행을 멈추고 함수 내부로 코드의 제어권이 이동됩니다. 이후 함수 코드를 평가하며 함수 코드의 평가 순서는 다음과 같습니다.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;함수 실행 컨텍스트 생성&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;함수의 실행 컨텍스트를 생성하여 함수 렉시컬 환경이 완성되면 실행 컨텍스트 스택에 담습니다.  함수 실행 컨텍스트는 실행 컨텍스트 스택의 최상단에 위치하게 되며 실행 중인 실행 컨텍스트가 됩니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;함수 렉시컬 환경 생성&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;함수 렉시컬 환경을 생하여 함수 실행 컨텍스트에 바인딩 됩니다.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;함수 환경 레코드 생성&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;함수 환경 레코드는 함수 렉시컬 환경 구성 요소 중 하나로 매개 변수, argument 객체, 함수 내부에서 선언한 지역 변수와 중첩 함수를 등록하고 관리합니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;this 바인딩&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;함수 환경 레코드의 [[ThisValue]] 내부 슬롯에 this가 바인딩 되며 바인딩 될 객체는 함수 호출 방식에 따라 결정됩니다.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;외부 렉시컬 환경에 대한 참조 결정&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;외부 렉시컬 환경에 대한 참조에는 함수 정의가 평가된 시점에 실행 중인 실행 컨텍스트의 렉시컬 환경의 참조가 할당됩니다.&lt;/p&gt;&lt;p&gt;자바스크립트는 함수 호출 위치가 아닌 정의 위치에 따라 상위 스코프를 결정합니다. 자바스크립트 엔진은 함수 정의를 평가하려 함수 객체 생성 시 실행 중인 실행 컨텍스트의 렉시컬 환경(함수의 상위 스코프)을 함수 객체 내부 슬롯인 [[Environment]]에 저장합니다. 함수 렉시컬 환경의 외부 렉시컬 환경에 대한 참조에 할당하는 것은 [[Environment]]에 저장된 렉시컬 환경의 참조로 이는 렉시컬 스코프를 구현하는 메커니즘이며 클로저를 이해할 수 있는 단서이기도 합니다.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;5. 함수 코드 실행&lt;/h2&gt;&lt;p&gt;함수 소스코드의 순차 실행으로 매개 변수에 인수가 할당되고 변수 할당문이 실행되어 지역 변수에 값이 할당됩니다.&lt;/p&gt;&lt;h2&gt;6. 함수 코드 실행 종료&lt;/h2&gt;&lt;p&gt;더 이상 실행할 함수의 소스코드가 없는 경우 실행 컨텍스트 스택에서 함수 실행 컨텍스트를 제거합니다. 함수 실행 컨텍스트의 제거가 함수 렉시컬 환경의 제거를 의미하는 것은 아닙니다. 렉시컬 환경은 실행 컨텍스트에 참조되지만 독립적인 객체로 다른 곳에서 참조되고 있다면 사라지지 않습니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 23_실행 컨텍스트(p.368 - 386)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]실행 컨텍스트]]></title><description><![CDATA[…]]></description><link>https://lcy042000.github.io/java-script-execution-context</link><guid isPermaLink="false">https://lcy042000.github.io/java-script-execution-context</guid><category><![CDATA[WHAT]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Execution Context]]></category><pubDate>Fri, 08 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;실행 컨텍스트는 자바스크립트가 스코프를 기반으로 식별자와 식별자에 바인딩 된 값(식별자 바인딩)을 관리하는 방식과 호이스팅이 발생하는 이유, 클로저의 동작 방식, 이벤트 핸들러와 비동기 처리 방식과 관련되어 있습니다. 따라서, 실행 컨텍스트는 자바스크립트 동작을 담당하는 중요한 개념입니다. 지금부터 자바스크립트의 실행 컨텍스트에 대해서 알아보도록 하겠습니다.&lt;/p&gt;&lt;h2&gt;소스코드의 타입&lt;/h2&gt;&lt;p&gt;ECMAScript는 4가지의 소스코드가 있습니다. 4가지 타입의 소스코드는 실행 컨텍스트를 생성합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;전역 코드:&lt;/strong&gt; 전역에 존재하는 소스코드.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;함수 코드:&lt;/strong&gt; 함수 내부에 존재하는 소스코드. 함수 내부의 중첩 함수, 클래스 등의 내부 코드는 포함&lt;span role=&quot;img&quot; aria-label=&quot;cross mark&quot;&gt;❌&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;eval 코드:&lt;/strong&gt; 빌트인 전역 함수인 eval 함수에 인수로 전달되어 실행되는 소스코드.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;모듈 코드:&lt;/strong&gt; 모듈 내부에 존재하는 소스코드.&lt;/p&gt;&lt;p&gt;소스코드를 구분하는 이유는 타입에 따라 실행 컨텍스트를 생성하는 과정과 관리 내용이 다르기 때문입니다. &lt;/p&gt;&lt;p&gt;전역 코드는 전역 변수 관리를 위해 최상위 스코프인 전역 스코프를 생성해야 합니다. 전역 코드가 평가되면 전역 실행 컨텍스트가 생성됩니다.&lt;/p&gt;&lt;p&gt;함수 코드는 지역 스코프를 생성하여 지역 변수, 매개 변수, arguments 객체를 관리해야 합니다. 또한, 지역 스코프를 전역 스코프에서 시작된 스코프 체인에 연결해야 합니다. 이를 위해 함수 코드가 평가되면 함수 실행 컨텍스트가 생성됩니다.&lt;/p&gt;&lt;p&gt;eval 코드는 strict mode에서 자신만의 스코프를 생성하며 eval 코드가 평가되면 eval 실행 컨텍스트가 생성됩니다.&lt;/p&gt;&lt;p&gt;모듈 코드는 모듈별로 독립적인 모듈 스코프를 생성하고 모듈 코드가 평가되면 모듈 실행 컨텍스트가 생성됩니다.&lt;/p&gt;&lt;h2&gt;소스코드의 평가와 실행&lt;/h2&gt;&lt;p&gt;자바스크립트 엔진은 소스코드의 평가와 소스코드의 실행 과정으로 나뉘어 처리합니다. 소스코드 평가 과정에서는 실행 컨텍스트를 생성하고 변수, 함수 선언문을 실행하여 생성된 변수와 함수 식별자를 키로 실행 컨텍스트가 관리하는 스코프에 등록합니다. 평가 과정 이후 선언문을 제외한 소스코드가 실행되며 ‘런타임’이 시작됩니다. 소스코드의 실행 결과는 실행 컨텍스트가 관리하는 스코프에 등록됩니다.&lt;/p&gt;&lt;h2&gt;실행 컨텍스트의 역할&lt;/h2&gt;&lt;p&gt;코드가 실행되려면 스코프를 구분하여 식별자와 바인딩 된 값의 관리가 필요하며, 중첩 관계에 의해 스코프 체인을 형성하여 식별자를 검색할 수 있어야 합니다. 또한, 전역 객체의 프로퍼티도 검색 가능해야 합니다. 함수 호출 종료 시 호출 이전으로 돌아가기 위해 현재 실행 중인 코드와 이전에 실행된 코드의 분리된 관리도 필요합니다. 이를 모두 관리하는 역할을 담당하는 것이 실행 컨텍스트입니다. 실행 컨텍스트는 소스코드가 실행되는 데 요구되는 환경 제공하고 코드 실행 결과를 관리하는 영역입니다. 식별자와 스코프는 실행 컨텍스트의 &lt;strong&gt;렉시컬 환경&lt;/strong&gt;으로 관리하고 코드 실행 순서는 &lt;strong&gt;실행 컨텍스트 스택&lt;/strong&gt;을 통해 관리합니다.&lt;/p&gt;&lt;h2&gt;실행 컨텍스트 스택&lt;/h2&gt;&lt;p&gt;생성된 실행 컨텍스트는 스택에서 관리되며, 이를 &lt;strong&gt;실행 컨텍스트 스택&lt;/strong&gt;이라고 합니다. 코드 실행 시 실행되는 시간의 흐름에 따라 실행 컨텍스트 스택에 추가되거나 제거됩니다. 실행 컨텍스트 스택은 코드의 실행 순서를 관리하며, 실행 컨텍스트 스택의 최상단에 존재하는 실행 컨텍스트는 현재 실행 중인 코드의 실행 컨텍스트입니다.&lt;/p&gt;&lt;h2&gt;렉시컬 환경&lt;/h2&gt;&lt;p&gt;식별자와 식별자에 바인딩 된 값, 상위 스코프에 대한 참조를 기록하는 자료구조로 실행 컨텍스트를 구성하는 컴포넌트를 &lt;strong&gt;렉시컬 환경&lt;/strong&gt;이라 합니다. 렉시컬 환경은 스코프와 식별자를 관리합니다. 렉시컬 환경은 키와 값을 갖는 객체 형태의 스코프를 생성하여 식별자를 키로 등록하며 바인딩된 값을 관리합니다.&lt;/p&gt;&lt;p&gt;렉시컬 환경은 환경 레코드와 외부 헥시컬 환경에 대한 참조로 구성되어 있습니다.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;환경 레코드: 스코프의 식별자 등록과 식별자에 바인딩 된 값을 관리하는 저장소&lt;/li&gt;&lt;li&gt;외부 렉시컬 환경에 대한 참조: 상위 스코프를 가리키며 참조를 통해 단방향 링크드 리스트 형태의 스코프 체인 구현&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;실행 컨텍스트의 생성과 식별자 검색 과정&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://lcy042000.github.io/java-script-execution-context-operate&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;[HOW] 실행 컨텍스트는 어떻게 동작할까?&lt;/a&gt;&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 23_실행 컨텍스트(p.359 - 387)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]What is This?]]></title><description><![CDATA[this…]]></description><link>https://lcy042000.github.io/java-script-this</link><guid isPermaLink="false">https://lcy042000.github.io/java-script-this</guid><category><![CDATA[WHAT]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[This]]></category><pubDate>Thu, 07 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;this 키워드&lt;/h2&gt;&lt;p&gt;객체 내의 메서드는 자신이 속한 객체의 프로퍼티에 접근하여 참조하거나 변경 가능해야 합니다. 자신이 속한 객체의 프로퍼티를 참조하기 위해서는 자신이 속한 객체를 가리키는 식별자를 참조할 수 있어야 합니다. 이를 위해 자바스크립트는 &lt;strong&gt;this&lt;/strong&gt; 키워드를 제공합니다.&lt;/p&gt;&lt;p&gt;this 키워드는 소속된 객체 또는 생성할 인스턴스를 가리키는 자기 참조 변수로 소속 객체나 생성할 인스턴스의 프로퍼티와 메서드에 접근할 수 있습니다. this는 자바스크립트 엔진에 의해 암묵적으로 생성되며 this가 가리키는 값은 함수 호출 방식에 따라 동적으로 결정됩니다.&lt;/p&gt;&lt;h2&gt;함수 호출 방식과 this 바인딩&lt;/h2&gt;&lt;h3&gt;일반 함수 호출&lt;/h3&gt;&lt;p&gt;일반 함수로 호출하면 함수 내부의 this에 전역 객체가 바인딩 됩니다.&lt;/p&gt;&lt;h3&gt;메서드 호출&lt;/h3&gt;&lt;p&gt;메서드 내부에서 this는 메서드를 호출할 때 메서드 이름 앞의 객체가 바인딩 됩니다. 여기서 주의할 점은 메서드 내부의 this는 메서드를 소유한 객체가 아닌 메서드를 호출한 객체에 바인딩 된다는 점입니다. this에 바인딩 될 객체는 호출 시점에 결정됩니다.&lt;/p&gt;&lt;h3&gt;생성자 함수 호출&lt;/h3&gt;&lt;p&gt;생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스가 바인딩 됩니다. 생성자 함수는 new 키워드를 붙이지 않고 사용할 경우, 일반 함수로 동작하기 때문에 이 경우에는 일반 함수 호출 방식으로 동작합니다.&lt;/p&gt;&lt;h3&gt;Function.prototype.apply/call/bind 메서드에 의한 간접 호출&lt;/h3&gt;&lt;p&gt;Function.prototype.apply()와 Function.prototype.call()은 this로 사용할 객체와 인수 리스트를 인수로 전달받아 함수를 호출합니다. apply 메서드와 call 메서드는 함수를 호출하는 기능을 수행하는 것으로 인수로 전달된 특정 객체를 호출한 함수의 this에 바인딩 합니다.&lt;/p&gt;&lt;p&gt;Function.prototype.bind()는 메서드는 첫 번째 인수로 전달한 값으로 this 바인딩이 교체된 함수를 새롭게 생성해 반환합니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 22_this(p.342 - 357)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]JavaScript의 prototype]]></title><description><![CDATA[…]]></description><link>https://lcy042000.github.io/java-script-prototype</link><guid isPermaLink="false">https://lcy042000.github.io/java-script-prototype</guid><category><![CDATA[WHAT]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Prototype]]></category><pubDate>Wed, 06 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;자바스크립트는 명령형, 함수형, 프로토타입 기반 객체지향 프로그래밍을 지원하는 멀티 패러다임 프로그래밍 언어입니다. 또한, 자바스크립트는 객체 기반의 프로그래밍 언어로써 자바스크립트를 이루고 있는 거의 모든 것이 객체입니다. 자바스크립트는 &lt;strong&gt;프로토타입&lt;/strong&gt;을 기반으로 상속을 구현합니다.&lt;/p&gt;&lt;p&gt;생성자 함수가 생성한 모든 인스턴스는 자신의 프로토타입의 모든 프로퍼티와 메서드를 상속받습니다. 상속은 코드 재사용 측면에서 매우 중요한 요소로 생성자 함수가 생성하는 모든 인스턴스는 공통으로 사용할 프로퍼티와 메서드를 공유할 수 있습니다.&lt;/p&gt;&lt;p&gt;지금부터 자바스크립트의 상속에서 빠질 수 없는 프로토타입에 대해 알아보도록 하겠습니다.&lt;/p&gt;&lt;h2&gt;프로토타입 객체&lt;/h2&gt;&lt;p&gt;프로토타입은 상위 객체의 역할을 하는 객체로서 다른 객체에 공유 프로퍼티를 제공합니다. 하위 객체는 프로토타입의 프로퍼티에 접근 가능하며 이를 자신의 프로퍼티처럼 사용 가능합니다. 객체가 생성되는 방식에 따라 프로토타입이 결정되며 [[Prototype]]에 저장됩니다. 모든 객체는 하나의 프로토타입을 가지며 객체, 프로토타입, 생성자 함수는 서로 연결되어 있습니다.&lt;/p&gt;&lt;p&gt;객체는 [[Prototype]]에 직접 접근할 수 없지만 &lt;strong&gt;&lt;strong&gt; proto &lt;/strong&gt; 접근자 프로퍼티&lt;/strong&gt;를 통해 자신의 프로토타입에 접근 가능합니다.&lt;/p&gt;&lt;p&gt;프로토타입에 접근하기 위해 &lt;strong&gt; proto &lt;/strong&gt; 접근자 프로퍼티를 사용하는 이유는 상호 참조에 의해 프로토타입 체인이 생성되는 것을 방지하기 위해서입니다. 프로토타입 체인은 순환이 되어서는 안되며 단방향 형태로만 이루어져야 합니다.&lt;/p&gt;&lt;p&gt;코드 내에서 &lt;strong&gt; proto &lt;/strong&gt; 접근자 프로퍼티를 사용하는 것은 권장되지 않습니다. 그 이유는 모든 객체가 &lt;strong&gt; proto &lt;/strong&gt; 접근자 프로퍼티를 사용할 수 있는 것이 아니기 때문입니다.&lt;/p&gt;&lt;h3&gt;함수 객체의 prototype 프로퍼티&lt;/h3&gt;&lt;p&gt;함수 객체는 유일하게 prototype 프로퍼티를 가지며 생성자 함수가 생성할 인스턴스의 프로토타입을 가리킵니다. non-constructir인 화살표 함수와 메서드 축약 표현으로 정의한 함수는 prototype 프로퍼티를 갖지 않으며 프로토타입을 생성하지 않습니다. 또한, 일반 함수도 prototype 프로퍼티를 가지고 있지만 객체를 생성하지 않으므로 아무런 의미를 갖지 않습니다.&lt;/p&gt;&lt;p&gt;모든 객체가 가지는 &lt;strong&gt; proto &lt;/strong&gt; 접근자 프로퍼티와 함수 객체의 prototype 프로퍼티는 동일한 프로토타입을 가리킵니다. 하지만 이 두 프로퍼티는 사용하는 주체가 다릅니다.&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;구분&lt;/th&gt;&lt;th&gt;소유&lt;/th&gt;&lt;th&gt;값&lt;/th&gt;&lt;th&gt;사용 주체&lt;/th&gt;&lt;th&gt;사용 목적&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt; proto &lt;/strong&gt; 접근자 프로퍼티&lt;/td&gt;&lt;td&gt;모든 객체&lt;/td&gt;&lt;td&gt;프로토타입의 참조&lt;/td&gt;&lt;td&gt;모든 객체&lt;/td&gt;&lt;td&gt;객체가 자신의 프로토타입에 접근 또는 교체하기 위해 사용&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;prototype 프로퍼티&lt;/td&gt;&lt;td&gt;constructor&lt;/td&gt;&lt;td&gt;프로토타입의 참조&lt;/td&gt;&lt;td&gt;생성자 함수&lt;/td&gt;&lt;td&gt;생성자 함수가 자신이 생성할 객체의 프로토타입을 할당하기 위해 사용&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h2&gt;프로토타입의 생성 시점&lt;/h2&gt;&lt;p&gt;모든 객체는 생성자 함수와 연결되어 있습니다. 프로토타입은 생성자 함수가 생성되는 시점에 같이 생성됩니다. 프로토타입과 생성자 함수는 단독으로 존재할 수 없고 언제나 쌍으로 존재하기 때문입니다.&lt;/p&gt;&lt;h2&gt;프로토타입 체인&lt;/h2&gt;&lt;p&gt;자바스크립트는 객체의 프로퍼티에 접근할 때 해당 객체에 접근하려는 프로퍼티가 없을 경우 [[Prototype]] 내부 슬롯의 참조를 따라 프로토타입의 프로퍼티에 접근합니다. 이를 프로토타입 체인이라 하며 프로토타입 체인은 자바스크립트가 객체지향 프로그래밍의 상속을 구현하는 메커니즘입니다.&lt;/p&gt;&lt;p&gt;프로토타입 체인의 종점은 항상 Object.prototype입니다. Object.prototype에서도 프로퍼티를 찾지 못하는 경우에도 에러를 발생하는 것이 아닌 undefined를 반환하므로 이점에 주의해야 합니다.&lt;/p&gt;&lt;h2&gt;오버라이딩과 프로퍼티 섀도잉&lt;/h2&gt;&lt;p&gt;프로토타입이 소유한 프로퍼티를 프로토타입 프로퍼티라고 하며, 인스턴스가 소유한 프로퍼티를 인스턴스 프로퍼티라고 합니다. 프로토타입 프로퍼티와 동일한 이름의 프로퍼티를 인스턴스에 추가하면 인스턴스 프로퍼티에 이를 추가합니다. 이를 &lt;strong&gt;오버라이딩&lt;/strong&gt;이라 하며 상속 관계에 의해 프로퍼티가 가려지는 현상을 &lt;strong&gt;프로퍼티 섀도잉&lt;/strong&gt;이라 합니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 19_프로토타입(p.260 - 311)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]var vs let vs const]]></title><description><![CDATA[var 키워드로 선언한 변수의 문제점 var 키워드는 ES5까지 변수를 선언할 수 있는 유일한 방법이었습니다. 하지만 이는 많은 문제점을 내포하고 있습니다. 변수 중복 선언 허용 var 키워드의 변수는 중복 선언이 가능합니다. var…]]></description><link>https://lcy042000.github.io/javascript-variable-keyword</link><guid isPermaLink="false">https://lcy042000.github.io/javascript-variable-keyword</guid><category><![CDATA[WHAT]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[VariableKeyword]]></category><category><![CDATA[let]]></category><category><![CDATA[var]]></category><category><![CDATA[const]]></category><pubDate>Tue, 05 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;var 키워드로 선언한 변수의 문제점&lt;/h2&gt;&lt;p&gt;var 키워드는 ES5까지 변수를 선언할 수 있는 유일한 방법이었습니다. 하지만 이는 많은 문제점을 내포하고 있습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;변수 중복 선언 허용&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;var 키워드의 변수는 중복 선언이 가능합니다. var 키워드로 선언한 변수를 중복 선언하면 초기화문 유무에 따라 다르게 동작합니다. 초기화문이 있는 변수 선언문은 자바스크립트 엔진에 의해 var 키워드기 없는 것처럼 동작하고 초기화문이 없는 변수 선언문은 무시됩니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;함수 레벨 스코프&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;var 키워드의 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정합니다. 따라서 함수 외부에서 var 키워드로 선언한 변수는 코드 블록 내에서 선언해도 모두 전역 변수가 됩니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;변수 호이스팅&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;변수 호이스팅에 의해 변수 선언문이 스코프의 선두로 끌어 올라진 것처럼 동작합니다. 실제 변수를 선언하기 전이더라도 변수를 참조하면 undefined를 반환합니다. 이는 코드의 가독성을 저하시키고 오류를 발생할 여지를 남니다.&lt;/p&gt;&lt;h2&gt;let 키워드&lt;/h2&gt;&lt;p&gt;ES6에서 새롭게 도입된 변수 선언 키워드인 let에 대해 알아보도록 하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;변수 중복 선언 금지&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;let 키워드의 경우 같은 이름의 변수를 중복 선언하면 문법 에러가 발생합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;블록 레벨 스코프&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;모든 코드 블록(함수, if 문, for 문, while 문 등)을 지역 스코프로 인정하는 블록 레벨 스코프를 따릅니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;변수 호이스팅&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;let 키워드로 선언한 변수는 호이스팅이 발생하지 않는 것처럼 동작합니다. 변수 선언 이전에 변수를 참조할 경우 참조 에러를 발생시킵니다. let 키워드로 선언한 변수는 “선언 단계”와 “초기화 단계”가 분리되어 진행됩니다. 스코프의 시작 지점부터 초기화 시작 지점까지 변수를 참조할 수 없는 구간을 &lt;strong&gt;일시적 사각지대&lt;/strong&gt;라고 부릅니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;전역 객체와 let&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;var 키워드로 선언한 전역 변수와 전역 함수, 선언하지 않은 변수에 값을 할당한 암묵적 전역은 전역 객체 window의 프로퍼티가 됩니다. 하지만, let 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 아닙니다.&lt;/p&gt;&lt;h2&gt;const 키워드&lt;/h2&gt;&lt;p&gt;let 키워드와 대부분 같지만 차이점을 기반으로 알아보도록 하겠습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;선언과 초기화&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;const 키워드의 변수는 선언과 동시에 초기화해야 합니다. 그렇지 않은 경우, 문법 에러가 발생하게 됩니다. 또한 let 키워드와 마찬가지로 블록 레벨 스코프를 가지며 변수 호이스팅이 발생하지 않습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;재할당 금지 및 상수&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;const 키워드의 변수는 재할당이 불가합니다. 또한, const 변수는 상수로 값의 변경이 불가합니다. 한 번 초기화된 상수는 재할당이 금지됩니다. &lt;/p&gt;&lt;p&gt;&lt;strong&gt;const 키워드와 객체&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;const 키워드로 선언된 변수에 원시 값을 선언한 경우에는 값을 변경할 수 없지만 객체를 선언한 경우 값 변경이 가능합니다. const 키워드는 재할당을 금지하는 것이며 값이 변하는 ‘불변’을 의미하지 않기 때문에 객체의 프로퍼티 생성, 삭제, 변경은 가능합니다. 하지만, 변수에 할당된 참조 값의 변경은 불가합니다.&lt;/p&gt;&lt;h2&gt;var vs let vs const&lt;/h2&gt;&lt;p&gt;변수 선언 시에는 const를 우선적으로 사용하고, 값의 변경이 있을 수 있는 경우 let을 사용하는 것이 좋습니다. 변수의 스코프는 최대한 좁게 설정하고 var 키워드의 사용을 지양하는 것이 좋은 코딩 습관입니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 15_let, const 키워드와 블록 레벨 스코프(p.208 - 218)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[HOW]JavaScript의 객체 변경 방지 방법]]></title><description><![CDATA[…]]></description><link>https://lcy042000.github.io/prevent-object-changes</link><guid isPermaLink="false">https://lcy042000.github.io/prevent-object-changes</guid><category><![CDATA[HOW]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Object]]></category><pubDate>Tue, 05 Dec 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;객체 변경 방지&lt;/h2&gt;&lt;p&gt;객체 변경 가능한 값으로 재할당 없이 프로퍼티의 생성, 변경, 삭제가 가능합니다. 자바스크립트는 객체의 변경을 방지하기 위해 다양한 기능을 제공합니다. 여러 객체 변경 방지 메서드들은 각각 객체의 변경 금지 정도가 다릅니다. 지금부터 각 메서드들에 대해 알아보도록 하겠습니다.&lt;/p&gt;&lt;h2&gt;객체 확장 금지&lt;/h2&gt;&lt;p&gt;객체의 확장을 금지하는 메서드는 Object.preventExtensions()입니다. 객체 확장 금지는 프로퍼티를 추가하는 것을 방지하는 것입니다. 객체의 프로퍼티는 동적 추가와 Object.defineProperty()로 가능하지만 확장이 금지된 경우에는 두 가지 방법 모두 불가능합니다. 객체의 확장 가능 여부는 Object.isExtensible()로 확인 가능합니다.&lt;/p&gt;&lt;h2&gt;객체 밀봉&lt;/h2&gt;&lt;p&gt;객체 밀봉이란 프로퍼티 추가 및 삭제, 프로퍼티 어트리뷰트 재정의 금지를 의미합니다. 밀봉된 객체는 읽기와 쓰기만 가능하며 Object.seal()로 객체를 밀봉할 수 있습니다. 객체가 밀봉됐는지 확인은 Object.isSealed()로 가능합니다.&lt;/p&gt;&lt;h2&gt;객체 동결&lt;/h2&gt;&lt;p&gt;객체 동결은 프로퍼티 추가, 삭제, 프로퍼티 어트리뷰트 재정의 금지, 프로퍼티 값 갱신 금지를 의미하며 동결된 객체는 읽기만 가능합니다. Object.freeze()를 통해 객체를 동결할 수 있습니다. Object.isFrozen()을 통해 객체 동결 여부를 확인할 수 있습니다.&lt;/p&gt;&lt;h2&gt;불변 객체&lt;/h2&gt;&lt;p&gt;객체 확장 금지, 객체 밀봉, 객체 동결은 얕은 변경 방지로 중첩된 객체는 영향을 끼칠 수 없습니다. 중첩된 객체까지 변경이 불가능한 객체를 만들기 위해서는 객체를 값으로 갖는 프로퍼티까지 재귀적으로 객체 변경 방지 메서드를 호출해야 합니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 16_프로퍼티 어트리뷰트(p.229 - 233)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[HOW]전역 변수의 사용을 억제하는 방법]]></title><description><![CDATA[…]]></description><link>https://lcy042000.github.io/not-global-variable-method</link><guid isPermaLink="false">https://lcy042000.github.io/not-global-variable-method</guid><category><![CDATA[HOW]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Global variable]]></category><pubDate>Thu, 30 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;전역 변수의 무분별한 사용은 위험한 결과를 초래할 수 있습니다. 전역 변수를 반드시 사용해야 하는 경우가 아니라면 사용을 자제해야 하며, 지역 변수를 사용해야 합니다. 지금부터 전역 변수의 사용을 줄일 수 있는 방법에 대해 알아보겠습니다.&lt;/p&gt;&lt;h3&gt;즉시 실행 함수&lt;/h3&gt;&lt;p&gt;함수 정의와 동시에 호출되는 즉시 실행 함수는 단 한 번만 호출되며, 모든 코드를 즉시 실행 함수로 감싸면 모든 변수는 즉시 실행 함수의 지역 변수가 됩니다.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; foo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3&gt;네임스페이스 객체&lt;/h3&gt;&lt;p&gt;전역 코드에 네임스페이스 객체를 생성하고 전역 변수처럼 사용코자 하는 변수를 프로퍼티로 추가하는 방법입니다. 하지만, 식별자 충돌 방지 효과는 있으나 네임스페이스 객체 자체가 전역 변수에 해당되어 좋은 방법은 아닙니다.&lt;/p&gt;&lt;h3&gt;모듈 패턴&lt;/h3&gt;&lt;p&gt;관련 있는 변수와 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈을 만드는 방법입니다. 모듈 패턴은 클로저를 기반으로 동작하여 전역 변수 사용 억제뿐만 아니라 캡슐화까지 구현할 수 있습니다.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; Counter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; num &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;increase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;num&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;

		&lt;span class=&quot;token function&quot;&gt;decrease&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;num&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3&gt;ES6 모듈&lt;/h3&gt;&lt;p&gt;ES6 모듈은 파일 자체의 독자적인 모듈 스코프를 제공합니다. 따라서 모듈 내에서 선언된 변수는 전역 변수가 아닙니다. 모던 브라우저에서 모듈을 사용할 수 있습니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 14_전역 변수의 문제점(p.204 - 207)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]전역 변수의 문제점]]></title><description><![CDATA[…]]></description><link>https://lcy042000.github.io/global-variable-problem</link><guid isPermaLink="false">https://lcy042000.github.io/global-variable-problem</guid><category><![CDATA[WHAT]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Global variable Problem]]></category><pubDate>Thu, 30 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;변수의 생명 주기&lt;/h2&gt;&lt;p&gt;변수는 선언에 의해 생성되고 할당을 통해 값을 갖습니다. 변수는 자신이 선언된 위치에서 생성되고 소멸합니다. 지역 변수의 생명 주기는 함수의 생명 주기와 동일합니다. 함수가 호출된 직후 함수 몸체의 코드가 한 줄씩 순차적으로 실행되기 이전에 자바스크립트 엔진에 의해 먼저 실행됩니다. 전역 변수의 경우 함수와 달리 전역 코드는 명시적인 호출과 종료가 없기 때문에 전역 코드와 생명 주기가 동일합니다.&lt;/p&gt;&lt;h2&gt;전역 변수의 문제점&lt;/h2&gt;&lt;h3&gt;1. 암묵적 결합&lt;/h3&gt;&lt;p&gt;전역 변수를 선언한 이유는 코드의 어느 영역에서나 참조하고 할당할 수 있는 변수를 사용하겠다는 뜻입니다. 이는 모든 코드가 전역 변수를 참조하고 변경할 수 있는 &lt;strong&gt;암묵적 결합&lt;/strong&gt;을 허용하는 것입니다. 변수의 유효 범위가 넓어질수록 코드의 가독성을 저하시키고 의도치 않는 변경을 유발할 수 있습니다.&lt;/p&gt;&lt;h3&gt;2. 긴 생명 주기&lt;/h3&gt;&lt;p&gt;전역 변수는 생명 주기가 길기 때문에, 그만큼 메모리 리소스도 사용하게 됩니다. 또한, 전역 변수의 상태를 변경할 수 있는 시간이 길고 기회도 많게 됩니다. 반면에, 지역 변수는 전역 변수보다 생명 주기가 짧고 메모리 리소스 사용도 적기 때문에 오류 발생 확률이 적습니다.&lt;/p&gt;&lt;h3&gt;3. 스코프 체인 상에서 종점 존재&lt;/h3&gt;&lt;p&gt;변수 검색 시 전역 변수가 사장 마지막에 검색되는 스코프 체인 상의 종점에 존재합니다. 따라서, 전역 변수의 검색 속도가 가장 느리기 때문에 성능 저하가 발생할 수 있습니다.&lt;/p&gt;&lt;h3&gt;4. 네임스페이스 오염&lt;/h3&gt;&lt;p&gt;자바스크립트의 문제점 중 하나는 파일이 분리되어 있더라고 하나의 전역 스코프를 공유한다는 것입니다. 만약의 경우, 각각 다른 파일에 동일한 이름의 변수가 존재한다면 예상하지 못한 결과를 가져올 수 있습니다.&lt;/p&gt;&lt;h2&gt;전역 변수 사용 억제법&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://lcy042000.github.io/not-global-variable-method&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://lcy042000.github.io/not-global-variable-method&lt;/a&gt;&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 14_전역 변수의 문제점(p.204 - 207)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]자바스크립트의 스코프]]></title><description><![CDATA[…]]></description><link>https://lcy042000.github.io/java-script-scope</link><guid isPermaLink="false">https://lcy042000.github.io/java-script-scope</guid><category><![CDATA[WHAT]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Scope]]></category><pubDate>Wed, 29 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;스코프란?&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;스코프&lt;/strong&gt;는 모든 식별자(변수 이름, 함수 이름, 클래스 이름 등)가 자신이 선언된 위치에 따라 다른 코드에서 참조할 수 있는 유효 범위를 의미합니다. 스코프는 식별자의 검색 규칙이며, 이를 통해 자바스크립트 엔진은 어떤 변수를 참조할지 결정합니다.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;global&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;local&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// local&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// global&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;위의 예제에서 함수 내부와 외부에서 &amp;#x27;x&amp;#x27;변수를 참조할 때, 자바스크립트 엔진은 어떤 변수를 참조할지 결정해야 합니다. 이러함 참조 결정을 &lt;strong&gt;식별자 결정&lt;/strong&gt;이라고 합니다. 자바스크립트 엔진은 스코프를 통해 어떤 변수를 참조할지 결정하기 때문에 &lt;strong&gt;스코프를 식별자 검색 시 사용하는 규칙&lt;/strong&gt;이라고 할 수 있습니다. &lt;/p&gt;&lt;h2&gt;스코프의 종류&lt;/h2&gt;&lt;p&gt;자신이 선언된 위치에 의해 자신이 유효한 범위인 스코프가 결정됩니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;전역과 전역 스코프:&lt;/strong&gt; 전역이란 코드의 가장 바깥 영역을 말하며, 전역은 전역 스코프(global scope)를 만듭니다. 전역 스코프를 가진 식별자는 코드 어느 곳에서나 참조가 가능합니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;지역과 지역 스코프:&lt;/strong&gt; 지역은 함수 몸체 내부를 말합니다. 지역은 지역 스코프를 만들며, 지역 스코프를 가진 식별자는 자신이 선언된 지역과 하위 지역(중첩 함수)에서만 참조가 가능합니다.&lt;/p&gt;&lt;h2&gt;스코프 체인&lt;/h2&gt;&lt;p&gt;함수는 전역에서 정의될 수 있고, 함수 내부에서도 정의될 수 있습니다. 함수 몸체 내부에서 정의된 함수를 중첩 함수라고 하며, 중첩 함수를 포함하는 함수를 외부 함수라고 합니다.&lt;/p&gt;&lt;p&gt;함수가 중첩될 수 있으므로 함수의 지역 스코프도 중첩될 수 있습니다. 이 경우 스코프가 함수의 중첩에 의해 계층적 구조를 갖습니다. 모든 지역 스코프의 최상위 스코프는 전역 스코프이며 외부 함수의 지역 스코프, 내부 함수의 지역 스코프 순으로 계층이 존재합니다. 이를 &lt;strong&gt;스코프 체인&lt;/strong&gt;이라고 합니다. 변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하며 선언된 변수를 검색합니다. 상위 스코프에서 유효한 변수는 하위 스코프에서 참조 가능하지만 하위 스코프의 변수는 상위 스코프에서 참조 불가능합니다.&lt;/p&gt;&lt;h2&gt;함수 레벨 스코프&lt;/h2&gt;&lt;p&gt;대부분의 프로그래밍 언어는 함수 몸체뿐만 아니라 코드 블록(if, for, while 등)도 지역 스코프를 만들지만, 자바스크립트는 함수만이 지역 스코프를 생성합니다. 코드 블록이 만드는 스코프는 &lt;strong&gt;블록 레벨 스코프&lt;/strong&gt;라 합니다. var 키워드로 선언된 변수는 오로지 함수의 코드 블록(함수 몸체)만을 지역 스코프로 인정하며, 이러한 특성을 &lt;strong&gt;함수 레벨 스코프&lt;/strong&gt;라 합니다. 반면, ES6에서 도입된 let, const 키워드는 블록 레벨 스코프를 지원합니다.&lt;/p&gt;&lt;h2&gt;렉시컬 스코프&lt;/h2&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;위의 코드는 bar 함수의 상위 스코프가 무엇인지에 따라 결정되며 두 가지 패턴을 예측할 수 있습니다.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;함수를 어디서 호출했는지에 따라 함수의 상위 스코프를 결정한다.&lt;/li&gt;&lt;li&gt;함수를 어디서 정의했는지에 따라 함수의 상위 스코프를 결정한다.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;첫 번째 방식은 &lt;strong&gt;동적 스코프&lt;/strong&gt;로 함수가 호출되는 시점에 따라 동적으로 상위 스코프가 결정됩니다. 두 번째 방식을 렉시컬 스코프 또는 정적 스코프라 하며 함수 정의가 평가되는 시점에 상위 스코프가 정적으로 결정됩니다. 자바스크립트를 비롯한 대부분의 프로그래밍 언어는 &lt;strong&gt;렉시컬 스코프&lt;/strong&gt;를 따릅니다.&lt;/p&gt;&lt;p&gt;따라서, 자바스크립트는 함수를 어디서 정의했는지에 따라 상위 스코프를 결정하며, 함수 호출 위치는 상위 스코프 결정에 영향을 주지 않습니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 13_스코프(p.189 - 199)&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]JavaScript란 무엇일까?]]></title><description><![CDATA[자바스크립트의 역사 199…]]></description><link>https://lcy042000.github.io/what-java-script</link><guid isPermaLink="false">https://lcy042000.github.io/what-java-script</guid><category><![CDATA[WHAT]]></category><category><![CDATA[JavaScript]]></category><pubDate>Tue, 28 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;aside&gt;💡 모든 브라우저의 표준 프로그래밍 언어이자 현재 웹 애플리케이션 개발에서 빠질 수 없는 존재인 JavaScript에 대해 알아봅시다!&lt;/aside&gt;&lt;img src=&quot;https://redmonk.com/rstephens/files/2023/05/redmonk-language-rankings-jan-2023.jpg&quot; alt=&quot;지난 10년간 프로그래밍 언어 순위&quot;/&gt;&lt;h2&gt;자바스크립트의 역사&lt;/h2&gt;&lt;p&gt;1995년, 웹 페이지의 보조적인 기능을 수행하기 위해 브라우저에서 동작하는 경량 프로그래밍 언어 도입을 위해 자바스크립트가 개발되었습니다. 초기에는 각 브라우저 제조사에서 자체적으로 자바스크립트의 기능을 추가함으로써 브라우저에 따라 웹 페이지가 정상적으로 동작하지 않게 되는 &lt;strong&gt;크로스 브라우징 이슈&lt;/strong&gt;가 발생하게 됨을 뜻합니다.&lt;/p&gt;&lt;p&gt;따라서, 자바스크립트의 파편화를 방지하고 모든 브라우저에서 정상적으로 동작할 수 있는 표준화된 자바스크립트의 필요성이 대두되었습니다. 이를 위해, 비영리 표준화 기구인 ECMA 인터네셔널이 표준화를 요청하여 1997년 표준화된 자바스크립트 &lt;strong&gt;ECMAScript&lt;/strong&gt;가 발표되었습니다.&lt;/p&gt;&lt;h2&gt;자바스크립트의 성장&lt;/h2&gt;&lt;p&gt;초창기 자바스크립트는 웹 페이지의 보조적인 역할만을 수행하였습니다. 하지만 점차 기술들이 발전하며 자바스크립트의 활용은 늘어갔습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. Ajax(Asynchronous JavaScript and XML)&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Ajax는 서버와 브라우저가 &lt;strong&gt;비동기 방식&lt;/strong&gt;으로 데이터를 교환할 수 있는 통신 기능입니다. 이전에는 HTML 코드를 전달받아 렌더링하는 방식으로 동작했지만, 필요한 데이터만 전달받아 일부 부분만 렌더링하는 방식이 가능해졌습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. jQuery&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;jQuery는 조작하기 어려웠던 DOM(Document Object Model)을 쉽게 다룰 수 있게 해주는 라이브러리입니다. 또한, 크로스 브라우징 이슈도 해결할 수 있었습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3. V8 자바스크립트 엔진&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;웹 프로그래밍 언어로서 가능성이 확인된 자바스크립트의 사용이 늘면서 더욱 발전된 자바스크립트 엔진이 요구되었습니다. 이로 인해, 2008년 구글은 V8 자바스크립트 엔진을 선보였고 이는 자바스크립트가 웹 애플리케이션 프로그래밍 언어로 정착하게 될 수 있는 계기가 되었습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4. Node.js&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Node.js는 구글 V8 자바스크립트 엔진으로 빌드된 자바스크립트 런타임 환경입니다. 브라우저의 자바스크립트 엔진에서만 동작하던 자바스크립트를 브라우저 이외의 환경에서도 동작할 수 있도록 자바스크립트 엔진을 브라우저에서 독립시킨 실행 환경입니다. Node.js는 &lt;strong&gt;비동기 입출력&lt;/strong&gt;을 지원하며 &lt;strong&gt;단일 스레드 이벤트 루프 기반&lt;/strong&gt;으로 동작하여 요청 처리 성능이 우수합니다. Node.js로 인해 프론트엔드 개발에서만 사용하던 자바스크립트를 백엔드 개발에도 활용할 수 있게 되었습니다. 그 결과, 자바스크립트는 크로스 플랫폼을 위한 언어로 주목받게 되었습니다.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5. SPA 프레임워크&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;현재의 웹 시스템은 뛰어난 성능과 사용자 경험을 제공해야 하는 것이 필수가 되었고, 이는 개발 복잡도를 상승시켰습니다. 이전과 달리 복잡해진 개발 과정을 수행하기 위해 많은 프레임워크들이 등장했고, 그 중 &lt;strong&gt;CBD(Component based development)방법론&lt;/strong&gt;을 기반으로 하는 &lt;strong&gt;SPA(Single Page Application)&lt;/strong&gt;가 대중화되어 React, Vue, Angular 등이 많은 사랑을 받고 있습니다.&lt;/p&gt;&lt;h2&gt;자바스크립트와 ECMAScript&lt;/h2&gt;&lt;p&gt;ECMAScript는 자바스크립트의 표준 사양으로 핵심 문법을 규정합니다. 브라우저 제조사들은 이를 준수하여 브라우저에 내장되는 자바스크립트 엔진을 구현합니다. 기본 골조를 이루는 ECMAScript를 기반으로 브라우저 제조사들이 별도로 Web API를 지원합니다.&lt;/p&gt;&lt;h2&gt;자바스크립트의 특징&lt;/h2&gt;&lt;p&gt;자바스크립트는 웹 브라우저에서 동작하는 유일한 프로그래밍 언어입니다. 다른 언어들과 마찬가지로 기존의 프로그래밍 언어로부터 많은 영향을 받아 기본 문법은 C언어, 자바와 유사하고 Self에서는 프로토타입 기반 상속, Scheme에서는 일급 함수의 개념을 차용했습니다. 자바스크립트는 개발자가 별도 컴파일 작업을 하지 않는 &lt;strong&gt;인터프리터 언어&lt;/strong&gt;로 대부분의 자바스크립트 엔진은 인터프리터와 컴파일러의 장점을 결합하여 처리 속도가 느린 인터프리터의 단점을 해소했습니다. 또한, 자바스크립트는 &lt;strong&gt;명령형&lt;/strong&gt;, &lt;strong&gt;함수형&lt;/strong&gt;, &lt;strong&gt;프로토타입 기반 객체지향 프로그래밍&lt;/strong&gt;을 지원하는 &lt;strong&gt;멀티 패러다임 프로그래밍 언어&lt;/strong&gt;입니다.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt;참고&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;이웅모, ⌈모던 자바스크립트 - Deep Dive⌋, 2020, 02_자바스크립트란?&lt;/p&gt;&lt;p&gt;JS 이미지 / &lt;a href=&quot;https://github.com/voodootikigod/logo.js&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://github.com/voodootikigod/logo.js&lt;/a&gt;&lt;/p&gt;&lt;p&gt;프로그래밍 언어 순위 이미지 / &lt;a href=&quot;https://redmonk.com/rstephens/2023/05/16/top20-jan2023/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://redmonk.com/rstephens/2023/05/16/top20-jan2023/&lt;/a&gt;&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHAT]React란 무엇일까?]]></title><description><![CDATA[들어가기에 앞서… 웹 개발에 관심이 있다면, 'React'라는 단어를 한 번쯤 들어봤을 것입니다. 이 자바스크립트 라이브러리는 웹 개발의 세계에서 큰 중요성을 차지하고 있습니다. 그렇다면 이 React…]]></description><link>https://lcy042000.github.io/what-react</link><guid isPermaLink="false">https://lcy042000.github.io/what-react</guid><category><![CDATA[WHAT]]></category><category><![CDATA[React]]></category><pubDate>Sun, 26 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;들어가기에 앞서…&lt;/h2&gt;&lt;p&gt;웹 개발에 관심이 있다면, &amp;#x27;React&amp;#x27;라는 단어를 한 번쯤 들어봤을 것입니다. 이 자바스크립트 라이브러리는 웹 개발의 세계에서 큰 중요성을 차지하고 있습니다. 그렇다면 이 React는 왜 만들어졌고 어떤 역할을 하는지 알아보도록 하겠습니다.&lt;/p&gt;&lt;h2&gt;React의 탄생 배경&lt;/h2&gt;&lt;p&gt;과거 웹 서비스는 주로 서버에서 HTML을 생성하여 클라이언트에게 제공하는 방식을 사용했습니다. 이는 서비스 제공자가 텍스트 기반의 콘텐츠만 제공하는 단방향 소통 방식이었습니다.&lt;/p&gt;&lt;p&gt;하지만, 디지털 플랫폼의 발전과 함께 사용자의 인터랙션에 따른 동적인 업데이트가 필요해졌고, 이를 위해 AJAX와 같은 기술이 등장하였습니다. 이를 기반으로 한 라이브러리인 jQuery 등이 널리 사용되었습니다.&lt;/p&gt;&lt;p&gt;그러나 사용량의 증가와 이로 인한 데이터의 증가로 웹 애플리케이션의 복잡성이 증가하면서 상태 관리가 점점 어려워졌습니다. 방대한 크기의 서비스를 제공하던 페이스북은 시스템을 유지 보수하기 위해 기존과 다른 방법이 필요했습니다. 이를 해결하기 위해 페이스북의 개발팀은 컴포넌트 기반의 개발 방식을 도입하였고, 이로써 React가 탄생하게 되었습니다.&lt;/p&gt;&lt;h2&gt;React란?&lt;/h2&gt;&lt;p&gt;React는 사용자 인터페이스를 구축하기 위한 JavaScript 라이브러리입니다. React는 싱글 페이지 애플리케이션(SPA)를 구현하며, 서버로부터 하나의 페이지만 받아오지만 라우팅을 통해 여러 화면을 제공합니다. 이는 규모가 큰 시스템에서 데이터 전송 과부화와 같은 성능 문제를 해결 가능하다는 이점을 갖고 있습니다.&lt;/p&gt;&lt;p&gt;React는 웹 페이지의 각 요소를 독립적인 컴포넌트로 취급하여, 이 컴포넌트들을 조합해 전체 애플리케이션을 구성합니다. 이는 각 컴포넌트가 자신의 상태를 관리하고, 다른 컴포넌트와 독립적으로 렌더링될 수 있게 함으로써, 코드의 재사용성을 높이고, 유지보수를 용이하게 합니다.&lt;/p&gt;&lt;p&gt;React의 또 다른 핵심 특징은 Virtual DOM입니다. React는 실제 DOM 대신 Virtual DOM을 사용하여, 변경 사항을 먼저 가상의 DOM에 적용한 후, 실제 DOM에 최소한의 변화만을 반영합니다. 이로 인해 React는 빠른 렌더링 성능을 보장합니다.&lt;/p&gt;&lt;h2&gt;마치며…&lt;/h2&gt;&lt;p&gt;React는 현재 웹 개발에서 주요한 도구로 사용되며, 다양한 기술과 결합하여 다양한 모습을 보여주고 있습니다. 지금까지 Front-end 개발에서 많은 사랑을 받고 있는 React가 어떻게 탄생하였고 무엇인지에 대해 알아보았습니다.&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[[WHY]React를 왜 써야할까?]]></title><description><![CDATA[들어가기에 앞서… React는 프론트엔드 프레임워크에서 가장 인기 있는 프레임워크입니다. HTML, CSS, JS 등 기본적인 웹 기술을 익힌 후, 많은 프론트엔드 개발자들이 React…]]></description><link>https://lcy042000.github.io/why-react</link><guid isPermaLink="false">https://lcy042000.github.io/why-react</guid><category><![CDATA[WHY]]></category><category><![CDATA[React]]></category><pubDate>Fri, 24 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;들어가기에 앞서…&lt;/h2&gt;&lt;p&gt;React는 프론트엔드 프레임워크에서 가장 인기 있는 프레임워크입니다. HTML, CSS, JS 등 기본적인 웹 기술을 익힌 후, 많은 프론트엔드 개발자들이 React를 학습합니다.&lt;/p&gt;&lt;p&gt;저 역시 웹 프론트엔드 개발을 위한 학습 경로로 이러한 순서를 따랐습니다. 그러나 React를 배우기 시작하면서, 왜 이런 프레임워크가 필요한지, 그리고 React의 특별함이 무엇인지에 대한 궁금증이 생겼습니다. 이 글을 통해 그러한 의문을 해결하고, React의 중요성을 이해하는 데 도움이 되고자 합니다.&lt;/p&gt;&lt;h2&gt;React란?&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://lcy042000.github.io/what-react&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://lcy042000.github.io/what-react&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Front-end Framework는 왜 쓰는 걸까?&lt;/h2&gt;&lt;p&gt;프로그래밍에서 프레임워크는 복잡한 문제를 해결하거나 서술하는 데 사용되는 뼈대나 체계를 말합니다. 프레임워크는 개발자가 반복적인 기본 작업을 수행하는 데 들이는 시간을 줄여주며, 안정성이 검증된 코드를 제공하여 개발 과정을 단순화합니다.&lt;/p&gt;&lt;p&gt;프론트엔드 개발에서도 이러한 프레임워크의 필요성은 큽니다. 프론트엔드 프레임워크를 사용하면, UI 구성, 상태 관리, 라우팅 등의 복잡한 문제를 해결하는 데 도움이 됩니다. 또한, 보안에 관련된 복잡한 이슈를 프레임워크가 대신 처리해 주므로, 개발자는 기능 개발에 집중할 수 있습니다.&lt;/p&gt;&lt;h2&gt;React 사용의 이점&lt;/h2&gt;&lt;h3&gt;1. 컴포넌트 기반 구조&lt;/h3&gt;&lt;p&gt;React는 컴포넌트 기반의 라이브러리입니다. 이는 코드를 작은 조각, 즉 컴포넌트로 나누어 개발하게 함으로써 코드의 재사용성을 높이고, 유지 보수를 용이하게 합니다. 동일한 기능을 하는 컴포넌트를 재사용함으로써 개발 시간을 단축할 수 있습니다.&lt;/p&gt;&lt;h3&gt;2. Virtual Dom&lt;/h3&gt;&lt;p&gt;React는 실제 DOM(Document Object Model) 대신 가상의 DOM을 사용하여 성능을 향상시킵니다. 일반적인 상황에서는 변경 사항 발생 시 일반 DOM에 접근하여 전체 DOM을 변경합니다. 하지만 Virtual DOM을 사용하면 변경 사항을 먼저 가상의 DOM에 적용한 후, 최종적으로 변경된 부분만 실제 DOM에 반영함으로써 불필요한 렌더링을 줄입니다. 이를 통해 브라우저의 연산 과정을 최소화하고 사용자의 자원 사용을 줄일 수 있습니다. 이는 특히 동적인 웹 애플리케이션에서 중요한 성능 향상을 가져옵니다.&lt;/p&gt;&lt;h3&gt;3. JSX&lt;/h3&gt;&lt;p&gt;JSX는 HTML과 Javascript의 결합으로 확장된 문법입니다. ****이를 통해 렌더링 로직과 UI 로직이 연결되어, 각각의 로직이 분리된 파일에 존재하는 것이 아닌 하나의 컴포넌트 안에서 연결되어 각 로직을 수행합니다. 이는 더욱 직관적인 코드 작성이 가능하도록 합니다. JSX는 또한 렌더링 전 문자열로 변환하여 작성된 내용만 주입한다는 특징을 갖고 있습니다. 이를 통해 XSS(cross-site-scripting) 공격을 방지하는 데 도움이 됩니다.&lt;/p&gt;&lt;h3&gt;4. 강력한 생태계&lt;/h3&gt;&lt;p&gt;가장 인기 있는 Frontend framework인 React는 강력한 생태계를 가지고 있습니다. 또한, 큰 커뮤니티와 다양한 라이브러리들이 존재하여 개발자가 사용하고자 하는 것을 선택하여 적용할 수 있습니다. 대형 IT 기업인 Facebook에서 만든 React로 인해 전문가들의 충분한 지원을 받음으로써 개발자들은 다양한 도구와 자원을 활용할 수 있습니다.&lt;/p&gt;&lt;h3&gt;5. 단방향 데이터 흐름&lt;/h3&gt;&lt;p&gt;React는 부모 컴포넌트에서 자식 컴포넌트로만 데이터를 전달합니다. 이러한 단방향 데이터 흐름은 데이터의 변화를 예측 가능하게 하고, 디버깅에 용이하다는 장점을 가지고 있습니다. 또한, 애플리케이션 내에서 상태 변화의 추적이 편리하고 복잡한 데이터 관리 문제를 해결할 수 있습니다.&lt;/p&gt;&lt;h2&gt;결론&lt;/h2&gt;&lt;p&gt;이 글을 통해 React의 중요성과 그 이유를 알아보았습니다. React의 특징인 컴포넌트 기반 구조, Virtual DOM, JSX, 강력한 생태계, 단방향 데이터 흐름 등은 프론트엔드 개발에 있어 큰 이점을 제공합니다. 이러한 React의 특징을 활용한다면, 더 나은 개발 경험을 가질 수 있을 것입니다.&lt;/p&gt;</content:encoded><author>8410294@naver.com</author></item><item><title><![CDATA[소개글]]></title><description><![CDATA[👨‍💻 Frontend Engineer, Web Developer 😀  세상에 편리한 시스템 제공을 목표로 하는 개발자입니다! 😃 👦 Profile 👶  2000년 01월 04일 출생 🏫  전북제일고등학교 졸업 (2015.0…]]></description><link>https://lcy042000.github.io/introduce-post</link><guid isPermaLink="false">https://lcy042000.github.io/introduce-post</guid><category><![CDATA[introduce]]></category><category><![CDATA[aboutme]]></category><pubDate>Tue, 21 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;&lt;span role=&quot;img&quot; aria-label=&quot;man technologist&quot;&gt;👨‍💻&lt;/span&gt; Frontend Engineer, Web Developer&lt;/h2&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;grinning face&quot;&gt;😀&lt;/span&gt;  세상에 편리한 시스템 제공을 목표로 하는 개발자입니다! &lt;span role=&quot;img&quot; aria-label=&quot;grinning face with big eyes&quot;&gt;😃&lt;/span&gt;&lt;/p&gt;&lt;h2&gt;&lt;span role=&quot;img&quot; aria-label=&quot;boy&quot;&gt;👦&lt;/span&gt; Profile&lt;/h2&gt;&lt;hr/&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;baby&quot;&gt;👶&lt;/span&gt;  2000년 01월 04일 출생&lt;/p&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;school&quot;&gt;🏫&lt;/span&gt;  전북제일고등학교 졸업 (2015.03. ~ 2018.02.)&lt;/p&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;man student&quot;&gt;👨‍🎓&lt;/span&gt;  금오공과대학교 컴퓨터소프트웨어공학과 재학 중 (2018.03 ~ )&lt;/p&gt;&lt;h2&gt;&lt;span role=&quot;img&quot; aria-label=&quot;light bulb&quot;&gt;💡&lt;/span&gt; Contact&lt;/h2&gt;&lt;hr/&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;open mailbox with lowered flag&quot;&gt;📭&lt;/span&gt;  &lt;a href=&quot;mailto:8410294@naver.com&quot;&gt;8410294@naver.com&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;telephone receiver&quot;&gt;📞&lt;/span&gt;  010-6223-0295&lt;/p&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;blue book&quot;&gt;📘&lt;/span&gt;  &lt;a href=&quot;https://www.linkedin.com/in/%EC%B6%A9%EC%97%BD-%EC%9D%B4-28a154283/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Linkedin Link&lt;/a&gt; &lt;/p&gt;&lt;h2&gt;🎞 Career&lt;/h2&gt;&lt;hr/&gt;&lt;ul&gt;&lt;li&gt;신호처리 및 지능형네트워크 연구실 소속 학부 연구생(2022.03 ~ )&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;span role=&quot;img&quot; aria-label=&quot;magic wand&quot;&gt;🪄&lt;/span&gt;Intro.&lt;/h3&gt;&lt;hr/&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;light bulb&quot;&gt;💡&lt;/span&gt; 일을 시작하면 스스로 마무리하기 위해 노력합니다. 문제가 발생하더라도 끝까지 해결 방안을 찾기 위해 노력합니다.&lt;/p&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;question mark&quot;&gt;❓&lt;/span&gt; 부족한 부분을 채우기 위해 나에게 필요한 것이 무엇인지 매일 질문합니다.&lt;/p&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;keyboard&quot;&gt;⌨️&lt;/span&gt; 사용자가 편리한 시스템 개발을 위해 노력합니다.&lt;/p&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;motorway&quot;&gt;🛣️&lt;/span&gt; 읽기 쉽고 효율적인 코드가 좋은 코드라는 가치관 아래 프로그래밍을 수행합니다.&lt;/p&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;alarm clock&quot;&gt;⏰&lt;/span&gt; 매일 계획을 세워 지키려고 노력합니다. 매일 밤 내일 할 일을 정리하여 계획합니다.&lt;/p&gt;&lt;p&gt;&lt;span role=&quot;img&quot; aria-label=&quot;man biking (skin tone 6)&quot;&gt;🚴🏿‍♂️&lt;/span&gt; 매일 두 시간 운동을 통해 자신을 관리합니다.&lt;/p&gt;&lt;h2&gt;🗃 Github&lt;/h2&gt;&lt;hr/&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/lcy042000&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;lcy042000 - Overview&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;🪪Certificate&lt;/h2&gt;&lt;hr/&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;OPIc&lt;/strong&gt; - IM1&lt;/li&gt;&lt;li&gt;&lt;strong&gt;정보처리기사&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;&lt;span role=&quot;img&quot; aria-label=&quot;hammer and pick&quot;&gt;⚒️&lt;/span&gt; Skills&lt;/h2&gt;&lt;hr/&gt;&lt;p&gt;&lt;strong&gt; Language&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;JavaScript / TypeScript / Java&lt;/p&gt;&lt;p&gt;&lt;strong&gt; Framework &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;React.js&lt;/p&gt;&lt;p&gt;&lt;strong&gt; Library &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;React-Query / Recoil / Three,js / Nivo Chart / TailwondCSS / Chakra UI&lt;/p&gt;&lt;p&gt;&lt;strong&gt; Tool &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Git / Figma&lt;/p&gt;&lt;h2&gt;⚒ Personal &amp;amp; Team Project&lt;/h2&gt;&lt;hr/&gt;&lt;h3&gt;&lt;strong&gt;SE Board 리뉴얼&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;금오공과대학교 컴퓨터소프트웨어공학과 커뮤니티&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;http://www.seboard.site&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;↗SE Board(커뮤니티 링크)&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;기간&lt;/strong&gt; 2023.01~&lt;/p&gt;&lt;p&gt;&lt;strong&gt;기술스택&lt;/strong&gt; &lt;a href=&quot;https://www.typescriptlang.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TypeScript&lt;/a&gt;, &lt;a href=&quot;https://ko.legacy.reactjs.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;React.js,&lt;/a&gt; &lt;a href=&quot;https://chakra-ui.com/?ref=retool-blog&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Chakra UI,&lt;/a&gt; &lt;a href=&quot;https://tanstack.com/query/v3/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;React-Query,&lt;/a&gt; &lt;a href=&quot;https://ckeditor.com/ckeditor-5/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;CKEditor5,&lt;/a&gt; &lt;a href=&quot;https://recoiljs.org/ko/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Recoil,&lt;/a&gt; &lt;a href=&quot;https://www.figma.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Figma&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/kit-SE-Project/SE-FE&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://github.com/kit-SE-Project/SE-FE&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;참여 파트&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Frontend 개발&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;특징&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;TypeScript를 사용한 구현으로 &lt;strong&gt;코드의 재사용성&lt;/strong&gt;과 &lt;strong&gt;효율성&lt;/strong&gt; 향상&lt;/li&gt;&lt;li&gt;React-Query의 캐싱을 활용한 &lt;strong&gt;데이터 관리&lt;/strong&gt; 및 &lt;strong&gt;성능&lt;/strong&gt; 향상&lt;/li&gt;&lt;li&gt;WYSIWYG 에디터인 CKEditor5 사용&lt;/li&gt;&lt;li&gt;스타일 기반 Chakra UI를 통한 유연성&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;개발 기능&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;UI 설계 및 디자인&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;커뮤니티 기능&lt;/p&gt;&lt;ul&gt;&lt;li&gt;사용자 권한별 게시글 조회&lt;/li&gt;&lt;li&gt;댓글 CRUD&lt;/li&gt;&lt;li&gt;게시글 작성 및 수정 기능&lt;/li&gt;&lt;li&gt;게시글 및 댓글 스크랩, 공유, 신고 기능&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;관리자 기능&lt;/p&gt;&lt;ul&gt;&lt;li&gt;커뮤니티 게시판(카테고리) 관리&lt;/li&gt;&lt;li&gt;관리자 메뉴 권한 설정 기능&lt;/li&gt;&lt;li&gt;회원 관리&lt;/li&gt;&lt;li&gt;댓글 관리&lt;/li&gt;&lt;li&gt;휴지통&lt;/li&gt;&lt;li&gt;일반 정책 관리&lt;/li&gt;&lt;li&gt;메인 페이지 관리(배너, 상단바 메뉴 설정)&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr/&gt;&lt;h3&gt;&lt;strong&gt;햄버거 가게 주문 및 배달 시스템&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;고급 웹 프로그래밍 교과목 프로젝트로 햄버거 가게의 주문 및 배달 시스템 개발&lt;/p&gt;&lt;p&gt;&lt;strong&gt;기간&lt;/strong&gt; 2023.05 ~ 2023.06&lt;/p&gt;&lt;p&gt;&lt;strong&gt;기술스택&lt;/strong&gt; &lt;a href=&quot;https://www.typescriptlang.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TypeScript&lt;/a&gt;, &lt;a href=&quot;https://ko.legacy.reactjs.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;React.js,&lt;/a&gt; &lt;a href=&quot;https://chakra-ui.com/?ref=retool-blog&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Chakra UI,&lt;/a&gt; &lt;a href=&quot;https://tanstack.com/query/v3/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;React-Query,&lt;/a&gt; &lt;a href=&quot;https://nivo.rocks/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nivo chart,&lt;/a&gt; &lt;a href=&quot;https://www.figma.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Figma&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/WebProgramming-Project/Advanced_WP-FE&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://github.com/WebProgramming-Project/Advanced_WP-FE&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;참여 파트&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Frontend Engineer&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;특징&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;WebRTC를 이용한 &lt;strong&gt;실시간 주문 현황 조회&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;OAuth를 통한 &lt;strong&gt;간편한 인증&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;개발 기능&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;UI 설계 및 디자인&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;시스템 UI 템플릿 구현&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;메뉴 상세 정보&lt;/p&gt;&lt;ul&gt;&lt;li&gt;햄버거 상세 정보 조회&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;장바구니&lt;/p&gt;&lt;ul&gt;&lt;li&gt;고객의 상품 장바구니 기능&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;OAuth 인증 시스템&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Google OAuth를 이용한 회원 가입 및 로그인 기능&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;주문 현황&lt;/p&gt;&lt;ul&gt;&lt;li&gt;고객 과거 주문 내역 조회&lt;/li&gt;&lt;li&gt;주문한 상품의 현재 상태를 WebRTC를 이용하여 주문 중/배달 중/배달 완료 조회 기능&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr/&gt;&lt;h3&gt;&lt;strong&gt;미래금속 스마트 팩토리 시스템&lt;/strong&gt;&lt;/h3&gt;&lt;p&gt;산합협력 프로젝트인 지역 알루미늄 빌렛 생산 기업의 스마트 팩토리 시스템 구축 프로젝트에 학부 연구생으로 참여&lt;/p&gt;&lt;p&gt;&lt;strong&gt;기간&lt;/strong&gt; 2022.07 ~ 2022.12&lt;/p&gt;&lt;p&gt;&lt;strong&gt;기술스택&lt;/strong&gt; JavaScript, &lt;a href=&quot;https://ko.legacy.reactjs.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;React.js&lt;/a&gt;, &lt;a href=&quot;https://tailwindcss.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Tailwind CSS&lt;/a&gt;, &lt;a href=&quot;https://nivo.rocks/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nivo chart&lt;/a&gt;, &lt;a href=&quot;https://threejs.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;three.js&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;참여 파트&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Frontend Engineer&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;특징&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;3D 콘텐츠&lt;/strong&gt; 표현을 위한 Three.js 적용&lt;/li&gt;&lt;li&gt;nivo 라이브러리를 사용하여 &lt;strong&gt;데이터 차트 그래프&lt;/strong&gt; 구현&lt;/li&gt;&lt;li&gt;TailwindCSS를 통한 &lt;strong&gt;일관된 디자인&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;개발 기능&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;JWT 토큰을 이용한 로그인 &amp;amp; 로그아웃&lt;/li&gt;&lt;li&gt;통계&lt;ul&gt;&lt;li&gt;서버로부터 공정 과정에 발생한 데이터 조회 기능&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;3D 대시보드&lt;ul&gt;&lt;li&gt;WebGL을 이용하여 공장의 모형 3D 콘텐츠 구현&lt;/li&gt;&lt;li&gt;공정 과정 데이터와 날씨 데이터 상관 관계 전달 기능&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;관리자 기능&lt;ul&gt;&lt;li&gt;일지 작성 시 필요한 요소 관리&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr/&gt;&lt;h1&gt;&lt;span role=&quot;img&quot; aria-label=&quot;grinning face with smiling eyes&quot;&gt;😄&lt;/span&gt; 감사합니다.&lt;/h1&gt;</content:encoded><author>8410294@naver.com</author></item></channel></rss>