<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>b_m_c.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sat, 16 Dec 2023 11:43:35 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>b_m_c.log</title>
            <url>https://images.velog.io/images/b_m_c/profile/d2db0099-4470-40e4-81e1-ea618a9c2579/social.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. b_m_c.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/b_m_c" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[apply함수]]></title>
            <link>https://velog.io/@b_m_c/apply%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@b_m_c/apply%ED%95%A8%EC%88%98</guid>
            <pubDate>Sat, 16 Dec 2023 11:43:35 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-python">for i in range(1, max_len + 1):
 df[f&#39;SE{i}&#39;] = df[&#39;worker&#39;].apply(lambda x: x[i-1] if len(x) &gt;= i else None)
</code></pre>
<p>apply 함수는 Pandas 데이터프레임 또는 시리즈의 각 행(axis=0) 또는 열(axis=1)에 함수를 적용하는 데 사용되는 메서드입니다. apply 함수를 사용하면 사용자 정의 함수나 람다 함수를 데이터프레임의 각 요소에 적용할 수 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[웹개발 부트캠프 2022 4주차(자바스크립트)]]></title>
            <link>https://velog.io/@b_m_c/%EC%9B%B9%EA%B0%9C%EB%B0%9C-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-2022-4%EC%A3%BC%EC%B0%A8%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8</link>
            <guid>https://velog.io/@b_m_c/%EC%9B%B9%EA%B0%9C%EB%B0%9C-%EB%B6%80%ED%8A%B8%EC%BA%A0%ED%94%84-2022-4%EC%A3%BC%EC%B0%A8%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8</guid>
            <pubDate>Thu, 19 May 2022 10:28:16 GMT</pubDate>
            <description><![CDATA[<p>(5/6 ~5/19) The Web Developer 부트캠프 2022 강의 내용 정리
범위 : YelpCamp CURD ~ Express와 Mongo연결하기(섹션 41 ~43)</p>
<h1 id="미들웨어">미들웨어</h1>
<p>미들웨어는 요청에서 응답 사이에 실행되는 함수이고 요청 객체와 응답 객체에 접근 및 수정할 수 있다.</p>
<blockquote>
<p>Express는 라우팅과 최소한의 기능을 갖춘 미들웨어 웹 프레임워크의 결합이다
즉, Express 앱은 미들웨어 함수 호출의 연쇄일 뿐이다</p>
</blockquote>
<h2 id="morgan">Morgan</h2>
<p>request logger middleware이다. 각종 Request 요청에 대한 간략한 정보들을 콘솔에 출력해주는 역할을 한다.</p>
<pre><code class="language-javascript">app.use(morgan(&#39;tiny&#39;));
//dev 옵션
app.use(morgan(&#39;dev&#39;));
//common 옵션
app.use(morgan(&#39;common&#39;));

//tiny
GET / 200 9 - 3.296 ms
GET /favicon.ico 404 150 - 3.272 ms

//dev
GET / 304 4.349 ms - -

//common
::1 - - [18/May/2022:14:23:40 +0000] &quot;GET / HTTP/1.1&quot; 304 -</code></pre>
<h1 id="미들웨어-정의">미들웨어 정의</h1>
<p>app.use((req,res,next)=&gt;{}) 형태로 정의하며 next함수를 통해 다음 미들웨어 또는 라우트 핸들러를 호출한다.</p>
<pre><code class="language-javascript">app.use((req, res, next) =&gt; {
    console.log(&#39;ThIS IS MY FIRST MIDDLEWARE!&#39;);
    next();
});
app.use((req, res, next) =&gt; {
    console.log(&#39;ThIS IS MY SECOND MIDDLEWARE!&#39;);
    req.requestTime = Date.now();
    next();
});

//미들웨어에서 요청이 들어온 시간을 요청객체의 requestTime에 넣어주어 라우트핸들러에서 접근할 수 있게 함
app.get(&#39;/&#39;, (req, res) =&gt; {
    console.log(req.requestTime);
    res.send(&#39;HOME PAGE&#39;);
});</code></pre>
<h1 id="404-경로-설정">404 경로 설정</h1>
<p>라우트 핸들러 마지막에 미들웨어를 추가하여 어떤 요청에도 매칭되지 않을 경우 동작하도록 한다.</p>
<pre><code class="language-javascript">app.get(...)
app.get(...)

app.use((req,res)=&gt;{
    res.status(404).send(&quot;Not Found&quot;);
})</code></pre>
<h1 id="미들웨어-패스워드-설정-데모">미들웨어 패스워드 설정 데모</h1>
<p>미들웨어에서 패스워드를 검사하여 일치하지 않는 패스워드일 경우 요청이 거부되도록 할 수 있다.
이를 토대로 특정 라우트에서 패스워드 확인을 하도록 할 수도 있다.</p>
<pre><code class="language-javascript">app.use((req, res, next) =&gt; {
    const { password } = req.query;
    if (password === &#39;secret&#39;) next();
    res.send(&#39;Sorry YOU NEED A PASSWORD&#39;);
});

app.get(...)</code></pre>
<h2 id="특정-라우트에서-패스워드-확인을-하는-경우">특정 라우트에서 패스워드 확인을 하는 경우</h2>
<pre><code class="language-javascript">const verifyPassword = (req, res, next) =&gt; {
    const { password } = req.query;
    if (password === &#39;secret&#39;) next();
    res.send(&#39;Sorry YOU NEED A PASSWORD&#39;);
};
//라우트 핸들러 2번째 인자에 미들웨어를 추가해주면 된다.
app.get(&#39;/&#39;, verifyPassword, (req, res) =&gt; {});</code></pre>
<h1 id="ejs-mate">ejs-mate</h1>
<p>상용구를 사용할 수 있게 해주는 툴이다.
view파일에서 &lt;% layout(&#39;layouts/boilerplate&#39;) %&gt; 로 선언하면
해당 view파일은 &lt;%- body%&gt; 여기에 들어가게 된다. 그렇게 되면 아래에
BEFORE , AFTER가 상용구가 되어 공통적으로 쓰일 수 있게 된다.</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;BOILERPLATE!!!&lt;/title&gt;
    &lt;/head&gt;
    &lt;body&gt;
        &lt;h1&gt;BEFORE&lt;/h1&gt;
        &lt;%- body%&gt;
        &lt;h1&gt;AFTER&lt;/h1&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>
<pre><code class="language-html">&lt;% layout(&#39;layouts/boilerplate&#39;) %&gt;

&lt;h1&gt;Edit Campground&lt;/h1&gt;
&lt;form action=&quot;/campgrounds/&lt;%=campground.id%&gt;?_method=PUT&quot; method=&quot;POST&quot;&gt;
    &lt;div&gt;
        &lt;label for=&quot;title&quot;&gt;Title&lt;/label&gt;
        &lt;input type=&quot;text&quot; id=&quot;title&quot; name=&quot;campground[title]&quot; value=&quot;&lt;%=campground.title%&gt;&quot; /&gt;
    &lt;/div&gt;
    &lt;div&gt;
        &lt;label for=&quot;location&quot;&gt;Location&lt;/label&gt;
        &lt;input
            type=&quot;text&quot;
            id=&quot;location&quot;
            name=&quot;campground[location]&quot;
            value=&quot;&lt;%=campground.location%&gt;&quot;
        /&gt;
    &lt;/div&gt;
    &lt;button&gt;Update Campground&lt;/button&gt;
&lt;/form&gt;
&lt;a href=&quot;/campgrounds/&lt;%=campground.id%&gt;&quot;&gt;Back To Campground&lt;/a&gt;</code></pre>
<h1 id="express-디폴트-오류-처리기">Express 디폴트 오류 처리기</h1>
<p>내장된 오류 핸들러가 앱에서 발생한 모든 오류를 처리한다.
오류 객체를 찾은 다음 상태 코드와 상태 메시지를 찾는다.
상태코드의 디폴트는 500이지만 바꿀 수 있다.</p>
<p>내장된 오류 핸들러만으로는 모든 오류를 처리할 수 없기에 다양한 유형에 대한
오류 핸들러를 추가하여야 한다.</p>
<p>예를 들면 Mongoose에서 유효성 오류가 발생한 경우 구문 오류나 인증 오류와는 다른 방법으로 처리해야한다.</p>
<h1 id="사용자-지정-오류-처리기-정의">사용자 지정 오류 처리기 정의</h1>
<pre><code class="language-javascript">app.use((err, req, res, next) =&gt; {
    console.log(&#39;ERROR!&#39;);
    res.status(500).send(&#39;Oh! Error!&#39;);
    //내장된 오류 처리기를 사용하고 싶으면 next함수 호출 이 때 인수로 err를 전달해야한다.
    //express는 next에 무언가를 전달하면 현재 요청을 오류로 간주하여 남아 있는 오류 처리에 대한 동작만 한다.
});</code></pre>
<h1 id="사용자-지정-오류-클래스">사용자 지정 오류 클래스</h1>
<p>오류에 대한 상태 코드와 메세지를 정해주는 작업을 각기 다른 상황에서 발생하는 모든 오류에 다 처리하려면 번거롭기에 이를 클래스로 만들은 것</p>
<pre><code class="language-javascript">class AppError extends Error {
    constructor(message, status) {
        super();
        this.message = message;
        this.status = status;
    }
}

const verifyPassword = (req, res, next) =&gt; {
    const { password } = req.query;
    if (password === &#39;secret&#39;) next();

    throw new AppError(&#39;password required&#39;, 401);
};

app.use((err, req, res, next) =&gt; {
    const { status = 500 } = err; //오류에 상태코드가 없을 경우 디폴트를 500으로 설정
    const { message = &#39;Something Went Wrong&#39; } = err;
    res.status(status).send(message);
});</code></pre>
<h1 id="비동기-오류-처리하기">비동기 오류 처리하기</h1>
<p>라우트 핸들러와 미들웨어에 의해 발동된 비동기 함수에서 반환된 오류의 경우에는
다음 함수로 전달하여 Express가 잡아내서 처리할 수 있게 해야 한다. 그렇지 않으면
오류 핸들러가 작동되지 않는다.</p>
<pre><code class="language-javascript">app.get(&#39;/products/:id&#39;, async (req, res, next) =&gt; {
    const product = await Product.findById(id);
    if (!product) {
        return next(new AppError(&#39;Product Not Found&#39;, 404));
    }
    //next가 호출되더라도 next다음 코드의 실행은 중단되지 않기 때문에 return이나 else로
    //정상 응답인 경우의 코드가 실행되지 않도록 해야한다.
    res.render(&#39;products/show&#39;, { product });
});</code></pre>
<h1 id="try-catch로-비동기-오류-처리">try-catch로 비동기 오류 처리</h1>
<p>비동기 함수에서는 모든 걸 try...catch 문으로 감싸야 한다.
비동기 함수일 때만 해당이 되고 다른 경우엔 Express가 처리하기에 예를 들어 new를 render할 땐
try...catch 문으로 감쌀 필요가 없다.</p>
<pre><code class="language-javascript">app.get(&#39;/products/:id&#39;, async (req, res, next) =&gt; {
    try {
        const product = await Product.findById(id);

        if (!product) {
            throw new AppError(&#39;Product Not Found&#39;, 404);
        }

        res.render(&#39;products/show&#39;, { product });
    } catch (e) {
        next(e);
    }
});</code></pre>
<h1 id="비동기-유틸리티-정의">비동기 유틸리티 정의</h1>
<p>try...catch 문을 모든 각각의 비동기 라우트 콜백 그리고 핸들러와 미들웨어 등에
일일이 추가하는 것은 번거롭기에 이를 해결하고자 wrapAsync라는 함수를 정의하여 사용한다.
이 함수는 함수를 전달받아 catch메소드를 체인하여 에러가 발생할 경우 next함수를 호출하도록 한다.</p>
<pre><code class="language-javascript">function wrapAsync(fn) {
    return function (req, res, next) {
        fn(req, res, next).catch((e) =&gt; next(e));
    };
}

app.get(
    &#39;/products/:id&#39;,
    wrapAsync(async (req, res, next) =&gt; {
        const product = await Product.findById(id);

        if (!product) {
            throw new AppError(&#39;Product Not Found&#39;, 404);
        }

        res.render(&#39;products/show&#39;, { product });
    })
);</code></pre>
<blockquote>
<p>Express 5부터 Promise를 반환하는 라우트 핸들러 및 미들웨어는 거부하거나 오류를 던질 때 자동으로 next(value) 호출 한다.</p>
</blockquote>
<blockquote>
<p>$ npm install express@next //최신 버전의 express v5 알파 버전 설치</p>
</blockquote>
<p>express5에서 비동기 오류 처리 예시</p>
<pre><code class="language-javascript">app.get(&#39;/user/:id&#39;, async function (req, res, next) {
    var user = await getUserById(req.params.id);
    res.send(user);
});</code></pre>
<h1 id="mongoose-오류-구분하기">Mongoose 오류 구분하기</h1>
<p>모든 Mongoose 오류에는 name이라는 특성이 있다. 이를 활용하여 오류 처리 미들웨어에서 오류마다 handle에러처리 함수를 호출하게할 수 있다.</p>
<ul>
<li><p>Mongoose 오류 종류</p>
<ul>
<li>ValidationError 유효성 검사 오류</li>
<li>CastError 캐스트 오류</li>
</ul>
</li>
</ul>
<pre><code class="language-javascript">const handleValidationErr=(err){
    console.dir(err)
    return new AppError(`Validation Failed...${err.message}`,400)
}


app.use((err, req, res, next) =&gt; {
    if (err.name === &#39;ValidationError&#39;) err = handleValidationErr(err);
    next(err);
});</code></pre>
<h1 id="joi">Joi</h1>
<p>자바스크립트 유효성 검사 도구이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[웹개발 부트캠프 2022 3주차(노드)]]></title>
            <link>https://velog.io/@b_m_c/%EB%85%B8%EB%93%9C</link>
            <guid>https://velog.io/@b_m_c/%EB%85%B8%EB%93%9C</guid>
            <pubDate>Thu, 12 May 2022 05:33:19 GMT</pubDate>
            <description><![CDATA[<p>(5/6 ~5/12) The Web Developer 부트캠프 2022 강의 내용 정리
범위 : 우리의 첫번째 도구 Node ~ 하나로 묶기 Express Mongoose(섹션 31 ~38)</p>
<h1 id="122-nodejs">122. Node.js</h1>
<p>Javascript 런타임이다. 즉 브라우저 밖에서 작동되는 JavaScript의 실행 환경이다.</p>
<p>덕분에 클라이언트 측 Javascript로는 브라우저에서 할 수 없었던 많은 일(웹 서비스를 만들고 파일 시스템과 상호작용 등의)들을 할 수 있게 됐다.</p>
<h1 id="123-node는-어디에-사용하나">123. Node는 어디에 사용하나</h1>
<ul>
<li>웹 서버 구축</li>
<li>명령줄 도구</li>
<li>네이티브 앱 (대표적 앱: vscode)</li>
<li>비디오 게임</li>
<li>드론 소프트웨어</li>
</ul>
<p>이처럼 브라우저를 벗어나 Javascript로 다양한 곳에 활용될 수 있다.</p>
<h1 id="124-node-repl">124. Node REPL</h1>
<blockquote>
<p>사용자가 특정 코드를 입력하면 그 코드를 평가하고 코드의 실행결과를 출력해주는 것을 반복해주는 환경</p>
</blockquote>
<p>터미널 또는 cmd창에서 node를 입력하면
REPL환경으로 접속이 가능하다.</p>
<p>REPL환경에서 간단한 연산, 함수 사용, 변수 활용등 테스트가 가능하고 바로 결과가 확인이 가능하다.</p>
<h1 id="125-node-파일-실행">125. Node 파일 실행</h1>
<blockquote>
<p>node /경로/파일명</p>
</blockquote>
<h1 id="126-process와-argv">126. process와 argv</h1>
<h2 id="process">process</h2>
<p>process는 Node에서 사용하는 객체이다.</p>
<p>RELP환경에서 process를 치면 메서드와 특성이 매우 많다.</p>
<p>예를 들면 아래같은 것들이 있다.</p>
<ul>
<li>process.version node버전</li>
<li>process.cwd() 현재 작업 디렉토리</li>
<li>process.argv node로 스크립트 실행 시 넘겨준 인수들에 대한 정보</li>
</ul>
<h2 id="processargv">process.argv</h2>
<p>스크립트 실행 시 넘겨준 인수들에 대한 정보</p>
<pre><code>node test.js hi</code></pre><pre><code class="language-javascript">console.log(process.argv[0]); //node 실행파일 경로
console.log(process.argv[1]); //스크립트 파일 경로
console.log(process.argv[2]); //hi 출력

//인수를 만든다면 argv 처음 요소 2개는 무시

const args = process.argv.slice(2);
for (let arg of args) {
    console.log(arg);
}</code></pre>
<h1 id="127-require">127. require</h1>
<ul>
<li>CommonJS를 사용</li>
<li>모듈을 로드하는 키워드</li>
</ul>
<pre><code class="language-javascript">//파일 시스템 모듈 사용 예제
const fs = require(&#39;fs&#39;);
const folderName = process.argv[2] || &#39;Project&#39;;

try {
    fs.mkdirSync(folderName);
    fs.writeFileSync(`${folderName}/index.html`, &#39;&#39;);
    fs.writeFileSync(`${folderName}/app.js`, &#39;&#39;);
    fs.writeFileSync(`${folderName}/style.css`, &#39;&#39;);
} catch (e) {
    console.log(&#39;SOMETHING WRONG!&#39;);
    console.log(e);
}</code></pre>
<h1 id="128-import">128. import</h1>
<ul>
<li>ES6에서만 사용</li>
<li>모듈 로드하는 키워드</li>
</ul>
<pre><code class="language-javascript">import fs from &#39;fs&#39;;</code></pre>
<h1 id="129-모듈-내보내기">129. 모듈 내보내기</h1>
<p>서로 다른 파일간에 Javascript 코드를 공유하는데 사용</p>
<h2 id="moduleexports">module.exports</h2>
<p>module.exports객체에 설정을 하면 다른 파일에서 require키워드를 통해 module.exports에 설정된 값에 액세스할 수 있다.</p>
<pre><code class="language-javascript">//math.js

const add = (x, y) =&gt; x + y;

module.exports.add = add;</code></pre>
<pre><code class="language-javascript">//app.js
const math = require(&#39;./math&#39;);
//구조분해도 가능하다
const { add, PI } require(&#39;./math&#39;);

math.add(2, 3);</code></pre>
<h2 id="exports">exports</h2>
<p>module.exports 단축 구문
exports는 module.exports객체를 참조한다.
exports 자체에 새로운 값을 넣으면 module.exports객체를 참조하지 않게 되므로 주의</p>
<pre><code class="language-javascript">//math.js
exports.add = function (x, y) {
    x + y;
};

//app.js
const math = require(&#39;./math&#39;);
//구조분해도 가능하다
const { add } = require(&#39;./math&#39;);

math.add(2, 3);</code></pre>
<blockquote>
<p>ES6에서는 import키워드를 통해 모듈을 load하고 export 키워드를 통해 객체를 내보낸다.</p>
</blockquote>
<h2 id="named-export">named export</h2>
<pre><code class="language-javascript">//math.js

export const add = (x, y) =&gt; {
    x + y;
};

exports.print = (x) =&gt; {
    console.log(x);
};

//app.js
import { add, print } from &#39;./math.js&#39;;
print(add(1, 2)); // 3 출력</code></pre>
<h2 id="default-export">default export</h2>
<p>내보낼 하나의 고정된 값만 내보낼 때 사용</p>
<pre><code class="language-javascript">//math.js
const test = &#39;test&#39;;
export default test;
//app.js
import test from &#39;./test&#39;;</code></pre>
<h2 id="indexjs-활용">index.js 활용</h2>
<p>디렉토리 전체를 불러오라고 하면 Node가 index 파일을 찾게 되고 해당 파일이 내보내는 게 바로 그 디렉토리가 내보내는 항목이 됨</p>
<ul>
<li><p>일종의 진입점으로 활용</p>
</li>
<li><p>디렉토리에서의 메인 파일</p>
</li>
<li><p>라이브러리를 만들거나 라이브러리로 작업을 할 때 중요한 역할을 함</p>
</li>
</ul>
<pre><code class="language-javascript">/*
shelter라는 디렉토리 안에 blue.js janet.js sadie.js
3개의 파일에서 각각 객체를 내보냄
이를 index.js에서 배열로 저장하여
내보내고 app.js에서 불러오는 예제임
*/
//blue.js
exports default {
    name:&#39;blue&#39;,
    color:&#39;grey&#39;
}

//janet.js
exports default {
    name:&#39;janet&#39;,
    color:&#39;gray&#39;
}
//sadie.js
exports default {
    name:&#39;sadie&#39;,
    color:&#39;silver&#39;
}
//index.js
import blue from &quot;./blue.js&quot;
import janet from &quot;./janet.js&quot;
import sadie from &quot;./sadie.js&quot;

exports const allCats=[blue,janet,sadie]

//app.js
import cats from &quot;./index.js&quot;</code></pre>
<h1 id="130-npm">130. NPM</h1>
<p>노드 패키지 매니저로 패키지(모듈)들을 손쉽게 설치하고 관리할 수 있게 해주는 명령줄 도구임</p>
<pre><code>npm install 패키지명
npm i 패키지명</code></pre><p>이렇게 설치되는 패키지는 node_modules 디렉토리에 위치하게된다.</p>
<h2 id="packagejson">package.json</h2>
<p>특정 프로젝트, 패키지, 앱에 대한 정보를 갖고 있음</p>
<p>패키지를 설치하게 되면 패키지에 대한 디펜던시(설치할 모듈 정보)가 추가됨</p>
<p>npm_modules 디렉토리는 파일의 양이 많으므로 이 폴더를 공유하는 것은 바람직하지 않다. 때문에 디펜던시 정보를 토대로 프로젝트의 모듈들을 한 번에 다운로드하는 방식을 사용한다.</p>
<p>script라는 것도 있는데 이것은 run 명령어를 통해서 실행할 것들을 적어두는 것이다.</p>
<pre><code>npm init //package.json파일 생성
npm i // 디펜던시에 기록된 모듈들 install</code></pre><h2 id="package-lockjson">package-lock.json</h2>
<p>node_modules 디렉토리의 콘텐츠에 대한 기록을 관리</p>
<p>의존성 트리에 대한 정보를 가지고 있으며 package-lock.json 파일이 작성된 시점의 의존성 트리가 다시 생성될 수 있도록 보장한다.</p>
<p>이 파일이 없다면 package.json에
A라는 모듈이 업데이트된 버전이 있다면
그 버전을 설치하기 때문에 프로젝트를 공유한 사람끼리 다른 버전의 모듈을 사용할 수 있게됨. 이 때문에 똑같은 버전의 모듈을 사용하도록 보장하는 것이 필요하다.</p>
<h2 id="패키지-지역-설치">패키지 지역 설치</h2>
<pre><code>npm install 패키지명</code></pre><p>지역 설치를 하는 이유는 버전마다 호환되는 환경이 다르거나 프로젝트마다 사용되는 패키지가 다를 수 있기 때문이다.</p>
<h2 id="패키지-전역-설치">패키지 전역 설치</h2>
<pre><code>npm install -g 패키지명</code></pre><h1 id="131-express">131. Express</h1>
<p>웹 개발 프레임워크로써
서버 역할을 하는 웹 어플리케이션을 만드는데 사용한다.</p>
<blockquote>
<p>프레임워크란 다양한 메서드, 애드온과 플러그인을 제공하여 Application개발을 위한 기본적인 뼈대를 제공해준다. 또한 제어의 역전으로 사용자로 하여금 코드를 어디서, 언제 호출할지를 강제한다.</p>
</blockquote>
<ul>
<li>코드의 유연성과 자유를 어느정도 감수하고 빠른 개발 속도와 다양한 기능을 사용하기 위해 프레임워크를 사용함</li>
</ul>
<pre><code>npm i express</code></pre><h2 id="간단한-서버-만들기">간단한 서버 만들기</h2>
<pre><code class="language-javascript">import express from &#39;express&#39;;
//app 객체에는 route, param path, get, post, setting등의 메소드나 정보가 들어있다.
const app = express();

//8080포트로 요청을 받도록 함
app.listen(8080, () =&gt; {
    console.log(&#39;LISTENING ON PORT 8080!&#39;);
});

//모든 요청타입에 대해 요청이 들어오면 콜백이 실행됨
app.use(() =&gt; {
    console.log(&#39;WE GOT A NEW REQUEST&#39;);
});</code></pre>
<blockquote>
<p>요청 타입으론 get, post, put, delete, patch가 있다.</p>
</blockquote>
<blockquote>
<p>HTTP 요청은 JAVASCRIPT 객체가 아닌 텍스트 정보이다. express에서는 이를 파싱하여 객체로 변환하여 콜백의 첫번 째 인수로 넘긴다.</p>
</blockquote>
<pre><code class="language-javascript">//req- 요청 객체
//res- 응답 객체
app.use(&#39;요청 url&#39;, (req, res) =&gt; {
    //요청에 대한 동작
    console.log(&#39;WE GOT A NEW REQUEST&#39;);
    //응답
    res.send(&#39;Hello, We got Your Request!&#39;);
});</code></pre>
<h1 id="132-라우팅">132. 라우팅</h1>
<p>요청과 요청된 경로를 가져와서
응답을 갖는 어떠한 코드에 맞추는 것을 의미한다.</p>
<pre><code class="language-javascript">//dogs로 요청할 경우
app.get(&#39;/dogs&#39;, (req, res) =&gt; {
    res.send(&#39;WOOF!&#39;);
});

//cats로 요청할 경우
app.get(&#39;/cats&#39;, (req, res) =&gt; {
    res.send(&#39;MEOW!&#39;);
});

/*요청 URL을 제네릭 패턴으로 하면
일치하는 요청경로 및 요청타입이 없을 경우 콜백이 실행된다.
이 경우 맨 밑에 둬야 다른 요청들에 대해 콜백을 수행하게 된다*/
app.get(&#39;*&#39;, (req, res) =&gt; {
    res.send(&quot;I don&#39;t know that path!&quot;);
});</code></pre>
<h1 id="133-express-경로-매개-변수">133. express 경로 매개 변수</h1>
<pre><code class="language-javascript">//요청 url 뒤에 /:매개 변수로 작성하면 params를 통해 매개변수를 받을 수 있다.
app.get(&#39;/r/:subreddit/:postId&#39;, (req, res) =&gt; {
    const { subreddit, postId } = req.params;
    res.send(&#39;subreddit:&#39;, subreddit, &#39;postId:&#39;, postId);
});</code></pre>
<h1 id="134-쿼리-스트링">134. 쿼리 스트링</h1>
<p>URL의 뒤에 입력 데이터를 함께 제공하는 데이터 전달 방법
req객체의 query라는 특성에 key-value값으로 들어간다.
GET방식으로 데이터를 요청할 때 쓰이는 방법</p>
<pre><code class="language-javascript">//요청 url /search?q=&quot;test&quot;&amp;n=&quot;test&quot;
app.get(&#39;/search&#39;, (req, res) =&gt; {
    const { q, t } = req.query;
    res.send(`q:${q}t:{t}`);
});</code></pre>
<h1 id="135-nodemon">135. Nodemon</h1>
<p>서버를 재시작하지 않고 변경된 부분을 자동으로 업데이트 해주는 도구</p>
<h1 id="136-템플레이팅">136. 템플레이팅</h1>
<p>특정 로직과 HTML 응답 생성을 결합하는 것</p>
<p>항상 같은, 정적인 HTML 코드를 쓰는 대신에 정보와 로직을 넣음으로써 동적인 템플릿을 만듬</p>
<blockquote>
<p>템플릿 : HTML 조각</p>
</blockquote>
<h1 id="137-ejs">137. EJS</h1>
<p>Embedded JavaScriptd의 약자로 템플릿 엔진(뷰 엔진) 중의 하나이며 Javascripts 로직을 템플릿에서 동작하게 해준다.</p>
<h2 id="view-engine-설정">view engine 설정</h2>
<pre><code class="language-javascript">app.set(&#39;view&#39;, &#39;ejs&#39;); // view engine 설정</code></pre>
<h2 id="view-디렉토리-설정">view 디렉토리 설정</h2>
<p>view 디렉토리 default값은 현재 작업하고 있는 디렉토리의 views이다.
따라서 view 디렉토리 설정을 하지 않으면 views가 없는 디렉토리에서 서버를 동작시키면 views 디렉토리를 찾지 못한다.</p>
<pre><code class="language-javascript">app.set(&#39;views&#39;, path.join(__dirname, &#39;/views&#39;)); //views폴더의 절대 경로</code></pre>
<h1 id="138-ejs-문법">138. EJS 문법</h1>
<h2 id="-">&lt;% %&gt;</h2>
<p>EJS 태그로 태그 사이에 자바스크립트를 넣는다.</p>
<h2 id="--1">&lt;%= %&gt;</h2>
<p>EJS 태그로 태그 사이에 받을 데이터의 변수명 또는 반환되는 값이 있는 자바스크립트문을(Math.rand()같은 것) 넣으면 된다.</p>
<blockquote>
<p>res.render(&quot;&quot;,&quot;&quot;) 첫 번째 인수에는 렌더링할 파일명, 두 번째 인수에는 템플릿에 같은 이름으로해서 값을 주면 템플릿에서 해당 값을 읽을 수 있다.</p>
</blockquote>
<h2 id="--">&lt;%- %&gt;</h2>
<p>HTML 코드를 날것(Raw)로 보여준다.
템플릿을 include할 때 사용</p>
<pre><code class="language-javascript">//app.js

app.get(&#39;/&#39;, (req, res) =&gt; {
    const num = Math.floor(Math.random() * 5);
    res.render(&#39;random&#39;, { rand: num }); // 렌더링할 ejs파일명, 넘길 값들
});</code></pre>
<pre><code class="language-html">&lt;body&gt;
    &lt;h1&gt;&lt;%=&quot;Math.floor(Math.random()*5)%&gt;&lt;/h1&gt;
    &lt;p&gt;&lt;%=rand%&gt;&lt;/p&gt;
    &lt;%-
    &lt;h1&gt;&lt;/h1&gt;
    %&gt;
&lt;/body&gt;
//0~5이하 자연수</code></pre>
<h2 id="ejs-조건문">EJS 조건문</h2>
<pre><code class="language-html">&lt;body&gt;
    &lt;%if(rand&gt;0){ %&gt;console.log(&quot;good&quot;) &lt;% } else{ %&gt; console.log(&quot;Not bad&quot;) &lt;%}%&gt;
&lt;/body&gt;</code></pre>
<h2 id="ejs-반복문">EJS 반복문</h2>
<pre><code class="language-html">&lt;body&gt;
    &lt;%for(i=0;i&lt;5;i++){%&gt; console.log(&lt;%=i%&gt;) &lt;%}%&gt;
&lt;/body&gt;</code></pre>
<h1 id="139-정적-assets-사용하기">139. 정적 Assets 사용하기</h1>
<h2 id="정적-assets">정적 Assets</h2>
<p>CSS,JAVASCRIPT,사진 같은 파일</p>
<pre><code class="language-javascript">//public 디렉토리를 정적 Assets의 base로 설정
app.use(express.static(&#39;public&#39;));

//public의 절대경로로 설정
app.use(express.static(path.join(__dirname), &#39;public&#39;));</code></pre>
<pre><code class="language-html">//app.css가 public 에 있을 경우 public경로 없이 사용 가능 &lt;link rel=&quot;stylesheet&quot; href=&quot;/app.css&quot; /&gt;</code></pre>
<h1 id="140-ejs와-파일-분할">140. EJS와 파일 분할</h1>
<p>&lt;%-include %&gt; 태그를 활용하여
head,navbar,footer 등등 템플릿을 포함시킬 수 있다.</p>
<pre><code class="language-html">//head.ejs
&lt;body&gt;
    &lt;h1&gt;head&lt;/h1&gt;
&lt;/body&gt;</code></pre>
<pre><code class="language-html">//home.ejs &lt;%- include(&#39;partials/head&#39;)&gt;

&lt;body&gt;
    &lt;h1&gt;home&lt;/h1&gt;
&lt;/body&gt;</code></pre>
<pre><code class="language-javascript"></code></pre>
<h1 id="141-get-요청과-post-요청">141. Get 요청과 Post 요청</h1>
<h2 id="get요청">Get요청</h2>
<ul>
<li>주로 정보를 가져올 때 (불러오기)</li>
<li>같이 따라오는 데이터는 쿼리스트링에 담는다.</li>
<li>URL의 최대길이가 있어 보낼 데이터가 한정된다.</li>
</ul>
<h2 id="post-요청">Post 요청</h2>
<ul>
<li>주로 정보를 올리거나 보낼 때(생성)</li>
<li>보낼 데이터는 Body에 포함된다.</li>
<li>길이가 제한된 Get방식보다 더 많은 데이터 보내기 가능</li>
<li>Body에 보내지는 데이터의 타입은 JSON,application/x-www-form-urlencoded, multipart/form-data등이 있다.</li>
</ul>
<h2 id="요청-구문-분석">요청 구문 분석</h2>
<pre><code>//body

{
    &quot;name&quot;:&quot;test&quot;,
    &quot;color&quot;:&quot;brown&quot;,
}
</code></pre><pre><code class="language-javascript">//form request body를 해석하기 위해 사용
app.use(express.urlencoded({ extended: true }));

//json 타입의 body를 해석하기 위해 사용
app.use(express.json())

app.post(&quot;/&quot;,(req,res){
    const {name,color} = req.body
})</code></pre>
<blockquote>
<p>extended 값을 false로 하면 querystring모듈을 사용
true로 하면 qs모듈을 사용</p>
</blockquote>
<h1 id="142-rest">142. REST</h1>
<p>REST(Representational State Transfer)의 약자로 자원을 이름으로 구분하여 해당 자원의 상태를 주고받는 모든 것을 의미</p>
<p>즉 요청 URI에 자원을 명시하고 HTTP Method를 통해 해당 자원에 대해 CURD를 적용하는 것을 의미</p>
<h1 id="143-restful-api">143. RESTful API</h1>
<p>URI + HTTP METHOD + 필요시 id나 고유 식별자를 사용하여 정보 교환을 하는 것</p>
<blockquote>
<p>HTTP METHOD(GET,POST,PATCH,DELETE,PUT)
GET /comments - list all comments
POST /comments - Create a new comment
GET /comments/:id -Get one comment(using ID)
PATCH /comments/:id -Update one comment
DELETE /comments/:id -Destroy one comment</p>
</blockquote>
<h1 id="144-express-redirect">144. Express redirect</h1>
<p>초기 응답에서 전송된 위치를 기반으로 두 번째 요청을 이어서 하게 한다.
res.redirect(&quot;요청 url&quot;)</p>
<h1 id="145-디테일-라우트-쇼-라우트">145. 디테일 라우트 (쇼 라우트)</h1>
<p>고유식별자를 활용하여 특정한 하나의 리소스에 대해 보여주는 것</p>
<p>경로 끝에 고유 식별자값을 넣으면 req.params에 값을 들어간다.</p>
<pre><code class="language-javascript">app.get(&#39;/comments/:id&#39;, (req, res) =&gt; {
    const { id } = req.params;
});</code></pre>
<h1 id="146-uuid">146. UUID</h1>
<p>범용 고유 식별자이다.</p>
<ul>
<li>데이터들이 나중에 단일 DB로 통합되더라도
식별자가 중복될 확률이 매우 낮다.</li>
<li>128비트이며, 32자리의 16진수로 표현</li>
<li>8자리-4자리-4자리-4자리-12자리 패턴으로 5개의 그룹으로 구분된다.</li>
<li>UUID를 만드는 버전에 따라 생성 기준이 다르다.(보통 4버전인 랜덤 생성을 사용한다.)</li>
</ul>
<pre><code class="language-javascript">//구조분해시 새로운 이름 명명
import { v4 as uuidv4 } from &#39;uuid&#39;;
const id = uuidv4();
console.log(id); //1944cc80-c239-4394-9f5f-9341f8f9945f</code></pre>
<h1 id="147-patch와-put">147. PATCH와 PUT</h1>
<h2 id="put">PUT</h2>
<p>전체 내용을 업데이트하는 용도</p>
<p>보내지지 않은 페이로드에 대해선 NULL값으로 업데이트</p>
<h2 id="patch">PATCH</h2>
<p>부분적으로 업데이트하는 용도</p>
<p>보내지지 않은 페이로드에 대해선 기존 값을 유지</p>
<h1 id="148-express-method-override">148. express method override</h1>
<p>브라우저의 HTML 폼은 get이나 post 요청만
전송할 수 있어서 Put 요청이나 Patch 요청 Delete 요청은 보낼 수 없다. 이 경우 method-override라는 패키지를 활용하여 우회하는 형식으로 가능하게 할 수 있다.</p>
<pre><code class="language-javascript">import methodOverride from &#39;method-override&#39;;
app.use(methodOverride(&#39;_method&#39;));

app.patch(&#39;/comments/:id&#39;, (req, res) =&gt; {});</code></pre>
<pre><code class="language-html">&lt;body&gt;
    //?_method부분으로 인해 patch요청으로 express가 인식함
    &lt;form method=&quot;post&quot; action=&quot;/comments/&lt;%=comment.id%&gt;/?_method=PATCH&quot;&gt;&lt;/form&gt;
&lt;/body&gt;</code></pre>
<h1 id="149-데이터베이스-개요">149. 데이터베이스 개요</h1>
<ul>
<li>데이터 지속성</li>
<li>데이터를 효율적으로 저장, 사용, 관리하기 쉽게 해준다.</li>
<li>데이터베이스 관리시스템으로 보안 기능이나 관리자로서의 접근을 누구에게 허용할지에 대한 제어가 가능하다.</li>
</ul>
<h1 id="150-sql-nosql">150. SQL, NOSQL</h1>
<h2 id="sql">SQL</h2>
<ul>
<li>관계형 데이터베이스</li>
<li>모든 작업이 테이블에서 이루어진다.</li>
<li>테이블과 테이블을 연결하여 작업한다.</li>
</ul>
<h2 id="nosql">NoSQL</h2>
<ul>
<li><p>특정한 패턴을 따르거나 X, Y를 따지느냐를 보아 그렇지 않은 건 전부 다 NoSQL</p>
</li>
<li><p>키 값 쌍도 있고 칼럼 데이터베이스도 있고
그래프 데이터베이스, 문서 데이터베이스와 튜플 저장소가 있다.</p>
</li>
<li><p>SQL에 비해 유연하고 자유롭다.</p>
</li>
</ul>
<h1 id="151-mongo">151. Mongo</h1>
<ul>
<li>NoSQL</li>
<li>배우기 쉽다.</li>
<li>express와 같이 많이 쓰인다.</li>
<li>Javascript 구문을 쓴다.</li>
</ul>
<h1 id="152-mongo-shell">152. Mongo Shell</h1>
<p>Javascript Shell이라 Javascript 코드 입력 가능</p>
<h2 id="db-명령어">db 명령어</h2>
<p>디폴트로 사용하게 될 데이터베이스</p>
<h2 id="show-dbsdatabases">show dbs(databases)</h2>
<p>데이터베이스 목록</p>
<h2 id="use-데이터베이스명">use 데이터베이스명</h2>
<p>없으면 데이터베이스 생성 있으면 db 전환</p>
<blockquote>
<p>Mongo db는 데이터베이스를 생성해도 실제 저장할 데이터가 있을 때까지 대기한다. 따라서
show dbs를 했을 때 생성한 db가 출력되지 않는다.</p>
</blockquote>
<h1 id="153-bson이란">153. BSON이란</h1>
<p>이진법 JSON이다. JSON보다 데이터를 훨씬 더 압축하여 저장할 수 있다.</p>
<p>JSON의 문제는 홈페이지나 문서에 들어갈 때
상당히 느려서 Mongo에선 JSON을 이진법으로 인코딩한 BSON을 사용한다.</p>
<h1 id="154-mongo-데이터베이스에-삽입">154. Mongo 데이터베이스에 삽입</h1>
<p>insertOne(하나의 객체만을 전달), insertMany(여러 객체 전달), insert(하나 또는 여러개 객체 전달) 세 가지 메소드가 있다.</p>
<pre><code class="language-javascript">db.dogs.insertOne({
    name: &#39;Charlie&#39;,
    age: 3,

    breed: &#39;corgi&#39;,
    catFriendly: true,
});

//아래처럼 뜨면 삽입되었음을  의미
{
&quot;acknowledged&quot; : true,
&quot;insertedId&quot; : ObjectId(&quot;627bf7a4491e7e80fb01fa6f&quot;)
}

//2개 객체 삽입
db.dogs.insert([{name: &quot;Wyatt&quot;,

breed: &quot;Golden&quot;,age: 14, catFriendly: false},{name: &quot;Tonya&quot;,

breed: &quot;Chihuahua&quot;,age:17, catFriendly: true}])

//아래처럼 뜨면 2개 모두 삽입되었음을 의미
BulkWriteResult({
        &quot;writeErrors&quot; : [ ],
        &quot;writeConcernErrors&quot; : [ ],
        &quot;nInserted&quot; : 2,
        &quot;nUpserted&quot; : 0,
        &quot;nMatched&quot; : 0,
        &quot;nModified&quot; : 0,
        &quot;nRemoved&quot; : 0,
        &quot;upserted&quot; : [ ]
})</code></pre>
<h1 id="155-mongo-데이터베이스에서-찾기">155. Mongo 데이터베이스에서 찾기</h1>
<p>find, findOne</p>
<pre><code class="language-javascript">
db.dogs.find() //해당 집합에 있는 객체 모두 출력

{ &quot;_id&quot; : ObjectId(&quot;627bf7a4491e7e80fb01fa6f&quot;), &quot;name&quot; : &quot;Charlie&quot;, &quot;age&quot; : 3, &quot;breed&quot; : &quot;corgi&quot;, &quot;catFriendly&quot; : true }
{ &quot;_id&quot; : ObjectId(&quot;627bf938491e7e80fb01fa70&quot;), &quot;name&quot; : &quot;Wyatt&quot;, &quot;breed&quot; : &quot;Golden&quot;, &quot;age&quot; : 14, &quot;catFriendly&quot; : false }
{ &quot;_id&quot; : ObjectId(&quot;627bf938491e7e80fb01fa71&quot;), &quot;name&quot; : &quot;Tonya&quot;, &quot;breed&quot; : &quot;Chihuahua&quot;, &quot;age&quot; : 17, &quot;catFriendly&quot; : true }


db.dogs.find({&quot;name&quot;:&quot;Tonya&quot;})

{ &quot;_id&quot; : ObjectId(&quot;627bf938491e7e80fb01fa71&quot;), &quot;name&quot; : &quot;Tonya&quot;, &quot;breed&quot; : &quot;Chihuahua&quot;, &quot;age&quot; : 17, &quot;catFriendly&quot; : true }</code></pre>
<h1 id="156-mongo-데이터베이스에서-업데이트">156. Mongo 데이터베이스에서 업데이트</h1>
<p>updateOne(매치되는 첫 항목만), updateMany(모두), replaceOne(document의 특정 내용 완전히 대체)</p>
<pre><code class="language-javascript">//첫 번째 인자는 선택자, 두 번째 인자는 업데이트할 값
//$set는 필드의 값을 새로운 값으로 대체할 때 사용
db.dogs.updateOne({ name: &#39;charlie&#39; }, { $set: { age: 4 } });

//업데이트 성공
{ &quot;acknowledged&quot; : true, &quot;matchedCount&quot; : 0, &quot;modifiedCount&quot; : 0 }

//없는 특성을 추가하면 객체에 추가됨
db.dogs.updateOne({ name: &#39;charlie&#39; }, { $set: { color: &quot;brown&quot; } })

db.dogs.updateMany({catFriendly:true},{$set:{isAvailable:false}})
//2건 모두 성공
{ &quot;acknowledged&quot; : true, &quot;matchedCount&quot; : 2, &quot;modifiedCount&quot; : 2 }

//$currentDate는 날짜 업데이트에 사용 true값이면 현재 날짜로 설정
db.dogs.updateOne({ name: &#39;charlie&#39; }, { $currentDate: { lastChanged: true } })

{ &quot;_id&quot; : ObjectId(&quot;627bf7a4491e7e80fb01fa6f&quot;), &quot;name&quot; : &quot;Charlie&quot;, &quot;age&quot; : 3, &quot;breed&quot; : &quot;corgi&quot;, &quot;catFriendly&quot; : true, &quot;isAvailable&quot; : false, &quot;lastChanged&quot; : ISODate(&quot;2022-05-11T18:16:47.596Z&quot;) }
</code></pre>
<h1 id="157-mongo-데이터베이스에서-삭제">157. Mongo 데이터베이스에서 삭제</h1>
<p>deleteMany, deleteOne 사용</p>
<pre><code class="language-javascript">db.dogs.deleteMany({ isAvailable: false });

//삭제됨
{ &quot;acknowledged&quot; : true, &quot;deletedCount&quot; : 2 }

//다 삭제시킴
db.dogs.deleteMany({})

//$or, $lt  연산자를 사용하여 조건을 추가로 줄 수 있음</code></pre>
<h1 id="158-기타-연산자">158. 기타 연산자</h1>
<p>중첩된 특성을 찾으려면 따옴표를 쓰고 dot 구문을 써야한다.</p>
<pre><code class="language-javascript">db.dogs.find({ &#39;personality.catFriendly&#39;: true });

//gt 초과인 값
db.dogs.find({ age: { $gt: 8 } });
//gte 이상인 값
db.dogs.find({ age: { $gte: 8 } });
//lt 미만인 값
db.dogs.find({ age: { $lt: 8 } });
//lte 이하인 값
db.dogs.find({ age: { $lte: 8 } });
//in 배열 검색 (하나라도 충족하면 검색)
db.dogs.find({ breed: { $in: [&#39;Mutt&#39;, &#39;Corgi&#39;] } });
//ne 일치하지 않는 값
db.dogs.find({ breed: { $ne: &#39;Mutt&#39; } });
//nin 배열에 없는 객체 검색
db.dogs.find({ breed: { $in: [&#39;Mutt&#39;, &#39;Corgi&#39;] } });

//$and,$not,$nor,$or 연산자도 있음</code></pre>
<h1 id="159-mongoose란">159. Mongoose란</h1>
<p>Express 앱이나 Node 앱을 Mongo와 연결하는데 사용되는 드라이버이다.</p>
<p>ODM(Object Data Mapper) 즉, 객체 데이터 매퍼로 데이터나 문서를 JavaScript 객체로 매핑한다.</p>
<p>사전에 프리셋 스키마 정의하여 데이터가 레이아웃된 스키마를 따르도록 강제할 수 있음</p>
<p>복잡한 쿼리를 만들 수 있도록 도와줌</p>
<h2 id="node-mongo연결">node-mongo연결</h2>
<pre><code class="language-javascript">import mongoose from &#39;mongoose&#39;;
main()
    .then(() =&gt; {
        console.log(&#39;CONNECTED!&#39;);
    })
    .catch((err) =&gt; console.log(err));

async function main() {
    await mongoose.connect(&#39;mongodb://localhost:27017/movieApp&#39;);
}

// node RELP에서 .load할 경우엔 이렇게 연결해주어야 한다.
let { mongoose } = await import(&#39;mongoose&#39;);
main()
    .then(() =&gt; {
        console.log(&#39;CONNECTED!&#39;);
    })
    .catch((err) =&gt; console.log(err));

async function main() {
    await mongoose.connect(&#39;mongodb://localhost:27017/movieApp&#39;);
}

</code></pre>
<h1 id="160-스키마">160. 스키마</h1>
<p>JavaScript 파일에서 데이터를 사용하거나 접근하려면 각 데이터를 정의하는 모델을 만들어야한다. 이 정의서가 스키마이다.</p>
<pre><code class="language-javascript">//스키마 생성
const movieSchema = new Mongoose.Schema({
    title: String,
    year: Number,
    score: Number,
    rating: String,
});

//movie 클래스 만듬
const Movie = mongoose.model(&#39;Movie&#39;, movieSchema);

//db에는 저장되지 않은 상태 
const amadeus = new Movie({ title: &#39;Amadeus&#39;, year: 1986, score: 9.2, rating: &#39;R&#39; });

//db에 저장
amadeus.save();
/*
mongo shell에서 저장됨을 확인
{ &quot;_id&quot; : ObjectId(&quot;627c5b2c569309a9c73b5602&quot;), &quot;title&quot; : &quot;Amadeus&quot;, &quot;year&quot; : 1986, &quot;score&quot; : 9.2, &quot;rating&quot; : &quot;R&quot;, &quot;__v&quot; : 0 }
 */

</code></pre>
<h1 id="161-대량-삽입하기">161. 대량 삽입하기</h1>
<pre><code class="language-javascript">const amadeus = new Movie({
  title: &quot;Amadeus&quot;,
  year: 1986,
  score: 9.2,
  rating: &quot;R&quot;,
});

//db에 저장
amadeus.save();
/*
mongo shell에서 저장됨을 확인
{ &quot;_id&quot; : ObjectId(&quot;627c5b2c569309a9c73b5602&quot;), &quot;title&quot; : &quot;Amadeus&quot;, &quot;year&quot; : 1986, &quot;score&quot; : 9.2, &quot;rating&quot; : &quot;R&quot;, &quot;__v&quot; : 0 }
 */

//insertMany메소드는 save하지 않아도 데이터베이스에 저장된다.
Movie.insertMany([
  { title: &quot;Amelie&quot;, year: 2001, score: 8.3, rating: &quot;R&quot; },
  { title: &quot;Alien&quot;, year: 1979, score: 7.5, rating: &quot;R&quot; },
  { title: &quot;The Iron Giant&quot;, year: 1986, score: 8.6, rating: &quot;R&quot; },
  { title: &quot;Moonrise Kingdom&quot;, year: 2012, score: 7.3, rating: &quot;PG-13&quot; },
]);

/* 
mongo shell에서 저장된 것을 확인할 수 있음
&gt; db.movies.find()
{ &quot;_id&quot; : ObjectId(&quot;627c57e59a049e1b03b869e4&quot;), &quot;title&quot; : &quot;Amelie&quot;, &quot;year&quot; : 2001, &quot;score&quot; : 8.3, &quot;rating&quot; : &quot;R&quot;, &quot;__v&quot; : 0 }
{ &quot;_id&quot; : ObjectId(&quot;627c57e59a049e1b03b869e5&quot;), &quot;title&quot; : &quot;Alien&quot;, &quot;year&quot; : 1979, &quot;score&quot; : 7.5, &quot;rating&quot; : &quot;R&quot;, &quot;__v&quot; : 0 }
{ &quot;_id&quot; : ObjectId(&quot;627c57e59a049e1b03b869e6&quot;), &quot;title&quot; : &quot;The Iron Giant&quot;, &quot;year&quot; : 1986, &quot;score&quot; : 8.6, &quot;rating&quot; : &quot;R&quot;, &quot;__v&quot; : 0 }
{ &quot;_id&quot; : ObjectId(&quot;627c57e59a049e1b03b869e7&quot;), &quot;title&quot; : &quot;Moonrise Kingdom&quot;, &quot;year&quot; : 2012, &quot;score&quot; : 7.3, &quot;rating&quot; : &quot;PG-13&quot;, &quot;__v&quot; : 0 }
{ &quot;_id&quot; : ObjectId(&quot;627c593d5b6ad45e3981881b&quot;), &quot;title&quot; : &quot;Amelie&quot;, &quot;year&quot; : 2001, &quot;score&quot; : 8.3, &quot;rating&quot; : &quot;R&quot;, &quot;__v&quot; : 0 }
{ &quot;_id&quot; : ObjectId(&quot;627c593d5b6ad45e3981881c&quot;), &quot;title&quot; : &quot;Alien&quot;, &quot;year&quot; : 1979, &quot;score&quot; : 7.5, &quot;rating&quot; : &quot;R&quot;, &quot;__v&quot; : 0 }
{ &quot;_id&quot; : ObjectId(&quot;627c593d5b6ad45e3981881d&quot;), &quot;title&quot; : &quot;The Iron Giant&quot;, &quot;year&quot; : 1986, &quot;score&quot; : 8.6, &quot;rating&quot; : &quot;R&quot;, &quot;__v&quot; : 0 }
{ &quot;_id&quot; : ObjectId(&quot;627c593d5b6ad45e3981881e&quot;), &quot;title&quot; : &quot;Moonrise Kingdom&quot;, &quot;year&quot; : 2012, &quot;score&quot; : 7.3, &quot;rating&quot; : &quot;PG-13&quot;, &quot;__v&quot; : 0 } 
*/</code></pre>
<h1 id="162-mongoose로-찾기">162. Mongoose로 찾기</h1>
<pre><code class="language-javascript">const Movie = mongoose.model(&quot;Movie&quot;, movieSchema);

//node REPL에서
Movie.find({ rating: &quot;R&quot; }).then((data) =&gt; {
  console.log(data);
});

Movie.findById({ id: &quot;59ws9i2o030&quot; }).thein((data) =&gt; {
  console.log(data);
});</code></pre>
<blockquote>
<p>쿼리를 실행하는 방법은 2가지가 있다.</p>
</blockquote>
<ul>
<li>1.콜백 함수를 넘기기</li>
<li>2 .exec()으로 Promise같이 쓰기</li>
</ul>
<h2 id="exec-옵션">exec 옵션</h2>
<blockquote>
<p>쿼리 인스턴스의 함수 중 콜백을 넘기지 않았을 때 Promise를 반환하는(정확히는 Promise-Like) 함수는 create(), save(), remove(), exec() 등 일부고 그 외엔 모두 자기 자신(쿼리 인스턴스)를 다시 반환하기 때문에 exec를 사용하여야 쿼리를 최종 실행시킬 수 있다.</p>
</blockquote>
<pre><code class="language-javascript">const movieR = await Movie.findOne({ rating: &quot;R&quot; }).exec();</code></pre>
<h1 id="163-mongoose로-업데이트하기">163. Mongoose로 업데이트하기</h1>
<pre><code class="language-javascript">Movie.updateOne({ title: &quot;Amadeus&quot; }, { year: 1984 }).then((res) =&gt; {
  console.log(res);
});

/*  갱신된 데이터가 반환되지 않음 update 메서드의 방식이 이러함.
{
  acknowledged: true,
  modifiedCount: 1,
  upsertedId: null,
  upsertedCount: 0,
  matchedCount: 1
} */

//여러개를 업데이트할 경우
Movie.updateMany(
  { title: { $in: [&quot;Amadeus&quot;, &quot;Stand By Me&quot;] } },
  { score: 10 }
).then((res) =&gt; {
  console.log(res);
});</code></pre>
<h2 id="findbyidupdate-findoneandupdate">findByIdUpdate, findOneAndUpdate</h2>
<p>갱신을 실행한 뒤 갱신된 객체를 돌려줌</p>
<pre><code class="language-javascript">Movie.findOneAndUpdate(
  { title: &quot;The Iron Giant&quot; },
  { score: 8 },
  { new: true } //이 옵션을 줘야 갱신된 객체를 반환함
).then((data) =&gt; {
  console.log(data);
});

Movie.findByIdUpdate(
  { id: &quot;5931l30oepp&quot; },
  { score: 8 },
  { new: true } //이 옵션을 줘야 갱신된 객체를 반환함
).then((data) =&gt; {
  console.log(data);
});</code></pre>
<h1 id="164-mongoose로-삭제하기">164. Mongoose로 삭제하기</h1>
<pre><code class="language-javascript">Movie.remove({ title: &quot;Alien&quot; }).then((res) =&gt; {
  console.log(res);
});
/* 
삭제된 객체를 반환하지 않음
{ acknowledged: true, deletedCount: 1 }
 */

Movie.deleteOne({ title: &quot;Alien&quot; }).then((res) =&gt; {
  console.log(res);
});

Movie.deleteMany({ year: { $gte: 2000 } }).then((res) =&gt; {
  console.log(res);
});</code></pre>
<h2 id="findoneanddelte-findbyidanddelete">findOneAndDelte, findByIdAndDelete</h2>
<p>삭제를 실행한 뒤 삭제된 객체 반환함</p>
<pre><code class="language-javascript">Movie.findOneAndUpdate({ title: &quot;The Iron Giant&quot; }).then((data) =&gt; {
  console.log(data);
});</code></pre>
<h1 id="165-스키마-유효성-검사">165. 스키마 유효성 검사</h1>
<pre><code class="language-javascript">const productSchema = new mongoose.Schema({
  //required:true를 넣어주면 특성의 디폴트가 설정됨
  name: { type: String, required: true }, //필수 특성
  price: { type: Number, required: true }, //필수 특성
});

const Product = mongoose.model(&quot;Product&quot;, productSchema);
const bike = new Product({ name: &quot;Moutain Bike&quot;, price: 599 });
const keyboard = new Product({
  name: &quot;developer Keyboadr&quot;,
  price: 599,
  color: &quot;brown&quot;, //스키마에 없는 특성을 추가하였을 경우 무시한다.
});
bike
  .save()
  .then((data) =&gt; {
    console.log(data);
  })
  .catch((err) =&gt; {
    console.log(err); //type이 다르거나 required인 특성에 값이 없을 경우 에러로 빠짐
  });

});</code></pre>
<h1 id="165-스키마-유효성-검사-1">165. 스키마 유효성 검사</h1>
<pre><code class="language-javascript">const productSchema = new mongoose.Schema({
  //required:true를 넣어주면 특성의 디폴트가 설정됨
  name: { type: String, required: true }, //필수 특성
  price: { type: Number, required: true }, //필수 특성
});

const Product = mongoose.model(&quot;Product&quot;, productSchema);
const keyboard = new Product({
  name: &quot;developer Keyboadr&quot;,
  price: 599,
  color: &quot;brown&quot;, //스키마에 없는 특성을 추가하면 무시한다.
});

keyboard.save();
/* {
  name: &#39;developer Keyboadr&#39;,
  price: 599,
  _id: new ObjectId(&quot;627c6f687bc64c5aa7e5fc75&quot;),
  __v: 0
} */</code></pre>
<h1 id="166-스키마-추가-제약조건">166. 스키마 추가 제약조건</h1>
<p>default 기본값 설정
maxlength 최대 길이 제한
minlength 최소 길이 제한
max 최대 값 제한
min 최소 값 제한
[type] type 배열
enum 배열을 제공 후 해당 값이 배열에 있는지 검사
등등</p>
<pre><code class="language-javascript">const productSchema = new mongoose.Schema({
  //required:true를 넣어주면 특성의 디폴트가 설정됨
  name: { type: String, required: true, minlength: 0, maxlength: 10 }, //필수 특성
  price: { type: Number, required: true, min:0}, //필수 특성
  onSale: { type: boolean, default: false },
  categories:{[String]},
  size:{enum:[S,M,L,XL]},
  qty:{
      online:{
          tpye:Number,
          default :0
      },
      instore:{
          tpye:Number,
          default :0
      }
  }
});</code></pre>
<h1 id="169-업데이트-유효성-검사">169. 업데이트 유효성 검사</h1>
<blockquote>
<p>runValidators:true를 안주면 해당 객체가 처음에만 유효성 검사를 하고 다음부턴 하지 않기 때문에 계속 유효성 검사를 하라고 명시해야함</p>
</blockquote>
<pre><code class="language-javascript">Product.findOneAndUpdate(
  { name: &quot;Moutain Bike&quot; },
  { price: -1 },
  { new: true, runValidators: true } // runValidators:true로 주면 유효성 검사 적용
)
  .then((data) =&gt; {
    console.log(data);
  })
  .catch((err) =&gt; {
    console.log(err); //price가 min:0으로 되어있기 때문에 에러남
  });</code></pre>
<h1 id="170-유효성-검사-오류">170. 유효성 검사 오류</h1>
<p>유효성 오류시 커스텀 메시지를 설정할 수 있다.</p>
<pre><code class="language-javascript">
const productSchema = new mongoose.Schema({
  name: { type: String, required: true, minlength: [0,too short], maxlength: 10 },
  price: { type: Number, required: true, min:[0,Price must be positive]},
  });</code></pre>
<h1 id="171-인스터스-메서드">171. 인스터스 메서드</h1>
<p>스키마에 .을 찍고 methods. 다음에 메서드명과 메서드 정의
이 메서드는 해당 스키마로 만들어진 클래스의 인스턴스에서 다 사용 가능</p>
<pre><code class="language-javascript">productSchema.methods.greet = function () {
  console.log(&quot;Hello!&quot;);
  console.log(${this.name})
};
productSchema.methods.toggleOnSale=function(){
    this.onSale=!this.OnSale;
    this.save();
}

productSchema.methods.addCategory = function(newCategory){
    this.Category.push(newCategory);
    this.save();
}

const Product = mongoose.model(&quot;Product&quot;, productSchema);

const keyboard = new Product({
  name: &quot;developer Keyboadr&quot;,
  price: 599,
});

const findProduct = async ()=&gt;{
    const foundProduct = await Product.findOne({name:&quot;Moutain Bike&quot;});
    await foundProduct.toggleOnSale();
    await foundProduct.addCategory(&quot;Outdoors&quot;);

}</code></pre>
<h1 id="172-정적-메서드-추가">172. 정적 메서드 추가</h1>
<p>스키마명.statics.메서드명 = 정의</p>
<pre><code class="language-javascript">
productSchema.statics.fireSale = function()=&gt;{
    return this.updateMany({},{onSale:true,price:0})
}
find.fireSale().then(()=&gt;{
    console.log(&quot;fireSale&quot;)
})</code></pre>
<h1 id="173-가상-mongoose">173. 가상 Mongoose</h1>
<p>실제 데이터베이스 자체에는 존재하지 않는 스키마에 특성을 추가할 수 있게 해준다.</p>
<p>첫 번째 예시로 사용할 것은 first name과 last name이 있는
사람 모델 first name과 last name이 있는 사용자 모델이다.</p>
<p>fullName을 데이터베이스에 저장할 필요가 없으나 마치 fullName이 데이터베이스에 있는 것처럼 접근할 수 있는 특성이 있다면 좋을 것이다.</p>
<p>get, set으로 값을 가져오거나 설정할 수 있다.</p>
<pre><code class="language-javascript">const personSchema = new mongoose.Schema({
  first: String,
  last: String,
});
personSchema
  .virtual(&quot;fullName&quot;)
  .get(function () {
    return `${this.first} ${this.last}`;
  })
  .set(function (v) {
    this.first = v.substr(0, v.indexOf(&quot; &quot;));
    this.last = v.substr(v.indexOf(&quot; &quot;) + 1);
  });

const Person = mongoose.model(&quot;Person&quot;, personSchema);
const tammy = new Person({ first: &quot;Tammy&quot;, last: &quot;Chow&quot; });
tammy.fullName; // Tammy Chow
tammy.fullName = Tammy Xios // tammy.first = Tammy tammy.last = Xios로 바뀐다.</code></pre>
<h1 id="174-mongoose를-미들웨어로-정의">174. Mongoose를 미들웨어로 정의</h1>
<p>어떤 것이 삭제되거나 저장되기 직전이나 updateMany나 find 등 어떤 함수를 호출할 때도 코드를 실행할 수 있습니다</p>
<p>방법은 .pre와 .post를 추가하는 것이다.</p>
<pre><code class="language-javascript">personSchema.pre(&quot;save&quot;, asyncc function () {
    console.log(&quot;ABOUT TO SAVE&quot;)
});
personSchema.post(&quot;save&quot;, asyncc function () {
    console.log(&quot;JUST SAVED&quot;)
});</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[object 정리]]></title>
            <link>https://velog.io/@b_m_c/object-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@b_m_c/object-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 08 May 2022 12:00:57 GMT</pubDate>
            <description><![CDATA[<h1 id="object">Object</h1>
<p>key:value의 집합으로 구성된 속성(프로퍼티)의 집합이다. 객체라고 부른다.</p>
<h2 id="object-literal객체-리터럴">object-literal(객체 리터럴)</h2>
<p>{key:value}형태로 객체를 정의하는 것</p>
<pre><code class="language-javascript">const obj = {
    name: &#39;test&#39;,
};</code></pre>
<ul>
<li>동적으로 속성을 추가및 제거할 수 있다.</li>
</ul>
<pre><code class="language-javascript">const obj = {
    name: &#39;test&#39;,
};

obj.color = &#39;brown&#39;; // 추가

delete obj.color; // 제거</code></pre>
<h2 id="object-constructor객체-생성자">object constructor(객체 생성자)</h2>
<p>new 키워드와 생성자 함수를 통해 생성하는 방법</p>
<pre><code class="language-javascript">function Pet(name)) {
  this.name = name;
}

const pet1 = new Pet(&quot;test&quot;);</code></pre>
<h2 id="dot-notation-점-표기법">Dot Notation (점 표기법)</h2>
<p>. 으로 객체의 속성에 접근하는 것</p>
<pre><code class="language-javascript">const obj = {
    name: &#39;test&#39;,
};
console.log(obj.name);</code></pre>
<h2 id="bracket-notation-괄호-표기법">Bracket Notation (괄호 표기법)</h2>
<ul>
<li>동적인 접근 가능</li>
<li>[ ](대괄호) 사용</li>
<li>string타입으로 지정해야함</li>
</ul>
<pre><code class="language-javascript">const obj = {
    name: &#39;test&#39;,
    color: &#39;brown&#39;,
};

function printValue(obj, key) {
    console.log(obj[key]);
}
printValue(obj, name);
printValue(obj, color);</code></pre>
<h2 id="property-value-shorthand-단축-속성명">Property value shorthand (단축 속성명)</h2>
<p>key와 value가 동일하다면 value를 생략할 수 있다.</p>
<pre><code class="language-javascript">let name = &#39;test&#39;;
const obj = {
    name, //단축 속성명을 쓰지 않았을 땐 name:name이라고 해야함
};
console.log(obj.name); //test</code></pre>
<h2 id="in-operator">in operator</h2>
<p>객체에 key값에 해당하는 속성이 있는지 확인</p>
<pre><code class="language-javascript">const obj = {
    name: &#39;test&#39;,
};
console.log(&#39;name&#39; in obj); //true
console.log(&#39;color&#39; in obj); //false</code></pre>
<h2 id="object-assign">object assign</h2>
<p>객체 복사시 사용</p>
<pre><code class="language-javascript">const fruit1 = { color: &#39;yellow&#39; };
const fruit2 = {
    color: &#39;blue&#39;,
    size: &#39;big&#39;,
};

const mixed = Object.assign({}, fruit1, fruit2);
console.log(mixed.color); // blue
console.log(mixed.size); //big 동일한 속성이 나오게되면 값을 덮어버림</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[this 정리]]></title>
            <link>https://velog.io/@b_m_c/this-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@b_m_c/this-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Sun, 08 May 2022 12:00:15 GMT</pubDate>
            <description><![CDATA[<h1 id="this">this</h1>
<p>this는 5가지의 경우에 따라 의미가 다르다.</p>
<ol>
<li><p>일반 함수에서의 this</p>
</li>
<li><p>오브젝트 내의 메소드에서의 this</p>
</li>
<li><p>생성자에서의 this</p>
</li>
<li><p>이벤트리스너 안에서의 this</p>
</li>
<li><p>화살표 함수에서의 this</p>
</li>
</ol>
<h2 id="1-일반-함수에서의-this">1. 일반 함수에서의 this</h2>
<p>widow객체를 가리킨다.</p>
<pre><code class="language-javascript">function(){
    this // window객체
}</code></pre>
<h2 id="2-오브젝트-내의-메소드에서의-this">2. 오브젝트 내의 메소드에서의 this</h2>
<p>오브젝트를 가리킨다.</p>
<pre><code class="language-javascript">const obj = {
    name: &#39;test&#39;,
    print() {
        console.log(this.name);
    },
    test: function () {
        console.log(this.name);
    },

    arrow: () =&gt; {
        console.log(this);
        console.log(this.name);
    },
};

obj.print(); //test
obj.test(); //test
obj.arrow(); //{} undefined</code></pre>
<h2 id="3-생성자에서의-this">3. 생성자에서의 this</h2>
<p>생성자로 생성되는 오브젝트를 가리킴</p>
<pre><code class="language-javascript">function dog(name) {
    this.name = name;
}
const pet = new dog(&#39;hi&#39;);
console.log(pet.name); // hi</code></pre>
<h2 id="4-이벤트리스너-안에서의-this">4. 이벤트리스너 안에서의 this</h2>
<blockquote>
<p>콜백함수 내부에서의 this는 해당 콜백함수의 제어권을 넘겨받은 함수가 정의한 바에 따르며, 정의하지 않은 경우에는 전역객체를 참조한다.</p>
</blockquote>
<pre><code class="language-javascript">const button = document.querySelector(&#39;button&#39;);

//일반 함수형을 콜백으로 한 경우
button.addEventListener(&#39;click&#39;, function () {
    this; // 이벤트를 수신하는 객체 여기선 button을 가리킨다.
});</code></pre>
<p>this가 addEventListener 내부에서 이벤트 수신을 받는 객체로 정의되었기에 button을 가리키는 것이다.(위 콜백에서의 this 원리에 따를때,일반 함수에서 this는 window를 가리키게 되있으므로)</p>
<pre><code class="language-javascript">//화살표 함수를 콜백으로 한 경우
button.addEventListener(&#39;click&#39;, () =&gt; {
    this; // window 참조
});</code></pre>
<p>화살표 함수는 call, apply, bind 메소드를 사용하여 this를 변경할 수 없다. &lt;=출처 : 딥다이브 블로그</p>
<p>화살표 함수에선 this를 변경할 수 없기에 무조건 상위 스코프를 따르게 되므로 여기서 this는 window를 가리키는 것이다</p>
<h2 id="5-화살표함수에서의-this">5. 화살표함수에서의 this</h2>
<p>함수 자체의 this 바인딩을 갖지 않고, 스코프 체인을 통해 상위 스코프의 this를 참조한다는 점
즉 화살표 밖의 this를 참조한다.</p>
<p>즉 function을 만날 때 마다 this값이 변경되지 않는다.</p>
<p>함수 내부의 this값을 새로 바꿔주지 않기 때문</p>
<pre><code class="language-javascript">const obj = {
    //현재 여기서 this는 객체를 가리킴
    name: &#39;test&#39;,
    test() {
        setTimeout(function () {
            console.log(this.name);
        }); // this가 window를 가리키므로 undefined
    },
    arrow() {
        setTimeout(() =&gt; {
            console.log(this.name); // this값이 바뀌지 않기 때문에 객체를 가리키므로 &quot;test&quot;
        }, 1000);
    },
};</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[웹개발 부트캠프 2022 2주차(자바스크립트)]]></title>
            <link>https://velog.io/@b_m_c/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-2%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@b_m_c/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-2%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Thu, 05 May 2022 08:37:18 GMT</pubDate>
            <description><![CDATA[<p>(4/29 ~5/5) The Web Developer 부트캠프 2022 강의 내용 정리
범위 : DOM이란? ~ 터미널 완벽 정리(섹션 24 ~30)</p>
<h1 id="78-dom-개요">78. DOM 개요</h1>
<h2 id="domdocument-object-model">DOM(Document Object Model)</h2>
<p>웹 페이지를 구성하는 Javascript 객체들의 집합</p>
<p>Javascript로 HTML,CSS를 다룰 수 있게함.</p>
<p>클릭으로 목록을 확장하거나 접는 것
배경을 바꾼다거나 텍스트 입력, 버튼을 생기게 하는 것등이 그 예이다.</p>
<h1 id="79-문서-오브젝트">79. 문서 오브젝트</h1>
<p>브라우저가 웹 페이지를 띄울 때 HTML,CSS 정보를 받아들인 다음 요소와 스타일을 기반으로 Javascript 객체를 생성한다. 이 때 생성되는 객체들은 트리 구조를 형성하며 유기적으로 연결 된 관계를 나타낸다. 이 트리 구조의 최상단에 있는 것이 document 객체이다. 또한 모든 특성과 메서드를 포함하고 있다.</p>
<p>이 트리 구조에 있는 객체들에 접근하여 html, css를 조작할 수 있다.</p>
<h1 id="80-getelementbyid">80. getElementById</h1>
<p>javascript에게 일치하는 id를 가진 요소를 페이지에서 찾아서 객체로 가져오라고 하는 메소드</p>
<p>문자열을 인수로 넣으면 일치하는 ID를 가진 요소를 찾아 나타낸다.</p>
<p>ID는 각 페이지마다 한 번만 나오게 되어 있어서 동일한 id가 있을 경우 먼저 검색된 element를 반환다.</p>
<pre><code class="language-javascript">/*
&lt;div id=&quot;test&quot;&gt;1&lt;/div&gt;
&lt;div id=&quot;test&quot;&gt;2&lt;/div&gt;

*/
document.getElementById(&#39;test&#39;);
//출력  &lt;div id=&quot;test&quot;&gt;&lt;/div&gt;</code></pre>
<pre><code class="language-javascript">// html에 &lt;button id=&quot;saveBtn&quot;&gt;저장&lt;/button&gt;이 있다 가정하고 밑에 코드를 수행하면 해당 버튼 요소를 나타낸다.

document.getElementById(&#39;saveBtn&#39;); // 없는 id를 넣을 경우엔 undefined가 출력된다.</code></pre>
<h1 id="81-getelementbytagname--classname">81. getElementByTagName &amp; className</h1>
<h2 id="getelementbytagname">getElementByTagName</h2>
<p>일치하는 Tag명에 대해 관련히여 반환되는 객체인 element를 담은 HTMLCollection을 반환한다.</p>
<p>HTMLCollection은 배열이 아니지만 [],인덱스,for of 사용이 가능하다. 하지만 map은 사용할 수 없다.</p>
<pre><code class="language-javascript">document.getElementByTagName(&#39;img&#39;);</code></pre>
<h2 id="getelementbyclassname">getElementByClassName</h2>
<p>클래스명으로 element를 담은 HTMLCollection을 반환받는다.</p>
<pre><code class="language-javascript">document.getClassName(&#39;클래스명&#39;);</code></pre>
<h1 id="82-queryselector--queryselectorall">82. querySelector &amp; querySelectorAll</h1>
<h2 id="queryselector">querySelector</h2>
<p>id, 클래스명, 요소 타입, 속성, CSS 스타일이든 원하는 선택자를 이용해서 첫 번째로 일치하는 element를 반환받는다.</p>
<pre><code class="language-javascript">document.querySelector(&#39;h1&#39;);
// tag를 선택자로할 경우
document.querySelector(&#39;.square&#39;);
// class를 선택자로할 경우 .을 붙인다.
document.querySelector(&#39;#banner&#39;);
// id를 선택자로할 경우 #을 붙인다.
document.querySelector(&#39;img:nth-of-type(2)&#39;); // img태그에 해당하는 것 중 2번째 element 반환

//&lt;a href=&quot;/wiki/Java&quot; title=&quot;Java&quot;&gt;
document.querySelector(&#39;a[title=&quot;Java&quot;]&#39;);
//태그와 속성명을 선택자로할 경우

document.querySelector(&#39;[colors=&quot;blue&quot;]&#39;);
//속성명을 선택자로할 경우

document.querySelector(&#39;p a&#39;);
//자식을 찾는 경우</code></pre>
<h2 id="queryselectorall">querySelectorAll</h2>
<p>사용법은 querySelector와 동일하지만 반환값이 NodeList이다.</p>
<blockquote>
<h2 id="htmlcollection과-nodelist-차이">HTMLCollection과 NodeList 차이</h2>
<p>NodeList는 앞의 HTMLCollection과 다르게 노드가 변경되도 그 상태를 반영하지 않는다.</p>
</blockquote>
<h1 id="83-innerhtml-textcontent--innertext">83. innerHTML, textContent &amp; innerText</h1>
<h2 id="innerhtml">innerHtml</h2>
<p>특정 요소의 포함된 마크업의 전체 내용을 출력</p>
<p>요소를 다른 요소 안에 추가,변경 할 때 사용</p>
<pre><code class="language-javascript">document.querySelector(&#39;h1&#39;).innerHTML = &#39;&lt;i&gt;test&lt;/i&gt;&#39;; //변경

document.querySelector(&#39;h1&#39;).innerHTML += &#39;&lt;i&gt;test&lt;/i&gt;&#39;; //추가</code></pre>
<h2 id="textcontent">textContent</h2>
<p>textContent 는 &lt;script&gt;
와 &lt;style&gt; 요소를 포함한 모든 요소의 콘텐츠를 가져옵니다. textContent 는 노드의 모든 요소를 반환한다.</p>
<pre><code class="language-html">&lt;p&gt;
    &lt;strong&gt;test &lt;/strong&gt;
    띄어쓰기
&lt;/p&gt;</code></pre>
<pre><code class="language-javascript">document.querySelector(&#39;p&#39;).textContent();
/* &#39;\n            test \n            띄어쓰기\n */</code></pre>
<h2 id="innertext">innerText</h2>
<p>여는 태그와 닫는 태그 사이의 텍스트값을 반환한다.(개행 문자 포함)</p>
<p>innerText 는 &quot;사람이 읽을 수 있는&quot; 요소만 반환한다. 태그 무시 ,display=none인 요소는 처리하지 않는다.</p>
<pre><code class="language-html">&lt;p&gt;여기가 innerText 부분&lt;/p&gt;</code></pre>
<p>값 변경 시</p>
<pre><code class="language-javascript">document.querySelector(&#39;p&#39;).innerText = &#39;변경 값&#39;;</code></pre>
<pre><code class="language-html">&lt;p&gt;
    &lt;strong&gt;test &lt;/strong&gt;
    띄어쓰기
&lt;/p&gt;</code></pre>
<pre><code class="language-javascript">document.querySelector(&#39;p&#39;).innerText; //&#39;test 띄어쓰기&#39;</code></pre>
<h1 id="84-getattribute-setattribute">84. getAttribute, setAttribute</h1>
<h2 id="getattribute">getAttribute</h2>
<p>HTML 자체에서 해당 속성 값을 직접 가져옴</p>
<p>직접 액세스 하는 경우엔 javascript를 거치게 됨</p>
<pre><code class="language-html">&lt;a href=&quot;www.naver.com&quot;&gt;네이버&lt;/a&gt;</code></pre>
<pre><code class="language-javascript">const firstLink = document.querySelector(&#39;a&#39;);

//직접 액세스 하는 경우엔 javascript를 거치게 됨
firstLink.href; //&#39;http://127.0.0.1:5500/www.naver.com&#39;

firstLink.getAttribute(&#39;href&#39;); //&#39;www.naver.com&#39;

//css와 관련된 속성은 style을 붙여야함
firstLink.style.color;</code></pre>
<h2 id="setattribute">setAttribute</h2>
<p>속성 값을 변경함</p>
<pre><code class="language-javascript">const firstLink = document.querySelector(&#39;a&#39;);
firstLink.setAttribute(&#39;href&#39;, &#39;http://www.google.com&#39;);

//직접 액세스하는 경우
firstLink.href = &#39;http://www.google.com&#39;;

//css와 관련된 속성은 style을 붙여야함
firstLink.style.color = &#39;black&#39;;</code></pre>
<blockquote>
<p>속성(attribute)과 특성(property) 차이</p>
<p>속성은 html문서 상에서 element의 추가적인 정보를 넣을 때 사용되는 요소</p>
<p>특성은 html DOM tree안에서 존재하는 element의 추가적인 정보</p>
<p>속성과 특성을 구분하는 이유는 속성은 html상에서 정적인 값으로 변하지 않지만 특성은 DOM tree안에서 동적으로 변하기 때문</p>
<p>예를 들어 체크박스 태그가 있을 때 유저가 체크박스에 체크를 하면 속성의 상태는 변하지 않지만 특성의 상태는 checked로 변하게 된다.</p>
</blockquote>
<h1 id="85-스타일-변경하기">85. 스타일 변경하기</h1>
<h2 id="인라인-스타일">인라인 스타일</h2>
<pre><code class="language-javascript">
const h1 = document.querySelector(&quot;h1&quot;);
h1.style.color=&quot;blue&quot;:
//&lt;h1 style=&quot;color:blue;&quot;&gt;테스트&lt;/h1&gt;
</code></pre>
<h2 id="클래스-사용">클래스 사용</h2>
<p>클래스를 정의하여 요소에 해당 클래스를 추가하여 스타일 적용</p>
<pre><code class="language-css">.title {
    color: blue;
}</code></pre>
<pre><code class="language-html">&lt;h1 class=&quot;title&quot;&gt;타이틀&lt;/h1&gt;</code></pre>
<pre><code class="language-javascript">document.querySelector(&#39;h1&#39;).className = &#39;title&#39;;
document.querySelector(&#39;h1&#39;).classList.add(&#39;title&#39;);</code></pre>
<h2 id="getcomputedstyle">getComputedStyle</h2>
<p>CSSStyleDeclaration을 반환한다. css 정보를 갖고 있다.</p>
<pre><code class="language-javascript">window.getComputedStyle(h1).color;</code></pre>
<h1 id="86-계층-이동">86. 계층 이동</h1>
<p>부모, 자식 형제 요소 등에 액세스</p>
<p>요소를 제거,변경, 삽입하는 작업에 사용</p>
<h2 id="parentelement">parentElement</h2>
<p>부모 요소에 액세스</p>
<pre><code class="language-html">&lt;html&gt;
    &lt;body&gt;
        &lt;p&gt;&lt;/p&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>
<pre><code class="language-javascript">const p = document.querySelector(&#39;p&#39;);
p.parentElement; // &lt;body&gt;&lt;/body&gt;
p.parentElement.parentElement; // &lt;html&gt; ... &lt;html&gt;</code></pre>
<h2 id="children">children</h2>
<p>자식 요소에 액세스</p>
<pre><code class="language-javascript">const p = document.querySelect(&#39;p&#39;).parentElement;
p.children; // HTMLCollection(2)[head,body]</code></pre>
<h2 id="nextsibling">nextSibling</h2>
<p>다음 형제</p>
<h2 id="nextelementsibling">nextElementSibling</h2>
<p>다음 형제 (공백과 텍스트 노드 무시)</p>
<h2 id="previoussibling-previouselementsibling">previousSibling previousElementSibling</h2>
<p>이전 형제</p>
<h2 id="previouselementsibling">previousElementSibling</h2>
<p>이전 형제 (공백과 텍스트 노드 무시)</p>
<h1 id="87-append--appendchild">87. Append &amp; AppendChild</h1>
<p>페이지에 새로운 DOM 요소를 추가하는데 사용</p>
<p>document.createElement();</p>
<p>새로운 DOM 요소를 만드는데 사용</p>
<h2 id="append">Append</h2>
<p>뒤에 추가,텍스트 추가 가능, 한 개 이상 삽입 가능</p>
<pre><code class="language-javascript">//텍스트 추가 가능
document.body.append(&#39;텍스트 추가&#39;);

//한 개 이상 삽입 가능
document.body.append(newImg1, newImg2);

//&lt;b&gt;hi&lt;/b&gt; 추가 예제
const newB = document.createElement(&#39;b&#39;);
newB.append(&#39;hi&#39;); // &lt;b&gt;hi&lt;/b&gt;
document.body.append(newB);</code></pre>
<h2 id="appendchild">AppendChild</h2>
<p>마지막 자식으로 추가</p>
<pre><code class="language-javascript">const newImg = document.createElement(&#39;img&#39;);
newImg.src = &#39;이미지 경로&#39;;
document.body.appendChild(newImg);
//body에 img 추가</code></pre>
<h2 id="prepend">prepend</h2>
<p>요소의 맨 앞 자식으로 추가</p>
<pre><code class="language-javascript">const newB = document.createElement(&#39;b&#39;);
newB.append(&#39;hi&#39;); // &lt;b&gt;hi&lt;/b&gt;
document.body.perpend(newB);</code></pre>
<h2 id="insertadjacentelement">insertAdjacentElement</h2>
<p>요소를 삽입하려는 위치를 지정해서 사용</p>
<pre><code>element.insertAdjacentHTML(position, text);</code></pre><p>position : beforebegin, afterbegin, beforeend, afterend</p>
<p>text : 해당 위치에 삽입될 HTML 요소의 text값</p>
<p>beforebegin 요소 이전. 요소가 DOM 트리에 있고 부모 요소가 있는 경우에만 유효</p>
<p>afterbegin 요소 바로 내부, 첫 번째 자식 앞</p>
<p>beforeend 요소 바로 내부, 마지막 자식 뒤.</p>
<p>afterend 요소 후. 요소가 DOM 트리에 있고 부모 요소가 있는 경우에만 유효</p>
<pre><code class="language-javascript">&lt;!--beforebegin--&gt;
&lt;body&gt;
    &lt;!--afterbegin--&gt;
    &lt;div class=&quot;box&quot;&gt;box1&lt;/div&gt;
    &lt;div class=&quot;box&quot;&gt;box2&lt;/div&gt;
    &lt;div class=&quot;box&quot;&gt;box3&lt;/div&gt;
    &lt;div class=&quot;box&quot;&gt;box4&lt;/div&gt;
    &lt;!--beforeend--&gt;
&lt;/body&gt;
&lt;!--afterend--&gt;</code></pre>
<h2 id="after">after</h2>
<p>요소를 다른 요소 다음에 삽입</p>
<pre><code class="language-javascript">const h3 = document.createElement(&#39;h3&#39;);
h3.innerText = &#39;I am h3&#39;;
const h2 = document.querySelector(&#39;h2&#39;);
h2.after(h3);</code></pre>
<h1 id="88-removechild--remove">88. removeChild &amp; remove</h1>
<h2 id="removechild">removeChild</h2>
<p>부모 요소를 찾고 해당 요소에서 제거하려는 요소를 인수로하여 제거해야한다</p>
<pre><code class="language-html">&lt;ul&gt;
    &lt;li&gt;a&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<pre><code class="language-javascript">const li = document.querySelector(&#39;li&#39;);
const ul = li.parentElement;
ul.removeChild(li);</code></pre>
<h2 id="remove">remove</h2>
<p>부모요소 없이 제거하려는 요소에서 실행하여 제거한다.</p>
<pre><code class="language-javascript">const li = document.querySelector(&#39;li&#39;);
li.remove();</code></pre>
<h1 id="89-이벤트-개요">89. 이벤트 개요</h1>
<p>사용자들이 하는 해동에 반응하는 작업</p>
<p>클릭, 드래그, 드롭, 마우스 올리기, 스크롤 움직이, 폼 제출 등</p>
<h1 id="90-인라인-이벤트">90. 인라인 이벤트</h1>
<p>이벤트를 태그 속성으로 지정하는 것</p>
<pre><code class="language-html">&lt;button onclick=&quot;alert(&#39;you clicked me!&#39;)&quot;&gt;&lt;/button&gt;</code></pre>
<h1 id="91-객체-이벤트-속성">91. 객체 이벤트 속성</h1>
<p>태그 속성이 아닌 객체 속성값에 이벤트를 지정할 수 있다.</p>
<pre><code class="language-javascript">//id가 v2인 버튼이 있다 가정하고
const btn = document.querySelector(&#39;#v2&#39;);
btn.onclick = function () {
    console.log(&#39;YOU CLICKED ME!&#39;);
};</code></pre>
<h1 id="92-addeventlistener">92. addEventListener</h1>
<p>감지하고 싶은 어떤 이벤트든 전달할 수 있다.
첫 번째 인수로는 이벤트 종류
두 번째 인수로는 이벤트의 동작을 콜백으로 넣는다.</p>
<pre><code class="language-javascript">const btn = document.querySelector(&#39;#v2&#39;);
btn.addEventListener(&#39;click&#39;, function () {
    console.log(&#39;You clicked me!&#39;);
});</code></pre>
<p>기존에 이벤트가 지정되어 있다면 이벤트를 덮어씌우는 것이 아닌 추가하는 것이므로 기존 이벤트는 유지된다.</p>
<blockquote>
<p>addEventListener를 사용하는 이유</p>
<ol>
<li>동일한 이벤트 종류라할지라도 다른 동작을 하게 할 수 있다.</li>
</ol>
</blockquote>
<pre><code class="language-html">&lt;body&gt;
    &lt;button id=&quot;btn&quot; onclick=&quot;console.log(&#39;clicked&#39;)&quot;&gt;Click Me&lt;/button&gt;
&lt;/body&gt;</code></pre>
<pre><code class="language-javascript">const btn = document.querySelector(&#39;#btn&#39;);
btn.addEventListener(&#39;click&#39;, function () {
    console.log(&#39;You clicked me!&#39;);
});
//버튼 클릭시 clicked , You clicked me! 출력</code></pre>
<blockquote>
<p>addEventListener를 사용하는 이유</p>
<ol start="2">
<li>한번만 이벤트가 발동되게 하는등 추가적인 설정을 할 수 있다.</li>
</ol>
</blockquote>
<pre><code class="language-javascript">const btn = document.querySelector(&#39;#btn&#39;);
btn.addEventListener(
    &#39;click&#39;,
    function () {
        console.log(&#39;You clicked me!&#39;);
    },
    { once: true }
); // 한번만 이벤트 발동</code></pre>
<h1 id="93-이벤트와-this">93. 이벤트와 this</h1>
<p>이벤트를 작업할 때 this는 해당 요소를 가리킨다.
(==this는 이벤트를 수신하는 특정 객체를 참조한다.)</p>
<pre><code class="language-javascript">const h1 = document.querySelector(&#39;h1&#39;);
h1.addEventListener(&#39;click&#39;, colorize());
//이 때 colorize에서 this는 h1을 가리킴

function colorize() {
    this.style.backgroundColor = &#39;blue&#39;;
}</code></pre>
<h1 id="94-키보드-이벤트와-이벤트-객체">94. 키보드 이벤트와 이벤트 객체</h1>
<h2 id="키보드-이벤트">키보드 이벤트</h2>
<p>입력 또는 특정 키에 대한 이벤트</p>
<pre><code class="language-html">&lt;input type=&quot;text&quot; /&gt;</code></pre>
<pre><code class="language-javascript">const input = document.querySelector(&#39;input&#39;);
input.addEventListener(&#39;keydown&#39;, () =&gt; {
    console.log(&#39;keydown&#39;);
});</code></pre>
<p>콜백 함수에 첫 번 째 인자는 이벤트 객체를 의미한다.
이 객체는 해당 타입의 이벤트에 대한 상세 정보를 갖고 있다.</p>
<p>key,code 속성</p>
<pre><code class="language-javascript">const input = document.querySelector(&#39;input&#39;);
input.addEventListener(&#39;keydown&#39;, (e) =&gt; {
    console.log(e.key); //입력한 문자 ex)shift
    console.log(e.code); //code는 키보드에서의 실제 위치를 표시 ex)shiftLeft , shiftRight
});</code></pre>
<h1 id="95-폼-이벤트와-preventdefault">95. 폼 이벤트와 PreventDefault</h1>
<pre><code class="language-html">&lt;form id=&quot;tweetForm&quot; action=&quot;/dogs&quot;&gt;
    &lt;input type=&quot;text&quot; name=&quot;username&quot; /&gt;
    &lt;input type=&quot;text&quot; name=&quot;comment&quot; /&gt;
    &lt;button&gt;Post tweet&lt;/button&gt;
&lt;/form&gt;</code></pre>
<pre><code class="language-javascript">const tweetForm = document.querySelector(&#39;#tweetForm&#39;);
tweetForm.addEventListener(&#39;submit&#39;, () =&gt; {
    alert(&#39;submit!&#39;);
});</code></pre>
<p>form 태그의 submit 이벤트 수행 시 페이지가 새로고침 되는데 이를 막는 데에 PreventDefault를 사용한다.</p>
<pre><code class="language-javascript">const tweetForm = document.querySelector(&#39;#tweetForm&#39;);
tweetForm.addEventListener(&#39;submit&#39;, (e) =&gt; {
    e.preventDefault();
});</code></pre>
<p>form객체의 elements 속성값으로 내부 요소에 좀 더 편리하게 접근할 수 있다.</p>
<pre><code class="language-javascript">const tweetForm = document.querySelector(&#39;#tweetForm&#39;);

tweetForm.addEventListener(&#39;submit&#39;, (e) =&gt; {
    e.preventDefault();
    console.log(tweetForm.elements.username.val);
    console.log(tweetForm.elements.comment.val);
    )
});</code></pre>
<h1 id="96-입력과-변경-이벤트">96. 입력과 변경 이벤트</h1>
<h2 id="입력">입력</h2>
<p>다른 곳에 포커싱하지 않아도 값을 변경할 때마다 발동</p>
<p>입력 시 이벤트 발동</p>
<pre><code class="language-javascript">const input = document.querySelector(&#39;input&#39;);

input.addEventListener(&#39;input&#39;, function (e) {
    console.log(&#39;input value changed&#39;);
});</code></pre>
<h2 id="변경">변경</h2>
<p>기존에 있던 값을 변경하고 다른 곳으로 포커싱(blur out)이되면 변경으로 간주한다. 즉 값을 변경하고 입력을 떠날 때 변경으로 간주한다. (복사 붙여넣기를 한 시점은 변경으로 간주x blur out할 때 변경으로 간주)</p>
<p>변경 시 이벤트 발동</p>
<pre><code class="language-javascript">const input = document.querySelector(&#39;input&#39;);

input.addEventListener(&#39;change&#39;, function (e) {
    console.log(&#39;input value changed&#39;);
});</code></pre>
<h1 id="97-이벤트-버블링">97. 이벤트 버블링</h1>
<p>부모와 자식에 이벤트가 종류가 동일한 상황에서 자식의 이벤트를 발동하면 부모의 이벤트도 발동되는 것을 말한다.</p>
<p>이처럼 이벤트는 위로 올라가며 이를 이벤트 버블링이라 한다.</p>
<pre><code class="language-html">&lt;!-- 
자식 요소인 button을 클릭하면 button의 클릭 이벤트가 발동되고 부모 요소인 p 클릭 이벤트가 발동된다. --&gt;
&lt;p onclick=&quot;alert(&#39;paragraph clicked&#39;)&quot;&gt;
    I am a paragraph
    &lt;button onclick=&quot;alert(&#39;button clicked&#39;)&quot;&gt;clicked&lt;/button&gt;
&lt;/p&gt;</code></pre>
<p>이벤트 버블링을 막는 방법은 이벤트 객체의 stopPropagation메소드를 호출하면 된다.</p>
<pre><code class="language-html">&lt;!-- 
자식 요소인 button을 클릭하면 button의 클릭 이벤트만 발동된다. --&gt;
&lt;p onclick=&quot;alert(&#39;paragraph clicked&#39;)&quot;&gt;
    I am a paragraph
    &lt;button onclick=&quot;event.stopPropagation();  alert(&#39;button clicked&#39;)&quot;&gt;clicked&lt;/button&gt;
&lt;/p&gt;</code></pre>
<h1 id="98-이벤트-위임">98. 이벤트 위임</h1>
<p>하위 요소마다 이벤트를 붙이지 않고 상위 요소에서 하위 요소의 이벤트들을 제어하는 방식</p>
<p>부모 요소에 이벤트 수신기를 달아 자식 요소를 다룬다.</p>
<p>부모 요소에 이벤트 수신기를 추가한 시점에 페이지에 없던 요소를 다룰 때 사용한다.</p>
<pre><code class="language-html">&lt;ul&gt;
    &lt;li&gt;1&lt;/li&gt;
    &lt;li&gt;2&lt;/li&gt;
&lt;/ul&gt;</code></pre>
<pre><code class="language-javascript">const ul = querySelector(&#39;ul&#39;);
ul.addEventListener(&#39;click&#39;, function (e) {
    //이벤트 객체의 target은 클릭한 요소를 가리킨다.
    console.log(e.target);
    e.target.remove();
});</code></pre>
<h1 id="99-콜-스택">99. 콜 스택</h1>
<p>자바스크립트 엔진이 구동되면서 실행 중인 코드를 추적하는 공간이 콜스택이다.
함수(function)의 호출(call)을 기록하는 스택(stack)자료구조</p>
<pre><code class="language-javascript">콜스택을 통해 isRightTriangle함수를 호출하여
square -&gt; multiply를 호출하고 해당 함수에서의 연산된 값이 multiply-&gt; square -&gt; isRightTriangle로 넘어올 수 있는 것이다.

const multiply = (x,y)=&gt;x*y;
const square =(x)=&gt;multiply(x,x);
const isRightTriangle = (a,b,c)=&gt;{
    return square(a)+square(b) ===square(c)
};

isRightTriangle(3,4,5)</code></pre>
<h1 id="100-webapi와-단일-스레드">100. WebAPI와 단일 스레드</h1>
<h2 id="단일-스레드">단일 스레드</h2>
<p>한 번에 하나의 작업을 할 수 있는 것
자바스크립트는 단일 스레드 언어이다.</p>
<h2 id="webapi">WebAPI</h2>
<p>브라우저에 내장된 API이다.
API는 응용프로그램 인터페이스로 컴퓨터나 컴퓨터 프로그램 사이의 상호작용을 도와주는 매개체이다.</p>
<p>브라우저에게 작업을 넘기고 자바스크립트는 다른 작업을 하게 해준다.</p>
<pre><code class="language-javascript">/*setTimeout함수는 WebAPI 함수로서  호출하면 해당 작업을 브라우저에 3초 타이머 작업으로 넘기고 그 시간동안
자바스크립트는 다른 작업을 하다가 3초가 지나면 브라우저에 있던 작업이 콜 스택에 추가되고 이를 자바스크립트가 넘겨 받아 실행하게 된다.
*/
setTimeout(function () {
    console.log(&#39;timer&#39;);
}, 3000);</code></pre>
<h1 id="101-callback-지옥">101. Callback 지옥</h1>
<p>JavaScript를 이용한 비동기 프로그래밍시 발생하는 문제로서, 함수의 매개 변수로 넘겨지는 콜백 함수가 반복되어 코드의 들여쓰기 수준이 감당하기 힘들 정도로 깊어지는 현상</p>
<p>어떤 일이 일어나야 하는 종속적인 행동이 있을 때
첫 번째 것이 끝나야 두 번째 것이 발생할 수 있죠
이런 경우 우리가 콜백을 사용한다.</p>
<pre><code class="language-javascript">const delayedColorChange = (newColor, delay, doNext) =&gt; {
    setTimeout(() =&gt; {
        document.body.style.backgroundColor = newColor;
        doNext &amp;&amp; doNext;
    }, delay);
};

delayedColorChange(&#39;orange&#39;, 1000, () =&gt; {
    delayedColorChange(&#39;orange&#39;, 1000, () =&gt; {
        delayedColorChange(&#39;orange&#39;, 1000, () =&gt; {});
    });
});</code></pre>
<h2 id="callback을-사용한-fakerequest">Callback을 사용한 fakeRequest</h2>
<pre><code class="language-javascript">function fakeRequestCallback(url, success, failure) {
    setTimeout(() =&gt; {
        if (delay &gt; 4000) {
            failure(&#39;Connection Timeout :(&#39;);
        } else {
            success(`Here is your fake data from ${url}`);
        }
    }, delay);
}

fakeRequestCallback(
    &#39;www.fake.com&#39;,
    function (response) {
        console.log(&#39;IT WORKED!!&#39;);
        console.log(response);
        fakeRequestCallback(
            &#39;www.fake.com/pag2&#39;,
            function (response) {
                console.log(&#39;IT WORKED!!&#39;);
                console.log(response);
            },
            function (err) {
                console.log(&#39;Error!&#39;);
                console.log(err);
            }
        );
    },
    function (err) {
        console.log(&#39;Error!&#39;);
        console.log(err);
    }
);</code></pre>
<h1 id="102-promise">102. Promise</h1>
<p>3가지의 상태 resolve(성공) reject(실패) pending(대기)를 가지며
호출할 때마다 Promise 객체를 반환한다.</p>
<p>promise 인스턴스 생성시 resolve,reject 콜백 함수를 인수로 받는다.</p>
<h2 id="promise를-사용한-fakerequest">Promise를 사용한 fakeRequest</h2>
<p>success,failure 대한 콜백 함수를 넣지 않으니 이에 대한 중첩이 제거됐다.</p>
<pre><code class="language-javascript">const fakeRequestPromise = (url) =&gt; {
    return new Promise((resolve, reject) =&gt; {
        const delay = Math.floor(Math.random() * 4500) + 500;

        setTimeout(() =&gt; {
            if (delay &gt; 4000) {
                if (delay &gt; 4000) {
                    reject(&#39;Connection Timeout :(&#39;);
                } else {
                    resolve(`Here is your fake data from ${url}`);
                }
            }
        }, delay);
    });
};

const request = fakeRequestPromise(&#39;www.test.com&#39;); //pending 상태
request //then 또는 catch를 해야 resolve, reject에 따라 처리된다.
    .then(() =&gt; {
        //resolve시 수행
        console.log(&#39;IT WORKED!!&#39;);
        fakeRequestPromise(&#39;www.test.com/page2&#39;)
            .then(() =&gt; {
                console.log(&#39;IT WORKED!!&#39;);
            })
            .catch(() =&gt; {
                console.log(&#39;ERROR!&#39;);
            });
    })
    .catch(() =&gt; {
        //reject시 수행
        console.log(&#39;ERROR!&#39;);
    });</code></pre>
<h2 id="promise의-마법">Promise의 마법</h2>
<p>return을 활용하여 then catch문에 대한 중첩을 줄일 수 있다.</p>
<pre><code class="language-javascript">const request = fakeRequestPromise(&#39;www.test.com&#39;);
request
    .then((data) =&gt; {
        console.log(&#39;IT WORKED!!&#39;);
        console.log(data);
        return fakeRequestPromise(&#39;www.test.com/page1&#39;);
    })
    .then((data) =&gt; {
        console.log(&#39;IT WORKED!!&#39;);
        console.log(data);
        return fakeRequestPromise(&#39;www.test.com/page2&#39;);
    })
    .then((data) =&gt; {
        console.log(&#39;IT WORKED!!&#39;);
        console.log(data);
        return fakeRequestPromise(&#39;www.test.com/page3&#39;);
    })
    //세 개의 then의 reject는 다 여기서 처리된다.
    .catch(() =&gt; {
        console.log(&#39;ERROR!&#39;);
    });</code></pre>
<h2 id="콜백에서-promise로-변환">콜백에서 Promise로 변환</h2>
<p>콜백사용한 코드</p>
<pre><code class="language-javascript">const delayedColorChange = (newColor, delay, doNext) =&gt; {
    setTimeout(() =&gt; {
        document.body.style.backgroundColor = newColor;
        doNext &amp;&amp; doNext(); //doNext가 전달되지 않았을 경우를 처리하기 위해 이런식으로 코드 작성한 것
    }, delay);
};

delayedColorChange(&#39;orange&#39;, 1000, () =&gt; {
    delayedColorChange(&#39;orange&#39;, 1000, () =&gt; {
        delayedColorChange(&#39;orange&#39;, 1000, () =&gt; {});
    });
});</code></pre>
<p>Promise사용 코드</p>
<pre><code class="language-javascript">const delayedColorChange = (newColor, delay) =&gt; {
    return new Promise((resolve, reject) =&gt; {
        setTimeout(() =&gt; {
            document.body.style.backgroundColor = newColor;
            resolve();
        }, delay);
    });
};

delayedColorChange(&#39;orange&#39;, 1000)
    .then(() =&gt; {
        delayedColorChange(&#39;blue&#39;, 1000);
    })
    .then(() =&gt; {
        delayedColorChange(&#39;blue&#39;, 1000);
    });</code></pre>
<h1 id="103-비동기-키워드">103. 비동기 키워드</h1>
<h2 id="async">async</h2>
<p>함수 선언시 앞에 async를 붙이면 promise 객체를 반환하게 된다.</p>
<pre><code class="language-javascript">const f = async (isTrue) =&gt; {
    if (!isTrue) throw &#39;error&#39;; //reject상태로 반환됨
    return &#39;async&#39;; //resolve상태로 반환됨
};

f(false)
    .then((result) =&gt; {
        console.log(result);
    })
    .catch((err) =&gt; {
        console.log(err);
    });</code></pre>
<pre><code class="language-javascript">const login = async (username, password) =&gt; {
    if (!username || !password) throw &#39;Missing Credentials&#39;;
    if (password === &#39;test&#39;) return &#39;WELCOME!&#39;;
    throw &#39;Invalid Password!&#39;;
};

login(&#39;test&#39;, &#39;test&#39;)
    .then((msg) =&gt; {
        console.log(&#39;LOGGED IN!&#39;);
        console.log(msg);
    })
    .catch((err) =&gt; {
        console.log(&#39;Error!&#39;);
        console.og(err);
    });</code></pre>
<h2 id="await">await</h2>
<p>함수 호출 앞에 await을 붙이면 promise를 반환할 때까지 기다리게 된다. await 키워드를 사용하기 위해서 해당 함수 앞에 async를 붙여야한다.</p>
<p>콜백을 전달하거나 반환된 값을 연결할 필요가 없어지게 된다.</p>
<p>async-await 적용 전</p>
<pre><code class="language-javascript">const delayedColorChange = (newColor, delay) =&gt; {
    return new Promise((resolve, reject) =&gt; {
        setTimeout(() =&gt; {
            document.body.style.backgroundColor = newColor;
            resolve();
        }, delay);
    });
};

delayedColorChange(&#39;orange&#39;, 1000)
    .then(() =&gt; {
        delayedColorChange(&#39;blue&#39;, 1000);
    })
    .then(() =&gt; {
        delayedColorChange(&#39;blue&#39;, 1000);
    });</code></pre>
<p>async-await 적용 후</p>
<pre><code class="language-javascript">const delayedColorChange = async (newColor, delay) =&gt; {
    return setTimeout(() =&gt; {
        document.body.style.backgroundColor = newColor;
    }, delay);
};

await delayedColorChange(&#39;orange&#39;, 1000);
await delayedColorChange(&#39;blue&#39;, 1000);
await delayedColorChange(&#39;blue&#39;, 1000);

//async함수를 호출하는 함수의 경우에도 async를 선언시 붙여줘야한다.
rainbow();

async rainbow(){
    await delayedColorChange(&#39;orange&#39;, 1000);
    await delayedColorChange(&#39;blue&#39;, 1000);
    await delayedColorChange(&#39;blue&#39;, 1000);
}</code></pre>
<h1 id="104-비동기-함수의-오류-처리하기">104. 비동기 함수의 오류 처리하기</h1>
<p>try-catch구문 사용</p>
<pre><code class="language-javascript">async function fakeRequest() {
    const randomValue = Math.floor(Math.random() * 2);
    if (randomValue &lt; 1) throw &#39;error&#39;;
    return &#39;data&#39;;
}

async function makeTwoRequest() {
    try {
        let data = await fakeRequest();
        console.log(data);
    } catch (e) {
        console.log(&#39;ITS OK!&#39;, e);
    }
}

makeTwoRequest();</code></pre>
<h1 id="105-ajax-개요">105. AJAX 개요</h1>
<p>자바스크립트를 통해서 서버에 데이터를 비동기 방식으로 요청하는 것
페이지 전체를 다시 로드하지 않고 응답 결과만을 다시 로드한다.</p>
<h1 id="106-apis-개요">106. APIs 개요</h1>
<p>애플리케이션 프로그래밍 인터페이스의 약자로 API는 컴퓨터가 여러 소프트웨어와 상호 작용하거나 소통하는 모든 인터페이스를 의미</p>
<p>웹 개발자들이 API란 용어를 사용할 때는 대부분 WebAPI를 뜻함
WebAPI는 웹, HTTP를 기반으로 하는 인터페이스이다.</p>
<p>특정 엔드포인트(특정url)를 제공하고 제공되는 엔드포인트는 사용되는 코드에 정보로 응답하거나 다른 소프트웨어에 정보로 응답한다.</p>
<p>API 예시</p>
<ul>
<li><p>비트코인 시세 같은 정보를 띄우는 API</p>
</li>
<li><p>reddit처럼 최신 글을 띄우거나 사용자의 최근 글을 찾는 API</p>
</li>
<li><p>메세지를 보내는 API</p>
</li>
<li><p>글을 자동으로 올릴 수 있는 API</p>
</li>
</ul>
<h1 id="107-json이란">107. JSON이란</h1>
<p>API가 주로 데이터를 전송할 때 쓰는 포맷으로
키:값으로 이루어져있다.</p>
<p>모든 키는 &quot;&quot;를 갖는다</p>
<p>유효한 값: 객체, 배열, 문자열,숫자 참 거짓,null</p>
<p>유효하지 않은 값 : undefined (모두 null로 바뀜)</p>
<pre><code class="language-javascript">{
    data:{
        &quot;id&quot;:&quot;test&quot;,
        &quot;password&quot;:&quot;test&quot;,
    }
}</code></pre>
<h2 id="jsonstringify">JSON.stringify</h2>
<p>객체를 json으로 변환</p>
<pre><code class="language-javascript">const dog = {
    breed: &#39;lab&#39;,
};

console.log(typeof(JSON.stringify(dog)); // string</code></pre>
<h2 id="jsonparse">JSON.parse</h2>
<p>json 문자열 값을 유효한 javascript 객체로 바꾸는 것</p>
<pre><code class="language-javascript">const dog = {
    breed: &#39;lab&#39;,
};

data = JSON.stringify(dog);
console.log(typeof JSON.parse(data));
//object</code></pre>
<h1 id="108-xhr-객체-만들기">108. XHR 객체 만들기</h1>
<p>비동기적으로 데이터 주고받는데 사용</p>
<p>사용하는데 복잡해서 주로 사용하는 방법이 아님</p>
<pre><code class="language-javascript">const req = new XMLHttpRequest();

req.onload = function () {
    console.log(&#39;ALL DONE WITH REQUEST!!!&#39;);
    const data = JSON.parse(this.responseText);
};

req.onerror = function () {
    console.log(&#39;Error!&#39;);
    console.log(this);
};

req.open(&#39;GET&#39;, &#39;https://api.cryptonator.com/api/ticker/btc-usd&#39;);
req.send();</code></pre>
<h1 id="109-fetch-api">109. Fetch API</h1>
<p>비동기 요청 방식 promise를 사용</p>
<p>우선 Promise를 반환하는 fetch 호출을 만들어야 한다.</p>
<p>Promise는 불완전한 응답 객체로 resolve되고</p>
<p>데이터는 계속 들어오고 파싱은 되지 않는다.</p>
<p>다른 Promise를 반환하는 res.json을 호출해야한다.</p>
<p>완료될 때까지 기다린다.</p>
<p>promise 버전</p>
<pre><code class="language-javascript">fetch(&#39;https://api.cryptonator.com/api/ticker/btc-usd&#39;)
    .then((res) =&gt; {
        console.log(&#39;Response&#39;, res);
        // data를 받으려면 resolve상태의 promise를 반환해줘야 한다.
        return res.json(); // promise반환
    })
    .then((data) =&gt; {
        console.log(data);
    })
    .catch((e) =&gt; {
        console.log(&#39;Error!&#39;, e);
    });</code></pre>
<p>비동기 함수 버전</p>
<pre><code class="language-javascript">const fetchBitcoinPrice = async () =&gt; {
    try {
        const res = await fetch(&#39;https://api.cryptonator.com/api/ticker/btc-usd&#39;);
        const data = await res.json();
    } catch (e) {
        console.log(&#39;SOMETHING WENT WRONG!&#39;);
    }
};</code></pre>
<h1 id="110-axios-개요">110. Axios 개요</h1>
<p>Fetch로만 작업할 때 처리해야 하는 것은</p>
<p>반환되거나 resolve된 첫 번째 Promise이다.</p>
<p>모두 완료될 때 모든 body가 파싱될 때</p>
<p>res.json을 호출하고 Promise를 반환하는데</p>
<p>이는 두 개의 별개의 단계가 된다.</p>
<p>Axios는 이걸 하나의 단계로 만들어준다.</p>
<pre><code class="language-javascript">axios.get(&#39;https://api.cryptonator.com/api/ticker/btc-usd&#39;).then((res) =&gt; {
    console.log(res.data.ticker.price);
});</code></pre>
<h1 id="111-axios로-헤더-세팅하기">111. Axios로 헤더 세팅하기</h1>
<pre><code class="language-javascript">const getDadJoke = async () =&gt; {
    const config = {
        headers: {
            Accept: &#39;application/json&#39;,
        }, //응답 형식을 json으로 설정
    };

    try {
        const res = await async(&#39;https://icanhazdadjoke.com&#39;, config);
        return res.data.joke;
    } catch (e) {
        return &#39;NO JOKES AVAILABLE! SORRY ;(&#39;;
    }
};</code></pre>
<h1 id="112-프로토타입이란">112. 프로토타입이란</h1>
<p>프로토타입은 JavaScript 객체가 서로 기능을 상속하는 방식의 메커니즘이다.</p>
<p>하나의 프로토타입이 있고 각각의 배열이 <strong>proto</strong>라는
특별한 특성으로 그 프로토타입을 참조한다.</p>
<p>예를 들면 배열을 만들고 그 배열에서 배열 메소드를 사용할 수 있는 건 해당 배열이 Array.proto타입을 참조하기에 가능한 것이다.</p>
<p>프로토 타입에 새로운 메서드와 특성을 추가할 수도 있다.</p>
<pre><code class="language-javascript">Array.prototype.pop = function () {
    return &#39;SORRY I WANT THAT ELEMENT, I WILL NEVER POP IT OFF!&#39;;
};
[3, 4, 5].pop(); // SORRY I WANT THAT ELEMENT, I WILL NEVER POP IT OFF!</code></pre>
<h1 id="113-객체-지향-프로그래밍">113. 객체 지향 프로그래밍</h1>
<p>메서드와 특성을 가지는 객체간 상호작용을 통해 로직을 구성하는 것</p>
<p>특성과 메서드를 정의하는 클래스를 만들고 클래스로 객체를 생성한다.</p>
<h1 id="114-팩토리-함수">114. 팩토리 함수</h1>
<p>패턴이나 레시피를 기반으로 한 객체를 만드는 하나의 방법</p>
<p>비어 있는 상태로 시작하지만 주어진 인수를 기반으로 속성을 추가한다. 몇 가지 메서드를 추가하고 객체를 반환한다.</p>
<pre><code class="language-javascript">function makeColor(r, g, b) {
    const color = {};
    color.r = r;
    color.g = g;
    color.b = b;
    color.rgb = function () {
        return `rgb(${r},${g},${b})`;
    };
    color.hex = function () {
        const { r, g, b } = this;
        return &#39;#&#39; + ((1 &lt;&lt; 24) + (r &lt;&lt; 16) + (g &lt;&lt; 8) + b).toString(16).slice(1);
    };
    return color;
}
const firstColor = makeColor(35, 255, 150);
firstColor.hex(); //#23ff96</code></pre>
<h1 id="115-생성자-함수">115. 생성자 함수</h1>
<p>new 키워드를 통해 새로운 객체를 생성해준다.</p>
<pre><code class="language-javascript">function Color(r, g, b) {
    this.r = r;
    this.g = g;
    this.b = b;
    console.log(this);
}
new Color(255, 40, 100); //new 키워드를 통해 this가 window객체가 아닌 새 객체를 참조한다.</code></pre>
<p>프로토 타입으로 메서드 추가
이 때 주의할건 기본 함수 표현식을 사용해야한다.
왜냐하면 this가 해당 객체를 가리키게 해야하기 때문</p>
<pre><code class="language-javascript">Color.prototype.rgb = function () {
    const { r, g, b } = this;
    return `rgb(${r},${g},${b})`;
};

const newColor = new Color(255, 40, 100);

console.log(newColor.rgb()); // rgb(255,40,100)</code></pre>
<h1 id="116-javascript-클래스">116. Javascript 클래스</h1>
<p>class 키워드를 사용하고 내부에 constructor가 생성자 역할을 한다.</p>
<p>해당 클래스에 메서드를 정의하고 생성자 안에서 특성을 할당할 수 있다.</p>
<p>생성자에서는 일반적으로 객체에 this로 액세스한다.</p>
<pre><code class="language-javascript">class Color {
    constructor(r, g, b) {
        this.r = r;
        this.g = g;
        this.b = b;
    }

    innerRGB() {
        const { r, g, b } = this;
        return `${r},${g},${b}`;
    }

    rgb() {
        //객체 내부 메서드에 접근할 때 this로 접근한다.
        return `rgb(${this.innerRGB()})`;
    }
    rgba(a = 1.0) {
        return `rgba(${this.innerRGB()},${a})`;
    }
    hex() {
        const { r, g, b } = this;
        return &#39;#&#39; + ((1 &lt;&lt; 24) + (r &lt;&lt; 16) + (g &lt;&lt; 8) + b).toString(16).slice(1);
    }
}
const c1 = new Color(255, 67, 89);
console.log(c1.rgb()); // rgb(255,67,89)
console.log(c1.hex()); // #ff3459</code></pre>
<h1 id="117-확장-및-슈퍼-키워드">117. 확장 및 슈퍼 키워드</h1>
<h2 id="extends">Extends</h2>
<p>extends 키워드를 통해 생성자, 특성, 메서드를 상속할 수 있다. 이를 통해 코드를 재사용하거나 확장할 수 있다.</p>
<pre><code class="language-javascript">class Pet {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    eat() {
        return `${this.name} is eating!`;
    }
}

class Cat extends Pet {
    /*   constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    eat() {
        return `${this.name} is eating!`;
    } */
    meow() {
        return `MEOW`;
    }
}

class Dog extends Pet {
    /*  constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    eat() {
        return `${this.name} is eating!`;
    } */
    bark() {
        return &#39;WOOOF!&#39;;
    }
}</code></pre>
<h2 id="super">super</h2>
<p>상속을 한 클래스는 super 클래스가 되고 이 클래스를 참조하는데 사용된다.</p>
<p>Pet 생성자에서</p>
<pre><code class="language-javascript">class Pet {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    eat() {
        return `${this.name} is eating!`;
    }
}

class Cat extends Pet {
    constructor(name, age, hobby) {
        super(name, age);
        this.hobby = hobby;
    }
    /* 
    eat() {
        return `${this.name} is eating!`;
    } */
    meow() {
        return `MEOW`;
    }
}

class Dog extends Pet {
    /*  constructor(name, age) {
        this.name = name;
        this.age = age;
    }
    eat() {
        return `${this.name} is eating!`;
    } */
    bark() {
        return &#39;WOOOF!&#39;;
    }
}</code></pre>
<h1 id="119-터미널이란">119. 터미널이란</h1>
<p>텍스트를 통해 내 기기와 상호작용할 수 있는
텍스트 기반의 프롬프트를 지칭한다.</p>
<h1 id="120-터미널-사용-이유">120. 터미널 사용 이유</h1>
<ul>
<li><p>한 번에 대여섯 개의 명령어를 실행할 수 있다.</p>
</li>
<li><p>보통은 마우스를 써서 클릭하고 드래그하던 작업을
타이핑만으로 다 할 수 있어 숙달이 되면 굉장히 빠르고 효율적으로 작업할 수 있다.</p>
</li>
<li><p>중대한 변경 사항을 반영하거나 권한을 바꿀 수 있는 등 보통은 접근 금지인 설정을 수정할 수 있다.</p>
</li>
<li><p>데이터베이스 등 개발에 사용하는 도구들을 다루려면 터미널을 사용할 줄 알아야한다.</p>
</li>
</ul>
<h2 id="shell">Shell</h2>
<p>Terminal 기기에서 실행되는 프로그램으로
명령을 받아 그것을 해석하고 프로그램을 실행하는 역할을 한다.</p>
<h1 id="121-터미널-명령어">121. 터미널 명령어</h1>
<h2 id="ls">LS</h2>
<p>list를 의미하며 현재 있는 디렉토리의 콘텐츠를 나열</p>
<h2 id="pwd">PWD</h2>
<p>print Working Directory를 의미하며
현재 작업중인 디렉토리를 출력한다.</p>
<h1 id="cd">cd</h1>
<p>change directory를 의미하여
작업중인 디렉토리를 변경한다.</p>
<h2 id="경로">경로</h2>
<p>특정 파일이나 리소스의 경로를 의미한다.</p>
<h2 id="절대-경로">절대 경로</h2>
<p>/(루트) 에서 시작하며 어느 위치에 있건 이 경로를 사용하면 접근할 수 있다.
ex) /Users</p>
<h2 id="상대-경로">상대 경로</h2>
<p>. , ..을 사용하며 현재 디렉토리를 기준으로 이동한다.</p>
<p>. 현재 디렉토리
.. 상위 디렉토리</p>
<p>디렉토리 간 이동하는 명령어
cd ~ 홈 디렉토리로 이동
cd .. 상위 디렉토리로 이동
cd 절대 경로</p>
<h1 id="mkdir">mkdir</h1>
<p>make directory이며 디렉토리를 생성한다.</p>
<h1 id="man">man</h1>
<p>manual이며 매뉴얼을 의미한다.
ex) man ls // ls의 정보를 제공한다.</p>
<h1 id="flag">flag</h1>
<p>명령어의 옵션으로 명령어의 동작을 바꾸는데 사용된다.</p>
<p>ex) mkidr -v // 디렉토리 생성 후 디렉토리를 출력한다.</p>
<h1 id="touch">touch</h1>
<p>파일을 호출하고 만약 없다면 해당 이름으로 파일을 만든다.</p>
<p>파일이 있는 경우 호출하게 되면 파일의 정보 중 접근시간이 바뀐다.</p>
<h1 id="rm">rm</h1>
<p>파일을 제거하는 명령어</p>
<h2 id="rmdir">rmdir</h2>
<p>디렉토리를 제거하는 명령어
이 때 디렉토리는 비어있는 경우에만 가능하다.</p>
<h2 id="rm--rf">rm -rf</h2>
<p>비어있지 않은 디렉토리를 제거한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[웹개발 부트캠프 2022 1주차 (자바스크립트)]]></title>
            <link>https://velog.io/@b_m_c/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-p2352g6l</link>
            <guid>https://velog.io/@b_m_c/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-p2352g6l</guid>
            <pubDate>Wed, 27 Apr 2022 17:12:43 GMT</pubDate>
            <description><![CDATA[<p>(4/18 ~4/28) The Web Developer 부트캠프 2022 강의 내용 정리
범위 : JavaScript 기초! ~ Javascript 최신 기능들(섹션 14 ~23)</p>
<h1 id="1-자바스크립트란">1. 자바스크립트란</h1>
<p>JavaScript는 움직임, UI 효과, 정보를 실시간으로 업데이트 하는 등의 기능을 포함한 동적인 웹사이트 제작 시 사용되는 프로그래밍 언어</p>
<br/>

<h1 id="2-기본-요소-및-콘솔">2. 기본 요소 및 콘솔</h1>
<h2 id="기본-요소">기본 요소</h2>
<h3 id="타입">타입</h3>
<p>보관하고 다룰 수 있는 다양한 정보의 타입</p>
<ul>
<li>Primitive Type (원시타입)
<br>원시 타입은 프로그래밍 언어에서 쓰기로 정해진 타입 - Number - String - Boolean - Null - Undefined - bigint - symbol</li>
</ul>
<h2 id="콘솔">콘솔</h2>
<p>브라우저에서 코드를 실행하고 결과 값을 확인할 수 있는 창</p>
<p>clear() 콘솔창 지우기</p>
<br/>

<h1 id="3-javascript-숫자">3. Javascript 숫자</h1>
<h2 id="numbers">Numbers</h2>
<pre><code class="language-Javascript">1 // 정수
-1 // 음수
3.14 // 실수</code></pre>
<h2 id="math-operations">Math Operations</h2>
<pre><code class="language-Javascript">50 + 5 // 55

90 - 1 // 89

11111 * 7 // 77777

400 / 25 // 16

27 % 2 // 1

2 ** 4 // 16

// : 주석

// 연산순서 (PEMDAS): parentheses(괄호) &gt; exponent(지수) &gt; multiplication(곱하기)
//                                     &gt; division(나누기) &gt; subtraction(빼기)</code></pre>
<br/>

<h1 id="4-nan은-또-뭘까">4. NaN은 또 뭘까?</h1>
<h2 id="nannot-a-number">NaN(NOT A NUMBER)</h2>
<pre><code class="language-javascript">0 / 0; // NaN

1 + NaN; // NaN

typeof 4; // &quot;number&quot;

typeof 4.231314; // &quot;number&quot;

typeof NaN; // &quot;number&quot; -&gt; 숫자로 간주됨</code></pre>
<br/>

<h1 id="5-변수와-let">5. 변수와 Let</h1>
<h2 id="variables">Variables</h2>
<p>데이터를 담는 공간( 재사용을 위해 값에 이름을 넣어 저장하는 것 )</p>
<pre><code class="language-javascript">let someName = value; // let 변수명 = 저장 하고자 하는 값

let year = 1985; // 변수 선언할때 세미콜론 있어야함

let numHens = 5;

let numRoosters = 1;

numHens + 1; // 6

numHens + numRoosters; // 6

let totalchicken = numHens + numRoosters;

totalchicken; // 6</code></pre>
<br/>

<h1 id="6변수-업데이트하기">6.변수 업데이트하기</h1>
<h2 id="숫자-업데이트">숫자 업데이트</h2>
<pre><code class="language-javascript">let score = 0;

score = score + 5; // 5, 자신에게 5를 더한 값을 score에 저장

score += 5; // 10, 위랑 같은 의미

score -= 5; // 5, 다른 연산자도 가능

score *= 2; // 10

score /= 2; // 5

score++; // 1증가, score+=1; 같은 의미

score--; // 1감소</code></pre>
<br/>

<h1 id="7const와-var">7.Const와 Var</h1>
<h2 id="const">const</h2>
<p>상수(항상 일정하고 바꾸지 않는 값)을 선언할 때 사용하는 키워드</p>
<pre><code class="language-javascript">const luckyNum = 26; //26

luckyNum += 1; //error, 변경할수 없다.

luckyNum = 7; //새로운 값을 할당할수 없다.</code></pre>
<h2 id="var">var</h2>
<p>옛날 방식.. 권장하지 않음(금지)</p>
<p>let과 차이점이 있지만 추후에 다시 다룸</p>
<pre><code class="language-javascript">var runDistance = 26.2; //26.2

runDistance += 1; //27.2</code></pre>
<h1 id="8-boolean">8. Boolean</h1>
<p>True / False 두개의 값이 있다.</p>
<pre><code class="language-javascript">let isActiveGame = true; // true

isActiveGame = false; //false</code></pre>
<h2 id="variable-can-change-types">Variable Can change Types</h2>
<p>type을 변경하는 변수를 가질수 있다.</p>
<pre><code class="language-javascript">let isLoggedIn = false; // false

isLoggiedIn = 2342324; // 타입을 변경해서 저장할수 있다. 권장 X</code></pre>
<h1 id="9변수-명명과-규칙">9.변수 명명과 규칙</h1>
<h2 id="변수-명명과-규칙">변수 명명과 규칙</h2>
<ol>
<li>숫자로 시작할수 없다.</li>
<li>공백을 사용할수 없다.</li>
<li>대소문자를 구별한다.</li>
<li>$, _는 첫글자로 자유롭게 올수 있다.</li>
</ol>
<h2 id="통상적인-관례">통상적인 관례</h2>
<p>카멜 케이스 :</p>
<p>한단어 이상을 써야 할경우 변수의 첫단어를 제외한 각단어의 첫문자를 대문자로 쓰는방법</p>
<pre><code class="language-javascript">let currentYear = 1999;

let userInputNumber = 1234;

let isLoggedIn = true;

let n = 9; // 의미없는 짧은 변수는 피해라, 간결성은 중요X</code></pre>
<h1 id="10-문자열-개요">10. 문자열 개요</h1>
<p>&quot; &quot;, &#39; &#39; 로 묶어야 한다.</p>
<pre><code class="language-javascript">let favAnimal = &#39;Dumbo Octopus&#39;;</code></pre>
<br />

<h1 id="11-indices와-length">11. Indices와 Length</h1>
<h2 id="indices">Indices</h2>
<p>문자열의 문자에는 각각 관련된 인덱스가 있다.</p>
<pre><code class="language-javascript">let animal = &#39;Octopus&#39;;
//animal[0]  &quot;O&quot;
//animal[1]   &quot;c&quot;</code></pre>
<p>문자열에 없는 인덱스인 경우 undefined가 나온다</p>
<pre><code class="language-javascript">let animal = &#39;Octopus&#39;;
//animal[7]  undeifned</code></pre>
<h2 id="length">Length</h2>
<p>문자열의 길이를 출력하는 함수</p>
<pre><code class="language-javascript">let animal = &#39;Octopus&#39;;
animal.length; // 7</code></pre>
<h2 id="문자열은-바꿀-수-없음">문자열은 바꿀 수 없음</h2>
<p>변수에 있는 문자열을 하나하나 바꿀 수 없다.
새로운 문자열을 저장해야함</p>
<pre><code class="language-javascript">let animal = &#39;Octopus&#39;;
animal[0] = &#39;t&#39;;
animal[0]; // 출력 결과: O

animal = &#39;tctopus&#39;; //새로운 문자열로 저장
animal[0]; // 출력 결과 :t</code></pre>
<h2 id="문자열--숫자">문자열 + 숫자</h2>
<p>숫자를 문자열로 바꿔서 합침</p>
<pre><code class="language-javascript">let year = &#39;1999&#39;;
year + 1; // &quot;19991&quot;</code></pre>
<br/>

<h1 id="12-문자열-메서드">12. 문자열 메서드</h1>
<pre><code class="language-javascript">let msg = &#39;hello&#39;;
msg.toUpperCase(); // &quot;HELLO&quot; 대문자로 변경
msg.toLowerCase(); // &quot;hello&quot; 소문자로 변경

msg = &#39; hello world &#39;;
msg.trim(); // &quot;hello world&quot; 앞 뒤 공백 제거 가운데 공백은 제거 안함

msg.trim().toUpperCase(); // &quot;HELLO WORLD&quot; 메소드를 연결해서 사용 가능
&#39; hello world &#39;.trim(); // &quot;hello world&quot; 문자열에 바로 메소드 사용 가능</code></pre>
<br/>

<h1 id="13-인수가-있는-문자열-메서드">13. 인수가 있는 문자열 메서드</h1>
<h2 id="인수">인수</h2>
<p>메서드로 전달되어서 메서드의 동작을 변경하는 입력 값</p>
<pre><code class="language-javascript">let tvShow = &#39;catdog&#39;;
//문자열에서 cat이라는 인수에 해당하는 인덱스 위치의 시작값을 반환
tvShow.indexOf(&#39;cat&#39;); // 출력 결과:0
//5인덱스 끝까지 자름
tvShow.slice(5); //출력 결과: &quot;g&quot;
//0인덱스부터 5인덱스까지 자름
tvShow.slice(0, 5); // 출력 결과: &quot;catdo&quot;
//뒤에서부터 해당 인덱스만큼 자름
tvShow.slice(-5); //출력 결과: &quot;atdog&quot;

let annoyingLaugh = &#39;teehee so funny! teehee!&#39;;
annoyingLaugh.replace(&#39;teehee&#39;, &#39;haha&#39;); // 출력결과 : &#39;haha so funny! teehee!&#39;
//해당 문자열 인수만큼 반복
annoyingLaugh.repeat(2);
//&#39;teehee so funny! teehee!teehee so funny! teehee!&#39;;</code></pre>
<br/>

<h1 id="14-문자열-템플릿">14. 문자열 템플릿</h1>
<p>``(back-tick)을 사용한다. 표현식은 ${}로 감싼다.</p>
<p>문자열 안에 표현식을 내장할 수 있는 문자열들을 만들고 해당 표현식은 평가된 후에 문자열로 바뀐다.</p>
<pre><code class="language-javascript">let count = 10;
let string = `back tick ${count}`; // 출력 결과: &quot;back tick 10&quot;
let string = `back tick ${count * 2}`; // 출력 결과: &quot;back tick 20&quot;</code></pre>
<br/>

<h1 id="15-undefined와-null">15. Undefined와 Null</h1>
<h2 id="undefined">Undefined</h2>
<p>정의된 값이 없다.</p>
<h2 id="null">Null</h2>
<p>값을 일부러 지정하지 않음을 명시적으로 표시</p>
<br/>

<h1 id="16-math-객체와-난수">16. Math 객체와 난수</h1>
<h2 id="math-객체">Math 객체</h2>
<p>수학과 관련된 특성과 메서드의 모음</p>
<pre><code class="language-javascript">Math.PI; // 3.141592... 수학적 상수
Math.round(4.9); //5 소수점 한자리가 5이상이면 올림
Math.abs(-456); // 456 절대값
Math.pow(2, 5); // 32  제곱수
Math.floor(3.999); //3 버림</code></pre>
<h2 id="난수">난수</h2>
<p>무작위로 생성되는 수</p>
<pre><code class="language-javascript">Math.random(); // 0~1 사이의 수를 무작위로 생성

// 특정 범위의 수를 구하기 위해선 범위의 끝 수를 곱하고, 자연수를 얻기 위해서 Math.floor를 사용해야함
Math.floor(Math.random() * 5); // 0~5사이의 자연수</code></pre>
<br/>

<h1 id="17-비교연산자">17. 비교연산자</h1>
<pre><code class="language-javascript">&gt;
&lt;
&gt;=
&lt;=
==
!=
=== // strict equality
!== // strict non-equality</code></pre>
<p>boolean 판단에 대한 결과 값은 true, false이다.</p>
<p>문자열 비교는 유니코드값으로 비교된다.</p>
<h1 id="18-이중-등호-vs-삼중-등호">18. 이중 등호 vs 삼중 등호</h1>
<h2 id="이중-등호-">이중 등호 (==)</h2>
<p>값에 대한 비교만 하며 타입에 대해선 하지 않는다.</p>
<pre><code class="language-javascript">10 == &#39;10&#39;; // true
null == undefined; //true
0 == false; // true
true == false; // false</code></pre>
<h2 id="삼중-등호-">삼중 등호 (===)</h2>
<p>값과 타입을 모두 비교한다.</p>
<pre><code class="language-javascript">10 === &#39;10&#39;; // false
null === undefined; // false
0 === false; // false
true === false; // false</code></pre>
<h2 id="엄격한-비동등-연산자-">엄격한 비동등 연산자 (!==)</h2>
<p>값과 타입에 대해 비동등한지 비교</p>
<br/>

<h1 id="19-console-alert-prompt">19. Console, Alert, Prompt</h1>
<h2 id="console">Console</h2>
<p>실시간으로 자바스크립트를 실행하고, 에러 메시지등을 출력해주는 기능</p>
<pre><code class="language-javascript">console.log(&#39;hi&#39;); // &#39;hi&#39;;
console.log(3 + 4); // 7;
console.err(&#39;err&#39;); // &#39;err&#39; 출력
console.warning(&#39;warning&#39;); // &#39;warning&#39; 출력
console.clear(); //콘솔 비우기</code></pre>
<h2 id="alert">Alert</h2>
<p>사용자에게 팝업창으로 메세지를 표시한다.</p>
<pre><code class="language-javascript">alert(&#39;alert!&#39;);</code></pre>
<h2 id="prompt">Prompt</h2>
<p>사용자로부터 입력값을 받는 창을 띄우며 입력한 값을 받는다.</p>
<pre><code class="language-javascript">prompt(&#39;저장하시겠습니까?&#39;);</code></pre>
<h1 id="20-javascript-실행하기">20. javascript 실행하기</h1>
<ol>
<li>실행하려는 javascript 코드를 script 태그로 감싼다.</li>
</ol>
<pre><code class="language-html">&lt;!DOCTYPE hmtl&gt;

&lt;html&gt;
    &lt;head&gt; &lt;/head&gt;

    &lt;body&gt;
        &lt;script&gt;
            consoel.log(&#39;hi&#39;);
        &lt;/script&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>
<ol start="2">
<li>외부에 script코드를 작성하고 src에 해당 경로 및 파일명을 기입한다.</li>
</ol>
<h2 id="appjs">app.js</h2>
<pre><code class="language-javascript">console.log(&#39;javascript!&#39;)&#39;</code></pre>
<h2 id="indexhtml">index.html</h2>
<pre><code class="language-html">&lt;!DOCTYPE hmtl&gt;

&lt;html&gt;
    &lt;head&gt;
        &lt;script src=&quot;app.js&quot;&gt;&lt;/script&gt;
    &lt;/head&gt;

    &lt;body&gt;&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p>=&gt; 콘솔에 javascript!가 찍힌다.</p>
<p>이 방법의 경우 javascript를 넣을 이상적인 위치는 body 끝 부분이다.</p>
<h2 id="indexhtml-1">index.html</h2>
<pre><code class="language-html">&lt;!DOCTYPE hmtl&gt;

&lt;html&gt;
    &lt;head&gt; &lt;/head&gt;

    &lt;body&gt;
        &lt;h1&gt;javascript!&lt;/h1&gt;
        &lt;script src=&quot;app.js&quot;&gt;&lt;/script&gt;
    &lt;/body&gt;
&lt;/html&gt;</code></pre>
<br/>

<h1 id="21-if-구문">21. If 구문</h1>
<p>조건에 대한 판단 값이 true이면 실행</p>
<pre><code class="language-javascript">if (1 + 1 == 2) {
    console.log(&#39;If Execute&#39;);
} // 출력 값 : &#39;If Execute&#39;;

if (1 + 2 == 2) {
    console.log(&#39;true&#39;);
} // 출력 값 : undefinded</code></pre>
<br/>

<h1 id="22-else-if-구문">22. Else-If 구문</h1>
<p>If 조건에 대한 판단 값이 false이면
해장 조건문 판단 후 true이면 실행</p>
<pre><code class="language-javascript">if (1 + 2 == 2) {
} else if (1 + 1 == 2) {
    console.log(&#39;Else-If Execute&#39;);
} // 출력 값 : &#39;Else-If Execute&#39;</code></pre>
<br/>

<h1 id="23-else">23. Else</h1>
<p>조건문이 없으며 if문 또는 else-if문에 대한 조건문 판단 값이 false이면 실행</p>
<pre><code class="language-javascript">
if(false)
else if(false)
else {
    console.log(&#39;Else Execute&#39;);
} // &#39;Else Execute&#39;
</code></pre>
<br/>

<h1 id="24-조건부-네스팅nesting">24. 조건부 네스팅(Nesting)</h1>
<p>조건문 안에 조건문 넣기</p>
<pre><code class="language-javascript">let password = &#39;cat dog&#39;;

if (password.length &gt;= 6) {
    if (password.indexOf(&#39; &#39;) === -1) {
        console.log(&#39;Valid password!&#39;);
    } else {
        console.log(&#39;Password cannot include spaces&#39;);
    }
} else {
    console.log(&#39;Password too short!&#39;);
}</code></pre>
<h1 id="25-truth-y-값과-false-y-값">25. Truth-y 값과 False-y 값</h1>
<p>Javascript의 모든 값에는 고유 truth-y, false-y가 있다.</p>
<pre><code>Falsy values :
false
0
&quot;&quot;(empty string)
null
undefined
NaN

Everything else is truthy!</code></pre><br/>

<h1 id="26-논리함수-and">26. 논리함수 AND</h1>
<p>두 조건이 다 참이여야 참</p>
<pre><code class="language-javascript">true &amp;&amp; true; // true
true &amp;&amp; false; // false
false &amp;&amp; false; // false</code></pre>
<h1 id="27-논리함수-or">27. 논리함수 OR</h1>
<p>한 조건이라도 참이면 참</p>
<pre><code class="language-javascript">true || true; // true
true || false; // true
false || false; // false</code></pre>
<h1 id="28-논리함수-not">28. 논리함수 NOT</h1>
<p>표현식에 대한 boolean 값을 반전시킴</p>
<pre><code class="language-javascript">!true; // false
!false; // true</code></pre>
<h1 id="29-switch-조건문">29. Switch 조건문</h1>
<p>switch문에 들어가는 인수에 따라 실행되는 코드가 다르다.</p>
<pre><code class="language-javascript">const day = 2;
switch (day) {
    case 1:
        console.log(&#39;MONDAY&#39;);
        break; // break를 넣어주어야 다음 case 코드가 실행되지 않는다.
    case 2:
        console.log(&#39;TUESDAY&#39;);
        break;
    default:
        console.log(&#39;INVALID NUMBER!&#39;); // case에 해당하지 않는 값일 경우 해당 코드 실행
} // 출력 값 : &quot;TUESDAY&quot;;</code></pre>
<br>

<h1 id="30-배열-개요">30. 배열 개요</h1>
<h2 id="배열">배열</h2>
<p>순서가 있는 값의 집합
여기서 순서란 인덱스 순서를 의미한다.</p>
<pre><code class="language-javascript">const colors = [&#39;red&#39;, &#39;blue&#39;, &#39;green&#39;];
// colors[0]=&#39;red&#39;
// colors[1]=&#39;blue&#39;
// colors[2]=&#39;green&#39;</code></pre>
<p>자바스크립트에서 배열은 여러 타입에 대한 값을 가질
수 있다.</p>
<pre><code class="language-javascript">const array = [1, &#39;1&#39;, null, undefined];</code></pre>
<br>

<h1 id="31-배열-임의-접근">31. 배열 임의 접근</h1>
<p>인덱스 접근으로 특정 요소를 찾거나 값의 변경이 가능하다.</p>
<pre><code class="language-javascript">let colors = [&#39;red&#39;, &#39;blue&#39;];
colors[0] = &#39;green&#39;;
colors[0]; // &#39;green&#39;</code></pre>
<pre><code class="language-javascript">let colors = [&#39;red&#39;, &#39;blue&#39;];
colors[10] = &#39;yellow&#39;;
//이렇게 하면 인덱스 2~9까지 undefined로 값이 들어간다.</code></pre>
<br>

<h1 id="32-push-와-pop-메소드">32. Push 와 Pop 메소드</h1>
<h2 id="push">Push</h2>
<p>배열에 마지막에 해당 값을 저장 후 배열의 길이 값을 반환한다.</p>
<pre><code class="language-javascript">let colors = [&#39;red&#39;];
arr.push(&#39;blue&#39;); // 2</code></pre>
<h2 id="pop">Pop</h2>
<p>배열에 마지막 값을 꺼낸다. 배열에 있던 값은 삭제한다.</p>
<pre><code class="language-javascript">let colors = [&#39;red&#39;, &#39;blue&#39;];
colors.pop(); // blue
colors; // [&#39;red&#39;]</code></pre>
<br>

<h1 id="33-shift-와-unshift">33. Shift 와 Unshift</h1>
<h2 id="shift">Shift</h2>
<p>배열 시작부터 제거하고 그 값을 반환</p>
<pre><code class="language-javascript">let arr = [1, 2, 3];
arr.shift(); // 1
arr; // [2,3]</code></pre>
<h2 id="unshift">Unshift</h2>
<p>배열 시작에 추가하고 배열 길이 반환</p>
<pre><code class="language-javascript">let arr = [1, 2, 3];
arr.unshift(5); // 4
arr; // [5,1,2,3]</code></pre>
<h1 id="34-concat-indexof-includes-reverse">34. Concat, indexOf, includes, reverse</h1>
<h2 id="concat">Concat</h2>
<p>2개의 배열을 붙여서 새로운 배열을 만든다.</p>
<pre><code class="language-javascript">let arr1 = [1, 2];
let arr2 = [3, 4];

arr1.concat(arr2); // [1,2,3,4]</code></pre>
<h2 id="indexof">indexOf</h2>
<p>인수가 배열에 있으면 해당 값의 인덱스 값을 반환한다. 없으면 -1을 반환한다.</p>
<pre><code class="language-javascript">let colors = [&#39;green&#39;, &#39;yellow&#39;];
colors.indexOf(&#39;blue&#39;); // -1
colors.indexOf(&#39;green&#39;); // 0</code></pre>
<h2 id="includes">includes</h2>
<p>인수가 배열에 있으면 true 없으면 false를 반환한다.</p>
<pre><code class="language-javascript">let arr = [1, 2];
arr.includes(1); // true</code></pre>
<h2 id="reverse">reverse</h2>
<p>파괴메서드로 원본 배열을 바꾼다.
해당 배열의 값을 뒤집는다.</p>
<pre><code class="language-javascript">let arr = [1, 2, 3];
arr.reverse(); // [3,2,1]</code></pre>
<br>

<h1 id="35-slice-splice-sort">35. Slice, Splice, Sort</h1>
<h2 id="slice">Slice</h2>
<p>배열을 잘라 새로운 배열을 만든다.<br>
인수가 1개 일 땐 slice(startIndex)
2개일 땐 slice(startIndex,endIndex)</p>
<pre><code class="language-javascript">let arr = [1, 2, 3];
arr.slice(); //인수가 없을 땐 원본 배열 그대로를 복사한다.

arr.slice(2); // [3]
arr.slice(0, 1); // [1] startIndex부터 endIndex이전까지 자른다</code></pre>
<h2 id="splice">Splice</h2>
<p>파괴메소드이며 원본 배열을 바꾼다.</p>
<p>배열에 삽입하거나 결합시킨다.</p>
<p>splice(startIndex, deleteCount, &quot;넣을 값&quot;) <br/>
deleteCount가 0이면 삽입만을 한다.</p>
<pre><code class="language-javascript">let arr = [1, 2, 3];
arr.splice(0, 0, &#39;3&#39;); // [3,1,2,3]</code></pre>
<h2 id="sort">Sort</h2>
<p>배열에 있는 모든 값을 문자열로 바꾼 후 유니코드 값으로 대소 비교를 한 후 정렬한다.</p>
<pre><code class="language-javascript">let arr = [1, 30, 200, 1000];

arr.sort(); // [1,1000,200,30,] 정렬이 제대로 되지 않는다.

/*
정렬 기준을 정해주는 함수를 넣어주면 제대로 대소비교가 된다.
1을 리턴하면 순서를 앞으로
0을 리턴하면 순서 변동x
-1을 리턴하면 순서를 뒤로한다.
*/
arr.sort(function (a, b) {
    if (a &gt; b) return 1;
    else if (a == b) return 0;
    else return -1;
});</code></pre>
<h1 id="36-참조-타입과-동일성-테스트">36. 참조 타입과 동일성 테스트</h1>
<h2 id="참조타입">참조타입</h2>
<p>자바스크립트에선 원시 자료형이 아닌 모든 것은 참조 자료형이다. 참조형은 원시형 데이터의 집합이다. 배열([])과 객체({}), 함수(function(){})가 대표적</p>
<p>여기서 참조란 메모리 주소상에서 해당 데이터가 위치한 주소를 가리키는 것이다.</p>
<pre><code class="language-javascript">let arr = [1, 2, 3];
arr === [1, 2, 3]; //false
let arr2 = arr;
arr2 === arr; //true</code></pre>
<br/>

<h1 id="37-배열--const">37. 배열 + Const</h1>
<p>배열에 컨텐츠는 바꿀 수 있지만
참조하는 배열은 바꾸지 못함</p>
<pre><code class="language-javascript">const arr = [1, 2, 3];
arr[0] = 2; // [2,2,3]
let arr2 = [1, 2, 3, 4];
arr = arr2; //  Uncaught TypeError: Assignment to constant variable.</code></pre>
<br/>

<h1 id="38-다차원-배열">38. 다차원 배열</h1>
<p>2차원 배열</p>
<p>3차원 배열</p>
<pre><code class="language-javascript">const colors = [
    [&#39;red&#39;, &#39;blue&#39;],
    [&#39;grren&#39;, &#39;orange&#39;],
];
colors[0][0]; // &#39;red&#39;
colors[1][1]; // &#39;orange&#39;</code></pre>
<br/>

<h1 id="39-객체-리터럴-개요-및-생성">39. 객체 리터럴 개요 및 생성</h1>
<h2 id="객체-리터럴">객체 리터럴</h2>
<p>중괄호({})로 감싸진 하나 이상의 속성 이름과 속성 값의 리스트
객체도 배열처럼 데이터 구조의 한 종류
객체는 key:value(프로퍼티) 형식으로 데이터 저장</p>
<p>key는 다 문자열로 변환되어 저장</p>
<pre><code class="language-javascript">// 객체 선언 및 초기화
const object = {
    totalSteps: 30867,
    totalMiles: 211.7,
};</code></pre>
<h1 id="40-객체-외부-데이터에-액세스하기">40. 객체 외부 데이터에 액세스하기</h1>
<h2 id="점-구문">점 구문</h2>
<pre><code class="language-javascript">const movie = {
    name: &#39;superman&#39;,
    date: &#39;2021.10.10&#39;,
    price: 6500,
};

movie.name; // &quot;superman&quot;</code></pre>
<h2 id="대괄호-구문">대괄호 구문</h2>
<p>변수 같은 유동적인 값을 객체에서 key로 쓰고 싶을 때 사용</p>
<pre><code class="language-javascript">const year = {
    1999: &#39;Ok&#39;,
    2000: &#39;Good&#39;,
};
let targetYear = &#39;1999&#39;;
movie[targetYear]; // &quot;Ok&quot;</code></pre>
<h1 id="41-객체-수정하기">41. 객체 수정하기</h1>
<p>객체.key = value
객체[key] = value
문자열은 &quot;key&quot; 숫자는 key 형식으로로 한다.</p>
<p>형식으로 수정을 한다.</p>
<pre><code class="language-javascript">const object = {
    color: &#39;blue&#39;,
};
object.color = &#39;skyblue&#39;;
object.color; // &#39;skyblue&#39;

object[&#39;color&#39;];</code></pre>
<h1 id="41-배열과-객체-네스트-구성하기">41. 배열과 객체 네스트 구성하기</h1>
<pre><code class="language-javascript">
const comments = [
    {username:&#39;Tammy&#39;, text=&quot;haha&quot;, votes:9},
    {username:&#39;Tammy&#39;, text=&quot;haha&quot;, votes:9}
]
</code></pre>
<h1 id="42-for-루프">42. For 루프</h1>
<p>for(
    &amp;nbsp [initialExpression]; //초기표현식
    &amp;nbsp [condition] //조건식
    &amp;nbsp [incrementExpression] // 증감식
)</p>
<pre><code class="language-javascript">for (let i = 0; i &lt; 3; i++) console.log(i);
// 1
// 2
// 3</code></pre>
<h1 id="43-배열-루프">43. 배열 루프</h1>
<pre><code class="language-javascript">const animals = [&#39;lions&#39;, &#39;tigers&#39;, &#39;bears&#39;];

for (let i=0;i&lt;animals.length;i++&gt;){
    console.log(animals[i]);
}
// &#39;lions&#39;
// &#39;tigers&#39;
// &#39;bears&#39;</code></pre>
<h1 id="44-네스트-구성-루프">44. 네스트 구성 루프</h1>
<pre><code class="language-javascript">//구구단
for (let i = 1; i &lt; 10; i++) {
    for (let j = 1; j &lt; 10; j++) {
        console.log(`${i}*${j}=${i * j}`);
    }
}

// 2차원 배열 원소 출력

const seatingChart = [
    [&#39;Kristen&#39;, &#39;Erik&#39;, &#39;Namita&#39;],
    [&#39;Geofferey&#39;, &#39;Junita&#39;, &#39;Antonio&#39;, &#39;Kevin&#39;],
    [&#39;Yuma&#39;],
];

for(let i=0;i&lt;seatingChart.length;i+++){
    const row = seatingChart[i]
    for(let j=0;j&lt;row;j++){
        console.log(row[j]);
    }
}</code></pre>
<h1 id="45-while-루프">45. While 루프</h1>
<p>while (조건식)
{ 실행문}</p>
<pre><code class="language-javascript">let num = 0;
while (num &lt; 10) {
    console.log(num);
    num++;
}

// 조건이 참이될 때가지 계속 실행문을 실행시킬 수 있음
const SECRET = &#39;CODE&#39;;

let guess = prompt(&#39;enter ther secret code...&#39;);

while (guess !== SECRET) {
    guess = prompt(&#39;enter ther secret code...&#39;);
}</code></pre>
<h1 id="46-정지break-키워드">46. 정지/break 키워드</h1>
<h2 id="break">break</h2>
<p>반복문을 벗어나게 하는 키워드</p>
<pre><code class="language-javascript">let num = 0;

while (num &lt; 5) {
    num++;
    if (num == 3) break; //3번 수행되고 반복문을 빠져나온다.
}</code></pre>
<h1 id="47-for루프의-유용함">47. For루프의 유용함</h1>
<h2 id="for-of">for of</h2>
<p>순서가 있는 배열 리스트에 사용</p>
<pre><code class="language-javascript">const items = [&#39;1&#39;, &#39;2&#39;, &#39;3&#39;];
for (let item of items) {
    console.log(item);
}
// 1
// 2
// 3</code></pre>
<h2 id="for-in">for in</h2>
<p>for in은 순서가 없는 경우에 사용</p>
<pre><code class="language-javascript">const obj = {
    name: &#39;test&#39;,
    color: &#39;brown&#39;,
};

for (key in obj) {
    console.log(key);
    // name
    //color
}</code></pre>
<h1 id="48-객체-루프">48. 객체 루프</h1>
<p>객체는 iterable이 아니기 때문에
반복을 하기 위한 방법이 따로 존재함</p>
<ol>
<li><p>for in</p>
</li>
<li><p>key,value 배열을 사용하는 방법</p>
<p> Object.keys() =&gt; key 배열 반환</p>
<p> Object.values() =&gt; value 배열 반환</p>
<p> Object.entries() =&gt; [key,value] 배열 반환</p>
</li>
</ol>
<pre><code class="language-javascript">const testScores = {
    A: 80,
    B: 90,
    C: 95,
};

for (let person in testScores) {
    console.log(`${person} scored ${testScores[person]}`);
}

for (let person of Object.keys(testScores)) {
    console.log(`${person} scored ${testScores[person]}`);
}
for (entry of Object.entries(testScores)) {
    console.log(entry);
}
// [&#39;A&#39;,80]
// [&#39;B&#39;,90]
// [&#39;C&#39;,95]</code></pre>
<h1 id="49-todo-list-프로젝트">49. todo list 프로젝트</h1>
<pre><code class="language-javascript">let isQuit = false;
let todos = [];
let todo = null;

while (!isQuit) {
    let input = prompt(&#39;what would you like to do&#39;);
    switch (input) {
        case &#39;new&#39;:
            todo = prompt(&#39;Insert todo&#39;);
            if (todo) todos.push(todo);
            console.log(todos);
            break;
        case &#39;list&#39;:
            for (let entry of Object.entries(todos)) {
                console.log(`${entry[0]}:${entry[1]}`);
            }
            break;
        case &#39;delete&#39;:
            const index = parseInt(prompt(&#39;Ok, enter an index to delete&#39;));
            if (!Number.isNaN(index) &amp;&amp; index &lt; todos.length) {
                const deleted = todos.splice(index, 1);
                console.log(`Ok, deleted ${deleted[0]}`);
            } else {
                console.log(&#39;Unknown index&#39;);
            }
            break;
        case &#39;quit&#39;:
        case &#39;q&#39;:
        case null:
            isQuit = true;
            break;

        default:
    }
}
console.log(&#39;Ok QUIT THE APP!&#39;);</code></pre>
<h1 id="50-함수-개요">50. 함수 개요</h1>
<h2 id="함수">함수</h2>
<p>코드의 재사용 가능한 일부로서 언제든 사용할 수 있도록 이름을 붙인 것이다.</p>
<p>코드의 가독성, 재사용성을 향상시킨다.</p>
<br/>

<h1 id="51-함수-정의-및-호출">51. 함수 정의 및 호출</h1>
<pre><code class="language-javascript">function first() {} //함수 정의

first(); // 함수 호출</code></pre>
<h1 id="52-인수와-매개변수-개요">52. 인수와 매개변수 개요</h1>
<h2 id="인수-1">인수</h2>
<p>함수에 입력하는 값을 의미한다.</p>
<h2 id="매개변수">매개변수</h2>
<p>함수 선언식의 괄호안에 작성되는 변수</p>
<br/>

<h1 id="53-return-키워드">53. return 키워드</h1>
<h2 id="return">return</h2>
<p>함수안에서 처리된 값을 외부에서 사용할 수 있게 해주거나
함수를 빠져나오게 하는데 사용된다.</p>
</br>

<h1 id="54-함수-범위">54. 함수 범위</h1>
<h2 id="함수-내-변수">함수 내 변수</h2>
<p>함수 안에서 정의한 변수들은 그 함수로 범위가 한정됨</p>
<h2 id="변수-액세스-범위">변수 액세스 범위</h2>
<p>함수 밖에 있는 변수에 액세스 가능
<br>
안에 있는 변수가 액세스 우선순위가 더 높음</p>
<pre><code class="language-javascript">let color = &#39;blue&#39;;

function f() {
    console.log(color); // blue
}

function t() {
    let color = &#39;green&#39;;
    console.log(color); // green
}</code></pre>
<br>

<h1 id="55-블록-범위">55. 블록 범위</h1>
<h2 id="블록">블록</h2>
<p>함수를 제외하고는 기본적으로 중괄호가 있는 모든 곳을 의미함
<br></p>
<p>블록에서 선언된 변수는 블록안에서만 유효함 (var타입 제외)</p>
<pre><code class="language-javascript">let radius = 8;
if (radius &gt; 0) {
    const PI = 3.14159;
    let msg = &#39;Hi&#39;;
} // if문 내부도 block임</code></pre>
<br/>

<h1 id="56-렉시컬-범위">56. 렉시컬 범위</h1>
<p>함수를 선언하는 시점에서 상위 스코프가 결정된다.</p>
<p>부모 함수의 안에 중첩된 내부 함수는 해당 외부 함수내 변수 또는 범위 내에서 정의된 변수에 액세스할 수 있다.
<br></p>
<p>외부 함수는 내부함수의 변수에 액세스할 수 없다.</p>
<p>동일한 스코프에서 함수를 선언한 경우</p>
<pre><code class="language-javascript">let x = 1;
function external() {
    let x = 10;
    internal(); // 선언한 시점에서 x=1이 internal의 상위 스코프이므로 출력결과는 1이다.
}

function internal() {
    console.log(x);
}</code></pre>
<p>중첩된 내부 함수의 경우</p>
<pre><code class="language-javascript">let color = &#39;green&#39;;

function external() {
    let color = &#39;blue&#39;;
    internal();
    function internal() {
        console.log(color); // 선언 시 internal의 상위 스코프는 external이기 때문
    }
}

external(); //출력 값 : blue</code></pre>
<br>

<h1 id="57-함수-표현식">57 함수 표현식</h1>
<p>함수를 정의한 것을 변수에 할당하는 것
<br/>
이것이 가능한 이유는 javascript에서 함수가 값으로 처리되기 때문 이 의미는 함수를 반환,저장할 수 있다는 의미이다.</p>
<br/>

<pre><code class="language-javascript">const f = function (parameter) {};</code></pre>
<h1 id="58-고차함수">58. 고차함수</h1>
<p>다른 함수를 인수로 받아서 보통은 그 인수로 어떤 작업을 하는 함수이자 또 함수를 반환할 수 있는 함수</p>
<pre><code class="language-javascript">function callFunc(func) {
    func();
}

function func() {
    console.log(&#39;call&#39;);
}

callFunc(func); // call</code></pre>
<h1 id="59-반환함수">59. 반환함수</h1>
<p>함수 내에서 함수를 반환하는 함수
<br/></p>
<p>팩토리 함수를 설정하는 패턴에 사용함</p>
<pre><code class="language-javascript">function makeBetweenFunc(min, max) {
    return function (num) {
        return num &gt;= min &amp;&amp; num &lt;= max;
    };
}
/* 아이,어른,노인인지 여부를 판단하는 코드는 같으므로 이를 반환함수를 사용하면
 코드를 재사용하여 처리할 수 있다.*/

const isChild = makeBetweenFunc(0, 18);
const isAdult = makeBetweenFunc(19, 64);
const isSenior = makeBetweenFunc(65, 120);

console.log(isChild(18)); //  true
console.log(isAdult(30)); // true
console.log(isSenior(115)); // true</code></pre>
<br/>

<h1 id="60-메서드-정의하기">60. 메서드 정의하기</h1>
<h2 id="메서드">메서드</h2>
<p>메서드는 객체에 종속된 특성으로 함수에 포함되는 개념</p>
<pre><code class="language-javascript">const obj = {
    add(a, b) {
        return a + b;
    }, // 속기법
    minus : function(a-b){
        return a-b
    }

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

<h1 id="61-this">61. this</h1>
<p>this는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수이다.</p>
<p>사용된 함수 호출 컨텍스트에 따라 this값이 바뀜</p>
<pre><code class="language-javascript">// 객체 안에서 this는 객체 자신을 가리킴
const cat = {
    name : &#39;cat&#39;;
    meow(){
        console.log(this.name);
    }

}

// 최상위 객체 window
function meow(){
    console.log(this) // window 객체를 가리킴
}
</code></pre>
<br>

<h1 id="62-trycatch-사용하기">62. Try/Catch 사용하기</h1>
<pre><code class="language-javascript">try {
    //실행 부분
} catch (e) {
    //에러 처리 부분
}</code></pre>
<br/>

<h1 id="63-foreach">63. foreach</h1>
<p>배열 아이템 각각에 대해 인수로 넣은 함수를 실행함</p>
<pre><code class="language-javascript">let nums = [1, 2, 3];

function print(num) {
    console.log(num);
}

nums.foreach(print);
//1
//2
//3</code></pre>
<h1 id="64-map-메서드">64. Map 메서드</h1>
<p>배열 아이템 각각에 대해 인수로 넣은 함수를 실행하고 콜백의 반환 값을 이용해서 새로운 배열을 만듬</p>
<pre><code class="language-javascript">let nums = [1, 2, 3];

nums.map(function (num) {
    return num * num;
});
// nums = [1,4,9]</code></pre>
<h1 id="65-화살표-함수">65 화살표 함수</h1>
<p>function 키워드 함수명을 쓰지 않고 =&gt; 를 사용하여 함수 정의
(매개변수) =&gt; { }
매개변수가 한개일 땐 ()</p>
<pre><code class="language-javascript">const sum = (x, y) =&gt; {
    return x + y;
};</code></pre>
<h1 id="66-화살표-함수의-반환">66 화살표 함수의 반환</h1>
<h2 id="암시적-반환">암시적 반환</h2>
<p>함수안에 return문 있을 경우 return 키워드 생략 가능 이 때 중괄호를 생략하거나 ()로 감싸야함</p>
<pre><code class="language-javascript">const test = (x) =&gt; x; // x
const test2 = (y) =&gt; y; // y</code></pre>
<br/>

<h1 id="67-settimeout과-setinterval">67. setTimeout과 setInterval</h1>
<h2 id="settimeout">setTimeout</h2>
<p>지정된 시간안에 한번만 수행</p>
<pre><code class="language-javascript">//3초 뒤 테스트 출력
setTimeout(() =&gt; {
    console.log(&#39;테스트&#39;);
}, 3000);</code></pre>
<h2 id="setinterval">setInterval</h2>
<p>지정된 시간을 주기로 반복 수행</p>
<pre><code class="language-javascript">//3초 주기로 반복
const id = setInterval(() =&gt; {
    console.log(&#39;test&#39;);
}, 3000);

clearInterval(id); // 중단됨</code></pre>
<br/>

<h1 id="68-filter">68. filter</h1>
<p>배열에서 조건을 충족하는 원소만 모아 새로운 배열 생성</p>
<pre><code class="language-javascript">const numbers = [1, 2, 3, 4, 5];

numbers.filter((num) =&gt; num % 2 == 0); // [2,4]</code></pre>
<br/>

<h1 id="69-some과-every-메소드">69. Some과 every 메소드</h1>
<h2 id="some">Some</h2>
<p>배열 원소중 일부만이라도 통과하면 참을 반환
그렇지 않으면 거짓을 반환</p>
<pre><code class="language-javascript">const nums = [1, 2, 3];

nums.some((num) =&gt; num % 2 == 0); // true</code></pre>
<h2 id="every">Every</h2>
<pre><code class="language-javascript">const nums = [1, 2, 3];
nums.every((num) =&gt; num % 2 == 0); //false</code></pre>
<p>배열 원소가 테스트를 다 통과하면 참을 반환
그렇지 않으면 거짓을 반환</p>
<br/>

<h1 id="70-reduce">70. reduce</h1>
<p>배열 원소에 함수를 수행시켜 최종적으로 하나의 결과값을 반환</p>
<pre><code class="language-javascript">[1, 3, 5, 7, 9, 11].reduce((accumulator, currentValue) =&gt; {
    return accumulator + currentValue;
}); // 36</code></pre>
<p>두 번째 인수를 주면 초기 값을 주게된다.</p>
<pre><code class="language-javascript">[1, 3, 5, 7, 9, 11].reduce((accumulator, currentValue) =&gt; {
    return accumulator + currentValue;
}, 100); // 136</code></pre>
<br/>

<h1 id="71-화살표-함수와-this">71. 화살표 함수와 &#39;this&#39;</h1>
<p>화살표 함수에서 this는 함수가 만든 범위에 상속되는 this 키워드 값과 같다.</p>
<pre><code class="language-javascript">
const cat ={

    name :&quot;cat&quot;,
    call:()=&gt;{console.log(this)},
    home:function(){console.log(this)}
    walk:function(){
        setTimeout(()=&gt;{
            console.log(this)
        },1000)
    }
}

cat.call() // window 객체
cat.home() // cat 객체
cat.walk() // cat 객체</code></pre>
<br/>

<h1 id="72-디폴트-매개변수">72. 디폴트 매개변수</h1>
<p>인수에 값이 없을 경우 매개변수에 지정한 값이 할당됨</p>
<pre><code class="language-javascript">function sum(a, b = 1) {
    return a + b;
}

sum(1); //2
sum(1, 2); //3</code></pre>
<br/>

<h1 id="73-스프레드">73. 스프레드</h1>
<p>배열,반복가능한 객체가 펼쳐지고 인수는 따로 들어감</p>
<h2 id="함수-호출시의-스프레드-구문">함수 호출시의 스프레드 구문</h2>
<pre><code class="language-javascript">const nums = [1, 2, 3];
Math.max(nums); // NaN
Math.max(...nums); // //3</code></pre>
<h2 id="행렬-리터럴-스프레드-구문">행렬 리터럴 스프레드 구문</h2>
<p>배열을 다른 배열에 복사</p>
<pre><code class="language-javascript">const cat = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;];
const dog = [&#39;d&#39;, &#39;e&#39;, &#39;f&#39;];
const allCatDog = [...cat, ...dog]; // [&#39;a&#39;,&#39;b&#39;,&#39;c&#39;,&#39;d&#39;,&#39;e&#39;,&#39;f&#39;]</code></pre>
<h2 id="객체-스프레드-구문">객체 스프레드 구문</h2>
<p>객체를 펼쳐서 복사할 때 사용
<br>
객체를 변형하지 않고 복사할 수 있음</p>
<pre><code class="language-javascript">const dataFromForm = {
    email: &#39;test@test.com&#39;,
    password: &#39;tobias123!&#39;,
    username: &#39;titk&#39;,
};
const newDataFormForm = { ...dataFromForm, id: &#39;test&#39;, password: &#39;1234&#39; };
/* {
    &quot;email&quot;: &quot;test@test.com&quot;,
    &quot;password&quot;: &quot;1234&quot;,
    &quot;username&quot;: &quot;titk&quot;,
    &quot;id&quot;: &quot;test&quot;
} */</code></pre>
<br/>

<h1 id="74-rest-매개-변수">74. rest 매개 변수</h1>
<h2 id="인수-객체">인수 객체</h2>
<p>인수에 ...붙이면 인수를 배열로 받음
인수의 갯수를 정하지 않을 경우 사용</p>
<pre><code class="language-javascript">function sum(...nums) {
    return nums.reduce((total, currentValue) =&gt; total + currentValue);
}

sum(1, 2, 3, 4, 5); //15</code></pre>
<br/>

<h1 id="75-배열-분해">75. 배열 분해</h1>
<p>값을 해체하고 꺼내고 선정하는 간편한 방식</p>
<pre><code class="language-javascript">const nums = [1, 2, 3, 4, 5];

//배열 앞에서 순서대로 해서 갯수만큼 값이 들어감
const [gold, silver, bronze] = nums;
// gold =&gt;1
// silver =&gt;2
// bronze =&gt; 3</code></pre>
<br/>

<h1 id="76-객체-분해">76. 객체 분해</h1>
<p>객체 속성명을 {}안에 넣고 객체를 할당하면
속섬명에 맞는 값이 할당됨</p>
<pre><code class="language-javascript">
const obj = {
    name :&quot;phone&quot;
    price : 250000
}
const {name,price} = obj
//name =&gt; &quot;phone&quot;
//price =&gt; 250000</code></pre>
<p>디폴트 값 객체 분해</p>
<pre><code class="language-javascript">const obj = {
    price: 250000,
};
const { name = &#39;test&#39;, price } = obj;
//name =&gt; &quot;test&quot;
//price =&gt; 250000</code></pre>
<br/>

<h1 id="77-매개-변수-분해">77. 매개 변수 분해</h1>
<p>함수를 정의할 때 괄호 안에 매개변수를 작성하면 전달되는 값의 구조를 분해할 수 있다.</p>
<pre><code class="language-javascript">const obj = {
    name: &#39;test&#39;,
    id: &#39;test&#39;,
};

function test({ name, id }) {
    console.log(name, id);
}

test(obj); // &quot;test test&quot;;</code></pre>
]]></description>
        </item>
    </channel>
</rss>