<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Web Club</title>
    <link>https://webclub.tistory.com/</link>
    <description>변화는 과거와의 이별로부터 시작된다 ..</description>
    <language>ko</language>
    <pubDate>Tue, 14 Apr 2026 13:34:03 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>jaiyah</managingEditor>
    <image>
      <title>Web Club</title>
      <url>https://tistory1.daumcdn.net/tistory/1830004/attach/ddde7e995aaf4ec69f5b4fd9645a9a56</url>
      <link>https://webclub.tistory.com</link>
    </image>
    <item>
      <title>해체할당(구조분해할당, 디스트럭쳐링)</title>
      <link>https://webclub.tistory.com/651</link>
      <description>    &lt;p&gt;&lt;mark&gt;이 글은 &lt;a href=&quot;https://www.inflearn.com/course/ecmascript-6-flow&quot; target=&quot;_blank&quot;&gt;[인프런] Javascript ES6+ 제대로 알아보기 - 초급(정재남)&lt;/a&gt;를 토대로 작성되었음을 알려드립니다.&lt;/mark&gt;&lt;/p&gt;
    &lt;p&gt;&lt;br&gt;&lt;/p&gt;

    &lt;p&gt;&lt;kbd&gt;destructuring assignment&lt;/kbd&gt;는 한 마디로 정의하기 어렵다고 합니다. &lt;br&gt;
        이 &lt;a href=&quot;https://groups.google.com/forum/#!topic/clojure-kr/g34ctSr2kFc&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;용어에 대한 번역&lt;/a&gt;이 여전히 뜨거운 감자로 의견이 분분한 가운데
        구조분해 할당란 용어에 무게가 실리고 있지만 책마다 제각기 다른 용어들을 사용하고 있기 때문에 유사한 용어들로 쓰이고 있다라는 정도만 숙지하고  의사소통하는 데에 유사한 용어를 사용하면 크게 문제될 것은 없을 것입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;h2 class=&quot;hh&quot;&gt;destructuring assignment&lt;/h2&gt;
    &lt;p&gt;여기서는 위에서 언급한 여러 용어들 중에 혼동을 줄이고자 &amp;nbsp;&lt;kbd&gt;해체할당&lt;/kbd&gt;이란 용어를 사용해 이 문법에 대해 살펴보도록 하겠습니다. &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning info&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt;해체 할당이란?&lt;/p&gt;
        &lt;p&gt;&lt;kbd&gt;해체 할당&lt;/kbd&gt;이란 말 그대로 &amp;nbsp;&lt;mark&gt;해체하였다가 해체했던 것을 모두 할당을 한다&lt;/mark&gt;란 의미입니다.&lt;/p&gt;
        &lt;p&gt;위 용어 중에 &amp;nbsp;&lt;kbd&gt;구조분해할당&lt;/kbd&gt;도 역시 구조를 분해하였다가 분해했던 것을 할당한다란 뜻이기 때문에 &amp;nbsp;&lt;kbd&gt;해체할당&lt;/kbd&gt;과 의미적으로 일맥상통한다고 할 수 있습니다.&lt;/p&gt;
    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;배열 해체할당&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;위에서 언급한 의미를 코드를 통해 알아보도록 하겠습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;line-numbers&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var colors = ['red', 'white', 'orange'];
var first = colors[0];
var second = colors[1];
var third = colors[2];

console.log(first, second, third)&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var colors = ['red', 'white', 'orange'];
        var first = colors[0];
        var second = colors[1];
        var third = colors[2];

        console.log(first, second, third)
    &lt;/script&gt;--&gt;

    &lt;p class=&quot;mt30 point-r&quot;&gt;기존 ES5 에서 배열 요소 하나하나를 위와 같이 접근하여 사용했다면 ES6 는 아래와 같이 할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var colors = ['red', 'white', 'orange'];
var [ first, second, third ] = colors;

console.log(first, second, third);&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 var colors = ['red', 'white', 'orange'];
		 var [ first, second, third ] = colors;
 
		 console.log(first, second, third);
	 &lt;/script&gt;--&gt;

    &lt;p&gt;
        위 예제를 분석해 보자면 &amp;nbsp;&lt;code&gt;colors&lt;/code&gt; 의 내용들을 모두 펼쳐서(해체) &amp;nbsp;&lt;kbd&gt;대괄호([ ])&lt;/kbd&gt; 안의 각각의 변수 하나하나에 다시 할당한다란 의미입니다.
    &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var colors = ['red', 'white', 'orange'];
const [ first, second, third ] = colors;

console.log(first, second, third);

first = 10; // Assignment to constant variable.
&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var colors = ['red', 'white', 'orange'];
        const [ first, second, third ] = colors;

        console.log(first, second, third);

        first = 10;
    &lt;/script&gt;--&gt;

    &lt;p&gt;
        로그를 확인해 보면 &amp;nbsp;&lt;code&gt;const&lt;/code&gt; 또는 &amp;nbsp;&lt;code&gt;let&lt;/code&gt; 으로 변수를 선언한 방식에 따라서 대괄호 안에 있는 변수들이 영향을 받는 것입니다.
        &lt;br&gt;
        즉, 위 예제의 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt; 코드와 해체할당 코드는 완전히 동일한 문장이라고 할 수 있습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;발췌하기&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;해체할당의 장점은 &amp;nbsp;&lt;kbd&gt;원하는 것만 할당&lt;/kbd&gt;할 수 있다는 것입니다.&lt;/p&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var colors = ['red', 'white', 'orange'];
let [ , second ] = colors;
let [ , , third ] = colors;

console.log(second);
console.log(third);

let [ first ] = ['red', 'white', 'orange'];
console.log( first );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var colors = ['red', 'white', 'orange'];
        let [ , second ] = colors;
        let [ , , third ] = colors;

        console.log(second);
        console.log(third);

        let [ first ] = ['red', 'white', 'orange'];
        console.log( first );
    &lt;/script&gt;--&gt;
    &lt;p&gt;우측에서 좌측 방향으로 펼쳐서 할당하는데 오른쪽에 있는 것들을 그대로 매칭해서 하나하나 할당하는 것이 &lt;kbd&gt;destructuring assignment&lt;/kbd&gt; 입니다.&lt;/p&gt;
    &lt;p class=&quot;mt30 point-r&quot;&gt;매칭할 대상이 없다면 undefined 가 할당된다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const colors = ['red', 'white', 'orange']
const [ , , third, fourth] = colors
console.log(third)&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;배열 해체할당 활용&lt;/p&gt;
    &lt;p class=&quot;mt20&quot;&gt;&lt;strong&gt;1) &amp;nbsp;&lt;kbd&gt;rest parameter&lt;/kbd&gt; 와의 연동&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const arr = [1, 2, 3, 4, 5];
const [ a, ...b ] = arr;
const [ , , ...c ] = arr;

console.log(a, b, c);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const arr = [1, 2, 3, 4, 5];
        const [ a, ...b ] = arr;
        const [ , , ...c ] = arr;

        console.log(a, b, c);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;&quot;&gt;&lt;strong&gt;2) &amp;nbsp;&lt;kbd&gt;default parameter&lt;/kbd&gt; 와의 연동&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const [a = 10, b = 20] = [undefined, 5];
console.log( a, b );&lt;/code&gt;&lt;/pre&gt;


    &lt;p&gt;위 코드를 풀이하자면 해체하여 할당하려고 하는데 &amp;nbsp;&lt;kbd&gt;a&lt;/kbd&gt; 에 값이 없으면 &amp;nbsp;&lt;kbd&gt;10&lt;/kbd&gt;으로 하고, &amp;nbsp;&lt;kbd&gt;b&lt;/kbd&gt;에 값이 없으면 &amp;nbsp;&lt;kbd&gt;20&lt;/kbd&gt; 으로 한다는 의미입니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language mt30&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; const [c, d = c * 2] = [5];
console.log( c, d );&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 const [c, d = c * 2] = [5];
		 console.log( c, d );
	 &lt;/script&gt;--&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const [e = f, f] = [undefined, 10];&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;

        const [e = f, f] = [undefined, 10];

    &lt;/script&gt;--&gt;
    &lt;p&gt;분석해 보면 &amp;nbsp;&lt;kbd&gt;e&lt;/kbd&gt; 에 해체할당하여 &amp;nbsp;&lt;code&gt;undefined&lt;/code&gt; 이기 때문에 &amp;nbsp;&lt;kbd&gt;default parameter&lt;/kbd&gt;로 호출이 되어 &amp;nbsp;&lt;kbd&gt;f&lt;/kbd&gt;
        를 보니 뒤에 선언한 &amp;nbsp;&lt;kbd&gt;f&lt;/kbd&gt; 를 가지고 할당하려고 하니 &amp;nbsp;&lt;kbd&gt;TDZ&lt;/kbd&gt; 영역에 걸려 에러가 발생하게 됩니다.
    &lt;/p&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;3) &amp;nbsp;다차원 배열에서의 동작&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const arr = [1, [2, [3, 4], 5], 6];
const [a, [b, [ , c], ], d] = arr;
const [e, [f], g] = [1, [2, [3, 4], 5], 6];

console.log(a, b, c, d);
console.log( e, f, g );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const arr = [1, [2, [3, 4], 5], 6];
        const [a, [b, [ , c], ], d] = arr;
        const [e, [f], g] = [1, [2, [3, 4], 5], 6];

        console.log(a, b, c, d);
        console.log( e, f, g );
    &lt;/script&gt;--&gt;

    &lt;p&gt;배열이 있는데 배열 안에 배열이 있고 또 그 안에 배열이 있는 다차원배열에서도 똑같이 매칭해 주면 위와 같이 추출되는 해체할당을 할 수 있습니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;4) &amp;nbsp;값 교환하기&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var a = 10;
var b = 20;
var temp = a;

a = b;
b = temp;

console.log(a, b)&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var a = 10;
        var b = 20;
        var temp = a;

        a = b;
        b = temp;

        console.log(a, b)
    &lt;/script&gt;--&gt;

    &lt;p&gt;기존에는 &amp;nbsp;&lt;kbd&gt;a&lt;/kbd&gt; 와 &amp;nbsp;&lt;kbd&gt;b&lt;/kbd&gt;의 값을 서로 바꾸고 싶을 경우(&lt;kbd&gt;예제에서 a = 20, b = 10&lt;/kbd&gt;)에 임시로 변수 하나를 만든 후 바꿔치기할 값 중에 하나를 저장해 놓고 할당하는 복잡한 과정이 필요했습니다.
    &lt;/p&gt;
    &lt;p class=&quot;mt30 point-r&quot;&gt;하지만 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt;에서는 간단하게 아래와 같이 할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let a = 10;
let b = 20;

[a, b] = [b, a];

console.log(a, b);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        let a = 10;
        let b = 20;

        [a, b] = [b, a];

        console.log(a, b);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;객체 해체할당&lt;/p&gt;
    &lt;p&gt;객체의 해체할당은 실무에서 다양하게 활용하고 자주 사용하기 때문에 무엇보다 중요합니다. &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;객체 해체할당 사용방법&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;1) &amp;nbsp;기본 : &lt;kbd&gt;{ 추출할 프로퍼티명 : 할당하고자 하는 변수명 }&lt;/kbd&gt;&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const sora = {
    name : '강소라',
    age : 29,
    gender : 'female'
};

const {
    name: n,
    age: a,
    gender: g
} = sora;

console.log(n, a, g); // 강소라 29 female&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 const sora = {
			 name : '강소라',
			 age : 29,
			 gender : 'female'
		 };
 
		 const {
			 name: n,
			 age: a,
			 gender: g
		 } = sora;
 
		 console.log(n, a, g);
	 &lt;/script&gt;--&gt;

    &lt;p&gt;
        앞서 살펴 본 &amp;nbsp;&lt;kbd&gt;배열 해체할당&lt;/kbd&gt;은 배열의 인덱스를 매칭시켜서 하나하나 변수명에 할당하는 형태였는데 객체에는 인덱스가 없는 대신에 그 역할을 &amp;nbsp;&lt;kbd&gt;key&lt;/kbd&gt;가 하는 것이므로
        &amp;nbsp;&lt;kbd&gt;key&lt;/kbd&gt;를 매칭시켜서 변수에 담는 것이 &amp;nbsp;&lt;kbd&gt;객체 해체할당&lt;/kbd&gt;입니다.
    &lt;/p&gt;
    &lt;p&gt;그래서 위 예제를 보면 &amp;nbsp;&lt;kbd&gt;n, a, g&lt;/kbd&gt;가 변수가 되고 &amp;nbsp;&lt;code&gt;name&lt;/code&gt;과 &amp;nbsp;&lt;code&gt;name&lt;/code&gt; 을 매칭시켜서 매칭된 &amp;nbsp;&lt;kbd&gt;'강소라'&lt;/kbd&gt;를
        &amp;nbsp;&lt;kbd&gt;n&lt;/kbd&gt; 에 할당하게 되는 형태입니다.&lt;/p&gt;
    &lt;p&gt;그리고 &amp;nbsp;&lt;code&gt;let&lt;/code&gt;으로 선언하면 내부의 모든 변수는 &amp;nbsp;&lt;code&gt;let&lt;/code&gt; 선언으로 &amp;nbsp;&lt;code&gt;const&lt;/code&gt;로 선언하면 모든 변수는
        &amp;nbsp;&lt;code&gt;const&lt;/code&gt; 선언으로 되는 것은 배열 객체할당에서&lt;br&gt; 알아본 내용과 동일합니다.&lt;/p&gt;


    &lt;p class=&quot;mt30 point-r&quot;&gt;배열 해체할당에서 &amp;nbsp;&lt;kbd&gt;발췌&lt;/kbd&gt;하는 방법보다 객체 해체할당이 더 간단합니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const sora = {
    name : '강소라',
    age : 29,
    gender : 'female'
};

const {
    gender: g,
    age: a
} = sora;

console.log( a, g );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const sora = {
            name : '강소라',
            age : 29,
            gender : 'female'
        };

        const {
            gender: g,
            age: a
        } = sora;

        console.log( a, g );
    &lt;/script&gt;--&gt;

    &lt;p&gt;객체 해체할당의 &amp;nbsp;&lt;kbd&gt;발췌&lt;/kbd&gt;는 순서도 지킬 필요없이 해체할당하고자 하는 대상만을 사용할 수 있기 때문에 배열 해체할당보다 편리한 측면이 있습니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;2) &amp;nbsp;할당할 변수명은 생략 가능하다. (property shorthand)&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const sora = {
    name : '강소라',
    age : 29,
    gender : 'female'
};

const {
    name : name,
    age : age,
    gender :gender
} = sora;

console.log(name, age, gender);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const sora = {
            name : '강소라',
            age : 29,
            gender : 'female'
        };

        const {
            name : name,
            age : age,
            gender :gender
        } = sora;

        console.log(name, age, gender);
    &lt;/script&gt;--&gt;

    &lt;p class=&quot;point-r&quot;&gt;위와 같은 코드를 프로퍼티를 축약형으로 변경하면 다음과 같습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const sora = {
    name : '강소라',
    age : 29,
    gender : 'female'
};

const {
    name,
    age,
    gender
} = sora;

console.log(name, age, gender);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const sora = {
            name : '강소라',
            age : 29,
            gender : 'female'
        };

        const {
            name,
            age,
            gender
        } = sora;

        console.log(name, age, gender);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;4) &amp;nbsp;중첩객체의 경우 - 접근자와 추출을 구분하는 것이 중요&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const loginInfo = {
    device: {
        createdAt: '2019-12-06T00:14:04+0000',
        deviceId: '0000000000004Vx',
        deviceType: 'desktop'
    },
    user: {
        createdAt: '2019-03-08T18:00:28+0000',
        email: 'power4ce@gmail.com',
        name: '김재희',
        nickname: 'jinsangsiki',
        phoneNumber: '010-4542-7077'
    }
};

const {
    device,
    user: {
        name,
        nickname,
        phoneNumber: phone
    }
} = loginInfo;

// user 는 변수선언이 되어있을까?
// phoneNumber 와 phone 중에 선언된 변수는 어느쪽일까?&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const loginInfo = {
            device: {
                createdAt: '2019-12-06T00:14:04+0000',
                deviceId: '0000000000004Vx',
                deviceType: 'desktop'
            },
            user: {
                createdAt: '2019-03-08T18:00:28+0000',
                email: 'power4ce@gmail.com',
                name: '김재희',
                nickname: 'jinsangsiki',
                phoneNumber: '010-4542-7077'
            }
        };

        const {
            device,
            user: {
                name,
                nickname,
                phoneNumber: phone
            }
        } = loginInfo;

        // user 는 변수선언이 되어있을까?
        // phoneNumber 와 phone 중에 선언된 변수는 어느쪽일까?

    &lt;/script&gt;--&gt;

    &lt;p&gt;위 예제에서 &amp;nbsp;&lt;kbd&gt;user&lt;/kbd&gt; 는 변순 선언이 아니라 접근만 했을 뿐입니다. &amp;nbsp; 즉, &amp;nbsp;&lt;kbd&gt;user&lt;/kbd&gt; 는 &lt;b&gt;접근자&lt;/b&gt;일 뿐입니다. &lt;br&gt;
        그리고 &amp;nbsp;&lt;kbd&gt;phoneNumber&lt;/kbd&gt; 는 접근자이고 &amp;nbsp;&lt;kbd&gt;phone&lt;/kbd&gt; 이 변수가 됩니다.
    &lt;/p&gt;


    &lt;p class=&quot;point-r mt30&quot;&gt;아래와 같이 사용할 일은 없겠지만 가능하다는 것을 보여주기 위한 예제입니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const loginInfo = {
    device: {
        createdAt: '2019-12-06T00:14:04+0000',
        deviceId: '0000000000004Vx',
        deviceType: 'desktop'
    },
    user: {
        createdAt: '2019-03-08T18:00:28+0000',
        email: 'power4ce@gmail.com',
        name: '김재희',
        nickname: 'jinsangsiki',
        phoneNumber: '010-4542-7077'
    }
};

const {
    device: {
        createdAt,
        deviceType
    },
    user: userInfo,
    user: {
        nickname,
    },
    user: {
        createdAt: userCreatedAt,
        email,
        name
    }
} = loginInfo;&lt;/code&gt;&lt;/pre&gt;
    &lt;!--&lt;script&gt;
        const loginInfo = {
            device: {
                createdAt: '2019-12-06T00:14:04+0000',
                deviceId: '0000000000004Vx',
                deviceType: 'desktop'
            },
            user: {
                createdAt: '2019-03-08T18:00:28+0000',
                email: 'power4ce@gmail.com',
                name: '김재희',
                nickname: 'jinsangsiki',
                phoneNumber: '010-4542-7077'
            }
        };

        const {
            device: {
                createdAt,
                deviceType
            },
            user: userInfo,
            user: {
                nickname,
            },
            user: {
                createdAt: userCreatedAt,
                email,
                name
            }
        } = loginInfo;
    &lt;/script&gt;--&gt;
    &lt;p&gt;위 예제는 중첩된 객체의 &lt;kbd&gt;key(접근자)&lt;/kbd&gt;를 여러번 작성하여 접근해 발췌할 수도 있다는 것을 보여주고 있습니다.&lt;/p&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;5) &amp;nbsp;&lt;kbd&gt;default parameter&lt;/kbd&gt; 와의 연동&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const phone = {
    name : 'iPhone',
    color : undefined
};

const {
    name: n,
    version: v = '8 edition',
    color: c = 'red'
} = phone;
console.log(n, v, c);

const {
    name,
    version = '11 Pro',
    color = 'space grey'
} = phone;
console.log(name, version, color);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const phone = {
            name : 'iPhone',
            color : undefined
        };

        const {
            name: n,
            version: v = '8 edition',
            color: c = 'red'
        } = phone;
        console.log(n, v, c);

        const {
            name,
            version = '11 Pro',
            color = 'space grey'
        } = phone;
        console.log(name, version, color);
    &lt;/script&gt;--&gt;

    &lt;p&gt;
        &lt;kbd&gt;name&lt;/kbd&gt; 에는 &amp;nbsp;&lt;kbd&gt;'iPhone'&lt;/kbd&gt; 값이 있으나 &amp;nbsp;&lt;kbd&gt;color&lt;/kbd&gt; 는 &amp;nbsp;&lt;kbd&gt;undefined&lt;/kbd&gt; 인 상태로 &lt;code&gt;version: v = '8 edition'&lt;/code&gt;
        &amp;nbsp;&lt;kbd&gt;version&lt;/kbd&gt; 과 &amp;nbsp;&lt;kbd&gt;version&lt;/kbd&gt; 을 매칭해서 값을 담으려고 할 때
        &amp;nbsp;&lt;kbd&gt;version&lt;/kbd&gt; 값이 없으면 &amp;nbsp;&lt;kbd&gt;'8 edition'&lt;/kbd&gt;을 할당해라라고 &amp;nbsp;&lt;kbd&gt;default parameter&lt;/kbd&gt;를 사용한 것입니다.
    &lt;/p&gt;
    &lt;p&gt;이러한 패턴은 서버에서 정보를 받는데 해당 정보가 있을 수도 있고 없을 수도 있는 정보(프로퍼티)가 있다면 &amp;nbsp;&lt;kbd&gt;default parameter&lt;/kbd&gt;를 이용하면 간단히 해결할 수 있습니다.
        다시 말해, 실무에서 통신할 때 유용하게 사용하실 수 있습니다.
    &lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;객체 해체할당의 사용예&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const getUrlParts = (url) =&gt; /^(https?):\/\/(\w{3,}\.[A-z.]{2,})(\/[a-z0-9]{1,}\/([a-z0-9\-.,]+))$/.exec(url);

console.log( getUrlParts( 'http://abc.com/es6/7-1.destructuring' ) );

const [ , protocol, host, , title] = getUrlParts('http://abc.com/es6/7-1.destructuring');
console.log(protocol, host, title);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const getUrlParts = (url) =&gt; /^(https?):\/\/(\w{3,}\.[A-z.]{2,})(\/[a-z0-9]{1,}\/([a-z0-9\-.,]+))$/.exec(url);

        console.log( getUrlParts( 'http://abc.com/es6/7-1.destructuring' ) );

        const [ , protocol, host, , title] = getUrlParts('http://abc.com/es6/7-1.destructuring');
        console.log(protocol, host, title);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;다음은 함수에 인자를 넘겨서 넘긴 정보를 객체 해체할당을 하여 받아오는 형태로 아래와 같이 다양하게 활용될 수 있습니다.&lt;/p&gt;
    &lt;p&gt;&lt;strong class=&quot;point-r&quot;&gt;Step #1&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const getArea = (info) =&gt; {
    const {width, height} = info; // 함수 내부에서 추출(발췌)하고 있음
    return width * height;
};

const result = getArea( {width: 10, height: 50} );
console.log( result );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const getArea = (info) =&gt; {
            const {width, height} = info; // 함수 내부에서 추출(발췌)하고 있음
            return width * height;
        };

        const result = getArea( {width: 10, height: 50} );
        console.log( result );
    &lt;/script&gt;--&gt;

    &lt;p class=&quot;mt30&quot;&gt;&lt;strong class=&quot;point-r&quot;&gt;Step #2&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const getArea2 = ({width, height}) =&gt; { // 함수 파라미터에서 추출함
    return width * height;
};

const result2 = getArea2( {width: 20, height: 60} );
console.log( result2 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const getArea2 = ({width, height}) =&gt; { // 함수 파라미터에서 추출함
            return width * height;
        };

        const result2 = getArea2( {width: 20, height: 60} );
        console.log( result2 );
    &lt;/script&gt;--&gt;

    &lt;p class=&quot;&quot;&gt;만약에 인자가 넘어오지 않을 경우를 대비한다면 아래와 같이 &amp;nbsp;&lt;kbd&gt;default parameter&lt;/kbd&gt; 이용할 수 있습니다.&lt;/p&gt;
    &lt;p class=&quot;mt30&quot;&gt;&lt;strong class=&quot;point-r&quot;&gt;Step #3&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// 인자가 넘어오지 않을 경우에 대비하여 default parameter 정의
const getArea3 = ({width, height} = { width:0, height: 0 }) =&gt; {
    return width * height;
};

const result3 = getArea3();
console.log( result3 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 // 인자가 넘어오지 않을 경우에 대비하여 default parameter 정의
		 const getArea3 = ({width, height} = { width:0, height: 0 }) =&gt; {
			 return width * height;
		 };
 
		 const result3 = getArea3();
		 console.log( result3 );
	 &lt;/script&gt;--&gt;

    &lt;p&gt;&lt;kbd&gt;Step #3&lt;/kbd&gt; 을 좀더 줄여본다면 아래와 같이 정의할 수 있습니다.&lt;/p&gt;
    &lt;p class=&quot;mt30 point-r&quot;&gt;&lt;strong&gt;Step #4&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const getArea4 = ({ width = 0, height = 0 }) =&gt; {
    return width * height;
};

const result4 = getArea4( {width: 15, height: 30} );
console.log( result4 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const getArea4 = ({ width = 0, height = 0 }) =&gt; {
            return width * height;
        };

        const result4 = getArea4( {width: 15, height: 30} );
        console.log( result4 );
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;지금까지 살펴본 &amp;nbsp;&lt;kbd&gt;destructuring assignment&lt;/kbd&gt;를 활용하면 실무에서 매우 유용할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const getArea = ({ width, height = width }) =&gt; {
  return width * height;
};

getArea({ width: 10 });&lt;/code&gt;&lt;/pre&gt;



    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;loof-wrap&quot;&gt;
        &lt;div class=&quot;loof&quot;&gt;
            &lt;svg class=&quot;rl-logo&quot; width=&quot;606&quot; height=&quot;300&quot; viewBox=&quot;0 0 606 300&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; preserveAspectRatio=&quot;none&quot;&gt;
                &lt;defs&gt;
                    &lt;clipPath id=&quot;clipLogo&quot;&gt;
                        &lt;path d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;
                        &lt;/path&gt;&lt;/clipPath&gt;
                &lt;/defs&gt;
                &lt;path class=&quot;rl-logo__path&quot; d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;&lt;/path&gt;
                &lt;path class=&quot;rl-logo__track&quot; clip-path=&quot;url(#clipLogo)&quot; d=&quot;M 323.9 178.9 C 344.8 202.5 383.7 245.8 412.2 261.3 C 447.3 282.3 494.3 278 527.7 255.5 C 586.6 217 597.8 127.5 557.2 72.1 C 530.3 33.4 479 17 434.2 28.2 C 389.3 41.5 358.1 79 330.7 114.3 C 318.9 128.6 277.3 185.4 277.3 185.4 C 249.9 220.7 218.7 258.1 173.8 271.5 C 129 282.7 77.7 266.3 50.8 227.6 C 10.2 172.2 21.4 82.7 80.3 44.2 C 113.7 21.6 160.7 17.4 195.8 38.4 C 224.3 53.9 261.2 96.2 282.1 119.7&quot;&gt;&lt;/path&gt;
            &lt;/svg&gt;
        &lt;/div&gt;
        &lt;div class=&quot;name&quot;&gt;
            Jaehee's&lt;span class=&quot;b&quot;&gt; WebClub&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/ES6+</category>
      <author>jaiyah</author>
      <guid isPermaLink="true">https://webclub.tistory.com/651</guid>
      <comments>https://webclub.tistory.com/651#entry651comment</comments>
      <pubDate>Fri, 26 Feb 2021 18:46:43 +0900</pubDate>
    </item>
    <item>
      <title>name property of function</title>
      <link>https://webclub.tistory.com/650</link>
      <description>    &lt;p&gt;&lt;mark&gt;이 글은 &lt;a href=&quot;https://www.inflearn.com/course/ecmascript-6-flow&quot; target=&quot;_blank&quot;&gt;[인프런] Javascript ES6+ 제대로 알아보기 - 초급(정재남)&lt;/a&gt;를 토대로 작성되었음을 알려드립니다.&lt;/mark&gt;&lt;/p&gt;
    &lt;p&gt;&lt;br&gt;&lt;/p&gt;

    &lt;p&gt;이번 장에서는 함수의 &amp;nbsp;&lt;code&gt;name&lt;/code&gt; 프로퍼티와 &amp;nbsp;&lt;code&gt;new.target&lt;/code&gt; 이라는 함수의 부가적인 내용들에 대해 알아보도록 하겠습니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;h2 class=&quot;hh&quot;&gt;name property of function&lt;/h2&gt;
    &lt;p&gt;함수의 &amp;nbsp;&lt;code&gt;name&lt;/code&gt; 프로퍼티는 주로 디버깅하는 경우에 사용하지만 &amp;nbsp;&lt;code&gt;name&lt;/code&gt; 프로퍼티를 가지고 디버깅을 할 사항이 거의 없기 때문에 간단히 알아보고 넘아가 보겠습니다.&lt;/p&gt;
    &lt;p&gt;아래의 다양한 함수 리터럴 표기법에 따른 &amp;nbsp;&lt;code&gt;name&lt;/code&gt; 프로퍼티가 어떻게 달라지는지 알아보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// 함수 선언문
function a () { }
console.log(a.name);

// 함수 표현식(변수 b 에 익명함수를 할당)
const b = function () { };
// 기존에는 익명함수의 이름이 로그에서 확인할 수 없었지만
// 모던 브라우저에서는 name 프로퍼티를 확인할 수 있도록 지원하고 있다.
console.log( b.name );

// 기명 함수 표현식
const c = function cc () { };
console.log(c.name); // 기존부터 함수의 이름을 나타내고 있었음

// Arrow Function(화살표 함수)
const d = () =&gt; { };
console.log(d.name);

// ES6 메소드 축약 방식, 화살표 함수를 할당한 경우
const e = {
    om1: function () {},
    om2 () {},
    om3: () =&gt; {}
};
console.log(e.om1.name, e.om2.name, e.om3.name);

// ES6 Class 문법
class F {
    static method1 () {}
    method2 () {}
}
const f = new F();
console.log(F.method1.name, f.method2.name);

// ES5 Class 흉내
function G() { }
G.method1 = function () { };
G.prototype.method2 = function () { };
const g = new G();
console.log( G.method1.name, g.method2.name );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        // 함수 선언문
        function a () { }
        console.log(a.name);

        const b = function () { };
        console.log( b.name );

        const c = function cc () { };
        console.log(c.name);

        const d = () =&gt; { };
        console.log(d.name);

        const e = {
            om1: function () {},
            om2 () {},
            om3: () =&gt; {}
        };
        console.log(e.om1.name, e.om2.name, e.om3.name);

        class F {
            static method1 () {}
            method2 () {}
        }
        const f = new F();
        console.log(F.method1.name, f.method2.name);

        function G() { }
        G.method1 = function () { };
        G.prototype.method2 = function () { };
        const g = new G();
        console.log( G.method1.name, g.method2.name );
    &lt;/script&gt;--&gt;

    &lt;p&gt;로그를 확인해 보면 마지막의 &amp;nbsp;&lt;kbd&gt;Class&lt;/kbd&gt; 를 흉내낸 패턴에서만 name 프로퍼티를 출력하지 않고 빈값으로 나오는 것을 확인할 수 있습니다. &lt;br&gt;
        추가된 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt; 의 클래스는 &amp;nbsp;&lt;code&gt;name&lt;/code&gt; 프로퍼티를 알려주지만 기존 방식에서는 &amp;nbsp;&lt;code&gt;name&lt;/code&gt; 프로퍼티가 없다라는 것을 알 수 있습니다. &lt;br&gt;
        중요한 사항은 아니지만 좀더 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt;에 이르러서 좀더 명확하고 견고하게 규정되었다는 정도로만 알고 넘어가자. &lt;br&gt;
    &lt;/p&gt;
    &lt;p&gt;정리하면, name 프로퍼티를 확인하여 함수의 대상을 찾아서 어떤 정보를 담고 있는지를 알 수 있습니다. &lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;h2 class=&quot;hh&quot;&gt;new.target&lt;/h2&gt;

    &lt;p class=&quot;mt20&quot;&gt;&lt;code&gt;new.target&lt;/code&gt; 을 알아보기 전에 다음의 코드를 살펴보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function Person (name) {
    if (this instanceof Person) {
        this.name = name;
    } else {
        throw new Error('new 연산자를 사용하세요.');
    }
}

var p1 = new Person('재희');
console.log(p1);

var p2 = Person('상윤');
console.log(p2);

var p3 = Person.call({}, '서비');
console.log(p3);

var p4 = Person.call(p1, '서비');
console.log(p4);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function Person (name) {
            if (this instanceof Person) {
                this.name = name;
            } else {
                throw new Error('new 연산자를 사용하세요.');
            }
        }

        var p1 = new Person('재희');
        console.log(p1);

       /* var p2 = Person('상윤');
        console.log(p2);

        var p3 = Person.call({}, '서비');
        console.log(p3);*/

        var p4 = Person.call(p1, '서비');
        console.log(p4);
        console.log( p1 );
    &lt;/script&gt;--&gt;

    &lt;p&gt;위 예제는 만약에 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 가 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt; 의 인스턴스라면 전달받은 &amp;nbsp;&lt;code&gt;name&lt;/code&gt; 을 &amp;nbsp;&lt;code&gt;this.name&lt;/code&gt; 에 할당하고
        그렇지 않다면&amp;nbsp;&lt;kbd&gt;new 연산자&lt;/kbd&gt;를 사용하도록 &lt;br&gt;에러를 던지는 코드로서 &amp;nbsp;&lt;kbd&gt;new 연산자&lt;/kbd&gt;없이 호출을 하면 에러를 내도록 한 것입니다.
        &lt;br&gt;
        이는 &amp;nbsp;&lt;mark&gt;new 연산자를 강제하기 위한 방법중(ES5 때)에 한가지&lt;/mark&gt;입니다.
    &lt;/p&gt;
    &lt;p&gt;좀더 풀이해 보자면, &amp;nbsp;&lt;code&gt;new Person('재희');&lt;/code&gt; 를 하면 생성될 인스턴스 자체가 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 가 되는데 그 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 가
        &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt; 의 인스턴스냐라고 물었을 때 참이면 &amp;nbsp;&lt;code&gt;this.name = name;&lt;/code&gt; 이 실행되고,
        이는 &amp;nbsp;&lt;code&gt;this.name&lt;/code&gt; 이라는 프로퍼티가 생성되서 반환이 될 것이고 &amp;nbsp;&lt;kbd&gt;new 연산자&lt;/kbd&gt;없이 호출하면
        &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 는 &lt;code&gt;window&lt;/code&gt; 를 가리키게 되고 &amp;nbsp;&lt;code&gt;this&lt;/code&gt;는 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt; 의 인스턴스가 아니기 때문에
        에러를 발생하는 코드가 실행되는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;위 예제를 하나씩 분석해 보자.&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;code class=&quot;v1&quot;&gt;var p1 = new Person('재희');&lt;/code&gt;
            &lt;p&gt;&lt;kbd&gt;p1&lt;/kbd&gt; 은 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt; 의 인스턴스이므로 에러가 나지 않는다.&lt;/p&gt;
        &lt;/li&gt;
        &lt;li class=&quot;mt20&quot;&gt;
            &lt;code class=&quot;v1&quot;&gt;var p2 = Person('상윤');&lt;/code&gt;
            &lt;p&gt;&lt;kbd&gt;p2&lt;/kbd&gt; 은 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt; 의 인스턴스가 아니기 때문에 에러가 발생한다.&lt;/p&gt;
        &lt;/li&gt;
        &lt;li class=&quot;mt20&quot;&gt;
            &lt;code class=&quot;v1&quot;&gt;var p3 = Person.call({}, '서비');&lt;/code&gt;
            &lt;p&gt;
                &lt;kbd&gt;p3&lt;/kbd&gt; 에서 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 는 &amp;nbsp;&lt;code&gt;call&lt;/code&gt; 메소드로 인해 &amp;nbsp;&lt;kbd&gt;{ } 인 빈 객체&lt;/kbd&gt;가 되고 이는 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt;의 인스턴스가 아니므로 에러가 발생한다.
            &lt;/p&gt;
        &lt;/li&gt;
        &lt;li class=&quot;mt20&quot;&gt;
            &lt;code class=&quot;v1&quot;&gt;var p4 = Person.call(p1, '서비');&lt;/code&gt;
            &lt;p&gt;
                &lt;code&gt;call(p1, '서비');&lt;/code&gt; 의 &amp;nbsp;&lt;kbd&gt;p1&lt;/kbd&gt; 은 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 가 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt;의 인스턴스가 맞기 때문에 &amp;nbsp;&lt;code&gt;this.name&lt;/code&gt; 에 '서비'이 할당될 것이고,
                &lt;br&gt;
                &amp;nbsp;&lt;kbd&gt;p4&lt;/kbd&gt; 는 &amp;nbsp;&lt;code&gt;call&lt;/code&gt; 메소드에 &amp;nbsp;&lt;kbd&gt;p1&lt;/kbd&gt;으로 인해 &amp;nbsp;&lt;kbd&gt;p1&lt;/kbd&gt; 을 바라보기 때문에 &amp;nbsp;&lt;kbd&gt;p4&lt;/kbd&gt;에는 반환하는 것이 없게 되어
                &lt;code&gt;undefined&lt;/code&gt;가 출력될 것입니다. &lt;br&gt;
                그리고 &amp;nbsp;&lt;kbd&gt;p1&lt;/kbd&gt;의 &amp;nbsp;&lt;code&gt;name&lt;/code&gt; 에는 &amp;nbsp;&lt;kbd&gt;'서비'&lt;/kbd&gt;가 할당되어 있는 것을 확인할 수 있습니다.
            &lt;/p&gt;
        &lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;기존의 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt;에서 new 연산자를 강제하기 위해서 위와 같은 조건문을 함수 내부에 작성하곤 했는데 이런 패턴은 &lt;code&gt;var p4 = Person.call(p1, '서비');&lt;/code&gt; 를 통해 확인했다시피
        완벽히 &amp;nbsp;&lt;code&gt;new&lt;/code&gt; 를 강제하는 코드는 아니라는 것입니다. &lt;br&gt;
        이 코드는 &amp;nbsp;&lt;code&gt;new&lt;/code&gt; 를 강제하려고 했으나 본래 의도와는 달리 동작하게된 예외적인 경우입니다. &lt;br&gt;
        다시 말해, &amp;nbsp;&lt;code&gt;new&lt;/code&gt; 연산자를 쓰지 않고도 에러가 나지 않는 상황이 발생된 예외적인 케이스인 것입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;new.target 의 등장&lt;/p&gt;
    &lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new.target&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;[MDN] new.target&lt;/a&gt; 바로가기&lt;/p&gt;
    &lt;p&gt;&lt;code&gt;new.target&lt;/code&gt;은 &amp;nbsp;&lt;kbd&gt;new 연산자&lt;/kbd&gt;를 사용하여 함수를 실행했을 경우에 그 실행한 함수 자체가 &amp;nbsp;&lt;code&gt;new.target&lt;/code&gt; 이 되는 것을 말합니다.&lt;/p&gt;
    &lt;p&gt;
        예를 들어 &amp;nbsp;&lt;kbd&gt;new Person(43);&lt;/kbd&gt; 이라고 할 경우 &amp;nbsp;&lt;code&gt;new&lt;/code&gt;가 붙은 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt;이 &amp;nbsp;&lt;code&gt;target&lt;/code&gt;이 된다는 의미입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;다음의 코드를 먼저 살펴보며 알아보도록 하자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function Person (name) {
    console.dir(new.target);
    if (new.target !== undefined) {
        this.name = name;
    } else {
        throw new Error('new 연산자를 사용하세요.');
    }
}

const p1 = new Person('재희');
console.log(p1);

const p2 = Person('상윤');
console.log(p2);

const p3 = Person.call({}, '서비');
console.log(p3);

const p4 = Person.call(p1, '서비');
console.log(p4)&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function Person (name) {
            console.dir(new.target);
            if (new.target !== undefined) {
                this.name = name;
            } else {
                throw new Error('new 연산자를 사용하세요.');
            }
        }

        const p1 = new Person('재희');
        console.log(p1);

        const p2 = Person('상윤');
        console.log(p2);

        const p3 = Person.call({}, '서비');
        console.log(p3);

        const p4 = Person.call(p1, '서비');
        console.log(p4)
    &lt;/script&gt;--&gt;

    &lt;p&gt;앞선 예제에서는 &amp;nbsp;&lt;code&gt;instanceof&lt;/code&gt; 연산자를 이용해 인스턴스를 판단했으나 위 예제에서는 &amp;nbsp;&lt;code&gt;new.target&lt;/code&gt;을 사용했습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;위 예제를 분석해 보자.&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;code class=&quot;v1&quot;&gt;const p2 = Person('상윤');&lt;/code&gt;
            &lt;p&gt;
                &lt;code&gt;console.dir(new.target);&lt;/code&gt; 를 확인해 보면 생성자 함수 자체가 출력된 것을 확인할 수 있고,
                &amp;nbsp;&lt;code&gt;new.target !== undefined&lt;/code&gt; 는 &amp;nbsp;&lt;code&gt;new.target&lt;/code&gt; 이 있으므로  &amp;nbsp;&lt;code&gt;this.name = name;&lt;/code&gt; 이 코드를 실행하게 됩니다.
            &lt;/p&gt;
        &lt;/li&gt;
        &lt;li class=&quot;mt20&quot;&gt;&lt;code class=&quot;v1&quot;&gt;const p2 = Person('상윤');&lt;/code&gt;
            &lt;p&gt;
                &amp;nbsp;&lt;code&gt;new.target&lt;/code&gt; 이 없기 때문에 에러가 발생합니다.
            &lt;/p&gt;
        &lt;/li&gt;
        &lt;li class=&quot;mt20&quot;&gt;&lt;code class=&quot;v1&quot;&gt;const p3 = Person.call({}, '서비');&lt;/code&gt;
            &lt;p&gt;
                &lt;code&gt;this&lt;/code&gt;가 빈 객체를 가리키고, 일반 함수를 호출한 것과 동일하므로 &amp;nbsp;&lt;code&gt;undefined&lt;/code&gt;를 반환하게 되고 &amp;nbsp;&lt;code&gt;new.target&lt;/code&gt;이 없기 때문에 에러가 발생합니다.
            &lt;/p&gt;
        &lt;/li&gt;
        &lt;li class=&quot;mt20&quot;&gt;&lt;code class=&quot;v1&quot;&gt;const p4 = Person.call(p1, '서비');&lt;/code&gt;
            &lt;p&gt;
                앞선 예제에서는 연산자를 쓰지 않아도 에러가 발생하지 않았으나 이 코드에서는 에러가 발생하게 됩니다. &lt;br&gt;
                즉, &amp;nbsp;&lt;kbd&gt;p1&lt;/kbd&gt;이 인스턴스이긴 하지만 &amp;nbsp;&lt;code&gt;new.target&lt;/code&gt; 으로 인해 &amp;nbsp;&lt;kbd&gt;new 연산자&lt;/kbd&gt; 자체를 사용하지 않으면 의도대로 &amp;nbsp;&lt;kbd&gt;new 연산자를 강제&lt;/kbd&gt;할 수 있습니다.
            &lt;/p&gt;
        &lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning tip&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt;new.target 은 객체인가? 변수인가?&lt;/p&gt;
        &lt;p&gt;&lt;code&gt;new.target&lt;/code&gt; 은 .target 의 형태로 보아 &amp;nbsp;&lt;kbd&gt;new&lt;/kbd&gt;라는 객체가 있을 것으로 보이고 &amp;nbsp;&lt;kbd&gt;new 객체&lt;/kbd&gt;에 프로퍼티로 &amp;nbsp;&lt;kbd&gt;target&lt;/kbd&gt;
            이라는 것이 있는 형태로 보입니다.
            하지만 콘솔 로그에서 &amp;nbsp;&lt;code&gt;console.log(new);&lt;/code&gt; 를 출력해 보면 읽어오질 못하는 것을 확인할 수 있습니다. &lt;br&gt;
            즉, 객체가 없다라고 할 수 있고 그렇다면 &amp;nbsp;&lt;code&gt;new.target&lt;/code&gt; 은 무엇일까? &lt;br&gt;
            &lt;code&gt;new.target&lt;/code&gt; 은 함수 생성시 생기는 것으로 그 자체로서 변수로 볼 수 있습니다. &lt;br&gt;
            다시 말해, 함수 내부에서만 접근이 가능한 &amp;nbsp;&lt;kbd&gt;내부 변수&lt;/kbd&gt;라고 할 수 있습니다.
        &lt;/p&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;중첩된 함수가 화살표 함수일 경우 new.target 은 어떻게 될까?&lt;/p&gt;
    &lt;p&gt;
        화살표 함수 파트에서 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 바인딩뿐만 아니라 &amp;nbsp;&lt;code&gt;super&lt;/code&gt;, &amp;nbsp;&lt;code&gt;new.target&lt;/code&gt; 도 바인딩하지 않는다고 언급했습니다. &lt;br&gt;
    &lt;/p&gt;
    &lt;p class=&quot;mt20 point-r&quot;&gt;다음의 예제를 살펴보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function Person (name) {
    const af = n =&gt; {
        this.name = n;
        console.log(new.target);
    };
    af(name);
}

const p1 = new Person('재남');
const p2 = Person('성훈');&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function Person (name) {
            const af = n =&gt; {
                this.name = n;
                console.log(new.target);
            };
            af(name);
        }

        const p1 = new Person('재남');
        const p2 = Person('성훈');
    &lt;/script&gt;--&gt;

    &lt;p&gt;위 예제는 내부함수로서 화살표 함수를 만들었고, 첫 번째 로그를 보면 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt; 함수가 담겨있는 것을 확인할 수 있습니다. &lt;br&gt;
        이것은 화살표 함수가 바인딩이 되지 않기 때문에 위 코드상 상위 스코프의 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt; 을 찾은 결과를 로그에서 확인할 수 있는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;그리고 &amp;nbsp;&lt;code&gt;const p2 = Person('성훈');&lt;/code&gt; 은 &lt;kbd&gt;new 연산자&lt;/kbd&gt;없이 호출한 경우로 역시 화살표 함수는 바인딩을 하지는 않지만 일반 함수를 호출하는 형태로서
        &lt;b&gt;반환(return)값&lt;/b&gt;이 없는 상태이므로 &amp;nbsp;&lt;code&gt;undefined&lt;/code&gt; 가 출력되는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;다른 상황을 다음의 예제를 통해 계속 알아보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function Person (name) {
    this.name = name;
}

function Android (name) {
    Person.call(this, name);
}

const p1 = new Android('시온봇');
console.log( p1 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function Person (name) {
            this.name = name;
        }

        function Android (name) {
            Person.call(this, name);
        }

        const p1 = new Android('시온봇');
        console.log( p1 );
    &lt;/script&gt;--&gt;

    &lt;p&gt;
        위 예제는 &amp;nbsp;&lt;code&gt;new Android('시온봇');&lt;/code&gt; 로 &amp;nbsp;&lt;code&gt;new&lt;/code&gt; 연산자를 사용하긴 했으나 &amp;nbsp;&lt;kbd&gt;Android&lt;/kbd&gt; 내부에서
        &amp;nbsp;&lt;code&gt;Person.call&lt;/code&gt; 를 이용해서 Person 함수를 빌려다 사용하고 있는 형태입니다.
        &amp;nbsp;&lt;code&gt;new&lt;/code&gt; 로 사용해서 생성자 함수는 &amp;nbsp;&lt;kbd&gt;Android&lt;/kbd&gt; 이지만 내부에서 실행할 내용이 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt; 에 있는 내용으로
        &amp;nbsp;&lt;kbd&gt;p1(=this)&lt;/kbd&gt;을 하여 &amp;nbsp;&lt;kbd&gt;name&lt;/kbd&gt; 을 넘겨준 것으로 실행하라는 코드로
        여기서 내부의 &amp;nbsp;&lt;code&gt;Person.call(this, name);&lt;/code&gt; 은 일반함수 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt; 을 실행한 것이나 마찬가지입니다. &lt;br&gt; 즉, 함수로서 실행이 된 것입니다.
    &lt;/p&gt;
    &lt;p class=&quot;mt20 point-r&quot;&gt;이 내용을 좀더 명확히 알아보기 위해 다음의 예제를 살펴보도록 하겠습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function Person (name) {
    this.name = name;
    return '복습 안하니까 따라오기 힘들지?';
}

function Android (name) {
    const res = Person.call(this, name);
    console.log( res );
}

const p1 = new Android('시온봇');
console.log( p1 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 function Person (name) {
			 this.name = name;
			 return '복습 안하니까 따라오기 힘들지?';
		 }
 
		 function Android (name) {
			 const res = Person.call(this, name);
			 console.log( res );
		 }
 
		 const p1 = new Android('시온봇');
		 console.log( p1 );
	 &lt;/script&gt;--&gt;

    &lt;p&gt;
        &lt;kbd&gt;p1&lt;/kbd&gt; 에 담긴 &amp;nbsp;&lt;kbd&gt;Android {name: &quot;시온봇&quot;}&lt;/kbd&gt; 내용은 달라질 것은 없지만 &amp;nbsp;&lt;code&gt;res&lt;/code&gt; 에 반환된 값이 &amp;nbsp;&lt;kbd&gt;'복습 안하니까 따라오기 힘들지?'&lt;/kbd&gt; 가
        출력되는 것으로 보아 생성자 함수로서의 호출이 아니라 일반 함수로서 호출된 것을 명확히 알 수 있는 대목입니다. &lt;br&gt;
        즉, Person.call 은 생성자 함수로 호출된 것이 아니라 일반 함수로 호출된 것입니다.
    &lt;/p&gt;
    &lt;p class=&quot;point-r mt20&quot;&gt;위 같은 문제를 우회하기 위해 상단에서 &amp;nbsp;&lt;kbd&gt;new 연산자를 강제&lt;/kbd&gt;하기 위해 사용한 코드(&lt;b&gt;new.target&lt;/b&gt;)를 이용하면 좋습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function Person (name) {
    console.log( new.target );
    if (new.target !== undefined) {
        this.name = name;
    } else {
        throw new Error( 'Person 생성자함수를 new 로 호출해야 합니다 !!' );
    }
    this.name = name;
}

function Android (name) {
    Person.call(this, name);
}

const p2 = new Android('시온봇');
console.log( p2 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function Person (name) {
            console.log( new.target );
            if (new.target !== undefined) {
                this.name = name;
            } else {
                throw new Error( 'Person 생성자함수를 new 로 호출해야 합니다 !!' );
            }
            this.name = name;
        }

        function Android (name) {
            Person.call(this, name);
        }

        const p2 = new Android('시온봇');
        console.log( p2 );
    &lt;/script&gt;--&gt;

    &lt;p&gt;
        위와 같이 작성하여 실행하면 &amp;nbsp;&lt;code&gt;new.target&lt;/code&gt; 에서 필터링되어 &amp;nbsp;&lt;code&gt;new Error&lt;/code&gt; 를 실행하게 됩니다.
    &lt;/p&gt;
    &lt;p class=&quot;mt20 point-r&quot;&gt;위 코드를 좀더 견고하게 만들기 위해 다음과 같이 작성했습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function Person (name) {
    console.log( new.target );
    if (new.target === Person) {
        this.name = name;
    } else {
        throw new Error( 'Person 생성자함수를 new 로 호출해야 합니다 !!' );
    }
    this.name = name;
}

function Android (name) {
    Person.call(this, name);
}

const p2 = new Android('시온봇');
console.log( p2 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function Person (name) {
            console.log( new.target );
            if (new.target === Person) {
                this.name = name;
            } else {
                throw new Error( 'Person 생성자함수를 new 로 호출해야 합니다 !!' );
            }
            this.name = name;
        }

        function Android (name) {
            Person.call(this, name);
        }

        const p2 = new Android('시온봇');
        console.log( p2 );
    &lt;/script&gt;--&gt;

    &lt;p&gt;앞선 코드에서 &amp;nbsp;&lt;code&gt;new.target !== undefined&lt;/code&gt;를 비교하기 보다 좀더 명확하게 하기 위해서 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt;이라고 비교하는 방법입니다.
        &lt;br&gt;
        사실 &amp;nbsp;&lt;code&gt;undefined&lt;/code&gt;와 비교하는 것과 생성자 이름과 비교하는 것이 별반 차이점은 없지만 명확하고 가독성 측면에서 좋을 수 있습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;지금까지 살펴본 안전 장치와 같은 코드는 &amp;nbsp;&lt;mark&gt;Class 에서 사용할 경우에 그 의미가 있다&lt;/mark&gt;고 할 수 있습니다.&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;아래 예제를 살펴보도록 하자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;class A {
    constructor () {
        console.log( new.target );
    }
}

class B extends A {
    constructor () {
        super();
    }
}

// 각각 해당 생성자를 가리킨다.
const b = new B();
const a = new A();&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        class A {
            constructor () {
                console.log( new.target );
            }
        }

        class B extends A {
            constructor () {
                super();
            }
        }

        // 각각 해당 생성자를 가리킨다.
        const b = new B();
        const a = new A();
    &lt;/script&gt;--&gt;

    &lt;p&gt;위 예제에서 클래스로 사용하여 로그를 확인해 보니 각각 올바르게 해당 생성자 함수를 출력하는데 이를 이용하면 &amp;nbsp;&lt;kbd&gt;추상 클래스를 흉내&lt;/kbd&gt;낼 수 있습니다.&lt;/p&gt;
    &lt;p class=&quot;mt20 point-r&quot;&gt;&lt;kbd&gt;추상 클래스&lt;/kbd&gt; 흉내내기&lt;/p&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;class A { // 추상클래스처럼 흉내
    constructor () {
        if (new.target === A) {
            throw new Error( 'A는 추상클래스입니다.' );
        }
    }
}

class B extends A {
    constructor () {
        super();
    }
}

// 각각 해당 생성자를 가리킨다.
const b = new B();
const a = new A();&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 class A { // 추상클래스처럼 흉내
			 constructor () {
				 if (new.target === A) {
					 throw new Error( 'A는 추상클래스입니다.' );
				 }
			 }
		 }
 
		 class B extends A {
			 constructor () {
				 super();
			 }
		 }
 
		 // 각각 해당 생성자를 가리킨다.
		 const b = new B();
		 const a = new A();
	 &lt;/script&gt;--&gt;

    &lt;p&gt;위와 같이 작성하면 &amp;nbsp;&lt;kbd&gt;A&lt;/kbd&gt; 자체를 &amp;nbsp;&lt;kbd&gt;new 연산자&lt;/kbd&gt;로 생성자 함수를 호출할 수 없게 됩니다. &lt;br&gt;
        즉, &amp;nbsp;&lt;kbd&gt;A&lt;/kbd&gt; 자체를 인스턴스로 호출할 수 없다는 의미로서 오직 B 에 의해서만 호출이 가능하게 되는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;로그를 확인해 보면 &amp;nbsp;&lt;kbd&gt;b&lt;/kbd&gt; 에는 인스턴스가 있으나 &amp;nbsp;&lt;kbd&gt;a&lt;/kbd&gt; 는 아무런 값도 정의되어 있지 않다는 것을 확인할 수 있습니다.&lt;/p&gt;
    &lt;p&gt;
        클래스 자체를 인스턴스로 만드는 것은 얼마든지 가능하지만 자바스크립트에는 추상클래스 자체를 지원하고 있지 않기 때문에
        위와 같은 조건문의 코드를 이용하여 인스턴스를 생성하려고 할 때 호출을 못하도록 막음으로서 오직 하위 서브 클래스인 즉, 상속받은
        구체적인 클래스에 의해서만 동작을 할 수 있게 끔 동작을 제한할 수 있는 것입니다.
    &lt;/p&gt;



    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;loof-wrap&quot;&gt;
        &lt;div class=&quot;loof&quot;&gt;
            &lt;svg class=&quot;rl-logo&quot; width=&quot;606&quot; height=&quot;300&quot; viewBox=&quot;0 0 606 300&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; preserveAspectRatio=&quot;none&quot;&gt;
                &lt;defs&gt;
                    &lt;clipPath id=&quot;clipLogo&quot;&gt;
                        &lt;path d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;
                        &lt;/path&gt;&lt;/clipPath&gt;
                &lt;/defs&gt;
                &lt;path class=&quot;rl-logo__path&quot; d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;&lt;/path&gt;
                &lt;path class=&quot;rl-logo__track&quot; clip-path=&quot;url(#clipLogo)&quot; d=&quot;M 323.9 178.9 C 344.8 202.5 383.7 245.8 412.2 261.3 C 447.3 282.3 494.3 278 527.7 255.5 C 586.6 217 597.8 127.5 557.2 72.1 C 530.3 33.4 479 17 434.2 28.2 C 389.3 41.5 358.1 79 330.7 114.3 C 318.9 128.6 277.3 185.4 277.3 185.4 C 249.9 220.7 218.7 258.1 173.8 271.5 C 129 282.7 77.7 266.3 50.8 227.6 C 10.2 172.2 21.4 82.7 80.3 44.2 C 113.7 21.6 160.7 17.4 195.8 38.4 C 224.3 53.9 261.2 96.2 282.1 119.7&quot;&gt;&lt;/path&gt;
            &lt;/svg&gt;
        &lt;/div&gt;
        &lt;div class=&quot;name&quot;&gt;
            Jaehee's&lt;span class=&quot;b&quot;&gt; WebClub&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/ES6+</category>
      <author>jaiyah</author>
      <guid isPermaLink="true">https://webclub.tistory.com/650</guid>
      <comments>https://webclub.tistory.com/650#entry650comment</comments>
      <pubDate>Fri, 26 Feb 2021 18:45:17 +0900</pubDate>
    </item>
    <item>
      <title>화살표 함수(Arrow function)</title>
      <link>https://webclub.tistory.com/649</link>
      <description>    &lt;p&gt;&lt;mark&gt;이 글은 &lt;a href=&quot;https://www.inflearn.com/course/ecmascript-6-flow&quot; target=&quot;_blank&quot;&gt;[인프런] Javascript ES6+ 제대로 알아보기 - 초급(정재남)&lt;/a&gt;를 토대로 작성되었음을 알려드립니다.&lt;/mark&gt;&lt;/p&gt;
    &lt;p&gt;&lt;br&gt;&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;h2 class=&quot;hh&quot;&gt;Arrow Function(화살표 함수)&lt;/h2&gt;

    &lt;p&gt;다음의 &amp;nbsp;&lt;kbd&gt;ES5 의 함수 표현식&lt;/kbd&gt;과 &amp;nbsp;&lt;kbd&gt;es2015 의 화살표 함수&lt;/kbd&gt;를 비교해 보도록 하자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;ES5 js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var a = function () {
  return new Date()
};

var b = function (a) {
  return a * a
};

var c = function (a, b) {
  return a + b
};

var d = function (a, b) {
  console.log( a * b )
}&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var a = function () {
            return new Date()
        };

        var b = function (a) {
            return a * a
        };

        var c = function (a, b) {
            return a + b
        };

        var d = function (a, b) {
            console.log( a * b )
        }
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot; style=&quot;text-transform:none&quot;&gt;ES6(es2015) JS&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let a = () =&gt; {
    return new Date()
};
let aa = () =&gt; new Date();

let b = (a) =&gt; {
    return a * a
};
let bb = a =&gt; a * a;

let c = (a, b) =&gt; {
    return a + b
};
let cc = (a, b) =&gt; a + b;

let d = (a, b) =&gt; {
    console.log( a * b )
};&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        let a = () =&gt; {
            return new Date()
        };
        let aa = () =&gt; new Date();

        let b = (a) =&gt; {
            return a * a
        };
        let bb = a =&gt; a * a;

        let c = (a, b) =&gt; {
            return a + b
        };
        let cc = (a, b) =&gt; a + b;

        let d = (a, b) =&gt; {
            console.log( a * b )
        };
    &lt;/script&gt;--&gt;

    &lt;p&gt;기존의 함수 표현식에서 &amp;nbsp;&lt;kbd&gt;function&lt;/kbd&gt; 키워드를 삭제하고 인자를 받는 매개변수의 &amp;nbsp;&lt;kbd&gt;괄호()&lt;/kbd&gt;와 &amp;nbsp;&lt;kbd&gt;코드블록({})&lt;/kbd&gt; 사이에
        &amp;nbsp;&lt;kbd&gt;화살표(=&gt;)&lt;/kbd&gt; 만 넣어주면 &lt;br&gt;
        이것이 바로 &lt;kbd&gt;화살표 함수(Arrow Function)&lt;/kbd&gt;입니다.
    &lt;/p&gt;
    &lt;p&gt;그리고 함수 내부의 내용이 반환값(&lt;b&gt;return&lt;/b&gt;)만 있다면 코드블록(함수의 몸통)인 &amp;nbsp;&lt;code&gt;중괄호({})&lt;/code&gt;와 &amp;nbsp;&lt;code&gt;return&lt;/code&gt; 을 생략할 수 있습니다.
        &lt;br&gt;
        그리고 또 하나 생략할 수 있는 것이 인자가 하나만 받는다면 매개변수의 &lt;kbd&gt;괄호()&lt;/kbd&gt;도 생략 가능하고, 여기서 주의해야 할 점은 인자가 없으면 생략할 수 없습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let step1 = (x) =&gt; {
    return {
        x : x
    }
};

let step2 = (x) =&gt; ({
    x : x
});

let step3 = x =&gt; ({
    x : x
});

let step4 = x =&gt; ({ x });&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        let step1 = (x) =&gt; {
            return {
                x : x
            }
        };

        let step2 = (x) =&gt; ({
            x : x
        });

        let step3 = x =&gt; ({
            x : x
        });

        let step4 = x =&gt; ({ x });
    &lt;/script&gt;--&gt;
    &lt;p&gt;위에서 함수 내부의 내용이 반환값(&lt;b&gt;return&lt;/b&gt;)만 있다면 &amp;nbsp;&lt;code&gt;return&lt;/code&gt; 과 코드 블록인 &amp;nbsp;&lt;kbd&gt;중괄호({})&lt;/kbd&gt;를 생략할 수 있다고 언급했으나
        객체 리터럴의 경우 &amp;nbsp;&lt;code&gt;return&lt;/code&gt; 과 &amp;nbsp;&lt;kbd&gt;코드블록({})&lt;/kbd&gt;을 생략하게 되면 남게 되는 &amp;nbsp;&lt;kbd&gt;코드블록({})&lt;/kbd&gt;의 경우는 화살표 함수의 함수 스코프로서 인식하게 되기 때문에
        안의 내용의 위에서는 &amp;nbsp;&lt;code&gt;x: x&lt;/code&gt; 의 형태로 즉, 객체 리터럴을 표기하려고 한 것이므로 에러를 내게 됩니다. &lt;br&gt;
        그렇기 때문에 &amp;nbsp;&lt;mark&gt;객체를 즉시 반환해야 하는 경우에는 예외적으로 객체임을 명시적으로 알려주기 위해서 ()를 묶어줌으로서 ()안의 값이 객체임을 표기&lt;/mark&gt;해 주어야 합니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;아래의 중접된 함수 형태에서 반환할 경우의 예제를 단계별로 좀더 살펴보도록 하겠습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let fn01_step1 = function (a) {
    return function (b) {
        return a + b;
    }
};

let fn01_step2 = (a) =&gt; {
    return function (b) {
        return a + b;
    }
};

let fn01_step3 = a =&gt; function (b) {
    return a + b;

};

let fn01_step4 = a =&gt; (b) =&gt; {
    return a + b;
};

let fn01_step5 = a =&gt; b =&gt; a + b;&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        let fn01_step1 = function (a) {
            return function (b) {
                return a + b;
            }
        };

        let fn01_step2 = (a) =&gt; {
            return function (b) {
                return a + b;
            }
        };

        let fn01_step3 = a =&gt; function (b) {
            return a + b;

        };

        let fn01_step4 = a =&gt; (b) =&gt; {
            return a + b;
        };

        let fn01_step5 = a =&gt; b =&gt; a + b;
    &lt;/script&gt;--&gt;

    &lt;p&gt;위 &amp;nbsp;&lt;kbd&gt;fn01_step1&lt;/kbd&gt; 코드를 줄여 나가면 최종적으로 아래와 같은 형태로 짧게 작성할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let finished = a =&gt; b =&gt; a + b;&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        let finished = a =&gt; b =&gt; a + b;

        var x = finished( 1 );
        var y = x( 2 );
        console.log( y );

        var z = finished(1)(2);
        console.log( z );
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;Arrow Function's detail info&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;1) &amp;nbsp; (매개변수) =&gt; { 본문 }&lt;/strong&gt;&lt;/p&gt;
    &lt;p class=&quot;&quot;&gt;&lt;strong&gt;2) &amp;nbsp; 매개변수가 하나뿐인 경우 괄호 생략 가능&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;3) &amp;nbsp; 매개변수가 없을 경우에는 괄호 필수&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;4) &amp;nbsp; 본문이 &amp;nbsp;&lt;kbd&gt;return [식 or 값]&lt;/kbd&gt; 뿐인 경우 &amp;nbsp;&lt;code&gt;{ }&lt;/code&gt; 와 &amp;nbsp;&lt;code&gt;return&lt;/code&gt; 키워드 생략 가능&lt;/strong&gt;&lt;/p&gt;

    &lt;p class=&quot;mt20&quot;&gt;&lt;strong&gt;5) &amp;nbsp; 위 4) 에서 &amp;nbsp;&lt;code&gt;return&lt;/code&gt; 할 값이 &amp;nbsp;&lt;kbd&gt;객체&lt;/kbd&gt;인 경우네는 괄호 필수&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const f = () =&gt; {
    a: 1,
    b: 2
};

const f = () =&gt; ({
    a: 1,
    b: 2
});&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;6) &amp;nbsp; 실행 컨텍스트 생성시 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 바인딩을 하지 않음&lt;/strong&gt;&lt;/p&gt;
    &lt;p&gt;화살표 함수는 기존 함수의 기능을 문법적으로 편하게 직관적으로 보여지기 위해 만들어진 이유보다 함수를 가볍게 하기 위해서 만들어진 목적이 더 큽니다.
        함수를 실행하는 순간 함수의 덩어리에 대한 데이터를 모두 들고 컨텍스트를 생성하고 하는 등등의 내부에서 하는 일들이 많아서 무거웠으나 이렇게 기존에 무거웠음에도
        무리없이 실행이 된 것은 무엇보다 컴퓨터의 성능이 좋아진 이유에 있습니다. 하지만 더이상 함수의 성능적 이슈를 방치할 수 없어서 좀더 가벼운 함수를 만들고자 화살표 함수가
        나타나게 된 것입니다. &lt;br&gt;
        이렇게 함수의 성능을 높이기 위해 변화된 것 중의 하나가 &amp;nbsp;&lt;kbd&gt;this 바인딩&lt;/kbd&gt; 입니다.
    &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const obj = {
    a : function () {
        console.log(this); // obj

        const b = function() {
            console.log( this ); // this 바인딩하는 객체가 window
        };
        b();
    }
};

obj.a();

const obj2 = {
    a : function () {
        console.log(this); // obj

        const b = () =&gt; {
            // this 를 바인딩하는 동작 자체를 하지 않음
            console.log( this ); // obj
        };
        b();
    }
};

obj2.a();&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 const obj = {
			 a : function () {
				 console.log(this); // obj
 
				 const b = function() {
					 console.log( this ); // this 바인딩하는 객체가 window
				 };
				 b();
			 }
		 };
 
		 obj.a();
 
		 const obj2 = {
			 a : function () {
				 console.log(this); // obj
 
				 const b = () =&gt; {
					 // this 를 바인딩하는 동작 자체를 하지 않음
					 console.log( this ); // obj
				 };
				 b();
			 }
		 };
 
		 obj2.a();
	 &lt;/script&gt;--&gt;

    &lt;!--
    b.call(this);
     var self = this;
     --&gt;

    &lt;p&gt;위 코드에서 확인해 보면 일반 함수에서 함수 자체가 실행되는 순간에 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 바인딩하는 작업을 하게 되는데 위 코드에서 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 찾는데 바인딩할 대상이 없으니
        자동으로 전역객체를 바인딩하여 &amp;nbsp;&lt;code&gt;window&lt;/code&gt; 가 출력된 것이고 &amp;nbsp;&lt;kbd&gt;Arrow Function(화살표 함수)&lt;/kbd&gt; 은 실행 컨텍스트가 생성될 때 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 바인딩하는 작업 자체를 하지 않도록 설계되어 있어서
        위 코드상에서는 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 찾으려고 하니 &amp;nbsp;&lt;kbd&gt;b&lt;/kbd&gt;의 실행 컨텍스트에 없으니 스코프 체이닝을 통해 외부 스코프에서 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 찾게 되어
        &amp;nbsp;&lt;kbd&gt;obj&lt;/kbd&gt; 가 출력되는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;&lt;mark&gt;즉, Arrow Function(화살표 함수)은 '함수 스코프'를 생성합니다. 다만, 실행 컨텍스트 생성시 this 를 바인딩하지 않습니다.&lt;/mark&gt;&lt;/p&gt;


    &lt;!--&lt;script&gt;
        const a = () =&gt; {
            var x = 10;
        };
        a();
        console.log( x );

        const b = function() {
            var x = 10; // var 는 블록 스코프의 영향을 받지 않는다.
        };
        b();
        console.log( x );
    &lt;/script&gt;--&gt;


    &lt;p class=&quot;mt20 point-r&quot;&gt;위 내용을 생각해 보면서 다음의 예제를 살펴보도록 하자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const obj = {
    grades: [80, 90, 100],
    getTotal: function () {
        this.total = 0;
        this.grades.forEach(function(v) {
            this.total += v // this ???
        })
    }
};

obj.getTotal();
console.log(obj.total);&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 const obj = {
			 grades: [80, 90, 100],
			 getTotal: function () {
				 this.total = 0;
				 this.grades.forEach(function(v) {
					 this.total += v // this ???
				 })
			 }
		 };
 
		 obj.getTotal();
		 console.log(obj.total);
 
		 console.log( total );
	 &lt;/script&gt;--&gt;

    &lt;p&gt;
        &lt;code&gt;this.total&lt;/code&gt;, &amp;nbsp;&lt;code&gt;this.grades&lt;/code&gt; 에서 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 는 &amp;nbsp;&lt;kbd&gt;obj&lt;/kbd&gt; 를 가리키고 있지만 &amp;nbsp;&lt;code&gt;forEach&lt;/code&gt;
        메소드 내부의 콜백 함수(forEach 가 돌려주는 콜백함수)는 그냥 함수 실행이기 때문에
        그 내부에서의 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 는 &amp;nbsp;&lt;code&gt;window&lt;/code&gt; 를 가리키게 되어 &amp;nbsp;&lt;code&gt;window.total&lt;/code&gt; 로 바인딩되게 됩니다.
    &lt;/p&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var total = 0;
const obj = {
    grades: [80, 90, 100],
    getTotal: function () {
        this.total = 0;
        this.grades.forEach(function(v) {
            this.total += v
        })
    }
};

obj.getTotal();

console.log( total ); // 270&lt;/code&gt;&lt;/pre&gt;
    &lt;!--&lt;script&gt;
        var total = 0;
        const obj = {
            grades: [80, 90, 100],
            getTotal: function () {
                this.total = 0;
                this.grades.forEach(function(v) {
                    this.total += v
                })
            }
        };

        obj.getTotal();

        console.log( total ); // 270
    &lt;/script&gt;--&gt;
    &lt;p&gt;위 코드는 원하는 결과는 얻었지만 의도한 코드는 아니었을 것입니다.&lt;/p&gt;
    &lt;p class=&quot;mt20 point-r&quot;&gt;즉, 콜백 함수에서의 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 가 달라졌기 때문에 &amp;nbsp;&lt;kbd&gt;this 바인딩&lt;/kbd&gt;을 해주어야 하는데 이는 다음과 같이 할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const obj = {
    grades: [80, 90, 100],
    getTotal: function () {
        this.total = 0;
        this.grades.forEach(function(v) {
            this.total += v
        }, this);
    }
};

obj.getTotal();
console.log( obj.total );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const obj = {
            grades: [80, 90, 100],
            getTotal: function () {
                this.total = 0;
                this.grades.forEach(function(v) {
                    this.total += v
                }, this);
            }
        };

        obj.getTotal();
        console.log( obj.total );
    &lt;/script&gt;--&gt;
    &lt;p&gt;위와 같이 &amp;nbsp;&lt;code&gt;forEach&lt;/code&gt; 메소드에서 제공해 주고 있는 스펙에 따라 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 넘겨줄 수도 있지만 아래와 같이 화살표 함수를 사용할 수도 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const obj = {
    grades: [80, 90, 100],
    getTotal: function () {
        this.total = 0;
        this.grades.forEach( v =&gt; {
            this.total += v
        });
    }
};

obj.getTotal();
console.log( obj.total );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const obj = {
            grades: [80, 90, 100],
            getTotal: function () {
                this.total = 0;
                this.grades.forEach( v =&gt; {
                    this.total += v
                });
            }
        };

        obj.getTotal();
        console.log( obj.total );
    &lt;/script&gt;--&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;7) &amp;nbsp; 6) 에서 화살표 함수는 this 바인딩이 안된다고 언급했는데 &lt;kbd&gt;명시적인 this 바인딩&lt;/kbd&gt;은 어떻게 될까? &lt;/strong&gt;&lt;/p&gt;
    &lt;p&gt;결론부터 말하자면 명시적인 this 바인딩을 되지 않습니다. 즉, this 바인딩이 안됩니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const a = () =&gt; {
    console.log( this );
};

a(); // window
a.call( {} ); // window&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const a = () =&gt; {
            console.log( this );
        };

        a(); // window
        a.call( {} ); // window
    &lt;/script&gt;--&gt;

    &lt;p&gt;명시적인 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 바인딩을 사용하는 방법 중에 하나가 &amp;nbsp;&lt;code&gt;call&lt;/code&gt; 을 이용하는데 &amp;nbsp;&lt;code&gt;call&lt;/code&gt; 메소드의 첫 번째 인자는 명시적으로 넘겨줄
        &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 바인딩할 대상을 넘겨줍니다. &amp;nbsp;화살표 함수를 사용할 경우 위와 같이 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 로 &lt;kbd&gt;{} 객체&lt;/kbd&gt;를 넘겨주더라도
        &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 는 여전히 &amp;nbsp;&lt;code&gt;window&lt;/code&gt; 를 가리키고 있는 것을 확인할 수 있을 것입니다.
    &lt;/p&gt;
    &lt;p class=&quot;point-r mt20&quot;&gt;그렇다면 일반 함수의 경우에는 어떻게 되는지 다음의 코드를 통해 확인해 보도록 합니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const a = function() {
    console.log( this );
};

a(); // window
a.call( {} ); // {} 빈 객체&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const a = function() {
            console.log( this );
        };

        a(); // window
        a.call( {} ); // {} 빈 객체
    &lt;/script&gt;--&gt;

    &lt;p&gt;&lt;code&gt;a.call( {} );&lt;/code&gt;는 &lt;kbd&gt;a&lt;/kbd&gt; 함수를 실행할 때 this 를 &lt;kbd&gt;{}&lt;/kbd&gt; 요놈인 채로 &lt;kbd&gt;c&lt;/kbd&gt; 함수를 실행하라.. 라고 했으니
        &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 가 빈 객체를 가리키게 됩니다. &lt;br&gt;
        즉, 일반적인 함수(콜백함수 포함)에서는 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 바인딩을 하지만 &lt;kbd&gt;Arrow Function(화살표함수)&lt;/kbd&gt; 에서는 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 바인딩하지 않는다는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning check&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt;화살표 함수에서 call, apply 의 기능은 수행하는가?&lt;/p&gt;
        &lt;p&gt;
            &lt;code&gt;call&lt;/code&gt;, &amp;nbsp;&lt;code&gt;apply&lt;/code&gt; 메소드는 본연의 기능은 수행하지만 제약이 있다는 점만 주의하면 됩니다. &lt;br&gt;
            즉, &lt;mark&gt;this 만 바인딩되지 않는다&lt;/mark&gt;는 것입니다.
        &lt;/p&gt;
        &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
        &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// 기존 ES5 함수 선언문
function sum(...arg) {
    console.log( this );
    return arg.reduce( (p,c) =&gt; p+ c);
}

console.log( sum( 1, 2, 3, 4, 5 ) ); // 15
sum.call( {}, 1, 2, 3, 4, 5 ); // 15


// 화살표 함수를 사용한 경우의 this
const sum2 = (...arg) =&gt; {
    console.log( this );
    return arg.reduce( (p,c) =&gt; p+ c);
};

console.log( sum2( 1, 2, 3, 4, 5 ) ); // 15
sum2.call( {}, 1, 2, 3, 4, 5 ); // 15
&lt;/code&gt;&lt;/pre&gt;
        &lt;p&gt;
            위 코드를 확인해 보면 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 만 다를 뿐 &amp;nbsp;&lt;code&gt;call&lt;/code&gt;, &amp;nbsp;&lt;code&gt;apply&lt;/code&gt; 는 인자들을 넘겨주는 것에 대한 그 기능은 충실히 수행하고
            &lt;br&gt;
            다만, &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 만 바인딩되지 않을 뿐입니다.&lt;/p&gt;
    &lt;/div&gt;

    &lt;!--&lt;script&gt;
        function sum(...arg) {
            console.log( this );
            return arg.reduce( (p,c) =&gt; p+ c);
        }

        console.log( sum( 1, 2, 3, 4, 5 ) ); // 15
        sum.call( {}, 1, 2, 3, 4, 5 ); // 15
    &lt;/script&gt;--&gt;

    &lt;!--&lt;script&gt;
        const sum2 = (...arg) =&gt; {
            console.log( this );
            return arg.reduce( (p,c) =&gt; p+ c);
        };

        console.log( sum2( 1, 2, 3, 4, 5 ) ); // 15
        sum2.call( {}, 1, 2, 3, 4, 5 ); // 15
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const a = (...rest) =&gt; {
  console.log(this, rest);
}
a.call({a: 1}, 1, 2, 3);
a.apply([], [4, 5, 6]);
const b = a.bind(null, 7, 8, 9, 10);
b()&lt;/code&gt;&lt;/pre&gt;


    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const obj = {
  f() {
    const a = (...rest) =&gt; {
      console.log(this, rest)
    };
    a.call({a: 1}, 1, 2, 3);
    a.apply([], [4, 5, 6]);
    const b = a.bind(null, 7, 8, 9, 10);
    b();
  }
};
obj.f()&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;8) &amp;nbsp; 화살표 함수는 생성자함수로 사용할 수 있을까?&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// ES5 함수 선언문
function sum(...arg) {
    console.log( this );
    return arg.reduce( (p,c) =&gt; p+ c);
}

// Arrow Function
const sum2 = (...arg) =&gt; {
    console.log( this );
    return arg.reduce( (p,c) =&gt; p+ c);
};

console.dir( sum );
console.dir( sum2 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 // ES5 함수 선언문
		 function sum(...arg) {
			 console.log( this );
			 return arg.reduce( (p,c) =&gt; p+ c);
		 }
 
		 // Arrow Function
		 const sum2 = (...arg) =&gt; {
			 console.log( this );
			 return arg.reduce( (p,c) =&gt; p+ c);
		 };
 
		 console.dir( sum );
		 console.dir( sum2 );
 
	 &lt;/script&gt;--&gt;
    &lt;p&gt;
        개발자 도구에서 &amp;nbsp;&lt;kbd&gt;sum&lt;/kbd&gt; 을 확인해 보면 &amp;nbsp;&lt;code&gt;prototype&lt;/code&gt; 이 있는 것을 볼 수 있고 이는 생성자 함수로 사용할 수 있다는 것을 의미합니다. &lt;br&gt;
        하지만, &amp;nbsp;&lt;kbd&gt;sum2&lt;/kbd&gt; 는 &amp;nbsp;&lt;code&gt;prototype&lt;/code&gt; 이 없는 것을 확인할 수 있고 이는 생성자 함수로 사용할 수 없다는 것을 말합니다.
    &lt;/p&gt;
    &lt;p class=&quot;mt20 point-r&quot;&gt;다음의 코드를 통해 개발자 도구에서 확인해 보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// ES5 함수 선언문
function sum() {
    console.log( this );
}

// Arrow Function
const sum2 = () =&gt; {
    console.log( this );
};

const b = new sum();

const c = new sum2(); // sum2 is not a constructor&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        // ES5 함수 선언문
        function sum() {
            console.log( this );
        }

        // Arrow Function
        const sum2 = () =&gt; {
            console.log( this );
        };

        const b = new sum();

        const c = new sum2();

    &lt;/script&gt;--&gt;
    &lt;p&gt;정리하면, &amp;nbsp;&lt;kbd&gt;Arrow Function(화살표 함수)&lt;/kbd&gt; 과 &amp;nbsp;&lt;kbd&gt;concise method(메소드 축약형)&lt;/kbd&gt; 은 prototype 프로퍼티가 없으며 이는 생성자 함수로 사용할 수 없다는 것을 의미합니다.&lt;/p&gt;
    &lt;p class=&quot;mt20 point-r&quot;&gt;아래 예제를 통해 차이점을 살펴보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; const b = {
    title: '자바스크립트',
    // ES6 메소드 형태
    bb () {
        return this.title;
    },
    // ES6 메소드이지만 화살표 함수를 사용한 경우
    a : x =&gt; {
        return this.title;
    }
};

console.log( b.bb() );
console.log( b.a() ); // this 바인딩을 하지 않아서 undefined 출력

window.title = 'ES6';
console.log( b.a() );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const b = {
            title: '자바스크립트',
            // ES6 메소드 형태
            bb () {
                return this.title;
            },
            // ES6 메소드이지만 화살표 함수를 사용한 경우
            a : x =&gt; {
                return this.title;
            }
        };

        console.log( b.bb() );
        console.log( b.a() ); // this 바인딩을 하지 않아서 undefined 출력

        window.title = 'ES6';
        console.log( b.a() );
    &lt;/script&gt;--&gt;

    &lt;p&gt;a 의 값이 화살표 함수일 경우 메소드처럼 호출할 수는 있으나 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 가 바인딩되지 않는 점을 보면 메소드의 역할보다는 함수로서의 기능을 한다는 것을 알 수 있습니다.&lt;/p&gt;
    &lt;p&gt;
        다시 말해, 객체에서 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 사용하는 것은 자신의 객체에 다른 프로퍼티를 바라보게 하기 위해 사용하는 목적이 있는데 그렇기 하려면 메소드 축약형이나 기존 방식을 사용하면 될 것이고,
        this 를 바라보게 할 상황이 아니라면 화살표 함수를 사용할 수 있습니다.  &lt;br&gt;
        &lt;mark&gt;정리하면, 메소드를 사용하려면 메소드 축약형, 기존 방식을 그렇지 않다면 화살표 함수를 사용하면 될 것이고,
            화살표 함수는 메소드 안에서 같은 this 를 바라보게 할 때 즉, 내부 함수로서 사용하는 경우에 의의가 있다고 할 수 있습니다.
        &lt;/mark&gt;
    &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; const b = {
    title: '자바스크립트',
    bb () {
        const c = x =&gt; {
            return this.title;
        };
        console.log( c() );
    },
};

b.bb();&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const b = {
            title: '자바스크립트',
            bb () {
                const c = x =&gt; {
                    return this.title;
                };
                console.log( c() );
            },
        };

        b.bb();

    &lt;/script&gt;--&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;9) &amp;nbsp; 이외의 기타 사항&lt;/strong&gt;&lt;/p&gt;
    &lt;p&gt;&lt;code&gt;this&lt;/code&gt; 외에도 &amp;nbsp;&lt;code&gt;super&lt;/code&gt;, &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt;, &amp;nbsp;&lt;code&gt;new.target&lt;/code&gt; 등을 바인딩하지 않는다.&lt;/p&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;loof-wrap&quot;&gt;
        &lt;div class=&quot;loof&quot;&gt;
            &lt;svg class=&quot;rl-logo&quot; width=&quot;606&quot; height=&quot;300&quot; viewBox=&quot;0 0 606 300&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; preserveAspectRatio=&quot;none&quot;&gt;
                &lt;defs&gt;
                    &lt;clipPath id=&quot;clipLogo&quot;&gt;
                        &lt;path d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;
                        &lt;/path&gt;&lt;/clipPath&gt;
                &lt;/defs&gt;
                &lt;path class=&quot;rl-logo__path&quot; d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;&lt;/path&gt;
                &lt;path class=&quot;rl-logo__track&quot; clip-path=&quot;url(#clipLogo)&quot; d=&quot;M 323.9 178.9 C 344.8 202.5 383.7 245.8 412.2 261.3 C 447.3 282.3 494.3 278 527.7 255.5 C 586.6 217 597.8 127.5 557.2 72.1 C 530.3 33.4 479 17 434.2 28.2 C 389.3 41.5 358.1 79 330.7 114.3 C 318.9 128.6 277.3 185.4 277.3 185.4 C 249.9 220.7 218.7 258.1 173.8 271.5 C 129 282.7 77.7 266.3 50.8 227.6 C 10.2 172.2 21.4 82.7 80.3 44.2 C 113.7 21.6 160.7 17.4 195.8 38.4 C 224.3 53.9 261.2 96.2 282.1 119.7&quot;&gt;&lt;/path&gt;
            &lt;/svg&gt;
        &lt;/div&gt;
        &lt;div class=&quot;name&quot;&gt;
            Jaehee's&lt;span class=&quot;b&quot;&gt; WebClub&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/ES6+</category>
      <category>화살표 함수</category>
      <author>jaiyah</author>
      <guid isPermaLink="true">https://webclub.tistory.com/649</guid>
      <comments>https://webclub.tistory.com/649#entry649comment</comments>
      <pubDate>Fri, 26 Feb 2021 18:41:59 +0900</pubDate>
    </item>
    <item>
      <title>enhanced object functionality</title>
      <link>https://webclub.tistory.com/648</link>
      <description>&lt;p&gt;&lt;mark&gt;이 글은 &lt;a href=&quot;https://www.inflearn.com/course/ecmascript-6-flow&quot; target=&quot;_blank&quot;&gt;[인프런] Javascript ES6+ 제대로 알아보기 - 초급(정재남)&lt;/a&gt;를 토대로 작성되었음을 알려드립니다.&lt;/mark&gt;&lt;/p&gt;
    &lt;p&gt;&lt;br&gt;&lt;/p&gt;

    &lt;h2 class=&quot;hh&quot;&gt;계산된 프로퍼티명, 고정된 프로퍼티 열거 순서&lt;/h2&gt;
    &lt;p&gt;먼저 계산된 프로퍼티명에 대한 내용을 알아보도록 하자.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;computed property name (계산된 프로퍼티명)&lt;/p&gt;
    &lt;p&gt;다음의 계산된 프로퍼티명에 대한 예제를 살펴보면서 알아보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var className = ' Class';
var obj = {};

obj.'ab cd' = 'AB CD'; // 잘못된 문법
obj['ab cd'] = 'AB CD'; // 올바른 문법

console.log( obj );

obj = {
    'ab cd' : 'AB CD'
};

// 규칙이 혼동스러운 부분
var obj2 = {
    'A' + className : 'A급'
};
obj2['A' + className] = 'A급';&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 var className = ' Class';
		 var obj = {};

		 obj.'ab cd' = 'AB CD'; // 잘못된 문법
		 obj['ab cd'] = 'AB CD'; // 올바른 문법

		 console.log( obj );

		 obj = {
			 'ab cd' : 'AB CD'
		 };

		 // 규칙이 혼동스러운 부분
		 var obj2 = {
			 'A' + className : 'A급'
		 };
		 obj2['A' + className] = 'A급';
	 &lt;/script&gt;--&gt;
    &lt;p class=&quot;point-r mt30&quot;&gt;&lt;kbd&gt;ES5&lt;/kbd&gt;는 위와 같은 문법으로 혼동스러운 부분이 있었으나 &lt;kbd&gt;ES6&lt;/kbd&gt;에서는 다음과 같이 객체 리터럴에서도 &lt;kbd&gt;대괄호([]) 표기법&lt;/kbd&gt;을 제공하고 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var className = ' Class';

var obj2 = {
    ['A' + className] : 'A급'
};
obj2['A' + className] = 'A급';&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 var className = ' Class';

		 var obj2 = {
			 ['A' + className] : 'A급'
		 };
		 obj2['A' + className] = 'A급';
	 &lt;/script&gt;--&gt;
    &lt;p&gt;
        기존에는 객체를 선언하는 순간이 아닌 객체리터럴이 이미 생성(선언)된 이후에 프로퍼티 하나씩만 추가할 때에는 가능했지만 내부에서 변수명을 위와 같이 조합해서 작성하는 것이 불가능했었습니다.
        &amp;nbsp; 즉, 외부에서만 작성이 가능했습니다. &lt;br&gt;
        이제 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt;부터는 객체리터럴을 선언하는 순간에도 바로 작성이 가능한 것입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;위에서 살펴봤 듯이 계산된 것이 가능하기 때문에 다음과 같은 코드 작성이 가능할 수 있습니다. &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; let suffix = ' name';
let iu = {
    ['last' + suffix]: '이',
    ['first' + suffix]: '지은'
};

console.log(iu);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        let suffix = ' name';
        let iu = {
            ['last' + suffix]: '이',
            ['first' + suffix]: '지은'
        };

        console.log(iu);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;재미삼아 분석해 보는 쉬어가는 코너&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// 너무 줄여놓은 거 아니야 ?! 좀 알아보게 해주면 안될까요? ㅠ
const counter = ((c) =&gt; () =&gt; c++)(0);

var obj = {
    [`a_${counter()}`] : counter(),
    [`a_${counter()}`] : counter(),
    [`a_${counter()}`] : counter()
};

console.log( obj );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        // 너무 줄여놓은 거 아니야 ?! 좀 알아보게 해주면 안될까요? ㅠ
        const counter = ((c) =&gt; () =&gt; c++)(0);

        var obj = {
            [`a_${counter()}`] : counter(),
            [`a_${counter()}`] : counter(),
            [`a_${counter()}`] : counter()
        };

        console.log( obj );
    &lt;/script&gt;--&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;Detail Info&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;1) &amp;nbsp;객체 리터럴 선언시 프로퍼티 키값에 대괄호 표기로 접근 가능&lt;/strong&gt;&lt;/p&gt;
    &lt;p class=&quot;&quot;&gt;&lt;strong&gt;2) &amp;nbsp;&lt;kbd&gt;대괄호([ ])&lt;/kbd&gt; 내에는 값 또는 식을 넣어 조합할 수 있음&lt;/strong&gt;&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;own property enumeration order (고정된 프로퍼티 열거 순서)&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;먼저 예제를 살펴보도록 하자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const obj1 = {
    c: 1,
    2: 2,
    a: 3,
    0: 4,
    b: 5,
    1: 6
};

const keys1 = [];
for (const key in obj1) {
    keys1.push(key)
}

console.log(keys1);
console.log(Object.keys(obj1));
console.log(Object.getOwnPropertyNames(obj1));&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const obj1 = {
            c: 1,
            2: 2,
            a: 3,
            0: 4,
            b: 5,
            1: 6
        };

        const keys1 = [];
        for (const key in obj1) {
            keys1.push(key)
        }

        console.log(keys1);
        console.log(Object.keys(obj1));
        console.log(Object.getOwnPropertyNames(obj1));
    &lt;/script&gt;--&gt;

    &lt;p&gt;위 에제는 객체와 빈 배열을 생성하여 &amp;nbsp;&lt;kbd&gt;for~in문&lt;/kbd&gt;을 사용해 빈 배열에 &amp;nbsp;&lt;kbd&gt;key&lt;/kbd&gt; 를 추가하는 코드입니다. &lt;br&gt;
        로그를 확인해 보면 숫자가 먼저 오고, 작은 수에서 큰 수로 그 다음 문자가 입력된 순서대로 출력되는 것을 알 수 있습니다. &lt;br&gt;
        이렇게 기존에는 의미없는 정렬을 하였지만 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt;부터는 숫자별, 문자별로 구성하여 차례로 열거 순서를 맞추어 나열하게 됩니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;다른 예제를 살펴보도록 하겠습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const obj2 = {
    '02': true,
    '10': true,
    '01': true,
    '2': true,
};

const keys2= [];
for(const key in obj2) {
    keys2.push(key)
}

console.log(keys2);
console.log(Object.keys(obj2));
console.log(Object.getOwnPropertyNames(obj2));
console.log(Reflect.ownKeys(obj2));&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const obj2 = {
            '02': true,
            '10': true,
            '01': true,
            '2': true,
        };

        const keys2= [];
        for(const key in obj2) {
            keys2.push(key)
        }

        console.log(keys2);
        console.log(Object.keys(obj2));
        console.log(Object.getOwnPropertyNames(obj2));
        console.log(Reflect.ownKeys(obj2));
    &lt;/script&gt;--&gt;

    &lt;p&gt;위에서 살펴본 내용에 따르면 위 예제는 숫자지만 문자열이기 때문에 문자는 입력된 순서대로 출력된다고 했는데 그렇지 않은 것을 알 수 있습니다. &lt;br&gt;
        잘 생각해 보면 객체 프로퍼티는 본래 문자열로 구성됩니다. &amp;nbsp; 하지만 숫자를 입력 받았을 때 숫자로서의 조건들이 있습니다. &lt;br&gt;
        &lt;mark&gt;숫자인데 첫 글자가 0이 아닌 경우에 숫자로 인식하게 됩니다.&lt;/mark&gt;
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;객체를 병합했을 경우의 예제를 살펴보도록 하자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const obj1 = {
    c: 1,
    2: 2,
    a: 3,
    0: 4,
    b: 5,
    1: 6
};

const obj2 = {
    '02': true,
    '10': true,
    '01': true,
    '2': true,
};

const obj3 = Object.assign({}, obj1, obj2);

const keys3= [];
for(const key in obj3) {
    keys3.push(key)
}

console.log(keys3);
console.log(Object.keys(obj3));
console.log(Object.getOwnPropertyNames(obj3));
console.log(Reflect.ownKeys(obj3));&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const obj1 = {
            c: 1,
            2: 2,
            a: 3,
            0: 4,
            b: 5,
            1: 6
        };

        const obj2 = {
            '02': true,
            '10': true,
            '01': true,
            '2': true,
        };

        const obj3 = Object.assign({}, obj1, obj2);

        const keys3= [];
        for(const key in obj3) {
            keys3.push(key)
        }

        console.log(keys3);
        console.log(Object.keys(obj3));
        console.log(Object.getOwnPropertyNames(obj3));
        console.log(Reflect.ownKeys(obj3));
    &lt;/script&gt;--&gt;

    &lt;p&gt;
        위 예제는 객체의 스태틱 메소드인 &amp;nbsp;&lt;code&gt;assign&lt;/code&gt;을 이용하여 객체를 병합하여 &amp;nbsp;&lt;kbd&gt;key&lt;/kbd&gt;를 열거해 보는 코드입니다. &lt;br&gt;
        로그를 확인해 보면 지금까지 확인해 본 규칙에 의해 출력되는 것을 확인할 수 있습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;Detail Info&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;1) &amp;nbsp; 열거순서는 다음 규칙을 따른다.&lt;/strong&gt;&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;kbd&gt;number&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;string&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;symbol&lt;/kbd&gt; 의 순서로 정렬된다.&lt;/li&gt;
        &lt;li&gt;&lt;kbd&gt;number key&lt;/kbd&gt;는 프로퍼티들 중 가장 앞에 위치하며, 오름차순이다.&lt;/li&gt;
        &lt;li&gt;&lt;kbd&gt;string key&lt;/kbd&gt;는 객체에 추가된 당시의 순서를 유지하면서 숫자 뒤에 위치한다.&lt;/li&gt;
        &lt;li&gt;&lt;kbd&gt;Symbol key&lt;/kbd&gt;는 객체에 추가된 당시의 순서를 유지하면서 제일 마지막에 위치한다.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;p class=&quot;mt20&quot;&gt;&lt;strong&gt;2) &amp;nbsp;number(index)로 인식하는 key는 다음과 같다.&lt;/strong&gt;&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;0 이상의, 첫째자리가 0이 아닌 수는, 문자열로 입력해도 똑같이 숫자로 인식한다.&lt;/li&gt;
        &lt;li&gt;첫 째자리가 0인 두자리 이상의 숫자는 문자열로 입력해야 하고, 문자열로 인식한다.&lt;/li&gt;
        &lt;li&gt;음수는 문자열로 입력해야 하고, 문자열로 인식한다.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;p style=&quot;text-indent:15px&quot;&gt;&lt;mark&gt;&lt;strong&gt;*&lt;/strong&gt; &amp;nbsp;'index'로 인식할 수 있는 경우에 한해서만 작은 수부터 나열한다.&lt;/mark&gt;&lt;/p&gt;

    &lt;p class=&quot;mt20&quot;&gt;&lt;strong&gt;3) &amp;nbsp; 열거순서를 엄격히 지키는 경우는 다음과 같다.&lt;/strong&gt;&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;code&gt;Object.getOwnPropertyNames()&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;Reflect.ownKeys()&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;Object.assign()&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p class=&quot;mt20&quot;&gt;&lt;strong&gt;4) &amp;nbsp; ES5 하위문법인 다음의 경우에는 정확성을 보장하지 않는다.&lt;/strong&gt;&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;code&gt;for in&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;Object.keys()&lt;/code&gt;&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;JSON.stringify()&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning tip&quot;&gt;
        &lt;p&gt;위 예제로 알아본 바 &lt;code&gt;Object.keys()&lt;/code&gt; 는 순서를 보장한 것처럼 보이지만 이는 브라우저 제조사마다 제각각이기 때문에 주의해야 한다. &lt;br&gt;
            즉, 어떤 환경이느냐에 따라 출력 결과가 달라질 수 있지만 새로 등장한 ES6의 메소드들은 브라우저 제조사들 모두 표준 스펙을 잘 따르고 있기 때문에 순서를 보장합니다.
            &amp;nbsp; 결론은 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt; 시절에 사용되던 문법은 순서를 보장하지 않는다는 점만 숙지하자.
        &lt;/p&gt;
    &lt;/div&gt;



    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;loof-wrap&quot;&gt;
        &lt;div class=&quot;loof&quot;&gt;
            &lt;svg class=&quot;rl-logo&quot; width=&quot;606&quot; height=&quot;300&quot; viewBox=&quot;0 0 606 300&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; preserveAspectRatio=&quot;none&quot;&gt;
                &lt;defs&gt;
                    &lt;clipPath id=&quot;clipLogo&quot;&gt;
                        &lt;path d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;
                        &lt;/path&gt;&lt;/clipPath&gt;
                &lt;/defs&gt;
                &lt;path class=&quot;rl-logo__path&quot; d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;&lt;/path&gt;
                &lt;path class=&quot;rl-logo__track&quot; clip-path=&quot;url(#clipLogo)&quot; d=&quot;M 323.9 178.9 C 344.8 202.5 383.7 245.8 412.2 261.3 C 447.3 282.3 494.3 278 527.7 255.5 C 586.6 217 597.8 127.5 557.2 72.1 C 530.3 33.4 479 17 434.2 28.2 C 389.3 41.5 358.1 79 330.7 114.3 C 318.9 128.6 277.3 185.4 277.3 185.4 C 249.9 220.7 218.7 258.1 173.8 271.5 C 129 282.7 77.7 266.3 50.8 227.6 C 10.2 172.2 21.4 82.7 80.3 44.2 C 113.7 21.6 160.7 17.4 195.8 38.4 C 224.3 53.9 261.2 96.2 282.1 119.7&quot;&gt;&lt;/path&gt;
            &lt;/svg&gt;
        &lt;/div&gt;
        &lt;div class=&quot;name&quot;&gt;
            Jaehee's&lt;span class=&quot;b&quot;&gt; WebClub&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/ES6+</category>
      <category>겍채의 향상된 기능들</category>
      <author>jaiyah</author>
      <guid isPermaLink="true">https://webclub.tistory.com/648</guid>
      <comments>https://webclub.tistory.com/648#entry648comment</comments>
      <pubDate>Fri, 26 Feb 2021 18:39:05 +0900</pubDate>
    </item>
    <item>
      <title>shorthand property, concise method</title>
      <link>https://webclub.tistory.com/647</link>
      <description>&lt;p&gt;&lt;mark&gt;이 글은 &lt;a href=&quot;https://www.inflearn.com/course/ecmascript-6-flow&quot; target=&quot;_blank&quot;&gt;[인프런] Javascript ES6+ 제대로 알아보기 - 초급(정재남)&lt;/a&gt;를 토대로 작성되었음을 알려드립니다.&lt;/mark&gt;&lt;/p&gt;
    &lt;p&gt;&lt;br&gt;&lt;/p&gt;

    &lt;p&gt;&lt;kbd&gt;es2015&lt;/kbd&gt; 로 넘어오면서 객체를 사용함에 있어 편리성, 간결성과 더불어 다양하게 향상된 기능들을 제공해 주고 있어 이에 대해 알아보고자 합니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;h2 class=&quot;hh&quot;&gt;프로퍼티 축약, 간결한 메소드&lt;/h2&gt;
    &lt;p&gt;먼저 객체의 프로퍼티를 간결하게 작성할 수 있는 방법에 대해 알아보겠습니다. &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p class=&quot;tit&quot;&gt;shorthand properties (프로퍼티 축약)&lt;/p&gt;
    &lt;p&gt;먼저 다음의 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt;  &amp;nbsp;vs &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt; 코드를 비교하며 살펴보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;ES5 JS&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var x = 10;
var y = 20;
var obj = {
    x: x,
    y: y
};&lt;/code&gt;&lt;/pre&gt;

    &lt;script&gt;
        var x = 10;
        var y = 20;
        var obj = {
            x: x,
            y: y
        };
    &lt;/script&gt;


    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;style=&quot;text-transform:none&quot;&gt;ES6(es2015) JS&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot; &gt;var x = 10;
var y = 20;
var obj = {
    x,
    y
};&lt;/code&gt;&lt;/pre&gt;

    &lt;script&gt;
        var x = 10;
        var y = 20;
        var obj = {
            x,
            y
        };
    &lt;/script&gt;
    &lt;p&gt;위 예제는 각각 똑같은 프로퍼티키와 선언된 변수명이 같도록 하여 변수명을 할당하고자 하는 경우에 사용할 수 있고,
        이는  &amp;nbsp;&lt;kbd&gt;key&lt;/kbd&gt; 가 곧 &amp;nbsp;&lt;kbd&gt;value&lt;/kbd&gt; 를 의미하게 됩니다.
        &amp;nbsp; &lt;mark&gt;즉, 프로퍼티의 key 와 value 에 할당할 변수명이 동일한 경우 value 를 생략 가능합니다.&lt;/mark&gt;
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;프로퍼티 축약 활용&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;1) &amp;nbsp; 함수에서 객체를 리턴할 때&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const convertExtension = function (fullFileName) {
    const fullFileNameArr = fullFileName.split('.');
    const filename = fullFileNameArr[0];
    const ext = fullFileNameArr[1] &amp;&amp; fullFileNameArr[1] === 'png' ? 'jpg' : 'gif';
    return {
        filename,
        ext
    }
};

const convertResult = convertExtension( 'abc.png' );
console.log( convertResult );
console.log( convertResult.filename );
console.log( convertResult.ext );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const convertExtension = function (fullFileName) {
            const fullFileNameArr = fullFileName.split('.');
            const filename = fullFileNameArr[0];
            const ext = fullFileNameArr[1] &amp;&amp; fullFileNameArr[1] === 'png' ? 'jpg' : 'gif';
            return {
                filename,
                ext
            }
        };

        const convertResult = convertExtension( 'abc.png' );
        console.log( convertResult );
        console.log( convertResult.filename );
        console.log( convertResult.ext );
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;2) &amp;nbsp; destructuring assignment(해체 할당)&lt;/strong&gt;&lt;/p&gt;
    &lt;p&gt;
        &lt;kbd&gt;destructuring assignment&lt;/kbd&gt; 은 이후 자세히 살펴보겠지만 여기선 프로퍼티 축약에 중점을 두고 살펴보도록 하자.
    &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const {
    name: name,
    age: age
} = {
    name: '재희',
    age: 30
};
console.log(name, age);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const {
            name: name,
            age: age
        } = {
            name: '재희',
            age: 30
        };
        console.log(name, age)
    &lt;/script&gt;--&gt;

    &lt;p&gt;앞 부분이 &amp;nbsp;&lt;kbd&gt;변수명 선언부&lt;/kbd&gt;이고 &amp;nbsp;&lt;code&gt;=&lt;/code&gt; 의 뒷 부분이 &amp;nbsp;&lt;kbd&gt;값으로 할당&lt;/kbd&gt;하는 형태로 이루어져 있습니다. &lt;br&gt;
        &lt;code&gt;const&lt;/code&gt; 에 바로 객체가 와서 낯설겠지만 이것은 객체의 형태를 뒷 부분과 매칭시켜서 동일하게 매칭되어 있는 &amp;nbsp;&lt;kbd&gt;key&lt;/kbd&gt; 마다 똑같이 할당해 주는 것입니다.
        &amp;nbsp; 이 코드상에서는 &amp;nbsp;&lt;code&gt;name : name,&lt;/code&gt; 의 프로퍼티의 값에 &amp;nbsp;&lt;kbd&gt;'재희'&lt;/kbd&gt;를 넣고, &amp;nbsp;&lt;kbd&gt;age&lt;/kbd&gt; 에는 &amp;nbsp;&lt;kbd&gt;30&lt;/kbd&gt;을 넣겠다라는 코드입니다.
    &lt;/p&gt;
    &lt;p class=&quot;point-r mt20&quot;&gt;위 코드도 프로퍼티 축약형으로 다음과 같이 할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const {
    name,
    age
} = {
    name: '재희',
    age: 30
};
console.log(name, age);&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;concise methods (간결한 메소드)&lt;/p&gt;
    &lt;p&gt;간결한 메소드는 앞서 살펴본 프로퍼티 축약형과 비슷한 느낌의 문법 형태를 띠고 있습니다.&lt;/p&gt;
    &lt;p class=&quot;point-r mt20&quot;&gt;먼저 다음의 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt; &amp;nbsp;vs &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt; 코드를 비교하며 살펴보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;ES5 JS&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var obj = {
    name: 'foo',
    getName: function () { return this.name }
};&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var obj = {
            name: 'foo',
            getName: function () { return this.name }
        };
    &lt;/script&gt;--&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot; style=&quot;text-transform:none&quot;&gt;ES6(es2015) JS&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var obj = {
    name: 'foo',
    getName () { return this.name }
};&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var obj = {
            name: 'foo',
            getName () { return this.name }
        };
    &lt;/script&gt;--&gt;

    &lt;p&gt;
        &lt;kbd&gt;ES5&lt;/kbd&gt; 코드에서 &amp;nbsp;&lt;code&gt;getName&lt;/code&gt; 은 메소드 부분으로 익명함수를 프로퍼티에 할당한 것입니다. &lt;br&gt;
        이렇게 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt;에서는 이러한 할당 자체를 콜론과 함수 키워드를 생략함으로서 간결한 문법을 제공해 주고 있습니다.
        즉, 간결한 &amp;nbsp;&lt;kbd&gt;메소드 축약형&lt;/kbd&gt;입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;그렇다면 기존 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt;의 메소드와 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt;의 메소드 축약형은 어떤 차이점을 가지고 있을까요?&lt;/p&gt;
    &lt;p class=&quot;mt20 point-r&quot;&gt;다음의 코드를 통해 차이점을 살펴보도록 하자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var obj = {
    name: 'foo',
    // ES6
    getName () { return this.name; },
    // ES5
    getName2 : function () { return this.name; }
};

console.dir( obj.getName );
console.dir( obj.getName2 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var obj = {
            name: 'foo',
            // ES6
            getName () { return this.name; },
            // ES5
            getName2 : function () { return this.name; }
        };

        console.dir( obj.getName );
        console.dir( obj.getName2 );
    &lt;/script&gt;--&gt;
    &lt;p&gt;
        로그를 확인해 보면 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt;의 &amp;nbsp;&lt;code&gt;getName&lt;/code&gt; 의 경우 &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt;, &amp;nbsp;&lt;code&gt;caller&lt;/code&gt; 는 호출(invoke)을 해야만 이에 대한 정보, 즉 값을 알 수 있는 것입니다. &lt;br&gt;
        이유는 실행 환경 당시에 값에 접근하는 것이 아니라 외부 스코프에서 이미 함수가 종료된 이후에 접근(이 코드상에서)하려고 한 것이기 때문에
        명시적인 에러를 나타내고 있는 것입니다. &lt;br&gt;
        하지만 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt;에서 &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt;, &amp;nbsp;&lt;code&gt;caller&lt;/code&gt; 는 실행이 종료된 이후에 접근하려고 해도 접근이 되고 다만 값만 &amp;nbsp;&lt;code&gt;null&lt;/code&gt; 일 뿐인 것입니다. &lt;br&gt;
        정리하면, 대부분의 기능들이 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt;부터는 에러를 명시적으로 보여주면서 디버깅하기 용이하도록 제공해 주고 있기 때문에 위와 같은 에러가 표시되어 보여주고 있는 것입니다. &lt;br&gt;
        즉, &amp;nbsp;&lt;code&gt;obj.getName&lt;/code&gt; 을 호출하고 난 후 &amp;nbsp;&lt;code&gt;console.dir&lt;/code&gt; 로 보여주려고 한 상태는 함수가 이미 종료된 상태이고 이렇게 접근할 수 없는 상태임을 명시적으로 나타내 주고 있는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;그리고 또 하나 다른 점은 &amp;nbsp;&lt;code&gt;getName2&lt;/code&gt; 에는 &amp;nbsp;&lt;kbd&gt;prototype 프로퍼티&lt;/kbd&gt; 가 존재하지만 ES6의 &amp;nbsp;&lt;kbd&gt;getName&lt;/kbd&gt; 에는 &amp;nbsp;&lt;code&gt;prototype 프로퍼티&lt;/code&gt;가 없습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;prototype 프로퍼티가 있고 없고의 차이점은 무엇일까?&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var obj = {
    name: 'foo',
    getName () { return this.name; },
    getName2 : function () { return this.name; }
};

const a = new obj.getName2();
console.log( a ); // 빈 객체

const b = new obj.getName();&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var obj = {
            name: 'foo',
            getName () { return this.name; },
            getName2 : function () { return this.name; }
        };

        const a = new obj.getName2();
        console.log( a ); // 빈 객체

        const b = new obj.getName();

    &lt;/script&gt;--&gt;

    &lt;p&gt;
        &lt;kbd&gt;getName2&lt;/kbd&gt; 라는 이름으로 하는 생성자 함수로 인스턴스를 만든 것으로 즉, 생성자 함수로서 동작을 한 것입니다. &lt;br&gt;
        기존의 함수는 생성자라는 것 자체가 암묵적인 약속된 대,소문자 구별로만 사용했을 뿐 &amp;nbsp;&lt;kbd&gt;new 연산자&lt;/kbd&gt;만 사용하면 인스턴스를 생성할 수 있었기 때문에
        &lt;code&gt;getName2 : function () { return this.name; }&lt;/code&gt; 이 코드도 생성자 함수로 사용할 수 있는 것입니다. &lt;br&gt;
        그리고 이때 생성자 함수가 하는 역할 중에는 이 함수가 들고 있던 프로토타입에 대한 내용을 인스턴스에 &amp;nbsp;&lt;kbd&gt;__proto__&lt;/kbd&gt; 로 연결해 주는 역할도 하게 됩니다.
        &amp;nbsp; 그렇기 때문에 기존 메소드는 생성자 함수로도 사용이 가능했으나 새로운 메소드 축약형에서는 명시적으로 메소드 역할에 중점을 두어 명시적인 에러를 나타내게 됩니다. &lt;br&gt;
        이 의미는 여태 함수는 함수로서... 생성자 함수로서... 두 가지로 사용이 가능했었지만 &lt;kbd&gt;ES6&lt;/kbd&gt;에 와서는 생성자 함수로서의 기능을 제약시킨 것입니다.
        즉, 메소드는 본연의 메소드로서의 역할만 하라는 뜻이고 &amp;nbsp;&lt;mark&gt;이 메소드로 딴 짓하면 친절하게 내가 에러를 내주도록 해줄게...&lt;/mark&gt;라는 뜻입니다. &lt;br&gt;
        그리고 이러한 본래의 역할 구분으로 인해 함수가 가벼워진 측면도 있습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning check&quot;&gt;
        &lt;p&gt;
            메소드 축약형을 사용하면 생성자 함수로 사용할 수 없고 &amp;nbsp;&lt;kbd&gt;prototype 프로퍼티&lt;/kbd&gt;가 존재하지 않으므로 오로지 함수 본연의 기능만 할 수 있도록 변경된 것입니다.
        &lt;/p&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;Detail Info&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;1) &amp;nbsp; :function 키워드 제거&lt;/strong&gt;&lt;/p&gt;
    &lt;p class=&quot;mt20&quot;&gt;&lt;strong&gt;2) &amp;nbsp; &lt;kbd&gt;super&lt;/kbd&gt; 명렁어로 상위 클래스에 접근 가능&lt;/strong&gt;&lt;/p&gt;
    &lt;p&gt;&lt;code&gt;super&lt;/code&gt; 명령어는 클래스(Class) 파트에서 자세히 다룰 예정으로 간단히 개념만 짚고 넘어가보도록 하겠습니다. &lt;/p&gt;
    &lt;p&gt;
        &lt;code&gt;super&lt;/code&gt; 는 사전적 의미로 &quot;상위의&quot; 그리고 &amp;nbsp;&lt;code&gt;sub&lt;/code&gt;는 &quot;하위의&quot;란 뜻을 가지고 있습니다. &lt;br&gt;
        그래서 &lt;kbd&gt;super Class(상위 클래스)&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;sub Class(하위 클래스)&lt;/kbd&gt; 가 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt;에 새롭게 등장했습니다.
    &lt;/p&gt;
    &lt;ul class=&quot;mt20&quot;&gt;
        &lt;li&gt;&lt;kbd&gt;super()&lt;/kbd&gt; : &amp;nbsp;&lt;mark&gt;상위에 있는 내용을 호출해라&lt;/mark&gt;란 명령어로서 프로토타입 체이닝상에 있는 상위에 있는 내용을 가지고 오는 것입니다.&lt;/li&gt;
        &lt;li&gt;&lt;kbd&gt;sub()&lt;/kbd&gt; : &lt;/li&gt;
    &lt;/ul&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const Person = {
    greeting: function () { return 'hello'; }
};

const friend = {
    greeting: function () {
        return 'hi, ' + super.greeting();
    }
};

// ES5 문법
Object.setPrototypeOf(friend, Person); // friend 의 프로토타입을 Person 으로 해라
&lt;/code&gt;&lt;/pre&gt;

    &lt;p class=&quot;point-r&quot; style=&quot;margin-top: 30px;&quot;&gt;&lt;code&gt;Object.setPrototypeOf(friend, Person);&lt;/code&gt; 는 내부적으로 다음과 같은 코드로 동작합니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;Object.setPrototypeOf(friend, Person);
// friend.__proto__ = { greeting: function() {} }

// 위 setPrototypeOf 은 아래 내용과 같다.
const Person = function () { };
Person.prototype.greeting = function () { return 'hello'; };

const friend = new Person();
friend.greeting = function () {
    return 'hi, ' + this.__proto__.greeting();
}&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const Person = {
            greeting: function () { return 'hello'; }
        };

        const friend = {
            greeting: function () {
                return 'hi, ' + super.greeting();
            }
        };

        Object.setPrototypeOf(friend, Person);
    &lt;/script&gt;--&gt;

    &lt;!--&lt;script&gt;
        Object.setPrototypeOf(friend, Person);

        const Person = function () { };
        Person.prototype.greeting = function () { return 'hello'; };

        const friend = new Person();
        friend.greeting = function () {
            return 'hi, ' + this.__proto__.greeting();
        }
    &lt;/script&gt;--&gt;

    &lt;p&gt;
        위 코드상에서 &amp;nbsp;&lt;code&gt;Object.setPrototypeOf(friend, Person);&lt;/code&gt;의 &amp;nbsp;&lt;code&gt;setPrototypeOf&lt;/code&gt; 는 &amp;nbsp;&lt;kbd&gt;friend&lt;/kbd&gt;라는 녀석을 인스턴스로 하고
        &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt;이라는 녀석을 &lt;br&gt;생성자 함수로 지정해라라는 내용입니다. &lt;br&gt;
        그렇게 되면 &amp;nbsp;&lt;kbd&gt;friend&lt;/kbd&gt; 의 프로토타입상의 생성자 함수가 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt; 이 되고 &amp;nbsp;&lt;kbd&gt;Person&lt;/kbd&gt; 에 있는 객체가 프로토타입이 되게 됩니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;위에서 언급한 내용을 생각하면서 예제를 다시 분석해보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const Person = {
    greeting () { return 'hello'; }
};

const friend = {
    greeting () {
        return 'hi, ' + super.greeting();
    }
};

Object.setPrototypeOf(friend, Person);
console.log( Object.setPrototypeOf( friend, Person ) );
console.log( friend );

friend.greeting();&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 const Person = {
			 greeting () { return 'hello'; }
		 };

		 const friend = {
			 greeting () {
				 return 'hi, ' + super.greeting();
			 }
		 };

		 Object.setPrototypeOf(friend, Person);
		 console.log( Object.setPrototypeOf( friend, Person ) );
		 console.log( friend );

		 friend.greeting();
	 &lt;/script&gt;--&gt;

    &lt;p&gt;
        기존 메소드 표기법으로 작성하면 동작하지 않기 때문에 위 예제를 메소드 축양형으로 변경한 코드이며, &amp;nbsp;&lt;code&gt;super&lt;/code&gt; 라는 접근자로 상위의 내용을 가져다 사용할 수 있게 됩니다.
        &amp;nbsp; 즉, 자신의 프로토타입 체이닝상에 있는 상위에 있는 메소드를 호출할 수 있습니다. &lt;br&gt;
        위 예제에서 friend 는 greeting 이라는 메소드를 자신이 가지고 있는 형태이고, 프로토타입 체이닝상에도 greeting 이라는 메소드도 있는 형태입니다.
    &lt;/p&gt;
    &lt;p&gt;&lt;img src=&quot;../../images/concise_02.png&quot; width=&quot;568&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
    &lt;p&gt;&lt;code&gt;friend.greeting();&lt;/code&gt; 이와 같이 호출할 때 프로토타입 체이닝을 생각해 보면 가장 가까운 메소드부터 찾고, 여기서는 자신에 있는 메소드인 &amp;nbsp;&lt;code&gt;greeting&lt;/code&gt; 부터 실행할 것입니다.
        &amp;nbsp; 그런데 상위에 있는 것을 실행한다고 할 때 &amp;nbsp;&lt;code&gt;friend.__proto__.greeting();&lt;/code&gt; 하면 &amp;nbsp;&lt;kbd&gt;'hello'&lt;/kbd&gt; 만 나올 것입니다.
    &lt;/p&gt;
    &lt;p&gt;본래 기존 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt; 방식에서는 상위에 있는 것을 호출할 방법이 마땅치 않았지만 &amp;nbsp;&lt;code&gt;super&lt;/code&gt; 접근자를 이용하면 바로 상위에 있는 것까지 접근할 수 있는 길이 열린 것입니다.  &lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;3) &amp;nbsp; &lt;kbd&gt;prototype 프로퍼티&lt;/kbd&gt;가 없고 이는 곧 생성자함수로 사용 불가하다.&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const Person = {
  greeting () { return 'hello' }
}

const p = new Person.greeting();&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;4) &amp;nbsp; 그 밖에는 모두 기존 함수/메소드와 동일하게 동작한다.&lt;/strong&gt;&lt;/p&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const obj = {
  a () { console.log('obj log') },
  log () { console.log(this) }
};

console.log(obj.a.name);
setTimeout(obj.a, 1000);
obj.log();
obj.log.call([]);
setTimeout(obj.log.bind('haha'), 2000);&lt;/code&gt;&lt;/pre&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;loof-wrap&quot;&gt;
        &lt;div class=&quot;loof&quot;&gt;
            &lt;svg class=&quot;rl-logo&quot; width=&quot;606&quot; height=&quot;300&quot; viewBox=&quot;0 0 606 300&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; preserveAspectRatio=&quot;none&quot;&gt;
                &lt;defs&gt;
                    &lt;clipPath id=&quot;clipLogo&quot;&gt;
                        &lt;path d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;
                        &lt;/path&gt;&lt;/clipPath&gt;
                &lt;/defs&gt;
                &lt;path class=&quot;rl-logo__path&quot; d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;&lt;/path&gt;
                &lt;path class=&quot;rl-logo__track&quot; clip-path=&quot;url(#clipLogo)&quot; d=&quot;M 323.9 178.9 C 344.8 202.5 383.7 245.8 412.2 261.3 C 447.3 282.3 494.3 278 527.7 255.5 C 586.6 217 597.8 127.5 557.2 72.1 C 530.3 33.4 479 17 434.2 28.2 C 389.3 41.5 358.1 79 330.7 114.3 C 318.9 128.6 277.3 185.4 277.3 185.4 C 249.9 220.7 218.7 258.1 173.8 271.5 C 129 282.7 77.7 266.3 50.8 227.6 C 10.2 172.2 21.4 82.7 80.3 44.2 C 113.7 21.6 160.7 17.4 195.8 38.4 C 224.3 53.9 261.2 96.2 282.1 119.7&quot;&gt;&lt;/path&gt;
            &lt;/svg&gt;
        &lt;/div&gt;
        &lt;div class=&quot;name&quot;&gt;
            Jaehee's&lt;span class=&quot;b&quot;&gt; WebClub&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/ES6+</category>
      <category>간결한 메소드</category>
      <category>축약 메소드</category>
      <author>jaiyah</author>
      <guid isPermaLink="true">https://webclub.tistory.com/647</guid>
      <comments>https://webclub.tistory.com/647#entry647comment</comments>
      <pubDate>Fri, 26 Feb 2021 18:36:07 +0900</pubDate>
    </item>
    <item>
      <title>default parameter, rest parameter, spread operator</title>
      <link>https://webclub.tistory.com/646</link>
      <description>&lt;p&gt;&lt;mark&gt;이 글은 &lt;a href=&quot;https://www.inflearn.com/course/ecmascript-6-flow&quot; target=&quot;_blank&quot;&gt;[인프런] Javascript ES6+ 제대로 알아보기 - 초급(정재남)&lt;/a&gt;를 토대로 작성되었음을 알려드립니다.&lt;/mark&gt;&lt;/p&gt;
    &lt;p&gt;&lt;br&gt;&lt;/p&gt;

    &lt;p&gt;&lt;kbd&gt;es2015&lt;/kbd&gt; 이후 새로운 매개 변수와 함수 그리고 그에 따른 기타 관련 내용에 대한 문법을 알아보도록 하겠습니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;h2 class=&quot;hh&quot;&gt;매개변수 기본값, 나머지 매개변수, 펼치기(전개) 연산자&lt;/h2&gt;
    &lt;p&gt;우선 새로운 매개 변수와 연산자에 대해 알아보고 이후 새로운 함수에 대해 살펴보도록 하겠습니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;default parameter(매개변수 기본값)&lt;/p&gt;
    &lt;p&gt;&lt;kbd&gt;default parameter&lt;/kbd&gt; 는 함수의 인자로 넘어오는 것에 기본값을 정의해 줄 수 있는 것입니다.  &lt;/p&gt;
    &lt;p class=&quot;point-r mt20&quot;&gt;아래의 기존 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt; 와 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt; 가 어떻게 달라졌는지 예제를 통해 살펴보도록 하자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js [ES5]&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const f = function (x, y, z) {
    x = x ? x : 4; // x 가 있다면 x 를 할당하고 없으면 4을 할당하라.

    // 위 삼항 연산자를 더 간단히 표현한 것으로 y 가 true 면 y 에 넘어온 값을 할당하고 그렇지 않다면 5 를 할당하라.
    y = y || 5;

    if (!z) { // z 가 false 에 해당하는 값이라면 true 로 바꿔서 z 에 6 을 할당하라.
        z = 6
    }

    console.log(x, y, z)
};
f(1);

f(0, null);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const f = function (x, y, z) {
            x = x ? x : 4;
            y = y || 5;

            if (!z) {
                z = 6
            }

            console.log(x, y, z)
        };
        f(1);

        f(0, null);
    &lt;/script&gt;--&gt;

    &lt;p&gt;위 코드처럼 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt; 에서는 인자에 대한 판단을 늘 함수 내부에서 정의해 사용해 왔습니다.&lt;/p&gt;
    &lt;p&gt;
        그런데 &lt;kbd&gt;f(1)&lt;/kbd&gt; 은 의도대로 로그값이 출력되었지만 &amp;nbsp;&lt;kbd&gt;f(0, null);&lt;/kbd&gt; 의도한 대로 출력되지 않은 것을 확인할 수 있습니다. &lt;br&gt;
        0 은 &amp;nbsp;&lt;code&gt;false&lt;/code&gt; 로 형변환되어  4 가 출력되고 &amp;nbsp;&lt;code&gt;null&lt;/code&gt; 역시 &amp;nbsp;&lt;code&gt;false&lt;/code&gt; 로 형변환되어 &amp;nbsp;&lt;kbd&gt;4, 5, 6&lt;/kbd&gt; 이 출력된 것입니다.
        &lt;br&gt;
        그렇기 때문에 위와 같이 판단하는 코드는 정확성이 떨어지고 이를 판단하기 위해 더 많은 코드를 작성하게 될 것입니다. &lt;br&gt;
        예를 들어 &amp;nbsp;&lt;code&gt;x !== undefined ? x : 4;&lt;/code&gt; 혹은 &amp;nbsp;&lt;code&gt;typeof y !== 'undefined' || 5;&lt;/code&gt; 와 같이 &amp;nbsp;&lt;code&gt;undefined&lt;/code&gt;
        일 경우에만 기본값을 할당해 주기를 바라는 의도에서 코드를 작성하려면 해야할 일이 많다고 할 수 있습니다.
    &lt;/p&gt;
    &lt;p class=&quot;point-r mt20&quot;&gt;Not Good !!! &amp;nbsp;&amp;nbsp; Not Right !!! &amp;nbsp;&amp;nbsp; I have a lot of work to do !!!&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const f = function (x, y, z) {
  x = (x !== undefined) ? x : 3;
  y = (typeof x !== &quot;undefined&quot;) ? y : 4;

  console.log(x, y);
}

f(0, null);&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;ES6&lt;/kbd&gt; 에서 위 코드를 &amp;nbsp;&lt;kbd&gt;default parameter&lt;/kbd&gt; 를 사용하면 다음과 같습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const f = function (x = 4, y = 5, z = 6) {
    console.log( x, y, z );
};

f( 0, null );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const f = function (x = 4, y = 5, z = 6) {
            console.log( x, y, z );
        };

        f( 0, null );
    &lt;/script&gt;--&gt;

    &lt;p class=&quot;point-r mt20&quot;&gt;위와 비슷한 예제로 다음의 값을 예상해 보기 바랍니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; const f = function (a = 1, b = 2, c = 3, d = 4, e = 5, f = 6) {
    console.log(a, b, c, d, e, f);
};

f(7, 0, &quot;&quot;, false, null)&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const f = function (a = 1, b = 2, c = 3, d = 4, e = 5, f = 6) {
            console.log(a, b, c, d, e, f);
        };

        f(7, 0, &quot;&quot;, false, null)
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;default parameter 에 대해 좀더 자세히 알아보기&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;1) &amp;nbsp;&lt;code&gt;undefined&lt;/code&gt; 혹은 누락된 파라미터에 대해서만 &amp;nbsp;&lt;kbd&gt;default parameter&lt;/kbd&gt; 가 동작을 합니다. &lt;/strong&gt;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;2) &amp;nbsp;그렇다면 &amp;nbsp;&lt;kbd&gt;식&lt;/kbd&gt;은 어떻게 될까?&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const f = function (x = 1, y = 3 + x) {
    console.log(x, y);
};

f();&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const f = function (x = 1, y = 3 + x) {
            console.log(x, y);
        };

        f();
    &lt;/script&gt;--&gt;
    &lt;p&gt;로그를 확인해 보면 에러없이 출력되는데 이러한 &amp;nbsp;&lt;kbd&gt;식&lt;/kbd&gt;이 가능한 이유는 &amp;nbsp;&lt;mark&gt;let 을 선언한 것과 동일한 효과&lt;/mark&gt;를 나타낸다라는 말과 같습니다.&lt;/p&gt;
    &lt;p class=&quot;mt20 point-r&quot;&gt;만약에 아래와 같은 함수가 있다고 가정해 보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function fn(a, b, c) { }

fn(1, 2, 3);&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;위 코드는 자바스크립트 엔진이 내부적으로 다음과 같이 처리하게 됩니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;1.&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function fn(a, b, c) {
    var a = 1;
    var b = 2;
    var c = 3;
}

fn(1, 2, 3);&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;이렇게 &amp;nbsp;&lt;code&gt;fn(1, 2, 3);&lt;/code&gt; 처럼 호출하면 실행 컨텍스트가 열리면서 인자 하나하나를 변수로 선언해서 변수에 값을 할당하는 것까지의 과정을 내부에서 처리하게 됩니다.
        &amp;nbsp;그렇기 때문에 함수의 인자로 넘어온 매개변수는 함수 내부 변수로서만 존재하게 됩니다.
    &lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;위 코드에서 &amp;nbsp;&lt;kbd&gt;default parameter&lt;/kbd&gt; 를 할당하는 순간 다음과 같은 과정이 내부적으로 처리됩니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function fn(a = 1, b = 2, c = 3) { }

fn(1, 2, 3);&lt;/code&gt;&lt;/pre&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function fn(a = 1, b = 2, c = 3) {
    let a = (a !== undefined) ? a : 1;
    let b = (b !== undefined) ? b : 2;
    let c = (c !== undefined) ? c : 3;
}

fn( 1, 2, 3 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function fn(a = 1, b = 2, c = 3) {
            let a = (a !== undefined) ? a : 1;
            let b = (b !== undefined) ? b : 2;
            let c = (c !== undefined) ? c : 3;
        }

        fn( 1, 2, 3 );
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;위와 같은 메커니즘을 이해했다면 다음의 코드를 살펴보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function fn(a = 1, b = a + 1, c = 3) {
    console.log( a, b, c );
}

fn( 1, undefined, 3 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function fn(a = 1, b = a + 1, c = 3) {
            console.log( a, b, c );
        }

        fn( 1, undefined, 3 );
    &lt;/script&gt;--&gt;

    &lt;p class=&quot;mt20&quot;&gt;위 코드는 잘 동작하지만 아래와 같이 &amp;nbsp;&lt;code&gt;b = a + 1&lt;/code&gt; 대신에 &amp;nbsp;&lt;code&gt;b = c + 1&lt;/code&gt; 로 변경한다면 어떻게 될까? &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; function fn(a = 1, b = c + 1, c = 3) {
    console.log( a, b, c );
}

fn( 1, undefined, 3 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function fn(a = 1, b = c + 1, c = 3) {
            console.log( a, b, c );
        }

        fn( 1, undefined, 3 );
    &lt;/script&gt;--&gt;

    &lt;!--
        let a;
        let b = c + 1;
        let c;
    --&gt;
    &lt;p&gt;로그를 확인하면 &amp;nbsp;&lt;kbd&gt;Cannot access 'c' before initialization&lt;/kbd&gt; 인 참조 에러가 발생합니다. &lt;br&gt;
        즉, &amp;nbsp;&lt;code&gt;let&lt;/code&gt; 과 같이 동작하기 때문에 &amp;nbsp;&lt;code&gt;c = 3&lt;/code&gt; 이 &amp;nbsp;&lt;code&gt;b = c + 1&lt;/code&gt; 뒤에 선언되어 있으므로 &amp;nbsp;&lt;kbd&gt;TDZ&lt;/kbd&gt; 로 인해 초기화되지 않은 변수에 접근할 수 없는 것입니다.
        다시 말해, 순서가 중요하다고 할 수 있습니다.
    &lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;이렇게 위와 같은 이유로 &amp;nbsp;&lt;kbd&gt;식&lt;/kbd&gt;이 올 수 있기 때문에 다음과 같은 작성도 가능합니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const getDefault = function () {
    console.log('getDefault Called.');

    return 10;
};

const sum = function (x, y = getDefault()) {
    console.log(x + y);
};

sum(1, 2);
sum(1);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const getDefault = function () {
            console.log('getDefault Called.');

            return 10;
        };

        const sum = function (x, y = getDefault()) {
            console.log(x + y);
        };

        sum(1, 2);
        sum(1);
    &lt;/script&gt;--&gt;
    &lt;p class=&quot;point-r mt20&quot;&gt;위 코드를 다음과 같이 좀더 활용해 볼 수도 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const checkValid = function () {
    console.error('There are no arguments.');
    return 0;
};

const sum = function (x = checkValid(), y = checkValid()) {
    console.log(x + y);
};

sum(1, 2);
sum();&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 const checkValid = function () {
			 console.error('There are no arguments.');
			 return 0;
		 };

		 const sum = function (x = checkValid(), y = checkValid()) {
			 console.log(x + y);
		 };

		 sum(1, 2);
		 sum();
	 &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;3) &amp;nbsp;&lt;kbd&gt;let&lt;/kbd&gt; 을 선언한 것과 동일한 효과를 나타낸다.&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const f = function (x = 1, y = 2 + x) {
    let z = y + 3;
    x = 4;
    console.log(x, y, z);
};
f();&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const f = function (x = 1, y = 2 + x) {
            let z = y + 3;
            x = 4;
            console.log(x, y, z);
        };
        f();
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;4) TDZ(Temporal Dead Zone)&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const multiply = function (x, y = x * 2) {
    console.log(x * y);
};
multiply(2, 3);
multiply(2);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const multiply = function (x, y = x * 2) {
            console.log(x * y);
        };
        multiply(2, 3);
        multiply(2);
    &lt;/script&gt;--&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const multiply = function (x = y * 3, y) {
    console.log(x, y);
};
multiply(2, 3);
multiply(undefined, 2);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const multiply = function (x = y * 3, y) {
            console.log(x, y);
        };
        multiply(2, 3);
        multiply(undefined, 2);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;5) 기본값으로 할당하고자 하는 값이 변수일 경우의 주의사항&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let a = 10;
let b = 20;

function f(aa = a, b = b) { // 기본값으로 할당하고자 하는 값인 a 가 할당할 aa 와 달라야 한다. a = a(X)
    console.log( aa, b );
}

f( 1, 2 ); // 인자를 전달하고 있기 때문에 디폴트값인 a 를 쳐다보지도 않음.
f( undefined, 2 ); // 첫 인자가 undefined 이기 때문에 디폴트값을 바라보고 에러없이 출력됨.
f( 1 ); // TDZ 로 인해 b is not defined 가 출력
f();&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        let a = 10;
        let b = 20;

        function f(aa = a, b = b) { // 기본값으로 할당하고자 하는 값인 a 가 할당할 aa 와 달라야 한다. a = a(X)
            console.log( aa, b );
        }

        f( 1, 2 ); // 인자를 전달하고 있기 때문에 디폴트값인 a 를 쳐다보지도 않음.
        f( undefined, 2 ); // 첫 인자가 undefined 이기 때문에 디폴트값을 바라보고 에러없이 출력됨.
        f( 1 ); // TDZ 로 인해 b is not defined 가 출력
        f();
    &lt;/script&gt;--&gt;
    &lt;p&gt;&lt;code&gt;f(1);&lt;/code&gt; 을 호출하면 &amp;nbsp;&lt;kbd&gt;b is not defined&lt;/kbd&gt; 가 출력되는 것은 다음과 같은 이유때문입니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let b = b;

// 자바스크립트 엔진은 다음과 같은 동작을 수행한다.
let b; // 메모리 주소에 할당하기 전

// b 는 메모리에 참조하기도 전인 상태로
// 즉, 오른쪽의 b 는 아직 참조할 주소가 없는 녀석을 들고 올려고 하니 TDZ 에 걸리는 것임
b = b;
&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;


    &lt;p&gt;&lt;strong&gt;6) &amp;nbsp;arguments 에도 영향을 줄까?&lt;/strong&gt;&lt;/p&gt;
    &lt;p&gt;먼저 arguments(유사배열 객체)에 대해 알아보자.&lt;/p&gt;
    &lt;p&gt;&lt;kbd&gt;arguments&lt;/kbd&gt; 는 유사배열 객체(&lt;b&gt;array-like object&lt;/b&gt;)라고 합니다. &lt;br&gt;
        이것은 객체이면서, 각 프로퍼티의 키가 인덱스이고, &amp;nbsp;&lt;code&gt;length&lt;/code&gt; 라는 프로퍼티가 있는 객체를 말합니다. &lt;br&gt;
        &lt;kbd&gt;ES5&lt;/kbd&gt; 때부터 있는 것으로 함수의 인자들을 유사배열 객체로 만들어 주며, &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt; 는 함수의 인자로 받고자 하는 갯수와 상관없이 실제로 넘어온 인자들의 유사배열입니다.
        즉, 넘겨준 인자들을 모두 받을 수 있는 객체입니다.
    &lt;/p&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const arg = function () {
    console.log( arguments );
};

arg( 1, 2, 3 );&lt;/code&gt;&lt;/pre&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; const arg = function () {
    console.log( arguments ); // { 0: 1, 1: 2, 2: 3, length: 3, callee: , ....}

    // 유사배열객체는 실제로 배열이 아니기 때문에 배열 메소드를 사용할 수 없다.
    // # pop() : 맨 마지막 요소를 뽑아주는 메소드
    console.log( arguments.pop() ); // 에러 발생

    // 배열 메소드를 사용하기 위해 배열 메소드를 빌려서 사용
    console.log( Array.prototype.pop.call( arguments ) );

    // 또 다른 방법으로 넘겨온 인자를 배열로 만든 후에 배열 메소드인 pop 을 사용
    const args = Array.prototype.slice.call(arguments);
    console.log( args );
    console.log( args.pop() );

};

arg( 1, 2, 3 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const arg = function () {
            console.log( arguments ); // { 0: 1, 1: 2, 2: 3, length: 3, callee: , ....}

            // 유사배열객체는 실제로 배열이 아니기 때문에 배열 메소드를 사용할 수 없다.
            // # pop() : 맨 마지막 요소를 뽑아주는 메소드
            console.log( arguments.pop() ); // 에러 발생

            // 배열 메소드를 사용하기 위해 배열 메소드를 빌려서 사용
            console.log( Array.prototype.pop.call( arguments ) );

            // 또 다른 방법으로 넘겨온 인자를 배열로 만든 후에 배열 메소드인 pop 을 사용
            const args = Array.prototype.slice.call(arguments);
            console.log( args );
            console.log( args.pop() );

        };

        arg( 1, 2, 3 );
    &lt;/script&gt;--&gt;

    &lt;p&gt;
        사실 이제는 &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt; 객체를 알아야 할 필요성이 없지만 다음에 다룰 &amp;nbsp;&lt;kbd&gt;rest parameter&lt;/kbd&gt; 가 &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt; 와 유사함과 동시에
        이를 대체하기 위한 것이기에 간단히 짚어보았으며, 계속해서 이런 유사배열객체인 &amp;nbsp;&lt;kbd&gt;arguments&lt;/kbd&gt; 에도 디폴트 파라미터에 영향을 줄 것인가에 대해 다음 코드를 통해 알아보도록 하겠습니다.
    &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const a = function(a = 1, b = 2, c = 3) {
    console.log(arguments);
    console.log(a, b, c);
};

a();
a(4);
a(4, 5);
a(4, undefined, 6);
a(4, 5, 6);&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&lt;code&gt;a();&lt;/code&gt; 를 호출하면 인자로 넘겨준 값은 없지만 디폴트 파라미터가 정의되어 있기 때문에
        과연 &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt; 에도 기본값이 정의되어 있을까를 확인해 보았더디 그 어떤 값도 확인할 수 없습니다. &lt;br&gt;
        즉, &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt; 는 실제로 값을 넘겨준 것에만 종속되어 있는 것입니다. &lt;br&gt;
        이 내용에 대해 깊이 알아야 필요도 활용할 일도 거의 없기 때문에 이러한 객체가 있다라는 정도로만 알고 넘어가 보자.
    &lt;/p&gt;

    &lt;!--&lt;script&gt;

        const a = function(a = 1, b = 2, c = 3) {
            console.log(arguments);
            console.log(a, b, c);
        };

        a();
        a(4);
        a(4, 5);
        a(4, undefined, 6);
        a(4, 5, 6);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p class=&quot;hh&quot;&gt;rest parameter(나머지 매개변수)&lt;/p&gt;
    &lt;p&gt;&lt;kbd&gt;rest&lt;/kbd&gt; 는 사전적 의미로 나머지로서 &amp;nbsp;&lt;mark&gt;~~를 제외한 나머지&lt;/mark&gt;라는 의미로 해석할 수 있습니다.&lt;/p&gt;
    &lt;p&gt;먼저 기존 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt; 시절의 코드를 살펴보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function foo (a, b) {
    a = 1;
    arguments[0] = 2;
    console.log(a, arguments[0]);
}

foo(10, 20);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function foo (a, b) {
            a = 1;
            arguments[0] = 2;
            console.log(a, arguments[0]);
        }

        foo(10, 20);
    &lt;/script&gt;--&gt;

    &lt;p&gt;위 로그를 확인해 보면 &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt; 객체가 변수 a 에 영향을 준 것을 확인할 수 있습니다. &lt;br&gt;
        다시 말해, &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt; 는 인자에는 영향을 준다는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;
        이렇게 &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt; 객체는 위에서 알아본 바와 같이 불확실성이 높고 유사배열 객체이기 때문에 실제 배열의 메소드를 사용하기 위해서는
        프로토타입에 있는 &amp;nbsp;&lt;code&gt;call&lt;/code&gt;, &amp;nbsp;&lt;code&gt;apply&lt;/code&gt; 를 사용해야 하는 등 난이도 높은 코드를 요구하기에 불편한 점이 많습니다.
    &lt;/p&gt;
    &lt;p&gt;그래서 이러한 에로사항을 해소해 주기 위해 나온 것이 &amp;nbsp;&lt;kbd&gt;rest parameter&lt;/kbd&gt; 라고 불리는 녀석입니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;다음의 코드를 먼저 살펴보도록 하겠습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function f (x, y) {
    var rest = Array.prototype.slice.call(arguments, 2);
    console.log(rest);
}

f(1, 2, true, null, undefined, 10);&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 function f (x, y) {
			 var rest = Array.prototype.slice.call(arguments, 2);
			 console.log(rest);
		 }

		 f(1, 2, true, null, undefined, 10);
	 &lt;/script&gt;--&gt;
    &lt;p&gt;
        위 코드에서 함수는 본래 받으려고 하는 인자가 2개뿐 인데도 불구하고 값을 여러 개 넘겨줬을 때 이러한 인자들을 제어하기 위해서는 기존에는 위에서 알아본
        arguments 객체를 사용해야 했지만 아래 코드와 같이 여러 인자를 넘겨받을 수 있습니다.
    &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function f (x, y, ...z) {
    console.log(z);
}

f(1, 2, true, null, undefined, 10);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function f (x, y, ...z) {
            console.log(z);
        }

        f(1, 2, true, null, undefined, 10);
    &lt;/script&gt;--&gt;

    &lt;p&gt;위 코드를 확인해 보면 &amp;nbsp;&lt;kbd&gt;x&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;y&lt;/kbd&gt; 를 제외한 나머지 매개변수들을 모두 넘겨받는 것을 확인할 수 있고 이 넘겨받은 타입은 순수 배열 객체라는 점입니다.
        &lt;br&gt;
        즉, 넘겨 받은 나머지 인자들을 취합하여 배열로 만들어주는 것입니다.
    &lt;/p&gt;
    &lt;p class=&quot;mt20&quot;&gt;그리고 &amp;nbsp;&lt;code&gt;arguments&lt;/code&gt; 를 대체하려면 다음과 같이 작성할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function f (...z) {
    console.log(z);
}

f(1, 2, true, null, undefined, 10);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function f (...z) {
            console.log(z);
        }

        f(1, 2, true, null, undefined, 10);
    &lt;/script&gt;--&gt;

    &lt;p&gt;여기서 주의할 사항은 나머지는 맨 마지막이기 때문에 매개변수를 정의할 위치도 맨 마지막이어야 하며, 오직 한 번만 사용할 수 있습니다.&lt;/p&gt;


    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function fn(a, b, c, ...z) {
    console.log( z );
}

fn( 1, 2 );&lt;/code&gt;&lt;/pre&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function fn(a, ...z) {
    console.log( z );
}

fn( 1, 2 );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function fn(a, ...z) {
            console.log( z );
        }

        fn( 1, 2 );
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;Detail Info&lt;/p&gt;
    &lt;p class=&quot;&quot;&gt;&lt;strong&gt;1) &amp;nbsp;...[매개변수명]&lt;/strong&gt;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;2) &amp;nbsp;오직 한 번, 매개 변수의 가장 마지막에서만 사용&lt;/strong&gt; &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const f = function (_first, ...rest, _last) {
  console.log(_first, _last)
}
f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 const f = function (_first, ...rest, _last) {
			 console.log(_first, _last)
		 };
		 f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
	 &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;3) &amp;nbsp;객체의 &amp;nbsp;&lt;code&gt;setter&lt;/code&gt; 에서 사용할 수 없다.&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let person = {
    name: 'name',
    age : 30,
    get personInfo(){
        return this.name + ' ' + this.age
    },
    set personInfo (...val) {
        this.name = val[0];
        this.age  = val[1];
    }
};
console.log(person.personInfo);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        let person = {
            name: 'name',
            age : 30,
            get personInfo(){
                return this.name + ' ' + this.age
            },
            set personInfo (...val) {
                this.name = val[0];
                this.age  = val[1];
            }
        };
        console.log(person.personInfo);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;게터와 세터&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const obj = {
    _a : 'a',
    get a () { return this._a; },
    set a (v) { this._a = v; }
};

obj.a = 10;
console.log( obj.a );
console.log( obj );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const obj = {
            _a : 'a',
            get a () { return this._a; },
            set a (v) { this._a = v; }
        };

        obj.a = 10;
        console.log( obj.a );
        console.log( obj );
    &lt;/script&gt;--&gt;

    &lt;p&gt;&lt;code&gt;obj.a = 10;&lt;/code&gt; 을 하면 세터가 동작하여 &amp;nbsp;&lt;kbd&gt;_a&lt;/kbd&gt; 에 10 을 할당하게 되고, &amp;nbsp;&lt;code&gt;console.log( obj.a );&lt;/code&gt; 출력하라고 하면 게터가 동작하여
        &amp;nbsp;&lt;kbd&gt;_a&lt;/kbd&gt; 값을 출력합니다. &lt;br&gt;
        그리고 &amp;nbsp;&lt;kbd&gt;obj&lt;/kbd&gt; 에는 &amp;nbsp;&lt;code&gt;{_a: 10}&lt;/code&gt; 를 확인할 수 있습니다. &lt;br&gt;
    &lt;/p&gt;
    &lt;p&gt;세터는 하나의 프로퍼티에 대해서 전달받은 하나의 프로퍼티 값만을 지정하는 역할을 합니다. &lt;br&gt;
        그리고 하나의 프로퍼티 키인 여기서는 &amp;nbsp;&lt;kbd&gt;_a&lt;/kbd&gt; 에서 하나의 &amp;nbsp;&lt;code&gt;value&lt;/code&gt; 밖에 할당할 수 밖에 없는 구조입니다. &lt;br&gt;
        배열이라고 해도 배열 전체를 하나(통)로 할당할 수 밖에 없습니다. 즉, 하나의 키에는 하나의 값만 할당할 수 있습니다. &lt;br&gt;
        그렇기 때문에 세터에는 값을 여러 개를 정의할 수 없으므로 나머지 매개변수를 사용할 수 없는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;설령 세터에 &amp;nbsp;&lt;code&gt;set a (x, y) { this._a = v; }&lt;/code&gt; 이와 같이 두 개를 지정한다고 해도 본래부터 하나의 인자만 받도록 설계되어 있기 때문에 에러가 발생합니다.&lt;/p&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;4) &amp;nbsp;&lt;kbd&gt;arguments&lt;/kbd&gt;를 대체한다.&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function argsAlternate (...args) {
    console.log(args.length, arguments.length);
    console.log(args[0], arguments[0]);
    console.log(args[args.length - 1], arguments[arguments.length - 1]);
    args[1] = 10;
    arguments[1] = 20;
    console.log(args[1], arguments[1]);
}

argsAlternate(1, 2, 3, 4);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        function argsAlternate (...args) {
            console.log(args.length, arguments.length);
            console.log(args[0], arguments[0]);
            console.log(args[args.length - 1], arguments[arguments.length - 1]);
            args[1] = 10;
            arguments[1] = 20;
            console.log(args[1], arguments[1]);
        }

        argsAlternate(1, 2, 3, 4);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;h2 class=&quot;hh&quot;&gt;spread operator(펼치기 연산자, 전개 연산자)&lt;/h2&gt;
    &lt;p&gt;펼치기 연산자, 전개 연산자란 용어는 ES6 를 소개하는 책에서도 제각각이며, 아직까지 국내에서는 정식 명칭이 정의되지 않았기 때문에
        의사 소통을 원할하게 하기 위해서라도 원문 그대로 사용하실 것을 권장합니다. &lt;br&gt;
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;먼저 다음의 코드를 살펴보도록 하겠습니다.&lt;/p&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var birds = ['eagle', 'pigeon'];
var mammals = ['rabbit', 'cat'];

var animals = birds.concat('whale').concat(mammals);

console.log(animals)&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var birds = ['eagle', 'pigeon'];
        var mammals = ['rabbit', 'cat'];

        var animals = birds.concat('whale').concat(mammals);

        console.log(animals);
    &lt;/script&gt;--&gt;

    &lt;p class=&quot;point-r&quot;&gt;기존 &lt;kbd&gt;ES5&lt;/kbd&gt; 해서 &amp;nbsp;&lt;code&gt;concat&lt;/code&gt; 메소드를 활용하여 하나의 배열로 만들었다면, &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt; 에서는 다음과 같이 할 수 있습니다.  &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var birds = ['eagle', 'pigeon'];
var mammals = ['rabbit', 'cat'];

const animals = [...birds, 'whale', ...mammals];

console.log(animals);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var birds = ['eagle', 'pigeon'];
        var mammals = ['rabbit', 'cat'];

        const animals = [...birds, 'whale', ...mammals];

        console.log(animals);
    &lt;/script&gt;--&gt;

    &lt;p&gt;로그를 확인해 보면 &amp;nbsp;&lt;code&gt;concat&lt;/code&gt; 을 사용한 결과와 동일합니다. 즉, 이 &amp;nbsp;&lt;kbd&gt;spread operator&lt;/kbd&gt; 는 펼쳐주는 연산자입니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;Detail Info&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;1) &amp;nbsp;배열의 각 인자를 펼친 효과&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const values = [20, 10, 30, 50, 40];
console.log(20, 10, 30, 50, 40);
console.log(...values);&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;
        &lt;kbd&gt;콤마(,)&lt;/kbd&gt;로 구성되어 있는 것들은 모두 펼치기 연산자를 사용할 수 있습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;아래에서 펼치기 연산자를 활용한 응용 예제를 살펴보도록 하자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const values = [20, 10, 30, 50, 40];

console.log(Math.max(20, 10, 30, 50, 40));
console.log(Math.max.apply(null, values));
console.log(Math.max(...values));&lt;/code&gt;&lt;/pre&gt;


    &lt;!--&lt;script&gt;
        const values = [20, 10, 30, 50, 40];

        console.log(Math.max(20, 10, 30, 50, 40));
        console.log(Math.max.apply(null, values));
        console.log(Math.max(...values));
    &lt;/script&gt;--&gt;

    &lt;p&gt;&lt;kbd&gt;Math&lt;/kbd&gt; 객체의 &amp;nbsp;&lt;code&gt;max&lt;/code&gt; 메소드는 인자의 갯수를 한정짓지 않고 많이 받을 수 있습니다.
        많이 사용하는 방법이 숫자로 구성된 배열을 가지고 &amp;nbsp;&lt;code&gt;max&lt;/code&gt; 메소드를 사용하곤 하는데 기존 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt; 에서는 &amp;nbsp;&lt;code&gt;apply&lt;/code&gt; 메소드를 사용하여 값을 얻었지만
        &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt; 에선 위와 같이 &amp;nbsp;&lt;code&gt;...values&lt;/code&gt; 펼쳐주기만 하면 되기 때문에 &lt;code&gt;apply&lt;/code&gt; 같은 메소드를 사용하지 않고 간결하게 작성할 수 있습니다.
    &lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;2)&amp;nbsp; 앞뒤로 다른 값들을 함께 사용할 수도 있다.&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const values = [3, 4, 5, 6, 7, 8];

// 인자의 갯수를 상관하지 않고 총합을 구하기 위해 나머지 매개변수를 사용
const sum = function (...args) {
  return args.reduce(function (p, c) {
    return p + c;
  })
};

console.log(sum(1, 2, ...values, 9, 10)); // 값을 펼쳐서 주는 입장&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const values = [3, 4, 5, 6, 7, 8];
        const sum = function (...args) {
            return args.reduce(function (p, c) {
                return p + c;
            })
        };

        console.log(sum(1, 2, ...values, 9, 10)); // 값을 펼쳐서 주는 입장
    &lt;/script&gt;--&gt;

    &lt;!--const sum = (...args) =&gt; args.reduce( (p, c) =&gt; p + c);--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning tip&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt;rest parameter 와 spread operator 의 차이점&lt;/p&gt;
        &lt;p&gt;&lt;kbd&gt;rest parameter&lt;/kbd&gt; 는 오직 인자의 맨 마지막에서만 사용할 수 있으며, 인자는 &amp;nbsp;&lt;mark&gt;받는 입장&lt;/mark&gt;인 반면에 &lt;br&gt;
            &lt;kbd&gt;spread operator&lt;/kbd&gt; 는 어떤 갖고 있는 정보를 펼쳐서 어떤 값은 이거다..라고 펼쳐서 &lt;mark&gt;주는 입장&lt;/mark&gt;이기 때문에 사용하는 위치가 자유롭습니다.
        &lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;kbd&gt;getter&lt;/kbd&gt; : 나머지 / 받는 입장&lt;/li&gt;
            &lt;li&gt;&lt;kbd&gt;setter&lt;/kbd&gt; : 펼치기 / 주는 입장&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;3) &amp;nbsp;&lt;kbd&gt;iterable&lt;/kbd&gt; 한 모든 데이터는 펼칠 수 있다.&lt;/strong&gt;&lt;/p&gt;
    &lt;p&gt;&lt;kbd&gt;iterable&lt;/kbd&gt; 은 &amp;nbsp;&lt;kbd&gt;&quot;반복할 수 있는&quot;&lt;/kbd&gt; 이라는 사전적 의미를 가지고 있는데, 의미 그대로 반복할 수 있는 데이터를 펼칠 수 있다라고 볼 수 있습니다.&lt;/p&gt;
    &lt;p&gt;
        다시 말해, 배열처럼 인덱스가 있고 인덱스마다 값들이 할당이 되서 그것들을 순회하면서 하나하나 처리할 수 있는 것을 &lt;kbd&gt;iterable&lt;/kbd&gt; 하다라고 합니다.
    &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const str = 'Hello!';

console.log( str[0] ); // H
console.log( str[2] ); // l

// ES5
console.log( str.split( '' ) );

// ES6
console.log( [...str] ); // 펼친 것을 배열로 받음
console.log( ...str );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const str = 'Hello!';

        console.log( str[0] ); // H
        console.log( str[2] ); // l

        // ES5
        console.log( str.split( '' ) );

        // ES6
        console.log( [...str] ); // 펼친 것을 배열로 받음
        console.log( ...str );
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;4) &amp;nbsp;&lt;code&gt;push&lt;/code&gt;, &amp;nbsp;&lt;code&gt;unshift&lt;/code&gt;, &amp;nbsp;&lt;code&gt;concat&lt;/code&gt; 등의 기능을 대체할 수 있다.&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let originalArr = [2, 3];
const preArr    = [-2, -1];
const sufArr    = [6, 7];

var a = originalArr.unshift(1); // 원본 배열
console.log( a, originalArr ); // 3, [1, 2, 3]

// originalArr = originalArr.unshift(1)
// 할당을 하면 원본 배열이 망가짐(?), 즉 배열이 아닌 length 가 출력

originalArr.push(4); // 원본 배열
console.log( originalArr ); // [1, 2, 3, 4]

originalArr = [0, ...originalArr, 5]; // 새로운 배열
console.log(originalArr);

const concatArr = preArr.concat(originalArr, sufArr);
const restArr = [...preArr, ...originalArr, ...sufArr];
console.log(concatArr, restArr);&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 let originalArr = [2, 3];
		 const preArr    = [-2, -1];
		 const sufArr    = [6, 7];

		 var a = originalArr.unshift(1); // 원본 배열
		 console.log( a, originalArr ); // 3, [1, 2, 3]

		 // originalArr = originalArr.unshift(1)
		 // 할당을 하면 원본 배열이 망가짐(?), 즉 배열이 아닌 length 가 출력

		 originalArr.push(4); // 원본 배열
		 console.log( originalArr ); // [1, 2, 3, 4]

		 originalArr = [0, ...originalArr, 5]; // 새로운 배열
		 console.log(originalArr);

		 const concatArr = preArr.concat(originalArr, sufArr);
		 const restArr = [...preArr, ...originalArr, ...sufArr];
		 console.log(concatArr, restArr);
	 &lt;/script&gt;--&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;5) &amp;nbsp;&lt;kbd&gt;&quot;새로운&quot;&lt;/kbd&gt; 배열이다.&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let originalArray = [1, 2];
let copiedArray = [...originalArray];
console.log(originalArray === copiedArray);

originalArray.push(3);
console.log(originalArray);
console.log(copiedArray);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        let originalArray = [1, 2];
        let copiedArray = [...originalArray];
        console.log(originalArray === copiedArray);

        originalArray.push(3);
        console.log(originalArray);
        console.log(copiedArray);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;6) &amp;nbsp;&lt;kbd&gt;&quot;얕은 복사&quot;&lt;/kbd&gt;만을 수행한다.&lt;/strong&gt;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let originalArray = [{
    first: 'Hello,',
    second: 'World!'
}, {
    first: 'Welcome',
    second: 'ES6!'
}];

let copiedArray = [...originalArray];
console.log( copiedArray === originalArray );
console.log(originalArray[0].first);

copiedArray[0].first = &quot;Hi,&quot;;
console.log(originalArray[0].first);

// 원본과 카피배열은 같은 곳을 참조한다.
// 즉, 참조가 바뀌어 있지 않은 것(얕은 복사)이다.
console.log( originalArray[0].first );
console.log( copiedArray[0].first );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        let originalArray = [{
            first: 'Hello,',
            second: 'World!'
        }, {
            first: 'Welcome',
            second: 'ES6!'
        }];

        let copiedArray = [...originalArray];
        console.log( copiedArray === originalArray );
        console.log(originalArray[0].first);

        copiedArray[0].first = &quot;Hi,&quot;;
        console.log(originalArray[0].first);

        console.log( originalArray[0].first );
        console.log( copiedArray[0].first );
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning info&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt;tc39 propersals&lt;/p&gt;
        &lt;p&gt;
            &lt;a href=&quot;https://github.com/tc39/proposals&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;tc39 propersals&lt;/a&gt;는 &amp;nbsp;&lt;kbd&gt;ECMAScript&lt;/kbd&gt;
            를 제정하는 위원회입니다. &lt;br&gt;
            &lt;kbd&gt;ECMAScript&lt;/kbd&gt; 라는 단체에 소규모의 위원회들이 있는데 &amp;nbsp;&lt;kbd&gt;39&lt;/kbd&gt; 넘버의 이름을 가지고 있는 위원회가 자바스크립트에 대한 표준 규약을 정의하는 집단입니다. &lt;br&gt;
            즉, &amp;nbsp;&lt;kbd&gt;tc39&lt;/kbd&gt; 라고 불리는 위원회가  &amp;nbsp;&lt;kbd&gt;ECMAScript&lt;/kbd&gt; 의 다음 버전에는 어떠한 내용들이 추가되는 지를 정하는 단체입니다. &lt;br&gt;
            보통 &lt;kbd&gt;ES6&lt;/kbd&gt; 를 &lt;kbd&gt;es2015&lt;/kbd&gt; 라고도 부릅니다. 그런데 &lt;kbd&gt;ES3&lt;/kbd&gt; 는 199x년대, &lt;kbd&gt;ES5&lt;/kbd&gt; 는 2009년대에 릴리즈되었는데
            &lt;kbd&gt;tc39&lt;/kbd&gt; 가 자바스크립트를 2015년에 대대적으로 업데이트하면서
            매년 업데이트(ES6(2015), ES7(2016. 6.), ES8(2017. 6), ES9(2018. 6.), ES10(2019. 6))를 하기로 하면서 이 6과 15, 7과 16... 숫자의 매칭이 되지가 않자
            오랜 기간의 침묵을 깨고 대대적인 업데이트를 한 ES6는 es2015 라고 둘다 통용되는 명칭으로 하고 그 이후부터 매년 업데이트되는 버전의 정식 명칭은 &lt;kbd&gt;es2016&lt;/kbd&gt;,
            &lt;kbd&gt;es2017&lt;/kbd&gt;, &lt;kbd&gt;es2018&lt;/kbd&gt;, &lt;kbd&gt;es2019&lt;/kbd&gt; 라고 부르기로 정하였습니다. &lt;br&gt;
            &lt;code&gt;es2015(ES6)&lt;/code&gt; 는 프로그래밍 언어(language)로서의 자격을 갖추면서 엄청난 변화를 가져왔지만 매년 큰 변화를 줄 수는 없기 때문에 차츰차츰 조금씩 추가하기로 결정했습니다.
        &lt;/p&gt;
        &lt;p class=&quot;mt20&quot;&gt;그리고 추가하려는 내용들을 전세계 사용자들에게 제안을 받고 다음과 같은 단계를 거치게 됩니다.&lt;/p&gt;

        &lt;ul&gt;
            &lt;li&gt;&lt;code&gt;stage 0&lt;/code&gt;&amp;nbsp; : &amp;nbsp;사용자들에게 &quot;이 기능을 추가해주세요&quot; 제안을 받는다.&lt;/li&gt;
            &lt;li&gt;&lt;code&gt;stage 1&lt;/code&gt;&amp;nbsp; : &amp;nbsp;검토&lt;/li&gt;
            &lt;li&gt;&lt;code&gt;stage 2&lt;/code&gt;&amp;nbsp; : &amp;nbsp;구체화&lt;/li&gt;
            &lt;li&gt;&lt;code&gt;stage 3&lt;/code&gt;&amp;nbsp; : &amp;nbsp;도입 예정&lt;/li&gt;
            &lt;li&gt;&lt;code&gt;stage 4&lt;/code&gt;&amp;nbsp; : &amp;nbsp;도입 확정 -&gt; 확정이 되면 대개 그 다음해에 기능이 추가된다고 볼 수 있다.&lt;/li&gt;
        &lt;/ul&gt;
        &lt;p&gt;&lt;code&gt;stage 4&lt;/code&gt;는 &amp;nbsp;&lt;kbd&gt;Finished Proposals&lt;/kbd&gt; 단계로 도입이 확정되면 그 다음해나 다음다음해에 기능이 추가되지만 그 이전 단계인 1단계부터 3단계까지는 언제 추가될지 미정이지만 언제가는 될 가능성이 높은 기능들입니다.&lt;/p&gt;

    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;link-refer&quot;&gt;

        &lt;h3&gt;Related Info&lt;/h3&gt;

        &lt;ol&gt;
            &lt;li&gt;&lt;a href=&quot;https://d2.naver.com/helloworld/7495331&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;2018년과 이후 JavaScript의 동향 - JavaScript(ECMAScript)&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;

    &lt;/div&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;loof-wrap&quot;&gt;
        &lt;div class=&quot;loof&quot;&gt;
            &lt;svg class=&quot;rl-logo&quot; width=&quot;606&quot; height=&quot;300&quot; viewBox=&quot;0 0 606 300&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; preserveAspectRatio=&quot;none&quot;&gt;
                &lt;defs&gt;
                    &lt;clipPath id=&quot;clipLogo&quot;&gt;
                        &lt;path d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;
                        &lt;/path&gt;&lt;/clipPath&gt;
                &lt;/defs&gt;
                &lt;path class=&quot;rl-logo__path&quot; d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;&lt;/path&gt;
                &lt;path class=&quot;rl-logo__track&quot; clip-path=&quot;url(#clipLogo)&quot; d=&quot;M 323.9 178.9 C 344.8 202.5 383.7 245.8 412.2 261.3 C 447.3 282.3 494.3 278 527.7 255.5 C 586.6 217 597.8 127.5 557.2 72.1 C 530.3 33.4 479 17 434.2 28.2 C 389.3 41.5 358.1 79 330.7 114.3 C 318.9 128.6 277.3 185.4 277.3 185.4 C 249.9 220.7 218.7 258.1 173.8 271.5 C 129 282.7 77.7 266.3 50.8 227.6 C 10.2 172.2 21.4 82.7 80.3 44.2 C 113.7 21.6 160.7 17.4 195.8 38.4 C 224.3 53.9 261.2 96.2 282.1 119.7&quot;&gt;&lt;/path&gt;
            &lt;/svg&gt;
        &lt;/div&gt;
        &lt;div class=&quot;name&quot;&gt;
            Jaehee's&lt;span class=&quot;b&quot;&gt; WebClub&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/ES6+</category>
      <author>jaiyah</author>
      <guid isPermaLink="true">https://webclub.tistory.com/646</guid>
      <comments>https://webclub.tistory.com/646#entry646comment</comments>
      <pubDate>Fri, 26 Feb 2021 18:19:14 +0900</pubDate>
    </item>
    <item>
      <title>template literal &amp;amp; 번외편(배열 메소드)</title>
      <link>https://webclub.tistory.com/645</link>
      <description>&lt;p&gt;&lt;mark&gt;이 글은 &lt;a href=&quot;https://www.inflearn.com/course/ecmascript-6-flow&quot; target=&quot;_blank&quot;&gt;[인프런] Javascript ES6+ 제대로 알아보기 - 초급(정재남)&lt;/a&gt;를 토대로 작성되었음을 알려드립니다.&lt;/mark&gt;&lt;/p&gt;
    &lt;p&gt;&lt;br&gt;&lt;/p&gt;

    &lt;p&gt;&lt;kbd&gt;ES5&lt;/kbd&gt; 에서는 홑따옴표, 쌍따옴표로 문자열을 표기(&lt;code&gt;var a = 'abc';&lt;/code&gt;)하였으나 &amp;nbsp;&lt;kbd&gt;ES6&lt;/kbd&gt; 에서 또 하나의 템플릿 문자열이 생겼습니다. &lt;/p&gt;
    &lt;p&gt;이번 장에서는 이 템플릿 문자열에 대해 알아보겠습니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;h2 class=&quot;hh&quot;&gt;템플릿 리터럴(Template Literal)&lt;/h2&gt;
    &lt;p&gt;다음의 코드를 살펴보도록 합니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// ES5
var a = 'abc';
var b = &quot;abc&quot;;

// ES6(es2015)
var c = `abc`;

console.log( a === b );
console.log( a === c );
console.log( b === c );
console.log( a === b &amp;&amp; b === c );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        // ES5
        var a = 'abc';
        var b = &quot;abc&quot;;

        // ES6(es2015)
        var c = `abc`;

        console.log( a === b );
        console.log( a === c );
        console.log( b === c );
        console.log( a === b &amp;&amp; b === c );

    &lt;/script&gt;--&gt;

    &lt;p&gt;위 코드에서 확인했다시피 키보드의 숫자키 1 바로 좌측에 있는 &amp;nbsp;&lt;kbd&gt;backtick ( ` )&lt;/kbd&gt; 이라고 불리는 문자로 문자열을 정의할 수 있습니다. &lt;br&gt;
        ES6 에서 왜 굳이 기존의 문자열 리터럴(string literal) 방법을 두고 하나를 더 추가했을까요? &lt;br&gt;
    &lt;/p&gt;
    &lt;p class=&quot;mt20&quot;&gt;일단 &lt;code&gt;template&lt;/code&gt; 이라는 용어에 집중할 필요가 있는데 우선 다음의 코드를 살펴보고 왜 템플릿이라고 불리는 &lt;kbd&gt;템플릿 리터럴&lt;/kbd&gt;을 만들었는지 살펴보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var a = 'abc\ndef'; // 기존의 문자열은 역슬래시를 사용하여 줄바꿈을 처리
var b = 'abc\n' + 'def';
console.log( a );
console.log( b );

var c = `abc
def`;
console.log( c );&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 var a = 'abc\ndef'; // 기존의 문자열은 역슬래시를 사용하여 줄바꿈을 처리
		 var b = 'abc\n' + 'def';
		 console.log( a );
		 console.log( b );

		 var c = `abc
		 def`;
		 console.log( c );
	 &lt;/script&gt;--&gt;

    &lt;p&gt;출력 결과를 확인해 보면 템플릿 리터럴은 코드상의 줄바꿈 처리가 그대로 수행된다는 점입니다. &lt;br&gt;
        여기서 주의할 점은 빈 공백도 문자열이기 때문에 빈 공백도 모두 문자열로 인식하여 빈 공백이 생긴다는 아쉬운 점을 가지고 있습니다.
    &lt;/p&gt;
    &lt;p class=&quot;mt20 point-r&quot;&gt;하지만 다음의 예제를 보면 템플릿으로서 중요한 기능을 가지고 있다는 것을 확인할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const a = 10;
const b = 20;

// 기존 문자열 접합(What the..., Hell.. 드럽게 복잡합 ㄷㄷ)
const beforeStr = a + ' + ' + b + ' = ' + (a + b);
console.log( beforeStr );

// ES6 문자열 접합
const str = `${a} + ${b} = ${ a + b }`;
console.log(str)&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const a = 10;
        const b = 20;

        // 기존 문자열 접합(What the..., Hell.. 드럽게 복잡합 ㄷㄷ)
        const beforeStr = a + ' + ' + b + ' = ' + (a + b);
        console.log( beforeStr );

        // ES6 문자열 접합
        const str = `${a} + ${b} = ${ a + b }`;
        console.log(str)
    &lt;/script&gt;--&gt;

    &lt;p&gt;
        템플릿 리터럴에서는 첫 번째 &amp;nbsp;&lt;kbd&gt;backtick&lt;/kbd&gt; 과 마지막 &amp;nbsp;&lt;kbd&gt;backtick&lt;/kbd&gt; 사이에 &amp;nbsp;&lt;code&gt;${ }&lt;/code&gt; 에 변수를 정의할 수 있습니다.
        &lt;br&gt;
        즉, &amp;nbsp;&lt;kbd&gt;backtick&lt;/kbd&gt; 사이에는 값이나 식을 정의(if 문과 같은 것은 제외)할 수 있습니다. &lt;br&gt;
        다시 말해, 값이 될 수 있는 것은 식이나 문이기 때문에 값, 식을 정의할 수 있으나 문 종류는 값이 될 수 없기 때문에 사용할 수 없습니다. &lt;br&gt;
        다시 생각해 보면 값을 출력하는 목적이 강한 측면이 있는 것입니다. &lt;br&gt;
        그래서 &amp;nbsp;&lt;mark&gt;${ } 에는 변수, 식, 함수의 호출, 삼항 연산자 등을 정의&lt;/mark&gt;할 수 있습니다.
    &lt;/p&gt;
    &lt;p class=&quot;mt20&quot;&gt;
        그런데 만약 위 코드에서 (a + b) 의 값이 실제로 달러($)로 표기되어야 한다는 어떻게 해야할까요?
    &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; const str = `${a} + ${b} = $${ a + b }`;&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;중괄호(&lt;b&gt;{&lt;/b&gt;)가 바로 앞에 붙은 달러부터 인식하기 때문에 사용하는데 무리가 없을 것입니다. &lt;/p&gt;
    &lt;p&gt;그리고 이렇게 &amp;nbsp;&lt;code&gt;${ }&lt;/code&gt; 사이에 값, 식을 정의할 수 있는 것을 &amp;nbsp;&lt;kbd&gt;string interpolation&lt;/kbd&gt; 이라고 합니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;quote&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt;interpolation&lt;/p&gt;
        &lt;p&gt;
            이 단어를 찾아보면 &amp;nbsp;&lt;kbd&gt;[수학]보간법, 내삽법, 써넣음(써넣은 어구)&lt;/kbd&gt; 이라는 사전적 의미를 가지고 있습니다. &lt;br&gt;
            &lt;kbd&gt;써넣음&lt;/kbd&gt;이라는 의미가 더 와닿겠지만 &amp;nbsp;&lt;kbd&gt;보간&lt;/kbd&gt;이란 뜻도 &lt;b&gt;사이간, 보충할 보&lt;/b&gt;자로서 사이에 보충에서 넣는다는 의미를 가지고 있습니다. &lt;br&gt;
            즉, &amp;nbsp;&lt;mark&gt;글자 사이에 무엇인가를 보충해 넣겠다&lt;/mark&gt;는 의미로 받아들 일 수 있습니다. &lt;br&gt;
            &lt;kbd&gt;내삽&lt;/kbd&gt; 역시 안쪽에 삽입한다는 의미입니다.
        &lt;/p&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning info&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt;string interpolation (문자열 보간법)&lt;/p&gt;
        &lt;p&gt;&lt;mark&gt;문자열(backtick) 안에 ${ } 로 변수를 삽입, 써넣겠다, 끼워넣겠다&lt;/mark&gt; 라고 해석할 수 있습니다.&lt;/p&gt;
    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;Detail Info&lt;/p&gt;
    &lt;p&gt;위에서 알아본 내용을 정리해 보고 추가적으로 더 살펴보도록 하겠습니다.&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;1) &amp;nbsp;&lt;kbd&gt;multi-line&lt;/kbd&gt;의 경우 들여쓰기에 주의&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const f = function () {
    const a = `abc
      def
      ghi`;

    console.log(a);
};
f()&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const f = function () {
            const a = `abc
  def
  ghi`;

            console.log(a)
        };
        f()
    &lt;/script&gt;--&gt;
    &lt;p&gt;위 코드 출력을 확인해 보면 이쁘게 정렬되지 않으나 &amp;nbsp;&lt;mark&gt;보간을 쓰기 위한 목적&lt;/mark&gt;에 충실하다면 유용할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const f = function () {
    const a = `abc ${10}\n` + `def\n` + `ghi\n`;

    console.log(a);
};
f()&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const f = function () {
            const a = `abc ${10}\n` + `def\n` + `ghi\n`;

            console.log(a);
        };
        f()
    &lt;/script&gt;--&gt;

    &lt;p&gt;&lt;kbd&gt;multi-line&lt;/kbd&gt; 을 사용하지 못하는 것이 아쉽지만 사용자 선택에 따라 활용하는 것이 나을 것입니다.&lt;/p&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;2) &amp;nbsp;&lt;code&gt;${ }&lt;/code&gt; 내에는 &amp;nbsp;&lt;kbd&gt;`값`&lt;/kbd&gt; 또는 &amp;nbsp;&lt;kbd&gt;`식`&lt;/kbd&gt;이 올 수 있다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; const counter = {
    current: 0,
    step: 1,
    count: function() { return this.current += this.step },
    reset: function() { return this.current = 0 }
};
console.log(`${counter.count()} ${counter.count()};
${counter.reset()} $${counter.count()}
${counter.count()}$`);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const counter = {
            current: 0,
            step: 1,
            count: function() { return this.current += this.step },
            reset: function() { return this.current = 0 }
        };
        console.log(`${counter.count()} ${counter.count()};
        ${counter.reset()} $${counter.count()}
        ${counter.count()}$`);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;3) 결국 문자열이므로, &amp;nbsp;&lt;mark&gt;자동으로 toString 처리&lt;/mark&gt;가 된다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;console.log(`${ [0, 1, 2] }`); // ①
console.log(`${ {a:1, b:2} }`);
console.log(`${ function(){ return 1 } }`);
console.log(`${ (function(){ return 1;})() }` + 1);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        console.log(`${ [0, 1, 2] }`); // ①
        console.log(`${ {a:1, b:2} }`);
        console.log(`${ function(){ return 1 } }`);
        console.log(`${ (function(){ return 1;})() }` + 1);
        // console.log(`${ (() =&gt; 1 )() }` + 1);
    &lt;/script&gt;--&gt;

    &lt;p&gt;① 보간안에 값으로 배열이 올 경우 문자열로 표현하기 위해 &amp;nbsp;&lt;code&gt;toString&lt;/code&gt; 이 자동 호출된다. &lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;4} 중첩된 &amp;nbsp;&lt;kbd&gt;backtick&lt;/kbd&gt; 처리&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;console.log(`Foo ${`Bar`}`); // ①
console.log(`Foo ${`Bar ${`Baz`}`}`); // ② &lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        console.log(`Foo ${`Bar`}`);
        console.log(`Foo ${`Bar ${`Baz`}`}`);
    &lt;/script&gt;--&gt;

    &lt;ul class=&quot;mt20&quot;&gt;
        &lt;li&gt;① 첫 백틱과 마지막 백틱이 쌍으로 이루고 &amp;nbsp;&lt;kbd&gt;${`Bar`}&lt;/kbd&gt; 보간이 최우선되고 중괄호 안의 백틱이 처리된다.&lt;/li&gt;
        &lt;li&gt;② 보간 내에 보간으로 구성되어 있다.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;5) 가독성을 위해 &amp;nbsp;&lt;code&gt;trim&lt;/code&gt; 처리&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function a () {
    return `
&amp;lt;div&gt;
    &amp;lt;h1&gt;Lorem ipsum.&amp;lt;/h1&gt;
&amp;lt;/div&gt;
  `.trim();
}

console.log(a());
console.log(a().replace(/\n/g, ''));&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
		function a () {
			return `
			&lt;div&gt;
		&lt;h1&gt;Lorem ipsum.&lt;/h1&gt;
	&lt;/div&gt;
				  `.trim();
		}

		console.log(a());
		console.log(a().replace(/\n/g, ''));
	&lt;/script&gt;--&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;h2 class=&quot;hh&quot;&gt;번외편 : forEach, map, reduce 메소드&lt;/h2&gt;
    &lt;p&gt;&lt;kbd&gt;배열&lt;/kbd&gt;을 다룰 때 유용한 메소드에 대해 알아보도록 하겠습니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;forEach method&lt;/p&gt;
    &lt;p&gt;
        &lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;MDN - Array.prototype.forEach&lt;/a&gt; 는 반복문으로 아래 문법을 살펴보겠습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning stx&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt; Array.prototype.forEach(callback [, thisArg])&lt;/p&gt;
        &lt;div class=&quot;syntax&quot;&gt;
            &lt;ul&gt;
                &lt;li&gt;&lt;kbd&gt;callback&lt;/kbd&gt; : &lt;kbd&gt;function (currentValue[, index[, originalArray]])&lt;/kbd&gt;
                    &lt;div style=&quot;margin-top: 10px;&quot;&gt;
                        &lt;ul&gt;
                            &lt;li&gt;&lt;kbd&gt;currentValue&lt;/kbd&gt; : 현재값&lt;/li&gt;
                            &lt;li&gt;&lt;kbd&gt;index&lt;/kbd&gt; : 현재 인덱스&lt;/li&gt;
                            &lt;li&gt;&lt;kbd&gt;originalArray&lt;/kbd&gt; : 원본 배열&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/div&gt;
                &lt;/li&gt;
                &lt;li&gt;&lt;kbd&gt;thisArg&lt;/kbd&gt; : this 에 할당할 대상. 생략시 global 객체&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;
    &lt;/div&gt;

    &lt;p&gt;
        &lt;kbd&gt;callback&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;thisArg&lt;/kbd&gt; 라는 인자를 두 개 받는데 &amp;nbsp;&lt;kbd&gt;대괄호([])&lt;/kbd&gt;가 표기되어 있으면 생략이 가능하다는 의미로 즉, 선택적으로 사용할 수 있다는 뜻입니다. &lt;br&gt;
        이 말은 &amp;nbsp;&lt;kbd&gt;대괄호([])&lt;/kbd&gt;가 아닌 &amp;nbsp;&lt;kbd&gt;callback&lt;/kbd&gt; 은 필수적으로 사용해야 한다는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;
        &lt;kbd&gt;callback&lt;/kbd&gt; 인자를 살펴보면, 콜백은 함수를 사용하라고 정의되어 있으며 함수의 인자로는 &amp;nbsp;&lt;kbd&gt;currentValue&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;index&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;originalArray&lt;/kbd&gt;
        를 사용할 수 있으며, &amp;nbsp;&lt;kbd&gt;currentValue&lt;/kbd&gt;는 대괄호에 포함되어 있지 않으므로 필수적으로 사용해야 하며, 이 외의 &amp;nbsp;&lt;kbd&gt;index&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;originalArray&lt;/kbd&gt;은 선택적으로
        사용해도 되고 사용하지 않아도 된다는 의미입니다. &lt;br&gt;
        이러한 표기를 &amp;nbsp;&lt;b&gt;API 명세서의 메타 표기&lt;/b&gt;법이라고 합니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;위에서 문법을 살펴본 후 다음의 예제를 보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const a = [ 1, 2, 3 ];
a.forEach(function (v, i, arr) {
    console.log(v, i, arr, this)
}, [ 10, 11, 12 ]);

const b = [ 1, 2, 3 ];
b.forEach(function (v, i, arr) {
    // 기타 목적으로 this 를 사용할 필요가 있을 경우에 활용
    // 일반적으로 많이 사용하지는 않음
    console.log( this[i] );
}, [ 10, 11, 12 ]);&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const a = [ 1, 2, 3 ];
        a.forEach(function (v, i, arr) {
            console.log(v, i, arr, this)
        }, [ 10, 11, 12 ]);

        const b = [ 1, 2, 3 ];
        b.forEach(function (v, i, arr) {
            // 기타 목적으로 this 를 사용할 필요가 있을 경우에 활용
            // 일반적으로 많이 사용하지는 않음
            console.log( this[i] );
        }, [ 10, 11, 12 ]);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;map method&lt;/p&gt;
    &lt;p&gt;
        &lt;code&gt;forEach&lt;/code&gt; 는 &amp;nbsp;&lt;kbd&gt;for 문&lt;/kbd&gt;을 사용해서 순회하는 것처럼 비슷한 개념이지만 &amp;nbsp;&lt;code&gt;map&lt;/code&gt; 은 &amp;nbsp;&lt;kbd&gt;for 문&lt;/kbd&gt;을 돌려서
        &lt;b&gt;새로운 배열을 만드는 목적&lt;/b&gt;을 가지고 있습니다.
    &lt;/p&gt;
    &lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;[MDN - Array.prototype.map] 참고&lt;/a&gt;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning stx&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt;Array.prototype.map(callback[, thisArg])&lt;/p&gt;
        &lt;div class=&quot;syntax&quot;&gt;
            &lt;ul&gt;
                &lt;li&gt;&lt;kbd&gt;callback&lt;/kbd&gt; : &lt;kbd&gt;function (currentValue[, index[, originalArray]])&lt;/kbd&gt;
                    &lt;div style=&quot;margin-top: 10px;&quot;&gt;
                        &lt;ul&gt;
                            &lt;li&gt;&lt;kbd&gt;currentValue&lt;/kbd&gt; : 현재값&lt;/li&gt;
                            &lt;li&gt;&lt;kbd&gt;index&lt;/kbd&gt; : 현재 인덱스&lt;/li&gt;
                            &lt;li&gt;&lt;kbd&gt;originalArray&lt;/kbd&gt; : 원본 배열&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/div&gt;
                &lt;/li&gt;
                &lt;li&gt;&lt;kbd&gt;thisArg&lt;/kbd&gt; : this 에 할당할 대상. 생략시 global 객체&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; const a = [ 1, 2, 3 ]
const b = a.map(function (v, i, arr) {
    console.log(v, i, arr, this);
    return this[0] + v
}, [ 10 ]);&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 const a = [ 1, 2, 3 ]
		 const b = a.map(function (v, i, arr) {
			 console.log(v, i, arr, this);
			 return this[0] + v
		 }, [ 10 ]);
	 &lt;/script&gt;--&gt;

    &lt;p&gt;map 은 새로운 배열, 아래에서 살펴볼 reduce 는 새로운 무언가를 만드는 것이기 때문에 반드시 반환(return)을 해주어야 합니다.&lt;/p&gt;
    &lt;p&gt;위 코드는 배열의 요소를 하나하나 순회하면서 즉, 함수가 세 번 실행되면서 반환된 값을 가지고 새로운 배열을 생성하게 됩니다. &lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;reduce&lt;/p&gt;
    &lt;p&gt;
        &lt;code&gt;reduce&lt;/code&gt; 는 &amp;nbsp;&lt;kbd&gt;for 문&lt;/kbd&gt;을 돌려서 최종적으로 다른 무엇인가를 만드를 목적을 가지고 있을 경우에 사용합니다.
    &lt;/p&gt;
    &lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;[MDN - Array.prototype.map] 참고&lt;/a&gt;&lt;/p&gt;


    &lt;script&gt;
        // res[item] = item;
        // return res;
    &lt;/script&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning stx&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt;Array.prototype.reduce(callback[, initialValue])&lt;/p&gt;
        &lt;div class=&quot;syntax&quot;&gt;
            &lt;ul&gt;
                &lt;li&gt;&lt;kbd&gt;callback&lt;/kbd&gt; : &lt;kbd&gt;function (accumulator, currentValue[, currentIndex[, originalArray]])&lt;/kbd&gt;
                    &lt;div style=&quot;margin-top: 10px;&quot;&gt;
                        &lt;ul&gt;
                            &lt;li&gt;&lt;kbd&gt;accumulator&lt;/kbd&gt; : 누적된 계산값&lt;/li&gt;
                            &lt;li&gt;&lt;kbd&gt;currentValue&lt;/kbd&gt; : 현재값&lt;/li&gt;
                            &lt;li&gt;&lt;kbd&gt;currentIndex&lt;/kbd&gt; : 현재 인덱스&lt;/li&gt;
                            &lt;li&gt;&lt;kbd&gt;originalArray&lt;/kbd&gt; : 원본 배열&lt;/li&gt;
                        &lt;/ul&gt;
                    &lt;/div&gt;
                &lt;/li&gt;
                &lt;li&gt;&lt;kbd&gt;initialValue&lt;/kbd&gt; : 초기값. 생략시 첫번째 인자가 자동 지정되며, 이 경우 currentValue 는 두번째 인자부터 배정된다.&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;다음의 예제를 통해 어떠한 동작을 하는지 알아보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const arr = [ 1, 2, 3 ];
const res = arr.reduce(function (p, c, i, arr) {
    console.log(p, c, i, arr, this);
    return p + c;
}, 10)&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const arr = [ 1, 2, 3 ];
        const res = arr.reduce(function (p, c, i, arr) {
            console.log(p, c, i, arr, this);
            return p + c;
        }, 10);

        console.log(res);
    &lt;/script&gt;--&gt;

    &lt;p&gt;&lt;kbd&gt;accumulator&lt;/kbd&gt; 는 누적된 계산값으로 위 예제에서 &amp;nbsp;&lt;kbd&gt;p&lt;/kbd&gt; 에는 처음 10이 들어오고 &amp;nbsp;&lt;kbd&gt;c&lt;/kbd&gt; 에는 1 이 들어오게 됩니다. 그에 대한 결과값이 &amp;nbsp;&lt;code&gt;return p + c&lt;/code&gt; 으로
        반환되어 11 이 되고 다음 순회할 때 &amp;nbsp;&lt;kbd&gt;accumulator&lt;/kbd&gt; 인 &amp;nbsp;&lt;kbd&gt;p&lt;/kbd&gt; 로 들어가게 되고 11 과
        다음 &amp;nbsp;&lt;kbd&gt;currentValue&lt;/kbd&gt; 인 2 와 더해서 13, 13 이 다시 &amp;nbsp;&lt;kbd&gt;p&lt;/kbd&gt; 로 들어가서 &amp;nbsp;&lt;kbd&gt;(13 + 3)&lt;/kbd&gt; 으로 최종 결과값은 16이 되는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; const arr = [ 1, 2, 3 ];
const res = arr.reduce(function (p, c, i, arr) {
    console.log(p, c, i, arr);
    return p + c;
});

console.log( res );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const arr = [ 1, 2, 3 ];
        const res = arr.reduce(function (p, c, i, arr) {
            console.log(p, c, i, arr);
            return p + c;
        });

        console.log( res );
    &lt;/script&gt;--&gt;
    &lt;p&gt;만약에 위 코드와 같이 &amp;nbsp;&lt;kbd&gt;initialValue&lt;/kbd&gt; 가 없다면 &amp;nbsp;&lt;kbd&gt;accumulator&lt;/kbd&gt;에 들어갈 첫 번째 값에 배열의 첫 번째 인덱스가 자동으로 들어가게 됩니다.
        여기선 1 이 될 테고, 그러고 나서 순회는 2 번째 인덱스부터 순회하여 콘솔 결과가 &amp;nbsp;&lt;kbd&gt;1 2 1&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;3 3 2&lt;/kbd&gt;가 출력되는 것입니다.
    &lt;/p&gt;
    &lt;p class=&quot;mt20 point-r&quot;&gt;위에서 언급했 듯이 &amp;nbsp;&lt;code&gt;reduce&lt;/code&gt; 는 &amp;nbsp;&lt;kbd&gt;for 문&lt;/kbd&gt;을 돌려서 무언가를 만드는 것이기 때문에 다음과 같은 &amp;nbsp;&lt;kbd&gt;문자열 조합&lt;/kbd&gt;도 가능할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; const arr = [ 'a', 'b', 'c', 'd'];
const str = arr.reduce(function (res, item, index, array) {
    return res + item;
});

console.log( str ); // abcd&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        const arr = [ 'a', 'b', 'c', 'd'];
        const str = arr.reduce(function (res, item, index, array) {
            return res + item;
        });

        console.log( str ); // abcd
    &lt;/script&gt;--&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;좀더 응용해서 객체를 만들 수는 없을까?&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;예를 들어 &amp;nbsp;&lt;code&gt;reduce&lt;/code&gt; 를 활용하여 다음과 같은 객체를 만든다고 가정해 보자.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; // 다음과 같은 배열이 있을 때
const arr = [ 'a', 'b', 'c', 'd'];

// 다음과 같은 객체를 만들고자 한다.
var obj = {
        a : 'a',
        b : 'b',
        c : 'c',
        d : 'd'
    }&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;고민해 보고 실습해 보도록 하자.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;code&gt;reduce&lt;/code&gt; 메소드를 통해 다양한 조합이 가능하기 때문에 활용도가 높고 편하다고 하는데 예를 들어 다음과 같은 동작도 수행할 수 있습니다.  &lt;/p&gt;
    &lt;p&gt;만약 배열에 &amp;nbsp;&lt;kbd&gt;1 ~10&lt;/kbd&gt; 까지의 숫자가 있을 경우에 모두 덧셈을 한다고 해보자.&lt;/p&gt;
    &lt;p&gt;아마도 &amp;nbsp;&lt;kbd&gt;for 문&lt;/kbd&gt;만 사용하는 개발자라면 다음과 같이 코드를 작성할 것입니다.&lt;/p&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let res = 0;
for (let i = 0; i &lt; a.length; i++) {
    res += a[i];
}
console.log( res );&lt;/code&gt;&lt;/pre&gt;

    &lt;!-- &lt;script&gt;
		 const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
		 let res = 0;
		 for (let i = 0; i &lt; a.length; i++) {
			 res += a[i];
		 }
		 console.log( res );
	 &lt;/script&gt;--&gt;

    &lt;p class=&quot;mt20 point-r&quot;&gt;위 코드는 reduce 를 활용하면 훨씬 간단해 질 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const res = a.reduce(function (acc, crrValue) { return acc + crrValue; });
console.log( res );&lt;/code&gt;&lt;/pre&gt;
    &lt;!--&lt;script&gt;
        const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

        const res = a.reduce(function (acc, crrValue) { return acc + crrValue; });
        console.log( res );
    &lt;/script&gt;
    --&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;!--const res = a.reduce((a, c) =&gt; a + c);--&gt;
    &lt;div class=&quot;warning tip&quot;&gt;
        &lt;p&gt;순수 자바스크립트는 &lt;b&gt;중요성이 높은 것&lt;/b&gt; 부터 사용합니다.&lt;/p&gt;
        &lt;div class=&quot;syntax&quot;&gt;
            &lt;ul&gt;
                &lt;li&gt;[1, 2, 3].forEach( function(item, index) { });&lt;/li&gt;
                &lt;li&gt;$('li').each( function(index, item) { });&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;
        &lt;p&gt;생각해 보면 순서보다 항목이 더 중요하기 때문에 순수 자바스크립트는 배열의 순서보다 요소의 값을 먼저 사용하고 있지만, &lt;br&gt;
            제이쿼리는 혼동스럽게도 반대로 사용하고 있습니다.
        &lt;/p&gt;
    &lt;/div&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;link-refer&quot;&gt;

        &lt;h3&gt;Related Info&lt;/h3&gt;

        &lt;ol&gt;
            &lt;li&gt;&lt;a href=&quot;https://webclub.tistory.com/563&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;forEach, map, filter 메서드&lt;/a&gt;&lt;/li&gt;
        &lt;/ol&gt;

    &lt;/div&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;loof-wrap&quot;&gt;
        &lt;div class=&quot;loof&quot;&gt;
            &lt;svg class=&quot;rl-logo&quot; width=&quot;606&quot; height=&quot;300&quot; viewBox=&quot;0 0 606 300&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; preserveAspectRatio=&quot;none&quot;&gt;
                &lt;defs&gt;
                    &lt;clipPath id=&quot;clipLogo&quot;&gt;
                        &lt;path d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;
                        &lt;/path&gt;&lt;/clipPath&gt;
                &lt;/defs&gt;
                &lt;path class=&quot;rl-logo__path&quot; d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;&lt;/path&gt;
                &lt;path class=&quot;rl-logo__track&quot; clip-path=&quot;url(#clipLogo)&quot; d=&quot;M 323.9 178.9 C 344.8 202.5 383.7 245.8 412.2 261.3 C 447.3 282.3 494.3 278 527.7 255.5 C 586.6 217 597.8 127.5 557.2 72.1 C 530.3 33.4 479 17 434.2 28.2 C 389.3 41.5 358.1 79 330.7 114.3 C 318.9 128.6 277.3 185.4 277.3 185.4 C 249.9 220.7 218.7 258.1 173.8 271.5 C 129 282.7 77.7 266.3 50.8 227.6 C 10.2 172.2 21.4 82.7 80.3 44.2 C 113.7 21.6 160.7 17.4 195.8 38.4 C 224.3 53.9 261.2 96.2 282.1 119.7&quot;&gt;&lt;/path&gt;
            &lt;/svg&gt;
        &lt;/div&gt;
        &lt;div class=&quot;name&quot;&gt;
            Jaehee's&lt;span class=&quot;b&quot;&gt; WebClub&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/ES6+</category>
      <category>js forEach</category>
      <category>js map</category>
      <category>templete leteral</category>
      <category>배열 메서드</category>
      <author>jaiyah</author>
      <guid isPermaLink="true">https://webclub.tistory.com/645</guid>
      <comments>https://webclub.tistory.com/645#entry645comment</comments>
      <pubDate>Fri, 26 Feb 2021 18:12:37 +0900</pubDate>
    </item>
    <item>
      <title>ES6   block-scope &amp;amp; let, const</title>
      <link>https://webclub.tistory.com/644</link>
      <description>&lt;p&gt;&lt;mark&gt;이 글은 &lt;a href=&quot;https://www.inflearn.com/course/ecmascript-6-flow&quot; target=&quot;_blank&quot;&gt;[인프런] Javascript ES6+ 제대로 알아보기 - 초급(정재남)&lt;/a&gt;를 토대로 작성되었음을 알려드립니다.&lt;/mark&gt;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;kbd&gt;ES6&lt;/kbd&gt; 에서 추가된 블록 스코프(block-scope)와 let, const 에 대해 살펴보도록 하겠습니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;h2 class=&quot;hh&quot;&gt;Block Scope&lt;/h2&gt;
    &lt;p&gt;&lt;kbd&gt;ES5&lt;/kbd&gt; 까지는 &quot;자바스크립트에는 블록 스코프가 없다&quot;고 알려져 있었으나 이제는 그렇지 않습니다. &lt;/p&gt;
    &lt;p&gt;&lt;kbd&gt;ES5&lt;/kbd&gt; 에서는 &lt;b&gt;함수 스코프가 함수에 의해서 생기는 변수의 유효범위&lt;/b&gt;였다면 &lt;kbd&gt;블록 스코프(block-scope)&lt;/kbd&gt;는 무엇일까요?&lt;/p&gt;
    &lt;p&gt;&lt;kbd&gt;블록 스코프&lt;/kbd&gt;의 스코프도 알다시피 유효범위를 의미하는데 그렇다면 블록이란? 바로 코드 문단인 &lt;code&gt;{ }&lt;/code&gt; 즉, &lt;kbd&gt;중괄호&lt;/kbd&gt;를 가리킵니다.&lt;/p&gt;
    &lt;p&gt;
        다시 말해, &lt;code&gt;{ }&lt;/code&gt; 에 의해서 생기는 변수의 유효범위,
        &lt;mark&gt;{ } 에 의해서 변수의 유효범위가 결정&lt;/mark&gt;된다고 할 수 있습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;ES6's block-scope&lt;/p&gt;
    &lt;p&gt;위 개념을 생각하면서 아래의 코드를 살펴보도록 합니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;{
    let a = 10;
    {
        let a = 20;
        console.log( a );
    }
    console.log( a );
}
console.log( a );&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;이전 &lt;kbd&gt;ES5&lt;/kbd&gt; 에서는 &lt;code&gt;var&lt;/code&gt; 키워드로 변수를 선언했다면 &lt;kbd&gt;ES6&lt;/kbd&gt; 부터는 &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt; 란 키워드가 생겨나 변수 선언시 &lt;code&gt;let&lt;/code&gt;,
        &lt;code&gt;const&lt;/code&gt; 키워드를 사용할 수 있습니다. &amp;nbsp;
        지난 시간에 살펴본 스코프를 생각하면 콘솔의 결과값이 다르다는 것을 확인하실 수 있습니다.

    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;위의 블록 스코프 코드를 함수 스코프와 비교해 보도록 하겠습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;(function () {
    var a = 10;

    (function() {
        var a = 20;
        console.log( a );
    })();

    console.log( a );
})();
console.log( a );&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;ES6 의 블록 스코프와 함수 스코프와 콘솔 결과값을 비교하면 같습니다. &lt;br&gt;
        함수 스코프를 이해하셨다면  함수 외부에 &lt;code&gt;a&lt;/code&gt; 란 변수가 전혀 선언되지 않았기 때문에 마지막의 콘솔 결과값이 &lt;kbd&gt;a is not defined&lt;/kbd&gt; 가 왜 출력되는지 알 수 있을 것입니다. &amp;nbsp;
        그리고 함수 안에서 선언한 내부 함수에서&lt;code&gt; var a = 20;&lt;/code&gt; 은 함수가 정의된 유효범위에서만 존재하므로 외부함수에서 콘솔값은 10 이 나오게 되는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;즉,
        &lt;mark&gt;블록 스코프는 함수 스코프와 같은 개념&lt;/mark&gt;으로 볼 수 있습니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;함수 스코프에서 &lt;kbd&gt;var 키워드&lt;/kbd&gt;를 사용한 경우와 &amp;nbsp;&lt;kbd&gt;let 키워드&lt;/kbd&gt;를 사용한 경우를 살펴보도록 하겠습니다.&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;&lt;code&gt;var&lt;/code&gt; 키워드를 사용한 경우&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; function hasValue(p) {
    console.log( v );
    if (p) {
        var v = 'blue';
        console.log( v );
    } else {
        var v = 'red';
        console.log( v );
    }
    console.log( v );
}
hasValue(10);&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&lt;code&gt;var&lt;/code&gt; 로 선언하면 블록 스코프의 영향을 받지 않습니다. &amp;nbsp;즉, 기존 ES5 에서 문법을 그대로 따르기 때문에 예상한 값들이 출력될 것입니다.  &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;&lt;code&gt;let&lt;/code&gt; 키워드를 사용한 경우&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;function hasValue2(p) {
    console.log( v );
    if (p) {
        let v = 'blue';
        console.log( v );
    } else {
        let v = 'red';
        console.log( v );
    }
    console.log( v );
}
hasValue2(10);&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;전 예제 코드에서 &amp;nbsp;&lt;code&gt;var&lt;/code&gt; 로 선언한 것과 다르게 &amp;nbsp;&lt;code&gt;let&lt;/code&gt; 을 선언하면 마지막 콘솔값은 &lt;kbd&gt;v is not defined&lt;/kbd&gt; 라고 출력됩니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;



    &lt;p class=&quot;subtt&quot;&gt;블록 스코프와 &amp;nbsp;let, const&lt;/p&gt;
    &lt;p&gt;위에서 살펴보면서 눈치챘듯이 &amp;nbsp;&lt;mark&gt;블록 스코프는 let, const 에 대해서만 적용&lt;/mark&gt;됩니다.&lt;/p&gt;
    &lt;p&gt;위의 내용을 상기해 보면서 결과를 예측해 보기 바랍니다.&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;&lt;code&gt;var&lt;/code&gt; 키워드를 사용한 경우&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;console.log( a );
if (true) {
    var a = 10;
    if (true) {
        var a = 20;
        console.log( a );
    }
    console.log( a );
}
console.log( a );&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;&lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt; 키워드를 사용한 경우&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;console.log( a );
if (true) {
    let a = 10;
    if (true) {
        const a = 20;
        console.log( a );
    }
    console.log( a );
}
console.log( a );&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;블록 스코프와 호이스팅 그리고 TDZ(Temporal Dead Zone)&lt;/p&gt;
    &lt;p&gt;블록스코프는 &lt;kbd&gt;중괄호&lt;/kbd&gt;에 의해서 영향을 받는다(단, 함수에서의 중괄호는 이미 ES5 에서 함수 스코프가 존재하니 제외)고 언급했습니다.&lt;/p&gt;
    &lt;p&gt;다음과 같은 &amp;nbsp;&lt;kbd&gt;if&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;for&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;while&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;switch-case&lt;/kbd&gt;은 중괄호를 가지고 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; if (true) {

} // 실행하고 끝.

for (var i = 0; i &lt; 10; i++) {

} // 순회하고 넘어가면 끝.

while (true) {

}

switch (a) {
    case: break;
}&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;위와 같은 것들을 우리는 &amp;nbsp;&lt;kbd&gt;if&lt;b&gt;문&lt;/b&gt;&lt;/kbd&gt;,&amp;nbsp; &lt;kbd&gt;for&lt;b&gt;문&lt;/b&gt;&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;while&lt;b&gt;문&lt;/b&gt;&lt;/kbd&gt;, &amp;nbsp;&lt;kbd&gt;switch-case&lt;b&gt;문&lt;/b&gt;&lt;/kbd&gt;이라고 명명하고 있으며,
        이러한 &lt;b&gt;문&lt;/b&gt;은 &lt;kbd&gt;'문단'&lt;/kbd&gt;은 약어입니다.
    &lt;/p&gt;
    &lt;p&gt;이러한 문과 반대되는 개념이 '식(expression)'이라고 하는데 이 식을 값이 될 수 있는 경우를 말합니다. &lt;br&gt;
        예를 들어, &lt;code&gt;(10 + 20)&lt;/code&gt;, &lt;code&gt;'abc' + 'def'&lt;/code&gt;, &lt;code&gt;function a() {return 1;} 에서 함수를 호출했을 때 a()&lt;/code&gt; 와 같이 값이 될 수 있는 것을 식이라고 합니다.
    &lt;/p&gt;
    &lt;p&gt;일반적으로 &lt;kbd&gt;값&lt;/kbd&gt;, &lt;kbd&gt;식&lt;/kbd&gt;, &lt;kbd&gt;문의&lt;/kbd&gt; 나눌 수 있는데 값과 식은 동일하게 간주됩니다.&lt;/p&gt;
    &lt;p&gt;여기서 문이라고 하는 &lt;kbd&gt;if문&lt;/kbd&gt;과 같은 '문단'은 결과를 리턴하지 않는다 것이 큰 차이점입니다. &lt;br&gt;
        &lt;mark&gt;다시 말해, 결과가 존재할 수 없습니다.&lt;/mark&gt;&lt;br&gt;
        &lt;kbd&gt;if 문&lt;/kbd&gt;을 실행해도 &lt;kbd&gt;if 문&lt;/kbd&gt;에서 실행한 코드의 값을 담아놓을 수 없습니다. &amp;nbsp;실행하면 그걸로 끝입니다. &amp;nbsp;
        &lt;kbd&gt;for 문&lt;/kbd&gt;도 마찬가지로 순회하고 다음 행으로 넘어갑니다. &amp;nbsp;&lt;kbd&gt;while 문&lt;/kbd&gt;, &lt;kbd&gt;switch-case 문&lt;/kbd&gt;도 마찬가지입니다.
    &lt;/p&gt;
    &lt;p&gt;결론은 &lt;mark&gt; 문 자체가 하나의 block-scope&lt;/mark&gt;가 되는 것입니다.&lt;/p&gt;
    &lt;p&gt;그리고 ES6 문법을 포함하면 스코프는 &lt;kbd&gt;함수 스코프&lt;/kbd&gt;와 &lt;kbd&gt;블록 스코프&lt;/kbd&gt;가 존재하는 것입니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;그럼 위의 예제 코드를 가지고 &lt;kbd&gt;호이스팅&lt;/kbd&gt;에 대해 살펴보겠습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;console.log( a );
if (true) { // if 문에 의한 블록 스코프가 생긴다.
    let a = 10; // 블록 스코프는 let 과 const 에 대해서만 영향을 받으므로 let 을 선언함. 10을 할당
    if (true) { // if 문을 다시 만나서 또 다른 해당 블록 스코프가 생긴다.
        console.log( a ); // ???
        const a = 20;
    }
    console.log( a );
}
console.log( a );&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;첫 번째 &lt;code&gt;console.log( a );&lt;/code&gt; 를 만났을 경우 호이스팅이 된다, 안된다를 가정해 봅시다.&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;호이스팅이 된다면...
            &lt;p&gt;&lt;code&gt;const a&lt;/code&gt; 를 끌어올릴 것이고 자동으로 &lt;code&gt;undefined&lt;/code&gt; 가 들어갈 것으로 예상할 수 있습니다.&lt;/p&gt;
        &lt;/li&gt;
        &lt;li&gt;호이스팅이 안된다면...
            &lt;p&gt;호이스팅이 이루어지지 않는다면 네 번째줄에서는 a 의 존재자체를 모를 것이고 자신의 스코프에 없으면 스코프 체이닝을 통해 상위 스코프를 찾을 것이고
                그러면 &lt;code&gt;a&lt;/code&gt; 는 10 이 출력될 것이라 예상할 수 있습니다.
            &lt;/p&gt;
        &lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;위 두 가지 경우를 생각해 보고나서 실제 결과를 확인해 보면 &lt;code&gt;a is not defined&lt;/code&gt; 란 에러가 나고 있습니다.&lt;/p&gt;
    &lt;p&gt;이러한 현상을 &lt;kbd&gt;TDZ(Temporal Dead Zone)&lt;/kbd&gt; 라고 하는데 의역하자면 &lt;kbd&gt;임시 사망지역&lt;/kbd&gt;, &lt;kbd&gt;임시 사각지대&lt;/kbd&gt;로 해석할 수 있습니다. &lt;br&gt;
        일반적으로 &lt;kbd&gt;임시 사각지대&lt;/kbd&gt;라고 많이 불리고 있습니다.  이 &lt;kbd&gt;TDZ&lt;/kbd&gt; 란 용어는 &lt;kbd&gt;EcmaScript&lt;/kbd&gt; 에서 정의한 개념은 아니고,
        다만 자바스크립트 개발자들이 이 개념을 가지고 언급하고 있습니다.
        명세서에서는 이 지역에서 &lt;kbd&gt;reference error&lt;/kbd&gt; 가 발생해야 한다라고 명세를 해 놓았는데 그 명세에 지칭할 용어를 만들어 놓지를 않아서
        개발자들이 이러한 현상에 대한 것을 &lt;kbd&gt;TDZ&lt;/kbd&gt; 라고 부르자라고 만들어낸 명칭입니다. &lt;br&gt;
        즉,&lt;mark&gt;정식 명칭은 아니지만 널리 통용되는 명칭&lt;/mark&gt;이라고 생각하면 됩니다.
    &lt;/p&gt;
    &lt;p&gt;&lt;kbd&gt;TDZ&lt;/kbd&gt; 라는 것은 &lt;code&gt;let&lt;/code&gt; 이나 &lt;code&gt;const&lt;/code&gt; 에 대해서 실제로 변수를 선언한 위치에 오기 전 까지는  해당 변수를 호출할 수 없다라는 것입니다. &lt;/p&gt;
    &lt;p&gt;자바스크립트에서 항상 주의하라고 했던 사항 중에 하나가 호이스팅입니다.  &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;
    console.log( a );


    // ... 많은 코드가 생략되어 있다고 했을 때 ...





    var a = 10;
&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;개발자가 일반적 상식으로 위부터 아래로 코드를 해석하는 순서에 따라야 하는데 소스 코드가 상당히 길었을 때 실수로 밑에서 선언한 변수를 상단에서 사용하려고 했을 때
        어떠한 오류도 내지 않고 넘어가는 경우가 발생합니다. 개발자 입장에서는 에러를 나지 않는 것이 좋은 것이 아니라 에러가 나서 찾아서 고칠 수 있어야 좋은 것인데 잘못된 코드에 대한
        에러를 내지 않으니 고치지 않을 확률이 높아지게 됩니다. 즉, 해당 오류를 찾기가 힘든 것입니다.
        그래서 흔히 자바스크립트의 디버깅이 어렵다고들 말합니다. 그리고 대표적으로 함수 선언문도 비슷한 맥락입니다. &lt;br&gt;
        자바스크립트를 잘 모르는 사람이라면 이러한 호이스팅은 일반적 상식에서 벗어나 있기 때문에 자바스크립트의 암묵적인 룰을 알아야만 얻을 수 있는 사항입니다. &lt;br&gt;
        이러한 일반적 상식에서 벗어난 것들을 배제하기 위해서 나온 것이 ES6 이며,
        &lt;mark&gt;ES6 의 철학은 암묵적인 규칙 그리고 예상하지 못했던 것들을 암기해야 숙지할 수 있었던 사항들을 최대한 배제하기 위한 것을 철학&lt;/mark&gt;으로 삼고 있습니다.
        하지만 지금까지 ES5 의 환경적인 룰들은 그대로 가져갈 수 밖에 없다라는 철학도 결부되어 있는 부분도 있습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;TDZ 를 설명하기 위해서는 기존 호이스팅에 대한 개념을 재정립할 필요가 있습니다.&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;code&gt;기존 var :&lt;/code&gt;
            &lt;ol&gt;
                &lt;li&gt;변수명만 위로 끌어 올린다.&lt;/li&gt;
                &lt;li&gt;undefined 를 할당(?)한다.(할당이라는 말보다는 값이 없을 경우 undefined 가 된다라고 설계되어 있는 표현이 정확함)&lt;/li&gt;
            &lt;/ol&gt;
        &lt;/li&gt;
        &lt;li&gt;&lt;code&gt;let, const :&lt;/code&gt;
            &lt;ol&gt;
                &lt;li&gt;변수명만 위로 끌어올리기만 한다. 이후 아무런 동작도 하지 않음 &lt;br&gt;
                    즉, 어떤 값과도 매칭되어 있지 않음을 의미합니다.
                &lt;/li&gt;
            &lt;/ol&gt;
        &lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;위 예제 코드의 블록 스코프에서 &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt; 를 선언한 경우에 &lt;code&gt;reference Error : a is not defined&lt;/code&gt; 가 출력된다는 것은
        &lt;code&gt;a&lt;/code&gt; 에 대한 존재를 알고 있는 것입니다.
        만약 호이스팅이 되지 않는다면 스코프 체이닝을 통해 상위 스코프의 값을 찾아서 출력했을 것이기 때문입니다.
        하지만 블록 스코프의 실행 컨텍스트가 열리는 순간 a 를 호이스팅하고 a 의 존재를 인지하고 있으나 다만 &lt;code&gt;undefined&lt;/code&gt; 를 할당(?)하는 과정이 빠진 것입니다.
    &lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;quote&quot;&gt;
        &lt;p&gt;ES6 의 블록 스코프에서 호이스팅을 하지 않는다라고 소개하는 서적이 많은데 감히 말씀드리는데 호이스팅은 합니다. &lt;br&gt;
            다만, TDZ 라는 것이 있어서 위와 같은 현상이 나타나는 것입니다. &lt;br&gt;
            사실 공식 문서에서는 호이스팅을 하지 않는다라고 설명해 놓은 것이 없음에도 잘못된 유추로 호이스팅을 하지 않는다라고 잘못된 지식을 전달하고 있고
            위의 현상만 놓고 보더라도 호이스팅을 안하는 것이 아니라 실질적으로 끌어올리기만을 한다는 것은 명백한 사실입니다.
            즉, 끌어올리기는 하지만 할당(?)을 하지 않는다로 이해하면 될 것입니다.
        &lt;/p&gt;
    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;모든 &amp;nbsp;&lt;kbd&gt;문&lt;/kbd&gt; 형태에 적용&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;위에서 살펴본 내용을 토대로 다음의 코드 결과값들을 예측해 보기 바랍니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;{
    let a = 2;
    if (a &gt; 1) {
        let b = a * 3;
        console.log( b );
    } else {
        let b = a / 3;
        console.log( b );
    }
    console.log( b );
}
console.log( a );&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let a = Math.ceil(Math.random() * 3); // 0 ~ 2.999...
switch (a) {
    case 1 : {
        let b = 10;
        console.log( a + b );
        break;
    }
    case 2 : {
        let b = 20;
        console.log( a + b );
    }
    case 3 : {
        let b = 30;
        console.log( a + b );
    }
}
console.log( a, b );&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p&gt;지금까지 잘 따라왔다면 어렵지 않게 위 코드 결과값을 예측해 봤을 것입니다. 그리고 다음의 &lt;code&gt;for 문&lt;/code&gt;을 살펴보도록 합니다. &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var sum = 0;
for (let i = 1; i &lt;= 10; i++) {
    sum += i;
}
console.log( sum );
console.log( i );&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;코드를 살펴보면 &lt;code&gt;for 문&lt;/code&gt;의 블록 스코프 밖에 &lt;code&gt;let&lt;/code&gt; 이 선언되어 있는데 콘솔값의 &lt;code&gt;i&lt;/code&gt; 는 어떻게 될까요?&lt;/p&gt;
    &lt;p&gt;&lt;code&gt;for 문&lt;/code&gt;의 조건식 부분은 블록 스코프에 포함하게 되어 반복문 밖에서 i 를 출력하려고 하면 &lt;kbd&gt;reference Error&lt;/kbd&gt; 가 나게 됩니다. &lt;br&gt;
        사실 &lt;code&gt;for 문&lt;/code&gt;의 조건식은 인덱싱을 순차적으로 증가시키기 위한 목적만 가지고 있을 뿐이기 때문입니다.
    &lt;/p&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;hh&quot;&gt;let, const&lt;/p&gt;
    &lt;p&gt;위 내용에서 블록 스코프를 살펴보면서 &lt;code&gt;let&lt;/code&gt; 과 &lt;code&gt;const&lt;/code&gt; 를 다루어 보아서 충분히 인지했겠지만 다시 한번 상기면서 코드를 예측해보고
        몇 가지 사항에 대해 추가적으로 살펴보도록 하겠습니다.
        &lt;br&gt;
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;let&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;다음의 코드의 콘솔 결과를 예측해 보기 바랍니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let a = 1;
function fn() {
    console.log( a, b, c );
    let b = 2;
    console.log( a, b, c );

    if (true) {
        let c = 3;
        console.log( a, b, c );
    }
    console.log( a, b, c );
}
fn();&lt;/code&gt;&lt;/pre&gt;


    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;for (let i = 0; i &lt; 5; i++) {
    console.log( i );
}
console.log( i );&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;재할당 가능&lt;/p&gt;
    &lt;p&gt;&lt;code&gt;let&lt;/code&gt; 은 &amp;nbsp;&lt;code&gt;var&lt;/code&gt; 와 똑같은 개념으로 이해하되 블록 스코프에 갇히며 &amp;nbsp;&lt;kbd&gt;TDZ&lt;/kbd&gt; 가 있다는 것을 숙지하고 있으면 됩니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let a = 1;
a = 2;
console.log( a );&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;반복문 내에서의 함수를 실행한 경우&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;반복문이 사용된 다음의 코드를 살펴봅니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var funcs = [];
for (var i = 0; i &lt; 10; i++) {
   funcs.push(function() {
       console.log( i );
   });
}

funcs.forEach( function (fn) {
    fn();
});&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;위 코드는 먼저 빈 배열을 선언한 후 빈 배열에 함수를 넣는 코드입니다. 그리고 나서 &lt;code&gt;forEach&lt;/code&gt; 를 통해서 각각의 함수를 실행하도록 하는 코드입니다.&lt;/p&gt;
    &lt;p&gt;코드를 좀더 살펴보자면 &lt;code&gt;i&lt;/code&gt; 가 순회할 때마다 빈 배열에 익명함수를 집어 넣고 있습니다. 즉, 다음과 같은 결과를 예상할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;[
   function() { console.log(i); },
   function() { console.log(i); },
   function() { console.log(i); },
   function() { console.log(i); },
   ...
]&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;여기서 &lt;code&gt;forEach&lt;/code&gt; 를 이용하여 함수를 실행하게 되면 &amp;nbsp;&lt;code&gt;i&lt;/code&gt; 의 값은 어떻게 될까요? &lt;br&gt;
        forEach 의 함수 실행은 반복문이 모두 순회한 후에 함수를 실행하게 됩니다. 실행 컨텍스트 함수를 실행할 때 열리게 됩니다. &lt;br&gt;
        즉, 함수를 실행할 때 비로소 변수를 호이스팅하고 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 바인딩하고 자신한테 없는 변수를 찾는 작업등을 하게 될 것입니다. &lt;br&gt;
        그럼 위 코드는 10번의 순회를 하면서 함수 10개가 생성되었을 것이고 그 다음 마지막 순회를 하고나서 &amp;nbsp;&lt;code&gt;i++&lt;/code&gt; 로 인해 for 문이 실행 종료된 후의 &lt;code&gt;i&lt;/code&gt;
        값은 &lt;kbd&gt;10&lt;/kbd&gt; 이 되어있는 상태일 것입니다.
        그렇기 때문에 함수를 반복문으로 계속 실행해도 &lt;code&gt;i&lt;/code&gt; 는 계속 &lt;kbd&gt;10&lt;/kbd&gt; 만 출력될 것입니다.
    &lt;/p&gt;
    &lt;p&gt;아마도 사용자는 일반적으로 0 ~ 9 가 차례대로 출력되는 것으로 예상했을 수 있습니다. &lt;br&gt; &lt;br&gt;
        그렇다면 0 ~ 9 까지 차례대로 출력하게 하려면 어떻게 해야 될까요 ? &lt;br&gt;
        예상한 결과대로 출력하려면 &amp;nbsp;&lt;code&gt;i&lt;/code&gt; 의 유효범위인 &amp;nbsp;&lt;code&gt;i&lt;/code&gt; 가 계속 살아있도록 만들어줘야 합니다. &lt;br&gt;
        즉, 각각의 반복문 안에서 &lt;code&gt;func.push(function() { console.log(i); })&lt;/code&gt; 에 &amp;nbsp;&lt;code&gt;i&lt;/code&gt; 를 넘겨(전달해) 줘야 할 것입니다. &lt;br&gt;
        &lt;code&gt;i&lt;/code&gt; 값을 증가한 것을 나중에 읽어오는게 아니라 처음부터 미리 넘겨줘야 합니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt; 그렇게 하기 위해서는 다음과 같이 &lt;kbd&gt;즉시 실행 함수&lt;/kbd&gt;를 사용하게 됩니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var funcs = [];
for (var i = 0; i &lt; 10; i++) {
   funcs.push(function(val) {
       return function () {
           console.log( val );
       };
   }(i));
}

funcs.forEach( function (fn) {
    fn();
});&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;위와 같이 즉시 실행 함수로 &lt;code&gt;i&lt;/code&gt; 값을 미리 넘겨주고 나서 나중에 함수를 호출했을 때 &lt;code&gt;i&lt;/code&gt; 값이 호출(출력)되도록 리턴을 하게 됩니다. &lt;br&gt;
        즉, &lt;code&gt;i&lt;/code&gt; 값을 미리 가지고 있게 한 후 나중에 호출할 때서야 그 값을 리턴문의 함수에서 출력하도록 하는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;사실 이 내용을 다루기 위해서는 &lt;kbd&gt;클로저(closure)&lt;/kbd&gt;라는 개념을 알아야 하지만 &lt;kbd&gt;ES6&lt;/kbd&gt;에서는 블록 스코프가 생겨나면서 이러한 현상에 대해 고민할 필요가 없어지게 됩니다. &amp;nbsp;
        클로저에 대해서는 이후에 다시 자세히 다루면서 알아보도록 하겠습니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot; &gt;위 코드의 즉시 실행함수를 걷어내고 &amp;nbsp;&lt;code&gt;var&lt;/code&gt; 키워드를 &amp;nbsp;&lt;code&gt;let&lt;/code&gt; 으로 변경한 후 코드를 실행해 보도록 하겠습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let funcs = [];
for (let i = 0; i &lt; 10; i++) {
    funcs.push(function() {
        console.log( i );
    });
}

funcs.forEach( function (fn) {
    fn();
});&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;반복문 자체가 블록 스코프이기 때문에 각각의 &amp;nbsp;&lt;code&gt;i&lt;/code&gt; 값마다 스코프가 생성되므로 &amp;nbsp;&lt;code&gt;i&lt;/code&gt;는 그대로 순차적으로 0 ~ 9 까지 출력되게 될 것입니다. &lt;/p&gt;
    &lt;p&gt;그래서 스코프로 인해 &amp;nbsp;&lt;kbd&gt;즉시 실행 함수&lt;/kbd&gt;를 사용하는 방법과 같은 고민들이 해소가 되어 메모리 소모를 덜 할 수 있게 되는 환경이 열리게 된 것입니다. &lt;/p&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;const&lt;/p&gt;
    &lt;p&gt;&lt;code&gt;const&lt;/code&gt; 는 &amp;nbsp;&lt;kbd&gt;constant variable&lt;/kbd&gt; 의 약자입니다. &lt;br&gt;
        사전적 의미는 상수 변수라고 하는데 뜻이 형용 모순되는 듯이 보이지만 프로그래밍 언어에서는 무엇인가를 선언(지정)한 순간부터가 상수라고 해석될 수 있습니다.
        그래서 아래와 같은 변수 A 에 10 을 할당하는 과정이 끝나야지만 A 가 상수로써의 역할을 하게 됩니다.
    &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const A = 10;&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;재할당&lt;/p&gt;
    &lt;p&gt;상수는 아래와 같이 할당을 한 후에 재할당을 하게 되면 &amp;nbsp;&lt;kbd&gt;Assigment to constant variable&lt;/kbd&gt; 인 &amp;nbsp;&lt;kbd&gt;TypeError&lt;/kbd&gt; 가 발생하게 됩니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const A = 10;
A = 20;&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;최초 선언시 할당하라 !&lt;/p&gt;
    &lt;p&gt;위에서 설명했듯이 상수를 선언과 동시에 할당을 해야만 합니다. 즉, 문장이 끝나기 전에 할당해 줘야 하는 것입니다.&lt;/p&gt;
    &lt;p&gt;다음과 같이 선언 후에 재할당을 하게 되면 할당되지 않습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const A;&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&lt;code&gt;const A;&lt;/code&gt; 라고만 선언하고 할당하지 않으면 &lt;kbd&gt;Missing initializer in const declaration&lt;/kbd&gt; 이란 문법 오류가 발생합니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;그리고 다음과 같이 다음 행에서 할당하더라도 오류가 나타납니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const A;
A = 10;&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;즉, &lt;code&gt;const&lt;/code&gt; 는 선언과 동시에 값을 할당해 주어야합니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p class=&quot;subtt&quot;&gt;참조타입 데이터의 경우&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; const OBJ = {
    prop1 : 1,
    prop2 : 2
};

OBJ = 10;&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;OBJ 자체에 접근하므로 오류가 발생합니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const OBJ = {
    prop1 : 1,
    prop2 : 2
};

OBJ.prop1 = 3;
console.log( OBJ );&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;위 코드는 &lt;code&gt;OBJ&lt;/code&gt; 자체에 접근한 것이 아니라 &lt;code&gt;OBJ&lt;/code&gt; 란 변수와는 별개의 다른 주소 공간에 저장되어 있기 때문에 &lt;code&gt;OBJ&lt;/code&gt; 가 가리키고 있는 따로 저장되어 있는 객체에 접근하여 객체 안에 있는
        &lt;code&gt;prop1&lt;/code&gt; 에 접근하라는 의미입니다. &lt;br&gt;
        즉, 상수는 OBJ 이고 객체 자체는 상수가 아니라는 뜻입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning check&quot;&gt;
        &lt;ul style=&quot;margin-top: 20px;margin-left: -20px;&quot;&gt;
            &lt;li&gt;&lt;kbd&gt;12번 : OBJ&lt;/kbd&gt; =&gt; OBJ 야... 너는 20번을 보고 있거라.. 그리고 너는 이제 상수이므로 20번이 아닌 다른 주소를 할당할 수 없느니라 !!!&lt;/li&gt;
            &lt;li&gt;&lt;kbd&gt;20번 : { }&lt;/kbd&gt;
                &lt;p&gt;=&gt; { } 이 객체는 &lt;kbd&gt;OBJ const&lt;/kbd&gt; 에 넣었기 때문에 이 객체 리터럴 자체를 바꿀 수 있는 방법은 없지만 객체 안에 있는 것은 상수가 아니기 때문에 얼마든지
                    변경할 수 있는 것입니다.&lt;/p&gt;
            &lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;다음의 코드를 예측해 보기 바랍니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let a = { prop1: 1};
const b = a;
b = 10;
a = 20;

console.log( b );&lt;/code&gt;&lt;/pre&gt;

    &lt;ul&gt;
        &lt;li&gt;@100 : a -&gt; 객체를 200번에 넣음&lt;/li&gt;
        &lt;li&gt;@200 : {prop1 : 1 }&lt;/li&gt;
        &lt;li&gt;@101 : b -&gt; @200번 객체를 바라봄&lt;/li&gt;
        &lt;li&gt;@100 : a -&gt; @1000&lt;/li&gt;
        &lt;li&gt;@1000 : 20&lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning tip&quot;&gt;
        &lt;p&gt;참조형 데이터를 상수에 할당할 경우에는 참조형 데이터 내부에 있는 프로퍼티들은 상수가 아니라는 점을 기억하기 바랍니다.&lt;/p&gt;
    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;다음은 배열을 const 에 할당했을 경우를 알아봅니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const ARR = [0, 1, 2];
ARR.push(3);

ARR = 10;
delete ARR[0];&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;let, const 공통 사항과 사용 전략&lt;/p&gt;
    &lt;p&gt;위에서 &lt;code&gt;let&lt;/code&gt;과 &amp;nbsp;&lt;code&gt;const&lt;/code&gt;에 대한 특성을 살펴봤다면 이 둘 간의 공통 사항들에 대해 알아보도록 하겠습니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p class=&quot;subtt&quot;&gt;유효범위&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;{
    let a = 10;
    {
        const b = 20;
        console.log(b);
    }
    console.log(a);
    console.log(b);
}
console.log(a);&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;재선언(재정의)&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;다음의 코드는 &lt;code&gt;var&lt;/code&gt;를 사용한 경우입니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var a = 0;
var a = 1;
console.log(a);&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;위 코드가 호이스팅을 하게 되면 다음과 같을 것입나다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var a;
var a; // 중첩되었으므로 하나만 남을 것임

a = 0;
a = 1;
console.log(a);&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;위와는 다르게 &amp;nbsp;&lt;code&gt;let&lt;/code&gt;과 &amp;nbsp;&lt;code&gt;const&lt;/code&gt; 를 사용한다면...&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let b = 2;
let b = 3;
console.log(b); // 식별자가 이미 선언되았다는 메시지가 출력&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const b = 2;
const b = 3;
console.log(b); // 식별자가 이미 선언되았다는 메시지가 출력&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;그렇다면 &amp;nbsp;&lt;code&gt;var&lt;/code&gt;와 &amp;nbsp;&lt;code&gt;let&lt;/code&gt;, &amp;nbsp;&lt;code&gt;const&lt;/code&gt;를 함께 사용한다면...&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var b = 10;
let b = 20;
console.log(b); // 식별자가 이미 선언되았다는 메시지가 출력&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;위 코드에서 확인했 듯이 &amp;nbsp;&lt;code&gt;var&lt;/code&gt;와 &amp;nbsp;&lt;code&gt;let&lt;/code&gt;, &amp;nbsp;&lt;code&gt;const&lt;/code&gt;는 함께 사용하지 않는 것이 좋습니다.&lt;/p&gt;
    &lt;p&gt;ES6 를 사용하는 환경에서는 &amp;nbsp;&lt;code&gt;var&lt;/code&gt;키워드를 사용하지 말 것을 권장하고 있습니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;그렇다면 let 과 const 중 무엇을 사용하는가?&lt;/p&gt;
    &lt;p&gt;이미 학습했다시피 &lt;code&gt;let&lt;/code&gt;, &amp;nbsp;&lt;code&gt;const&lt;/code&gt;는 목적이 다르지만 프론트엔드 환경에서는 전략적으로 &amp;nbsp;&lt;code&gt;const&lt;/code&gt;를 사용하는 편이 좋습니다.
        &lt;br&gt;
        일반적으로 프론트엔드 환경에서는 주로 객체를 다루기 때문이기도 하고 객체를 다루지 않는 변수를 쓰더라도 이 변수의 값을 재할당하면서 사용하는 경우가 생각보다 많지 않기 때문입니다.
        물론 변수의 값이 재할당이 필요한 경우라면 &amp;nbsp;&lt;code&gt;let&lt;/code&gt;을 사용하면 됩니다.
    &lt;/p&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning tip&quot;&gt;
        &lt;p&gt;&lt;code&gt;let&lt;/code&gt; : 값 자체의 변경이 필요한 예외적인 경우에 사용.&lt;/p&gt;
        &lt;p&gt;&lt;code&gt;const&lt;/code&gt; : 객체에 주로 사용.&lt;/p&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;전역 객체의 프로퍼티와 전역 변수&lt;/p&gt;
    &lt;p&gt;다음의 코드를 콘솔에서 확인해 보도록 하겠습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var a = 10;
console.log( window.a ); // 10
console.log( a ); // 10

delete a;
console.log( window.a ); // ?
console.log( a ); // ?

delete window.a; // 로그 확인해 볼 것&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var c = {
    d : 1
};
delete c.d; // 로그 확인해 볼 것

window.e = 10;
delete window.e;
console.log( e );

var f = 10;
delete f; // 로그 확인해 볼 것
delete window.f // 로그 확인해 볼 것&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;전역 공간에서 생성한 변수는 전역 변수임과 동시에 전액 객체의 프로퍼티가 됩니다. &lt;br&gt;
        전역 변수를 삭제하든 전역 객체의 프로퍼티를 삭제하든 간에 삭제가 되어야 하는 것이 논리적이긴 하지만 이러한 동작이 자바스크립트가 프로그래밍 언어로써 천대받는 이유 중의 하나이기도 했습니다.
        이러한 비논리적인 동작으로 인해 전역 변수의 선언을 최소화하고 전역 공간을 침범하지 않기 위해서 함수 스코프를 만든다던지 즉시 실행 함수를 사용한다던지 등의 다양한 디자인 패턴이 등장하게 된
        이유이기도 합니다.
    &lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;&amp;nbsp;&lt;code&gt;let&lt;/code&gt; 을 사용한다면...&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;let aa = 20;
console.log( window.aa );
console.log( aa );

delete aa; // 로그 확인해 볼 것

window.bb = 30;
delete bb; // 로그 확인해 볼 것&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;객체의 프로퍼티는 삭제할 수 있지만 그렇지 않은 것은 삭제할 수 없는 지극히 논리적인 형태로 변경되었습니다. &lt;br&gt;
        즉, 전역 객체의 공간과 전역 변수의 공간은 별개로써 동작하는 환경이 생겨났습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p class=&quot;tit&quot;&gt;for 문에서의 주의사항&lt;/p&gt;
    &lt;p&gt;반복문 내에서 &amp;nbsp;&lt;code&gt;const&lt;/code&gt; 를 사용시 특이한 점이 있는데 이에 대한 주의사항을 알아보겠습니다. &lt;/p&gt;
    &lt;p&gt;다음과 같은 객체가 있을 경우 &amp;nbsp;&lt;kbd&gt;for~in 문&lt;/kbd&gt;과 &amp;nbsp;&lt;kbd&gt;for 문&lt;/kbd&gt;을 사용해 본 코드입니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var obj = {
    prop1: 1,
    prop2: 1,
    prop3: 1
};

for (const prop in obj) {
    console.log( prop );
}

for (const i = 0; i &lt; 5; i++) {
    console.log( i );
}&lt;/code&gt;&lt;/pre&gt;

    &lt;script&gt;
        var obj = {
            prop1: 1,
            prop2: 1,
            prop3: 1
        };

        for (const prop in obj) {
            console.log( prop );
        }

        for (const i = 0; i &lt; 5; i++) {
            console.log( i );
        }
    &lt;/script&gt;
    &lt;p&gt;위 코드를 확인해 보면 &amp;nbsp;&lt;kbd&gt;for~in 문&lt;/kbd&gt;은 에러없이 결과를 출력하지만 &amp;nbsp;&lt;kbd&gt;for 문&lt;/kbd&gt;에서는 0 을 출력하고 &amp;nbsp;&lt;code&gt;Assignment to constant variable.&lt;/code&gt; 란 타입에러가 발생합니다.
        &amp;nbsp;&lt;kbd&gt;for 문&lt;/kbd&gt;에 대한 블록 스코프을 학습했을 때 &amp;nbsp;&lt;kbd&gt;for 문&lt;/kbd&gt;의 괄호(&lt;b&gt;{}&lt;/b&gt;)도 블록 스코프의 영역이고 &amp;nbsp;&lt;code&gt;const&lt;/code&gt;는 재할당이 되지 않는 상수라고 언급했습니다.
        &amp;nbsp; 이 개념대로라면 &amp;nbsp;&lt;kbd&gt;for 문&lt;/kbd&gt;의 &amp;nbsp;&lt;code&gt;i&lt;/code&gt; 를 출력했을 경우 &amp;nbsp;&lt;code&gt;i&lt;/code&gt; 를 재할당하려고 한 것이기 때문에 에러가 발생하는 것은 당연하지만
        &amp;nbsp;&lt;kbd&gt;for~in&lt;/kbd&gt; 문의 경우는 에러없이 출력된 것으로 의아해 할 수 있습니다.
    &lt;/p&gt;
    &lt;p&gt;예상해 보건대 위 코드에서 &amp;nbsp;&lt;kbd&gt;for~in 문&lt;/kbd&gt;은 다음과 같이 내부적으로 동작할 것으로 예측할 것입니다. &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;prop ⇒ prop1
prop ⇒ prop3
prop ⇒ prop2

prop = prop1;
prop = prop2;
prop = prop3;
&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&lt;code&gt;const&lt;/code&gt; 는 재할당이 되지 않는 상수인데도 불구하고 &amp;nbsp;&lt;kbd&gt;for~in 문&lt;/kbd&gt;에서는 재할당이 가능한 것으로 보이는 것은 예외적으로 이런 동작이 가능하도록 만들어 놓은 것이기 때문에
        이러한 특성을 암기(?)/숙지해야할 필요가 있습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;for~in 문&lt;/kbd&gt;에서 &amp;nbsp;&lt;code&gt;const&lt;/code&gt; 를 사용할 경우에는 내부적으로 다음과 같은 동작이 일어난다고 볼 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var obj = {
    prop1: 1,
    prop2: 1,
    prop3: 1
};

for (const prop in obj) {
    console.log( prop );
}

// 내부적으로 다음과 같은 동작이 발생
{
    let keys = Object.keys(obj); // 객체에 있는 키들을 가져와서 배열로 저장
    for (let i =0; i &lt; keys.length; i++) { // 배열을 순회
        const prop = obj[keys[i]];
        console.log( prop );
    }
}

// 즉, 여기서는 i 번째마다 각각의 블록 스코프가 생성
{
    const prop = obj[keys[0]];
    console.log( prop );
}
{
    const prop = obj[keys[1]];
    console.log( prop );
}
{
    const prop = obj[keys[2]];
    console.log( prop );
}&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var obj = {
            prop1: 1,
            prop2: 1,
            prop3: 1
        };

        for (const prop in obj) {
            console.log( prop );
        }

        // 내부적으로 다음과 같은 동작이 발생
        {
            let keys = Object.keys(obj); // 객체에 있는 키들을 가져와서 배열로 저장
            for (let i =0; i &lt; keys.length; i++) { // 배열을 순회
                const prop = obj[keys[i]];
                console.log( prop );
            }
        }

        // 즉, 여기서는 i 번째마다 각각의 블록 스코프가 생성
        {
            const prop = obj[keys[0]];
            console.log( prop );
        }
        {
            const prop = obj[keys[1]];
            console.log( prop );
        }
        {
            const prop = obj[keys[2]];
            console.log( prop );
        }
    &lt;/script&gt;--&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;h2 class=&quot;hh&quot;&gt;블록 스코프와 this&lt;/h2&gt;
    &lt;p&gt;다음의 코드를 살펴보도록 합니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt; var value = 0;
var obj = {
    value: 1,
    setValue: function () {
        this.value = 2;
        (function () {
            this.value = 3; // this : window, setValue, obj 중 무엇일까?
        })();
    }
};

obj.setValue();
console.log( value );
console.log( obj.value );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var value = 0;
        var obj = {
            value: 1,
            setValue: function () {
                this.value = 2;
                (function () {
                    this.value = 3; // this : window, setValue, obj 중 무엇일까?
                })();
            }
        };

        obj.setValue();
        console.log( value );
        console.log( obj.value );
    &lt;/script&gt;--&gt;

    &lt;p&gt;메소드에서 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 를 호출할 경우에는 &lt;kbd&gt;마침표(.)&lt;/kbd&gt;의 바로 앞에 그 대상이기 때문에 &amp;nbsp;&lt;code&gt;obj.value&lt;/code&gt; 는 2 가 출력됩니다. &lt;br&gt;
        그렇다면 즉시 실행 함수 내부에서의 &amp;nbsp;&lt;code&gt;this.value&lt;/code&gt; 의 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 는 무엇을 가리킬까요? &lt;br&gt;
        위 코드의 메소드 안에서 함수(즉시실행 함수)는 일반 함수로써 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 는 전역 객체인 &amp;nbsp;&lt;code&gt;window&lt;/code&gt; 를 가리킵니다. &lt;br&gt;
        즉, &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 는 &amp;nbsp;&lt;code&gt;window&lt;/code&gt; 를 가리키므로 &amp;nbsp;&lt;code&gt;window.value&lt;/code&gt; 라고 할 수 있어 &amp;nbsp;&lt;kbd&gt;console.log( value );&lt;/kbd&gt; 는 &amp;nbsp;&lt;kbd&gt;3&lt;/kbd&gt;이 출력될 것입니다.
    &lt;/p&gt;
    &lt;p class=&quot;mt20&quot;&gt;
        보통 개발자는 &amp;nbsp;&lt;code&gt;setValue&lt;/code&gt; 내부(메소드)에서의 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 와 중첩(내부)된 함수 안에서의 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 도 같았으면 하는 것이 편하고 논리적일 것입니다. &lt;br&gt;
        하지만 메소드 안의 중첩된 함수에서의 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 는 &amp;nbsp;&lt;code&gt;window&lt;/code&gt; 를 가리키는 특성때문에 &amp;nbsp;&lt;kbd&gt;ES5&lt;/kbd&gt; 까지만 하더라도 아래와 같은 코드로 우회하여&lt;br&gt;
        &lt;code&gt;this&lt;/code&gt;를 같도록 설정해 주었습니다.
    &lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var value = 0;
var obj = {
    value: 1,
    setValue: function () {
        this.value = 2;
        var self = this;
        (function () {
            self.value = 3;
        })();
    }
};

obj.setValue();
console.log( value );
console.log( obj.value );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var value = 0;
        var obj = {
            value: 1,
            setValue: function () {
                this.value = 2;
                var self = this;
                (function () {
                    self.value = 3;
                })();
            }
        };

        obj.setValue();
        console.log( value );
        console.log( obj.value );
    &lt;/script&gt;--&gt;

    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var value = 0;
var obj = {
    value: 1,
    setValue: function () {
        this.value = 2;
        var self = this;
        (function () {
            this.value = 3;
        }).call(this);
    }
};

obj.setValue();
console.log( value );
console.log( obj.value );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var value = 0;
        var obj = {
            value: 1,
            setValue: function () {
                this.value = 2;
                var self = this;
                (function () {
                    this.value = 3;
                }).call(this);

                /*var a = function () {
                    this.value = 3;
                };
                a.call( this );*/
            }
        };

        obj.setValue();
        console.log( value );
        console.log( obj.value );

    &lt;/script&gt;--&gt;

    &lt;p&gt;위 코드들은 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 우회하는 대표적인 방법들이지만 &amp;nbsp;&lt;kbd&gt;블록 스코프&lt;/kbd&gt;가 나타나면서 간결하게 변경되었습니다.&lt;/p&gt;
    &lt;p class=&quot;point-r mt20&quot;&gt;다음은 &amp;nbsp;&lt;kbd&gt;블록 스코프&lt;/kbd&gt;만 적용된 코드입니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var value = 0;
var obj = {
    value: 1,
    setValue: function () {
        this.value = 2;
        {
            this.value = 3;
        }
    }
};

obj.setValue();
console.log( value );
console.log( obj.value );&lt;/code&gt;&lt;/pre&gt;

    &lt;!--&lt;script&gt;
        var value = 0;
        var obj = {
            value: 1,
            setValue: function () {
                this.value = 2;
                {
                    this.value = 3;
                }
            }
        };

        obj.setValue();
        console.log( value );
        console.log( obj.value );
    &lt;/script&gt;--&gt;

    &lt;p&gt;이는 사용자가 스코프를 만들고 싶으면서 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 는 동일하게 사용하고 싶은 경우에 유용하게 활용할 수 있습니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
    &lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;var value = 0;
var obj = {
    value: 1,
    setValue: function () {
        let a = 20;
        this.value = 2;
        {
            let a = 10; // 내부에서만 사용하려고 하는 변수가 필요한 경우
            this.value = 3; // this 는 계속 동일하게 사용
        }
    }
};

obj.setValue();
console.log( value );
console.log( obj.value );&lt;/code&gt;&lt;/pre&gt;
    &lt;!--  &lt;script&gt;
		  var value = 0;
		  var obj = {
			  value: 1,
			  setValue: function () {
				  let a = 20;
				  this.value = 2;
				  {
					  let a = 10; // 내부에서만 사용하려고 하는 변수가 필요한 경우
					  this.value = 3; // this 는 계속 동일하게 사용
				  }
			  }
		  };

		  obj.setValue();
		  console.log( value );
		  console.log( obj.value );
	  &lt;/script&gt;--&gt;
    &lt;p&gt;
        사용자가 다른 변수를 사용하고 싶으면서 어떤 스코프가 필요로 할 경우에 즉, 내부에서만 사용하려고 하는 변수가 있을 때
        그 내부에서의 &amp;nbsp;&lt;code&gt;this&lt;/code&gt; 는 계속해서 동일하게 사용하려고 하는 경우 등에 활용할 수 있을 것입니다.
    &lt;/p&gt;
    &lt;p&gt;
        함수 스코프는 &amp;nbsp;&lt;kbd&gt;this 바인딩&lt;/kbd&gt;으로 인해 중첩된 함수는 &amp;nbsp;&lt;code&gt;window&lt;/code&gt; 를 가리키지만 블록 스코프는 &amp;nbsp;&lt;kbd&gt;this 바인딩&lt;/kbd&gt;을 하지 않는 특성으로 인해 바로 상위의
        &lt;code&gt;this&lt;/code&gt; 를 사용할 수 있습니다.
    &lt;/p&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;loof-wrap&quot;&gt;
        &lt;div class=&quot;loof&quot;&gt;
            &lt;svg class=&quot;rl-logo&quot; width=&quot;606&quot; height=&quot;300&quot; viewBox=&quot;0 0 606 300&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; preserveAspectRatio=&quot;none&quot;&gt;
                &lt;defs&gt;
                    &lt;clipPath id=&quot;clipLogo&quot;&gt;
                        &lt;path d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;
                        &lt;/path&gt;&lt;/clipPath&gt;
                &lt;/defs&gt;
                &lt;path class=&quot;rl-logo__path&quot; d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;&lt;/path&gt;
                &lt;path class=&quot;rl-logo__track&quot; clip-path=&quot;url(#clipLogo)&quot; d=&quot;M 323.9 178.9 C 344.8 202.5 383.7 245.8 412.2 261.3 C 447.3 282.3 494.3 278 527.7 255.5 C 586.6 217 597.8 127.5 557.2 72.1 C 530.3 33.4 479 17 434.2 28.2 C 389.3 41.5 358.1 79 330.7 114.3 C 318.9 128.6 277.3 185.4 277.3 185.4 C 249.9 220.7 218.7 258.1 173.8 271.5 C 129 282.7 77.7 266.3 50.8 227.6 C 10.2 172.2 21.4 82.7 80.3 44.2 C 113.7 21.6 160.7 17.4 195.8 38.4 C 224.3 53.9 261.2 96.2 282.1 119.7&quot;&gt;&lt;/path&gt;
            &lt;/svg&gt;
        &lt;/div&gt;
        &lt;div class=&quot;name&quot;&gt;
            Jaehee's&lt;span class=&quot;b&quot;&gt; WebClub&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>JavaScript/ES6+</category>
      <category>const</category>
      <category>ES6</category>
      <category>Let</category>
      <category>This</category>
      <author>jaiyah</author>
      <guid isPermaLink="true">https://webclub.tistory.com/644</guid>
      <comments>https://webclub.tistory.com/644#entry644comment</comments>
      <pubDate>Fri, 26 Feb 2021 16:30:10 +0900</pubDate>
    </item>
    <item>
      <title>Webpack Guide for beginner #3</title>
      <link>https://webclub.tistory.com/637</link>
      <description>&lt;h1 class=&quot;hh&quot;&gt;Webpack 기본 개발 환경을 위한 설정&lt;/h1&gt;
	&lt;p&gt;앞선 챕터에서 &lt;code&gt;webpack&lt;/code&gt; 의 기본 주요 속성들에 대해 알아보았습니다.&lt;/p&gt;
	&lt;p&gt;이번 장에서는 자주 사용되는 기본 개발 환경을 설정하면서 기타 유용한 사항들에 대해 알아보도록 하겠습니다.&lt;/p&gt;
	&lt;p&gt;참고로 여기서는 &lt;kbd&gt;SASS&lt;/kbd&gt;, &lt;kbd&gt;webpack-dev-server&lt;/kbd&gt; 등을 사용해 보도록 하겠습니다.&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 765px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/991DCE475DD34A3302&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F991DCE475DD34A3302&quot; width=&quot;765&quot; height=&quot;1410&quot; filename=&quot;config.final.jpg&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;

	&lt;p class=&quot;tac&quot;&gt;&lt;kbd&gt;webpack.config.js 개발환경 설정 사진&lt;/kbd&gt;&lt;/p&gt;


	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;tit&quot;&gt;프로젝트 초기 생성&lt;/p&gt;
	&lt;p&gt;앞선 내용을 따라 왔다면 &lt;kbd&gt;nodeJS&lt;/kbd&gt; 와 &lt;kbd&gt;webpack global&lt;/kbd&gt; 이 설치되어 있을 것입니다.
		만약 웹팩에 필요한 기본 설정이 되어 있지 않다면 이전 장을 참고하고, 여기서는 &lt;kbd&gt;nodeJS&lt;/kbd&gt; 와 &lt;kbd&gt;webpack global&lt;/kbd&gt; 이 설치되어 있음을 가정으로 진행합니다.
	&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;먼저 &lt;code&gt;node&lt;/code&gt;, &lt;code&gt;npm&lt;/code&gt; 버전을 확인 후 아래와 같이 디렉토리를 만들어 로컬에 &lt;code&gt;webpack&lt;/code&gt;과 &lt;code&gt;webpack-cli&lt;/code&gt;(커맨드라인에서 웹팩을 실행하는 도구)를 설치 및
		&lt;kbd&gt;package.json&lt;/kbd&gt;을 생성하는 초기 프로젝트 단계을 진행합니다.&lt;/p&gt;
	&lt;p class=&quot;point-r mt30&quot;&gt;프로젝트 초기 단계 설정&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;# npm, node 설치 확인
$ node -v
$ npm -v
$ mkdir getting-started &amp;amp;&amp;amp; cd getting-started
$ npm init -y
$ npm i webpack webpack-cli -D
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&lt;kbd&gt;CLI&lt;/kbd&gt;를 사용하지 않고 초기 디렉토리 생성은 사용자 편의대로 진행해도 무방합니다.&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;package.json&lt;/kbd&gt; 파일을 보면 아래와 같이 설치된 패키지를 확인하실 수 있습니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;// package.json
{
  &quot;name&quot;: &quot;getting-started&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;&quot;,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;scripts&quot;: {
    &quot;test&quot;: &quot;echo \&quot;Error: no test specified\&quot; &amp;amp;&amp;amp; exit 1&quot;
  },
  &quot;keywords&quot;: [],
  &quot;author&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;,
  &quot;devDependencies&quot;: {
    &quot;webpack&quot;: &quot;^4.36.1&quot;,
    &quot;webpack-cli&quot;: &quot;^3.3.6&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;div class=&quot;warning tip&quot;&gt;
		&lt;p class=&quot;subtt&quot;&gt;Version 보기 &amp;amp; 특정버전 설치&lt;/p&gt;
		&lt;p&gt;다음과 같이 웹팩의 특정 버전을 설치할 필요가 있다면 사용하고자 하는 버전을 확인한 후에 특정 버전을 설치할 수 있습니다.&lt;/p&gt;
		&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm view webpack versions --json
$ npm install webpack@3.8.1 --save-dev&lt;/code&gt;&lt;/pre&gt;
		&lt;p&gt;&amp;nbsp;&lt;/p&gt;

		&lt;p&gt;
			예를 들어 &lt;kbd&gt;jQuery&lt;/kbd&gt;의 특정 버전을 설치하려고 하는 경우 특정 버전을 모를 때 &amp;nbsp;&lt;code&gt;npm view jquery versions --json&lt;/code&gt; 를 통해 버전을 확인하고,
			&lt;code&gt;npm install jquery@2.2.4 --save&lt;/code&gt; 처럼 설치(jQuery 는 서비스시에 필요한 의존성이므로 &lt;code&gt;--save&lt;/code&gt; 로 설치)할 수 있습니다.
		&lt;/p&gt;
		&lt;p&gt;&lt;kbd&gt;CLI&lt;/kbd&gt;에서 아래와 같이 &lt;kbd&gt;jQuery versions&lt;/kbd&gt;을 확인할 수 있습니다.&lt;/p&gt;
		&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;[
	&quot;1.5.1&quot;,
	&quot;1.6.2&quot;,
	&quot;1.6.3&quot;,
	생략 ...
	&quot;2.2.4&quot;,
	&quot;3.0.0-alpha1&quot;,
	&quot;3.0.0-beta1&quot;,
	&quot;3.0.0-rc1&quot;,
	&quot;3.0.0&quot;,
	생략...
	&quot;3.4.0&quot;,
	&quot;3.4.1&quot;
]
&lt;/code&gt;&lt;/pre&gt;
	&lt;/div&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;subtt&quot;&gt;webpack.config.js 작성&lt;/p&gt;
	&lt;p&gt;&lt;kbd&gt;webpack.config.js&lt;/kbd&gt; 파일을 만들어 기본적인 웹팩에 필요한 초기 코드를 아래와 같이 작성해 봅니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;const path = require('path');

module.exports = {
    entry: './src/assets/js/main.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.app.js'
    },
    mode: 'development'
};&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;기본적인 &lt;code&gt;entry&lt;/code&gt;와, &lt;code&gt;mode&lt;/code&gt; 그리고 앞선 장에서 알아본 &lt;kbd&gt;path&lt;/kbd&gt; 모듈을 사용하여 &lt;code&gt;output&lt;/code&gt; 을 사용하였습니다. &lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;그리고 아래와 같이 &lt;kbd&gt;js 폴더&lt;/kbd&gt;와 &lt;kbd&gt;main.js&lt;/kbd&gt;, &lt;kbd&gt;sass 폴더&lt;/kbd&gt; 및 &lt;kbd&gt;index.html&lt;/kbd&gt; 을 추가로 진행하였습니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;getting-started
	│
	├─node_modules
	│  └─ ....
	│  └─ ....
	│  └─ 다수 모듈들
	│
	└─src
	│	│
	│	├─js
	│	│  └─main.js
	│	│
	│	└─sass
	│
	├─index.html
	├─package.json
	└─webpack.config.js
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;index.html&lt;/kbd&gt; 은 아래와 같이 기본 템플릿만 작성하였습니다.&lt;/p&gt;
	&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;html&quot;&gt;html&lt;/div&gt;&lt;/div&gt;
	&lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;ko&quot;&amp;gt;
&amp;lt;head&amp;gt;
	&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
	&amp;lt;title&amp;gt;Webpack beginner&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;main.js&lt;/kbd&gt; 는 단순히 로그만 작성해 봅니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;
// main.js
console.log( 'mainJS 테스트 실행' );&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;subtt&quot;&gt;플러그인 &lt;code&gt;html-webpack-plugin&lt;/code&gt; 설치&lt;/p&gt;
	&lt;p&gt;&lt;kbd&gt;html-webpack-plugin&lt;/kbd&gt;은 번들 된 파일을 &lt;code&gt;&amp;lt;script /&amp;gt;&lt;/code&gt;로 로드한 &lt;kbd&gt;html&lt;/kbd&gt; 파일을 자동으로 생성해 주는 &lt;kbd&gt;plugin&lt;/kbd&gt;입니다.&lt;/p&gt;
	&lt;p&gt;
		앞서 진행했 듯이 기본적으로, 번들링한 css, js 파일들은 &lt;kbd&gt;html&lt;/kbd&gt; 파일에
		&lt;code&gt;&amp;lt;script/&amp;gt;&lt;/code&gt; 나 &lt;code&gt;&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;style.css&quot;&amp;gt;&lt;/code&gt; 코드를 직접 추가 작성해야하는 번거로움이 있습니다.
	&lt;/p&gt;
	&lt;p&gt;이런 번거로운 작업을 &lt;kbd&gt;html-webpack-plugin&lt;/kbd&gt;을 사용하면 이 과정을 자동화 할 수 있습니다. &lt;/p&gt;
	&lt;p&gt;
		&lt;kbd&gt;Webpack&lt;/kbd&gt;의 성능을 향상시키고 개발 편리성 목적이 이 플러그인의 역할입니다. &lt;br /&gt;
		다시 말해, 설정에 따라 새로운 html 파일을 생성할 수도, 기존의 html 에 번들 된 파일을 &lt;code&gt;&amp;lt;script/&amp;gt;&lt;/code&gt;로 로드한 html 파일을 생성 할 수도 있습니다.
		그리고 해시(hash)된 파일 이름을 사용하는 webpack 번들을 로드하는데 유용하게 사용됩니다.
	&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;html-webpack-plugin&lt;/kbd&gt; 플러그인 사용을 위해 아래와 같이 설치합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm i html-webpack-plugin --save-dev&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;설치가 완료되면 &lt;kbd&gt;webpack.config.js&lt;/kbd&gt; 파일을 아래와 같이 수정합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // html-webpack-plugin 불러옴

module.exports = {
    entry: './src/js/main.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.app.js'
    },
    // 플러그인 설정
    plugins: [
        new HtmlWebpackPlugin({
            template: 'index.html', // 빌드 전에 사용되는 템플릿
            filename: 'index.html' // 빌드 후에 생성될 파일명
        })
    ],
    mode: 'development'
};&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;그리고 터미널(CLI)에서 &lt;code&gt;webpack&lt;/code&gt; 명령어를 실행한 후 &lt;kbd&gt;dist/index.html&lt;/kbd&gt;이 생성되고 아래와 같이 임포트된 &lt;code&gt;script&lt;/code&gt;를 확인할 수 있습니다.&lt;/p&gt;
	&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;html&quot;&gt;html&lt;/div&gt;&lt;/div&gt;
	&lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;ko&quot;&amp;gt;
&amp;lt;head&amp;gt;
	&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
	&amp;lt;title&amp;gt;Webpack beginner&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;script type=&quot;text/javascript&quot; src=&quot;bundle.app.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;그리고 &lt;kbd&gt;main.js&lt;/kbd&gt;에서 작성한 로그는 브라우저 개발자 도구의 &lt;kbd&gt;console&lt;/kbd&gt; 패널에서 확인하실 수 있습니다.&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;


	&lt;div class=&quot;warning info&quot;&gt;
		&lt;p&gt;&lt;code&gt;html-webpack-plugin&lt;/code&gt;에 대한 자세한 사용법은 다음의 링크에서 확인해 보실 수 있습니다.&lt;/p&gt;
		&lt;div class=&quot;link-refer&quot;&gt;

			&lt;h3&gt;Related Info&lt;/h3&gt;

			&lt;ol&gt;
				&lt;li&gt;&lt;a href=&quot;https://webpack.js.org/plugins/html-webpack-plugin/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;웹팩 공식페이지(HtmlWebpackPlugin)&lt;/a&gt;&lt;/li&gt;
				&lt;li&gt;&lt;a href=&quot;https://github.com/jantimon/html-webpack-plugin#options&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;HtmlWebpackPlugin documentation&lt;/a&gt;&lt;/li&gt;
			&lt;/ol&gt;

		&lt;/div&gt;
	&lt;/div&gt;


	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;

	&lt;p class=&quot;tit&quot;&gt;Custom JS &amp;amp; library 사용하기&lt;/p&gt;
	&lt;p&gt;이제 사용자 스크립트와 기타 라이브러리를 사용하면서 번들링해 보도록 하겠습니다. &lt;/p&gt;
	&lt;p&gt;여기서는 &lt;code&gt;jQuery&lt;/code&gt;와 &lt;code&gt;moment&lt;/code&gt;를 간단히 사용하면서 JS 파일을 번들링해 봅니다.&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;code&gt;jQuery&lt;/code&gt; 와 &lt;code&gt;moment&lt;/code&gt; 를 사용을 위해 다음과 같이 라이브러리를 다운로드 받습니다. &lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm i -S jquery moment&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;
		라이브러리 설치가 완료되었다면 &lt;code&gt;jquery&lt;/code&gt;, &lt;code&gt;moment&lt;/code&gt; 를 사용을 위해 다음과 같이 &lt;kbd&gt;index.html&lt;/kbd&gt;을 작성하고
		&lt;kbd&gt;main.js&lt;/kbd&gt; 와  &lt;kbd&gt;module01.js&lt;/kbd&gt;, &lt;kbd&gt;module02.js&lt;/kbd&gt;를 추가 생성하여
		다음과 같이 작성해 봅니다.
	&lt;/p&gt;

	&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;html&quot;&gt;html&lt;/div&gt;&lt;/div&gt;
	&lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;ko&quot;&amp;gt;
&amp;lt;head&amp;gt;
	&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
	&amp;lt;title&amp;gt;webpack beginner&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

	&amp;lt;header&amp;gt;
		&amp;lt;h3&amp;gt;Libraries Code Splitting&amp;lt;/h3&amp;gt;
	&amp;lt;/header&amp;gt;
	&amp;lt;div&amp;gt;
		&amp;lt;label&amp;gt;&amp;lt;strong&amp;gt;Moment JS : &amp;lt;/strong&amp;gt;&amp;lt;/label&amp;gt;
		&amp;lt;p class=&quot;main-moment&quot;&amp;gt;
			not yet Moment loaded
		&amp;lt;/p&amp;gt;
		&amp;lt;br&amp;gt;
		&amp;lt;label&amp;gt;&amp;lt;strong&amp;gt;jQuery : module1.js&amp;lt;/strong&amp;gt;&amp;lt;/label&amp;gt;
		&amp;lt;p class=&quot;jQ&quot;&amp;gt;jQuery 사용전&amp;lt;/p&amp;gt;
		&amp;lt;br&amp;gt;
		&amp;lt;label&amp;gt;&amp;lt;strong&amp;gt;Moment JS : module01.js&amp;lt;/strong&amp;gt;&amp;lt;/label&amp;gt;
		&amp;lt;p class=&quot;module01&quot;&amp;gt;module1 에서 사용&amp;lt;/p&amp;gt;
		&amp;lt;br&amp;gt;
		&amp;lt;label&amp;gt;&amp;lt;strong&amp;gt;jQuery : module02.js&amp;lt;/strong&amp;gt;&amp;lt;/label&amp;gt;
		&amp;lt;p class=&quot;module02&quot;&amp;gt;module2 사용&amp;lt;/p&amp;gt;
	&amp;lt;/div&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;

	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;main.js&lt;/kbd&gt;에서는 &lt;code&gt;moment&lt;/code&gt; 라이브러리를 사용.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// main.js

import moment from 'moment';
const ele = document.querySelector('.main-moment');

document.addEventListener(&quot;DOMContentLoaded&quot;, function(event) {
    ele.innerText = moment().format();
});&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;


	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;module01.js&lt;/kbd&gt;에서는 &lt;code&gt;jQuery&lt;/code&gt;와 &lt;code&gt;moment&lt;/code&gt; 라이브러리를 동시 사용.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// module01.js

import $ from 'jquery';
const moment = require('moment');
// require(), import '' 등의 모듈 로딩시에 어느 폴더를 기준할 것인지 정하는 옵션

$(function() {
    $('.jQ').text('module01.js 에서 jQuery 를 사용하고 있습니다!!!');
});
$('.module01').text( moment().format());&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;module02.js&lt;/kbd&gt; 에서는 &lt;code&gt;jQuery&lt;/code&gt; 라이브러리만 사용.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import $ from 'jquery';

$(function() {
    $('.module02').text('module-02.js 에서 jQuery 를 사용중입니다.');
});
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;마지막으로 &lt;kbd&gt;webpack.config.js&lt;/kbd&gt;를 업데이트하도록 합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // html-webpack-plugin 불러옴

module.exports = {
    entry: {
        'index': ['./src/js/main.js'], // index.js 생성
        'module': ['./src/js/module01.js', './src/js/module02.js'] // module.js 생성
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js'
    },
    // 플러그인 설정
    plugins: [
        new HtmlWebpackPlugin({
            template: 'index.html',
            filename: 'index.html'
        })
    ],
    mode: 'development'
};&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;위와 같이 작성 완료되었다다면 터미널에서 &lt;code&gt;webpack&lt;/code&gt;을 실행해 보세요.&lt;/p&gt;
	&lt;p&gt;&lt;kbd&gt;dist/index.html&lt;/kbd&gt; 에서 &lt;code&gt;jQuery&lt;/code&gt; 와 &lt;code&gt;moment&lt;/code&gt; 가 로드되어 사용되고 있는 것을 확인할 수 있습니다.&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;subtt&quot;&gt;splitChunks&lt;/p&gt;
	&lt;p&gt;위에서 작성한 방법에는 문제점이 있습니다.&lt;/p&gt;
	&lt;p&gt;
		라이브러리는 잘 동작하지만 번들링된 &lt;kbd&gt;index.js&lt;/kbd&gt;와 &lt;kbd&gt;module.js&lt;/kbd&gt;를 확인해 보면 라이브러리(jQuery, moment)가 각각 로드되어 각 파일에 포함되어 있습니다.
		이는 당연히 사용자가 원치않는 구성일 뿐더러 일반적인 방법이 아닙니다.&lt;/p&gt;
	&lt;p&gt;이를 해결하기 위해서는 &lt;kbd&gt;index.js&lt;/kbd&gt; 와 &lt;kbd&gt;module.js&lt;/kbd&gt;에 중복된 라이브러리인 코드 분할이 필요하게 됩니다. &lt;/p&gt;
	&lt;p&gt;
		&lt;mark&gt;코드 분할(Code Splitting)은 웹팩이 제공하는 좋은 기술&lt;/mark&gt; 중 하나로, 엔트리에서 사용하는 공통된 작은 번들로 나눌 수 있어서 애플리케이션을 로드하는 시간에 영향을 줄 수 있습니다.&lt;/p&gt;
	&lt;p&gt;위 코드 &lt;kbd&gt;main.js&lt;/kbd&gt;, &lt;kbd&gt;module01.js&lt;/kbd&gt;, &lt;kbd&gt;module02.js&lt;/kbd&gt; 의 각 청크간에 중복되는 패키지(여기선 라이브러리)들이 존재하고 있으며,
		이렇게 청크(chunk)간에 겹치는 패키지들을 별도의 파일로 추출하여 번들링할 수 있는데 이를 웹팩에서는 &lt;code&gt;vendor&lt;/code&gt; 부르고 있습니다.
	&lt;/p&gt;
	&lt;p&gt;
		벤더를 만드는 이유는
		한 파일이 (a, b, c) 패키지를 가지고 있고, 또 다른 파일이 (a, b, d) 패키지를 가지고 있다면, a와 b 패키지가 겹치기 때문에 두 번 로드하여 쓸모없는 용량을 차지하게 됩니다.
		이런 것은 vendor~A~B (a, b)로 만들어주고, A 청크는 (c), B 청크는 (d)로 만들어 중복을 최소화주어야 하기 때문입니다.
	&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;이전 &lt;kbd&gt;webpack v3&lt;/kbd&gt;에서는 직접 벤더를 지정해야 했으나, &lt;kbd&gt;v4&lt;/kbd&gt;에서는 웹팩이 알아서 벤더를 생성하여 줍니다.&lt;/p&gt;
	&lt;p&gt;&lt;code&gt;vendor&lt;/code&gt; 를 사용하기 위해서는 &lt;kbd&gt;webpack.config.js&lt;/kbd&gt;에 &lt;code&gt;optimization&lt;/code&gt; 속성을 추가하고 다음과 같이 정의해 줄 수 있습니다. &lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // html-webpack-plugin 불러옴

module.exports = {
    entry: {
        'index': ['./src/js/main.js'],
        'module': ['./src/js/module01.js', './src/js/module02.js'],
        // vendor: ['lodash', 'jquery'], // webpack v4 이전 방식
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
        // chunkFilename : '[name].js' // webpack v4 이전 방식
    },
    // 플러그인 설정
    plugins: [
        new HtmlWebpackPlugin({
            template: 'index.html',
            filename: 'index.html'
        })
    ],
    // optimization 로 중복된 모듈 없애기
    optimization: {
		// Splitting Duplicated Chunk
        // 전체 응용 프로그램의 vendors 모든 코드를 포함 하는 청크
		// 즉, 자주 사용되어 중복으로 import 된 모듈을 별도의 chunk 파일로 생성하기 위한 설정이다.
		// 번들 파일을 적절히 분리함으로써 브라우저 캐시를 전략적으로 활용할 수 있어 초기 로딩속도를 최적화할 수 있다.
        splitChunks: {
			// cacheGroups : 명시적으로 특정 파일들을 청크로 분리할 때 사용
            cacheGroups: {
                vendors: {
					// 대상이 되는 파일 지정(여기서는 node_modules 디렉터리에 있는 파일들이 대상)
                    test: /[\\/]node_modules[\\/]/,
					// 비동기 및 동기 모듈을 통한 최적화(test 조건에 포함되는 모든 것을 분리하겠다는 뜻)
                    chunks: 'all',
					// 청크로 분리할 때 이름으로 사용될 파일명
                    name: 'libs',
                }
            }
        }
    },
    mode: 'development'
};&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;
		기존 webpack v3 이전에는 &lt;code&gt;CommonsChunkPlugin&lt;/code&gt;을 이용해 사용에 맞게 자동으로 번들 파일을 분리했던 기능을 &lt;code&gt;optimization&lt;/code&gt;의
		&lt;code&gt;splitChunk&lt;/code&gt; 옵션을 통해 할 수 있습니다. &lt;br /&gt;
		이렇게 &lt;code&gt;splitChunk&lt;/code&gt;를 이용하면 대형 프로젝트에서 거대한 번들 파일을 적절히 분리하고 나눌 수 있으며,
		파일 사이즈, 비동기 요청 횟수 등의 옵션에 따라 자동으로 분리할 수 있고 정규식에 따라서 특정 파일들만 분리할 수 있고 혹은 특정 엔트리 포인트를 분리할 수 있습니다. &lt;br /&gt;
		번들 파일을 적절히 분리하면 브라우저 캐시를 전략적으로 활용할 수 있으며 초기 로딩속도를 최적화할 수도 있고,
		프로젝트의 필요에 따라 엔트리 포인트를 분리해서 여러 가지 번들 파일을 만들 때도 사용할 수 있습니다.
	&lt;/p&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;div class=&quot;warning info&quot;&gt;
		&lt;p class=&quot;subtt&quot;&gt;chunks 옵션&lt;/p&gt;
		&lt;ul&gt;
			&lt;li&gt;
				&lt;code&gt;all&lt;/code&gt; : test 조건에 해당하는 모든 모듈
				&lt;p&gt;이봐, 웹팩!! 동적으로 가져온 모듈 또는 비동기적으로 가져온 모듈인지 상관하지 않고 이들 모두에 최적화를 적용해줘..&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;code&gt;initial&lt;/code&gt; : 초기 로딩에 필요한 경우
				&lt;p&gt;
					이봐, 웹팩! 동적으로 가져온 모듈에 관한 건 상관 없는데 그들 각각에 대해 별도의 파일을 가질 수 있게 해줘, &lt;br /&gt;
					대신 비동기적으로 가져온 모듈을 다른 모듈과 공유하고 청크할 준비가되어 있지만 비동기적으로 가져온 모듈을 하나의 번들로 모두 가져오려고 해..
				&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;code&gt;async&lt;/code&gt; : &lt;kbd&gt;import()&lt;/kbd&gt; 를 이용해 다이나믹하게 사용되는 경우
				&lt;p&gt;
					이봐, 웹팩! 난 동적으로 가져온 모듈의 최적화에만 관심있으니 비동기적으로 가져온 모듈은 그대로 둬..
				&lt;/p&gt;
			&lt;/li&gt;
		&lt;/ul&gt;

	&lt;/div&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&lt;kbd&gt;webpack.config.js&lt;/kbd&gt;를 위와 같이 업데이트했다면 다시 &lt;code&gt;webpack&lt;/code&gt;을 실행해 보세요.&lt;/p&gt;
	&lt;p&gt;실행한 결과 &lt;kbd&gt;dist/index.js, module.js, libs.js&lt;/kbd&gt;가 생성되어 있으며 &lt;kbd&gt;libs.js&lt;/kbd&gt; 파일 내부에 &lt;code&gt;jquery&lt;/code&gt;,
		&lt;code&gt;moment&lt;/code&gt; 라이브러리가 함께 포함되어 있는 것을 확인하실 수 있습니다.  &lt;/p&gt;
	&lt;p&gt;그리고 &lt;kbd&gt;dist/index.html&lt;/kbd&gt; 을 확인해 보면 웹팩이 자동으로 스크립트 의존성에 맞게 다음과 같이 &lt;kbd&gt;import&lt;/kbd&gt;하고 있는 것을 확인하실 수 있습니다.&lt;/p&gt;
	&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;html&quot;&gt;html&lt;/div&gt;&lt;/div&gt;
	&lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;script type=&quot;text/javascript&quot; src=&quot;libs.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&quot;text/javascript&quot; src=&quot;index.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&quot;text/javascript&quot; src=&quot;module.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;subtt&quot;&gt;dist 내부 폴더 나누기 &amp;amp; 편하게 라이브러리 로드(ProvidePlugin)하여 사용하기 &lt;/p&gt;
	&lt;p&gt;지금까지는 &lt;kbd&gt;dist&lt;/kbd&gt; 폴더내에 자원들을 하위폴더로 분리하지 않고 사용하였으나 좀더 실무에 적합하도록 앞으로 사용할 &lt;kbd&gt;css&lt;/kbd&gt;와 &lt;kbd&gt;js&lt;/kbd&gt; 폴더를 나누기 위해서 하위 폴더를 구성해 보도록 하고,
		&lt;kbd&gt;main.js, module01.js, module02.js&lt;/kbd&gt;에서 라이브러리를 &lt;code&gt;import&lt;/code&gt; 하여 사용했던 구문, &amp;nbsp;
		예를 들어, jQuery 를 사용하고 있는 모든 모듈 JS 마다 &lt;code&gt;import $ from 'jquery';&lt;/code&gt; 불러온다면 꽤나 번거로운 일입니다. &lt;br /&gt;
		이를 수정하여 좀더 편하게 라이브러리를 로드하여 사용하는 방법에 대해 알아보도록 하겠습니다.
	&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;webpack.config.js&lt;/kbd&gt;를 다음과 같이 수정하도록 합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;const path = require('path');
const webpack = require('webpack'); // webpack 로드
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: {
        // 여기서는 output.path 의 dist 기준으로 폴더 생성
        'js/index': ['./src/js/main.js'],
        'js/module': ['./src/js/module01.js', './src/js/module02.js'],
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
    },
    // 플러그인 설정
    plugins: [
        new HtmlWebpackPlugin({
            template: 'index.html',
            filename: 'index.html'
        }),

        // 모든 라이브러리를 불러올 때
        new webpack.ProvidePlugin({
            // 라이브러리 로딩
            $: 'jquery',
            jQ : 'jquery',
            moment : 'moment'
        })
    ],
    optimization: {
        splitChunks: {
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    chunks: 'all',
                    // 여기서는 output.path dist 기준으로 폴더 생성
                    name: 'js/vendor/libs',
                }
            }
        }
    },
    mode: 'development'
};&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;
		&lt;code&gt;import $ from 'jquery';&lt;/code&gt; 와 같은 구문을 사용하지 않고 라이브러리를 불러오고자 할 경우에는 웹팩에서 제공하는 풀러그인 &lt;code&gt;ProvidePlugin&lt;/code&gt;를 사용할 수 있습니다. &amp;nbsp;
		위와 같이 라이브러리를 담아올 별칭을 정하고 라이브러리의 &lt;kbd&gt;node_module&lt;/kbd&gt; 이름을 작성하면 됩니다. &lt;br /&gt;
		그리고 하위 폴더를 구성하고자 하는 경우에는 &lt;code&gt;entry&lt;/code&gt;의 &lt;kbd&gt;key&lt;/kbd&gt;를 &lt;kbd&gt;/&lt;/kbd&gt; 를 구분자로 사용할 수 있습니다. &lt;br /&gt;
		예를 들어, 현재 &lt;kbd&gt;webpack.config.js&lt;/kbd&gt; 를 기준으로 진행할 경우 key 를 &lt;kbd&gt;'js/common'&lt;/kbd&gt; 작성했다면
		&lt;kbd&gt;dist/js/common.js&lt;/kbd&gt; 가 번들링될 것입니다. &lt;br /&gt;
		즉, 마지막 &lt;kbd&gt;/(슬래시)&lt;/kbd&gt;의 다음 문자열이 &lt;code&gt;output.filename&lt;/code&gt; 의 &lt;kbd&gt;'[name]'&lt;/kbd&gt; 으로 치환되게 됩니다.
	&lt;/p&gt;
	&lt;p class=&quot;mt30&quot;&gt;&lt;kbd&gt;webpack.config.js&lt;/kbd&gt;를 위와 같이 수정하였다면 기존에 작성했던 &lt;kbd&gt;main.js, module01.js, module02.js&lt;/kbd&gt; 를 아래와 같이 수정해 보도록 합니다.&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;main.js&lt;/kbd&gt; 에서 &lt;code&gt;import&lt;/code&gt; 구문 제거&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// main.js

const ele = document.querySelector('.main-moment');

document.addEventListener(&quot;DOMContentLoaded&quot;, function(event) {
    ele.innerText = moment().format();
});&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;module01.js&lt;/kbd&gt; 에서 &lt;code&gt;import, require&lt;/code&gt; 구문 제거&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// module01.js

$(function() {
    $('.jQ').text('module01.js 에서 jQuery 를 사용하고 있습니다!!!');
});
$('.module01').text( moment().format());&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;module02.js&lt;/kbd&gt; 에서 &lt;code&gt;import, require&lt;/code&gt; 구문 제거&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// module02.js

jQ(function() {
    jQ('.module02').text('module-02.js 에서 jQ 로 치환하여 사용중입니다.');
});&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;모든 JS 파일 수정 후에 &lt;code&gt;webpack&lt;/code&gt;을 실행하면 &lt;kbd&gt;dist/index.html&lt;/kbd&gt;에서 이상없이 라이브러리가 잘 로드되어 동작하고 있을 것입니다.
		&amp;nbsp;&amp;nbsp;
	&lt;/p&gt;
	&lt;p class=&quot;point-r mt30&quot;&gt;그리고 &lt;kbd&gt;dist&lt;/kbd&gt; 하위 디렉토리 구성 또한 다음과 같이 구성되어 있을 것입니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;dist
  │
  └─js
  │	├─vendor
  │	│  └─libs.js
  │	│
  │	├─index.js
  │	└─module.js
  │
  └─index.html&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;


	&lt;p class=&quot;tit&quot;&gt;webpack sass 컴파일&lt;/p&gt;
	&lt;p&gt;이번에는 웹팩을 통해 &lt;code&gt;sass&lt;/code&gt;를 컴파일하는 방법에 대해 살펴봅니다. &lt;br /&gt;
		&lt;code&gt;css&lt;/code&gt;만 번들링하는 것보다는 &lt;code&gt;sass&lt;/code&gt;를 번들링해 보면서 기타 &lt;kbd&gt;loader(로더)&lt;/kbd&gt;들의 쓰임새를 알아보는 것이 웹팩을 알아보는데 효과적일 것입니다.
		&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r mt30&quot;&gt;먼저 필요한 패키지를 다음과 같이 설치하도록 합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm install node-sass style-loader css-loader sass-loader --save-dev&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&lt;code&gt;node-sass&lt;/code&gt; 는 &lt;kbd&gt;node.js&lt;/kbd&gt; 환경에서 사용할 수 있는 Sass 라이브러리로 실제로 Sass 를 css 로 컴파일하는 것은
		&lt;code&gt;node-sass&lt;/code&gt; 이기 때문에 &lt;code&gt;node-sass&lt;/code&gt; 설치가 필요하며, &lt;code&gt;style-loader, css-loader, sass-loader&lt;/code&gt; 는 Webpack 플러그인입니다.
	&lt;/p&gt;
	&lt;p class=&quot;mt30 point-r&quot;&gt;그리고 앞선 내용에서 언급했던 &lt;code&gt;mini-css-extract-plugin&lt;/code&gt;(컴파일된 css 를 별도의 css 파일로 분리)를 설치하도록 합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm install --save-dev mini-css-extract-plugin&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&lt;kbd&gt;Sass&lt;/kbd&gt; 컴파일을 위한 sass 테스트 파일은 아래의 압축파일을 받으신 후 &lt;kbd&gt;src/sass&lt;/kbd&gt; 폴더로 복사해서 사용하시기 바랍니다.&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;현재까지 &lt;kbd&gt;src&lt;/kbd&gt; 폴더 구성은 다음과 같습니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;src
  ├─js
  │      main.js
  │      module01.js
  │      module02.js
  │
  └─sass
  	  ├─common
  	  │      _extend.scss
  	  │      _layout.scss
  	  │      _reset.scss
  	  │
  	  └─partials
  	  │		_extend.scss
  	  │		_mixins.scss
  	  │		_variables.scss
  	  │
  	  │  _common.scss
  	  │  _partials.scss
  	  │  pages.scss
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;

	&lt;p class=&quot;point-r&quot;&gt;이제 &lt;kbd&gt;sass&lt;/kbd&gt; 컴파일을 위한 &lt;kbd&gt;webpack.config.js&lt;/kbd&gt; 를 수정하도록 합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // mini-css-extract-plugin 로드

module.exports = {
    entry: {
        'js/index': ['./src/js/main.js', './src/sass/pages.scss'], // sass 파일 추가
        'js/module': ['./src/js/module01.js', './src/js/module02.js'],
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
    },
    module: {
        rules: [
            {
                // 대상 파일 지정
                test: /\.s(a?c)ss$/, // /\.(sa|sc|c)ss$/, /\.s(a?c)ss$/,
                use: [
                    // 트랜스파일링이 된 것을 외부 css 파일로 추출하는 역할
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
							// publicPath 는 Webpack 이 번들을 (선택적으로)로드 할 곳입니다.
                        	// entry 가 현재 'js/index' 로 js 폴더 내에 생성하지 않고 상위폴더로 빼내기 위함
                            publicPath: '../'
                        }
                    },

                    // css-loader : css 를 CommonJS 방식의 js 로 트랜스파일링 하는 역할
                    'css-loader',

                    // sass-loader : 기본적으로 node-sass 를 사용하여 sass 를 css 로 컴파일하는 역할
                    {
                        loader: 'sass-loader',
                        options: {
                            outputStyle: 'expanded',
                            indentType: 'tab', // 정의되어 있지 않으면 기본값은 space
                            indentWidth: 1 // 기본값 2
                        }
                    }
                    // &quot;sass-loader?outputStyle=expanded&quot;, // outputStyle=compressed
                ],
                exclude: /node_modules/
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'index.html',
            filename: 'index.html'
        }),

        new webpack.ProvidePlugin({
            $: 'jquery',
            jQ : 'jquery',
            moment : 'moment'
        }),

        // 컴파일 + 번들링 CSS 파일이 저장될 경로와 이름 지정
        new MiniCssExtractPlugin({
            // MiniCssExtractPlugin.loader 의 publicPath: '../' 의 설정을 통해
            // js 폴더를 빠져나와 dist/css/style.css 를 생성하게 됨
            filename: 'css/style.css'
        })
    ],
    optimization: {
        splitChunks: {
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    chunks: 'all',
                    name: 'js/vendor/libs',
                }
            }
        }
    },
    mode: 'development'
};&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;작성이 끝난 후 &lt;code&gt;webpack&lt;/code&gt;을 실행해 보면 &lt;kbd&gt;dist/css/style.css&lt;/kbd&gt; 가 생성되어 있는 것을 확인하실 수 있습니다.&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;그리고 성격이 다른 모듈 분리 차원에서 다음과 같이 &lt;code&gt;entry&lt;/code&gt;에 작성한 &lt;kbd&gt;'./src/sass/pages.scss'&lt;/kbd&gt; sass 를 삭제하고 &lt;kbd&gt;main.js&lt;/kbd&gt; 내에 &lt;code&gt;import&lt;/code&gt; 구문을 &lt;br /&gt; 이용하는 편이 좋습니다. &lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;sass 모듈 엔트리 포인트에서 제거 후 &lt;kbd&gt;import&lt;/kbd&gt; 구문을 이용하여 로드하기&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;import '../sass/pages.scss'; // sass 로드
const ele = document.querySelector('.main-moment');

document.addEventListener(&quot;DOMContentLoaded&quot;, function(event) {
    ele.innerText = moment().format();
});&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;subtt&quot;&gt;풍부한 CSS 환경을 위한 PostCSS&lt;/p&gt;
	&lt;p&gt;
		&lt;a href=&quot;https://github.com/postcss/postcss&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;PostCSS&lt;/a&gt; 는 JS 플러그인을 사용하여 CSS 를 변환시키는 도구로서 변수, mixin 을 사용하거나, 인라인 이미지 또는 미래의 CSS 문법을 사용할 수 있습니다.
		&amp;nbsp;다시 말해, &lt;kbd&gt;PostCSS&lt;/kbd&gt; 는 자바스크립트 기반의 플러그인을 사용하여 CSS 기능을 자동화하는 소프트웨어 개발 도구입니다.
	&lt;/p&gt;
	&lt;p&gt;
		&lt;kbd&gt;PostCSS&lt;/kbd&gt; 플러그인에는 300여개에 달하는 플러그인들(&lt;a href=&quot;https://github.com/postcss/postcss/blob/master/docs/plugins.md&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;PostCSS 플러그인 리스트&lt;/a&gt;)이 있으며
		국내 환경에서 유용한 &lt;a href=&quot;https://github.com/postcss/autoprefixer&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;autoprefixer&lt;/a&gt; 도 사용할 수 있습니다.
		&amp;nbsp;&amp;nbsp;여기서는 &lt;a href=&quot;https://postcss.org/&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;PostCSS 공식 홈페이지&lt;/a&gt;에서 소개하는
		&lt;code&gt;grid system&lt;/code&gt; 과&lt;code&gt;autoprefixer&lt;/code&gt; 를 간단히 사용해 보도록 하겠습니다.
	&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;먼저 &lt;kbd&gt;PostCSS&lt;/kbd&gt;를 사용을 위해 패키지 &lt;code&gt;postcss-loader&lt;/code&gt;, &lt;kbd&gt;PostCSS&lt;/kbd&gt;의 플러그인 종류 중에 &lt;code&gt;autoprefixer&lt;/code&gt;와 그리드 시스템 플러그인
		&lt;code&gt;lost&lt;/code&gt;를 설치하도록 합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm i -D postcss-loader autoprefixer lost&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;webpack.config.js&lt;/kbd&gt;를 업데이트를 위해 다음과 같이 작성합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    entry: {
        'js/index': ['./src/js/main.js'],
        'js/module': ['./src/js/module01.js', './src/js/module02.js'],
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
    },
    module: {
        rules: [
            {
                test: /\.s(a?c)ss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            publicPath: '../'
                        }
                    },
                    'css-loader',

                    // postcss-loader 설정
                    {
                        loader: 'postcss-loader',
                        options: {
                            ident: 'postcss',
                            plugins: [
                                require('lost'), // 그리드 시스템
                                require('autoprefixer'),
                                // require('autoprefixer')({
									//  browserslist를 package.json 또는 .browserslistrc file 로 사용을 권장함
									// 'browsers': ['&amp;gt; 1%', 'last 2 versions', 'not ie &amp;lt;=8']
									// 'browsers': ['cover 99.5%']
                                // }),
                            ]
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options: {
                            outputStyle: 'expanded',
                            indentType: 'tab',
                            indentWidth: 1
                        }
                    }
                ],
                exclude: /node_modules/
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'index.html',
            filename: 'index.html'
        }),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQ : 'jquery',
            moment : 'moment'
        }),
        new MiniCssExtractPlugin({
            filename: 'css/style.css'
        })
    ],
    optimization: {
        splitChunks: {
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    chunks: 'all',
                    name: 'js/vendor/libs',
                }
            }
        }
    },
    mode: 'development'
};&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;위와 같이 &lt;code&gt;module.rules&lt;/code&gt; 에 &lt;code&gt;postcss-loader&lt;/code&gt; 를 작성하고 옵션으로 사용할 플러그인들을 추가하여 사용할 수 있습니다.&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;그리고 앞서 다운로드 받은 sass 파일 중 &lt;kbd&gt;pages.scss&lt;/kbd&gt; 에 아래와 같은 코드를 확인하실 수 있습니다. &lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;다음 코드는 &lt;kbd&gt;PostCSS&lt;/kbd&gt; 공식 홈페이지에서 소개하는 그리드 시스템 문법(&lt;code&gt;lost-column&lt;/code&gt;)으로 소개 그대로 컴파일이 되는지 확인해 봅니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;.post-css {
	lost-column: 1/3;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;이전까지 &lt;code&gt;webpack&lt;/code&gt; 실행하면 위 코드 그대로 컴파일되었으나 이제 다시 &lt;code&gt;webpack&lt;/code&gt;을 실행하면 다음과 같이 컴파일될 것입니다.&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;[컴파일 css 결과확인]&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;.post-css {
	width: calc(99.9% * 1/3 - (30px - 30px * 1/3));
}

.post-css:nth-child(1n) {
	float: left;
	margin-right: 30px;
	clear: none;
}

.post-css:last-child {
	margin-right: 0;
}

.post-css:nth-child(3n) {
	margin-right: 0;
	float: right;
}

.post-css:nth-child(3n + 1) {
	clear: both;
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&lt;code&gt;lost-column: 1/3;&lt;/code&gt; 이 공식 홈페이지에서 소개한 대로 잘 컴파일되고 있지만 한가지 이상한 점이 있습니다.&lt;/p&gt;
	&lt;p&gt;
		&lt;code&gt;autoprefixer&lt;/code&gt;가 제대로 동작하지 않는 것으로 보여지고 있습니다. &lt;code&gt;autoprefixer&lt;/code&gt; 문서를 확인해 보면
		&lt;code&gt;autoprefixer&lt;/code&gt;는 &lt;code&gt;browserslist&lt;/code&gt;와 같이 사용된다고 안내하고 있습니다.
	&lt;/p&gt;
	&lt;p class=&quot;point-r mt30&quot;&gt;아래처럼 &lt;code&gt;browserslist&lt;/code&gt;를 설치 후 위에서 주석처리된 부분을 제거하고 다시 실행해 보면 &lt;code&gt;autoprefixer&lt;/code&gt;가 동작하는 것을 확인할 수 있습니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm i -D browserslist&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;자세한 &lt;code&gt;browserslist&lt;/code&gt; 의 옵션값은 다음의 링크인 &lt;a href=&quot;https://github.com/browserslist/browserslist&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;browserslist&lt;/a&gt; 에서 확인하시기 바랍니다.&lt;/p&gt;


	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;tit&quot;&gt;webpack-dev-server 설치하기&lt;/p&gt;
	&lt;p&gt;지금까지는 학습 목적으로 매번 소스를 수정할 때 마다 &lt;code&gt;webpack&lt;/code&gt;을 실행해 왔습니다.
		사실 명령창에서 &lt;code&gt;webpack -w&lt;/code&gt;를 실행하면 파일이 변경될 때마다 지속적 관찰을 하면서 컴파일이 진행됩니다.
		옵션 플래그인 &lt;code&gt;-w&lt;/code&gt;는 &lt;kbd&gt;watch&lt;/kbd&gt;의 약어로 지속적인 관찰을 의미합니다.
	&lt;/p&gt;
	&lt;p&gt;하지만 개발 단계에서는 일반적으로 로컬에서 개발용 서버를 통해서 프로젝트를 수행하기 때문에 &lt;code&gt;webpack -w&lt;/code&gt;를 실행하기 보다는
		&lt;code&gt;webpack-dev-server&lt;/code&gt;를 설치하여 사용하면 더 편리할 수 있습니다.
	&lt;/p&gt;
	&lt;p class=&quot;mt20&quot;&gt;
		웹팩 데브 서버는 웹 애플리케이션을 개발하는 과정에서 유용하게 쓰이는 도구로
		웹팩의 빌드 대상 파일이 변경 되었을 때 매번 웹팩 명령어를 실행하지 않아도 코드만 변경하고 저장하면 웹팩으로 빌드한 후 브라우저를 새로고침 해줍니다.
		즉, 이 기능을 사용하면 소스 파일을 감시(지속적 관찰)하고 내용이 변경될 마다 번들을 다시 컴파일하고 소스가 변경될 때마다 수시로 새로고침을 하지 않아도 새로고침되는 &lt;kbd&gt;live reloading&lt;/kbd&gt; 기능 또한 제공해 주고 있어서 편리합니다.
	&lt;/p&gt;
	&lt;p&gt;
		그렇기 때문에 매번 명령어를 치는 시간과 브라우저를 새로 고침하는 시간 뿐만 아니라 웹팩 빌드 시간 또한 줄여주기 때문에 웹팩 기반의 웹 애플리케이션 개발에 필수로 사용됩니다.
	&lt;/p&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;code&gt;webpack-dev-server&lt;/code&gt;를 설치하고 &lt;kbd&gt;webpack.config.js&lt;/kbd&gt;에 &lt;code&gt;devServer&lt;/code&gt;를 추가해 보도록 합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm i --save-dev webpack-dev-server&lt;/code&gt;&lt;/pre&gt;

	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    entry: {
        'js/index': ['./src/js/main.js'],
        'js/module': ['./src/js/module01.js', './src/js/module02.js'],
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
    },
    module: {
        rules: [
            {
                test: /\.s(a?c)ss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            publicPath: '../'
                        }
                    },
                    'css-loader',
                    {
                        loader: 'sass-loader',
                        options: {
                            outputStyle: 'expanded',
                            indentType: 'tab',
                            indentWidth: 1
                        }
                    }
                ],
                exclude: /node_modules/
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'index.html',
            filename: 'index.html'
        }),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQ : 'jquery',
            moment : 'moment'
        }),
        new MiniCssExtractPlugin({
            filename: 'css/style.css'
        })
    ],
    optimization: {
        splitChunks: {
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    chunks: 'all',
                    name: 'js/vendor/libs',
                }
            }
        }
    },
    devServer: {

        // 서버 포트 설정
        port: 9000,

		// contentBase 는 static 파일은 번들링되기 전이라든지 번들링된 이후의 결과물들을 총제적으로 한 번에 로딩할 수 있는 경로들을 의미합니다.
        // contentBase 는 웹팩 output.path 의 'publicPath' 와 동일해야 하며,
        // 정적 파일을 제공할 디렉토리 설정, 소스 파일을 감시하고 변경 될 때마다 번들을 다시 컴파일합니다
        // 다시 말해, 콘텐츠를 제공할 경로지정(정적파일을 제공하려는 경우에만 필요)
		// 기본값은 사용자가 작업하는 working directory 가 되고 특별히 개발계와 배포계로 나누려고 하는 경우
		// 즉, 개발 자원과 배포 자원을 분리한다고 했을 때 예를 들어 배포하는 자원의 디렉토리가 public 이라고 한다면
		// contentBase 의 위치를 public 으로 잡아 설정할 수 있습니다.
		// 여기서 주의할 점은 절대 경로를 사용해야 한다는 점입니다.
        // contentBase: path.resolve(__dirname, 'public'), // 'dist',

        // dev server 구동 후 브라우저 열기
        open: true,

        // 에러가 날 경우 브라우저에 표시
        // 이 옵션을 사용하지 않아도 개발자 도구 콘솔에서 알려주므로 반드시 사용하지 않아도 되지만
        // 에러가 났을 경우 확실히 알려주기 때문에 유용할 수 있다.
        // overlay: true,

        // hot: HotModuleReplacementPlugin 을 사용해 HMR 기능을 이용하는 옵션
        // 소스가 변경되면 자동으로 빌드되어 반영된다. 파일이 수정될 경우 그 부분에 대해 리로드를 해주는 옵션
        // hot: true,

        // host: 기본적으로 애플리케이션은 localhost 에서 서빙되지만 이 옵션을 이용해 다른 host 를 지정해줄 수 있다.
        // 또한 이 옵션에 ‘0.0.0.0’을 주면 개발중인 localhost 를 외부에서 접근할 수 있다.
        // host: '0.0.0.0'

		// compress : gzip 압축방식을 이용하여 웹 자원의 사이즈를 줄이는 방법
		// 웹 성능 최적화에 관한 기법으로 gzip(https://ko.wikipedia.org/wiki/Gzip) 은 파일들의 본래 크기를
		// 줄이는 것(minification, concatenation, compression)이 아니라 서버와 클라이언트 간의 압축 방식을 의미합니다.
		// compress : true
    },
    mode: 'development'
};&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;위에서 추가한 속성 &lt;code&gt;devServer&lt;/code&gt; 에서 포트를 &lt;kbd&gt;9000&lt;/kbd&gt; 그리고 &lt;code&gt;open: true&lt;/code&gt;로 설정되어 있습니다.&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;code&gt;webpack-dev-server&lt;/code&gt; 는 다음과 같이 실행할 수 있습니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;webpack-dev-server&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&lt;code&gt;webpack-dev-server&lt;/code&gt; 를 실행하면 브라우저창이 자동으로 열리면서 &lt;kbd&gt;localhost:9000&lt;/kbd&gt; 으로 &lt;kbd&gt;index.html&lt;/kbd&gt; 을 확인하실 수 있습니다.&lt;/p&gt;
	&lt;p&gt;브라우저가 자동으로 열리는 이유는 &lt;code&gt;devServer&lt;/code&gt; 의 옵션값으로 &amp;nbsp;&lt;code&gt; open: true&lt;/code&gt; 로 설정되어 있기 때문입니다.&lt;/p&gt;
	&lt;p class=&quot;point-r mt30&quot;&gt;만약, &lt;kbd&gt;open&lt;/kbd&gt;을 설정하지 않았다면 아래와 같이 실행해야 합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;webpack-dev-server --open&lt;/code&gt;&lt;/pre&gt;


	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;subtt&quot;&gt;웹팩 데브 서버의 특징&lt;/p&gt;
	&lt;p&gt;웹팩 데브 서버는 일반 웹팩 빌드와 다른점이 있습니다.&lt;/p&gt;
	&lt;p&gt;
		웹팩 데브 서버를 실행하여 웹팩 빌드를 하는 경우에는 빌드한 결과물이 파일 탐색기나 프로젝트 폴더에서 보이지 않습니다.
		좀 더 구체적으로 얘기하자면 웹팩 데브 서버로 빌드한 결과물은 메모리에 저장되고 파일로 생성하지는 않기 때문에 컴퓨터 내부적으로는 접근할 수 있지만 사람이 직접 눈으로 보고 파일을 조작할 순 없습니다.
	&lt;/p&gt;
	&lt;p class=&quot;mt20&quot;&gt;&lt;mark&gt;따라서, 웹팩 데브 서버는 개발할 때만 사용하다가 개발이 완료되면 웹팩 명령어를 이용해 결과물을 파일로 생성해야 합니다.&lt;/mark&gt;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;div class=&quot;warning tip&quot;&gt;
		&lt;p&gt;컴퓨터 구조 관점에서 파일 입출력보다 메모리 입출력이 더 빠르고 컴퓨터 자원이 덜 소모됩니다.&lt;/p&gt;
	&lt;/div&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;subtt&quot;&gt;HMR(Hot Module Replacement)&lt;/p&gt;
	&lt;p&gt;
		&lt;kbd&gt;HMR&lt;/kbd&gt;은 브라우저를 새로 고치지 않아도 웹팩으로 빌드한 결과물이 웹 애플리케이션에 실시간으로 반영될 수 있게 도와주는 설정입니다. &lt;br /&gt;
		브라우저 새로 고침을 위한 LiveReload 대신에 사용할 수 있으며 웹팩 데브 서버와 함께 사용할 수도 있습니다.
	&lt;/p&gt;
	&lt;p class=&quot;mt20&quot;&gt;
		리액트, 앵귤러, 뷰와 같이 대부분의 프레임워크에서 이미 &lt;kbd&gt;HMR&lt;/kbd&gt;을 사용할 수 있는 로더들을 지원하고 있지만 만약 개별적으로 설정하고 싶다면 &lt;br /&gt; 아래와 같은 방식으로 설정할 수 있습니다.
	&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;strong&gt;HMR 설정하기&lt;/strong&gt;&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;module.exports = {
  devServer: {
    hot: true
  }
}&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;
		데브 서버에 옵션으로 &lt;code&gt;hot:true&lt;/code&gt;를 추가하고 자바스크립트나 CSS 스타일시트를 변경하면 해당 모듈이 바로 업데이트가 됩니다.
		그리고 화면에서는 브라우저가 다시 로딩되지 않고도 변경된 내용을 확인할 수 있습니다.
	&lt;/p&gt;


	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;div class=&quot;link-refer&quot;&gt;
		&lt;h3&gt;Related Info&lt;/h3&gt;
		&lt;ol&gt;
			&lt;li&gt;&lt;a href=&quot;https://webpack.js.org/configuration/dev-server/&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;Webpack Dev Server 추가옵션&lt;/a&gt;&lt;/li&gt;
		&lt;/ol&gt;
	&lt;/div&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;subtt&quot;&gt;태스크 실행 스크립트 추가하기&lt;/p&gt;
	&lt;p&gt;&lt;kbd&gt;npm&lt;/kbd&gt;을 태스크 러너로 사용해 긴 명령어를 실행하는 것은 꽤나 번거로운 일일 수 있습니다.&lt;/p&gt;
	&lt;p&gt;위에서 실행한 &lt;code&gt;webpack-dev-server&lt;/code&gt;에 옵션 플래그인 &lt;code&gt;open&lt;/code&gt; 까지 명령어를 수행한다면 &lt;code&gt;webpack-dev-server --open&lt;/code&gt;을 매번 타이핑해줘야 합니다.
		하지만 반복적이고 자주 사용하는 명령어를 &lt;kbd&gt;package.json&lt;/kbd&gt;의 &lt;kbd&gt;scripts&lt;/kbd&gt;에 명령어를 등록해 놓는다면 좀더 수월하게 명령을 수행할 수 있습니다.
	&lt;/p&gt;
	&lt;p&gt;여기서는 위에서 수행했던 &lt;code&gt;webpack-dev-server&lt;/code&gt;를 &lt;code&gt;scripts&lt;/code&gt;에 등록해 보도록 하겠습니다.&lt;/p&gt;
	&lt;p&gt;그리고 기존 &lt;code&gt;devServer&lt;/code&gt; 에 작성한 &lt;code&gt;open: true&lt;/code&gt; 도 제거한 후 진행해 주시기 바랍니다. &lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;package.json&lt;/kbd&gt; 수정&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&quot;scripts&quot;: {
    &quot;start&quot;: &quot;webpack-dev-server --open&quot;,
},&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;package.json&lt;/kbd&gt; 을 수정하셨다면 아래와 같이 수행해 보시기 바랍니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm start&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;위 명령어를 수행하면 &lt;code&gt;webpack-dev-server&lt;/code&gt; 가 동작될 것입니다.
	&lt;/p&gt;
	&lt;p&gt;
		여기서는 start 를 타이핑했지만 &lt;kbd&gt;package.json&lt;/kbd&gt;에 등록한 명령어 이름인 &lt;kbd&gt;start&lt;/kbd&gt;를 &lt;kbd&gt;server&lt;/kbd&gt;로 변경한 후
		&lt;code&gt;npm server&lt;/code&gt;라고 실행하면 태스크가 수행되지 않습니다.
	&lt;/p&gt;
	&lt;p&gt;&lt;kbd&gt;start&lt;/kbd&gt;, &lt;kbd&gt;test&lt;/kbd&gt; 명령어 이름은 기본값으로 등록이 되어 있기 때문에 &lt;code&gt;npm start&lt;/code&gt;로 수행이 가능하지만
		&lt;code&gt;&quot;server&quot;: &quot;webpack-dev-server --open&quot;&lt;/code&gt; 라고 사용자 정의한다면 태스크 실행시에 &lt;code&gt;run&lt;/code&gt;을 함께 아래와 같이 작성해 주어야 합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&quot;scripts&quot;: {
	&quot;server&quot;: &quot;webpack-dev-server --open&quot;,
},&lt;/code&gt;&lt;/pre&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm run server&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;위와 같이 명령어를 사용자가 등록할 수 있기 때문에 지금까지 사용했던 &lt;kbd&gt;webpack.config.js&lt;/kbd&gt;를 수행했던 &lt;code&gt;webpack&lt;/code&gt; 명령어도 사용자 등록이 가능합니다.
		&amp;nbsp;예를 들어 webpack 구성파일을 개발 모드와 배포 모드로 구분해야 한다면 &lt;kbd&gt;webpack.dev.js&lt;/kbd&gt;, &lt;kbd&gt;webpack.prod.js&lt;/kbd&gt; 로 구성 파일을 나누어 사용할 수 있습니다.
	&lt;/p&gt;
	&lt;p class=&quot;point-r mt30&quot;&gt;개발계와 배포계를 나누었다고 가정할 경우 다음과 같이 &lt;code&gt;scripts&lt;/code&gt; 를 등록하여 사용할 수 있습니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&quot;scripts&quot;: {
	&quot;start&quot;: &quot;webpack-dev-server --open&quot;,
	&quot;dev&quot;: &quot;webpack --config webpack.dev.js&quot;,
	&quot;build&quot;: &quot;webpack --config webpack.prod.js&quot;
},&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;위와 같이 등록이 되어 있다면 개발시에는 &lt;code&gt;npm run dev&lt;/code&gt;를 배포시에는 &lt;code&gt;npm run build&lt;/code&gt;를 수행하실 수 있습니다.&lt;/p&gt;
	&lt;p&gt;다시 말해, &lt;kbd&gt;npm run {지정한 이름}&lt;/kbd&gt; 과 같은 간단한 명령으로 대체할 수 있습니다.&lt;/p&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;tit&quot;&gt;개발 편의성을 위한 Source map&lt;/p&gt;
	&lt;p&gt;
		개발을 진행하다보면 점차 js 파일이 많아지게 되고 webpack 은 여러 파일들을 하나 또는 특정 갯수의 번들된 파일로 묶다보니
		&lt;kbd&gt;error&lt;/kbd&gt;와 &lt;kbd&gt;warning&lt;/kbd&gt; 메시지를 통해 어느 파일의 어느 코드에서 문제가 발생했는지 정확히 추적하기가 어려워지게 됩니다. &lt;br /&gt;
		&lt;kbd&gt;소스 맵(Source Map)&lt;/kbd&gt;이란 배포용으로 빌드한 파일과 원본 파일을 서로 연결시켜주는 기능입니다. &lt;br /&gt;
		보통 서버에 배포를 할 때 성능 최적화를 위해 HTML, CSS, JS와 같은 웹 자원들을 압축합니다. 그런데 만약 압축하여 배포한 파일에서 에러가 난다면 어떻게 디버깅을 할 수 있을까요?
		이렇게 추적, 디버깅이 어려운 경우 Source map 을 이용해 배포용 파일의 특정 부분이 원본 소스의 어떤 부분인지 확인하는 것입니다. &lt;br /&gt;
		즉, 원본 파일을 통해 코드를 보여주고 error 및 warning 메세지와 함께 정확한 파일명과 코드 위치를 알려주기 때문에 유용할 수 있습니다.
	&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;웹팩에서 소스 맵을 설정하는 방법은 아래와 같습니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// webpack.config.js
module.exports = {
  devtool: 'cheap-eval-source-map'
}&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;&lt;code&gt;devtool&lt;/code&gt; 속성을 추가하고 소스 맵 설정 옵션 중 하나를 선택해 지정해주면 됩니다.&lt;/p&gt;


	&lt;p class=&quot;mt30&quot;&gt;현재 진행하고 있는 예제에서는 webpack 공식 문서에서 권장하고 있는 &lt;code&gt;cheap-eval-source-map&lt;/code&gt;을 추가하여 사용해 봅니다.&lt;/p&gt;
	&lt;p class=&quot;point-r&quot;&gt;&lt;kbd&gt;webpack.config.js&lt;/kbd&gt;에서 &lt;code&gt;devtool&lt;/code&gt; 속성을 추가하도록 합니다.&lt;/p&gt;
	&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    entry: {
        'js/index': ['./src/js/main.js'],
        'js/module': ['./src/js/module01.js', './src/js/module02.js'],
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].js',
    },
    module: {
        rules: [
            {
                // 대상 파일 지정
                test: /\.s(a?c)ss$/,
                use: [
                    {
                        loader: MiniCssExtractPlugin.loader,
                        options: {
                            publicPath: '../'
                        }
                    },
                    'css-loader',
                    {
                        loader: 'sass-loader',
                        options: {
                            outputStyle: 'expanded',
                            indentType: 'tab',
                            indentWidth: 1
                        }
                    }
                ],
                exclude: /node_modules/
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: 'index.html',
            filename: 'index.html'
        }),
        new webpack.ProvidePlugin({
            $: 'jquery',
            jQ : 'jquery',
            moment : 'moment'
        }),
        new MiniCssExtractPlugin({
            filename: 'css/style.css'
        })
    ],
    optimization: {
        splitChunks: {
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    chunks: 'all',
                    name: 'js/vendor/libs',
                }
            }
        }
    },
    devServer: {
        port: 9000,
        open: true,
    },

    // source map 설정
    devtool: 'cheap-eval-source-map',
    mode: 'development'
};
&lt;/code&gt;&lt;/pre&gt;
	&lt;p&gt;소스맵을 추가하셨다면 &lt;code&gt;webpack-dev-server&lt;/code&gt;를 실행해 보세요. &lt;br /&gt;
		그리고 js 파일 중에 고의로 문법을 틀리게 작성하면 개발자 도구의 &lt;kbd&gt;console&lt;/kbd&gt; 패널에서 에러가 발생한 파일명과 라인을 표시해 줄 것입니다.
	&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;소스맵 옵션에는 다양한 값들이 존재하는데 개발과 운영 모드에서 사용할 수 있는 옵션이 서로 다릅니다.&lt;/p&gt;
	&lt;p&gt;webpack 공식 문서에서는 개발 모드에서는 &lt;code&gt;eval-source-map&lt;/code&gt; 또는 &lt;code&gt;cheap-eval-source-map&lt;/code&gt;를,
		운영 모드에서는 &lt;code&gt;none(사용하지 않음)&lt;/code&gt; 이거나 &lt;code&gt;hidden-source-map&lt;/code&gt; 정도를 권장하고 있습니다. &lt;/p&gt;
	&lt;p&gt;이 소스맵 옵션에 사용자 개발 환경이나 기호에 맞게 선택적으로 사용할 수 있습니다.&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;div class=&quot;warning tip&quot;&gt;
		&lt;p class=&quot;subtt&quot;&gt;devtool options&lt;/p&gt;
		&lt;ul&gt;
			&lt;li&gt;
				&lt;code&gt;source-map&lt;/code&gt;
				&lt;p&gt;모든 기능이 포함된 완전한 소스맵을 별도의 파일로 생성 &lt;br /&gt;
					이 옵션은 최고 품질의 소스맵을 생성하지만 빌드 프로세스가 느려지는 단점이 있음
				&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;code&gt;cheap-module-source-map&lt;/code&gt;
				&lt;p&gt;별도의 파일에 컬럼 매핑을 제외한 소스 맵을 생성 &lt;br /&gt;
					컬럼 매핑을 생략하면 빌드 속도는 향상되지만 디버깅시 조금 불편할 수 있음&lt;br /&gt;
					브라우저 개발자 툴은 원래 소스 파일의 행만 가리킬 수 있으며, 특정 컬럼(또는 문자)을 가리킬 수 없다
				&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;code&gt;eval-source-map&lt;/code&gt;
				&lt;p&gt;
					&lt;kbd&gt;eval&lt;/kbd&gt;을 사용해 동일한 파일 안에 전체 소스맵과 소스코드 모듈을 중첩해 번들로 생성 &lt;br /&gt;
					이 옵션을 사용하면 빌드 시간에 대한 부담 없이 모든 기능이 포함된 소스맵을 생성할 수 있지만 &lt;br /&gt;
					자바스크립트를 실행할 때 성능과 보안이 저하되는 단점이 있다 &lt;br /&gt;
					즉, 개발 중에는 유용하지만 배포시에 빌드할 때는 사용하지 말아야 한다
				&lt;/p&gt;
			&lt;/li&gt;
			&lt;li&gt;
				&lt;code&gt;cheap-module-eval-source-map&lt;/code&gt;
				&lt;p&gt;
					빌드 중에 소스 맵을 생성하는 가장 빠른 방법 &lt;br /&gt;
					생성되는 소스맵에는 번들 자바스크립트 파일이 칼럼 매핑을 제외하고 동일하게 인라인으로 포함된다 &lt;br /&gt;
					이 옵션도 자바스크립트 성능을 저하시키기 때문에 production 에서는 적합하지 않다
				&lt;/p&gt;
			&lt;/li&gt;
		&lt;/ul&gt;
	&lt;/div&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;div class=&quot;link-refer&quot;&gt;
		&lt;h3&gt;Related Info&lt;/h3&gt;
		&lt;ol&gt;
			&lt;li&gt;&lt;a href=&quot;https://webpack.js.org/configuration/devtool/&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;Devtool 소스맵 옵션&lt;/a&gt;&lt;/li&gt;
		&lt;/ol&gt;
	&lt;/div&gt;


	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;



	&lt;p class=&quot;tit&quot;&gt;Conclusion&lt;/p&gt;
	&lt;p&gt;지금까지 실무에서 사용해볼 만한 몇 가지 웹팩 환경설정(라이브러리 로드, sass 컴파일, webpack-dev-server, source map)등에 대해 알아보았습니다.
		&amp;nbsp;아마도 입문자의 경우에 녹록치 않았을 것으로 생각되지만 웹팩을 사용하기 위한 최소한의 도움과
		변화하는 개발환경 트렌드에 적응하는데 필요한 시간이 되었으면 합니다.
	&lt;/p&gt;

	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;

	&lt;div class=&quot;loof-wrap&quot;&gt;
		&lt;div class=&quot;loof&quot;&gt;
			&lt;svg class=&quot;rl-logo&quot; width=&quot;606&quot; height=&quot;300&quot; viewBox=&quot;0 0 606 300&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; preserveAspectRatio=&quot;none&quot;&gt;
				&lt;defs&gt;
					&lt;clipPath id=&quot;clipLogo&quot;&gt;
						&lt;path d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;
						&lt;/path&gt;&lt;/clipPath&gt;
				&lt;/defs&gt;
				&lt;path class=&quot;rl-logo__path&quot; d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;&lt;/path&gt;
				&lt;path class=&quot;rl-logo__track&quot; clip-path=&quot;url(#clipLogo)&quot; d=&quot;M 323.9 178.9 C 344.8 202.5 383.7 245.8 412.2 261.3 C 447.3 282.3 494.3 278 527.7 255.5 C 586.6 217 597.8 127.5 557.2 72.1 C 530.3 33.4 479 17 434.2 28.2 C 389.3 41.5 358.1 79 330.7 114.3 C 318.9 128.6 277.3 185.4 277.3 185.4 C 249.9 220.7 218.7 258.1 173.8 271.5 C 129 282.7 77.7 266.3 50.8 227.6 C 10.2 172.2 21.4 82.7 80.3 44.2 C 113.7 21.6 160.7 17.4 195.8 38.4 C 224.3 53.9 261.2 96.2 282.1 119.7&quot;&gt;&lt;/path&gt;
			&lt;/svg&gt;
		&lt;/div&gt;
		&lt;div class=&quot;name&quot;&gt;
			Jaehee's&lt;span class=&quot;b&quot;&gt; WebClub&lt;/span&gt;
		&lt;/div&gt;
	&lt;/div&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;
	&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Web Tech/Webpack</category>
      <author>jaiyah</author>
      <guid isPermaLink="true">https://webclub.tistory.com/637</guid>
      <comments>https://webclub.tistory.com/637#entry637comment</comments>
      <pubDate>Tue, 19 Nov 2019 10:50:49 +0900</pubDate>
    </item>
    <item>
      <title>Webpack Guide for beginner #2</title>
      <link>https://webclub.tistory.com/636</link>
      <description>&lt;h1 class=&quot;hh&quot;&gt;Webpack 환경 설정 맛보기&lt;/h1&gt;
    &lt;p&gt;
        앞서 &lt;code&gt;Webpack&lt;/code&gt;의 전반적 이해와 Webpack 사용에 필요한 선수 지식에 대해 알아보았으며,
        이번 장부터는 &lt;code&gt;Webpack&lt;/code&gt;에 대한 기본 환경 구성부터 진행해 보도록 하겠습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    
    &lt;p class=&quot;tac&quot; style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 750px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99EF95505D4761271A&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99EF95505D4761271A&quot; width=&quot;750&quot; height=&quot;411&quot; filename=&quot;webpack_intro2.png&quot; filemime=&quot;image/jpeg&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
    &lt;p class=&quot;tac&quot;&gt;&lt;kbd&gt;사용자 코드작성과 번들 js&lt;/kbd&gt;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
   &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;프로젝트 초기 설정&lt;/p&gt;
    &lt;p&gt;이제부터 새로운 프로젝트를 초기화하고, Webpack 을 설치해 보도록 하겠습니다.&lt;/p&gt;
    &lt;p&gt;아직까지 &lt;a href=&quot;https://nodejs.org/ko/&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;node.js 설치&lt;/a&gt;를 하지 않았다면 설치 후에 진행 바랍니다.&lt;/p&gt;
    &lt;p class=&quot;subtt mt30&quot;&gt;Webpack 기본(일반적) 구성 절차&lt;/p&gt;
    &lt;ol style=&quot;margin-left: 12px;&quot;&gt;
        &lt;li&gt;&lt;code&gt;webpack&lt;/code&gt; 과 &lt;code&gt;webpack-cli&lt;/code&gt; 전역 설치&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;npm init&lt;/code&gt; 으로 &lt;kbd&gt;package.json&lt;/kbd&gt; 생성&lt;/li&gt;
        &lt;li&gt;&lt;kbd&gt;src/index.js&lt;/kbd&gt; 와 &lt;kbd&gt;index.html&lt;/kbd&gt; 생성&lt;/li&gt;
        &lt;li&gt;사용자 js 와 html 추가&lt;/li&gt;
        &lt;li&gt;&lt;kbd&gt;webapck.config.js&lt;/kbd&gt; 파일 생성&lt;/li&gt;
    &lt;/ol&gt;
    &lt;p class=&quot;mt30&quot;&gt;&lt;code&gt;webpack&lt;/code&gt;, &lt;code&gt;webpack-cli&lt;/code&gt; 를 &lt;kbd&gt;-global&lt;/kbd&gt; 로 설치한 후 &lt;kbd&gt;package.json&lt;/kbd&gt; 을 생성해도 되고 &lt;kbd&gt;package.json&lt;/kbd&gt; 을 생성한 후 webpack 을 설치해도 무방합니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;우선 로컬 디렉토리 내의 본인의 새로운 프로젝트 폴더를 생성하고, 몇 가지 파일을 생성해 보도록 합니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ mkdir webpack-task
$ cd webpack-task
$ npm init -y&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;CLI 명령어를 이용하여 디렉토리를 구성해도 되고 편한대로 새로운 프로젝트 네이밍으로 폴더를 구성한 후 &lt;code&gt;npm init -y&lt;/code&gt; 를 진행해도 됩니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;다음과 같이 아래 명령어를 수행합니다. &lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm i webpack webpack-cli -global
$ npm i webpack webpack-cli --save-dev &lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&lt;code&gt;webpack&lt;/code&gt;은 웹팩의 핵심 패키지로 Webpack &lt;code&gt;v3&lt;/code&gt;까지는 &lt;code&gt;webpack&lt;/code&gt;만 설치하였으나 Webpack &lt;code&gt;v4&lt;/code&gt;부터는 &lt;code&gt;webpack-cli&lt;/code&gt; 도 같이 설치해야 합니다.
        &lt;code&gt;webpack-cli&lt;/code&gt;는 터미널에서 &lt;code&gt;webpack&lt;/code&gt; 커맨드를 실행할 수 있게 해주는 커맨드라인 도구이며, 두 개의 패키지 모두 개발할 때만 필요한 의존성이므로
        &lt;code&gt;--save-dev&lt;/code&gt; 로 설치하도록 합니다.&lt;/p&gt;
    &lt;p&gt;
        그리고 &lt;code&gt;webpack&lt;/code&gt; 설치는 &lt;kbd&gt;webpack.config.js&lt;/kbd&gt; 파일에서 webpack 모듈을 불러다 사용하기 위함도 있습니다.

    &lt;/p&gt;
    &lt;p&gt;로컬 설치를 진행하면 &lt;kbd&gt;node_modules&lt;/kbd&gt; 폴더가 생성되면서 하위 폴더에 다수의 다수 모듈들이 설치되어 있을 것입니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;바로 위에서 수행했던 명령어는 아래와 같이 수행할 수도 있습니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm i -g webpack webpack-cli &amp;amp;&amp;amp; npm i -D webpack webpack-cli
$ npm i webpack webpack-cli -g &amp;amp;&amp;amp; npm i webpack webpack-cli -D&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;옵션 플래그인 &amp;nbsp;&lt;code&gt; -global(-g)&lt;/code&gt;, &lt;code&gt;--save-dev(-D)&lt;/code&gt; 는 install 바로 뒤에 타이핑해도 되고 마지막 패키지명 뒤에 입력하실 수 있습니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;설치된 패키지를 확인하기 위해 &lt;kbd&gt;package.json&lt;/kbd&gt;을 살펴보면 다음과 같습니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;name&quot;: &quot;webpack-task&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;description&quot;: &quot;&quot;,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;scripts&quot;: {
    &quot;test&quot;: &quot;echo \&quot;Error: no test specified\&quot; &amp;amp;&amp;amp; exit 1&quot;
  },
  &quot;keywords&quot;: [],
  &quot;author&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;,
  &quot;devDependencies&quot;: {
    &quot;webpack&quot;: &quot;^4.35.3&quot;,
    &quot;webpack-cli&quot;: &quot;^3.3.5&quot;
  }
}&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;
        &lt;code&gt;webpack&lt;/code&gt;, &lt;code&gt;webpack-cli&lt;/code&gt;는 실제 서비스에 배포되는 것이 아니라 개발에 필요한 도구일 뿐이기 때문에
        &lt;code&gt;--save-dev&lt;/code&gt;로 설치하면 &lt;kbd&gt;devDependencies&lt;/kbd&gt;에 그 내용이 추가된 것을 확인하실 수 있습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;다음으로 간단한 &lt;kbd&gt;index.html&lt;/kbd&gt;, &lt;kbd&gt;index.js&lt;/kbd&gt; 그리고 &lt;kbd&gt;webpack.config.js&lt;/kbd&gt; 파일을 생성하고 다음과 같이 작성합니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;html&quot;&gt;index.html&lt;/div&gt;&lt;/div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;ko&quot;&amp;gt;
&amp;lt;head&amp;gt;
	&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
	&amp;lt;title&amp;gt;Webpack Task&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
	&amp;lt;header&amp;gt;
		&amp;lt;h1&amp;gt;Webpack 학습하기&amp;lt;/h1&amp;gt;
	&amp;lt;/header&amp;gt;
	&amp;lt;div&amp;gt;
		&amp;lt;p&amp;gt;
			사실 웹팩 설정은 복잡하기로 악명 높지만 다양한 업무를 처리해 줄 수 있는 장점과
            계속해서 빠르고 쉽게(?) 개선되고 있습니다.
		&amp;lt;/p&amp;gt;
	&amp;lt;/div&amp;gt;
	&amp;lt;script src=&quot;dist/bundle.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// index.js
console.log('Webpack 번들링 실행');&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// webpack.config.js
// webpack 명령은 기본적으로 이 설정으로 시작
const path = require('path');

module.exports = {
    entry: './src/js/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist')
    },
    mode : 'development'
};&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;지금까지 폴더구성은 다음과 같습니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;webpack=task
|---index.html
|---package-lock.json
|---package.json
|---webpack.config.js
|
\---node_modules
|     \-- 생략
|
\---src
     \--js
         \--index.js
&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;&lt;code&gt;webpack.config.js&lt;/code&gt; 구성파일을 알아보기 전에 아래 명령어를 먼저 실행해 보겠습니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ webpack&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;위 명령어를 실행하면 &lt;kbd&gt;dist/bundle.js&lt;/kbd&gt; 가 생성되는 것을 확인하실 수 있습니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p class=&quot;point-r&quot;&gt;그리고 번들링된 &lt;code&gt;bundle.js&lt;/code&gt; 확인해 보면 다음과 같이 webpack 관련 코드와 하단에 &lt;code&gt;index.js&lt;/code&gt;에서 작성했던 콘솔 코드를 확인할 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;/***/ &quot;./src/js/index.js&quot;:
/*!*************************!*\
  !*** ./src/js/index.js ***!
  \*************************/
/*! no static exports found */
/***/ (function(module, exports) {

eval(&quot;console.log('Webpack 번들링 실행');\n\n//# sourceURL=webpack:///./src/js/index.js?&quot;);

/***/ })&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;실제 작업파일은 &lt;kbd&gt;index.js&lt;/kbd&gt;이지만 서비스(배포)시에는 번들링된 자원을 사용할 것이기 때문에 &lt;kbd&gt;index.html&lt;/kbd&gt;에 &lt;kbd&gt;bundle.js&lt;/kbd&gt;를 불러와 사용해야 합니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;이번에는 여전히 많이 사용하고 있는 &lt;code&gt;jQuery&lt;/code&gt;라는 라이브러리를 불러다가 사용해 보는 예제를 진행해 보겠습니다. &lt;/p&gt;
    &lt;p&gt;앞서 진행한 것처럼 맛보기(?)이지만 이해를 하는데 도움이 되실 수 있습니다.&lt;/p&gt;
    &lt;p class=&quot;point-r mt30&quot;&gt;아래와 같이 &lt;code&gt;jQuery&lt;/code&gt; 를 설치하고 &lt;code&gt;index.js&lt;/code&gt;를 수정해 보도록 합니다.&lt;/p&gt;

&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm i jquery --save&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// index.js
console.log('Webpack 번들링 실행');

// require 는 NodeJS 에서 사용되고 있는 CommonJS 키워드이고,
// import 는 ES6(ES2015)에서 새롭게 도입된 키워드로
// 두 개의 키워드 모두 하나의 파일에서 다른 파일의 코드를 불러온다는 동일한 목적을 가지고 있음
import $ from 'jQuery';

(function () {

    $(document).ready(function() {
        $('p').text('jQuery 를 불러와 사용하고 있습니다.')
    });

})();
&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&lt;code&gt;import $ from 'jQuery';&lt;/code&gt;는 node_modules 에 있는 &lt;kbd&gt;jQuery&lt;/kbd&gt;를 불러와 &lt;kbd&gt;$&lt;/kbd&gt;로 치환한다는 의미입니다.&lt;/p&gt;
    &lt;p&gt;다시 CLI 에서 webpack 명령어를 수행하면 &lt;kbd&gt;index.html&lt;/kbd&gt;을 확인해 보면 문단 텍스트가 바뀌어 있는 것을 확인하실 수 있을 것입니다.&lt;/p&gt;
    &lt;p&gt;그리고 &lt;kbd&gt;bundle.js&lt;/kbd&gt;에는 &lt;kbd&gt;jquery&lt;/kbd&gt;와 사용자 스크립트가 함께 합쳐져 있을 것입니다.&lt;/p&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning info&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt;ES6 Import/Export&lt;/p&gt;
        &lt;p&gt;&lt;kbd&gt;ES6&lt;/kbd&gt;는 다른 프로그래밍 언어처럼 하나의 자바스크립트 모듈에서 다른 자바스크립트 모듈을 불러다 사용할 수 있도록 &lt;code&gt;import&lt;/code&gt;나 &lt;code&gt;export&lt;/code&gt;와 키워드를 제공합니다.&lt;/p&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;warning tip&quot;&gt;
        &lt;p class=&quot;subtt&quot;&gt;npm install 시 특정버전 설치하기&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm i jquery@2.1.4 --save
# 특정버전을 설치하고자 하는 경우

$ npm i jquery@1 --save
# 1 버전대 중에 최신 버전을 설치하는 경우
&lt;/code&gt;&lt;/pre&gt;

    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;hh&quot;&gt;webpack.config.js (웹팩 구성 파일)&lt;/p&gt;
    &lt;p&gt;이제부터 &lt;code&gt;webpack&lt;/code&gt; 의 핵심 개념을 이해하기 위해서 구성 파일의 주요 속성인 &lt;kbd&gt;Entry&lt;/kbd&gt;, &lt;kbd&gt;Output&lt;/kbd&gt;, &lt;kbd&gt;Loader&lt;/kbd&gt;, &lt;kbd&gt;Plugins&lt;/kbd&gt;,
        &lt;kbd&gt;mode&lt;/kbd&gt; 에 대해 알아보면서,
        필요한 예제도 함께 진행해 보도록 하겠습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;entry 설정&lt;/p&gt;
    &lt;p&gt;번들을 설정하기 위한 진입점을 의미합니다.&lt;/p&gt;
    &lt;p&gt;다시말해, &lt;code&gt;entry&lt;/code&gt; 속성은 웹팩에서 웹 자원을 변환하기 위해 필요한 최초 진입점이자 자바스크립트 파일 경로입니다.&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;code&gt;String&lt;/code&gt; : 문자열이 들어오는 경우 시작시 로드되는 모듈로 해석&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;Array&lt;/code&gt; : 시작시 모든 모듈이 로드됩니다. 마지막 하나가 내보내집니다.&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;Object&lt;/code&gt; : 다중 항목 번들이 작성됩니다.
            &lt;p&gt;&lt;kbd&gt;key&lt;/kbd&gt;는 청크되는 파일의 이름이고, 값은 문자열 또는 배열이 가능합니다.&lt;/p&gt;
        &lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;여러가지 entry 유형 살펴보기&lt;/p&gt;
    &lt;p class=&quot;point-r mt20&quot;&gt;다음 코드는 &lt;kbd&gt;문자열(String)&lt;/kbd&gt;을 작성하는 경우입니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// webpack.config.js
module.exports = {
    entry: './src/myfolder/file.js'
};&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;위 코드는 웹팩을 실행했을 때 &lt;kbd&gt;src/myfolder&lt;/kbd&gt; 폴더 밑의 &lt;code&gt;file.js&lt;/code&gt;을 대상으로 웹팩이 빌드를 수행하는 코드입니다&lt;/p&gt;
&lt;p class=&quot;point-r mt30&quot;&gt;다음 코드는 아래와 같이 작성할 수도 있습니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// webpack.config.js
module.exports = {
    entry: {
        main: './src/myfolder/file.js'
    }
};
&lt;/code&gt;&lt;/pre&gt;

    &lt;p class=&quot;point-r mt30&quot;&gt;다음 코드는 &lt;kbd&gt;배열(Array)&lt;/kbd&gt;이 사용되는 경우입니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;module.exports = {
    entry: {
        main: ['./src/myfolder/file_01.js', './src/myfolder/file_02.js']
    }
};
&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;배열을 전달하면 &lt;kbd&gt;multi-main entry&lt;/kbd&gt;가 생성됩니다. &lt;br /&gt;
    여러개의 의존성 파일을 하나의 &lt;kbd&gt;chunk&lt;/kbd&gt;로 모으고 이들의 의존성 그래프를 생성하고 싶을때 유용하게 사용할 수 있지만
        이것은 (라이브러리 같은) 하나의 엔트리 포인트를 갖는 어플리케이션 혹은 툴을 빠르게 설정할때 좋은 선택이지만, 확장성이 떨어집니다.

        &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;Entry 파일에는 어떤 내용이 들어가야 하나?&lt;/p&gt;
    &lt;p&gt;
        &lt;code&gt;entry&lt;/code&gt; 속성에 지정된 파일에는 웹 애플리케이션의 전반적인 구조와 내용이 담겨져 있어야 합니다.
        웹팩이 해당 파일을 가지고 웹 애플리케이션에서 사용되는 모듈들의 연관 관계를 이해하고 분석하기 때문에 애플리케이션을 동작시킬 수 있는 내용들이 담겨져 있어야 합니다.
    &lt;/p&gt;
    &lt;p class=&quot;mt30&quot;&gt;예를 들어, 블로그 서비스를 웹팩으로 빌드한다고 했을 때 코드의 모양은 아래와 같을 수 있습니다.&lt;/p&gt;
&lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;javascript&quot;&gt;js&lt;/div&gt;&lt;/div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// index.js
import LoginView from './loginView.js';
import UI from './ui.js';
import Posting from './posting.js';

function initApp() {
  loginView.init();
  UI.init();
  Posting.init();
}

initApp();&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;
        위 코드는 해당 서비스가 &lt;kbd&gt;싱글 페이지 애플리케이션(SPA)&lt;/kbd&gt;이라고 가정하고 작성한 코드입니다.
        사용자의 로그인 화면, 로그인 후 진입하는 메인 화면, 그리고 게시글을 작성하는 화면 등 웹 서비스에 필요한 화면들이 모두 &lt;kbd&gt;index.js&lt;/kbd&gt; 파일에서 불려져 사용되고 있기 때문에 웹팩을 실행하면 해당 파일들의 내용까지 해석하여 파일을 빌드해줄 것입니다.
    &lt;/p&gt;
    &lt;p class=&quot;tac&quot; style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 800px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99BFD54F5DD3482034&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99BFD54F5DD3482034&quot; width=&quot;800&quot; height=&quot;571&quot; filename=&quot;webpack-entry.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
    &lt;p&gt;위와 같이 모듈 간의 의존 관계가 생기는 구조를 &lt;a href=&quot;https://webpack.js.org/concepts/dependency-graph/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;디펜던시 그래프(Dependency Graph)&lt;/a&gt;라고 합니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;앞에서 살펴본 것처럼 엔트리 포인트는 1개가 될 수도 있지만 아래와 같이 여러 개가 될 수도 있습니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;entry: {
  login: './src/loginView.js',
  main: './src/mainView.js'
}
&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;위와 같이 엔트리 포인트를 분리하는 경우는 싱글 페이지 애플리케이션이 아닌 특정 페이지로 진입했을 때 서버에서 해당 정보를 내려주는 형태의 멀티 페이지 애플리케이션에 적합합니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;quote&quot;&gt;
        &lt;p&gt;웹팩 구성 파일인 &lt;kbd&gt;webpack.config.js&lt;/kbd&gt; 해당 네이밍으로 정의해야 웹팩이 인식합니다.&lt;/p&gt;
        &lt;p&gt;
            네이밍을 다르게 설정하고 싶을 경우 예를 들어 빌드용으로 사용하는 경우 &lt;kbd&gt;webpack.config.prod.js&lt;/kbd&gt;라고 네이밍을 정의한다면 명령 프롬프트에서 실행할 때
            &lt;code&gt;webpack --config webpack.config.prod.js&lt;/code&gt;으로 실행해야 합니다. 이는 이후에 다시 다루도록 하겠습니다.&lt;/p&gt;
    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;output 설정&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;여기서 &lt;code&gt;entry&lt;/code&gt;와 연계하여 &lt;code&gt;output&lt;/code&gt;을 살펴보도록 하겠습니다.&lt;/p&gt;
    &lt;p&gt;&lt;code&gt;output&lt;/code&gt;은 결과물을 내는 설정으로 생성한 번들을 저장할 위치를 지정할 수 있습니다.&lt;/p&gt;
    &lt;p&gt;즉, &lt;code&gt;output&lt;/code&gt;은 웹팩이 어디에 번들을 만들어 낼것인지, 어떤 이름으로 파일들을 어떻게 만들 것인지에 대한 것을 정의할 수 있습니다.&lt;/p&gt;
    &lt;p&gt;&lt;kbd&gt;config&lt;/kbd&gt; 파일에 &lt;code&gt;output&lt;/code&gt;이 설정되어 있지 않다면 기본 값은 &lt;kbd&gt;./dist/main.js&lt;/kbd&gt;입니다. 생성된 번들 파일들이 &lt;kbd&gt;./dist&lt;/kbd&gt; 디렉토리 밑으로 들어가게 됩니다.&lt;/p&gt;
    &lt;p class=&quot;point-r mt30&quot;&gt;다음의 코드는 &lt;code&gt;기본 엔트리 포인트&lt;/code&gt;와 &lt;code&gt;output&lt;/code&gt;을 설정한 것 입니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;module.exports = {
    // 웹팩 v4부터는 mode 필수
    // mode 는 production, development, none 3가지 옵션이 존재
    // mode 의 production 은 각 설정마다 내장된 최적화 옵션을 자동으로 설정하여 준다
    mode : 'development',

    entry : './src/js/index.js',
    output: {
        // filename 으로 생성된 번들링을 어느 경로에 생성할 지를 설정
        // __dirname 은 node 에서 제공하는 node 파일의 경로를 담고 있는 변수
        // __이 붙어 있는 변수들은 항상 무엇인가를 담고있는 특별한 변수들임
        // path 에는 절대 경로 설정(절대값으로 static(정적)으로 사용)
        path: __dirname,
        // bundling 된 결과 파일의 이름
        filename: 'dist/biuld.js'
    }
};&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;최소한 &lt;kbd&gt;filename&lt;/kbd&gt;은 지정해줘야 하며 일반적으로 위와 같이 &lt;kbd&gt;path&lt;/kbd&gt; 속성을 함께 정의합니다.&lt;/p&gt;
    &lt;p&gt;
        여기서 &lt;kbd&gt;filename&lt;/kbd&gt; 속성은 웹팩으로 빌드한 파일의 이름을 의미하고, &lt;kbd&gt;path&lt;/kbd&gt; 속성은 해당 파일의 경로를 의미합니다.
        그리고 &lt;kbd&gt;path&lt;/kbd&gt; 속성에서 사용된 &lt;code&gt;path.resolve()&lt;/code&gt; 코드는 인자로 넘어온 경로들을 조합하여 유효한 파일 경로를 만들어주는 &lt;kbd&gt;Node.js API&lt;/kbd&gt;입니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning tip&quot;&gt;
        &lt;p&gt;위 코드에서 사용한 path 라이브러리의 자세한 사용법은 &lt;a href=&quot;https://nodejs.org/api/path.html&quot; class=&quot;tx-link&quot; target=&quot;_blank&quot;&gt;여기를 참고&lt;/a&gt;하세요.&lt;/p&gt;
    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;앞서 위에서 엔트리 포인트를 배열로 구성했듯이 객체로도 구성할 수 있습니다.&lt;/p&gt;
    &lt;p&gt;먼저, &lt;kbd&gt;module1.js&lt;/kbd&gt;, &lt;kbd&gt;module2.js&lt;/kbd&gt; 파일 생성 후 아래와 같다고 가정해 봅니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// module1.js
console.log('module1 실행');&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// module2.js
console.log('module2 실행');&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;Multi Entry &amp;amp; output&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;다음의 코드는 &lt;code&gt;다중 엔트리 포인트&lt;/code&gt;와 그에 따른 &lt;code&gt;output&lt;/code&gt; 설정입니다.&lt;/p&gt;

&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;module.exports = {
    module.exports = {
    mode : 'development', // 웹팩4부터는 mode(development||production)는 필수
    entry: {
        jaehee : './src/js/index.js',
        'module.chunk' : ['./src/js/module1.js', './src/js/module2.js'] // 배열 사용(오른쪽부터 왼쪽으로 읽어감)
    },
    output: {
        path : __dirname,
        filename : 'dist/[name].js' // 위에 지정한 entry 키의 이름에 맵핑되어 파일이 생성됨
    }
};&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&lt;code&gt;webpack&lt;/code&gt; 을 실행하면 &lt;kbd&gt;dist&lt;/kbd&gt; 폴더 내에 &lt;kbd&gt;jaehee.js&lt;/kbd&gt;, &lt;kbd&gt;module.chunk.js&lt;/kbd&gt; 이 생성되어 있는 것을 확인하실 수 있습니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;Output Name Options&lt;/p&gt;
    &lt;p&gt;앞에서 살펴본 filename 속성에 여러 가지 옵션을 넣을 수 있습니다.&lt;/p&gt;
    &lt;p class=&quot;point-r mt30&quot;&gt;결과 파일 이름에 entry 속성을 포함하는 옵션&lt;/p&gt;
    &lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;output : {
    // 정적인 절대값으로 이름을 구성
    filename : '[name].js'
}&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;


    &lt;p class=&quot;point-r&quot;&gt;결과 파일 이름에 웹팩 내부적으로 사용하는 모듈 ID를 포함하는 옵션&lt;/p&gt;
    &lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;output : {
    filename : '[id].bundle.js'
}&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;


    &lt;p class=&quot;point-r&quot;&gt;매 빌드시 마다 고유 해시 값을 붙이는 옵션&lt;/p&gt;
    &lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;output : {
    // webpack 을 build 할 때마다 hash 값이 변하면서 output 파일이 계속 변경 생성
    filename : '[name].[hash].bundle.js'
}&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p class=&quot;point-r&quot;&gt;웹팩의 각 모듈 내용을 기준으로 생생된 해시 값을 붙이는 옵션&lt;/p&gt;
    &lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;output : {
    // chunk(덩어리)에 따라서  hash 값이 변하면서 output 파일이 계속 변경 생성
    filename : '[chunkhash].bundle.js'
}&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;Loader 설정&lt;/p&gt;
    &lt;p&gt;
        &lt;mark&gt;webpack 은 모든 파일을 모듈로 관리할 수 있다고 언급했습니다.&lt;/mark&gt; &lt;br /&gt;
        하지만 webpack 은 자바스크립트 파일만 읽어 올 수 있기 때문에, css(스타일시트)나 이미지 등을 webpack 이 읽을 수 있는 자바스크립트로 변경되어야 하는데,
        &lt;code&gt;Loader&lt;/code&gt;가 &lt;kbd&gt;webpack&lt;/kbd&gt;이 이해 할 수 있는 모듈로 변경해 주는 역할을 하게 됩니다.
    &lt;/p&gt;
    &lt;p&gt;
       즉, 로더(Loader)는 웹팩이 웹 애플리케이션을 해석할 때 자바스크립트 파일이 아닌 웹 자원(HTML, CSS, Images, 폰트 등)들을 변환할 수 있도록 도와주는 속성입니다.
        &amp;nbsp;이런 점에서 로더는 다른 빌드 툴들의 &lt;kbd&gt;&quot;tasks&quot;&lt;/kbd&gt;와 유사하며, &lt;kbd&gt;Typescript&lt;/kbd&gt; 같은 다른 언어를 자바스크립트로 변경하거나 인라인 이미지를 &lt;kbd&gt;data URL&lt;/kbd&gt; 로 변경할 수도 있습니다.
        심지어 로더는 CSS 파일을 자바스크립트 모듈에서 직접 &lt;kbd&gt;import&lt;/kbd&gt; 할 수 있는 방법도 제공하고 있습니다.
    &lt;/p&gt;
    &lt;p&gt;그리고 일반적으로 웹팩을 사용하면 주로 &lt;code&gt;babel&lt;/code&gt; 을 함께 사용하는 경우가 많은데,  ES2015(ES6+) 이상의 문법을 IE 같은 구형 브라우저와 호환시키기 위해 사용하기도 하고,
        &lt;code&gt;jsx&lt;/code&gt; 같은 &lt;code&gt;react&lt;/code&gt; 문법을 컴파일하기 위해 사용하기도 합니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;기본 사용은 다음과 같이 작성합니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// webpack.config.js
module.exports = {
  module: {
    rules: []
  }
}&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;엔트리나 아웃풋 속성과는 다르게 &lt;code&gt;module&lt;/code&gt;라는 이름을 사용합니다&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    
    &lt;p class=&quot;subtt&quot;&gt;Loader 가 필요한 이유&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;웹팩으로 애플리케이션을 빌드할 때 만약 아래와 같은 코드가 있다고 가정해 보겠습니다.&lt;/p&gt;
    &lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// app.js
import './common.css';

console.log('css loaded');&lt;/code&gt;&lt;/pre&gt;

    &lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;/* common.css */
p {
  color: blue;
}&lt;/code&gt;&lt;/pre&gt;

    &lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// webpack.config.js
module.exports = {
  entry: './app.js',
  output: {
    filename: 'bundle.js'
  }
}&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;위 파일을 웹팩으로 빌드하게 되면 아래와 같은 에러가 발생합니다.&lt;/p&gt;
    &lt;p style=&quot;text-align: left; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 900px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99CF75455DD3487B34&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99CF75455DD3487B34&quot; width=&quot;900&quot; height=&quot;144&quot; filename=&quot;css-loading-error.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
    



    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;CSS Loader 적용하기&lt;/p&gt;
    &lt;p&gt;여기서는 간단히 로더를 사용하여 &lt;kbd&gt;css 파일을 로드&lt;/kbd&gt;하는 방법에 대해 알아보겠습니다.&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;다음과 같이 필요한 로더를 설치하도록 합니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm i -D css-loader style-loader&lt;/code&gt;&lt;/pre&gt;



    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;로더들을 설치한 후 다음과 같이 파일 생성 및 작성해 봅니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;html&quot;&gt;html&lt;/div&gt;&lt;/div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;ko&quot;&amp;gt;
&amp;lt;head&amp;gt;
	&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
	&amp;lt;title&amp;gt;Webpack Task&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
	&amp;lt;header&amp;gt;
		&amp;lt;h1&amp;gt;Webpack 학습하기&amp;lt;/h1&amp;gt;
	&amp;lt;/header&amp;gt;
	&amp;lt;div&amp;gt;
		&amp;lt;p&amp;gt;
			사실 웹팩 설정은 복잡하기로 악명 높지만 다양한 업무를 처리해 줄 수 있는 장점과
            계속해서 빠르고 쉽게(?) 개선되고 있습니다.
		&amp;lt;/p&amp;gt;
	&amp;lt;/div&amp;gt;
	&amp;lt;script src=&quot;dist/jaehee.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
	&amp;lt;script src=&quot;dist/module.chunk.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;앞서 번들링한 것을 확인해 보고 싶다면 &lt;kbd&gt;module.chunk.js&lt;/kbd&gt; 도 import(선택사항)하면 됩니다.&lt;/p&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;
        css 를 불러오기 위해 index.js 파일에서 마치 JS 파일을 임포트하듯이 CSS 파일을 임포트 합니다.
        아래와 같이 js 파일에서 import 하도록 합니다.
    &lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// index.js
import '../css/base.css'

console.log('Webpack 번들링 실행');&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;kbd&gt;src/css/base.css&lt;/kbd&gt; 파일 생성 후 아래와 같이 간단히 css를 작성해 봅니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;@charset &quot;UTF-8&quot;;
body {
	color: red;
}&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;기존 &lt;code&gt;webpack.config.js&lt;/code&gt;에 아래와 같이 추가하도록 합니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;module.exports = {
    mode : 'development', // 웹팩4부터는 mode(development||production)는 필수
    entry: {
        jaehee : './src/js/index.js',
        'module.chunk' : ['./src/js/module1.js', './src/js/module2.js'] // 배열 사용
    },
    output: {
        path : __dirname,
        filename : 'dist/[name].js' // 위에 지정한 entry 키의 이름에 맵핑되어 파일이 생성됨
    },
    // 로더를 지정하기 위한 module 정의
    module: {
        rules: [ //module.rules 를 사용해 여러개의 로더 지정이 가능.
            {
                // test : 변환 할 파일을 지정
                // 정규 표현식으로 문자열 .css 확장자로 끝나는 것을 찾음.
                test: /\.css$/,
                // use : 해당 파일에 적용할 로더의 이름
                // 로더에서 모듈 로딩 순서는 배열의 요소 오른쪽에서 왼쪽으로 로딩하며 진행
                use: ['style-loader', 'css-loader']
            }
        ]
    }
};&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;위와 같이 구성하신 후 &lt;kbd&gt;CLI&lt;/kbd&gt;에서 &lt;code&gt;webpack&lt;/code&gt;을 실행한 후 &lt;kbd&gt;index.html&lt;/kbd&gt;을 브라우저에서 확인하면 글자색이 빨간색으로 변경된 것을 확인하실 수 있을 것입니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p class=&quot;subtt&quot;&gt;module.rules 설정&lt;/p&gt;
    &lt;p&gt;&lt;code&gt;webpack.config.js&lt;/code&gt; 의 &lt;kbd&gt;module&lt;/kbd&gt;을 살펴보겠습니다. &lt;/p&gt;
    &lt;p&gt;&lt;code&gt;module.rules&lt;/code&gt; 를 사용해 여러 개의 로더 지정이 가능하며, 이는 로더를 표시하는 방법으로 코드를 간결하고 깔끔하게 유지하는데 도움이 됩니다.&lt;/p&gt;
    &lt;p&gt;&lt;code&gt;module.rule&lt;/code&gt; 내부에  &amp;nbsp;&lt;code&gt;test&lt;/code&gt;는 변환 할 파일을 지정하고, &amp;nbsp;&lt;code&gt;use&lt;/code&gt;는 변환 할 파일에 지정할 로더를 설정합니다.&lt;/p&gt;
    &lt;p&gt;그리고 &lt;code&gt;use&lt;/code&gt; 주석에도 설명해 놓았듯이 로더는 오른쪽에서 왼쪽으로 평가,실행되며, 위의 예시 코드에서는 &lt;kbd&gt;css-loader&lt;/kbd&gt;를 거쳐 &lt;kbd&gt;style-loader&lt;/kbd&gt;로 진행됨을 의미합니다.&lt;/p&gt;
    &lt;p&gt;다시 전체적으로 분석해 보자면,
        &lt;mark&gt;.css 확장자를 가진 모든 css 파일에 대해서 css-loader 를 통해 자바스크립트 파일로 번들링을 하고 style-loader 로 html 에 internal style 로 넣어주게 되는&lt;/mark&gt;입니다.
    &lt;/p&gt;
    &lt;p&gt;그래서 &lt;kbd&gt;index.html&lt;/kbd&gt;을 브라우저 개발자 도구의 소스보기에서 확인해 보면 아래와 같이 내부 스타일이 들어가 있는 것을 확인할 수 있습니다.&lt;/p&gt;
    &lt;p&gt;&lt;img src=&quot;../images/index.dev.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    
    &lt;p&gt;&lt;strong&gt;# 자주 사용되는 로더 종류&lt;/strong&gt;&lt;/p&gt;
    &lt;p&gt;앞에서 살펴본 CSS 로더 이외에도 실제 서비스를 만들 때 자주 사용되는 로더의 종류는 다음과 같습니다.&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;a href=&quot;https://webpack.js.org/loaders/babel-loader/#root&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Babel Loader&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://webpack.js.org/loaders/sass-loader/#root&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Sass Loader&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://webpack.js.org/loaders/file-loader/#root&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;File Loader&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://github.com/vuejs/vue-loader&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;Vue Loader&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://webpack.js.org/guides/typescript/#loader&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;TS Loader&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;# 로더를 여러 개 사용하는 경우&lt;/strong&gt;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;로더를 여러 개 사용하는 경우에는 아래와 같이 &lt;code&gt;rules&lt;/code&gt; 배열에 로더 옵션을 추가해주면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;module.exports = {
  module: {
    rules: [
      { test: /\.css$/, use: 'css-loader' },
      { test: /\.vue$/, use: 'vue-loader' },
      // ...
    ]
  }
}&lt;/code&gt;&lt;/pre&gt;



    &lt;p&gt;위에서 사용해본 &lt;kbd&gt;css&lt;/kbd&gt;를 번들링하여 사용한 방법은 실무에서 흔히 사용하는 방법이 아닐 것입니다.&lt;/p&gt;
    &lt;p&gt;일반적으로 css 파일을 내부 스타일로 작성하기 보다 개별 css 파일을 &lt;code&gt;import&lt;/code&gt; 하여 사용하는 것이 일반적입니다.&lt;/p&gt;
    &lt;p&gt;그렇다면 위와 같이 &lt;kbd&gt;css&lt;/kbd&gt;를 &lt;kbd&gt;jaehee.js&lt;/kbd&gt;에 번들링 하지 않고, 빌드시에 별도의 &lt;code&gt;.css&lt;/code&gt; 파일로 분리하여 &lt;kbd&gt;import&lt;/kbd&gt; 해야 하는데 이때 이용할 수 있는 것이 &lt;code&gt;plugins&lt;/code&gt; 입니다.
       &amp;nbsp; 아래에서 &lt;code&gt;Plugins&lt;/code&gt;에 대해 알아보겠습니다.
    &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;Plugin 설정&lt;/p&gt;
    &lt;p&gt;
        플러그인(plugin)은 웹팩의 기본적인 동작에 추가적인 기능을 제공하는 속성입니다. &lt;br /&gt;
        이는 웹팩의 핵심으로 로더가 할 수 없는 일들을 수행할 수 있습니다. &lt;br /&gt;
        로더랑 비교하면 로더는 파일을 해석하고 변환하는 과정에 관여하는 반면, 플러그인은 해당 결과물의 형태를 바꾸는 역할을 한다고 보면 됩니다.
    &lt;/p&gt;
    &lt;p&gt;즉, Loader 는 모듈을 처리하지만, Plugin 은 번들링된 파일을 처리한다는 점에 차이점이 있습니다.&lt;/p&gt;
    &lt;p&gt; Plugin 은 번들된 파일을 난독화, 압축할 수도 있고 핫리로딩, 파일복사, 파일추출, 별칭사용 등의 부가적인 작업을 할 수 있습니다.&lt;/p&gt;
    &lt;p&gt;즉, 플러그인은 파일별 커스텀 기능을 사용하기 위해서 사용하는 것입니다.&lt;/p&gt;
    &lt;p&gt;플러그인 사용 방법은 인자와 옵션을 사용할 수 있고, &lt;code&gt;plugins&lt;/code&gt; 속성에 &lt;kbd&gt;new 인스턴스&lt;/kbd&gt;를 전달해야 합니다.
    &lt;/p&gt;
    &lt;p&gt; 그리고 웹팩을 어떻게 사용하느냐에 따라 플러그인 사용법은 여러가지가 될 수 있습니다.&lt;/p&gt;
    &lt;p class=&quot;point-r mt30&quot;&gt;플러그인은 기본적으로 다음과 같이 선언합니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    mode : '',
    entry : {},
    output : {},
    module : {},
    plugins : [
        new HtmlWebpackPlugin(),
        new webpack.ProgressPlugin(),
        new webpack.optimize.UglifyJsPlugin()
        // ...
    ]
}&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;위와 같이 플러그인의 배열에는 생성자 함수로 생성한 객체 인스턴스만 추가될 수 있습니다. &lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;위의 두 플러그인은 각각 아래와 같은 역할을 합니다.&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;
            &lt;a href=&quot;https://webpack.js.org/plugins/html-webpack-plugin/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;HtmlWebpackPlugin&lt;/a&gt;
            : 웹팩으로 빌드한 결과물로 HTML 파일을 생성해주는 플러그인
        &lt;/li&gt;
        &lt;li&gt;
            &lt;a href=&quot;https://webpack.js.org/plugins/progress-plugin/#root&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;ProgressPlugin&lt;/a&gt;
            : 웹팩의 빌드 진행율을 표시해주는 플러그인
        &lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;subtt&quot;&gt;컴파일된 CSS를 별도의 CSS 파일로 분리하는 방법&lt;/p&gt;
    &lt;p&gt;앞선 예제코드에서 로더를 사용하여 css(내부스타일)를 DOM에 주입하였다면 예제 코드를 수정하여 css 파일을 추출해 보는 방법을 진행해 봅니다.&lt;/p&gt;
    &lt;p class=&quot;point-r mt30&quot;&gt;먼저 css 파일을 추출하기 위한 플러그인을 설치하도록 합니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ npm i --save-dev mini-css-extract-plugin&lt;/code&gt;&lt;/pre&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;warning tip&quot;&gt;
        &lt;p&gt;Webpack &lt;kbd&gt;v3&lt;/kbd&gt; 까지는 &lt;code&gt;extract-text-webpack-plugin&lt;/code&gt;을 사용했었으나 Webpack &lt;kbd&gt;v4&lt;/kbd&gt;부터
            &lt;kbd&gt;css&lt;/kbd&gt;와 관련된 파일 분리는 &lt;a href=&quot;https://webpack.js.org/plugins/mini-css-extract-plugin/&quot; target=&quot;_blank&quot; class=&quot;tx-link&quot;&gt;mini-css-extract-plugin(Webpack 공식사이트)&lt;/a&gt;을 사용하도록 변경되었습니다.&lt;/p&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p class=&quot;point-r&quot;&gt;설치가 끝났다면 기존 &lt;kbd&gt;webpack.config.js&lt;/kbd&gt; 와 &lt;kbd&gt;index.html&lt;/kbd&gt;을 아래와 같이 수정하도록 합니다.&lt;/p&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;// webpack.config.js
const path = require( 'path' ); // 경로를 설정
const MiniCssExtractPlugin = require('mini-css-extract-plugin'); // node_modules 에서 불러옴

module.exports = {
    mode : 'development',
    entry: {
        jaehee : './src/js/index.js'
    },
    output: {
        path : path.resolve(__dirname, 'dist'),
        filename : '[name].js'
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                // MiniCssExtractPlugin 사용
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader'
                ],
                // exclude 는 제외할 폴더나 파일
                // 다른 모듈을 사용해서 컴파일하지 않도록 지정(안전성 확보)
                exclude: /node_modules/
            }
        ]
    },
    // 플러그인 설정
    plugins: [
        // 컴파일 + 번들링 CSS 파일이 저장될 경로와 이름 지정
        new MiniCssExtractPlugin({ filename: 'css/style.css' })
    ]
};&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;지금까지 &lt;code&gt;output&lt;/code&gt;의 &lt;code&gt;path&lt;/code&gt;에서 &lt;code&gt;__dirname&lt;/code&gt; 을 사용했으나 앞으로는 nodeJS 에서 제공하는 &lt;code&gt;path&lt;/code&gt;라는 모듈을 활용하도록 하겠습니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;div class=&quot;quote&quot;&gt;
        &lt;p class=&quot;tit&quot;&gt;여기서 잠깐&lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;code&gt;path.join(path1, path2…)&lt;/code&gt;
                &lt;p&gt;파라미터로 전달받은 경로를 이어서 하나의 경로로 만듭니다 :&lt;/p&gt;
            &lt;/li&gt;
        &lt;/ul&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;path.join('/foo', 'bar', 'baz/asdf');
// Returns : 'foo/bar/baz/asdf'&lt;/code&gt;&lt;/pre&gt;


        &lt;p&gt;&amp;nbsp;&lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;code&gt;path.resolve([from…], to)&lt;/code&gt;
                &lt;p&gt;전달받은 경로의 절대 경로를 리턴합니다 :&lt;/p&gt;
            &lt;/li&gt;
        &lt;/ul&gt;
&lt;pre class=&quot;cm-s-dracula CodeMirror&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif');
// 만약에 현재 디릭토리가 /home/myself/node 라고 가정한다면
// 리턴되는 값은 다음과 같이 유효하지 않은 값들을 가공하여 나오게 됩니다.
// '/home/myself/node/wwwroot/static_files/gif/image.gif'&lt;/code&gt;&lt;/pre&gt;
        &lt;p&gt;&amp;nbsp;&lt;/p&gt;
        &lt;p&gt;&lt;code&gt;path.join()&lt;/code&gt;은 자바스크립트의 내장 API 에 있는 &lt;kbd&gt;join&lt;/kbd&gt; 과 비슷한 역할을 하지만
            해당 API 가 동작하는 OS 의 파일 구분자를 이용하여 파일 위치를 조합하기 때문에 OS 별로 결과값이 다를 수 있습니다.
        &lt;/p&gt;
        &lt;p&gt;&lt;code&gt;path.resolve()&lt;/code&gt;는 모듈을 해석하는데 있어 영향을 미치는 옵션으로 웹팩이 스스로 판단하여 경로나 확장자를 처리할 수 있게 도와주는 옵션입니다.
        &lt;/p&gt;
        &lt;p&gt;앞서 본 &lt;code&gt;join()&lt;/code&gt; 같은 경우는 그냥 문자열을 합치는 거지만, &lt;code&gt;resolve&lt;/code&gt;는 오른쪽에서 왼쪽을 파일 위치를 구성해 가며 유효한 위치를 찾습니다.
            만약, 결과 값이 유효하지 않으면 현재 디렉토리가 사용되며 반환되는 위치 값은 항상 절대 경로(absolute URL)입니다.
        &lt;/p&gt;
        &lt;p&gt;
            &lt;mark&gt;resolve 를 사용하는 이유가 웹팩 번들링을 할 때 기타 복잡한 다수의 loader 가 있을 경우 복잡함으로 인해 유효하지 않은 위치가 있다면 자동으로 제거해주고 검증이 된 폴더
                위치를 잡아주는 것이
                resolve 의 특성이기 때문에 좀 더 안전한 번들링을 위해서 사용하는 측면이 있습니다.
            &lt;/mark&gt;
        &lt;/p&gt;


    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;
        상단에서 &lt;code&gt;require( 'path' )&lt;/code&gt;로 &lt;kbd&gt;path&lt;/kbd&gt; 모듈을 불러오고 &lt;kbd&gt;output&lt;/kbd&gt;에서 &lt;code&gt;path.resolve(__dirname, 'dist')&lt;/code&gt; 로 경로를 지정하였으며,
        &lt;kbd&gt;test&lt;/kbd&gt; 를 통해 load 할 파일을 지정하고&lt;code&gt;[ MiniCssExtractPlugin.loader, 'css-loader']&lt;/code&gt; 를 통해 오른쪽부터 왼쪽으로 수행하도록 설정했습니다.
        &lt;br /&gt;
        &lt;br /&gt;
        그리고 &lt;code&gt;exclude: /node_modules/&lt;/code&gt; 로  제외할 폴더를 정의할 수 있으며, 여기서는 &lt;kbd&gt;MiniCssExtractPlugin.loader&lt;/kbd&gt;, &lt;kbd&gt;css-loader&lt;/kbd&gt; 이외의 기타 다른 모더,모듈로 컴파일이
        되지 않도록 하기 위한 안전성 확보차원에서 정의하는 것입니다.
    &lt;/p&gt;
    &lt;p&gt;반대로 &lt;code&gt;include&lt;/code&gt;로 꼭 이 로더를 사용해서 컴파일할 것들을 지정해 줄 수도 있습니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;
        마지막으로 css 파일을 추출하기 위한 플러그인 설정을 위해 &lt;code&gt;new MiniCssExtractPlugin({ filename: 'css/style.css' })&lt;/code&gt; 를 작성합니다.
        이때 옵션으로 컴파일과 번들링된 최종 파일이 저장될 경로로 번들링된 파일이름을 지정할 수 있습니다.
    &lt;/p&gt;
    &lt;p&gt;&lt;kbd&gt;webpack.config.js&lt;/kbd&gt; 작성이 끝났다면 &lt;kbd&gt;CLI&lt;/kbd&gt;에서 &lt;code&gt;webpack&lt;/code&gt;을 실행해 보면 &lt;kbd&gt;/dist/css/style.css&lt;/kbd&gt; 파일이 추출되어 있는 것을 확인할 수 있습니다.&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;point-r&quot;&gt;그리고 &lt;kbd&gt;index.html&lt;/kbd&gt;에 추출된 &lt;kbd&gt;css&lt;/kbd&gt;를 사용하기 위해 &lt;code&gt;import&lt;/code&gt; 시켜주도록 합니다.&lt;/p&gt;
    &lt;div class=&quot;prism-show-language&quot;&gt;&lt;div class=&quot;prism-show-language-label&quot; data-language=&quot;html&quot;&gt;index.html&lt;/div&gt;&lt;/div&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code class=&quot;language-markup&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;ko&quot;&amp;gt;
&amp;lt;head&amp;gt;
	&amp;lt;meta charset=&quot;UTF-8&quot;&amp;gt;
	&amp;lt;title&amp;gt;Webpack Task&amp;lt;/title&amp;gt;
	&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;dist/css/style.css&quot;&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
	&amp;lt;header&amp;gt;
		&amp;lt;h1&amp;gt;Webpack 학습하기&amp;lt;/h1&amp;gt;
	&amp;lt;/header&amp;gt;
	&amp;lt;div&amp;gt;
		&amp;lt;p&amp;gt;
			사실 웹팩 설정은 복잡하기로 악명 높지만 다양한 업무를 처리해 줄 수 있는 장점과
			계속해서 빠르고 쉽게(?) 개선되고 있습니다.
		&amp;lt;/p&amp;gt;
	&amp;lt;/div&amp;gt;
	&amp;lt;script src=&quot;dist/jaehee.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;&lt;kbd&gt;index.html&lt;/kbd&gt;을 브라우저에서 확인하면 &lt;kbd&gt;css&lt;/kbd&gt;가 적용된 것을 확인하실 수 있습니다.&lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p class=&quot;tit&quot;&gt;Concepts Review&lt;/p&gt;
    &lt;p&gt;지금까지 살펴본 웹팩 4가지 주요 속성을 도식으로 나타내보면 다음과 같습니다.&lt;/p&gt;
&lt;p class=&quot;tac&quot; style=&quot;text-align: center; clear: none; float: none;&quot;&gt;&lt;span class=&quot;imageblock&quot; style=&quot;display: inline-block; width: 570px;  height: auto; max-width: 100%;&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/cfile/tistory/99A0144C5DD348AB38&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Ft1.daumcdn.net%2Fcfile%2Ftistory%2F99A0144C5DD348AB38&quot; width=&quot;570&quot; height=&quot;320&quot; filename=&quot;diagram.png&quot; filemime=&quot;image/jpeg&quot; style=&quot;&quot;/&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class=&quot;tac&quot;&gt;&lt;br /&gt;&lt;/p&gt;
    &lt;p&gt;위 도식을 보면서 지금까지 배운 내용을 정리하면 다음과 같습니다.&lt;/p&gt;
    &lt;ol&gt;
        &lt;li&gt;&lt;code&gt;Entry&lt;/code&gt; 속성은 웹팩을 실행할 대상 파일. 진입점&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;Output&lt;/code&gt; 속성은 웹팩의 결과물에 대한 정보를 입력하는 속성. 일반적으로 &lt;kbd&gt;filename&lt;/kbd&gt;과 &lt;kbd&gt;path&lt;/kbd&gt;를 정의&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;Loader&lt;/code&gt; 속성은 CSS, 이미지와 같은 비 자바스크립트 파일을 웹팩이 인식할 수 있게 추가하는 속성. 로더는 오른쪽에서 왼쪽 순으로 적용&lt;/li&gt;
        &lt;li&gt;&lt;code&gt;Plugin&lt;/code&gt; 속성은 웹팩으로 변환한 파일에 추가적인 기능을 더하고 싶을 때 사용하는 속성. 웹팩 변환 과정 전반에 대한 제어권을 갖고 있음&lt;/li&gt;
    &lt;/ol&gt;


    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p class=&quot;tit&quot;&gt;Conclusion&lt;/p&gt;
    &lt;p&gt;이번 장에서 웹팩의 주요 속성인 &lt;code&gt;mode&lt;/code&gt;, &lt;code&gt;entry&lt;/code&gt;, &lt;code&gt;output&lt;/code&gt;, &lt;code&gt;module&lt;/code&gt;, &lt;code&gt;plugins&lt;/code&gt; 에 대해 알아보았습니다.&lt;/p&gt;
    &lt;p&gt;
        다음 장에서는 실제로 실무에 필요한 주요 환경 설정과 그에 따른 webpack Dev Server, SASS, 기타 로더, 플러그인 등을 다뤄보도록 하겠습니다.
    &lt;/p&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;div class=&quot;loof-wrap&quot;&gt;
        &lt;div class=&quot;loof&quot;&gt;
            &lt;svg class=&quot;rl-logo&quot; width=&quot;606&quot; height=&quot;300&quot; viewBox=&quot;0 0 606 300&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; preserveAspectRatio=&quot;none&quot;&gt;
                &lt;defs&gt;
                    &lt;clipPath id=&quot;clipLogo&quot;&gt;
                        &lt;path d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;
                        &lt;/path&gt;&lt;/clipPath&gt;
                &lt;/defs&gt;
                &lt;path class=&quot;rl-logo__path&quot; d=&quot;M 319.1 207 C 328.2 194.9 337.2 183.2 346.2 172 C 372 201.2 397.3 235.6 435.5 250 C 476.4 262.5 524.9 244.1 543.9 205 C 565.6 159.1 560 94 515.8 63.1 C 480.9 39.3 429.8 42.4 398.4 71.1 C 358.3 105.2 331.5 151.5 298.1 192 C 265.7 233.8 228.8 278.1 175.6 293.9 C 122.6 307.2 61.9 287.7 30.1 242 C -17.9 176.4 -3.4 71.7 66.2 26.1 C 105.7 -0.5 160.1 -6.8 201.7 18.1 C 235.4 36.5 261.3 65.2 286 93.1 C 277 105.4 268 117.5 258.9 129.1 C 231.7 98.2 204.7 60.7 162.6 50.1 C 118.3 38.2 70.4 66.2 56.2 109.1 C 41.9 154.2 50.9 212.7 94.3 240 C 134.6 265.8 191.4 253 221.8 217 C 255.7 182.1 280.6 139.4 312.1 102.1 C 342.8 63.9 377.7 24.2 426.5 8.1 C 488.2 -12.6 560.5 21.4 588.1 79.1 C 621.4 145.6 601.4 236 536.9 275.9 C 504.7 295.9 463.1 304.6 426.5 291.9 C 381.7 277.5 348.9 241.2 319.1 207 L 319.1 207 Z&quot;&gt;&lt;/path&gt;
                &lt;path class=&quot;rl-logo__track&quot; clip-path=&quot;url(#clipLogo)&quot; d=&quot;M 323.9 178.9 C 344.8 202.5 383.7 245.8 412.2 261.3 C 447.3 282.3 494.3 278 527.7 255.5 C 586.6 217 597.8 127.5 557.2 72.1 C 530.3 33.4 479 17 434.2 28.2 C 389.3 41.5 358.1 79 330.7 114.3 C 318.9 128.6 277.3 185.4 277.3 185.4 C 249.9 220.7 218.7 258.1 173.8 271.5 C 129 282.7 77.7 266.3 50.8 227.6 C 10.2 172.2 21.4 82.7 80.3 44.2 C 113.7 21.6 160.7 17.4 195.8 38.4 C 224.3 53.9 261.2 96.2 282.1 119.7&quot;&gt;&lt;/path&gt;
            &lt;/svg&gt;
        &lt;/div&gt;
        &lt;div class=&quot;name&quot;&gt;
            Jaehee's&lt;span class=&quot;b&quot;&gt; WebClub&lt;/span&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
    &lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Web Tech/Webpack</category>
      <category>webpack dev-server</category>
      <category>webpack entry</category>
      <category>webpack loader</category>
      <category>webpack plugin</category>
      <category>webpack 번들러</category>
      <category>webpack 환경설정</category>
      <author>jaiyah</author>
      <guid isPermaLink="true">https://webclub.tistory.com/636</guid>
      <comments>https://webclub.tistory.com/636#entry636comment</comments>
      <pubDate>Tue, 19 Nov 2019 10:44:03 +0900</pubDate>
    </item>
  </channel>
</rss>