<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Front</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Wed, 06 Sep 2023 04:10:36 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. Front. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/front-study" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[MIL - 데브코스 08월 회고
]]></title>
            <link>https://velog.io/@front-study/MIL-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-08%EC%9B%94-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@front-study/MIL-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-08%EC%9B%94-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Wed, 06 Sep 2023 04:10:36 GMT</pubDate>
            <description><![CDATA[<h2 id="🚩-8월-목표">🚩 8월 목표</h2>
<ul>
<li><del>강의 / 과제</del> </li>
<li><del>알고리즘 문제 풀기</del></li>
<li>WIL 4개 작성 해보기</li>
<li><del>코어 자바스크립트 스터디 참여</del></li>
<li><del>사이드 프로젝트 v2배포</del></li>
<li><del>타입 스크립트 스터디 개설</del></li>
</ul>
<h2 id="🚩-진행한-것">🚩 진행한 것</h2>
<h3 id="강의듣기">강의듣기</h3>
<ul>
<li>React</li>
</ul>
<h3 id="과제">과제</h3>
<ul>
<li>React 네비게이션 만들기</li>
</ul>
<h3 id="스터디-참여하기">스터디 참여하기</h3>
<ul>
<li>코어자바스크립트 스터디 (1회독을 완료하고 2회독을 하기로 했다)</li>
<li>타입스크립트 스터디 개설 (주 1회 참여)</li>
</ul>
<h3 id="사이드-프로젝트-v2-배포">사이드 프로젝트 v2 배포</h3>
<ul>
<li>스터디원들과 함께 v2를 무사히 배포했다</li>
</ul>
<h2 id="🚩-못한-것">🚩 못한 것</h2>
<h3 id="1-wil-작성하기">1. WIL 작성하기</h3>
<p>작성해야 하는데... 정리하는데 시간이 오래 걸리니까 작성을 계속 미루게 된다.
이제는 시간이 있을때 조금씩 해봐야 겠다.</p>
<h2 id="🚩-9월-목표">🚩 9월 목표</h2>
<ul>
<li>팀 프로젝트 </li>
<li>타입스크립트 스터디</li>
<li>코어 자바스크립트 스터디(2회독)</li>
<li>이력서 스터디</li>
<li>사이드 프로젝트 v3 개발</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git dev 브랜치 PR시 Issue 자동 close하기]]></title>
            <link>https://velog.io/@front-study/Git-dev-%EB%B8%8C%EB%9E%9C%EC%B9%98-PR%EC%9D%B4-Issue-%EC%9E%90%EB%8F%99-close%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@front-study/Git-dev-%EB%B8%8C%EB%9E%9C%EC%B9%98-PR%EC%9D%B4-Issue-%EC%9E%90%EB%8F%99-close%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 06 Sep 2023 04:01:44 GMT</pubDate>
            <description><![CDATA[<h2 id="개요">개요</h2>
<p>git hub에서 생성한 Issue가 PR시 종료되게 하려면<code>close ${이슈번호}</code> 를 붙이면 자동으로 Close되지만 이것은 default(main) 브랜치에서만 적용이 가능했다. 이런 문제를 해결하고 싶어 방법을 찾다가 git action을 사용해서 자동화 하는 방법이 있어 소개해보려고 한다.</p>
<h2 id="git-action-스크립트">git action 스크립트</h2>
<pre><code class="language-bash">name: Close associated issue

on:
  pull_request:
    branches:
      - dev
    types:
      - closed

jobs:
  close-issue:
    runs-on: ubuntu-latest
    steps:
    - name: Close associated issue
      run: |
        PR_NUMBER=${{ github.event.pull_request.number }}
        PR_URL=&quot;https://api.github.com/repos/${{ github.repository }}/pulls/$PR_NUMBER&quot;
        PR_BODY=$(curl -s -H &quot;Authorization: token ${{ secrets.ACTION_TOKEN }}&quot; $PR_URL | jq -r &#39;.body&#39;)
        ISSUE_NUMBER=$(echo $PR_BODY | grep -oE &quot;close #[0-9]+&quot; | tr -d &#39;close #&#39;)
        if [[ ! -z &quot;$ISSUE_NUMBER&quot; ]]; then
          curl -s -H &quot;Authorization: token ${{ secrets.ACTION_TOKEN }}&quot; -X PATCH &quot;https://api.github.com/repos/${{ github.repository }}/issues/$ISSUE_NUMBER&quot; -d &#39;{&quot;state&quot;: &quot;closed&quot;}&#39;
        fi
      shell: bash</code></pre>
<h4 id="pr_number">PR_NUMBER</h4>
<p>Git hub api를 사용해 PR 이슈 번호를 가져온다.</p>
<h4 id="pr_url">PR_URL</h4>
<p>PR 내용을 가져온다</p>
<h4 id="pr_body">PR_BODY</h4>
<p>PR 내용에서 Body값을 가져온다</p>
<h4 id="issue_number">ISSUE_NUMBER</h4>
<p>정규 표현식을 사용해 body에서 close #${이슈번호}를 가져온다</p>
<p>이슈 번호가 있는 경우 이슈의 상태를 close한다.</p>
<h4 id="secretsaction_token-">${{secrets.ACTION_TOKEN }}</h4>
<p>Git secrets token이 필요하다.</p>
<h2 id="코드">코드</h2>
<p><a href="https://github.com/marketplace/actions/automation-issue-closed">깃 주소</a></p>
<h2 id="사용해-보기">사용해 보기</h2>
<p>워크 플로우 생성시 Marketplace에서 Automation Issue Closed 검색
<img src="https://velog.velcdn.com/images/front-study/post/3d024fe7-1f41-4f27-b36b-b5ee066397a8/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MIL - 데브코스 07월 회고]]></title>
            <link>https://velog.io/@front-study/MIL-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-07%EC%9B%94-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@front-study/MIL-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-07%EC%9B%94-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Wed, 02 Aug 2023 09:58:34 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/front-study/post/fc255a61-f831-4b0b-9b41-92eb198528e4/image.png" alt=""></p>
<h2 id="🚩-7월-목표">🚩 7월 목표</h2>
<ul>
<li><del>강의/과제</del></li>
<li>알고리즘 문제 풀기</li>
<li><del>테스트 주도 개발 읽기</del></li>
<li>TIL 15개 작성 해보기</li>
<li><del>스터디 참여하기</del></li>
<li><del>사이드 프로젝트 참여</del></li>
</ul>
<h2 id="🚩-진행한-것">🚩 진행한 것</h2>
<h3 id="강의듣기">강의듣기</h3>
<ul>
<li>JavaScript 심화</li>
<li>CSS</li>
<li>Vue</li>
</ul>
<h3 id="과제">과제</h3>
<ul>
<li>Notion 클론 코딩</li>
<li>고양이 사진첩 만들기</li>
<li>CSS 클론 페이지</li>
</ul>
<h3 id="테스트-주도-개발tdd-읽기">테스트 주도 개발(TDD) 읽기</h3>
<p>7장 까지 읽었다. 블로그에 정리해야하는데 언제 정리하지?...</p>
<h3 id="스터디-참여하기">스터디 참여하기</h3>
<ul>
<li>코어자바스크립트 스터디 (4장 콜백 까지 완료)</li>
</ul>
<h3 id="사이드-프로젝트-참여">사이드 프로젝트 참여</h3>
<ul>
<li>리엑트를 사용해서 개발진행 중(8/4일 배포예정)</li>
</ul>
<h2 id="🚩-못한-것">🚩 못한 것</h2>
<h3 id="1-til-작성하기">1. TIL 작성하기</h3>
<p>작성해야 하는데... 정리하는데 시간이 오래 걸리니까 작성을 계속 미루게 된다.
아무래도 TIL은 어려울 거 같고 WIL을 작성해 봐야겠다.</p>
<h3 id="2-알고리즘-문제-풀기">2. 알고리즘 문제 풀기</h3>
<p>알고리즘... 해야지 
8월은 아침마다 하루 1문제씩 풀어봐야겠다.</p>
<h2 id="🚩-8월-목표">🚩 8월 목표</h2>
<ul>
<li>강의 / 과제 </li>
<li>알고리즘 문제 풀기</li>
<li>테스트 주도 개발 완독하기</li>
<li>WIL 4개 작성 해보기</li>
<li>코어 자바스크립트 스터디 참여</li>
<li>사이드 프로젝트 배포</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[CallBack함수가 뭐에요?]]></title>
            <link>https://velog.io/@front-study/CallBack%ED%95%A8%EC%88%98%EA%B0%80-%EB%AD%90%EC%97%90%EC%9A%94</link>
            <guid>https://velog.io/@front-study/CallBack%ED%95%A8%EC%88%98%EA%B0%80-%EB%AD%90%EC%97%90%EC%9A%94</guid>
            <pubDate>Thu, 27 Jul 2023 02:21:22 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/front-study/post/b376e685-e621-419b-b6c6-196d6b0f39bb/image.png" alt=""></p>
<h2 id="callback-함수란">CallBack 함수란?</h2>
<blockquote>
<p>함수를 호출할때 함수 인자로 다른 함수를 넘겨주어 내부에서 콜백함수를 실행시키는 방식 입니다.</p>
</blockquote>
<p>ex) 예제 코드</p>
<pre><code class="language-javascript">var newArr = [10,20,30].map(function (currentValue,index){
  console.log(currentValue,index);
  return currentValue + 5;
});</code></pre>
<h3 id="제어권">제어권</h3>
<pre><code class="language-javascript">var count = 0;
var clear = function () {
  if(++count &gt; 4) clearInterval(timer);
}
var timer = setInterval(clear, 300)</code></pre>
<p>setInterval함수를 호출할때 clear는 setInterval 내부에서 cbFunc는 함수는 0.3초마다 반복해서 수행이 된다.</p>
<blockquote>
<p>이를 통해 clear함수의 제어권과 호출은 setInterval에 있음을 알 수 있다.</p>
</blockquote>
<h3 id="인자">인자</h3>
<p>예제2)map</p>
<pre><code class="language-javascript">var newArr = [10,20,30].map(function (currentValue,index){
  console.log(currentValue,index);
  return currentValue + 5;
});</code></pre>
<p><img src="https://velog.velcdn.com/images/front-study/post/0eae8f85-1f61-4d85-a6ae-97cc29b58499/image.png" alt=""></p>
<p>위의 코드에서 map 함수의 콜백함수를 호출하기 위해서는 map메서드에서 정의된 인자와 순서가 있다.</p>
<blockquote>
<p>제어권을 넘겨받은 코드(map)는 콜백 함수를 호출할 때 인자에 어떤 값들을 어떤 순서로 넘길 것인지에 대한 제어권을 가진다.</p>
</blockquote>
<h3 id="this">this</h3>
<pre><code class="language-javascript">setTimeout(function() {console.log(this);}, 300) //window

[1,2,3,4,5].forEach(function(x) {
  console.log(this)                                //window
})

document.body.innerHtml += `&lt;button id=&quot;a&quot;&gt;클릭&lt;/button&gt;`;
document.body.querySelector(&#39;#a&#39;).addEventListener(&#39;click&#39;, function(e) {
  console.log(this, e);    //button
});</code></pre>
<p>콜백함수도 함수이기 때문에 this는 기본적으로 전역객체를 참조하지만 제어권을 넘겨받을 코드에서 콜백 함수에 별도로 this가 될 대상을 지정한 경우에는 그 대상을 참조한다.</p>
<h2 id="콜백-함수는-함수다">콜백 함수는 함수다</h2>
<pre><code class="language-javascript">//1
var obj = {
  vals: [1, 2, 3],
  logValues: function (v, i) {
    console.log(this, v, i)
  }
}
obj.logValues(1, 2) // {vals: [1, 2, 3], logValues: f} 1 2
//2
[4, 5, 6].forEach(obj.logValues) // Window  {...} 4 0</code></pre>
<blockquote>
<p>콜백 함수도 함수이기 때문에 어떤 객체의 메서드를 전달하더라도 그 메서드는 메서드가 아닌 ‘함수’로서 호출된다.</p>
</blockquote>
<p>1) obj 객체의 logValues는 메서드로 정의된다. 따라서 this는 object를 가르킨다.
2) obj 객체의 logValues는 메서드는 forEach에 의해 콜백이 함수로서 호출이 된다. 이때 별도로 this를 지정하지 않았으므로 함수 내부에서의 this는 전역객체를 바라본다.</p>
<h2 id="콜백-함수-내부의-this에-다른-값-바인딩-하기">콜백 함수 내부의 this에 다른 값 바인딩 하기</h2>
<p>객체의 메서드를 콜백 함수로 전달한 경우 메서드는 해당 객체를 this로 바라볼 수 없게 된다.
객체의 메서드가 객체를 바라보게하고 싶다면 다음과 같은 방법을 사용한다.</p>
<ol>
<li><p>클로저 사용</p>
<pre><code class="language-javascript">var obj1 = {
name: &#39;obj1&#39;,
func: function() {
 var    self = this;
 return function() {
   console.log(self.name)
 };
}
} 
var callback = obj1.func();
setTimeout(callback,1000)</code></pre>
<p>func메서드 내부에서 self에 this를 담고 클로저를 사용해서 this를 구현한 예제입니다.(현재는 비추천하는 방식)</p>
</li>
<li><p>객체자체를 호출</p>
<pre><code class="language-javascript">var obj1 = {
name: &#39;obj1&#39;,
func: function() {
 console.log(obj1.name)
}
}
setTimeout(obj1.func, 1000)</code></pre>
<p>func 메서드에서 객체를 직접 명시해서 호출하는 방식이다. 간결하고 직관적 이지만 재사용성이 떨어지게 된다.</p>
</li>
<li><p>객체복사 및 call메서드 사용</p>
<pre><code class="language-javascript">var obj1 = {
name: &#39;obj1&#39;,
func: function() {
 var    self = this;
 return function() {
   console.log(self.name)
 };
}
} 
var obj2 = {
name: &#39;obj2&#39;,
func: obj1.func
}
var callback2 = obj2.func();
setTimeout(callback2,1000);
</code></pre>
</li>
</ol>
<p>var obj3 = {name: &#39;obj3&#39;};
var callback3 = obj1.func.call(obj3);
setTimeout(callback3,1000);</p>
<pre><code>해당 방법은 obj1의 func함수를 재사용 할때 해당 함수가 재사용할 객체를 바라보게 하는 방법이다. obj2의 경우는 obj1에서 self를 통해 this를 설정해 obj1의 name이 출력된다.

이를 해결하기 위해 **call**를 사용해 this를 obj3을 가르키도록 우회하였다. 

4. bind 함수 사용
```javascript
var obj1 = {
  name: &#39;obj1&#39;,
  func: function() {
    console.log(this.name);
  }
}
setTimeout(obj1.func.bind(obj1),1000);

var obj2 = { name: &#39;obj2&#39; }
setTimeout(obj1.func.bind(obj2),1000);</code></pre><p>바인드 함수를 사용해 this를 지정해주는 방법이다. 위의 클로저보다 훨씬 코드의 가독성이 올라갔다.</p>
<h2 id="콜백지옥">콜백지옥</h2>
<p>콜백 함수를 익명 함수로 전달하는 과정이 반복되어 코드의 들여쓰기 수준이 감당하기 힘들 정도로 깊어지는 현상으로, 자바스크립트에서 흔히 발생하는 문제이다.</p>
<p>주로 이벤트 처리나 서버 통신과 같이 비동기적인 작업을 수쟁하기 위해 이런 형태가 자주 등장한다.</p>
<p>콜백지옥의 예시</p>
<pre><code class="language-javascript">setTimeout(
  function (name) {
    var coffeeList = name
    console.log(coffeeList)

    setTimeout(
      function (name) {
        coffeeList += &#39;, &#39; + name
        console.log(coffeeList)

        setTimeout(
          function (name) {
            coffeeList += &#39;, &#39; + name
            console.log(coffeeList)
            setTimeout(
              function (name) {
                coffeeList += &#39;, &#39; + name
                console.log(coffeeList)
              },
              500,
              &#39;에스프레소&#39;,
            )
          },
          500,
          &#39;카페라떼&#39;,
        )
      },
      500,
      &#39;카페모카&#39;,
    )
  },
  500,
  &#39;아메리카노&#39;,
)</code></pre>
<h4 id="해결방법">해결방법</h4>
<ol>
<li>기명함수로 전환<pre><code class="language-javascript">var coffeeList = &quot;&quot;;
</code></pre>
</li>
</ol>
<p>var addEspresso = function (name) {
  coffeeList = name;
  console.log(coffeeList);
  setTimeout(addAmericano, 500, &quot;아메리카노&quot;);
};</p>
<p>var addAmericano = function (name) {
  coffeeList += &quot;, &quot; + name;
  console.log(coffeeList);
  setTimeout(addMocha, 500, &quot;카페모카&quot;);
};</p>
<p>var addMocha = function (name) {
  coffeeList += &quot;, &quot; + name;
  console.log(coffeeList);
  setTimeout(addLatte, 500, &quot;카페라떼&quot;);
};</p>
<p>var addLatte = function (name) {
  coffeeList += &quot;, &quot; + name;
  console.log(coffeeList);
};</p>
<p>setTimeout(addEspresso, 500, &quot;에스프레소&quot;);</p>
<pre><code>이 방식의 코드는 함수 선언과 함수 호출만 구분할 수 있다면 위에서부터 아래로 순서대로 읽어내려갈 수 있어 가독성이 높다. 또한 변수를 최상단으로 끌어올림으로써 외부에 노출되는 문제가 있지만 즉시 실행 함수 등으로 감싸면 간단히 해결된다.

하지만 코드명을 일일이 따라다녀야 하고 일회성 함수를 전부 변수에 할당하는 것은 효율적이지는 않은 코드다.

2. 비동기 작업의 동기적 표현 - Promise
```javascript
var addCoffee = function (name) {
    return function (prevName) {
        return new Promise(function (resolve) {
            setTimeout(function () {
                var newName = prevName ? (prevName + &#39;, &#39; + name) : name;
                console.log(newName);
                resolve(newName);
            }, 500)
        })
    }
}
addCoffee(&#39;에스프레소&#39;)()
    .then(addCoffee(&#39;아메라카노&#39;))
    .then(addCoffee(&#39;카페모카&#39;))
    .then(addCoffee(&#39;카페라떼&#39;));</code></pre><p>ES6의 Promise를 이용한 방식으로 new 연산자와 함께 호출한 Promise는 호출할 때 바로 실행되지만 resolve 또는 reject 함수를 호출하는 구문이 있을 경우 둘 중 하나가 실행 되지 전까지는 다음(then) 또는 오류 구문(catch)로 넘어가지 않는다. 따라서 비동기 작업이 완료되어야만 resolve 또는 reject를 호출하는 방법으로 비동기 작업의 동기적 표현이 가능하다.</p>
<ol start="3">
<li>Generator<pre><code class="language-javascript">var addCoffee = function (prevName, name) {
setTimeout(function () {
 coffeeMaker.next(prevName ? prevName + &#39;, &#39; + name : name)
}, 500)
}
</code></pre>
</li>
</ol>
<p>var coffeeGenerator = function* () {
  var espresso = yield addCoffee(&#39;&#39;, &#39;에스프레소&#39;)
  console.log(espresso)
  var americano = yield addCoffee(espresso, &#39;아메리카노&#39;)
  console.log(americano)
  var mocha = yield addCoffee(americano, &#39;카페모카&#39;)
  console.log(mocha)
  var latte = yield addCoffee(mocha, &#39;카페라떼&#39;)
  console.log(latte)
}</p>
<p>var coffeeMaker = coffeeGenerator()
coffeeMaker.next()</p>
<pre><code>Es6의 Generator를 사용한 방법으로 *이 붙은 함수가 Generator 함수이다. 
Generator를 실행하면 Iterator가 반환되고 Iterator는 next라는 메서드를 가지고 있다.

next 메서드를 실행하면 yield에서 실행을 멈추고 다시 next를 호출하면 그 다음 yield를 만나기 전까지 코드가 수행된다. 


4. Promise + Async/await
```javascript
var addCoffee = function (name) {
  return new Promise(function (resolve) {
    setTimeout(function () {
      resolve(name)
    }, 500)
  })
}
var coffeeMaker = async function () {
  var coffeeList = &#39;&#39;
  var _addCoffee = async function (name) {
    coffeeList += (coffeeList ? &#39;,&#39; : &#39;&#39;) + (await addCoffee(name))
  }

  await _addCoffee(&#39;에스프레소&#39;)
  console.log(coffeeList)
  await _addCoffee(&#39;아메리카노&#39;)
  console.log(coffeeList)
  await _addCoffee(&#39;카페모카&#39;)
  console.log(coffeeList)
  await _addCoffee(&#39;카페라떼&#39;)
  console.log(coffeeList)
}

coffeeMaker()
</code></pre><p>ES2017에서 가독성도 뛰어나고, 작성법도 간단한 async/await 기능이 추가되었다. 
비동기 작업을 수행하고자 하는 함수 앞에 async를 표기하고 비동기 작업이 필요한 위치마다 await를 표기하면 뒤의 내용을 Promise로 자동 전환하고, 해당 내용이 resolve 된 이후에야 다음으로 진행하게 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MIL - 데브코스 06월 회고]]></title>
            <link>https://velog.io/@front-study/MIL-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-06%EC%9B%94-%ED%9A%8C%EA%B3%A0</link>
            <guid>https://velog.io/@front-study/MIL-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4-06%EC%9B%94-%ED%9A%8C%EA%B3%A0</guid>
            <pubDate>Wed, 05 Jul 2023 13:52:47 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/front-study/post/5bc426bd-d0f3-4704-acea-d47bef17c60d/image.png" alt=""></p>
<h2 id="🚩-6월-목표">🚩 6월 목표</h2>
<ol>
<li>강의듣기</li>
<li>과제</li>
<li>스터디 참여</li>
<li>TIL 작성하기</li>
<li>알고리즘 문제 풀기</li>
<li>테스트 주도 개발 읽기(TDD)</li>
</ol>
<h2 id="🚩-진행한-것">🚩 진행한 것</h2>
<h3 id="강의듣기">강의듣기</h3>
<ul>
<li>자료구조</li>
<li>CS</li>
<li>JavaScript 기초 문법<h3 id="과제">과제</h3>
</li>
<li>TodoList 구현하기</li>
<li>트라이를 사용한 자동완성 기능 구현하기</li>
<li>노션 클론 코딩(ing~)</li>
</ul>
<h3 id="테스트-주도-개발tdd-읽기">테스트 주도 개발(TDD) 읽기</h3>
<ul>
<li>블로그 정리하기</li>
</ul>
<h3 id="스터디-참여">스터디 참여</h3>
<ul>
<li>React 스터디</li>
<li>코어자바스크립트 스터디</li>
</ul>
<h2 id="🚩-못한-것">🚩 못한 것</h2>
<h3 id="1-til-작성하기">1. TIL 작성하기</h3>
<p>TIL 한 번에 너무 많은 내용을 닮으려고 하다 보니 글을 쓰다가 내가 지치게 돼서 작성을 못한 거 같다. 7월에는 한 개의 주제를 가지고 정리를 해보고 매일은 아니더라도 조금씩 작성해 봐야겠다.</p>
<h3 id="2-알고리즘-문제-풀기">2. 알고리즘 문제 풀기</h3>
<p>어느새 부터 문제가 안 풀리다 보니 문제 풀기에 흥미를 잃은거 같다.이 부분을 해결하기 위해 아침 시간을 활용해서 한 문제씩 풀어봐야 겠다.</p>
<h2 id="🚩-7월-목표">🚩 7월 목표</h2>
<ul>
<li>강의 / 과제 </li>
<li>알고리즘 문제 풀기</li>
<li>테스트 주도 개발 읽기</li>
<li>TIL 15개 작성 해보기</li>
<li>스터디 참여하기</li>
<li>사이드 프로젝트 참여</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[테스트 주도 개발 1장 - 임시]]></title>
            <link>https://velog.io/@front-study/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%A3%BC%EB%8F%84-%EA%B0%9C%EB%B0%9C-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@front-study/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%A3%BC%EB%8F%84-%EA%B0%9C%EB%B0%9C-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 25 Jun 2023 14:10:21 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/front-study/post/1b9f9b4f-5bf6-44d9-b108-f337f20eab01/image.png" alt=""></p>
<pre><code class="language-jsx">const Dollar = require(&#39;./Dollar.js&#39;)

test(&#39;testMultiplication&#39;, () =&gt; {
    let five = new Dollar(5);
    five.times(2);
    expect(five.amount).toBe(10);
});</code></pre>
<p><img src="https://velog.velcdn.com/images/front-study/post/a4c5bdc6-8eab-48d6-9523-ea4336a077f2/image.png" alt=""></p>
<p>위 테스트 코드는 실행조차 되지 않는다.</p>
<ol>
<li>Dollar 생성자 함수가 없음</li>
<li>생성자가 없음</li>
<li>times 메서드가 없음</li>
<li>amount 필드가 없음</li>
</ol>
<p>Dollar 생성자 함수 생성 </p>
<pre><code class="language-jsx">function Dollar(amount) {
    this.amount = amount;

    this.times = (multiplier) =&gt; {
        this.amount *= multiplier
    }
}</code></pre>
<p>테스트 코드 수행
<img src="https://velog.velcdn.com/images/front-study/post/cc2fc35d-12d6-4cb0-97b4-7fae8f34fb62/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 프론트엔드 데브코스] TIL - Day 01]]></title>
            <link>https://velog.io/@front-study/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4FE-TIL-Day-01</link>
            <guid>https://velog.io/@front-study/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8D%B0%EB%B8%8C%EC%BD%94%EC%8A%A4FE-TIL-Day-01</guid>
            <pubDate>Fri, 02 Jun 2023 07:55:23 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/front-study/post/424a1011-6b13-49af-9ab1-2a8c94912e74/image.png" alt=""></p>
<h2 id="🚩-들어가기전">🚩 들어가기전</h2>
<p>OT 이후 진짜 데브 코스 시작이다. JavaScript 주요 문법을 공부하였다.
공부를 하면서 내가 어디까지 알고 있고 어떤 부분에서 헷갈려 하는지 다시 한번 짚게 되어 좋았다.</p>
<h2 id="🚩-오늘-공부한-것">🚩 오늘 공부한 것</h2>
<p><del>1. 변수, 호이스팅, 상수, 자료형, 메모리,
2. 표현식과 연산자
3. 흐름 제어
4. 배열과 객체
5. 스코프와 클로저</del></p>
<h2 id="🚩-변수-상수-자료형-메모리">🚩 변수, 상수, 자료형 메모리</h2>
<h3 id="🏁-변수">🏁 변수</h3>
<h4 id="변수란">변수란</h4>
<blockquote>
<p>수학에서 변수는 변하는 값을 의미하지만 컴퓨터 공학에서 변수는 개발자가 직접 메모리에 값을 할당하는 것을 의미한다. </p>
</blockquote>
<h4 id="변수-선언방법">변수 선언방법</h4>
<p>자바스크립트에서 변수를 선언하는 방법은 var, let이 존재한다.
<strong>var</strong>는 ES6이전에 나온 선언 방법으로 호이스팅으로 인해 권장하지 않으며 window 객체의 프로퍼티 이다.
<strong>let</strong>은 ES6이후에 나온 선언 방법으로 변수를 선언 시 권장하는 키워드이다.</p>
<pre><code class="language-javascript">let data1 = 1;
var data2 = 2;</code></pre>
<h3 id="🏁-상수">🏁 상수</h3>
<h4 id="상수란">상수란</h4>
<blockquote>
<p>상수는 변하지 않는 값을 의미한다. 즉 한번 할당을 했을 경우 재할당이 금지된다.</p>
</blockquote>
<h4 id="상수-선언방법">상수 선언방법</h4>
<blockquote>
<p>const 키워드를 사용한다. ES6이후에 추가되었다.</p>
</blockquote>
<pre><code class="language-javascript">const data = 1;</code></pre>
<h4 id="const와-재할당">const와 재할당</h4>
<p>const 키워드로 선언한 상수에 재할당을 했을 경우 다음과 같은 에러가 발생하게 된다.
<img src="https://velog.velcdn.com/images/front-study/post/4741a837-c6f6-44ba-a605-28b1a7f96cf6/image.png" alt=""></p>
<h3 id="🏁-자료형">🏁 자료형</h3>
<p>자바스크립트는 원시 타입과 참조 타입으로 나누어진다.</p>
<ul>
<li>원시타입</li>
</ul>
<table>
<thead>
<tr>
<th align="left">타입</th>
<th>특징</th>
<th>값</th>
</tr>
</thead>
<tbody><tr>
<td align="left">Number</td>
<td>숫자와 관련된 타입을 의미함</td>
<td>정수,실수,nan(연산불가능),Infinity(무한대)</td>
</tr>
<tr>
<td align="left">String</td>
<td>문자와 관련된 타입을 의미함</td>
<td>작은따옴표(&#39;&#39;), 큰따옴표(&quot;&quot;), 백틱(``)</td>
</tr>
<tr>
<td align="left">Boolean</td>
<td>논리적 참, 거짓을 나타냄</td>
<td>true,false</td>
</tr>
<tr>
<td align="left">undefined</td>
<td>자바스크립트 엔진이 변수를 초기화할 때 사용하는 값</td>
<td>undefined 유일 값</td>
</tr>
<tr>
<td align="left">null</td>
<td>변수에 값이 없다는 것을 의도적으로 명시할때 사용하는 값</td>
<td>null 유일 값</td>
</tr>
<tr>
<td align="left">Symbol</td>
<td>다른 값과 중복되지 않는 유일무일한 값이다.</td>
<td>Symbol 키워드로 생성</td>
</tr>
</tbody></table>
<ul>
<li>객체 타입<ul>
<li>Object : Key, value로 여러 값을 가지는 타입<pre><code class="language-javascript">const person = {name: &#39;홍길동&#39;}</code></pre>
</li>
<li>Array : 인덱스를 통해 값에 접근할 수 있음<pre><code class="language-javascript">let arr = [1,2,3,4,5]</code></pre>
</li>
<li>function<pre><code class="language-javascript">let func = function (){};</code></pre>
</li>
</ul>
</li>
</ul>
<h3 id="🏁-메모리">🏁 메모리</h3>
<h4 id="가비지-컬렉터">가비지 컬렉터</h4>
<p>일반적으로 메모리는 <code>할당 -&gt; 사용 -&gt; 해제</code>의 순서를 이룬다. 변수를 생성 했을때 변수는 메모리에 할당이 되고 값을 넣어 사용한다. 메모리의 공간은 한정되어 있기 때문에 사용이 완료되었을 때는 할당된 공간을 해제해야 한다.</p>
<p>우리가 사용하는 자바스크립트는 가비지컬렉터가 있어 개발자가 직접 메모리에 접근하지 않아도 가비지컬렉터가 더이상 사용되지 않는 값을 메모리에서 해제시킨다. </p>
<h4 id="원시값의-메모리-참조">원시값의 메모리 참조</h4>
<pre><code class="language-javascript">
  let a = 1;
  let b = a;</code></pre>
 <img src="https://velog.velcdn.com/images/front-study/post/cca66cbf-9662-431d-94b7-9f8ecf769614/image.png" align="left">
 지금까지 나는 원시 값은 같은 값일 경우 서로 다른 메모리 공간에 저장되는 것으로 알고 있었다. 

<p> 즉 위 코드를 실행했을 때 메모리 영역은 그림처럼 30이라는 값이 복사되어 서로 다른 메모리에 할당되는 줄 알고있었다. 그런데 질문을 통해 값은 하나의 주소에서 참조되고 있음 알게되었다.(답변해주신 멘토님 정말 감사합니다!!)</p>
<p> <img src="https://velog.velcdn.com/images/front-study/post/4fdfeab5-7ac3-468d-b784-cee279724a37/image.png" alt=""></p>
<p> 위 사진에서 변수 a, b는 다른 주소이고 참조하고 있는 값 1은 @173 주소를 참조하는 것을 알 수 있었다.</p>
<h4 id="callstackheap">CallStack/Heap</h4>
<p>자바스크립트엔진은 CallStack영역과 Heap영역으로 이뤄져 있으며 원시타입과, 참조타입을 나누어 할당한다.</p>
<blockquote>
<p>CallStack: 원시타입
Heap : 참조타입</p>
</blockquote>
<pre><code class="language-javascript">const a = 1;
const b = 10;
const c = [];
c.push(1);
c.push(2);</code></pre>
<p>위 코드를 실행 했을때 순차적으로 CallStack에 쌓이며 배열의 경우 Heap 영역의 배열주소를 참조한다.</p>
<p><img src="https://velog.velcdn.com/images/front-study/post/98228886-7932-4422-9b2c-5b336e894aa0/image.png" alt=""></p>
<h3 id="🏁-호이스팅">🏁 호이스팅</h3>
<h4 id="호이스팅이란">호이스팅이란?</h4>
<p><strong>호이스팅</strong>이란 var키워드, 함수선언문을 사용했을때 자바스크립트 엔진에 의해 선두로 끌어올려 초기화 되는 것을 의미한다. </p>
<ul>
<li><p>var 키워드 사용</p>
<pre><code class="language-javascript">  console.log(score);
  var score;</code></pre>
<img src="https://velog.velcdn.com/images/front-study/post/85757504-331e-4c29-9534-78d5d388f6d2/image.png" align="left">
위 코드 예제에서 score를 선언하기 전에 먼저출력을 했지만 호이스팅으로 인해 에러가 발생하지 않는다. 
</li>
<li><p>function 선언문</p>
<pre><code class="language-javascript">console.dir(add);
console.log(add(2, 5));
function add(x, y) {
 return x + y;
}</code></pre>
<img src="https://velog.velcdn.com/images/front-study/post/09e5f1ac-057d-44f4-9a6c-685a50e7d687/image.png" align="left">
위 예제 역시 add 함수가 선언하기 전에 먼저 함수를 실행시켰지만 호이스팅으로 정상적으로 실행된 것을 확인할 수 있다.
</li>
<li><p>let,const에서는?
  let과 const에서는 호이스팅이 발생하지만 호출전에 초기화 되지 않아 참조에러가 발생하게 된다. 이것을 <strong>일시적 사각지대(TDZ:Temporal Dead Zone)</strong>라고 하며 아래 예제에서 확인해 보자</p>
<img src="https://velog.velcdn.com/images/front-study/post/349230e4-d8d1-4650-ba6c-6f37da3239f5/image.png" align="left">

</li>
</ul>
<h4 id="왜-발생하는-걸까">왜 발생하는 걸까?</h4>
<p>호이스팅이 발생하는 이유를 알기 위해 실행 컨텍스트 알아야 하지만 이 글에서 작성하기에는 너무 길어 해당 내용은 따로 정리 중이다.</p>
<h2 id="🚩-표현식과-연산자">🚩 표현식과 연산자</h2>
<h3 id="🏁-표현식">🏁 표현식</h3>
<h4 id="표현식이란">표현식이란?</h4>
<blockquote>
<p>어떠한 결과가 값으로 평가되는 식을 의미한다. </p>
</blockquote>
<h4 id="예제">예제</h4>
<pre><code class="language-javascript">//리터럴 표현식
&#39;Hello&#39;

//식별자 표현식(선언이 이미 존재한다고 가정)
sum
person.name
arr[1]

//연산자 표현식10 + 20
sum = 10
sum !== 10

//함수/메서드 호출 표현식(선언이 이미 존재한다고 가정)
square()
person.getName()</code></pre>
<h3 id="🏁-연산자">🏁 연산자</h3>
<h4 id="할당-연산자">할당 연산자</h4>
<blockquote>
<p>오른쪽에 표현식을 왼쪽 피연산자에 할당하는 연산자</p>
</blockquote>
<table>
<thead>
<tr>
<th>할당 연산자</th>
<th>예</th>
<th>동일 표현</th>
</tr>
</thead>
<tbody><tr>
<td>=</td>
<td>x = 5</td>
<td>x = 5</td>
</tr>
<tr>
<td>+=</td>
<td>x += 5</td>
<td>x = x + 5</td>
</tr>
<tr>
<td>-=</td>
<td>x -= 5</td>
<td>x = x - 5</td>
</tr>
<tr>
<td>*=</td>
<td>x *= 5</td>
<td>x = x * 5</td>
</tr>
<tr>
<td>/=</td>
<td>x /= 5</td>
<td>x = x / 5</td>
</tr>
<tr>
<td>%=</td>
<td>x %= 5</td>
<td>x = x % 5</td>
</tr>
</tbody></table>
<h4 id="비교-연산자">비교 연산자</h4>
<p>좌측과 우측의 피연산자를 비교하는 연산자 true,false를 반환한다. </p>
<table>
<thead>
<tr>
<th>비교 연산자</th>
<th>의미</th>
<th>사례</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>==</td>
<td>동등 비교</td>
<td>x == y</td>
<td>x와 y의 값이 같음</td>
</tr>
<tr>
<td>===</td>
<td>일치 비교</td>
<td>x === y</td>
<td>x와 y의 값과 타입이 같음</td>
</tr>
<tr>
<td>!=</td>
<td>부동등 비교</td>
<td>x != y</td>
<td>x와 y의 값이 다름</td>
</tr>
<tr>
<td>!==</td>
<td>불일치 비교</td>
<td>x !== y</td>
<td>x와 y의 값과 타입이 다름</td>
</tr>
</tbody></table>
<h4 id="비트-연산자">비트 연산자</h4>
<p>비트를 조작하는 연산자 
(논리합의 경우 파이프 기호가 테이블 마크다운으로 인해 적용되지 않아 l로 대체)</p>
<table>
<thead>
<tr>
<th>비트 연산자</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td>l</td>
<td>논리합(OR)</td>
</tr>
<tr>
<td>&amp;</td>
<td>논리곱(AND)</td>
</tr>
<tr>
<td>~</td>
<td>부정(NOT)</td>
</tr>
<tr>
<td>^</td>
<td>배타적 논리합(XOR)</td>
</tr>
<tr>
<td>&lt;&lt;</td>
<td>왼쪽 쉬프트</td>
</tr>
<tr>
<td>&gt;&gt;</td>
<td>오른쪽 쉬프트</td>
</tr>
</tbody></table>
<h4 id="논리-연산자">논리 연산자</h4>
<p>참과 거짓을 검증하는 연산자</p>
<table>
<thead>
<tr>
<th>논리연산자</th>
<th>의미</th>
</tr>
</thead>
<tbody><tr>
<td></td>
<td></td>
</tr>
<tr>
<td>&amp;&amp;</td>
<td>논리곱(AND)</td>
</tr>
<tr>
<td>!</td>
<td>부정(NOT)</td>
</tr>
</tbody></table>
<h4 id="삼항-연산자">삼항 연산자</h4>
<p>조건? 참 : 거짓 형태를 가지는 연산자</p>
<pre><code class="language-javascript">let x = 2;
let result = x % 2 ? &#39;홀수&#39; : &#39;짝수&#39;;</code></pre>
<h4 id="관계-연산자">관계 연산자</h4>
<p>객체의 속성이 있는지 확인하는 연산자</p>
<pre><code class="language-javascript">const person = {
    name:&quot;TEST&quot;
}
console.log(&quot;name&quot; in person); // true
console.log(&quot;address&quot; in person); // false</code></pre>
<h4 id="typeof">typeof</h4>
<p>피연산자의 타입을 반환하는 연산자(문자열로 반환된다);</p>
<pre><code class="language-javascript">const x = 10;
const y = &quot;string&quot;;
const z = false;

console.log(typeof x); // number
console.log(typeof y); // string
console.log(typeof z); // boolean</code></pre>
<h2 id="🚩-흐름-제어">🚩 흐름 제어</h2>
<h3 id="🏁-조건문">🏁 조건문</h3>
<h4 id="if조건참">if(조건){참}</h4>
<p>조건이 맞을 때만 실행되는 문법이다. 소괄호 안에 조건을 넣고 조건이 참인 경우 중괄호 안의 내용을 실행시킨다.</p>
<p><strong>예제</strong> </p>
<pre><code class="language-javascript">if(true){
   console.log(&#39;hello&#39;);
}</code></pre>
<p><strong>주의사항</strong></p>
<blockquote>
<p>false 뿐만 아닌 null,0,NaN,undefined,&#39;&#39; 도 거짓이다.</p>
</blockquote>
<h3 id="if조건참else거짓">if(조건){참}else{거짓}</h3>
<p>if문과 같지만 거짓일 경우 실행하는 else가 추가되었다.</p>
<p><strong>예제</strong> </p>
<pre><code class="language-javascript">if(false){
  console.log(&#39;true&#39;);
}else{
  console.log(&#39;false&#39;)
}</code></pre>
<h4 id="if조건참else-if다음-조건참else거짓">if(조건){참}else if(다음 조건){참}else{거짓}</h4>
<p>if문과 같지만 거짓일 경우 한번더 조건을 체크 후 else로 빠지게된다.</p>
<pre><code class="language-javascript">if(false){
  console.log(&#39;false&#39;);
}else if(true){
  console.log(&#39;true&#39;)
}else{
  console.log(&#39;false&#39;);
}</code></pre>
<h4 id="switch문">switch문</h4>
<p>괄호 안 값에 따라 분기되는 문법</p>
<p><strong>예제</strong></p>
<pre><code class="language-javascript">const grade = &quot;B&quot;;
switch (grade) {
  case &quot;A&quot;:
    console.log(&quot;A grade&quot;);
    break;
  case &quot;B&quot;:
    console.log(&quot;B grade&quot;);
    break;
  case &quot;C&quot;:
    console.log(&quot;C grade&quot;);
    break;
  case &quot;D&quot;:
    console.log(&quot;D grade&quot;);
    break;
  default:
    console.log(&quot;Unknown&quot;);</code></pre>
<h3 id="🏁-반복문">🏁 반복문</h3>
<h4 id="for초기문-조건문-증감문">for(초기문; 조건문; 증감문)</h4>
<p>조건문의 결과가 거짓이 되면 반복을 종료한다.</p>
<p><strong>예제</strong></p>
<pre><code class="language-javascript">for (let i = 0; i &lt; 10; i+=1) {
  console.log(i);
}</code></pre>
<h4 id="while조건">while(조건){}</h4>
<p>괄호안 조건이 거짓이 될 때까지 반복</p>
<p><strong>예제</strong></p>
<pre><code class="language-javascript">let x = 0;
while (x &lt; 10){
  x += 1;
  console.log(x);
}</code></pre>
<h4 id="do-while조건">do-while(조건)</h4>
<p>로직을 먼저 실행한 다음 조건을 검사</p>
<p><strong>예제</strong></p>
<pre><code class="language-javascript">let x = 0;
do {
  console.log(&quot;Fire&quot;);
} while (x &gt; 10);</code></pre>
<h2 id="🚩-배열과-객체">🚩 배열과 객체</h2>
<h3 id="🏁-배열">🏁 배열</h3>
<p>연관된 데이터를 연속적인 형태로 저장하는 복합 타입으로 순서대로 번호가 붙는다.</p>
<h4 id="배열-생성">배열 생성</h4>
<pre><code class="language-javascript">const arr1 = new Array();
const arr2 = [];</code></pre>
<h4 id="배열-초기화">배열 초기화</h4>
<pre><code class="language-javascript">const arr3 = [1,2,3,4,5];
const arr4 = new Array(5);
const arr5 = new Array(5).fill(5);
const arr6 = Array.from(Array(5), function(v,k){ 
    return k + 1;
});</code></pre>
<h4 id="배열-삽입삭제">배열 삽입,삭제</h4>
<pre><code class="language-javascript">const arr = [1,2,3,4,5];
//추가
arr.push(6); 
//첫번째 요소 삭제
arr.shift();
//요소를 배열의 맨 앞쪽에 추가하고
arr.unShift()
//중간요소 출력
arr.slice(2,4);
//중간요소 삭제
arr.aplice(2,4);</code></pre>
<h4 id="배열-순회">배열 순회</h4>
<p><strong>for문</strong></p>
<pre><code class="language-javascript">const arr = [1,2,3,4,5];
for(let i=0; i&lt;arr.length; i++){
  console.log(arr[i]);
}</code></pre>
<p><strong>for of문</strong></p>
<pre><code class="language-javascript">const arr = [1,2,3,4,5];
for(const item of arr){
  console.log(item);
}</code></pre>
<h4 id="주요함수">주요함수</h4>
<p><a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/concat">MDN에서</a> 검색해서 사용해보는 것을 추천한다.</p>
<h3 id="🏁-객체">🏁 객체</h3>
<p>Key, value로 여러 값을 가지는 타입</p>
<p><strong>예제</strong></p>
<pre><code class="language-javascript">const obj = { name: &quot;test&quot; }

//객체 추가
obj[&#39;test1&#39;] = 1;
obj.test2 = 2;

//객체 삭제
delete obj.test2;

//객체 순회
for(const key in obj){
  console.log(key, obj[key]);
}</code></pre>
<h2 id="🚩-스코프와-클로저">🚩 스코프와 클로저</h2>
<h3 id="🏁-스코프">🏁 스코프</h3>
<p>변수가 참조되는 범위를 말한다. 전역 스코프, 블록 스코프, 함수 스코프의 종류가 있다. </p>
<blockquote>
<p>var: 경우 함수 스코프를 가진다
let,const: 블록 스코프를 가진다.</p>
</blockquote>
<h3 id="🏁-클로저">🏁 클로저</h3>
<p>함수가 선언된 환경의 스코프를 기억하여 함수가 스코프 밖에서 실행될 때에도 기억한 스코프에 접근할 수 있게 만드는 문법이다.</p>
<p><strong>예제</strong></p>
<pre><code>const x = 1;

function outer() {
    const x = 10;
    const inner = function () {
        console.log(x);
    }
    return inner;
}

const innerFunc = outer();
innerFunc() // 10;</code></pre><p>우리가 클로저를 알아야 하는 이유는 유용하게 사용하기 보단 알기 힘든 버그를 쉽게 수정하기 위해서이다.</p>
<h4 id="자주-발생하는-실수">자주 발생하는 실수</h4>
<pre><code class="language-javascript">function counting(){
  let i = 0;
  for (i = 0; i &lt; 5; i += 1) {
    setTimeout(function(){
      console.log(i);
    }, i * 100)
  }
}

counting()</code></pre>
<p>위 코드의 경우 setTimeout이 응답을 하기전에 루프가 먼저실행되어 5,5,5,5,5가 출력된다.</p>
<h4 id="해결방법1-let">해결방법1 (let)</h4>
<pre><code class="language-javascript">function counting(){
  for (let i = 0; i &lt; 5; i += 1) {
    setTimeout(function(){
      console.log(i);
    }, i * 100)
  }
}

counting();</code></pre>
<p>밖에 선언한 let i를 for문 안에서 사용한다.</p>
<h4 id="해결방법2-iife즉시실행함수">해결방법2 IIFE(즉시실행함수)</h4>
<pre><code class="language-javascript">function counting(){
  let i = 0;
  for (i = 0; i &lt; 5; i += 1) {
    (function(number){
        setTimeout(function(){
            console.log(number);
        }, i * 100)
    })(i)
  }
}

counting()</code></pre>
<p>즉시 실행함수를 만들어 루프마다 클로저를 만든다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Rest API가 뭐에요?]]></title>
            <link>https://velog.io/@front-study/what-is-it-rest-api</link>
            <guid>https://velog.io/@front-study/what-is-it-rest-api</guid>
            <pubDate>Wed, 24 May 2023 09:34:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/front-study/post/d90bf29a-ce49-472e-a712-1ef11c75c1fd/image.png" alt=""></p>
<h2 id="🚩rest-api란">🚩<strong>Rest API란?</strong></h2>
<p>REST API는 REST 아키텍처를 기반으로 구현되는 API로서 <strong>자원, 행위, 표현</strong>의 세 가지 요소로 구성되어 있습니다. 또한 REST API를 올바르게 구현하기 위해서는 <strong>6가지 제약조건</strong>을 준수해야 합니다. 그렇다면 <strong>3가지 구성 요소</strong> 와 <strong>6가지 제약조건</strong>에 대해서 자세히 살펴보겠습니다.</p>
<h2 id="🚩rest-api-구성-요소">🚩<strong>Rest API 구성 요소</strong></h2>
<h3 id="🏁자원">🏁<strong>자원</strong></h3>
<ul>
<li>URI를 사용하여 자원을 표현합니다.</li>
<li>모든 자원에는 고유한 ID가 존재하고 이 자원은 Server에 존재합니다.</li>
</ul>
<h3 id="🏁행위">🏁<strong>행위</strong></h3>
<ul>
<li>자원에 대한 어떤 행위를 할 것인지 <a href="https://developer.mozilla.org/ko/docs/Web/HTTP/Methods"><strong>HTTP Method</strong></a>를 사용해 나타냅니다.<strong>(Get, Post, Put, Patch, Delete)</strong></li>
</ul>
<h3 id="🏁표현">🏁<strong>표현</strong></h3>
<ul>
<li>Client와 Server가 데이터를 주고받는 형태로 대표적으로 Json, XML, HTML등이 있습니다.</li>
</ul>
<p><img src="https://velog.velcdn.com/images/front-study/post/ca74b67e-6151-4f9c-89fe-5ac156f06c28/image.png" alt=""><img src="https://velog.velcdn.com/images/front-study/post/02b105c9-88ef-4e5a-bca1-e4371fcf375a/image.png" alt=""></p>
<p>위 사진은 구글 Gmail의 <a href="https://developers.google.com/gmail/api/reference/rest?hl=ko#rest-resource:-v1.users.labels">Label API문서</a>를 가져왔습니다. Label API문서를 통해 3가지 구성요소를 작성해보겠습니다.</p>
<p><strong>자원</strong> : <a href="https://gmail.googleapis.com/gmail/v1/users/">https://gmail.googleapis.com/gmail/v1/users/</a>{userId}/labels/{id}<br><strong>행위</strong> : GET<br><strong>표현</strong> : JSON</p>
<h2 id="🚩rest-api-제약조건">🚩<strong>Rest API 제약조건</strong></h2>
<h3 id="🏁client-server클라이언트-서버">🏁<strong>Client-Server(클라이언트-서버)</strong></h3>
<p>클라이언트와 서버가 서로 분리되어 있어야 함을 의미합니다.</p>
<ul>
<li><strong>Server(서버)</strong><br>자원(API)을 제공하며 클라이언트 요청에 따라 데이터를 처리하고 응답을 보내는 역할을 합니다.</li>
<li><strong>Client(클라이언트)</strong><br>서버에 요청을 보내고 응답을 받으며 사용자 인증, 세션, 로그인 정보 등을 관리하며 이러한 정보를 사용하여 서버에 요청을 보낼 수 있습니다.</li>
</ul>
<h3 id="🏁stateles무상태성">🏁<strong>Stateles(무상태성)</strong></h3>
<p>서버는 클라이언트의 정보를 저장, 관리하지 않으며 요청만을 처리합니다.</p>
<h3 id="🏁cacheable캐시-가능">🏁<strong>Cacheable(캐시 가능)</strong></h3>
<p>클라이언트가 서버로부터 받은 응답을 캐시에 저장하여 재사용할 수 있음을 의미합니다.</p>
<ul>
<li>HTTP 프로토콜을 사용해 HTTP가 가진 <a href="https://developer.mozilla.org/ko/docs/Web/HTTP/Caching">캐싱</a> 정책이 적용 가능합니다.</li>
</ul>
<h3 id="🏁layered-system계층형-구조">🏁<strong>Layered System(계층형 구조)</strong></h3>
<p>클라이언트는 최종 서버에 직접 연결되었는지 중개 서버에 연결되었는지 알 수 없습니다.</p>
<h3 id="🏁uniform-interface인터페이스-일관성">🏁<strong>Uniform Interface</strong>(인터페이스 일관성)</h3>
<p>통일된 Interface를 통해 어떤 플랫폼에서도 사용이 가능해야 하며 이를 위해 4가지 제약 조건을 만족해야 합니다.</p>
<h4 id="identification-of-resources"><strong>Identification of resources</strong></h4>
<p>서버의 자원은 URI로 식별되어야 합니다.</p>
<h4 id="manipulation-of-resources-through-representations"><strong>Manipulation of Resources Through Representations</strong></h4>
<p>클라이언트가 HTTP 메서드를 사용해 서버의 자원을 조작(CRUD) 할 수 있으며 조작을 위해 JSON, XML 등의 표현 형식을 사용해야 합니다.</p>
<h4 id="self-descriptive-messages"><strong>Self-descriptive Messages</strong></h4>
<p>메시지가 스스로를 설명할 수 있는 구조를 가져야 함을 의미합니다.</p>
<p><img src="https://velog.velcdn.com/images/front-study/post/1734a92c-d26d-4958-962f-e62176d34693/image.png" alt="">
<img src="https://velog.velcdn.com/images/front-study/post/48c70e3a-4d74-4b45-9cd5-69785b64a316/image.png" alt=""></p>
<p>위 사진은 카카오의 Open API 문서입니다. 클라이언트는 api 명세만으로 api를 알 수 있습니다.</p>
<h4 id="hateoashypermedia-as-the-engine-of-application-state"><strong>HATEOAS(Hypermedia as the Engine of Application State)</strong></h4>
<p>애플리케이션 상태를 이동할 때 하이퍼링크를 통해 가능한 행동들을 파악하고 그에 따라 요청을 보낼 수 있어야 한다를 의미합니다.</p>
<pre><code>GET /users/123 HTTP/1.1
Host: https://api.example.com</code></pre><p>다음과 같은 API 명세가 있다고 가정해보겠습니다. HATEOAS를 적용한 API 응답결과는 다음과 같습니다.</p>
<pre><code class="language-json">{
  &quot;id&quot;: 123,
  &quot;name&quot;: &quot;John Doe&quot;,
  &quot;email&quot;: &quot;john.doe@example.com&quot;,
  &quot;links&quot;: {
    &quot;self&quot;: {
      &quot;href&quot;: &quot;https://api.example.com/users/123&quot;
    },
    &quot;friends&quot;: {
      &quot;href&quot;: &quot;https://api.example.com/users/123/friends&quot;
    },
    &quot;edit&quot;: {
      &quot;href&quot;: &quot;https://api.example.com/users/123&quot;,
      &quot;method&quot;: &quot;PUT&quot;
    },
    &quot;delete&quot;: { 
      &quot;href&quot; :  &quot;https://api.example.com/users/123&quot; , 
      &quot;method&quot; :  &quot;DELETE&quot; 
    } 
  } 
}</code></pre>
<p>links 객체 안에 사용자 정보를 조회, 수정 등의 관련된 작업을 수행할 수 있는 링크 정보들이 포함되어 있습니다. 이를 통해 클라이언트는 각 링크가 어떤 작업에 대응되는지 알 수 있고 이러한 정보를 바탕으로 동적으로 애플리케이션 상태를 변경할 수 있습니다.</p>
<h3 id="🏁code-on-demand옵션">🏁Code on demand(옵션)</h3>
<p>서버는 클라이언트에 실행 가능한 코드를 제공할 수 있어야 합니다. (이 규칙은 선택 사항입니다.)</p>
<p>예를 들어 Swagger를 사용해 클라이언트는 서버가 제공하는 API를 확인하고 테스트할 수 있습니다.</p>
<h2 id="🚩api-디자인-가이드">🚩<strong>API 디자인 가이드</strong></h2>
<p>마지막으로 Restful API 디자인 가이드를 소개하며 글을 마치겠습니다.</p>
<ol>
<li>URI는 동사보다는 명사를 사용합니다<br>ex) /getUsers =&gt; X / users =&gt; O</li>
<li>URI는 계층 구조를 가지며 자원 간 관계를 나타내야 합니다.<br>ex) /users/1/posts</li>
<li>URI에 소문자를 사용해 일관성을 유지합니다.</li>
<li>적절한 HTTP 메서드와 HTTP 상태 코드를 사용합니다.<br>ex) 게시물 생성(post) / Response(201)</li>
<li>API가 변경될 가능성이 있으므로 버전 관리를 통해 호환성을 유지할 수 있도록 해야 합니다.<br>ex) /api/v1/users</li>
<li>URI에 파일 확장자를 포함하지 않습니다.<br>ex) users/image.png =&gt; X / users/image =&gt; O</li>
<li>쿼리 매개변수를 사용하여 자원 목록을 필터링, 정렬 및 페이징할 수 있게 해야 합니다.<br>ex) /users?sort=asc&amp;page=2&amp;limit=10</li>
</ol>
<h2 id="🚩reference">🚩<strong>Reference</strong></h2>
<ul>
<li><a href="https://www.restapitutorial.com/">restapitutorial</a></li>
<li><a href="https://meetup.nhncloud.com/posts/92">Rest API 제대로 알고 사용하기</a></li>
<li><a href="https://www.youtube.com/watch?v=RP_f5dMoHFc">그런 REST API로 괜찮은가</a></li>
<li><a href="https://learn.microsoft.com/ko-kr/azure/architecture/best-practices/api-design">RESTful 웹 API 디자인</a></li>
<li><a href="https://www.ibm.com/docs/ko/zos-connect/zosconnect/3.0?topic=apis-designing-restful">RESTful API 디자인</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>