<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>잼코딩</title>
    <link>https://jamin0619.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Wed, 28 Oct 2026 12:55:04 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>잼coding</managingEditor>
    <item>
      <title>JavaScript 심화 ③ 배열 메서드, Date 객체, 비동기 처리</title>
      <link>https://jamin0619.tistory.com/29</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에는 배열을 더욱 편리하게 다룰 수 있는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;순회 및 탐색 메서드&lt;/span&gt;&lt;/b&gt;&lt;span&gt;, 배열을 새로운 형태로 가공하는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;변형 메서드&lt;/span&gt;&lt;/b&gt;&lt;span&gt;, 날짜와 시간을 다루는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Date 객체&lt;/span&gt;&lt;/b&gt;&lt;span&gt;, 그리고 JavaScript에서 중요한 &lt;/span&gt;&lt;b&gt;&lt;span&gt;동기와 비동기 처리&lt;/span&gt;&lt;/b&gt;&lt;span&gt;에 대해 정리한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;특히 &lt;/span&gt;&lt;span&gt;forEach&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;map&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;filter&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;find&lt;/span&gt;&lt;span&gt;와 같은 배열 메서드는 실제 웹 개발과 React에서도 매우 자주 사용하기 때문에 동작 방식의 차이를 정확하게 이해해두는 것이 중요하다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;1. 배열의 순회 및 탐색 메서드&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;배열의 요소를 하나씩 확인하거나 원하는 값을 찾을 때 사용할 수 있는 대표적인 메서드는 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;forEach()
includes()
indexOf()
findIndex()
find()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;각각 비슷해 보이지만 반환하는 값과 목적이 다르다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;2. forEach()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;forEach()&lt;/span&gt;&lt;span&gt;는 배열의 모든 요소를 하나씩 순회하면서 원하는 동작을 수행하는 메서드이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;let arr1 = [1, 2, 3];

arr1.forEach(function (item, index, arr) {

    console.log(index, item);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;콜백 함수에는 기본적으로 다음과 같은 값이 전달된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;item  &amp;rarr; 현재 요소
index &amp;rarr; 현재 요소의 인덱스
arr   &amp;rarr; 현재 순회 중인 원본 배열&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;let arr = [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;];

arr.forEach((item, index) =&amp;gt; {

    console.log(index, item);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과는 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;basic&quot;&gt;&lt;code&gt;0 A
1 B
2 C&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;일반적인 &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt;문보다 배열의 요소를 간단하게 순회할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;3. forEach 활용&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;각 요소를 두 배로 만들어 새로운 배열에 저장해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr1 = [1, 2, 3];

let doubledArr = [];

arr1.forEach((item) =&amp;gt; {

    doubledArr.push(item * 2);
});

console.log(doubledArr);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[2, 4, 6]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;forEach()&lt;/span&gt;&lt;span&gt; 자체가 새로운 배열을 만들어주는 것은 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 예제에서는 &lt;/span&gt;&lt;span&gt;doubledArr&lt;/span&gt;&lt;span&gt;라는 배열을 따로 만들고 &lt;/span&gt;&lt;span&gt;push()&lt;/span&gt;&lt;span&gt;를 사용했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이처럼 값을 변환해서 &lt;/span&gt;&lt;b&gt;&lt;span&gt;새로운 배열을 만들 목적이라면 이후에 나올 &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;map()&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;이 더 적합하다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;4. includes()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;includes()&lt;/span&gt;&lt;span&gt;는 배열에 특정 값이 존재하는지 확인한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr2 = [1, 2, 3];

let isInclude = arr2.includes(3);

console.log(isInclude);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;값이 존재하면 &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;, 존재하지 않으면 &lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;span&gt;를 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;console.log(arr2.includes(10));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서 단순하게&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 배열 안에 이 값이 존재하는가?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;를 확인할 때 사용하기 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;5. indexOf()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;indexOf()&lt;/span&gt;&lt;span&gt;는 배열에서 특정 값을 찾아 &lt;/span&gt;&lt;b&gt;&lt;span&gt;해당 값의 인덱스를 반환&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr3 = [1, 2, 3];

let index = arr3.indexOf(2);

console.log(index);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;배열의 인덱스는 &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;부터 시작하기 때문에 숫자 &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;의 위치는 &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;찾으려는 값이 없다면 &lt;/span&gt;&lt;span&gt;-1&lt;/span&gt;&lt;span&gt;을 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;console.log(arr3.indexOf(10));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;-1&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;6. 객체 배열에서 indexOf 사용 시 주의점&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체 배열에서는 &lt;/span&gt;&lt;span&gt;indexOf()&lt;/span&gt;&lt;span&gt; 사용 시 주의해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;let objectArr = [

    { name: &quot;정재민&quot; },

    { name: &quot;홍길동&quot; }
];

console.log(
    objectArr.indexOf({ name: &quot;정재민&quot; })
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;겉으로 보기에는 배열 안에 동일한 객체가 존재하기 때문에 &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;이 나올 것 같지만 결과는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;-1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;왜냐하면 객체는 내부 값이 아니라 &lt;/span&gt;&lt;b&gt;&lt;span&gt;참조값을 기준으로 비교하기 때문&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;{ name: &quot;정재민&quot; } === { name: &quot;정재민&quot; }&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;서로 따로 생성된 객체이기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체 내부의 특정 값을 기준으로 찾고 싶다면 &lt;/span&gt;&lt;span&gt;findIndex()&lt;/span&gt;&lt;span&gt;를 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;7. findIndex()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;findIndex()&lt;/span&gt;&lt;span&gt;는 배열의 모든 요소를 순회하면서 &lt;/span&gt;&lt;b&gt;&lt;span&gt;콜백 함수의 조건을 만족하는 첫 번째 요소의 인덱스&lt;/span&gt;&lt;/b&gt;&lt;span&gt;를 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr4 = [1, 2, 3];

const findedIndex = arr4.findIndex(
    (item) =&amp;gt; item % 2 !== 0
);

console.log(findedIndex);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;첫 번째 홀수는 &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;이고 인덱스가 &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;이므로 결과는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;객체 배열에서 활용&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;let objectArr = [

    { name: &quot;정재민&quot; },

    { name: &quot;홍길동&quot; }
];

const index = objectArr.findIndex(
    (item) =&amp;gt; item.name === &quot;정재민&quot;
);

console.log(index);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;indexOf()&lt;/span&gt;&lt;span&gt;와 달리 객체 자체를 비교하는 것이 아니라&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;item.name === &quot;정재민&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이라는 조건을 직접 작성할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서 객체 배열에서는 &lt;/span&gt;&lt;span&gt;findIndex()&lt;/span&gt;&lt;span&gt;가 매우 유용하다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;8. find()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;find()&lt;/span&gt;&lt;span&gt;는 &lt;/span&gt;&lt;span&gt;findIndex()&lt;/span&gt;&lt;span&gt;와 비슷하지만 인덱스가 아니라 &lt;/span&gt;&lt;b&gt;&lt;span&gt;조건을 만족하는 요소 자체를 반환&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xquery&quot;&gt;&lt;code&gt;let arr5 = [

    { name: &quot;정재민&quot; },

    { name: &quot;문지수&quot; }
];

const finded = arr5.find(
    (item) =&amp;gt; item.name === &quot;정재민&quot;
);

console.log(finded);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;{
    name: &quot;정재민&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정리하면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;findIndex() &amp;rarr; 위치 반환

find() &amp;rarr; 요소 자체 반환&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;9. includes, indexOf, findIndex, find 비교&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;네 가지 메서드는 무엇을 찾느냐에 따라 구분하면 이해하기 쉽다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드목적반환값&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;includes()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;값 존재 여부&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;true / false&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;indexOf()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;값의 위치 검색&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;index&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;findIndex()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;조건을 만족하는 요소 위치&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;index&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;find()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;조건을 만족하는 요소 검색&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;요소&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;10. 배열 변형 메서드&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에는 기존 배열을 이용해 새로운 결과를 만드는 메서드를 정리한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;대표적으로 다음 메서드를 살펴본다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;filter()
map()
sort()
toSorted()
join()&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;11. filter()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;filter()&lt;/span&gt;&lt;span&gt;는 배열의 요소 중에서 &lt;/span&gt;&lt;b&gt;&lt;span&gt;조건을 만족하는 요소들만 모아 새로운 배열로 반환&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xquery&quot;&gt;&lt;code&gt;let arr1 = [

    {
        name: &quot;정재민&quot;,
        hobby: &quot;테니스&quot;
    },

    {
        name: &quot;김효빈&quot;,
        hobby: &quot;테니스&quot;
    },

    {
        name: &quot;홍길동&quot;,
        hobby: &quot;독서&quot;
    }
];

const tennisPeople = arr1.filter(
    (item) =&amp;gt; item.hobby === &quot;테니스&quot;
);

console.log(tennisPeople);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;[
    {
        name: &quot;정재민&quot;,
        hobby: &quot;테니스&quot;
    },

    {
        name: &quot;김효빈&quot;,
        hobby: &quot;테니스&quot;
    }
]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;콜백 함수가 &lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;span&gt;를 반환하는 요소만 새로운 배열에 포함된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;쉽게 말하면&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;조건에 맞는 데이터만 골라낸다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 이해하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;12. map()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;map()&lt;/span&gt;&lt;span&gt;은 배열의 모든 요소를 순회하면서 각각의 요소를 변환한 뒤 &lt;/span&gt;&lt;b&gt;&lt;span&gt;변환 결과를 모아 새로운 배열을 반환&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr2 = [1, 2, 3];

const mapResult = arr2.map((item) =&amp;gt; {

    return item * 2;
});

console.log(mapResult);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[2, 4, 6]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;화살표 함수를 사용하면 더 간결하게 작성할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;const mapResult = arr2.map(
    (item) =&amp;gt; item * 2
);&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;13. 객체 배열에서 map 사용&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체 배열에서 특정 프로퍼티만 뽑아낼 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xquery&quot;&gt;&lt;code&gt;let people = [

    {
        name: &quot;정재민&quot;,
        hobby: &quot;테니스&quot;
    },

    {
        name: &quot;김효빈&quot;,
        hobby: &quot;테니스&quot;
    },

    {
        name: &quot;홍길동&quot;,
        hobby: &quot;독서&quot;
    }
];

let names = people.map(
    (item) =&amp;gt; item.name
);

console.log(names);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[&quot;정재민&quot;, &quot;김효빈&quot;, &quot;홍길동&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;실제 API 데이터를 가공할 때 매우 자주 사용하는 패턴이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;14. forEach와 map의 차이&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 메서드 모두 배열 전체를 순회하기 때문에 처음에는 비슷해 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 목적이 다르다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;forEach&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;arr.forEach((item) =&amp;gt; {

    console.log(item);
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;주로 각 요소에 대해 &lt;/span&gt;&lt;b&gt;&lt;span&gt;어떤 동작을 실행하는 목적&lt;/span&gt;&lt;/b&gt;&lt;span&gt;으로 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;map&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;const newArr = arr.map(
    (item) =&amp;gt; item * 2
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;각 요소를 변환하여 &lt;/span&gt;&lt;b&gt;&lt;span&gt;새로운 배열을 만드는 목적&lt;/span&gt;&lt;/b&gt;&lt;span&gt;으로 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정리하면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;forEach &amp;rarr; 하나씩 뭔가 실행

map &amp;rarr; 하나씩 변환해서 새로운 배열 생성&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이라고 생각하면 편하다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;15. filter와 map을 같이 사용하기&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;실제 개발에서는 여러 배열 메서드를 연결해서 사용하는 경우도 많다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;const people = [

    {
        name: &quot;정재민&quot;,
        hobby: &quot;테니스&quot;
    },

    {
        name: &quot;김효빈&quot;,
        hobby: &quot;테니스&quot;
    },

    {
        name: &quot;홍길동&quot;,
        hobby: &quot;독서&quot;
    }
];

const tennisNames = people
    .filter((person) =&amp;gt; person.hobby === &quot;테니스&quot;)
    .map((person) =&amp;gt; person.name);

console.log(tennisNames);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[&quot;정재민&quot;, &quot;김효빈&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;먼저&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;filter()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;로 테니스를 좋아하는 사람만 추리고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그 결과에서&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;map()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;을 사용해 이름만 가져온 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이러한 방식을 **메서드 체이닝(Method Chaining)**이라고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;16. sort()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;sort()&lt;/span&gt;&lt;span&gt;는 배열을 정렬하는 메서드이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;문자열 배열을 정렬해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;let arr = [&quot;b&quot;, &quot;a&quot;, &quot;c&quot;];

arr.sort();

console.log(arr);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;17. 숫자 배열에서 sort 사용 시 주의점&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;숫자 배열에서는 그냥 &lt;/span&gt;&lt;span&gt;sort()&lt;/span&gt;&lt;span&gt;를 사용하면 주의해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;sort()&lt;/span&gt;&lt;span&gt;의 기본 정렬은 숫자의 크기를 그대로 비교하는 것이 아니라 &lt;/span&gt;&lt;b&gt;&lt;span&gt;문자열처럼 비교하는 방식&lt;/span&gt;&lt;/b&gt;&lt;span&gt;을 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서 숫자는 비교 함수를 전달해주는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr3 = [10, 3, 5];

arr3.sort((a, b) =&amp;gt; {

    if (a &amp;gt; b) {

        return 1;

    } else if (b &amp;gt; a) {

        return -1;

    } else {

        return 0;
    }
});

console.log(arr3);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[3, 5, 10]&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;18. sort 비교 함수 이해하기&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;sort()&lt;/span&gt;&lt;span&gt;의 비교 함수에서는 반환값에 따라 순서가 결정된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;음수 &amp;rarr; a를 b보다 앞에 배치

양수 &amp;rarr; b를 a보다 앞에 배치

0 &amp;rarr; 순서를 유지&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;숫자를 오름차순으로 정렬할 때는 훨씬 간단하게 작성할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;arr3.sort((a, b) =&amp;gt; a - b);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;내림차순은 반대로 작성한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;arr3.sort((a, b) =&amp;gt; b - a);&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;19. sort는 원본 배열을 수정한다&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;sort()&lt;/span&gt;&lt;span&gt;에서 특히 중요한 특징이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;const numbers = [3, 1, 2];

numbers.sort();

console.log(numbers);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기존 &lt;/span&gt;&lt;span&gt;numbers&lt;/span&gt;&lt;span&gt; 배열 자체가 정렬된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉, &lt;/span&gt;&lt;span&gt;sort()&lt;/span&gt;&lt;span&gt;는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;원본 배열을 변경하는 메서드&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;20. toSorted()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;toSorted()&lt;/span&gt;&lt;span&gt;는 &lt;/span&gt;&lt;span&gt;sort()&lt;/span&gt;&lt;span&gt;와 비슷하게 배열을 정렬하지만 중요한 차이가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span&gt;원본 배열을 변경하지 않고 정렬된 새로운 배열을 반환한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let arr5 = [&quot;c&quot;, &quot;a&quot;, &quot;b&quot;];

const sorted = arr5.toSorted();

console.log(arr5);

console.log(sorted);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[&quot;c&quot;, &quot;a&quot;, &quot;b&quot;]

[&quot;a&quot;, &quot;b&quot;, &quot;c&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기존 배열은 그대로 유지된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정리하면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;sort()
&amp;rarr; 원본 배열 수정

toSorted()
&amp;rarr; 원본 유지 + 새로운 배열 반환&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;불변성을 중요하게 생각하는 코드에서는 &lt;/span&gt;&lt;span&gt;toSorted()&lt;/span&gt;&lt;span&gt;가 유용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;21. join()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;join()&lt;/span&gt;&lt;span&gt;은 배열의 모든 요소를 하나의 문자열로 합친다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;vbscript&quot;&gt;&lt;code&gt;let arr6 = [
    &quot;hi&quot;,
    &quot;im&quot;,
    &quot;jaemin&quot;
];

const joined = arr6.join();

console.log(joined);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;hi,im,jaemin&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기본 구분자는 쉼표 &lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;22. join의 구분자 변경&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;원하는 문자열을 구분자로 지정할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;processing&quot;&gt;&lt;code&gt;const joined = arr6.join(&quot; &quot;);

console.log(joined);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;hi im jaemin&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다음처럼 사용할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;arr6.join(&quot;-&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;hi-im-jaemin&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;배열의 값을 화면에 문자열 형태로 보여줘야 할 때 유용하다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;배열 메서드 한 번에 정리&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드역할결과&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;forEach()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;모든 요소 순회&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;별도 반환 배열 없음&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;includes()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;특정 값 존재 확인&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Boolean&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;indexOf()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;값의 위치 검색&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;index&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;findIndex()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;조건 만족 요소의 위치 검색&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;index&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;find()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;조건 만족 요소 검색&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;요소&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;filter()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;조건 만족 요소만 추출&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;새 배열&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;map()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;모든 요소 변환&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;새 배열&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;sort()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배열 정렬&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;원본 변경&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;toSorted()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배열 정렬&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;새 배열&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;join()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배열을 문자열로 결합&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;String&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;23. Date 객체&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript에서는 날짜와 시간을 다루기 위해 &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt; 객체를 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 날짜와 시간을 만들려면 &lt;/span&gt;&lt;span&gt;new Date()&lt;/span&gt;&lt;span&gt;를 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let date1 = new Date();

console.log(date1);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;실행하는 시점의 날짜와 시간이 저장된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;24. 특정 날짜의 Date 객체 생성&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;특정 날짜를 전달해서 &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt; 객체를 만들 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let date2 = new Date(&quot;1997-01-07T10:10:10&quot;);

console.log(date2);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;날짜와 시간을 문자열로 전달할 때는 가능한 한 표준적인 형태를 사용하는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;YYYY-MM-DDTHH:mm:ss&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;arcade&quot;&gt;&lt;code&gt;new Date(&quot;1997-01-07T10:10:10&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처럼 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;또는 숫자를 따로 전달할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let date3 = new Date(
    1997,
    0,
    7,
    10,
    10,
    10
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여기서 주의할 점은 &lt;/span&gt;&lt;b&gt;&lt;span&gt;월(month)은 0부터 시작&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;0  &amp;rarr; 1월
1  &amp;rarr; 2월
2  &amp;rarr; 3월
...
11 &amp;rarr; 12월&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;25. 타임스탬프&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;타임스탬프(Timestamp)는 특정 기준 시점부터 얼마나 시간이 지났는지를 숫자로 나타낸 값이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript의 &lt;/span&gt;&lt;span&gt;Date&lt;/span&gt;&lt;span&gt;에서는 기본적으로&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1970년 1월 1일 00:00:00 UTC&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;를 기준으로 몇 밀리초가 지났는지를 나타낸다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 날짜의 타임스탬프를 가져오려면 &lt;/span&gt;&lt;span&gt;getTime()&lt;/span&gt;&lt;span&gt;을 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let date1 = new Date();

let timestamp = date1.getTime();

console.log(timestamp);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과는 다음과 같이 큰 숫자로 나온다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1750000000000&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;실제 값은 실행 시점에 따라 달라진다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;26. 타임스탬프로 Date 생성&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;타임스탬프를 이용해 다시 날짜 객체를 만들 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let date1 = new Date();

let ts1 = date1.getTime();

let date2 = new Date(ts1);

console.log(date1);
console.log(date2);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 Date 객체는 같은 시점을 나타낸다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;타임스탬프는 날짜끼리 비교하거나 시간을 계산할 때 유용하다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;27. Date에서 시간 요소 가져오기&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Date 객체에서는 연도, 월, 일, 시간 등을 각각 추출할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;vbscript&quot;&gt;&lt;code&gt;let date = new Date();

let year = date.getFullYear();

let month = date.getMonth() + 1;

let day = date.getDate();

let hour = date.getHours();

let minute = date.getMinutes();

let seconds = date.getSeconds();

console.log(
    year,
    month,
    day,
    hour,
    minute,
    seconds
);&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;28. getMonth()에 +1 하는 이유&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript의 월은 &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;부터 시작한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;date.getMonth();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;에서&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;0  &amp;rarr; 1월
1  &amp;rarr; 2월
2  &amp;rarr; 3월
...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이기 때문에 우리가 일반적으로 사용하는 월로 표현하려면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;date.getMonth() + 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처럼 &lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;을 더해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;29. 날짜 수정하기&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Date 객체에 저장된 날짜와 시간을 수정할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;lasso&quot;&gt;&lt;code&gt;let date = new Date();

date.setFullYear(2023);

date.setMonth(2);

date.setDate(30);

date.setHours(23);

date.setMinutes(59);

date.setSeconds(59);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;각각 다음 값을 변경한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;setFullYear() &amp;rarr; 연도

setMonth() &amp;rarr; 월

setDate() &amp;rarr; 일

setHours() &amp;rarr; 시

setMinutes() &amp;rarr; 분

setSeconds() &amp;rarr; 초&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;setMonth(2)&lt;/span&gt;&lt;span&gt;는 3월을 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;30. Date 출력 형식 변경&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Date 객체에는 날짜와 시간을 다양한 형태의 문자열로 출력하는 메서드가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;toDateString()&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;console.log(
    date.toDateString()
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;날짜 중심의 문자열로 표현한다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;toLocaleString()&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;console.log(
    date.toLocaleString()
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;사용자의 로케일 환경에 맞는 날짜와 시간 형식으로 변환한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;한국 환경이라면 일반적으로 한국에서 익숙한 날짜&amp;middot;시간 형식으로 표시된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;특정 로케일을 직접 지정할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;console.log(
    date.toLocaleString(&quot;ko-KR&quot;)
);&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;31. JavaScript의 동기 처리&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript 코드는 기본적으로 **동기적(Synchronous)**으로 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;동기적이라는 것은 작성된 코드가 기본적으로 위에서 아래로 순서대로 실행된다는 의미이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(1);

console.log(2);

console.log(3);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
2
3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;앞의 코드가 끝나야 다음 코드가 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;32. 비동기 처리&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 웹 개발에서는 시간이 오래 걸리는 작업이 많다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;서버에서 데이터 받아오기

파일 처리

타이머

사용자 이벤트 기다리기&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;등이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이런 작업이 끝날 때까지 JavaScript의 전체 실행이 멈춰버리면 웹 페이지가 제대로 동작하기 어렵다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이를 해결하기 위해 &lt;/span&gt;&lt;b&gt;&lt;span&gt;비동기(Asynchronous) 처리&lt;/span&gt;&lt;/b&gt;&lt;span&gt;를 활용한다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;33. setTimeout()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript에서 가장 간단하게 비동기 동작을 확인할 수 있는 방법 중 하나가 &lt;/span&gt;&lt;span&gt;setTimeout()&lt;/span&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;console.log(1);

setTimeout(() =&amp;gt; {

    console.log(2);

}, 3000);

console.log(3);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;코드를 위에서부터 보면 &lt;/span&gt;&lt;span&gt;1 &amp;rarr; 2 &amp;rarr; 3&lt;/span&gt;&lt;span&gt; 순서로 출력될 것 같지만 실제 결과는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
3
2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;는 약 3초 후에 출력된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;34. 왜 1 &amp;rarr; 3 &amp;rarr; 2 순서일까?&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;먼저&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(1);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그다음&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;gams&quot;&gt;&lt;code&gt;setTimeout(...)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;을 만난다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 JavaScript는 3초 동안 이 위치에서 멈춰있는 것이 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;타이머 처리를 실행 환경에 맡기고 다음 코드를 계속 실행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(3);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 먼저 실행된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 타이머 조건이 만족된 후 콜백 함수가 실행되면서&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;가 출력된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;최종 결과는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
3
2&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;35. JavaScript는 싱글 스레드인가?&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript의 코드 실행을 담당하는 핵심 실행 흐름은 기본적으로 하나의 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Call Stack&lt;/span&gt;&lt;/b&gt;&lt;span&gt;을 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;쉽게 표현하면 JavaScript는 한 순간에 하나의 JavaScript 작업을 처리하는 구조라고 이해할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그렇다면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;setTimeout()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;같은 비동기 작업은 어떻게 처리할 수 있을까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;브라우저 환경에서는 JavaScript 엔진 외부에 있는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Web APIs&lt;/span&gt;&lt;/b&gt;&lt;span&gt;가 이러한 기능을 지원한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;대표적으로&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;setTimeout
DOM Event
fetch&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;등이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;36. Web APIs&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Web APIs는 JavaScript 언어 자체의 기능이라기보다 &lt;/span&gt;&lt;b&gt;&lt;span&gt;웹 브라우저가 제공하는 기능&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 다음 코드를 실행한다고 해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;setTimeout(() =&amp;gt; {

    console.log(&quot;3초 후 실행&quot;);

}, 3000);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개념적인 흐름은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;JavaScript 실행

&amp;darr;

setTimeout 발견

&amp;darr;

브라우저의 Web APIs에서 타이머 처리

&amp;darr;

JavaScript는 다음 코드 계속 실행

&amp;darr;

타이머 완료

&amp;darr;

콜백 함수가 실행 가능한 상태가 됨

&amp;darr;

JavaScript에서 콜백 실행&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 덕분에 JavaScript는 시간이 걸리는 작업을 기다리는 동안 다른 코드를 계속 처리할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;37. Web API와 JavaScript 엔진&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;전체적인 구조를 간단하게 보면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;┌─────────────────────┐
│  JavaScript Engine  │
│                     │
│     Call Stack      │
└─────────┬───────────┘
          │
          │ 비동기 작업 요청
          ▼
┌─────────────────────┐
│      Web APIs       │
│                     │
│ setTimeout          │
│ fetch               │
│ DOM Event           │
└─────────────────────┘&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;브라우저의 도움을 받아 시간이 오래 걸리는 작업을 처리한 뒤, 완료된 작업의 콜백을 다시 JavaScript에서 실행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 과정에는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Callback Queue와 Event Loop&lt;/span&gt;&lt;/b&gt;&lt;span&gt;라는 개념도 관여한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 부분은 다음 비동기 JavaScript 파트에서 더 자세히 공부할 예정이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;38. 브라우저와 Node.js의 차이&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여기서 한 가지 알아둘 점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;비동기 작업은 모두 Web API가 처리한다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 무조건 외우기보다는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;브라우저 환경에서는 Web APIs가 처리한다&lt;/span&gt;&lt;/b&gt;&lt;span&gt;고 이해하는 것이 더 정확하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript는 브라우저뿐만 아니라 Node.js에서도 실행할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;브라우저에서는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;Web APIs&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;가 비동기 기능을 제공하고,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Node.js에서는 Node.js의 런타임 환경이 타이머, 파일 입출력 등의 비동기 기능을 제공한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉, 비동기 처리를 지원하는 주체는 JavaScript가 실행되는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;런타임 환경에 따라 달라질 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;39. 이번 배열 메서드에서 중요한 차이&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에 배운 메서드 중에서는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;원본 배열을 변경하는지 여부&lt;/span&gt;&lt;/b&gt;&lt;span&gt;도 중요하다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;원본 배열을 변경하는 메서드&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;sort()&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;원본 배열을 변경하지 않고 새로운 값을 반환&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;filter()
map()
toSorted()
join()
find()
findIndex()
includes()
indexOf()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;특히 React에서는 기존 상태를 직접 수정하지 않는 것이 중요하기 때문에 &lt;/span&gt;&lt;span&gt;map()&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;filter()&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;toSorted()&lt;/span&gt;&lt;span&gt;와 같은 메서드를 자주 사용하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;실전 예제로 연결해보기&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 서버에서 다음과 같은 사용자 데이터를 받았다고 해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;const users = [

    {
        id: 1,
        name: &quot;정재민&quot;,
        active: true
    },

    {
        id: 2,
        name: &quot;홍길동&quot;,
        active: false
    },

    {
        id: 3,
        name: &quot;문지수&quot;,
        active: true
    }
];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;활성화된 사용자만 가져오려면 &lt;/span&gt;&lt;span&gt;filter()&lt;/span&gt;&lt;span&gt;를 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;const activeUsers = users.filter(
    (user) =&amp;gt; user.active
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이름만 가져오려면 &lt;/span&gt;&lt;span&gt;map()&lt;/span&gt;&lt;span&gt;을 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;const names = activeUsers.map(
    (user) =&amp;gt; user.name
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 메서드를 합치면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;const names = users
    .filter((user) =&amp;gt; user.active)
    .map((user) =&amp;gt; user.name);

console.log(names);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[&quot;정재민&quot;, &quot;문지수&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이런 식의 코드는 실제 프론트엔드 개발에서도 매우 자주 사용하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;정리&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에 배운 내용을 정리하면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개념설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;forEach()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배열 전체를 순회하며 작업 수행&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;includes()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;특정 값의 존재 여부 확인&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;indexOf()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;특정 값의 인덱스 검색&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;findIndex()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;조건을 만족하는 요소의 인덱스 검색&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;find()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;조건을 만족하는 요소 자체 반환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;filter()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;조건을 만족하는 요소만 새로운 배열로 반환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;map()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;각각의 요소를 변환하여 새로운 배열 생성&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;sort()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;원본 배열을 정렬&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;toSorted()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;정렬된 새로운 배열 반환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;join()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배열을 하나의 문자열로 변환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;Date&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;날짜와 시간을 다루는 객체&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;getTime()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;타임스탬프 반환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;getFullYear()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;연도 추출&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;getMonth()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;월 추출, 0부터 시작&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;toLocaleString()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;로케일에 맞는 날짜&amp;middot;시간 문자열&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;동기 처리&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;코드를 순서대로 실행&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;비동기 처리&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;특정 작업을 기다리는 동안 다른 코드 실행 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;setTimeout()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;일정 시간 후 콜백 함수 실행&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;Web APIs&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;브라우저가 제공하는 여러 기능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;Call Stack&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;JavaScript 코드의 실행 흐름을 관리&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번 파트에서 특히 중요하게 느껴지는 부분은 &lt;/span&gt;&lt;b&gt;&lt;span&gt;배열 메서드의 역할을 구분하는 것&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;isbl&quot;&gt;&lt;code&gt;찾고 싶다
&amp;rarr; find()

조건에 맞는 것만 남기고 싶다
&amp;rarr; filter()

모든 요소를 다른 형태로 바꾸고 싶다
&amp;rarr; map()

그냥 모든 요소에 어떤 작업을 하고 싶다
&amp;rarr; forEach()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 네 가지를 구분할 수 있으면 배열 데이터를 다루는 코드가 훨씬 읽기 쉬워진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 비동기 처리에서는 우선&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;erlang&quot;&gt;&lt;code&gt;JavaScript 코드는 기본적으로 순서대로 실행된다.

하지만 오래 걸리는 작업을 효율적으로 처리하기 위해
비동기 방식을 사용할 수 있다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정도까지 이해하고, 이후 &lt;/span&gt;&lt;b&gt;&lt;span&gt;Event Loop &amp;rarr; Promise &amp;rarr; async/await &amp;rarr; fetch API&lt;/span&gt;&lt;/b&gt;&lt;span&gt; 순서로 연결해 공부하면 될 것 같다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>개발/자바스크립트</category>
      <category>자바스크립트 #JS #Javascript #심화</category>
      <author>잼coding</author>
      <guid isPermaLink="true">https://jamin0619.tistory.com/29</guid>
      <comments>https://jamin0619.tistory.com/29#entry29comment</comments>
      <pubDate>Tue, 6 Oct 2026 16:37:36 +0900</pubDate>
    </item>
    <item>
      <title>JavaScript 심화 ② 원시&amp;middot;객체 타입, 객체 복사와 비교, 순회, 배열 메서드</title>
      <link>https://jamin0619.tistory.com/28</link>
      <description>&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript 심화 문법 두 번째 정리.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에는 JavaScript에서 데이터를 이해할 때 매우 중요한 &lt;/span&gt;&lt;b&gt;&lt;span&gt;원시 타입과 객체 타입의 차이&lt;/span&gt;&lt;/b&gt;&lt;span&gt;부터 시작해서 객체의 복사와 비교, 배열과 객체를 순회하는 방법, 그리고 배열의 요소를 추가하거나 삭제하는 다양한 메서드에 대해 정리한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;특히 객체 타입은 원시 타입과 저장되는 방식이 다르기 때문에 앞으로 React의 상태 관리 등을 이해할 때도 중요한 개념이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;1. 원시 타입과 객체 타입&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript의 자료형은 크게 두 가지 관점으로 나누어 생각할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;원시 타입(Primitive Type)
객체 타입(Object Type)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 타입의 가장 큰 차이는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;값을 저장하고 복사하는 방식&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;2. 원시 타입&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;원시 타입은 &lt;/span&gt;&lt;b&gt;&lt;span&gt;값 자체가 변수에 저장되고 복사되는 타입&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;대표적인 원시 타입은 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;mathematica&quot;&gt;&lt;code&gt;Number
String
Boolean
Null
Undefined
BigInt
Symbol&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 다음과 같은 코드가 있다고 해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;let a = 10;

let b = a;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;현재 &lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;의 값을 &lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;에 복사했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이후 &lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;를 변경해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;b = 20;

console.log(a);
console.log(b);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;10
20&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;의 값을 수정해도 &lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;에는 영향을 주지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;왜냐하면 &lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;에는 &lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;가 가지고 있던 &lt;/span&gt;&lt;b&gt;&lt;span&gt;값 자체인 &lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;10&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span&gt;이 복사되었기 때문&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개념적으로 보면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;a &amp;rarr; 10

b &amp;rarr; 10&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;각각 독립적인 값을 가지고 있다고 이해할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;3. 원시 타입은 불변 값이다&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;원시 타입의 값은 **불변(Immutable)**이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여기서 주의할 점은&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;변수의 값을 변경할 수 없다는 의미는 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 다음 코드는 당연히 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;let num = 10;

num = 20;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 기존 메모리의 &lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;이라는 값을 &lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt;으로 직접 수정하는 것이 아니라 새로운 값 &lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt;을 변수에 다시 할당하는 방식이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉,&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;원시 값 자체 &amp;rarr; 변경 불가능

변수가 가리키는 값 &amp;rarr; 다른 값으로 재할당 가능&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이라고 이해하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;4. 객체 타입&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체 타입은 원시 타입과 다르게 동작한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체를 변수에 저장하면 객체 자체가 직접 저장되는 것이 아니라 &lt;/span&gt;&lt;b&gt;&lt;span&gt;해당 객체를 참조할 수 있는 값&lt;/span&gt;&lt;/b&gt;&lt;span&gt;을 통해 접근하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 다음 객체가 있다고 해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let o1 = {
    name: &quot;정재민&quot;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 다른 변수에 객체를 복사한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;gcode&quot;&gt;&lt;code&gt;let o2 = o1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 경우 객체가 새로 만들어지는 것이 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;o1&lt;/span&gt;&lt;span&gt;과 &lt;/span&gt;&lt;span&gt;o2&lt;/span&gt;&lt;span&gt;가 &lt;/span&gt;&lt;b&gt;&lt;span&gt;같은 객체를 참조하게 된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;개념적으로 표현하면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;o1 ─┐
    ├──&amp;gt; { name: &quot;정재민&quot; }
o2 ─┘&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서 &lt;/span&gt;&lt;span&gt;o2&lt;/span&gt;&lt;span&gt;를 통해 객체를 수정하면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;o2.name = &quot;홍길동&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;o1&lt;/span&gt;&lt;span&gt;에서도 변경된 값을 확인할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;console.log(o1.name);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;홍길동&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 변수가 같은 객체를 참조하고 있기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;5. 객체는 가변 값이다&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체는 일반적으로 **가변(Mutable)**한 값이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체가 생성된 이후에도 내부 프로퍼티를 수정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;const person = {
    name: &quot;정재민&quot;,
    age: 27
};

person.age = 28;

person.job = &quot;Developer&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt;로 선언했더라도 객체 내부의 프로퍼티는 수정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다만 변수에 새로운 객체를 다시 할당하는 것은 불가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;const person = {
    name: &quot;정재민&quot;
};

// 오류 발생
person = {
    name: &quot;홍길동&quot;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉,&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;const 객체의 내부 수정 &amp;rarr; 가능

const 변수 자체에 새로운 객체 재할당 &amp;rarr; 불가능&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;6. 객체 복사&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체를 복사할 때는 특히 주의해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다음 코드를 보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let o1 = {
    name: &quot;정재민&quot;,
    age: 27
};

let o2 = o1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이것은 새로운 객체를 만드는 것이 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;단순히 &lt;/span&gt;&lt;b&gt;&lt;span&gt;같은 객체의 참조를 복사&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;o2.age = 30;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;을 실행하면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;console.log(o1.age);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과 역시&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;30&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;7. 참조 복사&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다음처럼 객체 변수를 그대로 대입하는 방식은 객체 자체가 아니라 참조가 복사된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let o1 = {
    name: &quot;정재민&quot;
};

let o2 = o1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서 두 변수는 같은 객체를 바라본다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(o1 === o2);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;8. 얕은 복사&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;원본과 다른 새로운 객체를 만들고 싶다면 Spread 문법 등을 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let o1 = {
    name: &quot;정재민&quot;,
    age: 27
};

let o2 = {
    ...o1
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이제 &lt;/span&gt;&lt;span&gt;o1&lt;/span&gt;&lt;span&gt;과 &lt;/span&gt;&lt;span&gt;o2&lt;/span&gt;&lt;span&gt;는 서로 다른 객체이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(o1 === o2);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;o2&lt;/span&gt;&lt;span&gt;를 수정하더라도&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;o2.age = 30;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;o1.age&lt;/span&gt;&lt;span&gt;는 그대로 유지된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(o1.age); // 27
console.log(o2.age); // 30&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 여기서 중요한 점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 방식은 **깊은 복사가 아니라 얕은 복사(Shallow Copy)**이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;9. 얕은 복사의 한계&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체 내부에 또 다른 객체가 있는 경우를 생각해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;const person1 = {

    name: &quot;정재민&quot;,

    job: {
        title: &quot;Developer&quot;
    }
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Spread 문법으로 복사한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;const person2 = {
    ...person1
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;겉의 객체는 서로 다른 객체이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(person1 === person2);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 내부의 &lt;/span&gt;&lt;span&gt;job&lt;/span&gt;&lt;span&gt; 객체는 어떨까?&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;cos&quot;&gt;&lt;code&gt;console.log(person1.job === person2.job);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;내부 객체는 여전히 같은 객체를 참조하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;person2.job.title = &quot;Designer&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;를 실행하면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;console.log(person1.job.title);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과 역시&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;Designer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;로 변경된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉, Spread 문법을 이용한 복사는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;1단계 프로퍼티만 새롭게 복사하는 얕은 복사&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;10. 깊은 복사&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;깊은 복사(Deep Copy)는 객체 내부에 또 다른 객체나 배열이 있어도 모두 새로운 객체로 복사하는 방식이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;최근 JavaScript에서는 &lt;/span&gt;&lt;span&gt;structuredClone()&lt;/span&gt;&lt;span&gt;을 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;const person1 = {

    name: &quot;정재민&quot;,

    job: {
        title: &quot;Developer&quot;
    }
};

const person2 = structuredClone(person1);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 경우 내부의 &lt;/span&gt;&lt;span&gt;job&lt;/span&gt;&lt;span&gt; 객체도 별도로 복사된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(person1 === person2);
console.log(person1.job === person2.job);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;false
false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;person2.job.title = &quot;Designer&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;를 실행해도 &lt;/span&gt;&lt;span&gt;person1&lt;/span&gt;&lt;span&gt;에는 영향을 주지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;console.log(person1.job.title);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;Developer&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;정리하면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;참조 복사
&amp;rarr; 같은 객체를 바라봄

얕은 복사
&amp;rarr; 가장 바깥 객체만 새로운 객체

깊은 복사
&amp;rarr; 내부 객체까지 모두 별도로 복사&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 이해할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;11. 객체 비교&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체끼리 &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; 연산자를 사용하여 비교하면 &lt;/span&gt;&lt;b&gt;&lt;span&gt;객체 내부의 값이 아니라 참조를 기준으로 비교&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let o1 = {
    a: 1
};

let o2 = {
    a: 1
};

console.log(o1 === o2);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 객체의 내용은 완전히 동일해 보인다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 결과는&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;false&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;각각 별도로 생성된 서로 다른 객체이기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;같은 객체를 참조하면?&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let o1 = {
    a: 1
};

let o2 = o1;

console.log(o1 === o2);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 변수가 동일한 객체를 참조하고 있기 때문이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서 객체의 &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; 비교는&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;내부 값이 같은가?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;가 아니라&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;같은 객체인가?&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;를 비교한다고 이해하면 된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;12. JSON.stringify를 이용한 비교&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;간단한 객체라면 &lt;/span&gt;&lt;span&gt;JSON.stringify()&lt;/span&gt;&lt;span&gt;를 이용하여 객체를 문자열로 변환한 후 비교하는 방법도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;let o1 = {
    name: &quot;정재민&quot;,
    age: 27
};

let o2 = {
    name: &quot;정재민&quot;,
    age: 27
};

console.log(
    JSON.stringify(o1) === JSON.stringify(o2)
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체 자체를 비교한 것이 아니라&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;JSON.stringify(o1)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;을 통해 문자열로 변환된 결과를 비교한 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;JSON.stringify 비교의 주의점&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 이 방법을 &lt;/span&gt;&lt;b&gt;&lt;span&gt;모든 객체의 정확한 깊은 비교 방법이라고 생각하면 안 된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;프로퍼티 순서 등의 영향을 받을 수 있고, &lt;/span&gt;&lt;span&gt;undefined&lt;/span&gt;&lt;span&gt;, 함수, &lt;/span&gt;&lt;span&gt;Symbol&lt;/span&gt;&lt;span&gt; 등이 포함된 경우 원하는 형태로 변환되지 않을 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서 복잡한 객체를 실제 서비스에서 비교해야 한다면 별도의 깊은 비교 로직이나 라이브러리를 사용하는 경우가 많다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;13. 배열과 함수도 객체인가?&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript에서 배열과 함수 역시 객체 계열에 속한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 배열도 프로퍼티와 메서드를 가지고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;const arr = [1, 2, 3];

console.log(arr.length);

arr.push(4);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;함수 역시 값으로 저장하고 객체처럼 다룰 수 있는 특징을 가지고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;다만 &lt;/span&gt;&lt;span&gt;typeof&lt;/span&gt;&lt;span&gt;를 사용하면 조금 특이한 결과가 나타난다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;console.log(typeof []);
console.log(typeof {});
console.log(typeof function () {});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;object
object
function&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;배열의 &lt;/span&gt;&lt;span&gt;typeof&lt;/span&gt;&lt;span&gt; 결과는 &lt;/span&gt;&lt;span&gt;&quot;object&quot;&lt;/span&gt;&lt;span&gt;이고, 함수는 특별히 &lt;/span&gt;&lt;span&gt;&quot;function&quot;&lt;/span&gt;&lt;span&gt;이 반환된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;14. 순회란?&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;순회(Iteration)란 배열이나 객체에 저장되어 있는 여러 값에 &lt;/span&gt;&lt;b&gt;&lt;span&gt;순서대로 하나씩 접근하는 것&lt;/span&gt;&lt;/b&gt;&lt;span&gt;을 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 다음과 같은 데이터가 있다고 해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;let numbers = [1, 2, 3];

let person = {

    name: &quot;정재민&quot;,

    age: 27,

    hobby: &quot;공부&quot;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;배열과 객체는 구조가 다르기 때문에 순회하는 방법에도 차이가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;15. 배열 순회 - 인덱스 이용&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;가장 기본적인 배열 순회 방법은 &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt;문과 배열의 인덱스를 사용하는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;matlab&quot;&gt;&lt;code&gt;let arr = [1, 2, 3];

for (let i = 0; i &amp;lt; arr.length; i++) {

    console.log(arr[i]);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
2
3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;여기서&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;arr.length&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;는 배열의 길이를 의미한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;배열의 인덱스는 &lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;부터 시작하기 때문에&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;matlab&quot;&gt;&lt;code&gt;i &amp;lt; arr.length&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;까지 반복한다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;다른 배열도 동일&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr2 = [4, 5, 6, 7, 8];

for (let i = 0; i &amp;lt; arr2.length; i++) {

    console.log(arr2[i]);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;배열의 길이가 달라지더라도 &lt;/span&gt;&lt;span&gt;length&lt;/span&gt;&lt;span&gt;를 사용하면 배열 전체를 순회할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;주의: 배열 요소 접근은 &lt;/span&gt;&lt;span&gt;arr(i)&lt;/span&gt;&lt;span&gt;가 아니라 &lt;/span&gt;&lt;span&gt;arr&lt;span&gt;[i]&lt;/span&gt;&lt;/span&gt;&lt;span&gt;로 작성해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;16. for...of 반복문&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;배열을 순회할 때는 &lt;/span&gt;&lt;span&gt;for...of&lt;/span&gt;&lt;span&gt; 문법을 사용할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xquery&quot;&gt;&lt;code&gt;let arr = [1, 2, 3];

for (let item of arr) {

    console.log(item);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
2
3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기존의 &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt;문처럼 인덱스를 직접 관리할 필요가 없다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;lisp&quot;&gt;&lt;code&gt;for (let item of arr)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;에서 배열의 각 요소가 순서대로 &lt;/span&gt;&lt;span&gt;item&lt;/span&gt;&lt;span&gt;에 들어간다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;17. 일반 for문과 for...of&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 방식에는 약간의 차이가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;일반 for문&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;matlab&quot;&gt;&lt;code&gt;for (let i = 0; i &amp;lt; arr.length; i++) {

    console.log(i, arr[i]);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;인덱스를 직접 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;for...of&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;for (let item of arr) {

    console.log(item);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;요소 자체가 필요한 경우 간단하게 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;cos&quot;&gt;&lt;code&gt;인덱스가 필요함 &amp;rarr; 일반 for문

값만 필요함 &amp;rarr; for...of&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 생각하면 이해하기 쉽다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;18. 객체 순회&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체는 배열과 달리 일반적인 숫자 인덱스로 데이터를 관리하지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;let person = {

    name: &quot;정재민&quot;,

    age: 27,

    hobby: &quot;랩&quot;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서 객체의 &lt;/span&gt;&lt;span&gt;key&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;value&lt;/span&gt;&lt;span&gt;를 가져올 수 있는 여러 방법이 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;19. Object.keys()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Object.keys()&lt;/span&gt;&lt;span&gt;는 객체의 &lt;/span&gt;&lt;b&gt;&lt;span&gt;key만 모아서 새로운 배열로 반환&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let keys = Object.keys(person);

console.log(keys);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[&quot;name&quot;, &quot;age&quot;, &quot;hobby&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;반환되는 값이 배열이기 때문에 &lt;/span&gt;&lt;span&gt;for...of&lt;/span&gt;&lt;span&gt;를 이용할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;q&quot;&gt;&lt;code&gt;for (let key of keys) {

    const value = person[key];

    console.log(key, value);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;name 정재민
age 27
hobby 랩&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;20. Object.values()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Object.values()&lt;/span&gt;&lt;span&gt;는 객체의 &lt;/span&gt;&lt;b&gt;&lt;span&gt;value만 모아서 새로운 배열로 반환&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;let values = Object.values(person);

console.log(values);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[&quot;정재민&quot;, 27, &quot;랩&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;반환된 배열을 순회할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;for (let value of values) {

    console.log(value);
}&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;21. for...in&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체의 key를 바로 순회하고 싶다면 &lt;/span&gt;&lt;span&gt;for...in&lt;/span&gt;&lt;span&gt;을 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;for (let key in person) {

    console.log(key);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;name
age
hobby&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;key를 이용하면 value도 가져올 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;for (let key in person) {

    console.log(key, person[key]);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;name 정재민
age 27
hobby 랩&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;객체를 순회할 때 자주 볼 수 있는 형태이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;22. 배열과 객체 순회 정리&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대상방법특징&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;배열&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;일반 &lt;/span&gt;&lt;span&gt;for&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;인덱스 사용 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;배열&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;for...of&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;요소를 바로 가져옴&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;객체&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Object.keys()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;key 배열 반환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;객체&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;Object.values()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;value 배열 반환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;객체&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;for...in&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;객체의 key 순회&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;추가로 이후에는 &lt;/span&gt;&lt;span&gt;Object.entries()&lt;/span&gt;&lt;span&gt;나 배열의 &lt;/span&gt;&lt;span&gt;forEach()&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;map()&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;filter()&lt;/span&gt;&lt;span&gt; 등을 이용한 순회도 배우게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;23. 배열 요소 조작 메서드&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;JavaScript 배열에는 요소를 추가하거나 제거하고, 새로운 배열을 만들어내는 다양한 메서드가 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에는 대표적인 6개를 정리한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;perl&quot;&gt;&lt;code&gt;push
pop
shift
unshift
slice
concat&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;24. push()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;push()&lt;/span&gt;&lt;span&gt;는 배열의 &lt;/span&gt;&lt;b&gt;&lt;span&gt;맨 뒤에 새로운 요소를 추가&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr1 = [1, 2, 3];

arr1.push(4);

console.log(arr1);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[1, 2, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;한 번에 여러 개를 추가할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;arr1.push(5, 6, 7);&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span&gt;push의 반환값&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;push()&lt;/span&gt;&lt;span&gt;는 요소를 추가한 후 &lt;/span&gt;&lt;b&gt;&lt;span&gt;변경된 배열의 길이&lt;/span&gt;&lt;/b&gt;&lt;span&gt;를 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr1 = [1, 2, 3];

const newLength = arr1.push(4, 5, 6, 7);

console.log(arr1);
console.log(newLength);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;[1, 2, 3, 4, 5, 6, 7]

7&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;중요한 점은 &lt;/span&gt;&lt;span&gt;push()&lt;/span&gt;&lt;span&gt;가 원본 배열을 직접 변경한다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;25. pop()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;pop()&lt;/span&gt;&lt;span&gt;은 배열의 &lt;/span&gt;&lt;b&gt;&lt;span&gt;맨 뒤 요소를 제거하고, 제거한 값을 반환&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr2 = [1, 2, 3];

const poppedItem = arr2.pop();

console.log(poppedItem);
console.log(arr2);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;3

[1, 2]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;즉,&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;push &amp;rarr; 뒤에 추가

pop &amp;rarr; 뒤에서 제거&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;라고 생각하면 쉽다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;26. shift()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;shift()&lt;/span&gt;&lt;span&gt;는 배열의 &lt;/span&gt;&lt;b&gt;&lt;span&gt;맨 앞 요소를 제거하고 반환&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr3 = [1, 2, 3];

const shiftedItem = arr3.shift();

console.log(shiftedItem);
console.log(arr3);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1

[2, 3]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;pop()&lt;/span&gt;&lt;span&gt;이 마지막 요소를 제거한다면 &lt;/span&gt;&lt;span&gt;shift()&lt;/span&gt;&lt;span&gt;는 첫 번째 요소를 제거한다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;27. unshift()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;unshift()&lt;/span&gt;&lt;span&gt;는 배열의 &lt;/span&gt;&lt;b&gt;&lt;span&gt;맨 앞에 새로운 요소를 추가&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr4 = [1, 2, 3];

const newLength = arr4.unshift(0);

console.log(arr4);
console.log(newLength);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;[0, 1, 2, 3]

4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;push()&lt;/span&gt;&lt;span&gt;와 마찬가지로 새로운 배열의 길이를 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;배열 앞/뒤 요소 조작 정리&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;네 가지 메서드는 함께 외우면 이해하기 쉽다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드위치동작반환값&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;push()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;뒤&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;추가&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;새로운 배열 길이&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;pop()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;뒤&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;제거&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;제거한 요소&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;unshift()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;앞&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;추가&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;새로운 배열 길이&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;shift()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;앞&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;제거&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;제거한 요소&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;그리고 이 네 메서드는 모두 &lt;/span&gt;&lt;b&gt;&lt;span&gt;원본 배열을 직접 수정한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;28. slice()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;slice()&lt;/span&gt;&lt;span&gt;는 배열의 특정 범위를 잘라 &lt;/span&gt;&lt;b&gt;&lt;span&gt;새로운 배열로 반환&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr5 = [1, 2, 3, 4, 5];

let sliced = arr5.slice(2, 5);

console.log(sliced);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[3, 4, 5]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;slice(start, end)&lt;/span&gt;&lt;span&gt; 형태로 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;중요한 점은&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;livecodeserver&quot;&gt;&lt;code&gt;start &amp;rarr; 포함

end &amp;rarr; 포함하지 않음&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이라는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;따라서&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;arr5.slice(2, 5);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;는 인덱스 &lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;의 요소를 가져온다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;29. 끝 위치 생략하기&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 번째 인수를 생략하면 시작 위치부터 배열의 끝까지 가져온다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr5 = [1, 2, 3, 4, 5];

let sliced = arr5.slice(2);

console.log(sliced);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[3, 4, 5]&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;30. slice는 원본 배열을 수정하지 않는다&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;push&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;pop&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;shift&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;unshift&lt;/span&gt;&lt;span&gt;와 달리 &lt;/span&gt;&lt;span&gt;slice()&lt;/span&gt;&lt;span&gt;는 원본 배열을 변경하지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr = [1, 2, 3, 4, 5];

let newArr = arr.slice(1, 3);

console.log(arr);
console.log(newArr);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[1, 2, 3, 4, 5]

[2, 3]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;원본 배열 &lt;/span&gt;&lt;span&gt;arr&lt;/span&gt;&lt;span&gt;은 그대로 유지된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;31. concat()&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;concat()&lt;/span&gt;&lt;span&gt;은 두 개 이상의 배열을 이어 붙여 &lt;/span&gt;&lt;b&gt;&lt;span&gt;새로운 배열을 반환&lt;/span&gt;&lt;/b&gt;&lt;span&gt;한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let arr6 = [1, 2];

let arr7 = [3, 4];

let concatenatedArr = arr6.concat(arr7);

console.log(concatenatedArr);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[1, 2, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;기존 배열은 그대로 유지된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(arr6);
console.log(arr7);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[1, 2]

[3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;32. Spread를 이용해서 배열 합치기&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이전에 배운 Spread 문법을 이용해 같은 기능을 구현할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let arr6 = [1, 2];

let arr7 = [3, 4];

let newArr = [
    ...arr6,
    ...arr7
];

console.log(newArr);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[1, 2, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;최근 JavaScript 코드에서는 &lt;/span&gt;&lt;span&gt;concat()&lt;/span&gt;&lt;span&gt;뿐만 아니라 Spread 문법도 자주 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;33. 원본 배열을 변경하는 메서드와 그렇지 않은 메서드&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;배열 메서드를 사용할 때 굉장히 중요한 기준 중 하나이다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;원본 배열을 변경하는 메서드&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;push()
pop()
shift()
unshift()&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;원본 배열을 변경하지 않는 메서드&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;slice()
concat()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;const arr = [1, 2, 3];

const newArr = arr.concat(4);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;에서는 &lt;/span&gt;&lt;span&gt;arr&lt;/span&gt;&lt;span&gt;은 그대로 유지되고 새로운 배열이 만들어진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이러한 차이는 앞으로 React에서 상태를 관리할 때 특히 중요하게 사용된다.&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;34. 객체 타입과 배열 메서드가 중요한 이유&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번에 공부한 &lt;/span&gt;&lt;b&gt;&lt;span&gt;객체의 참조와 불변성을 유지하는 방식&lt;/span&gt;&lt;/b&gt;&lt;span&gt;은 단순한 JavaScript 문법을 넘어서 실제 프론트엔드 개발에서 매우 중요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;예를 들어 다음처럼 배열에 직접 값을 추가할 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;const numbers = [1, 2, 3];

numbers.push(4);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;하지만 기존 배열을 수정하지 않고 새로운 배열을 만들 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;const numbers = [1, 2, 3];

const newNumbers = [
    ...numbers,
    4
];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;결과는 둘 다&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[1, 2, 3, 4]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이지만 동작 방식은 다르다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;첫 번째 방식은&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;기존 배열 직접 수정&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;두 번째 방식은&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;기존 배열 유지
+
새로운 배열 생성&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;React에서는 상태를 변경할 때 기존 객체나 배열을 직접 수정하지 않고 새로운 객체나 배열을 만들어 사용하는 패턴이 중요하기 때문에, 지금 배우는 &lt;/span&gt;&lt;b&gt;&lt;span&gt;참조값과 얕은 복사 개념이 그대로 연결된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;&lt;hr data-ke-style=&quot;style1&quot; /&gt;&lt;/div&gt;
&lt;h1&gt;&lt;span&gt;정리&lt;/span&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번 내용을 정리하면 다음과 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개념설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;원시 타입&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;값 자체가 복사됨&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;객체 타입&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;객체의 참조를 통해 접근&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;원시 값&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;불변 값&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;객체&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;일반적으로 내부 값을 수정 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;참조 복사&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;같은 객체를 바라봄&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;얕은 복사&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;바깥 객체만 새롭게 복사&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;깊은 복사&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;내부 객체까지 별도로 복사&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; 객체 비교&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;참조가 같은지 비교&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;Object.keys()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;객체의 key 배열 반환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;Object.values()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;객체의 value 배열 반환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;for...of&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배열 등의 값을 순회&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;for...in&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;객체의 key를 순회&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;push()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배열 뒤에 요소 추가&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;pop()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배열 뒤 요소 제거&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;shift()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배열 앞 요소 제거&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;unshift()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배열 앞에 요소 추가&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;slice()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;특정 범위를 새로운 배열로 반환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;span&gt;concat()&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&lt;span&gt;배열을 합친 새로운 배열 반환&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이번 파트에서 가장 중요하게 이해해야 할 부분은 &lt;/span&gt;&lt;b&gt;&lt;span&gt;객체는 값을 그대로 복사하는 것이 아니라 참조를 다룬다는 점&lt;/span&gt;&lt;/b&gt;&lt;span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;const obj1 = {
    value: 1
};

const obj2 = obj1;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 코드는 객체 두 개가 생긴 것이 아니라 &lt;/span&gt;&lt;span&gt;obj1&lt;/span&gt;&lt;span&gt;과 &lt;/span&gt;&lt;span&gt;obj2&lt;/span&gt;&lt;span&gt;가 같은 객체를 바라보고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;반면&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;const obj2 = {
    ...obj1
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;처럼 작성하면 새로운 객체를 만들 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;이 차이는 앞으로 배열 메서드뿐만 아니라 &lt;/span&gt;&lt;b&gt;&lt;span&gt;React의 State, Props, 리렌더링, 불변성&lt;/span&gt;&lt;/b&gt;&lt;span&gt;을 이해하는 데도 그대로 연결되는 중요한 개념이다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>개발/자바스크립트</category>
      <category>자바스크립트 #IT #개념 #컴공 #컴소</category>
      <author>잼coding</author>
      <guid isPermaLink="true">https://jamin0619.tistory.com/28</guid>
      <comments>https://jamin0619.tistory.com/28#entry28comment</comments>
      <pubDate>Tue, 6 Oct 2026 16:36:31 +0900</pubDate>
    </item>
    <item>
      <title>좋은 코드 리뷰, 나쁜 코드 리뷰 | 개발자는 코드만 잘 짜면 될까? 코드 리뷰와 커뮤니케이션을 배우는 책</title>
      <link>https://jamin0619.tistory.com/27</link>
      <description>&lt;h1 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;328&quot; data-start=&quot;267&quot; data-section-id=&quot;fd2q1r&quot;&gt;&amp;nbsp;&lt;/h1&gt;
&lt;blockquote data-end=&quot;373&quot; data-start=&quot;330&quot; data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;※&amp;nbsp;이 글은 출판사로부터 도서를 제공받아 직접 읽고 작성한 리뷰입니다.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;430&quot; data-start=&quot;375&quot; data-ke-size=&quot;size16&quot;&gt;개발 공부를 하다 보면 자연스럽게 코드를 작성하는 방법이나 프레임워크, 언어 문법에 집중하게 된다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;533&quot; data-start=&quot;432&quot; data-ke-size=&quot;size16&quot;&gt;그런데 실제로 여러 사람이 함께 개발하는 환경에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;코드를 작성하는 것만큼이나 내가 작성한 코드를 설명하고, 다른 사람의 코드를 리뷰하고, 의견을 주고받는 과정&lt;/b&gt;도 중요하다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;592&quot; data-start=&quot;535&quot; data-ke-size=&quot;size16&quot;&gt;이번에 읽어본 책은 바로 이런 부분을 다루고 있는&lt;br /&gt;&lt;b&gt;《좋은 코드 리뷰, 나쁜 코드 리뷰》&lt;/b&gt;다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_3560.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b4rGv2/dJMcahMHLoS/yHqtdjNrspx4WpvDnMpE00/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b4rGv2/dJMcahMHLoS/yHqtdjNrspx4WpvDnMpE00/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b4rGv2/dJMcahMHLoS/yHqtdjNrspx4WpvDnMpE00/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb4rGv2%2FdJMcahMHLoS%2FyHqtdjNrspx4WpvDnMpE00%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot; data-filename=&quot;IMG_3560.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;688&quot; data-start=&quot;617&quot; data-ke-size=&quot;size16&quot;&gt;《좋은 코드 리뷰, 나쁜 코드 리뷰》. 19가지 사례와 33가지 팁을 통해 코드 리뷰 과정에서의 커뮤니케이션 방법을 다룬다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;699&quot; data-start=&quot;690&quot; data-ke-size=&quot;size16&quot;&gt;표지에 적혀 있는&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;730&quot; data-start=&quot;701&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;좋은 개발팀은 어떻게 리뷰하고 소통하는가?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;764&quot; data-start=&quot;732&quot; data-ke-size=&quot;size16&quot;&gt;라는 문장이 이 책의 내용을 가장 잘 설명해주는 것 같다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;878&quot; data-start=&quot;766&quot; data-ke-size=&quot;size16&quot;&gt;단순히 코드의 오류를 찾아내거나 더 좋은 코드를 작성하는 방법을 알려주는 책이라기보다는,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;코드 리뷰 과정에서 개발자끼리 어떻게 의견을 전달하고 받아들여야 하는지&lt;/b&gt;를 실제 사례를 중심으로 설명한다.&lt;/p&gt;
&lt;hr data-end=&quot;883&quot; data-start=&quot;880&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;906&quot; data-start=&quot;885&quot; data-section-id=&quot;18shmdc&quot; data-ke-size=&quot;size26&quot;&gt;코드 리뷰에도 &amp;lsquo;방법&amp;rsquo;이 필요하다&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;975&quot; data-start=&quot;908&quot; data-ke-size=&quot;size16&quot;&gt;처음에는 코드 리뷰에 관한 책이라고 해서 리팩터링이나 클린 코드처럼 코드 작성 방식에 관한 내용이 많을 거라고 생각했다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1034&quot; data-start=&quot;977&quot; data-ke-size=&quot;size16&quot;&gt;하지만 실제로 읽어보니 이 책에서 중요하게 다루는 부분은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;사람과 사람 사이의 커뮤니케이션&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_3567.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bELLEM/dJMcabFHk7s/wFJkJatO95Czhf40sGjDMK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bELLEM/dJMcabFHk7s/wFJkJatO95Czhf40sGjDMK/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bELLEM/dJMcabFHk7s/wFJkJatO95Czhf40sGjDMK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbELLEM%2FdJMcabFHk7s%2FwFJkJatO95Czhf40sGjDMK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot; data-filename=&quot;IMG_3567.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1098&quot; data-start=&quot;1059&quot; data-ke-size=&quot;size16&quot;&gt;책은 &amp;lsquo;마음가짐 - 실전 사례 - 실무 팁&amp;rsquo; 순서로 구성되어 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1126&quot; data-start=&quot;1100&quot; data-ke-size=&quot;size16&quot;&gt;목차를 보면 책의 성격을 더 쉽게 알 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1133&quot; data-start=&quot;1128&quot; data-ke-size=&quot;size16&quot;&gt;책은 크게&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1184&quot; data-start=&quot;1135&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;PART 1 마음가짐&lt;/b&gt;&lt;br /&gt;&lt;b&gt;PART 2 실전&lt;/b&gt;&lt;br /&gt;&lt;b&gt;PART 3 TIPS&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1196&quot; data-start=&quot;1186&quot; data-ke-size=&quot;size16&quot;&gt;로 구성되어 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1252&quot; data-start=&quot;1198&quot; data-ke-size=&quot;size16&quot;&gt;특히 PART 2에는 실제 코드 리뷰에서 충분히 발생할 수 있는 상황들이 사례별로 정리되어 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1260&quot; data-start=&quot;1254&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-end=&quot;1391&quot; data-start=&quot;1262&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1278&quot; data-start=&quot;1262&quot; data-section-id=&quot;dah6wl&quot;&gt;긴장감 넘치는 리뷰 코멘트&lt;/li&gt;
&lt;li data-end=&quot;1291&quot; data-start=&quot;1279&quot; data-section-id=&quot;a7lb4i&quot;&gt;설명이 부족한 PR&lt;/li&gt;
&lt;li data-end=&quot;1303&quot; data-start=&quot;1292&quot; data-section-id=&quot;138dr27&quot;&gt;진행이 더딘 PR&lt;/li&gt;
&lt;li data-end=&quot;1321&quot; data-start=&quot;1304&quot; data-section-id=&quot;1am2lco&quot;&gt;지나치게 자세한 리뷰 코멘트&lt;/li&gt;
&lt;li data-end=&quot;1334&quot; data-start=&quot;1322&quot; data-section-id=&quot;yd090k&quot;&gt;리뷰되지 않은 PR&lt;/li&gt;
&lt;li data-end=&quot;1353&quot; data-start=&quot;1335&quot; data-section-id=&quot;1gczjhc&quot;&gt;코멘트에 대한 정정 정보 부족&lt;/li&gt;
&lt;li data-end=&quot;1362&quot; data-start=&quot;1354&quot; data-section-id=&quot;15tmza9&quot;&gt;방치된 논의&lt;/li&gt;
&lt;li data-end=&quot;1374&quot; data-start=&quot;1363&quot; data-section-id=&quot;1tnbwir&quot;&gt;놓친 질문 코멘트&lt;/li&gt;
&lt;li data-end=&quot;1391&quot; data-start=&quot;1375&quot; data-section-id=&quot;m3fhn8&quot;&gt;찾아보지도 않고 하는 질문&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1430&quot; data-start=&quot;1393&quot; data-ke-size=&quot;size16&quot;&gt;등 제목만 봐도 개발 과정에서 한 번쯤 마주칠 법한 상황들이 많다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1494&quot; data-start=&quot;1432&quot; data-ke-size=&quot;size16&quot;&gt;그래서 이론적인 개발 서적보다는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;실제 팀 개발 상황을 옆에서 구경하면서 배우는 느낌&lt;/b&gt;에 조금 더 가까웠다.&lt;/p&gt;
&lt;hr data-end=&quot;1499&quot; data-start=&quot;1496&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1528&quot; data-start=&quot;1501&quot; data-section-id=&quot;1e8qlqz&quot; data-ke-size=&quot;size26&quot;&gt;먼저 필요한 것은 코드가 아니라 &amp;lsquo;마음가짐&amp;rsquo;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_3568.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cIS94O/dJMcaatpyIb/umZIDw40jHtvM7K5LK8fP0/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cIS94O/dJMcaatpyIb/umZIDw40jHtvM7K5LK8fP0/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cIS94O/dJMcaatpyIb/umZIDw40jHtvM7K5LK8fP0/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcIS94O%2FdJMcaatpyIb%2FumZIDw40jHtvM7K5LK8fP0%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot; data-filename=&quot;IMG_3568.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1607&quot; data-start=&quot;1553&quot; data-ke-size=&quot;size16&quot;&gt;1부에서는 본격적인 사례에 들어가기 전, 코드 리뷰를 어떤 관점에서 바라봐야 하는지 설명한다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1636&quot; data-start=&quot;1609&quot; data-ke-size=&quot;size16&quot;&gt;개인적으로 책의 구성이 괜찮다고 느꼈던 부분이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1699&quot; data-start=&quot;1638&quot; data-ke-size=&quot;size16&quot;&gt;바로 사례부터 들어가는 것이 아니라 1부에서 먼저&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;코드 리뷰를 어떤 마음가짐으로 해야 하는지&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;설명한다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1719&quot; data-start=&quot;1701&quot; data-ke-size=&quot;size16&quot;&gt;코드 리뷰를 하다 보면 자연스럽게&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1737&quot; data-start=&quot;1721&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이 코드가 맞다 / 틀리다&amp;rdquo;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1801&quot; data-start=&quot;1739&quot; data-ke-size=&quot;size16&quot;&gt;라는 관점으로 접근하기 쉬운데, 이 책에서는 리뷰의 목적을 단순히 상대방의 잘못을 찾아내는 것으로 보지 않는다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1862&quot; data-start=&quot;1803&quot; data-ke-size=&quot;size16&quot;&gt;결국 코드 리뷰의 목적은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;더 나은 결과물을 만들기 위해 서로 정보를 주고받고 합의하는 것&lt;/b&gt;에 가깝다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;1943&quot; data-start=&quot;1864&quot; data-ke-size=&quot;size16&quot;&gt;리뷰어는 리뷰이가 생각하지 못했던 부분을 알려줄 수 있고, 반대로 리뷰이 역시 자신이 그렇게 구현한 이유나 배경을 리뷰어에게 알려줄 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2001&quot; data-start=&quot;1945&quot; data-ke-size=&quot;size16&quot;&gt;즉, 리뷰 자체가 일방적인 평가라기보다는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;서로의 정보를 보완하는 과정&lt;/b&gt;이라는 점이 인상적이었다.&lt;/p&gt;
&lt;hr data-end=&quot;2006&quot; data-start=&quot;2003&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2034&quot; data-start=&quot;2008&quot; data-section-id=&quot;qo7j8v&quot; data-ke-size=&quot;size26&quot;&gt;가장 공감됐던 부분, &amp;lsquo;놓친 질문 코멘트&amp;rsquo;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_3564.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/etlAV1/dJMcagfZuOS/SFySDnPU5kaxaCvuwK2c31/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/etlAV1/dJMcagfZuOS/SFySDnPU5kaxaCvuwK2c31/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/etlAV1/dJMcagfZuOS/SFySDnPU5kaxaCvuwK2c31/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FetlAV1%2FdJMcagfZuOS%2FSFySDnPU5kaxaCvuwK2c31%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot; data-filename=&quot;IMG_3564.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2128&quot; data-start=&quot;2059&quot; data-ke-size=&quot;size16&quot;&gt;Case 15 &amp;lsquo;놓친 질문 코멘트&amp;rsquo;. 질문을 남기는 것만큼 그 질문에 제대로 답변하는 것도 코드 리뷰의 중요한 과정이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2180&quot; data-start=&quot;2130&quot; data-ke-size=&quot;size16&quot;&gt;책에는 여러 사례가 등장하는데 그중 재미있었던 것이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&amp;lsquo;놓친 질문 코멘트&amp;rsquo;&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;사례였다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2241&quot; data-start=&quot;2182&quot; data-ke-size=&quot;size16&quot;&gt;PR에 리뷰어가 질문을 남겼는데, 리뷰이가 코드만 수정한 뒤 질문 자체에 대한 답변은 하지 않는 상황이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2285&quot; data-start=&quot;2243&quot; data-ke-size=&quot;size16&quot;&gt;겉으로 보면 이미 코드가 수정되었으니 문제가 해결된 것처럼 보일 수도 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2300&quot; data-start=&quot;2287&quot; data-ke-size=&quot;size16&quot;&gt;하지만 리뷰어 입장에서는&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2356&quot; data-start=&quot;2302&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;왜 이렇게 수정했지?&amp;rdquo;&lt;br /&gt;&amp;ldquo;내 질문의 의도를 이해한 건가?&amp;rdquo;&lt;br /&gt;&amp;ldquo;다른 이유가 있었던 건가?&amp;rdquo;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2369&quot; data-start=&quot;2358&quot; data-ke-size=&quot;size16&quot;&gt;라는 의문이 남는다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2442&quot; data-start=&quot;2371&quot; data-ke-size=&quot;size16&quot;&gt;이 사례를 보면서 코드 리뷰에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;코드를 고치는 것과 커뮤니케이션을 끝내는 것이 같은 의미는 아니라는 점&lt;/b&gt;이 꽤 와닿았다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2518&quot; data-start=&quot;2444&quot; data-ke-size=&quot;size16&quot;&gt;질문이 있었다면 그 질문에 답변하고, 수정했다면 어떤 방식으로 수정했는지 알려주는 과정까지 포함되어야 하나의 커뮤니케이션이 완성된다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2543&quot; data-start=&quot;2520&quot; data-ke-size=&quot;size16&quot;&gt;회사에서 업무를 할 때도 비슷한 것 같다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2563&quot; data-start=&quot;2545&quot; data-ke-size=&quot;size16&quot;&gt;요청받은 일을 처리하는 것만큼이나&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2624&quot; data-start=&quot;2565&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;확인했습니다.&amp;rdquo;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;ldquo;이런 이유로 이렇게 처리했습니다.&amp;rdquo;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&amp;ldquo;수정 완료했습니다.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2661&quot; data-start=&quot;2626&quot; data-ke-size=&quot;size16&quot;&gt;처럼 상대방에게 결과를 다시 전달하는 과정이 중요하기 때문이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2684&quot; data-start=&quot;2663&quot; data-ke-size=&quot;size16&quot;&gt;개발에서도 결국 같은 원리가 적용된다.&lt;/p&gt;
&lt;hr data-end=&quot;2689&quot; data-start=&quot;2686&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2714&quot; data-start=&quot;2691&quot; data-section-id=&quot;csnfgr&quot; data-ke-size=&quot;size26&quot;&gt;코드만 보고 상대방까지 판단하지 않기&lt;/h2&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2738&quot; data-start=&quot;2716&quot; data-section-id=&quot;1b8e7ma&quot; data-ke-size=&quot;size23&quot;&gt;  IMG_3569.jpg 삽입&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2791&quot; data-start=&quot;2739&quot; data-ke-size=&quot;size16&quot;&gt;코드 리뷰에서 문제가 되는 것은 코드에 대한 지적이 사람에 대한 지적으로 변하는 순간이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2850&quot; data-start=&quot;2793&quot; data-ke-size=&quot;size16&quot;&gt;또 하나 기억에 남았던 부분은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;코드에 대한 의견과 사람에 대한 평가를 구분해야 한다는 것&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2864&quot; data-start=&quot;2852&quot; data-ke-size=&quot;size16&quot;&gt;코드 리뷰를 하다 보면&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2880&quot; data-start=&quot;2866&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;왜 이렇게 작성했어요?&amp;rdquo;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2922&quot; data-start=&quot;2882&quot; data-ke-size=&quot;size16&quot;&gt;같은 질문 하나도 상황에 따라서는 상대방에게 공격적으로 느껴질 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;2980&quot; data-start=&quot;2924&quot; data-ke-size=&quot;size16&quot;&gt;반대로 리뷰를 받는 사람 역시 단순히 코드에 대한 의견인데도 자신에 대한 평가처럼 받아들일 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3030&quot; data-start=&quot;2982&quot; data-ke-size=&quot;size16&quot;&gt;책에서는 이런 상황에서 코드 자체와 작성자를 분리해서 생각해야 한다는 점을 이야기한다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3038&quot; data-start=&quot;3032&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어,&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3063&quot; data-start=&quot;3040&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;이 코드는 이해하기 어렵습니다.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3070&quot; data-start=&quot;3065&quot; data-ke-size=&quot;size16&quot;&gt;라는 것과&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3104&quot; data-start=&quot;3072&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;당신이 작성한 코드는 항상 이해하기 어렵습니다.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3118&quot; data-start=&quot;3106&quot; data-ke-size=&quot;size16&quot;&gt;는 전혀 다른 의미다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3187&quot; data-start=&quot;3120&quot; data-ke-size=&quot;size16&quot;&gt;첫 번째는 현재 코드에서 개선할 부분을 이야기하지만, 두 번째는 코드가 아니라 작성자 자체를 평가하는 표현이 되어버린다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3231&quot; data-start=&quot;3189&quot; data-ke-size=&quot;size16&quot;&gt;코드 리뷰에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;사람이 아니라 코드와 문제에 초점을 맞춰야 한다는 것&lt;/b&gt;.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3285&quot; data-start=&quot;3233&quot; data-ke-size=&quot;size16&quot;&gt;당연한 이야기처럼 보이지만 실제 협업에서는 오히려 가장 놓치기 쉬운 부분이라는 생각이 들었다.&lt;/p&gt;
&lt;hr data-end=&quot;3290&quot; data-start=&quot;3287&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3327&quot; data-start=&quot;3292&quot; data-section-id=&quot;phmxa8&quot; data-ke-size=&quot;size26&quot;&gt;좋은 리뷰 코멘트는 &amp;lsquo;정답을 알려주는 것&amp;rsquo;과도 조금 다르다&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3378&quot; data-start=&quot;3329&quot; data-ke-size=&quot;size16&quot;&gt;책을 읽으면서 계속 등장하는 키워드 중 하나가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;상대방의 상황을 고려하는 것&lt;/b&gt;이었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3407&quot; data-start=&quot;3380&quot; data-ke-size=&quot;size16&quot;&gt;리뷰어가 자신의 방식이 무조건 정답이라고 생각하고&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3420&quot; data-start=&quot;3409&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이렇게 바꾸세요.&amp;rdquo;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3432&quot; data-start=&quot;3422&quot; data-ke-size=&quot;size16&quot;&gt;라고 말하는 것과,&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3481&quot; data-start=&quot;3434&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이 부분은 이러한 문제가 발생할 수 있는데, 이런 방법을 사용하는 것은 어떨까요?&amp;rdquo;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3527&quot; data-start=&quot;3483&quot; data-ke-size=&quot;size16&quot;&gt;라고 이야기하는 것은 같은 내용을 전달하더라도 받아들이는 느낌이 상당히 다르다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3554&quot; data-start=&quot;3529&quot; data-ke-size=&quot;size16&quot;&gt;또 리뷰 코멘트의 목적도 구분할 필요가 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3616&quot; data-start=&quot;3556&quot; data-ke-size=&quot;size16&quot;&gt;단순한 질문인지,&lt;br /&gt;수정을 요청하는 것인지,&lt;br /&gt;참고로 전달하는 것인지,&lt;br /&gt;반드시 해결해야 하는 문제인지&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3656&quot; data-start=&quot;3618&quot; data-ke-size=&quot;size16&quot;&gt;명확하게 표현하면 리뷰를 받는 사람 역시 훨씬 쉽게 대응할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3728&quot; data-start=&quot;3658&quot; data-ke-size=&quot;size16&quot;&gt;결국 좋은 코드 리뷰는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;내가 하고 싶은 말을 쓰는 것이 아니라 상대방이 이해할 수 있도록 쓰는 것&lt;/b&gt;이라는 생각이 들었다.&lt;/p&gt;
&lt;hr data-end=&quot;3733&quot; data-start=&quot;3730&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3763&quot; data-start=&quot;3735&quot; data-section-id=&quot;hzpzey&quot; data-ke-size=&quot;size26&quot;&gt;19가지 사례 + 33가지 팁이라 읽기 편하다&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3812&quot; data-start=&quot;3765&quot; data-ke-size=&quot;size16&quot;&gt;이 책에서 마음에 들었던 부분은 내용이 지나치게 이론적으로 흘러가지 않는다는 점이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3891&quot; data-start=&quot;3814&quot; data-ke-size=&quot;size16&quot;&gt;PART 2에서는 실제 사례를 통해 문제 상황과 개선 방법을 보여주고, PART 3에서는 조금 더 짧게 활용할 수 있는 팁들을 정리해준다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;3914&quot; data-start=&quot;3893&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 목차에 있는 팁을 살펴보면,&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4033&quot; data-start=&quot;3916&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;커밋을 나누는 방법, 영향 범위 확인, 상대방의 의도를 단정하지 않는 법, Linter 활용, 리뷰 요청 방법, 질문하는 방법, 효과적으로 재촉하는 방법&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;등 실제 개발 업무에서 사용할 만한 주제가 많다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4128&quot; data-start=&quot;4035&quot; data-ke-size=&quot;size16&quot;&gt;그래서 처음부터 끝까지 순서대로 읽어도 되지만, 나중에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;코드 리뷰를 하다가 고민되는 상황이 생겼을 때 필요한 부분만 찾아보는 식으로 활용해도 괜찮을 것 같다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;4133&quot; data-start=&quot;4130&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4160&quot; data-start=&quot;4135&quot; data-section-id=&quot;1vsh84i&quot; data-ke-size=&quot;size26&quot;&gt;기술보다 사람 이야기가 더 많은 개발 책&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_3566.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lDGOV/dJMcaiyeG9Z/UG20UoO9fIGZgzoRBYAOE1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lDGOV/dJMcaiyeG9Z/UG20UoO9fIGZgzoRBYAOE1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lDGOV/dJMcaiyeG9Z/UG20UoO9fIGZgzoRBYAOE1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlDGOV%2FdJMcaiyeG9Z%2FUG20UoO9fIGZgzoRBYAOE1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot; data-filename=&quot;IMG_3566.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4224&quot; data-start=&quot;4185&quot; data-ke-size=&quot;size16&quot;&gt;여러 저자의 실제 개발 및 팀 협업 경험을 바탕으로 작성된 책이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4282&quot; data-start=&quot;4226&quot; data-ke-size=&quot;size16&quot;&gt;저자 소개를 보면 실제 개발자와 개발 조직에서의 경험을 바탕으로 책이 작성되었다는 점도 알 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4297&quot; data-start=&quot;4284&quot; data-ke-size=&quot;size16&quot;&gt;그래서인지 책을 읽으면서&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4319&quot; data-start=&quot;4299&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이론적으로는 이렇게 해야 합니다.&amp;rdquo;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4335&quot; data-start=&quot;4321&quot; data-ke-size=&quot;size16&quot;&gt;라고 이야기하는 느낌보다는&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4383&quot; data-start=&quot;4337&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;실제로 팀에서 이런 일이 발생하는데, 이런 방식으로 해결해보면 어떨까요?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4402&quot; data-start=&quot;4385&quot; data-ke-size=&quot;size16&quot;&gt;라고 이야기하는 느낌이 강했다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4498&quot; data-start=&quot;4404&quot; data-ke-size=&quot;size16&quot;&gt;특히 개발 경력이 많지 않거나 아직 코드 리뷰를 많이 경험해보지 않은 개발자라면, 실제 회사에서 어떤 방식으로 리뷰가 진행되는지 간접적으로 경험해보기에도 괜찮아 보였다.&lt;/p&gt;
&lt;hr data-end=&quot;4503&quot; data-start=&quot;4500&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4525&quot; data-start=&quot;4505&quot; data-section-id=&quot;1rut96m&quot; data-ke-size=&quot;size26&quot;&gt;이런 사람에게 추천하고 싶은 책&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4618&quot; data-start=&quot;4527&quot; data-ke-size=&quot;size16&quot;&gt;개인적으로는 코딩 테스트나 프로그래밍 문법을 공부하기 위한 책이라기보다&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;협업 개발을 준비하거나 실제 팀 개발을 시작한 사람에게 더 잘 맞는 책&lt;/b&gt;이라고 느꼈다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4749&quot; data-start=&quot;4620&quot; data-ke-size=&quot;size16&quot;&gt;특히 Git과 GitHub를 이용해서 PR을 만들어보기 시작했거나, 회사에서 다른 개발자의 코드를 리뷰해야 하는 사람, 반대로 리뷰를 받을 때 코멘트를 어떻게 받아들이고 대응해야 할지 고민되는 사람에게 도움이 될 만한 내용이 많다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4781&quot; data-start=&quot;4751&quot; data-ke-size=&quot;size16&quot;&gt;그리고 의외로 개발자가 아니더라도 공감할 부분이 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4795&quot; data-start=&quot;4783&quot; data-ke-size=&quot;size16&quot;&gt;책의 많은 내용이 결국&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4852&quot; data-start=&quot;4797&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;질문하는 법, 의견을 전달하는 법, 상대방의 의도를 단정하지 않는 법, 피드백을 주고받는 법&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4870&quot; data-start=&quot;4854&quot; data-ke-size=&quot;size16&quot;&gt;에 관한 이야기이기 때문이다.&lt;/p&gt;
&lt;hr data-end=&quot;4875&quot; data-start=&quot;4872&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4885&quot; data-start=&quot;4877&quot; data-section-id=&quot;1c6v4zg&quot; data-ke-size=&quot;size26&quot;&gt;읽고 나서&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_3563.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/tpcRI/dJMcagHdYz2/ObK80Z3nLBctOHZFfsKiKk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/tpcRI/dJMcagHdYz2/ObK80Z3nLBctOHZFfsKiKk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/tpcRI/dJMcagHdYz2/ObK80Z3nLBctOHZFfsKiKk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtpcRI%2FdJMcagHdYz2%2FObK80Z3nLBctOHZFfsKiKk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot; data-filename=&quot;IMG_3563.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4962&quot; data-start=&quot;4910&quot; data-ke-size=&quot;size16&quot;&gt;코드 리뷰의 핵심은 결국 &amp;lsquo;코드&amp;rsquo;와 &amp;lsquo;사람&amp;rsquo; 사이에서 균형을 잡는 것이라는 생각이 들었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;4992&quot; data-start=&quot;4964&quot; data-ke-size=&quot;size16&quot;&gt;이 책을 읽기 전에는 코드 리뷰라고 하면 자연스럽게&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;5020&quot; data-start=&quot;4994&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;잘못된 코드를 찾아내고 수정하는 과정&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;5042&quot; data-start=&quot;5022&quot; data-ke-size=&quot;size16&quot;&gt;이라는 이미지가 가장 먼저 떠올랐다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;5069&quot; data-start=&quot;5044&quot; data-ke-size=&quot;size16&quot;&gt;하지만 읽고 난 뒤에는 조금 다르게 느껴졌다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;5164&quot; data-start=&quot;5071&quot; data-ke-size=&quot;size16&quot;&gt;코드 리뷰는 단순히 오류를 찾는 과정이 아니라&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;한 사람이 작성한 코드를 팀 전체가 이해하고, 더 나은 방향으로 발전시키기 위한 커뮤니케이션 과정&lt;/b&gt;에 더 가깝다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;5229&quot; data-start=&quot;5166&quot; data-ke-size=&quot;size16&quot;&gt;좋은 리뷰어가 되기 위해서는 코드를 많이 아는 것도 중요하지만, 자신의 생각을 정확하게 설명하는 능력도 필요하다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;5321&quot; data-start=&quot;5231&quot; data-ke-size=&quot;size16&quot;&gt;그리고 리뷰를 받는 입장에서도 단순히 지적을 받았다고 생각하는 것이 아니라&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;왜 이런 의견이 나왔는지 이해하고 필요한 정보를 다시 전달하는 능력&lt;/b&gt;이 필요하다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;5386&quot; data-start=&quot;5323&quot; data-ke-size=&quot;size16&quot;&gt;결국 개발을 잘한다는 것은 단순히 코드를 잘 작성하는 것만을 의미하지 않는다는 점을 다시 생각해보게 된 책이었다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;5468&quot; data-start=&quot;5388&quot; data-ke-size=&quot;size16&quot;&gt;코드 작성 방법은 공부하고 있었지만&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;&amp;lsquo;코드에 대해 어떻게 이야기해야 하는지&amp;rsquo;는 따로 생각해본 적이 없었다면 한 번 읽어볼 만한 책&lt;/b&gt;이다.&lt;/p&gt;
&lt;hr data-end=&quot;5473&quot; data-start=&quot;5470&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;IMG_3559.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vBPME/dJMcaf2pDfg/ciTbnr2WVkI5EfCHzOkkAk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vBPME/dJMcaf2pDfg/ciTbnr2WVkI5EfCHzOkkAk/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vBPME/dJMcaf2pDfg/ciTbnr2WVkI5EfCHzOkkAk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvBPME%2FdJMcaf2pDfg%2FciTbnr2WVkI5EfCHzOkkAk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;2048&quot; data-filename=&quot;IMG_3559.jpg&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;2048&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;5554&quot; data-start=&quot;5507&quot; data-ke-size=&quot;size16&quot;&gt;좋은 코드를 만드는 것만큼, 좋은 방식으로 코드에 대해 이야기하는 것도 중요하다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;5565&quot; data-start=&quot;5556&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;한 줄 평&lt;/b&gt;&lt;/p&gt;
&lt;blockquote style=&quot;color: #000000; text-align: start;&quot; data-end=&quot;5622&quot; data-start=&quot;5567&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;5622&quot; data-start=&quot;5569&quot; data-ke-size=&quot;size16&quot;&gt;좋은 코드 리뷰는 상대방의 틀린 점을 찾는 것이 아니라, 함께 더 나은 답을 찾아가는 과정이다.&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>책</category>
      <category>길벗출판사 #좋은코드리뷰 나쁜코드리뷰 #책 #개발자 #it</category>
      <category>협찬 #</category>
      <author>잼coding</author>
      <guid isPermaLink="true">https://jamin0619.tistory.com/27</guid>
      <comments>https://jamin0619.tistory.com/27#entry27comment</comments>
      <pubDate>Tue, 22 Sep 2026 20:40:41 +0900</pubDate>
    </item>
    <item>
      <title>JavaScript 심화 ① Truthy&amp;middot;Falsy, 단락 평가, 구조 분해 할당, Spread와 Rest</title>
      <link>https://jamin0619.tistory.com/26</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript 기본 문법을 어느 정도 공부하고 이제 조금 더 심화된 문법을 정리해본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 조건문을 더욱 간결하게 사용할 수 있게 해주는 &lt;b&gt;Truthy와 Falsy&lt;/b&gt;, 논리 연산자의 특성을 활용하는 &lt;b&gt;단락 평가&lt;/b&gt;, 배열과 객체에서 원하는 값을 편리하게 꺼낼 수 있는 &lt;b&gt;구조 분해 할당&lt;/b&gt;, 그리고 데이터를 펼치거나 모으는 &lt;b&gt;Spread와 Rest 문법&lt;/b&gt;에 대해 정리한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;1. Truthy와 Falsy&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 Boolean 타입인 true, false뿐만 아니라 다른 자료형의 값도 조건문 안에서 참 또는 거짓처럼 평가될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 참으로 평가되는 값을 &lt;b&gt;Truthy&lt;/b&gt;, 거짓으로 평가되는 값을 &lt;b&gt;Falsy&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같은 코드를 작성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;if (&quot;hello&quot;) {
    console.log(&quot;실행됩니다.&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;hello&quot;는 Boolean 타입이 아니라 문자열이지만 JavaScript에서는 참으로 평가된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 조건문 내부의 코드가 실행된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;2. Falsy한 값&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서 거짓으로 평가되는 대표적인 값은 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let f1 = undefined;

let f2 = null;

let f3 = 0;

let f4 = -0;

let f5 = NaN;

let f6 = &quot;&quot;;

let f7 = 0n;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 값들을 조건문에서 사용하면 모두 false처럼 처리된다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;if (0) {
    console.log(&quot;실행&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;0은 Falsy한 값이기 때문에 해당 코드는 실행되지 않는다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;대표적인 Falsy 값&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;값의미&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;undefined&lt;/td&gt;
&lt;td&gt;값이 할당되지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;의도적으로 값이 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;td&gt;숫자 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-0&lt;/td&gt;
&lt;td&gt;음의 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NaN&lt;/td&gt;
&lt;td&gt;숫자가 아님&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&quot;&quot;&lt;/td&gt;
&lt;td&gt;빈 문자열&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0n&lt;/td&gt;
&lt;td&gt;BigInt의 0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가로 Boolean 값인 false 자체도 당연히 Falsy이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 실질적으로는 다음과 같이 이해하면 된다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;false
undefined
null
0
-0
NaN
&quot;&quot;
0n
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 값들은 조건식에서 모두 거짓으로 평가된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;3. Truthy한 값&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Falsy한 값을 제외한 대부분의 값은 Truthy한 값으로 평가된다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let t1 = &quot;hello&quot;;

let t2 = 123;

let t3 = [];

let t4 = {};

let t5 = () =&amp;gt; {};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 처음 보면 헷갈릴 수 있는 부분이 배열과 객체이다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;[];

{};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;빈 배열과 빈 객체라고 하더라도 JavaScript에서는 Truthy한 값이다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;if ([]) {
    console.log(&quot;실행됩니다.&quot;);
}

if ({}) {
    console.log(&quot;이것도 실행됩니다.&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;둘 다 조건문 내부가 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;빈 문자열 &quot;&quot; &amp;rarr; Falsy

빈 배열 [] &amp;rarr; Truthy
빈 객체 {} &amp;rarr; Truthy
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라는 차이를 기억할 필요가 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;4. Truthy와 Falsy 활용&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Truthy와 Falsy는 값이 존재하는지 검사할 때 유용하게 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 함수가 있다고 해보자.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function printName(person) {

    if (person === undefined) {
        console.log(&quot;person의 값이 없음&quot;);
        return;
    }

    console.log(person.name);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용해보면&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;let person = {
    name: &quot;정재민&quot;
};

printName(person);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 출력된다.&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;정재민
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 person에 값을 전달하지 않는다면&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;printName();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;undefined가 전달되므로&lt;/p&gt;
&lt;pre class=&quot;inform7&quot;&gt;&lt;code&gt;person의 값이 없음
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 출력된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;5. Truthy/Falsy를 활용한 코드 간소화&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞의 코드는 다음과 같이 조금 더 간단하게 작성할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function printName(person) {

    if (!person) {
        console.log(&quot;person의 값이 없음&quot;);
        return;
    }

    console.log(person.name);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;person이 undefined, null 등 Falsy한 값이라면&lt;/p&gt;
&lt;pre class=&quot;diff&quot;&gt;&lt;code&gt;!person
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은 true가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 별도로&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;person === undefined
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처럼 비교하지 않아도 값의 존재 여부를 검사할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 여기에는 주의할 점도 있다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;0
&quot;&quot;
false
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 값도 Falsy로 처리되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &lt;b&gt;정말 undefined만 검사해야 하는 상황이라면 명시적인 비교가 더 적절할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;6. 단락 평가&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단락 평가(Short-Circuit Evaluation)는 논리 연산자 &amp;amp;&amp;amp;, ||를 평가할 때 &lt;b&gt;결과가 이미 결정되었다면 뒤쪽 표현식을 실행하지 않는 특성&lt;/b&gt;을 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 다음 코드를 보자.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;true || false
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OR 연산자는 둘 중 하나만 true여도 결과가 true이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 값이 이미 true이므로 뒤의 값을 확인하지 않아도 최종 결과는 true라는 것을 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 JavaScript는 뒤의 표현식을 평가하지 않을 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;7. OR 연산자의 단락 평가&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 함수를 만들어보자.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function returnFalse() {

    console.log(&quot;False 함수&quot;);

    return false;
}

function returnTrue() {

    console.log(&quot;True 함수&quot;);

    return true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 다음과 같이 실행한다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(returnTrue() || returnFalse());
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 returnTrue()가 실행된다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;True 함수
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 true를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OR 연산자는 이미 첫 번째 값이 Truthy이므로 결과가 결정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 뒤쪽의&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;returnFalse()
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;는 실행하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과적으로&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;True 함수
true
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만 출력된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;8. AND 연산자의 단락 평가&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;amp;&amp;amp; 연산자도 비슷하게 동작한다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;false &amp;amp;&amp;amp; true
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AND 연산자는 두 값이 모두 참이어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 값이 이미 false라면 결과는 무조건 false이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 두 번째 값은 확인하지 않아도 된다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function returnFalse() {

    console.log(&quot;False 함수&quot;);

    return false;
}

function returnTrue() {

    console.log(&quot;True 함수&quot;);

    return true;
}

console.log(returnFalse() &amp;amp;&amp;amp; returnTrue());
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행하면 returnFalse()에서 이미 결과가 결정되기 때문에 returnTrue()는 실행되지 않는다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;9. &amp;amp;&amp;amp;는 값을 선택하는 데도 사용할 수 있다&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;논리 연산자는 꼭 Boolean 값만 반환하는 것은 아니다.&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;let result = &quot;hello&quot; &amp;amp;&amp;amp; &quot;world&quot;;

console.log(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;world
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;hello&quot;는 Truthy한 값이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 &amp;amp;&amp;amp;는 오른쪽 값까지 확인하고 &quot;world&quot;를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let result = null &amp;amp;&amp;amp; &quot;world&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에서는 첫 번째 값 null이 Falsy이므로 바로 null이 반환된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;A &amp;amp;&amp;amp; B
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에서&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A가 Falsy &amp;rarr; A 반환&lt;/li&gt;
&lt;li&gt;A가 Truthy &amp;rarr; B 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이라고 이해할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;10. || 역시 값을 선택할 수 있다&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;||도 비슷하게 동작한다.&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;let result = &quot;hello&quot; || &quot;world&quot;;

console.log(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;hello
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 값 &quot;hello&quot;가 Truthy이므로 뒤쪽 값을 확인하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;let result = undefined || &quot;world&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에서는 첫 번째 값이 Falsy이므로 &quot;world&quot;가 반환된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;A || B
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;는&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;A가 Truthy &amp;rarr; A 반환&lt;/li&gt;
&lt;li&gt;A가 Falsy &amp;rarr; B 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이라고 볼 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;11. 단락 평가 활용&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 특징을 이용하면 코드를 상당히 간결하게 작성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;fortran&quot;&gt;&lt;code&gt;function printName(person) {

    const name = person &amp;amp;&amp;amp; person.name;

    console.log(name || &quot;person의 값이 없음&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 다음 코드를 보자.&lt;/p&gt;
&lt;pre class=&quot;delphi&quot;&gt;&lt;code&gt;const name = person &amp;amp;&amp;amp; person.name;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 person이 존재하지 않는다면&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;undefined &amp;amp;&amp;amp; person.name
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;형태가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 값이 Falsy이므로 뒤쪽의 person.name을 확인하지 않고 바로 undefined가 반환된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 존재하지 않는 객체의 프로퍼티에 접근하면서 발생할 수 있는 오류를 피할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;person이 없는 경우&lt;/h2&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;printName();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;person은 undefined이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서&lt;/p&gt;
&lt;pre class=&quot;delphi&quot;&gt;&lt;code&gt;const name = person &amp;amp;&amp;amp; person.name;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;의 결과는 undefined가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;name || &quot;person의 값이 없음&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에서 name이 Falsy이므로 다음 문자열이 반환된다.&lt;/p&gt;
&lt;pre class=&quot;inform7&quot;&gt;&lt;code&gt;person의 값이 없음
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;person이 존재하는 경우&lt;/h2&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;printName({
    name: &quot;정재민&quot;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;person이 Truthy이므로&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;person.name
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;까지 평가한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 name에는&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;정재민
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 저장된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;name || &quot;person의 값이 없음&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에서 name이 Truthy이므로 &quot;정재민&quot;이 출력된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;12. 단락 평가와 Optional Chaining&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 JavaScript에서는 객체의 값이 존재하는지 검사할 때 Optional Chaining도 많이 사용한다.&lt;/p&gt;
&lt;pre class=&quot;delphi&quot;&gt;&lt;code&gt;const name = person?.name;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;person이 null 또는 undefined이면 오류를 발생시키지 않고 undefined를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 앞의 코드는 다음처럼 더욱 간결하게 작성할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;fortran&quot;&gt;&lt;code&gt;function printName(person) {

    const name = person?.name;

    console.log(name || &quot;person의 값이 없음&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Optional Chaining은 이후 객체 심화 문법에서 다시 자세히 정리하면 좋을 것 같다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;13. 구조 분해 할당&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조 분해 할당(Destructuring Assignment)은 배열이나 객체에 저장되어 있는 여러 값을 &lt;b&gt;각각의 변수로 쉽게 꺼내는 문법&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서 배열이나 객체를 많이 다루다 보니 실제 개발에서도 자주 사용된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;14. 배열 구조 분해 할당&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 배열이 있다고 해보자.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr = [1, 2, 3];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 방식으로 값을 각각 변수에 저장한다면 다음처럼 작성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;let one = arr[0];
let two = arr[1];
let three = arr[2];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조 분해 할당을 사용하면 한 줄로 작성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;let [one, two, three] = arr;

console.log(one, two, three);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;basic&quot;&gt;&lt;code&gt;1 2 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열의 순서대로 각각의 변수에 값이 할당된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;15. 배열 구조 분해 할당의 기본값&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열보다 더 많은 변수를 선언하면 존재하지 않는 값에는 undefined가 들어간다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr = [1, 2, 3];

let [one, two, three, four] = arr;

console.log(four);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;undefined
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이때 기본값을 지정할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;let [one, two, three, four = 4] = arr;

console.log(four);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;4
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열에 해당 값이 존재하지 않을 경우 기본값인 4가 사용된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;16. 구조 분해 할당으로 변수 교환하기&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조 분해 할당을 이용하면 두 변수의 값을 쉽게 교환할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;let a = 10;

let b = 20;

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

console.log(a, b);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;basic&quot;&gt;&lt;code&gt;20 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;별도의 임시 변수를 만들지 않아도 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;17. 객체 구조 분해 할당&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체에서도 구조 분해 할당을 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;let person = {

    name: &quot;정재민&quot;,

    age: 27,

    hobby: &quot;테니스&quot;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 방식이라면&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;let name = person.name;

let age = person.age;

let hobby = person.hobby;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처럼 작성해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조 분해 할당을 사용하면 다음과 같이 작성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;autohotkey&quot;&gt;&lt;code&gt;let {
    name,
    age,
    hobby
} = person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 각각의 변수를 바로 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;console.log(name, age, hobby);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;정재민 27 테니스
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;18. 배열과 객체 구조 분해의 차이&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열에서는 &lt;b&gt;순서&lt;/b&gt;가 중요하다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr = [1, 2, 3];

let [a, b, c] = arr;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 객체에서는 &lt;b&gt;프로퍼티 이름&lt;/b&gt;을 기준으로 값을 찾는다.&lt;/p&gt;
&lt;pre class=&quot;xquery&quot;&gt;&lt;code&gt;let person = {
    name: &quot;정재민&quot;,
    age: 27
};

let {
    age,
    name
} = person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;순서를 바꾸더라도 정상적으로 값을 가져올 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;배열 구조 분해 &amp;rarr; 위치 기준

객체 구조 분해 &amp;rarr; 프로퍼티 이름 기준
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;19. 객체 구조 분해하면서 변수 이름 변경하기&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체의 프로퍼티 이름과 다른 변수명을 사용하고 싶을 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 작성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;let person = {

    name: &quot;정재민&quot;,

    age: 27,

    hobby: &quot;테니스&quot;
};

let {
    name,
    age: myAge,
    hobby
} = person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에서&lt;/p&gt;
&lt;pre class=&quot;avrasm&quot;&gt;&lt;code&gt;age: myAge
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;는 age라는 프로퍼티의 값을 myAge라는 변수에 저장한다는 의미이다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(myAge);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;27
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 경우 age라는 변수가 만들어지는 것이 아니라 myAge가 만들어진다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;20. 함수 매개변수에서 구조 분해 할당&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 구조 분해 할당은 함수의 매개변수에서도 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;autoit&quot;&gt;&lt;code&gt;const func = ({ name, age, hobby }) =&amp;gt; {

    console.log(name, age, hobby);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체를 전달해보면&lt;/p&gt;
&lt;pre class=&quot;autoit&quot;&gt;&lt;code&gt;func(person);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 내부에서 바로 name, age, hobby를 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 방식이라면&lt;/p&gt;
&lt;pre class=&quot;autoit&quot;&gt;&lt;code&gt;const func = (person) =&amp;gt; {

    console.log(person.name);

    console.log(person.age);

    console.log(person.hobby);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처럼 반복해서 person.을 작성해야 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조 분해 할당을 사용하면 코드를 조금 더 간결하게 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React를 공부하다 보면 컴포넌트의 props를 받을 때 이러한 문법을 매우 자주 사용하게 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;21. Spread 연산자&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spread는 영어로 &lt;b&gt;펼치다, 흩뿌리다&lt;/b&gt;라는 의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript의 Spread 문법은 배열이나 객체에 저장되어 있는 여러 값을 &lt;b&gt;개별 값으로 펼쳐주는 역할&lt;/b&gt;을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문법은 점 세 개를 사용한다.&lt;/p&gt;
&lt;pre class=&quot;asciidoc&quot;&gt;&lt;code&gt;...
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;22. 배열에서 Spread 사용하기&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 배열이 있다고 해보자.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr1 = [1, 2, 3];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;arr1의 값을 다른 배열 중간에 넣고 싶다면 Spread를 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr2 = [4, ...arr1, 5, 6];

console.log(arr2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[4, 1, 2, 3, 5, 6]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;...arr1이 배열 내부의 값들을 각각 펼쳐준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[4, ...arr1, 5, 6]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;은 사실상 다음과 비슷하다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[4, 1, 2, 3, 5, 6]
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;23. 배열 복사에도 활용&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spread를 이용하면 기존 배열을 이용해 새로운 배열을 만들 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let arr1 = [1, 2, 3];

let arr2 = [...arr1];

console.log(arr2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;겉으로는 같은 값을 가지고 있지만 서로 다른 배열이다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(arr1 === arr2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;false
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체와 배열은 참조형 데이터이기 때문에 이런 방식은 React에서 상태를 변경할 때도 중요하게 사용된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;24. 객체에서 Spread 사용하기&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체에서도 Spread 문법을 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;let obj1 = {

    a: 1,

    b: 2
};

let obj2 = {

    ...obj1,

    c: 3
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력하면&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(obj2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 객체가 만들어진다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;{
    a: 1,
    b: 2,
    c: 3
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;25. Spread와 같은 프로퍼티 이름&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 코드를 보자.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;let obj1 = {

    a: 1,

    b: 2
};

let obj2 = {

    ...obj1,

    c: 3,

    b: 4
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과는&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;{
    a: 1,
    b: 4,
    c: 3
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;...obj1을 통해 먼저&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;b: 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 들어갔지만 뒤에서&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;b: 4
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;를 다시 작성했기 때문에 나중에 작성한 값으로 덮어씌워진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;객체에서는 뒤에 작성된 프로퍼티가 우선된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 특징은 객체를 복사하면서 일부 값만 수정할 때 매우 유용하다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;const user = {

    name: &quot;정재민&quot;,

    age: 27,

    job: &quot;ERP Developer&quot;
};

const updatedUser = {

    ...user,

    age: 28
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 값은 유지하면서 age만 변경할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;26. 함수 호출에서 Spread 사용하기&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수의 인수로도 Spread 문법을 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;function funcA(p1, p2, p3) {

    console.log(p1, p2, p3);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열이 있다고 해보자.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr1 = [1, 2, 3];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 다음과 같이 전달할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;funcA(arr1[0], arr1[1], arr1[2]);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spread를 이용하면 훨씬 간단하다.&lt;/p&gt;
&lt;pre class=&quot;gams&quot;&gt;&lt;code&gt;funcA(...arr1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로는 다음과 같이 전달되는 것과 같다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;funcA(1, 2, 3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;basic&quot;&gt;&lt;code&gt;1 2 3
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;27. Rest 매개변수&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spread와 비슷하게 점 세 개 ...를 사용하는 문법으로 &lt;b&gt;Rest Parameter&lt;/b&gt;가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rest는 영어로 &lt;b&gt;나머지&lt;/b&gt;라는 뜻이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수에 전달된 여러 개의 인수 중 나머지 값들을 하나의 배열로 모으는 역할을 한다.&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;function funcB(one, two, ...rest) {

    console.log(rest);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같이 호출해보자.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;funcB(1, 2, 3, 4, 5);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;one에는&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 들어가고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;two에는&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;2
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나머지 값은 모두 rest 배열에 들어간다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[3, 4, 5]
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;28. Spread와 Rest의 차이&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 문법 모두 ...을 사용해서 처음에는 상당히 헷갈릴 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 역할은 반대라고 생각하면 이해하기 쉽다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Spread&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나로 묶여 있는 값을 &lt;b&gt;펼친다.&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr = [1, 2, 3];

funcA(...arr);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동작&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;[1, 2, 3]

&amp;darr; 펼치기

1, 2, 3
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Rest&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 값을 &lt;b&gt;하나의 배열로 모은다.&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;function funcB(...rest) {

    console.log(rest);
}

funcB(1, 2, 3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동작&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1, 2, 3

&amp;darr; 모으기

[1, 2, 3]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;Spread &amp;rarr; 펼치기

Rest &amp;rarr; 모으기
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 기억하면 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;29. Rest 매개변수의 위치&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rest 매개변수는 항상 &lt;b&gt;마지막에 위치해야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 코드는 정상적이다.&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;function func(one, two, ...rest) {

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 다음처럼 작성할 수는 없다.&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;// 오류

function func(...rest, one) {

}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rest는 말 그대로 &lt;b&gt;나머지 모든 인수&lt;/b&gt;를 가져오기 때문에 이후에 다른 매개변수가 존재할 수 없다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;한 번에 이해하기&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 내용을 간단한 흐름으로 정리하면 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;const person = {

    name: &quot;정재민&quot;,

    age: 27,

    hobby: &quot;테니스&quot;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체에서 값을 꺼낼 때는 구조 분해 할당을 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;const {
    name,
    age
} = person;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체를 복사하면서 값을 추가하려면 Spread를 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;cos&quot;&gt;&lt;code&gt;const newPerson = {

    ...person,

    job: &quot;ERP Developer&quot;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수에서 필요한 프로퍼티만 바로 받아올 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const introduce = ({ name, job }) =&amp;gt; {

    console.log(`${name}의 직업은 ${job}입니다.`);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 인수를 함수에서 한꺼번에 받고 싶다면 Rest를 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;const printAll = (...values) =&amp;gt; {

    console.log(values);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 이런 문법들을 조합해서 사용하는 경우가 많다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;정리&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개념설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Falsy&lt;/td&gt;
&lt;td&gt;조건식에서 false로 평가되는 값&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Truthy&lt;/td&gt;
&lt;td&gt;조건식에서 true로 평가되는 값&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;단락 평가&lt;/td&gt;
&lt;td&gt;결과가 정해지면 뒤의 연산을 실행하지 않는 특성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A &amp;amp;&amp;amp; B&lt;/td&gt;
&lt;td&gt;A가 Truthy이면 B까지 평가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A || B&lt;/td&gt;
&lt;td&gt;A가 Falsy이면 B를 평가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;구조 분해 할당&lt;/td&gt;
&lt;td&gt;배열이나 객체의 값을 각각 변수로 꺼내는 문법&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Spread&lt;/td&gt;
&lt;td&gt;배열이나 객체의 값을 펼치는 문법&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rest&lt;/td&gt;
&lt;td&gt;여러 값을 하나의 배열로 모으는 문법&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 내용은 단순 문법이라기보다 &lt;b&gt;앞으로 실제 JavaScript와 React 코드를 읽기 위해 반드시 익숙해져야 하는 문법&lt;/b&gt;에 가깝다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 다음과 같은 코드는 React를 공부하면 굉장히 자주 보게 될 것 같다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;const User = ({ name, age }) =&amp;gt; {

    const user = {

        name,

        age
    };

    const newUser = {

        ...user,

        job: &quot;Developer&quot;
    };

    return newUser;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 기호가 많아서 복잡해 보이지만 결국&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;값을 확인하고 &amp;rarr; 필요한 값만 꺼내고 &amp;rarr; 데이터를 펼치거나 모으는 과정&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이라고 생각하면 조금 더 쉽게 이해할 수 있다.&lt;/p&gt;</description>
      <category>개발/Javascript</category>
      <author>잼coding</author>
      <guid isPermaLink="true">https://jamin0619.tistory.com/26</guid>
      <comments>https://jamin0619.tistory.com/26#entry26comment</comments>
      <pubDate>Thu, 17 Sep 2026 09:48:38 +0900</pubDate>
    </item>
    <item>
      <title>JavaScript 기초 정리 ③ 콜백 함수, 스코프, 객체, 배열</title>
      <link>https://jamin0619.tistory.com/25</link>
      <description>&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript 기본 문법 세 번째 정리.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 함수를 조금 더 활용하는 방법인 &lt;b&gt;콜백 함수&lt;/b&gt;부터 시작해서, 변수의 접근 범위를 결정하는 &lt;b&gt;스코프&lt;/b&gt;, 여러 데이터를 하나로 묶어 관리하는 &lt;b&gt;객체와 배열&lt;/b&gt;에 대해 정리한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;1. 콜백 함수&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콜백 함수(Callback Function)는 &lt;b&gt;다른 함수의 인수로 전달되는 함수&lt;/b&gt;를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 함수도 하나의 값처럼 사용할 수 있기 때문에 다른 함수에 전달할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같은 함수가 있다고 해보자.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function main(value) {
    console.log(value);
}

function sub() {
    console.log(&quot;I am sub&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;sub라는 함수를 main 함수에 전달할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;perl&quot;&gt;&lt;code&gt;main(sub);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 sub는 함수의 실행 결과가 아니라 &lt;b&gt;함수 자체가 전달되는 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;sub
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;와&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;sub()
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;는 의미가 다르다.&lt;/p&gt;
&lt;pre class=&quot;gcode&quot;&gt;&lt;code&gt;sub   &amp;rarr; 함수 자체
sub() &amp;rarr; 함수를 즉시 실행
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;2. 콜백 함수 활용&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콜백 함수는 특정 작업을 수행한 뒤 &lt;b&gt;어떤 동작을 실행할지 외부에서 전달하고 싶을 때&lt;/b&gt; 유용하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 반복 작업을 수행하는 함수를 만들어보자.&lt;/p&gt;
&lt;pre class=&quot;fortran&quot;&gt;&lt;code&gt;function repeat(count, callback) {

    for (let idx = 1; idx &amp;lt;= count; idx++) {
        callback(idx);
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;repeat() 함수는 두 개의 값을 전달받는다.&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;count    &amp;rarr; 몇 번 반복할 것인지
callback &amp;rarr; 반복할 때 실행할 함수
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;숫자를 그대로 출력하기&lt;/h2&gt;
&lt;pre class=&quot;lisp&quot;&gt;&lt;code&gt;repeat(5, (idx) =&amp;gt; {
    console.log(idx);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
2
3
4
5
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;repeat() 함수 내부에서 다음 코드가 반복해서 실행된다.&lt;/p&gt;
&lt;pre class=&quot;lisp&quot;&gt;&lt;code&gt;callback(idx);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에 전달한 콜백 함수는&lt;/p&gt;
&lt;pre class=&quot;livescript&quot;&gt;&lt;code&gt;(idx) =&amp;gt; {
    console.log(idx);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이므로 현재 idx 값이 그대로 출력된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;숫자를 두 배로 출력하기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 다른 함수를 전달할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;lua&quot;&gt;&lt;code&gt;repeat(5, function (idx) {
    console.log(idx * 2);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;2
4
6
8
10
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;repeat() 함수 자체는 똑같지만 전달하는 콜백 함수가 달라졌기 때문에 다른 결과를 만들 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 콜백 함수의 핵심은&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공통적인 동작은 그대로 두고, 세부적인 동작만 외부에서 함수로 전달할 수 있다는 것&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이라고 이해할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로 map, filter, forEach, 이벤트 처리, 비동기 작업 등을 공부할 때 콜백 함수가 계속 등장한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;3. 스코프&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스코프(Scope)는 &lt;b&gt;변수나 함수에 접근할 수 있는 범위&lt;/b&gt;를 의미한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 크게 두 가지로 나눌 수 있다.&lt;/p&gt;
&lt;pre class=&quot;coq&quot;&gt;&lt;code&gt;전역 스코프(Global Scope)
지역 스코프(Local Scope)
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;4. 전역 스코프&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수나 블록 바깥에서 선언된 변수는 일반적으로 전역 스코프를 가진다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let a = 1;

function funcA() {
    console.log(a);
}

funcA();

console.log(a);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;a는 함수 밖에서 선언되었기 때문에 함수 내부에서도 사용할 수 있고 바깥에서도 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 전역 변수는 여러 영역에서 접근할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;5. 지역 스코프&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 내부에서 선언된 변수는 해당 함수 내부에서만 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function funcA() {

    let b = 2;

    console.log(b);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;b는 funcA() 내부에서 선언되었기 때문에 함수 내부에서는 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 다음과 같이 함수 밖에서 사용하면 오류가 발생한다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function funcA() {

    let b = 2;
}

console.log(b);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;b는 함수 내부의 지역 변수이기 때문이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;6. 블록 스코프&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;let과 const는 {}를 기준으로 하는 &lt;b&gt;블록 스코프&lt;/b&gt;를 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 if문 안에서 변수를 선언해보자.&lt;/p&gt;
&lt;pre class=&quot;swift&quot;&gt;&lt;code&gt;if (true) {

    let c = 1;

    console.log(c);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;블록 내부에서는 사용할 수 있지만&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(c);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처럼 블록 밖에서는 사용할 수 없다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;for문도 마찬가지&lt;/h2&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;for (let i = 0; i &amp;lt; 10; i++) {

    let d = 1;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;i와 d는 모두 해당 for문의 블록 안에서만 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 바깥에서&lt;/p&gt;
&lt;pre class=&quot;matlab&quot;&gt;&lt;code&gt;console.log(i);
console.log(d);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;를 실행하면 오류가 발생한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하면&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;전역 변수 &amp;rarr; 전체 영역에서 접근 가능

지역 변수 &amp;rarr; 선언된 특정 영역에서만 접근 가능
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 이해할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;7. 객체&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체(Object)는 여러 개의 데이터를 하나로 묶어서 관리할 수 있는 자료형이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 한 사람의 정보를 저장한다고 생각해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이름, 나이, 취미, 직업을 각각 별도의 변수로 관리할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;let name = &quot;정재민&quot;;
let age = 27;
let hobby = &quot;노래듣기&quot;;
let job = &quot;ERP Developer&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 값들은 모두 한 사람에 대한 정보이므로 객체로 묶으면 더 편리하다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;8. 객체 생성&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체를 만드는 방법에는 대표적으로 두 가지가 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;객체 생성자&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let obj1 = new Object();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;객체 리터럴&lt;/h2&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let obj2 = {};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제로 JavaScript에서는 간결한 &lt;b&gt;객체 리터럴 방식&lt;/b&gt;을 훨씬 많이 사용한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;9. 객체 프로퍼티&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 내부에 저장된 각각의 값을 &lt;b&gt;프로퍼티(Property)&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;let person = {

    name: &quot;정재민&quot;,
    age: 27,
    hobby: &quot;노래듣기&quot;,
    job: &quot;ERP Developer&quot;,

    extra: {},

    10: 20,

    &quot;like cat&quot;: true,
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체는 기본적으로 다음과 같은 구조를 가진다.&lt;/p&gt;
&lt;pre class=&quot;q&quot;&gt;&lt;code&gt;key : value
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;name: &quot;정재민&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에서&lt;/p&gt;
&lt;pre class=&quot;fortran&quot;&gt;&lt;code&gt;name     &amp;rarr; 프로퍼티의 key
정재민   &amp;rarr; 프로퍼티의 value
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체에는 문자열이나 숫자뿐만 아니라 다른 객체, 배열, 함수 등 다양한 값을 저장할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;10. 객체 프로퍼티 접근&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 내부의 값에 접근하는 방법은 크게 두 가지이다.&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;점 표기법
괄호 표기법
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;점 표기법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 기본적인 방법이다.&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;let name = person.name;

console.log(name);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;정재민
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 이름 뒤에 .을 붙이고 프로퍼티 이름을 작성한다.&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;person.name
person.age
person.hobby
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;11. 괄호 표기법&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대괄호 []를 이용해서 접근할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;let age = person[&quot;age&quot;];

console.log(age);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;27
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;괄호 표기법에서는 프로퍼티 이름을 문자열로 작성해야 한다.&lt;/p&gt;
&lt;pre class=&quot;inform7&quot;&gt;&lt;code&gt;person[&quot;age&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음처럼 작성하면 의미가 달라진다.&lt;/p&gt;
&lt;pre class=&quot;inform7&quot;&gt;&lt;code&gt;person[age]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript는 age라는 변수가 존재하는지 찾게 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;12. 변수를 이용한 프로퍼티 접근&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;괄호 표기법의 중요한 장점은 &lt;b&gt;변수에 저장된 값을 이용해 프로퍼티에 접근할 수 있다는 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;pre class=&quot;qml&quot;&gt;&lt;code&gt;let property = &quot;hobby&quot;;

let hobby = person[property];

console.log(hobby);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행하면&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;노래듣기
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 출력된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;property 안에 &quot;hobby&quot;라는 문자열이 들어 있기 때문에 사실상 다음과 동일하다.&lt;/p&gt;
&lt;pre class=&quot;inform7&quot;&gt;&lt;code&gt;person[&quot;hobby&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로퍼티 이름이 실행 중에 달라질 수 있는 경우 유용하다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;13. 점 표기법으로 접근할 수 없는 경우&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 프로퍼티가 있다고 해보자.&lt;/p&gt;
&lt;pre class=&quot;smalltalk&quot;&gt;&lt;code&gt;&quot;like cat&quot;: true
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로퍼티 이름에 공백이 있기 때문에 다음처럼 사용할 수 없다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;// person.like cat
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 때는 괄호 표기법을 사용한다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(person[&quot;like cat&quot;]);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;true
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;14. 객체에 새로운 프로퍼티 추가&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript 객체는 생성한 이후에도 새로운 프로퍼티를 추가할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;person.job = &quot;FE Developer&quot;;

person[&quot;favoriteFood&quot;] = &quot;떡볶이&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력해보면 기존 객체에 값이 추가된 것을 확인할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(person);
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;15. 프로퍼티 수정&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 존재하는 프로퍼티에 새로운 값을 대입하면 수정할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;person.job = &quot;Educator&quot;;

person[&quot;favoriteFood&quot;] = &quot;초콜릿&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주의해야 할 점은 &lt;b&gt;JavaScript는 대소문자를 구분한다는 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;person[&quot;favoriteFood&quot;] = &quot;떡볶이&quot;;

person[&quot;favoritefood&quot;] = &quot;초콜릿&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이라고 작성하면 기존 favoriteFood가 수정되는 것이 아니다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;favoriteFood
favoritefood
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;를 서로 다른 프로퍼티로 판단한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 프로퍼티 이름의 대소문자를 정확하게 작성해야 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;16. 프로퍼티 삭제&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체의 프로퍼티를 삭제할 때는 delete 연산자를 사용한다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;delete person.job;

delete person[&quot;favoriteFood&quot;];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삭제 후 객체를 출력하면 해당 프로퍼티가 사라진 것을 확인할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;17. 프로퍼티 존재 여부 확인&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 안에 특정 프로퍼티가 존재하는지 확인할 때는 in 연산자를 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;let result1 = &quot;name&quot; in person;

let result2 = &quot;cat&quot; in person;

console.log(result1);
console.log(result2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;person 객체에는 name 프로퍼티가 있으므로&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;true
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 반환된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 cat이라는 프로퍼티는 존재하지 않으므로&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;false
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 반환된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;in 연산자의 형태는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;&quot;프로퍼티 이름&quot; in 객체
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;18. const로 선언한 객체&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체는 const로 선언하는 경우가 많다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;const animal = {

    type: &quot;고양이&quot;,
    name: &quot;나비&quot;,
    color: &quot;black&quot;,
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;const는 값을 바꿀 수 없다고 배웠지만 객체에서는 조금 주의해서 이해해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 코드는 정상적으로 동작한다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;animal.age = 2;

animal.name = &quot;까망이&quot;;

delete animal.color;

console.log(animal);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 내부의 프로퍼티를 추가하거나 수정하거나 삭제하는 것은 가능하다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;19. const 객체는 왜 수정할 수 있을까?&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;const는 객체 내부를 절대 수정할 수 없다는 의미가 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;변수 자체에 새로운 값을 다시 할당할 수 없다는 의미&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 다음은 가능하다.&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;const animal = {
    name: &quot;나비&quot;
};

animal.name = &quot;까망이&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 객체 자체를 새로운 객체로 교체하는 것은 불가능하다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;const animal = {
    name: &quot;나비&quot;
};

// 오류 발생
animal = {
    name: &quot;초코&quot;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;객체 내부 변경 &amp;rarr; 가능

변수에 새로운 객체 재할당 &amp;rarr; 불가능
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이라고 이해하면 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;20. 메서드&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체의 프로퍼티 값으로 함수를 저장할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 &lt;b&gt;값이 함수인 프로퍼티를 메서드(Method)&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;const person = {

    name: &quot;정재민&quot;,

    sayHi() {
        console.log(&quot;안녕!&quot;);
    },
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 sayHi가 메서드이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;21. 메서드 호출&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메서드도 일반적인 프로퍼티처럼 점 표기법과 괄호 표기법을 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;person.sayHi();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는&lt;/p&gt;
&lt;pre class=&quot;markdown&quot;&gt;&lt;code&gt;person[&quot;sayHi&quot;]();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;erlang-repl&quot;&gt;&lt;code&gt;안녕!
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체가 단순히 데이터만 저장하는 것이 아니라 &lt;b&gt;관련 기능까지 함께 묶을 수 있다는 것&lt;/b&gt;이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 사람 객체라면 다음처럼 구성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const person = {

    name: &quot;정재민&quot;,
    age: 27,

    sayHi() {
        console.log(`안녕하세요. 저는 ${this.name}입니다.`);
    },
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;this에 대한 내용은 이후 객체와 메서드를 더 공부할 때 따로 정리할 예정이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;22. 배열&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열(Array)은 &lt;b&gt;여러 개의 값을 순서대로 저장할 수 있는 자료구조&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체가 key를 이용해서 값을 관리한다면 배열은 &lt;b&gt;순서(Index)&lt;/b&gt;를 이용해서 값을 관리한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;23. 배열 생성&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열을 만드는 방법도 객체와 마찬가지로 두 가지가 있다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;배열 생성자&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let arrA = new Array();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;배열 리터럴&lt;/h2&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;let arrB = [];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 경우 배열 리터럴 방식을 사용한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;24. 배열에 값 저장하기&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열에는 여러 개의 값을 저장할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let arr = [1, 2, 3];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript 배열에는 서로 다른 자료형도 함께 저장할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;autohotkey&quot;&gt;&lt;code&gt;let arrC = [

    1,
    2,
    3,

    true,

    &quot;hello&quot;,

    null,

    undefined,

    () =&amp;gt; {},

    {},

    [],
];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숫자, 문자열, Boolean뿐만 아니라 함수, 객체, 다른 배열까지 저장할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;25. 배열 요소와 인덱스&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열 안에 저장된 각각의 값을 &lt;b&gt;요소(Element)&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 요소에는 순서를 나타내는 &lt;b&gt;인덱스(Index)&lt;/b&gt;가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중요한 점은 배열의 인덱스는 0부터 시작한다는 것이다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;let arr = [&quot;A&quot;, &quot;B&quot;, &quot;C&quot;];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 요소의 인덱스는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;&quot;A&quot; &amp;rarr; 0
&quot;B&quot; &amp;rarr; 1
&quot;C&quot; &amp;rarr; 2
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;26. 배열 요소 접근&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스를 이용해서 원하는 배열 요소에 접근할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let arrC = [1, 2, 3];

let item1 = arrC[0];

let item2 = arrC[1];

console.log(item1);
console.log(item2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
2
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;27. 배열 요소 수정&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열의 특정 위치에 새로운 값을 대입하면 해당 요소를 수정할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;lsl&quot;&gt;&lt;code&gt;let arrC = [1, 2, 3];

arrC[0] = &quot;hello&quot;;

console.log(arrC);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;[&quot;hello&quot;, 2, 3]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 인덱스 0에 저장되어 있던 1이 &quot;hello&quot;로 변경된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;객체와 배열의 차이&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체와 배열은 모두 여러 데이터를 하나로 묶을 수 있지만 데이터를 관리하는 방식이 다르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구분객체배열&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;기본 형태&lt;/td&gt;
&lt;td&gt;{}&lt;/td&gt;
&lt;td&gt;[]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;데이터 구분&lt;/td&gt;
&lt;td&gt;key&lt;/td&gt;
&lt;td&gt;index&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;접근 방식&lt;/td&gt;
&lt;td&gt;person.name&lt;/td&gt;
&lt;td&gt;arr[0]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;적합한 상황&lt;/td&gt;
&lt;td&gt;속성이 있는 데이터&lt;/td&gt;
&lt;td&gt;순서가 있는 데이터&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 사람 한 명의 정보를 관리한다면 객체가 적절하다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;const person = {

    name: &quot;정재민&quot;,
    age: 27,
    job: &quot;ERP Developer&quot;,
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 여러 명의 이름을 순서대로 저장한다면 배열이 적절하다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;const users = [
    &quot;정재민&quot;,
    &quot;김철수&quot;,
    &quot;이영희&quot;
];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 실제 개발에서는 객체와 배열을 함께 사용하는 경우가 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 여러 사용자의 정보를 저장한다면 다음처럼 작성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;const users = [

    {
        name: &quot;정재민&quot;,
        age: 27
    },

    {
        name: &quot;김철수&quot;,
        age: 30
    },

    {
        name: &quot;이영희&quot;,
        age: 25
    }
];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열 안에 여러 개의 객체가 들어 있는 형태이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 구조는 서버에서 데이터를 받아오거나 API 데이터를 처리할 때 자주 보게 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;정리&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 JavaScript의 콜백 함수부터 객체와 배열까지 공부했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개념설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;콜백 함수&lt;/td&gt;
&lt;td&gt;다른 함수에 인수로 전달되는 함수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;스코프&lt;/td&gt;
&lt;td&gt;변수나 함수에 접근할 수 있는 범위&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;전역 스코프&lt;/td&gt;
&lt;td&gt;전체 영역에서 접근 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;지역 스코프&lt;/td&gt;
&lt;td&gt;특정 함수나 블록에서만 접근 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;객체&lt;/td&gt;
&lt;td&gt;여러 데이터를 key-value 형태로 관리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;프로퍼티&lt;/td&gt;
&lt;td&gt;객체 내부에 존재하는 각각의 속성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;점 표기법&lt;/td&gt;
&lt;td&gt;person.name&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;괄호 표기법&lt;/td&gt;
&lt;td&gt;person[&quot;name&quot;]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;delete&lt;/td&gt;
&lt;td&gt;객체 프로퍼티 삭제&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;in&lt;/td&gt;
&lt;td&gt;객체에 특정 프로퍼티가 있는지 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;메서드&lt;/td&gt;
&lt;td&gt;객체의 값으로 저장된 함수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;배열&lt;/td&gt;
&lt;td&gt;여러 데이터를 순서대로 저장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;인덱스&lt;/td&gt;
&lt;td&gt;배열 요소의 위치를 나타내는 번호&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 내용부터 JavaScript에서 데이터를 어떻게 구조화하고 함수와 데이터를 어떻게 함께 사용할 수 있는지가 조금씩 보이기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 &lt;b&gt;콜백 함수는 앞으로 배열 메서드와 비동기 JavaScript를 공부할 때 계속 등장하는 핵심 개념&lt;/b&gt;이고, 객체와 배열은 실제 웹 개발에서 데이터를 다룰 때 거의 항상 사용하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에는 배열을 더욱 편리하게 다룰 수 있는 &lt;b&gt;배열 메서드와 객체 순회&lt;/b&gt;에 대해 정리해볼 예정이다.&lt;/p&gt;</description>
      <category>개발/Javascript</category>
      <author>잼coding</author>
      <guid isPermaLink="true">https://jamin0619.tistory.com/25</guid>
      <comments>https://jamin0619.tistory.com/25#entry25comment</comments>
      <pubDate>Wed, 16 Sep 2026 09:39:19 +0900</pubDate>
    </item>
    <item>
      <title>JavaScript 기초 정리 ② 조건문, 반복문, 함수</title>
      <link>https://jamin0619.tistory.com/24</link>
      <description>&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript 기본 문법 두 번째 정리.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 첫 번째 글에서 다룬 기본 연산자에 이어 &lt;b&gt;null 병합 연산자, typeof, 삼항 연산자&lt;/b&gt;를 알아보고, 프로그램의 흐름을 제어하는 &lt;b&gt;조건문과 반복문&lt;/b&gt;, 그리고 JavaScript에서 중요한 &lt;b&gt;함수&lt;/b&gt;에 대해 정리한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;1. Null 병합 연산자 ??&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Null 병합 연산자는 여러 값 중에서 &lt;b&gt;null 또는 undefined가 아닌 값을 선택할 때 사용하는 연산자&lt;/b&gt;이다.&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;let var1;

let var2 = 10;
let var3 = 20;

let var4 = var1 ?? var2;
let var5 = var1 ?? var3;

console.log(var4);
console.log(var5);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;10
20
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var1은 값을 할당하지 않았기 때문에 undefined 상태이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;var1 ?? var2
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에서 var1이 undefined이므로 오른쪽 값인 var2가 선택된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실제 활용 예시&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자의 이름이 존재하면 이름을 표시하고, 이름이 없다면 닉네임을 표시하는 상황을 생각해볼 수 있다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let userName = &quot;정재민&quot;;
let userNickName = &quot;Winterlood&quot;;

let displayName = userName ?? userNickName;

console.log(displayName);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;정재민
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;userName에 값이 존재하기 때문에 왼쪽 값인 &quot;정재민&quot;이 선택된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 다음과 같은 경우에는 닉네임이 출력된다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let userName = null;
let userNickName = &quot;Winterlood&quot;;

let displayName = userName ?? userNickName;

console.log(displayName);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;Winterlood
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;왼쪽 값 ?? 오른쪽 값
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에서&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;왼쪽 값이 null 또는 undefined &amp;rarr; 오른쪽 값 반환&lt;/li&gt;
&lt;li&gt;왼쪽 값이 정상적인 값 &amp;rarr; 왼쪽 값 반환&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이라고 이해할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;??와 ||의 차이&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 ||와 비슷해 보이지만 차이가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;??는 오직 &lt;b&gt;null과 undefined만 없는 값으로 판단&lt;/b&gt;한다.&lt;/p&gt;
&lt;pre class=&quot;ceylon&quot;&gt;&lt;code&gt;let value = 0;

console.log(value ?? 10);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;0
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 ||는 0, &quot;&quot;, false 등도 거짓으로 판단한다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;console.log(value || 10);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;10
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 0이나 false도 정상적인 값으로 사용해야 한다면 ??를 사용하는 것이 적절하다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;2. typeof 연산자&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;typeof는 &lt;b&gt;값의 자료형을 문자열 형태로 반환하는 연산자&lt;/b&gt;이다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let var7 = 1;

console.log(typeof var7);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;number
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript 변수는 하나의 자료형에 고정되어 있지 않기 때문에 다른 타입의 값을 다시 저장할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;let var7 = 1;

var7 = &quot;hello&quot;;
var7 = true;

let t1 = typeof var7;

console.log(t1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;boolean
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로 저장된 값이 true이므로 현재 var7의 타입은 boolean이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대표적인 결과는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;console.log(typeof 10);          // number
console.log(typeof &quot;hello&quot;);     // string
console.log(typeof true);        // boolean
console.log(typeof undefined);   // undefined
console.log(typeof function(){});// function
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 안에 어떤 종류의 값이 들어있는지 확인하고 싶을 때 유용하다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;3. 삼항 연산자&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삼항 연산자는 이름 그대로 &lt;b&gt;3개의 항을 사용하는 연산자&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건에 따라 서로 다른 값을 반환하고 싶을 때 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 형태는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;조건식 ? 참일 때 값 : 거짓일 때 값
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 어떤 숫자가 짝수인지 홀수인지 판단한다고 해보자.&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let var8 = 10;

let res = var8 % 2 === 0 ? &quot;짝수&quot; : &quot;홀수&quot;;

console.log(res);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;짝수
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 조건을 검사하고 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;var8 % 2 === 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숫자를 2로 나누었을 때 나머지가 0이면 짝수이므로 &quot;짝수&quot;를 반환하고, 그렇지 않으면 &quot;홀수&quot;를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 if문으로 작성하면 다음과 비슷하다.&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;let res;

if (var8 % 2 === 0) {
    res = &quot;짝수&quot;;
} else {
    res = &quot;홀수&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 조건에 따라 하나의 값을 결정해야 할 때 삼항 연산자를 사용하면 코드를 짧게 작성할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 조건이 너무 복잡해진다면 삼항 연산자를 여러 번 중첩하기보다는 if문을 사용하는 것이 읽기 쉽다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;4. 조건문&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건문은 &lt;b&gt;특정 조건에 따라 서로 다른 코드를 실행하도록 만드는 문법&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 대표적으로 if와 switch를 사용할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;5. if문&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 기본적인 조건문이다.&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;let num = 10;

if (num &amp;gt;= 10) {
    console.log(&quot;num은 10 이상입니다.&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;() 안의 조건식이 true이면 {} 내부의 코드가 실행된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;if - else&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건이 참일 때와 거짓일 때 각각 다른 코드를 실행할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;let num = 10;

if (num &amp;gt;= 10) {
    console.log(&quot;조건이 참입니다.&quot;);
} else {
    console.log(&quot;조건이 거짓입니다.&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;else if&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 조건을 차례대로 검사해야 할 때 else if를 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;let num = 10;

if (num &amp;gt;= 10) {
    console.log(&quot;num은 10 이상입니다.&quot;);
} else if (num &amp;gt;= 5) {
    console.log(&quot;num은 5 이상입니다.&quot;);
} else if (num &amp;gt;= 3) {
    console.log(&quot;num은 3 이상입니다.&quot;);
} else {
    console.log(&quot;num은 3 미만입니다.&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건은 위에서부터 순서대로 검사한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 num은 10이기 때문에 첫 번째 조건인&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;num &amp;gt;= 10
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 true가 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;num은 10 이상입니다.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 출력되고 이후의 else if 조건은 검사하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, &lt;b&gt;먼저 만족하는 조건 하나만 실행된다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;6. switch문&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;switch문 역시 조건에 따라 서로 다른 코드를 실행하기 위해 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 변수의 값에 따라 여러 경우를 나누어 처리할 때 if문보다 직관적으로 표현할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let animal = &quot;cat&quot;;

switch (animal) {
    case &quot;cat&quot;:
        console.log(&quot;고양이&quot;);
        break;

    case &quot;dog&quot;:
        console.log(&quot;강아지&quot;);
        break;

    case &quot;bear&quot;:
        console.log(&quot;곰&quot;);
        break;

    case &quot;snake&quot;:
        console.log(&quot;뱀&quot;);
        break;

    case &quot;tiger&quot;:
        console.log(&quot;호랑이&quot;);
        break;

    default:
        console.log(&quot;그런 동물은 전 모릅니다.&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;animal의 값이 &quot;cat&quot;이므로&lt;/p&gt;
&lt;pre class=&quot;&quot;&gt;&lt;code&gt;고양이
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 출력된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;case&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;case에는 비교하고 싶은 값을 작성한다.&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;case &quot;cat&quot;:
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;switch에 전달된 값과 일치하면 해당 부분의 코드가 실행된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;break&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;break는 현재 switch문을 종료한다.&lt;/p&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;case &quot;cat&quot;:
    console.log(&quot;고양이&quot;);
    break;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;break를 작성하지 않으면 일치하는 case를 찾은 이후 다음 case까지 계속 실행될 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 일반적인 switch문에서는 break를 함께 사용한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;default&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어떤 case에도 해당하지 않을 때 실행된다.&lt;/p&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;default:
    console.log(&quot;그런 동물은 전 모릅니다.&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;if문의 마지막 else와 비슷한 역할을 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;7. 반복문&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반복문은 &lt;b&gt;같은 코드를 여러 번 실행해야 할 때 사용하는 문법&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 대표적으로 for문을 사용할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;8. for문&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본적인 for문의 형태는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;for (초기식; 조건식; 증감식) {
    실행할 코드
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 다음 코드는 0부터 10까지 반복한다.&lt;/p&gt;
&lt;pre class=&quot;lisp&quot;&gt;&lt;code&gt;for (let idx = 0; idx &amp;lt;= 10; idx++) {
    console.log(idx);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 부분의 역할은 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let idx = 0 &amp;rarr; 반복문에서 사용할 변수 생성
idx &amp;lt;= 10   &amp;rarr; 반복을 계속할 조건
idx++       &amp;rarr; 한 번 반복한 뒤 idx를 1 증가
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;9. continue&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;continue는 &lt;b&gt;현재 반복을 건너뛰고 다음 반복으로 이동&lt;/b&gt;한다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;for (let idx = 0; idx &amp;lt;= 10; idx++) {

    if (idx % 2 === 0) {
        continue;
    }

    console.log(idx);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 숫자가 짝수라면 continue가 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 짝수에서는 아래의 console.log()가 실행되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
3
5
7
9
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 이 코드는 홀수만 출력한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;10. break&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;break는 &lt;b&gt;반복문 자체를 종료&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;continue와 함께 사용해보면 차이를 쉽게 이해할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;for (let idx = 0; idx &amp;lt;= 10; idx++) {

    if (idx % 2 === 0) {
        continue;
    }

    console.log(idx);

    if (idx &amp;gt;= 5) {
        break;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 과정을 보면 짝수는 continue로 건너뛴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 출력되는 값은&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;1
3
5
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;idx가 5가 되었을 때&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;if (idx &amp;gt;= 5) {
    break;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조건을 만족하여 반복문 전체가 종료된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리하면&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot;&gt;&lt;code&gt;continue &amp;rarr; 현재 반복만 건너뛰기
break    &amp;rarr; 반복문 자체 종료하기
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 이해할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;11. 함수&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수(Function)는 &lt;b&gt;특정 기능을 수행하는 코드를 하나의 단위로 묶어놓은 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반복해서 사용하는 코드를 함수로 만들어두면 필요할 때마다 호출해서 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 사각형의 넓이를 계산하는 함수를 만들어보자.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;function getArea(width, height) {

    let area = width * height;

    return area;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;getArea       &amp;rarr; 함수 이름
width, height &amp;rarr; 매개변수
return area   &amp;rarr; 함수가 반환하는 값
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;12. 함수 호출&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만들어진 함수는 함수 이름 뒤에 ()를 붙여 실행할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;getArea(10, 20);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;10은 width, 20은 height로 전달된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수가 반환하는 값을 변수에 저장할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let area1 = getArea(10, 20);

console.log(area1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;200
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 값을 전달하면 같은 함수를 다시 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let area2 = getArea(30, 20);

console.log(area2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;600
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 함수의 장점은 &lt;b&gt;같은 로직을 여러 번 작성하지 않고 필요한 값만 전달하여 재사용할 수 있다는 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;13. 매개변수와 인수&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수를 공부할 때 비슷해서 헷갈리는 용어가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 &lt;b&gt;매개변수(Parameter)&lt;/b&gt;와 &lt;b&gt;인수(Argument)&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수를 선언할 때 사용하는 변수는 매개변수이다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;function getArea(width, height) {
    return width * height;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;width
height
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가 매개변수이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반면 함수를 실제로 호출하면서 전달하는 값은 인수라고 한다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;getArea(10, 20);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;10
20
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 인수이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;14. return&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;return은 함수에서 계산된 값을 함수 밖으로 반환한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;function getArea(width, height) {

    let area = width * height;

    return area;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수에서 반환된 값은 다음과 같이 변수에 저장할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;applescript&quot;&gt;&lt;code&gt;let result = getArea(10, 20);

console.log(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;200
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;return이 실행되면 함수는 그 지점에서 종료된다는 점도 중요하다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;15. 중첩 함수&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 내부에 또 다른 함수를 선언할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 &lt;b&gt;중첩 함수&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;function getArea(width, height) {

    function another() {
        console.log(&quot;another&quot;);
    }

    another();

    let area = width * height;

    return area;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;another() 함수는 getArea() 내부에서 선언되었기 때문에 기본적으로 getArea() 내부에서 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 안에서만 필요한 기능을 별도의 함수로 분리하고 싶을 때 활용할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;16. 함수 호이스팅&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript의 함수 선언문에는 &lt;b&gt;호이스팅(Hoisting)&lt;/b&gt;이라는 특징이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호이스팅은 단어 그대로 코드를 위쪽으로 끌어올린 것처럼 동작하는 현상이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 함수를 선언하기 전에 호출해도 실행할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;let area1 = getArea(10, 20);

console.log(area1);

function getArea(width, height) {
    return width * height;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코드상으로는 getArea() 함수가 아래에서 선언되어 있지만 정상적으로 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 JavaScript가 함수 선언문을 실행 전에 처리하기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 다음처럼 작성하는 것이 가능하다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;hello();

function hello() {
    console.log(&quot;Hello&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;Hello
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, &lt;b&gt;모든 함수 작성 방식이 동일하게 호이스팅되는 것은 아니다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뒤에서 다룰 함수 표현식과는 차이가 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;17. 함수 표현식&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 함수도 하나의 값처럼 변수에 저장할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function funcA() {
    console.log(&quot;funcA&quot;);
}

let varA = funcA;

varA();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;funcA라는 함수 자체를 varA에 저장했기 때문에&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;varA();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;를 이용해서도 함수를 실행할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;18. 익명 함수&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 이름 없이 함수를 생성할 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 &lt;b&gt;익명 함수(Anonymous Function)&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let funcB = function () {
    console.log(&quot;funcB&quot;);
};

funcB();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 자체에는 이름이 없지만 funcB 변수에 저장했기 때문에 해당 변수를 이용하여 호출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이처럼 함수를 변수에 저장하는 방식을 함수 표현식이라고 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;19. 함수 표현식과 호이스팅&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 선언문과 함수 표현식은 호이스팅에서 중요한 차이가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 선언문은 선언보다 먼저 호출할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;hello();

function hello() {
    console.log(&quot;Hello&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 다음과 같은 함수 표현식은 선언 전에 호출할 수 없다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;hello();

let hello = function () {
    console.log(&quot;Hello&quot;);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;let으로 선언된 변수는 초기화되기 전에 사용할 수 없기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 함수 표현식을 사용할 때는 일반적으로 &lt;b&gt;함수를 변수에 할당한 이후 호출해야 한다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;20. 블록 스코프 주의하기&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음 작성했던 다음 코드에는 주의할 부분이 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;{
    let varB = function () {
        console.log(&quot;funcB&quot;);
    };
}

varB();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 코드는 정상적으로 실행되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;let은 &lt;b&gt;블록 스코프(Block Scope)&lt;/b&gt;를 가지기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;pre class=&quot;lasso&quot;&gt;&lt;code&gt;{
    let varB = ...
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에서 선언한 varB는 {} 내부에서만 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 사용하려면 다음과 같이 같은 블록 안에서 호출해야 한다.&lt;/p&gt;
&lt;pre class=&quot;clojure&quot;&gt;&lt;code&gt;{
    let varB = function () {
        console.log(&quot;funcB&quot;);
    };

    varB();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는 블록 밖에서 사용할 예정이라면 변수 자체를 바깥에서 선언해야 한다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let funcB = function () {
    console.log(&quot;funcB&quot;);
};

funcB();
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수를 어디에서 선언했느냐에 따라 사용할 수 있는 범위가 달라진다는 점은 앞으로 JavaScript를 공부하면서 중요한 개념이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;21. 화살표 함수&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ES6부터 함수를 더욱 간결하게 작성할 수 있는 &lt;b&gt;화살표 함수(Arrow Function)&lt;/b&gt;가 추가되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 함수 표현식은 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;let funcC = function () {
    return 1;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화살표 함수로 바꾸면 다음처럼 작성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;let funcC = () =&amp;gt; {
    return 1;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 이름 대신 =&amp;gt; 기호를 사용하는 것이 특징이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;22. 화살표 함수 간단하게 작성하기&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 내부에서 단순히 하나의 값을 반환한다면 {}와 return도 생략할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;let addOne = (value) =&amp;gt; value + 1;

console.log(addOne(10));
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;11
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 다음 함수와 동일한 역할을 한다.&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;let addOne = function (value) {
    return value + 1;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;화살표 함수를 사용하면 훨씬 간결하게 표현할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;매개변수가 하나일 경우&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매개변수가 하나라면 괄호를 생략할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;ocaml&quot;&gt;&lt;code&gt;let addOne = value =&amp;gt; value + 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 개인적으로 처음 공부할 때는 구조를 명확하게 보기 위해 다음처럼 괄호를 작성하는 것도 좋다.&lt;/p&gt;
&lt;pre class=&quot;ocaml&quot;&gt;&lt;code&gt;let addOne = (value) =&amp;gt; value + 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;매개변수가 여러 개인 경우&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매개변수가 여러 개라면 괄호가 필요하다.&lt;/p&gt;
&lt;pre class=&quot;armasm&quot;&gt;&lt;code&gt;let add = (a, b) =&amp;gt; a + b;

console.log(add(10, 20));
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;30
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;함수 선언 방식 비교&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서 지금까지 배운 함수 작성 방식을 비교하면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;방식예시&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;함수 선언문&lt;/td&gt;
&lt;td&gt;function add(a, b) { return a + b; }&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;함수 표현식&lt;/td&gt;
&lt;td&gt;let add = function(a, b) { return a + b; };&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;화살표 함수&lt;/td&gt;
&lt;td&gt;let add = (a, b) =&amp;gt; a + b;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 기능을 수행할 수 있지만 작성 방법과 일부 동작에는 차이가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 세 가지 방식이 있다는 정도로 이해하고, 이후 JavaScript를 더 공부하면서 각각의 차이를 알아가면 될 것 같다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1&gt;정리&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에는 JavaScript의 연산자부터 조건문, 반복문, 함수까지 공부했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개념설명&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;??&lt;/td&gt;
&lt;td&gt;null, undefined가 아닌 값 선택&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;typeof&lt;/td&gt;
&lt;td&gt;값의 자료형 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;조건 ? A : B&lt;/td&gt;
&lt;td&gt;삼항 연산자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;if&lt;/td&gt;
&lt;td&gt;조건에 따라 코드 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;else if&lt;/td&gt;
&lt;td&gt;여러 조건을 순서대로 검사&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;switch&lt;/td&gt;
&lt;td&gt;하나의 값을 여러 경우와 비교&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;for&lt;/td&gt;
&lt;td&gt;코드를 반복 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;continue&lt;/td&gt;
&lt;td&gt;현재 반복을 건너뜀&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;break&lt;/td&gt;
&lt;td&gt;반복문 또는 switch 종료&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;function&lt;/td&gt;
&lt;td&gt;재사용 가능한 코드 묶음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;return&lt;/td&gt;
&lt;td&gt;함수 실행 결과 반환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;호이스팅&lt;/td&gt;
&lt;td&gt;함수 선언을 위에서 한 것처럼 사용할 수 있는 특성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;함수 표현식&lt;/td&gt;
&lt;td&gt;함수를 변수에 저장&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;익명 함수&lt;/td&gt;
&lt;td&gt;이름이 없는 함수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;화살표 함수&lt;/td&gt;
&lt;td&gt;=&amp;gt;를 이용한 간결한 함수 표현&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 내용부터는 단순히 값을 저장하고 계산하는 것을 넘어서 &lt;b&gt;프로그램의 실행 흐름을 직접 제어하는 문법&lt;/b&gt;이 등장했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 if, for, function은 앞으로 JavaScript 코드를 작성하면서 계속 사용하게 될 핵심 문법이기 때문에 동작 방식을 확실하게 이해해둘 필요가 있다.&lt;/p&gt;</description>
      <category>개발/Javascript</category>
      <category>자바스크립트 #JS #javascript #자바스크립트 기초 정리</category>
      <author>잼coding</author>
      <guid isPermaLink="true">https://jamin0619.tistory.com/24</guid>
      <comments>https://jamin0619.tistory.com/24#entry24comment</comments>
      <pubDate>Tue, 15 Sep 2026 08:31:28 +0900</pubDate>
    </item>
    <item>
      <title>JavaScript 기초 정리 1. 변수, 자료형, 형 변환, 연산자</title>
      <link>https://jamin0619.tistory.com/23</link>
      <description>&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Js를 다시 공부하면서 오랜만에 정리해 두었던 내용을 토대로 블로그에 기재할려고 한다. js를 다시 공부하거나, 잘 모르는 분들에게 도움을 주기 위해 이 글을 작성한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;1. 변수와 상수&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;프로그램을 작성하다 보면 데이터를 저장해두고 필요한 순간에 다시 사용해야 하는 경우가 많다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이때 데이터를 저장하기 위해 사용하는 것이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;변수(Variable)&lt;/b&gt;이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 주로&lt;span&gt;&amp;nbsp;&lt;/span&gt;let과&lt;span&gt;&amp;nbsp;&lt;/span&gt;const를 사용한다.&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;let&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;let으로 선언한 변수는 이후에 값을 변경할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let age = 27;

console.log(age);

age = 30;

console.log(age);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;실행 결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;27
30
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;처음에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;age에&lt;span&gt;&amp;nbsp;&lt;/span&gt;27을 저장했지만 이후&lt;span&gt;&amp;nbsp;&lt;/span&gt;30으로 값을 변경할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;값이 변경될 가능성이 있는 데이터에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;let을 사용한다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;const&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;const는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;상수(Constant)&lt;/b&gt;를 선언할 때 사용한다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;한 번 값을 할당하면 다른 값으로 다시 할당할 수 없다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;const birth = &quot;2000.06.19&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 다음과 같이 값을 다시 대입하면 오류가 발생한다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;const birth = &quot;2000.06.19&quot;;

birth = &quot;2000.07.19&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 값이 변경될 필요가 없다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;let보다&lt;span&gt;&amp;nbsp;&lt;/span&gt;const를 사용하는 것이 좋다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;2. 변수 명명 규칙&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;변수 이름을 아무렇게나 만들 수 있는 것은 아니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 몇 가지 기본적인 변수 명명 규칙이 존재한다.&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2-1.&lt;span&gt;&amp;nbsp;&lt;/span&gt;$,&lt;span&gt;&amp;nbsp;&lt;/span&gt;_를 제외한 특수문자는 사용할 수 없다.&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음과 같은 변수명은 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let name1;
let $name2;
let _name3;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;반면 다음과 같은 변수명은 사용할 수 없다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;// let user-name;
// let user@name;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2-2. 숫자로 시작할 수 없다.&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;숫자가 변수명에 들어가는 것은 가능하지만&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;첫 번째 글자로 사용할 수는 없다.&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;abnf&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let name1;
let user2;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음과 같은 형태는 사용할 수 없다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;// let 1name;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;2-3. 예약어를 변수명으로 사용할 수 없다.&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript에서 이미 문법적인 의미를 가지고 있는 단어를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;예약어(Reserved Word)&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;span&gt;&amp;nbsp;&lt;/span&gt;if,&lt;span&gt;&amp;nbsp;&lt;/span&gt;for,&lt;span&gt;&amp;nbsp;&lt;/span&gt;while,&lt;span&gt;&amp;nbsp;&lt;/span&gt;class&lt;span&gt;&amp;nbsp;&lt;/span&gt;등의 키워드는 변수명으로 사용할 수 없다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;// let if;
// let for;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;3. 변수 이름은 의미가 드러나도록 작성하기&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문법적으로 문제가 없는 변수명이라고 해서 좋은 변수명인 것은 아니다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;변수 이름만 보고도&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;어떤 데이터를 저장하고 있는지 알 수 있도록 작성하는 것이 중요하다.&lt;/b&gt;&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let salesCount = 1;
let refundCount = 1;

let totalSalesCount = salesCount - refundCount;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어&lt;span&gt;&amp;nbsp;&lt;/span&gt;a,&lt;span&gt;&amp;nbsp;&lt;/span&gt;b,&lt;span&gt;&amp;nbsp;&lt;/span&gt;c처럼 작성하는 것보다&lt;span&gt;&amp;nbsp;&lt;/span&gt;salesCount,&lt;span&gt;&amp;nbsp;&lt;/span&gt;refundCount처럼 의미가 드러나는 이름을 사용하는 것이 코드를 이해하기 쉽다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 여러 단어를 연결할 때 일반적으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;camelCase&lt;/b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;방식을 많이 사용한다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let totalSalesCount;
let userName;
let productPrice;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;첫 단어는 소문자로 시작하고, 이후 단어의 첫 글자를 대문자로 작성하는 방식이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;4. JavaScript의 자료형&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 변수에 숫자, 문자열, 참/거짓 등 다양한 형태의 데이터를 저장할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이러한 데이터의 종류를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;자료형(Data Type)&lt;/b&gt;이라고 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;4-1. Number Type&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;숫자를 표현하는 자료형이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 정수와 실수를 별도의 자료형으로 나누지 않고 대부분&lt;span&gt;&amp;nbsp;&lt;/span&gt;Number&lt;span&gt;&amp;nbsp;&lt;/span&gt;타입으로 처리한다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let num1 = 27;
let num2 = 1.5;
let num3 = -20;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Number 타입을 이용하면 기본적인 산술 연산을 수행할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;matlab&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;console.log(num1 + num2);
console.log(num1 - num2);
console.log(num1 * num2);
console.log(num1 / num2);
console.log(num1 % num2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;%&lt;span&gt;&amp;nbsp;&lt;/span&gt;연산자는 나머지를 구하는 연산자이다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;console.log(10 % 3);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;1
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;Infinity&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript에는 무한대를 나타내는&lt;span&gt;&amp;nbsp;&lt;/span&gt;Infinity라는 값도 존재한다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let inf = Infinity;
let mInf = -Infinity;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각각 양의 무한대와 음의 무한대를 의미한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;NaN&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;NaN은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Not a Number&lt;/b&gt;의 약자로, 숫자가 아닌 값을 의미한다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let nan = NaN;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 숫자와 숫자로 변환할 수 없는 문자열을 곱하면 정상적인 계산을 할 수 없기 때문에&lt;span&gt;&amp;nbsp;&lt;/span&gt;NaN이 발생한다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;console.log(1 * &quot;hello&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;arcade&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;NaN
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주의할 점은 이름은&lt;span&gt;&amp;nbsp;&lt;/span&gt;Not a Number이지만 JavaScript에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;NaN&lt;span&gt;&amp;nbsp;&lt;/span&gt;자체는 Number 타입에 포함된다는 것이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;5. String Type&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문자열을 표현하는 자료형이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문자열은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot; &quot;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;' ', 또는 백틱&lt;span&gt;&amp;nbsp;&lt;/span&gt;` `을 사용해 표현할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let myName = &quot;정재민&quot;;
let myLocation = &quot;목동&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문자열끼리는&lt;span&gt;&amp;nbsp;&lt;/span&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;연산자를 이용해 연결할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let introduce = myName + myLocation;

console.log(introduce);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 이렇게 작성하면 문자열 사이에 공백이나 문장을 직접 추가해야 하는 경우 코드가 복잡해질 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이럴 때 사용할 수 있는 것이&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;템플릿 리터럴(Template Literal)&lt;/b&gt;이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;템플릿 리터럴&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;템플릿 리터럴은 백틱&lt;span&gt;&amp;nbsp;&lt;/span&gt;`을 사용하며&lt;span&gt;&amp;nbsp;&lt;/span&gt;${}&lt;span&gt;&amp;nbsp;&lt;/span&gt;안에 변수를 넣을 수 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let myName = &quot;정재민&quot;;
let myLocation = &quot;목동&quot;;

let introduceText = `${myName}은 ${myLocation}에 거주합니다`;

console.log(introduceText);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;정재민은 목동에 거주합니다
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;문자열과 변수를 함께 사용해야 할 때 매우 편리하다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;6. Boolean Type&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Boolean은&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;참(True)과 거짓(False)&lt;/b&gt;을 나타내는 자료형이다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let isSwitchOn = true;
let isEmpty = false;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;주로 조건문이나 상태를 판단할 때 사용한다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;예를 들어 로그인 여부를 저장한다면 다음과 같이 작성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let isLogin = true;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;7. Null Type&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;null은 개발자가 의도적으로&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;값이 없다&lt;/b&gt;는 것을 나타낼 때 사용한다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let empty = null;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;즉, 어떤 변수에 값이 존재하지 않는 상태를 직접 명시하고 싶을 때 사용할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;8. Undefined Type&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;undefined는 변수를 선언했지만 아직 값을 할당하지 않은 상태를 의미한다.&lt;/p&gt;
&lt;pre class=&quot;lasso&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let none;

console.log(none);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;undefined
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;null과&lt;span&gt;&amp;nbsp;&lt;/span&gt;undefined는 둘 다 값이 없다는 느낌이 있지만 차이가 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc; color: #000000; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;null&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 개발자가 의도적으로 값이 없다고 지정&lt;/li&gt;
&lt;li&gt;undefined&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 아직 값이 할당되지 않은 상태&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;9. 형 변환&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript에서는 하나의 자료형을 다른 자료형으로 변환할 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;형 변환에는 크게 두 가지가 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;묵시적 형 변환&lt;/b&gt;과&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;명시적 형 변환&lt;/b&gt;이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;9-1. 묵시적 형 변환&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;묵시적 형 변환은 개발자가 직접 자료형을 변경하지 않아도&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;JavaScript 엔진이 상황에 따라 자동으로 자료형을 변환하는 것&lt;/b&gt;이다.&lt;/p&gt;
&lt;pre class=&quot;maxima&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let num = 10;
let str = &quot;20&quot;;

const result = num + str;

console.log(result);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;1020
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;숫자&lt;span&gt;&amp;nbsp;&lt;/span&gt;10과 문자열&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;20&quot;을 더했지만 결과는&lt;span&gt;&amp;nbsp;&lt;/span&gt;30이 아니라&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;1020&quot;이 된다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;+&lt;span&gt;&amp;nbsp;&lt;/span&gt;연산을 수행하는 과정에서 숫자&lt;span&gt;&amp;nbsp;&lt;/span&gt;10이 문자열&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;10&quot;으로 자동 변환되었기 때문이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;pre class=&quot;basic&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;10 + &quot;20&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;은 사실상&lt;/p&gt;
&lt;pre class=&quot;1c&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;&quot;10&quot; + &quot;20&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;처럼 동작하여&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;1020&quot;이 된다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이처럼 JavaScript의 자동 형 변환은 편리하지만 예상하지 못한 결과를 만들 수도 있기 때문에 주의해야 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;10. 명시적 형 변환&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;개발자가 직접 내장 함수를 사용하여 자료형을 변환하는 것을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;명시적 형 변환&lt;/b&gt;이라고 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;문자열 &amp;rarr; 숫자&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Number()를 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;armasm&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let str1 = &quot;10&quot;;

let strToNum1 = Number(str1);

console.log(strToNum1);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;10
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;하지만 숫자로 변환할 수 없는 문자열이 포함되어 있다면&lt;span&gt;&amp;nbsp;&lt;/span&gt;NaN이 발생한다.&lt;/p&gt;
&lt;pre class=&quot;armasm&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let str2 = &quot;10개&quot;;

let strToNum2 = Number(str2);

console.log(strToNum2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;arcade&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;NaN
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Number()는 문자열 전체가 정상적인 숫자 형태여야 변환할 수 있다는 점을 기억해야 한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;숫자 &amp;rarr; 문자열&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;숫자를 문자열로 변경할 때는&lt;span&gt;&amp;nbsp;&lt;/span&gt;String()을 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let num1 = 20;

let numToStr1 = String(num1);

console.log(numToStr1 + &quot;입니다&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;20입니다
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;11. 연산자&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;연산자는 값을 계산하거나 비교하는 등의 작업을 수행하기 위해 사용하는 기호이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript에는 다양한 종류의 연산자가 존재한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;11-1. 대입 연산자&lt;/h2&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;=는 오른쪽의 값을 왼쪽 변수에 저장하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;대입 연산자&lt;/b&gt;이다.&lt;/p&gt;
&lt;pre class=&quot;maxima&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let var1 = 1;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;수학에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;=가 '같다'라는 의미지만 프로그래밍에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;오른쪽 값을 왼쪽 변수에 저장한다&lt;/b&gt;는 의미로 사용된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;12. 산술 연산자&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;숫자를 계산하기 위해 사용하는 연산자이다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let num1 = 3 + 2;
let num2 = 3 - 2;
let num3 = 3 * 2;
let num4 = 3 / 2;
let num5 = 3 % 2;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;각각 다음을 의미한다.&lt;/p&gt;
&lt;pre class=&quot;ada&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;+ : 덧셈
- : 뺄셈
* : 곱셈
/ : 나눗셈
% : 나머지
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;괄호를 이용해 연산 순서를 지정할 수도 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let num6 = (1 + 2) * 10;

console.log(num6);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;30
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;13. 복합 대입 연산자&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;현재 변수의 값을 이용해 연산한 후 다시 같은 변수에 저장할 때 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let num7 = 10;

num7 += 20;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;위 코드는 다음 코드와 같은 의미이다.&lt;/p&gt;
&lt;pre class=&quot;ini&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;num7 = num7 + 20;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다른 연산자도 동일한 방식으로 사용할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;gcode&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;num7 += 20;
num7 -= 20;
num7 *= 20;
num7 /= 20;
num7 %= 10;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;반복적으로 값을 변경해야 할 때 코드를 간결하게 작성할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;14. 증감 연산자&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;숫자를 1 증가시키거나 감소시키기 위해 사용하는 연산자이다.&lt;/p&gt;
&lt;pre class=&quot;gcode&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let num8 = 10;

num8++;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;++는 값을 1 증가시키며&lt;span&gt;&amp;nbsp;&lt;/span&gt;--는 값을 1 감소시킨다.&lt;/p&gt;
&lt;pre class=&quot;brainfuck&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;num8++;
num8--;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;증감 연산자에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;전위 연산과 후위 연산&lt;/b&gt;이라는 차이도 존재한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;후위 연산&lt;/h2&gt;
&lt;pre class=&quot;maxima&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let num = 10;

console.log(num++);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 현재 값인&lt;span&gt;&amp;nbsp;&lt;/span&gt;10을 사용하고 그 이후 값이&lt;span&gt;&amp;nbsp;&lt;/span&gt;11이 된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;전위 연산&lt;/h2&gt;
&lt;pre class=&quot;maxima&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let num = 10;

console.log(++num);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;먼저 값을&lt;span&gt;&amp;nbsp;&lt;/span&gt;11로 증가시킨 다음 증가된 값을 사용한다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;즉,&lt;/p&gt;
&lt;pre class=&quot;ada&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;num++ : 현재 값을 먼저 사용 &amp;rarr; 이후 증가
++num : 먼저 증가 &amp;rarr; 증가한 값을 사용
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;단순히 한 줄에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;num++만 사용하는 경우에는 큰 차이가 없지만 다른 연산과 같이 사용할 때는 결과가 달라질 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;15. 논리 연산자&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Boolean 값을 이용한 논리 연산에 사용한다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript에서 대표적인 논리 연산자는&lt;span&gt;&amp;nbsp;&lt;/span&gt;||,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;amp;&amp;amp;,&lt;span&gt;&amp;nbsp;&lt;/span&gt;!이다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let or = true || false;
let and = true &amp;amp;&amp;amp; false;
let not = !true;

console.log(or, and, not);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;true false false
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;OR&lt;span&gt;&amp;nbsp;&lt;/span&gt;||&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;둘 중 하나라도&lt;span&gt;&amp;nbsp;&lt;/span&gt;true이면&lt;span&gt;&amp;nbsp;&lt;/span&gt;true이다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;true || false
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;true
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;AND&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;amp;&amp;amp;&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;두 값이 모두&lt;span&gt;&amp;nbsp;&lt;/span&gt;true여야&lt;span&gt;&amp;nbsp;&lt;/span&gt;true이다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;true &amp;amp;&amp;amp; false
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;false
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;NOT&lt;span&gt;&amp;nbsp;&lt;/span&gt;!&lt;/h3&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;Boolean 값을 반대로 바꾼다.&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;!true
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;false
&lt;/code&gt;&lt;/pre&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;16. 비교 연산자&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;두 값을 비교할 때 사용한다.&lt;/p&gt;
&lt;pre class=&quot;nix&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;let comp1 = 1 === &quot;1&quot;;
let comp2 = 1 !== 2;

console.log(comp1, comp2);
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;결과&lt;/p&gt;
&lt;pre class=&quot;yaml&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;false true
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;===는 두 값의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;값과 자료형까지 모두 같은지 확인&lt;/b&gt;한다.&lt;/p&gt;
&lt;pre class=&quot;basic&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;1 === &quot;1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;숫자&lt;span&gt;&amp;nbsp;&lt;/span&gt;1과 문자열&lt;span&gt;&amp;nbsp;&lt;/span&gt;&quot;1&quot;은 눈으로 보이는 값은 같지만 자료형이 다르기 때문에 결과는&lt;span&gt;&amp;nbsp;&lt;/span&gt;false이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;반대로&lt;span&gt;&amp;nbsp;&lt;/span&gt;!==는 두 값이 서로 다른지를 확인한다.&lt;/p&gt;
&lt;pre class=&quot;basic&quot; style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;code&gt;1 !== 2
&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;두 값이 다르기 때문에 결과는&lt;span&gt;&amp;nbsp;&lt;/span&gt;true이다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript에는&lt;span&gt;&amp;nbsp;&lt;/span&gt;==도 존재하지만 자동 형 변환이 발생할 수 있어 예상하지 못한 결과가 만들어질 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;따라서 일반적으로는&lt;span&gt;&amp;nbsp;&lt;/span&gt;==보다&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;===를 사용하는 습관을 들이는 것이 좋다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h1 style=&quot;color: #000000; text-align: start;&quot;&gt;정리&lt;/h1&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;이번에 공부한 JavaScript의 기본 문법을 정리하면 다음과 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구분내용&lt;/p&gt;
&lt;table style=&quot;color: #000000; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;let&lt;/td&gt;
&lt;td&gt;값을 변경할 수 있는 변수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;const&lt;/td&gt;
&lt;td&gt;재할당할 수 없는 상수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Number&lt;/td&gt;
&lt;td&gt;숫자 자료형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;문자열 자료형&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;td&gt;true,&lt;span&gt;&amp;nbsp;&lt;/span&gt;false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;의도적으로 값이 없음을 표현&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;undefined&lt;/td&gt;
&lt;td&gt;값이 아직 할당되지 않은 상태&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Number()&lt;/td&gt;
&lt;td&gt;문자열 등을 숫자로 변환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;String()&lt;/td&gt;
&lt;td&gt;값을 문자열로 변환&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+ - * / %&lt;/td&gt;
&lt;td&gt;산술 연산자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+= -= *= /=&lt;/td&gt;
&lt;td&gt;복합 대입 연산자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;++ --&lt;/td&gt;
&lt;td&gt;증감 연산자&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;`&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;=== !==&lt;/td&gt;
&lt;td&gt;비교 연산자&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;JavaScript는 자동으로 자료형을 변환해주는 경우가 많기 때문에 처음에는 편리해 보이지만, 이러한 특성 때문에 예상하지 못한 결과가 발생하기도 한다.&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특히 앞으로 조건문이나 함수 등을 공부할 때&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;자료형과 형 변환에 대한 이해가 중요할 것 같다.&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;다음에는 JavaScript의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;조건문과 반복문&lt;/b&gt;에 대해 정리해볼 예정이다.&lt;/p&gt;</description>
      <category>개발/Javascript</category>
      <category>js #javascript #기초 #it #컴공</category>
      <author>잼coding</author>
      <guid isPermaLink="true">https://jamin0619.tistory.com/23</guid>
      <comments>https://jamin0619.tistory.com/23#entry23comment</comments>
      <pubDate>Mon, 14 Sep 2026 19:51:36 +0900</pubDate>
    </item>
    <item>
      <title>V8 엔진 메모리 관리 및 GC 동작 원리</title>
      <link>https://jamin0619.tistory.com/22</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;1. V8 엔진 개요&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V8은 Google이 개발한 오픈소스 JavaScript 런타임 엔진으로, Chrome 브라우저와 Node.js의 핵심 실행 환경이다. V8은 JavaScript 소스 코드를 기계어로 컴파일하고 실행하며, 메모리 할당과 회수(Garbage Collection)를 전담한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V8의 핵심 구성 요소는 다음과 같다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;V8 Engine
├── Parser         &amp;mdash; JS 소스를 AST(추상 구문 트리)로 변환
├── Ignition       &amp;mdash; AST를 바이트코드로 해석&amp;middot;실행 (인터프리터)
├── TurboFan       &amp;mdash; 자주 실행되는 코드를 기계어로 최적화 (JIT 컴파일러)
└── Orinoco GC     &amp;mdash; 메모리 할당 및 가비지 컬렉션 전담
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript는 메모리를 개발자가 직접 해제하지 않는다. V8의 GC가 &quot;더 이상 참조되지 않는 객체&quot;를 자동으로 탐지하여 메모리를 회수한다.&lt;/p&gt;
&lt;h1&gt;&lt;b&gt;2. V8 힙(Heap) 구조&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V8은 객체를 저장하는 공간인 힙을 용도에 따라 여러 영역으로 분리하여 관리한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;495&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bftIHg/dJMcab5ua72/PsWb9LWoPZ1vKesjdJlqG1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bftIHg/dJMcab5ua72/PsWb9LWoPZ1vKesjdJlqG1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bftIHg/dJMcab5ua72/PsWb9LWoPZ1vKesjdJlqG1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbftIHg%2FdJMcab5ua72%2FPsWb9LWoPZ1vKesjdJlqG1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;880&quot; height=&quot;495&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;495&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;세대 가설 (Generational Hypothesis)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V8이 이러한 분리 구조를 채택한 이유는&amp;nbsp;&lt;b&gt;세대 가설&lt;/b&gt;에 근거한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;대부분의 객체는 생성 직후 금방 죽는다. 오래 살아남은 객체는 더 오래 살아남을 가능성이 높다.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 함수 안에서 생성되는 임시 배열, 루프 변수, VNode 등은 매우 짧게 살고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역 상태나 컴포넌트 인스턴스처럼 앱 구조에 필요한 객체는 오래 산다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 두 집단을 분리하면 짧게 사는 객체들만 빠르게 검사할 수 있어 GC 효율이 크게 높아진다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;3. Minor GC &amp;mdash; Scavenger 알고리즘&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.1 개요&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Minor GC는 Young Generation(Nursery + Intermediate) 영역만을 대상으로 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용하는 알고리즘은&amp;nbsp;&lt;b&gt;Cheney's Copying Algorithm(스캐빈저)&lt;/b&gt;&amp;nbsp;이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실행 시간: ~1ms (체감 불가)&lt;/li&gt;
&lt;li&gt;실행 빈도: Nursery가 꽉 찰 때마다 (수십 초 간격)&lt;/li&gt;
&lt;li&gt;STW(Stop-The-World): 매우 짧아 UI 영향 없음&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;3.2 동작 과정&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1780384928909&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[단계 1] Nursery 영역이 꽉 참
─────────────────────────────────────────────
Nursery
┌─────────────────────────────────────────┐
│ obj_A (rAF 임시 결과)  &amp;mdash; 참조 없음      │
│ obj_B (VNode 이전 버전) &amp;mdash; 참조 없음     │
│ obj_C (ref 객체)        &amp;mdash; 컴포넌트 참조 │
│ obj_D (BboxQueueEntry)  &amp;mdash; watch 참조    │
│ obj_E (계산 중간 배열)  &amp;mdash; 참조 없음     │
└─────────────────────────────────────────┘

[단계 2] 루트에서 참조 가능한 객체 탐색 (Mark)
─────────────────────────────────────────────
루트(Root): 현재 실행 중인 함수 스택, Vue 컴포넌트 트리, 전역 변수

obj_C &amp;rarr; 컴포넌트가 참조 중 &amp;rarr; 살아있음 ✓
obj_D &amp;rarr; watch 핸들러가 참조 중 &amp;rarr; 살아있음 ✓
obj_A, obj_B, obj_E &amp;rarr; 아무도 참조 안 함 &amp;rarr; 죽음 ✗

[단계 3] 살아있는 객체를 Intermediate 영역으로 복사 (Copy)
─────────────────────────────────────────────
Intermediate
┌──────────────────────┐
│ obj_C (복사됨)       │
│ obj_D (복사됨)       │
└──────────────────────┘

[단계 4] Nursery 전체 초기화 &amp;mdash; 죽은 객체 일괄 소거
─────────────────────────────────────────────
Nursery: 완전히 빈 상태 (메모리 재사용 가능)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.3 Intermediate &amp;rarr; Old Generation 승격 조건&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Intermediate에 있는 객체가 Minor GC에서 또 살아남으면 Old Generation으로 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, GC를 2회 이상 통과한 객체가 Old Generation의 주민이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;4. Major GC &amp;mdash; Mark-Sweep-Compact 알고리즘&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4.1 개요&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Major GC는 Old Generation 전체를 대상으로 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;알고리즘은&amp;nbsp;&lt;b&gt;Mark-Sweep-Compact&lt;/b&gt;&amp;nbsp;3단계로 구성된다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실행 시간: ~10ms ~ 100ms (프레임 드롭 가능성 있음)&lt;/li&gt;
&lt;li&gt;실행 조건: Old Generation이 임계치(힙 크기의 약 70%) 도달, 브라우저 idle 상태, 탭 백그라운드 전환&lt;/li&gt;
&lt;li&gt;STW: 일부 단계에서 발생 (V8은 Incremental Marking으로 분산 처리)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; &lt;span data-token-index=&quot;0&quot;&gt;4.2 동작 과정&lt;/span&gt; &lt;/b&gt;&lt;/h4&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cioM0I/dJMcaffNhvq/OXCxibeL51kfGFCbFkNBk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cioM0I/dJMcaffNhvq/OXCxibeL51kfGFCbFkNBk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cioM0I/dJMcaffNhvq/OXCxibeL51kfGFCbFkNBk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcioM0I%2FdJMcaffNhvq%2FOXCxibeL51kfGFCbFkNBk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1536&quot; height=&quot;1024&quot; data-origin-width=&quot;1536&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;5. 우리 프로젝트에서의 메모리 흐름&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5.1 Vue 반응형 객체의 생애 주기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vue의&amp;nbsp;ref,&amp;nbsp;computed,&amp;nbsp;watch는 모두 V8 힙의 객체다.&lt;/p&gt;
&lt;pre class=&quot;properties&quot;&gt;&lt;code&gt;컴포넌트 마운트
      &amp;darr;
setup() 실행
  const cameraId = ref('cam_1')          &amp;rarr; Nursery 할당
  const syncState = { bboxQueue: [] }    &amp;rarr; Nursery 할당
  const inference = computed(() =&amp;gt; ...)  &amp;rarr; Nursery 할당
      &amp;darr;
Minor GC 1회: 컴포넌트가 참조 중 &amp;rarr; Intermediate로 이동
Minor GC 2회: 여전히 살아있음   &amp;rarr; Old Generation으로 이동
      &amp;darr;
컴포넌트가 살아있는 동안 Old Generation 거주
      &amp;darr;
컴포넌트 언마운트
  Vue: 반응형 그래프 링크 해제
  JS: 참조 없어짐
      &amp;darr;
다음 Major GC: 루트에서 도달 불가 &amp;rarr; 수거
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5.2 rAF 루프의 Minor GC 활용&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;useBoundingBoxOverlay의 rAF(requestAnimationFrame) 루프는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매 프레임마다 임시 객체를 생성한다.&lt;/p&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;function drawLoop() {
  const entry = dequeueBbox()           // 매 프레임 생성
  const ctx = canvas.getContext('2d')   // 매 프레임 참조
  const { videoW, videoH } = computeVideoRect(...)  // 매 프레임 생성
  // ...
}  // 함수 끝: entry, ctx, videoW, videoH 참조 소멸
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 객체들은 함수 종료 즉시 참조가 없어지므로 다음 Minor GC에서 Nursery째로 소거된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실측 성능 프로파일에서 Minor GC의 톱니 패턴이 규칙적으로 나타난 것이 이를 증명한다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;6. 결론&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;V8 GC 관점 요약&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;V8의 세대별 GC는 객체의 생존 기간에 따라 Minor GC(Nursery 빠른 정리)와&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Major GC(Old Generation 전체 회수)로 역할을 분리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 설계 덕분에 rAF 루프처럼 매 프레임 생성&amp;middot;소멸하는 단명 객체는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Minor GC가 ~1ms 만에 처리하고, 컴포넌트&amp;middot;싱글턴 같은 장수 객체는&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Old Generation에서 안정적으로 관리된다.&lt;/p&gt;</description>
      <category>개발/Frontend</category>
      <category>vue #html #브라우저 #GC #heap #V8</category>
      <author>잼coding</author>
      <guid isPermaLink="true">https://jamin0619.tistory.com/22</guid>
      <comments>https://jamin0619.tistory.com/22#entry22comment</comments>
      <pubDate>Tue, 2 Jun 2026 16:24:31 +0900</pubDate>
    </item>
    <item>
      <title>1. Vue란 무엇인가?</title>
      <link>https://jamin0619.tistory.com/21</link>
      <description>&lt;h1&gt;Vue란 무엇인가? 자바스크립트 프레임워크 Vue 기초 정리&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Vue란?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vue(발음: /vjuː/, view와 유사)는 사용자 인터페이스(UI)를 구축하기 위한 자바스크립트 프레임워크이다. HTML, CSS, JavaScript를 기반으로 만들어졌으며, 선언적 렌더링과 컴포넌트 기반 구조를 통해 복잡한 웹 애플리케이션도 효율적으로 개발할 수 있도록 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쉽게 말하면, 화면을 구성하는 요소들을 작은 단위의 컴포넌트로 나누고 상태 변화에 따라 화면을 자동으로 업데이트해주는 도구라고 볼 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Vue의 핵심 특징&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;① 선언적 렌더링 (Declarative Rendering)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vue는 데이터 상태와 화면을 연결하여 개발자가 화면 결과를 직접 조작하지 않아도 되도록 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 데이터 값이 변경되면 HTML을 직접 수정하지 않아도 자동으로 화면이 변경된다.&lt;/p&gt;
&lt;pre class=&quot;django&quot;&gt;&lt;code&gt;&amp;lt;button&amp;gt;
  Count is: {{ count }}
&amp;lt;/button&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 예시에서 count 값만 변경하면 화면도 함께 업데이트된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;② 반응성 (Reactivity)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vue의 가장 큰 특징 중 하나는 반응형 시스템이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript 변수의 변경을 자동으로 감지하여 필요한 부분의 DOM만 효율적으로 다시 렌더링한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;const count = ref(0)

count.value++
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;별도로 화면 갱신 코드를 작성하지 않아도 UI가 즉시 변경된다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Vue가 &amp;lsquo;점진적 프레임워크&amp;rsquo;인 이유&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vue는 다양한 규모와 목적의 프로젝트에 유연하게 적용할 수 있도록 설계되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;활용 방식은 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;기존 HTML 페이지 일부 기능 강화&lt;/li&gt;
&lt;li&gt;웹 컴포넌트 형태로 삽입&lt;/li&gt;
&lt;li&gt;SPA(Single Page Application) 개발&lt;/li&gt;
&lt;li&gt;SSR(Server Side Rendering)&lt;/li&gt;
&lt;li&gt;SSG(Static Site Generation)&lt;/li&gt;
&lt;li&gt;모바일 및 데스크톱 애플리케이션 개발&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 작은 기능부터 대규모 서비스까지 단계적으로 확장할 수 있다는 특징이 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. 싱글 파일 컴포넌트(SFC)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vue에서는 일반적으로 .vue 파일을 사용하여 컴포넌트를 구성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 싱글 파일 컴포넌트(Single File Component, SFC)라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 파일 안에서 다음 요소를 함께 관리한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;lt;template&amp;gt; &amp;rarr; 화면 구조(HTML)&lt;/li&gt;
&lt;li&gt;&amp;lt;script&amp;gt; &amp;rarr; 로직(JavaScript)&lt;/li&gt;
&lt;li&gt;&amp;lt;style&amp;gt; &amp;rarr; 스타일(CSS)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시:&lt;/p&gt;
&lt;pre class=&quot;django&quot;&gt;&lt;code&gt;&amp;lt;script setup&amp;gt;
import { ref } from 'vue'

const count = ref(0)
&amp;lt;/script&amp;gt;

&amp;lt;template&amp;gt;
  &amp;lt;button&amp;gt;
    Count is: {{ count }}
  &amp;lt;/button&amp;gt;
&amp;lt;/template&amp;gt;

&amp;lt;style scoped&amp;gt;
button {
  font-weight: bold;
}
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구조와 역할이 명확하여 유지보수가 용이하다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;5. Vue의 두 가지 개발 방식&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vue는 컴포넌트를 작성할 때 두 가지 스타일을 제공한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;옵션 API (Options API)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체 형태로 상태와 메서드를 구성하는 방식이다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;export default {
  data() {
    return {
      count: 0
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특징&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;구조가 직관적이다&lt;/li&gt;
&lt;li&gt;초보자가 접근하기 쉽다&lt;/li&gt;
&lt;li&gt;this 기반으로 동작한다&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;컴포지션 API (Composition API)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;함수 중심으로 상태를 조합하는 방식이다.&lt;/p&gt;
&lt;pre class=&quot;dust&quot;&gt;&lt;code&gt;&amp;lt;script setup&amp;gt;
import { ref } from 'vue'

const count = ref(0)
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특징&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;재사용성과 확장성이 높다&lt;/li&gt;
&lt;li&gt;대규모 프로젝트에 유리하다&lt;/li&gt;
&lt;li&gt;로직 분리가 쉽다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 Vue 3에서는 &lt;b&gt;Composition API + SFC 조합&lt;/b&gt;이 권장되는 방식이다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;6. 어떤 방식을 선택해야 할까?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;학습 단계라면 이해하기 쉬운 방식부터 시작하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 프로젝트 기준으로는 다음과 같이 추천한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;간단한 프로젝트 &amp;rarr; 옵션 API&lt;/li&gt;
&lt;li&gt;중&amp;middot;대형 프로젝트 &amp;rarr; 컴포지션 API + SFC&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두 방식 모두 동일한 Vue의 핵심 개념을 기반으로 동작하기 때문에 하나를 익히면 다른 방식도 비교적 쉽게 이해할 수 있다.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;마무리&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Vue는 배우기 쉬운 문법과 강력한 반응형 시스템을 제공하는 프론트엔드 프레임워크이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 점진적 도입이 가능하고 컴포넌트 기반 개발을 지원하기 때문에 개인 프로젝트부터 대규모 서비스까지 폭넓게 활용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드 개발을 시작하려는 사람이라면 HTML, CSS, JavaScript 기본기를 학습한 뒤 Vue를 익혀보는 것을 추천한다.&lt;/p&gt;</description>
      <category>개발/Frontend</category>
      <author>잼coding</author>
      <guid isPermaLink="true">https://jamin0619.tistory.com/21</guid>
      <comments>https://jamin0619.tistory.com/21#entry21comment</comments>
      <pubDate>Tue, 2 Jun 2026 09:27:47 +0900</pubDate>
    </item>
    <item>
      <title>PySide6란 무엇인가? &amp;mdash; Python GUI 개발</title>
      <link>https://jamin0619.tistory.com/20</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;현재 회사에서 파이썬으로 GUI 프로그램을 만들기 위해 오픈소스를 찾던 도중, pyside라는 python GUI 툴이 있어서 그것에 대해&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세히 리뷰를 해볼려고 한다.&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. PySide6 소개&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PySide6는&amp;nbsp;Qt&amp;nbsp;Company가&amp;nbsp;공식&amp;nbsp;제공하는&amp;nbsp;Qt&amp;nbsp;6&amp;nbsp;프레임워크의&amp;nbsp;Python&amp;nbsp;바인딩이다.&amp;nbsp;Qt는&amp;nbsp;C++로&amp;nbsp;작성된&amp;nbsp;크로스&amp;nbsp;플랫폼&amp;nbsp;GUI&amp;nbsp;툴킷으로,&amp;nbsp;PySide6를&amp;nbsp;통해&amp;nbsp;Python에서&amp;nbsp;그&amp;nbsp;모든&amp;nbsp;기능을&amp;nbsp;사용할&amp;nbsp;수&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;- 개발사: The Qt Company (공식) &lt;br /&gt;- 라이선스: LGPL v3 / 상업용 라이선스 (무료 사용 가능) &lt;br /&gt;- 지원 플랫폼: Windows, macOS, Linux, Android, iOS, WebAssembly &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;설치 방법:&lt;/p&gt;
&lt;pre id=&quot;code_1777451444778&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install PySide6&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;&lt;b&gt;2. PySide6 vs PyQt6 &amp;mdash; 무엇이 다른가?&lt;/b&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;가장&amp;nbsp;많이&amp;nbsp;받는&amp;nbsp;질문이다.&amp;nbsp;둘&amp;nbsp;다&amp;nbsp;Qt를&amp;nbsp;Python에서&amp;nbsp;쓰기&amp;nbsp;위한&amp;nbsp;바인딩인데,&amp;nbsp;왜&amp;nbsp;두&amp;nbsp;개가&amp;nbsp;존재할까? &lt;br /&gt;&lt;br /&gt;항목 PySide6 PyQt6 &lt;br /&gt;개발사 Qt&amp;nbsp;Company&amp;nbsp;(공식) Riverbank&amp;nbsp;Computing&amp;nbsp;(서드파티) &lt;br /&gt;라이선스 LGPL&amp;nbsp;v3 GPL&amp;nbsp;v3&amp;nbsp;/&amp;nbsp;상업용&amp;nbsp;유료 &lt;br /&gt;상업적&amp;nbsp;사용 무료&amp;nbsp;가능 유료&amp;nbsp;라이선스&amp;nbsp;필요 &lt;br /&gt;API&amp;nbsp;호환성 거의&amp;nbsp;동일 거의&amp;nbsp;동일 &lt;br /&gt;Signal&amp;nbsp;선언 Signal() pyqtSignal() &lt;br /&gt;Slot&amp;nbsp;선언 Slot() pyqtSlot() &lt;br /&gt;공식&amp;nbsp;지원 Qt&amp;nbsp;로드맵&amp;nbsp;직접&amp;nbsp;반영 Qt&amp;nbsp;릴리즈&amp;nbsp;이후&amp;nbsp;업데이트 &lt;br /&gt;핵심&amp;nbsp;차이:&amp;nbsp;라이선스.&amp;nbsp;상업&amp;nbsp;앱을&amp;nbsp;만들&amp;nbsp;계획이라면&amp;nbsp;PySide6가&amp;nbsp;훨씬&amp;nbsp;유리하다.&amp;nbsp;API는&amp;nbsp;거의&amp;nbsp;동일하기&amp;nbsp;때문에&amp;nbsp;코드&amp;nbsp;마이그레이션도&amp;nbsp;어렵지&amp;nbsp;않다. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;3. 기본 구조 이해하기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PySide6 앱은 크게 세 가지 레이어로 구성된다.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;QApplication&amp;nbsp;&amp;nbsp;&amp;rarr;&amp;nbsp;&amp;nbsp;최상위&amp;nbsp;앱&amp;nbsp;객체&amp;nbsp;(이벤트&amp;nbsp;루프&amp;nbsp;관리) &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└──&amp;nbsp;QMainWindow&amp;nbsp;/&amp;nbsp;QWidget&amp;nbsp;&amp;nbsp;&amp;rarr;&amp;nbsp;&amp;nbsp;윈도우 &lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;└──&amp;nbsp;Layout&amp;nbsp;+&amp;nbsp;Widget&amp;nbsp;&amp;nbsp;&amp;rarr;&amp;nbsp;&amp;nbsp;실제&amp;nbsp;UI&amp;nbsp;구성요소&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최소 동작 예제&lt;/p&gt;
&lt;pre id=&quot;code_1777451464328&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import sys
from PySide6.QtWidgets import QApplication, QLabel, QMainWindow

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle(&quot;Hello PySide6&quot;)
        self.setFixedSize(400, 300)
        
        label = QLabel(&quot;안녕하세요!&quot;, self)
        label.move(150, 130)

app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;&lt;b&gt;4.&amp;nbsp;주요&amp;nbsp;모듈&amp;nbsp;구성&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;PySide6는&amp;nbsp;목적별로&amp;nbsp;모듈이&amp;nbsp;분리되어&amp;nbsp;있다. &lt;br /&gt;&lt;br /&gt;모듈 역할 &lt;br /&gt;- &lt;b&gt;QtWidgets&lt;/b&gt; 전통적인 UI 위젯 (버튼, 레이블, 리스트 등) &lt;br /&gt;- &lt;b&gt;QtCore&lt;/b&gt; Signal/Slot, Timer, Thread, 파일시스템 &lt;br /&gt;- &lt;b&gt;QtGui&lt;/b&gt; 폰트, 색상, 아이콘, 페인팅 &lt;br /&gt;- &lt;b&gt;QtNetwork&lt;/b&gt; HTTP, TCP/UDP 네트워킹 &lt;br /&gt;- &lt;b&gt;QtMultimedia&lt;/b&gt; 오디오, 비디오 재생 &lt;br /&gt;- &lt;b&gt;QtOpenGL OpenGL&lt;/b&gt; 렌더링 통합 &lt;br /&gt;- &lt;b&gt;QtWebEngineWidgets&lt;/b&gt; 내장 웹 브라우저 (Chromium 기반) &lt;br /&gt;- &lt;b&gt;QtQuick / QtQml &lt;/b&gt;QML 기반 모던 UI&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;&lt;b&gt;5. Signal &amp;amp; Slot &amp;mdash; Qt의 핵심 패턴&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PySide6에서&amp;nbsp;가장&amp;nbsp;중요한&amp;nbsp;개념이다.&amp;nbsp;이벤트&amp;nbsp;기반&amp;nbsp;프로그래밍의&amp;nbsp;근간. &lt;br /&gt;&lt;br /&gt;Signal:&amp;nbsp;&quot;이런&amp;nbsp;일이&amp;nbsp;일어났다&quot;고&amp;nbsp;알리는&amp;nbsp;신호 &lt;br /&gt;Slot: 그 신호를 받아 처리하는 함수&lt;/p&gt;
&lt;pre id=&quot;code_1777451500216&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from PySide6.QtCore import Signal, QObject

class Worker(QObject):
    finished = Signal(str)   # 커스텀 Signal 정의
    progress = Signal(int)

    def run(self):
        for i in range(100):
            self.progress.emit(i)   # Signal 발생
        self.finished.emit(&quot;완료!&quot;)
        # 연결
worker = Worker()
worker.finished.connect(lambda msg: print(msg))   # Slot 연결
worker.progress.connect(lambda v: print(f&quot;{v}%&quot;))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Signal은&amp;nbsp;타입을&amp;nbsp;명시할&amp;nbsp;수&amp;nbsp;있고,&amp;nbsp;여러&amp;nbsp;Slot에&amp;nbsp;동시에&amp;nbsp;연결할&amp;nbsp;수&amp;nbsp;있다.&amp;nbsp;disconnect()로&amp;nbsp;해제도&amp;nbsp;가능하다. &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. 레이아웃 시스템&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;픽셀&amp;nbsp;단위로&amp;nbsp;위젯을&amp;nbsp;배치하는&amp;nbsp;것은&amp;nbsp;유지보수&amp;nbsp;악몽이다.&amp;nbsp;Qt의&amp;nbsp;레이아웃&amp;nbsp;매니저를&amp;nbsp;사용하면&amp;nbsp;창&amp;nbsp;크기&amp;nbsp;변화에&amp;nbsp;자동으로&amp;nbsp;대응한다. &lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777451523577&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from PySide6.QtWidgets import QVBoxLayout, QHBoxLayout, QGridLayout
# 수직 배치
vbox = QVBoxLayout()
vbox.addWidget(button1)
vbox.addWidget(button2)

# 수평 배치
hbox = QHBoxLayout()
hbox.addWidget(label)
hbox.addStretch()   # 빈 공간으로 밀기
hbox.addWidget(button)

# 중첩
main_layout = QVBoxLayout()
main_layout.addLayout(hbox)
main_layout.addLayout(vbox)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;QSplitter를&amp;nbsp;사용하면&amp;nbsp;사용자가&amp;nbsp;패널&amp;nbsp;크기를&amp;nbsp;드래그로&amp;nbsp;조절할&amp;nbsp;수&amp;nbsp;있다. &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;7. 스타일링 &amp;mdash; Qt Style Sheets (QSS)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSS와 매우 유사한 문법으로 위젯을 스타일링할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1777451543919&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;app.setStyleSheet(&quot;&quot;&quot;
    QMainWindow {
        background-color: #1e1e1e;
    }
    QPushButton {
        background-color: #0078d4;
        color: white;
        border-radius: 6px;
        padding: 8px 16px;
        font-size: 14px;
    }
    QPushButton:hover {
        background-color: #1084d8;
    }
    QPushButton:pressed {
        background-color: #006cc1;
    }
&quot;&quot;&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;CSS와의 차이점:&lt;/b&gt;&lt;br /&gt;&lt;i&gt;선택자는 클래스명 기반 (QPushButton, QLabel) &lt;/i&gt;&lt;i&gt;pseudo-state는&amp;nbsp;:hover,&amp;nbsp;:pressed,&amp;nbsp;:checked,&amp;nbsp;:disabled&amp;nbsp;등 &lt;/i&gt;&lt;br /&gt;&lt;i&gt;setObjectName()으로 ID 선택자처럼 특정 위젯만 지정 가능&lt;/i&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;&lt;b&gt;8.&amp;nbsp;멀티스레딩&amp;nbsp;&amp;mdash;&amp;nbsp;QThread&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;GUI 앱에서 무거운 작업을 메인 스레드에서 실행하면 UI가 멈춘다. QThread와 Worker 패턴으로 해결한다.&lt;/p&gt;
&lt;pre id=&quot;code_1777451557570&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from PySide6.QtCore import QThread, QObject, Signal

class Worker(QObject):
    result = Signal(object)
    
    def process(self):
        # 오래 걸리는 작업
        data = heavy_computation()
        self.result.emit(data)

class MainWindow(QMainWindow):
    def start_task(self):
        self.thread = QThread()
        self.worker = Worker()
        self.worker.moveToThread(self.thread)
        
        self.thread.started.connect(self.worker.process)
        self.worker.result.connect(self.on_result)
        self.worker.result.connect(self.thread.quit)
        
        self.thread.start()
    
    def on_result(self, data):
        # GUI 업데이트는 항상 메인 스레드에서
        self.label.setText(str(data))&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;중요:&amp;nbsp;Qt에서&amp;nbsp;GUI&amp;nbsp;위젯은&amp;nbsp;반드시&amp;nbsp;메인&amp;nbsp;스레드에서만&amp;nbsp;건드려야&amp;nbsp;한다.&amp;nbsp;Worker에서&amp;nbsp;직접&amp;nbsp;위젯을&amp;nbsp;수정하면&amp;nbsp;크래시가&amp;nbsp;발생한다.&amp;nbsp;Signal을&amp;nbsp;통해&amp;nbsp;결과를&amp;nbsp;메인&amp;nbsp;스레드로&amp;nbsp;전달하는&amp;nbsp;패턴을&amp;nbsp;지켜야&amp;nbsp;한다. &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;br /&gt;&lt;b&gt;9. 커스텀 위젯 &amp;mdash; paintEvent 오버라이드&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 위젯으로 부족할 때 QPainter로 직접 그릴 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1777451565506&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from PySide6.QtWidgets import QWidget
from PySide6.QtGui import QPainter, QColor, QPen
from PySide6.QtCore import Qt

class CircleWidget(QWidget):
    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.RenderHint.Antialiasing)
        
        pen = QPen(QColor(&quot;#0078d4&quot;), 3)
        painter.setPen(pen)
        painter.setBrush(QColor(&quot;#e3f2fd&quot;))
        
        rect = self.rect().adjusted(10, 10, -10, -10)
        painter.drawEllipse(rect)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;paintEvent는&amp;nbsp;창이&amp;nbsp;다시&amp;nbsp;그려져야&amp;nbsp;할&amp;nbsp;때마다&amp;nbsp;자동&amp;nbsp;호출된다.&amp;nbsp;update()를&amp;nbsp;호출하면&amp;nbsp;강제로&amp;nbsp;다시&amp;nbsp;그리기를&amp;nbsp;트리거할&amp;nbsp;수&amp;nbsp;있다. &lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;10.&amp;nbsp;실용적인&amp;nbsp;팁&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;1. __init__ 에서 UI 메서드 분리하기&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777451574724&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def __init__(self):
    super().__init__()
    self._init_ui()
    self._connect_signals()&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;2.&amp;nbsp;리소스&amp;nbsp;파일은&amp;nbsp;Qt&amp;nbsp;Resource&amp;nbsp;System&amp;nbsp;활용&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;pyside6-rcc&amp;nbsp;resources.qrc&amp;nbsp;-o&amp;nbsp;resources_rc.py&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;3. UI 파일 (.ui) 로드&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1777451584073&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from PySide6.QtUiTools import QUiLoader
loader = QUiLoader()
ui = loader.load(&quot;main.ui&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;4. 앱 종료 시 정리&lt;/b&gt;&lt;br /&gt;app.aboutToQuit.connect(cleanup_function)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;5. 고DPI 스케일링&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;#&amp;nbsp;main&amp;nbsp;실행&amp;nbsp;전에&amp;nbsp;설정 &lt;br /&gt;os.environ[&quot;QT_AUTO_SCREEN_SCALE_FACTOR&quot;]&amp;nbsp;=&amp;nbsp;&quot;1&quot; &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;마치며&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;PySide6는 Python GUI 프레임워크 중 가장 강력하고 성숙한 선택지 중 하나다. 초기 학습 곡선이 있지만, Signal/Slot 패턴과 레이아웃 시스템에 익숙해지고 나면 복잡한 데스크톱 앱도 체계적으로 구성할 수 있다. 라이선스 측면에서도 LGPL이라 상업적 프로젝트에 부담 없이 사용할 수 있다는 점이 큰 장점이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발/Python</category>
      <category>python #라이브러리 #pyqt #pySide #PySIde6 #pyside6 #컴공 #개발자</category>
      <author>잼coding</author>
      <guid isPermaLink="true">https://jamin0619.tistory.com/20</guid>
      <comments>https://jamin0619.tistory.com/20#entry20comment</comments>
      <pubDate>Wed, 29 Apr 2026 17:39:12 +0900</pubDate>
    </item>
  </channel>
</rss>