<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>new__world.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Thu, 19 Aug 2021 12:56:14 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>new__world.log</title>
            <url>https://images.velog.io/images/new__world/profile/849bb4d1-28bc-41b4-84ef-bd64ee6e045e/프로필_002.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. new__world.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/new__world" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[부스트코스 파이썬(PY4E) 코칭스터디 1기 - 6주차 학습]]></title>
            <link>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-5%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5-t3gel3e7</link>
            <guid>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-5%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5-t3gel3e7</guid>
            <pubDate>Thu, 19 Aug 2021 12:56:14 GMT</pubDate>
            <description><![CDATA[<h1 id="📖딕셔너리-개념-및-특징">📖딕셔너리 개념 및 특징</h1>
<hr>
<h3 id="들어가며">들어가며</h3>
<p>지금까지는 리스트라는 컬렉션만 배웠었는데, 오늘은 파이썬의 강력한 컬렉션인 딕셔너리에 대해 배워도록 하자. 먼저 딕셔너리의 개념과 특징에 대해 살펴보고, 딕셔너리를 생성하는 방법과 딕셔너리에 저장된 값에 접근하는 방법을 배워 보도록 하자.</p>
<h3 id="학습-목표">학습 목표</h3>
<p>딕셔너리의 개념과 특징을 이해하고 딕셔너리를 생성하여 값에 접근할 수 있다.</p>
<h3 id="핵심-키워드">핵심 키워드</h3>
<ul>
<li>컬렉션</li>
<li>딕셔너리</li>
<li>연관 배열</li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용">학습 내용</h2>
<hr>
<h4 id="컬렉션collection">컬렉션(Collection)</h4>
<p>리스트나 딕셔너리 같은 변수를 가지는 상황이며 하나의 정보보다는 여러 개의 정보를 저장할 때 사용된다.</p>
<h4 id="리스트list">리스트(List)</h4>
<p>리스트는 순서대로 정리된 컬렉션이다. 데이터를 추가하면 항상 리스트의 끝에 추가되고 0부터 n-1번 위치까지 순서대로  n개의 원소가 저장되어 있다.</p>
<h4 id="딕셔너리dictionary">딕셔너리(Dictionary)</h4>
<p>리스트와 달리 딕셔너리에는 순서라는 것이 없다.
대신 키(Key)라는 것이 존재한다. 마치 물건에 포스트잇으로 라벨을 붙이는 것과 비슷하다. 딕셔너리는 다음과 같이 <code>dict()</code>라는 생성자를 통해 생성할 수 있다. 그리고 다음과 같이 생성할 수 있다.</p>
<pre><code>purse = dict() # 또는 purse = {} 와 같이 생성할 수도 있다.
purse[&#39;money&#39;] = 12 # &#39;money&#39;라는 키에 12라는 값 연결
purse[&#39;candy&#39;] = 3  # &#39;candy&#39;라는 키에 3이라는 값 연결
purse[&#39;tissues&#39;] = 75 # &#39;tissues&#39;라는 키에 75라는 값 연결</code></pre><p>이때 purse를 실행해보면 다음과 같은 형태로 출력이 된다. 여기서는 입력한 순서대로 나오지만 항상 입력한 순서대로 출력되는 것은 아니다.</p>
<pre><code>print(purse)
#{&#39;money&#39;: 12, &#39;candy&#39;: 3, &#39;tissues&#39;: 75}</code></pre><p>여기에서 candy라는 키에 저장된 값에 접근하려면 다음과 같이 대괄호 안에 키를 넣어서 접근할 수 있으며</p>
<pre><code>print(purse[&#39;candy&#39;])
#3</code></pre><p>접근한 내용을 업데이트할 수도 있다.</p>
<pre><code>purse[&#39;candy&#39;]  = purse[&#39;candy&#39;] + 2
print(purse)
#{&#39;money&#39;: 12, &#39;candy&#39;: 5, &#39;tissues&#39;: 75}</code></pre><h4 id="연관-배열associative-arrays">연관 배열(Associative Arrays)</h4>
<p>이렇게 키와 값이 연결되는 개념을 보통 <strong>연관 배열</strong>이라고 한다. 접근하는 방식이 리스트와 비슷하지만 키를 갖고 접근한다는 차이점이 있다. 여기에서 연관이 의미하는 것은 키와 값 사이의 연결 관계이다. 리스트에는 위치와 값 사이에 연결 관계가 있었다. 그러나 위치와의 연결 관계는 비교적 덜 강력하고 덜 유연하다. 그래서 대부분의 현대 프로그래밍 언어에는 연관 배열이라는 개념이 있다.</p>
<p><strong>연관 배열의 다양한 이름</strong></p>
<ul>
<li>property maps : Perl / PHP</li>
<li>hash maps : Java</li>
<li>property bags : C# /  .Net</li>
</ul>
<p><br><br><br><br></p>
<h1 id="📖튜플-개념-및-특징">📖튜플 개념 및 특징</h1>
<hr>
<h3 id="들어가며-1">들어가며</h3>
<p>파이썬의 강력한 컬렉션인 딕셔너리에 대해 배웠는데, 리스트와 비슷하지만 또 다른 특성을 갖고 있는 튜플에 대해 알아보자. 먼저 튜플과 비슷한 리스트와의 공통점과 차이점에 대해 알아보고, 튜플의 특성을 어떤 상황에서 활용할 수 있는지 간단히 살펴보자.</p>
<h3 id="학습-목표-1">학습 목표</h3>
<p>튜플과 리스트의 차이를 이해하고, 튜플의 특성을 활용해 문제를 해결할 수 있다.</p>
<h3 id="핵심-키워드-1">핵심 키워드</h3>
<ul>
<li>튜플(tuple)</li>
<li>immutable</li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용-1">학습 내용</h2>
<hr>
<h4 id="리스트list와-비슷한-컬렉션-튜플tuple">리스트(List)와 비슷한 컬렉션, 튜플(Tuple)</h4>
<p>튜플은 리스트와 굉장히 비슷하다.
다음 코드를 보면 리스트와의 차이는 단지 대괄호 대신 소괄호를 사용했다는 정도라는 것을 알 수 있다. 리스트와 같이 순서가 있어서 인덱스로 접근이 가능하고, 최대값도 찾을 수 있다.</p>
<pre><code>x = (&#39;Glenn&#39;, &#39;Sally&#39;, &#39;Joseph&#39;)
print(x[2])
# Joseph
y = ( 1, 9, 2 )
print(y)
# (1, 9, 2)
print(max(y))
# 9</code></pre><p>뿐만 아니라, for 반복문에서 반복을 시키면 리스트와 같이 원소를 순서대로 출력해준다.</p>
<pre><code>for iter in y :
    print(iter)
# 1
# 9
# 2</code></pre><h4 id="변경-불가능한-속성immutable">변경 불가능한 속성(immutable)</h4>
<p>하지만 리스트와 큰 차이가 있는데, 그것은 변경불가능(immutable), 즉 값을 변경할 수 없다는 특성이다. 예를 들면, 리스트에서는 다음과 같이 원소의 값을 변경할 수 있다.</p>
<pre><code>x = [9, 8, 7]
x[2] = 6
print(x)
# [9, 8, 6]</code></pre><p>하지만 다음과 같이 튜플일 경우에는 오류가 발생한다. 그 이유는 바로 변경 불가능한 속성 때문이다.</p>
<pre><code>x = (9, 8, 7)
x[2] = 6
print(x)

# ---------------------------------------------------------------------------
# TypeError                                 Traceback (most recent call last)
# &lt;ipython-input-4-6136e7d6cb90&gt; in &lt;module&gt;()
#       1 x = (9, 8, 7)
# ----&gt; 2 x[2] = 6
#       3 print(x)
# 
# TypeError: &#39;tuple&#39; object does not support item assignment</code></pre><p>이런 변경 불가능한 속성 때문에 튜플은 리스트보다 훨씬 더 효율적으로 동작한다. 용량도 적게 차지하고, 접근도 훨씬 빠르다. 물론, 이런 특성으로 인해 리스트에서 할 수 있는 일을 하지 못하는 경우도 있다. 다음 코드를 보면, <strong>한 번 생성된 튜플은 정렬하거나, 값을 추가하거나, 순서를 바꿀 수 없다.</strong></p>
<pre><code>x = (3, 2, 1)
x.sort()
# Traceback:
# AttributeError: &#39;tuple&#39; object has no attribute &#39;sort&#39;
x.append(5)
# Traceback:
# AttributeError: &#39;tuple&#39; object has no attribute &#39;append&#39;
x.reverse()
# Traceback:
# AttributeError: &#39;tuple&#39; object has no attribute &#39;reverse&#39;</code></pre><p>이외에도 리스트에서 할 수 있는 것 중 값을 변경하는 것들은 튜플에서 할 수 없다. 구체적으로 리스트에 내장된 함수와 튜플에 내장된 함수를 비교하면 다음과 같다.</p>
<pre><code> l = list()
 dir(l)
# [&#39;append&#39;, &#39;count&#39;, &#39;extend&#39;, &#39;index&#39;, &#39;insert&#39;, &#39;pop&#39;, &#39;remove&#39;, &#39;reverse&#39;, &#39;sort&#39;]

 t = tuple()
 dir(t)
# [&#39;count&#39;, &#39;index&#39;]</code></pre><p>즉, 값을 변경하지 않아도 되는 <code>count</code>, <code>index</code>와 같은 함수만 작동하는 것이다.</p>
<br>

<h4 id="튜플의-장점">튜플의 장점</h4>
<h4 id="임시-변수로-활용">임시 변수로 활용</h4>
<p>변경이 되지 않는 속성으로 인해 튜플은 파이썬에서 더 효율적으로 동작된다. 하지만 이런 특성은 입문하는 사람들에겐 큰 장점이 아닐 수도 있다. 그러면 튜플은 언제 사용하면 좋을까? 튜플을 다음과 같이 좌변에 사용하면 간단하게 여러 변수에 값을 넣을 수 있다. 단, 이럴 경우 좌변과 우변의 개수는 일치해야한다.</p>
<pre><code>(x, y) = (4, &#39;fred&#39;)
print(y)
# fred
(a, b) = (99, 98)
print(a)
# 99</code></pre><p>이와 같은 특성을 잘 활용하면 함수에서 여러 개의 값을 한꺼번에 반환할 수도 있다.</p>
<pre><code>def t() :
    return (10, 20)
x, y = t()
print(x, y)

# 10 20</code></pre><p>한가지 팁은, 소괄호를 사용하지 않아도 컴마로 여러 값을 나열하면 파이썬에서는 튜플로 인식하기 때문에 다음과 같이 간단히 사용할 수도 있다.</p>
<pre><code>x, y = 1, 10
print(x, y)
# 1 10

x, y = y, x
print(x, y)
# 10 1</code></pre><h4 id="딕셔너리를-처리하는데-활용">딕셔너리를 처리하는데 활용</h4>
<p>딕셔너리의 <code>items</code> 메소드는 딕셔너리에 저장된 각 키와 값의 한 쌍을 튜플로 이루어진 리스트 형태로 만들어준다. 따라서 다음과 같이 사용할 수도 있다.</p>
<pre><code>d = dict()
d[&#39;csev&#39;] = 2
d[&#39;cwen&#39;] = 4
for (k,v) in d.items(): 
    print(k, v)
# csev 2
# cwen 4

tups = d.items()
print(tups)
# dict_items([(&#39;csev&#39;, 2), (&#39;cwen&#39;, 4)])</code></pre><h4 id="여러-값에-대해-비교-가능">여러 값에 대해 비교 가능</h4>
<p>튜플의 또 다른 장점은 여러 값에 대해 비교가 가능하다는 점이다.
비교의 방법은 각 튜플의 가장 왼쪽 값끼리 비교한 후 둘의 값이 다를 경우에는 나머지 값들을 비교하지 않고 큰지, 작은지 여부를 판단한다. 만약 가장 왼쪽 값이 동일할 경우에는 그 다음 값을 비교하고, 그 값도 같으면 또 다음 값을 비교하는 형태로 비교가 진행된다.</p>
<pre><code> (0, 1, 2) &lt; (5, 1, 2)
# True 값을 가진다.
 (0, 1, 2000000) &lt; (0, 3, 4)
# True 값을 가진다.
 ( &#39;Jones&#39;, &#39;Sally&#39; ) &lt; (&#39;Jones&#39;, &#39;Sam&#39;)
# True 값을 가진다.
 ( &#39;Jones&#39;, &#39;Sally&#39;) &gt; (&#39;Adams&#39;, &#39;Sam&#39;)
# True 값을 가진다.</code></pre><p><br><br><br><br></p>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<hr>
<p>6주간의 부스트코스 파이썬 코칭스터디! 마지막 6주차 학습 끝!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[부스트코스 파이썬(PY4E) 코칭스터디 1기 - 5주차 학습]]></title>
            <link>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-5%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5</link>
            <guid>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-5%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5</guid>
            <pubDate>Fri, 13 Aug 2021 14:33:56 GMT</pubDate>
            <description><![CDATA[<h1 id="📖리스트의-개념-및-특징">📖리스트의 개념 및 특징</h1>
<hr>
<h3 id="들어가며">들어가며</h3>
<p>지금까지 우리는 하나의 값만을 할당하는 변수에 대해서 알아 보았다. 하지만 필요에 따라서 하나의 변수에 많은 데이터를 넣을 수도 있다. 파이썬에서는 이를 리스트라고 한다.</p>
<h3 id="학습-목표">학습 목표</h3>
<p>리스트의 개념에 대해서 이해하고 개별 값에 대해 접근하고 내장 함수를 활용할 수 있다.</p>
<h3 id="핵심-키워드">핵심 키워드</h3>
<ul>
<li>리스트</li>
<li>내장 함수</li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용">학습 내용</h2>
<hr>
<h4 id="프로그래밍">프로그래밍</h4>
<p>통상 프로그래밍은 알고리즘과 자료구조로 나눌 수가 있다. 알고리즘이 특정 문제를 해결하기 위한 규칙 또는 단계라면, 자료구조는 컴퓨터내에서 자료를 구조화 하는 특별한 방식이라고 생각할 수 있다.</p>
<h4 id="무엇이-컬렉셕이-아닌가">무엇이 컬렉셕이 아닌가?</h4>
<p>컬렉션이 무엇인지 알기 위해 우리는 컬렉션이 아닌 것을 알아야 한다. 하나의 변수에 새로운 값을 할당하게 되면 기존의 값은 사라지고 그 자리에 대체하게 된다. 즉, 하나의 변수에는 하나의 값만 할당하는 것을 우리는 배웠다. <strong>하나의 변수에 여러 값을 넣는 것이 가능하도록 하는 것이 컬렉션</strong>이다.</p>
<h4 id="리스트list">리스트(List)</h4>
<p>리스트는 컬렉션의 한 종류이다.</p>
<ol>
<li>리스트의 각 항목들은 <code>[]</code> 로 둘러싸게 된다.</li>
<li>리스트 내의 항목들에 대한 구분은 <code>,</code>로 구분한다.</li>
<li>리스트 내에 또 다른 리스트를 내포할 수 있다.</li>
<li>비어 있는 리스트를 만들 수 있다.</li>
<li>리스트의 항목들에 인덱스 값으로 접근할 수 있다.</li>
<li>리스트의 항목들은 바뀔 수 있다.</li>
</ol>
<pre><code>friends = [&#39;Joseph&#39;, &#39;Glenn&#39;, &#39;Sally&#39;]
carryon = [&#39;socks&#39;, &#39;shirt&#39;, &#39;perfume&#39;]
colors = [&#39;red&#39;, [&#39;yellow&#39;,&#39;blue&#39;], &#39;black&#39;]
emptyList = []
print(colors[0])
# red라고 출력됨
lotto = [2, 14, 26, 41, 63]
print(lotto)
# [2, 14, 26, 41, 63]이 출력됨
lotto[2] = 28
print(lotto)
# [2, 14, 28, 41, 63]이 출력됨`</code></pre><br>

<h4 id="len">len()</h4>
<p>리스트에서도 해당 리스트가 몇 개의 항목을 가지고 있는지를  <code>len()</code> 함수를 통해서 확인할 수 있다.</p>
<pre><code>friends = [&#39;Joseph&#39;, &#39; Glenn&#39;, &#39;Sally&#39;]
print(len(friends))
# 3으로 출력됨</code></pre><h4 id="range">range()</h4>
<p><code>range()</code> 함수는 인자로 전달되는 값에 따라서 숫자로 이루어진 리스트를 반환하게 된다.</p>
<pre><code>for i in range(5):
    print(i)

# 0
# 1
# 2
# 3
# 4 로 출력된다.</code></pre><p><br><br><br></p>
<h1 id="📖리스트-활용하기">📖리스트 활용하기</h1>
<hr>
<h3 id="들어가며-1">들어가며</h3>
<p>계속해서 리스트와 관련된 내장 함수들을 살펴보도록 하자.</p>
<h3 id="학습-목표-1">학습 목표</h3>
<p>리스트를 이해하고 내장 함수를 활용해 리스트를 만들 수 있다.</p>
<h3 id="핵심-키워드-1">핵심 키워드</h3>
<ul>
<li>리스트</li>
<li>내장 함수</li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용-1">학습 내용</h2>
<hr>
<h4 id="연산자-활용">연산자 활용</h4>
<ul>
<li>리스트 병합: 리스트 타입도 <code>+</code> 연산자를 활용해서 서로 다른 리스트를  더 할 수 있다.</li>
</ul>
<pre><code>a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print(c)
# [1, 2, 3, 4, 5, 6]로 출력된다.</code></pre><ul>
<li>리스트 슬라이싱: 리스트도 <code>:</code> 를 이용해 자를 수가 있다. 여기서 중요한 것은 예를 들어 <code>t[1:3]</code>과 같은 경우 3번째 인덱스에 해당하는 항목은 포함되지 않는다는 것이다.</li>
</ul>
<pre><code>t = [9, 41, 12, 3, 74, 15]
print(t[1:3])
print(t[:4])
print(t[3:])
print(t[:])

# [41, 12]
# [9, 41, 12, 3]
# [3, 74, 15]
# [9, 41, 12, 3, 74, 15] 로 출력된다.</code></pre><ul>
<li>dir() 메소드: 특정 타입에서  사용할 수 있는 메소드의 목록들을 볼 수 있는 함수도 있다.</li>
</ul>
<pre><code>x = list()
print(dir(x))</code></pre><ul>
<li>리스트 만들기: 빈 리스트 만들기 -&gt; 항목 추가하기 -&gt; 항목 정렬하기 -&gt; in을 활용해 &#39;Glenn&#39;이 친구 목록에 있는지 확인하기.</li>
</ul>
<pre><code>friends = list()
friends.append(&#39;Joseph&#39;)
friends.append(&#39;Glenn&#39;)
friends.append(&#39;Sally&#39;)
print(friends)
# [&#39;Joseph&#39;, &#39;Glenn&#39;, &#39;Sally&#39;]
friends.sort()
print(friends)
# [&#39;Glenn&#39;, &#39;Joseph&#39;, &#39;Sally&#39;]
print(&#39;Glenn&#39; in friends)
# True로 출력된다.</code></pre><p><br><br><br></p>
<h1 id="📖리스트를-활용해-원하는-값-추출하기">📖리스트를 활용해 원하는 값 추출하기</h1>
<hr>
<h3 id="들어가며-2">들어가며</h3>
<p>기본적인 메소드를 활용해서 생각보다 많은 일들을 할 수 있다는 것을 확인할 수 있다.</p>
<h3 id="학습-목표-2">학습 목표</h3>
<p>리스트의 개념을 이해하고 기존의 데이터에서 email만 추출할 수 있다.</p>
<h3 id="핵심-키워드-2">핵심 키워드</h3>
<ul>
<li>리스트</li>
<li>내장 함수</li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용-2">학습 내용</h2>
<hr>
<h4 id="문자열과-리스트">문자열과 리스트</h4>
<p>문자열과 리스트는 잘 어울려 사용된다.</p>
<pre><code>abc = &#39;With three words&#39;
stuff = abc.split()
print(stuff)

# [&#39;With&#39;, &#39;three&#39;, &#39;words&#39;] 로 출력된다.</code></pre><h4 id="구분자">구분자</h4>
<p>명시적으로 구분자를 넣어주지 않으면, 빈칸을 구분자로 인지하고 나누게 된다.</p>
<pre><code>words2 = &#39;first;second;third&#39;
stuff2 = words2.split()
print(stuff2)
# [&#39;first;second;third&#39;]
stuff2 = words2.split(&#39;;&#39;)
print(stuff2)
# [&#39;first&#39;, &#39;second&#39;, &#39;third&#39;]</code></pre><h4 id="이메일-주소-추출하기">이메일 주소 추출하기</h4>
<p>지금까지 배운 메소드와 자료구조를 활용하면 우리가 원하는 값만을 추출할 수가 있다.</p>
<pre><code>line = &#39;From stephen.marquard@uct.ac.za Sat Jan 5 09:14:16 2008&#39;
# line 에 uct.ac.za만 추출하는 방법을 찾아 보도록 하자.
words = line.split()
# words는 해당 라인을 빈칸을 구분자로 하여 리스트로 저장된다.
print(words[1])
# stephen.marquard@uct.ac.za이 출력된다.
email = words[1]
address = email.split(&#39;@&#39;)
print(address)
# [&#39;stephen.marquard&#39;, &#39;uct.ac.za&#39;] 가 출력된다.
print(address[1])
# uct.ac.za가 출력된다.</code></pre><p><br><br><br><br></p>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<hr>
<ul>
<li><a href="https://docs.python.org/3/tutorial/datastructures.html">리스트 자료구조</a> : 리스트에서 사용할 수 있는 메소드들에 대해 확인할 수 있다.)</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[부스트코스 파이썬(PY4E) 코칭스터디 1기 - 4주차 학습]]></title>
            <link>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-4%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5</link>
            <guid>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-4%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5</guid>
            <pubDate>Thu, 05 Aug 2021 17:19:52 GMT</pubDate>
            <description><![CDATA[<h1 id="📖문자열">📖문자열</h1>
<hr>
<h3 id="들어가며">들어가며</h3>
<p>데이터는 다양한 타입으로 저장된다. 특히 많이 사용하게 될 문자열은 빼놓을 수 없다. 파이썬의 문자열의 특성과 루프와의 활용될 접점을 찾아 보도록 하자.</p>
<h3 id="학습-목표">학습 목표</h3>
<p>문자열의 특성을 이해하고 루프와 함께 문자(Character) 타입을 출력할 수 있다.</p>
<h3 id="핵심-키워드">핵심 키워드</h3>
<ul>
<li>문자열 </li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용">학습 내용</h2>
<hr>
<h4 id="문자열">문자열</h4>
<p>문자열 타입과 관련하여서는 타입 변환, 인덱싱, len 함수, for 루프 활용을 이해하고 사용할 수 있으면 된다.</p>
<h4 id="1-문자열-읽기-타입-변환">1. 문자열 읽기, 타입 변환</h4>
<p>문자열을 사용한 데이터를 읽어 오게 되면 우리는 에러나 사용자 입력에 대해 많은 대처를 할 수 있게 된다. 또한, 사용자 입력으로 들어오는 값은 문자열 타입으로 입력되므로 입력된 값으로 다른 무엇인가를 하기를 원한다면 적절한 타입 변환을 해줘야 한다.</p>
<pre><code>name = input(&#39;Enter:&#39;)
print(type(name))
print(name)

# &gt; Enter: 123 으로 입력한다.
# 인풋값 123의 타입은 &lt;class &#39;str&#39;&gt;과 같다.
# 123으로 출력된다.</code></pre><h4 id="2-문자열의-내부-들여다-보기">2. 문자열의 내부 들여다 보기</h4>
<p>우리는 특정 문자열을 구성하고 있는 개별 문자 값에 <strong>인덱스</strong>를 활용해서 접근할 수 있다. 여기서 유의해야 할 것은 첫 번째 오는 문자에 대한 <strong>인덱스는 0부터 시작</strong>한다는 점이다. 만약 해당 문자열이 가지고 있는 인덱스를 넘어서는 값을 호출하게 되면 오류가 발생하게 된다.</p>
<pre><code>fruite = &#39;banana&#39;
letter = fruit[0]
print(letter)
letter = fruit[1]
print(letter)
letter = fruit[2]
print(letter)

# b로 출력
# a로 출력
# n로 출력</code></pre><h4 id="3-len-함수">3. len 함수</h4>
<p>문자열에  대해서 우리는 <code>len()</code> 내장 함수를 활용해서 <strong>문자열의 길이</strong>를 알 수 있다. 예를 들어, <code>len(banana)</code> 라고 한다면 banana가 몇 개의 문자로 구성되어 있는지를 알 수 있게 되는 것이다.</p>
<pre><code>fruit = &#39;banana&#39;
print(len(fruit))

# 6으로 출력된다.</code></pre><h4 id="4-문자열의-길이만큼-루프-실행">4. 문자열의 길이만큼 루프 실행</h4>
<p>우리는 <code>len()</code> 함수를 활용하면 문자열의 길이 만큼 루프를 실행할 수 있다.</p>
<pre><code>fruit = &#39;banana&#39;
index = 0

# while 루프

while index &lt; len(fruit) :
    letter = fruit[index]
    print(index, letter)
    index = index + 1

# 0 b
# 1 a
# 2 n
# 3 a
# 4 n
# 5 a

# for 루프

for letter in fruit :
    print(letter)</code></pre><p><br><br><br><br></p>
<h1 id="📖파일-열기">📖파일 열기</h1>
<hr>
<h3 id="들어가며-1">들어가며</h3>
<p>저장된 텍스트 파일을 열려고 할 때 단순히 더블클릭만으로 우리는 목적을 달성할 수 있다. 하지만 파이썬에서는 텍스트 파일을 열기 위해 어떻게 해야 할까?</p>
<h3 id="학습-목표-1">학습 목표</h3>
<p>파일이 어떠한 방식으로 열리는 것인지 이해하고 파일을 열기 위한 <code>open()</code> 함수를 사용할 수 있다. 텍스트 파일의 구성과 이와 관련된 기본적인 코드들을 이해하고 사용할 수 있다.</p>
<h3 id="핵심-키워드-1">핵심 키워드</h3>
<ul>
<li><code>open()</code> 함수</li>
<li>개행문자</li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용-1">학습 내용</h2>
<hr>
<h4 id="텍스트-파일은-무엇인가">텍스트 파일은 무엇인가?</h4>
<p>텍스트 파일은 연속적으로 연결되어 있는 <strong>줄글들의 집합</strong>이라고 생각할 수 있다. 우리는 지금까지 많은 텍스트 파일을 만들어 왔다. 그럼 텍스트 파일을 열고 처리하는 것과 관련된 몇 가지 함수들을 살펴보도록 하자.</p>
<h4 id="open">open()</h4>
<p>파일을 여는 것은 <code>open()</code> 함수를 이용해 달성할 수 있다. <code>open()</code> 함수는 <code>handle</code>을 반환하게 되고 <code>handle</code>은 파일에 대한 작업을 수행하기 위해 사용된다. <strong><code>handle</code></strong>은 텍스트가 파일 형태, 메모리에 저장된 문자열의 형태, 웹 사이트에서 존재하는 형태와 같이 다른 방식으로 저장되어 있는 <strong>텍스트를 처리하는 하나의 표준화된 방식</strong>이다. 또한, 많은 양의 문자 파일을 한꺼번에 읽어 발생할 수 있는 성능의 문제를 handle은 점진적으로 읽어 방지한다.</p>
<pre><code>fhand = open(&#39;hello.txt&#39;,&#39;r&#39;)

# open(&#39;파일명입력&#39;,&#39;모드 선택&#39;)
# 1. 파일명 입력
# 파일명은 문자열 타입으로 입력하며, 확장자까지 포함시켜 준다.
# 2. 모드 선택
# 모드에서는 w 또는 r 두가지를 선택할 수 있다. &#39;w&#39;는 파일을 작성할  때 사용하며, &#39;r&#39;은 파일을 읽을 때 사용한다.</code></pre><br>

<h4 id="개행-문자">개행 문자</h4>
<p>파이썬에서 행을 바꾸는 문자인 개행 문자는 <code>&#39;\n&#39;</code> 이다. <code>print()</code> 함수를 사용하게 되면 해당 함수에 의해 <code>&#39;\n&#39;</code>가 발생하게 된다. 여기서 중요한 것은 <code>\n&#39;</code> 도 <strong>하나의 문자</strong>라는 점이다. 아래에 보는 것처럼 문자열의 길이를 확인하기 위해 <code>len()</code> 함수를 호출해 보면 <code>&#39;Hello World!&#39;</code>와 <code>&#39;Hello\nWorld!&#39;</code> 길이가 동일한 것을 확인할 수 있다.</p>
<pre><code>stuff1 = &#39;Hello World!&#39;
print(stuff1)
print(len(stuff1))
stuff2 = &#39;Hello\nWorld!&#39;
print(stuff2)
print(len(stuff2))

# Hello World!
# 12
# Hello
# World!
# 12</code></pre><p><br><br><br></p>
<h2 id="📖quiz-6">📖Quiz 6</h2>
<hr>
<p><img src="https://images.velog.io/images/new__world/post/01f68059-9987-4f15-85e2-edb0251479d5/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/657d4e49-3a65-4b84-af65-4647d881d8a1/image.png" alt=""></p>
<p><br><br><br><br></p>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<hr>
<p>Quiz는 6까지만 있고 이후에는 퀴즈가 없다. 부스트코스 팀 과제를 올리고 싶은데 저작권 문제로 올리지 못하는게 정말 아쉽다!😥</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[부스트코스 파이썬(PY4E) 코칭스터디 1기 - 3주차 학습]]></title>
            <link>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-3%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5</link>
            <guid>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-3%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5</guid>
            <pubDate>Fri, 30 Jul 2021 14:35:34 GMT</pubDate>
            <description><![CDATA[<h1 id="📖-while-루프">📖 while 루프</h1>
<hr>
<h3 id="들어가며">들어가며</h3>
<p>컴퓨터가 인간보다 나은점은 하나의 작업을 반복적으로 빠르게 수행할 수 있다는 것이다. 이를 루프라고 하며, 파이썬에서는 어떤식으로 반복작업에 대한 코드를 작성하는지 살펴 보도록 하자.</p>
<h3 id="학습-목표">학습 목표</h3>
<p>파이썬에서의 반복작업은 어떤식으로 수행되는지 이해하고 활용할 수 있다.</p>
<h3 id="핵심-키워드">핵심 키워드</h3>
<ul>
<li>while 루프</li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용">학습 내용</h2>
<hr>
<h4 id="while-루프">while 루프</h4>
<p>아래의 코드를 살펴 보면, <code>while</code> 과 <code>:(콜론)</code> 사이에 오는 조건문이 참의 값을 가지는 경우에는 <code>:(콜론)</code> 이하의 코드가 반복해서 작동하게 된다. 통상적으로 while문을 자주 사용하게 된다면 자신의 코드를 되돌아볼 필요가 있다. 물론 while은 반복적으로 작업할 수 있도록 해주는 편리한 문법이지만 무한루프에 빠질 수 있는 단점도 내포하고 있기 때문이다.</p>
<pre><code>n = 5

while n &gt; 0 :
  print(n)
  n = n - 1

print(&#39;Blastoff!&#39;)
print(n)</code></pre><h4 id="루프loop-제어하기">루프(Loop) 제어하기</h4>
<p><strong>break</strong> 루프가 <code>break</code>를 만나게 되면 해당 루프는 실행이 종료 되고 while문 바로 뒤의 코드를 실행하게 된다.</p>
<pre><code>while True :
  line = input(&#39;&gt;&#39;)
  if line == &#39;done&#39; :
    break
  print(line)
print(&#39;Done!&#39;)

# &lt; hello there로 입력
# hello there로 출력됨
# &gt; finished로 입력
# finished로 출력됨
# &gt; done로 입력
# Done!으로 출력됨</code></pre><h4 id="continue">continue</h4>
<p>루프가 <code>continue</code>를 만나게 되면 해당 루프는 실행이 종료되고 루프가 시작된 지점부터 다시 루프를 실행하게 된다.</p>
<pre><code>while True:
    line = input(&#39;&gt; &#39;)
    if line[0] == &#39;#&#39; :
        continue
    if line == &#39;done&#39; :
        break
    print(line)
print(&#39;Done!&#39;)

# &gt; hello there 입력
# hello there로 출력
# # don&#39;t print this &#39;#&#39;을 입력하게 되면 continue를 만나게 되고 continue는 loop의 시작점으로 다시 돌아가서 loop를 실행하게 된다.
# &gt; print this! 입력
# print this!로 출력
# &gt; done 입력
# Done!으로 출력 done을 입력하게 되면 break를 만나게 되고 break는 loop끝나는 점 바로 다음에 오는 코드를 실행하게 된다.</code></pre><p><br><br><br></p>
<h2 id="📖quiz-5">📖Quiz 5</h2>
<hr>
<p><img src="https://images.velog.io/images/new__world/post/0c2e914a-6a12-411d-b30f-153cf380d719/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/42254817-c886-40c3-b30b-d1d4d2426176/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[부스트코스 파이썬(PY4E) 코칭스터디 1기 - 2주차 학습]]></title>
            <link>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-2%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5</link>
            <guid>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-2%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5</guid>
            <pubDate>Sat, 24 Jul 2021 15:40:55 GMT</pubDate>
            <description><![CDATA[<h1 id="📖조건문if-else">📖조건문(if else)</h1>
<hr>
<h3 id="들어가며">들어가며</h3>
<p>어린 시절 한번쯤은 해보았을 &#39;스무고개&#39;라는 게임은 질문자가 질문을 하면, 답변자는 Yes 또는 No의 대답을 하는데, 질문자는 20개의 질문만으로 답을 맞춰야 하는 게임이다. 스무고개는 하나의 정답을 맞추기 위해 트리 구조를 만든다면, 컴퓨터의 결정 트리는 Yes 또는 No 각각의 경우에 맞춰 컴퓨터가 동작할 수 있게 프로그래밍 하는 것이다. 이를 <strong>흐름제어(Control Flow)</strong>라고 한다.</p>
<h3 id="학습-목표">학습 목표</h3>
<p>조건부 실행(Conditional Execution)에 대해서 알아보려 한다.
조건부 실행은 우리의 코드가 무언가가 <strong>검사</strong>를 하거나 <strong>결정</strong>을 내릴 때 사용한다. 파이썬이 명령문을 실행시키거나 넘어가는 방법을 알아보도록 하자.</p>
<h3 id="핵심-키워드">핵심 키워드</h3>
<ul>
<li>조건부 실행(Conditional Execution)</li>
<li>들여쓰기</li>
<li>if</li>
<li>else</li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용">학습 내용</h2>
<hr>
<h3 id="if문">if문</h3>
<p>if문의 기본적인 형태는 아래와 같다.</p>
<p><img src="https://images.velog.io/images/new__world/post/4bbead03-01c2-4ad8-9441-d2a91921a4d4/image.png" alt=""></p>
<br>

<h3 id="비교-연산자">비교 연산자</h3>
<p>조건문의 참 또는 거짓을 판별하기 위해 사용되는 비교 연산자들이 있다. 아래와 같은 비교 연산자들을 사용한다.</p>
<table>
<thead>
<tr>
<th align="center">연산자</th>
<th>의미</th>
<th>예시</th>
</tr>
</thead>
<tbody><tr>
<td align="center">&gt;</td>
<td>x가 y보다 클 때 True, 그 외에는 False</td>
<td>x &gt; y</td>
</tr>
<tr>
<td align="center">&lt;</td>
<td>x가 y보다 작을 때 True, 그 외에는 False</td>
<td>x &lt; y</td>
</tr>
<tr>
<td align="center">&gt;=</td>
<td>x가 y보다 크거나 같을 때 True, 그 외에는 False</td>
<td>x &gt;= y</td>
</tr>
<tr>
<td align="center">&lt;=</td>
<td>x가 y보다 작거나 같을 때 True, 그 외에는 False</td>
<td>x &lt;=y</td>
</tr>
<tr>
<td align="center">==</td>
<td>x와 y가 같을 때 True, 그 외에는 False</td>
<td>x == y</td>
</tr>
<tr>
<td align="center">!=</td>
<td>x와 y가 다를 때 True, 그 외에는 False</td>
<td>x != y</td>
</tr>
</tbody></table>
<br>

<h3 id="들여-쓰기-indentation">들여 쓰기 (indentation)</h3>
<p>파이썬에서는 들여쓰기를 매우 엄격하게 생각한다.
들여쓰기가 제대로 되어 있지 않다면 파이썬은 <strong>문법 에러</strong>를 통해 우리에게 동무을 요청하게 된다.</p>
<p><img src="https://images.velog.io/images/new__world/post/d7c83850-a084-401a-8788-0f22b5579f4d/image.png" alt=""></p>
<p>조건문에서 x가 가진 값이 10보다 작기 때문에 Smaller가 출력이 되겠다고 생각하겠지만, 들여쓰기를 제대로 하지 않았기 때문에 파이썬은 아래와 같이 <strong>들여쓰기 에러</strong>를 통해 들여쓰기가 잘못되었어! 라고 이야기 해준다.</p>
<p><code>IndentationError: expected an indented block</code></p>
<p>통상 들여쓰기는 <code>Tab</code> 또는 <code>Space</code> 네 번 과 같다.
컴퓨터가 탭을 잘못 인식하는 경우도 있으므로 <code>Tab</code> 보다는 <code>Space</code> 네 번으로 사용하도록 하자.</p>
<br>

<h3 id="단일-if문-if-else문">단일 if문, if else문</h3>
<h4 id="단일-if-문">단일 if 문</h4>
<p>단일 if문으로 사용하는 경우, 조건문이 참인 경우에만 미리 입력해 놓은 실행코드를 실행하게 된다.</p>
<h4 id="if-else-문">if else 문</h4>
<p>첫번째 조건문의 조건이 거짓인 경우에 대해 처리하기 위해 우리는 else를 사용할 수가 있다. 즉, 첫번째 if문의 조건이 거짓인 경우 else문 이하의 실행코드가 실행된다.</p>
<p><img src="https://images.velog.io/images/new__world/post/68540296-9e8f-4a0a-b635-9af9860094dc/image.png" alt=""></p>
<br>

<h3 id="주의사항">주의사항</h3>
<p>조건문(if, else)을 사용할 떄에는 주의할 점이 2가지 있다.</p>
<ul>
<li>조건문 후에 <code>: (콜론)</code>을 찍어야 한다.</li>
<li>조건문이 참일 경우 실행할 코드는 <code>들여쓰기</code>를 해야한다.</li>
</ul>
<p>코드를 실행시켰는데 에러가 난다면 위 두 조건을 제대로 만족하였는지 확인해보자!</p>
<p><br><br><br></p>
<h1 id="📖조건문elif과-예외처리try-except">📖조건문(elif)과 예외처리(try, except)</h1>
<hr>
<h3 id="들어가며-1">들어가며</h3>
<p>단일 if 문을 통해 조건문의 활용 가능성을 파악하였다. 지금부터는 심화과정으로 if ... else 문과 다중 분기를 배워보도록 하자.</p>
<h3 id="학습-목표-1">학습 목표</h3>
<p>다중 분기(Multi-way Decision) 조건문을 이해하고 사용할 수 있다.
try / except 문을 이용하여 오류를 처리 할 수 있다.</p>
<h3 id="핵심-키워드-1">핵심 키워드</h3>
<ul>
<li>다중 분기 (Multi-way Decision)</li>
<li>try / except</li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용-1">학습 내용</h2>
<hr>
<h3 id="다중-분기-multi-way-decisions">다중 분기 (Multi-way decisions)</h3>
<p>우리는 하나의 조건문 블럭에 프로그래머의 필요에 의해 조건문들을 추가할 수 있다. <code>elif</code> 라는 예약어를 통해서 가능하다.</p>
<p><img src="https://images.velog.io/images/new__world/post/2778ffa1-56a9-40b5-b209-d129f59ae9a0/image.png" alt=""></p>
<h4 id="try--except">try / except</h4>
<p>파이썬에서는 발생할 수 있는 error에 대해서 프로그래머가 미리 대처를 할 수 있도록 하였다. 이는 try / except로 가능하다.</p>
<p><img src="https://images.velog.io/images/new__world/post/b432cdd4-1633-4b4d-94b6-14d4ab3b0333/image.png" alt=""></p>
<p>예를 들어 사용자가 입력값으로 숫자만 넣어야 하는 경우 문자를 넣었을 때 프로그램이 종료 되고 멈출 것이 아니라, 올바른 입력값을 넣도록 하는 것이 합리적인 방법이다.</p>
<p><br><br><br></p>
<h1 id="📖함수">📖함수</h1>
<hr>
<h3 id="들어가며-2">들어가며</h3>
<p>함수는 하나의 박스라고 생각하면 된다. 프로그래밍에서 함수를 사용하는 이유는 반복적으로 실행되어야하는 코드의 묶음을 프로그래머가 기억하기 쉬운 이름으로 저장하여 반복적으로 호출하고 싶을 때 함수를 사용한다. 파이썬에서는 어떻게 함수를 정의하고 호출하는지 살펴보도록 하자.</p>
<h3 id="학습-목표-2">학습 목표</h3>
<p>함수의 개념을 이해하고 내장 함수를 잘 사용 할 수 있다.</p>
<h3 id="핵심-키워드-2">핵심 키워드</h3>
<ul>
<li>함수</li>
<li>내장 함수</li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용-2">학습 내용</h2>
<hr>
<h3 id="함수function">함수(Function)</h3>
<p>함수는 반복적으로 호출해야 하는 코드의 묶음을 하나의 블럭으로 만들어 이름을 붙여 <strong>재사용률</strong>을 높인 <strong>&quot;코드의 묶음&quot;</strong>이다.</p>
<p>예를 들어, 이를 닦는다를 어린 아이에게 가르친다고 생각해 보자. 그리고 아이한테는 각 단계를 매일 하나하나 알려줘야 한다고 가정해 보자.</p>
<ol>
<li>치약과 칫솔을 꺼낸다 </li>
<li>치약을 칫솔에 1cm가량 바른다 </li>
<li>물을 묻힌다 </li>
<li>윗니를 닦는다.</li>
<li>아랫니를 닦는다.</li>
<li>물로 헹군다.</li>
</ol>
<p>만약, 위와 같은 과정을 매일 반복해서 알려줘야 한다면, 비효율적인 반복적인 일이 될거다.</p>
<p>이것을 하나의 함수로 정의를 한다면 아래와 같이 될 것이며, <code>양치질()</code>이라는 함수의 이름만 호출해주게 되면 <code>: (콜론)</code> 이후에 입력해 놓은 실행 코드를 순차적으로 실행하게 된다.</p>
<p><img src="https://images.velog.io/images/new__world/post/4821ace5-62cf-4db3-85b6-507f6dd249bb/image.png" alt=""></p>
<br>

<h3 id="내장-함수">내장 함수</h3>
<p>파이썬에는 이미 정의된 함수들이 있다. 우리가 지금까지 사용해 왔던 내장 함수들은 아래와 같다.</p>
<p><img src="https://images.velog.io/images/new__world/post/545031ea-e60b-458e-b66b-e3fa8dcee5af/image.png" alt=""></p>
<p><br><br><br></p>
<h1 id="📖함수-만들기">📖함수 만들기</h1>
<hr>
<h3 id="들어가며-3">들어가며</h3>
<p>반복적으로 실행되어야 하는 코드의 덩어리를 우리가 쉽게 호출 할 수 있는 이름으로 정의하여 한번의 호출로 함수내의 실행코드를 순차적으로 실행하고 싶을 때 우리는 함수를 사용한다고 했다. 지금부터는 함수에 입력값과 출력값에 대해서 살펴 보도록 하자.</p>
<h3 id="학습-목표-3">학습 목표</h3>
<p>함수의 개념을 이해하고 나만의 함수를 만들 수 있다.
매개변수를 사용하는 정의된 함수를 호출할 때 인자를 전달하여 원하는 결과를 볼 수 있다.</p>
<h3 id="핵심-키워드-3">핵심 키워드</h3>
<ul>
<li>함수</li>
<li>인자(Argument)</li>
<li>매개변수(Parameter)</li>
</ul>
<p><br><br><br></p>
<h2 id="학습-내용-3">학습 내용</h2>
<hr>
<h3 id="우리만의-함수-만들기">우리만의 함수 만들기</h3>
<p>함수를 만드는 과정에서 가장 중요한 것은 저장과 호출에 대한 이해이다. 앞서 살펴본 것처럼 함수를 저장하기 위해서는 <code>def</code> 라는 예약어를 사용한다.</p>
<pre><code>def greeting() :
  print(&quot;Hello World&quot;)</code></pre><p><code>:(콜론)</code> 뒤에 우리가 실행하고자 하는 실행 코드를 입력하는 것으로 우리가 원하는 결과(만약 &quot;Hello World&quot; 가 출력되기를 바란다면)를 기대할 수는 없다. 여기까지는 함수를 정의하는 단계이다. 지금부터는 함수 호출 방법이다. 우리가 원하는 결과를 즉, Hello World가 실행되기를 바란다면 우리가 정의한 이름으로 저장된 함수를 호출해야 한다.
여기서는 <code>greeting()</code> 이라는 이름으로 호출하면 된다.</p>
<pre><code>def greeting():
  print(&quot;Hello World&quot;)

greeting()
# Hello World가 출력된다.</code></pre><h3 id="인자argument">인자(Argument)</h3>
<p>인자란 함수를 호출할 때 <strong>전달하는 값</strong>을 말한다. 넘겨 받는 수 또는 값이라고 생각하면 쉽게 이해할 수 있다! 앞서 사용했었던 print 함수에 들어가는 문자열도 인자이다.</p>
<h3 id="매개변수parameters">매개변수(Parameters)</h3>
<p>매개변수는 함수가 정의된 곳에서 <strong>변수처럼 사용하는 것</strong>을 말한다.</p>
<pre><code>def greeting(lang):
  print(lang)

greeting(&quot;Hello World&quot;)

# Hello World가 출력된다.</code></pre><h3 id="반환값return-value">반환값(Return Value)</h3>
<p>종종 함수는 함수가 정의된 곳에서 전달받은 매개변수를 이용해 프로그래머가 의도한 코드를 실행한 뒤, 계산 결과인 값을 반환 할 수도 있다. 이와 같은 상황이라면 당연히 함수를 다른 함수의 인자로 사용 할 수도 있다.</p>
<pre><code>def greet():
  return &quot;Hello&quot;

print(greet(), &quot;Connect&quot;)
print(greet(), &quot;Python&quot;)

# Hello Connect으로 출력된다.
# Hello Python으로 출력된다.</code></pre><h3 id="multiple-매개변수--인자">Multiple 매개변수 / 인자</h3>
<p>여러개의 매개변수를 받는 함수를 만들 수도 있다. 더하기 함수를 만들어 보도록 하자!</p>
<pre><code>def add(left, right):
  return left + right

print(add(1, 2))

# 3으로 출력 된다.</code></pre><p><br><br><br></p>
<h1 id="퀴즈">퀴즈</h1>
<h2 id="📖quiz-3">📖Quiz 3</h2>
<hr>
<p><img src="https://images.velog.io/images/new__world/post/f4754011-3d0e-44b5-8b86-ccc32ef73874/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/e001e0e8-e630-4d2e-853d-d9cf4b2273f2/image.png" alt=""></p>
<p><br><br><br></p>
<h2 id="📖quiz-4">📖Quiz 4</h2>
<hr>
<p><img src="https://images.velog.io/images/new__world/post/aad253c1-774c-4258-a936-4a81db9a5fbb/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/4a576514-58c3-4d17-9920-aaa4ba3c3d92/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[부스트코스 파이썬(PY4E) 코칭스터디 1기 - 1주차 학습]]></title>
            <link>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-1%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5</link>
            <guid>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%ACPY4E-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0-1%EC%A3%BC%EC%B0%A8-%ED%95%99%EC%8A%B5</guid>
            <pubDate>Tue, 20 Jul 2021 10:15:56 GMT</pubDate>
            <description><![CDATA[<h1 id="📖프로그래밍을-왜-할까">📖프로그래밍을 왜 할까?</h1>
<hr>
<blockquote>
<p>인공지능, 게임, 네이게이션, 모바일 앱, 엔터테인먼트 등 여러가지 응용의 시작점에 오신 여러분들을 환영합니다.</p>
</blockquote>
<blockquote>
<p>강좌의 목적은 컴퓨터가 여러분들을 위해 특정 역할을 수행할 수 있도록, 컴퓨터에게 명령을 내리는 것입니다.</p>
</blockquote>
<blockquote>
<p>명령을 하기 위한 언어로 파이썬을 배우게 되실것이고 올바른 소통을 위한 문법들을 배우게 됩니다.</p>
</blockquote>
<blockquote>
<p>자 이제 준비 되셨으면 함께 시작해 보겠습니다. </p>
</blockquote>
<h3 id="학습-목표">학습 목표</h3>
<ul>
<li>사용자가 아닌, 프로그래머로서 컴퓨터를 바라보는 관점 변화의 필요성을 이해하고 설명할 수 있다.</li>
</ul>
<h3 id="들어가며">들어가며</h3>
<ul>
<li>우리가 프로그래밍을 배우는 목적이 컴퓨터가 우리를 위해 일 하도록 만드는 것이라는 점.</li>
<li>컴퓨터는 우리가 시킨 일을 실행하도록 디자인됐고 만들어졌다.</li>
<li>기본적으로 컴퓨터는 다음에 할 작업이 무엇인지 우리에게 물어본다. 다음 해야할 일이 무엇인지 알려주지 않으면 가만히 기다리기만 한다. 우리 주변에 있는 모든 하드웨어와 컴퓨터들은 명령을 기다리고 있다.</li>
<li>우리가 컴퓨터에게 일을 시키는 것이 중요하다. 컴퓨터 자체는 전혀 똑똑하지 않기 때문에 우리가 컴퓨터의 언어를 배워야 한다. 우리가 프로그램을 배우는 것이 우리의 세계에서 동작하는 방법을 기계에게 가르치는 것보다 쉽기 때문</li>
</ul>
<h3 id="프로그래밍">프로그래밍?</h3>
<ul>
<li>사용자의 <strong>요구</strong>를 충족시키기 위해 컴퓨터 내에 있는 자원에게 내리는 <strong>명령문들의 집합</strong>이다. 가끔은 프로그래머 스스로가 사용자가 되기도 한다. 창업을 하거나 모바일 게임을 만드는게 아니라 자신을 위한 프로그램을 짤 수 있다. 어떤 때는 문제를 해결하기 위해 혹은 무언가 해보기 위해 프로그래밍을 한다.</li>
<li>수작업으로 해야하는 작업을 25~100줄의 코드로 할 수도 있다.</li>
<li>또한 오픈소스 학습관리 시스템인 <a href="https://en.wikipedia.org/wiki/Sakai_(software)">사카이(Sakai)</a>에서 작업하면 독창적인 아이디어를 수백만 사용자들과 나눌 수 있다.</li>
<li>컴퓨터는 문자 그대로 받아들이기 때문에 정확하게 입력해야 한다. 컴퓨터는 우리가 뜻하는 것과 말하는 것의 차이를 구분 못한다.</li>
</ul>
<p><br><br><br></p>
<h2 id="📖컴퓨터의-내부-구조">📖컴퓨터의 내부 구조</h2>
<hr>
<h3 id="하드웨어">하드웨어?</h3>
<ul>
<li>하드웨어에 대해 말하고자 하는 이유는 보조 기억장치, CPU, RAM, 주변 장치, 입력 장치와 같은 단어들을 이해하고 사용할 수 있어야 하기 때문이다.</li>
<li>라즈베리 파이는 &#39;단일 보드 컴퓨터&#39;이다. 이런 것들은 점점 작아지고 있으며, 흥미로운 것은 구조는 같지만 부품 개수는 줄어들고 있다는 것이다.</li>
<li><strong>컴퓨터</strong>에서 뇌와 가장 비슷한 기능을 하는 것은 <strong>&#39;소프트웨어&#39;</strong>이다. (물론 컴퓨터는 뇌가 없다.)</li>
<li><strong>하드웨어</strong>에서 뇌와 가장 비슷한 기능을 하는 것은 마이크로 프로세서 혹은 <a href="https://ko.wikipedia.org/wiki/%EC%A4%91%EC%95%99_%EC%B2%98%EB%A6%AC_%EC%9E%A5%EC%B9%98"><strong>&#39;중앙연산처리장치(CPU)&#39;</strong></a> 라고 한다. 1초에 30억 번씩 무엇을 다음에 해야 하는지 묻는다. 뒤에 있는 32개나 64개의 작은 핀들을 통해 1초에 30억번 명령을 보낸다.</li>
<li>명령을 CPU에 대고 말할 수 없기 때문에 <strong>메인 메모리</strong>에 <strong>명령</strong>이 <strong>저장</strong>되어 있다. 메인 메모리는 아주 빠르다. 메인 메모리가 CPU에 필요한 것을 공급한다. <strong>CPU</strong>가 새로운 명령이 필요하면 메인 메모리에게 어디에 명령이 있는지 물어보고 <strong><a href="https://ko.wikipedia.org/wiki/%EC%A3%BC%EA%B8%B0%EC%96%B5%EC%9E%A5%EC%B9%98">메인 메모리</a>에게 전달받은 명령을 실행한다.</strong> 다른 명령을 요청하면 CPU가 또 실행한다. 이는 프로그래밍의 핵심이라고 볼 수 있다.</li>
<li><strong><a href="https://ko.wikipedia.org/wiki/%EB%A9%94%EC%9D%B8%EB%B3%B4%EB%93%9C">마더보드(메인보드)</a></strong>는 모든 부품들을 연결하기 때문에 마더보드라고 부른다. 메모리만 있으면 아무 것도 할 수 없다. 마더보드에 끼워 넣어야 사용할 수 있다. 마더보드는 모든 부품들을 연결해준다.</li>
<li><strong><a href="https://ko.wikipedia.org/wiki/%ED%95%98%EB%93%9C_%EB%94%94%EC%8A%A4%ED%81%AC_%EB%93%9C%EB%9D%BC%EC%9D%B4%EB%B8%8C">하드 드라이브</a></strong>는 <strong>보조 기억장치</strong>이다. 보조 기억장치가 메인 메모리와 다른점을 살펴보면, 우선 메인 메모리는 매우 빠르다. 하지만 전원을 끄면 정보가 사라진다. 워드 파일, 텍스트 파일 같은 것들을 기록해 두려면 오래 저장할 수 있는 곳에 보관해야 한다. 보조 저장소가 그 역할을 한다. 보조 저장소는 <strong>전원이 꺼져도 영구적으로 메모리를 저장</strong>한다. 외형을 살펴보면 돌아가는 원판이 있는데 자성체와 전자가 이것의 자기를 만들고 없앤다. 디스크가 1분에 몇 번 회전하는지에 따라 성능을 구분하기도 한다. <strong>운영 체제, 파일, 응용 프로그램이 저장되는 곳</strong>이다. <strong>컴퓨터가 꺼져있는 동안 보관되고 켜지면 로딩한다.</strong></li>
<li>CPU는 메인 메모리에서 데이터를 받아 1분에 30억개의 작업을 한다. 전기전자를 잘 안다면 알고 있겠지만, 작은 은색들은 축전지이고 색깔 있는 것들은 저항기이다. <strong>현대 CPU는</strong> 1960년대와 달리 축전기, 저항기, 트랜지스터 회로가 <strong>극소화</strong> 됐다. 광학적인 방법으로 더 작고 더 많이 회로를 새기는 것이다. 현재 주머니에 컴퓨터를 갖고 다닐 수 있는 이유는(스마트폰) 여기에 있는 CPU, 메모리, 저장소 등 모든 것들이 작아지고 작아져서 단일 보드 컴퓨터인 &#39;라즈베리 파이&#39;에 CPU, 메모리, 키보드 같은 장치 등 모든 것들을 놓을 수 있는 것이다.(아직은 여기에 보조 기억장치가 없다. USB를 통해서 보조 기억장치에 연결된다.) 스마트폰은 보조 기억장치가 내장되어 있다.</li>
<li>CPU는 생각을 하고 프로그램을 실행시킨다. 무엇을 다음으로 해야할 지 물어본다. 별로 똑똑하지는 않지만 매우 빠르다. 아주 잘 짜여진 소프트웨어가 지능 역할을 대신한다. 폰의 음성인식 기능은 저장공간이 많고 속도가 빠르기 때문에 가능한 것이다.</li>
<li>입력 장치는 키보드, 마우스, 펜이다.</li>
<li>출력 장치는 우리가 보는 스크린이다.</li>
<li>메인 메모리는 빠르게 작동하며 프로그램을 저장한다.</li>
<li>보조 기억장치는 영구적으로 데이터를 저장한다.</li>
<li>내장된 보조 기억장치로 플래시 메모리 혹은 스태틱 RAM 사용이 늘어나고 있다. 아마 몇 년 후에는 별도로 장착하는 보조 기억장치를 찾아볼 수 없을 것이다.(영구적인 메모리란 지워지지 않는 저장소라는 말이다.)</li>
</ul>
<p><br><br><br></p>
<h2 id="📖언어로써-파이썬">📖언어로써 파이썬</h2>
<hr>
<ul>
<li>파이썬이 최근에 인기가 많아진 이유는 배우기 <strong>쉽고 간결하고 강력</strong>하기 때문이다.</li>
<li>파이썬을 사용해 소프트웨어를 개발하는 것을 배우며 문법 에러를 자주 만나게 될 것이다. 문법 에러가 부족한 프로그래머라는 것을 의미하지 않는다.</li>
<li>프롬프트에 이상한 것을 치면 파이썬은 받아들이지 않을 것이다. 그래서 파이썬이 받아들일 수 있는 언어를 배우고자 하는 것이다!</li>
</ul>
<p><br><br><br></p>
<h2 id="📖-학습하기-전예약어-순차문-조건문-및-반복문">📖 (학습하기 전)예약어, 순차문, 조건문 및 반복문</h2>
<hr>
<ul>
<li>처음에는 원래 이해하기 힘들다. 힘들어도 참고 따라하자. 용어부터 시작해서 문장과 문단을 만들어 이야기를 만들 것이다.</li>
<li><strong>예약어</strong>는 무엇일까? 지정한 의미로만 쓰이는 단어이다. 지정하지 않은 다른 의미로는 쓸 수 없다. 일종의 약속과 같다. 예를 들어, 강아지한테 &quot;저 TV 프로그램 어때?&quot; 라고 물어보면 전혀 알아듣지 못한다. 또한 &quot;목요일까지 기다렸다가 수의사 만나러 갈 거야?&quot; 라고 물어봐도 알아듣지 못한다. 하지만 &quot;산책하러 갈 거야?&quot; 라고 물어보면 &quot;산책&quot;을 알아듣고 나갈 것이다. 이처럼 강아지는 &quot;어쩌구 저쩌구.. 간식!&quot;, &quot;어쩌구 저쩌구.. 산책!&quot; 으로 듣는다. 이것이 파이썬이 예약어를 보는 방식과 같다.</li>
<li>단어 class를 보면 예약어로서 알고 있는 의미로 받아 들이고, 단어 zap을 보면 사용자 마음대로 사용할 수 있다. 예를 들면 변수 이름으로 사용할 수 있다.</li>
<li>파이썬에 있는 예약어는 아래와 같다.<ul>
<li>and</li>
<li>del</li>
<li>if</li>
<li>pass</li>
<li>in
그저 파이썬 예약어로 돼있을 뿐이다. 파이썬 자체가 사용하는 어휘이다.<ul>
<li>파이썬 프로그램은 문장으로 구성되어 있다. 컴퓨터가 다음으로 원하는 것이 있기 때문에 순서가 있다.</li>
<li>문장을 쌓아 문단으로 만든다. 프롬프트에 <code>python3</code>라고 친 다음에 한 문장 입력하고, 또 한 문장 입력하여 실행하는 것을 반복하는 것은 불편하고 생산적이지가 않다. 따라서, 프로그램이 길어지면 스크립트로 작성하는 것이 편리하다. 파일에 프로그램을 짜면 <strong>파이썬이 코드를 순서대로 읽는다.</strong> 파일 이름은 <code>.py</code>로 지정한다.</li>
<li>프로그래밍에는 몇 가지 기본적인 패턴들이 있다. 이 패턴들을 이해하는 것은 매우 중요하다. 첫 번째는 순차문이다. 말 그대로 순서대로 진행하는 것이다. 조건문은 어느 부분을 건너뛰는 것이다. 반복문은 계속 반복하는 것이다. 우리는 같은 일을 계속 반복하는 것을 질려하고 컴퓨터는 우리보다 반복적인 일을 잘한다. 반복할 문구를 저장해 두기도 한다.</li>
</ul>
</li>
</ul>
</li>
</ul>
<p><br><br><br><br></p>
<h2 id="📖변수-표현식-문장">📖변수, 표현식, 문장</h2>
<hr>
<ul>
<li>파이썬의 기본 토대인 변수, 상수, 명령문, 표현식에 대해 알아보자.</li>
<li>먼저, 상수에 대해 알아보자면 상수는 변하지 않기 때문에 상수라고 한다.
숫자, 문자열 등이 상수이고 계산을 위해 사용한다.(예를 들어 만약 40시간 보다 긴 경우 무엇인가를 실행하도록 한다면 이때 40이 상수로 쓰인다.)</li>
<li>변수는 메모리를 할당하고 이름을 지어 무언가를 그 곳에 넣을 수(담을 수) 있다. 보통은 한 개의 값만 넣는다. 컬렉션을 배울 때 한 개 이상의 값을 변수에 넣을 수 있다는 것을 보게 된다.</li>
<li>대입문에서 상수를 지정한다. 대입문은 화살표와 같다.</li>
<li>변수 이름을 정하는데 규칙이 있다. 문자나 밑줄로 시작할 수 있다. 파이썬과 대화할 때 밑줄을 쓰기 때문에 되도록 변수 이름을 밑줄로 시작하지 않는다. 첫 글자 다음으로 문자, 숫자, 밑줄이 올 수 있다. 대소문자를 구분하지만 대소문자로 변수를 구별하지 말자.</li>
</ul>
<p><br><br><br></p>
<h2 id="📖연산자-데이터-타입-및-타입-변환">📖연산자, 데이터 타입 및 타입 변환</h2>
<hr>
<ul>
<li>표현식은 대입문 오른쪽에 쓸 수 있는 조금 더 복잡한 계산이다. 표현식에 사용하는 대표적인 것 중의 하나가 연산자이다. 프로그래밍에서 쓰이는 연산자는 수학 연산자와 매우 비슷하다. 하지만 수학에서 쓰는 특별한 기호 전체를 사용할 수 없기 때문에 키보드에 주어진 것을 쓴다. 이는 1960, 1970년대 키보드에 있었던 것을 사용해서 이런 연산자들을 만들었다.<code>(+, -, *, /, **, %)</code></li>
<li>연산자 순위에서 괄호가 제일 우선순위이다. 다음으로 거듭제곱, 곱하기(나누기), 더하기(빼기) 순서이다. 기본적으로 왼쪽에서 오른쪽으로 계산된다.</li>
<li>파이썬은 다양한 종류의 데이터를 사용한다. 더하기를 할 때 파이썬은 정수와 정수라는 것을 알고 두 개를 더해 정수를 만든다. 또한 문자열을 더할 수 있다.</li>
<li>프로그래밍에서 또 다른 요소는 주석이다. 파이썬, SEER 등 어떤 언어를 사용하든 주석은 무시된다. <code>#</code>으로 시작하는데 파이썬은 <code>#</code> 다음 글을 모두 무시한다. 주석은 사람이 읽기 위한 용도이다. 프로그래머나 프로그램을 수정할 사람이 읽는데 매우 유용하다. 특별한 문법을 사용하거나 변수 이름 짓는 것과 달리 규칙이 없다.</li>
</ul>
<p><br><br><br></p>
<h2 id="📖quiz-1">📖Quiz 1</h2>
<hr>
<p><img src="https://images.velog.io/images/new__world/post/72774b52-9c24-4061-829a-826e8ea3172e/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/6481499a-592d-4c8b-8c0f-b40d1c8ddcfc/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/8a2358c4-2b47-4ebe-8ff0-91ba96556788/image.png" alt=""></p>
<p><br><br><br></p>
<h2 id="📖quiz-2">📖Quiz 2</h2>
<hr>
<p><img src="https://images.velog.io/images/new__world/post/ddc40305-9644-4e73-acfd-cf05fb0670e1/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/c67ca4e0-f954-42a0-b188-44af1701876a/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/989866bf-f91d-4876-acdf-61c7aa2df5e7/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/24c68572-0e77-4212-81b6-7560c4407f95/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/fd3870e3-202e-46ad-bc1e-a79af1e08428/image.png" alt=""></p>
<p><br><br><br><br></p>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<hr>
<p>부스트코스 팀 과제(미션)는 저작권 문제로 업로드 못하다니! 정말 아쉽다!😥</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[부스트코스 파이썬 코칭스터디 1기 ]]></title>
            <link>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0</link>
            <guid>https://velog.io/@new__world/%EB%B6%80%EC%8A%A4%ED%8A%B8%EC%BD%94%EC%8A%A4-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%BD%94%EC%B9%AD%EC%8A%A4%ED%84%B0%EB%94%94-1%EA%B8%B0</guid>
            <pubDate>Thu, 08 Jul 2021 16:03:39 GMT</pubDate>
            <description><![CDATA[<h2 id="참가-계기">참가 계기</h2>
<hr>
<p>지난주, &#39;프로그래밍에 대해서 자유롭게 이야기도 하고 상호 간에 자문도 구하는 스터디 그룹 없을까?&#39;라는 생각에 검색을 하던 중 네이버와 네이버 커넥트 재단의 지원으로 양질의 강의를 무료로 제공하는 비영리 SW 온라인 교육 플랫폼 <a href="https://www.boostcourse.org/">부스트코스</a>를 발견하였다! 
처음 접하는 지식! 새로운 도전! 나를 한 단계 더 성장시킬 수 있는 좋은 기회가 아닌가! 부랴부랴 지금 신청 가능한 게 어떤 것들이 있는지 살펴보기 시작했다.</p>
<p>우선, 가장 먼저 눈에 들어오는 <a href="https://www.boostcourse.org/opencourse">무료강의</a>를 클릭해 보았다.</p>
<p>2021년 7월 기준으로 전체 48개의 강의가 있었으며 6개로 분류되었고 해당 항목은 다음과 같다.</p>
<ul>
<li>컴퓨터 과학(12)</li>
<li>웹(4)</li>
<li>모바일(6)</li>
<li>인공지능(12)</li>
<li>데이터 사이언스(8)</li>
<li>디지털 마케팅(6)</li>
</ul>
<p><img src="https://images.velog.io/images/new__world/post/0714fcb4-225f-4bcc-b6d4-b650522175ee/image.png" alt=""></p>
<p>모두 탐나는 강의들 뿐이었다.(나는 내가 모르는 새로운 무언가를 볼 때 배워보고 싶다는 욕심이 가득 들끓는 것 같다) 강의 리스트들을 한참을 살펴보고 나서야 무료 강의 옆에 있는 <a href="https://www.boostcourse.org/coachingstudy">코칭스터디</a>가 눈에 들어왔다.</p>
<p><img src="https://images.velog.io/images/new__world/post/0470edfe-eac5-4ce4-aa0a-8e2781fcba32/image.png" alt=""></p>
<p>_- 학습자는 무료 코칭스터디를 통해 혼자일때보다 더 쉽게, 더 많은것을 배우고 개발자, 전공자라면 코칭스터디로 재능을 나누고 더 많은 이와의 소통을 경험하세요.
_</p>
<p>찾았다! 이거다! 이것이야 말로 진정 내가 원하던 스터디 그룹이 아니던가~😭
현재 모집중인 코칭스터디가 있기를 바라며 스크롤을 내렸다.
(아직도 그 간절했던 찰나의 순간이 떠오른다..)</p>
<p>다행히 모집 중인 코칭스터디는 있었고 단 하나뿐이었는데,
그것은 바로.. 온라인으로 진행되는 <a href="https://m.post.naver.com/viewer/postView.nhn?volumeNo=31690489&amp;memberNo=34635212">온택트 파이썬 스터디</a>였다.🙌</p>
<p> <img src="https://images.velog.io/images/new__world/post/49233e31-69bb-490e-ad45-6732bccc4802/image.png" alt=""></p>
<p> &#39;엥.. 파이썬? 짱 간편하고 짱 좋다는 파이썬?! 근데 파이썬이 어떤 거지?&#39; 
 어떤 문법 구조를 가지고 어떻게 동작하는지에 대해서는 무지했다.
(크리스마스 때 연구실이 닫혀있어서 심심한 김에 만든 프로그래밍 언어라는 건 익히 들어보았다. <a href="https://namu.wiki/w/Python">-나무위키</a>) </p>
<p>&#39;파이썬에 대해서 무지한 내가 과연 스터디에 참여할 수 있을까?&#39; 고민도 했지만
판단은 부스트코스에서 하겠거니~ 하고, 일단 참여하고 나서 뒷일은 나중에 생각하자는 생각으로 참가 신청서부터 작성하기 시작했다.</p>
<p><br><br></p>
<h2 id="참가-신청-및-일정">참가 신청 및 일정</h2>
<hr>
<p>우선, 모집 대상과 지원 일정은 다음과 같았다.</p>
<p><img src="https://images.velog.io/images/new__world/post/568036ce-c55a-43cc-8c82-0389b29087dd/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/7ca78645-c1ae-46a2-b677-91234d2d74b6/image.png" alt=""></p>
<p><strong>컴퓨터 과학 입문을 위한 누구나 가능하며 전공, 나이, 직업과 무관.</strong>
(파이썬 공부가 처음인 전국에 있는 대학생/취업 준비생/ 직장인, 프로그래밍 언어에 관심이 있고 본격적으로 배워보고 싶은 누구나)</p>
<p>7월 2일 18시를 끝으로, 7월 5일~7월 7일 3일간 선발하여 7월 8일에 선발 결과를 메일을 통해 개별통보한다. 그 후에 오리엔테이션과 본격적인 스터디가 시작된다.</p>
<p>스터디 참가를 관련 전공자나 기본 지식을 갖춘 사람만 참여할 수 있으면 어떡하나 라는 걱정은 정말 쓸모없는 걱정이었다!</p>
<p>다음으로, 모집 부문은 두 가지의 유형이 있었다.</p>
<p><img src="https://images.velog.io/images/new__world/post/927e72be-fdc7-4713-855b-ffb276147747/image.png" alt=""></p>
<ul>
<li>리드 부스터: 따뜻한 리더십을 보유하고 팀 내 커뮤니케이션을 중요시하며 학습하는 팀원들을 잘 이끌어갈 수 있는 역량을 보유하신 분</li>
<li>부스터: 적극적으로 소통을 하고자 하는 마인드를 가지고 있으며, 학습에 대한 열정과 의지를 지니신 분</li>
</ul>
<p>리드 부스터는 팀장의 임무를 수행할 테니 적어도 기본 지식을 갖춘 사람이 팀장에 제격이라 생각하여 부스터로 신청하였다.</p>
<p>그 뒤로, 간단한 개인정보와 함께 지원동기, 학습의지 등을 작성했는데,
지원동기에 대해서 간단하게 몇 줄 작성하는데도 정말 심혈을 기울여서 최대한 진심을 담아 작성했다.</p>
<p><br><br></p>
<h2 id="선발-결과">선발 결과</h2>
<hr>
<p><img src="https://images.velog.io/images/new__world/post/d64a4982-bb0e-4e6a-9d05-f2fb60918b26/image.png" alt=""></p>
<p>7월 8일에 예정되었던 선발 결과였지만 사실 나는 그전에 결과를 알고 있었다. 7월 6일 오후에 부스트코스 담당자분으로부터 연락이 왔는데, 모집 부문 유형으로 부스터(팀원)로 신청했으나 리드 부스터(팀장)로 해 볼 의향이 없냐는 것이었다. 지원자들 대다수가 부스터(팀원)로 신청해서 리드 부스터(팀장) 인원이 부족하여 부스터 신청 인원 중 선별하여 리드 부스터 제의 연락을 주신 것이다. </p>
<p>파이썬 기본 지식이 없어 고민 중이었던 나를 꿰뚫어 보셨던 걸까..😳 
리드 부스터의 역할이 프로그래밍 실력과는 크게 상관없다며 리드 부스터의 역할을 간단히 설명해 주셨다. 언제 이런 제의를 또 받아볼까 싶기도 하고, 책임감을 가지고 학습에 더 전념할 수 있을 것 같아 리드 부스터로 하겠다고 말씀드렸다.</p>
<p>그렇게 선발 결과를 기분 좋게 스포(?) 당해버렸다!
부스트코스 선발 해줘서 고마워요!
친절하게 설명해주신 부스트코스 담당자 분도 감사드립니다.</p>
<p><br><br></p>
<h2 id="💬">💬</h2>
<hr>
<p><a href="https://m.post.naver.com/viewer/postView.nhn?volumeNo=31690489&amp;memberNo=34635212"><img src="https://images.velog.io/images/new__world/post/3df39341-ea35-4a01-b980-312aa8dd5140/image.png" alt="PY4E 파이썬 기초"></a></p>
<p>국비교육은 여러 개의 언어를 겉핥기로 얕게 배우고 지나가다 보니 어떤 원리로 동작이 되며 왜 이런 것들이 존재하는지에 대해서는 생각할 시간이 많이 부족했다. 예를 들어 브라우저는 어떻게 동작이 되고, 웹이란 무엇이고 웹 표준은 왜 있는지 같은 기본 개념 이해와 동작 원리 말이다.</p>
<p>덕분에 여러 개의 언어를 겉핥기로 배우기보다는 하나의 언어라도 잘해보자는 생각을 가지고 있었지만, 항상 마음 한 편에는 짱 좋다는 파이썬을 배워보고 싶은 마음이 있었다.</p>
<p>부스트코스 코칭스터디는 파이썬에 입문할 좋은 기회라고 생각된다.
새로운 프로그래밍 언어를 배울 생각에 벌써부터 설렌다.
7월도 열심히 해보자! 파이팅!🔥</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 
벤더 프리픽스]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EB%B2%A4%EB%8D%94-%ED%94%84%EB%A6%AC%ED%94%BD%EC%8A%A4</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EB%B2%A4%EB%8D%94-%ED%94%84%EB%A6%AC%ED%94%BD%EC%8A%A4</guid>
            <pubDate>Tue, 22 Jun 2021 16:53:33 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<p>CSS3 표준으로 확정되기 이전 또는 브라우저 개발사가 실험적으로 제공하는 기능을 사용하기 위해서는 벤더 프리픽스(Vendor Prefix)를 사용하여야 한다.</p>
<p><a href="http://caniuse.com/">Can I use?</a> 에서 제공하는 브라우저별 CSS 지원 정보를 보면 텍스트와 요소의 선택을 방지하는 <code>user-select</code> 프로퍼티는 모든 브라우저에 벤더 프리픽스를 사용하여야 한다. 브라우저의 버전이 올라감에 따라 벤더 프리픽스를 사용하지 않아도 될 수 있다. 그러나 구형 브라우저를 지원하기 위하여 벤더 프리픽스를 사용하여야 할 필요가 있다.</p>
<p><img src="https://images.velog.io/images/new__world/post/d186ab3c-e1b1-44fa-aba2-5d425adc3cb4/image.png" alt=""></p>
<pre><code>* {
  -webkit-user-select: none;  /* Chrome all / Safari all */
  -moz-user-select: none;     /* Firefox all */
  -ms-user-select: none;      /* IE 10+ */
  user-select: none;          /* Likely future */
}</code></pre><p><img src="https://images.velog.io/images/new__world/post/a989ce80-e576-43f0-b8d8-b3d3ea6e1422/image.png" alt=""></p>
<br>

<p><strong>브라우저 별 벤더 프리픽스는 다음과 같다.</strong></p>
<table>
<thead>
<tr>
<th>Browser</th>
<th>Vendor  Prefix</th>
</tr>
</thead>
<tbody><tr>
<td>IE or Edge</td>
<td>-ms-</td>
</tr>
<tr>
<td>Chrome</td>
<td>-webkit-</td>
</tr>
<tr>
<td>Firefox</td>
<td>-moz-</td>
</tr>
<tr>
<td>Safari</td>
<td>-webkit-</td>
</tr>
<tr>
<td>Opera</td>
<td>-o-</td>
</tr>
<tr>
<td>IOS Safari</td>
<td>-webkit-</td>
</tr>
<tr>
<td>Android Browser</td>
<td>-webkit-</td>
</tr>
<tr>
<td>Chrome for Android</td>
<td>-webkit-</td>
</tr>
</tbody></table>
<br>
<br>


<p>많은 브라우저를 위한 벤더 프리픽스를 사용하는 것은 코드의 양을 늘게 하고 또한 브라우저는 매달 업데이트가 이루어지고 있어 불필요한 벤더 프리픽스를 사용할 가능성이 크다. 사용하지 않아도 되는 벤더 프리픽스를 사용하는 것은 성능에도 영향을 주기 때문에 <a href="http://leaverou.github.io/prefixfree/">Prefix Free 라이브러리</a> 를 사용하는 것은 매우 유용한 방법이다.</p>
<p>사용법은 매우 간단하다. <a href="http://leaverou.github.io/prefixfree/">Prefix Free</a> 사이트에서 라이브러리를 다운로드하고 include 하기만 하면 이후에는 벤더 프리픽스 없이 모든 CSS를 사용할 수 있다.</p>
<pre><code>&lt;script src=&quot;prefixfree.min.js&quot;&gt;&lt;/script&gt;</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive -  화살표 함수]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98</guid>
            <pubDate>Mon, 21 Jun 2021 17:38:12 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<p><img src="https://images.velog.io/images/new__world/post/bd1ca34a-4ee2-402b-b005-970ae7cd1e4a/image.png" alt=""></p>
<h3 id="1-화살표-함수의-선언">1. 화살표 함수의 선언</h3>
<p>화살표 함수(Arrow function)는 function 키워드 대신 화살표(<code>=&gt;</code>)를 사용하여 보다 간략한 방법으로 함수를 선언할 수 있다. 하지만 모든 경우 화살표 함수를 사용할 수 있는 것은 아니다. 화살표 함수의 기본 문법은 아래와 같다.
<img src="https://images.velog.io/images/new__world/post/5b01f3ee-33e4-497c-9c91-9e6ea72c0ae8/1.png" alt=""></p>
<pre><code>// 매개변수 지정 방법
    () =&gt; { ... } // 매개변수가 없을 경우
     x =&gt; { ... } // 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.
(x, y) =&gt; { ... } // 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없다.

// 함수 몸체 지정 방법
x =&gt; { return x * x }  // single line block
x =&gt; x * x             // 함수 몸체가 한줄의 구문이라면 중괄호를 생략할 수 있으며 암묵적으로 return된다. 위 표현과 동일하다.

() =&gt; { return { a: 1 }; }
() =&gt; ({ a: 1 })  // 위 표현과 동일하다. 객체 반환시 소괄호를 사용한다.

() =&gt; {           // multi line block.
  const x = 10;
  return x * x;
};</code></pre><p><br><br></p>
<hr>
<h3 id="2-화살표-함수의-호출">2. 화살표 함수의 호출</h3>
<p>화살표 함수는 익명 함수로만 사용할 수 있다. 따라서 화살표 함수를 호출하기 위해서는 함수 표현식을 사용한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/e053c878-cca9-434a-a347-f84957740c66/2.png" alt=""></p>
<pre><code>// ES5
var pow = function (x) { return x * x; };
console.log(pow(10)); // 100</code></pre><pre><code>// ES6
const pow = x =&gt; x * x;
console.log(pow(10)); // 100</code></pre><p>또는 콜백 함수로 사용할 수 있다. 이 경우 일반적인 함수 표현식보다 표현이 간결하다.</p>
<p><img src="https://images.velog.io/images/new__world/post/8d220d19-d657-40ff-a0aa-2ef29cd032ee/3.png" alt=""></p>
<pre><code>// ES5
var arr = [1, 2, 3];
var pow = arr.map(function (x) { // x는 요소값
  return x * x;
});
console.log(pow); // [ 1, 4, 9 ]

// ES6
const arr = [1, 2, 3];
const pow = arr.map(x =&gt; x * x);
console.log(pow); // [ 1, 4, 9 ]</code></pre><p><br><br></p>
<hr>
<h3 id="3-this">3. this</h3>
<p>function 키워드로 생성한 일반 함수와 화살표 함수의 가장 큰 차이점은 this이다.</p>
<h3 id="31-일반-함수의-this">3.1 일반 함수의 this</h3>
<p>자바스크립트의 경우 함수 호출 방식에 의해 <a href="https://poiemaweb.com/js-this">this</a>에 바인딩할 어떤 객체가 동적으로 결정된다. 다시 말해, 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정되는 것이 아니고, <strong>함수를 호출할 때 함수가 어떻게 호출되었는지에 따라</strong> this에 바인딩할 객체가 동적으로 결정된다.</p>
<p>콜백 함수 내부의 this는 전역 객체 window를 가리킨다.</p>
<p><img src="https://images.velog.io/images/new__world/post/0898974c-b023-410a-9fcd-0810c6fd0961/4.png" alt=""></p>
<pre><code>function Prefixer(prefix) {
  this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
  // (A)
  return arr.map(function (x) {
    return this.prefix + &#39; &#39; + x; // (B)
  });
};

var pre = new Prefixer(&#39;Hi&#39;);
console.log(pre.prefixArray([&#39;Lee&#39;, &#39;Kim&#39;]));</code></pre><br>

<ul>
<li><p>(A) 지점에서의 this는 생성자 함수 Prefixer가 생성한 객체, 즉 생성자 함수의 인스턴스(위 예제의 경우 pre)이다.</p>
</li>
<li><p>(B) 지점에서 사용한 this는 아마도 생성자 함수 Prefixer가 생성한 객체(위 예제의 경우 pre)일 것으로 기대하였겠지만, 이곳에서 this는 전역 객체 window를 가리킨다. 이는 생성자 함수와 객체의 메소드를 제외한 모든 함수(내부 함수, 콜백 함수 포함) 내부의 this는 전역 객체를 가리키기 때문이다.</p>
</li>
</ul>
<br>

<p>위 설명이 잘 이해되지 않는다면 <a href="https://poiemaweb.com/js-this">this</a>를 참조하기 바란다.</p>
<p>콜백 함수 내부의 this가 메소드를 호출한 객체(생성자 함수의 인스턴스)를 가리키게 하려면 아래의 3가지 방법이 있다.</p>
<p><img src="https://images.velog.io/images/new__world/post/0deca912-299f-4154-b3d5-5544eb57020a/5.png" alt=""></p>
<pre><code>// Solution 1: that = this
function Prefixer(prefix) {
  this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
  var that = this;  // this: Prefixer 생성자 함수의 인스턴스
  return arr.map(function (x) {
    return that.prefix + &#39; &#39; + x;
  });
};

var pre = new Prefixer(&#39;Hi&#39;);
console.log(pre.prefixArray([&#39;Lee&#39;, &#39;Kim&#39;]));</code></pre><p><img src="https://images.velog.io/images/new__world/post/2c009352-6f35-4c4c-9e3f-d061bb52f63c/6.png" alt=""></p>
<pre><code>// Solution 2: map(func, this)
function Prefixer(prefix) {
  this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
  return arr.map(function (x) {
    return this.prefix + &#39; &#39; + x;
  }, this); // this: Prefixer 생성자 함수의 인스턴스
};

var pre = new Prefixer(&#39;Hi&#39;);
console.log(pre.prefixArray([&#39;Lee&#39;, &#39;Kim&#39;]));</code></pre><br>

<p>ES5에 추가된 <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">Function.prototype.bind()</a>로  this를 바인딩한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/9372df68-34e2-4149-8934-94ef6369b5df/7.png" alt=""></p>
<pre><code>// Solution 3: bind(this)
function Prefixer(prefix) {
  this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
  return arr.map(function (x) {
    return this.prefix + &#39; &#39; + x;
  }.bind(this)); // this: Prefixer 생성자 함수의 인스턴스
};

var pre = new Prefixer(&#39;Hi&#39;);
console.log(pre.prefixArray([&#39;Lee&#39;, &#39;Kim&#39;]));</code></pre><p><br><br></p>
<h3 id="32-화살표-함수의-this">3.2 화살표 함수의 this</h3>
<p>일반 함수는 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정되는 것이 아니고, 함수를 호출할 때 함수가 어떻게 호출되었는지에 따라 this에 바인딩할 객체가 동적으로 결정된다고 하였다.</p>
<p>화살표 함수는 함수를 선언할 때 this에 바인딩할 객체가 정적으로 결정된다. 동적으로 결정되는 일반 함수와는 달리 <strong>화살표 함수의 this 는 언제나 상위 스코프의 this를 가리킨다.</strong> 이를 <strong><code>Lexical this</code></strong> 라고 한다. 화살표 함수는 앞서 살펴본 Solution 3의 Syntactic sugar이다.</p>
<blockquote>
<p>화살표 함수의 this 바인딩 객체 결정 방식은 함수의 상위 스코프를 결정하는 방식인 <a href="https://poiemaweb.com/js-scope#7-%EB%A0%89%EC%8B%9C%EC%BB%AC-%EC%8A%A4%EC%BD%94%ED%94%84">렉시컬 스코프</a>와 유사하다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/new__world/post/bcc281c6-387c-4a3a-a6fb-bb6ccf89627f/8.png" alt=""></p>
<pre><code>function Prefixer(prefix) {
  this.prefix = prefix;
}

Prefixer.prototype.prefixArray = function (arr) {
  // this는 상위 스코프인 prefixArray 메소드 내의 this를 가리킨다.
  return arr.map(x =&gt; `${this.prefix}  ${x}`);
};

const pre = new Prefixer(&#39;Hi&#39;);
console.log(pre.prefixArray([&#39;Lee&#39;, &#39;Kim&#39;]));</code></pre><br>

<p>화살표 함수는 call, apply, bind 메소드를 사용하여 this를 변경할 수 없다.</p>
<p><img src="https://images.velog.io/images/new__world/post/fd61f202-87a8-4494-9b16-f2e8996a8c7b/9.png" alt=""></p>
<pre><code>window.x = 1;
const normal = function () { return this.x; };
const arrow = () =&gt; this.x;

console.log(normal.call({ x: 10 })); // 10
console.log(arrow.call({ x: 10 }));  // 1</code></pre><p><br><br></p>
<hr>
<h3 id="4-화살표-함수를-사용해서는-안되는-경우">4. 화살표 함수를 사용해서는 안되는 경우</h3>
<p>화살표 함수는 Lexical this를 지원하므로 콜백 함수로 사용하기 편리하다. 하지만 화살표 함수를 사용하는 것이 오히려 혼란을 불러오는 경우도 있으므로 주의하여야 한다.</p>
<h3 id="41-메소드">4.1 메소드</h3>
<p>화살표 함수로 메소드를 정의하는 것은 피해야 한다. 화살표 함수로 메소드를 정의하여 보자.</p>
<pre><code>// Bad
const person = {
  name: &#39;Lee&#39;,
  sayHi: () =&gt; console.log(`Hi ${this.name}`)
};

person.sayHi(); // Hi undefined</code></pre><p>위 예제의 경우, 메소드로 정의한 화살표 함수 내부의 this는 메소드를 소유한 객체, 즉 메소드를 호출한 객체를 가리키지 않고 상위 컨택스트인 전역 객체 window를 가리킨다. 따라서 화살표 함수로 메소드를 정의하는 것은 바람직하지 않다.</p>
<p>이와 같은 경우는 메소드를 위한 단축 표기법인 <a href="https://poiemaweb.com/es6-enhanced-object-property#3-%EB%A9%94%EC%86%8C%EB%93%9C-%EC%B6%95%EC%95%BD-%ED%91%9C%ED%98%84">ES6의 축약 메소드 표현</a>을 사용하는 것이 좋다.</p>
<pre><code>// Good
// Good
const person = {
  name: &#39;Lee&#39;,
  sayHi() { // === sayHi: function() {
    console.log(`Hi ${this.name}`);
  }
};

person.sayHi(); // Hi Lee</code></pre><br>

<h3 id="42-prototype">4.2 prototype</h3>
<p>화살표 함수로 정의된 메소드를 prototype에 할당하는 경우도 동일한 문제가 발생한다. 화살표 함수로 정의된 메소드를 prototype에 할당하여 보자.</p>
<pre><code>// Bad
const person = {
  name: &#39;Lee&#39;,
};

Object.prototype.sayHi = () =&gt; console.log(`Hi ${this.name}`);

person.sayHi(); // Hi undefined</code></pre><p>화살표 함수로 객체의 메소드를 정의하였을 때와 같은 문제가 발생한다. 따라서 prototype에 메소드를 할당하는 경우, 일반 함수를 할당한다.</p>
<pre><code>// Good
const person = {
  name: &#39;Lee&#39;,
};

Object.prototype.sayHi = function() {
  console.log(`Hi ${this.name}`);
};

person.sayHi(); // Hi Lee</code></pre><br>

<h3 id="43-생성자-함수">4.3 생성자 함수</h3>
<p>화살표 함수는 생성자 함수로 사용할 수 없다. 생성자 함수는 prototype 프로퍼티를 가지며 prototype 프로퍼티가 가리키는 프로토타입 객체의 constructor를 사용한다. 하지만 화살표 함수는 prototype 프로퍼티를 가지고 있지 않다.</p>
<pre><code>const Foo = () =&gt; {};

// 화살표 함수는 prototype 프로퍼티가 없다
console.log(Foo.hasOwnProperty(&#39;prototype&#39;)); // false

const foo = new Foo(); // TypeError: Foo is not a constructor</code></pre><br>

<h3 id="44-addeventlistener-함수의-콜백-함수">4.4 addEventListener 함수의 콜백 함수</h3>
<p>addEventListener 함수의 콜백 함수를 화살표 함수로 정의하면 this가 <strong>상위 컨택스트인 전역 객체 window</strong>를 가리킨다.</p>
<pre><code>// Bad
var button = document.getElementById(&#39;myButton&#39;);

button.addEventListener(&#39;click&#39;, () =&gt; {
  console.log(this === window); // =&gt; true
  this.innerHTML = &#39;Clicked button&#39;;
});</code></pre><p>따라서 addEventListener 함수의 콜백 함수 내에서 this를 사용하는 경우, function 키워드로 정의한 일반 함수를 사용하여야 한다. 일반 함수로 정의된 addEventListener 함수의 콜백 함수 내부의 <a href="https://poiemaweb.com/js-event#43-dom-level-2-event-listener">this</a>는 이벤트 리스너에 바인딩된 요소(currentTarget)를 가리킨다.</p>
<pre><code>// Good
var button = document.getElementById(&#39;myButton&#39;);

button.addEventListener(&#39;click&#39;, function() {
  console.log(this === button); // =&gt; true
  this.innerHTML = &#39;Clicked button&#39;;
});</code></pre><p><br><br></p>
<hr>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<ul>
<li><a href="http://www.ecma-international.org/ecma-262/6.0/ECMA-262.pdf">ECMAScript 6</a></li>
<li><a href="http://es6-features.org/#Constants">ECMAScript 6 New Features: Overview &amp; Comparison</a></li>
<li><a href="https://kangax.github.io/compat-table/es6/">ES6 compat table</a></li>
<li><a href="http://exploringjs.com/es6/ch_arrow-functions.html">Arrow functions</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 템플릿 리터럴]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%ED%85%9C%ED%94%8C%EB%A6%BF-%EB%A6%AC%ED%84%B0%EB%9F%B4</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%ED%85%9C%ED%94%8C%EB%A6%BF-%EB%A6%AC%ED%84%B0%EB%9F%B4</guid>
            <pubDate>Sat, 19 Jun 2021 12:10:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<p><img src="https://images.velog.io/images/new__world/post/7841e49e-d18e-46ee-8f82-58ed81fb91ad/image.png" alt=""></p>
<p>ES6는 템플릿 리터럴(Template literal)이라고 불리는 새로운 문자열 표기법을 도입하였다. 템플릿 리터럴은 일반 문자열과 비슷해 보이지만, &#39; 또는 &quot; 같은 통상적인 따옴표 문자 대신 백틱(backtick) 문자 <strong>`</strong> 를 사용한다.</p>
<pre><code>const template = `템플릿 리터럴은 
&#39;작은따옴표(single quotes)`과 &quot;큰따옴표(double quotes)&quot;를 혼용할 수 있다.`;

console.log(template);</code></pre><p>일반적인 문자열에서 줄바꿈은 허용되지 않으며 공백(white-space)을 표현하기 위해서는 백슬래시\로 시작하는 <a href="https://msdn.microsoft.com/ko-kr/library/2yfce773(v=vs.94).aspx#Anchor_1">이스케이프 시퀀스</a>를 사용하여야 한다. ES6 템플릿 리터럴은 일반적인 문자열과 달리 여러 줄에 걸쳐 문자열을 작성할 수 있으며 템플릿 리터럴 내의 모든 white-space는 있는 그대로 적용된다.</p>
<pre><code>const template = `&lt;ul class=&quot;nav-items&quot;&gt;
  &lt;li&gt;&lt;a href=&quot;#home&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#news&quot;&gt;News&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#contact&quot;&gt;Contact&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#about&quot;&gt;About&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;`;

console.log(template);</code></pre><p>템플릿 리터럴은 + 연산자를 사용하지 않아도 간단한 방법으로 새로운 문자열을 삽입할 수 있는 기능을 제공한다. 이를** 문자열 인터폴레이션(String Interpolation)**이라 한다.</p>
<pre><code>const first = &#39;Ung-mo&#39;;
const last = &#39;Lee&#39;;

// ES5: 문자열 연결
console.log(&#39;My name is &#39; + first + &#39; &#39; + last + &#39;.&#39;);
// &quot;My name is Ung-mo Lee.&quot;

// ES6: String Interpolation
console.log(`My name is ${first} ${last}.`);
// &quot;My name is Ung-mo Lee.&quot;</code></pre><p>문자열 인터폴레이션은 <code>${ ... }</code> 으로 표현식을 감싼다. 문자열 인터폴레이션 내의 표현식은 문자열로 강제 타입 변환된다.</p>
<pre><code>console.log(`1 + 1 = ${1 + 1}`); // &quot;1 + 1 = 2&quot;</code></pre><p><br><br></p>
<hr>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<ul>
<li><a href="http://www.ecma-international.org/ecma-262/6.0/#sec-template-literals">ECMAScript 6: Template Literals</a></li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals">MDN: Template literals</a></li>
<li><a href="https://kangax.github.io/compat-table/es6/">ES6 compat table</a></li>
<li><a href="https://zetawiki.com/wiki/%EB%A6%AC%ED%84%B0%EB%9F%B4">리터럴</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - let, const와 블록 레벨 스코프]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-let-const%EC%99%80-%EB%B8%94%EB%A1%9D-%EB%A0%88%EB%B2%A8-%EC%8A%A4%EC%BD%94%ED%94%84</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-let-const%EC%99%80-%EB%B8%94%EB%A1%9D-%EB%A0%88%EB%B2%A8-%EC%8A%A4%EC%BD%94%ED%94%84</guid>
            <pubDate>Sun, 13 Jun 2021 08:58:50 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<p><img src="https://images.velog.io/images/new__world/post/18c6f8c2-f726-44c8-9379-d51d79ac4afd/image.png" alt=""></p>
<p>ES5까지 변수를 선언할 수 있는 유일한 방법은 <a href="https://poiemaweb.com/js-data-type-variable#2-%EB%B3%80%EC%88%98-variable">var 키워드</a>를 사용하는 것이었다. var 키워드로 선언된 변수는 아래와 같은 특징이 있다. 이는 다른 언어와는 다른 특징으로 주의를 기울이지 않으면 심각한 문제를 일으킨다.</p>
<ol>
<li><p><a href="https://poiemaweb.com/js-scope#3-function-level-scope">함수 레벨 스코프(Function-level scope)</a></p>
<ul>
<li>함수의 코드 블록만을 스코프로 인정한다. 따라서 전역 함수 외부에서 생성한 변수는 모두 전역 변수이다. 이는 전역 변수를 남발할 가능성을 높인다.</li>
<li>for 문의 변수 선언문에서 선언한 변수를 for 문의 코드 블록 외부에서 참조할 수 있다.</li>
</ul>
</li>
<li><p>var 키워드 생략 허용</p>
<ul>
<li>암묵적 전역 변수를 양산할 가능성이 크다.</li>
</ul>
</li>
<li><p>변수 중복 선언 허용</p>
<ul>
<li>의도하지 않은 변수값의 변경이 일어날 가능성이 크다.</li>
</ul>
</li>
<li><p><a href="https://poiemaweb.com/js-data-type-variable#24-%EB%B3%80%EC%88%98-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85variable-hoisting">변수 호이스팅</a></p>
<ul>
<li>변수를 선언하기 이전에 참조할 수 있다.</li>
</ul>
</li>
</ol>
<p><strong>대부분의 문제는 전역 변수로 인해 발생</strong>한다. 전역 변수는 간단한 애플리케이션의 경우, 사용이 편리하다는 장점이 있지만 불가피한 상황을 제외하고 사용을 억제해야 한다. 전역 변수는 <strong>유효 범위(scope)</strong>가 넓어서 어디에서 어떻게 사용될 것인지 파악하기 힘들며, <a href="https://github.com/nhnent/fe.javascript/wiki/April-11---April-15,-2016">비순수 함수(Impure function)</a>에 의해 의도하지 않게 변경될 수도 있어서 <strong>복잡성</strong>을 증가시키는 원인이 된다. 따라서 <strong>변수의 스코프는 좁을수록 좋다.</strong></p>
<p>ES6는 이러한 var 키워드의 단점을 보완하기 위해 <strong>let</strong>과 <strong>const</strong> 키워드를 도입하였다.</p>
<p><br><br></p>
<hr>
<h2 id="1-let">1. let</h2>
<h3 id="11-블록-레벨-스코프">1.1 블록 레벨 스코프</h3>
<p>대부분의 프로그래밍 언어는 블록 레벨 스코프(Block-level scope)를 따르지만 자바스크립트는 함수 레벨 스코프(Function-level scope)를 따른다.</p>
<ul>
<li><p>함수 레벨 스코프(Function-level scope)
함수 내에서 선언된 변수는 함수 내에서만 유효하며 함수 외부에서는 참조할 수 없다. <strong>즉, 함수 내부에서 선언한 변수는 지역 변수이며 함수 외부에서 선언한 변수는 모두 전역 변수</strong>이다.</p>
</li>
<li><p>블록 레벨 스코프(Block-level scope)
모든 코드는 블록(함수, if 문, for 문, while 문, try/catch 문 등) 내에서 선언된 변수는 코드 블록 내에서만 유효하며 코드 블록 외부에서는 참조할 수 없다. <strong>즉, 코드 블록 내부에서 선언한 변수는 지역 변수</strong>이다.</p>
</li>
</ul>
<br>

<p><em>아래 예제를 살펴보자.</em></p>
<pre><code>var foo = 123; // 전역 변수

console.log(foo); // 123

{
 var foo = 456; 전역 변수
}

console.log(foo); // 456</code></pre><p>블록 레벨 스코프를 따르지 않는 var 키워드의 특성 상, 코드 블록 내의 변수 foo는 전역 변수이다. 그런데 이미 전역 변수 foo가 선언되어 있다. <strong>var 키워드</strong>를 사용하여 선언한 변수는 <strong>중복 선언</strong>이 허용되므로 위의 코드는 문법적으로 아무런 문제가 없다. 단, 코드 블록 내의 변수 foo는 전역 변수이기 때문에 전역에서 선언된 전역 변수 foo의 값 123을 새로운 값 456으로 <strong>재할당</strong>하여 덮어쓴다.</p>
<p><strong>ES6</strong>는 <strong>블록 레벨 스코프</strong>를 따르는 변수를 선언하기 위해 <code>let</code> 키워드를 제공한다.</p>
<pre><code>let foo = 123; // 전역 변수

{
 let foo = 456; // 지역 변수
 let bar = 456; // 지역 변수
}

console.log(foo); // 123
console.log(bar); // ReferenceError: bar is not defined</code></pre><p>let 키워드로 선언된 변수는 블록 레벨 스코프를 따른다. 위 예제에서 코드 블록 내에 선언된 변수 foo는 블록 레벨 스코프를 갖는 지역 변수이다. 전역에서 선언된 변수 foo와는 다른 별개의 변수이다. 또한 변수 bar도 블록 레벨 스코프를 갖는 지역 변수이다. 따라서 전역에서는 변수 bar를 참조할 수 없다.</p>
<p><br><br></p>
<h3 id="12-변수-중복-선언-금지">1.2 변수 중복 선언 금지</h3>
<p><code>var</code> 키워드로는 동일한 이름을 갖는 변수를 중복해서 선언할 수 있었다. 하지만, <code>let</code> 키워드로는 동일한 이름을 갖는 변수를 중복해서 선언할 수 없다. 변수를 중복선언하면 문법 에러(SyntaxError)가 발생한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/43ae0084-9b75-4a64-8573-ca0a8d20340f/1.2-2.png" alt="">
<br><br></p>
<h3 id="13-호이스팅">1.3 호이스팅</h3>
<p>자바스크립트는 ES6에서 도입된 let, const를 포함하여 모든 선언(var, let ,const, function, <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/function*">function*</a>, class)을 호이스팅한다. 호이스팅(Hoisting)이란, var 선언문이나 function 선언문 등을 <strong>해당 스코프의 선두로 옮긴 것처럼 동작하는 특성</strong>을 말한다.</p>
<p>하지만 <code>var</code> 키워드로 선언된 변수와는 달리 <code>let</code> 키워드로 선언된 변수를 <strong>선언문 이전에 참조하면 참조 에러(ReferenceError)가 발생</strong>한다. 이는 <code>let</code> 키워드로 선언된 변수는 스코프의 시작에서 변수의 선언까지 <strong>일시적 사각지대(Temporal Dead Zone; TDZ)</strong>에 빠지기 때문이다.</p>
<p><img src="https://images.velog.io/images/new__world/post/67983c38-35a8-490c-9fe7-929192e8d3cd/1.2-1.png" alt=""></p>
<p>변수가 어떻게 생성되며 호이스팅은 어떻게 이루어지는지 좀 더 자세히 살펴보자.
변수는 3단계에 걸쳐 생성된다. 자세한 내용은 <a href="https://poiemaweb.com/js-execution-context">Execution Context</a>을 참조하기 바란다.</p>
<ul>
<li><p>선언 단계(Declaration phase)
변수를 실행 컨텍스트의 변수 객체(Variable Object)에 <strong>등록</strong>한다. 이 변수 객체는 스코프가 참조하는 대상이 된다.</p>
</li>
<li><p>초기화 단계(Initialization phase)
변수 객체(Variable Object)에 등록된 변수를 위한 공간을 메모리에 확보한다. 이 단계에서 변수는 undefined로 <strong>초기화</strong>된다.</p>
</li>
<li><p>할당 단계(Assignment phase)
undefined로 초기화된 변수에 실제 값을 <strong>할당</strong>한다.</p>
</li>
</ul>
<br>

<p><strong>var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다.</strong> </p>
<p>즉, 스코프에 변수를 등록(선언 단계)하고 메모리에 변수를 위한 공간을 확보한 후, undefined로 초기화(초기화 단계)한다. 따라서 변수 선언문 이전에 변수에 접근하여도 스코프에 변수가 존재하기 때문에 에러가 발생하지 않는다. 다만 undefined를 반환한다. 이후 변수 할당문에 도달하면 비로소 값이 할당된다. 이러한 현상을 <a href="https://poiemaweb.com/js-data-type-variable#24-%EB%B3%80%EC%88%98-%ED%98%B8%EC%9D%B4%EC%8A%A4%ED%8C%85variable-hoisting">변수 호이스팅(Variable Hoisting)</a>이라 한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/72ccfdc7-4354-4861-88a3-ed66f4595984/3.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/543b2075-dece-4f5b-a0d7-43bbd157c5aa/image.png" alt=""></p>
<br>

<p><strong>let 키워드로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.</strong></p>
<p>즉, 스코프에 변수를 등록(선언단계)하지만 초기화 단계는 변수 선언문에 도달했을 때 이루어진다. 초기화 이전에 변수에 접근하려고 하면 참조 에러(ReferenceError)가 발생한다. </p>
<p>이는 변수가 아직 초기화되지 않았기 때문이다. 다시 말하면 변수를 위한 메모리 공간이 아직 확보되지 않았기 때문이다. 따라서 스코프의 시작 지점부터 초기화 시작 지점까지는 변수를 참조할 수 없다. 스코프의 시작 지점부터 초기화 시작 지점까지의 구간을 &#39;일시적 사각지대(Temporal Dead Zone; TDZ)&#39;라고 부른다.</p>
<p><img src="https://images.velog.io/images/new__world/post/94d60914-bb6f-49d5-85bf-56a243754d57/4.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/acc918e2-0ded-406b-882c-9486b51d8d75/image.png" alt=""></p>
<br>

<p>결국 ES6에서는 호이스팅이 발생하지 않는 것과 차이가 없어 보인다. 하지만 그렇지 않다. 아래 예제를 살펴보자.</p>
<p><img src="https://images.velog.io/images/new__world/post/62e7977c-673d-4905-851d-5272bbfc1ac9/5.png" alt=""></p>
<p>위 예제의 경우, 전역 변수 foo의 값이 출력될 것처럼 보인다. 하지만 ES6의 선언문도 여전히 호이스팅이 발생하기 때문에 참조 에러(ReferenceError)가 발생한다.</p>
<p>ES6의 <code>let</code> 으로 선언된 변수는 블록 레벨 스코프를 가지므로 코드 블록 내에서 선언된 변수 foo는 지역 변수이다. 따라서 지역 변수 foo도 해당 스코프에서 호이스팅되고 코드 블록의 선두부터 초기화가 이루어지는 지점까지 일시적 사각지대(TDZ)에 빠진다. 따라서 전역 변수 foo의 값이 출력되지 않고 참조 에러(ReferenceError)가 발생한다.</p>
<p><br><br></p>
<h3 id="14-클로저">1.4 클로저</h3>
<p>블록 레벨 스코프를 지원하는 let은 var보다 직관적이다. 다음 코드를 살펴보자.</p>
<p><img src="https://images.velog.io/images/new__world/post/b9701e0b-1e4c-4b7d-a668-021a48949322/6.png" alt=""></p>
<p>위 코드의 실행 결과로 0, 1, 2를 기대할 수도 있지만 결과는 3이 세 번 출력된다.
그 이유는 for 루프의 var i가 전역 변수이기 때문이다. 0, 1, 2를 출력하려면 아래와 같은 코드가 필요하다.</p>
<p><img src="https://images.velog.io/images/new__world/post/c090451a-8c19-4b88-b8a7-71497f807016/7.png" alt=""></p>
<p>자바스크립트의 함수 레벨 스코프로 인하여 for 루프의 초기화 식에 사용된 변수가 전역 스코프를 갖게 되어 발생하는 문제를 회피하기 위해 <a href="https://poiemaweb.com/js-closure">클로저</a>를 활용한 방법이다.</p>
<p>ES6의 <code>let</code> 키워드를 for 루프의 초기화 식에 사용하면 클로저를 사용하지 않아도 위 코드와 동일한 동작을 한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/d561cc5f-c695-4db4-b046-8d5c2e66d1b4/8.png" alt=""></p>
<p>for 루프의 let i는 for loop에서만 유효한 지역 변수이다. 또한, i는 자유 변수로서 for 루프의 생명주기가 종료되어도 변수 i를 참조하는 함수가 존재하는 한 계속 유지된다.</p>
<p><img src="https://images.velog.io/images/new__world/post/5b733c3f-761d-4076-94b6-bc5e76f71731/image.png" alt=""></p>
<p><br><br></p>
<h3 id="15-전역-객체와-let">1.5 전역 객체와 let</h3>
<p>전역 객체(Global Object)는 모든 객체의 유일한 최상위 객체를 의미하며 일반적으로 Browser-side에서는 window 객체, Server-side(Node,js)에서는 global 객체를 의미한다. var 키워드로 선언된 변수를 전역 변수로 사용하면 전역 객체의 프로퍼티가 된다.</p>
<pre><code>var foo = 123; // 전역변수

console.log(window.foo); // 123</code></pre><p>let 키워드로 선언된 변수를 전역 변수로 사용하는 경우, let 전역 변수는 전역 객체의 프로퍼티가 아니다. </p>
<p>즉, window.foo와 같이 접근할 수 없다. let 전역 변수는 보이지 않는 개념적인 블록 내에 존재하게 된다.</p>
<pre><code>let foo = 123; // 전역변수

console.log(window.foo); // undefined</code></pre><p><br><br></p>
<h3 id="2-const">2. const</h3>
<p><code>const</code>는 <strong>상수(변하지 않는 값)을 위해 사용</strong>한다. 하지만 반드시 상수만을 위해 사용하지는 않는다. 이에 대해서는 후반부에 설명한다. const의 특징은 let과 대부분 동일하므로 let과 다른 점만 살펴보도록 하자.</p>
<h3 id="21-선언과-초기화">2.1 선언과 초기화</h3>
<p><code>let</code> 은 재할당이 자유로우나 <code>const</code> 는 재할당이 금지된다.</p>
<pre><code>const FOO = 123;
FOO = 456; // TypeError: Assignment to constant variable.</code></pre><p>주의할 점은 <strong>const는 반드시 선언과 동시에 할당이 이루어져야 한다</strong>는 것이다. 그렇지 않으면 다음처럼 문법 에러(SyntaxError)가 발생한다.</p>
<pre><code>const FOO; // SyntaxError: Missing initializer in const declaration</code></pre><p>또한, const는 let과 마찬가지로 블록 레벨 스코프를 갖는다.</p>
<pre><code>{
  const FOO = 10;
  console.log(FOO); //10
}
console.log(FOO); // ReferenceError: FOO is not defined</code></pre><p><br><br></p>
<h3 id="22-상수">2.2 상수</h3>
<p>상수는 가독성과 유지보수의 편의를 위해 적극적으로 사용해야 한다. 예를 들어 아래 코드를 살펴보자.</p>
<pre><code>// 10의 의미를 알기 어렵기 때문에 가독성이 좋지 않다.
if (rows &gt; 10) {
}

// 값의 의미를 명확히 기술하여 가독성이 향상되었다.
const MAXROWS = 10;
if (rows &gt; MAXROWS) {
}</code></pre><p>조건문 내의 10은 어떤 의미로 사용하였는지 파악하기가 곤란하다. 하지만 네이밍이 적절한 상수로 선언하면 가독성과 유지보수성이 대폭 향상된다.</p>
<p>const는 객체에도 사용할 수 있다. 물론 이때도 재할당은 금지된다.</p>
<pre><code>const obj = { foo: 123 };
obj = { bar: 456 }; // TypeError: Assignment to constant variable.</code></pre><p><br><br></p>
<h3 id="23-const와-객체">2.3 const와 객체</h3>
<p>const는 재할당이 금지된다. 이는 const 변수의 타입이 객체인 경우, 객체에 대한 참조를 변경하지 못한다는 것을 의미한다. 하지만 이때 <strong>객체의 프로퍼티는 보호되지 않는다.</strong> 다시 말하자면 재할당은 불가능하지만 할당된 객체의 내용(프로퍼티의 추가, 삭제, 프로퍼티 값의 변경)은 변경할 수 있다.</p>
<p><img src="https://images.velog.io/images/new__world/post/bc2f23ab-5ff1-424f-92dd-580ff9056f2b/12.png" alt=""></p>
<p>객체의 내용이 변경되더라도 객체 타입 변수에 할당된 <strong>주소값은 변경되지 않는다.</strong> 따라서 <strong>객체 타입 변수 선언에는 const를 사용하는 것이 좋다.</strong> 만약에 명시적으로 객체 타입 변수의 주소값을 변경(재할당)하여야 한다면 let을 사용한다.</p>
<p><br><br></p>
<h3 id="3-var-vs-let-vs-const">3. var vs. let vs. const</h3>
<p>변수 선언에는 기본적으로 const를 사용하고 let은 재할당이 필요한 경우에 한정해 사용하는 것이 좋다. 원시 값의 경우, 가급적 상수를 사용하는 편이 좋다. 그리고 객체를 재할당하는 경우는 생각보다 흔하지 않다. const 키워드를 사용하면 의도치 않은 재할당을 방지해 주기 때문에 보다 안전하다.</p>
<p>var와 let, 그리고 const는 다음처럼 사용하는 것을 추천한다.</p>
<ul>
<li>ES6를 사용한다면 var 키워드는 사용하지 않는다.</li>
<li>재할당이 필요한 경우에 한정해 let 키워드를 사용한다. 이때 변수의 스코프는 최대한 좁게 만든다.</li>
<li>변경이 발생하지 않는(재할당이 필요 없는 상수) 원시 값과 객체에는 const 키워드를 사용한다. const 키워드는 재할당을 금지하므로 var, let 보다 안전하다.</li>
</ul>
<br>

<p>변수를 선언하는 시점에는 재할당이 필요할지 잘 모르는 경우가 많다. 그리고 객체는 의외로 재할당을 하는 경우가 드물다. 따라서 변수를 선언할 때에는 일단 const 키워드를 사용하도록 하자. 반드시 재할당이 필요하다면(반드시 재할당이 필요한지 한번 생각해 볼 일이다) 그때 const를 let 키워드로 변경해도 결코 늦지 않는다.</p>
<p><br><br></p>
<hr>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<ul>
<li><a href="http://www.ecma-international.org/ecma-262/6.0/ECMA-262.pdf">ECMAScript 6</a></li>
<li><a href="http://es6-features.org/#Constants">ECMAScript 6 New Features: Overview &amp; Comparison</a></li>
<li><a href="https://kangax.github.io/compat-table/es6/">ES6 compat table</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_dead_zone_and_errors_with_let">Temporal dead zone and errors with let</a></li>
<li><a href="http://stackoverflow.com/questions/31219420/are-variables-declared-with-let-or-const-not-hoisted-in-es6">Are variables declared with let or const not hoisted in ES6?</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 자바스크립트의 기본 문법]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Tue, 08 Jun 2021 10:24:45 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<h3 id="1-변수">1. 변수</h3>
<p>변수(Variable)는 값(value)을 저장(할당)하고 그 저장된 값을 참조하기 위해 사용한다. 한번 쓰고 버리는 값이 아닌 <strong>유지(캐싱)</strong>할 필요가 있는 값은 변수에 담아 사용한다. 또한 변수 이름을 통해 값의 <strong>의미</strong>를 명확히 할 수 있어 <strong>코드의 가독성</strong>이 좋아진다.</p>
<p>변수는 <strong>위치(주소)</strong>를 기억하는 <strong>저장소</strong>이다. 위치란 메모리 상의 주소(address)를 의미한다. <strong>즉, 변수란 메모리 주소(Memory address)에 접근하기 위해 사람이 이해할 수 있는 언어로 지정한 식별자(identifier)</strong>이다.</p>
<p>변수를 선언할 때 <code>var</code> 키워드를 사용한다. 할당 연산자 <code>=</code>는 변수에 값을 할당하기 위해 사용한다.</p>
<p>아래의 예에서 x는 변수로 선언되었고 변수 x에는 정수값 6이 할당되었다.</p>
<pre><code>var x; // 변수의 선언
x = 6; // 정수값의 할당</code></pre><p><br><br></p>
<h3 id="2-값">2. 값</h3>
<pre><code>var str = &#39;Hello World&#39;;</code></pre><p>위 예제는 str이라는 이름의 <strong>변수</strong>를 선언하고 문자열 <strong>리터럴</strong> &#39;Hello World&#39;를 <strong>값</strong>으로 할당하였다. 이때 문자열 리터럴 &#39;Hello World&#39;는 문자열 타입의 값이다.</p>
<table>
<thead>
<tr>
<th>용어</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>데이터 타입(Data Type)</td>
<td>프로그래밍 언어에서 사용할 수 있는 값의 종류</td>
</tr>
<tr>
<td>변수(Variable)</td>
<td>값이 저장된 메모리 공간의 주소를 가리키는 식별자(identifier)</td>
</tr>
<tr>
<td>리터럴(literal)</td>
<td>소스코드 안에서 직접 만들어 낸 상수 값 자체를 말하며 값을 구성하는 최소 단위</td>
</tr>
</tbody></table>
<p><a href="https://en.wikipedia.org/wiki/Value_(computer_science)">값</a> 은 프로그램에 의해 조작될 수 있는 대상을 말한다. 값은 다양한 방법으로 생성할 수 있다. 가장 간단한 방법은 <a href="https://en.wikipedia.org/wiki/Literal_(computer_programming)">리터럴</a> 표기법(literal notation)을 사용하는 것이다.</p>
<pre><code>// 숫자 리터럴
10.50
1001

// 문자열 리터럴
&#39;Hello&#39;
&quot;World&quot;

// 불리언 리터럴
true
false

// null 리터럴
null

// undefined 리터럴
undefined

// 객체 리터럴
{ name: &#39;Lee&#39;, gender: &#39;male&#39; }

// 배열 리터럴
[ 1, 2, 3]

// 정규표현식 리터럴
/ab+c/

// 함수 리터럴
function() {}</code></pre><p>숫자, 문자열, 불리언과 같은 <strong>원시 타입</strong>의 리터럴은 다양한 연산자의 피연산자가 되어 <strong>하나의 값</strong>으로 평가될 수 있다. 이렇게 리터럴은 연산에 의해 하나의 값이 될 수 있다.</p>
<pre><code>// 산술 연산
10.50 + 1001</code></pre><p>자바스크립트의 모든 값은 데이터 타입을 갖는다. 자바스크립트는 7가지 데이터 타입을 제공한다.</p>
<ul>
<li>원시 타입(primitive data type)<ul>
<li><code>number</code></li>
<li><code>string</code></li>
<li><code>boolean</code></li>
<li><code>null</code></li>
<li><code>undefined</code></li>
<li><code>symbol</code> (New in ECMAScript 6)</li>
</ul>
</li>
</ul>
<ul>
<li>객체 타입(Object data type)<ul>
<li><code>object</code></li>
</ul>
</li>
</ul>
<p>자바스크립트는 <code>C</code>나 <code>Java</code>외는 다르게 변수를 선언할 때 데이터 타입을 미리 지정하지 않는다. 다시 말해, 변수에 할당된 값의 타입에 의해 <strong>동적</strong>으로 변수의 타입이 결정된다. 이를 <strong>동적 타이핑</strong>이라 하며 <strong>자바스크립트가 다른 프로그래밍 언어와 구별되는 특징</strong> 중 하나이다.</p>
<pre><code>// Number
var num1 = 1001;
var num2 = 10.50;

// String
var string1 = &#39;Hello&#39;;
var string2 = &quot;World&quot;;

// Boolean
var bool = true;

// null
var foo = null;

// undefined
var bar;

// Object
var obj = { name: &#39;Lee&#39;, gender: &#39;male&#39; };

// Array
var array = [ 1, 2, 3 ];

// function
var foo = function() {};</code></pre><p><br><br></p>
<h3 id="3-연산자">3. 연산자</h3>
<p>연산자(Operator)는 하나 이상의 표현식을 대상으로 산술, 할당, 비교, 논리, 타입 연산 등을 수행해 하나의 값을 만든다. 이때 연산의 대상을 피연산자(Operand)라 한다.</p>
<pre><code>// 산술 연산자
var area = 5 * 4; // 20

// 문자열 연결 연산자
var str = &#39;My name is &#39; + &#39;Lee&#39;; // &quot;My name is Lee&quot;

// 할당 연산자
var color = &#39;red&#39;; // &quot;red&quot;

// 비교 연산자
var foo = 3 &gt; 5; // false

// 논리 연산자
var bar = (5 &gt; 3) &amp;&amp; (2 &lt; 4);  // true

// 타입 연산자
var type = typeof &#39;Hi&#39;; // &quot;string&quot;

// 인스턴스 생성 연산자
var today = new Date(); // Sat Dec 01 2018 00:57:19 GMT+0900 (한국 표준시)</code></pre><p>피연산자의 타입은 반드시 일치할 필요는 없다. 이때 자바스크립트는 <a href="https://poiemaweb.com/js-type-coercion#1-%EC%95%94%EB%AC%B5%EC%A0%81-%ED%83%80%EC%9E%85-%EA%B0%95%EC%A0%9C-%EB%B3%80%ED%99%98">암묵적 타입 강제 변환</a>을 통해 연산을 수행한다.</p>
<pre><code>var foo = 1 + &#39;10&#39;; // &#39;110&#39;
var bar = 1 * &#39;10&#39;; // 10</code></pre><p><br><br></p>
<h3 id="4-키워드">4. 키워드</h3>
<p>키워드(keyword)는 수행할 동작을 규정한 것이다. 예를 들어 <code>var</code> 키워드는 새로운 변수를 생성할 것을 지시한다.</p>
<pre><code>// 변수의 선언
var x = 5 + 6;

// 함수의 선언
function foo (arg) {
  // 함수 종료 및 값의 반환
  return ++arg;
}

var i = 0;
// 반복문
while (1) {
  if (i &gt; 5) {
    // 반복문 탈출
    break;
  }
  console.log(i);
  i++;
}</code></pre><p><br><br></p>
<h3 id="5-주석">5. 주석</h3>
<p>주석(Comment)은 작성된 코드의 의미를 설명하기 위해 사용한다.</p>
<p>코드는 읽기(이해하기) 쉬워야 한다.(가독성이 좋아야 한다) 여러분이 작성한 코드를 다른 누군가가 읽는다면 &quot;아니, 이게 뭐하는 코드야?&quot;라고 생각하는 순간이 있기 마련이다. 여러분이 해야 하는 일은 바로 그런 부분에 주석을 다는 것이다.<strong>(읽기 좋은 코드가 좋은 코드이다)</strong></p>
<p>한줄 주석은 <code>//</code> 다음에 작성하며 여러 줄 주석은 <code>/*</code> 과 <code>*/</code> 사이에 작성한다. <strong>주석은 해석기(parser)가 무시하며 실행되지 않는다.</strong></p>
<pre><code>// 주석(Comment)은 작성된 코드의 의미를 설명하기 위해 사용한다. 코드는 읽기(이해하기) 쉬워야 한다.

/*
  주석(Comment)은 작성된 코드의 의미를 설명하기 위해 사용한다.
  코드는 읽기(이해하기) 쉬워야 한다.
*/</code></pre><p>하지만 과도한 주석은 오히려 가독성을 해칠 수 있다. 주석 없이도 읽을 수 있는 코드가 최선이다.</p>
<pre><code>// Bad
// 변수 x는 나이를 나타낸다. x에는 정수 10을 할당한다.
var x = 10;

// Good
var age = 10;</code></pre><p><br><br></p>
<h3 id="6-문">6. 문</h3>
<p><strong>프로그램(스크립트)</strong>은 컴퓨터(Client-side Javascript의 경우, 엄밀히 말하면 웹 브라우저)에 의해 <strong>단계별로 수행될 명령들의 집합</strong>이다.</p>
<p>각각의 명령을 문(statement)이라 하며 문이 실행되면 무슨 일인가가 일어나게 된다.</p>
<p>문은 리터럴, 연산자(Operator), 표현식(Expression), 키워드(Keyword) 등으로 구성되며 세미콜론(<code>;</code>)으로 끝나야 한다.</p>
<pre><code>var x = 5;
var y = 6;
var z = x + y;

console.log(z);</code></pre><p>문은 <strong>코드 블록(code block, {...})</strong>으로 <strong>그룹화</strong>할 수 있다. 그룹화의 목적은 함께 실행되어져야 하는 문을 정의하기 위함이다.</p>
<pre><code>// 함수
function myFunction(x, y) {
  return x + y;
}

// if 문
if(x &gt; 0) {
  // do something
}

// for 문
for (var i = 0; i &lt; 10; i++) {
  // do something
}</code></pre><p><strong>문들은 일반적으로 위에서 아래로 순서대로 실행된다.</strong> 이러한 실행 순서는 조건문(if, switch)이나 반복문(while, for)의 사용으로 제어할 수 있다 이를 <strong>흐름제어(Control Flow)</strong>라 한다. 또는 <strong>함수 호출</strong>로 변경될 수 있다.</p>
<p><img src="https://images.velog.io/images/new__world/post/d1770399-6273-4359-ba59-446793def83c/image.png" alt=""></p>
<p>다른 언어와 달리 <strong>자바스크립트</strong>에서는 블록 유효범위(Block-level scope)를 생성하지 않는다. <strong>함수 단위의 유효범위(Function-level scope)만이 생성</strong>된다.</p>
<p><br><br></p>
<h3 id="7-표현식">7. 표현식</h3>
<p><strong>표현식(Expression)은 하나의 값으로 평가(Evaluation)된다.</strong> 값(리터럴), 변수, 객체의 프로퍼티, 배열의 요소, 함수 호출, 메소드 호출, 피연산자와 연산자의 조합은 모두 표현식이며 하나의 값으로 평가(Evaluation)된다. 표현식은 결국 하나의 값이 되기 때문에 다른 표현식의 일부가 되어 조금 더 복잡한 표현식을 구성할 수도 있다. 아래의 예에서 <code>5 * 10</code>은 <code>50</code>으로 평가(연산)된다.</p>
<pre><code>// 표현식
5             // 5
5 * 10        // 50
5 * 10 &gt; 10   // true
(5 * 10 &gt; 10) &amp;&amp; (5 * 10 &lt; 100)  // true</code></pre><p><br><br></p>
<h3 id="8-문과-표현식의-비교">8. 문과 표현식의 비교</h3>
<p>자연어에서 문(Statement)이 마침표로 끝나는 하나의 완전한 문장이라고 한다면 표현식은 문을 구성하는 요소이다. 표현식은 그 자체로 하나의 문이 될 수도 있다.</p>
<pre><code>// 선언문(Declaration statement)
var x = 5 * 10; // 표현식 x = 5 * 10를 포함하는 문이다.
// 할당문(Assignment statement)
x = 100; // 이 자체가 표현식이지만 완전한 문이기도 하다.</code></pre><p><strong>표현식과 문은 매우 유사</strong>하여 구별이 어려울 수 있다. 표현식은 평가되어 값을 만들지만 그 이상의 행위는 할 수 없다. 문은 var, function과 같은 선언 키워드를 사용하여 변수나 함수를 생성하기도 하고 if, for, while 문과 같은 제어문을 생성하여 프로그램의 흐름을 제어하기도 한다. <strong>표현식을 통해 평가한 값을 통해 실제로 컴퓨터에게 명령을 하여 무언가를 하는 것은 문이다.</strong></p>
<p><br><br></p>
<h3 id="9-함수">9. 함수</h3>
<p>함수란 <strong>어떤 작업</strong>을 수행하기 위해 필요한 <strong>문(Statement)들의 집합을 정의한 코드 블록</strong>이다. 함수는 <strong>이름</strong>과 <strong>매개변수</strong>를 갖으며 필요한 때에 <strong>호출</strong>하여 코드 블록에 담긴 문들을 일괄적으로 실행할 수 있다.</p>
<pre><code>// 함수의 정의(함수 선언문)
function square(number) {
  return number * number;
}</code></pre><p>함수는 호출에 의해 실행되는데 한 번만 호출할 수 있는 것이 아니라 여러번 호출할 수 있다.</p>
<pre><code>// 함수의 정의(함수 선언문)
function square(number) {
  return number * number;
}

// 함수의 호출
square(2); // 4</code></pre><p><strong>동일한 작업을 반복적으로 수행</strong>해야 한다면(동일한 구문을 계속해서 중복해서 작성하는 것이 아니라) 미리 정의된 함수를 재사용하는 것이 효율적이다. 이러한 특성은 <strong>코드의 재사용</strong>이라는 측면에서 매우 유용하다.</p>
<p><br><br></p>
<h3 id="10-객체">10. 객체</h3>
<p><strong>자바스크립트</strong>는 <strong>객체(object) 기반의 스크립트 언어</strong>이며 자바스크립트를 이루고 있는 거의 &quot;모든 것&quot;이 객체이다. 원시 타입(Primitives)을 제외한 나머지 값들(함수, 배열, 정규표현식 등)은 모두 객체이다.</p>
<p>자바스크립트 객체는 <strong>키(이름)</strong>와 값으로 구성된 <strong>프로퍼티(property)</strong>의 집합이다. 프로퍼티의 값으로 자바스크립트에서 사용할 수 있는 모든 값을 사용할 수 있다. 자바스크립트의 함수는 일급 객체이므로 값으로 취급할 수 있다. 따라서 프로퍼티 값으로 함수를 사용할 수도 있으며 프로퍼티 값이 함수일 경우, 일반 함수와 구분하기 위해 <strong>메소드</strong>라 부른다.</p>
<p><img src="https://images.velog.io/images/new__world/post/3d96465e-c15f-4c7c-a128-e5f8f6904bf4/image.png" alt=""></p>
<p>이와 같이 객체는 데이터를 의미하는 프로퍼티(property)와 데이터를 참조하고 조작할 수 있는 동작(behavior)을 의미하는 메소드(method)로 구성된 집합이다. 객체는 데이터(프로퍼티)와 그 데이터에 관련되는 동작(메소드)을 모두 포함할 수 있기 때문에 데이터와 동작을 하나의 단위로 구조화할 수 있어 유용하다.</p>
<p>자바스크립트의 객체는 객체지향의 상속을 구현하기 위해 <strong>&quot;프로토타입&quot;</strong>이라고 불리는 <strong>객체의 프로퍼티와 메소드를 상속</strong>받을 수 있다. </p>
<p><strong>이 프로토타입은 타 언어와 구별되는 중요한 개념이다.</strong></p>
<p><br><br></p>
<h3 id="11-배열">11. 배열</h3>
<p><strong>배열(array)</strong>은 <strong>하나의 변수</strong>에 <strong>여러 개의 값</strong>을 순차적으로 <strong>저장</strong>할 때 사용한다. 자바스크립트의 배열은 <strong>객체</strong>이며 유용한 <strong>내장 메소드를 포함</strong>하고 있다.</p>
<pre><code>var arr = [1, 2, 3, 4, 5];

console.log(arr[1]); // 2</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[네이버 검색의 SRE 시스템]]></title>
            <link>https://velog.io/@new__world/%EB%84%A4%EC%9D%B4%EB%B2%84-%EA%B2%80%EC%83%89%EC%9D%98-SRE-%EC%8B%9C%EC%8A%A4%ED%85%9C</link>
            <guid>https://velog.io/@new__world/%EB%84%A4%EC%9D%B4%EB%B2%84-%EA%B2%80%EC%83%89%EC%9D%98-SRE-%EC%8B%9C%EC%8A%A4%ED%85%9C</guid>
            <pubDate>Tue, 08 Jun 2021 04:15:09 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>NAVER D2</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://d2.naver.com/helloworld/2047663">https://d2.naver.com/helloworld/2047663</a></p>
</blockquote>
<hr>
<br>

<h3 id="💬">💬</h3>
<h3 id="네이버-검색의-sre-시스템">네이버 검색의 SRE 시스템</h3>
<p>네이버 검색은 국내 최대 규모의 트래픽과 데이터를 다루는 <strong>대용량 분산 시스템</strong>이다. 수만 대의 서버에서 수백 개의 검색 서비스가 운영되고 있으며, 하루에도 몇 번씩 크고 작은 신규 개발과 유지보수 활동이 활발하게 반영되고 있다. 이렇게 거대하고 역동적인 시스템이 안정적으로 운영되려면, 그리고 항상 최고의 성능을 보장하려면 어떤 노력이 필요할까? 단순히 많은 비용을 들여서 서버 장비를 증설하거나 유능한 개발자를 많이 채용하면 될까? 당연하게도, 이 문제를 은탄환 같은 만능 해결책이나 딱 떨어지는 정답이 존재하지는 않다. 하지만 수많은 시행착오를 겪어가면서 노하우를 차곡 차곡 쌓아나가다 보면 어느 정도 쓸 만한 현실적인 해결책은 만들어 낼 수 있을 것이다.</p>
<p>이렇게 스케일이 큰 인터넷 서비스를 개발하고 운영하기 위한 방법론을 모으고 모아서 잘 정리한 것이 바로 <strong>Site Reliability Engineering(이하 SRE)</strong>이다. 이 글에서는 네이버 검색에서 SRE를 도입한 계기를 소개하고, 실제로 어떻게 활용하고 있는지, 그리고 어떤 성과로 이어지고 있는지 소개해 준다.</p>
<p><br><br></p>
<h3 id="💬-1">💬</h3>
<h3 id="sre-도입-계기">SRE 도입 계기</h3>
<p>대부분의 인터넷 서비스가 마찬가지이지만, 네이버 검색은 특히 온 국민이 사용하는 공공재나 다름없기 때문에 더욱 장애에 민감한 특성을 가지고 있다. 다르게 말하자면 &#39;<strong>신뢰성</strong>이 매우 중요한 시스템&#39;인데, 여기서 신뢰성이란 365일, 24시간 언제나 <strong>서비스가 정상적으로 무중단 제공되는 특성</strong>을 의미한다. 서비스의 규모가 커질수록 아래와 같은 이유로 시스템의 신뢰성을 보장하는 일이 점점 어려워진다.</p>
<br>

<ul>
<li>첫 번째, 스케일이 한 단계씩 커질 때마다 <strong>새로운 방법론</strong>이 필요하다.
처리해야 하는 데이터의 규모는 기하급수적으로 증가하고, 그만큼 필요한 서버 장비의 수나 시스템의 종류도 계속 늘어난다. 하지만 숙련된 엔지니어의 숫자는 서비스의 성장 속도만큼 빠르게 증가하기 어렵다. 심지어 엔지니어의 수가 비슷한 속도로 늘어난다고 해도 문제는 해결되지 않는다. 왜냐하면 조직이든 시스템이든 규모가 커질수록 <strong>복잡도</strong>가 높아지고 관리가 어려워져 점점 효율이 떨어지기 때문이다.</li>
</ul>
<ul>
<li>두 번째, 예측이 불가능한 일들이 일어난다.
지진과 같은 재난이나 각종 사회, 경제, 문화적으로 우리나라 사람들의 관심이 집중될 만한 이슈가 발생하면 네이버 검색으로 유입되는 요청량이 순간적으로 몇 배씩 폭증한다. 이런 사건 사고는 대부분 사전에 예측이 불가능하기 때문에 검색 시스템 입장에서는 미리 준비하거나 대응하기가 매우 어렵다.</li>
</ul>
<br>

<p>실제로 지난 2016년 9월 경주에서 전례없는 규모의 대형 지진이 일어났을 때, <strong>네이버 통합검색 전체 시스템</strong>에서 약 10분간 검색을 수행할 수 없는 <strong>장애가 발생</strong>했다. 당시 검색 시스템을 구성하는 수만 대의 서버 중에서 단 8대를 차지하는 작은 서비스에서 <strong>가용량 문제</strong>가 있었는데, 이 작은 문제가 순식간에 전체 통합검색의 장애로 이어졌다. 아주 작은 문제라고 하더라도 전체 시스템을 순식간에 마비시킬 수 있다는 것을 보여준 사례였다. 이후 증상 완화와 원인 파악, 영향도 분석까지 총 1시간에 가까운 시간이 소요되었고 재발 방지책까지 포함한 사후 분석(postmortem)이 완료되는 데 총 48시간이나 걸렸다.</p>
<p>당시 상황에서는 충분히 빠른 대응이었지만 이대로는 앞으로 더 커질 규모를 감당할 수 없다는 위기의식을 느끼게 되었다. 이 사건을 계기로 네이버 검색에서는 <strong>SRE</strong>라는 기술의 도입을 적극적으로 검토하기 시작했다.</p>
<p><img src="https://images.velog.io/images/new__world/post/90f3a904-6ff8-4f3d-b513-54f5789c64f9/image.png" alt=""></p>
<p><code>[그림1] 작은 원인에서 시작된 장애는 순식간에 전체 통합검색 시스템을 마비시켰다.</code></p>
<p><br><br></p>
<h3 id="💬-2">💬</h3>
<h3 id="네이버-검색에-딱-맞는-sre">네이버 검색에 딱 맞는 SRE</h3>
<p>SRE를 위한 모니터링 도구, 자동화 도구는 이미 많이 만들어져 있었다. 하지만 대규모로 구축하여 오랜 시간 운영해 온 시스템에 이 모든 도구를 적용하는 것은 쉬운 일이 아니었다. 그래서 네이버 검색에서는 어떤 도구를 사용할지 고민하기보다는, <strong>일단 어떤 문제가 존재하는지를 먼저 파악하고 분석하는 작업에 집중했다.</strong> <strong>취약한 부분과 개선이 필요한 부분이 무엇인지 정리한 뒤 하나씩 차근차근 극복해 나가자는 전략이었다.</strong></p>
<p><br><br></p>
<h3 id="💬-3">💬</h3>
<h3 id="비상-상황-대응-체계">비상 상황 대응 체계</h3>
<p>2016년 경주 지진처럼 갑자기 발생하는 비상 상황에 대한 대응 체계가 없었다. 그래서 먼저 네이버 검색 시스템이 맞이할 수 있는 <strong>비상 상황(contingency)</strong>을 아래와 같이 <strong>크게 두 가지로 정의</strong>하고 각 상황에서 어떻게 행동해야 하는지 <strong>대응 체계</strong>를 만들었다.</p>
<ul>
<li>첫 번째, 자연 재해나 국가적 이슈에 의해 <strong>갑자기 트래픽이 폭증</strong>하는 상황이다. 이 상황은 지진 등 이슈의 주제가 되는 <strong>특정 검색어</strong>가 집중적으로 증폭된다는 특징이 있다. 중복된 검색 요청이 많을 경우 <strong>캐시 서버</strong>를 최대한 활용하는 방법으로 충격을 완화할 수 있다는 점에 착안하여 대응 방안을 정리했다. 그리고 이 원리를 응용하여 특정 조건을 만족하는 경우에는 자동으로 비상 대응 모드로  전환되는 <strong>자동화 시스템</strong>도 마련했다.</li>
</ul>
<p><img src="https://images.velog.io/images/new__world/post/bb10a06e-a163-494c-bc1d-954323de2f54/image.png" alt=""></p>
<p><code>[그림2] 2019년 2월에 발생한 포항 지진 상황에서는 트래픽이 증가하기 전에 비상 모드가 먼저 발동 되었다.</code></p>
<br>

<ul>
<li>두 번째, <strong>경쟁사</strong>의 검색 서비스가 동작하지 않아 트래픽이 모두 네이버로 <strong>집중</strong>되는 상황이다. 이 상황에서는 <strong>모든 종류</strong>의 검색어가 골고루 증폭되기 때문에 캐시 서버로는 대응이 어렵다. 하지만 검색 시장 점유율 기반으로 총 유입 트래픽의 규모가 어느 정도일지 유추할 수 있기 때문에 사전에 <strong>가용량 대비</strong>를 해두는 것이 가능하다.</li>
</ul>
<blockquote>
<p>이 내용은 <a href="https://m.blog.naver.com/naver_search/221150527232">네이버 검색 블로그 - 지진에도 흔들리지 않는 네이버 검색 시스템 1편</a>에서도 소개한 적이 있다.</p>
</blockquote>
<p><br><br></p>
<h3 id="💬-4">💬</h3>
<h3 id="장애-위험-탐지detection">장애 위험 탐지(detection)</h3>
<p>시스템 내부에서 오류가 발생하거나 실제 사용자 장애 상황이 되면 시스템 경보 또는 제보를 통해 담당자가 이를 인지한다. 하지만 이렇게 문제가 발생한 다음에 하는 대응은, 아무리 신속 정확하게 처리된다고 하더라도 이미 복구하기 어려운 손실을 동반하고 있는 경우가 많다. 그래서 문제가 발생하기 전에 미리 <strong>&#39;위험을 탐지&#39;</strong>하여 <strong>예방</strong>하는 것이 중요하다.</p>
<p>이렇게 장애 발생 전에 <strong>&#39;위험도 판단&#39;</strong>을 하려면 특정한 <strong>&#39;기준&#39;</strong>이 필요할 텐데 이 &#39;기준&#39;은 어떻게 정의해야 할까? 만약 서비스마다 특성이 다르다는 이유로 복잡하고 파편화된 기준을 적용하면 정말 긴급한 상황에서 직관적으로 판단하기 어려울 것이다. 쉽고 간단한, 그러면서도 확장성이 있는 <strong>규칙</strong>이 필요하다.</p>
<p>그리고 이미 장애가 발생한 상황에서도 이 <strong>기준</strong>은 여전히 유용하다. 지진으로 통합검색 전체가 동작하지 않았을 때에도 가장 절실하게 필요했던 것은 바로 <strong>각 서비스별 위험도 판단 기준</strong>이었다. 그 기준이 있어야 어떤 서비스가 병목인지, 어느 서비스가 회복되었고 어느 서비스가 여전히 위험한지를 빠르게 <strong>확인하고 대처</strong>할 수 있기 때문이다.</p>
<p>고민 끝에 네이버 검색에서는 범용적으로 사용할 수 있는 <strong>가용량 지표</strong>를 개발했다. 공식이 단순하고 직관적이라 누구나 <strong>숫자 하나로</strong> 쉽게 시스템의 상태를 <strong>인지</strong>할 수 있으면서도, 서비스의 규모나 성격과 상관없이 <strong>적용</strong>해볼 수 있는 방법이었다. 2016년 말, 이 새로운 가용량 지표를 도입했더니 1년도 안 되는 기간 동안 문제 상황이 <strong>90% 가까이 해소</strong>되었다. 그리고 2020년인 현재까지도 유용하게 잘 활용되고 있다. (본문 작성일: 2020.02.11)</p>
<p><img src="https://images.velog.io/images/new__world/post/d93f1ef1-d310-4be0-afc4-2cf6805770ac/image.png" alt=""></p>
<p><code>[그림3] 부하증가배수와 최대가용배수를 이용한 임계 상황 판단 방법</code></p>
<blockquote>
<p>자세한 가용량 공식과 적용 방법은 <a href="https://m.blog.naver.com/naver_search/221151934172">네이버 검색 블로그 - 지진에도 흔들리지 않는 네이버 검색 시스템 2편</a>에서 확인할 수 있다.</p>
</blockquote>
<p><br><br></p>
<h3 id="💬-5">💬</h3>
<h3 id="사후-분석postmortem-문화">사후 분석(postmortem) 문화</h3>
<p>사후 분석 문화가 잘 형성되는 것이 중요한 이유는, 시스템에서 발생하는 여러 가지 사건 사고와 여기서 얻는 좋은 교훈이 잘 쌓여서 나중에 복리로 <strong>문제 해결 효과</strong>를 만들어 내기 때문이다. 네이버 검색에서는 장애 사례에 대한 사후 분석 결과가 잘 누적되지 않고 있었다. 장애가 발생했을 때 <strong>복구에 집중</strong>하느라 <strong>내용 공유가 잘 되지 않거나 장애가 해결된 뒤에도 사후 분석 내용이 잘 전파되지 않는 등</strong> 여러 측면에서 개선이 필요한 상황이었다.</p>
<p>SRE 팀에서는 이 문제를 해결하기 위해 약 3개월 이상의 기간 동안 <strong>사후 분석 보고서(postmortem report)</strong>를 직접 작성하여 예시를 보여주었다. 사후 분석 보고서가 얼마나 유용하고 중요한지를 직접 보여줌으로써 자연스럽게 문화가 형성되도록 한 것이다. 이 방법은 천천히 효과가 발생했고, 약 3년이 흐른 현재 모든 엔지니어가 요청 없이도 자율적으로 사후 분석 보고서를 작성하고 있다. 문화 정착에는 시간이 걸리지만 효과는 강력하다.</p>
<blockquote>
<p>몇 가지 재미있는 분석 사례를 <a href="https://deview.kr/2018/schedule/253">2018년 DEVIEW 발표 - Search Reliability Engineering</a>에서 소개했다.</p>
</blockquote>
<p><img src="https://images.velog.io/images/new__world/post/4c480273-2240-44ca-bd4e-9c6658209b04/image.png" alt=""></p>
<p><code>[그림4] 장애가 발생할 때마다 엔지니어가 자율적으로 사후 분석 보고서를 작성하는 문화가 정착되었다</code></p>
<p><br><br></p>
<h3 id="💬-6">💬</h3>
<h3 id="전체-시스템을-한눈에-보기">전체 시스템을 한눈에 보기</h3>
<p><strong>SRE 도입 전</strong> 네이버 검색에서는 문제 해결에 꼭 필요한 주요 정보를 적절한 시점에 바로 획득하기가 어려웠다. 워낙 시스템이 거대하고 수많은 시스템과 조직이 엮여 있었기 때문에 통계 정보를 <strong>수작업</strong>으로 취합하거나 담당자를 찾아 <strong>문의</strong>하는 방식으로 문제를 해결하는 경우가 많았다. 이 문제는 <strong>상황 판단</strong>과 <strong>의사 결정</strong>을 느리게 하고, 커뮤니케이션 과정에서 <strong>잘못된 정보가 전달</strong>될 확률을 높여, 원활한 장애 대응에 <strong>큰 장애물</strong>이 되었다. 그래서 이런 수작업이나 불필요한 커뮤니케이션을 줄이는 작업을 시작했다.</p>
<p>네이버 검색에서는 일단 오래 전부터 사용하던 <strong>모니터링 시스템</strong>이 존재했고 각종 <strong>주요 지표</strong>가 잘 쌓이고 있었다. 하지만 모든 지표는 <strong>서버 단위로 집계</strong>되고 있어, <strong>서비스 단위</strong>로는 어떤 일이 발생하고 있는지, 그리고 <strong>전체 시스템 관점</strong>에서 어떤 문제가 있는지 한눈에 볼 방법이 없었다.</p>
<p>그래서 SRE 팀은 먼저 서비스별 <strong>고유 ID</strong>를 발급하는 일부터 시작했다. 서버 단위로 잘 수집된 지표가 각각 어떤 서비스의 지표로 이어져야 하는지 <strong>&#39;메타 정보&#39;</strong>를 하나씩 추가해 나가는 것이었다. 그리고 이렇게 만들어진 서비스 ID와 연계하여 <strong>담당자 정보</strong>도 직접 관리했다. 장애의 빠른 해결을 위해서는 항상 최신화된 담당자 정보가 필요했기 때문이다. 이렇게 서비스 ID와 담당자 정보 관리 체계를 전체 도입하는 데 거의 2년의 시간이 걸렸다. 그리고 마침내, 이렇게 모인 메타 정보와 지표를 엮어서 네이버 검색 시스템을 한눈에 볼 수 있는 <strong>대시보드</strong>가 만들어졌다.</p>
<p><img src="https://images.velog.io/images/new__world/post/8796b91f-185e-435d-bcc5-c03631547b16/image.png" alt=""></p>
<p><code>[그림5] 대시보드에서는 네이버 검색 시스템의 주요 지표를 한 화면에 요약하여 보여준다.</code></p>
<p><br><br></p>
<h3 id="💬-7">💬</h3>
<h3 id="경보-시스템-고도화">경보 시스템 고도화</h3>
<p>대시보드의 완성으로 중요한 지표를 한눈에 볼 수 있게 되자, 자연스럽게 이 지표에 <strong>문제</strong>가 생겼을 때 <strong>경보</strong>를 보내줬으면 좋겠다는 <strong>요구사항</strong>이 나왔다. 예를 들어, 프로그램 오류가 없더라도 트래픽이 갑자기 폭증하거나 반대로 갑자기 트래픽 유입이 중단되는 경우, <strong>서비스에 중대한 변화</strong>가 발생했거나 앞으로 발생할 확률이 높다. 이러한 신호를 놓치지 않고 잘 감시하기 위하여 다양한 지표에 각양각색의 기준으로 경보를 걸기 시작했다.</p>
<p>처음에는 이런 지표 변화를 거의 실시간에 가깝게 파악할 수 있었기 때문에 매우 유용했다. 하지만 시간이 흐를수록 우리가 만든 경보의 규칙에 포함되지 않는 <strong>예외 경우</strong>가 점점 발견되기 시작했고, 갈수록 경보 발생 수에 비해 유용한 정보의 비율이 낮아졌다. 심지어 하루에 수백 통의 경보 메일을 받는 날도 있었는데, 이런 날은 거의 다른 업무 진행이 되지 않을 정도로 큰 불편함을 겪어야 했다. <strong>SRE 업무가 성숙해지려면 경보의 고도화가 꼭 필요했다.</strong></p>
<p>경보는 너무 적게 발생하면 중요한 정보를 놓치기 쉽고, 너무 많이 발생하면 불필요한 스트레스와 피로를 유발하기 때문에 적당한 수준을 잘 유지하는 것이 중요하다. 적당한 빈도로 핵심적인 정보만 정확하게 잘 전달하려면 결국 <strong>지표 분석을 일정 부분 자동화</strong>해야 한다. SRE가 경보를 받고 나서 판단하는 경험적인 규칙과 원리를 경보 시스템에 직접 구현하여 자동으로 분석하게 만들었다. 분석 결과에 따라 아예 경보 발생 자체를 막는 방법이었다. 몇 가지 지표를 조합하여 확인하여 우리가 미리 알고 있는 패턴을 추출할 수 있었고 이 패턴을 활용해 <strong>경보 발생 빈도를 대폭 조절</strong>할 수 있었다.</p>
<blockquote>
<p>자세한 패턴 분석 방식은 <a href="https://m.blog.naver.com/naver_search/221217634238">네이버 검색의 스마트한 경보 시스템</a> 포스트에서 소개했다.</p>
</blockquote>
<p>이뿐만 아니라, 시스템 개편에 따른 트래픽 전환을 자동으로 탐지하거나, 조건에 걸리더라도 경보를 바로 발송하는 것이 아니라 문제가 확정될 때까지 기다리거나, 공휴일의 트래픽 패턴을 학습하여 경보에 반영하는 등 다양한 기법을 계속해서 연구하고 도입하고 있다. 이렇게 네이버 SRE의 경보 시스템은 지속적인 노력을 통해 점점 더 정교하게 다듬어지는 중이다.</p>
<p><img src="https://images.velog.io/images/new__world/post/bf5d6475-ef55-4350-b8eb-fba1bb3d81c0/image.png" alt=""></p>
<p><code>[그림6] 하인리히의 1:29:300 법칙에 따라 중대한 장애가 발생하기 전에 일어나는 경미한 사고를 정확히 탐지하여 알리는 것이 경보의 역할이다.</code></p>
<p><br><br></p>
<h3 id="💬-8">💬</h3>
<h3 id="sre의-효과">SRE의 효과</h3>
<p>SRE는 서비스를 직접 구현하지도 않고, 장애가 발생한 서버를 직접 재구동하거나 버그 패치를 만들지도 않는다. 하지만 <strong>장애가 발생했을 때</strong> 모든 문제가 해결될 때까지의 <strong>시간</strong>을 대폭 단축시키고, 장애 발생 자체를 원천적으로 <strong>차단</strong>하는 중요한 역할을 한다.</p>
<p>이상 징후가 탐지된 시점부터 모든 문제가 해결되고 재발 방지 대책까지 만들어지기까지 여러 과정을 거치는데, 여기서 SRE는 줄일 수 있는 시간을 가능하면 최대한 압축하여 문제가 빠르게 해결되도록 돕는다. 예를 들면, <strong>이상 징후 탐지</strong>를 <strong>자동화</strong>하고 전체 시스템을 한눈에 볼 수 있도록 <strong>대시보드</strong>를 만들어 커뮤니케이션 및 의사 결정 시간을 <strong>단축</strong>시킨다. 또한 장애에 직접 대응해야 하는 서비스 담당자가 복구와 상세 원인 파악에 집중하는 동안, <strong>외부 영향</strong>도 파악을 대신 수행하여 시간 낭비를 막아준다.</p>
<p><img src="https://images.velog.io/images/new__world/post/2d5f1db4-4476-4815-800a-c26ac6976ab2/image.png" alt=""></p>
<p><code>[그림7] 네이버 검색 SRE는 장애 복구와 상세 원인 분석을 제외한 활동에 필요한 시간을 최소화한다.</code></p>
<br>

<p>네이버 검색에서는 이렇게 SRE가 도입된 최근 3년 동안, 엄청나게 장애 비율이 감소했다. 2017년 1,311건의 업데이트가 진행되는 동안 57건의 크고 작은 장애가 발생하여 4.35%의 장애 비율을 기록했는데, 2018년에는 훨씬 많은 2,110건의 업데이트를 하면서도 2017년보다 더 적은 49건의 장애만 발생했다. 비율은 절반 수준인 2.32%이다. 심지어 2019년에는 여기서 더 발전하여 2,273건의 업데이트를 하는 동안 22건의 장애만 발생, 0.97%의 장애 비율을 기록했다. 이 수치를 통해 SRE 활동이 장애 예방에 얼마나 큰 도움이 되었는지를 유추해볼 수 있다.</p>
<p><img src="https://images.velog.io/images/new__world/post/59ef4297-87a9-43ed-b68d-1ed6c5a3bf6d/image.png" alt=""></p>
<p><code>[그림8] 최근 네이버 검색에서는 장애 발생 빈도가 매년 절반 수준으로 떨어지고 있다.</code></p>
<p><br><br></p>
<h3 id="💬-9">💬</h3>
<h3 id="마치며">마치며</h3>
<p><strong>SRE 활동을 하면서 뼈저리게 느끼는 것은 100% 완벽한 시스템이나 방법론은 존재하지 않는다는 것이다.</strong> 아무리 지속적으로 안정화 작업을 하더라도 언젠가는 예기치 못했던, 전에는 겪어본 적 없는 사건 사고가 발생한다. 이러한 불확실함 속에서도 지속적인 성과를 내기 위해서는 <strong>완벽한 도구나 방법론을 찾기보다는 실질적인 문제의 해결에 집중</strong>해야 한다. 너무나 많은 경우의 수, 복잡한 상호작용 속에서 세상에 존재할지 모를 완벽한 해답만 찾아 헤매다 보면 정작 눈앞의 문제조차 해결하지 못하고 수렁에 빠질 수 있기 때문이다.</p>
<p>그리고 <strong>포기하지 않고 끊임없이 개선해 나가는 끈기의 중요성</strong>도 알게 되었다. 정답이 없고 100%가 없다는 말은 다르게 이야기하면 끝이 없다는 뜻이다. 끝없이 나타나는 새로운 문제를 매일매일 풀어야 하고, 그때마다 수많은 시행착오를 겪을 수 밖에 없다. 하지만 이 과정을 <strong>차근차근 잘 극복해 나가다 보면 어느새 시스템이 점점 개선되는 모습</strong>을 볼 수 있다.</p>
<p>마지막으로 강조하고 싶은 것은 바로 <strong>도메인 지식과 전문가의 필요성</strong>이다. 워낙 크고 복잡한 시스템을 다뤄야 하기 때문에 범용적인 접근법만으로는 가시적인 성과를 얻기 힘들 수 있다. <strong>해당 도메인에 정통한 전문가가 구석구석 찾아가서 최적화하지 않으면 생각보다 SRE의 효과를 누리기 어려울 것</strong>이다. 네이버 검색 SRE 시스템에서도 검색 시스템의 동작 방식과 지표 특성, 사용자 패턴 등을 모두 동원하여 경보를 튜닝하고 장애 분석 및 예방 활동을 할 때 활용하고 있다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive -  브라우저 동작 원리]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC</guid>
            <pubDate>Mon, 07 Jun 2021 10:36:10 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<h3 id="브라우저-동작-원리">브라우저 동작 원리</h3>
<p>구글의 Chrome V8 자바스크립트 엔진으로 빌드된 자바스크립트 런타임 환경(Runtime Environment)인 <strong>Node.js</strong> 의 등장으로 자바스크립트는 웹 브라우저를 벗어나 서버 사이드 애플리케이션 개발에서도 사용되는 범용 개발 언어가 되었다. 하지만 가장 많이 사용되는 분야는 역시 웹 브라우저 환경에서 동작하는 웹 페이지/애플리케이션이다.</p>
<p>대부분의 프로그래밍 언어는 운영체제(Operating System, OS) 위에서 실행되지만 웹 애플리케이션의 자바스크립트는 브라우저에서 HTML, CSS와 함께 실행된다. 따라서 브라우저 환경을 고려할 때 보다 효율적인 자바스크립트 프로그래밍이 가능하다.</p>
<blockquote>
<p>브라우저의 핵심 기능은 사용자가 참조하고자 하는 <strong>웹페이지를 서버에 요청(Request)</strong>하고 <strong>서버의 응답(Response)</strong>을 받아 브라우저에 표시하는 것이다.</p>
</blockquote>
<p>브라우저는 서버로부터 HTML, CSS, Javascript, 이미지 파일 등을 응답받는다. HTML, CSS 파일은 렌더링 엔진의 HTML 파서와 CSS 파서에 의해 <strong>파싱(Parsing)</strong> 되어 <strong>DOM, CSSOM 트리로 변환</strong>되고 <strong>렌더 트리로 결합</strong>된다. 이렇게 생성된 렌더 트리를 기반으로 브라우저는 웹페이지를 표시한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/c12c644f-eac7-4b72-a4ea-329338a2c98c/image.png" alt=""></p>
<p>자바스크립트는 렌더링 엔진이 아닌 <strong>자바스크립트 엔진</strong>이 처리한다. HTML 파서는 script 태그를 만나면 자바스크립트 코드를 실행하기 위해 DOM 생성 프로세스를 중지하고 자바스크립트 엔진으로 <strong>제어 권한</strong>을 넘긴다. 제어 권한을 넘겨 받은 자바스크립트 엔진은 script 태그 내의 자바스크립트 코드 또는 script 태그의 src 어트리뷰트에 정의된 자바스크립트 파일을 로드하고 파싱하여 실행한다. 자바스크립트의 <strong>실행이 완료</strong>되면 다시 <strong>HTML 파서</strong>로 제어 권한을 넘겨서 브라우저가 중지했던 시점부터 <strong>DOM 생성을 재개</strong>한다.</p>
<p>이처럼 브라우저는 <strong>동기(Synchronous)</strong>적으로 HTML, CSS, Javascript를 처리한다. 이것은 script 태그의 위치에 따라 블로킹이 발생하여 DOM의 생성이 지연될 수 있다는 것을 의미한다. 따라서 <strong>script 태그의 위치는 중요한 의미</strong>를 갖는다.</p>
<br>

<p>body 요소의 가장 아래에 자바스크립트를 위치시키는 것은 좋은 아이디어이다. 그 이유는 아래와 같다.</p>
<ul>
<li><p>HTML 요소들이 스크립트 로딩 지연으로 인해 렌더링에 지장 받는 일이 발생하지 않아 페이지 로딩 시간이 단축된다.</p>
</li>
<li><p>DOM이 완성되지 않은 상태에서 자바스크립트가 DOM을 조작한다면 에러가 발생한다.</p>
</li>
</ul>
<p><br><br></p>
<hr>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<ul>
<li><a href="http://d2.naver.com/helloworld/59361">브라우저는 어떻게 동작하는가?</a></li>
<li><a href="https://developers.google.com/web/fundamentals/performance/critical-rendering-path/render-tree-construction?hl=ko">Render-tree Construction, Layout, and Paint</a></li>
<li><a href="https://developers.google.com/web/fundamentals/performance/critical-rendering-path/adding-interactivity-with-javascript?hl=ko">Adding interactivity with javascript</a></li>
<li><a href="http://rtcc.hanyang.ac.kr/sitedata/2015_2_ISP/howbrowserswork_20150915.pdf">오픈소스 웹킷(WebKit)의 구조와 원리</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 자바스크립트란?]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%9E%80</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%9E%80</guid>
            <pubDate>Mon, 07 Jun 2021 09:40:59 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<h3 id="1-자바스크립트의-탄생">1. 자바스크립트의 탄생</h3>
<p>1995년 당시 약 90%의 시장 점유율로 웹 브라우저 시장을 지배하고 있던 <a href="https://ko.wikipedia.org/wiki/%EB%84%B7%EC%8A%A4%EC%BC%80%EC%9D%B4%ED%94%84">넷스케이프 커뮤니케이션즈(Netscape comunications)</a>는 정적인 HTML을 동적으로 표현하기 위해 경량의 프로그래밍 언어를 도입하기로 결정했다. 그래서 탄생한 것이 브렌던 아이크(Brendan Eich)가 개발한 자바스크립트이다.</p>
<p>자바스크립트는 1996년 3월 넷스케이프 커뮤니케이션즈의 웹 브라우저인 <a href="https://en.wikipedia.org/wiki/Netscape_Navigator_2">Netscape Navigator 2</a>에 탑재되었고 &quot;Mocha&quot;로 명명되었다. 그해 9월 &quot;LiveScript&quot;로 이름이 변경되었고, 12월 &quot;JavaScript&quot;로 최종 명명되었다.</p>
<p><img src="https://images.velog.io/images/new__world/post/02ae6677-6ccd-4a82-ab22-f786f49b9bdb/image.png" alt=""></p>
<p>이렇게 탄생한 자바스크립트는 현재 모든 브라우저의 표준 프로그래밍 언어가 되었다. 그러나 자바스크립트가 순탄하게 성장했던 것은 아니다. 자바스크립트가 탄생한 뒤 얼마 지나지 않아 자바스크립트의 파생 버전인 JScript가 출시되어 자바스크립트는 위기를 맞게 된다.</p>
<p><br><br></p>
<hr>
<h3 id="2-자바스크립트의-파편화와-표준화">2. 자바스크립트의 파편화와 표준화</h3>
<p>1996년 8월, 마이크로소프트는 자바스크립트의 파생 버전인 &quot;JScript&quot;를 Internet Explorer 3.0에 탑재하였다. 그런데 문제는 JScript와 자바스크립트가 표준화되지 못하고 적당히 호환되었다는 것이다. 즉, 자사 브라우저의 시장 점유율을 점유하기 위해 자사 브라우저에서만 동작하는 기능을 경쟁적으로 추가하기 시작했다는 것이다. 이로 인해 브라우저에 따라 웹 페이지가 정상 동작하지 않는 <strong>크로스 브라우징 이슈</strong>가 발생하기 시작했고 <strong>모든 브라우저에서 동작하는 웹 페이지를 개발하는 것은 무척 어려워졌다.</strong></p>
<p>이에 자바스크립트의 파편화를 방지하고 모든 브라우저에서 동일하게 동작하는 표준화된 자바스크립트에 대한 필요성이 제기되기 시작했다.
이를 위해 1996년 11월, 넷스케이프 커뮤니케이션즈는 컴퓨터 시스템의 표준을 관리하는 비영리 표준화 기구인 <a href="https://www.ecma-international.org/">ECMA 인터내셔널</a>에 자바스크립트의 표준화를 요청하였다.</p>
<p>1997년 7월, ECMA-262라 불리는 표준화된 자바스크립트 초판(ECMAScript 1)의 명세(specification)가 완성되었고 상표권 문제로 자바스크립트는 <strong>ECMAScript</strong>로 명명되었다. 이후 1999년 ECMAScript 3(ES3)가 공개되었고 10년 만인 2009년 출시된 ECMAScript 5(ES5)는 HTML5와 함께 출현한 표준안이다.</p>
<p>2015년 ECMAScript 6(ECMAScript 2015)가 공개되었고 범용 프로그래밍 언어로서 갖추어야 할 <a href="https://poiemaweb.com/es6-block-scope">let/const 키워드</a>, <a href="https://poiemaweb.com/es6-arrow-function">화살표 함수</a>, <a href="https://poiemaweb.com/es6-class">클래스</a>, <a href="https://poiemaweb.com/es6-module">모듈</a> 등과 같은 기능들을 대거 도입하는 큰 변화가 있었다. ES6 이후의 버전업은 작은 기능의 추가 레벨로 매년 공개할 것으로 예고되었다. ECMAScript 버전별 특징은 아래와 같다.</p>
<p><img src="https://images.velog.io/images/new__world/post/47e69c4d-a75c-4615-ba3f-a038b864ec5b/image.png" alt=""></p>
<ul>
<li><a href="https://github.com/tc39/proposal-object-rest-spread">Object Rest/Spread 프로퍼티</a></li>
</ul>
<p><br><br></p>
<hr>
<h3 id="3-자바스크립트-성장의-역사">3. 자바스크립트 성장의 역사</h3>
<p>초창기 자바스크립트는 웹 페이지의 보조적인 기능을 수행하기 위해 한정적인 용도로 사용되었다. 이 시기에 대부분 로직은 주로 웹 서버에서 실행되었고 브라우저는 서버로부터 전달받은 HTML과 CSS를 단순히 렌더링하는 수준이었다.</p>
<p>1999년, 자바스크립트를 이용해서 <strong>비동기적(Asynchronous)</strong>으로 서버와 브라우저가 데이터를 교환할 수 있는 통신 기능인 <strong>Ajax(Asynchronous JavaScript and XML)</strong>가 <code>XMLHttpRequest</code> 이라는 이름으로 등장했다.</p>
<p>이전의 웹 페이지는 서버로부터 완전한 HTML을 전송 받아 웹 페이지 전체를 렌더링하는 방식으로 동작했다. 따라서 화면이 전환되면 서버로부터 새로운 HTML을 전송 받아 <strong>웹 페이지 전체를 처음부터 다시 렌더링</strong>하였다. 이는 변경이 없는 부분까지 포함된 HTML을 서버로부터 다시 전송 받기 때문에 <strong>불필요한 데이터 통신이 발생</strong>하고, 변경이 없는 부분까지 처음부터 다시 렌더링해야 하기 때문에 <strong>퍼포먼스 측면에서도 불리한 방식</strong>이다. 이로 인해 <strong>화면 전환이 일어나면 화면이 순간적으로 깜박</strong>이는 현상이 발생하고 이는 웹 애플리케이션의 한계로 받아들여졌다.</p>
<p><strong>Ajax의 등장</strong>은 이전의 패러다임을 획기적으로 전환했다. 즉, 웹페이지의 변경이 필요 없는 부분은 다시 렌더링하지 않고, 서버로부터 필요한 데이터만을 전송 받아 <strong>변경이 필요한 부분만을 한정적으로 렌더링</strong>하는 방식이 가능해진 것이다. 이로 인해 웹 브라우저에서도 데스크톱 애플리케이션과 유사한 <strong>빠른 퍼포먼스</strong>와 <strong>부드러운 화면 전환</strong>이 가능케 되었다.</p>
<p>2005년, 구글이 발표한 <a href="https://www.google.com/maps">Google Maps</a>는 웹 애플리케이션 개발 프로그래밍 언어로서 자바스크립트의 가능성을 확인하는 계기를 마련했다. 웹 브라우저에서 <strong>자바스크립트와 Ajax를 기반으로 동작</strong>하는 Google Maps가 데스크톱 애플리케이션과 비교해 손색이 없을 정도의 퍼포먼스와 부드러운 화면 전환 효과를 보여준 것이다.</p>
<p><img src="https://images.velog.io/images/new__world/post/7ff6299e-074f-43a9-948f-320ea49ed924/image.png" alt=""></p>
<p>2006년, <a href="https://jquery.com/">jQuery</a>의 등장으로 다소 번거롭고 논란이 있던 DOM(Document Object Model)을 보다 쉽게 제어할 수 있게 되었고 크로스 브라우징 이슈도 어느 정도 해결되었다. jQuery는 넓은 사용자 층을 순식간에 확보했다. 이로 인해 당시 다소 까다로운 자바스크립트보다 배우기 쉽고 직관적인 jQuery를 선호하는 개발자가 양산되기도 했다.</p>
<p><img src="https://images.velog.io/images/new__world/post/8701b76d-b892-4aec-a7f4-b45867081c24/image.png" alt=""></p>
<p>Google Maps를 통해 가능성이 확인된 자바스크립트로 웹 애플리케이션을 구축하려는 시도가 늘어가면서 보다 빠르게 동작하는 자바스크립트 엔진이 요구되었다. 2008년 등장한 구글의 <a href="https://v8.dev/">V8 자바스크립트 엔진</a>은 이러한 요구에 부합하는 빠른 성능을 보여 주었다. V8 자바스크립트 엔진의 등장으로 자바스크립트는 데스크톱 애플리케이션과 유사한 사용자 경험(user experience)을 제공할 수 있는 웹 애플리케이션 개발 프로그래밍 언어로 정착하게 되었다.</p>
<p>V8 자바스크립트 엔진으로 촉발된 자바스크립트의 발전으로 말미암아 과거 웹 서버에서 수행되던 역할들이 클라이언트(브라우저)로 이동하였고, 이로써 웹 애플리케이션에서 프론트엔드 영역이 주목받는 계기가 되었다.</p>
<p><img src="https://images.velog.io/images/new__world/post/2bdc1f28-5405-4aeb-9ee0-cdd4b1a606ff/image.png" alt=""></p>
<p>2009년, 브라우저에서만 동작하던 자바스크립트를 <strong>브라우저 이외의 환경에서 동작시킬 수 있는 자바스크립트 실행 환경</strong>인 <a href="https://nodejs.org/">Node.js</a>의 등장으로 자바스크립트는 웹 브라우저를 벗어나 서버 사이드 애플리케이션 개발에서도 사용되는 범용 프로그래밍 언어가 되었다. 웹 브라우저에서만 동작하는 반쪽짜리 프로그래밍 언어 취급을 받던 자바스크립트는 이제 프론트엔드 영역은 물론 백엔드 영역까지 아우르는 웹 프로그래밍 언어의 표준으로 자리잡고 있다.</p>
<p><img src="https://images.velog.io/images/new__world/post/20b4bb02-720b-4e2e-8210-5c8bf596ea77/image.png" alt=""></p>
<p>자바스크립트는 <a href="https://ko.wikipedia.org/wiki/%ED%81%AC%EB%A1%9C%EC%8A%A4_%ED%94%8C%EB%9E%AB%ED%8F%BC">크로스 플랫폼</a>을 위한 가장 중요한 언어로 주목받고 있다. </p>
<p>자바스크립트는 웹은 물론 모바일 하이브리드 앱(<a href="http://phonegap.com/">PhoneGap</a>, <a href="https://ionicframework.com/">Ionic</a>), 서버 사이드(<a href="https://nodejs.org/">NodeJS</a>), 데스크톱(<a href="https://electronjs.org/">Electron</a>), 머신 러닝(<a href="https://js.tensorflow.org/">TensorFlow.js</a>), 로보틱스(<a href="http://johnny-five.io/">Johnny-Five</a>) 프로그래밍 언어로서 세계에서 가장 인기있는 프로그래밍 언어이다.</p>
<p><img src="https://images.velog.io/images/new__world/post/84d72311-b06a-4927-84d2-38f98246f378/image.png" alt=""></p>
<ul>
<li><a href="https://insights.stackoverflow.com/survey/2018#most-popular-technologies">Stackoverflow Developer Survey Results 2018</a></li>
</ul>
<br>

<p>이제 웹 애플리케이션은 데스크톱 애플리케이션과 비교해도 손색없는 성능과 사용자 경험을 제공하는 것이 필수가 되었고, 개발 규모와 복잡도도 더불어 상승했다. 이전의 개발 방식으로는 복잡해진 개발 과정을 수행하기 어려워졌고, 이러한 필요에 따라 많은 패턴과 라이브러리가 출현하였다. 이는 개발에 많은 도움을 주었지만 유연하면서 확장이 쉬운 애플리케이션 아키텍처 구축을 어렵게 하였고 필연적으로 프레임워크가 등장하게 되었다. <strong>SPA(Single Page Application)</strong>가 대중화 되면서 <a href="https://angular.io/">Angular</a>, <a href="https://facebook.github.io/react">React</a>, <a href="https://vuejs.org/">Vue.js</a> 등 다양한 SPA 프레임워크/라이브러리 또한 많은 사용층을 확보하고 있다.</p>
<p><br><br></p>
<hr>
<h3 id="4-javascript와-ecmascript">4. JavaScript와 ECMAScript</h3>
<p>ECMAScript는 자바스크립트의 표준 명세인 ECMA-262를 말하며 프로그래밍 언어의 타입, 값, 객체와 프로퍼티, 함수, 빌트인 객체 등 핵심 문법(core syntax)을 규정한다. 각 브라우저 제조사는 ECMAScript를 준수하여 브라우저에 내장되는 자바스크립트 엔진을 구현한다.</p>
<p>자바스크립트는 일반적으로 프로그래밍 언어로서 기본 뼈대를 이루는 ECMAScript와 브라우저가 별도 지원하는 <a href="https://www.w3.org/standards/webdesign/script">클라이언트 사이드 Web API</a>, 즉 <code>DOM, BOM, Canvas, XMLHttpRequest, Fetch, requestAnimationFrame, SVG, Web Storage, Web Component, Web worker</code> 등을 아우르는 개념이다.</p>
<p>클라이언트 사이드 Web API는 ECMAScript와는 별도로 <a href="https://www.w3.org/">World Wide Web Consortium(W3C)</a>에서 별도의 명세로 관리하고 있다. 클라이언트 사이드 Web API의 자세한 내용은 <a href="https://developer.mozilla.org/ko/docs/Web/API">MDN web docs: Web API</a>를 참고하기 바란다.</p>
<p><br><br></p>
<hr>
<h3 id="5-자바스크립트의-특징">5. 자바스크립트의 특징</h3>
<p>자바스크립트는 HTML, CSS와 함께 <strong>웹을 구성하는 요소 중 하나로 웹 브라우저에서 동작하는 유일한 프로그래밍 언어</strong>이다. 자바스크립트는 기존의 프로그래밍 언어에서 많은 영향을 받았다. 기본 문법은 C, Java와 유사하고 Self에서는 프로토타입 기반 상속을, Scheme에서는 일급 함수의 개념을 차용했다.</p>
<p>자바스크립트는 개발자가 별도의 컴파일 작업을 수행하지 않는 <strong><a href="https://ko.wikipedia.org/wiki/%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%84%B0">인터프리터</a> 언어(Interpreter Language)</strong>이다. 대부분의 모던 자바스크립트 엔진(Chrome의 V8, FireFox의 Spidermonkey, Safari의 JavaScriptCore, Microsoft Edge의 Chakra 등)은 인터프리터와 컴파일러의 장점을 결합하여 비교적 처리 속도가 느린 인터프리터의 단점을 해결했다. <strong>인터프리터는 소스코드를 즉시 실행하고 컴파일러는 빠르게 동작하는 머신 코드를 생성하고 최적화한다.</strong> 이를 통해 컴파일 단계에서 추가적인 시간이 필요함에도 불구하고 보다 빠른 코드의 실행이 가능하다.</p>
<p>자바스크립트는 <a href="https://ko.wikipedia.org/wiki/%EB%AA%85%EB%A0%B9%ED%98%95_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D">명령형(imperative)</a>, <a href="https://ko.wikipedia.org/wiki/%ED%95%A8%EC%88%98%ED%98%95_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D">함수형(functional)</a>, <a href="https://ko.wikipedia.org/wiki/%ED%94%84%EB%A1%9C%ED%86%A0%ED%83%80%EC%9E%85_%EA%B8%B0%EB%B0%98_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D">프로토타입 기반(prototype-based) 객체지향 프로그래밍</a>을 지원하는 <a href="https://ko.wikipedia.org/wiki/%EB%8B%A4%EC%A4%91_%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84_%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D_%EC%96%B8%EC%96%B4">멀티 패러다임 프로그래밍 언어</a>이다.</p>
<p>비록 다른 객체지향 언어들과의 차이점에 대한 논쟁들이 있긴 하지만, 자바스크립트는 강력한 객체지향 프로그래밍 능력을 지니고 있다. 간혹 클래스(ES6에서 새롭게 도입되었다), 상속, 정보 은닉을 위한 키워드 private가 없어서 객체지향 언어가 아니라고 오해(<a href="http://javascript.crockford.com/javascript.html">자바스크립트는 가장 많은 오해를 받는 언어이다</a>)하는 경우도 있지만 <strong>자바스크립트는 클래스 기반 객체지향 언어보다 효율적이면서 강력한 프로토타입 기반의 객체지향 언어</strong>이다.</p>
<p><br><br></p>
<hr>
<h3 id="5-es6-브라우저-지원-현황">5. ES6 브라우저 지원 현황</h3>
<p>Internet Explorer를 제외한 대부분의 모던 브라우저는 ES6를 지원하고 있지만 100% 지원하고 있지는 않다. Node.js의 경우 v4부터 ES6를 지원하기 시작했다. ES6 지원 현황은 아래의 웹 사이트에서 확인할 수 있다.</p>
<p><img src="https://images.velog.io/images/new__world/post/d158d9f5-9f4c-4daa-a4a7-09ccac80f7cb/image.png" alt=""></p>
<ul>
<li><a href="https://kangax.github.io/compat-table/es6">ECMAScript compatibility table</a></li>
</ul>
<br>

<p>Internet Explorer를 제외한 모던 브라우저의 ES6 지원 비율은 96~99%로 거의 100%에 육박하지만 Internet Explorer나 구형 브라우저는 ES6를 대부분 지원하지 않는다. 따라서 Interneet Explorer나 구형 브라우저를 고려해야 하는 상황이라면 <a href="https://babeljs.io/">babel</a> 과 같은 트랜스파일러를 사용하여 ES6로 구현한 소스코드를 ES5 이하의 버전으로 다운그레이드할 필요가 있다. 또한 ES6에서 도입된 모듈 import/export는 아직 대부분의 브라우저가 지원하고 있지 않다. 따라서 프로젝트에서 모듈을 도입하려면 <a href="https://webpack.js.org/">Webpack</a> 과 같은 모듈 번들러를 사용해야 한다.</p>
<blockquote>
<p>트랜스파일러(Transpiling)이란 특정 언어로 작성된 코드를 비슷한 다른 언어로 변환시키는 행위를 말하며 이를 해주는 것이 <strong>트랜스파일러</strong>(Transpiler)이다.</p>
</blockquote>
<blockquote>
<p>웹 애플리케이션을 구성하는 몇십, 몇백개의 자원들을 하나의 파일로 병합 및 압축 해주는 동작을 <strong>모듈 번들링</strong>이라고 한다.</p>
</blockquote>
<p><br><br></p>
<hr>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/%EC%96%B8%EC%96%B4_%EB%A6%AC%EC%86%8C%EC%8A%A4">ECMAScript Version</a></li>
<li><a href="https://kangax.github.io/compat-table/es6">ECMAScript compatibility table</a></li>
<li><a href="http://es6-features.org/">ECMAScript 6 New Features: Overview &amp; Comparison</a></li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/API">MDN web docs: Web API</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 기본 개념과 동작 원리 이해의 중요성]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EC%9D%B4%ED%95%B4%EC%9D%98-%EC%A4%91%EC%9A%94%EC%84%B1</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90%EA%B3%BC-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC-%EC%9D%B4%ED%95%B4%EC%9D%98-%EC%A4%91%EC%9A%94%EC%84%B1</guid>
            <pubDate>Mon, 07 Jun 2021 02:19:50 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<h3 id="1-프로그래밍이란">1. 프로그래밍이란?</h3>
<p>프로그래밍이란 컴퓨터에게 실행을 요구하는 일종의 <strong>커뮤니케이션</strong>이다. 이를 위해 먼저 무엇을 실행하기 원하는지에 대한 정의가 필요하다. 다시 말해, 프로그래밍에 앞서 문제(요구사항)을 명확히 이해한 후 적절한 문제 해결 방안의 정의가 필요하다.</p>
<p>이때 요구되는 것이 <strong>문제 해결 능력</strong>이다. 혹자는 문제 해결 능력을 알고리즘과 동일시하려는 경향이 있지만 반드시 그런 것은 아니다. 물론 문제 해결 능력의 함양에 있어 알고리즘 학습은 큰 도움이 되지만 문제 해결 능력은 더 큰 차원의 능력이다.</p>
<p>대부분의 문제(요구사항)는 복잡하며 명확하지 않을 수도 있다. 따라서 문제(요구사항)를 명확히 이해하는 것이 우선되어야 하며 복잡함을 단순하게 분해(Decomposition)하고 자료를 정리하고 구분(Modeling)해야 하며 순서에 맞게 행위를 배열해야 한다.</p>
<p>즉, 프로그래밍이란 0과 1밖에 알지 못하는 기계가 실행할 수 있는 정도로 <strong>정확하고 상세하게 요구사항을 설명</strong>하는 작업이며 그 결과물이 바로 코드이다. 모호하고 대략적인 요구사항을 전달해도 우리의 머리 속에 있는 의도를 정확히 꿰뚫어 완벽히 이해하는 컴퓨터는 절대 존재할 수 없다.</p>
<p>우리는 문제 해결 방안을 고려할 때 컴퓨터의 입장에서 문제를 바라보아야 한다. 이때 필요한 것이 <strong>Computational thinking</strong>이다. 사람의 일반적인 사고 방식은 매우 포괄적이며 실생활에서 경험하고 있는 익숙한 사항에 대해 당연시하는 안이한 인식이 있다.</p>
<p>문제 해결 능력은 직감과 직관의 영역이라고 볼 수 있는데 이는 문제를 바라보는 우리의 사고와 경험에 영향을 받는다. 예를 들어 &quot;듣다(Listen)&quot; 라는 행위를 사람은 하나의 간단하고 당연한 기능으로 생각한다. 하지만 컴퓨터에게 이 행위를 설명하는 것은 단순하지 않다. 그리고 사람은 소리의 크기를 &quot;크다&quot; 또는 &quot;작다&quot; 라고 표현한다. 하지만 크다 또는 작다는 의미는 상대적인 개념으로 기준이 불명확하다. 컴퓨터에게는 양적 개념인 숫자를 사용하여 &quot;현재 볼륨보다 1단계 크게 조정하라&quot; 또는 &quot;볼륨을 60으로 조정하라&quot; 라고 명령해야 한다. 또한 &quot;좋다&quot;, &quot;붉다&quot;, &quot;사랑&quot; 과 같은 <strong>관념적 개념은 컴퓨터에게 난해한 개념</strong>이다. 사람은 지인의 얼굴을 보고 누구인지 바로 인지하지만 컴퓨터에게 이것은 매우 어려운 일이다. 347의 9제곱의 계산은 사람에게는 쉽지 않지만 컴퓨터에게는 매우 쉬운 작업이다.</p>
<p>이처럼 <strong>컴퓨터와 사람은 사고, 인지의 방식이 다르다.</strong> 따라서 해결 과제를 <strong>컴퓨터의 관점으로 사고(Computational thinking)</strong> 해야 한다. 이에는 논리적, 수학적 사고가 필요하게 되며 해결 과제를 작은 단위로 분해하고 패턴화하여 추출하며 프로그래밍 내에서 사용될 모든 개념은 평가 가능하도록 정의되어야 한다.</p>
<p>예를 들어 사람처럼 두발로 걷는 로봇을 위해 &quot;걷다&quot; 라는 기능을 디자인해 보자.</p>
<p><img src="https://images.velog.io/images/new__world/post/a6996f3c-7d9c-487b-8763-f9d64f0c0065/image.png" alt=""></p>
<p>&quot;걷다&quot; 라는 기능을 디자인하려면 판단하여야 하는 상태와 그 상태를 판단하는 시기, 그리고 판단 기준을 정의하여야 하며 이를 바탕으로 분해한 처리(Process)의 실행 여부를 결정한다. 예를 들어 장애물이란 무엇(크기, 움직임...)인지 어떤 범위 내에 있는 것인지 명확히 수치화하여 정의해야 한다.</p>
<p><br><br></p>
<hr>
<h3 id="2-프로그래밍-언어">2. 프로그래밍 언어</h3>
<p>이와 같이 문제 해결 능력을 바탕으로 정의된 문제 해결 방안은 컴퓨터에게 전달되어야 한다. 이때 명령을 수행할 주체는 컴퓨터이다. 따라서 인간이 이해할 수 있는 자연어가 아니라 컴퓨터가 이해할 수 있는 언어, 즉 <strong>기계어(Machine code)</strong>로 명령을 전달해야 한다.</p>
<p>인간이 기계어를 이해하여 직접 기계어로 명령을 전달하는 것은 매우 어려운 작업이다. 기계어는 우리가 사용하는 언어와는 너무나도 다른 체계를 가지기 때문이다. 심지어 비트 단위로 기술되어 있다.</p>
<p>아래는 x86 아키텍처 리눅스 환경에서 그 유명한 <code>&quot;Hello world&quot;</code> 를 출력하는 기계어 코드이다.</p>
<p><img src="https://images.velog.io/images/new__world/post/bc45cd39-0c9c-4f06-8975-033edd8926bf/image.png" alt=""></p>
<p>직접 기계어로 명령을 전달하는 것을 대신할 가장 유용한 대안은 인간이 이해할 수 있는 약속된 <strong>구문(Syntax, 문법)</strong> 으로 구성된 &quot;프로그래밍 언어(Programming Language)&quot;를 사용하여 프로그램을 작성한 후, 그것을 컴퓨터가 이해할 수 있는 기계어로 변환하여 주는 일종의 번역기를 이용하는 것이다. 이 일종의 번역기를 <strong>컴파일러(compiler) 혹은 인터프리터(interpreter)</strong> 라고 한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/4fc66887-0c5d-4700-94bb-920fe3371f7b/image.png" alt=""></p>
<p>언어(Language)는 자신의 생각을 상대에게 전달하는 방법으로 언어 공동체 내에서 이해될 수 있는 말의 집합이다.</p>
<p><img src="https://images.velog.io/images/new__world/post/288b8ef3-53f4-4c97-a1bb-7b69d8df918f/image.png" alt=""></p>
<p>언어는 자연어와 인공어로 구분할 수 있다. 프로그래밍 언어란 컴퓨터와의 대화(명령)에 사용되는 일종의 표현 수단으로 인간과 컴퓨터(컴파일러 또는 인터프리터) 모두가 이해할 수 있는 약속된 형태의 인공어이다.</p>
<p>아래는 &quot;Hello world&quot;를 출력하는 자바스크립트 코드이다. 위의 기계어 코드보다 인간이 이해하기 쉬운, 즉 읽기 쉬운 코드가 되었다.</p>
<pre><code>// Javascript

console.log(&#39;hello world&#39;);</code></pre><p>프로그래밍은 프로그래밍 언어를 사용하여 컴퓨터에게 실행을 요구하는 일종의 <strong>커뮤니케이션</strong>이다. 프로그래밍 언엉는 <strong>Syntax(구문)</strong>과 <strong>Semantics(의미)</strong>의 조합으로 표현된다.</p>
<p><br><br></p>
<hr>
<h3 id="3-syntax--semantics">3. Syntax &amp; Semantics</h3>
<p>프로그래밍 학습은 일반적으로 프로그래밍 언어의 문법을 배우는 것부터 시작한다. 이는 외국어 학습과 유사하다고 할 수 있다. 그러나 이미 경험을 통해 알고 있겠지만 문법을 잘 안다고 해서 외국어를 잘한다고 말할 수는 없다.</p>
<p>외국어를 잘하려면 외국어 화자의 말이나 문장을 정확히 이해한 후, 문맥에 따른 적절한 어휘 선택, 그리고 순차적으로 결론을 향해 나아가는 문장 구성이 필요하다. 즉, 문법에 맞는 문장을 구성하는 것은 물론 <strong>의미(Semantics)</strong>를 가지고 있어야 언어의 역할을 충실히 수행할 수 있다.</p>
<blockquote>
<p>Colorless green ideas sleep furiously.
– 노엄 촘스키(Noam Chomsky)</p>
</blockquote>
<p>MIT의 저명한 언어학자인 <a href="https://ko.wikipedia.org/wiki/%EB%85%B8%EC%97%84_%EC%B4%98%EC%8A%A4%ED%82%A4">노엄 촘스키</a>는 위 문장을 통해서 언어의 의미는 문맥에 있는 것이지 문법에 있는 것이 아니란 것을 지적하고 있다. 위 문장은 문법(Syntax)적으로 전혀 문제가 없지만 의미(Semantics)는 없다. 프로그래밍도 마찬가지다. 아래 예제를 보자.</p>
<pre><code>// Javascript

const number = &#39;string&#39;;
console.log(number * number*); // NaN</code></pre><p>자바스크립트의 변수에는 어떠한 타입의 값이라도 할당할 수 있다. 따라서 위 예제는 문법적으로 전혀 문제가 없다. 하지만 의미적으로는 옳지 않다. number라는 변수 이름에 문자열이 할당되어 있기 때문이다. number라는 변수 이름에는 숫자를 할당하는 것이 의미적으로 옳다.</p>
<p>결국 문제 해결 능력을 통해 만들어낸 해결 방안은 프로그래밍 언어의 문법을 통해 표현한다. 즉, 작성된 코드는 해결 방안의 구체적 구현물이다. 그리고 이것은 프로그래밍 언어의 문법에 부합하는 것은 물론이고 수행하고자 하는 바를 정확히 수행하는 것, <strong>즉 요구사항이 실현(문제가 해결)되어야 의미가 있다.</strong></p>
<p><img src="https://images.velog.io/images/new__world/post/98dbf8af-ab37-4639-a893-913d92ee5cfc/image.png" alt=""></p>
<p>대부분의 프로그래밍 언어는 “변수와 값”, “키워드”, “연산자”, “표현식과 문”, “조건문”과 “반복문”에 의한 “흐름제어(Control flow)”, “함수” 그리고 “객체”, “배열” 등의 “자료구조”와 같은 문법을 제공한다.</p>
<p>프로그래밍 언어가 제공하는 문법을 적절히 사용하여 변수를 통해 값을 저장하고 참조하며 연산자로 값을 연산, 평가하고 조건문과 반복문에 의한 흐름제어로 코드의 실행 순서를 제어하고 함수로 재사용이 가능한 문의 집합을 만들며 객체, 배열 등으로 자료를 구조화한다.</p>
<p><strong>결국 프로그래밍은 요구사항의 집합을 분석하여 적절한 자료구조와 함수의 집합으로 변환한 후, 그 흐름을 제어하는 것이다.</strong></p>
<p><br><br></p>
<hr>
<h3 id="4-기본-개념과-동작-원리-이해의-중요성">4. 기본 개념과 동작 원리 이해의 중요성</h3>
<p>프로그래머가 해야 할 일은 문제를 해결하기 위한 방안을 고안하고 이것을 문법에 맞게 코드로 구현하는 것이다. 구현된 코드는 의도한 대로 정확히 동작하여 문제를 해결해야 한다. 이때 자신이 구현한 코드가 컴퓨터 내부에서 어떻게 동작할 것인지 그리고 무엇을 돌려 줄 것인지 예측 가능해야 하며 이것을 동료에게 명확히 설명할 수 있어야 한다.</p>
<p>이를 위해서는 <strong>프로그래밍 언어의 기본 개념과 동작 원리를 정확히 이해하는 것이 중요하다.</strong> 기본 개념과 동작 원리를 이해하지 못한 상태에서 Copy &amp; Paste로 단순히 동작만 하는 코드를 만들고 그것에 만족한다면 여러분이 구현한 코드는 언제 무너져도 이상할 것이 없는 사상누각일 뿐이다. 신뢰할 수 없고 유지하고 보수하기 까다로운 코드가 될 것이다. 그리고 문제 해결 능력은 어느 선에서 성장을 멈추고 말 것이다.</p>
<p>기본 개념은 문맥에 맞는 정확한 용어를 사용할 수 있게 돕는다. 문맥에 맞는 정확한 용어의 사용은 오해를 불러 일으키지 않는 명확한 의사 소통을 가능케 한다. 이는 협업의 기본이며 필수 요소이다.</p>
<p>동작 원리의 이해는 코드의 동작을 예측할 수 있게 돕는다. 요구 사항을 코드로 구현하려면 당연히 자신이 작성하는 코드의 동작을 예측할 수 있어야 한다. 동작이 예측되지 않는 코드를 작성한다는 것은 말이 되지 않는다. 또한 에러를 발생시키는 코드를 만나면 에러가 발생하는 원인을 이해해야 디버깅이 가능하다. 이를 위해 코드의 동작을 예측할 수 있는 능력은 필수 불가결적 요소이다.</p>
<p>즉, 기본 개념과 동작 원리의 이해는 어렵고 생소한 용어들로 이루어진 기술적 의사소통을 가능케하고, 자신의 머리 속에서 코드를 실행시켜 볼 수 있는 능력을 갖게 한다. 이를 통해 다른 사람이 작성한 코드를 이해하는 것은 물론 의도 또한 파악할 수 있게 되어 보다 효과적인 코드를 생산할 수 있는 기본기를 쌓을 수 있다. 기본기는 아무리 강조해도 지나침이 없다.</p>
<blockquote>
<p>빨리 가는 유일한 방법은 제대로 가는 것이다.
-로버트 C. 마틴(Robert C. Martin), “클린 코드”의 저자</p>
</blockquote>
<p><br><br></p>
<hr>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<ul>
<li><a href="https://www.vikingcodeschool.com/posts/why-learning-to-code-is-so-damn-hard">Why Learning to Code is So Damn Hard</a></li>
<li><a href="https://github.com/kamranahmedse/developer-roadmap">Web development roadmap 2019</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 반응형 레이아웃]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EB%B0%98%EC%9D%91%ED%98%95-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EB%B0%98%EC%9D%91%ED%98%95-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83</guid>
            <pubDate>Thu, 03 Jun 2021 20:44:07 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<h2 id="반응형-레이아웃">반응형 레이아웃</h2>
<p><a href="https://poiemaweb.com/css3-layout">앞에서 살펴본 layout</a> 에는 사실 몇가지 문제가 숨겨져 있다. 그 문제를 해결할 열쇠는 바로 <strong>Responsive Web Design</strong>이다.</p>
<p>먼저 어떤 문제가 있는지 알아본다. 화면폭을 좁히면 아래 그림과 같이 화면이 망가지는데 이것은 HTML 요소에 고정폭을 지정하여 가로 스크롤을 발생시키지 않으면 해결이 어렵다.</p>
<p><img src="https://images.velog.io/images/new__world/post/ef85cfe7-9438-44a3-bbda-172c17bf8952/image.png" alt=""></p>
<p>그리고 모바일과 같이 작은 해상도의 디바이스에서 접근했을 때 화면이 너무 작아져 가시성에 문제가 발생한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/2556056f-f2a5-4c7a-be73-268cb472f387/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="1-responsive-web-design-개요">1. Responsive Web Design 개요</h3>
<p>사용자가 어떤 디바이스로 웹사이트를 방문할 지 알 수 없다. layout은 방문자의 화면 해상도를 고려하여야 한다. 가로폭이 너무 큰 layout을 작성하면 작성 해상도 모니터로 방문하였을 때 가로 스크롤이 생겨서 사용이 불편할 수도 있다.</p>
<p>또한 스마트폰이나 태블릿 등 모바일 기기는 화면이 작기 때문에 가독성에 더욱 신경써야 한다.
보통 웹사이트가 축소되어 가로 스크롤 없이 콘텐츠를 볼 수 있으나 글자가 너무 작아지기 때문이다. <strong>데스크탑용, 테블릿용, 모바일용 웹사이트를 별도 구축할 수도 있지만 One Sourece Multi Use의 관점에서 올바른 해결책은 아니다.</strong></p>
<p>이러한 문제를 해결하는 방법 중의 하나가 <strong>반응형 웹디자인(Responsive Web Design)</strong> 이다. 화면 해상도에 따라 가로폭이나 배치를 변경하여 가독성을 높이는 것이다. <strong>즉, 하나의 웹사이트를 구축하여 다양한 디바이스의 화면 해상도에 최적화된 웹사이트를 제공하는 것이다.</strong></p>
<p><img src="https://images.velog.io/images/new__world/post/8c59c326-aa90-4d01-b05d-fb796c474072/image.png" alt=""></p>
<p>또한 최근 모바일 웹페이지는 대부분 애플리케이션의 형태로 진화하고 있어 앱인지 웹인지 구분이 어려울 정도이다. HTML5/CSS3/Javascript만으로 네이티브 앱과 차이를 느낄 수 없는 앱을 만들 수 있다. </p>
<p><em>다음은 최근 관심을 끌고 있는 Web App Framework이다.</em></p>
<ul>
<li><a href="http://ionicframework.com/">ionic</a></li>
<li><a href="http://electron.atom.io/">Electron</a></li>
<li><a href="http://phonegap.com/">PhoneGap</a></li>
<li><a href="https://www.sencha.com/">Sencha Touch</a></li>
</ul>
<p><br><br></p>
<hr>
<h4 id="11-viewport-meta-tag">1.1 viewport meta tag</h4>
<p><strong>viewport란 웹페이지의 가시영역을 의미한다. viewport는 디바이스에 따라 차이가 있다.</strong></p>
<p>예를 들어 모바일 브라우저는 주화면이 세로 화면이고 윈도우 resize가 불가하며 화면 터치를 사용하는 등 데스크탑 브라우저와 구성이나 형태가 다르다. 또한 모바일의 화면은 데스크탑 화면보다 훨씬 작으므로 데스크탑용 웹페이지를 그대로 모바일에 출력하면 가독성이 현저히 나빠진다. </p>
<p>따라서 <strong>viewport를 이용하여 디바이스의 특성과 디바이스의 화면 크기 등을 고려하여 각종 디바이스 사용자에게 최적화된 웹페이지를 제공할 수 있다.</strong></p>
<p><img src="https://images.velog.io/images/new__world/post/ab35ae21-fb4e-44d8-971d-957f702d1069/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/42839da1-688e-4794-9c7a-9ae0f210a7f2/image.png" alt=""></p>
<p><a href="https://poiemaweb.com/html5-tag-basic#35-meta-tag">meta tag</a>는 브라우저 혹은 검색엔진최적화(SEO)를 위해 검색엔진에게 메타데이터를 전달하기 위해 사용된다.</p>
<p>viewport meta tag는 브라우저의 화면 설정과 관련된 정보를 제공한다.</p>
<table>
<thead>
<tr>
<th>프로퍼티</th>
<th>Description</th>
<th>사용예</th>
</tr>
</thead>
<tbody><tr>
<td>width</td>
<td>viewport 너비(px). 기본값:980px</td>
<td>width=240</td>
</tr>
<tr>
<td></td>
<td></td>
<td>width=device-width</td>
</tr>
<tr>
<td>height</td>
<td>viewport높이(px)</td>
<td>height=800</td>
</tr>
<tr>
<td></td>
<td></td>
<td>width=device-height</td>
</tr>
<tr>
<td>initial-scale</td>
<td>viewport 초기 배율</td>
<td>initial-scale=1.0</td>
</tr>
<tr>
<td>user-scale</td>
<td>확대 축소 가능 여부</td>
<td>user-scale=no</td>
</tr>
<tr>
<td>maximum-scale</td>
<td>viewport 최대 배율</td>
<td>maximun=scale=2.0</td>
</tr>
<tr>
<td>minimun-scale</td>
<td>viewport 최소 배율</td>
<td>minimum-scale=1.0</td>
</tr>
</tbody></table>
<p>meta tag에서는 px단위를 사용하며 단위 표현은 생략한다. 복수개의 프로퍼티를 사용할 때는 쉼표(,)로 구분한다.</p>
<p><strong>일반적으로 viewport meta tag는 모바일 디바이스에서만 적용된다.</strong></p>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta">meta tag: MDN</a></li>
</ul>
<p><img src="https://images.velog.io/images/new__world/post/ac701209-8753-4948-91e9-664fd3cc2cac/image.png" alt=""></p>
<p>위 예제는 가장 일반적인 viewport 설정이다. 가로폭을 디바이스의 가로폭에 맞추고 초기 화면 배율을 100%로 설정하는 것을 의미한다.</p>
<p><br><br></p>
<hr>
<h4 id="12-media">1.2 @media</h4>
<p>이것은 서로 다른 미디어 타입(print, screen...)에 따라 각각의 styles을 지정하는 것을 가능하게 한다. 다음은 일반화면(screen)과 인쇄장치 별로 서로 다른 style을 지정하는 예이다.</p>
<pre><code>&lt;!-- HTML --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;style&gt;
    @media screen {
      * { color: red; }
    }
    @media print {
      * { color: blue; }
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1&gt;@media practice&lt;/h1&gt;
  &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://images.velog.io/images/new__world/post/73d71686-5e46-46b9-864e-09d3fe746eb5/image.png" alt=""></p>
<p>반응형 웹디자인에 사용되는 핵심 기술은 <code>@media</code> 이다.</p>
<p><strong><code>@media</code> 을 사용하여 미디어 별로 style을 지정하는 것을 <code>Media Query</code> 라 한다. 디바이스를 지정하는 것뿐만 아니라 디바이스의 크기나 비율까지 구분할 수 있다.</strong></p>
<p><br><br></p>
<p><em>다음은 Media Query의 문법이다.</em></p>
<pre><code>[CODE]
@media not|only mediatype and (expressions) {
  CSS-Code;
}</code></pre><pre><code>/* CSS */
@media screen and (min-width: 480px) {
  body {
    background-color: lightgreen;
  }
}</code></pre><p><br><br></p>
<p><em>아래의 표는 Media Query의 표현식에서 사용할 수 있는 프로퍼티이다.</em></p>
<table>
<thead>
<tr>
<th>프로퍼티</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td>width</td>
<td>viewport 너비(px)</td>
</tr>
<tr>
<td>height</td>
<td>viewport 높이(px)</td>
</tr>
<tr>
<td>device-width</td>
<td>디바이스의 물리적 너비(px)</td>
</tr>
<tr>
<td>device-height</td>
<td>디바이스의 물리적 높이(px)</td>
</tr>
<tr>
<td>orientation</td>
<td>디바이스 방향 (가로 방향: landscape, 세로방향: portrait</td>
</tr>
<tr>
<td>device-aspect-ratio</td>
<td>디바이스의 물리적 width/height 비율</td>
</tr>
<tr>
<td>color</td>
<td>디바이스에서 표현 가능한 최대 색상 비트 수</td>
</tr>
<tr>
<td>monochrome</td>
<td>흑백 디바이스의 픽셀 당 비트수</td>
</tr>
<tr>
<td>resolution</td>
<td>디바이스 해상도</td>
</tr>
</tbody></table>
<p>orientation을 제외한 모든 프로퍼티는 min/max 접두사를 사용할 수 있다.</p>
<p><a href="https://www.w3.org/TR/css3-mediaqueries/#media1">W3C &gt; Media Queries &gt; Media features</a></p>
<p>일반적으로 반응형 웹 디자인은 viewport 너비(width 프로퍼티)를 기준으로 한다.</p>
<p>viewport의 width 프로퍼티를 이용하여 viewport 너비에 따라 반응하는 범위(breakpoint)를 지정할 수 있다.</p>
<pre><code>/* CSS */
/*==========  Mobile First Method  ==========*/
/* All Device */

/* Custom, iPhone Retina : 320px ~ */
@media only screen and (min-width : 320px) {

}
/* Extra Small Devices, Phones : 480px ~ */
@media only screen and (min-width : 480px) {

}
/* Small Devices, Tablets : 768px ~ */
@media only screen and (min-width : 768px) {

}
/* Medium Devices, Desktops : 992px ~ */
@media only screen and (min-width : 992px) {

}
/* Large Devices, Wide Screens : 1200px ~ */
@media only screen and (min-width : 1200px) {

}

/*==========  Non-Mobile First Method  ==========*/
/* All Device */

/* Large Devices, Wide Screens : ~ 1200px */
@media only screen and (max-width : 1200px) {

}
/* Medium Devices, Desktops : ~ 992px */
@media only screen and (max-width : 992px) {

}
/* Small Devices, Tablets : ~ 768px */
@media only screen and (max-width : 768px) {

}
/* Extra Small Devices, Phones : ~ 480px */
@media only screen and (max-width : 480px) {

}
/* Custom, iPhone Retina : ~ 320px */
@media only screen and (max-width : 320px) {

}</code></pre><p><img src="https://images.velog.io/images/new__world/post/22a660db-6c86-4ff0-b4b7-7067987a6b1d/image.png" alt=""></p>
<p><br><br></p>
<p><em>다음은 임의로 해상도를 3단계로 구분하여 breakpoint를 정의한 예제이다.</em></p>
<pre><code>&lt;!-- HTML --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;style&gt;
    /* 801px ~ */
    * { color: black; }
    /* ~ 800px */
    @media screen and (max-width: 800px) {
      * { color: blue; }
    }
    /* ~ 480px */
    @media screen and (max-width: 480px) {
      * { color: red; }
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1&gt;@media practice&lt;/h1&gt;
  &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://images.velog.io/images/new__world/post/f793b5d4-6097-4f70-8eb5-6f88e9e90561/image.png" alt=""></p>
<p><br><br></p>
<p><em>다음은 화면이 세로일 때, 가로일 때를 구분하는 예제이다.</em></p>
<p>주의할 점은 데스크탑은 언제나 가로 화면이기 때문에 <code>device-width</code> 로 스마트폰의 해상도를 지정하지 않으면 데스크탑에서도 가로화면 style이 적용되는 문제가 발생한다.</p>
<pre><code>&lt;!-- HTML --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;style&gt;
    /* 세로  */
    * { color: black; }
    /* 가로 */
    /* Desktop의 화면은 가로화면(landscape)이므로 아래 rule이 적용된다. */
    /*
    @media screen and (orientation: landscape) {
      { color: blue; }
    }
    */

    /* Landscape */
    @media screen
      /* 디바이스가 모바일일때(device-width 0 ~ 768px) */
      and (max-device-width: 760px)
      /* 가로 */
      and (orientation: landscape) {
      * { color: blue; }
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1&gt;@media practice: orientation&lt;/h1&gt;
  &lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://images.velog.io/images/new__world/post/4a319ce8-19ea-43b9-bbbc-4aa6733c5018/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="2-responsive-navigation-bar">2. Responsive Navigation Bar</h3>
<p>이제까지의 내용을 바탕으로 <a href="https://poiemaweb.com/css3-layout#1-header--navigation-bar">앞서 만들어본 예제</a>를 Responsive Web Design에 맞추어 수정해 보자.</p>
<p>디바이스 해상도에 따라 반응할 수 있도록 <code>viewport meta tag</code> 와 <code>media query</code> 를 추가한다.</p>
<pre><code>&lt;!-- HTML --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;style&gt;
    /* Media Query */
    /* for Desktop: 801px ~ */

    /* for tablet: ~ 800px */
    @media screen and (max-width: 800px) {

    }
    /* for smartphone: ~ 480px */
    @media screen and (max-width: 480px) {

    }
  &lt;/style&gt;
&lt;/head&gt;
...</code></pre><p>스마트폰, 태블릿, 데스크탑 그룹의 3단계로 구분하여 breakpoint를 정의하였다. Non Mobile First Method로 정의하였기 때문에 Media Query로 정의하지 않은 스타일은 데스크탑 그룹을 위한 코드가 된다.</p>
<pre><code>/* CSS */
/* for Desktop: 801px ~ */

/* for tablet: ~ 800px */
@media screen and (max-width: 800px) {
}</code></pre><p><strong>최대 viewport width를 800px로 한정하였다는 것은 화면 크기가 800px 이하인 디바이스(태블릿)를 위한 정의란 의미</strong>가 된다. 위 예제 내에 정의 되는 스타일은 화면 크기가 800px 이하인 디바이스에서 웹사이트가 표시될 때 실행된다.</p>
<p><a href="https://poiemaweb.com/css3-inheritance-cascading#2-%EC%BA%90%EC%8A%A4%EC%BA%90%EC%9D%B4%EB%94%A9cascading">CSS 적용 우선 순위(Cascading Order</a>에 따라 나중에 선언된 스타일이 우선 적용된다. 따라서 Media Query는 기술 순서에 의미가 있다. 만일 스마트폰용 스타일을 태블릿용 스타일보다 먼저 기술하면 최종적으로 태블릿용 스타일이 적용된다. </p>
<p>따라서 Non Mobile First 방식의 경우, max-width의 값이 큰 것부터 기술하여야 한다.</p>
<br>

<pre><code>/* CSS */
/* Media Query */
/* for Desktop: 801px ~ */

/* for smartphone: ~ 480px */
/*
Media Query는 기술 순서에 의미가 있다.
만일 스마트폰용 스타일을 태블릿용 스타일보다 먼저 기술하면 최종적으로 태블릿용 스타일이 적용된다.
Non Mobile First Method의 경우, max-width의 값이 큰 것부터 기술하여 한다.
*/
@media screen and (max-width: 480px) {

}

/* for tablet: ~ 800px */
@media screen and (max-width: 800px) {

}</code></pre><br>

<p>일반적으로 Mobile-first 방식은 해상도가 작은 순서로, Non Mobile-first 방식은 해상도가 큰 순서로 기술한다.</p>
<p><br><br></p>
<hr>
<h4 id="21-responsive-navigation-bar---tablet">2.1 Responsive Navigation Bar - Tablet</h4>
<p>데스크탑 layout에서 화면이 작아질 때 header navigation bar가 header 영역 아래로 내려오는 현상이 발생하였다. 이를 보완하기 위해 다음과 같이 태블릿에서의 layout을 정의한다.</p>
<p>viewport width가 800px 이하가 되면 header 영역을 2단(logo영역과 navigation bar영역)으로 구분하기 위하여 header 영역의 높이를 현재(60px)의 2배로 넓힌다. 그리고 logo image와 navigation bar를 centering 한다.</p>
<pre><code>/* CSS */
@media screen and (max-width: 800px) {
  header {
    height: 120px;
    text-align: center;
  }
}</code></pre><p>이때 aside, section 영역도 header의 height만큼 내려가야 한다.</p>
<pre><code>/* CSS */
@media screen and (max-width: 800px) {
  header {
    height: 120px;
    text-align: center;
  }
  #wrap {
    /* margin-top = header height */
    margin-top: 120px;
  }
  aside {
    top: 120px;
  }
}</code></pre><p>가로로 나란히 정렬되어 있던 logo image와 navigation bar를 상단과 하단으로 분리 배치하기 위하여 navigation bar의 <code>float: right;</code> 프로퍼티를 해체한다. 그러면 navigation bar는 <code>block</code> 프로퍼티를 가지게 되어 logo image의 아래 영역으로 내려가게 된다.</p>
<pre><code>/* CSS */
@media screen and (max-width: 800px) {
  header {
    height: 120px;
    text-align: center;
  }
  nav {
    float: none;
    /*margin-right: 0;*/
  }
  #wrap {
    /* margin-top = header height */
    margin-top: 120px;
  }
  aside {
    top: 120px;
  }
}</code></pre><p><img src="https://images.velog.io/images/new__world/post/bec7d1ce-0f89-4dd1-88ae-e354c1170aea/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h4 id="22-responsive-navigation-bar---smartphone">2.2 Responsive Navigation Bar - Smartphone</h4>
<p>태블릿 layout에서는 header 영역을 2단으로 분리하여 navigation bar는 header 하단 영역에 배치하였다. 하지만 스마트폰의 viewport width는 가로로 나란히 정렬되어 있는 navigation bar를 모두 담기에는 너무 좁다. </p>
<p><em>다음과 같이 스마트폰 layout을 정의한다.</em></p>
<p><img src="https://images.velog.io/images/new__world/post/4d4f86d6-050e-43b4-b571-0466c293fca4/image.png" alt=""></p>
<p>우측 navigation icon을 클릭하면 navigation bar가 수직 정렬되어 화면에 나타나도록 한다. 한번 더 클릭하면 화면에서 사라지도록 한다. 이때 navigation icon에 <code>animation</code> 효과를 부여한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/0dcbe261-e323-408a-840b-b1bf564d1488/image.png" alt=""></p>
<p>nav 요소 내에 클릭할 수 있는 navigation icon을 만들기 위한 html tag를 추가한다. label tag의 for 프로퍼티값과 input tag의 id 프로퍼티값이 일치하여야 한다.</p>
<br>

<pre><code>&lt;!-- HTML --&gt;
&lt;nav&gt;
  &lt;input class=&quot;nav-toggle&quot; id=&quot;nav-toggle&quot; type=&quot;checkbox&quot;&gt;
  &lt;label class=&quot;navicon&quot; for=&quot;nav-toggle&quot;&gt;&lt;span class=&quot;navicon-bar&quot;&gt;&lt;/span&gt;&lt;/label&gt;
  &lt;ul class=&quot;nav-items&quot;&gt;
    &lt;li&gt;&lt;a href=&quot;#home&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
...</code></pre><p>위의 코드는 checkbox의 기본 외관을 사용하지 않고 <strong>커스텀 navigation icon을 사용하기 위한 방법</strong>이다.</p>
<br>

<pre><code>&lt;!-- HTML --&gt;
&lt;label for=&quot;remeber-pw&quot;&gt;Remeber password?&lt;/label&gt;
&lt;input type=&quot;checkbox&quot; name=&quot;remeber-pw&quot; id=&quot;remeber-pw&quot;&gt;</code></pre><p>input checkbox 요소의 id 프로퍼티값과 label 요소의 for 프로퍼티값을 일치시켜 연동하면 label 요소를 클릭하여도 input checkbox 요소가 클릭된다.
이것을 이용하여 label 요소의 콘텐츠를 커스텀 navigation icon으로 만들어주고 input checkbox 요소의 기본 외관을 비표시하는 방법이다.</p>
<p>그럼 navigation icon을 만들어 보자.
navigation icon은 input checkbox 요소와 연동되어야 하므로 label 요소를 사용하였다.  즉, navigation icon을 클릭하면 checkbox input tag도 checked 상태가 된다.</p>
<p>🔽navigation icon의 style은 다음과 같이 정의한다.</p>
<pre><code>/* CSS */
.navicon {
  cursor: pointer;
  height: 60px;
  padding: 28px 15px;
  position: absolute;
  top: 0; right: 0;
}</code></pre><p>navigation icon은 header 우측의 절대위치에 배치되어야 하므로 <code>position: absolute;</code> 를 지정한다.</p>
<p>absolute 프로퍼티는 부모 요소 또는 가장 가까이 있는 조상 요소(static 제외)를 기준으로 좌표 프로퍼티(top, bottom, left, right)만큼 이동한다. 즉, <strong>relative, absolute, fixed 프로퍼티가 선언되어 있는 부모 또는 조상 요소를 기준으로 위치가 결정</strong>된다. 만일 부모 또는 조상 요소가 static인 경우, document body를 기준으로 하여 좌표 프로퍼티대로 위치하게 된다.</p>
<p>이 경우, navigation icon은 body를 기준으로 위치하면 되므로 부모 요소에 별도의 처리가 필요없다.</p>
<br>

<p>_다음은 label tag 내의 span tag의 style을 정의한다. _ 
span tag는 navigation icon의 내부 막대 3개(클릭 시에는 X표시)를 표현하기 위해 정의하였다.</p>
<pre><code>/* CSS */
.navicon-bar {
  display: block;
  width: 20px;
  height: 3px;
  background-color: #333;
}</code></pre><p><img src="https://images.velog.io/images/new__world/post/d2354b64-5e10-408f-b2e1-a5495b03ddd0/image.png" alt=""></p>
<p>위 그림과 같이 navigation icon의 내부 막대 1개가 표기된다.
<code>가상 요소 선택자(Pseudo-Element Selector)</code> 를 사용하여 navigation icon의 내부 막대 앞뒤 공간에 내부 막대를 추가한다.</p>
<pre><code>/* CSS */
.navicon-bar::before,
.navicon-bar::after {
  background-color: #333;
  content: &quot;&quot;;
  display: block;
  height: 100%;
  width: 100%;
  position: absolute;
}
.navicon-bar::before {
  top: -7px;
}
.navicon-bar::after {
  top: 7px;
}</code></pre><p>절대 위치를 지정하기 위해 <code>position: absolute;</code> 를 사용하였으므로 가상 요소의 부모 요소인 span 요소(.navicon-bar)에 <code>position: relative;</code> 를 추가한다.</p>
<pre><code>/* CSS */
.navicon-bar {
  background-color: #333;
  display: block;
  position: relative;
  width: 20px;
  height: 3px;
}</code></pre><p><br><br></p>
<p><img src="https://images.velog.io/images/new__world/post/789b28c1-fb46-4479-8d37-2a9e200ca91d/image.png" alt=""></p>
<p>아직 navigation icon을 클릭하여도 아무런 반응이 없다. navigation icon을 클릭하면 클릭되었음을 사용자가 확이할 수 있도록 navigation icon의 style을 변화시킨다.</p>
<p>input checkbox tag의 가<strong>상 클래스 선택자 checked를 이용하여 클릭되었을 때(input:checked)와 그렇지 않을 때를 구분할 수 있다.</strong></p>
<pre><code>/* CSS */
.nav-toggle:checked ~ .navicon &gt; .navicon-bar {
  background: transparent;
}
.nav-toggle:checked ~ .navicon &gt; .navicon-bar::before {
  transform: rotate(45deg);
  top: 0;
}
.nav-toggle:checked ~ .navicon &gt; .navicon-bar::after {
  transform: rotate(-45deg);
  top: 0;
}</code></pre><p>먼저 중간에 위치한 막대를 없앤다. 그리고 상하 막대롤 45도 회전시킨다. 
이때 위치가 틀어지므로 <code>top: 0;</code> 로 보정한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/7165c5b3-d7b3-41aa-ac1b-89f0d9d83d8c/image.png" alt=""></p>
<p>navigation icon에 transition 효과를 부여하여 좀 더 부드럽게 움직이도록 한다.</p>
<pre><code>/* CSS */
.navicon-bar {
  background-color: #333;
  display: block;
  position: relative;
  transition: background-color .2s ease-out;
  width: 20px;
  height: 3px;
}
.navicon-bar::before,
.navicon-bar::after {
  background-color: #333;
  content: &quot;&quot;;
  display: block;
  height: 100%;
  width: 100%;
  position: absolute;
  transition: all .2s ease-out;
}</code></pre><p><strong>transition 프로퍼티는 property, duration, delay 순으로 정의한다.</strong>
navigation icon을 클릭하면 의도하지 않게 이미지가 선택되는 현상이 발생할 수 있다.</p>
<p><img src="https://images.velog.io/images/new__world/post/cf4da4e6-77db-4349-8ccc-444c92f5fdbd/image.png" alt=""></p>
<p>이것은 navigation icon이 텍스트이기 때문에 발생하는 문제이다. 이 문제는 텍스트 선택을 차단하는 방법인 <code>user-select: none;</code> 프로퍼티를 지정하여 회피할 수 있다. user-select 프로퍼티는 혀재 W3C(World Wide Web 컨소시엄) CSS 사양에 포함되어 있지 않기 때문에 벤더프리픽스(vendor prefix)를 사용하여야 한다.</p>
<blockquote>
</blockquote>
<p>💬
벤더 프리픽스(Vendor Prefix): 
세계적으로 가장 많이 사용되는 웹 브라우저에는 익스플로러, 크롬, 파이어폭스, 사파리, 오페라 등이 있다.
이러한 주요 웹 브라우저 공급자가 새로운 실험적인 기능을 제공할 때 이전 버전의 웹 브라우저에 그 사실을 알려주기 위해 사용하는 접두사(prefix)를 의미한다. <strong>즉 아직 CSS 권고안에 포함되지 못한 기능이나, CSS 권고안에는 포함되어 있지만 아직 완벽하게 제정된 상태가 아닌 기능을 사용하고자 할 때 벤더 프리픽스를 사용</strong>하게 된다.
그렇게 하면 <strong>해당 기능이 포함되어 있지 않은 이전 버전의 웹 브라우저에서도 그 기능을 사용할 수 있게 된다.</strong>
<a href="http://tcpschool.com/css/css3_module_vendorPrefix">벤더프리픽스(TCP)</a></p>
<pre><code>/* CSS */
.navicon {
  cursor: pointer;
  height: 60px;
  padding: 28px 15px;
  position: absolute;
  top: 0; right: 0;

  -webkit-user-select: none;  /* Chrome all / Safari all */
  -moz-user-select: none;     /* Firefox all */
  -ms-user-select: none;      /* IE 10+ */
  user-select: none;          /* Likely future */
}</code></pre><p>navigation icon과 checkbox input tag는 스마트폰 layout 이외의 경우, 화면에 표시되어서는 안된다. 따라서 <code>display: none;</code> 으로 화면에 표시되지 않도록 한다. <code>display: none;</code> 은 해당 공간조차 점유하지 않지만 <code>visibility: hidden;</code> 을 사용하면 해당 공간은 남아있고 표시만 되지 않는다. <a href="https://poiemaweb.com/css3-display">참고: CSS display</a></p>
<p><a href="https://poiemaweb.com/css3-inheritance-cascading#2-%EC%BA%90%EC%8A%A4%EC%BA%90%EC%9D%B4%EB%94%A9cascading">CSS 적용 우선 순위 (Cascading Order)</a> 를 고려하여 가장 마지막에 정의하는 것이 안전하다. <strong>일반적으로 media query를 가장 마지막에 정의하므로 media query 정의부 직전에 위치시킨다.</strong></p>
<pre><code>/* CSS */
.nav-toggle {
  display: none;
}
.navicon {
  display: none;
}</code></pre><p>🔽tablet용 layout에서 header height를 2배로 하였으므로 mobile용 layout을 위해 다시 60px로 되돌린다.</p>
<pre><code>/* CSS */
@media screen and (max-width: 480px) {
  header {
    height: 60px;
  }
}</code></pre><p>🔽스마트폰 layout에서는 navigation bar가 초기상태에서 비표시되어야 한다. 그리고 navigation icon은 표시되어야 한다. 아직 navigation icon을 완성하지 않았으므로 표시되지 않는다.</p>
<pre><code>/* CSS */
@media screen and (max-width: 480px) {
  header {
    height: 60px;
  }
  .nav-items {
    display: none;
  }
  .navicon {
    display: block;
  }
}</code></pre><p>🔽콘텐츠 영역이 아직 tablet layout에 맞추어 아래로 내려가 있다. header 영역 바로 아래로 다시 끌어 올린다.</p>
<pre><code>/* CSS */
@media screen and (max-width: 480px) {
  /*...*/
  #wrap {
    /* margin-top = header height */
    margin-top: 60px;
  }
  aside {
    top: 60px;
  }
  /*...*/
}</code></pre><p>🔽마지막으로 navigation icon을 클릭하면 navigation item이 표시되도록 한다.</p>
<pre><code>/* CSS */
@media screen and (max-width: 480px) {
  ...

  .nav-toggle:checked ~ .nav-items {
    display: block;
    width: 100%;
    background-color: #fff;
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
  }
  .nav-items &gt; li  {
    display: block;
  }
  .nav-items &gt; li &gt; a {
    line-height: 50px;
  }
}</code></pre><p><br><br></p>
<hr>
<h4 id="완성된-responsive-navigation-bar-소스코드">완성된 Responsive Navigation Bar 소스코드</h4>
<p><em>다음은 완성된 Responsive Navigation Bar 소스코드이다.</em></p>
<pre><code>/* HTML */
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
  &lt;style&gt;
    /* Simple Reset CSS */
    * {
      margin: 0; padding: 0;
      box-sizing: border-box;
    }
    body {
      font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;
      color: #58666e;
      background-color: #f0f3f4;
      -webkit-font-smoothing: antialiased;
      -webkit-text-size-adjus: 100%;  /* iphone font size 변경 방지 */
    }
    li { list-style: none; }
    a { text-decoration: none; }
    h1, h2, h3, h4, h5, h6, p {
      margin: 10px 5px;
    }
    h1 { font-size: 1.8em; }

    #wrap {
      width: 100%;
      /* margin-top = header height */
      margin-top: 60px;
    }

    /* Navigation bar */
    header {
      /* for sticky header */
      position: fixed;
      top: 0;

      width: 100%;
      height: 60px;
      z-index: 2000;
      background-color: #fff;
      box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
    }
    .logo {
      display: inline-block;
      height: 36px;
      margin: 12px 0 12px 25px;
    }
    .logo &gt; img { height: 36px; }
    nav {
      float: right;
    }
    .nav-items {
      margin-right: 20px;
    }
    .nav-items &gt; li {
      display: inline-block; /* 가로정렬 */
    }
    .nav-items &gt; li &gt; a {
      line-height: 60px; /* for Vertical Centering */
      padding: 0 30px;   /* nav item간 간격 */
      color: rgba(0,0,0,0.4);
    }
    .nav-items &gt; li &gt; a:hover {
      color: rgba(0,0,0,0.8);
    }

    /* navigation icon for Mobile Layout */
    .navicon {
      cursor: pointer;
      height: 60px;
      padding: 28px 15px;
      position: absolute;
      top: 0; right: 0;

      -webkit-user-select: none;  /* Chrome all / Safari all */
      -moz-user-select: none;     /* Firefox all */
      -ms-user-select: none;      /* IE 10+ */
      user-select: none;          /* Likely future */
    }
    /* nav icon의 내부 막대 */
    .navicon-bar {
      background-color: #333;
      display: block;
      position: relative;
      /* navigation icon animation */
      transition: background-color .2s ease-out;
      width: 20px;
      height: 3px;
    }
    .navicon-bar::before,
    .navicon-bar::after {
      background-color: #333;
      content: &quot;&quot;;
      display: block;
      height: 100%;
      width: 100%;
      position: absolute;
      /* navigation icon animation */
      transition: all .2s ease-out;
    }
    .navicon-bar::before {
      top: -7px;
    }
    .navicon-bar::after {
      top: 7px;
    }
    /* toggle navigation icon */
    .nav-toggle:checked ~ .navicon &gt; .navicon-bar {
      background: transparent;
    }
    .nav-toggle:checked ~ .navicon &gt; .navicon-bar::before {
      transform: rotate(45deg);
      top: 0;
    }
    .nav-toggle:checked ~ .navicon &gt; .navicon-bar::after {
      transform: rotate(-45deg);
      top: 0;
    }

    /* contents */
    /* clearfix */
    #content-wrap:after {
      content: &quot;&quot;;
      display: block;
      clear: both;
    }
    aside {
      /* for fixed side bar */
      position: fixed;
      top: 60px;
      bottom: 0;

      width: 200px;  /* 너비 고정 */
      padding-top: 25px;
      background-color: #333;
    }
    /* aside navigation */
    aside &gt; ul {
      width: 200px;
    }
    aside &gt; ul &gt; li &gt; a {
      display: block;
      color: #fff;
      padding: 10px 0 10px 20px;
    }
    aside &gt; ul &gt; li &gt; a.active {
      background-color: #4CAF50;
    }
    aside &gt; ul &gt; li &gt; a:hover:not(.active) {
      background-color: #555;
    }
    aside &gt; h1 {
      padding: 20px 0 20px 20px;
      color: #fff;
    }
    /* Section */
    section {
      float: right;
      margin-left: 200px;  /*aside width*/
    }
    article {
      margin: 10px;
      padding: 25px;
      background-color: white;
    }
    /* footer */
    footer {
      /* footer를 aside위에 올리기 위해 사용(부유객체) */
      position: absolute;
      left: 0;
      bottom: 0;
      width: 100%;
      height: 60px;
      padding: 0 25px;
      line-height: 60px;
      color: #8a8c8f;
      border-top: 1px solid #dee5e7;
      background-color: #f2f2f2;
    }

    .nav-toggle {
      display: none;
    }
    .navicon {
      display: none;
    }

    /* Media Query */
    /* for tablet: ~ 800px */
    @media screen and (max-width: 800px) {
      header {
        height: 120px;
        text-align: center;
      }
      nav {
        float: none;
        margin-right: 0;
      }
      #wrap {
        /* margin-top = header height */
        margin-top: 120px;
      }
      aside {
        top: 120px;
      }
    }
    /* for smartphone: ~ 480px */
    @media screen and (max-width: 480px) {
      header {
        height: 60px;
      }
      .nav-items {
        display: none;
      }
      .navicon {
        display: block;
      }
      #wrap {
        /* margin-top = header height */
        margin-top: 60px;
      }
      aside {
        top: 60px;
      }
      /* View navigation item */
      .nav-toggle:checked ~ .nav-items {
        display: block;
        width: 100%;
        background-color: #fff;
        box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
      }
      .nav-items &gt; li  {
        display: block;
      }
      .nav-items &gt; li &gt; a {
        line-height: 50px;
      }
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id=&quot;wrap&quot;&gt;
    &lt;header&gt;
      &lt;a class=&quot;logo&quot; href=&quot;#home&quot;&gt;&lt;img src=&quot;https://poiemaweb.com/img/logo.png&quot;&gt;&lt;/a&gt;
      &lt;nav&gt;
        &lt;input class=&quot;nav-toggle&quot; id=&quot;nav-toggle&quot; type=&quot;checkbox&quot;&gt;
        &lt;label class=&quot;navicon&quot; for=&quot;nav-toggle&quot;&gt;&lt;span class=&quot;navicon-bar&quot;&gt;&lt;/span&gt;&lt;/label&gt;
        &lt;ul class=&quot;nav-items&quot;&gt;
          &lt;li&gt;&lt;a href=&quot;#home&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#news&quot;&gt;News&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#contact&quot;&gt;Contact&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#about&quot;&gt;About&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/nav&gt;
    &lt;/header&gt;

    &lt;div id=&quot;content-wrap&quot;&gt;
      &lt;aside&gt;
        &lt;h1&gt;Aside&lt;/h1&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#&quot; class=&quot;active&quot;&gt;London&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Paris&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Tokyo&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Newyork&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/aside&gt;
      &lt;section&gt;
        &lt;article id=&quot;london&quot;&gt;
          &lt;h1&gt;London&lt;/h1&gt;
          &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
          &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
          &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
        &lt;/article&gt;
        &lt;article id=&quot;paris&quot;&gt;
          &lt;h1&gt;Paris&lt;/h1&gt;
          &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
          &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
          &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
        &lt;/article&gt;
        &lt;article id=&quot;tokyo&quot;&gt;
          &lt;h1&gt;Tokyo&lt;/h1&gt;
          &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
          &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
          &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
        &lt;/article&gt;
        &lt;article id=&quot;newyork&quot;&gt;
          &lt;h1&gt;Newyork&lt;/h1&gt;
          &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
          &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
          &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
        &lt;/article&gt;
      &lt;/section&gt;
      &lt;!-- end of content-wrap --&gt;
    &lt;/div&gt;
    &lt;footer&gt;© Copyright 2016 ungmo2&lt;/footer&gt;
  &lt;!-- end of wrap   --&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://images.velog.io/images/new__world/post/85fbb6c8-0d21-45d3-9945-9fde65c0228a/image.png" alt=""></p>
<pre><code>© Copyright 2016 ungmo2</code></pre><p><br><br></p>
<hr>
<h3 id="3-section--aside--footer">3. Section &amp; Aside &amp; Footer</h3>
<p>현재 article은 layout에 상관없이 1행에 1개씩 배치되었다. responsive web design의 효과를 좀 더 체감하기 위하여 1행에 2열로 배치한다. </p>
<p>article을 2열로 배치하기 위해서 width 값을 지정하여야 한다. <code>%</code> 로 width 값을 지정하여 viewport에 상대적인 너비를 갖도록 한다. 이때 margin도 <code>%</code> 로 지정한다. 그리고 <code>float: left;</code> 를 지정하여 2열로 정렬되도록 한다.</p>
<pre><code>/* CSS */
article {
  width: 48.5%;
  margin: 1%;
  padding: 25px;
  background-color: white;
  float: left;
}</code></pre><p>🔽짝수번째 배치되는 article의 좌측 마진과 3번째부터 등장하는 article의 위측 마진을 <code>0</code> 으로 하여 가운데 마진이 2배가 되는 것을 방지한다.</p>
<pre><code>/* CSS */
article:nth-of-type(2n) {
  margin-left: 0;
}
article:nth-of-type(n+3) {
  margin-top: 0;
}</code></pre><p>🔽tablet layout을 작성한다. 800px 이하로 화면이 작아지면 2열 배치되어 있던 article을 1열로 배치한다.</p>
<pre><code>/* CSS */
@media screen and (max-width: 800px) {
  ...
  article {
    width: inherit;
    display: block;
    margin: 10px;
    float: none;
  }
  article:nth-of-type(2n) {
    margin: 10px;
  }
  article:nth-of-type(n+2) {
    margin-top: 0;
  }
}</code></pre><p>🔽mobile layout을 작성한다. 480px 이하로 화면이 작아지면 고정 배치되어 있던 aside를 article 위로 올려 배치한다.</p>
<pre><code>/* CSS */
@media screen and (max-width: 480px) {
  /*...*/
  aside {
    top: 60px;
    position: static;
    width: 100%;
    padding: 5px 0;
  }
  /* aside navigation */
  aside &gt; ul {
    width: 100%;
  }
  aside &gt; h1 {
    padding: 5px 0 10px 20px;
    color: #fff;
  }
  section {
    float: none;
    margin-left: 0;
  }
  /*...*/
}</code></pre><p><br><br></p>
<hr>
<h3 id="완성된-전체-코드">완성된 전체 코드</h3>
<p><em>완성된 코드는 아래와 같다.</em></p>
<pre><code>&lt;!--- HTML --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
    &lt;style&gt;
      /* Simple Reset CSS */
      * {
        margin: 0; padding: 0;
        box-sizing: border-box;
      }
      body {
        font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;
        color: #58666e;
        background-color: #f0f3f4;
        -webkit-font-smoothing: antialiased;
        -webkit-text-size-adjus: 100%;  /* iphone font size 변경 방지 */
      }
      li { list-style: none; }
      a { text-decoration: none; }
      h1, h2, h3, h4, h5, h6, p {
        margin: 10px 5px;
      }
      h1 { font-size: 1.8em; }

      #wrap {
        width: 100%;
        /* margin-top = header height */
        margin-top: 60px;
      }

      /* Navigation bar */
      header {
        /* for sticky header */
        position: fixed;
        top: 0;

        width: 100%;
        height: 60px;
        z-index: 2000;
        background-color: #fff;
        box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
      }
      .logo {
        display: inline-block;
        height: 36px;
        margin: 12px 0 12px 25px;
      }
      .logo &gt; img { height: 36px; }
      nav {
        float: right;
      }
      .nav-items {
        margin-right: 20px;
      }
      .nav-items &gt; li {
        display: inline-block; /* 가로정렬 */
      }
      .nav-items &gt; li &gt; a {
        line-height: 60px; /* for Vertical Centering */
        padding: 0 30px;   /* nav item간 간격 */
        color: rgba(0,0,0,0.4);
      }
      .nav-items &gt; li &gt; a:hover {
        color: rgba(0,0,0,0.8);
      }

      /* navigation icon for Mobile Layout */
      .navicon {
        cursor: pointer;
        height: 60px;
        padding: 28px 15px;
        position: absolute;
        top: 0; right: 0;

        -webkit-user-select: none;  /* Chrome all / Safari all */
        -moz-user-select: none;     /* Firefox all */
        -ms-user-select: none;      /* IE 10+ */
        user-select: none;          /* Likely future */
      }
      /* nav icon의 내부 막대 */
      .navicon-bar {
        background-color: #333;
        display: block;
        position: relative;
        /* navigation icon animation */
        transition: background-color .2s ease-out;
        width: 20px;
        height: 3px;
      }
      .navicon-bar::before,
      .navicon-bar::after {
        background-color: #333;
        content: &quot;&quot;;
        display: block;
        height: 100%;
        position: absolute;
        /* navigation icon animation */
        transition: all .2s ease-out;
        width: 100%;
      }
      .navicon-bar::before {
        top: -7px;
      }
      .navicon-bar::after {
        top: 7px;
      }
      /* toggle navigation icon */
      .nav-toggle:checked ~ .navicon &gt; .navicon-bar {
        background: transparent;
      }
      .nav-toggle:checked ~ .navicon &gt; .navicon-bar::before {
        transform: rotate(45deg);
        top: 0;
      }
      .nav-toggle:checked ~ .navicon &gt; .navicon-bar::after {
        transform: rotate(-45deg);
        top: 0;
      }

      /* contents */
      /* clearfix */
      #content-wrap:after {
        content: &quot;&quot;;
        display: block;
        clear: both;
      }
      aside {
        /* for fixed side bar */
        position: fixed;
        top: 60px;
        bottom: 0;

        width: 200px;  /* 너비 고정 */
        padding-top: 25px;
        background-color: #333;
      }
      /* aside navigation */
      aside &gt; ul {
        width: 200px;
      }
      aside &gt; ul &gt; li &gt; a {
        display: block;
        color: #fff;
        padding: 10px 0 10px 20px;
      }
      aside &gt; ul &gt; li &gt; a.active {
        background-color: #4CAF50;
      }
      aside &gt; ul &gt; li &gt; a:hover:not(.active) {
        background-color: #555;
      }
      aside &gt; h1 {
        padding: 20px 0 20px 20px;
        color: #fff;
      }
      /* Section */
      section {
        float: right;
        margin-left: 200px;  /*aside width*/
      }
      article {
        width: 48.5%;
        margin: 1%;
        padding: 25px;
        background-color: white;
        float: left;
      }
      article:nth-of-type(2n) {
        margin-left: 0;
      }
      article:nth-of-type(n+3) {
        margin-top: 0;
      }
      /* footer */
      footer {
        /* footer를 aside위에 올리기 위해 사용(부유객체) */
        position: absolute;
        height: 60px;
        width: 100%;
        padding: 0 25px;
        line-height: 60px;
        color: #8a8c8f;
        border-top: 1px solid #dee5e7;
        background-color: #f2f2f2;
      }

      .nav-toggle {
        display: none;
      }
      .navicon {
        display: none;
      }

      /* Media Query */
      /* for tablet: ~ 800px */
      @media screen and (max-width: 800px) {
        header {
          height: 120px;
          text-align: center;
        }
        nav {
          float: none;
          margin-right: 0;
        }
        #wrap {
          /* margin-top = header height */
          margin-top: 120px;
        }
        aside {
          top: 120px;
        }

        article {
          width: inherit;
          display: block;
          margin: 10px;
          float: none;
        }
        article:nth-of-type(2n) {
          margin: 10px;
        }
        article:nth-of-type(n+2) {
          margin-top: 0;
        }
      }
      /* for smartphone: ~ 480px */
      @media screen and (max-width: 480px) {
        header {
          height: 60px;
        }
        .nav-items {
          display: none;
        }
        .navicon {
          display: block;
        }
        #wrap {
          /* margin-top = header height */
          margin-top: 60px;
        }
        aside {
          top: 60px;
          position: static;
          width: 100%;
          padding: 5px 0;
        }
        /* aside navigation */
        aside &gt; ul {
          width: 100%;
        }
        aside &gt; h1 {
          padding: 5px 0 10px 20px;
          color: #fff;
        }
        section {
          float: none;
          margin-left: 0;
        }
        /* View navigation item */
        .nav-toggle:checked ~ .nav-items {
          display: block;
          width: 100%;
          background-color: #fff;
          box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
        }
        .nav-items &gt; li  {
          display: block;
        }
        .nav-items &gt; li &gt; a {
          line-height: 50px;
        }
      }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div id=&quot;wrap&quot;&gt;
      &lt;header&gt;
        &lt;a class=&quot;logo&quot; href=&quot;#home&quot;&gt;&lt;img src=&quot;https://poiemaweb.com/img/logo.png&quot;&gt;&lt;/a&gt;
        &lt;nav&gt;
          &lt;input class=&quot;nav-toggle&quot; id=&quot;nav-toggle&quot; type=&quot;checkbox&quot;&gt;
          &lt;label class=&quot;navicon&quot; for=&quot;nav-toggle&quot;&gt;&lt;span class=&quot;navicon-bar&quot;&gt;&lt;/span&gt;&lt;/label&gt;
          &lt;ul class=&quot;nav-items&quot;&gt;
            &lt;li&gt;&lt;a href=&quot;#home&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#news&quot;&gt;News&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#contact&quot;&gt;Contact&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#about&quot;&gt;About&lt;/a&gt;&lt;/li&gt;
          &lt;/ul&gt;
        &lt;/nav&gt;
      &lt;/header&gt;

      &lt;div id=&quot;content-wrap&quot;&gt;
        &lt;aside&gt;
          &lt;h1&gt;Aside&lt;/h1&gt;
          &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;#&quot; class=&quot;active&quot;&gt;London&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Paris&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Tokyo&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Newyork&lt;/a&gt;&lt;/li&gt;
          &lt;/ul&gt;
        &lt;/aside&gt;
        &lt;section&gt;
          &lt;article id=&quot;london&quot;&gt;
            &lt;h1&gt;London&lt;/h1&gt;
            &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
            &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
            &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
          &lt;/article&gt;
          &lt;article id=&quot;paris&quot;&gt;
            &lt;h1&gt;Paris&lt;/h1&gt;
            &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
            &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
            &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
          &lt;/article&gt;
          &lt;article id=&quot;tokyo&quot;&gt;
            &lt;h1&gt;Tokyo&lt;/h1&gt;
            &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
            &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
            &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
          &lt;/article&gt;
          &lt;article id=&quot;newyork&quot;&gt;
            &lt;h1&gt;Newyork&lt;/h1&gt;
            &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
            &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
            &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
          &lt;/article&gt;
        &lt;/section&gt;
        &lt;!-- end of content-wrap --&gt;
      &lt;/div&gt;
      &lt;footer&gt;© Copyright 2016 ungmo2&lt;/footer&gt;
    &lt;!-- end of wrap   --&gt;
    &lt;/div&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://images.velog.io/images/new__world/post/22eb133c-9e6c-4512-9443-f6db562e0b8c/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/aa32f860-2d25-488f-be40-2be00a5868d3/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/159ffc78-ed32-4cce-a0d8-c4e76bff9925/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<ul>
<li><a href="https://quirksmode.org/css/mediaqueries/mobile.html">Media queries</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive - 레이아웃]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EB%A0%88%EC%9D%B4%EC%95%84%EC%9B%83</guid>
            <pubDate>Tue, 01 Jun 2021 17:26:33 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<h2 id="레이아웃">레이아웃</h2>
<p>table을 사용하여 layout을 만들기도 하였으나 html과 css의 본연의 취지와도 맞지 않을 뿐더러 반응형 웹 페이지 작성이 곤란하며 코드의 양 또한 많아져 현재는 거의 사용하지 않는다. 모던한 웹 페이지는 style과 layout을 담당하는 CSS를 사용하여 layout을 구성하는 것이 바람직하다.</p>
<p><strong>layout의 핵심은 블록 레벨 요소들을 원하는 위치에 배열하는 것이다.</strong></p>
<p><img src="https://images.velog.io/images/new__world/post/9b35ca3c-b25c-4fbc-8f9f-552f16d134d7/image.png" alt=""></p>
<p>모바일 사용자가 데스크탑 사용자보다 많은 상황을 감안하여 화면의 크기에 따라 적절히 화면 구성을 변화시키는 반응형 웹 디자인(Responsive Web Design) 또한 모던 웹 사이트의 필수 사항이 되었다.</p>
<p><img src="https://images.velog.io/images/new__world/post/02f0b174-d669-47e9-affa-611942a2f374/image.png" alt=""></p>
<p>CSS를 사용하여 layout을 구성할 때에 자주 사용되는 핵심 기술은 <code>float</code> 이다. 다음은 전형적인 웹사이트의 layout 이다.</p>
<p><img src="https://images.velog.io/images/new__world/post/2de9c214-ce8c-48ae-943a-3183af4956be/image.png" alt=""></p>
<p><code>layout</code> 이란 <strong>웹사이트를 구성하는 요소들을 배치할 공간을 분할하고 정렬하는 것이다.</strong> 공간을 분할할 때는 먼저 행을 구분한 후, 행 내부 요소를 분리하는 것이 일반적이다.</p>
<p>아래 예제는 <em>2 column layout</em> 의 일반적인 골격이다.</p>
<pre><code>&lt;!-- html --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;body&gt;
  &lt;div id=&quot;wrap&quot;&gt;
    &lt;header&gt;
      &lt;nav&gt;
        &lt;ul&gt;
          &lt;li&gt;...&lt;/li&gt;
          &lt;li&gt;...&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/nav&gt;
    &lt;/header&gt;
    &lt;div id=&quot;content-wrap&quot;&gt;
      &lt;aside&gt;
        &lt;ul&gt;
          &lt;li&gt;...&lt;/li&gt;
          &lt;li&gt;...&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/aside&gt;
      &lt;section&gt;
        &lt;article&gt;...&lt;/article&gt;
        &lt;article&gt;...&lt;/article&gt;
      &lt;/section&gt;
    &lt;/div&gt;
    &lt;footer&gt;&lt;/footer&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://images.velog.io/images/new__world/post/e02013da-b441-46ec-8dbf-cf82ac3471e8/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="1-header--navigation-bar">1. Header &amp; Navigation Bar</h3>
<p>대부분의 웹사이트는 Navigation Bar를 가지고 있다. <strong>Navigation Bar는 웹사이트의 필수 구성 요소라고 할 수 있을 것이다.</strong></p>
<p><img src="https://images.velog.io/images/new__world/post/387b6100-8a54-4f65-b6c7-758a659ae054/image.png" alt=""></p>
<p><br><br></p>
<p><strong>Navigation Bar는 기본적으로 링크들의 리스트이다. 따라서 ul, li tag를 이용하여 작성하는 것이 일반적이다.</strong></p>
<p>다음은 최소한의 Reset CSS를 추가한 링크들의 리스트이다. 주의할 점은 직관적인 box model을 위해 <code>box-sizing: border-box;</code> 을 사용했다는 것이다.</p>
<p>실제 웹사이트를 구축할 시에는 Reset CSS를 좀 더 정교하게 초기화할 필요가 있다.</p>
<pre><code>&lt;!-- html --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;style&gt;
    /* Simple Reset CSS */
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    body {
      font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;
      color: #58666e;
      background-color: #f0f3f4;
    }
    li {
      list-style: none;
    }
    a {
      text-decoration: none;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id=&quot;wrap&quot;&gt;
    &lt;header&gt;
      &lt;a class=&quot;logo&quot; href=&quot;#home&quot;&gt;
        &lt;img src=&quot;https://poiemaweb.com/img/logo.png&quot; height=&quot;36px&quot;&gt;
      &lt;/a&gt;
      &lt;nav&gt;
        &lt;ul class=&quot;nav-items&quot;&gt;
          &lt;li&gt;&lt;a href=&quot;#home&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#news&quot;&gt;News&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#contact&quot;&gt;Contact&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#about&quot;&gt;About&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/nav&gt;
    &lt;/header&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://images.velog.io/images/new__world/post/08614265-2c53-4e0b-acc1-78cbeafc286f/image.png" alt=""></p>
<p>🔽header 요소에 화면폭 만큼의 <code>width</code>와 고정 <code>height</code>를 지정한다.
<code>background-color</code>와 <code>box-shadow</code> 효과를 추가한다.</p>
<pre><code>/* css */
header {
  width: 100%;
  height: 60px;
  z-index: 2000;
  background-color: #fff;
  box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
}</code></pre><p><img src="https://images.velog.io/images/new__world/post/f38bd8ba-d154-442c-8a53-7a5949b5a3c3/image.png" alt=""></p>
<p>🔽이제 float 프로퍼티를 이용하여 Navigation bar를 우측정렬한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/f1a0a96d-5a67-46f7-b1d7-0962fa57ae79/image.png" alt=""></p>
<p>🔽아래의 logo image를 수직으로 중앙 정렬한다.</p>
<pre><code>&lt;!-- html --&gt;
&lt;a class=&quot;logo&quot; href=&quot;#home&quot;&gt;&lt;img src=&quot;https://poiemaweb.com/img/logo.png&quot;
height=&quot;36px&quot;&gt;&lt;/a&gt;</code></pre><p><code>logo image</code> 를 포함하는 <code>a tag(.logo)</code> 의 <code>height</code> 를 <code>logo image</code> 와 같은 <code>height</code> 인 36px로 지정하고 상하 <code>margin</code> 을 12px씩 부여하면 logo 요소의 높이는 60px이 되고 header의 height와 같아져 이미지는 <strong>수직 중앙 정렬</strong>된다.</p>
<p>a tag는 inline 요소이므로 margin을 정의하기 위해서 <code>display: inline-block;</code> 을 설정한다. 또한 img tag에 부여한 height 어트리뷰트를 css로 옮긴다.</p>
<pre><code>/* css */
.logo {
  display: inline-block;
  height: 36px;
  margin: 12px 0 12px 25px;
}
.logo &gt; img { height: 36px; }</code></pre><p><img src="https://images.velog.io/images/new__world/post/adb0777c-8337-4f2e-adc9-58a5729fb247/image.png" alt=""></p>
<p><br><br></p>
<p>🔽수직 정렬되어 있는 Navigation bar를 수평 정렬한다. block 요소인 li에 <code>display: inline-block;</code> 를 설정하여 inline 요소와 같이 가로로 정렬케 한다.</p>
<pre><code>/* css */
.nav-items &gt; li {
  display: inline-block;
}</code></pre><p><img src="https://images.velog.io/images/new__world/post/6c7dac0b-d801-4bfa-a381-86735634dcac/image.png" alt=""></p>
<p><br><br></p>
<p>🔽수평 정렬된 Navigation bar 수직 중앙 정렬한다. <code>line-height: 60px;</code> 으로 텍스트의 높이를 header의 height와 동일하게 60px로 고정시킨다. 그리고 텍스트 간 적당한 간격 유지를 위해 <code>padding</code>을 정의한다.</p>
<pre><code>/* css */
.nav-items &gt; li &gt; a {
  line-height: 60px;
  padding: 0 30px;
  color: rgba(0, 0, 0, 0.4);
}</code></pre><p><img src="https://images.velog.io/images/new__world/post/34a4af8d-636e-4417-ba9a-87f5027a9ccd/image.png" alt=""></p>
<p><br><br></p>
<p>🔽마우스가 Navigation bar 위에 올라오면 Navigation item의 텍스트 색상이 변경되도록 한다.</p>
<pre><code>.nav-items &gt; li &gt; a:hover {
  color: rgba(0, 0, 0, 0.8);
}</code></pre><p><br><br></p>
<p>🔽아래는 완성된 Navigation bar의 예제 코드이다.</p>
<pre><code>&lt;!-- html --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;

&lt;head&gt;
  &lt;style&gt;
    /* Simple Reset CSS */
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    body {
      font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;
      color: #58666e;
      background-color: #f0f3f4;
    }
    li {
      list-style: none;
    }
    a {
      text-decoration: none;
    }
    header {
      width: 100%;
      height: 60px;
      z-index: 2000;
      background-color: #fff;
      box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
    }
    nav {
      float: right;
    }
    .logo {
      display: inline-block;
      height: 36px;
      margin: 12px 0 12px 25px;
    }
    .logo &gt; img { height: 36px; }
    .nav-items &gt; li {
      display: inline-block;
    }
    .nav-items &gt; li &gt; a {
      line-height: 60px;
      padding: 0 30px;
      color: rgba(0,0,0,0.4);
    }
    .nav-items &gt; li &gt; a:hover {
      color: rgba(0,0,0,0.8);
    }
  &lt;/style&gt;
&lt;/head&gt;

&lt;body&gt;
  &lt;div id=&quot;wrap&quot;&gt;
    &lt;header&gt;
      &lt;a class=&quot;logo&quot; href=&quot;#home&quot;&gt;
        &lt;img src=&quot;https://poiemaweb.com/img/logo.png&quot;&gt;
      &lt;/a&gt;
      &lt;nav&gt;
        &lt;ul class=&quot;nav-items&quot;&gt;
          &lt;li&gt;&lt;a href=&quot;#home&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#news&quot;&gt;News&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#contact&quot;&gt;Contact&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#about&quot;&gt;About&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/nav&gt;
    &lt;/header&gt;
  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre><p><img src="https://images.velog.io/images/new__world/post/9d2e9ed6-5ae1-41da-a12e-9089ef68b085/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="2-section--aside">2. Section &amp; Aside</h3>
<p><strong>콘텐츠의 영역을 Section, 콘텐츠에 대한 Navigation item 이나 부가 정보 영역을 Aside라 한다.</strong> Section 영역은 다시 article 영역으로 구분할 수 있다.</p>
<p>이 두개의 영역은 <code>float</code> 프로퍼티를 사용하여 <strong>수평 정렬</strong>하는 것이 일반적이다.</p>
<p>header 요소 뒤에 aside, section, article을 포함하는 content-wrap 요소를 정의한다.</p>
<pre><code>&lt;!-- html --&gt;
&lt;div id=&quot;content-wrap&quot;&gt;
  &lt;aside&gt;
    &lt;h1&gt;Aside&lt;/h1&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;#&quot; class=&quot;active&quot;&gt;London&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Paris&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Tokyo&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Newyork&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/aside&gt;
  &lt;section&gt;
    &lt;article id=&quot;london&quot;&gt;
      &lt;h1&gt;London&lt;/h1&gt;
      &lt;p&gt;...&lt;/p&gt;
    &lt;/article&gt;
    &lt;article id=&quot;paris&quot;&gt;
      &lt;h1&gt;Paris&lt;/h1&gt;
      &lt;p&gt;...&lt;/p&gt;
    &lt;/article&gt;
    &lt;article id=&quot;tokyo&quot;&gt;
      &lt;h1&gt;Tokyo&lt;/h1&gt;
      &lt;p&gt;...&lt;/p&gt;
    &lt;/article&gt;
    &lt;article id=&quot;newyork&quot;&gt;
      &lt;h1&gt;Newyork&lt;/h1&gt;
      &lt;p&gt;...&lt;/p&gt;
    &lt;/article&gt;
  &lt;/section&gt;
&lt;!-- end of content-wrap   --&gt;
&lt;/div&gt;</code></pre><p><img src="https://images.velog.io/images/new__world/post/271ad67f-37f3-466e-a46c-01cb8f5544b6/image.png" alt=""></p>
<p>aside을 좌측정렬, section을 우측 정렬한다. 이때 float 프로퍼티 요소를 감싸는 <strong>wrap 요소에 clearfix을 부여하여 float 프로퍼티가 선언된 두개의 자식 요소를 포함하는 부모 요소의 높이가 정상적인 값을 가지지 못하는 문제를 해결해야 한다.</strong></p>
<pre><code>/* css */
/* clearfix */
#content-wrap:after {
  content: &quot;&quot;;
  display: block;
  clear: both;
}
aside {
  float: left;
  width: 20%;
}
section {
  float: right;
  width: 80%;
}</code></pre><p>2개의 블록 영역이 수평 정렬되었고 wrap 요소도 정상적인 높이를 가지게 되었다. 그런데 아래 그림처럼 화면을 아래로 스크롤하면 header 영역도 따라 올라가버려 navigation bar가 사라져 버리는 현상이 발생한다.</p>
<p>navigation bar가 화면에 없으면 조작이 불편할 수 있으므로 navigation bar를 화면 상단에 고정시키도록 한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/230b8b08-a4ff-465e-b551-150cb354d6f5/image.png" alt=""></p>
<p><strong>fixed 프로퍼티를 사용하여 header 요소를 상단에 고정시킨다.</strong></p>
<p><code>fixed 프로퍼티</code> 은 부모 요소와 관계없이 브라우저의 viewport를 기준으로 좌표  프로퍼티(top, bottom, left, right)을 사용하여 위치를 이동시킨다. 스크롤이 되더라도 화면에서 사라지지 않고 항상 같은 곳에 위치한다.</p>
<pre><code>/* css */
header {
  /* for sticky header */
  position: fixed;
  top: 0;
  ...
}</code></pre><p>🔽contents 영역 상단이 header 영역과 겹치므로 contents 영역을 header의 height 만큼 아래로 끌어 내린다.</p>
<pre><code>/* css */
#wrap {
  /* margin-top = header height */
  margin-top: 60p;
}</code></pre><p><img src="https://images.velog.io/images/new__world/post/15eb773c-5bf7-4ef6-b06a-8b7276d81fff/image.png" alt=""></p>
<p>이제 header 영역은 고정되었다. 그런데 화면이 스크롤될 때 좌측 aside의 navigation이 사라지는 것은 마찬가지로 불편할 수 있다. aside 영역도 고정시키도록 하자.</p>
<p><code>float: left;</code> 를 삭제하고 header와 같이 <code>position: fixed;</code> 를 추가한다.
%로 지정했던 width도 고정폭으로 변경한다. 이때 section 영역의 % width 도 삭제하여 aside 영역 만큼 우측으로 밀어서 나머지 영역을 모두 차지하도록 한다.</p>
<pre><code>/* css */
aside {
  /* for fixed side bar */
  position: fixed;
  top: 60px;
  bottom: 0;

  width: 200px;
}
section {
  float: right;
  margin-left: 200px;
}</code></pre><p><img src="https://images.velog.io/images/new__world/post/0dc553a8-3db8-40a7-bc00-b20557a696bf/image.png" alt=""></p>
<br>

<p>🔽다음은 aside navigation의 style을 정리한다. 현재 active한 item을 컬러로 구분할 수 있게 하고 마우스 hover 상태일 때도 컬러로 구분할 수 있게 한다. 또한 텍스트의 style도 정리한다.</p>
<pre><code>/* css */
aside {
  /* for fixed side bar */
  position: fixed;
  top: 60px;
  bottom: 0;

  width: 200px;
  padding-top: 25px;
  background-color: #333;
}
/* aside navigation */
aside &gt; ul {
  width: 200px;
}
aside &gt; ul &gt; li &gt; a {
  display: block;
  color: #fff;
  padding: 10px 0 10px 20px;
}
aside &gt; ul &gt; li &gt; a.active {
  background-color: #4CAF50;
}
aside &gt; ul &gt; li &gt; a:hover:not(.active) {
  background-color: #555;
}
aside &gt; h1 {
  padding: 20px 0 20px 20px;
  color: #fff;
}
/* Section */
section {
  float: right;
  /* aside width */
  margin-left: 200px;
}
article {
  margin: 10px;
  padding: 25px;
  background-color: white;
}</code></pre><p>heading tag(h1)의 크기가 위치한 영역에 따라 다름에 주의하여야 한다. 즉, header내의 h1은 section내의 h1 보다 크다. 이것을 방지하기 위해서는 다음을 Rest CSS에 추가할 필요가 있다. 크기는 적당히 조절하면 된다. 다른 텍스트 태그의 style도 정리한다.</p>
<pre><code>/* css */
h1 { font-size: 1.8em; }
h1, h2, h3, h4, h5, h6, p {
  margin: 10px 5px;
}</code></pre><p>자세한 사항은 <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_HTML_sections_and_outlines">MDN</a> 참조하기 바란다.</p>
<p><img src="https://images.velog.io/images/new__world/post/be192d50-ab5f-48d8-82da-a5ab7e2490d1/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="3-footer">3. footer</h3>
<p>content-wrap 영역 다음에 footer를 배치한다.</p>
<pre><code>&lt;!-- html --&gt;
&lt;footer&gt;© Copyright 2016 ungmo2&lt;/footer&gt;</code></pre><p>footer도 고정되어 있을 필요가 있지만 본문을 가리는 것은 곤란하다. 
따라서 fixed 프로퍼티를 설정해서는 안된다. fixed 프로퍼티는 스크롤이 되어도 언제나 그 자리를 고수하기 때문이다.</p>
<p>footer는 <code>absolute</code> 프로퍼티를 설정한다. <strong>absolute를 사용하면 다른 요소가 먼저 위치를 점유하고 있어도 뒤로 밀리지 않고 덮어쓰게 된다. (이런 특성을 부유 또는 부유 객체라 한다)</strong></p>
<p>footer의 style 정의는 다음과 같다.</p>
<pre><code>/* css */
footer {
  /* footer를 aside위에 올리기 위해 사용(부유객체) */
  position: absolute;
  height: 60px;
  width: 100%;
  padding: 0 25px;
  line-height: 60px;
  color: #8a8c8f;
  border-top: 1px solid #dee5e7;
  background-color: #f2f2f2;
}</code></pre><p><img src="https://images.velog.io/images/new__world/post/e12310a8-1a22-4cd5-bcfa-4de0a16e5449/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="전체-코드">전체 코드</h3>
<p>🔽다음은 지금까지 작성한 예제의 전체 코드이다.</p>
<pre><code>&lt;!-- html --&gt;
&lt;!DOCTYPE html&gt;
&lt;html&gt;

&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
  &lt;style&gt;
    /* Simple Reset CSS */
    * {
      margin: 0; padding: 0;
      box-sizing: border-box;
    }
    body {
      font-family: &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;
      color: #58666e;
      background-color: #f0f3f4;
      -webkit-font-smoothing: antialiased;
      -webkit-text-size-adjus: 100%;  /* iphone font size 변경 방지 */
    }
    li { list-style: none; }
    a { text-decoration: none; }
    h1, h2, h3, h4, h5, h6, p {
      margin: 10px 5px;
    }
    h1 { font-size: 1.8em; }

    #wrap {
      width: 100%;
      /* margin-top = header height */
      margin-top: 60px;
    }

    /* Navigation bar */
    header {
      /* for sticky header */
      position: fixed;
      top: 0;

      width: 100%;
      height: 60px;
      z-index: 2000;
      background-color: #fff;
      box-shadow: 0 2px 2px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(0, 0, 0, 0.05);
    }
    .logo {
      display: inline-block;
      height: 36px;
      margin: 12px 0 12px 25px;
    }
    .logo &gt; img { height: 36px; }
    nav {
      float: right;
    }
    .nav-items {
      margin-right: 20px;
    }
    .nav-items &gt; li {
      display: inline-block;  /* 가로정렬 */
    }
    .nav-items &gt; li &gt; a {
      /* for Vertical Centering */
      line-height: 60px;
      padding: 0 30px;
      color: rgba(0, 0, 0, 0.4);
    }
    .nav-items &gt; li &gt; a:hover {
      color: rgba(0, 0, 0, 0.8);
    }

    /* contents */
    /* clearfix */
    #content-wrap:after {
      content: &quot;&quot;;
      display: block;
      clear: both;
    }
    aside {
      /* for fixed side bar */
      position: fixed;
      top: 60px;
      bottom: 0;
      width: 200px;  /* 너비 고정 */
      padding-top: 25px;
      background-color: #333;
    }
    /* aside navigation */
    aside &gt; ul {
      width: 200px;
    }
    aside &gt; ul &gt; li &gt; a {
      display: block;
      color: #fff;
      padding: 10px 0 10px 20px;
    }
    aside &gt; ul &gt; li &gt; a.active {
      background-color: #4CAF50;
    }
    aside &gt; ul &gt; li &gt; a:hover:not(.active) {
      background-color: #555;
    }
    aside &gt; h1 {
      padding: 20px 0 20px 20px;
      color: #fff;
    }
    /* Section */
    section {
      float: right;
      /* aside width */
      margin-left: 200px;
    }
    article {
      margin: 10px;
      padding: 25px;
      background-color: white;
    }
    /* footer */
    footer {
      /* footer를 aside위에 올리기 위해 사용(부유객체) */
      position: absolute;
      height: 60px;
      width: 100%;
      padding: 0 25px;
      line-height: 60px;
      color: #8a8c8f;
      border-top: 1px solid #dee5e7;
      background-color: #f2f2f2;
    }
  &lt;/style&gt;
&lt;/head&gt;

&lt;body&gt;
  &lt;div id=&quot;wrap&quot;&gt;
    &lt;header&gt;
      &lt;a class=&quot;logo&quot; href=&quot;#home&quot;&gt;&lt;img src=&quot;https://poiemaweb.com/img/logo.png&quot;&gt;&lt;/a&gt;
      &lt;nav&gt;
        &lt;ul class=&quot;nav-items&quot;&gt;
          &lt;li&gt;&lt;a href=&quot;#home&quot;&gt;Home&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#news&quot;&gt;News&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#contact&quot;&gt;Contact&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#about&quot;&gt;About&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/nav&gt;
    &lt;/header&gt;

    &lt;div id=&quot;content-wrap&quot;&gt;
      &lt;aside&gt;
        &lt;h1&gt;Aside&lt;/h1&gt;
        &lt;ul&gt;
          &lt;li&gt;&lt;a href=&quot;#&quot; class=&quot;active&quot;&gt;London&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Paris&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Tokyo&lt;/a&gt;&lt;/li&gt;
          &lt;li&gt;&lt;a href=&quot;#&quot;&gt;Newyork&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/aside&gt;
      &lt;section&gt;
        &lt;article id=&quot;london&quot;&gt;
          &lt;h1&gt;London&lt;/h1&gt;
          &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
          &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
          &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
        &lt;/article&gt;
        &lt;article id=&quot;paris&quot;&gt;
          &lt;h1&gt;Paris&lt;/h1&gt;
          &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
          &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
          &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
        &lt;/article&gt;
        &lt;article id=&quot;tokyo&quot;&gt;
          &lt;h1&gt;Tokyo&lt;/h1&gt;
          &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
          &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
          &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
        &lt;/article&gt;
        &lt;article id=&quot;newyork&quot;&gt;
          &lt;h1&gt;Newyork&lt;/h1&gt;
          &lt;p&gt;London is the capital city of England. It is the most populous city in the United Kingdom, with a metropolitan area of over 13 million inhabitants.&lt;/p&gt;
          &lt;p&gt;Standing on the River Thames, London has been a major settlement for two millennia,its history going back to its founding by the Romans, who named it Londinium.&lt;/p&gt;
          &lt;p&gt;London, also referred to as Greater London, is one of 9 regions of England and the top-level subdivision covering most of the city&#39;s metropolis. The small ancient City of London at its core once comprised the whole settlement, but as its urban area grew, the Corporation of London resisted attempts to amalgamate the city with its suburbs, causing &quot;London&quot; to be defined in a number ways for different purposes.&lt;/p&gt;
        &lt;/article&gt;
      &lt;/section&gt;
      &lt;!-- end of content-wrap --&gt;
    &lt;/div&gt;
    &lt;footer&gt;© Copyright 2016 ungmo2&lt;/footer&gt;
  &lt;!-- end of wrap   --&gt;
  &lt;/div&gt;
&lt;/body&gt;

&lt;/html&gt;</code></pre><p><img src="https://images.velog.io/images/new__world/post/bd67b285-78eb-4ede-aefb-d13049686bc1/image.png" alt=""></p>
<p>사실 위의 예제에는 몇가지 문제가 숨겨져 있다.
그 문제를 해결할 열쇠는 바로 <a href="https://poiemaweb.com/css3-responsive-web-design">Responsive Web Design</a> 이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive -
텍스트 관련 태그]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EA%B4%80%EB%A0%A8-%ED%83%9C%EA%B7%B8</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%ED%85%8D%EC%8A%A4%ED%8A%B8-%EA%B4%80%EB%A0%A8-%ED%83%9C%EA%B7%B8</guid>
            <pubDate>Fri, 28 May 2021 16:47:59 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<p>최근의 웹 트랜드는 텍스트를 줄이고 이미지나 동영상 등으로 콘텐츠를 구성하는 것이지만 HTML 콘텐츠의 대부분은 텍스트로 구성된다.</p>
<p>제목이나 본문, 글자의 형태와 중요도를 나타내는 텍스트에 관련된 태그들을 알아보도록 하자.</p>
<h3 id="1-제목headings-태그">1. 제목(Headings) 태그</h3>
<p>Heading 태그는 제목을 나타낼 때 사용하며 h1에서 h6까지의 태그가 있다. h1이 가장 중요한 제목을 의미하며 글자의 크기도 가장 크다.</p>
<p><strong>시맨틱 웹</strong>의 의미를 살려서 제목 이외에는 사용하지 않는  것이 좋다. 검색엔진은 제목 태그를 중요한 의미로 받아들일 가능성이 크다.</p>
<p><img src="https://images.velog.io/images/new__world/post/4631770f-05d1-4468-99f7-b4fa2f6a4a66/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/ef67c540-4190-4a75-bfac-bf7854fe5108/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="2-글자-형태-text-formatting-태그">2. 글자 형태 (Text Formatting) 태그</h3>
<h4 id="🔽21-b">🔽2.1 b</h4>
<p><code>bold</code>체를 지정한다. 제목 태그와 같이 의미론적(Semantic) 중요성의 의미는 없다.</p>
<p><img src="https://images.velog.io/images/new__world/post/3e8a1f45-e87e-4fe0-b69a-43e982943b65/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/a1902b90-37c9-4de7-8297-3e17a3742797/image.png" alt=""></p>
<br>

<h4 id="🔽22-strong">🔽2.2 strong</h4>
<p>b tag와 동일하게 <code>bold</code>체를 지정한다. 하지만 <strong>의미론적(Semantic) 중요성의 의미</strong>를 갖는다. 표현되는 외양은 b tag와 동일하지만 <strong>웹표준을 준수하고자 한다면 strong을 사용하는 것이 바람직하다.</strong></p>
<p><img src="https://images.velog.io/images/new__world/post/130f01d6-607d-4b34-ba9d-1473364e5c21/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/c391f50b-7334-4515-9c51-e8c6077bdeed/image.png" alt=""></p>
<br>

<h4 id="🔽23-i">🔽2.3 i</h4>
<p><code>Italic</code>체를 지정한다. 의미론적(Semantic) 중요성의 의미는 없다.</p>
<p><img src="https://images.velog.io/images/new__world/post/fa582fb5-008a-4f3f-b1fc-4802e68c7268/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/4108d2c4-1657-4cd9-9d24-fcc7fa974b89/image.png" alt=""></p>
<br>

<h4 id="🔽24-em">🔽2.4 em</h4>
<p><strong>emphasized(강조, 중요한)</strong> text를 지정한다. i tag와 동일하게 <code>Italic</code>체로 표현된다. <strong>의미론적(Semantic) 중요성의 의미를 갖는다.</strong></p>
<p><img src="https://images.velog.io/images/new__world/post/d30671cc-01cd-44be-8d67-a8a8c773447a/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/8e82234a-1577-423e-9345-29baa7b0dae4/image.png" alt=""></p>
<br>

<h4 id="🔽25-small">🔽2.5 small</h4>
<p>small text를 지정한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/97390ebb-0a38-4af7-90f3-26e6c6a5f3e4/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/c5ec911b-b694-4977-8949-56cca4c2e624/image.png" alt=""></p>
<br>

<h4 id="🔽26-mark">🔽2.6 mark</h4>
<p>highlighted text를 지정한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/dd0bb3fc-22c3-4b95-8afe-969dc259dfe1/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/394f1e6b-b131-42b4-b2c8-308fd4dd20c7/image.png" alt=""></p>
<br>

<h4 id="🔽27-del">🔽2.7 del</h4>
<p>deleted(removed) text를 지정한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/249f6bcd-71cd-46d8-90b6-ebc45096e506/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/2526be00-013f-461f-a5ed-85a40bcd307c/image.png" alt=""></p>
<h4 id="🔽28-ins">🔽2.8 ins</h4>
<p>inserted(added) text를 지정한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/d44fc396-da87-4de0-8551-4daebce2e61c/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/fc4196e4-0357-4522-9f08-fceb8c6e30f0/image.png" alt=""></p>
<br>

<h4 id="🔽29-sub--sup">🔽2.9 sub / sup</h4>
<p>sub 태그는 subscripted(아래에 쓰인) text를,
sup 태그는 superscripted(위에 쓰인) text를 지정한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/86258f00-9362-433f-8d5a-fa3d08fd57f7/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/bc335cc3-7e3f-47a0-a8cd-50eb91e5ae51/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="3-본문-태그">3. 본문 태그</h3>
<h4 id="🔽31-p">🔽3.1 p</h4>
<p>단락(Paragraphs)을 지정한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/fc42c2cf-968b-464d-9150-d09cc7443b5c/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/98b6b9ab-ae00-4bdf-a0de-437a32e2b52d/image.png" alt=""></p>
<br>

<h4 id="🔽32-br">🔽3.2 br</h4>
<p>br tag는 (강제)개행 (line break)을 지정한다. br tag는 빈 요소(empty element)로 종료태그가 없다.</p>
<p><img src="https://images.velog.io/images/new__world/post/590c78cf-369d-44b3-9601-0f7f4c1ef349/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/70a0cbd5-16bb-409c-a30e-610305990e07/image.png" alt=""></p>
<p>🔽HTML에서는 1개 이상의 연속된 공백(space)을 삽입하여도 1개의 공백으로 표시된다. 1개 이상의 연속된 줄바꿈(enter)도 1개의 공백으로 표시된다.</p>
<p><img src="https://images.velog.io/images/new__world/post/f1408c9e-48bb-4c29-b5d8-ab6202d07523/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/8451fc04-df88-4b99-88d1-8497b3ad4736/image.png" alt=""></p>
<p>🔽연속적 공백을 삽입하는 방법은 아래와 같다.</p>
<p><img src="https://images.velog.io/images/new__world/post/d6901b2d-f852-4022-9065-5ea6180d9b74/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/fe9622a8-e15d-4554-bfdb-22db3c39cb26/image.png" alt=""></p>
<br>

<h4 id="🔽33-pre">🔽3.3 pre</h4>
<p>형식화된(preformatted) text를 지정한다. pre 태그 내의 content는 작성된 그대로 브라우저에 표시된다.</p>
<p><img src="https://images.velog.io/images/new__world/post/335afec7-893f-4125-8bfa-f0eb5246ff4d/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/7f42da92-2c7c-4176-a016-d1651931393b/image.png" alt=""></p>
<br>

<h4 id="🔽34-hr">🔽3.4 hr</h4>
<p>수평줄을 삽입한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/e795f89a-fe07-4164-9eb6-42ad13929342/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/08c83faf-03da-4ab4-931e-9c909af4fa72/image.png" alt=""></p>
<br>

<h4 id="🔽35-q">🔽3.5 q</h4>
<p>짧은 인용문(quotation)을 지정한다. 브라우저는 인용부호(큰따옴표/quotation marks)로 q 요소를 감싼다.</p>
<p><img src="https://images.velog.io/images/new__world/post/d5162b53-8bdb-4844-b25c-f0d3cc3c7e50/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/f6c68754-6076-4bd2-b43e-f21e47f4db21/image.png" alt=""></p>
<br>

<h4 id="🔽36-blockquote">🔽3.6 blockquote</h4>
<p>긴 인용문 블록을 지정한다. 브라우저는 blockquote 요소를 들여쓰기한다.
css를 이용하여 다양한 style을 적용할 수 있다.</p>
<p><img src="https://images.velog.io/images/new__world/post/bb5ac488-f30d-4123-ba90-c59f8fb74d8c/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/95fe19c7-e42f-4ebe-b4ce-b92671f26c9d/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/HTML/Element">HTML 요소 레퍼런스</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[모던 자바스크립트 Deep Dive -웹페이지의 구성하는 기본 태그]]></title>
            <link>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EC%9D%98-%EA%B5%AC%EC%84%B1%ED%95%98%EB%8A%94-%EA%B8%B0%EB%B3%B8-%ED%83%9C%EA%B7%B8</link>
            <guid>https://velog.io/@new__world/%EB%AA%A8%EB%8D%98-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-Deep-Dive-%EC%9B%B9%ED%8E%98%EC%9D%B4%EC%A7%80%EC%9D%98-%EA%B5%AC%EC%84%B1%ED%95%98%EB%8A%94-%EA%B8%B0%EB%B3%B8-%ED%83%9C%EA%B7%B8</guid>
            <pubDate>Fri, 28 May 2021 11:00:57 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>해당 게시물은 <code>poiemaweb</code> 사이트를 참고 및 인용 하였음을 알려드립니다.
정보 출처: <a href="https://poiemaweb.com/">https://poiemaweb.com/</a></p>
</blockquote>
<hr>
<br>

<h3 id="1-문서-형식-정의-tag">1. 문서 형식 정의 tag</h3>
<p>문서 형식 정의(Document Type Definition, DTD) 태그는 출력할 웹 페이지의 형식을 브라우저에게 전달한다. 문서의 최상위에 위치해야 하며 대소문자를 구별하지 않는다. 문서별 기술 양식은 아래와 같다.</p>
<p><img src="https://images.velog.io/images/new__world/post/6f73487d-5268-4317-aaf4-419a49c2c73e/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="2-html-tag">2. html tag</h3>
<p>html 태그는 모든 HTML 요소의 부모 요소이며 웹페이지에 단 하나만 존재한다. <strong>즉, 모든 요소는 html 요소의 자식 요소이며 html 요소 내부에 기술해야 한다.</strong> <code>&lt;!DOCTYPE&gt;는 예외이다.</code></p>
<p><img src="https://images.velog.io/images/new__world/post/755b7ac6-49fe-4f42-a2c8-8d3d964ed0ff/image.png" alt=""></p>
<p>html은 글로벌 어트리뷰트를 지원한다. 특히 lang 어트리뷰트를 사용하는 경우가 많다. 다음은 한국어를 주언어로 사용하는 경우의 예이다.</p>
<p><img src="https://images.velog.io/images/new__world/post/14bc7f59-1d88-4942-b2fc-8a0af2f72e0f/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="3-head-tag">3. head tag</h3>
<p>head 요소는 <strong>메타데이터</strong>를 포함하기 위한 요소이며 웹페이지에 단 하나만 존재한다. <strong>메타데이터는 HTML 문서의 title, style, link, script에 대한 데이터로 화면에 표시되지 않는다.</strong></p>
<blockquote>
<p>head 요소에는 메타데이터 이외의 화면에 표시되는 일체의 요소를 포함시킬 수 없다.</p>
</blockquote>
<br>

<h4 id="31-title-tag">3.1 title tag</h4>
<p>🔽title 요소는 문서의 제목을 정의한다. 정의된 제목은 브라우저의 탭에 표시된다.</p>
<p><img src="https://images.velog.io/images/new__world/post/6698291b-b85b-4452-936b-da3f71f7a0b2/image.png" alt=""></p>
<br>

<h4 id="32-style-tag">3.2 style tag</h4>
<p>🔽style 요소에는 HTML 문서를 위한 style 정보를 정의한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/0ba5e3c1-f903-4e81-bcd6-555ada892eca/image.png" alt=""></p>
<br>

<h4 id="33-link-tag">3.3 link tag</h4>
<p>🔽link 요소에는 외부 리소스와의 연계 정보를 정의한다. 주로 HTML과 CSS 파일을 연계에 사용된다.</p>
<p><img src="https://images.velog.io/images/new__world/post/5c735b47-2dad-4d44-9b3a-011953206a20/image.png" alt=""></p>
<br>

<h4 id="34-script-tag">3.4 script tag</h4>
<p>🔽script 요소에는 client-side JavaScript를 정의한다.</p>
<p><code>클라이언트 사이드란 네트워크의 한 방식인 클라이언트-서버 구조의 클라이언트 쪽에서 행해지는 처리를 말한다. -위키백과</code></p>
<p><img src="https://images.velog.io/images/new__world/post/5589c6d3-3b0a-42ca-9cb9-9dec34971151/image.png" alt=""></p>
<p>🔽src 어트리뷰트를 사용하면 외부 JavaScript 파일을 로드할 수 있다.</p>
<p><img src="https://images.velog.io/images/new__world/post/b40cf42b-1bfe-470e-8d0a-841f1c34f58e/image.png" alt=""></p>
<br>

<h4 id="35-meta-tag">3.5 meta tag</h4>
<p>meta 요소는 description, keywords, author, 기타 메타데이터 정의에 사용된다. 메타데이터는 브라우저, 검색엔진(keywords) 등에 의해 사용된다.
charset 어트리뷰트는 브라우저가 사용할 문자셋을 정의한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/5f44a981-4534-42a9-aa18-67ffbf13aad8/image.png" alt=""></p>
<p><img src="https://images.velog.io/images/new__world/post/123689fd-0082-4856-8815-cd2716a56298/image.png" alt=""></p>
<p>🔽SEO(검색엔진 최적화)를 위해 검색엔진이 사용할 keywords를 정의한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/08bf72fb-572d-4c85-a3bf-3bc17d3b46c2/image.png" alt=""></p>
<p>🔽웹 페이지의 설명을 정의한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/609bfecf-9e56-464d-b28e-479382e01540/image.png" alt=""></p>
<p>🔽웹 페이지를 30초 마다 Refresh 한다.</p>
<p><img src="https://images.velog.io/images/new__world/post/2ef94915-cb6e-45e2-934c-74997465fc41/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="4-body-tag">4. body tag</h3>
<p>body tag는 HTML 문서의 내용을 나타내며 웹페이지에 단 하나만 존재한다.</p>
<p><strong>메타데이터를 제외한 웹페이지를 구성하는 대부분의 요소가 body 요소 내에 기술된다.</strong></p>
<p><img src="https://images.velog.io/images/new__world/post/33e0587f-b2da-445c-846b-5da444c7eafb/image.png" alt=""></p>
<p><br><br></p>
<hr>
<h3 id="💬">💬</h3>
<h3 id="reference">Reference</h3>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/HTML/Element">HTML 요소 레퍼런스</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>