<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev-yun.log</title>
        <link>https://velog.io/</link>
        <description>기본을 탄탄하게🌳</description>
        <lastBuildDate>Thu, 21 Jul 2022 15:52:02 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. dev-yun.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/dev-yun" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[TypeScript (Interface, Type Alias)]]></title>
            <link>https://velog.io/@dev-yun/TypeScript-Interface-Type-Alias</link>
            <guid>https://velog.io/@dev-yun/TypeScript-Interface-Type-Alias</guid>
            <pubDate>Thu, 21 Jul 2022 15:52:02 GMT</pubDate>
            <description><![CDATA[<h2 id="타입-지정-방법">타입 지정 방법</h2>
<p>TypeScript에는 <strong>기본 타입</strong>과 <strong>객체 타입</strong>이 존재한다.</p>
<p>기본 타입은 JS에도 존재하는 <code>Number, String, Object..</code> 같은 데이터 타입 + <code>Enum, Never</code>같은 TS에서 추가된 타입을 의미한다.</p>
<blockquote>
<p>자세한 사항은 <a href="https://joshua1988.github.io/ts/guide/basic-types.html#%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B8%B0%EB%B3%B8-%ED%83%80%EC%9E%85">typescript 핸드북</a>에서 볼 수 있다.
기본 타입을 부여하는 방법은 어렵지 않아 따로 설명하지 않겠다.</p>
</blockquote>
<p>객체 타입은 말 그대로 객체형식으로 설정된 타입이다. </p>
<p>사용자가 필요에 의해 새로 만드는 형식이기 때문에 매우 다양한 방법으로 타입을 지정할 수 있다.</p>
<blockquote>
<p>새로 만든 타입에 Type Alias와 Interface간의 차이가 존재하는데 아래에서 정리하겠다.</p>
</blockquote>
<p>객체 타입을 지정하는 방법은 2가지가 존재한다.</p>
<h3 id="1-type-alias">1. Type Alias</h3>
<p>타입 별칭이라는 의미의 Type Alias는 의미 그대로 타입에 이름을 붙힐 수 있다.</p>
<h4 id="사용-방식-1-기본-타입에-별칭을-짓는-방법">사용 방식 1. 기본 타입에 별칭을 짓는 방법</h4>
<p>모든 식별자(함수, 클래스, 변수, 객체..)에는 타입을 정의 해야하고
사용 방식은 <code>type 타입이름 = 데이터타입</code>으로 설정한다.</p>
<pre><code class="language-typescript">// type alias 미사용
const age: number = 25;

// type alias 사용
type UserAge = number;
const age: UserAge = 25;

// type alias의 사용 2
type RGB = &quot;R&quot; | &quot;G&quot; | &quot;B&quot;;
const rgb : RGB = &quot;R&quot;;  // 성공
const rgb1 : RGB = &quot;H&quot;;  // 실패</code></pre>
<p>사용 효과 </p>
<ol>
<li><p>type에 이름을 붙히므로써 표현력을 높힐 수 있다.</p>
</li>
<li><p>직접 type에 들어갈 값을 설정함으로써 더 안정적인 코드를 작성할 수 있다. </p>
</li>
</ol>
<blockquote>
<p>단순히 number, string이라면 무슨 숫자인데? 무슨 문자열인데? 라는 의문이 생길 수 있는데 
type에 이름을 붙혀 더 세세한 정보를 제공한다.</p>
</blockquote>
<h4 id="사용-방식-2-객체-타입을-생성하는-방법">사용 방식 2. 객체 타입을 생성하는 방법</h4>
<p>사용방식은 <code>type 타입이름 = { 속성명 : 데이터타입 }</code>으로 작성한다.</p>
<pre><code class="language-typescript">// type alias 미사용
const person: object = {
  name: &quot;Yun&quot;,
  age : 25,
  address : &quot;seoul&quot;,
}

// type alias 사용
type PersonInfo = {
  name : string;
  age : number;
}
const person: PersonInfo = {
  name : &quot;Yun&quot;,
  age : 25,
}</code></pre>
<blockquote>
<p>일반 객체의 타입을 object로 설정하면 내부 속성들은 모두 <code>타입 추론</code>을 통해 타입이 지정된다. 
 이는 잘못된 타입이 설정될 수 있으며 사용자가 직접 타입을 하나 하나 설정할 수 없다.</p>
</blockquote>
<p> 때문에 type alias를 통해 객체 타입을 설정하여 객체의 속성을 지정해 줘야한다.</p>
<h4 id="사용-방식-3-타입을-합치는-방법">사용 방식 3. 타입을 합치는 방법</h4>
<p>사용 방식은 <code>type 타입1 = 타입2 &amp; 타입3 &amp; { 타입1의 내용 }</code>처럼 <code>&amp;</code>를 통해 합칠 수 있다.</p>
<pre><code class="language-typescript">type Year = { month : 12 }
type Month = Year &amp; { day : 30 }
type Day = Month &amp; { hour : 24 }

const day : Day = {
    month : 12,
    day : 30,
    hour : 24,
}
// 만약 month or day or hour 중 하나라도 빠지면 타입 에러 발생</code></pre>
<pre><code class="language-typescript">type Year = { month : 12 }
type Month = Year &amp; { day : 30 }
type Day = Month | { hour : 24 }

const day : Day = {
    //month : 12,
    //day : 30,
    hour : 24,
}
// 에러가 발생하지 않음</code></pre>
<blockquote>
<p><code>&amp;</code>와 <code>|</code>의 차이점</p>
</blockquote>
<ul>
<li>유니온을 사용할 경우 or 연산이 되어 <code>month &amp; day</code> 또는 <code>hour</code> 중 하나만 있으면 에러가 발생하지 않는다.</li>
<li>인터섹션을 사용할 경우 and 연산이 되어 <code>month &amp; day &amp; hour</code> 모두 정의 되어야 에러가 발생하지 않는다.</li>
</ul>
<h3 id="2-interface">2. Interface</h3>
<p>인터페이스도 기본적으로 타입 별칭과 같이 타입에 이름을 부여합니다.</p>
<h4 id="사용-방식-1-객체-타입을-지정하는-방법">사용 방식 1. 객체 타입을 지정하는 방법</h4>
<p>사용 방식은 <code>interface { 속성명 : 데이터타입 }</code>으로 작성한다.</p>
<pre><code class="language-typescript">// 단순 객체 생성
interface Person {
  name : string;
  age : number;
}

const person: Person = {
  name : &quot;Yun&quot;,
  age : 25,
}</code></pre>
<p>약간의 문법 차이가 있을 뿐 type alias와 유사하다.</p>
<h4 id="사용-방식-2-타입을-합치는-방법">사용 방식 2. 타입을 합치는 방법</h4>
<p>사용 방식은 <code>interface 타입1 extends 타입2, 타입3 { 타입1의 내용 }</code>으로 작성한다.</p>
<pre><code class="language-typescript">interface R { r : &quot;Red&quot;; }
interface G { g : &quot;Green&quot;; }
interface B extends R, G{ b : &quot;Blue&quot;; color : string}

const rgb2: B = {
    r : &quot;Red&quot;,
    g : &quot;Green&quot;,
    b : &quot;Blue&quot;,
    color : &quot;삼원색&quot;,
}
// r, g, b, color 중 하나라도 빠지면 타입 에러 발생</code></pre>
<p><code>extends</code>도 <code>&amp;</code>와 마찬가지로 and 연산을 하여서 하나라도 타입의 속성이 없다면 에러를 발생시킨다.</p>
<h3 id="type-alias와-interface의-차이점">Type Alias와 Interface의 차이점</h3>
<p><strong>1. Type Alias는 타입을 값으로 갖고 Interface는 값으로 갖지 않는다.</strong></p>
<pre><code class="language-typescript">type A = { a : string }
interface A { a : string }
// 때문에 interface는 할당연산자(=)를 사용할 수 없다</code></pre>
<p>때문에 interface는 <code>type a = string;</code> 같은 기본타입에 별칭을 짓는 방법이 없다.</p>
<p>또한 타입에 커서를 올려 자세한 정보를 확인할 경우 type alias는 타입의 값을 보여주는데, interface는 interface 명만 표시한다.
<img src="https://velog.velcdn.com/images/dev-yun/post/cb9c437f-7807-43d4-ae74-d53be23835c7/image.png" alt=""></p>
<p><strong>2. Interface는 같은 이름으로 재선언과 확장이 가능하지만 Type Alias는 불가능하다.</strong></p>
<pre><code class="language-typescript">// 확장 가능한 interface의 특징
interface UserInfo {
    id : string;
    password : string;
}
interface UserInfo {
    email : string;
}

const user: UserInfo = {
    id : &quot;gameU&quot;,
    password : &quot;passW&quot;,
    email : &quot;user@abc.com&quot;,
}</code></pre>
<img src="https://velog.velcdn.com/images/dev-yun/post/1b5bbae1-b685-44b9-9884-9b09b680b0b4/image.png" width = 450px>
Type Alias에서는 오류가 발생한다.

<p>이러한 확장성 때문에 interface를 선호하는 사람들도 있다.</p>
<p><strong>3. Type Alias에서는 유니온(|) 타입을 사용할 수 있지만 Interface에서는 불가능하다.</strong></p>
<p><strong>4. Type Alias에서는 튜플 타입을 사용할 수 있지만 Interface에서는 불가능하다.</strong></p>
<blockquote>
<p>튜플이란 TS에서 새로 탄생한 데이터 타입으로 기존 JS의 배열 타입을 확장한 개념이다.</p>
</blockquote>
<p>차이점 : 배열의 모든 특성을 유지한 채, 배열의 원소에 하나하나 타입을 지정한다.
=&gt; 이를 통해 배열 원소의 수와 타입을 고정시킬 수 있다.</p>
<pre><code class="language-typescript">// 일반 배열
const userArr = [&quot;Yun&quot;, 25, &quot;y@abc.com&quot;, true]

// 튜플
const userTuple: [string, number, string, boolean] = [&quot;Yun&quot;, 25, &quot;y@abc.com&quot;, true]</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[TypeScript (기본 세팅)]]></title>
            <link>https://velog.io/@dev-yun/TypeScript-%EA%B8%B0%EB%B3%B8-%EC%84%B8%ED%8C%85</link>
            <guid>https://velog.io/@dev-yun/TypeScript-%EA%B8%B0%EB%B3%B8-%EC%84%B8%ED%8C%85</guid>
            <pubDate>Wed, 20 Jul 2022 12:58:37 GMT</pubDate>
            <description><![CDATA[<h2 id="typescript란">TypeScript란</h2>
<p>Javascript의 확장된 개념으로 기존 Javascript에 type을 부여한 코드이다.</p>
<p>타입을 부여함으로써 얻을 수 있는 이점</p>
<ol>
<li><p>사전에 에러를 방지할 수 있다.</p>
<ul>
<li><p>TypeScript의 핵심 기능으로 식별자에 명확한 타입을 부여함으로써 엉뚱한 데이터 타입이 들어가 예상치 못한 결과가 발생하는 것을 막을 수 있다.</p>
</li>
<li><p>기본 타입 외에 더 세세한 타입 별칭을 붙히거나 여러 TypeScript 만의 기능을 사용하여 더 견고한 코드를 작성할 수 있다.</p>
</li>
</ul>
</li>
<li><p>코드의 자동 완성을 통한 생산성 증가 </p>
<ul>
<li><p>명확한 타이핑을 함으로써 해당 데이터 타입에 존재하는 메서드나 속성을 자동완성으로 사용할 수 있게된다.</p>
<ul>
<li><p>javascript에서는 <code>a = 5</code>, <code>a.toString()</code>을 사용하는 경우 <code>toString</code>은 자동완성이 되지 않는다. (a의 타입이 확실하지 않으므로)</p>
</li>
<li><p>하지만 typescript에서는 <code>a : number = 5</code>로 a에 number라는 타이핑을 하면 <code>Number</code>의 메서드인 <code>toString</code>이 자동완성 목록에 나온다.</p>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<p><a href="https://joshua1988.github.io/ts/why-ts.html#%EC%99%9C-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EB%A5%BC-%EC%8D%A8%EC%95%BC%ED%95%A0%EA%B9%8C%EC%9A%94">출처 : TypeScript 핸드북</a></p>
<h2 id="typescript-프로젝트-환경-설정">TypeScript 프로젝트 환경 설정</h2>
<p>TypeScript 프로젝트를 진행하기 위해 우선 설치해야하는 패키지들이 있다.</p>
<ol>
<li>package.json 파일 생성 - node.js의 여러 라이브러리를 사용할 수 있는 환경이 된다.<pre><code>// npm을 통한 package.json 파일 생성
npm init - y

</code></pre></li>
</ol>
<p>// yarn이 설치되지 않았다면 우선 yarn 설치가 필요
npm install -g yarn</p>
<p>// yarn을 통한 package.json 파일 생성
yarn init -y</p>
<pre><code>
2. 패키지 매니저를 통해 TypeScript 설치</code></pre><p>// npm 사용 (프로젝트 내에 설치, 글로벌은 -g 옵션 추가)
npm i typescript</p>
<p>// yarn 사용 (프로젝트 내에 설치, 글로벌은 global 옵션 추가)
yarn add typescript</p>
<pre><code>
&gt;2까지의 과정을 통해 이제 `tsc` 명령어를 사용할 수 있게 된다.
&gt;
`tsc`란 `typescript compiler`로 typescript를 javascript로 변환할때 사용하는 명령어다.
&gt;
`tsc app.ts`를 실행하면 `app.js`로 컴파일됨

3. tsconfig.json 파일 생성</code></pre><p>// npx 사용 (npx는 패키지 실행기로 tsc --init을 실행하여 tsconfig.json파일을 생성한다.)
// 글로벌이 아니라 프로젝트 내에서만 typescript를 설치하였기 때문에 npx를 사용해야한다. 
npx tsc --init</p>
<p>// yarn 사용
yarn tsc --init</p>
<pre><code>

모든 과정이 성공했다면 무사히 typescript 프로젝트가 생성된 것이다.


## tsconfig.json

tsconfig.json에는 typescript에서 javascript로 변환될때 설정이 담겨있다.

기본설정은 javascript를 그대로 typescript로 옮겨도 작동될만큼 유연하게 설정되어있는데, 이러면 의미가 없다.

대표적인 설정들을 몇가지 살펴보고 바꿔보겠다.

&gt;
1. strict : typescript의 엄격한 문법을 따를지 설정한다. `true로 설정 권장`
2. noImplicitAny : Any 타입을 사용하지 않도록 설정한다. `true로 설정 권장`
3. noImplicitThis : This 타입을 사용하지 않도록 설정한다. `true로 설정 권장`
4. allowJs : TS코드를 컴파일 할때 JS코드도 포함할지 설정한다. 
`기존의 js코드를 리팩토링하는 과정이라면 true 권장`
5. alwaysStrict : use strict 모드를 켤지 설정한다. `true로 설정 권장`
&gt;
이외에도 많은 설정이 있는데 그때그때 추가해주면 된다.
</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[vscode 터미널에서 외부 스크립트 실행 불가능 해결]]></title>
            <link>https://velog.io/@dev-yun/vscode-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90%EC%84%9C-%EC%99%B8%EB%B6%80-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%8B%A4%ED%96%89-%EB%B6%88%EA%B0%80%EB%8A%A5-%ED%95%B4%EA%B2%B0</link>
            <guid>https://velog.io/@dev-yun/vscode-%ED%84%B0%EB%AF%B8%EB%84%90%EC%97%90%EC%84%9C-%EC%99%B8%EB%B6%80-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%8B%A4%ED%96%89-%EB%B6%88%EA%B0%80%EB%8A%A5-%ED%95%B4%EA%B2%B0</guid>
            <pubDate>Fri, 08 Jul 2022 13:31:56 GMT</pubDate>
            <description><![CDATA[<p>vscode에서 패키지 매니저(npm또는 yarn)을 통해 외부 모듈이나 스크립트를 실행하려 할 경우 아래와 같은 오류가 발생한다.
<code>\Users\유저폴더\AppData\Roaming\npm\스크립트파일명 파일을 로드할 수 없습니다. 자세한 내용은 about_Execution_Polici 
es(https://go.microsoft.com/fwlink/?LinkID=135170)를   
참조하십시오.
위치 줄:1 문자:1</code></p>
<p>이는 기본 터미널이 powershell일 경우 발생하는데</p>
<p>아래와 같은 과정으로 해결할 수 있다.</p>
<ol>
<li><p>PowerShell을 관리자 권한으로 실행한다.</p>
</li>
<li><p><code>get-help Set-ExecutionPolicy</code> 명령어를 실행하고 Y를 입력한다.
(powerShell의 실행 정책에 관한 설정 권한을 얻는다.)</p>
</li>
<li><p><code>Set-ExecutionPolicy RemoteSigned</code> 명령어를 실행하고 Y를 입력한다.
(스크립트의 실행 권한을 Yes로 설정하는 과정이다.)
<img src="https://velog.velcdn.com/images/dev-yun/post/8838cf48-e9ec-4e00-ba9d-6336dbbac491/image.png" alt="">
설명과 같이 악의적인 스크립트를 실행할 경우 문제가 발생할 수 있으므로 실행 권한을 바꾼후에는 보안에 주의해야한다. </p>
</li>
</ol>
<p><a href="https://m.blog.naver.com/vanstraat/221732533202">출처 블로그</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[알고리즘 해결 패턴]]></title>
            <link>https://velog.io/@dev-yun/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%ED%95%B4%EA%B2%B0-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@dev-yun/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%ED%95%B4%EA%B2%B0-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Thu, 19 May 2022 06:46:51 GMT</pubDate>
            <description><![CDATA[<h2 id="1통용적인-해결-패턴이-없는-경우">1.통용적인 해결 패턴이 없는 경우</h2>
<h4 id="1-문제를-이해">1. 문제를 이해</h4>
<pre><code>  1-1. 나만의 방식으로 문제를 이해하여 정리하자.
  1-2. 조건을 정확히 이해하고 정리하자.
  1-3. 문제의 입력값과 어떤 출력값이 필요한지 파악하자.</code></pre><h4 id="2-구체적인-예시를-탐색">2. 구체적인 예시를 탐색</h4>
<pre><code>2-1. 간단한 예시부터 복잡한 예시 순으로 넣어보자.
2-2. 빈 값과 유효하지 않은 값등 예외케이스를 넣어보자.
2-3. 이때 넣어본다는 의미는 완성된 코드에 넣는다는 것이 아닌 머리속으로 넣어본다는 의미이다.</code></pre><h4 id="3-문제를-세분화">3. 문제를 세분화</h4>
<pre><code>3-1. 문제를 이해했다면 단계별 수행할 작업을 명시적으로 표시하자.(수도코드)
3-2. 만약 코딩테스트에서 시간이 부족해 통과하지 못했다면 이러한 단계를 명시한 것이 도움이 될 수있다.</code></pre><h4 id="4-문제를-해결-단순화">4. 문제를 해결, 단순화</h4>
<pre><code>4-1. 만약 해결 가능하다면 바로 문제 해결을 시작하고,
4-2. 해결법이 떠오르지 않는다면 세분화하며 간단한 구현부터 시작하자.</code></pre><h4 id="5-문제를-복습-및-재구성">5. 문제를 복습 및 재구성</h4>
<pre><code>5-1. 위에서 해결한 문제는 해결을 위한 방법이였다.
5-2. 이를 리팩토링하여 코드를 정리하고 효율적으로 만드는 것이 실력향상의 지름길이다.</code></pre><br>
<br>


<h2 id="통용적인-해결-패턴이-없는-경우의-풀이-예시">통용적인 해결 패턴이 없는 경우의 풀이 예시</h2>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/77484" target="_blank">문제링크</a></p>
<h4 id="1-문제-이해">1. 문제 이해</h4>
<ul>
<li>로또 번호와 당첨 번호 리스트가 입력값으로 주어진다.</li>
<li>이때 로또 번호는 (숫자, 0)으로 이루어져있다.</li>
<li>당첨 번호별 등수가 주어진다. (6개 당첨 =&gt; 1등)</li>
<li>0은 조커로 무조건 당첨될 수 있고, 무조건 낙첨될 수 있다.</li>
<li>이때 최대 당첨 등수와 최저 당첨 등수 순으로 배열을 만들어 출력하라.</li>
<li>6 -&gt; 1등, 5 -&gt; 2등 ... 1 -&gt; 6등, 0 -&gt; 6등으로 6등과 매칭되는 당첨 번호 개수는 2개이다.(주의점)</li>
</ul>
<h4 id="2-구체적인-예시를-탐색-1">2. 구체적인 예시를 탐색</h4>
<ul>
<li>보통 테스트 케이스에 명시된 예시를 사용하여 문제에 대입해 본다.<ul>
<li>나의 로또 번호([44, 1, 0, 0, 31, 25]), 당첨 로또 번호([31, 10, 45, 1, 6, 19]) 일때, <strong>0이외에 당첨 개수</strong>는 [1, 31]이므로 [0,0]을 모두 당첨으로 따지면 4개 당첨(3등), [0,0]을 모두 낙첨으로 따지면 2개 당첨(5등)이다. =&gt; [3,5]</li>
</ul>
</li>
<li>[0,0,0,0,0,0]을 입력한다면 0이 모두 당첨일경우 1등, 0이 모두 낙첨일 경우 6등이므로 [1,6]이 return되어야 한다.</li>
<li>입력값은 항상 길이가 6인 0이상 45이하의 정수 배열이므로 빈배열은 들어갈 수 없다.</li>
</ul>
<h4 id="3-문제를-세분화-1">3. 문제를 세분화</h4>
<ul>
<li>우선 주어진 로또 번호에서 0 이외에 몇개가 당첨번호와 일치하는지 구해야한다.</li>
<li>주어진 로또 번호에서 0의 개수를 구하여 위에서 구한 일치한 당첨번호 개수와 더한 뒤 최대 당첨 번호의 개수를 구한다.</li>
<li>0의 개수를 더하지 않은 개수는 최저 당첨 개수이다.</li>
<li>문제에서 주어진 당첨번호 개수별 당첨 등수를 통해 당첨 등수를 구한다.<ul>
<li>이때 당첨번호 1개, 0개는 모두 6등으로 취급하여야 한다.(주의점)</li>
</ul>
</li>
</ul>
<h4 id="4-문제-해결">4. 문제 해결</h4>
<ul>
<li><p>해결법을 통해 문제를 해결한다.</p>
<pre><code class="language-javascript">function solution(lottos, win_nums) {
 var answer = [];
 let correctNumCount = 0;
 let zeros = 0;

   // 문제 세분화를 코드에 수도코드식으로 적고 해결하자.
   // 주어진 로또 번호에서 0을 제외한 당첨 번호의 개수를 저장한다.
 lottos.map((num) =&gt; win_nums.includes(num) ? correctNumCount += 1 : correctNumCount)
   // 주어진 로또 번호에서 0의 개수를 저장한다.
 lottos.map((num) =&gt; (num === 0) &amp;&amp; (zeros += 1))

   // 0을 제외한 당첨 번호에 맞는 등수를 저장한다.
 const low = 7-correctNumCount &lt;= 5 ? 7-correctNumCount : 6;
   // 0을 포한한 당첨 번호에 맞는 등수를 저장한다.
 const high = low-zeros &lt;= 1 ? 1 : low-zeros;

 answer = [high, low];

</code></pre>
</li>
</ul>
<pre><code>return answer;</code></pre><p>}</p>
<pre><code>
#### 5. 문제 복습 및 리팩토링
 - 위에 코드는 실제 문제를 처음 봤을때 내가 짠 코드이다. 
 그런데 가독성이 좋지 않고 복잡하게 구현한 점과 줄일 수 있는 for문이 있었다. (2N을 N으로 줄인것이라 큰 의미는 없다.)

```javascript
function solution(lottos, win_nums) {
    var answer = []
    let minSameCnt = 0;
    let maxSameCnt = 0;

      // 최소 당첨 개수에 0을 제외한 당첨 번호를 넣고, 최대 당첨 개수에 0을 합한 당첨 번호를 넣는다.
    lottos.forEach(e =&gt; {
      if(win_nums.includes(e)){
        minSameCnt++;
      };
      if(win_nums.includes(e) || e===0){
        maxSameCnt++;
      }
    })

      // 최대 당첨 개수와 최소 당첨 개수를 통해 당첨 등수를 구한다. 
    topRank = (7 - maxSameCnt === 7) ? 6 : 7-maxSameCnt; 
    lowRank = (7 - minSameCnt === 7) ? 6 : 7-minSameCnt;

    answer = [topRank, lowRank]

    return answer;
}</code></pre><ul>
<li><p>앞서 <code>주어진 로또 번호에서 0의 개수를 구하여 위에서 구한 일치한 당첨번호 개수와 더한 뒤 최대 당첨 번호의 개수를 구한다.</code>, <code>0의 개수를 더하지 않은 개수는 최저 당첨 개수이다.</code>의 부분을 하나의 for문으로 처리하였다.</p>
</li>
<li><p>최대 등수와 최저 등수의 로직을 동일하게 구현하여 가독성을 높혔다.</p>
</li>
</ul>
<br>
<br>

<h2 id="2-통용적인-해결-패턴이-있는-경우">2. 통용적인 해결 패턴이 있는 경우</h2>
<h4 id="grid-dfs-bfs-divide-and-conquer-dijkstra-등등-통용적인-해결-패턴이-있는-경우">Grid, DFS, BFS, Divide And Conquer, Dijkstra 등등 통용적인 해결 패턴이 있는 경우</h4>
<pre><code>=&gt; 관련 문제를 많이 풀고 알고리즘을 이해하는 노력이 필요하다.</code></pre><br>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[Modern Javascipt (깊은복사, 얕은복사)]]></title>
            <link>https://velog.io/@dev-yun/Modern-Javascipt-%EA%B9%8A%EC%9D%80%EB%B3%B5%EC%82%AC-%EC%96%95%EC%9D%80%EB%B3%B5%EC%82%AC</link>
            <guid>https://velog.io/@dev-yun/Modern-Javascipt-%EA%B9%8A%EC%9D%80%EB%B3%B5%EC%82%AC-%EC%96%95%EC%9D%80%EB%B3%B5%EC%82%AC</guid>
            <pubDate>Sun, 17 Apr 2022 16:42:25 GMT</pubDate>
            <description><![CDATA[<h2 id="자료형">자료형</h2>
<p>Javascript에서 자료형(Data Type)은 기본형과 참조형 두가지로 나눌 수 있습니다.
앞서 작성한 <a href="https://velog.io/@dev-yun/%EC%BD%94%EC%96%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-1" target="_blank" rel="noreferrer noopener">데이터 타입</a>에서 자세히 다뤘으니 간단하게 짚고 넘어가겠습니다.</p>
<p>기본형(Primitive Data Type)의 특징과 종류</p>
<ul>
<li>한번에 하나의 값 만 가질 수 있습니다. </li>
<li>하나의 고정된 메모리 공간을 이용합니다. </li>
<li>종류에는 Number, String, Boolean, Undefined, Null 등이 있습니다.</li>
</ul>
<p>참조형(Non-Primitive DataType)의 특징과 종류 </p>
<ul>
<li>한번에 여러 값을 갖을 수 있습니다.</li>
<li>여러개의 고정되지 않은 동적인 메모리 공간을 이용합니다.</li>
<li>종류에는 Object, Array, Function 등이 있습니다.</li>
</ul>
<hr>
<h1 id="얕은-복사">얕은 복사</h1>
<p>얕은 복사는 참조형에서만 발생하며 참조형의 <strong>프로퍼티들이 담긴 주소를 복사</strong>합니다.</p>
<p>즉 <strong>&#39;값을 담은 주소&#39;</strong>를 복사해서 <strong>&#39;값&#39;</strong>이 변해도 <strong>&#39;값을 담은 주소&#39;</strong>는 그대로이므로 원본데이터와 복사한데이터의 값이 같이 변합니다. </p>
<p><img src="https://velog.velcdn.com/images/dev-yun/post/0dc09486-18f8-49ea-88fe-3aa836c57024/image.png" alt=""></p>
<p>그림으로 설명하면 <code>obj2 = obj1</code>에서 <code>obj2</code>는 <code>obj1</code>의 프로퍼티들이 담긴 주소 @2000~을 가리키는 <strong>주소</strong> @1000을 복사합니다.</p>
<pre><code class="language-javascript">let obj1 = {
  a : 10,
  b : &#39;abc&#39;
};
obj2 = obj1

console.log(obj2 === obj1)         // true
console.log(obj2.a === obj1.a)     //true

obj2.a = 20;
console.log(obj1.a)             // 20</code></pre>
<p>때문에 복사한<code>obj2</code>의 프로퍼티를 변경하면 <code>obj1</code>의 프로퍼티도 변하고,
<code>obj2</code>와 <code>obj1</code>을 비교하면 같다고 나옵니다.</p>
<p>이렇게 복사한 값이 원본 데이터를 변경하면 매우 큰 문제가 발생할 수 있으므로 상황에 따라 깊은 복사를 사용해야 합니다.</p>
<hr>
<h1 id="깊은-복사">깊은 복사</h1>
<p>깊은 복사는 기본형과 참조형에서 약간 다르게 복사해야합니다.</p>
<p>기본형에서는 값에 직접 연결된 주소를 복사하므로 그 자체가 깊은 복사입니다.
참조형에서는 <strong>&#39;값을 담은 주소&#39;</strong>를 원본데이터와 다른 메모리 주소로 복사해야합니다.</p>
<blockquote>
<p>Javascript에서는 값을 서로 다른 새로운 값으로 재할당하면 새로운 메모리 주소로 배치합니다. (같은 값은 같은 주소를 사용함) </p>
</blockquote>
<h2 id="기본형의-깊은-복사">기본형의 깊은 복사</h2>
<p>기본적으로 기본형 데이터타입의 복사는 깊은 복사를 합니다.</p>
<p><img src="https://velog.velcdn.com/images/dev-yun/post/1419d0a7-b279-4dad-9d85-be125bb1f2e6/image.png" alt=""></p>
<p>그림을 살펴보면 <code>a</code>를 복사한 <code>b</code>는 값 100을 가리키는 주소 @1001을 복사합니다.
즉 값(100)의 주소(@1001)를 복사합니다.</p>
<pre><code class="language-javascript">let a = 100;
b = a;

console.log(a === b);     // true
b = 200;

console.log(a);            // 100
console.log(a === b);     // false</code></pre>
<p>그리고 기본형은 값의 주소를 복사할 경우 식별자에 새로운 값을 할당할 시 새로운 값의 주소를 메모리에 연결합니다.</p>
<h2 id="참조형의-깊은-복사">참조형의 깊은 복사</h2>
<p>이제 중요한 참조형의 깊은 복사를 알아보겠습니다.</p>
<p><strong>이론적으로</strong> 얕은 복사에서 원본 참조형과 복사된 참조형이 같이 변경되는 이유는 같은 주소값을 바라보기 때문입니다.</p>
<p>즉, 간단하게 생각하면 같은 <strong>값을 담은 주소값</strong>(아래 그림에선 @1000)를 참조하지 않으면 됩니다.
<img src="https://velog.velcdn.com/images/dev-yun/post/125a495d-3649-467d-b5fb-ea10200b4d15/image.png" alt="">
그림에선 <code>obj1</code>과 <code>obj2</code>가 서로 다른 주소값을 가리킵니다.</p>
<p>이때 <code>obj2.a</code>의 값을 변경하면 아래 그림처럼 <code>obj1.a</code>의 값은 변하지 않게 됩니다. </p>
<p><img src="https://velog.velcdn.com/images/dev-yun/post/c5889284-2ffa-4afd-af74-4c0dc6ff2f5b/image.png" alt=""></p>
<p>이러한 생각을 갖고 참조형의 여러 깊은 복사를 살펴보겠습니다.</p>
<h3 id="직접-재귀-함수를-통해-깊은-복사-함수-구현">직접 재귀 함수를 통해 깊은 복사 함수 구현</h3>
<p>위의 이론을 토대로 직접 깊은 복사를 구현해보겠습니다.</p>
<pre><code class="language-javascript">const copyObjectDeep = (obj) =&gt; {
  if(obj === null || typeof obj !== &quot;object&quot;){
    return obj;
  }

  let copyResult = {}
  for (let prop in obj){
    copyResult[prop] = copyObjectDeep(obj[prop]);
  }
  return copyResult;
}

const obj = {
  a: 10, 
  b: {
      c: null,
    d: [1, 2]
  },
};
const obj2 = copyObjctDeep(obj);
console.log(obj === obj2)     // false

obj2.a = 1000;
console.log(obj, obj2);     // {a: 10, b: {…}} {a: 1000, b: {…}}

obj2.b.c = 200;
console.log(obj.b, obj2.b);    // {c: null, d: Array(2)} {c: 200, d: {…}}</code></pre>
<p>앞선 이론처럼 재귀함수를 통해 원본 객체 <code>obj</code>의 모든 프로퍼티를 복사하여 새로운 객체 <code>result</code>에 넣었습니다. </p>
<p>즉, 완전히 다른 주소를 참조하는 깊은 복사를 하였습니다.</p>
<p>때문에 복사된 <code>obj2</code>의 프로퍼티를 변경해도 원본 객체에 영향을 주지 않습니다.</p>
<h3 id="json를-활용한-깊은-복사">JSON를 활용한 깊은 복사</h3>
<p>원리는 객체를 JSON.stringify() 메서드로 문자열로 전환했다가 
다시 JSON.parse() 메서드를 통해 문자열을 객체로 변환하는 것입니다.</p>
<p>이렇게 하면 기존과 값만 같을 뿐 새로운 주소를 갖게되므로 
이론상 깊은 복사를 합니다.</p>
<pre><code class="language-javascript">const copyObjectUsingJSON = (obj) =&gt; {
  return JSON.parse(JSON.stringify(obj));
}

const obj = {
  a: 10, 
  b: {
      c: null,
    func1 : function () { console.log(&quot;함수&quot;); },
  },
  func2 : function () { console.log(&quot;함수2&quot;); },
};

const obj2 = copyObjectUsingJSON(obj);
console.log(obj === obj2)     // false

obj2.a = 1000;
console.log(obj, obj2);     // {a: 10, b: {…}} {a: 1000, b: {…}, func2: f}

obj2.b.c = 200;
console.log(obj.b, obj2.b);    // {c: null, func1: ƒ} {c: 200}</code></pre>
<p>JSON을 사용해 깊은 복사를 사용하는 것은 몇가지 주의사항이 있습니다.</p>
<ol>
<li><p>function, _<em>proto_</em>, getter/setter 같이 JSON으로 변경 불가능한 프로퍼티는 모두 무시합니다.</p>
</li>
<li><p>다른 방법에 비해 처리 속도가 느립니다.</p>
</li>
</ol>
<h3 id="spread-연산자를-사용한-깊은-복사">spread 연산자를 사용한 깊은 복사</h3>
<p>spread 연산자 <code>...obj</code>를 사용해도 참조형의 깊은 복사를 할 수 있습니다.</p>
<pre><code class="language-javascript">const obj = {
  a: 10, 
  b: {
      c: null,
    func1 : function () { console.log(&quot;함수&quot;); },
  },
};

const obj2 = {...obj};
console.log(obj === obj2)     // false

obj2.a = 1000;
console.log(obj, obj2);        // {a: 10, b: {…}} {a: 1000, b: {…}} 

obj2.b.c = 200;
console.log(obj.b, obj2.b); // {c: 200, func1: ƒ} {c: 200, func1: ƒ}</code></pre>
<p>spread 연산자를 사용하면 매우 간단하게 깊은 복사를 할 수 있지만</p>
<p>예제코드에서도 확인할 수 있듯이 큰 문제점이 있습니다.
<strong>spread 연산자를 통한 깊은 복사는 중첩된 객체에서는 얕은 복사를 한다는 점 입니다.</strong></p>
<p>때문에 상황에 맞게 잘 사용해야 합니다.</p>
<h3 id="lodash-모듈의-clonedeep을-사용한-깊은-복사">lodash 모듈의 cloneDeep을 사용한 깊은 복사</h3>
<blockquote>
<p>직접 구현하기엔 귀찮고,
JSON을 사용하기엔 function같은 자료형을 복사하지 못하고,
spread 연산자를 사용하자니 중첩 객체를 깊은 복사하지 못합니다.</p>
</blockquote>
<p>이런 우리를 위해 나온 좋은 모듈이 있습니다.
<code>lodash</code> 모듈의 <code>cloneDeep()</code> 메서드를 활용하면 됩니다.</p>
<pre><code class="language-node.js">// 먼저 lodash 모듈을 설치해줍니다.
&amp; npm i lodash</code></pre>
<pre><code class="language-javascript">const lodash = require(&quot;lodash&quot;);

const obj = {
  a: 10, 
  b: {
      c: null,
    func1 : function () { console.log(&quot;함수&quot;); },
  },
};

const obj2 = lodash.cloneDeep(obj);
console.log(obj === obj2)     // false

obj2.a = 1000;
console.log(obj, obj2);        // {a: 10, b: {…}} {a: 1000, b: {…}} 

obj2.b.c = 200;
console.log(obj.b, obj2.b); // {c: null, func1: ƒ} {c: 200, func1: ƒ}</code></pre>
<p>지금까지 알아본 방법 중 가장 간단하고 단점이 없는 방법인 것 같습니다.</p>
<p>깊은 복사를 하려면 lodash를 사용해야할 듯 합니다.!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Modern Javascipt (배열 내장 함수)]]></title>
            <link>https://velog.io/@dev-yun/Modern-Javascipt-%EB%B0%B0%EC%97%B4-%EB%82%B4%EC%9E%A5-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@dev-yun/Modern-Javascipt-%EB%B0%B0%EC%97%B4-%EB%82%B4%EC%9E%A5-%ED%95%A8%EC%88%98</guid>
            <pubDate>Fri, 15 Apr 2022 10:20:47 GMT</pubDate>
            <description><![CDATA[<p>이번에는 자주 사용하는 배열 내장 함수를 정리해보겠습니다.</p>
<h3 id="foreach">forEach</h3>
<p>forEach : 배열을 순회하는 간단한 내장함수</p>
<pre><code class="language-javascript">const array = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;];

array.forEach((param) =&gt; console.log(param)); // a, b, c, d</code></pre>
<p>내장함수 forEach는 push, pop, shift, unshift 등을 함께 사용하여 더 유용하게 사용할 수 있습니다.</p>
<pre><code class="language-javascript">const array = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;];
const newArray = [];

array.forEach((param) =&gt; newArray.push(param + param));

console.log(newArray);  // [&#39;aa&#39;, &#39;bb&#39;, &#39;cc&#39;, &#39;dd&#39;]</code></pre>
<br>

<h3 id="map">map</h3>
<p>map : 원본 배열을 순환하며 각각 모든 요소마다 콜백함수를 실행하고 <strong>return값을 반환</strong></p>
<p>forEach와 비슷하지만 return을 반환하기 때문에 변수에 대입을 할 수 있습니다.</p>
<pre><code class="language-javascript">const array = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;];

const newArray = array.map((param) =&gt; {return param + param + param;})

console.log(newArray); // [&#39;aaa&#39;, &#39;bbb&#39;, &#39;ccc&#39;, &#39;ddd&#39;]</code></pre>
<br>

<h3 id="includes">includes</h3>
<p>includes : 임의의 값이 주어진 배열에 존재하는지 판단 (true, false)</p>
<pre><code class="language-javascript">const array = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;];
let str = &quot;b&quot;;

console.log(array.includes(str));    // true</code></pre>
<br>

<h3 id="indexof">indexOf</h3>
<p>indexOf : 임의의 값이 주어진 배열의 몇번째에 존재하는지 반환. (없으면 -1)</p>
<blockquote>
<p>indexOf가 첫번째값 즉, 0을 반환시 False처리가 되는 경우가 있어 (0은 falsy)
이를 보완하기 위해 includes가 등장하였습니다.</p>
</blockquote>
<pre><code class="language-javascript">const array = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;];
let str = &quot;b&quot;;

console.log(array.indexOf(str));    // 1</code></pre>
<br>

<h3 id="findindex">findIndex</h3>
<p>findIndex : 조건에 맞는 배열의 <strong>인덱스 번호</strong>를 반환</p>
<pre><code class="language-javascript">const arrObj = [
  {color : &quot;red&quot;},
  {color : &quot;blue&quot;},
  {color : &quot;green&quot;},
  {color : &quot;pink&quot;},
  {color : &quot;blue&quot;}
]

console.log(arrObj.findIndex((value) =&gt; { 
  return value.color === &quot;pink&quot;;    // 3
}));</code></pre>
<br>

<h3 id="find">find</h3>
<p>find : 조건에 맞는 배열의 요소를 반환</p>
<pre><code class="language-javascript">const arrObj = [
  {color : &quot;red&quot;},
  {color : &quot;blue&quot;},
  {color : &quot;green&quot;},
  {color : &quot;pink&quot;},
  {color : &quot;blue&quot;}
]

console.log(arrObj.find((value) =&gt; {
  return value.color === &quot;pink&quot;;    // {color : pink}
}));</code></pre>
<br>

<h3 id="filter">filter</h3>
<p>filter : 조건에 따라 배열내에서 <strong>true를 반환</strong>하는 모든 요소 반환</p>
<pre><code class="language-javascript">const arrObj = [
  {color : &quot;red&quot;},
  {color : &quot;blue&quot;},
  {color : &quot;green&quot;},
  {color : &quot;pink&quot;},
  {color : &quot;blue&quot;}
]

console.log(arrObj.filter((value) =&gt; value.color === &quot;blue&quot;))    // [{color: &#39;blue&#39;}, {color: &#39;blue&#39;}]</code></pre>
<br>

<h3 id="slice">slice</h3>
<p>slice : 조건에 맞게 배열의 요소를 자르는 메서드</p>
<pre><code class="language-javascript">const arrObj = [
  {color : &quot;red&quot;},
  {color : &quot;blue&quot;},
  {color : &quot;green&quot;},
  {color : &quot;pink&quot;},
  {color : &quot;blue&quot;}
]

console.log(arrObj.slice(0,3));    [{color: &#39;red&#39;}, {color: &#39;blue&#39;}, {color: &quot;green&quot;}]</code></pre>
<br>

<h3 id="concat">concat</h3>
<p>concat : 두개의 배열을 합치는 메서드</p>
<pre><code class="language-javascript">const array = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;]
const arrObj = [
  {color : &quot;red&quot;},
  {color : &quot;blue&quot;},
  {color : &quot;green&quot;},
  {color : &quot;pink&quot;},
  {color : &quot;blue&quot;}
]

console.log(array.concat(arrObj)); // [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, {…}, {…}, {…}, {…}, {…}]</code></pre>
<br>

<h3 id="sort">sort</h3>
<p>sort : 원본 배열의 순서를 사전순으로 정렬</p>
<pre><code class="language-javascript">const engs = [&#39;d&#39;, &#39;e&#39;, &#39;a&#39;, &#39;c&#39;, &#39;b&#39;];

engs.sort();

console.log(engs);  //[&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;]</code></pre>
<p>하지만 숫자를 정렬할 시 숫자를 문자로 취급하여 1, 12, 2, 233, 3 처럼 정렬합니다.</p>
<pre><code class="language-javascript">const numbers = [3,124,23,5,46,345,32,12,3,41,24,2];

numbers.sort();

console.log(numbers); //[12, 124, 2, 23, 24, 3, 3, 32, 345, 41, 46, 5]

// 때문에 비교함수를 만드는 사전 작업이 필요함
const compare = (num1 , num2) =&gt; {
  if (num1 &gt; num2){
    // numb1 이 num2 보다 크다면 num1을 num2보다 뒤로 보냄
    return 1;   
  };
  if (num1 &lt; num2){
    // numb1 이 num2 보다 작다면 num1을 num2보다 앞으로 보냄
    return -1;
  };
  return 0;
};
numbers.sort(compare);
console.log(numbers);   //[2, 3, 3, 5, 12, 23, 24, 32, 41, 46, 124, 345]</code></pre>
<br>

<h3 id="join">join</h3>
<p>join : 배열의 값을 이어서 출력해주는 메서드</p>
<pre><code class="language-javascript">const strings = [&quot;안녕하세요&quot;, &quot;자바스크립트&quot;, &quot;es6&quot;, &quot;이후&quot;, &quot;공부중입니다.&quot;];

console.log(strings.join(&quot; &quot;)); // 안녕하세요 자바스크립트 es6 이후 공부중입니다.</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Modern Javascipt (화살표 함수)]]></title>
            <link>https://velog.io/@dev-yun/Modern-Javascipt-%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@dev-yun/Modern-Javascipt-%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98</guid>
            <pubDate>Fri, 15 Apr 2022 09:39:50 GMT</pubDate>
            <description><![CDATA[<h2 id="함수의-3가지-표현-방법">함수의 3가지 표현 방법</h2>
<ol>
<li><p>함수 선언문
<code>function func1() {}</code></p>
</li>
<li><p>(익명) 함수 표현식
<code>const func2 = function() {};</code></p>
</li>
<li><p>화살표 함수
<code>const func3 = () =&gt; {};</code></p>
</li>
</ol>
<p>함수 선언문과 함수 표현식은 앞서 <a href="https://velog.io/@dev-yun/%EC%BD%94%EC%96%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-2" target="_blank">코어 자바스크립트</a>책에서 정리한 적이 있으므로 <code>화살표함수</code>에 대해 알아보겠습니다.
<br></p>
<h2 id="화살표-함수의-특징">화살표 함수의 특징</h2>
<p><strong><div style ="font-size:22px"> 1. 화살표 함수는 항상 익명입니다. </div></strong></p>
<p>화살표 함수는 항상 익명이기 때문에 재사용하기 위해선 <code>함수 표현식</code> 방식으로 작성해야합니다.</p>
<p>하지만 재사용을 하지 않는 경우 <code>함수 선언문</code>방식 으로도 작성할 수 있습니다. </p>
<p>때문에 용도에 맞춰 두가지 방식의 사용법을 알아보겠습니다.
<br>
<strong>1. 화살표함수를 재사용할 경우</strong> 
<code>var/let/const 함수명 = (매개변수) =&gt; {실행문}</code></p>
<pre><code class="language-javascript">// 기본형
const func1 = (a, b) =&gt; { return console.log(a,b) };

// 매개변수가 1개인 경우 () 생략가능
const func2 = a =&gt; { return console.log(a) };

// 1개의 실행문만 갖는 경우 {} 생략가능
const func3 = (a, b) =&gt; console.log(a,b);</code></pre>
<p>이 경우에는 함수명을 통해 화살표 함수를 불러와 재사용할 수 있습니다.</p>
<br>

<p><strong>2. 화살표 함수를 재사용하지 않을경우</strong></p>
<p>기본적으로 화살표 함수를 단독으로 <code>함수 선언문</code>방식으로 사용할 순 없습니다.</p>
<pre><code class="language-javascript">function (a,b) =&gt; { return console.log(a,b); };  // Uncaught SyntaxError: Function statements require a function name</code></pre>
<p>오류 메세지에 나와있듯 function name이 필요하기 때문입니다.
<br></p>
<p>하지만 재사용이 필요하지 않은 콜백함수에 사용할 경우 유용하게 사용할 수 있습니다.</p>
<pre><code class="language-javascript">const array = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;];

array.forEach((value) =&gt; console.log(value + value)); // aa bb cc</code></pre>
<p>만약 화살표 함수를 사용하지 않고 함수 선언문으로 작성할 경우</p>
<pre><code class="language-javascript">const array = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;];

array.forEach(function (value) {
  console.log(value + value);
}); // aa bb cc</code></pre>
<p>이처럼 코드의 가독성이 떨어지게됩니다. (간단한 예제라 별 차이가 없지만 긴 코드에서는 더 복잡해집니다.)</p>
<br>

<p><strong>3. 화살표 함수 사용할 수 없는 경우</strong></p>
<ol>
<li><p>객체의 메소드를 정의하는 경우(사용할 순 있지만 권장하지 않음)
<code>화살표 함수는 자신의 this를 가지고(&quot;bind&quot; 바인드)있지 않습니다.</code> (아래 자세히 설명)</p>
</li>
<li><p>prototype에 메소드를 할당하는 경우
<code>화살표 함수는 prototype 속성이 없습니다.</code></p>
<pre><code class="language-javascript">var Foo = () =&gt; {};
var foo = new Foo(); // TypeError: Foo is not a constructor</code></pre>
</li>
<li><p>생성자 함수로 사용하는 경우
<code>화살표 함수는 생성자로서 사용될 수 없으며 new와 함께 사용하면 오류가 발생합니다.</code></p>
<pre><code class="language-javascript">var Foo = () =&gt; {};
var foo = new Foo(); // TypeError: Foo is not a constructor</code></pre>
</li>
</ol>
<p>==&gt; <a href="https://velog.io/@raram2/%ED%99%94%EC%82%B4%ED%91%9C-%ED%95%A8%EC%88%98%EB%A5%BC-%EB%82%A8%EC%9A%A9%ED%95%98%EB%A9%B4-%EC%95%88%EB%90%98%EB%8A%94-%EC%9D%B4%EC%9C%A0">화살표 함수를 사용할때 자주 하는 실수를 잘 정리한 블로그</a></p>
<br>


<h2 id="화살표-함수의-this">화살표 함수의 this</h2>
<p>일반 함수나 메서드는 자신이 호출될때 생성된 실행 컨텍스트에 <a href="https://velog.io/@dev-yun/%EC%BD%94%EC%96%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-3" target="_blank">this binding</a> 정보를 생성합니다.</p>
<p>하지만 화살표 함수는 호출될때 this binding을 하지 않습니다. 쉽게말하면 누가 자기를 호출한지 알지 못합니다.</p>
<p>때문에 화살표함수는 자체적으로 호출되는 시점과 무관하게 <strong>화살표 함수가 선언되어 있는 실행 콘텍스트가 참조하는 thisBinding 정보</strong>를 참조합니다. </p>
<p>즉, 항상 자신의 상위 스코프의 this를 가리키는 것입니다.</p>
<p>예제를 통해 살펴보겠습니다.</p>
<pre><code class="language-javascript">// 일반 함수로 작성한 메서드
var name = &#39;yun&#39;;
var info = {
    name : &#39;kim&#39;,
    getName : function(){
        console.log(this.name);
    },
};
info.getName();     // &#39;kim&#39;
// .을 기준으로 getName의 상위 스코프인 info를 this로 바인딩하여 &#39;kim&#39;이 출력된다.</code></pre>
<br>

<pre><code class="language-javascript">var name2 = &#39;yun&#39;;
var info2 = {
    name2 : &#39;kim&#39;,
    getName: () =&gt; console.log(this.name),
};
info2.getName();     // &#39;yun&#39;
// this가 정적으로 바인딩되어 info의 상위 스코프인 window를 가리키고 &#39;yun&#39;이 출력된다.</code></pre>
<br>

<p>메서드로 화살표함수를 사용한 두번째 예제는 화살표함수가 선언되어 있는 실행 컨텍스트 ==&gt; <strong>즉, info2의 실행 컨텍스트의 this를 가리킵니다.</strong></p>
<p>때문에 info2의 상위 스코프인 window를 this가 가리키고 window.name인 &#39;yun&#39;이 호출됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Modern Javascipt  (const, let, var)]]></title>
            <link>https://velog.io/@dev-yun/Modern-Javascipt-const-let-var</link>
            <guid>https://velog.io/@dev-yun/Modern-Javascipt-const-let-var</guid>
            <pubDate>Mon, 14 Mar 2022 09:50:10 GMT</pubDate>
            <description><![CDATA[<h1 id="const-let을-사용하는-이유">const, let을 사용하는 이유</h1>
<p>블록 레벨 스코프, 함수 레벨 스코프, 호이스팅 등의 차이를 알아보기 이전에 코드를 작성할 때 왜 const와 let을 사용하는지 배워보겠습니다.</p>
<h2 id="const를-사용하는-이유">const를 사용하는 이유</h2>
<p>결론부터 말하자면 <strong>대부분의 경우에 const를 사용하는 것이 좋습니다.</strong> </p>
<p>const는 가장 많은 제약이 있고 이는 코드를 쉽게 이해할 수 있게 만듭니다.</p>
<blockquote>
<p>왜 가장 기능이 적은 const가 코드를 쉽게 만든다는 것 일까요?</p>
</blockquote>
<p>한번 값을 할당하면 재할당이 불가능하다는 const의 성질은 코드를 훑어보는 개발자가 <strong>const로 선언된 변수</strong>를 신경쓰지 않도록 만듭니다.</p>
<p>두가지 예제를 살펴보겠습니다.</p>
<pre><code class="language-javascript">// var 선언
var salePercent = 0.2;
var totalPrice = 100 - (100 * salePercent);
// 200행의 코드 생략
return `총 구매 금액은 ${totalPrice}입니다.`;</code></pre>
<pre><code class="language-javascript">// const 선언
const salePercent = 0.2;
const totalPrice = 100 - (100 * salePercent);
// 200행의 코드 생략
return `총 구매 금액은 ${totalPrice}입니다.`;</code></pre>
<p>만약 var로 선언된 코드를 읽는다면 생략된 200줄의 코드에서 salePercent가 변경되는 부분이 있는지 꼼꼼히 읽어봐야합니다.</p>
<p>하지만 salePercent가 const로 선언된다면 200줄의 코드에서 <strong>salePercent가 변경될 일이 없기 때문에</strong> 해당 변수는 신경쓰지 않아도 됩니다.</p>
<p>이러한 가독성과 코드의 이해력을 높히기 위해 재할당이 필요없는 변수는 const를 사용하길 권장합니다.</p>
<h3 id="const-사용시-주의사항">const 사용시 주의사항</h3>
<p>앞서 const는 재할당이 불가능한 변수라고 설명했습니다.
하지만 const에 할당된 값이 불변값이 되는 것은 아닙니다.</p>
<p>모순되는 말처럼 들릴 수 있지만 <a href="https://velog.io/@dev-yun/%EC%BD%94%EC%96%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-1">이전 데이터 할당 포스트를 보면 이해를 도울 수 있습니다.</a></p>
<p>기본적으로 자바스크립트는 배열이나 객체를 할당할때 <strong>객체나 배열의 프로퍼티의 주소</strong>를 변수에 할당하므로 
const로 선언한 변수 자체를 변경하는 것이 아닌 <strong>변수의 주소와 연결된 프로퍼티는 변경 가능</strong>한 것입니다.</p>
<p>조금 어려운 부분인데, 요약하자면 const에 배열 또는 객체를 선언할 경우 내부 프로퍼티는 변경 가능하기 때문에 const값을 확신할 수 없다는 것 입니다.</p>
<h2 id="let을-사용하는-이유">let을 사용하는 이유</h2>
<p>앞서 변수를 다룰 때는 재할당을 피하는 것이 낫다고 배웠습니다. 하지만 재할당이 필요할 경우 let을 사용해야 합니다.</p>
<p>var이 아닌 let을 사용하는 이유는 무엇일까요?</p>
<p>var은 함수 레벨 스코프, let은 블록 레벨 스코프이기 때문입니다. (<a href="https://velog.io/@dev-yun/%EC%BD%94%EC%96%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-2">스코프</a>에 관한 글)</p>
<p>왜 블록 레벨 스코프를 사용해야 하는지 예제를 통해 알아보겠습니다. </p>
<pre><code class="language-javascript">//var 사용
const item = {
    inventory: 3,
    price: 3,
    salePrice: 2,
    saleInventory: 0,
  };

function getLowestPrice(item) {
    var count = item.inventory;
    var price = item.price;

    if (item.salePrice) {
      var count = item.saleInventory;
      if (count &gt; 0) {
        price = item.salePrice;
      }
    }

    if (count) {
      return price;
    }

    return 0;
  }</code></pre>
<p>의도대로 함수 결과를 출력한다면 saleInventory가 0이므로 정상적인 가격 Price(2)를 출력해야 합니다.</p>
<p>하지만 var는 함수 레벨 스코프이므로 <code>var count = item.inventory;</code>의 count를 if문 내의 <code>var count = item.saleInventory;</code>에서 재할당합니다.</p>
<p>때문에 <code>if (count) { return price; }</code>에서 count를 0으로 인식하여 return 0을 반환한 것 입니다.</p>
<pre><code class="language-javascript">//let 사용
const item = {
    inventory: 3,
    price: 3,
    salePrice: 2,
    saleInventory: 0,
  };

function getLowestPrice(item) {
    let count = item.inventory;
    let price = item.price;

    if (item.salePrice) {
      let count = item.saleInventory;
      if (count &gt; 0) {
        price = item.salePrice;
      }
    }

    if (count) {
      return price;
    }

    return 0;
  }</code></pre>
<p>하지만 let을 사용하면 각각의 변수를 블록 레벨 스코프로 인식하여 <code>let count = item.inventory;</code>의 count와 <code>if (item.salePrice)</code> 내의 count와 다른 변수로 인식하여 앞서 생긴 버그를 해결합니다.</p>
<blockquote>
<p>블록 레벨 스코프에서는 내부 블록에서 외부 블록의 변수를 사용할 수 있지만, 외부 블록에서는 내부 블록의 변수에 접근할 수 없습니다.</p>
</blockquote>
<p>이 외에도 let은 유효범위 내에서 같은 변수명을 재사용할 수 없다는 장점도 있습니다.</p>
<h2 id="const-let-var의-차이점">const, let, var의 차이점</h2>
<p>앞서 const와 let을 사용하는 이유에서 몇몇 차이점을 언급했지만 다시 정리해보겠습니다.</p>
<ol>
<li><p>var은 함수 레벨 스코프이고 const,let은 블록 레벨 스코프입니다.</p>
</li>
<li><p>var은 유효범위 내에서 이미 선언한 변수명과 같은 변수를 선언할 수 있지만, let과 const는 이미 존재하는 변수와 똑같은 변수를 선언할 수 없습니다.</p>
</li>
<li><p>var와 let은 변수 선언시 초기 값을 할당하지 않아도 되지만 const는 항상 초기값을 할당하여 선언해야합니다.</p>
</li>
<li><p>var은 선언하고 값을 할당하기 전에 사용하면 undefined값을 반환하지만, const, let은 선언하고 값을 할당하기 전에 사용하면 에러를 발생시킵니다.(TDZ)</p>
</li>
<li><p>var, let은 할당된 값을 변경할 수 있지만 const는 할당된 값을 변경할 수 없습니다.(하지만 const가 배열또는 객체일 경우 내부 프로퍼티는 변경할 수 있습니다.)</p>
</li>
</ol>
<p>⁂ TDZ : Temporal Dead Zone의 약자로 var과 달리 let과 const는 호이스팅 시 자동으로 부여되는 초기값이 없어 TDZ구간에서 let과 const로 선언된 변수를 사용시 에러가 발생됩니다.</p>
<p>정리하자면 최대한 const변수를 사용하고 재할당이 필요한 경우 let을 사용합시다! (var은 안됩니다(˘･_･˘)) </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML, CSS (BEM)]]></title>
            <link>https://velog.io/@dev-yun/HTML-CSS-BEM</link>
            <guid>https://velog.io/@dev-yun/HTML-CSS-BEM</guid>
            <pubDate>Thu, 03 Mar 2022 15:14:57 GMT</pubDate>
            <description><![CDATA[<h2 id="bem이란">BEM이란?</h2>
<p>BEM(Block Element and Modifiers)은 클래스 이름을 짓는 규칙을 의미합니다.</p>
<p>좀더 쉽게 읽히는 CSS를 사용하기 위해 만들어진 규칙입니다.</p>
<p>🤔그렇다면 정확히 어떤 규칙을 의미하는것 일까요?</p>
<blockquote>
<p>이름에서 볼 수 있듯이 Block과 Element, Modifiers로 이루어진 이름을 짓는 규칙입니다.</p>
</blockquote>
<p>Block, Element, Modifiers로 이루어진 이름이라... 잘 감이 오지 않습니다.</p>
<p>우선 간단한 예제를 통해 알아보겠습니다.</p>
<pre><code class="language-html">&lt;style&gt;
  &lt;!--blcok--&gt;
  .btn {}

  &lt;!--Element : block에 속한 하위 element--&gt;
  .btn__text {}

  &lt;!--Modifiers : block에 속성을 부여하는 의미--&gt;
  .btn--big {}
  .btn--blue {}
&lt;/style&gt;

&lt;button class=&quot;btn btn--big btn--blue&quot;&gt;
  &lt;span class=&quot;btn__text&quot;&gt;
  &lt;/span&gt;
&lt;/button&gt;</code></pre>
<p>약간 예제를 보니 감이 오지 않나요?</p>
<ul>
<li><p>상위 블록은 평소대로 이름을 작성한다.</p>
</li>
<li><p>상위 블록에 속하는 하위 <code>element</code>는 <code>상위블록이름__element이름</code>으로 표현한다.</p>
</li>
<li><p>상위 블록의 속성들은 <code>상위블록이름--modifiers이름</code>으로 표현한다.</p>
</li>
</ul>
<p>간단하게 이렇게 정리할 수 있습니다.</p>
<h3 id="세부적인-규칙">세부적인 규칙</h3>
<p>위에서 전체적인 BEM의 규칙을 살펴봤습니다.</p>
<p>그런데 이외에도 세부적으로 알아야할 규칙들이 있습니다.</p>
<ol>
<li>상위 블록의 하위 <code>element</code>는 <strong>모두</strong> 상위 블록의 하위 <code>element</code>로 작성한다.</li>
</ol>
<p>이게 무슨말인가 싶기도 합니다.</p>
<p>예제를 보면 좀 더 쉽게 이해할 수 있습니다.</p>
<pre><code class="language-html">&lt;div class=&quot;first-block&quot;&gt;
  &lt;div class=&quot;first-block__first-element&quot;&gt;
    &lt;!--&lt;div class=&quot;first-block__first-element__second-element&gt; ==&gt; 틀린 표현입니다.--&gt;
    &lt;div class=&quot;first-block__second-element&quot;&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></pre>
<p>이처럼 상위 블록 내의 하위 <code>element</code>의 depth level이 다르더라도 모두 상위 블록의 직계 하위 <code>element</code>처럼 표현합니다.</p>
<hr>
<ol start="2">
<li>상위 블록의 내부에 정의된 class라도 상위 블록과 연관이 없다면 <code>element(__)</code>로 표현하지 않는다.</li>
</ol>
<pre><code class="language-html">&lt;div class=&quot;header&quot;&gt;
  &lt;div class=&quot;header__inner&quot;&gt;
    &lt;div class=&quot;tabzilla&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;header__logo&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;nav&quot;&gt;&lt;/div&gt;
    &lt;div class=&quot;header__search&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;</code></pre>
<p>모두 상위 block인 <code>header</code>에 묶인 element들입니다.</p>
<p>하지만 중간중간 <code>tabzilla</code>, <code>nav</code>가 눈에 띄네요</p>
<p>이들은 다른곳에도 쓰이는 <code>component CSS</code>라서 <code>element</code>가 아닌 <code>block</code>으로 취급하는것 같습니다.</p>
<p>이처럼 BEM을 사용하면</p>
<ol>
<li><p>클래스의 이름만으로 구조와 역할을 파악할 수 있습니다.</p>
</li>
<li><p>검색과 유지보수가 쉬워집니다.</p>
</li>
<li><p>중복으로 사용되는 <code>.div</code>, <code>.header</code>, <code>.main</code>등을 구분하지 않고 유니크한 클래스명으로 style을 작성할 수 있습니다.</p>
</li>
</ol>
<p>하지만 단점도 존재합니다.</p>
<ol>
<li><p><code>.btn</code> 하나를 <code>.btn--color</code>, <code>.btn--size</code>등으로 나누면 관리할 내용들이 많아집니다.</p>
</li>
<li><p><code>.first-block__second-element</code> 같이 클래스명이 매우 길어집니다.</p>
</li>
</ol>
<p><strong><a href="https://nykim.work/15">https://nykim.work/15</a></strong> ==&gt; BEM에 대해 정말 잘 정리된 블로그입니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML,CSS (transition, transform, animation)]]></title>
            <link>https://velog.io/@dev-yun/HTMLCSS-animation</link>
            <guid>https://velog.io/@dev-yun/HTMLCSS-animation</guid>
            <pubDate>Wed, 23 Feb 2022 15:08:55 GMT</pubDate>
            <description><![CDATA[<p>이전에는 페이지에 효과를 주기위해선 자바스크립트를 사용해야 했지만 CSS에서도 이를 가능하게 하는 방법이 생겼습니다.</p>
<p>이번에는 이 방법들에 대해 알아보겠습니다.</p>
<h2 id="transition">transition</h2>
<p>transition : 어떤 조건일때 특정 상태에서 다른 상태로 <strong>&quot;변화&quot;</strong> 시키는 <strong>방법을 컨트롤</strong>합니다.</p>
<p>기본 구조는 <code>transition : &quot;변화시킬 속성&quot; &quot;변화할 시간&quot; &quot;변환방식&quot;;</code> 입니다. </p>
<p>예제를 통해 알아보겠습니다.</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&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;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;style&gt;
        a{
            background-color: aqua;
            color: teal;
            font-size: 50px;
            border-radius: 10px;
            text-decoration: none;
        }

        a:hover{
            background-color: teal;
            color: aqua;
        }
    &lt;/style&gt;

    &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;a href=&quot;#&quot;&gt;
        Hover Button
    &lt;/a&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p><img src="https://images.velog.io/images/dev-yun/post/98ad7edb-6bba-4bf7-bd63-ee20d56bd887/2022-03-04%2011;00;04.gif" alt=""></p>
<p>이처럼 transition을 주지 않을 경우, hover 조건일때 a{} 상태에서 a:hover{} 상태로 <strong>효과 없이</strong> 변화하게 됩니다.</p>
<p>이제 transition을 적용한 경우를 살펴보겠습니다.</p>
<pre><code class="language-html">&lt;style&gt;
  a{
    background-color: aqua;
    color: teal;
    font-size: 50px;
    border-radius: 10px;
    text-decoration: none;

    transition: background-color 3s ease-in-out, color 3s ease-in-out;
  }

  a:hover{
    background-color: teal;
    color: aqua;
  }
&lt;/style&gt;</code></pre>
<p><img src="https://images.velog.io/images/dev-yun/post/c6b5f2c9-0e26-44d8-ba47-568d13e0ebb6/2022-03-04%2014;52;11.gif" alt=""></p>
<p>이처럼 transition을 사용하면 변화를 컨트롤할 수 있습니다.</p>
<p>transition의 몇가지 특별한 사용방법에 대해 알아보겠습니다.</p>
<ul>
<li><p><code>transition : all &quot;변화할 시간&quot; &quot;변환방식&quot;;</code>을 사용하여 변화되는 모든 속성을 선택할 수 있습니다.</p>
</li>
<li><p><code>transition : &quot;변화시킬 속성&quot; &quot;변화할 시간&quot; &quot;변환방식&quot;, &quot;변화시킬 속성&quot; &quot;변화할 시간&quot; &quot;변환방식&quot;, ...</code> 이처럼 쉼표를 사용해 계속해서 이어 붙일 수 있습니다.</p>
</li>
<li><p>transition은 state selector이 없는 곳에서 사용되어야 합니다. 
(예를 들면 .a:hover{}이 아닌 .a{}에 정의)</p>
</li>
</ul>
<p>ease-in-out같은 <code>&quot;변환방법&quot;</code>은 이미 정의된 방법을 사용할 수 있고, 사용자가 직접 비율을 지정하여 사용할 수 있습니다. </p>
<p><a href="https://matthewlein.com/tools/ceaser">이 사이트</a>에서 여러 변환 방법과 예제를 확인할 수 있습니다.</p>
<h2 id="transform">transform</h2>
<p>transform은 HTML 요소의 모양, 크기, 위치, 각도등을 자유롭게 변경시키는 속성입니다.</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&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;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;style&gt;
        img{
            width: 200px;
            height: 200px;
            border: 3px solid black;
            border-radius: 50%;
        }
        img:first-child{
            transform: translateX(-100px);
        }
        img:nth-child(2){
            transform: rotate(0.5turn);
        }
        img:nth-child(3){
            transform: scaleY(2);
        }
        img:nth-child(4){
            transform: skew(30deg, 20deg);
        }
    &lt;/style&gt;

    &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;img src=&quot;img/gugu.jpg&quot;&gt;
    &lt;img src=&quot;img/gugu.jpg&quot;&gt;
    &lt;img src=&quot;img/gugu.jpg&quot;&gt;
    &lt;img src=&quot;img/gugu.jpg&quot;&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p><img src="https://images.velog.io/images/dev-yun/post/c76061e9-6af0-49c5-971e-a89f50803670/image.png" alt=""></p>
<p>기본 이미지를 translate로 위치를 옮기거나
rotate로 돌리거나, scale로 늘리고 줄이거나, skew로 x, y각도로 기울일 수 있습니다.</p>
<hr>
<p>그런데 그냥 transform만 사용하면 약간 밋밋합니다. 
transition를 곁들이면 더 이쁜 효과를 만들 수 있을 것 같습니다.</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&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;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;style&gt;
        img{
            width: 200px;
            height: 200px;
            border: 3px solid black;
            border-radius: 50%;

            transition: transform 3s ease-in-out;
        }

        img:hover{
            transform: rotateX(0.5turn) translateX(400px);
        }
    &lt;/style&gt;

    &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;img src=&quot;img/gugu.jpg&quot;&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p><img src="https://images.velog.io/images/dev-yun/post/d6f3b647-0b4b-4d0c-b0fa-afd665528ad5/2022-03-04%2015;52;22.gif" alt=""></p>
<p>tranform과 transition을 같이 사용하니 그럴듯한 효과가 만들어졌습니다.
(rotateX가 회전을 저렇게 하는진 상상도 못했는데 과정을 보니 새롭게 느껴지네요 ..)</p>
<p>transform 효과는 매우 많은 종류가 있는데 
<a href="https://developer.mozilla.org/ko/docs/Web/CSS/transform">여기서</a> 또는 <a href="https://developer.mozilla.org/ko/docs/Web/CSS/transform-function">여기서</a>확인할 수 있습니다.</p>
<h2 id="animation">animation</h2>
<p>지금까지 배운것들이 다 animation같은데 또 따로 animation이라는 개념이 나왔습니다.</p>
<p>차이가 무엇일까요?</p>
<p>transition으로 만든 효과는 항상 특정 조건(:hover, :active...)일때만 실행됐습니다.</p>
<p>이번에 배워볼 animation은 이를 보완하여 우리가 원하는 만큼, 원할때 실행할 수 있도록 도와줍니다.</p>
<p>animation은 keyframes를 사용하여 만드는데 기본 구조는 아래와 같습니다.</p>
<pre><code class="language-html">@keyframes animation-name{
  from {
    설정 효과;
  }
  to {
    설정 효과;
  }
#또는 0% {} 25% {} 50% {} 75% {} 100% {} 등도 있습니다. 
}

.class{
  animation : animation-name &quot;설정 시간&quot; &quot;변환 효과&quot; &quot;변환 기간&quot;
}</code></pre>
<p>이제 실제로 animation을 사용한 예제를 살펴보겠습니다.</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&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;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;style&gt;
        img{
            width: 200px;
            height: 200px;
            border: 3px solid black;
            border-radius: 50%;

            animation : guImg 3s ease-in-out infinite;
        }

        @keyframes guImg {
            0%{
                transform : rotateY(0);
            }
            25% {
                transform: rotateY(0.25turn) scale(1.5);
                border-radius: 25%;
            }
            50% {
                transform: rotateY(0.5turn) scale(2);
                border-radius: 5%;
            }
            75% {
                transform: rotateY(0.25turn) scale(1.5);
                border-radius: 25%;
            }
            100% {
                transform: rotateY(0);
            }
        }
    &lt;/style&gt;

    &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;img src=&quot;img/gugu.jpg&quot;&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p><img src="https://images.velog.io/images/dev-yun/post/954410c5-4154-46ef-a037-128d6e3967c5/2022-03-04%2016;29;15.gif" alt=""></p>
<p>state selector을 사용하지 않아도 animation이 잘 작동하는 것을 확인할 수 있습니다.</p>
<p>이처럼 animation을 사용하는 이유와 예제도 살펴봤습니다.</p>
<p><a href="https://animista.net/">animation의 여러 방식을 소개한 사이트</a>인데 매우 유용하므로 필요하면 사용하시면 됩니다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML,CSS (custom property)]]></title>
            <link>https://velog.io/@dev-yun/HTMLCSS-custom-property</link>
            <guid>https://velog.io/@dev-yun/HTMLCSS-custom-property</guid>
            <pubDate>Tue, 22 Feb 2022 15:26:08 GMT</pubDate>
            <description><![CDATA[<h2 id="custom-property">custom property</h2>
<p>커스텀 속성(custom property)은 개발자가 정의한 속성의 집합입니다. </p>
<p>개발자는 임의로 정한 이름의 속성에 임의의 값을 할당할수 있습니다.</p>
<p>임의로 정한 이름에 임의의 값을 할당한다.. 많이 익숙한 것 같습니다.</p>
<p>맞습니다. 변수의 사용과 유사합니다. 
(임의의 이름은 변수명, 임의의 값은 변수의 값으로 생각할 수 있습니다.)</p>
<blockquote>
<p>즉 custom property는 CSS에서 변수를 사용할 수 있도록 만든 방법이라 생각하면 쉽습니다.</p>
</blockquote>
<h3 id="root">root{}</h3>
<p>custom property를 설명하기 전에 root{}라는 개념을 알고 가야합니다.</p>
<p>root{} 란 문서 트리에서 가장 상위 요소를 의미합니다.</p>
<p>따라서 모든 CSS 파일에 적용할 CSS변수는 :root{}내부에 정의해야 합니다.</p>
<p>사용 방법은 매우 간단합니다.</p>
<p>임의의 CSS파일(어떤곳이든)에 <code>:root{ }</code>를 사용하면 됩니다.</p>
<h3 id="custom-property-사용법">custom property 사용법</h3>
<p>앞서 custom property는 root{} 내부에 정의해야한다는 것을 배웠습니다.</p>
<p>이번엔 어떤식으로 정의하여 사용해야하는지 배워보겠습니다.</p>
<pre><code class="language-css">:root{
    --name : value;
}</code></pre>
<p>기본적인 구조는 예제처럼 구현됩니다.</p>
<ul>
<li><p>--name : 커스텀 속성의 이름은 <code>--</code>로 시작되며 <code>name</code>은 사용자가 임의로 정의합니다.</p>
</li>
<li><p>value : 커스텀 속성의 값은 css의 모든 속성 값(#24545a, flex, 10rem ...)이 들어갈 수 있습니다.</p>
</li>
</ul>
<hr>
<p>이제는 이렇게 :root{}에 구현한 custom property를 사용하는 방법을 알아보겠습니다.</p>
<pre><code class="language-css">:root{
  --yellow : #fae100;
}

.class-name{
    color : var(--yellow) tomato;
}</code></pre>
<p><code>color : var(--yellow) tomato</code>는 만약 root에서 --yellow가 정의되지 않았을 경우 tomato 색상을 정의하라는 의미로 예비속성을 주는 방법입니다.</p>
<p>custom property를 사용하는 이유</p>
<ol>
<li><p>중복된 height, width, margin.. 등의 값에 이름을 정의하여 알아보기 쉽게할 수 있고, 한번에 변경 가능하여 유지보수에 이점이 있습니다.</p>
</li>
<li><p>예제처럼 #fae100 같은 색상에 이름을 부여하므로서 더 가독성과 일관성을 높힐 수 있습니다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML,CSS (selectors)]]></title>
            <link>https://velog.io/@dev-yun/HTMLCSS-selectors</link>
            <guid>https://velog.io/@dev-yun/HTMLCSS-selectors</guid>
            <pubDate>Tue, 22 Feb 2022 15:20:28 GMT</pubDate>
            <description><![CDATA[<h2 id="pseudo-selectors">pseudo selectors</h2>
<p>가상선택자(pseudo selector) 직접 id, class, tag를 사용하지 않고 세부적으로 엘리먼트를 선택하는 방법입니다.</p>
<p>정의를 봤을때 pseudo selector가 어떤것인지 와닿지 않아 몇가지 예제를 통해 알아보겠습니다.</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&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;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div&gt;1&lt;/div&gt;
    &lt;div&gt;2&lt;/div&gt;
    &lt;div&gt;3&lt;/div&gt;
    &lt;div&gt;4&lt;/div&gt;
    &lt;div&gt;5&lt;/div&gt;
    &lt;div&gt;6&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>예제에서 여러 div태그들을 개별적으로 다루기 위해선 어떻게 해야할까요?</p>
<ol>
<li>div마다 id를 정의하고 css에서 style을 적용한다.</li>
<li>div마다 class를 정의하고 css에서 style을 적용한다. </li>
</ol>
<p>이런 방식이 있습니다.</p>
<p>하지만 매번 하나의 태그마다 하나의 id나 class를 부여하는 것은 매우 비효율적입니다. </p>
<p>이때 pseudo selector을 사용할 수 있습니다.</p>
<pre><code class="language-html">&lt;style&gt;
    div:first-child{
            background-color: aqua;
    }
    div:nth-child(2n){
          background-color: tomato;
    }
&lt;/style&gt;</code></pre>
<p><img src="https://images.velog.io/images/dev-yun/post/c78b11ef-1cfa-4c6e-ad86-ab7064e42666/image.png" alt=""></p>
<p>이렇게 pseudo selector을 사용하여 특정 엘리먼트를 선택하여 style을 적용할 수 있습니다.
(first:child, nth:child() 이외에도 수많은 pseudo selector이 있고 모두 외울필요는 없습니다!)</p>
<p><a href="https://developer.mozilla.org/ko/docs/Web/CSS/Pseudo-classes">pseudo selector MDN</a> ==&gt; pseudo selector의 종류와 기능들을 알아보기 좋은 사이트입니다.</p>
<h2 id="state-selectors">state selectors</h2>
<p>state selectors도 위에서 설명한 가상선택자(pseudo selectors)의 한 종류입니다.</p>
<p>하지만 따로 설명하는 이유는 그만큼 많이 사용하기 때문이고 약간의 특이점이 있기 때문입니다.</p>
<p>F12를 통해 개발자도구를 들어가 확인해보면 Force element state라는 녀석들이 따로 존재합니다.
<img src="https://images.velog.io/images/dev-yun/post/68902475-6064-4024-8614-48fca5beee80/image.png" alt=""></p>
<p>이 친구들은 css 이벤트에서 발생하는 element들입니다.</p>
<p>pseudo selectors로도 이 state selectors들을 제어할 수 있습니다.</p>
<p>자주 사용하는 state selectors</p>
<ul>
<li><a href="https://developer.mozilla.org/ko/docs/Web/CSS/:active">:active</a> : 보통 버튼과 링크에 사용되며 element가 활성화될때 지정된 style을 반환합니다. (&#39;활성&#39; 이란 마우스를 사용하는 경우 눌렀을때부터 ~ 떼는 시점까지를 의미)</li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/CSS/:hover">:hover</a> : 포인팅장치(마우스)를 사용해 마우스가 해당 element의 위에 존재할 경우 지정된 style을 반환합니다.</li>
<li><a href="https://developer.mozilla.org/ko/docs/Web/CSS/:focus">:focus</a> : 클릭하여 대상을 지정한 동안 style을 반환합니다. </li>
</ul>
<p>state selectors도 pseudo selectors의 일부이므로 <a href="https://developer.mozilla.org/ko/docs/Web/CSS/Pseudo-classes">MDN</a>에서 자세한 태그와 예제를 확인할 수 있습니다.</p>
<h2 id="attribute-selectors">attribute selectors</h2>
<p>특성 선택자(attribute selectors)는 id나 class가 아닌 <strong>속성값을 통해</strong> 특정 element를 선택하는 방법입니다.</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&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;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=&quot;#&quot;&gt;
        &lt;input type=&quot;text&quot; required placeholder=&quot;id&quot;&gt;
        &lt;input type=&quot;password&quot; placeholder=&quot;password&quot;&gt;
        &lt;input type=&quot;button&quot; value=&quot;submit&quot;&gt;    
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<pre><code class="language-html">&lt;style&gt;
    input:required{
        background-color: tomato;
    }
    input[type=&quot;password&quot;]{
        background-color: aqua;
    }
&lt;/style&gt;</code></pre>
<p><img src="https://images.velog.io/images/dev-yun/post/63502100-655a-48e6-8f94-420dd1c69069/image.png" alt=""></p>
<p>이처럼 id나 class가 아닌 속성값들을 통해 style을 지정하는 방법이 attribute selectors입니다.</p>
<p>관련 MDN 주소 : <a href="https://developer.mozilla.org/ko/docs/Web/CSS/Attribute_selectors">https://developer.mozilla.org/ko/docs/Web/CSS/Attribute_selectors</a></p>
<h2 id="combinators">combinators</h2>
<p>연결자 혹은 결합자로 불리는 combinators는 <strong>선택자(selectors)들 사이의 관계를 설명</strong>하는 역할을 합니다.</p>
<p>combinators의 종류는 4가지가 있습니다.</p>
<ol>
<li><p>자손 결합자 (공백) : 자손 결합자는 지정된 태그의 자손을 모든 노드에서 검색하고 선택합니다.
(<code>div span</code>은 <code>&lt;div&gt;</code> 태그 내에 위치한 모든 <code>&lt;span&gt;</code> 태그를 의미합니다.)</p>
</li>
<li><p>자식 결합자 (&gt;) : 자식 결합자는 지정된 태그의 직접적인 자녀만 선택합니다.
(<code>div &gt; p</code>는 <code>&lt;div&gt;</code>태그의 직계 자식에서만 <code>&lt;p&gt;</code>를 찾아 선택합니다.)</p>
</li>
<li><p>인접 형제 결합자 (+) : 인접 형제 결합자는 지정된 태그와 같은 레벨의 <strong>인접</strong> 노드만 선택합니다.
(<code>div + p</code>는 <code>&lt;div&gt;</code>태그의 인접 형제 중 가장 가까운 <code>&lt;p&gt;</code>태그를 찾아 선택합니다.)</p>
</li>
<li><p>일반 형제 결합자 (~) : 인접 형제 결합자와 달리 같은 레벨의 <strong>모든</strong> 형제 노드들을 찾아 선택합니다.</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[웹 브라우저 동작 과정]]></title>
            <link>https://velog.io/@dev-yun/%EC%9B%B9-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%8F%99%EC%9E%91-%EA%B3%BC%EC%A0%95</link>
            <guid>https://velog.io/@dev-yun/%EC%9B%B9-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EB%8F%99%EC%9E%91-%EA%B3%BC%EC%A0%95</guid>
            <pubDate>Mon, 21 Feb 2022 15:39:05 GMT</pubDate>
            <description><![CDATA[<h2 id="1-웹-브라우저의-구성요소와-동작과정">1. 웹 브라우저의 구성요소와 동작과정</h2>
<p><img src="https://images.velog.io/images/dev-yun/post/c48bc973-5588-411b-82b2-7c769ad20135/image.png" alt=""></p>
<hr>
<p>7가지로 구성된 웹브라우저의 동작 과정을 살펴보면</p>
<ol>
<li><p><strong>User interface</strong> : 사용자에게 브라우저의 화면을 보여주는 부분 (웹 주소를 입력하면 user interface get)</p>
</li>
<li><p><strong>Browser engine</strong> : 유저가 url을 입력하면 rendering engine으로 보내며 동작을 제어</p>
</li>
<li><p><strong>Rendering engine</strong> : 요청 받은 주소를 networking 모델로 보내 서버에 요청</p>
</li>
<li><p><strong>Networking</strong> : 서버에서 받아온 정보를 Rendering engine에게 보냄</p>
</li>
<li><p><strong>Rendering engine</strong> : 서버로부터 받은 정보가 Js 파일이면 Js engine에게 해석 요청</p>
</li>
<li><p><strong>JS engine</strong> : 요청 받은 정보를 파싱하여 HTML/CSS로 이루어진 Dom 파일을 Rendering engine에 보냄</p>
</li>
<li><p><strong>Rendering engine</strong> : 받아온 Dom 파일들 하나하나를 객체화 하여(render object) Render Tree를 만듬</p>
</li>
<li><p><strong>UI backend</strong> : 입력받은 Render Tree를 통해 UI backend에서 Dom 객체를 화면에 표시</p>
</li>
</ol>
<blockquote>
<p>Data storage : 쿠키나 캐쉬파일들을 저장함, 웹브라우저 동작과정에서 페이지 정보들이 쌓이며 이전에 했던 작업은 Data storage에서 꺼내씀 (Brower engine은 사실 Rendering engine에 url를 보내지 않고 Data storage에서 먼저 검색함)</p>
</blockquote>
<h2 id="2-rendering-engine-process렌더링-엔진-처리-과정">2. Rendering engine process(렌더링 엔진 처리 과정)</h2>
<p><img src="https://user-images.githubusercontent.com/71367408/136028439-93fbf546-44a3-4fa6-a9bd-e23e6f26882b.PNG" alt="web2"></p>
<hr>
<h4 id="과정-설명">과정 설명</h4>
<p><strong>HTML/CSS 파싱</strong> =&gt; <strong>DOM tree 구축</strong> =&gt; <strong>Render tree 구축</strong> =&gt; <strong>Render tree 배치</strong> =&gt; <strong>Render tree 그리기</strong> =&gt; <strong>Display 출력</strong></p>
<ul>
<li><p>[1] HTML 문서가오면 파싱하여 Dom Tree에 저장</p>
</li>
<li><p>[2] CSS 문서가 오면 파싱하여 Style Rules에 저장</p>
</li>
<li><p>[3] 만들어진 Dom Tree와 Style Rules를 합쳐 RenderTree에 저장</p>
</li>
<li><p>[4] Render Tree의 (layout)배치를 위한 과정</p>
</li>
<li><p>[5] UI backend에 요청하여 화면에 보여줌</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[HTML,CSS (Flexbox)]]></title>
            <link>https://velog.io/@dev-yun/HTMLCSS-Flexbox</link>
            <guid>https://velog.io/@dev-yun/HTMLCSS-Flexbox</guid>
            <pubDate>Sun, 20 Feb 2022 08:13:08 GMT</pubDate>
            <description><![CDATA[<p>제대로 HTML을 배우지 않고 웹 뼈대를 작성할시 UI구성에서 많은 어려움을 느낄 수 있습니다. (나처럼..)</p>
<p>가운데 정렬을 해도 어떤 박스는 제대로 되는 반면 어떤 박스는 그자리 그대로 있거나 길게 늘어집니다.</p>
<p>이번에는 박스 구조를 마음대로 구성할 수 있게 flexbox에 대해 배워볼것 입니다.</p>
<h2 id="기본-display">기본 display</h2>
<p>flexbox를 배워보기 이전에 우선 기본적인 display인 block, inline, inline-block 박스에 대해 간단히 알아보겠습니다.</p>
<ul>
<li><p>block : <code>&lt;div&gt;</code>같은 block 태그를 통해 만들어지는 박스로 한 라인에 하나만 위치할 수 있습니다.</p>
</li>
<li><p>inline : <code>&lt;span&gt;</code>같은 inline 태그를 통해 만들어지는 박스로 한 라인에 여러개가 위치할 수 있습니다. 특징으로는 높이와 너비(height, width)를 가질 수 없습니다.</p>
</li>
<li><p>inline-block : block과 inline의 특징을 섞은 박스로 높이와 너비를 가질 수 있고 한 라인에 여러개가 위치할 수 있습니다.</p>
</li>
</ul>
<p>과거에는 inline-block을 많이 사용했지만 유연하지 못하고 편의 기능이 부족하였고 이를 보완하기위해 개발된 것이 flexbox입니다.</p>
<h2 id="flexbox">flexbox</h2>
<p>앞서 말했듯 flexbox는 정렬, 좌우 대칭, reverse, 행열 변경등 여러 기능을 지원합니다.</p>
<p>이를 사용하기 전에 flexbox의 세가지 주의사항부터 살펴보겠습니다.</p>
<ol>
<li>자식 엘리먼트에 적용하기 위해선 무조건 부모 클래스에 <code>display : flex</code>를 선언한다. (속성들도 부모클래스에서 적용한다.)</li>
<li>justify-content는 수평에서 적용되는 것이 아니라 주축에서 적용된다.</li>
<li>align-items는 수직에서 적용되는 것이 아니라 교차축에서 적용된다.</li>
</ol>
<blockquote>
</blockquote>
<p>주의사항 1을 자세히 살펴보면 </p>
<pre><code class="language-html">&lt;body&gt;
  &lt;div&gt;&lt;/div&gt;
  &lt;div&gt;&lt;/div&gt;
  &lt;div&gt;&lt;/div&gt;
&lt;/body&gt;</code></pre>
<p>앞서 <code>display : inline, block, inline-block</code>등은 적용을 원하는 해당 박스에 직접 선언하여 사용하였습니다. (<code>&lt;div display : inline&gt;</code>)</p>
<blockquote>
</blockquote>
<p>하지만 flex의 경우 자식 엘리먼트인 <code>&lt;div&gt;</code> 박스에 적용을 원할 경우 부모 엘리먼트에 선언하여 사용합니다. (<code>&lt;body display : flex&gt;</code>)</p>
<blockquote>
<p>주의사항 2,3을 살펴보면</p>
</blockquote>
<p>flex에는 주축과 교차축이라는 개념이 존재합니다.</p>
<blockquote>
</blockquote>
<p>기본적으로 주축은 row 즉, 수평으로 적용되어 있기 때문에 <code>justify-content</code>가 수평에서 정렬되고 <code>align-items</code>가 수직에서 정렬되는것 입니다.
<img src="https://images.velog.io/images/dev-yun/post/053fd814-58e5-4a77-b129-c2bdef0f67bc/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>하지만 <code>flex-direction : column</code>으로 주축을 수직으로 변경시키면
<img src="https://images.velog.io/images/dev-yun/post/31061590-ec4a-4b5b-b1c0-de2d4b58bcde/image.png" alt=""></p>
<blockquote>
</blockquote>
<p>주축은 수직이되고 교차축은 수평이 됩니다.</p>
<blockquote>
</blockquote>
<p>사진 출처 : <a href="https://usingu.co.kr/references/css/flexbox-layout/">https://usingu.co.kr/references/css/flexbox-layout/</a></p>
<h3 id="flex의-주요-속성들">flex의 주요 속성들</h3>
<p>각 속성에 대한 자세한 정보는 <a href="https://developer.mozilla.org/ko/docs/Learn/CSS/CSS_layout/Flexbox">mdn</a>을 참고하여 사용합시다.</p>
<ol>
<li><p>justify-content : 주축의 정렬 방법을 설정</p>
</li>
<li><p>align-items : 교차축의 정렬 방법을 설정</p>
</li>
<li><p>flex-wrap : flex 박스들의 각 요소를 wrapping함 (기본값 : nowrap)</p>
</li>
<li><p>flex-direction : flex 박스들의 주축을 설정 (기본값 : row), row-reverse, column-reverse등으로 요소의 순서도 바꿀 수 있음)</p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[CSS (margin, padding, border)  ]]></title>
            <link>https://velog.io/@dev-yun/TIL-HTML-CSS</link>
            <guid>https://velog.io/@dev-yun/TIL-HTML-CSS</guid>
            <pubDate>Fri, 18 Feb 2022 13:43:54 GMT</pubDate>
            <description><![CDATA[<h2 id="margin-padding의-차이와-border">margin, padding의 차이와 border</h2>
<p>박스의 경계를 나누는 방법 3가지를 알아보겠습니다.
<img src="https://images.velog.io/images/dev-yun/post/90b50c9a-dc0c-4f58-a1df-860078aa4100/image.png" alt="">
외부부터 순서대로 margin, border, padding으로 구성됩니다.</p>
<p>margin : 박스 외부 영역의 크기입니다. 
padding : 박스 내부 영역의 크기입니다.</p>
<p>글로는 이해가 잘 가지 않으니 그림으로 알아보겠습니다.
(여기서 기본 first, second 박스에 margin값은 기본적으로 설정된 body의 margin이므로 신경쓰지 않아도 됩니다.)</p>
<p><img src="https://images.velog.io/images/dev-yun/post/26e2fcea-193c-4430-95a5-4d34f2df001f/image.png" alt="">
그림처럼 margin에 값을 주면 박스의 외부에 영역을 줍니다.</p>
<blockquote>
<p>주의점 : first에도 second에도 margin : 50px을 주었으므로 first와 second사이의 margin은 100px이여야 할듯합니다. </p>
</blockquote>
<p>하지만 collapsing margins라는 현상이 발생하여 하나의 margin만 인식해 50px가 됩니다.</p>
<blockquote>
</blockquote>
<p>만약 first와 second를 <code>inline-block</code>으로 수평에 위치시키면
<img src="https://images.velog.io/images/dev-yun/post/d4740a6e-8172-4fda-8747-86aac0fadbad/image.png" alt="">
좌우의 경계가 서로 50px씩 100px가 생기게 됩니다.</p>
<h4 id="collapsing-margins--박스의-위-아래-경계에서만-발생하는-현상으로-경계가-같다면-하나의-margin으로-인식함">collapsing margins : 박스의 위 아래 경계에서만 발생하는 현상으로 경계가 같다면 하나의 margin으로 인식함.</h4>
<p><img src="https://images.velog.io/images/dev-yun/post/d34316a9-3832-4ab8-9df6-e193e9334962/image.png" alt="">
그림처럼 padding값을 주면 박스의 내부에 영역을 주게 됩니다.</p>
<blockquote>
<p>특징으로는 padding값만큼 box의 크기가 증가하게 되므로 주의해야합니다.</p>
</blockquote>
<p>마지막으로 border에 대해 알아보겠습니다.</p>
<p>border : 박스 경계를 나타내는 영역입니다.
<img src="https://images.velog.io/images/dev-yun/post/3a45287b-0759-46e0-bac6-41a82ffcd711/image.png" alt="">
border은 크기(px,rem..)외에 선의 종류, 색깔을 지정해 주어야합니다.
<code>border : 10px solid black</code></p>
<blockquote>
<p>padding과 마찬가지로 border의 크기만큼 box의 크기가 증가하게 됩니다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[코어 자바스크립트 마무리]]></title>
            <link>https://velog.io/@dev-yun/%EC%BD%94%EC%96%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%A7%88%EB%AC%B4%EB%A6%AC</link>
            <guid>https://velog.io/@dev-yun/%EC%BD%94%EC%96%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%A7%88%EB%AC%B4%EB%A6%AC</guid>
            <pubDate>Thu, 17 Feb 2022 07:59:31 GMT</pubDate>
            <description><![CDATA[<h2 id="드디어-완독-👏">드디어 완독 👏</h2>
<p>Django, flask, 딥러닝, 데이터분석 등등 여러 분야를 공부해보면서 문득 프론트 분야도 한번 공부해볼까? 하는 생각에 여러 사람들에게 조언을 구했습니다. (<del>나에게 맞는 분야라는 생각이 들지 않아서..</del>)</p>
<p>그 결과 다들 모던 자바스크립트와 이 책을 추천해주셨습니다.</p>
<p>처음 책을 봤을땐 그렇게 두껍지 않아 보름정도면 마칠 수 있겠단 생각을 했습니다. 그런데 그 결과 한달하고도 일주일.. </p>
<p>핑계를 대자면 노마드 챌린지와 타 독서 병행, 처음 블로그 글 작성..등을 해보니 생각보다 완독에 시간이 걸렸습니다. 😢</p>
<p>사담은 여기까지 하고</p>
<p>이 책을 통해 자바스크립드의 콜백함수, 클로저, 프로토타입, 실행 컨텍스트 등 핵심 개념들과 동작 원리등을 배울 수 있었습니다.</p>
<p>정말 자바스크립트에 대해선 하나도 모르는 노베이스 상태인 저에게도 이해가 잘되도록 세세히 설명해 주셨고 목차도 정말 잘 구성되어서 전 단원을 읽으면 다음 단원에서 한번더 이해가 되는 책이였습니다.</p>
<p>현 ES6에 맞춰진 책이 아니지만 핵심 개념은 어디 도망가지 않으므로 읽으면 무조건 도움이 될듯합니다.</p>
<p>이젠 ES6 공부와 자바스크립트 프로젝트 진행, 리엑트 스터디로 방향을 잡고 열심히 공부하겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[📘클린코드 (2022.02.15) - 동시성(2)]]></title>
            <link>https://velog.io/@dev-yun/%ED%81%B4%EB%A6%B0%EC%BD%94%EB%93%9C-2022.02.15-%EB%8F%99%EC%8B%9C%EC%84%B12</link>
            <guid>https://velog.io/@dev-yun/%ED%81%B4%EB%A6%B0%EC%BD%94%EB%93%9C-2022.02.15-%EB%8F%99%EC%8B%9C%EC%84%B12</guid>
            <pubDate>Tue, 15 Feb 2022 09:34:09 GMT</pubDate>
            <description><![CDATA[<h2 id="day-24"><strong>DAY 24</strong></h2>
<h3 id="오늘-읽은-범위"><strong>오늘 읽은 범위</strong></h3>
<p><strong>12장 동시성 ~p244</strong></p>
<blockquote>
<p>😃  <strong>책에서 기억하고 싶은 내용을 써보세요.</strong></p>
</blockquote>
<ul>
<li><p>한정된 자원을 사용하는 스레드는 데드락 상태에 빠지지 않도록 조심해야한다.</p>
</li>
<li><p>처리율을 강조해서 처리기간을 늘리면 기아현상이나 오래된 정보가 쌓이게 된다.</p>
<ul>
<li>읽기 스레드와 쓰기 스레드의 요구를 적절히 맞춰 적당한 처리율을 유지시키고 기아현상을 없애야한다.</li>
</ul>
</li>
<li><p>대다수의 다중 스레드 문제는 한정된 자원을 여러 프로세스에서 얻기 위해 경쟁한다.</p>
<ul>
<li>데드락, 라이브락, 처리율 저하, 효율성 저하등의 문제를 해결하기 위해 알고리즘을 공부해 해법을 직접 구현해보는 공부가 필요하다.</li>
</ul>
</li>
<li><p>동기화하는 메서드 사이에 존재하는 의존성을 이해해야한다.</p>
<ul>
<li>메서드 사이에 의존성이 존재하면 동시성 코드에 찾아내기 어려운 버그가 생긴다.</li>
<li>즉, 공유 객체 하나에는 메서드 하나만 사용해야한다.</li>
<li>만약 여러 메서드를 사용해야하는 상황이라면 아래 세가지 방법 중 하나를 사용하라.<ul>
<li>클라이언트에서 잠금 : 클라이언트에서 첫 번째 메서드를 호출하기 전에 서버를 잠근다.</li>
<li>서버에서 잠금 : &quot;서버를 잠그고 모든 메서드를 호출한 후 잠금을 해제하는&quot; 메서드를 구현한다.</li>
<li>연결 서버 : 잠금을 수행하는 중간 단계를 생성한다. &quot;서버에서 잠금&quot;과 다른점은 원래 서버를 변경하지 않는 점이다.</li>
</ul>
</li>
</ul>
</li>
<li><p>동기화하는 부분을 작게 만들어라.</p>
</li>
<li><p>스레드 코드 테스트하기</p>
<ul>
<li>코드가 올바르다고 증명하기는 현실적으로 불가능하다.</li>
<li>그럼에도 충분한 테스트는 위험을 낮추므로 시스템 설정과 부하를 바꿔가며 자주 돌려라</li>
</ul>
</li>
<li><p>여러 스레드가 돌아가는 프로그램이라면 같은 테스트가 통과할때도, 실패할때도 있을것이다. 이런 경우엔 고려할 사항이 많다.</p>
<ul>
<li>말이 안되는 실패는 잠정적인 스레드 문제로 취급하라.</li>
<li>다중 스레드를 고려하지 않은 순차 코드부터 제대로 돌게 만들자</li>
<li>다중 스레드를 쓰는 코드 부분을 상황에 맞게 조율할 수 있게 작성하라.</li>
<li>프로세서 수보다 많은 스레드를 돌려봐라</li>
<li>다른 플랫폼에서 돌려봐라</li>
<li>코드에 보조 코드(Object.wait(), Object.sleep()...)를 넣어 돌려보고 강제로 실패를 일으키게 해봐라.</li>
</ul>
</li>
</ul>
<blockquote>
<p>🙄*<em>오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요 *</em></p>
</blockquote>
<ul>
<li><p>예전 운영체제 시간에 배웠던 기아, 데드락, 상호 배제등을 보니 반갑기도 하고 더 이해가 잘갔다. 사실 알고 있던 내용을 다시 배운 느낌이였다.
책을 읽으면서 느낀게 모든 코드에 &#39;한번에 한가지일만, 짧게 작성하라&#39;라는 규칙이 적용되는것 같다. 스레드에도 적용된다니.. 다중 스레드를 구현할 일이 있을지 모르겠지만 그때가 되서 다시 읽어보면 도움이 될듯하다.</p>
</li>
<li><p>드디어 클리코드 책 TIL가 마무리됐다. 뒷 내용들을 간단히 살펴보니 17장의 냄새와 휴리스틱 페이지는 꼭 읽어봐야겠다. 하지만 앞에 내용들과 중복되는 내용이 많으므로 그냥 독서식으로 살펴보고 따로 포스팅을 하진 않겠다.</p>
</li>
</ul>
<blockquote>
<p>✏ <strong>소감 3줄 요약</strong></p>
</blockquote>
<ul>
<li>다중 스레드를 올바르게 구현하긴 어렵다. 각별히 깨끗한 코드와 꾸준한 테스트를 작성해야한다.</li>
<li>오류를 해결하기 위해선 기본 알고리즘과 유사한 문제들의 해결법들을 이해하고 적용할줄 알아야한다.</li>
<li>드디어 클린코드가 마무리됐다. 다음책을 골라야겠다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[📘클린코드 (2022.02.14) - 동시성(1)]]></title>
            <link>https://velog.io/@dev-yun/%ED%81%B4%EB%A6%B0%EC%BD%94%EB%93%9C-2022.02.14</link>
            <guid>https://velog.io/@dev-yun/%ED%81%B4%EB%A6%B0%EC%BD%94%EB%93%9C-2022.02.14</guid>
            <pubDate>Mon, 14 Feb 2022 06:06:21 GMT</pubDate>
            <description><![CDATA[<h2 id="day-23"><strong>DAY 23</strong></h2>
<h3 id="오늘-읽은-범위"><strong>오늘 읽은 범위</strong></h3>
<p><strong>12장 동시성 ~p233</strong></p>
<blockquote>
<p>😃  <strong>책에서 기억하고 싶은 내용을 써보세요.</strong></p>
</blockquote>
<ul>
<li><p>일단 동시성과 깔끔한 코드는 양립하기 어렵다는 점을 알고 가자.</p>
</li>
<li><p>이 단원에서는 여러 스레드를 돌리는 이유와 어려움을 논한다. 또한 이 어려움에 대처하고 깨끗한 코드를 작성하는 방법도 제안한다.</p>
</li>
<li><p>동시성이 필요한 이유</p>
<ul>
<li>동시성은 결합을 없애는 전략이다. 즉, <strong>무엇</strong>과 <strong>언제</strong>를 분리하는 전략이다.</li>
<li><strong>무엇</strong>과 <strong>언제</strong>를 분리하면 구조적 관점에서 프로그램이 거대한 하나의 루프가 아니라 작은 협력 프로그램 여럿으로 보인다.</li>
<li>한번에 하나를 처리하는 단일 스레드는 대규모 프로그램에서 너무 느리다. =&gt; 다중 스레드로 병렬 처리해야하는 이유 =&gt; 동시성이 중요한 이유</li>
</ul>
</li>
<li><p>미신과 오해</p>
<ul>
<li>동시성은 항상 성능을 높혀준다.</li>
<li>동시성을 구현해도 설계는 변하지 않는다.</li>
<li>웹 또는 EJB 컨테이너를 사용하면 동시성을 이해할 필요가 없다. (헉 ...)</li>
</ul>
</li>
<li><p>동시성의 실체</p>
<ul>
<li>동시성은 다소 부하를 유발한다.</li>
<li>동시성은 복잡하다.</li>
<li>일반적으로 동시성 버그는 재현하기 어렵다.</li>
<li>동시성을 구현하려면 흔히 근본적인 설계 전략을 재고해야한다.</li>
</ul>
</li>
<li><p>동시성 방어 원칙 : 동시성 코드가 일으키는 문제로부터 시스템을 방어하는 원칙</p>
<ul>
<li>단일 책임 원칙(SRP)<ul>
<li>동시성은 복잡성 하나만으로도 따로 분리할 이유가 있다. 즉, 동시성 관련 코드는 다른 코드와 분리해야 한다는 것이다.</li>
<li>권장사항 : 동시성 코드는 다른 코드와 분리하라.</li>
</ul>
</li>
<li>따름 정리 : 자료범위를 제한하라 <ul>
<li>스레드 간의 간섭 때문에 예상치 못한 결과가 나타날 수 있다.</li>
<li>이런 문제를 해결하기 위해 공유 객체를 사용하는 코드 내 임계영역을 synchronized 키워드로 보호하라 권장한다.</li>
<li>권장사항 : 자료를 캡슐화하라. 공유 자료를 최대한 줄여라</li>
</ul>
</li>
<li>따름 정리 : 자료 사본을 사용하라<ul>
<li>공유 자료를 줄이려면 처음부터 공유하지 않는 방법이 제일 좋다.</li>
<li>객체를 복사해 읽기 전용으로 사용하거나 각 스레드가 객체를 복사해 사용한 후 한 스레드가 해당 사본에서 결과를 가져오는 방법이 있다.</li>
<li>사본으로 동기화를 피할 수 있다면 복사 비용보다 줄어드는 비용이 클것이다.</li>
</ul>
</li>
<li>따름 정리 : 스레드는 가능한 독립적으로 구현하라<ul>
<li>다른 스레드와 자료를 공유하지 않아야한다.</li>
<li>각 스레드는 클라이언트 요청 하나를 처리하며 모든 정보는 비공유 출처에서 가져와 로컬 변수에 저장한다.</li>
<li>권장사항 : 독자적인 스레드로, 가능하면 다른 프로레서에서, 돌려도 괜찮도록 자료를 독립적인 단위로 분할하라.</li>
</ul>
</li>
</ul>
</li>
</ul>
<blockquote>
<p>🙄*<em>오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요 *</em></p>
</blockquote>
<ul>
<li><p>처음에는 싱글 스레드를 사용하는 JS를 공부하고 있어서 이 단원은 읽지 않을려고 했다. 하지만 생각해보니 비동기처리로 유사 동시성?을 구현하는 자바스크립트와 브라우저 엔진을 떠올리며 읽으면 좋을것 같아 읽어보았다. 역시 멀티 스레드 내용은 정말 어려웠다. 개념 자체는 어렵지 않지만 내부적인 코드를 보면 정신이 혼미해진다. 하지만 중간의 &#39;미신과 오해&#39; 부분에서 뼈를 맞아 열심히 읽었다.</p>
</li>
<li><p>솔직히 말하면 JS로 계속 개발을 할 경우 그렇게 유용한 내용은 아닌것 같다. 그냥 멀티 스레드의 주의점과 개념, 필요성등을 이해하고 넘어가도 될듯하다. </p>
</li>
</ul>
<blockquote>
<p>🔎 <strong>궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.</strong></p>
</blockquote>
<ul>
<li>synchronized : 여러개의 스레드가 한개의 자원을 사용하고자 할 때, 현재 데이터를 사용하고 있는 해당 스레드를 제외하고 나머지 스레드들은 데이터에 접근 할 수 없도록 막는 개념
출처 : <a href="https://coding-start.tistory.com/68">https://coding-start.tistory.com/68</a></li>
</ul>
<blockquote>
<p>✏ <strong>소감 3줄 요약</strong></p>
</blockquote>
<ul>
<li>동시성 구현의 필요성과 어려움을 배웠다.</li>
<li>동시성을 사용해도 항상 성능이 좋아지는 것은 아니므로 잘 설계하여 구현해야한다.</li>
<li>웹 또는 EJB 컨테이너를 사용해도 동시성을 이해해야 한다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[코어 자바스크립트 #7 클래스]]></title>
            <link>https://velog.io/@dev-yun/%EC%BD%94%EC%96%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-7-%ED%81%B4%EB%9E%98%EC%8A%A4</link>
            <guid>https://velog.io/@dev-yun/%EC%BD%94%EC%96%B4-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-7-%ED%81%B4%EB%9E%98%EC%8A%A4</guid>
            <pubDate>Mon, 14 Feb 2022 03:56:24 GMT</pubDate>
            <description><![CDATA[<h1 id="클래스">클래스</h1>
<p>프로토 타입을 공부하며 &#39;클래스의 상속과 거의 같은게 아닌가?&#39; 라는 생각을 했습니다. </p>
<p>그런데 제 생각을 어떻게 알았는지 이번 장에서 클래스와 프로토타입 체인은 비슷한 점이 있지만 왜 같다고 생각하면 위험한지에 대한 설명을 해주었습니다.</p>
<p>이번 장에선 클래스와 인스턴스의 개념과 자바스크립트 ES5에서의 클래스 작성법, ES6에서의 클래스 사용법등을 알아보겠습니다.</p>
<h2 id="클래스와-인스턴스의-개념-이해">클래스와 인스턴스의 개념 이해</h2>
<p>클래스의 일반적인 개념은 공통 속성의 정의라고 할 수 있습니다.</p>
<p>직업이라는 공통 속성 내에 IT라는 분야가 있을 수 있고 IT라는 분야 내에 개발자라는 분야가 있을 수 있습니다.</p>
<p>개발자의 내부에는 구체적인 직업들이 있을 수 있죠</p>
<img src="https://images.velog.io/images/dev-yun/post/e0bbaab9-d83e-4a0c-ba6b-ae222d582479/image.png" width = 70%>

<p>여기서 직업, IT, 개발자라는 개념은 공통 속성을 모아 정의한 추상적인 개념이고
프론트엔드, 백엔드, 임베디드, 모바일 어플리케이션 등은 구체적인 개념에 해당합니다.</p>
<p>또한 직업은 IT의 상위 클래스(superClass)이고, IT는 개발자의 상위 클래스(superClass)이며
반대로 IT는 직업의 하위 클래스(subClass), 개발자는 IT의 하위 클래스(subClass)입니다.</p>
<p>클래스의 속성을 자세히 살펴보겠습니다.</p>
<ul>
<li>직업 : 일을 하여 돈을 벌 수 있음.</li>
<li>IT : 일을 하여 돈을 벌 수 있음 + IT 분야에서 일함</li>
<li>개발자 : 일을 하여 돈을 벌 수 있음 + IT 분야에서 일함 + 요구사항에 맞춰 각종 소프트웨어, 웹, 어플리케이션등을 유지보수, 개발함</li>
</ul>
<p>이처럼 하위 클래스는 상위 클래스의 속성을 상속하며 점차 구체적인 요건이 추가 또는 변경됩니다.</p>
<p>여기서 프론트엔드, 백엔드, 임베디드 등은 개발자 클래스의 속성을 지니는 구체적인 개체들입니다.</p>
<p>이처럼 클래스의 속성을 지니는 실존하는 개체들을 일컬어 인스턴스(instance)라고 합니다.</p>
<blockquote>
<p>현실세계에서는 개체들이 먼저 만들어지고 서로 공통점을 묶어 상위 개념이 만들어집니다. 
(ex. 기현, 병현, 수연 등 개인이 모여 가족을 이루고, 가족이 모여 동네를 만들고 동네가 모여 도시가 만들어집니다.)</p>
</blockquote>
<p>하지만 프로그래밍 상에서는 클래스가 먼저 정의되고 점차 하위 클래스가 만들어지며 필요해의해 클래스를 바탕으로 구체적인 개체들이 만들어집니다.</p>
<blockquote>
</blockquote>
<p>이러한 차이때문에 클래스를 이해할때 약간의 헷갈림이 생길 수 있습니다.</p>
<h2 id="자바스크립트의-클래스">자바스크립트의 클래스</h2>
<p>일반적으로 프로토타입 기반의 언어는 클래스의 개념이 없다고 하지만 <strong>프로토타입 체이닝을 통해 상위 프로토타입의 내용을 참조</strong>한다는 점이 클래스의 개념과 약간 비슷하게 해석할 수 있습니다.</p>
<p>생성자 함수로 인스턴스를 생성할 경우 해당 인스턴스는 생성자 함수의 prototype 객체 내부 요소들을 참조합니다. 
(클래스의 개념에선 상속이지만 프로토타입은 참조를 하므로 약간의 차이가 발생합니다. (결과적으론 동일하게 작동!))</p>
<p>하지만 앞서 6장에서 배웠듯이 인스턴스가 생성자 함수를 참조할때 모든 내용을 참조하는것은 아니고 구분할 수 있습니다.</p>
<ul>
<li>스태틱 멤버 : 생성자 함수에서만 정의되어 인스턴스에서 참조할 수 없음</li>
<li>인스턴스 멤버 : 프로토타입에 정의되어 인스턴스에서 참조할 수 있음</li>
</ul>
<p>그런데 여느 클래스 기반 언어와 달리 자바스크립트는 인스턴스에서도 직접 메서드를 정의할 수 있습니다. (메서드 오버라이딩)</p>
<pre><code class="language-javascript">// 6장에서 사용한 내용
var Person = function (name) {
  this.name = name;
};
Person.prototype.getName = function () {
  return this.name;
};

var myName = new Person(&#39;윤철&#39;);
myName.getName = function () {
  return &#39;신&#39; + this.name;
};
console.log(myName.getName());            // 신윤철</code></pre>
<p>때문에 &#39;인스턴스 멤버&#39;의 &#39;인스턴스 메서드&#39;라는 명칭은 프로토타입에 정의한 메서드인지 인스턴스에 정의한 메서드인지 혼란스럽습니다.
(예제에선 <code>Person.prototype.getName</code>도 인스턴스 메서드이고 <code>myName.getName</code>도 인스턴스 메서드입니다.)</p>
<p>때문에 인스턴스 메서드는 프로토타입 메서드라고 부르는편이 좋습니다.
(<code>Person.prototype.getName</code> == 프로토타입 메서드, <code>myName.getName</code> == 인스턴스 메서드)</p>
<p>코드를 약간 수정하여 스태틱 멤버, 프로토타입 멤버에 대해 예제를 통해 알아보겠습니다. </p>
<pre><code class="language-javascript">var Person = function (name) {
  this.name = name;
};
Person.isPerson = function (instance) {
  return instance instanceof Person;
};
Person.prototype.getName = function () {
  return this.name;
};

var myName = new Person(&#39;윤철&#39;);

console.log(myName.getName());                // 윤철
console.log(myName.isPerson(myName));        // (error) myName.isPerson is not a function
console.log(Person.isPerson(myName));        // true</code></pre>
<p>프로토타입 객체에 할당한 메서드는 인스턴스에서 자신의 것처럼 (<code>__proto__</code>를 생략해서) 사용할 수 있다고 했고 실제로 <code>myName.getName</code>에서 잘 사용할 수 있습니다.</p>
<p>그리고 생성자 함수 Person에서 생성한 <code>isPerson</code> 메서드는 스태틱 메서드이므로 인스턴스에서 사용할 수 없고, 생성자 함수에서만 사용할 수 있습니다.</p>
<blockquote>
<p>함수를 생성할 때 prototype을 붙히지 않고 생성하면 스태틱 멤버,
prototype을 붙히고 생성하면 프로토타입 멤버입니다.</p>
</blockquote>
<p>앞서 클래스는 추상적인 개념이라고 설명했는데 <code>Person.isPerson</code>같이 클래스에서 스태틱 메서드를 호출할 때 클래스는 하나의 개체로서 취급됩니다.</p>
<h2 id="클래스-상속">클래스 상속</h2>
<p>클래스 상속은 객체지향에서 가장 중요한 요소 중 하나입니다.</p>
<p>하지만 자바스크립트에선 클래스가 존재하지 않기 때문에 ES5까지는 최대한 프로토타입 체인을 활용하여 클래스와 비슷한 형태를 흉내냈습니다.</p>
<p>ES6에선 클래스 문법이 도입되었기 때문에 이러한 방식을 사용할 일은 없겠지만 
ES6에서의 클래스 문법도 prototype을 기반으로 만들어진것이기 때문에 그 이전의 방식들을 배우는 것도 이해에 도움이 될 것입니다. 
(<del>책에선 너무 확실히 이해하려 하진 않아도 된다고 합니다.</del>)</p>
<h3 id="기본-구현">기본 구현</h3>
<pre><code class="language-javascript">var Grade = function () {
  var args = Array.prototype.slice.call(arguments);
  for (var i = 0; i &lt; args.length; i++) {
    this[i] = args[i];
  }
  this.length = args.length;
};

Grade.prototype = [];
var g = new Grade(100, 80);</code></pre>
<p>앞서 자바스크립트에서 클래스를 흉내내기 위해 prototype을 사용한다고 하였습니다.</p>
<p>다만 겉으로는 비슷해보여도 세부적으로 superClass와 subClass를 완변하게 구현한 것은 아닙니다.</p>
<p>위 코드에는 length 프로퍼티가 삭제 가능하단 점과 <code>Grade.prototype</code>이 빈 배열을 참조한다는 문제점이 있는데 자세히 알아보겠습니다.</p>
<h4 id="문제점-1-length-프로퍼티-삭제가능-상위-클래스의-값이-하위-클래스의-값에-영향을-줌">문제점 1. length 프로퍼티 삭제가능, 상위 클래스의 값이 하위 클래스의 값에 영향을 줌</h4>
<pre><code class="language-javascript">// 위 코드의 이어서 작성
g.push(90);
console.log(g)            // Grade(3) [100, 80, 90] length : 3

delete g.length;
g.push(70);
console.log(g);            // Grade [70, 1: 80, 2: 90] length : 1</code></pre>
<p><code>g.push(90)</code>을 통해 Grade의 마지막값에 90이 잘 추가되고 length도 정상적으로 늘어났습니다.</p>
<p>그런데 <code>delete g.length</code>를 통해 length를 한번 지우고 <code>g.push(70)</code>을 할 경우 Grade의 첫번째 행에 70이 추가되고, length도 1이 됩니다.</p>
<p>왜 그럴까요❓</p>
<p>바로 내장객체 Array의 length 프로퍼티는 configurable 속성이 false라서 삭제가 불가능하지만, Grade의 length 프로퍼티는 삭제가 가능하기 때문입니다.</p>
<p><img src="https://images.velog.io/images/dev-yun/post/c4019e4e-1479-4bdb-bfea-bfcf85452d8b/image.png" alt=""></p>
<p>실제 결과를 보니 약간 더 이해가 잘 가네요.</p>
<p>delete로 삭제한 결과 Grade의 length 프로퍼티가 삭제되었고 그 다음 <code>g.push(70)</code>을 실행한 결과 <code>g.length</code>가 없어졌기 때문에 프로토타입 체이닝을 통해 <code>g.__proto__.length</code>의 값을 찾아 +1을 한 것입니다.
(length가 삭제되어 기존의 값도 새로운 push값으로 대체됩니다.)</p>
<p>만약 <code>Grade.prototype = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;];</code> 처럼 빈 배열이 아닌 값을 할당하면 어떻게 될까요?</p>
<pre><code class="language-javascript">Grade.prototype = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;];
var g = new Grade(100, 80);

g.push(90);
console.log(g)            // Grade(3) [100, 80, 90] length : 3

delete g.length;
g.push(70);
console.log(g);            // Grade(6) [100, 80, 90, empty × 2, 70], length : 6</code></pre>
<p>마찬가지로 <code>g.length</code>가 사라져서 프로토타입 체이닝을 통해 <code>g.__proto__</code>의 정보를 찾습니다. </p>
<p>그런데 해당 <code>Grade.prototype</code>의 length가 5라서 length + 1인 6이 되고, 비어있지 않은 인덱스 5에 70을 넣게됩니다. (인덱스 0~4는 &#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;,&#39;e&#39; 가 들어있음)</p>
<p>이처럼 <strong>superClass의 값이 인스턴스의 동작에 영향을 미치는데</strong> 정상적인 클래스에서는 추상성을 해치는 일입니다.</p>
<p>클래스는 인스턴스에 구체적인 데이터를 주지 않고 추상적인 틀로서 역할을 해야하는데 이렇게 사용한다면 예기치 않은 오류가 발생할 가능성이 있습니다.</p>
<h4 id="문제점-2-intance와-subclass의-constructor이-superclass의-constructor을-보고있음">문제점 2. intance와 subClass의 constructor이 superClass의 constructor을 보고있음</h4>
<p><code>g.constructor</code>은 <code>g.__proto__.__proto__.constructor</code>, 즉 Array를 가리키고 있습니다.</p>
<p>때문에 아래와 같은 코드가 성립하게 됩니다.</p>
<pre><code class="language-javascript">var g2 = new g.constructor(10, 20);
console.log(g2);            // [10, 20]</code></pre>
<p>클래스의 관점에서 instance에서 상위 클래스의 constructor에 접근하여 새로운 instance를 생성하는것은 구조적으로 안전성이 떨어집니다. </p>
<p>문제점 1을 해결한 후 하위 개체들이 상위 클래스의 constructor을 바라보지 못하게 만들겠습니다.</p>
<h4 id="문제점-1-해결--클래스가-구체적인-데이터를-지니지-않게-만들기">문제점 1 해결 =&gt; 클래스가 구체적인 데이터를 지니지 않게 만들기</h4>
<p><strong>첫번째 방법</strong>으로 클래스가 구체적인 데이터를 지니지 않게 하는 가장 간단한 방법은 프로퍼티들을 일일이 지우고 freeze하여 더는 추가할 수 없게 만드는 것입니다.</p>
<pre><code class="language-javascript">delete superClass.prototype.method;            // 상위 클래스의 메서드를 지
Object.freeze(superClass.prototype);        // freeze로 더는 추가할 수 없게 만듬</code></pre>
<hr>
<p><strong>두번째 방법</strong>은 더글라스 크락포드가 제시한 방법으로</p>
<p>subClass의 prototype에 직접 superClass의 instance를 할당하는 대신
아무런 프로퍼티를 생성하지 않는 빈 생성자 함수(Bridge)를 하나 더 만드는 것 입니다.</p>
<pre><code class="language-javascript">var Bridge = function () {};
Bridge.prototype = superClass.prototype;
subClass.prototype = new Bridge();
Object.freeze(subClass.prototype);</code></pre>
<p><img src="https://images.velog.io/images/dev-yun/post/f972d89a-c200-43c2-9186-b3a684c6016a/image.png" alt="">
즉, superClass와 subClass 사이에 Bridge 추가
<img src="https://images.velog.io/images/dev-yun/post/ceec4960-bcfb-43a9-95b3-52407ea3a713/image.png" alt=""></p>
<p>그런데 이때 <code>subClass.prototype</code>을 freeze하므로써 상위 클래스의 prototype을 참조할 수 없게 만듭니다.
(<code>subClass.prototype</code>이 빈 값이므로)</p>
<p>이로써 intance를 제외한 프로토타입 체인 경로상에는 구체적인 데이터가 남아있지 않게 됩니다.</p>
<hr>
<p><strong>세번째 방법</strong>은 ES5에서 도입된 Object.create를 이용한 방법입니다.</p>
<pre><code class="language-javascript">subClass.prototype = Object.create(superClass.prototype);
Object.freeze(subClass.prototype);</code></pre>
<p>Object.create는 아무 내용이 없는 prototype을 생성합니다.
때문에 위의 코드를 실행하고 freeze할시 subClass의 prototype에는 아무 prototype이 남아있지 않게 됩니다.</p>
<p>구체적인 코드로 살펴보기위해 앞서 &quot;클래스 상속 부분의 기본 구현&quot;의 코드로 비교해보겠습니다.</p>
<pre><code class="language-javascript">//Object.create(superClass.prototype)을 구현한 코드
var Grade = function () {
  var args = Array.prototype.slice.call(arguments);
  for (var i = 0; i &lt; args.length; i++) {
    this[i] = args[i];
  }
  this.length = args.length;
};

Grade.prototype = Object.create(Array.prototype);
Object.freeze(Grade.prototype);

var g = new Grade(100, 80);
console.log(g);</code></pre>
<p><img src="https://images.velog.io/images/dev-yun/post/9b7683e2-fdaa-4341-9bef-60b767de37ef/image.png" alt=""></p>
<p>결과를 보니 Grade의 기본 length값이 사라져서 상위 클래스의 값에 영향을 받지 않게 된것을 확인할 수 있습니다.</p>
<h4 id="문제점-2-해결--instance와-하위-클래스가-상위-클래스의-constructor을-가리키는-문제-해결">문제점 2 해결 =&gt; instance와 하위 클래스가 상위 클래스의 constructor을 가리키는 문제 해결</h4>
<p>이 문제의 해결법은 간단합니다.</p>
<pre><code class="language-javascript">subClass.prototype.constructor = subClass;
Object.freeze(subClass.prototype);</code></pre>
<p>이처럼 subClass의 prototype에 직접 subClass를 담는것 입니다.</p>
<p>이 예시도 위에서 사용한 코드에 추가하여 살펴보겠습니다.</p>
<pre><code class="language-javascript">var Grade = function () {
  var args = Array.prototype.slice.call(arguments);
  for (var i = 0; i &lt; args.length; i++) {
    this[i] = args[i];
  }
  this.length = args.length;
};

Grade.prototype = Object.create(Array.prototype);
Grade.prototype.constructor = Grade;                // 이 부분 추가
Object.freeze(Grade.prototype);

var g = new Grade(100, 80);
console.log(g);</code></pre>
<p><img src="https://images.velog.io/images/dev-yun/post/5c65db56-c3f8-45d2-ab4e-bc72119f8f23/image.png" alt=""></p>
<p>그 결과 constructor에 Grade가 잘 들어간 것을 확인할 수 있습니다.
이로써 하위 클래스는 자신의 constructor을 제대로 가리키게 됩니다.</p>
<hr>
<h2 id="es6의-클래스-및-클래스-상속">ES6의 클래스 및 클래스 상속</h2>
<p>앞서 언급했든 ES6부터는 클래스 문법이 도입되었습니다.</p>
<p>ES5와 ES6의 클래스 문법을 비교하여 소개해보겠습니다.</p>
<pre><code class="language-javascript">// ES5에서 유사 클래스 문법
var ES5 = function (name) {
  this.name = name;
};
ES5.staticMethod = function () {
  return this.name + &#39; staticMethod&#39;;
};
ES5.prototype.prototypeMethod = function () {
  return this.name + &#39; prototypeMethod&#39;;
};
var es5Instance = new ES5(&#39;es5&#39;);
console.log(es5Instance);
console.log(ES5.staticMethod());
console.log(es5Instance.prototypeMethod());

// ES6에서 클래스 문법
var ES6 = class {
  constructor(name) {
    this.name = name;
  }
  static staticMethod() {
    return this.name + &#39; staticMethod&#39;;
  }
  prototypeMethod() {
    return this.name + &#39; prototypeMethod&#39;;
  }
};
var es6Instance = new ES6(&#39;es6&#39;);
console.log(es6Instance);
console.log(ES6.staticMethod());
console.log(es6Instance.prototypeMethod());</code></pre>
<p>ES5는 일일이 staticMethod, prototypeMethod, 프로퍼티등을 하나하나 작성하였습니다.</p>
<p>하지만 ES6에서는 class로 묶어 static 메서드와 prototype 메서드등을 한번에 정의하는 것을 확인할 수 있습니다.</p>
<p>그럼 결과를 살펴보겠습니다.</p>
<p><img src="https://images.velog.io/images/dev-yun/post/a6aec3bc-7c74-4364-adea-ec84058f1b83/image.png" alt=""></p>
<p>ES5와 ES6의 <code>console.log</code> 결과는 같게 나옵니다.</p>
<p>하지만 내부 구조를 살펴보면 많은 차이가 있습니다.</p>
<p>가장 큰차이는 ES5의 constructor은 함수, ES6의 constructor은 class라는 점입니다.</p>
<p>그 외에도 prototypeMethod, staticMethod 등도 차이를 보입니다. (코드를 작성해서 직접 구조를 보는 것을 추천)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[📘클린코드 (노개북 후기)]]></title>
            <link>https://velog.io/@dev-yun/%ED%81%B4%EB%A6%B0%EC%BD%94%EB%93%9C-%EB%85%B8%EA%B0%9C%EB%B6%81-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@dev-yun/%ED%81%B4%EB%A6%B0%EC%BD%94%EB%93%9C-%EB%85%B8%EA%B0%9C%EB%B6%81-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Sat, 12 Feb 2022 08:26:36 GMT</pubDate>
            <description><![CDATA[<h2 id="노개북-종료">노개북 종료!</h2>
<p>약 3주간 매일 클린코드를 읽고 TIL를 작성하며 노마드 코더 회원분들과 서로의 TIL를 공유하며 좋은 시너지를 낼 수 있었습니다!</p>
<p>과연 혼자였으면 꾸준히 읽었을 수 있었을지..</p>
<p>니코쌤이 자바스크립트를 공부하는 우리에게 필요한 단원과 스케줄을 짜주셔서 부담없이 진행할 수 있었던 것 같습니다.😃</p>
<p>중간중간 <a href="https://nomadcoders.co/community/thread/1705">잘 작성한 TIL</a>에 뽑히기도 하고 끝까지 완주한 리스트와 열심히 참여한 목록에 올라가니 열심히한 보람이 있네요..ㅎㅎ</p>
<p>노개북이 끝나고 남은 뒷부분을 읽어보니 코드 리펙토링 과정, JUnit, SerialDate 내부 구조 공부 등 자바 코드로 구현된 부분들만 남았습니다.</p>
<p>그래서 니코쌤이 여기까지 스케줄을 잡으셨나 싶기도 합니다. 앞으로 동시성 부분만 읽고 클린코드 TIL를 마치겠습니다.</p>
]]></description>
        </item>
    </channel>
</rss>